Understanding programmer's block

published: Wed, 11-Feb-2004   |   updated: Thu, 27-Oct-2005
Bird house

There I was, implementing some requirements, when I suddenly stopped. Nothing would come. My fingers hovered over the keyboard, hesitant. My thoughts were looping, going nowhere. I had programmer's block.

You've all heard of writer's block, I'm sure. This is when an author stares at a blank piece of paper (or a blank document in Word) totally unable to write anything. Nothing comes, no character, no plot point, no dialog. The writer cannot think of anything to say. Sometimes, I'll admit, under time pressure, this hits me too. I have to write an article for The Delphi Magazine by the 25th, but my mind is blank. What was that nifty algorithm I came across last week and made a mental note to investigate further? Nope, gone; the synapses have reformed in another configuration. Hard cheese. Stare at the screen some more.

Programmer's block is like that. You're faced with a blank editor page in your IDE and nothing comes. No brilliant connection from requirement to design, let alone to implementation. Just stuck. Why is this?

1. You don't understand the requirement. Nothing for it but to go back to the customer or the business analyst. What did you mean by...? It may be, of course, that the requirement is too general and needs refining into two or more simpler, more well-defined requirements. Robert Glass talks about this in Facts and Fallacies in Software Engineering in Fact 26: "The list of derived requirements is often 50 times longer than the list of original requirements." This is not a failing of software development, it's more a fact of life. The reverse is worse: trying to refine all of the original requirements into step-wise design requirements before you start coding. This way leads to madness and "analysis paralysis." I know about this too: I've been there.

So, the solution to this kind of programmer's block is to talk to your customer or to the business analyst that provided the requirement. Try and get more understanding about the requirement by getting the writer of the requirement to talk it through.

2. You can't think of how to implement the requirement. OK, you understand the requirement, but you're vacillating between two or more ways of implementing it. Like the donkey between the bale of hay and the bag of carrots, you're hovering in the middle unsure of which is better, and consequently starve to death.

The reasoning to apply to this kind of programmer's block is to consider the characteristics by which you are weighing up the different possible implementations. Is it elegance? Is it performance? Is it a coolness factor? Is it familiarity with class X versus class Y? Is it the amount of research needed? Step back a moment. Think about what you are trying to achieve. You want to write code that will be easy to test (and prove that it works) and that will be easy to maintain later on. An added benefit might be extensibility points, for example.

So, elegance? That will come from writing the simplest code that will do the work. Performance? Leave it until you have something to measure, to profile. (It is one of the stupidest things a developer can do, to optimize for performance when he doesn't have any code to profile. How does he know whether he's made an improvement? Optimizing for performance without writing any code is like describing a Pollock painting. You can't.) Coolness factor? Get over it. It's way cooler to be in the pub before closing time than be still hacking away at your desk because you just can't get cool class X working the way you want it. Familiarity? Approach new classes slowly, method by method. Don't try and understand everything straight off. For example, the Queue class in System.Collections has a constructor whereby you can pass in a growth factor. So what? Forget it, just use the standard constructor. Research? Sometimes it's unavoidable, but try and avoid it as long as possible.

I may sounds like a broken record here, but Test-Driven Development (TDD) helps a lot here. Attack the problem bit by bit. It's like creating a statue from a chunk of marble. You start off with a goal, Michelangelo's David, say, and you chip a bit off here, and a bit off there, and pretty soon you have a recognizable statue. TDD is like that, but with a safety net (the tests). You write a simple test, and then the simple code to satisfy and pass the test. Refactor to simplify even more. Repeat and rinse. You never attack the whole thing at once; you're implementing it bit by bit.

TDD forces elegance (you never get so much code that you're scared to refactor to make it simpler and more elegant). Performance can be addressed as early as you want by writing performance related tests (run a test loop several times, or run a test that mimics real use of the class, and fail the test if it completes in longer than some time limit). Coolness is the ability to show that your code works, rather than assuming that it does. Familiarity with the unfamiliar comes with just using what you need right now. Research is also limited to what you need right now.

3. You're under stress from an unreasonable schedule. This class has to be finished by 5pm. This form has to be complete by the time the customer arrives for the meeting. Whatever. The stress causes your wheels to grind to a halt, and you sit there and shake. You sit there like a deer in the headlights, unable to move.

I don't have any great ideas here. We've all been in the situation, and we will all be in a similar situation before too much longer. Me? I try and relax for five minutes or so, by doing something else. Review some other code. Check your e-mail. Listen to some music. Fiddle with the settings in your IDE. Get your mind off the code. When you go back, take it easy, take it step by step. Don't succumb to the feeling of helplessness. Don't abandon testing.

Maybe an ounce of prevention is worth a pound of cure. Before you get into this kind of programmer's block again, think about why it happened last time. Was it because you had to make a change to some code, but didn't have the tests to make sure you didn't screw it up? Then make a resolution to write more tests, and to use TDD. Was it because the build failed? Think about how you'd make sure it didn't fail again. Maybe some effort should go into strengthening the build script before the next inevitable mad rush. Maybe the build should happen every day like they say it should in all the good agile methodology books, so make sure it is. Was it because Visual Source Safe corrupted its database and you lost all the new code from the last two weeks? Maybe you should use another source control system, maybe you should make sure that backups are done daily. Research and make it so.

Whatever the problem is (or was), think positively about how you'd try and avoid it in the future. In general, it means using your intelligence and your computer to help you. Write scripts, write programs, use the Windows scheduler to help you backup, run tests, build, run diffs, create result pages, page your phone, whatever.

4. You're totally and utterly bored and can't get the motivation to code. Think of why you're bored. Maybe the boredom comes from writing the same trivial type of code for the 42nd time. So, think about how you'd use code generation techniques to create it on the fly. Research that. Make it a side project to spring on your co-workers once it's complete.

Maybe the boredom comes from the type of work. You're a UI-type of developer, but you're being forced to write database access code (or vice versa). Alas, the solution to this depends on your workplace: how easy is it to move to another "layer"?

Maybe the boredom stems from something else that's not immediately obvious. Think of ways to make your work more interesting. Do some refactoring. Go for a walk around the block to take your mind off it. Spend half an hour planning how you'd like to make it better, how you'd reorganize it to avoid the boredom, and see if you can't implement it. Invent a sudden malaise that requires you to go home and rest in a darkened room. If it's the fifth day of this problem, then maybe this job is not all it's cut out to be. Maybe you cannot get passionate enough about the product, the company, or the market. Time for a new job.

5. You've realized that you're not cut out to be a developer. So, get another job.

I've hit the first four reasons for programmer's block before, but never the fifth. Sometimes the solutions to my programmer's block have been simple, sometimes more drastic. Many times I've been able to remove the block by researching and implementing some piece of a methodology (which is why I'm a fan of TDD and code generation). I'll admit that avoiding the "deadline crunch" type of programmer's block is the hardest for me: sometimes I get through the crunch, go home in relief and forget to make plans to avoid it in the future. I'm getting better though in my old age.