The Inconvenience of Immutability

June 05, 2012

Have you ever tried to get down to the bottom of functional programming and tried to make everything immutable? It’s hard, very hard.

But what exactly is the problem?

For once, there is the abstraction of state in functions. State, the injective thing that functions need and change but yet consider an annoyance that needs to be passed around. Yes, even in functional programming you need state.

And what is state? An abstraction for us humans, to have some conclusive fixed location that isn’t in a flux like the rest of the program. Remember, the CPU counter is always in a hurry and the heap and stackframes change like the contents of your kitchen’s trashcan in super fast motion. Except for a few boring tables, there is nothing in your computer’s memory you would be able to comprehend in realtime.

And so we stop to debug that application and expect something that we can see. That’s state, an interface to your computer. Effectively state is a user interface.

Now, monads are a  fine tool to tunnel state through code that only wants to care about it every now and then. But – from my current perspective - Monads are ugly, isolated and hard to compose and even harder to understand.

One other problem with state is nesting. As soon state gets rather complicated and needs to be changed in deeper levels, there is no pretty way of doing it without compromising the immutable nature of your data structures.

There are, however, some options to get this problem solved, for example Lenses are read and write accessors to data structures which are composable. But as long lenses are not built into the language, the construction needs to be done by hand, for every data member.

Lisp to the rescue, with macros, we simply could build lenses into arbitrary deep nested structures, or even do the nested updates dynamically. And in Clojure for example, there are update-in and assoc-in functions which take a path of the members, change the leaf value and reconstruct the overall associative structure. A nice solution? Probably.

Right now I wonder if modern object oriented languages like C#, Scala just need this one more feature to keep up with the magic of functional programming languages: A type safe and convenient method to change and reconstruct nested immutable structures.