It’s not mutable state. It’s however “variable rebinding”. Your example means there are now two values in memory. 1 and 2. So no memory was mutated. However the value the binding a points to changed. It no longer points to the value of 1, but the value 2.
Erlang doesn’t even have variable rebinding (and you can see that in the code elixir compiles to as well). There you’d essentially need to write:
In immutability as memory immutability. You must not confuse single assignment with immutability. You can have immutability with multiple assignments and you can have mutability with single assignment. These are 2 completely different topics.
Yes, but it is about immutability. In languages with mutability you can change value of a and it will change in the closure. It is how “old-school” private members in JS worked:
function Counter() {
var value = 0;
return {
inc: function() { value += 1; return value; },
dec: function() { value -= 1; return value; }
}
}
var counter = Counter();
counter.inc() // => 1
counter.inc() // => 2
counter.dec() // => 1
Simplifying things - yes. However sometimes new binding can reuse old value due to compiler optimisations, for example:
def foo({a, b}) when a > 10, do: {a, b}
Can reuse tuple, so in the end it will be the same as:
def foo({a, _} = tuple) when a > 10, do: tuple
Instead of creating new tuple.
However conceptually you can assume that each assignment will use new memory cell. That will simplify the reasoning.
That works in this way, because this a closure to previous value. I think a different topic in respect to re-binding. It isn’t?
I guess you are right, it is actually about scope. But it generally helps to understand how variables behave in Elixir.
Also how can I have the pointer to old values (for other processes, for example). I think I can not.
You cannot, unless of course you keep a variable bound to it. Processes do not share memory (with a few exceptions), so if you pass a value to another process the value be copied to the other process own memory space.
That means that there is a new memory cell occupation for the new value.
As @hauleth said values can be reused but also values like the first a in basic code like a = 1; do_stuff(a); a = 2 will typically only exist on the stack as they are short lived.