aboutsummaryrefslogtreecommitdiff
path: root/spec/evaluate.md
diff options
context:
space:
mode:
Diffstat (limited to 'spec/evaluate.md')
-rw-r--r--spec/evaluate.md4
1 files changed, 2 insertions, 2 deletions
diff --git a/spec/evaluate.md b/spec/evaluate.md
index 575558ff..3d1ea1c5 100644
--- a/spec/evaluate.md
+++ b/spec/evaluate.md
@@ -10,7 +10,7 @@ Here we assume that the referent of each identifier, or equivalently the connect
The result of parsing a valid BQN program is a `PROGRAM`, and the program is run by evaluating this term.
-A `PROGRAM` or `BODY` is a list of `STMT`s (for `BODY`, the last must be an `EXPR`, a particular kind of `STMT`), which are evaluated in program order. The statement `nothing` does nothing when evaluated, while `EXPR` evaluates some APL code and possibly assigns the results, as described below.
+A `PROGRAM` or `BODY` is a list of `STMT`s (for `BODY`, the last must be an `EXPR`, a particular kind of `STMT`), which are evaluated in program order. The statement `EXPR` evaluates some APL code and possibly assigns the results, while `nothing` evaluates any `subject` or `Derv` terms it contains but discards the results.
A block consists of several `BODY` terms, some of which may have an accompanying header describing accepted inputs and how they are processed. An immediate block `brImm` can only have one `BODY`, and is evaluated by evaluating the code in it. Other types of blocks do not evaluate any `BODY` immediately, but instead return a function or modifier that obtains its result by evaluating a particular `BODY`. The `BODY` is identified and evaluated once the block has received enough inputs (operands or arguments), which for modifiers can take one or two calls: if two calls are required, then on the first call the operands are simply stored and no code is evaluated yet. Two calls are required if there is more than one `BODY` term, if the `BODY` contains the special names `๐•จ๐•ฉ๐•ค๐•Ž๐•๐•Š`, or if its header specifies arguments (the header-body combination is a `_mCase` or `_cCase_`). Otherwise only one is required.
@@ -18,7 +18,7 @@ To evaluate a block when enough inputs have been received, first the correct cas
The only remaining step before evaluating the `BODY` is to bind the inputs and other names. Special names are always bound when applicable: `๐•จ๐•ฉ๐•ค` if arguments are used, `๐•จ` if there is a left argument, `๐•—๐•˜` if operands are used, and `_๐•ฃ` and `_๐•ฃ_` for modifiers and combinators, respectively. Any names in the header are also bound, allowing multiple assignment for arguments.
-If there is no left argument, but the `BODY` contains `๐•จ` at the top level, then it is conceptually re-parsed with `๐•จ` replaced by `ยท` to give a monadic version before application. As the only effect when this re-parsed form is valid is to change some instances of `arg` to `nothing`, this can be achieved efficiently by annotating parts of the AST that depend on `๐•จ` as conditionally-nothing. However, it also causes an error if `๐•จ` is used as an operand or list element, where `nothing` is not allowed by the grammar.
+If there is no left argument, but the `BODY` contains `๐•จ` at the top level, then it is conceptually re-parsed with `๐•จ` replaced by `ยท` to give a monadic version before application; this modifies the syntax tree by replacing some instances of `arg` with `nothing`. However, it also causes an error if, in a function that is called with no left argument, `๐•จ` is used as an operand or list element, where `nothing` is not allowed by the grammar. The same effect can also be achieved dynamically by treating `ยท` as a value and checking for it during execution. If it is used as a left argument, then the function should instead be called with no left argument (and similarly in trains); it it is used as a right argument, then the function and its left argument are evaluated but rather than calling the function `ยท` is "returned" immediately; and if it is used in another context then it causes an error.
### Assignment