Date

Complexity is a hot-topic and catchy phrase. Everyone agrees "Complexity is bad" and "simplicity is good", but the terms continue to be muddled in mixed meaning and over-use. This page serves as a series of notes on the terms. I don't agree with all the theories here, I'm just penning them down. I plan to update it over time (updating the date in the process). Let's begin.

Rich Hickey gave the iconic talk Simple Made Easy which proposes a distinction between 'easy' and 'simple'. The talk also seeks to turn complexity into an objective measure.

Kolmogorov complexity also seeks to turn complexity into an objective measure. It measures the length of the shortest computer program that produces the object as output.

Another theory has complexity as branching in code. Every if statement or switch statements increases complexity. This understanding breaks down when it comes to polymorphism where adding additional sub-instances which conform to some protocol don't increase complexity all that much. (or do they?) This intuition follows Cyclomatic complexity, "the number of linearly independent paths through a program's source code".

Complexity is the size of the code (Number of lines, number of methods, number of characters, etc.)

Complexity is the use of a nail gun where a thumb tack would do. Using infrastructure that requires high setup time, maintenance, or cognitive load.

Complexity is using novel or nontraditional tools.

Product

Product requirements are often a source of complexity. Having multiple types of users. Or some customers with slightly different behavior.

Hiding complexity behind configuration files or neater abstractions won't avoid the increased product complexity. If user's can configure their account with N different toggles then you have 2^N different account states that could cause issues. These will show up in bug reports. Perhaps some of them can be easily ruled out, but determining which configuration options are relevant is part of what makes measuring complexity so difficult.

Humor

"Complexity is any code written by someone else. Elegance is any code written by yourself (recently)." This gets at the subjective use of the term. It ties into Rich Hickey's concern with inflating 'easy' and 'simple'.

Other Notes

Complexity is the number of configuration states your application can be in"

-- Jussi Pakkanen's “Let’s play a game of not adding options”

"People say that Haskell is not complex, and that it is just different. But I think that is a useless statement. When the thing you are dealing with is vastly different from what you are used to, it can appear complex no matter how simple it actually is."

-- Learning Haskell - Miscellaneous Enlightenments

Big systems are often complex, but not all complex systems are big. Signs of complexity in software include the number of direct dependencies and the depth of the dependency tree, the number of integrations, the hierarchy of users and ability to delegate, the number of edge cases the system must control for, the amount of input from untrusted sources, the amount of legal variety in that input, and so on, and so forth.

-- Kill it with Fire - Marianne Bellotti

A Note on Essential Complexity by Olano.dev

An overview article, like this page.

Complexity is anything that makes it hard to understand and modify a system.

Quoting John Ousterhout

If software developers should always be thinking about design issues, and reducing complexity is the most important element of software design, then software developers should always be thinking about complexity.

And now quoting Fred Brooks

In my experience most of the complexities which are encountered in systems work are symptoms of organizational malfunctions. Trying to model this reality with equally complex programs is actually to conserve the mess instead of solving the problems.

A good summary of the article:

In general, given a complex component of a software system (or an organization), it can happen that:

  • The complexity is accidental, so we can remove it.
  • The complexity is essential and we need to keep it.
  • The complexity is essential but we could remove it by redefining the problem specification.
  • The knowledge to tell whether something is essential or not is lost, the customer or the product owner can’t tell, or there isn’t such an authority to make the call.

Two's Complement

In the podcast Two's Complement Ben Rady says "Complexity is one of those things that I think is a more useful thing for programmers to talk about rather than the metaphor of technical debt."

It's complex and it's hard to change and it's hard to understand and it's hard to add more people to the team so that you can add more changes right?

And, how to know when a project has reached a critical point of complexity:

Ah, a piece of software is reaching its middle age and needs to be. You need to start thinking about how many cheeseburgers a week you're eating um when the lines of code are in the you know hundreds of thousands when the test suite starts to take longer.

And

You know we've talked about the rule of eights before right? you know, ah point 8 seconds yeah that's great 8 seconds okay that's fine 80 seconds I've lost attention right? And so when you start making that transition from 8

In another episode they discuss the topic of Technical Debt:

imagine if every time you wanted to add the line of code to your system, you had to read log-based 10, uh, of the lines in your system

How dear listener, how many times have you seen in your career the phenomena of the old system that has turned into the haunted graveyard that nobody wants to touch, and then they bring in a new person to maintain it, or maybe a whole two team, and they look at it for a few months and they're like, the solution here is a rewrite, we're going to rebuild it. Yeah. And then they rebuild it, and then five years later, the exact same thing has occurred.

Ben Rady identifies three categories to replace the idea of technical debt:

  1. Risks
  2. Capabilities
  3. Complexity

I think the thing that you really just sort of wanna be looking at is the total complexity, whether it's necessary, whether it's unnecessary. It's still there. It's still makes your code harder to understand, harder to change.

Two's Complement: How to Stop Abandonware Two's Complement: Technical Debt

Complex For Whom?

This post from PaulTag offers some opinions on complexity:

Complexity within a problem domain I’ve come to believe, is fairly zero-sum – there’s a fixed amount of complexity in the problem to be solved, and you can choose to either solve it, or leave it for those downstream of you to solve that problem on their own.

Although I believe there is a fixed amount of complexity in the lower bound of a problem, you always have the option to change the problem you're solving!

And the culture around reducing complexity:

When we get a bunch of folks from far-flung corners of an organization in a room, fire up a slide deck and throw up some aspirational to-be architecture diagram... the initial reaction will, more often than I’d like, start to devolve into a discussion of how this is going to introduce a bunch of complexity, going to be hard to maintain, why can’t you make it less complex?