Like so many aspects of modern life, in programming good is defined in absolute terms and bad is defined as the failure to live up to the standards established by good. In that great storehouse of all that is good in programming, perhaps no quality receives more praise than simplicity. Reading quotations from famous programmers about the pursuit of simplicity is like reading about the quest for the Grail. We're told that simplicity is always hard work. That inside every complex bit of code, there's a simpler version waiting to be set free. That simplicity is the hallmark of great minds. And so on.
- The People Problem: Cyber Threats Aren't Just a Technology Challenge
- Securosis Analyst Report: Security and Privacy on the Encrypted Network
- Architecting Private and Hybrid Cloud Solutions: Best Practices Revealed
- Defense Against the Dark Arts
Predictably, complex code is regularly savaged: It's the telling symptom of laziness, lack of skill, or lack of discipline. It's a code smell. Any idiot can write complex code, the true art is writing simple code.
I need not continue. Everyone has heard, thought, and even embraced these platitudes to some extent. But in fact, I believe, they are mostly wrong. And what bothers me is that they invariably go unchallenged. Listeners nod in assent and move on to the next thing.
Let's tease this out a little. It's not true that any idiot can write complex code. Complex code is difficult, often very difficult, to write. It's entirely true that it's more difficult to maintain, too. But that's the nature of complexity. Some things are intensely difficult to express in code and they require complexity, simply because they're not inherently simple.
Perhaps you've been led to believe that complexity is the product of insufficient skill. A real-life example should lay that theory to rest. For grins, let's take one of the best-known programmers in parser theory (Al Aho, coauthor of the Dragon book), team him with Brian Kernighan (the K in K&R), and have him write a DSL that becomes the very model of programming elegance (awk). If skill were all that were needed to write simple code, then you'd expect Aho to deliver the simplest parser code imaginable clean and elegant as K&R's examples of C. Now, the reality, as written by Aho himself: "I had incorporated some sophisticated regular expression pattern-matching technology into AWK Brian Kernighan once took a look at the pattern-matching module that I had written and his only addition was putting a comment, 'Abandon all hope, ye who enter here.' As a consequence, neither Kernighan nor Weinberger would touch that part of the code. I was the one who always had to make the bug fixes to that module" (from Masterminds of Programming, p. 103). Complex problems require complex code.
There's a big difference between poorly written code and complexity. Unfortunately, parts of the Agile movement have tended to obfuscate the distinction. A rule of thumb I've seen cited several times is that functions with a cyclomatic complexity number (CCN) of more than 30 or 35 must be rewritten. This is patent nonsense and implies that all complex code is equivalent to badly written code. Moreover, there's a peripheral problem with the assertion; namely, that every branch of a switch statement adds 1 to the CCN. So, if your switch has 35 branches, you violate the threshold with no reasonable way to simplify your code. (Sure, you could use some kind of table instead of the switch, but now you've taken logic that was easy to read and made it considerably more difficult to follow.)
This brings me to the point that is truly the heart of the matter: It's not simplicity that matters, but readability. Can the code be understood with the least amount of effort given its inherent complexity? That is the true criterion. How readable, or if you prefer, how maintainable is the code with respect to its complexity?
As to the obsessive reverence for simplicity, it is to me quixotic and sentimental. If we look at nature, we find that absolutely nothing in it is simple. Everything in nature is characterized by extraordinary complexity that masks further layers of complexity. As to human creations such as the automobile, they induce people, like the mechanic at my garage, to remember with fondness days past when everything was "simpler." But in fact, in the last 15 years, the rates of unexpected mechanical failures in cars has plummeted and gas mileage has soared. One of the biggest reasons for these advances is the 5 to 10 million lines of code in cars today. Yes, indeed, vastly complex code has delivered significant benefits and made the mechanic's repair work considerably simpler.
My view of simplicity is unemotional and free of idolatry because I define it with respect to complexity, rather than the other way around: Simplicity is the quality of code that is no more complex than required to express the underlying complexity. In this way, simple code can be intensely complex. There is no inherent good/bad dichotomy.