Debugging Driven Development

[RSS feed]

March 26 2006

There are an awful lot of development methodologies floating about these days, running the gamut from agile development to model driven development. For the purposes of this entry, the success (or even the utility) of such development methodologies is irrelevant. What is relevant is what these methodologies promise: follow these rules, and you'll create better software.

What I'm not sure that any of these methodologies tackle sufficiently is a far more down-to-earth part of development: how to ensure developers stay motivated during the development process. What I mean by this is how can developers be kept interested in the task at hand, so as to ensure that the software they are working on moves forward at a reasonable rate? This is an overlooked factor because it is hard to define and even harder to measure. Programming is generally a long drawn out affair; even small percentage losses in productivity can have fairly large real world effects on timeliness, and on the quality of the delivered product. Since ultimately it is programmers who do the programming, the lack of focus on this area does us all a disservice.

I've known for quite some time that I suffer from a habit that is common to many programmers. When I finish a challenging part of a program - after having spent an awful lot of time looking at incorrect output of one form or another - I find myself so surprised that things are working that I then spend a silly amount of time rerunning the program and admiring the correct output. It's almost like I don't believe that it's really correct. When I eventually pull myself away from the programming equivalent of navel gazing, I find myself in a familiar, but unappealing, situation: I have a functioning, but incomplete system, and I need to add the next feature on the list to it. But adding another feature means that everything is going to stop working properly, and it's going to take an awful lot of work to get back to another point where the system will be working properly. And so I stare and stare at the screen, semi-paralyzed by the thought of breaking my perfectly functioning (if incomplete) system. Of course, eventually I pull myself together, make the first stages of the necessary change for the new feature and then I'm away, only for the cycle to repeat itself when the system reaches its next stable state. I've come to realise that all I'm going through in such instances is the programming equivalent of writers block; the fear of setting pen to paper for fear of starting down the wrong track.

Interestingly, over the past couple of years I've inadvertently stumbled on an effective technique for avoiding this problem in many circumstances. It's taken me a little while to analyse exactly what I was doing, but now that I have, I feel confident enough to coin a new development methodology (hoping that no-one has coined it before): debugging driven development.

The first thing to note from my previous description is that whenever a system I was developing got to a stable point, I paused (sometimes fairly considerably) before eventually starting on the path to the next stable point. These pauses are clearly a, if not the, major development bottleneck. As the length of these pauses seems largely outside of my control, logically - and although it may be counter-intuitive at first - the only solution to reducing the number of times I pause is to reduce the number of stable points the system is in. The less times the system reaches a stable point, the less times I pause my development.

One defining characteristic of all genuinely keen programmers is that they dislike their systems to have any errors in. If a programmer stays late after work one day, it's far more likely that they're trying to debug their system than it is that they're adding a new feature in. Therefore what I found myself doing was continually leaving some small part of my system in such a state that it needed to be debugged. So as soon as I finished one feature, there was a little bit of the system screaming at me that it needed to be fixed. Disliking any system screaming at me, I would beaver away until the message was gone. At which point another message would have popped up somewhere, demanding to be fixed. And so on and so forth. Suddenly I found the number of times I was pausing to navel gaze had diminished significantly. This may well sound like a recipe for anarchy at best, or low-quality systems at worst but the aim of this isn't to prevent the system ever reaching a stable state, nor is it the aim to leave small, and easily forgotten, bugs in. Rather the aim is to minimise the number of times the system reaches a stable state - outside of those dictated by the release schedule - by leaving blindingly obvious cock-ups in of the sort that stop the system in a predictable fashion whenever it is run. In practise I've found that ultimately the programs I've created using this approach have had significantly less bugs than those I created previously.

I've gradually refined this technique, and these days I often use the XXX exceptions I outlined in my previous entry about exceptions to insert annoying messages into the system at any point where a feature hasn't yet been filled in. Sprinkling around XXX errors leads to a situation where mentally I think I'm in a continual state of debugging because such messages appear as program aborts, but really I'm not debugging in the traditional sense of the term: I'm just using it as a carrot (or is it a stick?) to force me to continue to program. My overall productivity has increased quite significantly due to this technique.

Maybe this technique only works if your brain is wired similarly to mine, but I have a sneaking feeling it might be something that works for anyone else who takes pride in their programs. Debugging driven development might sound masochistic, or even deranged, but it works for me and it might work for somebody else - who knows?

Follow me on Twitter @laurencetratt

Link to this entry


All posts


Last 10 posts

An editor for composed programs
The Bootstrapped Compiler and the Damage Done
Relative and Absolute Levels
General Purpose Programming Languages' Speed of Light
Another Non-Argument in Type Systems
Server Failover For the Cheap and Forgetful
Fast Enough VMs in Fast Enough Time
Problems with Software 3: Creating Crises Where There Aren't Any
Problems with Software 2: Failing to Use the Computing Lever
Problems with Software 1: Confusing Problems Whose Solutions Are Easy to State With Problems Whose Solutions Are Easy to Realise


Tony Clark
Zef Hemel


Mark Delgano
Steven Kelly
Jim Steel


Marc Balmer
Ross Burton
Peter Hansteen
OpenBSD Journal
Ted Unangst


Peter Bell
Gilad Bracha
Tony Clark
Cliff Click
William Cook
Jonathan Edwards
Fabien Fleutot
Martin Fowler
John Goerzen
James Hague
James Iry
Ralf Laemmel
Lambda the Ultimate
Daniel Lemire
Michael Lucas
Bertrand Meyer
Keith Packard
Havoc Pennington
Brown PLT
John Regehr
Diomidis Spinellis
Shin Tai
Markus Voelter
Phil Wadler
Russel Winder
Steve Yegge