aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authoralandonovan <adonovan@google.com>2020-08-04 11:31:21 -0400
committerGitHub <noreply@github.com>2020-08-04 11:31:21 -0400
commit4379bb3f9ac0b7f6e21b1441663122a26f96be31 (patch)
treeb051e782247dd0e178a6b40c715a294a8070c0ec
parentf21d2f77688f64bf3834da4e16dad4d7f316bf9c (diff)
downloadstarlark-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.md27
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