Ernest Hemmingway once said that writing is easy: all you have to do is sit at a typewriter and bleed. The same could be said of coding, although you really need a computer rather than a typewriter. Writing code on a typewriter is a very long-winded way of going about developing software, and isn’t generally recommended unless you’re some kind of super-committed hipster with an bespoke typewriter and an artisanal hair clip to keep your epic beard from getting caught in the hammers.
I like writing, and I like writing code. I especially like writing code that kind of reads like writing, but I try and avoid the opposite, because it’s very frustrating and ultimately pointless, like region encoding and DRM.
I’ve been thinking for a while about the similarities and differences between writing and writing code, and I thought it might make an interesting post. Fortunately, as previously stated, I like writing, so here it is.
Know Your Audience
“The best audience is intelligent, well educated and a little drunk.”
Alben W Barkley
It’s well-established that when writing, you should keep your audience in mind. Who are they? Why will they be reading this? What will they be hoping to get out of it? What knowledge can you assume? How easily offended might they be? Is this really the right forum for that dick joke?
The hardest part about writing code is that you’re writing something that necessarily has to be consumed by two completely different audiences at the same time: the machine, and other programmers. The machine is precise, unwavering, pedantic, and utterly refuses to help you out by looking past the specifics of what you said to what you obviously mean, whereas programmers… well maybe the two audiences aren’t completely different, but nevertheless.
Writing good code is the art of giving the machine precise instructions in a highly constrained language while at the same time clearly conveying your intent to a human reader. Most bugs live in the gap between what the programmer intended and what they actually wrote, so it’s really helpful if you can express that intent as part of the code. The downside is that this can feel like a lot of extra work at the time, and it means that you don’t get to name your variables fun things like “foobar”, “l33Tsk1lZ” or “bumsex”†.
However, even if you hate your fellow programmers or work alone, the next person to come along and read your code might be a future instance of yourself, and they’re going to be really pissed off if you make life hard for them: about as annoyed as they are when you set the alarm the night before so they can get up early and exercise.
Don’t Make Me Think
“Thinking is the hardest work there is, which is probably the reason why so few engage in it.”
Henry Ford
Understanding code is hard work, especially code you’ve not written yourself. Even modern programming languages are heavily constrained in terms of how expressive they are for the human reader, so part of your job as a programmer is to make it as easy as possible for someone else to understand what the merry hell they’re looking at.
There are a lot of techniques you can apply here, but the main thing to bear in mind is that you’re trying to reduce the cognitive load on the reader. It might take longer for you to think of and type a precise, descriptive variable name, or to break a function out into several smaller pieces, but your team will recoup all that in time not spent furrowing their brows and cursing you under their breath.
The same is true in writing. If you read what you’ve just written and find yourself stumbling over a sentence, something needs to change. Maybe you need to put a hyphen between two words to clarify something which would otherwise be ambiguous, or maybe you need to reverse the whole sentence because the context at the end would help the reader interpret the point you made at the beginning. Again, all the extra effort you put into crafting and polishing the text makes it easier to absorb, allowing people to focus on what you’re trying to say instead of stumbling over how you’ve said it.
Less is More
“A smaller quantity may, counter-intuitively, prove to have greater impact than if there had been more of whatever it was that there was, in fact, less of.”
Ludwig Mies van der Rohe (early draft)
When writing, you should aim to express yourself as succinctly and simply as possible. No one will thank you for making them read something that didn’t add any value, just as no one will thank you for making them read code that’s duplicated or unused.
That is all.
Read
“I’m one of the few people who’s written more books than I’ve read.”
Garth Marenghi
It would be ill-advised for someone to attempt to write anything of much importance if they hadn’t read that much, but I’m pretty sure when I graduated with my Computer Science degree back in the heady days of 2001 that I really had written more code that I’d read. That’s preposterous. You learn to write well by reading good writing: you learn to code well by reading good code.
Step Away from the Keyboard
“You’re not paid to think! A mindless worker is a happy worker!”
Professor Farnsworth
When writing or coding, most of the really important work happens before your hands touch the keyboard.
There’s no point in sitting down and trying to write something if you’ve given it little prior thought. Sure, there comes a point when you need to actually start typing in order to thrash out the details, but you need some sense of where you’re headed before you start, and it’s easier to work that out if you’re lying in the bath drinking cheap Merlot than if you’re sitting in front of an uncooperative text editor being badgered by the spell-checker. ‡
Likewise, there’s no point in typing frantically into an IDE if you have no idea how your code is going to work. Before you start, you need to understand the problem you’re trying to solve and roughly how you’re going to go about it. At the very least, you need to be able articulate clearly what it is you’re trying to achieve.
Kill Your Darlings
“In writing, you must kill your darlings.”
William Faulkner
Sometimes you can spend a significant portion of time lovingly crafting something, only to find yourself suspecting that what you’ve produced is, in fact, a steaming pile of crap. This is fine: it’s part of the process. It’s not always possible or sensible to try and work out where a line of thinking will take you before you’ve made a start: sometimes the result has to be staring you in the face before you know for sure.
However, just because you spent a lot of time on something doesn’t mean it’s valuable. Don’t be afraid to delete whole paragraphs that add nothing, and don’t feel bad about putting that beautiful-but-ultimately-useless class to one side and doing a git reset — hard.
Don’t Be Clever
“It’s such a fine line between stupid and clever.”
David St. Hubbins
If someone has to be a genius to understand what you’re trying to convey, in most cases, you’ve done a bad job. Likewise, if someone needs to be a Linus Torvalds-grade propeller-head to understand your code, in most cases, something’s gone wrong.
Just because something is clever (an obscure word, or a little-know language feature), that doesn’t necessarily mean it’s a good idea. All else being equal, if there’s a simpler way to do it, do it that way. Your job is to make life easy for everyone else, not to show off.
Always Write Well
“It’s a funny thing, the more I practice the luckier I get.”
Arnold Palmer
One of the best ways to maintain and improve your writing is to always write well, no matter what you’re writing. It doesn’t matter if it’s an email, a comment on a blog post, or a text message: always aim to communicate clearly.
The same is true when writing code, although if I’m honest I find this more difficult to stick to. Just because this code is part of a unit test, that doesn’t mean it shouldn’t still be readable and clear: in fact it might be even more important.
Prose Before Codez
“Without requirements or design, programming is the art of adding bugs to an empty text file.”
Louis Srygley
How may times have you started to write some code only to realise you didn’t fully understand what it was you were trying to do? Likewise, how many times have you started to explain something you thought you understood to someone else, only for it to slowly dawn on you that there were whole aspects you hadn’t thought about, and now you feel kind of silly.
The act of putting ideas into words forces you to think clearly and precisely, which isn’t how the human brain works a lot of the time (at least mine doesn’t). We have a lot to think about, so we tend to bleep over things and make lazy assumptions. However, once you’re putting those fuzzy thoughts into words you’re forced to make choices about how to express them, and those choices force you to crystallise the, you know, fuzzy stuff.
The upshot of this is that it’s often a good idea to write down what it is you’re about to try to do before you start. Do you really know what the requirement is, or are you working off the back of a one-line user story? Can you define the scope and purpose of your system, let alone the change you’re about to make to it?
Conclusion
Conclusion — noun; a concatenation of “concussion” and “illusion”. To browbeat a victim until they hallucinate understanding.
Writing and coding are both hard to do well, but nevertheless very worthwhile and often overlapping and complementary. No matter how long you do either, there’ll always be room for improvement, and I’m starting to suspect there’s a limit to how well you can do the latter without putting effort into getting better at the former.
† This is a real one taken from some code I reviewed quite a while ago. It’s second in it’s inappropriateness only to the name of a test method I wrote while testing a security feature, which in all innocence I decided to call “attemptToDoForbidenThingsOnBackEnd”.
‡ This works for me at any rate: your millage my vary. Also bear in mind that drinking in the bath violates most companies’ open-plan etiquette, so work from home or pick your moment wisely.