In my previous article, I looked at how the concept of simplicity in fiction writing can be applied to writing code. In this follow-up piece, I explore how writing that first draft, and editing, can help guide programmers towards perfecting their code.
“The first draft of anything is shit.”
The cornerstone of writing a novel or short story is to write. This may seem obvious, but it’s not. A lot of time, aspiring authors get bogged down in the details. I know, I’m one of them, and it’s hard to break the habit. I’ve done some of this while writing this post. It’s easy to get obsessed with details: going back and re-reading what was written; making tweaks and editing previous pages before carrying on; pondering on the world you’ve created; or thinking of the myriad of details and research you need to get it perfect.
While these activities can be important, all too often it diverts attention from the central activity, which is that you need to write, and then worry later when that first draft is finished. This is why, for example, the National Novel Writing Month tries to encourage people to write a completed novel of 50,000 words in a month, by “giving yourself permission to make mistakes. To forgo the endless tweaking and editing and just create.”
Very few authors write a first draft that they consider to be complete or perfect. That first draft almost always requires substantial editing, maybe several major rewrites, to get it polished enough that it is publishable in book form.
None of this is possible, however, unless you actually finish what you set out to write.
A finished novel will be imperfect, but it’s something you can potentially fix. No amount of editing could save an unfinished novel. And even if you cannot fix it, as Neil Gaiman says, “You will learn more from a glorious failure than you ever will from something you never finished.”
The same advice is equally applicable for programming. How will you know your code will work, or do what you set out to do, if you don’t finish it? How will you know if your open source project is something people will use if it’s never finished and released into the wild? Margaret Atwood put it beautifully: “If I waited for perfection, I would never write a word.”
It’s too easy as a coder to get fixated on getting it right, first time: working out the perfect abstractions, planning every object, optimizing everything in your code, going back and changing what you’ve done already because you figured out a more efficient way of doing it. Again, that’s not to say that these activities are not important, but your primary focus should be on completing and implementing what you set out to do. It’s never perfect from word go, so finish what you start.
One caveat to remember is, as Stephen King notes, that “it’s rare that incoherence or dull storytelling can be solved by something so minor as a second draft”. Whatever you’re writing has to deliver the central story or idea you’re trying to convey, and so too your code should satisfy all necessary business requirements and at least be done in such a way that future change is easier and possible, and you’re able to understand it easily enough to rework it.
Now, fortunately, programmers do like to create code, especially new code. What they often hate is working on existing systems, or dealing with legacy code. How often have you heard the classic mantra, “This system is awful. We need to throw it out and start from scratch.”? Almost always, this is because it’s harder to learn an existing system than to just create new code. This is how we end up in a situation where a code base can have similar libraries, or even competing frameworks embedded within one another.
Project managers, on the other hand, love programmers that finish fast in order to move onto the next task, and we often are more than capable of delivering. Coders don’t want to get stuck in a project that drags on and on, and if we’re bug fixing trying to do something in a massive, sprawling legacy system, we want to get in and out without any fuss. We’ve got a ton of work, tight deadlines, and the idea of creating more work for ourselves within the same deadline is unappealing.
The problem, however, is that “finishing” tends to get defined as “it’s working”: prototype code is viewed as production code, and gets deployed as is, and any bugs that appear are fixed as time goes past, but the necessary second part of “finishing” is ignored: refactoring.
Imagine the author who completed his first draft and submitted it as-is for publishing. It’s highly unlikely that anyone would accept such a piece of work. Editing is an essential part of the process: fixing typos; identifying plot holes and continuity errors; stripping out all that is unnecessary; choosing the right words; reorganising your text into a coherent structure. It is a long list, and it’s where the real work begins.
To return to the quote at the start of this article from Ernest Hemingway, a more complete version is as follows:
Don’t get discouraged because there’s a lot of mechanical work to writing. There is, and you can’t get out of it. I rewrote the first part of A Farewell to Arms at least fifty times. You’ve got to work it over. The first draft of anything is shit. When you first start to write you get all the kick and the reader gets none, but after you learn to work it’s your object to convey everything to the reader so that he remembers it not as a story he had read but something that happened to himself.
This is useful advice to any coder, and can be adapted to our context: There’s a lot of mechanical work to programming, and you can’t get out of it. We get a kick out of creating our code, but afterwards, we need to rewrite and refactor. The central aim is to get it into such a position that another reader – that is, another coder – is able to look at your code and understand it in such a way that it is as if they had built it themselves.
In order to edit effectively, you need to look at what you’ve done with fresh eyes. Steven King spoke about locking away the first draft of a novel in a drawer for before taking it back out to edit, and other authors have given similar advice. Being able to re-read your work as if it were the first time you’ve ever seen it gives you the ability to be able to rip it apart, strip it down, and hone it to the bare essentials.
While we often don’t have the luxury as coders to lock our code away for a few weeks before refactoring, we are always working with systems that have been in existence for some time, or delving into code that we wrote weeks or months ago. Perfecting code is an ongoing process, and you should allow yourself to revisit what you’ve done in the past with the aim of improving it where possible. How often have you looked at your old code, and realized while looking at it how greatly it could be simplified or improved? This ties in directly with the concept of technical debt, and helps pay it off.
In the more immediate short-term, in order to get that fresh perspective, Neil Gaiman advises writers to “Show it to friends whose opinion you respect and who like the kind of thing that this is.” This is where code reviews and advice from team members or open-source collaborators becomes critical in getting your code into better shape. If you cannot see beyond that cluster of methods and classes, look through another’s eyes and get their advice.
While all of this can help you fix your code, never forget another piece of valuable advice from Neil Gaiman, that “sooner or later, before it ever reaches perfection, you will have to let it go and move on and start to write the next thing. Perfection is like chasing the horizon. Keep moving.” Treat your code in the same fashion, and remember that the perfection you seek will arise from continuing to code, finishing it, refactoring it, and moving forward.