The Pursuit of Simplicity in Programming
Currently, I am writing some documentation and a coding styleguide with a colleague of mine. Whether it’s in our writing or in our coding, we’ve based as many of our decisions as possible on a single concept: minimizing incidental complexity.
In 2011 at Strangeloop, Rich Hickey, the author of Clojure, gave a delightful presentation called Simple Made Easy. In the presentation he discusses the differences between the notion of easy and simple.
This has deeply influenced the vocabulary our team uses in our daily decisions, code critiques and the underlying philosophy that shapes our arguments.
The single value that shapes our programming philosophy is the intentional reduction of incidental complexity because the problems we solve for our companies and customers are already complex enough. We call this the pursuit of radical simplicity.
Fools ignore complexity; pragmatists suffer it; experts avoid it; geniuses remove it.
—Alan Perlis
Simple vs easy #
Simple is a potentially misleading term, so we begin by defining what simple is. To define simple let’s start with the opposite word: complex. Terminology
defines complex as: “complicated in structure; consisting of interconnected parts”. Simple is not simplistic nor is it another word for easy. It is about the lack of complexity. Simplistic would imply naivety in our solutions while easy would indicate that something is not hard. The irony is that it can be quite hard to make things simple without being simplistic.
Simplicity is about reducing incidental complexity as much as possible in order to be able to focus on the complexity that is inherent to the problems we solve. The notion of “accidental complexity” as opposed to “essential complexity” is discussed in Fred Brooks’ 1986 paper entitled No Silver Bullet. Essential complexity is the complexity that is caused by the problem we are solving. It is essential, not removable. Accidental complexity, on the other hand, is caused by the people solving the problem and can be fixed.
Defined as such, simplicity is actually an objective quality. Easy is a subjective measurement based on familiarity or skill-set, simplicity is not. The same is true about personal opinion or preference. Reduced complexity is a more objective foundation on which to build our discussions, arguments and code reviews.
Of course it’s possible to be wrong about which decisions promote simplicity in our software. This means we also need to have measurements of simplicity. We also have to accept that even our objective foundation is subject to subjective human logic. None the less, it frames our intentions and conversations in a far more useful manner than personal preference. It reduces the total number of arguments while the remaining arguments tend to be based on different interpretations of the same underlying value. This actually helps further our mutual understanding and respect of each other.
Sometimes our arguments are still based on a subjective preference or subjective interpretation. These aren’t automatically invaluable arguments but we choose actively to recognize that we are dealing with something subjective and attempt to determine if the solution can be found by testing the argument by the objective notion of reducing complexity.
As we adopt a paradigm of radical simplicity, we begin to see opportunities all around us. From the code we write to the processes we are a part of, actively removing unnecessary complexity allows us to focus on the things that are truly important. In software development, this contributes to clean scalable solutions and a higher velocity of development. Additionally, by developing a shared paradigm for evaluating the software we are building, a layer of incidental complexity is removed from the development process itself. It frees us to be more flexible with each other while remaining both critical and proud of the work we produce as individuals and as a team.