Map iteration order

The iteration order of an iterator created with maps:iterator(M, undefined) is undefined (yeah, duh). That is fine. I wonder however if that iteration order is guaranteed to be stable, that is, that repeated iterations return the map entries in the same order for the same M.

Looking at the code, maps:iterator(M, Order) returns [Path|M], and the first call to maps:next/1 turns this into a nested tuple structure via a call to erts_internal:map_next, which in turn is used for iteration from that point on, and thereby fixed.

When using maps:iterator(M, undefined), [0|M] is returned, which means “no particular path”. So the deeper question is, does erts_internal:map_next always build the same tuple structure when it gets no instruction about a particular path?


A related question concerns using a key ordering function, for example erlang:'=<'/2. Now, using =< can result in different equally valid orderings: 1, 1.0 as well as 1.0, 1. Any one of which is fine, but the question is again, is the order guaranteed to be stable?

Looking at the code again, maps:iterator(M, F) builds the path by retrieving the keys of M via maps:keys(M) and then sorts them via lists:sort(F, Ks) (which is documented as stable), which then gets used as a specific path for erts_internal:map_next (which in this case, ie being given a path, produces a stable tuple structure). So the deeper question here is, is the order in which maps:keys returns the keys guaranteed to be stable, that is, the same order for the same M?


Whether it is guaranteed or not, it should be documented.

From a functional perspective, it should be guaranteed in both scenarios, because same input should result in same output.

The iteration order of multiple calls to maps:iterator/1 on the same map is not guaranteed, though the current implementation does it like that given that you are on the same node. So yes erts_internal:map_next does always build the tuple the same way, but that is not guaranteed by the API so it might change.

maps:keys/1 is also not guaranteed to be stable, though the current implementation is, again given that you are on the same node.

I don’t foresee the implementation ever returning anything but the same order for the same set of keys on the same node, but something that could make this happen is if we come up with some clever optimization for really large sets of keys where it would have to yield while collecting keys and thus the yield point does something to the order.