As a coder, I like to continually draw inspiration and insight into my craft from as wide a variety of sources as possible, and one of the most rewarding sources of inspiration has been from my enjoyment of writing and reading fiction. This has been a personal pursuit, rather than with a goal of being published or becoming an author, and while I’m not going to be the next Terry Pratchett, the more I’ve explored the craft of writing, the more I’ve come to realise how the basic principles of good fiction can be applied to writing good code.
In a series of posts, I’ll explore some key principles about writing fiction, and how these can help you become a better coder.
“Employ a simple and straightforward style.”
When you write fiction or non-fiction, one of the most critical aspects is making yourself understood, and the best way to do that is to make sure the language you use is simple. No-one wants to read a book where they have to reach for the dictionary every two seconds; it hampers understanding of the overall text. Neither do people want to read confusing sentences that are constructed poorly, or lack clarity in expression. Imagine having to spend several minutes after each sentence deciphering its meaning just so you could progress to the next . You would quickly get frustrated, and lose interest.
Plato once wrote that “Beauty of style and harmony and grace and good rhythm depends on simplicity.” Beautiful stories are, more often than not, stories simply told. It doesn’t matter how complex the overall story is; if the individual component parts of that story are done simply, you will have a thing of beauty.
In a programming context, the same principles apply. If your code is illegible and unnecessarily complex, not only will this increase the amount of time it takes to develop, it will also cause immense frustration for anyone working with it, leading to a higher risk of bugs and other defects.
At this point, you may be wondering, what makes code illegible, or unnecessarily complex?
- Poor structure and organisation of code. Imagine trying to read a book with no index, pages weren’t numbered and in a random order, and chapter titles didn’t correspond to the content that followed. Or you’re reading a page at the start of a book that requires you to know something that’s only revealed in the middle of the book. This is akin to having spaghetti code, code that is not organised into a logical structure like some sort of MVC pattern, clearly named folders and files that categorize and group common functionality, or don’t use namespaces and other native features of the language you’re working with to organise your work logically and effectively.
- Purple code. In fiction, you have a concept of ‘purple prose‘, text that is so flowery and ornate that it breaks the flow of what you’re reading. Likewise, with code, creating a dozen variables when you only need one, or creating a sprawling mass of objects and using design patterns for no good reason other than demonstrating your skills – all of these can be considered as the code equivalent of purple prose.
- Duplication. How frustrating would it be to read a book where the author included the same sentences ever several paragraphs, describing the same thing, or reworded slightly, yet the message is the same as what was said previously? Or telling you the same piece of information over and over again, as if you’d somehow forgotten this detail. Likewise, complexity increases by not reusing common objects and methods, adhering to the DRY principle, or keeping code to a bare minimum.
- Inconsistency and contradiction. Nothing breaks the flow of a good novel than discovering that the author is being inconsistent, or that they’ve contradicted something that was said earlier: it was sunny a few minutes ago, but now it’s raining; someone is said to be fat and overweight, but now they’re able to outrun an athletic villain; plot holes where conventions are established at the beginning of a science fiction novel as to how the laws of this universe work, only for the author to ignore them later. In code, the same applies: be consistent. Don’t name a variable one way, then suddenly change it later. Don’t have a method called
createAccount()that doesn’t create an account, or creates an account and also does other things like processing an order. Don’t create objects of a particular type, but then introduce methods that need to interact with the data of the object that expects arrays, or a different object type, forcing you to transform the original object into this new one (unless you have a very good reason to do so).
- Ignorance of language. Nothing is more annoying that trying to read a book filled with grammatical errors or spelling mistakes, and nothing is more taxing to a developer than dealing with code that clearly was written by someone who doesn’t know the actual language itself: custom methods that duplicate native inbuilt methods; not using language conventions and style guides; or ignoring the rules defined by the domain you’re working in (for example, you’re already working with an MVC architecture, and you decide to introduce your own MVC architecture to exist alongside the existing one). Understand the language and domain you’re working in.
There are many other examples, some of which we’ll cover in future articles.
Another point to keep in mind related to simplicity is brevity. While people don’t mind reading thick tomes of books, what they do mind is reading unnecessarily; that is, reading swathes of text that could be trimmed down to just a single sentence, or even a single word. As the saying goes, something is perfect not because there is nothing left to add, but because there is nothing left to take away. Boasting that you’ve written a 1,000 page novel is meaningless if those thousand pages contain reams of repetition, irrelevant events and descriptions, or worse, purple prose.
In a similar vein, boasting that your app consists of 20,000 lines of code in order to demonstrate the complexity of what you’re doing is meaningless. Imagine how much simpler it would be to understand five lines of code where every variable and function call was necessary and meaningful, than understanding 50 lines of code doing the same thing.
Jeff Attwood from Coding Horror has touched on this in the past by pointing out that the best code is no code at all and, quoting Wil Shipley, you should “start with brevity”.
A fantastic by-product of using simple, clear, and concise language, is that you will make your code self-documenting, whereby it becomes unnecessary for you to pepper your code with comments to try explain what you’re doing. This in itself makes your code cleaner, but it also makes your comments more meaningful; if there’s a single comment appearing within a function, it’s a good bet that you should pay attention to what it says. Constantly coming across paragraphs of comments for everything creates an effect akin to banner-blindness, and you quickly don’t bother reading comments at all.
The bottom line is this: it doesn’t matter how complex your overall software is, if its component parts are simple, then you’ve achieved something beautiful. And that is something worth striving for. It decreases the chance of hidden bugs, improves understanding of what your code actually does should someone else need to work on it, helps with code reviews, and a myriad of other benefits.