Elixir 1.3

Chapter 3

Immutability

Functional-programming aficionados making a big deal about immutability
and Elixir enforces immutable data.

Buy why?

 

You Already Have (Some) Immutable Data

count = 99
​do_something_with(count)
​print(count)

You would assume that count was 99.
At your very core, you believe that 99 will always have the value 99.

Imagine programming in a world where you couldn’t rely on that—where some other code, possibly running in parallel with your own, could change the value of 99.

But what if do_something_with(count)
actually changed count?

What about this code?

array = [ 1, 2, 3 ]
​do_something_with(array)
​print(array)

In most languages do_something_with receives array as a reference. If it decides to change the second element or empty the array the output won't be what you expect.

Take this a step further—run multiple threads, all with access to the array.
Who knows what the state will be!

Elixir sidesteps these problems. In Elixir, all values are immutable. The most complex nested list, the database record, behave just like the simplest integer.

 

Once a variable references a list you know it will always reference those same values (until you rebind the variable). And this makes concurrency a lot less frightening.

 

When we update [1,2,3] we don’t hack it in place,
we transform it into something new.

Immutable Data Is Known Data

Performance Implications of Immutability

Creating all these new values feels inefficient.

But because Elixir knows that existing data is immutable, it can reuse it, in part or as a whole, when building new structures.

​iex>​ list1 = [ 3, 2, 1 ]
​[3, 2, 1]
​​iex>​ list2 = [ 4 | list1 ]
​[4, 3, 2, 1]

Elixir knows list1 will never change, so it simply constructs a new list with a head of 4 and a tail of list1

Coding with Immutable Data

iex>​ name = ​"​​elixir"​
​"elixir"
​​iex>​ cap_name = String.capitalize name
​"Elixir"
​​iex>​ name
​"elixir

Coding with immutable data is surprisingly easy. 

Just remember that any function that transforms data will return a new copy of it.

In a functional language, we always transform data.
name is "elixir" and will always be "elixir"
cap_name is "Elixir" and will always be "Elixir"
(*unless you rebind the variable)

Thank you!

Programming Elixir 1.3 Chapter 03

By Dustin McCraw

Programming Elixir 1.3 Chapter 03

  • 983