Most of the code I write, for my research or just for fun, isn’t writen to a hard deadline. Consequently, it’s too damn easy to ignore it and write blog entries, read other people’s blogs, go for a beer: in general, without a looming deadline it’s too easy to procrastinate.
I’ve read a fair bit about “agile processes” — eXtreme Programming and so forth — and like what I’ve read. Index cards, refactoring, test-driven development. It’s all good, but it doesn’t address the procrastination issue.
I’ve also read some sorta-conflicting advice from such people as Steve McConnell and Joel Spolsky — lightweight schedules, functional specs, and so forth — and also like what I’ve read. It’s good stuff, but it still doesn’t address procrastination.
I’ve written programs that work. I’ve also started projects that never got past the design document, or the first header file, or what have you. What’s the difference between the two? Why do some of my projects take off, and others fall flat?
The ones that get going do interesting things right away.
For example, in my copious spare time I’ve found myself writing a hex map library in SDL and OpenGL. I started by opening a text editor and writing:
libhex design
0. Introduction
Libhex is a hexmap library, written in C. It uses SDL and OpenGL to draw the hexmap.
Then I got bored writing design documents and wrote a program that opened an SDL window. It took me all of about thirty seconds, and already I had something running. FIve minutes later, I could draw a white hexagon outline on a black background.
Hey, neat: a hex!
From there it’s just a matter of saying “glBegin(GL_TRIANGLE_FAN)” instead of “glBegin(GL_LINE_LOOP)” and adding a couple more vertices and I have a filled hex. Half a dozen small and easy changes later, my program can load a hexmap from a text file and draw it. This took me about three hours.
If you’re up on your Agile Methods theology, you’ll recognize this process as something of a cross between a Vertical Slice (get a small end-to-end working solution ASAP) and Test-Driven Development (make a small change, make sure it works, refactor, repeat). Okay, I’m not actually writing formal unit tests — perhaps I should be, but that’s a rant for another time. The thought process is the same: “It’d be really cool if my code did <foo>. It doesn’t. Let’s make it do <foo> — oh wait, that’s too complicated. Let’s make it do <bar>, which is a good first step. <code, code, code> Hey, that was easy. Run it — look, it does <bar>; outstanding. Now it’s just a matter of adding <baz> — that shouldn’t be too hard.” And so it goes.
There’s one catch: refactoring is vital to the process. If you start with a program that does one thing well enough to give you a shot of satisfaction and keep glomming features on top of it, you’ll end up with a big ball of bullshit. Adding more and more features will take longer and longer and cost you more and more pain, and eventually you’ll give up. The whole point of this method is that you stay motivated — every time you do something, you end up with either a program that does something new or a codebase that looks prettier. Let the refactoring slide and you end up with a codebase that looks awful and a program to which you can’t add features without excruciating pain.
So this is all cool when you have a long list of small features to add, but what do you do when you run out of easy little features? Daydream. Think of features you’d love to end up with until you hit something that fires you up — remember, the primary goal here is motivation to keep hacking. Motivation is mother, motivation is father. Once you get something that’s cool enough to get you motivated — but not intimidatingly complex — start picking at it until you’ve decomposed it into a good long list of easy little features. Then fire up Vim and start hacking.
Another caveat: I’ve never tried this approach as part of a team, and I’m not sure I want to. The goal isn’t to keep a team working productively, it’s to keep a programmer motivated enough to get stuff done.