Developing Software is Like Writing an Essay
September 19, 2012
In summary, Paul discusses his process for crafting his famous essays. It's by no means a revolutionary process and will be familiar with most anyone who had written a lot and/or professionally before. However, as I read this and acknowledged this is how I approach writing commissioned articles (for this blog, I tend to not draft at all, but I consider blog post writing and writing articles that someone is paying me to write, completely different), someone else struck me.
This writing process is something that I (and I would say many developers) follow when writing software. For software, we just adjust some of the verbs, since we are writing code and not words, but the activities I believe are very strong parallels to the authoring of words.
Fast first draft == Just get something working
Rewrite == Refactor or Fresh-Starting
- Review == Code Review and/or Pull Requests
- Design for light readers == Clean API and Good Docs
Fast First Draft
The fast first draft when writing an essay is just to get ideas out on paper. It's as if the words might get lost if you don't get them out of your head. As you write, and write fast, you are pulling ideas from you head quickly, and this process will naturally encourage other thoughts and ideas to emerge that may or may not be related. However, by silencing your inner editor while getting this first draft out, you permit a freer flow of ideas out into your editor, yellow legal pad, or wherever else you may do your drafting.
When writing code, the idea is you just want to get to working software as quickly as possible with your first "draft". It's a very hard thing to do sometimes. To help with this inclination to do small refactors while I am still getting to "first draft", I do permit myself to leave comments in the code like # @@@ Refactor this later. I don't worry about security, performance, reusability, maintainability, and generally good architecture and API design on this pass. I am just trying to accomplish a singular external goal of having the software work.
Rewrites are what turn your pile of gibberish into something publishable and worthy of readers. In this phase, you are correcting simple spelling and grammatical errors, as well as we rewording complete sections of your draft. You may add new blocks of material as well as cut large parts of what was there already. You may find it necessary to rewrite multiple times until you are happy with it's refinements.
In software, this is where the working software is giving one or more passes to clean code up with an eye on quality. By quality, I mean things like what I previously listed--security, performance, reusability, maintainability, good architecture, solid API design, and so forth. This is where making good use of Patterns can be helpful. One approach that is useful is to reduce as much code as possible without changing functionality. However, you don't want to reduce to the point of having to be clever and thereby making it harder for another developer to read, understand, and maintain.
It's really easy to either fall in love with your own pile of junk that you have written, or complete hate and despise your masterpiece. Having a reviewer provide an outside opinion on your work not only helps spots areas for possibly improvement but also provides a reality check on the material. With the right reviewers, it is also an opportunity to grow and learn as you take and incorporate the feedback received.
With software, this review process is even more critical to produce really high quality software. It's extremely difficult to produce high quality, flawless software, and unlike an article that a reader likely will only ever read once, your software has the potential to be reused many times over and to have other software build on top of it.
At Eldarion, we use GitHub pull requests extensively to facilitate code reviews, whether it's working on client projects, building our own software, or writing open source software. We quite often submit pull requests within the same repo from a feature branch to master (or dev), then either an approval by at least one other person occurs before the merge, or there is a discussion about the code either via comments on the pull request or on specific commits. This discussion can range just from asking questions about a certain approach, or providing guidance on how something could be made better.
Design for Light Readers
When authoring essays that you want others to read and be influenced or learn something from your writing, you want to use clear language that's easy to understand. You also want to structure your writing in a way that easy to skim by using bullet points and section headings. I generally find Paul Graham's writing clear and concise without being dumbed down, however, I do find his essays hard to skim as even some of his longer essays lack the use of section headings and/or bullets. But then again, maybe that is by design. Perhaps he doesn't want someone to skim his articles. Or maybe this is just a style thing for him.
With software, this principal applies in your API design and the documentation/help you ship with. There are two classes of software where this applies in different ways. First, software that is designed to be used by other developers, should be written in a way that has a consistent and clearly designed API. Learning parts of the API should allow me as a developer to infer a lot about other other news parts of the API work without having to reference too much documentation. For the other class of software, the software used directly by end users, your UX design should reduce or eliminate a user from having to read manuals or forms of online help to figure out how to use your software. The goal should be to make it obvious and clear to users what they can and should do with your software.