aboutsummaryrefslogtreecommitdiff
path: root/doc
diff options
context:
space:
mode:
authoralandonovan <adonovan@google.com>2020-09-01 15:57:27 -0400
committerGitHub <noreply@github.com>2020-09-01 15:57:27 -0400
commit6e684ef5eeee284749e13eae206cb4dd899b3472 (patch)
treef6b246291bc165025fe5b85dd9f9bc2c18e76a83 /doc
parent949cc6f4b09716061bc5c308049b0da811aeca10 (diff)
downloadstarlark-go-6e684ef5eeee284749e13eae206cb4dd899b3472.tar.gz
spec: clarify resolution of undefined names (#303)
Diffstat (limited to 'doc')
-rw-r--r--doc/spec.md20
1 files changed, 18 insertions, 2 deletions
diff --git a/doc/spec.md b/doc/spec.md
index 743e6cd..203ce28 100644
--- a/doc/spec.md
+++ b/doc/spec.md
@@ -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.
@@ -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.
@@ -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,
@@ -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: