google / skylark

Skylark in Go: the Skylark configuration language, implemented in Go [MOVED to go.starlark.net]
BSD 3-Clause "New" or "Revised" License
1.19k stars 74 forks source link

spec: clarify rules concerning updates during iteration #141

Closed alandonovan closed 6 years ago

alandonovan commented 6 years ago

The Go implementation dynamically rejects all attempts to update a list during iteration, except list[i] = ..., which it considers a non-structural mutation:

$ cat ~/a.sky
def iterator1():
    list = [0, 1, 2]
    for x in list:
        list[x] = 2 * x
    return list

print(iterator1(), [0, 2, 4])
$ skylark a.sky
[0, 2, 4] [0, 2, 4]

The Java and Rust implementations reject even this.

The Go semantics came out of a discussion with the Bazel team that was never concluded. The task of this issue is to clarify the semantics for mutation during iteration. See Google Issue b/37964285 for context.

@laurentlb

laurentlb commented 6 years ago

From the specification:

It is a dynamic error to mutate a sequence such as a list or a dictionary while iterating over it.

In the Go implementation:

def foo(arg):
  for i in arg:
    arg[0] = 5

foo([10, 11])  # allowed

foo({0: 10, 1: 11})  # error

The difference between the list and the dictionary doesn't seem consistent.

My recommendation is to follow the specification, forbid both calls (in the example above). We can easily revisit this restriction later, as this would be a backward-compatible change.