What-if fatigue

Aug 28, 2017

The what-if fatigue is when you try to understand a piece of code, but it's a convoluted mess, and you get tired just by looking at it. I'm sure you've seen such code, and chances are, you wrote some too.

I call it the what-if fatigue as it is caused by the number of cases the code handles and the different states of the environment it uses. Understanding a piece of code is usually done by asking questions starting with what if. What if this parameter is null? What if this list has 100 elements, but this other parameter is 1000?

A function's complexity usually comes from its parameters and any external state it accesses. Sometimes, the latter is more important than the former. The worst kind of function is that calls some global function that potentially accesses a lot of global variables. In this case, the complexity explodes, as you have to consider virtually the whole global state too.

In a highly cited paper, Fred Brooks splits complexity into two parts. The first part, essential complexity is inherent to the problem. When you need to handle many use cases, complexity grows accordingly. There is no way to reduce it, as it is hardcoded into the specification.

Accidental complexity, on the other hand, is avoidable. It is the result of the programming environment, the architectural choices, and performance considerations.

In many occasions in my career, I've looked at a piece of code and thought "how is it so complex, yet the functionality it provides is simple?" That is accidental complexity. It tends to accumulate over time, and sometimes it is called technical debt.

When a new feature does not fit into the existing architecture, and you add a new special case to one of the central places, that is accidental complexity. It complicates all execution paths, not just the one you're trying to add.

If for example, a year later you decide to remove the feature and forget about that special case, it remains in the code, making it more complex one feature at a time.

What can you do about it?

Usually, when the code feels "hard to grasp", it's a sign that accidental complexity is unnecessarily high. It signals a good candidate for refactoring.

Takeaway

Understanding a piece of code is usually done through a series of what if questions. If there are many edge cases or it depends on many variables, understanding gets harder and harder. In some cases, it explodes. It is a sign that this code could use some refactoring.

Refactor until you can ask and answer all the what if questions. That means the next time someone looks at the code they won't get tired when asking them. And it is the sign of a maintainable codebase.