The data in Elixir is still immutable, but there are couple of shorthands, that let you type less or don't worry about finding new names. In Erlang, you could often see code like this:
SortedList = sort(List),
FilteredList = filter(SortedList),
List3 = do_something_with(FilteredList),
List4 = another_thing_with(List3)
In Elixir, you could just write:
list = sort(list)
list = filter(list)
list = do_something_with(list)
list = another_thing_with(list)
This is exactly the same, but it looks a little better. Of course the best solutions would be to write like this:
list |> sort |> filter |> do_something |> another_thing_with
Every time, you assign new thing to list
variable, you get new instance:
iex(1)> a = 1
1
iex(2)> b = [a, 2]
[1, 2]
iex(3)> a = 2
2
iex(4)> b
[1, 2] # first a did not change, it is immutable, currently a just points to something else
You just say, that you are no longer interested in the old a
and let it point to something else. If you are coming from Erlang background, you probably know the f
function from shell.
A = 1.
f(A).
A = 2.
In Elixir you just don't have to write the f
. It is done automatically for you. This means, that every time, you have variable on the left side of the pattern match, you are assigning new value to it.
Without the ^
operator, you wouldn't be able to have a variable on the left side of pattern match, because it would get new value from the right side. ^
means do not assign new things to this variable - treat it as a literal value.
That is why in Elixir
x = 1
[1, x, 3] = [1, 2, 3]
is equivalent in Erlang to:
X = 1,
[1, CompletelyNewVariableName, 3] = [1, 2, 3]
and:
x = 1
[1, ^x, 3] = [1, 2, 3]
is equivalent to:
x = 1
[1, 1, 3] = [1, 2, 3]
which in Erlang is:
X = 1,
[1, X, 3] = [1, 2, 3]