Programming is hard. Everyone knows this; there are hundreds of books written each year about how hard it is and what to do about it. Universities teach classes in managing programming projects, because the general difficulty of scheduling software is an acknowledged business problem. Can nobody do anything to make it easier?
Well, people have tried. They try all the time, and a lot of pretty innovative improvements to programming technique have come along. Structured programming, object-oriented programming, functional programming, data-driven programming, even extreme programming have been devised. New languages have been invented and new system architectures have been derived. New development environments have been created, including spiffy on-the-fly compilers and interactive debuggers. All of these things help, no question. But the thing that helps most is writing good specifications.
Ask any programmer about writing specs, and they'll cringe. Generally coders don't like to code in English. So, if spec writing is the one thing that helps, why do programmers hate writing specs?
Yeah, writing specs is hard. Why? What makes specs hard? What makes anything hard? And why do we resist doing hard things?
Okay, here we go, let's launch into a bit of philosophy. First, things are easy when you know what to do. Even if the thing you have to do itself is not simple, the overall task is still "easy", because it is fully understood. Things are hard when you don't know what to do. The act of figuring out what to do is usually more difficult and complicated than the "what to do" itself. The reason spec writing is hard is that it requires figuring out how something is going to be built. Essentially you must force yourself to be creative; you must derive a solution given a set of constraints.
So that's why writing specs is hard, now, why do we resist hard things?
I believe happiness comes from liking oneself. Things which make you feel good about yourself are "fun", and things which make you feel bad about yourself are not. Anything you don't know how to do is necessarily going to make you feel a little less good about yourself. After all, if you were that good, you'd know what to do! There is uncertainty; what if you can't figure out what to do? Or what if you figure it out, but your solution proves sub-optimal? The fear of failure hangs over any "hard" task. It is actually must easier simply not to try than to try and fail, so we resist. (This is related to the whole idea of Trying, see my essay on this...)
Okay, writing specs is hard, and we resist it, but why is it good? Can't we simply avoid doing this thing which is hard :)
Unfortunately writing specs is good for the same reason that it is hard. It requires figuring out how something is going to be built. This figuring out is crucial. It avoids a lot of blind alleys and wasted time, and this is why programming is made more efficient by spec writing. Most of the time if you know exactly how to solve a programming task, writing the spec for that task is not hard. It is only when you don't know what to do - when there is creativity involved - that spec writing is hard, and this is precisely when you should write specs.
Now with fullscreen editors and interactive IDEs and incremental compilers and just-in-time debuggers, there is no need to do any planning. You launch the IDE, you start typing some code, and poof - you run it. If you have a problem, you figure it out. The careful up-front planning is lost, as is the efficiency of thinking through a problem and its solution before diving in to implementation. Writing specs is the best way to get that efficiency back.
So writing specs is good, but certainly some specs are better than others. What makes a good spec good?
First, you need the right level of detail. There must be an overall description of the problem to be solved, from the user's point of view. These are often called functional requirements, and are sometimes packaged as a separate document. They are often written by product marketing folks rather than programmers. (They may even be written by customers!) Regardless, this information is crucial for a programmer. They must understand the desired behavior of the program, its reason for being, and the other functional considerations. This is the only way the programmer can develop a good solution.
Beyond the functional requirements, there must be information about the design constraints. This includes compatibility with other software, tools to be used, target platform, support considerations, performance goals, etc. The emphasis here should be on describing the constraints and goals of the solution without specifying the solution itself. As a spec writer you want to leave the programmer as much scope for creativity in devising a solution as possible - especially if the programmer is yourself :)
Too much detail can be as bad as too little. Overspecification is time-consuming and rarely helpful. Specs can have GUI guidelines, but they should not contain pixel-perfect screen shots or detailed example reports. Specs can give design considerations, but they should not dictate a design.
Okay, so spec writing is hard, and spec writing is good. Doesn't this contradict the fundamental equation of life, W=UH?
At first glance it would certainly seem so. After all, things which are hard, are wrong, right? Well, no. The problem is that writing specs cannot be considered in a vacuum. We have to consider the whole task, which is to program a solution to some problem. So we have to ask, which is harder:
Overall, approach (1) is harder than approach (2), and uglier, and hence wrong-er. Although writing specs is hard, programming without a spec is harder, since the spec makes the subsequent programming so much easier that the entire task considered together is easier as well.
Well maybe you accept that, but you're still troubled by the fact that writing specs is hard, and W=UH. How can spec writing be made easier? Here's some ideas...
If you can actually make spec writing seem easy, then you've truly got it made :)