# Concluding the definition of 'simplicity'

Sun, Oct 24, 2021 ❝Bringing the journey of defining 'simplicity' to its natural conclusion.❞## Contents

In previous blog posts, we explored a possible definition of ‘simplicity’. We started out with a definition. We explored how broadly we might be able to apply this definition. It is general enough to apply outside of software, or computer science, or – for that matter – STEM.

This will be a concise summary of the findings documented in previous blog posts.

## Motivation

One should “*simply do this*”, or “*just think of a simple solution*”, or “*keep it simple*”, or you name it. However, no-one really tells you when something is or isn’t simple. In the technical domain, “simplicity” is also used to argue for or against a certain solution, but without having a solid foundation to argue with. Instead, they rely on experiential intuition.

There is a large body of disputed, conflicting best-practices. Rules that work sometimes but not all the time, and which sometimes contradict each-other. It is difficult for such a body of practices to be used to argue for a solution under any circumstances. Which means that one often needs to resort to intuition. And everyone’s intuition is slightly different.

As I primarily have knowledge in the technical domain, I decided to explore possible definitions that could lead to a definition of *simplicity* in concrete terms.

There are consequences to decisions in engineering. Concerns such as *premature optimization*, *premature abstraction* and *technical debt* refer to concerns that negatively affect engineering. These concerns seem to be related to simplicity. Other concerns, such as *compiler optimizations*, rely on simplicity for their performance. With a definition of simplicity, we can make this relationship concrete.

## Definition

From considering the various scenarios. Things that are preferred, valued, I came up with the following definition.

Given a question that is **specific**. An answer is **simple** if it is **unoptimized**, **specialized** and **reduced**. Each of these properties represent a quality of the answer in a certain dimension.

**specific**: the question should be exact. It should include everything significant and exclude everything else.**simple**: the answer is most*simple*if all three properties*unoptimized*,*specialized*and*reduced*are fully satisfied.

Properties:

**unoptimized**: the answer is completely unoptimized, i.e. any optimization is undone.**specialized**: the answer is formulated specifically for the use case indicated by the question. There is no (unnecessary) generalization, which may impose additional restrictions.**reduced**: the answer is formulated with as few “moving parts” as possible. Either the parts of the answer or rules prescribing restrictions.

These properties are orthogonal. Each property operates in its own dimension. Changing the answer along any one dimension does change the answer itself however. It changes the expression of the answer to which the other properties also apply. Each property has a distinct type of influence on the answer as a whole. There is no definite order to these dimensions.

### Dimension: optimization

*Optimization* represents transitioning to a different domain, i.e. level of abstraction, to answer the question. Any transition to another level of abstraction requires new domain knowledge. A transition to a lower level brings different tools for expressing the answer: different strengths and weaknesses, limits and restrictions.

A lower level brings more detailed control and certain peculiarities. These peculiarities can either be beneficial, such as enabling taking shortcuts given certain circumstances, or may pose risks due to assumptions and restrictions that are inherent to the domain.

#### 2022-04-03 characteristic: reducing variation

*note: this is an observation that seems to be prevalent in most cases*

A consequence of optimization is often a reduction in variation. The idea with the *unoptimized* solution is that it is expressed as-is. However, when we intentionally *optimize*, we tend to make deliberate choices for which use-cases to optimize for. We reach for a lower level of abstraction to gain more control, and optimize for few cases to mitigate current (and future) cost.

In case of programming code, we tend to write highly-specialized assembly for a few (very similar) platforms. That means we drop support for many (the majority) other platforms. These platforms either use the *unoptimized* (i.e. simple) code at the cost of lower performance and/or other consequences, or they are no longer supported. (See update for details.)

### Dimension: generalization

*Generalization* represents the answer as a whole, or individual parts of the answer, more general than strictly necessary to satisfy the question. Generality enables broader applicability. Typically making one answer available for a whole class of (similar) questions. This comes at a cost: the general answer may be less finely tuned to the current question.

Furthermore, the consequence of using more general terms over concrete terms may make it harder to understand the answer and how it is relevant to the question. Having used general terms may mean there are multiple variations possible.

