4 ms·
If variables don't mutate, all it means is that the memory location that stores the value of that variable is guaranteed to never change. Thus, if you reassign
by lectrick 11y ago
If variables don't mutate, all it means is that the memory location that stores the value of that variable is guaranteed to never change. Thus, if you reassign that same-named variable, it actually points to a new memory location with the new value. That is what "rebinding" is vs. "mutating." The advantage of this is concurrency, etc. etc. The disadvantage is you have to have good GC since you'll be doing a lot more garbage collection. It may LOOK like it's changing a variable, but it's not- the variable merely points to a new memory location.
Other languages, like Ruby, do not work this way. If you reassign an instance variable, the memory that is storing that value actually does change.
Here, compare the same sequence of operations in Ruby and Elixir, first Ruby:
bash>> irb
>> a = {a: 5}
=> {:a=>5}
>> b = a
=> {:a=>5}
>> a[:a] = 10
=> 10
>> b
=> {:a=>10}
and now Elixir:
bash>> iex
Erlang/OTP 18 [erts-7.1] [source] [64-bit] [smp:8:8] [async-threads:10] [hipe] [kernel-poll:false] [dtrace]
Interactive Elixir (1.1.0) - press Ctrl+C to exit (type h() ENTER for help)
iex(1)> a = %{a: 5}
%{a: 5}
iex(2)> b = a
%{a: 5}
iex(3)> a = %{a | a: 10} # updates a mapping
%{a: 10}
iex(4)> b
%{a: 5}
Notice how b's value changed in Ruby, but not in Elixir. In both cases, the hash was updated.
- rdtsc 11y ago> If variables don't mutate I think we are talking about two different things when we say "variables". When I say "variable" I mean x, y, a, b etc. That is the variable. It has a value, you can see it in the shell (repl) or when printing it. Look at what happens to variable x: iex(1)> x=1 1 iex(2)> x=2 2 It was 1 then 2. It changed. Mutation is a synonym for "change". I think it is a pretty simple concept. Did the framework create a new memory cell, put a 2 in there and now x behind the scene dereferences that. Did it update the old cell in place. Was it on the stack? That's not the point. The point is x now has a new value. x is a variable that means variable x mutated. Compare to Erlang: 1> X=1. 1 2> X=2. ** exception error: no match of right hand side value 2 You can't mutate variable X. variable X is immutable. Again, I think that is pretty clear and simple. What you showed in your example is how data is immutable in Elixir but not in Ruby. > The advantage of this is concurrency, etc. etc. Actually most data, except larger binaries, are copied between processes anyway. So concurrency advantage is mostly theoretical. In the future they could be switched to reference counting for other things. But that is a hidden implementation detail anyway.
- lectrick 11y agoAre you Löic Hoguin?