Skip to content

Commit

Permalink
spec: clarify resolution of undefined names (google#303)
Browse files Browse the repository at this point in the history
  • Loading branch information
adonovan authored Sep 1, 2020
1 parent 949cc6f commit 6e684ef
Showing 1 changed file with 18 additions and 2 deletions.
20 changes: 18 additions & 2 deletions doc/spec.md
Original file line number Diff line number Diff line change
Expand Up @@ -1273,7 +1273,7 @@ Names in this block (such as `a` and `b` in the example)
are bound only by `load` statements.
The sets of names bound in the file block and in the module block do not overlap:
it is an error for a load statement to bind the name of a global,
or for a top-level statement to assign to a name bound by a load statement.
or for a top-level statement to bind a name bound by a load statement.

A file block contains a _function_ block for each top-level
function, and a _comprehension_ block for each top-level comprehension.
Expand Down Expand Up @@ -1318,7 +1318,7 @@ print(x) # dynamic error: global variable x referenced before ass
x = "hello"
```

and for nested loops in comprehensions.
The same is also true 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.
Expand All @@ -1330,6 +1330,7 @@ even though such references would fail if actually executed.
[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,
Expand All @@ -1343,6 +1344,21 @@ even though such references would fail if actually executed.
1//0
-->

It is a static error to refer to a name that has no binding at all.
```
def f():
if False:
g() # static error: undefined: g
```
(This behavior differs from Python, which treats such references as global,
and thus does not report an error until the expression is evaluated.)

<!-- Consequently, the REPL, which consumes one compound statement at a time,
cannot resolve forward references such as
def f(): return K
K = 1
because the first chunk has an unresolved reference to K.
-->

It is a static error to bind a global variable already explicitly bound in the file:

Expand Down

0 comments on commit 6e684ef

Please sign in to comment.