Loading...

State Is the Root of All Evil

August 17, 2023
3 minutes to read
Share this post:

Hi,

What distinguishes an application from a (mathematical) function?

A function takes an input x and transforms it into an output. If f(x) = 2 * x, then the result of this function for the input of any x is always the same.

There are no side effects. We call this behavior stateless.

But what does this have to do with the question from the beginning? An application goes beyond this. (Almost) every application must work with state. As soon as we have I/O operations in our system, we inherently have state. And often a method call, with the same input, can yield different results at different times. And this is also unavoidable and is in the nature of the task we want to solve.

An API call to GET /users will always deliver a different result, depending on which users are registered in the system. That’s exactly what it’s supposed to do.

But what’s easier?

Naturally the former.

If our method is stateless and therefore deterministic, then it is:

  • Easy to test. We only have to cover all edge conditions for the possible input. Perhaps the set of inputs is even finite, and we can test all possible values.
  • Easy to adapt. A new developer can consider this single method in absolute isolation.
  • Easy to parallelize. We can run this method with as many threads and processes simultaneously as we want. There can be no conflict.
  • Easy to cache. If the output for an input is always the same, then we can remember the output. It cannot change. (Memoization is the keyword here.)

Everything becomes more difficult when we have state.

A few days ago, I was dealing with code that had unnecessarily transported a lot of state. I was looking for a bug.

This code had repeatedly remembered a state that comes from the database. It was just a Boolean. But this information was duplicated across several classes.

The result was very confusing code. I was able to quickly locate exactly where the bug occurred. But figuring out why it occurred there took a lot of time. I had to precisely track when the state was manipulated. It must have been forgotten somewhere.

All this would not have been necessary. The state was only needed in the database. It would have been enough to keep it at the outer layer - the database layer. And then it was passed as a parameter deeper into the underlying layers.

State is the root of all evil

As soon as state is in play, everything becomes more difficult.

That’s why you must avoid state as long as possible. This requires a different way of thinking from you at first - but it will quickly become easy for you.

Rule the Backend,

~ Marcus

Top