Want to write some code? Get away from your computer
blog.rtwilson.com
blog.rtwilson.com
I think you are right, about letting go of all assumptions, and that helps you find the edge cases.
Any time they had a problem they couldn't figure out, they'd come to me and ask me to help with it.
My trick was to listen to their problem and then go take a walk. Our office was in a nice area with plenty of sidewalks. So, I'd get the details of the problem and then go take a walk for about a half hour while I thought about the issue.
After the walk I was able to sit down and my computer and implement whatever weird thing it was.
These days I do work from home (freelance) so I find myself pacing around my house while trying to figure out something odd. I think I've worn a groove in the grass at this point.
It really does do wonders for the brain.
I've found that when I'm in bed trying to fall asleep is when I do a lot of brainstorming for my ideas rather than problem solving
Also, I may have, on one or two occasions, written code on the tile walls with tub crayons.... after all, you get a brilliant idea, you don't want to lose it in the time it takes to dry of.
I'd say that in addition to letting go of assumptions, it's just as much about breaking patterns.
I often find that once I start trying to fix a problem, my brain gets stuck in that way of fixing it and if that doesn't work, it then becomes a matter of fixing the fix, etc. It all just kind of builds up. If I'm standing in the shower with hot water pouring over my head, I can free my mind of whatever I was concentrating on and then new ideas emerge.
But I think it's much deeper than that. It's the basic truth that creativity emerges from a still mind. First you spend hours obsessing in front of the screen seemingly achieving nothing. Later you seemingly do nothing and solve the hardest problems.
It's an excellent practice to take breaks where you do nothing. Pretend to be a smoker and step out for a smoking break every hour or so.
Sometimes a relevant idea will just come to me while I'm away (I carry a pencil and bit of paper for such occurrences, as it is very annoying to get back to my desk and forget the beneficial train of thought!), sometimes I'll hit the problem from a slightly different angle when I get back and find success that way.
I think mainly the difference is usually stress. Forcing your mind to think about a particular problem can drive you into a mental rut in which you think the same things over and over and get nowhere, getting more irritated at your lack of getting anywhere as time goes on which creates more stress and makes matters worse. At times like that inspiration is less likely to strike (or be recognised when it does). Having time to ponder a problem, consciously or otherwise, can be very fruitful.
This fits in quite nicely with the idea that the sleep pattern we've evolved is as much about rearranging what we've learnt and experienced while awake as it is about anything else (like the brain's DBA taking time to run DBCC REINDEX on everything so our thinking is more efficient the next day). It also tallies with the fact that some of the most successful people I know are generally more relaxed (and not just because they are more comfortable due to earlier success) than myself!
A developer sitting in another office had written it; I was roped in at the moment the nasty bug was discovered, basically to have a look from a fresh set of eyes. It had to be shipped in a couple of days time.
The neat thing about writing code on paper is the amazing gain in clarity. Of course, like all approaches, it has to be taken with a grain of salt.
It seems to me that the necessity of scrolling on a Laptop screen somehow creates additional cognitive overhead, especially when we want to rapidly jump across sections of code. Perhaps, it forces us being physically away from the machine to reflect more deeply on the problem.
Can't entirely agree. I'm not a grizzled programmer, so sometimes when I'm coding for microcontrollers the debugger winds up teaching me about some new quirk in architecture. It's often something I was aware of (endianness, some of the finer details of addressing) but had not yet actually dealt with in person.
When it comes to a dynamic language, knowing how and what lead to a particular function being called is important and all that information isn't exactly saved on the stack trace---you have to step through to find it.
However, a lot of the biggest headaches are conceptual and in which case taking a break from the computer almost always helps I find.
It's just the catalyzing power of the internet that drives people to the extreme of insisting one should never, ever use a debugger. Or a plane.
That fact that other people can misuse a tool is a really stupid reason to not use it yourself. I've had great success in using debuggers to identify which assumption I was wrong about when the code did something unexpected. If you're so awesome that you never make bad assumptions about your code... you're probably not pushing yourself hard enough. Perhaps that's your job's fault. I'm pushing myself to my limits in my job, and I'll take all the help I can get.
Sometimes good old pen and paper is the best solution when you find yourself getting into a bind. Other times, stepping through the code and watching what happens to the data/memory is the way to go.
Then recently Randal Munroe published an XKCD cartoon on attention deficit management [1] which when I saw it, it really resonated with this same experience. Basically by slowing things down, quality improved. Clearly there is a fundamental principle here somewhere, something along that lines that there is an ideal pace for development (perhaps unique to each individual) where going faster or slower than that ideal negatively impacts quality.
On the other hand, in a fast-turnaround environment like Lisp, I can make three stupid mistakes in about a minute, and when I realize I'm thrashing, I still have all the context in my head to figure out what I should really do.
The experience of "coding", with its quick feedback loop hypnotizes people into an unproductive leash. The nature of the problem, the language and tools either help or exacerbate.
My experience is that most hard problem solving needs at least three approaches - I paraphrase them as 1. Zoom Out, 2. Zoom In 3. Zoom away. Debuggers aside, I found that program construction in interpreted languages (my work was in Lisp) supported with a good toolset and modularity in design, allowed productive zoom-in, zoom-out whereas programming in "edit/compile/debug" languages even with the toolset and modularity required "zooming away" more often. Could be that the context switching cycle of edit/compile/debug is a cognitive tax that really hampers hard problem solving or when things are not working as expected.
Marvin Minsky said in his influential paper Steps Toward Artificial Intelligence that "everyone should know the work of George Pólya on how to solve problems." - Wikipedia
I adhere to this adage and find it to be true
> 5. Make small change to the code on the off-chance that it might solve the problem
Whether practising TDD or trying to formalise the problem on paper (or in your head), this is not the way to write code. Programming is not a random search problem.
These days, I tend to only step away from the keyboard when I'm losing my bearings for where I am in the big picture. Usually, that's when I'm "making small changes to the code on the off-chance that it might solve the problem"… this means I don't really know what the problem is.
"It’s very easy to slip into the mindset of:"
His point is that the procedure that he gives (in particular step 5) is the wrong one.
Guess and check, supported by a scaffolding of tests is not the path to being a better or more professional programmer and this is precisely what he's advocating against.
Every once in a while I'll get motivated and start coding it up. I'll start to think "I didn't think I could do it that way when planning it on paper, but I can't remember the reason...I'll just see what happens."
A few hours later I get to the "oh yeah..." part.
Funny thing is, that works both ways. Sometimes no matter how much you plan, if you just start coding you get the positive "Oh yeah!" moments that wouldn't have happened on paper.
I try to emulate this environment (by not compiling/running code) and trying to tell myself that I really should get a large chunk of thought (followed by relatively bug-free code) down before I let the compiler/interpreter in. This discipline has helped me a lot imho.
If you did indeed write good test cases, then that's a prime indicator that you understand the problem you're solving well. Try test first programming, it's trickier than it sounds at first. In my opinion, it is too easy to get caught up into coding something (especially with languages that have large amounts of boilerplate, such as Java) and lose perspective of what you're actually trying to do. Writing test cases beforehand forces you into thinking about what you're actually doing.
I've found this approach does give a better result and eliminates false starts. When I'm at the computer now I have already thought through what I'm going to do completely and writing the code is just a minor detail.
I do most of my outlining away from the computer, with pen and paper. UML is your friend! http://en.wikipedia.org/wiki/Unified_Modeling_Language
Honest question, I'm a student and none of my school/pet projects have been difficult enough that stepping away from the computer was beneficial. Only puzzles have been hard enough.
This is a rant against write, run, debug, repeat, not visual studio.
Even Notepad++ has run in it.