Critical Section

The Lead Bullet - Writing Specs

Thursday,  07/24/03  01:28 AM

Programming is hard

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?

Writing specs is hard

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...)

Writing specs is good

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.

In the old days (yeah, I'm dating myself here), programmers used to write code on paper first.  There was such a think as "desk checking", which essentially meant carefully reading your written-on-paper code to try to find errors.  Then you would laboriously keypunch the program onto cards, and run the deck.  Keypunching took a long time and fixing errors was difficult, and running a deck took a long time and fixing errors was even more difficult, so it really paid off to spend some time planning up front, and carefully desk checking code.

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.

Writing good specs is good

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.

W=UH and specs

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:

  1. Programming without a spec
  2. Writing a spec, then programming

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...

  • Get as much functional requirement information as possible.  As noted above, much of the difficulty in spec writing stems from uncertainty.  So more information is good.
  • Leverage existing documents and code as much as possible.  Why reinvent the wheel?  Nothing is easier than cutting-and-pasting, both for documents like specs and for programs.  Often crafting a design in such a way as to allow document and code reuse is well worth it.
  • Leverage other people as much as possible.  Is there a product marketing person or salesperson who knows a lot about the problem to be solved?  Ask for their help.  Is there a customer who can help?  Very often customers and prospects will gladly document their requirements, simplifying the spec writing process and making it more likely the problem you're solving is one the customers care about.

If you can actually make spec writing seem easy, then you've truly got it made :)

About Me

Greatest Hits
Correlation vs. Causality
The Tyranny of Email
Unnatural Selection
Aperio's Mission = Automating Pathology
On Blame
Try, or Try Not
Books and Wine
Emergent Properties
God and Beauty
Moving Mount Fuji The Nest Rock 'n Roll
IQ and Populations
Are You a Bright?
Adding Value
The Joy of Craftsmanship
The Emperor's New Code
Toy Story
The Return of the King
Religion vs IQ
In the Wet
the big day
solving bongard problems
visiting Titan
unintelligent design
the nuclear option
estimating in meatspace
second gear
On the Persistence of Bad Design...
Texas chili cookoff
almost famous design and stochastic debugging
may I take your order?
universal healthcare
triple double
New Yorker covers
Death Rider! (da da dum)
how did I get here (Mt.Whitney)?
the Law of Significance
Holiday Inn
Daniel Jacoby's photographs
the first bird
Gödel Escher Bach: Birthday Cantatatata
Father's Day (in pictures)
your cat for my car
Jobsnotes of note
world population map
no joy in Baker
vote smart
exact nonsense
introducing eyesFinder
to space
where are the desktop apps?