Clarification about iterating over maps

39 views
Skip to first unread message

Matthew Dempsky

unread,
Jan 11, 2013, 1:41:09 PM1/11/13
to golang-dev
The January 9, 2013 spec says this about iterating over a map:

"If map entries are inserted during iteration, the behavior is implementation-dependent, but the iteration values for each entry will be produced at most once."

Does "for each entry" here mean "for each map entry" or "for each inserted entry"?

For example, consider the following code:

    m := make(map[int]int)
    for i := 0; i < 10; i++ {
        m[i] = i
    }
    for k := range m {
        fmt.Println(k)
        m[100] = 100
    }

Is it conforming for an implementation to print out only a single value?  Or is it required that the implementation should print (in an undefined order) 0 through 9 and possibly (at the implementation's discretion) 100?

Allowing the former could simplify implementing hash algorithms that rely on relocating existing hash table entries during insertions, though I suspect the spec actually intends the latter interpretation.  More importantly, I think users would find the latter interpretation less surprising, which arguably far outweighs implementer convenience.

Ian Lance Taylor

unread,
Jan 11, 2013, 2:13:44 PM1/11/13
to Matthew Dempsky, golang-dev
On Fri, Jan 11, 2013 at 10:41 AM, Matthew Dempsky <mdem...@google.com> wrote:
> The January 9, 2013 spec says this about iterating over a map:
>
> "If map entries are inserted during iteration, the behavior is
> implementation-dependent, but the iteration values for each entry will be
> produced at most once."
>
>
> Does "for each entry" here mean "for each map entry" or "for each inserted
> entry"?

For each inserted entry. Conceptually, inserting an entry should not
disturb the map iteration, but the new key may be before or after the
current iteration point so whether the new key is returned during the
iteration is implementation dependent.

> For example, consider the following code:
>
> m := make(map[int]int)
> for i := 0; i < 10; i++ {
> m[i] = i
> }
> for k := range m {
> fmt.Println(k)
> m[100] = 100
> }
>
> Is it conforming for an implementation to print out only a single value? Or
> is it required that the implementation should print (in an undefined order)
> 0 through 9 and possibly (at the implementation's discretion) 100?

The latter.

Ian

Matthew Dempsky

unread,
Jan 11, 2013, 2:23:04 PM1/11/13
to Ian Lance Taylor, golang-dev
On Fri, Jan 11, 2013 at 11:13 AM, Ian Lance Taylor <ia...@google.com> wrote:
On Fri, Jan 11, 2013 at 10:41 AM, Matthew Dempsky <mdem...@google.com> wrote:
> The January 9, 2013 spec says this about iterating over a map:
>
> "If map entries are inserted during iteration, the behavior is
> implementation-dependent, but the iteration values for each entry will be
> produced at most once."
>
>
> Does "for each entry" here mean "for each map entry" or "for each inserted
> entry"?

For each inserted entry.  Conceptually, inserting an entry should not
disturb the map iteration, but the new key may be before or after the
current iteration point so whether the new key is returned during the
iteration is implementation dependent.

Cool, that's what I expected.  Is it worth a CL to make this wording more explicit?

minux

unread,
Jan 11, 2013, 2:33:28 PM1/11/13
to Matthew Dempsky, Ian Lance Taylor, golang-dev
Reply all
Reply to author
Forward
0 new messages