3 ms·
Genuine question: From an application developer's perspective, what's the difference between mutating a value and transparently rebinding an old name to a new v
by killthebuddha 3y ago
Genuine question: From an application developer's perspective, what's the difference between mutating a value and transparently rebinding an old name to a new value? Is it just that in the latter case other references don't pick up the changes? So with rebinding we don't have something like
a = 10
b = a
a = 11
print(b) // 11
?
- OkayPhysicist 3y agodef func() do a = 10 def func2() do a + 1 end a = 20 func2() end Mutation would have func() return 21. Rebinding has it return 11. Likewise, mutating languages typically allow for a method to modify its arguments when those arguments are objects public void modify(MyObject a){ a.changed = true; } public bool test_modify(){ MyObject b = new MyObject(); b.changed = false; modify(b); return b.changed } test_modify will return true in languages that allow mutation.
- Miner49er 3y agoThis is a great example of why the pin-operator is bad, IMO. Rebinding isn't worth this complication.
- OkayPhysicist 3y agoOn the contrary. I'd like the pin operator regardless of whether rebinding is allowed or not. def func() do s = g() ...several lines of code l = t() case l do {s, q} -> #blah {q,q} -> #blah {p, r} -> #blah end end Without the "^s", you need context to determine "s"'s behavior. If s is currently unbound, then it'd be assignment. If it's unbound, it'd be pattern matching. It's a rare enough operation that it's nice to make it explicit. Erlang didn't have rebinding, and Elixir learned from the mistake. Rebinding is not complicated: the scope rules are simple, you learn them and then you're done. It's Day 1 type stuff, which is absolutely not worth optimizing for if you're trying to build a useful language. Without them, you end up coming up with a bunch of bogus variable names that don't add anything to the conversation. Imagine modifying an entry in a struct (or, more exactly, you're making a copy of a struct with one value changed) With rebinding, it's easy: def func(dict) do dict = dict |> Map.put("apple", 1) end Without rebinding, you need a pointless new variable name: def func(dict) do dict_with_one_apple = dict |> Map.put("apple", 1) end
- Miner49er 3y agoI do agree with the pin-operator, after more thought. I actually think it's good, it's just the rebinding that I don't like. I understand the argument for rebinding, as an Erlang developer I have to deal with not having it all the time. I guess I don't really see it as that big of a deal to have to use more variable names. The way I see it, if you're transforming something, it's fine for it to have a different name. I haven't used elixir, but I would guess pipelining covers 95% of the time that rebinding would be wanted, and the other 5% of the time I think I would prefer not to have it, but it's really just nitpicking, it's not too big of a deal.