Skip to content

Simple Made Easy and Simplicity Matters

I am merging notes on both talks into one summary as they deal with the same problem.

Summary

The talks goes around what the definition of simple and easy, and how as programmers we like complex constructs, because they are familiar and as we are in the conceptual and creative industry, our egos forbid us to accept that some tasks are too complex for us to handle (but especially for familiarity).

Simple is an objective measure of how things are entangled, intertwined, not compound, whereas easy has a notion of familiarity and nearness (physical, knowledge and mental capability). Complex is the opposite of simple (when things are braided, tied, or folded together) and hard is the opposite of easy.

When accessing the output of work, we should consider the properties of the artifacts (that thing that was made) more than those of the constructs. Is it effective? Understandable? Modifiable? Can be debugged? In contrast, none of our customer will care how easy it was to create the artifact if it does not fulfill the previous objectives.

Simplicity matters as our cognitive ability to handle complexity is limited, hence complexity undermines the ability to think in isolation. Complexity affects our ability to change our artifacts as we need to able reason about a program for changing without fear (using informal reasoning, not category theory). Similarly, the ability to reason about a program allows us to solve bugs and no types nor tests increase the ability to reason about a program.

Even though ease provides early speed, ignoring complexity will slow down the development or the long haul (it does not matter for trivial projects). Simplicity will be slower at the beginning because it requires thinking and design.

Notes

I usually summarize point I find interesting and quote the moment I find legendary. Some of the following sentence are just copy pasting from the slides.

Simple, Complexes in contrast to Easy and Hard.

Simple means disentangled, without braid, not compound, not twisted. Usually, it goes around one role, topic, concept, dimension, subject. But we should not focus on the one thing, instance or operations. It is about the lack of interleaving and it is objective.

How to make complex things simple. Simple you have to disentangle them (or simplify them by the definition of unfolding).

Ease is about adjacency or nearness and easy is relative. It is near at hand (hard drive, tool set, ID, understanding and skill set, familiar).

I think that, collectively, we are infatuated with these two notions of easy. We are just so self-involved in these two aspects; it's hurting us tremendously. Right? All we care about is, you know, can I get this instantly and start running it in five seconds? It could be this giant hairball that you got, but all you care is, you know, can you get it.

In addition, we're fixated on, oh, I can't; I can't read that. Now I can't read German. Does that mean German is unreadable? No. I don't know German. So, you know, this sort of approach is definitely not helpful. In particular, if you want everything to be familiar, you will never learn anything new because it can't be significantly different from what you already know and not drift away from the familiarity.

Finally it is near our capabilities. This point is taboo, because we are in conceptual work and due to a combination of hubris and insecurity, we never talk about.

Ease is subjective and relative as well (language and skills acquired by training are example).

There's a third aspect of being easy that I don't think we think enough about that's going to become critical to this discussion, which now is being near to our capabilities. And we don't like to talk about this because it makes us uncomfortable because what kind of capabilities are we talking about? If we're talking about easy in the case of violin playing or piano playing or mountain climbing or something like that, well, you know, I don't personally feel bad if I don't play the violin well because I don't play the violin at all.

But the work that we're in is conceptual work, so when we start talking about something being outside of our capability, well, you know, it really starts trampling on our egos in a big way. And so, you know, due to a combination of hubris and insecurity, we never really talk about whether or not something is outside of our capabilities. It ends up that it's not so embarrassing after all because we don't have tremendously divergent abilities in that area.

The relevant point here is that whenever is hard, because it is conceptually complex, our egos prevent us to accept that the task is too complex and that we probably can't handle it.

The reason why we can not have objective discussion about qualities that matters in our software is because we conflate the two notions of easy and simple (because we say something that is simple if it is near our abilities or familiarity).

Construct vs Artifact

Software are created using constructs (programming language, libraries) which, in and of themselves, have characteristic and we build artifact out of them..

But we're in a business of artifacts. Right? We don't ship source code, and the user doesn't look at our source code and say, "Ah, that's so pleasant." Right? No? They run our software, and they run it for a long period of time. And, over time, we keep glomming more stuff on our software. All of that stuff, the running of it, the performance of it, the ability to change it all is an attribute of the artifact, not the original construct.

However, developers focus on their experience and the characteristic of the constructs (language, less typing) leading to the notion of programmer convenience at the detriment of the programmer: employers love the fact they can replace any programmer as long as our artifacts seems familiar to anyone (does not mean someone else can understand it though).

That focus on experience of the use of the construct comes at the expanse the long term result. Does the software do what it is supposed to do? High quality? Can we rely on it? Fix problems when they arise? Change it, given a new requirement? These question are not properties of the constructs but with the attribute of the artifacts.

Limits

  • We can only hope to make reliable those thing we can understand.
  • We can only consider a few things at a time.
  • Intertwined things must be considered together. We lose the ability to think of them in isolation. And the burden becomes combinatorial with the number of things under consideration.
  • Complexity undermines understanding.

Change and Debugging

So how do we change our software? Apparently, I heard in a talk today, that Agile and Extreme Programming have shown that refactoring and tests allow us to make change with zero impact.

I never knew that. I still do not know that. That's not actually a knowable thing. That's phooey.

Change to software require analysis and decisions. What will be impacted of a potential change? Where do changes need to be made?

You know, I don't care if you're using XP or Agile or anything else. You're not going to get around the fact that if you can't reason about your program, you can't make these decisions

The ability to reason about your program is critical to changing it without fear. Not talking about proof, just informal reasoning. One problem is to create new functionalities and the other face of the problem is to fix the parts we did not solve correctly (debugging).

And I like to ask this question: What's true of every bug found in the field? … It passed the type checker … [and] all the tests. … I think we're in this world I'd like to call guardrail programming. … We're like: I can make change because I have tests.

Who does that? Who drives their car around banging against the guardrail saying, "Whoa! I'm glad I've got these guardrails because I'd never make it to the show on time."

Right? And - and do the guardrails help you get to where you want to go? Like, do guardrails guide you places? No. There are guardrails everywhere. They don't point your car in any particular direction.

We are going to need to be able to reason about our program and use ordinary logic to determine the location of the problem in a program.

Development Speed

What kind of runner can run as fast as they possibly can from the very start of a race? Right, only somebody who runs really short races, okay?

But of course, we are programmers, and we are smarter than runners, apparently, because we know how to fix that problem, right? We just fire the starting pistol every hundred yards and call it a new sprint.

I don't know why they haven't figured that out, but – right. It's my contention, based on experience, that if you ignore complexity, you will slow down. You will invariably slow down over the long haul.

Easy Yet Complex

And they're easy to use. In fact, by all measures, conventional measures, you would look at them and say this is easy. Right? But we don't care about that. Right? Again, the user is not looking at our software, and they don't actually care very much about how good a time we had when we were writing it. Right? What they care about is what the program does, and if it works well, it will be related to whether or not the output of those constructs were simple. In other words, what complexity did they yield?

When there is complexity there, we're going to call that incidental complexity. Right? It wasn't part of what the user asked us to do. We chose a tool. It had some inherent complexity in it. It's incidental to the problem. I didn't put the definition in here, but incidental is Latin for your fault.

How do we usually complect our work?

I don't know and I don't wanna know.

(Rich Hickey, about communication between modules)

What, Who, When, Where, Why, How

See also (generated)