I get that, but I just wanted to have a discussion and not pitch a proposal.
I’m asking why a base functionality for maps that is present in Erlang isn’t supported in Elixir when Elixir delegates most of its map logic to Erlang. Those two that you’re referring to aren’t supported in Erlang’s map literal syntax, so although I see what you’re getting at, I don’t think those comparisons are accurate.
I’ve been either writing or code reviewing Elixir on a daily basis at my job for more than a couple of years. I would never claim to be an expert, but I also wouldn’t refer to myself as a newcomer or outsider who is bewildered by how things are done in Elixir relative to other languages. I’m not even sure that a newcomer would have cared enough about Erlang to notice the inconsistency and ask the question.
I agree with all the arguments for sticking with status quo though I’m too lazy to upvote them all, lol.
From what I gather, Elixir’s update syntax isn’t even equivalent to Erlang’s := since it can update multiple keys in one go. If the insert one were to stay consistent with the update syntax, what would it look like? It sort of feels weird to give several keys to insert then raise if some already exist, no? Maybe not. This feels to more of ditching => and := altogether a new class of “update multiple keys if they all exist” syntax.
I personally really don’t care about inconsistencies if it (arguably) improves clarity. Like send/receive in Elixir are both prefix functions whereas one is infix and the other is prefix in Erlang.
There is clearly a disconnect between what I’m saying and what certain people are interpreting because nowhere did I challenge the status quo.
Map#{Key := Val} is identical to %{map | key => val}. If key exists, it will be updated with val. Otherwise, it will raise with a key error. You can update as many valid keys as you want.
Yes. But I don’t know what that has to do with anything since I never suggested anything like that.
Not at all. This is merely a question of Erlang supporting both Map#{Key := Val} and Map#{Key => Val} simultaneously, i.e. Map#{Key := Val, Key => Val}, so why has Elixir chosen to only support the former and leave the latter to just the Map module. That’s all.
Well then as far as just discussion goes, my point was that %{map | key: val} is only incidentally identical in the case that you are only updating one key. But the syntax allows for %{map | key1: val2, key2: val2, key3: val3} which is different. | takes a map and a keyword list, := takes one key and one value. Unless there is Erlang syntax I don’t know which is entirely possible.
It is not a case common enough to prioritize, in my opinion, at the cost of having additional syntax for it. You may agree or disagree, but that’s the rationale.
Erlang also allows multiple keys to be given and you can add and update several keys at once.
I personally think the question has been answered, so it is probably a good time to wrap it up.
But wouldn’t that look like Map#{Key := Value, Key2 := Value2}? The semantics feel different since everything to the right of the | are the key/values to update whereas the Erlang one it’s multiple := doing the update. I guess I’m wrong, but still feels a bit different, lol.
Just for the record, I tried a quick benchmark to make sure we weren’t missing out any performance benefit compared to multiple Map.put/3 calls or a Map.merge/2: turns out all of these approaches are equivalent performance wise (so nothing to be gained on this front).
It would be interesting to measure the update syntax too. The Erlang docs state it (the Erlang syntax, at least) is faster for adding and updating multiple keys: Erlang -- Maps