Avatar

Thoughts on immutability

14 Oct 2019

I find that most uses of mutability are actually just “fine”. Immutability may simplify data flow, but it also forces people to keep track of many more things.

As an example, let’s take the following piece of code (written using mutable variables).

role = 'member'
role = 'admin' if user.admin?
role = 'superuser' if user.superuser?

All we’re doing here is checking a few conditions to figure out what role is supposed to be. To figure out the value of role for yourself all you need to know is which conditions are going to be true.

But some people consider this “bad code”. Bad because mutability is bad.

If I was asked to refactor this snippet to immutability, I’d probably end up with something like this:

default_role = 'member'
admin_role = 'admin'
superuser_role = 'superuser'

role = user.superuser? ? superuser_role : user.admin? ? admin_role : default_role

Now this code certainly looks better documented. But I wouldn’t say it’s more readable.

In my opinion “Bounded mutability” is much more redable than most immutable code. By “bounded” I mean that there should be a point in the code where the values becomes stable. After that point the value should never change.

But for bounded mutability to make sense, the boundary must be obvious to the reader. A function body can be a good example of a boundary. It’s perfectly fine for a function to mutate variables that it declares. But it should not mutate things that exist outside of it, i.e. things that it only references.

A pure immutable approach may result in fewer unintended mutations, but it hurts code readability in the process. It becomes much harder to understand the code’s intent. And no one wants to touch code that they don’t fully understand. People are naturally afraid of breaking something unintentionally. So they prefer to just rewrite it instead. And no one benefits from such unnecessary rewrites.

I think it’s important to make your code as easy to understand as you can. The best way to do that is neither “always mutable” or “always immutable”, it’s to rely on your best judgment. Blindly following best practices is itself a bad practice.