Mutable State Considered Harmful

Goto in the olden days was a huge source of bugs. Little do we know that we use its evil cousin in our day-to-day work.

Photo by engin akyurt on Unsplash

A Little History

Photo by bert brrr on Unsplash
Source: xkcd.com

The Two Pillars of Computing

Photo by Pea on Unsplash

Code and state can rightfully be called the two pillars of computing.

Code

First, let’s talk about code.

State

What about the second pillar, state? This is where things get interesting. In a typical program, can one easily answer the question “how did I get to this particular state?”

This post was inspired by Jessica Joy Kerr’s tweet

Goto’s Evil Cousin

Photo by Tirza van Dijk on Unsplash

A simple example

Let’s take a look at a simple example:

Not made for concurrency

Mutable state has one other major drawback. It doesn’t work well with concurrency. Nowadays, processors aren’t getting any faster. We’re about to hit the limit of Moore’s law. Processors mainly become more powerful by having more processor cores. Therefore, we have to design our programs to make good use of multiple cores. And mutable state isn’t our friend when things come to concurrent programming.

The need for discipline

Mutable state can rightfully be called an “undisciplined approach to state management.”

The Kickass Solution

Photo by Pablo Heimplatz on Unsplash

What’s the solution?

Nothing changed, nothing shared. Ever.

Immutability takes this idea further and makes sure that nothing is ever changed. A new array will always be returned instead of changing the original one. Updating the user’s name? A new user object will be returned with its name updated, leaving the original one intact.

Example with immutable state

array.sort would return a new array, instead of sorting the original array in place.

Before: [3, 5, 4, 1, 2, 9]
After: [1, 2, 3, 4, 5, 9]

Nothing new

In fact, you’ve already encountered this idea in other languages. Strings are immutable in most programming languages. string.toUpperCase() won’t change the original string — it’ll always return a new string. Working with strings would’ve been terrible had they defaulted to mutating the string in place.

Advantages of immutable state

Immutable state has numerous advantages over mutable state:

  • Concurrency: Immutable data is great for sharing information between multiple threads. Concurrent software and immutable state is a match made in heaven.
  • Chaining: Operations on immutable data are easy to chain — e.g., "a" + "b" + "c" can be thought of as ("a" + "b") + "c" == "ab" + "c" . This is only possible because the + operator is immutable and is guaranteed to always return a new string without having any side effects — and without changing the original string.
  • Predictable: Immutable data can’t be modified, which means that its state is very predictable — always the same
  • Comparison: Instead of performing an expensive deep-equality comparison of two data structures, we can simply compare their hashes, which is nearly instantaneous
  • Testing: Functions using immutable data structures are extremely easy to test since they typically have no side effects

Disadvantages of immutable state

You may have noticed that with immutable state, we create a brand new copy of some data structure on every single change. Imagine copying over an array of over 100,000 items over and over again — that must be slow, right? Isn’t this wasteful?

Persistent data structures

Here’s how a persistent binary tree might be implemented:

Illustration by Vineet Kumar on Wikimedia Commons

The Functional Age Is Coming

Photo by Ameer Basheer on Unsplash

Nulls

Error handling

Catching exceptions isn’t a good way to handle errors. Throwing exceptions is fine — but only in exceptional circumstances, like when the program has no way to recover and has to crash. Just like nulls, exceptions break the type system.

Concurrency

As I’ve already said, we’ve reached the end of Moore’s law: Processors won’t get any faster, period. We live in the era of multi-core CPUs. Any modern application has to take advantage of multiple cores.

Programming with pure functions

Unlike imperative programming, functional programming encourages programming with pure functions.

What’s Next?

Thanks for reading, I hope I was able to convey the benefits of programming with immutable state. Immutable state is the single biggest change one can make to avoid most of the bugs, and finally become a 10x developer. And Functional Programming simply builds on the idea of programming with immutable state.

Senior full-stack engineer. Elixir/ReasonML/React.

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store