diff options
author | alandonovan <adonovan@google.com> | 2020-08-04 11:31:21 -0400 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-08-04 11:31:21 -0400 |
commit | 4379bb3f9ac0b7f6e21b1441663122a26f96be31 (patch) | |
tree | b051e782247dd0e178a6b40c715a294a8070c0ec | |
parent | f21d2f77688f64bf3834da4e16dad4d7f316bf9c (diff) | |
download | starlark-go-4379bb3f9ac0b7f6e21b1441663122a26f96be31.tar.gz |
spec: clarify scope rules for comprehensions (#299)
- first loop operand is resolved in enclosing environment
- all loop vars are bound before any expression is resolved
See https://github.com/bazelbuild/starlark/issues/84
-rw-r--r-- | doc/spec.md | 27 |
1 files changed, 26 insertions, 1 deletions
diff --git a/doc/spec.md b/doc/spec.md index 41ccc7f..743e6cd 100644 --- a/doc/spec.md +++ b/doc/spec.md @@ -1302,7 +1302,6 @@ def hello(): if x == 1: y = "hello" ``` - It is a dynamic error to evaluate a reference to a local variable before it has been bound: @@ -1319,6 +1318,32 @@ print(x) # dynamic error: global variable x referenced before ass x = "hello" ``` +and for nested loops in comprehensions. +In the (unnatural) examples below, the scope of the variables `x`, `y`, +and `z` is the entire compehension block, except the operand of the first +loop (`[]` or `[1]`), which is resolved in the enclosing environment. +The second loop may thus refer to variables defined by the third (`z`), +even though such references would fail if actually executed. + +``` +[1//0 for x in [] for y in z for z in ()] # [] (no error) +[1//0 for x in [1] for y in z for z in ()] # dynamic error: local variable z referenced before assignment +``` + +<!-- This is similar to Python[23]. Presumed rational: it resembles + the desugaring to nested loop statements, in which the scope + of all three variables is the entire enclosing function, + including the portion before the bindings. + + def f(): + ... + for x in []: + for y in z: + for z in (): + 1//0 +--> + + It is a static error to bind a global variable already explicitly bound in the file: ```python |