Simple ≠ Easy

Malina Tran
Tech and the City
Published in
4 min readJul 13, 2016

What is simple is not always easy. Rich Hickey’s talk, “Simple Made Easy,” talks about being intentional in choosing simplicity. The word “simple” originates from the word “one fold or braid” and he encourages us to think about it in the context of programming. Imagine: something that has one of something, whether it is one role, one task, one concept, or one dimension. That thing therefore becomes focused and clear in its objective when it is just one.

This makes me think of single-responsibility class. In a previous post, I delve into this topic further; Sandi Metz says that a class “should do the smallest possible useful thing; that is, it should have a single responsibility.” That is how we should construct our software applications.

So, why is simplicity more desired than complexity?

  • Ease of understanding
  • Ease of change
  • Easier debugging
  • Flexibility in relocating due to independence of decision (orthogonality)

The first one makes sense to me and is enough to have me sold. Even if I am starting to learn Clojure, I just want to point to an example in Ruby. My mentor, Sylwia, encouraged me to think about the understandability of methods. See the first code snippet:

def valid_marker(marker)      
marker.capitalize != MARKER[:X] &&
marker.length == 1 &&
/[a-zA-Z]/.match(marker) ? true : false
end

But it’s hard to understand. By abstracting and simplifying this method, I make it easier to understand (and if ever need be, relocate it to another part of the code base). Hickey provides ways to abstract code, which he clarifies is not about hiding code, and says that it needs to be broken up into smaller units and not concerned with the how which deals with implementation and should not be mixed up. While I initially thought abstracting code would mean creating more methods (e.g. more lines of code, more unit tests), Hickey reassures us that simplicity does not mean fewer things. In fact, it often means making more things.

See my refactored code snippet below. I won’t go into the nitty gritty of it, but you can definitely see how much more accessible and readable the code becomes when I’ve abstracted code and put them under very explicit, well-named methods.

def valid_marker(marker)      
is_not_computer_marker?(marker) &&
is_single_char?(marker) &&
is_not_digit?(marker)
end
def is_not_computer_marker?(marker)
marker.capitalize != MARKER[:X]
end
def is_single_char?(marker)
marker.length == 1
end
def is_not_digit?(marker)
/[a-zA-Z]/.match(marker) ? true : false
end

Hickey challenges programmers’ mentality about what is easy based on how we type, how we construct programs. Yet, he encourages us to think about long-term results instead: software quality and maintenance during change. And this is true — even in my short period programming, I’ve heard remarks about the ease and familiarity of learning certain tools, languages, and frameworks. (To me, it was all equally foreign and new and often difficult).

Limitations: Programmers are faced with very real limitations: we can only make things reliable if we understand them, we cannot think about parts of the code in isolation if they are intertwined, and we can only consider a few things at a time. Fundamentally, this complexity in our system undermines simplicity.

Development speed: One aspect of programming that I have not yet had to consider is development speed. Emphasizing ease gives early speed. Yet, ignoring complexity will slow you down in the long haul. I thought this was particularly true when doing tic-tac-toe in Ruby.

True simplicity: Components that are modular or partitioned do not imply simplicity. This is an interesting point: just because a code looks organized doesn’t mean it is simplified. The reason being is that those components can still have knowledge of each other. The best way to simplify is to abstract that knowledge. Hickey’s lego diagram with thought cloud is pretty on-point. The blue lego is not thinking of the yellow lego, but rather some semblance of it (and vice versa). I would argue that this would create a circular dependency.

Modular code does not imply simplicity, but it is enabled by it.

“Complecting”: The opposite of simplicity is complexity. Hickey breaks it down by word origin (how very English major-like) and talks about complexity as deriving from braiding and interweaving. Here is a great diagram about particular aspects of programming and how in bringing things together, they are rendering them to be more complex.

There is environmental complexity, which comes with limited resources, inherent complexity in implementation, and inability of policies that cannot be composed.

From Rich Hickey’s talk at Strange Loop 2011.

Admittedly, Hickey’s “The Simplicity Toolkit” is beyond me. Some of the concepts that he talks about–queues, polymorphism a la carte, protocols–are pure abstraction to me. But there are also concepts that do make sense, such as information being inherently simple. We tend to make them more complex and hide them behind languages; there is no need to make a class for every (new) information we have. Rather, the best thing we can do with data is to leave it alone.

Simplicity is the ultimate sophistication.

Simplifying is about disentangling. To do this, we as programmers need to think through user stories and code. The underlying message behind Hickey’s talk is that simplicity is a choice, but it require vigilance and sensibilities around entanglement, in order to forgo a culture of complexity.

--

--