From: Raphaël Van Dyck Date: Tue, 17 Mar 2026 14:19:00 +0000 (+0100) Subject: revise user manual, tutorial, and reference manual X-Git-Url: http://evlambda.org/gitweb/gitweb.cgi?a=commitdiff_plain;p=evlambda.git revise user manual, tutorial, and reference manual --- diff --git a/system-files/IMPLEMENTATION-NOTES b/system-files/IMPLEMENTATION-NOTES index 52784d7..268faa0 100644 --- a/system-files/IMPLEMENTATION-NOTES +++ b/system-files/IMPLEMENTATION-NOTES @@ -11,7 +11,7 @@
- $\DeclareMathOperator{\bindingmathop}{binding}$ + $\DeclareMathOperator{\binding}{binding}$

Implementation Notes

The implementation notes document the JavaScript file /system/core.js, which implements the “core” of the EVLambda programming language and the EVL to XML converter (one of the two components of the documentation generator, the other one being the XSLT stylesheet). The implementation notes and the JavaScript file have the same organization (the same sections, in the same order) and are meant to be read side by side.

@@ -293,13 +293,13 @@
  • Extending a lexical or dynamic environment is achieved by copying the two sets of bindings and then deleting and adding some bindings from/to the copy of one of the two sets.
  • A lexical or dynamic environment is represented not by the result of the sequence of extensions leading to the environment but by a recording of the sequence of extensions leading to the environment. A single extension is recorded into a data structure called a frame and a sequence of extensions is recorded into a chain of frames.

    -

    Let $\env$ be a lexical or dynamic environment and$$[(\ns_1,[\var_{1,1},\ldots,\var_{1,m_1}],[\obj_{1,1},\ldots,\obj_{1,m_1}]),\ldots,(\ns_n,[\var_{n,1},\ldots,\var_{n,m_n}],[\obj_{n,1},\ldots,\obj_{n,m_n}])]$$be the sequence of extensions leading to the environment. The extensions are applied from left to right and the first extension is applied to an empty environment. The $i$-th extension$$(\ns_i,[\var_{i,1},\ldots,\var_{i,m_i}],[\obj_{i,1},\ldots,\obj_{i,m_i}])$$extends the previous environment by binding, in the namespace $\ns_i$, the variable $\var_{i,j}$ to the object $\obj_{i,j}$ (for all $i$ from $1$ to $n$ and all $j$ from $1$ to $m_i$). We will denote by $\bindingmathop(i,j)$ the binding between $\var_{i,j}$ and $\obj_{i,j}$ created by the $i$-th extension.

    +

    Let $\env$ be a lexical or dynamic environment and$$[(\ns_1,[\var_{1,1},\ldots,\var_{1,m_1}],[\obj_{1,1},\ldots,\obj_{1,m_1}]),\ldots,(\ns_n,[\var_{n,1},\ldots,\var_{n,m_n}],[\obj_{n,1},\ldots,\obj_{n,m_n}])]$$be the sequence of extensions leading to the environment. The extensions are applied from left to right and the first extension is applied to an empty environment. The $i$-th extension$$(\ns_i,[\var_{i,1},\ldots,\var_{i,m_i}],[\obj_{i,1},\ldots,\obj_{i,m_i}])$$extends the previous environment by binding, in the namespace $\ns_i$, the variable $\var_{i,j}$ to the object $\obj_{i,j}$ (for all $i$ from $1$ to $n$ and all $j$ from $1$ to $m_i$). We will denote by $\binding(i,j)$ the binding between $\var_{i,j}$ and $\obj_{i,j}$ created by the $i$-th extension.

    The binding for the variable $\var$ in the namespace $\ns$ of the environment $\env$ can easily be located using the following lookup rule expressed in pseudocode:

    Initialize $i$ to $n$.
    While $i>0$, do the following:
    - If $\ns_i=\ns$ and there exists $j\in\{1,\ldots,m_i\}$ such that $\var_{i,j}=\var$ (if such $j$ exists, it is necessarily unique because the variables $\var_{i,1},\ldots,\var_{i,m_i}$ are distinct), then $\bindingmathop(i,j)$ is the binding for the variable $\var$ in the namespace $\ns$ of the environment $\env$. Otherwise, decrement $i$ by $1$. + If $\ns_i=\ns$ and there exists $j\in\{1,\ldots,m_i\}$ such that $\var_{i,j}=\var$ (if such $j$ exists, it is necessarily unique because the variables $\var_{i,1},\ldots,\var_{i,m_i}$ are distinct), then $\binding(i,j)$ is the binding for the variable $\var$ in the namespace $\ns$ of the environment $\env$. Otherwise, decrement $i$ by $1$.
    The variable $\var$ in unbound in the namespace $\ns$ of the environment $\env$.
    diff --git a/system-files/REFERENCE-MANUAL b/system-files/REFERENCE-MANUAL index 71ab8ce..dcaad6d 100644 --- a/system-files/REFERENCE-MANUAL +++ b/system-files/REFERENCE-MANUAL @@ -12,9 +12,34 @@
    $\newcommand{\unicode}[1]{U{+}\code{#1}}$ + $\newcommand{\outcome}{\mlvar{outcome}}$ $\DeclareMathOperator{\lex}{lex}$ $\DeclareMathOperator{\pat}{pat}$ $\DeclareMathOperator{\spread}{spread}$ + $\DeclareMathOperator{\serialform}{serial-form}$ + $\DeclareMathOperator{\iftestform}{if-test-form}$ + $\DeclareMathOperator{\setvalueform}{set-value-form}$ + $\DeclareMathOperator{\blockserialforms}{block-serial-forms}$ + $\DeclareMathOperator{\returnfromvaluesform}{return-from-values-form}$ + $\DeclareMathOperator{\catchexittagform}{catch-exit-tag-form}$ + $\DeclareMathOperator{\catchserialforms}{catch-serial-forms}$ + $\DeclareMathOperator{\throwexittagform}{throw-exit-tag-form}$ + $\DeclareMathOperator{\throwvaluesform}{throw-values-form}$ + $\DeclareMathOperator{\handlerbindhandlerform}{\_handler-bind-handler-form}$ + $\DeclareMathOperator{\handlerbindserialforms}{\_handler-bind-serial-forms}$ + $\DeclareMathOperator{\unwindprotectprotectedform}{unwind-protect-protected-form}$ + $\DeclareMathOperator{\unwindprotectcleanupforms}{unwind-protect-cleanup-forms}$ + $\DeclareMathOperator{\foreachfunctionform}{\_for-each-function-form}$ + $\DeclareMathOperator{\foreachlistform}{\_for-each-list-form}$ + $\DeclareMathOperator{\foreachelement}{\_for-each-element}$ + $\DeclareMathOperator{\functioncalloperatorform}{function-call-operator-form}$ + $\DeclareMathOperator{\functioncalloperandform}{function-call-operand-form}$ + $\DeclareMathOperator{\macro}{macro}$ + $\DeclareMathOperator{\evalserialforms}{eval-serial-forms}$ + $\DeclareMathOperator{\evalserialformforms}{eval-serial-form-forms}$ + $\DeclareMathOperator{\foreach}{\_for-each}$ + $\DeclareMathOperator{\evaloperandforms}{eval-operand-forms}$ + $\DeclareMathOperator{\invoke}{invoke}$

    Reference Manual

    The reference manual provides a detailed account of the programming language. It supplements and amends the user manual (particularly the sections “Programming Language” and “Listener Buffers”) and the tutorial.

    @@ -805,7 +830,7 @@ $\metavar{special-form}$ $\Coloneq$ - $\metavar{quote-form}$ | $\metavar{progn-form}$ | $\metavar{if-form}$ | $\metavar{lambda-abstraction}$ | $\metavar{variable-reference}$ | $\metavar{variable-assignment}$ | $\metavar{\_for-each-form}$ | $\metavar{\_catch-errors-form}$ | $\metavar{apply-form}$ | $\metavar{multiple-value-call-form}$ | $\metavar{multiple-value-apply-form}$ + $\metavar{quote-form}$ | $\metavar{progn-form}$ | $\metavar{if-form}$ | $\metavar{lambda-abstraction}$ | $\metavar{variable-reference}$ | $\metavar{variable-assignment}$ | $\metavar{block-form}$ | $\metavar{return-from-form}$ | $\metavar{catch-form}$ | $\metavar{throw-form}$ | $\metavar{\_handler-bind-form}$ | $\metavar{unwind-protect-form}$ | $\metavar{\_for-each-form}$ | $\metavar{apply-form}$ | $\metavar{multiple-value-call-form}$ | $\metavar{multiple-value-apply-form}$ $\metavar{quote-form}$ @@ -928,27 +953,77 @@ $\metavar{form}$ - $\metavar{\_for-each-form}$ + $\metavar{block-form}$ $\Coloneq$ - (_for-each $\metavar{function-form}$ $\metavar{list-form}$) + (block $\metavar{block-name}$ $\metavar{serial-form}$*) - $\metavar{function-form}$ + $\metavar{return-from-form}$ + $\Coloneq$ + (return-from $\metavar{block-name}$ $\metavar{values-form}$) + + + $\metavar{catch-form}$ + $\Coloneq$ + (catch $\metavar{exit-tag-form}$ $\metavar{serial-form}$*) + + + $\metavar{throw-form}$ + $\Coloneq$ + (throw $\metavar{exit-tag-form}$ $\metavar{values-form}$) + + + $\metavar{block-name}$ + $\Coloneq$ + $\variable$ + + + $\metavar{exit-tag-form}$ $\Coloneq$ $\metavar{form}$ - $\metavar{list-form}$ + $\metavar{values-form}$ + $\Coloneq$ + $\metavar{form}$ + + + $\metavar{\_handler-bind-form}$ + $\Coloneq$ + (_handler-bind $\metavar{handler-form}$ $\metavar{serial-form}$*) + + + $\metavar{handler-form}$ $\Coloneq$ $\metavar{form}$ - $\metavar{\_catch-errors-form}$ + $\metavar{unwind-protect-form}$ $\Coloneq$ - (_catch-errors $\metavar{try-form}$) + (unwind-protect $\metavar{protected-form}$ $\metavar{cleanup-form}$*) - $\metavar{try-form}$ + $\metavar{protected-form}$ + $\Coloneq$ + $\metavar{form}$ + + + $\metavar{cleanup-form}$ + $\Coloneq$ + $\metavar{form}$ + + + $\metavar{\_for-each-form}$ + $\Coloneq$ + (_for-each $\metavar{function-form}$ $\metavar{list-form}$) + + + $\metavar{function-form}$ + $\Coloneq$ + $\metavar{form}$ + + + $\metavar{list-form}$ $\Coloneq$ $\metavar{form}$ @@ -1009,7 +1084,7 @@ $\metavar{special-operator}$ $\Coloneq$ - quote | progn | if | _vlambda | _mlambda | _flambda | _dlambda | vref | fref | dref | vset! | fset! | dset! | _for-each | _catch-errors | apply | multiple-value-call | multiple-value-apply + quote | progn | if | _vlambda | _mlambda | _flambda | _dlambda | vref | fref | dref | vset! | fset! | dset! | block | return-from | catch | throw | _handler-bind | unwind-protect | _for-each | apply | multiple-value-call | multiple-value-apply $\metavar{call}$ @@ -1040,6 +1115,13 @@
  • A list whose first element is a variable (other than a special operator) naming a macro according to the lookup rule used by fref is never analyzed as a plain function call. Either the list is successfully analyzed as a macro call or the analysis fails.
  • The variables of a parameter list must be distinct.
  • +

    The subforms of a form are the forms that are directly or indirectly contained inside the form but are not contained inside a lambda abstraction. The serial-forms of the body of a lambda abstraction are not considered to be subforms of the lambda abstraction because the evaluation of a lambda abstraction does not entail the evaluation of the serial-forms of its body.

    +

    A form is said to be in tail position with respect to a lambda abstraction if and only if one of the following mutually exclusive conditions is satisfied:

    +

    Documentation Generator

    In this section, the character ⇰ marks the places where line breaks have been added to wrap long lines.

    Let us consider the following documented EVLambda source file:

    @@ -1059,7 +1141,7 @@

    Semantics

    Primitive Data Types and Primitive Functions

    This section inventories all the primitive data types and all the primitive functions.

    -

    For each primitive function, a template function call and a description of the primitive function's behavior are provided.

    +

    For each primitive function, a template function call, an indication of the outcome of the corresponding invocation, and a description of the primitive function's behavior are provided.

    In template function calls, argument names imply the following type restrictions:

    -

    If any argument is not of its required type, then the invocation of the primitive function completes abruptly with a reason of type error.

    +

    If any argument is not of its required type, then the invocation of the primitive function completes abruptly for a reason of type error.

    Primitive Data Types

    Here is a tree-view representation of the hierarchy of primitive data types:

    object
    |-void
    |-boolean
    |-number
    |-character
    |-string
    |-symbol
    | |-keyword
    | |-variable
    |-list
    | |-empty-list
    | |-cons
    |-vector
    |-function
    | |-primitive-function
    | |-closure

    Primitive Data Type object and Related Primitive Functions

    -
    (object? $\object$)
    +
    (object? $\object$) ⇒ $\boolean$
    The primitive function returns #t if $\object$ is of type object (which is always the case) and #f otherwise.
    -
    (eq? $\object_1$ $\object_2$)
    +
    (eq? $\object_1$ $\object_2$) ⇒ $\boolean$
    The primitive function is an equality predicate. It returns #t if and only if the two objects are one and the same. In other words, it returns #t if and only if the two objects have the same address in the heap.
    -
    (eql? $\object_1$ $\object_2$)
    +
    (eql? $\object_1$ $\object_2$) ⇒ $\boolean$
    The primitive function is an equality predicate. If both objects are of type number, then it returns #t if and only if the two objects represent the same mathematical number. Otherwise, if both objects are of type character, then it returns #t if and only if the two objects represent the same UTF-$16$ code unit. Otherwise, if both objects are of type string, then it returns #t if and only if the two objects represent the same indexed sequence of UTF-$16$ code units. Otherwise, it returns #t if and only if the two objects are eq?.

    Primitive Data Type void and Related Primitive Functions

    -
    (void? $\object$)
    +
    (void? $\object$) ⇒ $\boolean$
    The primitive function returns #t if $\object$ is of type void and #f otherwise.

    Primitive Data Type boolean and Related Primitive Functions

    -
    (boolean? $\object$)
    +
    (boolean? $\object$) ⇒ $\boolean$
    The primitive function returns #t if $\object$ is of type boolean and #f otherwise.

    Primitive Data Type number and Related Primitive Functions

    Objects of type number represent mathematical numbers using the floating-point format IEEE 754 binary 64. Some (but not all) of the integers that can be represented exactly by an object of type number are the integers between $-2^{53}=−9,007,199,254,740,992$ and $2^{53}=9,007,199,254,740,992$ (bounds included).

    -
    (number? $\object$)
    +
    (number? $\object$) ⇒ $\boolean$
    The primitive function returns #t if $\object$ is of type number and #f otherwise.
    -
    (_+ $\number_1$ $\number_2$)
    +
    (_+ $\number_1$ $\number_2$) ⇒ $\number$
    The primitive function returns the sum $\number_1+\number_2$.
    -
    (_- $\number_1$ $\number_2$)
    +
    (_- $\number_1$ $\number_2$) ⇒ $\number$
    The primitive function returns the difference $\number_1-\number_2$.
    -
    (_* $\number_1$ $\number_2$)
    +
    (_* $\number_1$ $\number_2$) ⇒ $\number$
    The primitive function returns the product $\number_1\times\number_2$.
    -
    (_/ $\number_1$ $\number_2$)
    +
    (_/ $\number_1$ $\number_2$) ⇒ $\number$
    The primitive function returns the quotient $\number_1\div\number_2$.
    -
    (% $\number_1$ $\number_2$)
    +
    (% $\number_1$ $\number_2$) ⇒ $\number$
    The primitive function returns the remainder of the division of $\number_1$ by $\number_2$ when the quotient is forced to be an integer.
    -
    (= $\number_1$ $\number_2$)
    +
    (= $\number_1$ $\number_2$) ⇒ $\boolean$
    The primitive function returns #t if $\number_1$ and $\number_2$ are numerically equal and #f otherwise.
    -
    (/= $\number_1$ $\number_2$)
    +
    (/= $\number_1$ $\number_2$) ⇒ $\boolean$
    The primitive function returns #t if $\number_1$ and $\number_2$ are numerically different and #f otherwise.
    -
    (< $\number_1$ $\number_2$)
    +
    (< $\number_1$ $\number_2$) ⇒ $\boolean$
    The primitive function returns #t if $\number_1$ is numerically less than $\number_2$ and #f otherwise.
    -
    (<= $\number_1$ $\number_2$)
    +
    (<= $\number_1$ $\number_2$) ⇒ $\boolean$
    The primitive function returns #t if $\number_1$ is numerically less than or equal to $\number_2$ and #f otherwise.
    -
    (> $\number_1$ $\number_2$)
    +
    (> $\number_1$ $\number_2$) ⇒ $\boolean$
    The primitive function returns #t if $\number_1$ is numerically greater than $\number_2$ and #f otherwise.
    -
    (>= $\number_1$ $\number_2$)
    +
    (>= $\number_1$ $\number_2$) ⇒ $\boolean$
    The primitive function returns #t if $\number_1$ is numerically greater than or equal to $\number_2$ and #f otherwise.

    The primitive functions _+, _-, _*, and _/ have an underscore at the beginning of their names to distinguish them from the similarly named nonprimitive functions +, -, *, and /, which all accept a variable number of arguments.

    Primitive Data Type character and Related Primitive Functions

    Contrary to what was said in the user manual, an object of type character represents a UTF-$16$ code unit (instead of a Unicode character).

    -
    (character? $\object$)
    +
    (character? $\object$) ⇒ $\boolean$
    The primitive function returns #t if $\object$ is of type character and #f otherwise.

    Primitive Data Type string and Related Primitive Functions

    Contrary to what was said in the user manual, an object of type string represents an indexed sequence of UTF-$16$ code units (instead of an indexed sequence of Unicode characters).

    -
    (string? $\object$)
    +
    (string? $\object$) ⇒ $\boolean$
    The primitive function returns #t if $\object$ is of type string and #f otherwise.

    Primitive Data Type symbol and Related Primitive Functions

    -
    (symbol? $\object$)
    +
    (symbol? $\object$) ⇒ $\boolean$
    The primitive function returns #t if $\object$ is of type symbol and #f otherwise.

    Primitive Data Type keyword and Related Primitive Functions

    -
    (keyword? $\object$)
    +
    (keyword? $\object$) ⇒ $\boolean$
    The primitive function returns #t if $\object$ is of type keyword and #f otherwise.
    -
    (make-keyword? $\string$)
    +
    (make-keyword? $\string$) ⇒ $\keyword$
    The primitive function returns a new keyword whose name is $\string$. The keyword is not interned.

    Primitive Data Type variable and Related Primitive Functions

    -
    (variable? $\object$)
    +
    (variable? $\object$) ⇒ $\boolean$
    The primitive function returns #t if $\object$ is of type variable and #f otherwise.
    -
    (make-variable $\string$)
    +
    (make-variable $\string$) ⇒ $\variable$
    The primitive function returns a new variable whose name is $\string$. The variable is not interned.
    -
    (variable-value $\variable$)
    +
    (variable-value $\variable$) ⇒ $\object$
    If there exists a binding for $\variable$ in the value namespace of the global environment, then the primitive function returns the value of that binding. Otherwise, the primitive function returns #v.
    -
    (variable-set-value! $\variable$ $\object$)
    +
    (variable-set-value! $\variable$ $\object$) ⇒ $\object$
    If there exists a binding for $\variable$ in the value namespace of the global environment, then the primitive function replaces the value of that binding by $\object$. Otherwise, the primitive function adds to the value namespace of the global environment a new binding between $\variable$ and $\object$. In both cases, the primitive function returns $\object$.
    -
    (variable-value-bound? $\variable$)
    +
    (variable-value-bound? $\variable$) ⇒ $\boolean$
    If there exists a binding for $\variable$ in the value namespace of the global environment, then the primitive function returns #t. Otherwise, the primitive function returns #f.
    -
    (variable-unbind-value! $\variable$)
    +
    (variable-unbind-value! $\variable$)#v
    If there exists a binding for $\variable$ in the value namespace of the global environment, then that binding is deleted and the primitive function returns #v. Otherwise, the primitive function simply returns #v.
    -
    (variable-function $\variable$)
    +
    (variable-function $\variable$) ⇒ $\object$
    If there exists a binding for $\variable$ in the function namespace of the global environment, then the primitive function returns the value of that binding. Otherwise, the primitive function returns #v.
    -
    (variable-set-function! $\variable$ $\object$)
    +
    (variable-set-function! $\variable$ $\object$) ⇒ $\object$
    If there exists a binding for $\variable$ in the function namespace of the global environment, then the primitive function replaces the value of that binding by $\object$. Otherwise, the primitive function adds to the function namespace of the global environment a new binding between $\variable$ and $\object$. In both cases, the primitive function returns $\object$.
    -
    (variable-function-bound? $\variable$)
    +
    (variable-function-bound? $\variable$) ⇒ $\boolean$
    If there exists a binding for $\variable$ in the function namespace of the global environment, then the primitive function returns #t. Otherwise, the primitive function returns #f.
    -
    (variable-unbind-function! $\variable$)
    +
    (variable-unbind-function! $\variable$)#v
    If there exists a binding for $\variable$ in the function namespace of the global environment, then that binding is deleted and the primitive function returns #v. Otherwise, the primitive function simply returns #v.

    Primitive Data Type list and Related Primitive Functions

    -
    (list? $\object$)
    +
    (list? $\object$) ⇒ $\boolean$
    The primitive function returns #t if $\object$ is of type list and #f otherwise.

    Primitive Data Type empty-list and Related Primitive Functions

    -
    (empty-list? $\object$)
    +
    (empty-list? $\object$) ⇒ $\boolean$
    The primitive function returns #t if $\object$ is of type empty-list and #f otherwise.

    Primitive Data Type cons and Related Primitive Functions

    -
    (cons? $\object$)
    +
    (cons? $\object$) ⇒ $\boolean$
    The primitive function returns #t if $\object$ is of type cons and #f otherwise.
    -
    (cons $\object_1$ $\object_2$)
    +
    (cons $\object_1$ $\object_2$) ⇒ $\cons$
    The primitive function returns a new cons whose first element is $\object_1$ and whose second element is $\object_2$.
    -
    (car $\cons$)
    +
    (car $\cons$) ⇒ $\object$
    The primitive function returns the first element of $\cons$.
    -
    (set-car! $\cons$ $\object$)
    +
    (set-car! $\cons$ $\object$) ⇒ $\object$
    The primitive function replaces the first element of $\cons$ by $\object$ and returns $\object$.
    -
    (cdr $\cons$)
    +
    (cdr $\cons$) ⇒ $\object$
    The primitive function returns the second element of $\cons$
    -
    (set-cdr! $\cons$ $\object$)
    +
    (set-cdr! $\cons$ $\object$) ⇒ $\object$
    The primitive function replaces the second element of $\cons$ by $\object$ and returns $\object$.

    Primitive Data Type vector and Related Primitive Functions

    -
    (vector? $\object$)
    +
    (vector? $\object$) ⇒ $\boolean$
    The primitive function returns #t if $\object$ is of type vector and #f otherwise.

    Primitive Data Type function and Related Primitive Functions

    -
    (function? $\object$)
    +
    (function? $\object$) ⇒ $\boolean$
    The primitive function returns #t if $\object$ is of type function and #f otherwise.

    Primitive Data Type primitive-function and Related Primitive Functions

    -
    (primitive-function? $\object$)
    +
    (primitive-function? $\object$) ⇒ $\boolean$
    The primitive function returns #t if $\object$ is of type primitive-function and #f otherwise.

    Primitive Data Type closure and Related Primitive Functions

    -
    (closure? $\object$)
    +
    (closure? $\object$) ⇒ $\boolean$
    The primitive function returns #t if $\object$ is of type closure and #f otherwise.

    Miscellaneous Primitive Functions

    -
    (values $\object_1\ldots\object_n$)
    +
    (values $\object_1\ldots\object_n$) ⇒ $\object_1,\ldots,\object_n$
    The primitive function converts its arguments into values: when invoked on the arguments $\object_1,\ldots,\object_n$, the primitive function returns the values $\object_1,\ldots,\object_n$.
    -
    (error $\string$)
    -
    The invocation of the primitive function completes abruptly with a reason of type error whose payload is $\string$.
    -
    (now)
    +
    (error $\string$) ⇒ completes abruptly for a reason of type error
    +
    The invocation of the primitive function completes abruptly for a reason of type error whose payload is $\string$.
    +
    (now) ⇒ $\number$
    The primitive function returns the number of milliseconds elapsed since 1970-01-01 00:00:00.000 UTC.

    Forms

    This section supplements and amends the evaluation rules stated in the user manual.

    +

    Advanced Control Structures

    +

    The two pairs of special forms block/return-from and catch/throw use two additional namespaces: the block-name namespace and the exit-point namespace.

    +
    Special Forms block/return-from
    +

    The special forms block and return-from are evaluated as follows:

    +
    +
    (block $\metavar{block-name}$ $\metavar{serial-form}$*)
    +
    Let $\mlvar{exit-tag}$ be a new uninterned variable. The serial-forms are evaluated in sequence from left to right with respect to (1) the environment extending the current lexical environment to bind, in the block namespace, the variable $\mlvar{block-name}$ to $\mlvar{exit-tag}$ and (2) the environment extending the current dynamic environment to bind, in the exit-point namespace, the variable $\mlvar{exit-tag}$ to #v (the value is unimportant). If the evaluation of any serial-form completes abruptly for any reason, then the following serial-forms are not evaluated and the evaluation of the block-form proceeds as follows: +
    Let $\mlvar{reason}$ be the reason for the abrupt completion of the serial-form. If $\mlvar{reason}$ is of type nonlocal-exit and carries an exit tag eq? to $\mlvar{exit-tag}$, then the evaluation of the block-form completes normally and produces the values carried by $\mlvar{reason}$. Otherwise, the evaluation of the block-form completes abruptly for the reason $\mlvar{reason}$.
    + Otherwise, the evaluations of the serial-forms all complete normally and the evaluation of the block-form completes normally and produces the values of the last serial-form or #v if there are no serial-forms.
    +
    (return-from $\metavar{block-name}$ $\metavar{values-form}$)
    +
    If there exists no binding for the variable $\metavar{block-name}$ in the block namespace of the current lexical environment, then the evaluation of the return-from-form completes abruptly for a reason of type error. Otherwise, let $\mlvar{exit-tag}$ be the value of the binding for the variable $\mlvar{block-name}$ in the block namespace of the current lexical environment. If there exists no binding for the variable $\mlvar{exit-tag}$ in the exit-point namespace of the current dynamic environment, then the evaluation of the return-from-form completes abruptly for a reason of type error. Otherwise, the values-form is evaluated. If the evaluation of the values-form completes abruptly for any reason, then the evaluation of the return-from-form completes abruptly for the same reason. Otherwise, the evaluation of the return-from-form completes abruptly for a reason of type nonlocal-exit carrying $\mlvar{exit-tag}$ and the values of the values-form.
    +
    +
    Special Forms catch/throw
    +

    The special forms catch and throw are evaluated as follows:

    +
    +
    (catch $\metavar{exit-tag-form}$ $\metavar{serial-form}$*)
    +
    The exit-tag-form is evaluated. If the evaluation of the exit-tag-form completes abruptly for any reason, then the evaluation of the catch-form completes abruptly for the same reason. Otherwise, let $\mlvar{exit-tag}$ be the primary value of the exit-tag-form. If $\mlvar{exit-tag}$ is not a variable, then the evaluation of the catch-form completes abruptly for a reason of type error. Otherwise, the serial-forms are evaluated in sequence from left to right with respect to (1) the current lexical environment and (2) the environment extending the current dynamic environment to bind, in the exit-point namespace, the variable $\mlvar{exit-tag}$ to #v (the value is unimportant). If the evaluation of any serial-form completes abruptly for any reason, then the following serial-forms are not evaluated and the evaluation of the catch-form proceeds as follows: +
    Let $\mlvar{reason}$ be the reason for the abrupt completion of the serial-form. If $\mlvar{reason}$ is of type nonlocal-exit and carries an exit tag eq? to $\mlvar{exit-tag}$, then the evaluation of the catch-form completes normally and produces the values carried by $\mlvar{reason}$. Otherwise, the evaluation of the catch-form completes abruptly for the reason $\mlvar{reason}$.
    + Otherwise, the evaluations of the serial-forms all complete normally and the evaluation of the catch-form completes normally and produces the values of the last serial-form or #v if there are no serial-forms.
    +
    (throw $\metavar{exit-tag-form}$ $\metavar{values-form}$)
    +
    The exit-tag-form is evaluated. If the evaluation of the exit-tag-form completes abruptly for any reason, then the evaluation of the throw-form completes abruptly for the same reason. Otherwise, let $\mlvar{exit-tag}$ be the primary value of the exit-tag-form. If $\mlvar{exit-tag}$ is not a variable, then the evaluation of the throw-form completes abruptly for a reason of type error. Otherwise, if there exists no binding for the variable $\mlvar{exit-tag}$ in the exit-point namespace of the current dynamic environment, then the evaluation of the throw-form completes abruptly for a reason of type error. Otherwise, the values-form is evaluated. If the evaluation of the values-form completes abruptly for any reason, then the evaluation of the throw-form completes abruptly for the same reason. Otherwise, the evaluation of the throw-form completes abruptly for a reason of type nonlocal-exit carrying $\mlvar{exit-tag}$ and the values of the values-form.
    +
    +
    Special Form _handler-bind
    +

    The special form _handler-bind is evaluated as follows:

    +
    +
    (_handler-bind $\metavar{handler-form}$ $\metavar{serial-form}$*)
    +
    The handler-form is evaluated. If the evaluation of the handler-form completes abruptly for any reason, then the evaluation of the _handler-bind-form completes abruptly for the same reason. Otherwise, let $\mlvar{handler}$ be the primary value of the handler-form. If $\mlvar{handler}$ is not a function, then the evaluation of the _handler-bind-form completes abruptly for a reason of type error. Otherwise, the serial-forms are evaluated in sequence from left to right. If the evaluation of any serial-form completes abruptly for any reason, then the following serial-forms are not evaluated and the evaluation of the _handler-bind-form proceeds as follows: +
    Let $\mlvar{reason}$ be the reason for the abrupt completion of the serial-form. If $\mlvar{reason}$ is of type nonlocal-exit, then the evaluation of the _handler-bind-form completes abruptly for the reason $\mlvar{reason}$. Otherwise, $\mlvar{handler}$ is invoked on the payload of $\mlvar{reason}$. If the invocation completes abruptly for any reason, then the evaluation of the _handler-bind-form also completes abruptly for the same reason. Otherwise, if the invocation does not complete, then the evaluation of the _handler-bind-form does not complete either. Otherwise, the _handler-bind-form evaluates to the values of the invocation.
    + Otherwise, the evaluations of the serial-forms all complete normally and the evaluation of the _handler-bind-form completes normally and produces the values of the last serial-form or #v if there are no serial-forms.
    +
    +
    Special Form unwind-protect
    +

    The special form unwind-protect is evaluated as follows:

    +
    +
    (unwind-protect $\metavar{protected-form}$ $\metavar{cleanup-form}$*)
    +
    The protected-form is evaluated. If the evaluation of the protected-form completes abruptly for any reason, then the evaluation of the unwind-protect-form proceeds as follows: +
    Let $\mlvar{reason}$ be the reason for the abrupt completion of the protected-form. The cleanup-forms are evaluated in sequence from left to right. If the evaluation of any cleanup-form completes abruptly for any reason, then the following serial-forms are not evaluated and the evaluation of the unwind-protect-form completes abruptly for the same reason. Otherwise, the evaluations of the cleanup-forms all complete normally and the evaluation of the unwind-protect-form completes abruptly for the reason $\mlvar{reason}$.
    + Otherwise, the evaluation of the protected-form completes normally and the evaluation of the unwind-protect-form proceeds as follows: +
    The cleanup-forms are evaluated in sequence from left to right. If the evaluation of any cleanup-form completes abruptly for any reason, then the following serial-forms are not evaluated and the evaluation of the unwind-protect-form completes abruptly for the same reason. Otherwise, the evaluations of the cleanup-forms all complete normally and the evaluation of the unwind-protect-form completes normally and produces the values of the protected-form.
    +
    +

    Special Form _for-each

    The special form _for-each is evaluated as follows:

    (_for-each $\metavar{function-form}$ $\metavar{list-form}$)
    -
    The function-form and the list-form are evaluated, in that order. Let $\primval_1$ be the primary value of the function-form and $\primval_2$ be the primary value of the list-form. If $\primval_1$ is not a function or $\primval_2$ is not a proper list, then the evaluation of the _for-each-form completes abruptly with a reason of type error. Otherwise, the function $\primval_1$ is invoked on each element of the proper list $\primval_2$, from the first element to the last element. If any invocation completes abruptly for any reason, then the evaluation of the _for-each-form completes abruptly for the same reason. Otherwise, if any invocation does not complete, then the evaluation of the _for-each-form does not complete either. Otherwise, the _for-each-form evaluates to #v.
    -
    -

    Special Form _catch-errors

    -

    The special form _catch-errors is evaluated as follows:

    -
    -
    (_catch-errors $\metavar{try-form}$)
    -
    The try-form is evaluated. If the evaluation of the try-form completes abruptly for a reason of type error, then the evaluation of the _catch-errors-form completes normally and the _catch-errors-form evaluates to #v. Otherwise, if the evaluation of the try-form completes abruptly for a reason of type exit, then the evaluation of the _catch-errors-form completes abruptly for the same reason. Otherwise, if the evaluation of the try-form does not complete, then the evaluation of the _catch-errors-form does not complete either. Otherwise, the _catch-errors-form evaluates to the values of the try-form.
    +
    The function-form is evaluated. Let $\mlvar{function}$ be the primary value of the function-form. If $\mlvar{function}$ is not a function, then the evaluation of the _for-each-form completes abruptly for a reason of type error. Otherwise, the list-form is evaluated. Let $\mlvar{list}$ be the primary value of the list-form. If $\mlvar{list}$ is not a proper list, then the evaluation of the _for-each-form completes abruptly for a reason of type error. Otherwise, the function $\mlvar{function}$ is invoked in sequence on each element of the list $\mlvar{list}$, from the first element to the last element. If any invocation completes abruptly for any reason or does not complete, then the evaluation of the _for-each-form also completes abruptly for the same reason or does not complete either. Otherwise, the _for-each-form evaluates to #v.

    Function Calls

    A spreadable sequence of objects is a nonempty sequence of objects such that the last element of the sequence is a proper list of objects. Let $\mlvar{seq}=[\obj_1,\ldots,\obj_n,\code{(}\obj'_1\ldots\obj'_m\code{)}]$, where $n$ and $m$ are nonnegative integers, be a spreadable sequence of objects. We will denote by $\spread(\mlvar{seq})$ the sequence of objects $[\obj_1,\ldots,\obj_n,\obj'_1,\ldots,\obj'_m]$.

    The function calls are evaluated as follows (the differences in behavior between the different types of function calls are highlighted with a gray background):

    ($\metavar{operator-form}$ $\metavar{operand-forms}$)
    -
    The operator-form and the operand-forms are evaluated in sequence from left to right. If the primary value of the operator-form is not a function, then the evaluation of the plain function call completes abruptly with a reason of type error. Otherwise, the primary values of the operand-forms are collected into a sequence $\mlvar{seq}$ and the primary value of the operator-form is invoked on $\mlvar{seq}$. If the invocation completes abruptly for any reason, then the evaluation of the plain function call also completes abruptly for the same reason. Otherwise, if the invocation does not complete, then the evaluation of the plain function call does not complete either. Otherwise, the plain function call evaluates to the values of the invocation. (The behavior described here is identical to the behavior described in the user manual.)
    +
    The operator-form is evaluated. Let $\mlvar{operator}$ be the primary value of the operator-form. If $\mlvar{operator}$ is not a function, then the evaluation of the plain function call completes abruptly for a reason of type error. Otherwise, the operand-forms are evaluated in sequence from left to right, the primary values of the operand-forms are collected into a sequence $\mlvar{seq}$, and $\mlvar{operator}$ is invoked on $\mlvar{seq}$. If the invocation completes abruptly for any reason, then the evaluation of the plain function call also completes abruptly for the same reason. Otherwise, if the invocation does not complete, then the evaluation of the plain function call does not complete either. Otherwise, the plain function call evaluates to the values of the invocation. (The behavior described here is identical to the behavior described in the user manual.)
    (apply $\metavar{operator-form}$ $\metavar{operand-forms}$)
    -
    The operator-form and the operand-forms are evaluated in sequence from left to right. If the primary value of the operator-form is not a function, then the evaluation of the apply-form completes abruptly with a reason of type error. Otherwise, the primary values of the operand-forms are collected into a sequence $\mlvar{seq}$ and the primary value of the operator-form is invoked on $\spread(\mlvar{seq})$. (The evaluation of the apply-form completes abruptly with a reason of type error if $\mlvar{seq}$ is not a spreadable sequence of objects.) If the invocation completes abruptly for any reason, then the evaluation of the apply-form also completes abruptly for the same reason. Otherwise, if the invocation does not complete, then the evaluation of the apply-form does not complete either. Otherwise, the apply-form evaluates to the values of the invocation.
    +
    The operator-form is evaluated. Let $\mlvar{operator}$ be the primary value of the operator-form. If $\mlvar{operator}$ is not a function, then the evaluation of the apply-form completes abruptly for a reason of type error. Otherwise, the operand-forms are evaluated in sequence from left to right, the primary values of the operand-forms are collected into a sequence $\mlvar{seq}$, and $\mlvar{operator}$ is invoked on $\spread(\mlvar{seq})$. (The evaluation of the apply-form completes abruptly for a reason of type error if $\mlvar{seq}$ is not a spreadable sequence of objects.) If the invocation completes abruptly for any reason, then the evaluation of the apply-form also completes abruptly for the same reason. Otherwise, if the invocation does not complete, then the evaluation of the apply-form does not complete either. Otherwise, the apply-form evaluates to the values of the invocation.
    (multiple-value-call $\metavar{operator-form}$ $\metavar{operand-forms}$)
    -
    The operator-form and the operand-forms are evaluated in sequence from left to right. If the primary value of the operator-form is not a function, then the evaluation of the multiple-value-call-form completes abruptly with a reason of type error. Otherwise, all the values of the operand-forms are collected into a sequence $\mlvar{seq}$ and the primary value of the operator-form is invoked on the sequence $\mlvar{seq}$. If the invocation completes abruptly for any reason, then the evaluation of the multiple-value-call-form also completes abruptly for the same reason. Otherwise, if the invocation does not complete, then the evaluation of the multiple-value-call-form does not complete either. Otherwise, the multiple-value-call-form evaluates to the values of the invocation.
    +
    The operator-form is evaluated. Let $\mlvar{operator}$ be the primary value of the operator-form. If $\mlvar{operator}$ is not a function, then the evaluation of the multiple-value-call-form completes abruptly for a reason of type error. Otherwise, the operand-forms are evaluated in sequence from left to right, all the values of the operand-forms are collected into a sequence $\mlvar{seq}$, and $\mlvar{operator}$ is invoked on the sequence $\mlvar{seq}$. If the invocation completes abruptly for any reason, then the evaluation of the multiple-value-call-form also completes abruptly for the same reason. Otherwise, if the invocation does not complete, then the evaluation of the multiple-value-call-form does not complete either. Otherwise, the multiple-value-call-form evaluates to the values of the invocation.
    (multiple-value-apply $\metavar{operator-form}$ $\metavar{operand-forms}$)
    -
    The operator-form and the operand-forms are evaluated in sequence from left to right. If the primary value of the operator-form is not a function, then the evaluation of the multiple-value-apply-form completes abruptly with a reason of type error. Otherwise, all the values of the operand-forms are collected into a sequence $\mlvar{seq}$ and the primary value of the operator-form is invoked on $\spread(\mlvar{seq})$. (The evaluation of the multiple-value-apply-form completes abruptly with a reason of type error if $\mlvar{seq}$ is not a spreadable sequence of objects.) If the invocation completes abruptly for any reason, then the evaluation of the multiple-value-apply-form also completes abruptly for the same reason. Otherwise, if the invocation does not complete, then the evaluation of the multiple-value-apply-form does not complete either. Otherwise, the multiple-value-apply-form evaluates to the values of the invocation.
    +
    The operator-form is evaluated. Let $\mlvar{operator}$ be the primary value of the operator-form. If $\mlvar{operator}$ is not a function, then the evaluation of the multiple-value-apply-form completes abruptly for a reason of type error. Otherwise, the operand-forms are evaluated in sequence from left to right, all the values of the operand-forms are collected into a sequence $\mlvar{seq}$, and $\mlvar{operator}$ is invoked on $\spread(\mlvar{seq})$. (The evaluation of the multiple-value-apply-form completes abruptly for a reason of type error if $\mlvar{seq}$ is not a spreadable sequence of objects.) If the invocation completes abruptly for any reason, then the evaluation of the multiple-value-apply-form also completes abruptly for the same reason. Otherwise, if the invocation does not complete, then the evaluation of the multiple-value-apply-form does not complete either. Otherwise, the multiple-value-apply-form evaluates to the values of the invocation.

    A primitive function is invoked as described in the user manual. A closure is invoked as described in the user manual except for the way the parameters are paired with the arguments in order to extend the value namespace of the lexical environment captured by the closure (when the corresponding lambda abstraction is a _vlambda-form or an _mlambda-form), the function namespace of the lexical environment captured by the closure (when the corresponding lambda abstraction is an _flambda-form), or the value namespace of the current dynamic environment (when the corresponding lambda abstraction is a _dlambda-form). Let $\arg_1,\ldots,\arg_n$ be the arguments and $var_1,\ldots,\var_m$ be the required parameters. The way the parameters are paired with the arguments depends on the absence or presence of a rest parameter:

    Case 1, there is no rest parameter:
    -
    If $n\neq m$, then the invocation completes abruptly with a reason of type error. Otherwise, the appropriate namespace of the appropriate environment is extended to bind $\var_i$ to $\arg_i$ for all $i$ from $1$ to $m$. (This is the behavior described in the user manual.)
    +
    If $n\neq m$, then the invocation completes abruptly for a reason of type error. Otherwise, the appropriate namespace of the appropriate environment is extended to bind $\var_i$ to $\arg_i$ for all $i$ from $1$ to $m$. (This is the behavior described in the user manual.)
    Case 2, there is a rest parameter $\var_{m+1}$:
    -
    If $n\lt m$, then the invocation completes abruptly with a reason of type error. Otherwise, the appropriate namespace of the appropriate environment is extended to bind $\var_i$ to $\arg_i$ for all $i$ from $1$ to $m$ and $\var_{m+1}$ to a proper list whose elements are $\arg_{m+1},\ldots,arg_{n}$. The conses used to build the proper list are not necessarily new conses. When the function call is an apply-form or a multiple-value-apply-form, the proper list and the last element of the spreadable sequence of objects can share conses.
    +
    If $n\lt m$, then the invocation completes abruptly for a reason of type error. Otherwise, the appropriate namespace of the appropriate environment is extended to bind $\var_i$ to $\arg_i$ for all $i$ from $1$ to $m$ and $\var_{m+1}$ to a proper list whose elements are $\arg_{m+1},\ldots,arg_{n}$. The conses used to build the proper list are not necessarily new conses. When the function call is an apply-form or a multiple-value-apply-form, the proper list and the last element of the spreadable sequence of objects can share conses.

    Here are some examples, where the bindings are assumed to belong to the value namespace:

    @@ -1269,5 +1385,141 @@

    Here is one way to reproduce the preceding examples using plain function calls and _vlambda-forms:

    > ((_vlambda (a b) (list a b)) 1 2 3)
    ERROR: Too many arguments.

    > ((_vlambda (a b c) (list a b c)) 1 2 3)
    (1 2 3)

    > ((_vlambda (a b c d) (list a b c d)) 1 2 3)
    ERROR: Too few arguments.

    > ((_vlambda a (list a)) 1 2 3)
    ((1 2 3))

    > ((_vlambda (a . b) (list a b)) 1 2 3)
    (1 (2 3))

    > ((_vlambda (a b . c) (list a b c)) 1 2 3)
    (1 2 (3))

    > ((_vlambda (a b c . d) (list a b c d)) 1 2 3)
    (1 2 3 ())

    > ((_vlambda (a b c d . e) (list a b c d e)) 1 2 3)
    ERROR: Too few arguments.
    +

    Evaluation Rules in Continuation-Passing Style

    +

    Elementary continuations:

    + +

    Auxiliary functions:

    + +
    + +
    To evaluate (quote $\mlvar{literal}$) with respect to $\lexenv$, $\dynenv$, and $k$, do the following:
    +
    Invoke $k$ on $\mlvar{literal}$.
    + +
    To evaluate (progn $\mlvar{serial-forms}$) with respect to $\lexenv$, $\dynenv$, and $k$, do the following:
    +
    Invoke the auxiliary function $\evalserialforms$ on $\mlvar{serial-forms}$, $\lexenv$, $\dynenv$, and $k$.
    +
    To invoke the auxiliary function $\evalserialforms$ on $\mlvar{serial-forms}$, $\lexenv$, $\dynenv$, and $k$, do the following:
    +
    If $\mlvar{serial-forms}$ is empty, then invoke $k$ on #v. Otherwise, invoke the auxiliary function $\evalserialformforms$ on $\mlvar{serial-forms}$, $\lexenv$, $\dynenv$, and $k$.
    +
    To invoke the auxiliary function $\evalserialformforms$ on $\mlvar{serial-forms}$, $\lexenv$, $\dynenv$, and $k$, do the following:
    +
    If $\mlvar{serial-forms}$ contains exactly one element, then evaluate the single element of $\mlvar{serial-forms}$ with respect to $\lexenv$, $\dynenv$, and $k$. Otherwise, evaluate the first element of $\mlvar{serial-forms}$ with respect to $\lexenv$, $\dynenv$, and a $\serialform$ continuation capturing $\mlvar{serial-forms}$ minus its first element, $\lexenv$, $\dynenv$, and $k$.
    +
    To invoke the continuation $\serialform(\mlvar{serial-forms},\lexenv,\dynenv,k)$ on $\outcome$, do the following:
    +
    If $\outcome$ is an abrupt completion reason, then invoke $k$ on $\outcome$. Otherwise, invoke the auxiliary function $\evalserialformforms$ on $\mlvar{serial-forms}$, $\lexenv$, $\dynenv$, and $k$.
    + +
    To evaluate (if $\mlvar{test-form}$ $\mlvar{then-form}$ $\mlvar{else-form}$) with respect to $\lexenv$, $\dynenv$, and $k$, do the following:
    +
    Evaluate $\mlvar{test-form}$ with respect to an $\iftestform$ continuation capturing $\mlvar{then-form}$, $\mlvar{else-form}$, $\lexenv$, $\dynenv$, and $k$.
    +
    To invoke the continuation $\iftestform(\mlvar{then-form},\mlvar{else-form},\lexenv,\dynenv,k)$ on $\outcome$, do the following:
    +
    If $\outcome$ is an abrupt completion reason, then invoke $k$ on $\outcome$. Otherwise, let $\mlvar{test}$ be the primary value of $\outcome$. If $\mlvar{test}$ is not a boolean, then invoke $k$ on an abrupt completion reason of type error. If $\mlvar{test}$ is the boolean #t, then evaluate $\mlvar{then-form}$ with respect to $\lexenv$, $\dynenv$, and $k$. If $\mlvar{test}$ is the boolean #f, then evaluate $\mlvar{else-form}$ with respect to $\lexenv$, $\dynenv$, and $k$.
    + +
    To evaluate (_vlambda $\mlvar{parameter-list}$ $\mlvar{body}$) with respect to $\lexenv$, $\dynenv$, and $k$, do the following:
    +
    To evaluate (_mlambda $\mlvar{parameter-list}$ $\mlvar{body}$) with respect to $\lexenv$, $\dynenv$, and $k$, do the following:
    +
    To evaluate (_flambda $\mlvar{parameter-list}$ $\mlvar{body}$) with respect to $\lexenv$, $\dynenv$, and $k$, do the following:
    +
    To evaluate (_dlambda $\mlvar{parameter-list}$ $\mlvar{body}$) with respect to $\lexenv$, $\dynenv$, and $k$, do the following:
    +
    Invoke $k$ on a closure recording the lambda abstraction and $\lexenv$.
    + +
    To evaluate (vref $\mlvar{variable}$) with respect to $\lexenv$, $\dynenv$, and $k$, do the following:
    +
    To evaluate (fref $\mlvar{variable}$) with respect to $\lexenv$, $\dynenv$, and $k$, do the following:
    +
    To evaluate (dref $\mlvar{variable}$) with respect to $\lexenv$, $\dynenv$, and $k$, do the following:
    +
    If a binding exists for $\mlvar{variable}$, then invoke $k$ on its value. Otherwise, invoke $k$ on an abrupt completion reason of type error.
    + +
    To evaluate (vset! $\mlvar{variable}$ $\mlvar{value-form}$) with respect to $\lexenv$, $\dynenv$, and $k$, do the following:
    +
    To evaluate (fset! $\mlvar{variable}$ $\mlvar{value-form}$) with respect to $\lexenv$, $\dynenv$, and $k$, do the following:
    +
    To evaluate (dset! $\mlvar{variable}$ $\mlvar{value-form}$) with respect to $\lexenv$, $\dynenv$, and $k$, do the following:
    +
    Evaluate $\mlvar{value-form}$ with respect to a $\setvalueform$ continuation capturing $\mlvar{variable}$, $\lexenv$, $\dynenv$, and $k$.
    +
    To invoke the continuation $\setvalueform(\mlvar{variable},\lexenv,\dynenv,k)$ on $\outcome$, do the following:
    +
    If $\outcome$ is an abrupt completion reason, then invoke $k$ on $\outcome$. Otherwise, let $\mlvar{value}$ be the primary value of $\outcome$. If a binding exists for $\mlvar{variable}$, then set its value to $\mlvar{value}$ and invoke $k$ on $\mlvar{value}$. Otherwise, create a binding between $\mlvar{variable}$ and $\mlvar{value}$ and invoke $k$ on $\mlvar{value}$.
    + +
    To evaluate (block $\mlvar{block-name}$ $\mlvar{serial-forms}$) with respect to $\lexenv$, $\dynenv$, and $k$, do the following:
    +
    Let $\mlvar{exit-tag}$ be a new uninterned variable. Invoke the auxiliary function $\evalserialforms$ on $\mlvar{serial-forms}$ and a $\blockserialforms$ continuation capturing $\mlvar{exit-tag}$, the environment extending $\lexenv$ to bind, in the block namespace, the variable $\mlvar{block-name}$ to $\mlvar{exit-tag}$, the environment extending $\dynenv$ to bind, in the exit-point namespace, the variable $\mlvar{exit-tag}$ to #v, and $k$.
    +
    To invoke the continuation $\blockserialforms(\mlvar{exit-tag},\lexenv,\dynenv,k)$ on $\outcome$, do the following:
    +
    If $result$ is an abrupt completion reason of type nonlocal-exit carrying an exit tag eq? to $\mlvar{exit-tag}$, then invoke $k$ on the values carried by $\outcome$. Otherwise, invoke $k$ on $\outcome$.
    + +
    To evaluate (return-from $\mlvar{block-name}$ $\mlvar{values-form}$) with respect to $\lexenv$, $\dynenv$, and $k$, do the following:
    +
    If there exists no binding for the variable $\mlvar{block-name}$ in the block namespace of $\lexenv$, then invoke $k$ on an abrupt completion reason of type error. Otherwise, let $\mlvar{exit-tag}$ be the value of the binding for the variable $\mlvar{block-name}$ in the block namespace of $\lexenv$. If there exists no binding for the variable $\mlvar{exit-tag}$ in the exit-point namespace of $\dynenv$, then invoke $k$ on an abrupt completion reason of type error. Otherwise, evaluate $\mlvar{values-form}$ with respect to $\lexenv$, $\dynenv$, and a $\returnfromvaluesform$ continuation capturing $\mlvar{exit-tag}$, $\lexenv$, $\dynenv$, and $k$.
    +
    To invoke the continuation $\returnfromvaluesform(\mlvar{exit-tag},\lexenv,\dynenv,k)$ on $\outcome$, do the following:
    +
    If $\outcome$ is an abrupt completion reason, then invoke $k$ on $\outcome$. Otherwise, invoke $k$ on an abrupt completion reason of type nonlocal-exit carrying $\mlvar{exit-tag}$ and $\outcome$.
    + +
    To evaluate (catch $\mlvar{exit-tag-form}$ $\mlvar{serial-forms}$) with respect to $\lexenv$, $\dynenv$, and $k$, do the following:
    +
    Evaluate $\mlvar{exit-tag-form}$ with respect to a $\catchexittagform$ continuation capturing $\mlvar{serial-forms}$, $\lexenv$, $\dynenv$, and $k$.
    +
    To invoke the continuation $\catchexittagform(\mlvar{serial-forms},\lexenv,\dynenv,k)$ on $\outcome$, do the following:
    +
    If $\outcome$ is an abrupt completion reason, then invoke $k$ on $\outcome$. Otherwise, let $\mlvar{exit-tag}$ be the primary value of $\outcome$. If $\mlvar{exit-tag}$ is not a variable, then invoke $k$ on an abrupt completion reason of type error. Otherwise, invoke the auxiliary function $\evalserialforms$ on $\mlvar{serial-forms}$ and a $\catchserialforms$ continuation capturing $\mlvar{exit-tag}$, $\lexenv$, the environment extending $\dynenv$ to bind, in the exit-point namespace, the variable $\mlvar{exit-tag}$ to #v, and $k$.
    +
    To invoke the continuation $\catchserialforms(\mlvar{exit-tag},\lexenv,\dynenv,k)$ on $\outcome$, do the following:
    +
    If $result$ is an abrupt completion reason of type nonlocal-exit carrying an exit tag eq? to $\mlvar{exit-tag}$, then invoke $k$ on the values carried by $\outcome$. Otherwise, invoke $k$ on $\outcome$.
    + +
    To evaluate (throw $\mlvar{exit-tag-form}$ $\mlvar{values-form}$) with respect to $\lexenv$, $\dynenv$, and $k$, do the following:
    +
    Evaluate $\mlvar{exit-tag-form}$ with respect to a $\throwexittagform$ continuation capturing $\mlvar{values-form}$, $\lexenv$, $\dynenv$, and $k$.
    +
    To invoke the continuation $\throwexittagform(\mlvar{values-form},\lexenv,\dynenv,k)$ on $\outcome$, do the following:
    +
    If $\outcome$ is an abrupt completion reason, then invoke $k$ $\outcome$. Otherwise, let $\mlvar{exit-tag}$ be the primary value of $\outcome$. If $\mlvar{exit-tag}$ is not a variable, then invoke $k$ on an abrupt completion reason of type error. Otherwise, if there exists no binding for the variable $\mlvar{exit-tag}$ in the exit-point namespace of $\dynenv$, then invoke $k$ on an abrupt completion reason of type error. Otherwise, evaluate $\mlvar{values-form}$ with respect to a $\throwvaluesform$ continuation capturing $\mlvar{exit-tag}$, $\lexenv$, $\dynenv$, and $k$.
    +
    To invoke the continuation $\throwvaluesform(\mlvar{exit-tag},\lexenv,\dynenv,k)$ on $\outcome$, do the following:
    +
    If $\outcome$ is an abrupt completion reason, then invoke $k$ on $\outcome$. Otherwise, invoke $k$ on an abrupt completion reason of type nonlocal-exit carrying $\mlvar{exit-tag}$ and $\outcome$.
    + +
    To evaluate (_handler-bind $\mlvar{handler-form}$ $\mlvar{serial-forms}$) with respect to $\lexenv$, $\dynenv$, and $k$, do the following:
    +
    Evaluate $\mlvar{handler-form}$ with respect to a $\handlerbindhandlerform$ continuation capturing $\mlvar{serial-forms}$, $\lexenv$, $\dynenv$, and $k$.
    +
    To invoke the continuation $\handlerbindhandlerform(\mlvar{serial-forms},\lexenv,\dynenv,k)$ on $\outcome$, do the following:
    +
    If $\outcome$ is an abrupt completion reason, then invoke $k$ on $\outcome$. Otherwise, let $\mlvar{handler}$ be the primary value of $\outcome$. If $\mlvar{handler}$ is not a function, then invoke $k$ on an abrupt completion reason of type error. Otherwise, invoke the auxiliary function $\evalserialforms$ on $\mlvar{serial-forms}$ and a $\handlerbindserialforms$ continuation capturing $\mlvar{handler}$, $\lexenv$, $\dynenv$, and $k$.
    +
    To invoke the continuation $\handlerbindserialforms(\mlvar{handler},\lexenv,\dynenv,k)$ on $\outcome$, do the following:
    +
    If $\outcome$ is an abrupt completion reason of type error, then invoke the auxiliary function $\invoke$ on $\mlvar{handler}$, the string carried by $\outcome$, $\dynenv$, and $k$. Otherwise, invoke $k$ on $\outcome$.
    + +
    To evaluate (unwind-protect $\mlvar{protected-form}$ $\mlvar{cleanup-forms}$) with respect to $\lexenv$, $\dynenv$, and $k$, do the following:
    +
    Evaluate $\mlvar{protected-form}$ with respect to an $\unwindprotectprotectedform$ continuation capturing $\mlvar{cleanup-forms}$, $\lexenv$, $\dynenv$, and $k$.
    +
    To invoke the continuation $\unwindprotectprotectedform(\mlvar{cleanup-forms},\lexenv,\dynenv,k)$ on $\outcome$, do the following:
    +
    Invoke the auxiliary function $\evalserialforms$ on $\mlvar{cleanup-forms}$ and an $\unwindprotectcleanupforms$ continuation capturing $\outcome$, $\lexenv$, $\dynenv$, and $k$.
    +
    To invoke the continuation $\unwindprotectcleanupforms(\mlvar{protected-form-outcome},\lexenv,\dynenv,k)$ on $\outcome$, do the following:
    +
    If $\outcome$ is an abrupt completion reason, then invoke $k$ on $\outcome$. Otherwise, invoke $k$ on $\mlvar{protected-form-outcome}$.
    + +
    To evaluate (_for-each $\mlvar{function-form}$ $\mlvar{list-form}$) with respect to $\lexenv$, $\dynenv$, and $k$, do the following:
    +
    Evaluate $\mlvar{function-form}$ with respect to a $\foreachfunctionform$ continuation capturing $\mlvar{list-form}$, $\lexenv$, $\dynenv$, and $k$.
    +
    To invoke the continuation $\foreachfunctionform(\mlvar{list-form},\lexenv,\dynenv,k)$ on $\outcome$, do the following:
    +
    If $\outcome$ is an abrupt completion reason, then invoke $k$ on $\outcome$. Otherwise, let $\mlvar{function}$ be the primary value of $\outcome$. If $\mlvar{function}$ is not a function, then invoke $k$ on an abrupt completion reason of type error. Otherwise, evaluate $\mlvar{list-form}$ with respect to a $\foreachlistform$ continuation capturing $\mlvar{function}$, $\lexenv$, $\dynenv$, and $k$.
    +
    To invoke the continuation $\foreachlistform(\mlvar{function},\lexenv,\dynenv,k)$ on $\outcome$, do the following:
    +
    If $\outcome$ is an abrupt completion reason, then invoke $k$ on $\outcome$. Otherwise, let $\mlvar{list}$ be the primary value of $\outcome$. If $\mlvar{list}$ is not a proper list, then invoke $k$ on an abrupt completion reason of type error. Otherwise, invoke the auxiliary function $\foreach$ on $\mlvar{function}$, $\mlvar{list}$, $\lexenv$, $\dynenv$, and $k$.
    +
    To invoke the auxiliary function $\foreach$ on $\mlvar{function}$, $\mlvar{list}$, $\lexenv$, $\dynenv$, and $k$, do the following:
    +
    If $\mlvar{list}$ is empty, then invoke $k$ on #v. Otherwise, invoke the auxiliary function $\invoke$ on $\mlvar{function}$, the car of $\mlvar{list}$, $\dynenv$, and a $\foreachelement$ continuation capturing $\mlvar{function}$, the cdr of $\mlvar{list}$, $\lexenv$, $\dynenv$, and $k$.
    +
    To invoke the continuation $\foreachelement(\mlvar{function},\mlvar{list},\lexenv,\dynenv,k)$ on $\outcome$, do the following:
    +
    If $\outcome$ is an abrupt completion reason, then invoke $k$ on $\outcome$. Otherwise, invoke the auxiliary function $\foreach$ on $\mlvar{function}$, $\mlvar{list}$, $\lexenv$, $\dynenv$, and $k$.
    + +
    To evaluate ($\mlvar{operator-form}$ $\mlvar{operand-forms}$) with respect to $\lexenv$, $\dynenv$, and $k$, do the following:
    +
    To evaluate (apply $\mlvar{operator-form}$ $\mlvar{operand-forms}$) with respect to $\lexenv$, $\dynenv$, and $k$, do the following:
    +
    To evaluate (multiple-value-call $\mlvar{operator-form}$ $\mlvar{operand-forms}$) with respect to $\lexenv$, $\dynenv$, and $k$, do the following:
    +
    To evaluate (multiple-value-apply $\mlvar{operator-form}$ $\mlvar{operand-forms}$) with respect to $\lexenv$, $\dynenv$, and $k$, do the following:
    +
    Evaluate $\mlvar{operator-form}$ with respect to a $\functioncalloperatorform$ continuation capturing $\mlvar{operand-forms}$, $\lexenv$, $\dynenv$, and $k$.
    +
    To invoke the continuation $\functioncalloperatorform(\mlvar{operand-forms},\lexenv,\dynenv,k)$ on $\outcome$, do the following:
    +
    If $\outcome$ is an abrupt completion reason, then invoke $k$ on $\outcome$. Otherwise, let $\mlvar{operator}$ be the primary value of $\outcome$. If $\mlvar{operator}$ is not a function, then invoke $k$ on an abrupt completion reason of type error. Otherwise, invoke the auxiliary function $\evaloperandforms$ on $\mlvar{operator}$, $\mlvar{operand-forms}$, $[]$, $\lexenv$, $\dynenv$, and $k$.
    +
    To invoke the auxiliary function $\evaloperandforms$ on $\mlvar{operator}$, $\mlvar{operand-forms}$, $\mlvar{arguments}$, $\lexenv$, $\dynenv$, and $k$, do the following:
    +
    If $\mlvar{operand-forms}$ is not empty, then evaluate the first element of $\mlvar{operand-forms}$ with respect to a $\functioncalloperandform$ continuation capturing $\mlvar{operator}$, $\mlvar{operand-forms}$ minus its first element, $\mlvar{arguments}$, $\lexenv$, $\dynenv$, and $k$. Otherwise, invoke the auxiliary function $\invoke$ on $\mlvar{operator}$, $\mlvar{arguments}$, $\dynenv$, and $k$.
    +
    To invoke the continuation $\functioncalloperandform(\mlvar{operator},\mlvar{operand-forms},\mlvar{arguments},\lexenv,\dynenv,k)$ on $\outcome$, do the following:
    +
    If $\outcome$ is an abrupt completion reason, then invoke $k$ on $\outcome$. Otherwise, let $\mlvar{augmented-arguments}$ be the result of appending the primary value of $\outcome$ or all the values of $\outcome$ to $\mlvar{arguments}$. Invoke the auxiliary function $\evaloperandforms$ on $\mlvar{operator}$, $\mlvar{operand-forms}$, $\mlvar{augmented-arguments}$, $\lexenv$, $\dynenv$, and $k$.
    +
    To invoke the auxiliary function $\invoke$ on $\mlvar{function}$, $\mlvar{arguments}$, $\dynenv$, and $k$, do the following:
    +
    If $\mlvar{function}$ is a primitive function, then invoke $k$ on the outcome of the invocation of the JavaScript function implementing $\mlvar{function}$ on $\mlvar{arguments}$. If $\mlvar{function}$ is a closure, then invoke the auxiliary function $\evalserialforms$ on the body of the lambda abstraction recorded by the closure, the lexical environment recorded by the closure or an extension thereof, $\dynenv$ or an extension thereof, and $k$.
    + +
    To evaluate ($\mlvar{macro-operator}$ $\mlvar{macro-operands}$) with respect to $\lexenv$, $\dynenv$, and $k$, do the following:
    +
    Let $\mlvar{macro}$ be the macro named by $\mlvar{macro-operator}$. Invoke the auxiliary function $\invoke$ on $\mlvar{macro}$, $\mlvar{macro-operands}$, $\dynenv$, and a $\macro$ continuation capturing $\lexenv$, $\dynenv$, and $k$.
    +
    To invoke the continuation $\macro(\lexenv,\dynenv,k)$ on $\outcome$, do the following:
    +
    If $\outcome$ is an abrupt completion reason, then invoke $k$ on $\outcome$. Otherwise, evaluate the primary value of $\outcome$ with respect to $\lexenv$, $\dynenv$, and $k$.
    +
    diff --git a/system-files/TUTORIAL b/system-files/TUTORIAL index b514db7..324a0e6 100644 --- a/system-files/TUTORIAL +++ b/system-files/TUTORIAL @@ -38,16 +38,16 @@
    > (not #t)
    #f

    > (not #f)
    #t
    (and $\metavar{test-forms}$)
    -
    The macro returns #t if all its arguments are #t and #f otherwise. The exact behavior of the macro is as follows: The macro evaluates the test-forms in sequence from left to right. If a test-form evaluates to an object that is not a boolean, then the following test-forms are not evaluated and the evaluation of the macro call completes abruptly with a reason of type error. If a test-form evaluates to #f, then the following test-forms are not evaluated and the macro call evaluates to #f. If all test-forms evaluate to #t, then the macro call evaluates to #t. Note that the previous condition is automatically satisfied if there are no test-forms.
    +
    The macro returns #t if all its arguments are #t and #f otherwise. The exact behavior of the macro is as follows: The macro evaluates the test-forms in sequence from left to right. If a test-form evaluates to an object that is not a boolean, then the following test-forms are not evaluated and the evaluation of the macro call completes abruptly for a reason of type error. If a test-form evaluates to #f, then the following test-forms are not evaluated and the macro call evaluates to #f. If all test-forms evaluate to #t, then the macro call evaluates to #t. Note that the previous condition is automatically satisfied if there are no test-forms.
    > (and)
    #t

    > (and #t)
    #t

    > (and #f)
    #f

    > (and #t #t)
    #t

    > (and #t #f)
    #f

    > (and #f #t)
    #f

    > (and #f #f)
    #f
    (or $\metavar{test-forms}$)
    -
    The macro returns #f if all its arguments are #f and #t otherwise. The exact behavior of the macro is as follows: The macro evaluates the test-forms in sequence from left to right. If a test-form evaluates to an object that is not a boolean, then the following test-forms are not evaluated and the evaluation of the macro call completes abruptly with a reason of type error. If a test-form evaluates to #t, then the following test-forms are not evaluated and the macro call evaluates to #t. If all test-forms evaluate to #f, then the macro call evaluates to #f. Note that the previous condition is automatically satisfied if there are no test-forms.
    +
    The macro returns #f if all its arguments are #f and #t otherwise. The exact behavior of the macro is as follows: The macro evaluates the test-forms in sequence from left to right. If a test-form evaluates to an object that is not a boolean, then the following test-forms are not evaluated and the evaluation of the macro call completes abruptly for a reason of type error. If a test-form evaluates to #t, then the following test-forms are not evaluated and the macro call evaluates to #t. If all test-forms evaluate to #f, then the macro call evaluates to #f. Note that the previous condition is automatically satisfied if there are no test-forms.
    > (or)
    #f

    > (or #t)
    #t

    > (or #f)
    #f

    > (or #t #t)
    #t

    > (or #t #f)
    #t

    > (or #f #t)
    #t

    > (or #f #f)
    #f

    When we say that a macro does this and that, what we really mean is that the expansion of the macro does this and that. In the case of the macros and and or, it is their expansions that evaluate the test-forms in sequence from left to right, etc.

    -

    The macros and and or stop evaluating their operands as soon as they can determine that the result of the macro call is definitively true or definitively false. This short-circuiting behavior is possible only because and and or are macros. When a function call is evaluated, all the operands are always evaluated (unless the evaluation of the operator or the evaluation of one of the operands other than the last one completes abruptly or does not complete).

    +

    The macros and and or stop evaluating their operands as soon as they can determine that the result of the macro call is definitively true or definitively false. This short-circuiting behavior is possible only because and and or are macros. When a function call is evaluated, all the operand-forms are always evaluated (unless the evaluation of the operator-form completes abruptly or does not complete, the primary value of the operator-form is not a function, or the evaluation of one of the operand-forms other than the last one completes abruptly or does not complete).

    Here are two expansions illustrating the implementations of the macros and and or:

    -

    Let $n_\mathrm{init}$ be the the argument of fib-iter and $n$, $a$, and $b$ be the arguments of the invocation of fib-iter-internal under consideration. When processing the invocation of fib-iter-internal from fib-iter, $n=n_\mathrm{init}$, $a=F_0$, and $b=F_1$. If $n_\mathrm{init}=0$, then fib-iter-internal returns $a=F_0$. Otherwise, if $n_\mathrm{init}=1$, then fib-iter-internal returns $b=F_1$. Otherwise, fib-iter-internal invokes itself recursively. On each recursive invocation of fib-iter-internal, $n$ is decremented by $1$, $a$ is replaced by the next Fibonacci number in the sequence $F_0,F_1,F_2,\ldots$, and $b$ is replaced by the next Fibonacci number in the sequence $F_1,F_2,F_3,\ldots$ When processing the $(n_\mathrm{init}-1)$-th recursive invocation of fib-iter-internal, $n=n_\mathrm{init}-(n_\mathrm{init}-1)=1$, $a=F_{0+n_\mathrm{init}-1}=F_{n_\mathrm{init}-1}$, and $b=F_{1+n_\mathrm{init}-1}=F_{n_\mathrm{init}}$ and fib-iter-internal returns $b=F_{n_\mathrm{init}}$.

    +

    Let $n_\textrm{init}$ be the the argument of fib-iter and $n$, $a$, and $b$ be the arguments of the invocation of fib-iter-internal under consideration. When processing the invocation of fib-iter-internal from fib-iter, $n=n_\textrm{init}$, $a=F_0$, and $b=F_1$. If $n_\textrm{init}=0$, then fib-iter-internal returns $a=F_0$. Otherwise, if $n_\textrm{init}=1$, then fib-iter-internal returns $b=F_1$. Otherwise, fib-iter-internal invokes itself recursively. On each recursive invocation of fib-iter-internal, $n$ is decremented by $1$, $a$ is replaced by the next Fibonacci number in the sequence $F_0,F_1,F_2,\ldots$, and $b$ is replaced by the next Fibonacci number in the sequence $F_1,F_2,F_3,\ldots$ When processing the $(n_\textrm{init}-1)$-th recursive invocation of fib-iter-internal, $n=n_\textrm{init}-(n_\textrm{init}-1)=1$, $a=F_{0+n_\textrm{init}-1}=F_{n_\textrm{init}-1}$, and $b=F_{1+n_\textrm{init}-1}=F_{n_\textrm{init}}$ and fib-iter-internal returns $b=F_{n_\textrm{init}}$.

    Here is an invocation trace of the evaluation of the form (fib-iter 6):

    The primary value of a form whose evaluation completed normally is defined as follows: If the result consists of one or more objects, then the primary value of the form is the first object. Otherwise, the primary value of the form is #v.

    -

    The abrupt completion of an evaluation has an associated reason, which has a type and carries a payload. An abrupt completion caused by an error has an associated reason of type error, which carries a payload consisting of an object of type string describing the error. An abrupt completion caused by a nonlocal exit has an associated reason of type exit, which carries a payload described in the reference manual.

    +

    The abrupt completion of an evaluation has an associated reason, which has a type and carries a payload. An abrupt completion caused by an error has an associated reason of type error, which carries a payload consisting of a string describing the error. An abrupt completion caused by a nonlocal exit has an associated reason of type nonlocal-exit, which carries a payload consisting of a variable (the exit tag identifying the exit point) and a sequence of zero or more objects (the values to propagate to the exit point).

    Forms submitted to the evaluator through a listener buffer, through the Evaluate Form command, or through the Load Buffer command are called top-level forms. A consequence of the evaluation rules stated later in this section is that the evaluation of a top-level form usually entails the evaluation of other non-top-level forms.

    Execution of EVLambda code is achieved through interpretation or compilation.

    An interpreter for a language $X$ is a program capable of directly executing code written in language $X$. Language $X$ is called the source language of the interpreter. A compiler for a language $X$ is a program capable of translating code written in language $X$ into code written in a language $Y$. Language $X$ is called the source language of the compiler and language $Y$ is called the target language of the compiler. Code handed to an interpreter or compiler is called source code. A file containing source code is called a source file. Code produced by a compiler is called compiled code. A file containing compiled code is called a compiled file.

    @@ -173,7 +173,7 @@

    A consequence of the lookup rules is that a binding in the value/function namespace of the current lexical/dynamic environment will effectively shadow a binding for the same variable in the value/function namespace of the global environment.

    A global variable is a binding between a variable and an object (of any type) in the value namespace of the global environment, or the name or value of such binding. A global function is a binding between a variable and a function other than a macro in the function namespace of the global environment, or the name or value of such binding. A global macro is a binding between a variable and a macro in the function namespace of the global environment, or the name or value of such binding. Global variables, global functions, and global macros are created and altered using language constructs called global definitions.

    A local variable is a binding between a variable and an object (of any type) in the value namespace of a lexical environment, or the name or value of such binding. A local function is a binding between a variable and a function other than a macro in the function namespace of a lexical environment, or the name or value of such binding. A local macro is a binding between a variable and a macro in the function namespace of a lexical environment, or the name or value of such binding. A dynamic variable is a binding between a variable and an object (of any type) in the value namespace of a dynamic environment, or the name or value of such binding. Local variables, local functions, local macros, and dynamic variables are created (but not altered) using language constructs called binding constructs.

    -

    When a form is submitted to the evaluator, the evaluator analyzes the form to determine how to evaluate it. If the form is the empty list, then the evaluation completes abruptly with a reason of type error. Otherwise, if the form is neither a variable nor a cons, then the result of the evaluation is the form itself. (Objects that are neither the empty list, nor a variable, nor a cons are said to be self-evaluating.) Otherwise, if the form is a variable $\var$, then the variable is treated as an abbreviation for either (vref $\var$) or (fref $\var$), depending on the context of its occurrence. Otherwise, the form is necessarily a cons and the evaluation completes abruptly with a reason of type error unless the form matches one of the following patterns:

    +

    When a form is submitted to the evaluator, the evaluator analyzes the form to determine how to evaluate it. If the form is the empty list, then the evaluation completes abruptly for a reason of type error. Otherwise, if the form is neither a variable nor a cons, then the result of the evaluation is the form itself. (Objects that are neither the empty list, nor a variable, nor a cons are said to be self-evaluating.) Otherwise, if the form is a variable $\var$, then the variable is treated as an abbreviation for either (vref $\var$) or (fref $\var$), depending on the context of its occurrence. Otherwise, the form is necessarily a cons and the evaluation completes abruptly for a reason of type error unless the form matches one of the following patterns:

    1. (quote $\metavar{literal}$)
    2. (progn $\metavar{serial-forms}$)
    3. @@ -188,8 +188,13 @@
    4. (fset! $\metavar{variable}$ $\metavar{value-form}$)
    5. (dref $\metavar{variable}$)
    6. (dset! $\metavar{variable}$ $\metavar{value-form}$)
    7. +
    8. (block $\metavar{block-name}$ $\metavar{serial-forms}$)
    9. +
    10. (return-from $\metavar{block-name}$ $\metavar{values-form}$)
    11. +
    12. (catch $\metavar{exit-tag-form}$ $\metavar{serial-forms}$)
    13. +
    14. (throw $\metavar{exit-tag-form}$ $\metavar{values-form}$)
    15. +
    16. (_handler-bind $\metavar{handler-form}$ $\metavar{serial-forms}$)
    17. +
    18. (unwind-protect $\metavar{protected-form}$ $\metavar{cleanup-forms}$)
    19. (_for-each $\metavar{function-form}$ $\metavar{list-form}$)
    20. -
    21. (_catch-errors $\metavar{try-form}$)
    22. (apply $\metavar{operator-form}$ $\metavar{operand-forms}$)
    23. (multiple-value-call $\metavar{operator-form}$ $\metavar{operand-forms}$)
    24. (multiple-value-apply $\metavar{operator-form}$ $\metavar{operand-forms}$)
    25. @@ -207,9 +212,14 @@
    26. $\metavar{body}$ matches any sequence of zero or more objects
    27. $\metavar{variable}$ matches any variable
    28. $\metavar{value-form}$ matches any object
    29. +
    30. $\metavar{block-name}$ matches any variable
    31. +
    32. $\metavar{exit-tag-form}$ matches any object
    33. +
    34. $\metavar{values-form}$ matches any object
    35. +
    36. $\metavar{handler-form}$ matches any object
    37. +
    38. $\metavar{protected-form}$ matches any object
    39. +
    40. $\metavar{cleanup-forms}$ matches any sequence of zero or more objects
    41. $\metavar{function-form}$ matches any object
    42. $\metavar{list-form}$ matches any object
    43. -
    44. $\metavar{try-form}$ matches any object
    45. $\metavar{macro-operator}$ matches any variable naming a macro according to the lookup rule used by fref
    46. $\metavar{macro-operands}$ matches any sequence of zero or more objects
    47. $\metavar{operator-form}$ matches any object
    48. @@ -217,14 +227,14 @@

      By way of example, a form matches the first pattern if and only if it is a list of two elements whose first element is the variable quote.

      The patterns are tried in sequence and the first matching pattern wins.

      -

      A form matching one of the first eighteen patterns is called a special form and the variables quote, progn, if, _vlambda, _mlambda, _flambda, _dlambda, vref, vset!, fref, fset!, dref, dset!, _for-each, _catch-all, apply, multiple-value-call, and multiple-value-apply are called special operators.

      -

      Special forms matching patterns 4 (_vlambda), 5 (_mlambda), 6 (_flambda), and 7 (_dlambda) are called lambda abstractions. Lambda abstractions are the fundamental binding constructs from which all other binding constructs are built. Forms consisting of a variable and special forms matching patterns 8 (vref), 10 (fref), and 12 (dref) are called variable references. Special forms matching patterns 9 (vset!), 11 (fset!), and 13 (dset!) are called variable assignments. Forms matching pattern 19 are called macro calls. Forms matching pattern 20 are called plain function calls.

      +

      A form matching one of the first twenty-three patterns is called a special form and the variables quote, progn, if, _vlambda, _mlambda, _flambda, _dlambda, vref, vset!, fref, fset!, dref, dset!, block, return-from, catch, throw, _handler-bind, unwind-protect, _for-each, apply, multiple-value-call, and multiple-value-apply are called special operators.

      +

      Special forms matching patterns 4 (_vlambda), 5 (_mlambda), 6 (_flambda), and 7 (_dlambda) are called lambda abstractions. Lambda abstractions are the fundamental binding constructs from which all other binding constructs are built. Forms consisting of a variable and special forms matching patterns 8 (vref), 10 (fref), and 12 (dref) are called variable references. Special forms matching patterns 9 (vset!), 11 (fset!), and 13 (dset!) are called variable assignments. Forms matching pattern 24 are called macro calls. Forms matching pattern 25 are called plain function calls.

      The rule regarding forms consisting of a variable is the following: If a variable $\var$ occurs in operator position, then the variable is treated as an abbreviation for (fref $\var$) and the function namespace is used. Otherwise, the variable is treated as an abbreviation for (vref $\var$) and the value namespace is used. For example, the plain function call (f x) would be treated as an abbreviation for ((fref f) (vref x)). The full forms (fref $\var$) and (vref $\var$) can always be used to force the use of a specific namespace.

      -

      As we will see below, the evaluation of a form containing subforms entails the evaluation of some or all of the subforms. When a subform is evaluated, the following rules apply:

      +

      As we will see below, the evaluation of a form entails the evaluation of some or all of the forms directly contained inside the form. When a direct subform is evaluated, the following rules apply:

        -
      • The subform is evaluated with respect to the same lexical and dynamic environments as the containing form. (But see below how closures are invoked.)
      • -
      • Generally, if the evaluation of the subform completes abruptly for any reason, then the evaluation of the containing form also completes abruptly for the same reason. The only form that can behave differently is the special form _catch-errors.
      • -
      • If the evaluation of the subform does not complete, then the evaluation of the containing form does not complete either.
      • +
      • The direct subform is evaluated with respect to the same lexical and dynamic environments as the containing form. (But see below how closures are invoked.)
      • +
      • Generally, if the evaluation of the direct subform completes abruptly for any reason, then the evaluation of the containing form immediately completes abruptly for the same reason. The only forms that can behave differently are the special forms block, catch, _handler-bind, and unwind-protect, which are described in the reference manual.
      • +
      • If the evaluation of the direct subform does not complete, then the evaluation of the containing form does not complete either.

      Special forms, macro calls, and plain function calls are evaluated as follows:

      @@ -233,36 +243,41 @@
      (progn $\metavar{serial-forms}$)
      The serial-forms are evaluated in sequence from left to right. If there is at least one serial-form, then the progn-form evaluates to the values of the last serial-form. Otherwise, the progn-form evaluates to #v.
      (if $\metavar{test-form}$ $\metavar{then-form}$ $\metavar{else-form}$)
      -
      The test-form is evaluated. Let $\primval$ be the primary value of the test-form. If $\primval$ is not a boolean, then the evaluation of the if-form completes abruptly with a reason of type error. If $\primval$ is the boolean #t, then the then-form is evaluated and the if-form evaluates to the values of the then-form. If $\primval$ is the boolean #f, then the else-form is evaluated and the if-form evaluates to the values of the else-form.
      +
      The test-form is evaluated. Let $\mlvar{test}$ be the primary value of the test-form. If $\mlvar{test}$ is not a boolean, then the evaluation of the if-form completes abruptly for a reason of type error. If $\mlvar{test}$ is the boolean #t, then the then-form is evaluated and the if-form evaluates to the values of the then-form. If $\mlvar{test}$ is the boolean #f, then the else-form is evaluated and the if-form evaluates to the values of the else-form.
      (_vlambda $\metavar{parameter-list}$ $\metavar{body}$)
      (_mlambda $\metavar{parameter-list}$ $\metavar{body}$)
      (_flambda $\metavar{parameter-list}$ $\metavar{body}$)
      (_dlambda $\metavar{parameter-list}$ $\metavar{body}$)
      A lambda abstraction evaluates to a closure recording the following two pieces of information: the lambda abstraction and the current lexical environment (which is said to be captured by the closure). A closure resulting from the evaluation of an _mlambda-form is tagged as being a macro.
      (vref $\metavar{variable}$)
      -
      If there exists a binding for the variable in the value namespace of the current lexical environment, then the vref-form evaluates to the value of that binding. Otherwise, if there exists a binding for the variable in the value namespace of the global environment, then the vref-form evaluates to the value of that binding. Otherwise, the evaluation of the vref-form completes abruptly with a reason of type error.
      +
      If there exists a binding for the variable in the value namespace of the current lexical environment, then the vref-form evaluates to the value of that binding. Otherwise, if there exists a binding for the variable in the value namespace of the global environment, then the vref-form evaluates to the value of that binding. Otherwise, the evaluation of the vref-form completes abruptly for a reason of type error.
      (vset! $\metavar{variable}$ $\metavar{value-form}$)
      -
      The value-form is evaluated. Let $\primval$ be the primary value of the value-form. If there exists a binding for the variable in the value namespace of the current lexical environment, then the value of that binding is replaced by $\primval$. Otherwise, if there exists a binding for the variable in the value namespace of the global environment, then the value of that binding is replaced by $\primval$. Otherwise, a new binding between the variable and $\primval$ is added to the value namespace of the global environment. In all three cases, the vset-form evaluates to $\primval$.
      +
      The value-form is evaluated. Let $\mlvar{value}$ be the primary value of the value-form. If there exists a binding for the variable in the value namespace of the current lexical environment, then the value of that binding is replaced by $\mlvar{value}$. Otherwise, if there exists a binding for the variable in the value namespace of the global environment, then the value of that binding is replaced by $\mlvar{value}$. Otherwise, a new binding between the variable and $\mlvar{value}$ is added to the value namespace of the global environment. In all three cases, the vset-form evaluates to $\mlvar{value}$.
      (fref $\metavar{variable}$)
      -
      If there exists a binding for the variable in the function namespace of the current lexical environment, then the fref-form evaluates to the value of that binding. Otherwise, if there exists a binding for the variable in the function namespace of the global environment, then the fref-form evaluates to the value of that binding. Otherwise, the evaluation of the fref-form completes abruptly with a reason of type error.
      +
      If there exists a binding for the variable in the function namespace of the current lexical environment, then the fref-form evaluates to the value of that binding. Otherwise, if there exists a binding for the variable in the function namespace of the global environment, then the fref-form evaluates to the value of that binding. Otherwise, the evaluation of the fref-form completes abruptly for a reason of type error.
      (fset! $\metavar{variable}$ $\metavar{value-form}$)
      -
      The value-form is evaluated. Let $\primval$ be the primary value of the value-form. If there exists a binding for the variable in the function namespace of the current lexical environment, then the value of that binding is replaced by $\primval$. Otherwise, if there exists a binding for the variable in the function namespace of the global environment, then the value of that binding is replaced by $\primval$. Otherwise, a new binding between the variable and $\primval$ is added to the function namespace of the global environment. In all three cases, the fset-form evaluates to $\primval$.
      +
      The value-form is evaluated. Let $\mlvar{value}$ be the primary value of the value-form. If there exists a binding for the variable in the function namespace of the current lexical environment, then the value of that binding is replaced by $\mlvar{value}$. Otherwise, if there exists a binding for the variable in the function namespace of the global environment, then the value of that binding is replaced by $\mlvar{value}$. Otherwise, a new binding between the variable and $\mlvar{value}$ is added to the function namespace of the global environment. In all three cases, the fset-form evaluates to $\mlvar{value}$.
      (dref $\metavar{variable}$)
      -
      If there exists a binding for the variable in the value namespace of the current dynamic environment, then the dref-form evaluates to the value of that binding. Otherwise, if there exists a binding for the variable in the value namespace of the global environment, then the dref-form evaluates to the value of that binding. Otherwise, the evaluation of the dref-form completes abruptly with a reason of type error.
      +
      If there exists a binding for the variable in the value namespace of the current dynamic environment, then the dref-form evaluates to the value of that binding. Otherwise, if there exists a binding for the variable in the value namespace of the global environment, then the dref-form evaluates to the value of that binding. Otherwise, the evaluation of the dref-form completes abruptly for a reason of type error.
      (dset! $\metavar{variable}$ $\metavar{value-form}$)
      -
      The value-form is evaluated. Let $\primval$ be the primary value of the value-form. If there exists a binding for the variable in the value namespace of the current dynamic environment, then the value of that binding is replaced by $\primval$. Otherwise, if there exists a binding for the variable in the value namespace of the global environment, then the value of that binding is replaced by $\primval$. Otherwise, a new binding between the variable and $\primval$ is added to the value namespace of the global environment. In all three cases, the dset-form evaluates to $\primval$.
      +
      The value-form is evaluated. Let $\mlvar{value}$ be the primary value of the value-form. If there exists a binding for the variable in the value namespace of the current dynamic environment, then the value of that binding is replaced by $\mlvar{value}$. Otherwise, if there exists a binding for the variable in the value namespace of the global environment, then the value of that binding is replaced by $\mlvar{value}$. Otherwise, a new binding between the variable and $\mlvar{value}$ is added to the value namespace of the global environment. In all three cases, the dset-form evaluates to $\mlvar{value}$.
      +
      (block $\metavar{block-name}$ $\metavar{serial-forms}$)
      +
      (return-from $\metavar{block-name}$ $\metavar{values-form}$)
      +
      (catch $\metavar{exit-tag-form}$ $\metavar{serial-forms}$)
      +
      (throw $\metavar{exit-tag-form}$ $\metavar{values-form}$)
      +
      (_handler-bind $\metavar{handler-form}$ $\metavar{serial-forms}$)
      +
      (unwind-protect $\metavar{protected-form}$ $\metavar{cleanup-forms}$)
      +
      These special forms, which implement advanced control structures, are described in the reference manual.
      (_for-each $\metavar{function-form}$ $\metavar{list-form}$)
      -
      This special form is described in the reference manual.
      -
      (_catch-errors $\metavar{try-form}$)
      -
      This special form is described in the reference manual.
      +
      This special form, which is a hack only needed and implemented by some of the interpreters, is described in the reference manual.
      (apply $\metavar{operator-form}$ $\metavar{operand-forms}$)
      (multiple-value-call $\metavar{operator-form}$ $\metavar{operand-forms}$)
      (multiple-value-apply $\metavar{operator-form}$ $\metavar{operand-forms}$)
      -
      These special forms are variants of the plain function call described below. They are described in the reference manual.
      +
      These special forms, which are variants of the plain function call, are described in the reference manual.
      ($\metavar{macro-operator}$ $\metavar{macro-operands}$)
      Following the definition of a macro call, the macro-operator matches a variable naming a macro according to the lookup rule used by fref. That macro is invoked on the unevaluated macro-operands. If the invocation completes abruptly for any reason, then the evaluation of the macro call also completes abruptly for the same reason. Otherwise, if the invocation does not complete, then the evaluation of the macro call does not complete either. Otherwise, the primary value of the invocation, which is called the expansion of the macro call, is evaluated with respect to the current lexical and dynamic environments. If the evaluation of the expansion completes abruptly for any reason, then the evaluation of the macro call also completes abruptly for the same reason. Otherwise, if the evaluation of the expansion does not complete, then the evaluation of the macro call does not complete either. Otherwise, the macro call evaluates to the values of the expansion.
      ($\metavar{operator-form}$ $\metavar{operand-forms}$)
      -
      The operator-form and the operand-forms are evaluated in sequence from left to right. If the primary value of the operator-form is not a function, then the evaluation of the plain function call completes abruptly with a reason of type error. Otherwise, the primary value of the operator-form is invoked on the primary values of the operand-forms. If the invocation completes abruptly for any reason, then the evaluation of the plain function call also completes abruptly for the same reason. Otherwise, if the invocation does not complete, then the evaluation of the plain function call does not complete either. Otherwise, the plain function call evaluates to the values of the invocation.
      +
      The operator-form is evaluated. Let $\mlvar{operator}$ be the primary value of the operator-form. If $\mlvar{operator}$ is not a function, then the evaluation of the plain function call completes abruptly for a reason of type error. Otherwise, the operand-forms are evaluated in sequence from left to right and $\mlvar{operator}$ is invoked on the primary values of the operand-forms. If the invocation completes abruptly for any reason, then the evaluation of the plain function call also completes abruptly for the same reason. Otherwise, if the invocation does not complete, then the evaluation of the plain function call does not complete either. Otherwise, the plain function call evaluates to the values of the invocation.

      Invoking a function is what causes the function to compute the output corresponding to an input. The input of an invocation consists of zero or more objects—object references actually—called the arguments of the invocation. (The function is said to be invoked on the arguments and the arguments are said to be passed to the function.) The invocation of a function has three possible outcomes:

        @@ -277,21 +292,21 @@
        Let us assume that, as is the case with all the evaluators currently available, the primitive function is implemented by a JavaScript function accepting (an encoding of) the arguments of the invocation of the primitive function and returning (an encoding of) the values of the invocation of the primitive function. The JavaScript function is invoked on the arguments. If the invocation of the JavaScript function completes abruptly for any reason, then the invocation of the primitive function also completes abruptly for the same reason. Otherwise, if the invocation of the JavaScript function does not complete, then the invocation of the primitive function does not complete either. Otherwise, the primitive function returns the values returned by the JavaScript function.

        A closure is invoked as follows:

        -

        If the number of variables in the parameter list of the lambda abstraction recorded by the closure and the number of arguments are different, then the invocation completes abruptly with a reason of type error. (As we will see in the reference manual, it is actually possible to create closures accepting a variable number of arguments.) Otherwise, let $\var_1,\ldots,\var_n$ be the variables composing the parameter list of the lambda abstraction recorded by the closure, $\arg_1,\ldots,\arg_n$ be the arguments, and $\lexenv$ and $\dynenv$ be the following environments:

        +

        If the number of variables in the parameter list of the lambda abstraction recorded by the closure and the number of arguments are different, then the invocation completes abruptly for a reason of type error. (As we will see in the reference manual, it is actually possible to create closures accepting a variable number of arguments.) Otherwise, let $\var_1,\ldots,\var_n$ be the variables composing the parameter list of the lambda abstraction recorded by the closure, $\arg_1,\ldots,\arg_n$ be the arguments, and $\lexenv$ and $\dynenv$ be the following environments:

        • If the closure results from the evaluation of a _vlambda-form or an _mlambda-form, then $\lexenv$ is the environment extending the lexical environment recorded by the closure to bind, in the value namespace, the variable $\var_i$ to the argument $\arg_i$ (for all $i$ from $1$ to $n$) and $\dynenv$ is the current dynamic environment.
        • If the closure results from the evaluation of an _flambda-form, then $\lexenv$ is the environment extending the lexical environment recorded by the closure to bind, in the function namespace, the variable $\var_i$ to the argument $\arg_i$ (for all $i$ from $1$ to $n$) and $\dynenv$ is the current dynamic environment.
        • If the closure results from the evaluation of a _dlambda-form, then $\lexenv$ is the lexical environment recorded by the closure and $\dynenv$ is the environment extending the current dynamic environment to bind, in the value namespace, the variable $\var_i$ to the argument $\arg_i$ (for all $i$ from $1$ to $n$).
        -

        The objects composing the body of the lambda abstraction recorded by the closure are evaluated with respect to $\lexenv$ and $\dynenv$ as if they were the serial-forms of a progn-form. If the evaluation of the progn-form completes abruptly for any reason, then the invocation also completes abruptly for the same reason. Otherwise, if the evaluation of the progn-form does not complete, then the invocation does not complete either. Otherwise, the closure returns the values of the progn-form.

        +

        The objects composing the body of the lambda abstraction recorded by the closure are evaluated with respect to $\lexenv$ and $\dynenv$ as if they were the serial-forms of a progn-form. (The serial-forms are said to belong to an implicit progn-form.) If the evaluation of the progn-form completes abruptly for any reason, then the invocation also completes abruptly for the same reason. Otherwise, if the evaluation of the progn-form does not complete, then the invocation does not complete either. Otherwise, the closure returns the values of the progn-form.

        -

        When the evaluation of a top-level form completes abruptly for a reason of type exit, that reason is immediately converted into a reason of type error. The three possible outcomes of the evaluation of a top-level form are thus the following:

        +

        As we will see in the reference manual, the evaluation of a top-level form cannot complete abruptly for a reason of type nonlocal-exit. The three possible outcomes of the evaluation of a top-level form are thus the following:

        • The evaluation of the top-level form completes normally.
        • The evaluation of the top-level form completes abruptly for a reason of type error.
        • The evaluation of the top-level form does not complete.
        -

        The special operators _vlambda, _mlambda, _flambda, and _dlambda have an underscore at the beginning of their names to distinguish them from the similarly named macros vlambda, mlambda, flambda, and dlambda. The purpose of those macros is to facilitate the creation of closures accepting a variable number of arguments. The special operator _for-each has an underscore at the beginning of its name because it is a hack only needed and implemented by some of the interpreters. The special operator _catch-errors has an underscore at the beginning of its name because it will eventually be replaced by another special operator.

        +

        The special operators _vlambda, _mlambda, _flambda, and _dlambda have an underscore at the beginning of their names to distinguish them from the similarly named macros vlambda, mlambda, flambda, and dlambda. The purpose of those macros is to facilitate the creation of closures accepting a variable number of arguments. The special operator _handler-bind has an underscore at the beginning of its name to distinguish it from the similarly named macro handler-bind. The special operator _for-each has an underscore at the beginning of its name because it is a hack only needed and implemented by some of the interpreters.

        The evaluator uses a data structure called the control stack to coordinate its activities. Each time a top-level form is submitted to the evaluator, a new control stack is created that will be used throughout the evaluation of the form. The same control stack is used to evaluate the top-level form and all non-top-level forms whose evaluations are entailed by the evaluation of the top-level form.

        An evaluation/invocation that completes normally produces a result/output consisting of zero or more objects. The production of that result/output, which only occurs if the evaluation/invocation completes normally, is the primary effect of the evaluation/invocation. In addition to or in place of its primary effect, an evaluation/invocation can also have secondary effects called side effects. Examples of side effects are:

          @@ -324,7 +339,7 @@
          • The prompt is the greater-than sign printed at the beginning of a line to inform you that the listener buffer is waiting for a form to be typed in.
          • If you press the Return or Enter key when (1) the cursor is not at the very end of the buffer or (2) the form is missing or incomplete, then a newline is simply inserted into the buffer and no evaluation takes place.
          • -
          • If the evaluation completes abruptly, then the reason is necessarily of type error and its payload (an object of type string describing the error) is printed in place of the printable representations of the (nonexisting) resulting values.
          • +
          • If the evaluation completes abruptly, then the reason of the abrupt completion is necessarily of type error and the payload of the reason (a string describing the error) is printed in place of the printable representations of the (nonexisting) resulting values.
          • If the evaluation does not complete, then you must abort the evaluation or restart the evaluator in order to get a new prompt.

          We will now illustrate some of the concepts introduced in the section Programming Language by providing a commented transcript of a sequence of evaluations conducted in a listener buffer. If you want to reproduce the evaluations, be sure to start with a fresh Trampoline++ evaluator. To get a fresh Trampoline++ evaluator, restart the evaluator (using the Restart Evaluator… command from the Eval menu) with Trampoline++ selected as the evaluator name.

          @@ -360,7 +375,7 @@
          > (car '(1 2 3))⏎
          1

          The evaluation produces a result consisting of the first element of the list (1 2 3). Because lists are not self-evaluating, quoting the list is necessary.

          > (car (1 2 3))⏎
          ERROR: The operator-form does not evaluate to a function.
          -

          The evaluation completes abruptly with a reason of type error if the list is not quoted. The explanation for this behavior is as follows: The evaluator treats the list (1 2 3) as a plain function call and the operator-form, the number 1, does not evaluate to a function.

          +

          The evaluation completes abruptly for a reason of type error if the list is not quoted. The explanation for this behavior is as follows: The evaluator treats the list (1 2 3) as a plain function call and the operator-form, the number 1, does not evaluate to a function.

          > (cdr '(1 2 3))⏎
          (2 3)

          The evaluation produces a result consisting of the sublist of the list (1 2 3) obtained by omitting its first element.

          > (car (cdr '(1 2 3)))⏎
          2
          @@ -372,9 +387,9 @@
          > (cdr (cdr (cdr '(1 2 3))))⏎
          ()

          The evaluation produces a result consisting of the sublist of the list (1 2 3) obtained by omitting its first three elements.

          > (car (cdr (cdr (cdr '(1 2 3)))))⏎
          ERROR: The 1st argument is not of type EVLCons.
          -

          The evaluation completes abruptly with a reason of type error because the empty list is not a cons.

          +

          The evaluation completes abruptly for a reason of type error because the empty list is not a cons.

          > (disk-area 2)⏎
          ERROR: The variable 'disk-area' is unbound in the FUNCTION namespace.
          -

          The evaluation completes abruptly with a reason of type error because the global function disk-area is undefined.

          +

          The evaluation completes abruptly for a reason of type error because the global function disk-area is undefined.

          > (fdef disk-area (r) (* 3.14 r r))⏎
          disk-area

          The evaluation produces a result consisting of the variable disk-area. More importantly, the evaluation has the side effect of defining the global function disk-area. In its intended usage, the function accepts the radius of a disk and returns the area of the disk computed using 3.14 as the value of pi. When the function is invoked, its body is evaluated with respect to a lexical environment binding, in the value namespace, the variable r to the argument of the invocation (that is, the radius of the disk).

          > (disk-area 2)⏎
          12.56
          @@ -386,7 +401,7 @@
          > (fdef disk-area (r) (* *pi* r r))⏎
          disk-area

          The evaluation has the side effect of redefining the global function disk-area to compute the area of the disk using the value of the global variable *pi* as the value of pi. It is customary for a global or dynamic variable to have a name starting and ending with an asterisk.

          > (disk-area 2)⏎
          ERROR: The variable '*pi*' is unbound in the VALUE namespace.
          -

          The evaluation completes abruptly with a reason of type error because the global variable *pi* is undefined.

          +

          The evaluation completes abruptly for a reason of type error because the global variable *pi* is undefined.

          > (vdef *pi* 3.141593)⏎
          *pi*

          The evaluation produces a result consisting of the variable *pi*. More importantly, the evaluation has the side effect of defining the global variable *pi*.

          > *pi*⏎
          3.141593
          @@ -443,12 +458,12 @@
        • Otherwise, if the first nonblank character before the cursor position is the last character of a top-level form, then that form is selected for evaluation.
        • Otherwise, no form is selected for evaluation and no evaluation takes place.
        -

        If the evaluation of the top-level form completes normally, then the printable representations of the resulting values are printed in the minibuffer, separated by a comma. If the evaluation of the top-level form completes abruptly, then the reason is necessarily of type error and its payload is printed in the minibuffer. If the evaluation of the top-level form does not complete, then no new evaluation is possible until the evaluation is aborted or the evaluator is restarted.

        +

        If the evaluation of the top-level form completes normally, then the printable representations of the resulting values are printed in the minibuffer, separated by a comma. If the evaluation of the top-level form completes abruptly, then the reason of the abrupt completion is necessarily of type error and the payload of the reason is printed in the minibuffer. If the evaluation of the top-level form does not complete, then no new evaluation is possible until the evaluation is aborted or the evaluator is restarted.

        Load Buffer

        Evaluates the top-level forms contained inside the selected file buffer.

        This command is only available when the selected window displays the contents of an EVLambda source file.

        The top-level forms contained inside the selected file buffer are evaluated as if they were part of a progn-form.

        -

        If the evaluation of the progn-form completes normally, then the printable representations of the resulting values are printed in the minibuffer, separated by a comma. If the evaluation of the progn-form completes abruptly, then the reason is necessarily of type error and its payload is printed in the minibuffer. If the evaluation of the progn-form does not complete, then no new evaluation is possible until the evaluation is aborted or the evaluator is restarted.

        +

        If the evaluation of the progn-form completes normally, then the printable representations of the resulting values are printed in the minibuffer, separated by a comma. If the evaluation of the progn-form completes abruptly, then the reason of the abrupt completion is necessarily of type error and the payload of the reason is printed in the minibuffer. If the evaluation of the progn-form does not complete, then no new evaluation is possible until the evaluation is aborted or the evaluator is restarted.

        Abort Evaluation

        Aborts the current evaluation.

        Restart Evaluator…

        diff --git a/system-files/all-caps.js b/system-files/all-caps.js index ce7cd38..a8a3fec 100644 --- a/system-files/all-caps.js +++ b/system-files/all-caps.js @@ -38,22 +38,17 @@ window.MathJax = { mlvar: ['\\textit{#1}', 1], metavar: ['\\langle\\textrm{#1}\\rangle', 1], metavarn: ['\\langle\\textrm{#1}_{#2}\\rangle', 2], - form: '\\mlvar{form}', var: '\\mlvar{var}', - arg: '\\mlvar{arg}', obj: '\\mlvar{obj}', - fun: '\\mlvar{fun}', + arg: '\\mlvar{arg}', env: '\\mlvar{env}', lexenv: '\\mlvar{lexenv}', dynenv: '\\mlvar{dynenv}', ns: '\\mlvar{ns}', - binding: '\\mlvar{binding}', vbind: '\\rightarrow_\\textrm{v}', vbinding: ['\\code{#1}\\vbind\\code{#2}', 2], fbind: '\\rightarrow_\\textrm{f}', fbinding: ['\\code{#1}\\fbind\\code{#2}', 2], - primval: '\\mlvar{primval}', - type: '\\mlvar{type}', object: '\\mlvar{object}', void: '\\mlvar{void}', boolean: '\\mlvar{boolean}', diff --git a/system-files/core.js b/system-files/core.js index 1c1bcf4..bc654d4 100644 --- a/system-files/core.js +++ b/system-files/core.js @@ -4416,7 +4416,7 @@ class EVLVoid extends EVLObject { } } -// the only object of type void +// the single object of type void EVLVoid.VOID = new EVLVoid(); function nullToVoid(x) { @@ -4441,9 +4441,9 @@ class EVLBoolean extends EVLObject { } } -// the only object of type boolean representing true +// the single object of type boolean representing true EVLBoolean.TRUE = new EVLBoolean(true); -// the only object of type boolean representing false +// the single object of type boolean representing false EVLBoolean.FALSE = new EVLBoolean(false); function evlBoolean(jsBoolean) { @@ -4788,7 +4788,7 @@ class EVLEmptyList extends EVLList { } } -// the only object of type empty-list +// the single object of type empty-list EVLEmptyList.NIL = new EVLEmptyList(); primitiveFunction('empty-list?', 1, 1, function(args) { diff --git a/system-files/mantle.evl b/system-files/mantle.evl index ed3d11c..527762c 100644 --- a/system-files/mantle.evl +++ b/system-files/mantle.evl @@ -737,7 +737,7 @@ Signaling and Handling Conditions (error <string>) (test-error (error "foo")) -(_catch-errors <form>) +(_catch-errors <form>*) (test #v (_catch-errors :no-error)) (test "Error" (_catch-errors (error "foo")))