Welcome to the world of Elixir! Without answering your question directly, I see where you are coming from. So let’s take a step back and explain immutability as you will need to understand that first before anything else.
A variable is a binding between a name
and a memory location
. By executing echo $name
the computer does actually echo #memory_location_17458
The code you have written assumes mutability. That is: you can change the value of a variable (=memory location). In many languages that can be done the way you wrote the function. But it has side effects.
Say p1
is bound to #memory_location_17458
. What if function2()
runs at the same time and also puts values in variable p1
(= #memory_location_17458
)? Once p1
returns the end result stored in #memory_location_17458
, you are surprised to find numbers of function1()
and function2()
in your list! They both wrote to the same memory location.
Elixir is based on immutability. Once a memory location has a value, it can’t be changed. However, what we can do is store a new value in a new memory address and let name p1
point to the new memory location! With one important fact: the new p1
is only bound to the new memory location within the current function scope.
So in the example with two functions, here is some pseudo code, using curly braces to make the scopes easier to spot.
p1 = [ ]
execute function1(p1) -> { p1 = p1 + 3 }
execute function2(p1) -> { p1 = p1 + 8 }
echo p1
- both receive p1 as
#memory_location_17458
. - as soon as
function1()
changes the value ofp1
by adding ‘3’ to the list is does not change#memory_location_17458
but it stores the new value in another memory address (say:#memory_location_11111
) and points thep1
in it’s own scope to the new address. - if function2() now would look at ‘his’
p1
it would still be#memory_location_17458
which is an empty list. - as soon as
function2()
changes the value ofp1
by adding ‘8’ is does not change#memory_location_17458
but it it stores the new value in another memory address (say:#memory_location_222222
) and points thep1
in it’s own scope to the new address.
We now have 3 times the p1
name bound to 3 different memory addresses.
The original p1
in global scope bound to #memory_location_17458 which has [ ]
The p1
in scope of function1 bound to #memory_location_11111 which has [ 3 ]
The p1
in scope of function2 bound to #memory_location_22222 which has [ 8 ]
- When we print
p1
at the last line, we are in the same scope as the first time we createdp1
so it still references#memory_location_17458
and prints[ ]
cause that is the value of that memory address.
Advantage
Every function can run at the same time as they will never(!!!) influence other variables (=memory address).
Conclusion
Keep reading about this until you understand it well. As understanding immutability is key to understanding Elixir. Once you understand how immutability works, start reading some blogs about tail recusion (the technique that makes for-loops
in Elixir without influencing memory addresses ).
Hope this helps a bit. I will edit my post when the Elixir gods correct me