There are certain moments in programming that make it really satisfying. There are eureka moments, learning moments, and finally-fixed-that-elusive-bug moments. And then sometimes there are spontaneous moments of creation, like watching a thousand shards of crystal fall together into an equisite vase.
There are several different schools of thought when it comes to how one should engineer code. The traditional, old-school outlook is to write out a design on paper first (probably done by a dedicated software architect). Then that design would be divided up, and each piece given to a low-level programmer (a true code monkey) who would then translate his piece into working code.
The currently fashionable, agile (or rather Agile) schools of thought favor an iterative design. Start with something really simple and small, but get that little atom of functionality working as soon as possible. Then, taking many small steps, add more atoms of working functionality, refactoring what’s already written, until the whole resembles the desired outcome, even if you don’t know exactly what the desired outcome is supposed to look right.
It’s like constructing a skyscraper: you build a foundation first, then a skeleton of a building, then flesh it out with brick and mortar, one story at a time, building upward.
I don’t think anyone advocates visualizing an entire design and coding the whole thing in one, huge step. The process is error-prone, there’s nothing to show the users until the whole construction is complete and debugged, and there’s little flexibility for improving the design when something new is discovered. It’s like building all parts of all stories of the skyscraper simultaneously. There’s nothing in the mechanics of computer programming that naturally discourages you from doing this, though, in the way that Earth’s gravity naturally discourages building an entire skyscraper in one step. Programming happens in the microgravity of space — all the myriad pieces can float uselessly beside one another until the last connection is made.
But sometimes this rather haphazard approach feels like the natural one. Sometimes an entire design occurs to you all in one flash. With no discoveries assumed to be made during the building process, turning the design into working code suddenly feels like a tedious process. You’re impatient to get it behind you so you can move on to the next cool challenge. When this happens, all of those prudent schools of software design — new and old — become such a drag: drawing out a paper design ahead of time seems like artifact overkill, agile methods seems like taking baby steps when you’re ready for adult leaps, and test-driven development seems like belaboring a question that’s already been answered.
But in the same way that the mental image of crystal shards coming together in one moment to form a perfect vase is cool, writing the code that way feels cool. So you try it anyway.
Sometimes you fail. You work for hours, only to realize you made a flawed assumption from the beginning, and the code you’ve written is useless — a twitching lump of tissue and muscle in Dr. Frankenstein’s reanimation lab. You’re devastated. Less so by the fact that your beloved creation has to be abandoned, and more so because you’re now faced with no choice but to do proceed slowly and prudently, the boring way.
But other times you win. Big. Sometimes the gamble pays off, and you accomplish in hours what would have taken you days otherwise. You feel a rush from your level of accomplishment spiking at tenfold of normal. You’ve kicked ass. And you want to do it again. Do you try?
Your lucky number at the roulette table just won you a month’s salary in one spin. Do you walk away from the table, or bet your winnings on the same number again?
Here I sit this Monday morning, staring at my code. Green and amber typography on a black canvas. I’m sipping my coffee and pondering that gambler’s choice.
But there really isn’t a choice, is there? I open a new source file, roll the dice, and type like mad…