<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
</head>
<body text="#000000" bgcolor="#FFFFFF">
<p>Yes. All Erlang terms, including maps, have a globally defined,
implementation independent, total order.<br>
</p>
The reason, for this "surprising" order of maps, is the alternative
of using the normal arithmetic order for keys is much worse.<br>
<br>
If we want 1 and 1.0 to be different keys (which we do as we use
matching (=:=) to lookup keys)<br>
then we need to order 1 and 1.0, and normal arithmetic term ordering
does not (1 == 1.0).<br>
<br>
<br>
It has been discussed (more and less serious) to expose this
"map-key-order" with operators like :<, :>, =:<, >:=.<br>
<br>
<br>
/Sverker<br>
<br>
<br>
<div class="moz-cite-prefix">On 10/27/2017 03:13 PM, Ulf Wiger
wrote:<br>
</div>
<blockquote type="cite"
cite="mid:CADPRLo-ToDY4w83iGvs1zB3qfiuoDLVr7ZbVqYCtgG1kC7axKw@mail.gmail.com">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<div dir="ltr">Actually, that's roughly what I started out
assuming too, but it's not sufficient. Consider:
<div><br>
</div>
<div>
<div>1> lists:sort([#{[-1.0] => 0}, #{[1] => 0}]).</div>
<div>[#{[1] => 0},#{[-1.0] => 0}]</div>
</div>
<div><br>
</div>
<div>You must dig into each structure and find occurrences of
floats to determine whether they affect the ordering.</div>
<div><br>
</div>
<div>But yes, the documented sort order should be stable across
versions. This means, in practice, that it's safe to rely on
the sorting properties of maps.</div>
<div><br>
</div>
<div>BR,</div>
<div>Ulf</div>
</div>
<div class="gmail_extra"><br>
<div class="gmail_quote">2017-10-27 10:49 GMT+02:00 Richard
Carlsson <span dir="ltr"><<a
href="mailto:carlsson.richard@gmail.com" target="_blank"
moz-do-not-send="true">carlsson.richard@gmail.com</a>></span>:<br>
<blockquote class="gmail_quote" style="margin:0 0 0
.8ex;border-left:1px #ccc solid;padding-left:1ex">
<div dir="ltr">My interpretation of the reference manual is
that maps compare to each other like the tuples created by
this transformation:
<div><br>
</div>
<div>t(Map) -></div>
<div> {Ks,Vs} = lists:unzip(lists:keysort(1, [{{if
is_integer(K) -> 0; is_float(K) -> 1; true -> 2
end, K}, V} || {K,V} <- maps:to_list(M)])),</div>
<div> list_to_tuple(Ks ++ Vs).<br>
</div>
<div><br>
</div>
<div>For example:</div>
<div><br>
</div>
<div><font face="monospace, monospace"> t(#{65 =>
"A", 2.71 => e, 1.0e308 => alot, pi => 3.14,
[] => 0})</font></div>
<div><br>
</div>
<div>yields</div>
<div><br>
</div>
<div>
<div><font face="monospace, monospace"> {{0,65},
{1,2.71}, {1,1.0e308}, {2,pi}, {2,[]},</font></div>
<div><font face="monospace, monospace"> "A",
e, alot, 3.14, 0}</font></div>
</div>
<div><br>
</div>
<div>Which:</div>
<div>1) should be independent of the underlying
implementation and choice of hash function, and thus
stable across future versions of Erlang;</div>
<div>2) is cumbersome to express using the normal term
order over the basic data types, since float keys always
sort higher than integers (not really following the rule
of least surprise).</div>
<span class="HOEnZb"><font color="#888888">
<div><br>
</div>
<div><br>
</div>
<div><br>
</div>
</font></span></div>
<div class="gmail_extra"><span class="HOEnZb"><font
color="#888888"><br clear="all">
<div>
<div class="m_-3576336282511749221gmail_signature"
data-smartmail="gmail_signature"><br>
/Richard</div>
</div>
<br>
</font></span>
<div class="gmail_quote"><span class="">2017-10-27 9:25
GMT+02:00 Ulf Wiger <span dir="ltr"><<a
href="mailto:ulf@wiger.net" target="_blank"
moz-do-not-send="true">ulf@wiger.net</a>></span>:<br>
</span>
<div>
<div class="h5">
<blockquote class="gmail_quote" style="margin:0 0 0
.8ex;border-left:1px #ccc solid;padding-left:1ex">
<div dir="ltr">Actually, they ARE, in some ways.
<div><br>
</div>
<div>I should have been clearer. I was, of
course, referring to the uses of records where
they were never optimal in the first place,
but were tolerated e.g. because of the great
convenience of referencing elements by name in
pattern-matching.<br>
</div>
<div><br>
</div>
<div>Quoted from EEP-0043:</div>
<div><br>
</div>
<div>«The idea was a data-type, a syntax-aware
mapping of key-value associations with pattern
matching. A syntax similar to records but
without the hassle of compile-time dependency
and with arbitrary terms as keys. Order was
not important and it could be implemented with
a Hash-Array-Mapped-Trie with good performance
and memory trade-offs. This was a different
approach than to replace records. It was meant
to replace records where suitable and in other
regards not be a replacement but its own
_thing_.»</div>
<div><br>
</div>
<div>Further, relevant to this discussion:</div>
<div><br>
</div>
<div>«A restriction set on the implementation by
the Erlang specification is that order is
total, i.e. satisfies _antisymmetry,
transitivity and totality_.</div>
<div>...</div>
<div>- Ordered maps impose restrictions on the
underlying implementation and a hashing
approach will be nearly impossible.</div>
<div>- The underlying structure does not need to
be sorted, an order could be produced when
needed,»</div>
<div><br>
</div>
<div>The thing I tried to highlight was that "an
order could be produced when needed" is
actually a bit more involved than you'd think,
given that no API function does it for you. At
least if you want to reflect the internal sort
order - given that the actual implementation
is NOT as described in the EEP: "If a key or
value differs, the order of the respective
terms, in Erlang term order".</div>
<div><br>
</div>
<div>You'd have to write your own sort function,
in which you visit all elements of complex
structures, finding all instances of floats
and ensuring that they get the right priority.</div>
<div><br>
</div>
<div>Or... you simply do this:</div>
<div><br>
</div>
<div>lists:sort(fun(A, B) -> #{A => 0}
=< #{B => 0} end, maps:to_list(Map))</div>
<div><br>
</div>
<div><br>
</div>
<div>As evidenced e.g. by Benoit's comment
above, I believe lots of people already
rely on the order of map elements being IN
SOME WAY stable. This is likely a brittle
assumption, but one that may - in time - trap
the OTP team into having to preserve the
current APPARENT order.</div>
<div><br>
</div>
<div>And the apparent order does appear to be
sorted, as long as only maps of size =< 32
("flatmaps") are inspected. For larger maps
("hashmaps"), the order of elements returned
by maps:to_list/1 indeed appears arbitrary.</div>
<div><br>
</div>
<div>BR,</div>
<div>Ulf W</div>
</div>
<div class="m_-3576336282511749221HOEnZb">
<div class="m_-3576336282511749221h5">
<div class="gmail_extra"><br>
<div class="gmail_quote">2017-10-27 6:01
GMT+02:00 zxq9 <span dir="ltr"><<a
href="mailto:zxq9@zxq9.com"
target="_blank" moz-do-not-send="true">zxq9@zxq9.com</a>></span>:<br>
<blockquote class="gmail_quote"
style="margin:0 0 0 .8ex;border-left:1px
#ccc solid;padding-left:1ex">On
2017年10月26日 木曜日 21:13:07 Ulf Wiger
wrote:<br>
> ... to use as a replacement for
records.<br>
<br>
But they are IN NO WAY a replacement for
records.<br>
<br>
-Craig<br>
<div
class="m_-3576336282511749221m_-8808523036434140903HOEnZb">
<div
class="m_-3576336282511749221m_-8808523036434140903h5">______________________________<wbr>_________________<br>
erlang-questions mailing list<br>
<a
href="mailto:erlang-questions@erlang.org"
target="_blank"
moz-do-not-send="true">erlang-questions@erlang.org</a><br>
<a
href="http://erlang.org/mailman/listinfo/erlang-questions"
rel="noreferrer" target="_blank"
moz-do-not-send="true">http://erlang.org/mailman/list<wbr>info/erlang-questions</a><br>
</div>
</div>
</blockquote>
</div>
<br>
</div>
</div>
</div>
<br>
______________________________<wbr>_________________<br>
erlang-questions mailing list<br>
<a href="mailto:erlang-questions@erlang.org"
target="_blank" moz-do-not-send="true">erlang-questions@erlang.org</a><br>
<a
href="http://erlang.org/mailman/listinfo/erlang-questions"
rel="noreferrer" target="_blank"
moz-do-not-send="true">http://erlang.org/mailman/list<wbr>info/erlang-questions</a><br>
<br>
</blockquote>
</div>
</div>
</div>
<br>
</div>
</blockquote>
</div>
<br>
</div>
<br>
<fieldset class="mimeAttachmentHeader"></fieldset>
<br>
<pre wrap="">_______________________________________________
erlang-questions mailing list
<a class="moz-txt-link-abbreviated" href="mailto:erlang-questions@erlang.org">erlang-questions@erlang.org</a>
<a class="moz-txt-link-freetext" href="http://erlang.org/mailman/listinfo/erlang-questions">http://erlang.org/mailman/listinfo/erlang-questions</a>
</pre>
</blockquote>
<br>
</body>
</html>