aboutsummaryrefslogtreecommitdiff
path: root/spec/scope.md
diff options
context:
space:
mode:
authorMarshall Lochbaum <mwlochbaum@gmail.com>2020-10-18 20:49:40 -0400
committerMarshall Lochbaum <mwlochbaum@gmail.com>2020-10-18 20:49:40 -0400
commit94fc6cbc5299fd5a151e9274b6a73e0adea55325 (patch)
tree042ed2b455c01bf72c3368eba7db328f9c877098 /spec/scope.md
parentd7d5c92da88b05871fd1fcdee06a9e0edf0c0604 (diff)
Everyone's a little dyslexic
Diffstat (limited to 'spec/scope.md')
-rw-r--r--spec/scope.md4
1 files changed, 2 insertions, 2 deletions
diff --git a/spec/scope.md b/spec/scope.md
index 7af09957..e1288cdb 100644
--- a/spec/scope.md
+++ b/spec/scope.md
@@ -18,7 +18,7 @@ Two identifier instances have the *same name* if their tokens, as strings, match
- The two identifiers are the same instance (a defined variable is its own definition).
The definition for an identifier is chosen from the potential definitions based on their containing scopes: it is the one whose containing scope does not contain or match the containing scope of any other potential definition. If for any identifier there is no definition, then the program is not valid and results in an error. This can occur if the identifier has no potential definition, and also if two potential definitions appear in the same scope. In fact, under this scheme it is never valid to make two definitions with the same name at the top level of a single scope, because both definitions would be potential definitions for the one that comes second in program order. Both definitions have the same containing scope, and any potential definition must contain or match this scope, so no potential definition can be selected.
-The definition of *program order* for identifier tokens follows the order of BQN [execution](evaluate.md). It corresponds to the order of a particular traversal of the abstract syntax tree for a program. To find the relative ordering of two identifiers in a program, we consider the highest-depth node that they both belong to; in this node they must occur in different components, or that component would be a higher-depth node containing both of them. In most nodes, the program order goes from right to left: components further to the left come earlier in program order. The exceptions are `PROGRAM`, `BODY`, `NS_BODY`, `list`, `subject` (for stranding), and body case (`FCase`, `_mCase`, `_cCase_`, `FMain`, `_mMain`, `_cMain_`, `brSub`, `BrFunc`, `_brMod1`, and `_brMod2_`) nodes, in which program order goes in the opposite order, from left to right (some assignment target nodes also contain lists or strands, but their ordering is irrelevant because if two identifiers with the same name appear in such a list, then it can't be a definition).
+The definition of *program order* for identifier tokens follows the order of BQN [execution](evaluate.md). It corresponds to the order of a particular traversal of the abstract syntax tree for a program. To find the relative ordering of two identifiers in a program, we consider the highest-depth node that they both belong to; in this node they must occur in different components, or that component would be a higher-depth node containing both of them. In most nodes, the program order goes from right to left: components further to the right come earlier in program order. The exceptions are `PROGRAM`, `BODY`, `NS_BODY`, `list`, `subject` (for stranding), and body case (`FCase`, `_mCase`, `_cCase_`, `FMain`, `_mMain`, `_cMain_`, `brSub`, `BrFunc`, `_brMod1`, and `_brMod2_`) nodes, in which program order goes in the opposite order, from left to right (some assignment target nodes also contain lists or strands, but their ordering is irrelevant because if two identifiers with the same name appear in such a list, then it can't be a definition).
### Special names
@@ -36,6 +36,6 @@ An identifier is exported if the `ASGN` node in its definition is `"⇐"`, or if
A *variable* is an entity that permits two operations: it can be *set* to a particular value, and its *value* can be obtained, resulting in the last value it was set to. When either operation is performed it is referred to as *accessing* the variable.
-When a body in a block is evaluated, a variable is created for each definition (that is, defined identifier instance) the body contains. Whenever another block—the block itself, not its contents—is evaluated during the execution of the block, it is linked to the currently-evaluating block, so that it will use the variables defined in this instance. These links are recursive, so that every instance of a block is linked to exactly one instance of each block that contains it. These links form a tree that is not necessarily related to the call stack of functions and modifiers. Using these links, the variable an identifier refers to is the one corresponding to that variable's definition in the linked instance of the containing scope for the definition.
+When a body in a block is evaluated, a variable is created for each definition (that is, defined identifier instance) the body contains. Whenever another block—the block itself, not its contents—is evaluated during the execution of the block, it is linked to the currently-evaluating block, so that it will use the variables defined in this instance. By following these links repeatedly, an instance of a block is always linked to exactly one instance of each block that contains it. These links form a tree that is not necessarily related to the call stack of functions and modifiers. Using the links, the variable an identifier refers to is the one corresponding to that variable's definition in the linked instance of the containing scope for the definition.
The first access to a variable must be made by its definition (this also means it sets the variable). If a different instance of its identifier accesses it first, then an error results. This can happen because every scope contained in a particular scope sees all the definitions it uses, and such a scope could be called before the definition is run. Because of conditional execution, this property must be checked at run time in general; however, in cases where it is possible to statically determine that a program will always violate it, a BQN instance can give an error at compile time rather than run time.