### Dimension: expansion

*Expansion* represents the introduction of additional “moving parts” and rules to the answer. To answer the one question, we can reduce the answer until there is no more variation remaining, i.e. variability is unnecessary. By expanding the answer we introduce variation. Through additional “moving parts” or rules, we make things more flexible, more dynamic. Rules may enforce conditions on this variation, either for an individual part or – as a dependency – between multiple parts. This is similar to specialization, but using different mechanisms. It allows for re-use and variation in applicability, but at the cost of complexity.

Reduction reduces the “size” of the semantic body: less parts, less rules, less dependencies between parts. Having less body means the semantics apply to fewer cases, i.e. *reduced*, and thus are less complex.

## Scope

We can distinguish between an answer being *simple* if the *question* posed is not allowed to change, and when the question is itself subject to re-evaluation given its context. The way the question is phrased can be influential to the quality of the answer. Further insights may allow rephrasing, fine-tuning the question itself, or it may be considered fixed.

**Relatively simple** the question is considered fixed. It may be impossible to give the simplest answer you know, because the question is not phrased exact enough to reflect these subtleties. In addition, a question asked at a high level of abstraction, may require you to go down a level of abstraction merely to express the answer correctly. If the question cannot be rephrased, that may limit how simple the answer can be.

**Absolutely simple** the question is given to you as a starting point, but not set in stone. Now it is possible to investigate towards an answer, and if you discover that the answer leads you to some subtleties that are not clear from the question itself, you may fine-tune the question. The question is no longer a limiting factor for a simple(r) answer.

This definition of *simplicity* is not restricted to a particular domain, or even the exact sciences. The definition can be applied equally well for the evaluation of a story or fairytale expressed in a natural language. Essentially, anything that has a “*question-answer*"-relationship (e.g. problem statement-solution, “ancient wisdom”-story/fairytale), such that the “answer” can be validated against the given “question” using the defined properties, suffices. The same properties hold for a mathematical expression as well as a fairytale.

## Trade-offs

In use cases where simple is not the desired outcome, we can evaluate for which property or properties we deviate from the goal of simplicity. Understanding this, we can reason about the trade-offs being made.

*Optimization* transitions to another domain – another level of abstraction, typically, a lower level. In general, this means that you need to comprehend this new domain and its subtleties. The benefit is more control, specifically control of that domain and thus access to its tools. The trade-offs are possible limits and restrictions, that need to be taken into account.

*Generalization* makes a specific answer applicable to a whole class. The main benefit is being able to make it applicable for similar questions. The trade-offs are that the (larger) class may have additional restrictions, making the answer less precisely suited to the intended question itself.

*Expansion* makes a specific answer more adaptable, either through the addition of variables, i.e. increasing the number of parts, or through rules, i.e. prescribed dependencies between parts. Although this allows for re-use and variation, it also means there may be more rules imposed than strictly necessary, meaning there is more to consider for full comprehension.

## Evaluation

The properties of simplicity cannot be rated with absolute values in a fixed range of, for example, 1 to 10. They may not even be limited at both ends.

“

All problems in computer science can be solved by another level of indirection” – David J. Wheeler

We can say that there is a limit to how far we can *deoptimize* or *specialize* or *reduce*: there is a hard limit to simplifying. At some point, no further simplification is possible without losing connection with the question. Conversely, in any dimension, there may not be a limit to how far you can go in *optimizing*, *generalizing* or *expanding*.

“

… except for the problem of too many layers of indirection.” – David J. Wheeler

We evaluate each property by exploring whether or not further improvement along the dimension of this property is possible. If none of the properties can be improved, we can conclude that we have arrived at the simplest form (given question and context).

**Unoptimized**? Is the answer expressed in the same domain, i.e. the same level of abstraction, as the question? Can we transition back to that domain?

**Specialized**? Can we make the answer more concrete? Does the question seem overly general or have any overly-general parts?

**Reduced**? Can we further reduce the number of parts of the answer? Can we remove any of the rules expressing demands on a part or between parts?

