In 2011 at a computer science conference in St. Louis called Strange Loop, a programmer best known for creating his own language gave a talk about the differences between simple and easy. This talk was referenced at the same conference I mentioned having attended in my last post, and so I decided to check it out.
Rich Hickey starts by pointing out how simplicity is too often mistaken for easiness and goes on to talk about the differences in detail, laying out the argument for why simplicity is a prerequisite for reliability in software systems.
As I was listening to his talk, it was obvious that the main ideas branched beyond software in applicability. Enjoy those main ideas.
Simple:
Easily understood or done; presenting no difficulty.
The root of simple comes from sim-plex, which means something like one fold, braid or twist. Simple things solve one role, task or concept, but do not need to be one instance or operation. For something to be simple means that it lacks interleaving rather than cardinality.
Easy:
Achieved without great effort; presenting few difficulties.
Easy’s word origin stems from the parent word of adjacent, meaning to lie near. Easy things are achieved with little hassle, and present few barriers to overcome. Easy can also mean near to understanding or familiarity.
Speaking German
The above definitions may not seem all that separate, but one of the key differences is in the objective vs subjective nature of each word.
Simple is objective. Easy is subjective.
Hickey makes the case for this distinction by outlining a comparison between his knowledge of the German language and a native speaker’s. He notes how for him, German is hard, but for someone who grew up in Germany, the language could be considered easy.
The Downfalls of Complecting
To complect means to interleave, entwine or braid.
Making something more complex is often an unintended byproduct of aiming to make something more easy. In Hickey’s talk, he shows why this is the case in software by outlining the branching tree of technologies that the modern programmer needs to know to build a full stack application. How did we let this landscape get so complex he asks? It was because at every opportunity, we created quick solutions to solve problems of the day rather than going back to the drawing board on how to keep the system as a whole simple.
Not everyone writes software though, I’ll swing for a more relatable example in brevity. I think we’re seeing the same issue creep up in the automotive space. HowStuffWorks.com gives the gist better than I could reword:
This new equipment dramatically increased the complexity of the systems found in automobiles -- and dramatically increased the cost. A 1968 Toyota Corolla, for example, went for about $1,700; the 2009 model started at around $15,000. This complex system has vastly improved vehicle performance, safety and fuel efficiency, but it has also increased the likelihood of breakdowns. The more interdependent parts a system has, the higher the probability that the system will fail, after all.
I was so happy to read this on a quick search for some vehicle statistics, because this last sentence is exactly the point that Hickey aims at in making his case for simplification.
Complexity undermines understanding. Ignoring complexity when adding too or building a new system will slow you down over the long term.
Benefits of Going Simple
The most actionable advice Hickey gives for going simple in what you build, is to have parts composed through abstractions, not interleaving. By taking on building like this from the get go, easiness will be the byproduct of simplicity, and you can win in both domains.
Here’s an example Hickey provides of what that looks like in practice:
Designing for simplicity in this way makes interacting with a system easier in 2 key areas:
Ease of Understanding
It is easier to understand something as a whole when you know not just which part of a system interacts with another, but to understand which parts interact with which type of parts.
Ease of Change
It is easier to adapt a system built for abstractions because parts are not reliant on other specific parts. To change one component in an interleaved system may lead to a cascading requirement to change out other components, but to change out one component in an abstractly linked system makes for an easy swap.
Sold on simple? If you’d like to watch whole talk for the many ideas I didn’t include in this post, you can check that out here.
Next week, I’ll be sharing one of my regular summaries for a book called Connectography.
K.I.S.S.
-Benjamin Anderson