erlang/otp

Non-deterministic representation of map as string

Closed this issue · 1 comments

pguyot commented

Describe the bug
Until OTP-27, the following map:

#{a => 1, b => 2}

would have the following representation:

"#{a => 1,b => 2}"

With OTP-27, the representation can non-deterministically also be:

"#{b = >2,a => 1}"

To Reproduce

mkdir /tmp/test_beam
cd /tmp/test_beam

Then run the following command a dozen times:

erl -pa . -eval 'io:format("~p\n", [#{a=>1,b=>2}]).' -run init stop -noshell

Expected behavior
Representation should be deterministic or non-determinism should be documented (couldn't find it in OTP27 release notes).

Affected versions
OTP-27.0

Additional context

This was observed on macOS:

ProductName: macOS
ProductVersion: 14.5
BuildVersion: 23F79

with OTP-27 from MacPorts on an amd64 machine.

Screenshot 2024-06-22 at 22 51 22

This was changed in OTP 26 and is documented in the release notes: https://erlang.org/download/otp_src_26.0.readme (under OTP-18414). Maps were never documented as having any particular order, and in fact maps larger than 32 keys in previous releases would have a largely unpredictable order of keys when printed (different to maps with less than 32 keys) - such order should have never been relied upon, as it was never guaranteed.

Maps can be printed sorted using io:format("~kp", [Value])., with the k and K modifiers documented in io:fwrite/3.