Search code examples
immutabilityelixir

Are Elixir variables really immutable?


In Dave Thomas's book Programming Elixir he states "Elixir enforces immutable data" and goes on to say:

In Elixir, once a variable references a list such as [1,2,3], you know it will always reference those same values (until you rebind the variable).

This sounds like "it won't ever change unless you change it" so I'm confused as to what the difference between mutability and rebinding is. An example highlighting the differences would be really helpful.


Solution

  • Immutability means that data structures don't change. For example the function HashSet.new returns an empty set and as long as you hold on to the reference to that set it will never become non-empty. What you can do in Elixir though is to throw away a variable reference to something and rebind it to a new reference. For example:

    s = HashSet.new
    s = HashSet.put(s, :element)
    s # => #HashSet<[:element]>
    

    What cannot happen is the value under that reference changing without you explicitly rebinding it:

    s = HashSet.new
    ImpossibleModule.impossible_function(s)
    s # => #HashSet<[:element]> will never be returned, instead you always get #HashSet<[]>
    

    Contrast this with Ruby, where you can do something like the following:

    s = Set.new
    s.add(:element)
    s # => #<Set: {:element}>