[erlang-questions] map elements in defined order

Fred Hebert mononcqc@REDACTED
Fri Oct 27 23:58:16 CEST 2017


On 10/27, Richard Carlsson wrote:
>(switching the order of the keys in the left tuple), both of which 
>would be
>equally "legal" since 1 == 1.0. But this switches the order of x and y, so
>that the comparisons of the maps would give different results. One way to
>avoid this situation would be to say that you can't have two keys that
>compare equal with == in the same map, just as for an orddict.

This would, unfortunately, break pattern matching:

M = #{1 => 1},
case M of
    #{1.0 := _} -> % it is safe to add 1.0 if we match
        M#{1.0 := 2}; % does this crush a value and change the key?
    _ ->
        other
end.

The fourth line here is problematic. Either (1) maps have a special 
magical pattern matching case where 1.0 and 1 compare equal (which 
happens nowhere else) and decide whether to replace the key or keep it 
the same, or (2) you keep current pattern matching semantics and you 
can't use existing pattern matching to enforce the constraints above.

(1) is particularly nasty for cases such as:

X = 1.0,
case {#{1 => 1}, 1} of
    {#{X := _}, X} -> true = X =:= X; % works
    {#{X := _}, Y} -> false = X =/= Y % crashes
end

Which one should match? In the first clause, the map would match fine, 
even though X =/= X! We just broke a lot of language here. To preserve 
safe pattern matching, you should probably not be able to make 1 be 
equal to 1.0 in a map through pattern insertions (M#{K := NewVal}).



More information about the erlang-questions mailing list