The Benefits of Immutable Data Structures
Recently I've been playing around with Clojure. Clojure, as opposed to Ruby, is a functional programming languages. One of the key distinctions between functional and object-oriented languages is immutable data structures. Immutable data structures, as opposed to mutuble structures, cannot be changed once created. When you change the value of an immutable data structure, you are actually creating a new copy of that structure. A string or an array in Ruby is mutable. Let's prove that with a simple example I just cooked up in IRB.
> a = "hello" #=> "hello" > a.object_id #=> 70270455113460 > a = "F" #=> "F" > a #=> "heFlo" > a.object_id #=> 70270455113460
As you can see, we created a new string called "hello" and assigned it to the variable "a". We modified the third letter in the string but the object_id stayed the same. It's the same string, mutated.
Imagine you are constructing a class that must receive an object in a specific state. You have no way of knowing by default in Ruby whether that object is in the state that you aassume it will be. If you want to be sure of an object's state as it's passed to another class, you have to weave up the entire method chain and break down how each function is mututing your object. That becomes confusing really quickly and makes it difficult to onboard new developers to your project.
To prevent these kinds of errors from hapening, some people implemnt the Builder pattern in Ruby and other object-oriented languages. The Builder pattern sets the state of an object exactly as you want it and then locks it down. You never have to guess whether the object is in the middle of contstruction because it's built to a certain state from the beginning.
But there's an additional challenge associated with mutuble data structures that is fixed with immutability. To demonstrate this, I'm going to steal an example used by David Nolan at the New York Times.
Let's jump back to Ruby. If you had a billion element array, there's no way that we would be able to know if there was a change in that array besides for iterating through the entire structure. In Ruby and other object-oriented languages you constantly have to "check-in" with your objects and manage their state.
I've learned a lot playing with Clojure and am looking forward to learning more about the language. Every programming language has something unique to teach which can be learned from.