[erlang-bugs] Maps equality failure / Maps merge failure

Björn-Egil Dahlberg wallentin.dahlberg@REDACTED
Wed Mar 25 00:04:01 CET 2015


Answers inline ..

2015-03-24 23:00 GMT+01:00 Jesper Louis Andersen <
jesper.louis.andersen@REDACTED>:

>
> On Tue, Mar 24, 2015 at 3:28 PM, Björn-Egil Dahlberg <egil@REDACTED>
> wrote:
>
>> We will look into the others now.
>
>
> I extended the tests for the branch egil/fix-term-cmp/OTP-12623
> (commit-ID: a1520d8) which fixes the binary_to_term/term_to_binary
> conversions. I had some model errors with maps:map/2, which I fixed. Then I
> added generators for floating point values. Look at this little gem:
>
> Erlang/OTP 17 [erts-6.3.1] [source-a1520d8] [64-bit] [smp:8:8]
> [async-threads:10] [hipe] [kernel-poll:false]
>
> Eshell V6.3.1  (abort with ^G)
> 1> L = [{-1,0},{0.0,0},{0,0},{1,0}].
> [{-1,0},{0.0,0},{0,0},{1,0}]
> 2> lists:sort(L).
> [{-1,0},{0.0,0},{0,0},{1,0}]
> 3> lists:sort(maps:to_list(maps:from_list(L))).
> [{-1,0},{0,0},{0.0,0},{1,0}]
> 4> v(2) =:= v(3).
> false
> 5> maps:to_list(maps:from_list(L)).
> [{-1,0},{0,0},{1,0},{0.0,0}]
>
> In other words, factoring L through a map makes the comparison and the
> sort go wrong. I would expect the factoring to be the identity such that
> v(4) would be true in the above. But it looks like something happens to the
> value so 0 and 0.0 swaps place in the ordering. There *has* to be a
> floating point 0.0 in there. So it has something to do with this, but I
> can't be more specific :) Note that this bug may be related to the merge
> bug I reported earlier today, but the merge tests succeed on this branch.
>

I don't think anything is wrong here.

Maps (small maps) store keys in "term order" not "arithmetic order". Where
"term order" is defined as erlangs arithmetic order but integers types are
less than float types. This gives us a total order of all erlang terms.

Furthermore, maps:to_list/1 is defined to return pairs in arbitrary order.
=)

v(2) =:= v(3) returns false because lists:sort/1 is stable, 0.0 and 0
compares equal and those keys started in different positions before the
sort.

However, we will change map comparison between maps to 18. Two maps will
compare keys by term order and not by arithmetic order as it is today.
Values will still use arithmetic order.


>
> Also, another peculiar thing:
>
> 7> maps:put(-1, 3, #{}).
> #{-1 => 3}
> 8> #{ -1 => 3 }.
> * 1: illegal map key
>
> Negative integers are not valid map keys, but I don't know exactly why
> that is the case. This is compiler-land however, and I have not yet a
> QuickCheck model for that :)
>

This is a (not so) known fact. It has to do with the fact that we only
handle literal keys with maps syntax in 17 and negative integers are not
literals. They are unary expressions on positive integers and thusly not
handled by the compiler.
This is not the case in 18 (current master) where we can handle map keys
with variables.

 // Björn-Egil
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://erlang.org/pipermail/erlang-bugs/attachments/20150325/43ec695a/attachment.htm>


More information about the erlang-bugs mailing list