Code Simplicity by Max Kanat-Alexander (published by O’Reilly, 2012) is the kind of book you might give to a junior or journeyman programmer and say: “Read this over the weekend, and then on Monday we’ll talk about your design.” There are many quotable passages, pithy aphorisms, and axioms that take the form of definitions, facts, rules, and laws. Kanat-Alexander uses a conversational tone that takes this already common-sense study on the subject and makes it even more approachable and straightforward. And just what is the subject here? As the title dictates, the subject of the book is code simplicity: dealing with complexity, identifying areas where complexity is likely to creep in, and strategies for eliminating or reducing that complexity.
At a high level, Kanat-Alexander’s discussions of the component parts of this subject are deft and lucid. He is able to evoke familiar situations and scenarios (e.g., coding under a deadline; e.g., dealing with large legacy code bases) and uses those to frame and present his recommended methodologies for keeping code “simple”. A lot of the techniques and suggestions will all seem like common sense to anyone who has been programming for a non-trivial interval: reduce maintenance effort before trying to reduce implementation effort; the larger your change, the more likely you are to break something; don’t “fix” things unless you know that you have (and have evidence of) a problem — and so on. Again: to experienced programmers1 these suggestions will all seem like conventional wisdom, like the elements of craftsmanship that they perform and preach every day. To those programmers, I say: Give it a whirl for the sake of the reminder, and if nothing else, at least be familiar with it so you’ll know whether it is a good tract to hand out to your young and eager recruits.
Again, the book has a conversational style and is filled with pithy aphorisms and witticisms that make it easy to absorb and retain Kanat-Alexander’s message. I found myself frequently transcribing passages into my notebook for later reference and for sharing with peers. Many stand out, but two in particular that I wanted to share. First:
Having good comments in code is a big part of making it readable. However, you generally should not add comments that say what a piece of code is doing. That should be obvious from reading the code. If it isn’t obvious, the code should be made simpler. Only if you can’t make code simpler should you have a comment explaining what it does.
I felt this was worth calling out because it was highly illustrative, and emblematic of the theme. Every programmer has had in-depth discussions about comments; and every programmer has committed code that should have been commented, and wasn’t; and every programmer has committed code that was commented unnecessarily; etc. This is something that we’ve all done, and that we’ll all do again. Thus, it is easy to identify with the message embedded in this lesson. But what makes it particularly demonstrative of the book’s theme is that Kanat-Alexander is trying to teach you first how to do without the comments. “If it isn’t obvious, the code should be made simpler. Only if you can’t make code simpler should you have a comment explaining what it does.” And yes, he does immediately go on (in the next paragraph) to state that comments are really more about capturing the ephemeral why of a piece of code, but again the message remains: Consider first what you may add in value by taking away what is written and committed.2
Kanat-Alexander’s take on the comments is interesting one to me because it underscores the book’s message about taking the time to engage with the code, to execute on thoughtful designs, and to take the time to understand what you’re “doing” — the problem you’re trying to solve, the technologies that you’ve chosen to use, the sacrifices that you’re making by choosing one approach instead of another, etc. He talks quite a bit about understanding, about taking the time to read and fully comprehend code before changing it; about taking the time to engage with the problem space and design a solution instead of simply stabbing at one.3 Not taking the time to arrive at that understanding is (he asserts) a disastrous source of recursive complexity:
Programmers who don’t fully understand their work tend to develop complex systems. It can become a vicious cycle: misunderstanding leads to complexity, which leads to further misunderstanding, and so on.
Which reminds me of a joke we have going at the office:
QOTD: “Anger leads to hate. Hate leads to suffering. Suffering leads to re-factoring.” #refactoringleadstomoreanger
— founddrama (@founddrama) February 9, 2012
But this is a point which seems to prove itself: that “of course if you don’t understand [the problem domain / the programming language / the library / the requirements / the legacy code / the customers / etc.] then of course you’re just going to create an at-best mistake-riddled solution.” And to those “experienced programmers” out there, stroking your beards and condescendingly shaking your heads with your unspoken “I told you so”: I’ve seen you do it, too.
As for Code Simplicity itself: I do not actually have all that much in the way of critique. As I have said, it is a short text, pithy and aphorismic — but this is indicative that it has accomplished its goal. So what would I have liked to see, or see more of? First off, there is effectively no code presented at all; not that Kanat-Alexander promises us any — just the opposite, he eschews code to drive home the philosophical points. Perhaps specific code examples would detract from that — but there is a part of me that would liked to have seen something concrete in this area. My other nit to pick was that the book’s sub-heading is “The Science of Software Development”, and though Kanat-Alexander presents things as “facts” and “laws”, I didn’t exactly see… science. I read a lot of anecdotes, but I didn’t see too many experiments of empirical methods. Given Kanat-Alexander’s pedigree, and given the common-sense nature of so much of the advice contained in the book, I’ll grant him a pass on this — but I cannot in good conscience call it all scientific, even if I find myself vigorously agreeing with (say…) 99% of it.4
So where do I land on this one? I’d heartily recommend it to any junior or journeyman programmer that is looking for some insights into how to improve their craft and how to cultivate simplicity in their designs. I know I’ll likely be recommending it to folks that I mentor in the future — again: as a quick weekend read, but with the caveat that you’ll want to keep a notebook and jot down those really good parts.
Disclosure: I received an electronic copy of this book from the publisher in exchange for writing this review.
- And (arguably) also to someone who has just sat in on 4+ years worth of computer science lectures? [↩]
- Which of course immediately brings to mind this quote:
The more code I write, the more code I get wrong. Therefore, it behooves me to write as little code as possible.
…which I saw tweeted by @al3x, and is attributed to “Pony” in a piece called “Why Haskell?” and/but the original source link has 404ed for as long as I’ve known about it. [↩]
- It is worth noting that there is a tacit acknowledgment in the text that you cannot “waterfall” your way through designing your solution. He doesn’t come right out and use that phrase, nor does he come out and admit that Agile-style rapid iterations are the way to go either. That isn’t the subject of the book, and he is wise to stay away from “going there” — but it’s in there, at least a little bit. (No one could help that.) [↩]
- On the other hand, you’ve got Kent R. Spillner and his review on Amazon.com — and he is decidedly not giving Kanat-Alexander a pass on the “not scientific” bit. That review is a bit more eviscerating, and though I don’t know if I agree with the one-star rating (there are lots of redeemable qualities to this book), I do think that Spillner makes some good points in his critique. [↩]