Performing this evaluation means that you either have identified steps for further simplification or, if simplification is not necessary, they act as indicators for properties that have priority over simplicity. You evaluate to either: 1. actively improve, or 2. identify the current state and its choices.

### Complex questions

A question may be complex in itself. Questions may ask for an amount of in-depth knowledge or detail such that they cannot be answered with a simple answer. These questions may depend on any one or more dimensions to be answered completely, thus preventing any answer from being simple. For example, a question posed in the domain of biology that can only be answered using intimate knowledge of chemical processes. The nature of the question demands a transition into another level of abstraction just to access the necessary tools.

Another variation are answers that seem (overly) complex, but further investigation reveals that this complexity is part of the question. An example of this is the story of *Alice’s Adventures in Wonderland* by Lewis Carroll. The story contains many strange objects, beings and events. It seems excessively complex for a children’s story. However, the story is written with the intention to illustrate new, more abstract branches of mathematics. Considering that this is the question, makes the story itself *relatively simple*. Similarly, *Through the Looking Glass* sources the characteristics of chess.

### Question reverse-engineering

The evaluation can also be applied in reverse. Assume that the given “answer” is simple. Derive the requirements for possible questions and reconstruct potential questions.

If you can reasonably assume that the “answer” is simple, it means that there is purpose to all its parts and trade-offs. Any question posed must have need for all of these. Using the three dimensions and the answer, one can reconstruct *a number of possible questions*. Obvious lack of need for some parts, may indicate unnecessary complexity in the answer or lack of understanding.

This practice is by far the most obvious. Even without the knowledge discussed here, we can analyze content and reconstruct a matching reason. This definition only gives you tools to reason about the analysis from different perspectives, i.e. the three dimensions.

## Foundational

The definition of simplicity as it is posed here, is concrete enough to be used as a property in an analysis. Even though the three dimensions are only limited at one side, as discussed, it provides a more structured format. By evaluating the three dimensions individually, we can then draw reasoned conclusions that hold for the over-all *simplicity* – or *complexity* if you will – of a subject.

This definition does not help in quantifying simplicity, but it can be used to *qualify*, to some extent. The definition is *general-purpose*, therefore applicable in any domain.

## 2022-04-03 update

Posts Engineering: The “minimal-objects” approach to OOP and Engineering: The unified OOP paradigm apply this definition in the process of developing those ideas.

The former applies the dimensions of simplicity to small-scale implementations scoped to a single class. This use is partially biased as this was also a source for the definition. The latter post applies the definition to *the OOP paradigm*. This post explores applying the definition to the OOP (design-level) paradigm, with unknown results beforehand.

In particular, the mapping of *Concurrency* to the dimension “*optimization*” was found by matching the characteristics of *optimization*. From the successful application it becomes clear that the same pattern, i.e. the identified dimensions, are emergent in design as well. The idea is that this is a result from the paradigm in itself is an attempt to manage (software) complexity.

## Open questions / Future work

- Are there any angles that are not covered by any one of the properties?
- Is there overlap between the three defined properties?
- Are there any limitations to the applicability of this definition? (Given that we claim that the definition is generally applicable.)
- Confirm that this definition of
*simplicity*:- is the opposite of what we intuitively understand the property
*complexity*to be. - is the opposite of
*complexity*as implied by various*complexity metrics*. - is
*a definition of complexity by duality*?

- is the opposite of what we intuitively understand the property
- There exist many metrics that attempt to define some form of complexity. We should investigate to see whether these can be classified into one (or more) of the three defined dimensions. Therefore grouping and unifying the various concepts of
*complexity*. - Engineering: use
*simplicity*to relate and explain*technical debt*,*premature optimization*,*premature abstraction*,*implementation of a design*,*design patterns*,*reliability*,*compiler optimizations*and*JIT compilers*, and more. To further clarify and more intimately understand well-established technical concerns. And, where possible, establishing their fundamental position and value.

## Changelog

This article will receive updates, if necessary.

*2022-04-03*Updated document to clarify and elaborate on dimension*optimization*and to reference Engineering-articles that apply the definition of simplicity.*2022-03-23*Updated document based on feedback: clarifications for section*scope*.*2021-10-24*Initial version.