<body>
<div class="preamble">
$\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}$
</div>
<h1>Reference Manual</h1>
<p>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.</p>
<tr>
<td class="lhs">$\metavar{special-form}$</td>
<td class="def">$\Coloneq$</td>
- <td class="rhs"><code>$\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}$</code></td>
+ <td class="rhs"><code>$\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}$</code></td>
</tr>
<tr>
<td class="lhs">$\metavar{quote-form}$</td>
<td class="rhs"><code>$\metavar{form}$</code></td>
</tr>
<tr>
- <td class="lhs">$\metavar{\_for-each-form}$</td>
+ <td class="lhs">$\metavar{block-form}$</td>
<td class="def">$\Coloneq$</td>
- <td class="rhs"><code>(_for-each $\metavar{function-form}$ $\metavar{list-form}$)</code></td>
+ <td class="rhs"><code>(block $\metavar{block-name}$ $\metavar{serial-form}$*)</code></td>
</tr>
<tr>
- <td class="lhs">$\metavar{function-form}$</td>
+ <td class="lhs">$\metavar{return-from-form}$</td>
+ <td class="def">$\Coloneq$</td>
+ <td class="rhs"><code>(return-from $\metavar{block-name}$ $\metavar{values-form}$)</code></td>
+ </tr>
+ <tr>
+ <td class="lhs">$\metavar{catch-form}$</td>
+ <td class="def">$\Coloneq$</td>
+ <td class="rhs"><code>(catch $\metavar{exit-tag-form}$ $\metavar{serial-form}$*)</code></td>
+ </tr>
+ <tr>
+ <td class="lhs">$\metavar{throw-form}$</td>
+ <td class="def">$\Coloneq$</td>
+ <td class="rhs"><code>(throw $\metavar{exit-tag-form}$ $\metavar{values-form}$)</code></td>
+ </tr>
+ <tr>
+ <td class="lhs">$\metavar{block-name}$</td>
+ <td class="def">$\Coloneq$</td>
+ <td class="rhs"><code>$\variable$</code></td>
+ </tr>
+ <tr>
+ <td class="lhs">$\metavar{exit-tag-form}$</td>
<td class="def">$\Coloneq$</td>
<td class="rhs"><code>$\metavar{form}$</code></td>
</tr>
<tr>
- <td class="lhs">$\metavar{list-form}$</td>
+ <td class="lhs">$\metavar{values-form}$</td>
+ <td class="def">$\Coloneq$</td>
+ <td class="rhs"><code>$\metavar{form}$</code></td>
+ </tr>
+ <tr>
+ <td class="lhs">$\metavar{\_handler-bind-form}$</td>
+ <td class="def">$\Coloneq$</td>
+ <td class="rhs"><code>(_handler-bind $\metavar{handler-form}$ $\metavar{serial-form}$*)</code></td>
+ </tr>
+ <tr>
+ <td class="lhs">$\metavar{handler-form}$</td>
<td class="def">$\Coloneq$</td>
<td class="rhs"><code>$\metavar{form}$</code></td>
</tr>
<tr>
- <td class="lhs">$\metavar{\_catch-errors-form}$</td>
+ <td class="lhs">$\metavar{unwind-protect-form}$</td>
<td class="def">$\Coloneq$</td>
- <td class="rhs"><code>(_catch-errors $\metavar{try-form}$)</code></td>
+ <td class="rhs"><code>(unwind-protect $\metavar{protected-form}$ $\metavar{cleanup-form}$*)</code></td>
</tr>
<tr>
- <td class="lhs">$\metavar{try-form}$</td>
+ <td class="lhs">$\metavar{protected-form}$</td>
+ <td class="def">$\Coloneq$</td>
+ <td class="rhs"><code>$\metavar{form}$</code></td>
+ </tr>
+ <tr>
+ <td class="lhs">$\metavar{cleanup-form}$</td>
+ <td class="def">$\Coloneq$</td>
+ <td class="rhs"><code>$\metavar{form}$</code></td>
+ </tr>
+ <tr>
+ <td class="lhs">$\metavar{\_for-each-form}$</td>
+ <td class="def">$\Coloneq$</td>
+ <td class="rhs"><code>(_for-each $\metavar{function-form}$ $\metavar{list-form}$)</code></td>
+ </tr>
+ <tr>
+ <td class="lhs">$\metavar{function-form}$</td>
+ <td class="def">$\Coloneq$</td>
+ <td class="rhs"><code>$\metavar{form}$</code></td>
+ </tr>
+ <tr>
+ <td class="lhs">$\metavar{list-form}$</td>
<td class="def">$\Coloneq$</td>
<td class="rhs"><code>$\metavar{form}$</code></td>
</tr>
<tr>
<td class="lhs">$\metavar{special-operator}$</td>
<td class="def">$\Coloneq$</td>
- <td class="rhs"><code>quote | progn | if | _vlambda | _mlambda | _flambda | _dlambda | vref | fref | dref | vset! | fset! | dset! | _for-each | _catch-errors | apply | multiple-value-call | multiple-value-apply</code></td>
+ <td class="rhs"><code>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</code></td>
</tr>
<tr>
<td class="lhs">$\metavar{call}$</td>
<li>A list whose first element is a variable (other than a special operator) naming a macro according to the lookup rule used by <code>fref</code> is never analyzed as a plain function call. Either the list is successfully analyzed as a macro call or the analysis fails.</li>
<li>The variables of a parameter list must be distinct.</li>
</ul>
+ <p>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.</p>
+ <p>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:</p>
+ <ul>
+ <li>The form is the last serial-form of the body of the lambda abstraction.</li>
+ <li>The form is the last serial-form of a progn-form in tail position with respect to the lambda abstraction.</li>
+ <li>The form is the then-form or the else-form of an if-form in tail position with respect to the lambda abstraction.</li>
+ </ul>
<h3>Documentation Generator</h3>
<p>In this section, the character ⇰ marks the places where line breaks have been added to wrap long lines.</p>
<p>Let us consider the following documented EVLambda source file:</p>
<h2>Semantics</h2>
<h3>Primitive Data Types and Primitive Functions</h3>
<p>This section inventories all the primitive data types and all the primitive functions.</p>
- <p>For each primitive function, a template function call and a description of the primitive function's behavior are provided.</p>
+ <p>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.</p>
<p>In template function calls, argument names imply the following type restrictions:</p>
<ul>
<li>Arguments named $\object$, with or without a subscript, can be of any type.</li>
<li>Arguments named $\variable$, with or without a subscript, must be of type <code>variable</code>.</li>
<li>Arguments named $\cons$, with or without a subscript, must be of type <code>cons</code>.</li>
</ul>
- <p>If any argument is not of its required type, then the invocation of the primitive function completes abruptly with a reason of type <code>error</code>.</p>
+ <p>If any argument is not of its required type, then the invocation of the primitive function completes abruptly for a reason of type <code>error</code>.</p>
<h4>Primitive Data Types</h4>
<p>Here is a tree-view representation of the hierarchy of primitive data types:</p>
<pre>object<br> |-void<br> |-boolean<br> |-number<br> |-character<br> |-string<br> |-symbol<br> | |-keyword<br> | |-variable<br> |-list<br> | |-empty-list<br> | |-cons<br> |-vector<br> |-function<br> | |-primitive-function<br> | |-closure</pre>
<h4>Primitive Data Type <code>object</code> and Related Primitive Functions</h4>
<dl>
- <dt><code>(object? $\object$)</code></dt>
+ <dt><code>(object? $\object$)</code> ⇒ $\boolean$</dt>
<dd>The primitive function returns <code>#t</code> if $\object$ is of type <code>object</code> (which is always the case) and <code>#f</code> otherwise.</dd>
- <dt><code>(eq? $\object_1$ $\object_2$)</code></dt>
+ <dt><code>(eq? $\object_1$ $\object_2$)</code> ⇒ $\boolean$</dt>
<dd>The primitive function is an equality predicate. It returns <code>#t</code> if and only if the two objects are one and the same. In other words, it returns <code>#t</code> if and only if the two objects have the same address in the heap.</dd>
- <dt><code>(eql? $\object_1$ $\object_2$)</code></dt>
+ <dt><code>(eql? $\object_1$ $\object_2$)</code> ⇒ $\boolean$</dt>
<dd>The primitive function is an equality predicate. If both objects are of type <code>number</code>, then it returns <code>#t</code> if and only if the two objects represent the same mathematical number. Otherwise, if both objects are of type <code>character</code>, then it returns <code>#t</code> if and only if the two objects represent the same UTF-$16$ code unit. Otherwise, if both objects are of type <code>string</code>, then it returns <code>#t</code> if and only if the two objects represent the same indexed sequence of UTF-$16$ code units. Otherwise, it returns <code>#t</code> if and only if the two objects are <code>eq?</code>.</dd>
</dl>
<h4>Primitive Data Type <code>void</code> and Related Primitive Functions</h4>
<dl>
- <dt><code>(void? $\object$)</code></dt>
+ <dt><code>(void? $\object$)</code> ⇒ $\boolean$</dt>
<dd>The primitive function returns <code>#t</code> if $\object$ is of type <code>void</code> and <code>#f</code> otherwise.</dd>
</dl>
<h4>Primitive Data Type <code>boolean</code> and Related Primitive Functions</h4>
<dl>
- <dt><code>(boolean? $\object$)</code></dt>
+ <dt><code>(boolean? $\object$)</code> ⇒ $\boolean$</dt>
<dd>The primitive function returns <code>#t</code> if $\object$ is of type <code>boolean</code> and <code>#f</code> otherwise.</dd>
</dl>
<h4>Primitive Data Type <code>number</code> and Related Primitive Functions</h4>
<p>Objects of type <code>number</code> represent mathematical numbers using the floating-point format <a href="https://en.wikipedia.org/wiki/Double-precision_floating-point_format" target="_blank">IEEE 754 binary 64</a>. Some (but not all) of the integers that can be represented exactly by an object of type <code>number</code> are the integers between $-2^{53}=−9,007,199,254,740,992$ and $2^{53}=9,007,199,254,740,992$ (bounds included).</p>
<dl>
- <dt><code>(number? $\object$)</code></dt>
+ <dt><code>(number? $\object$)</code> ⇒ $\boolean$</dt>
<dd>The primitive function returns <code>#t</code> if $\object$ is of type <code>number</code> and <code>#f</code> otherwise.</dd>
- <dt><code>(_+ $\number_1$ $\number_2$)</code></dt>
+ <dt><code>(_+ $\number_1$ $\number_2$)</code> ⇒ $\number$</dt>
<dd>The primitive function returns the sum $\number_1+\number_2$.</dd>
- <dt><code>(_- $\number_1$ $\number_2$)</code></dt>
+ <dt><code>(_- $\number_1$ $\number_2$)</code> ⇒ $\number$</dt>
<dd>The primitive function returns the difference $\number_1-\number_2$.</dd>
- <dt><code>(_* $\number_1$ $\number_2$)</code></dt>
+ <dt><code>(_* $\number_1$ $\number_2$)</code> ⇒ $\number$</dt>
<dd>The primitive function returns the product $\number_1\times\number_2$.</dd>
- <dt><code>(_/ $\number_1$ $\number_2$)</code></dt>
+ <dt><code>(_/ $\number_1$ $\number_2$)</code> ⇒ $\number$</dt>
<dd>The primitive function returns the quotient $\number_1\div\number_2$.</dd>
- <dt><code>(% $\number_1$ $\number_2$)</code></dt>
+ <dt><code>(% $\number_1$ $\number_2$)</code> ⇒ $\number$</dt>
<dd>The primitive function returns the remainder of the division of $\number_1$ by $\number_2$ when the quotient is forced to be an integer.</dd>
- <dt><code>(= $\number_1$ $\number_2$)</code></dt>
+ <dt><code>(= $\number_1$ $\number_2$)</code> ⇒ $\boolean$</dt>
<dd>The primitive function returns <code>#t</code> if $\number_1$ and $\number_2$ are numerically equal and <code>#f</code> otherwise.</dd>
- <dt><code>(/= $\number_1$ $\number_2$)</code></dt>
+ <dt><code>(/= $\number_1$ $\number_2$)</code> ⇒ $\boolean$</dt>
<dd>The primitive function returns <code>#t</code> if $\number_1$ and $\number_2$ are numerically different and <code>#f</code> otherwise.</dd>
- <dt><code>(< $\number_1$ $\number_2$)</code></dt>
+ <dt><code>(< $\number_1$ $\number_2$)</code> ⇒ $\boolean$</dt>
<dd>The primitive function returns <code>#t</code> if $\number_1$ is numerically less than $\number_2$ and <code>#f</code> otherwise.</dd>
- <dt><code>(<= $\number_1$ $\number_2$)</code></dt>
+ <dt><code>(<= $\number_1$ $\number_2$)</code> ⇒ $\boolean$</dt>
<dd>The primitive function returns <code>#t</code> if $\number_1$ is numerically less than or equal to $\number_2$ and <code>#f</code> otherwise.</dd>
- <dt><code>(> $\number_1$ $\number_2$)</code></dt>
+ <dt><code>(> $\number_1$ $\number_2$)</code> ⇒ $\boolean$</dt>
<dd>The primitive function returns <code>#t</code> if $\number_1$ is numerically greater than $\number_2$ and <code>#f</code> otherwise.</dd>
- <dt><code>(>= $\number_1$ $\number_2$)</code></dt>
+ <dt><code>(>= $\number_1$ $\number_2$)</code> ⇒ $\boolean$</dt>
<dd>The primitive function returns <code>#t</code> if $\number_1$ is numerically greater than or equal to $\number_2$ and <code>#f</code> otherwise.</dd>
</dl>
<p>The primitive functions <code>_+</code>, <code>_-</code>, <code>_*</code>, and <code>_/</code> have an underscore at the beginning of their names to distinguish them from the similarly named nonprimitive functions <code>+</code>, <code>-</code>, <code>*</code>, and <code>/</code>, which all accept a variable number of arguments.</p>
<h4>Primitive Data Type <code>character</code> and Related Primitive Functions</h4>
<p>Contrary to what was said in the user manual, an object of type <code>character</code> represents a UTF-$16$ code unit (instead of a Unicode character).</p>
<dl>
- <dt><code>(character? $\object$)</code></dt>
+ <dt><code>(character? $\object$)</code> ⇒ $\boolean$</dt>
<dd>The primitive function returns <code>#t</code> if $\object$ is of type <code>character</code> and <code>#f</code> otherwise.</dd>
</dl>
<h4>Primitive Data Type <code>string</code> and Related Primitive Functions</h4>
<p>Contrary to what was said in the user manual, an object of type <code>string</code> represents an indexed sequence of UTF-$16$ code units (instead of an indexed sequence of Unicode characters).</p>
<dl>
- <dt><code>(string? $\object$)</code></dt>
+ <dt><code>(string? $\object$)</code> ⇒ $\boolean$</dt>
<dd>The primitive function returns <code>#t</code> if $\object$ is of type <code>string</code> and <code>#f</code> otherwise.</dd>
</dl>
<h4>Primitive Data Type <code>symbol</code> and Related Primitive Functions</h4>
<dl>
- <dt><code>(symbol? $\object$)</code></dt>
+ <dt><code>(symbol? $\object$)</code> ⇒ $\boolean$</dt>
<dd>The primitive function returns <code>#t</code> if $\object$ is of type <code>symbol</code> and <code>#f</code> otherwise.</dd>
</dl>
<h4>Primitive Data Type <code>keyword</code> and Related Primitive Functions</h4>
<dl>
- <dt><code>(keyword? $\object$)</code></dt>
+ <dt><code>(keyword? $\object$)</code> ⇒ $\boolean$</dt>
<dd>The primitive function returns <code>#t</code> if $\object$ is of type <code>keyword</code> and <code>#f</code> otherwise.</dd>
- <dt><code>(make-keyword? $\string$)</code></dt>
+ <dt><code>(make-keyword? $\string$)</code> ⇒ $\keyword$</dt>
<dd>The primitive function returns a new keyword whose name is $\string$. The keyword is not interned.</dd>
</dl>
<h4>Primitive Data Type <code>variable</code> and Related Primitive Functions</h4>
<dl>
- <dt><code>(variable? $\object$)</code></dt>
+ <dt><code>(variable? $\object$)</code> ⇒ $\boolean$</dt>
<dd>The primitive function returns <code>#t</code> if $\object$ is of type <code>variable</code> and <code>#f</code> otherwise.</dd>
- <dt><code>(make-variable $\string$)</code></dt>
+ <dt><code>(make-variable $\string$)</code> ⇒ $\variable$</dt>
<dd>The primitive function returns a new variable whose name is $\string$. The variable is not interned.</dd>
- <dt><code>(variable-value $\variable$)</code></dt>
+ <dt><code>(variable-value $\variable$)</code> ⇒ $\object$</dt>
<dd>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 <code>#v</code>.</dd>
- <dt><code>(variable-set-value! $\variable$ $\object$)</code></dt>
+ <dt><code>(variable-set-value! $\variable$ $\object$)</code> ⇒ $\object$</dt>
<dd>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$.</dd>
- <dt><code>(variable-value-bound? $\variable$)</code></dt>
+ <dt><code>(variable-value-bound? $\variable$)</code> ⇒ $\boolean$</dt>
<dd>If there exists a binding for $\variable$ in the value namespace of the global environment, then the primitive function returns <code>#t</code>. Otherwise, the primitive function returns <code>#f</code>.</dd>
- <dt><code>(variable-unbind-value! $\variable$)</code></dt>
+ <dt><code>(variable-unbind-value! $\variable$)</code> ⇒ <code>#v</code></dt>
<dd>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 <code>#v</code>. Otherwise, the primitive function simply returns <code>#v</code>.</dd>
- <dt><code>(variable-function $\variable$)</code></dt>
+ <dt><code>(variable-function $\variable$)</code> ⇒ $\object$</dt>
<dd>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 <code>#v</code>.</dd>
- <dt><code>(variable-set-function! $\variable$ $\object$)</code></dt>
+ <dt><code>(variable-set-function! $\variable$ $\object$)</code> ⇒ $\object$</dt>
<dd>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$.</dd>
- <dt><code>(variable-function-bound? $\variable$)</code></dt>
+ <dt><code>(variable-function-bound? $\variable$)</code> ⇒ $\boolean$</dt>
<dd>If there exists a binding for $\variable$ in the function namespace of the global environment, then the primitive function returns <code>#t</code>. Otherwise, the primitive function returns <code>#f</code>.</dd>
- <dt><code>(variable-unbind-function! $\variable$)</code></dt>
+ <dt><code>(variable-unbind-function! $\variable$)</code> ⇒ <code>#v</code></dt>
<dd>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 <code>#v</code>. Otherwise, the primitive function simply returns <code>#v</code>.</dd>
</dl>
<h4>Primitive Data Type <code>list</code> and Related Primitive Functions</h4>
<dl>
- <dt><code>(list? $\object$)</code></dt>
+ <dt><code>(list? $\object$)</code> ⇒ $\boolean$</dt>
<dd>The primitive function returns <code>#t</code> if $\object$ is of type <code>list</code> and <code>#f</code> otherwise.</dd>
</dl>
<h4>Primitive Data Type <code>empty-list</code> and Related Primitive Functions</h4>
<dl>
- <dt><code>(empty-list? $\object$)</code></dt>
+ <dt><code>(empty-list? $\object$)</code> ⇒ $\boolean$</dt>
<dd>The primitive function returns <code>#t</code> if $\object$ is of type <code>empty-list</code> and <code>#f</code> otherwise.</dd>
</dl>
<h4>Primitive Data Type <code>cons</code> and Related Primitive Functions</h4>
<dl>
- <dt><code>(cons? $\object$)</code></dt>
+ <dt><code>(cons? $\object$)</code> ⇒ $\boolean$</dt>
<dd>The primitive function returns <code>#t</code> if $\object$ is of type <code>cons</code> and <code>#f</code> otherwise.</dd>
- <dt><code>(cons $\object_1$ $\object_2$)</code></dt>
+ <dt><code>(cons $\object_1$ $\object_2$)</code> ⇒ $\cons$</dt>
<dd>The primitive function returns a new cons whose first element is $\object_1$ and whose second element is $\object_2$.</dd>
- <dt><code>(car $\cons$)</code></dt>
+ <dt><code>(car $\cons$)</code> ⇒ $\object$</dt>
<dd>The primitive function returns the first element of $\cons$.</dd>
- <dt><code>(set-car! $\cons$ $\object$)</code></dt>
+ <dt><code>(set-car! $\cons$ $\object$)</code> ⇒ $\object$</dt>
<dd>The primitive function replaces the first element of $\cons$ by $\object$ and returns $\object$.</dd>
- <dt><code>(cdr $\cons$)</code></dt>
+ <dt><code>(cdr $\cons$)</code> ⇒ $\object$</dt>
<dd>The primitive function returns the second element of $\cons$</dd>
- <dt><code>(set-cdr! $\cons$ $\object$)</code></dt>
+ <dt><code>(set-cdr! $\cons$ $\object$)</code> ⇒ $\object$</dt>
<dd>The primitive function replaces the second element of $\cons$ by $\object$ and returns $\object$.</dd>
</dl>
<h4>Primitive Data Type <code>vector</code> and Related Primitive Functions</h4>
<dl>
- <dt><code>(vector? $\object$)</code></dt>
+ <dt><code>(vector? $\object$)</code> ⇒ $\boolean$</dt>
<dd>The primitive function returns <code>#t</code> if $\object$ is of type <code>vector</code> and <code>#f</code> otherwise.</dd>
</dl>
<h4>Primitive Data Type <code>function</code> and Related Primitive Functions</h4>
<dl>
- <dt><code>(function? $\object$)</code></dt>
+ <dt><code>(function? $\object$)</code> ⇒ $\boolean$</dt>
<dd>The primitive function returns <code>#t</code> if $\object$ is of type <code>function</code> and <code>#f</code> otherwise.</dd>
</dl>
<h4>Primitive Data Type <code>primitive-function</code> and Related Primitive Functions</h4>
<dl>
- <dt><code>(primitive-function? $\object$)</code></dt>
+ <dt><code>(primitive-function? $\object$)</code> ⇒ $\boolean$</dt>
<dd>The primitive function returns <code>#t</code> if $\object$ is of type <code>primitive-function</code> and <code>#f</code> otherwise.</dd>
</dl>
<h4>Primitive Data Type <code>closure</code> and Related Primitive Functions</h4>
<dl>
- <dt><code>(closure? $\object$)</code></dt>
+ <dt><code>(closure? $\object$)</code> ⇒ $\boolean$</dt>
<dd>The primitive function returns <code>#t</code> if $\object$ is of type <code>closure</code> and <code>#f</code> otherwise.</dd>
</dl>
<h4>Miscellaneous Primitive Functions</h4>
<dl>
- <dt><code>(values $\object_1\ldots\object_n$)</code></dt>
+ <dt><code>(values $\object_1\ldots\object_n$)</code> ⇒ $\object_1,\ldots,\object_n$</dt>
<dd>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$.</dd>
- <dt><code>(error $\string$)</code></dt>
- <dd>The invocation of the primitive function completes abruptly with a reason of type <code>error</code> whose payload is $\string$.</dd>
- <dt><code>(now)</code></dt>
+ <dt><code>(error $\string$)</code> ⇒ completes abruptly for a reason of type <code>error</code></dt>
+ <dd>The invocation of the primitive function completes abruptly for a reason of type <code>error</code> whose payload is $\string$.</dd>
+ <dt><code>(now)</code> ⇒ $\number$</dt>
<dd>The primitive function returns the number of milliseconds elapsed since 1970-01-01 00:00:00.000 UTC.</dd>
</dl>
<h3>Forms</h3>
<p>This section supplements and amends the evaluation rules stated in the user manual.</p>
+ <h4>Advanced Control Structures</h4>
+ <p>The two pairs of special forms <code>block</code>/<code>return-from</code> and <code>catch</code>/<code>throw</code> use two additional namespaces: the block-name namespace and the exit-point namespace.</p>
+ <h5>Special Forms <code>block</code>/<code>return-from</code></h5>
+ <p>The special forms <code>block</code> and <code>return-from</code> are evaluated as follows:</p>
+ <dl>
+ <dt><code>(block $\metavar{block-name}$ $\metavar{serial-form}$*)</code></dt>
+ <dd>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 <code>#v</code> (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:
+ <blockquote>Let $\mlvar{reason}$ be the reason for the abrupt completion of the serial-form. If $\mlvar{reason}$ is of type <code>nonlocal-exit</code> and carries an exit tag <code>eq?</code> 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}$.</blockquote>
+ 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 <code>#v</code> if there are no serial-forms.</dd>
+ <dt><code>(return-from $\metavar{block-name}$ $\metavar{values-form}$)</code></dt>
+ <dd>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 <code>error</code>. 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 <code>error</code>. 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 <code>nonlocal-exit</code> carrying $\mlvar{exit-tag}$ and the values of the values-form.</dd>
+ </dl>
+ <h5>Special Forms <code>catch</code>/<code>throw</code></h5>
+ <p>The special forms <code>catch</code> and <code>throw</code> are evaluated as follows:</p>
+ <dl>
+ <dt><code>(catch $\metavar{exit-tag-form}$ $\metavar{serial-form}$*)</code></dt>
+ <dd>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 <code>error</code>. 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 <code>#v</code> (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:
+ <blockquote>Let $\mlvar{reason}$ be the reason for the abrupt completion of the serial-form. If $\mlvar{reason}$ is of type <code>nonlocal-exit</code> and carries an exit tag <code>eq?</code> 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}$.</blockquote>
+ 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 <code>#v</code> if there are no serial-forms.</dd>
+ <dt><code>(throw $\metavar{exit-tag-form}$ $\metavar{values-form}$)</code></dt>
+ <dd>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 <code>error</code>. 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 <code>error</code>. 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 <code>nonlocal-exit</code> carrying $\mlvar{exit-tag}$ and the values of the values-form.</dd>
+ </dl>
+ <h5>Special Form <code>_handler-bind</code></h5>
+ <p>The special form <code>_handler-bind</code> is evaluated as follows:</p>
+ <dl>
+ <dt><code>(_handler-bind $\metavar{handler-form}$ $\metavar{serial-form}$*)</code></dt>
+ <dd>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 <code>error</code>. 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:
+ <blockquote>Let $\mlvar{reason}$ be the reason for the abrupt completion of the serial-form. If $\mlvar{reason}$ is of type <code>nonlocal-exit</code>, 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.</blockquote>
+ 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 <code>#v</code> if there are no serial-forms.</dd>
+ </dl>
+ <h5>Special Form <code>unwind-protect</code></h5>
+ <p>The special form <code>unwind-protect</code> is evaluated as follows:</p>
+ <dl>
+ <dt><code>(unwind-protect $\metavar{protected-form}$ $\metavar{cleanup-form}$*)</code></dt>
+ <dd>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:
+ <blockquote>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}$.</blockquote>
+ Otherwise, the evaluation of the protected-form completes normally and the evaluation of the unwind-protect-form proceeds as follows:
+ <blockquote>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.</blockquote>
+ </dd>
+ </dl>
<h4>Special Form <code>_for-each</code></h4>
<p>The special form <code>_for-each</code> is evaluated as follows:</p>
<dl>
<dt><code>(_for-each $\metavar{function-form}$ $\metavar{list-form}$)</code></dt>
- <dd>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 <code>error</code>. 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 <code>#v</code>.</dd>
- </dl>
- <h4>Special Form <code>_catch-errors</code></h4>
- <p>The special form <code>_catch-errors</code> is evaluated as follows:</p>
- <dl>
- <dt><code>(_catch-errors $\metavar{try-form}$)</code></dt>
- <dd>The try-form is evaluated. If the evaluation of the try-form completes abruptly for a reason of type <code>error</code>, then the evaluation of the _catch-errors-form completes normally and the _catch-errors-form evaluates to <code>#v</code>. Otherwise, if the evaluation of the try-form completes abruptly for a reason of type <code>exit</code>, 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.</dd>
+ <dd>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 <code>error</code>. 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 <code>error</code>. 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 <code>#v</code>.</dd>
</dl>
<h4>Function Calls</h4>
<p>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]$.</p>
<p>The function calls are evaluated as follows (the differences in behavior between the different types of function calls are highlighted with a gray background):</p>
<dl>
<dt><code>($\metavar{operator-form}$ $\metavar{operand-forms}$)</code></dt>
- <dd>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 <code>error</code>. <span class="bg">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}$.</span> 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.)</dd>
+ <dd>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 <code>error</code>. <span class="bg">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}$.</span> 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.)</dd>
<dt><code>(apply $\metavar{operator-form}$ $\metavar{operand-forms}$)</code></dt>
- <dd>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 <code>error</code>. <span class="bg">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 <code>error</code> if $\mlvar{seq}$ is not a spreadable sequence of objects.)</span> 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.</dd>
+ <dd>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 <code>error</code>. <span class="bg">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 <code>error</code> if $\mlvar{seq}$ is not a spreadable sequence of objects.)</span> 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.</dd>
<dt><code>(multiple-value-call $\metavar{operator-form}$ $\metavar{operand-forms}$)</code></dt>
- <dd>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 <code>error</code>. <span class="bg">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}$.</span> 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.</dd>
+ <dd>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 <code>error</code>. <span class="bg">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}$.</span> 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.</dd>
<dt><code>(multiple-value-apply $\metavar{operator-form}$ $\metavar{operand-forms}$)</code></dt>
- <dd>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 <code>error</code>. <span class="bg">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 <code>error</code> if $\mlvar{seq}$ is not a spreadable sequence of objects.)</span> 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.</dd>
+ <dd>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 <code>error</code>. <span class="bg">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 <code>error</code> if $\mlvar{seq}$ is not a spreadable sequence of objects.)</span> 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.</dd>
</dl>
<p>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:</p>
<dl>
<dt>Case 1, there is no rest parameter:</dt>
- <dd>If $n\neq m$, then the invocation completes abruptly with a reason of type <code>error</code>. 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.)</dd>
+ <dd>If $n\neq m$, then the invocation completes abruptly for a reason of type <code>error</code>. 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.)</dd>
<dt>Case 2, there is a rest parameter $\var_{m+1}$:</dt>
- <dd>If $n\lt m$, then the invocation completes abruptly with a reason of type <code>error</code>. 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.</dd>
+ <dd>If $n\lt m$, then the invocation completes abruptly for a reason of type <code>error</code>. 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.</dd>
</dl>
<p>Here are some examples, where the bindings are assumed to belong to the value namespace:</p>
<table class="plain">
</table>
<p>Here is one way to reproduce the preceding examples using plain function calls and _vlambda-forms:</p>
<pre class="repl">> ((_vlambda (a b) (list a b)) 1 2 3)<br>ERROR: Too many arguments.<br><br>> ((_vlambda (a b c) (list a b c)) 1 2 3)<br>(1 2 3)<br><br>> ((_vlambda (a b c d) (list a b c d)) 1 2 3)<br>ERROR: Too few arguments.<br><br>> ((_vlambda a (list a)) 1 2 3)<br>((1 2 3))<br><br>> ((_vlambda (a . b) (list a b)) 1 2 3)<br>(1 (2 3))<br><br>> ((_vlambda (a b . c) (list a b c)) 1 2 3)<br>(1 2 (3))<br><br>> ((_vlambda (a b c . d) (list a b c d)) 1 2 3)<br>(1 2 3 ())<br><br>> ((_vlambda (a b c d . e) (list a b c d e)) 1 2 3)<br>ERROR: Too few arguments.</pre>
+ <h3>Evaluation Rules in Continuation-Passing Style</h3>
+ <p>Elementary continuations:</p>
+ <ul>
+ <li>$\serialform$</li>
+ <li>$\iftestform$</li>
+ <li>$\setvalueform$</li>
+ <li>$\blockserialforms$</li>
+ <li>$\returnfromvaluesform$</li>
+ <li>$\catchexittagform$</li>
+ <li>$\catchserialforms$</li>
+ <li>$\throwexittagform$</li>
+ <li>$\throwvaluesform$</li>
+ <li>$\handlerbindhandlerform$</li>
+ <li>$\handlerbindserialforms$</li>
+ <li>$\unwindprotectprotectedform$</li>
+ <li>$\unwindprotectcleanupforms$</li>
+ <li>$\foreachfunctionform$</li>
+ <li>$\foreachlistform$</li>
+ <li>$\foreachelement$</li>
+ <li>$\functioncalloperatorform$</li>
+ <li>$\functioncalloperandform$</li>
+ <li>$\macro$</li>
+ </ul>
+ <p>Auxiliary functions:</p>
+ <ul>
+ <li>$\evalserialforms$</li>
+ <li>$\evalserialformforms$</li>
+ <li>$\foreach$</li>
+ <li>$\evaloperandforms$</li>
+ <li>$\invoke$</li>
+ </ul>
+ <dl>
+ <!-- quote-form -->
+ <dt>To evaluate <code class="bg">(quote $\mlvar{literal}$)</code> with respect to $\lexenv$, $\dynenv$, and $k$, do the following:</dt>
+ <dd>Invoke $k$ on $\mlvar{literal}$.</dd>
+ <!-- progn-form -->
+ <dt>To evaluate <code class="bg">(progn $\mlvar{serial-forms}$)</code> with respect to $\lexenv$, $\dynenv$, and $k$, do the following:</dt>
+ <dd>Invoke the auxiliary function $\evalserialforms$ on $\mlvar{serial-forms}$, $\lexenv$, $\dynenv$, and $k$.</dd>
+ <dt>To invoke the auxiliary function $\evalserialforms$ on $\mlvar{serial-forms}$, $\lexenv$, $\dynenv$, and $k$, do the following:</dt>
+ <dd>If $\mlvar{serial-forms}$ is empty, then invoke $k$ on <code>#v</code>. Otherwise, invoke the auxiliary function $\evalserialformforms$ on $\mlvar{serial-forms}$, $\lexenv$, $\dynenv$, and $k$.</dd>
+ <dt>To invoke the auxiliary function $\evalserialformforms$ on $\mlvar{serial-forms}$, $\lexenv$, $\dynenv$, and $k$, do the following:</dt>
+ <dd>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$.</dd>
+ <dt>To invoke the continuation $\serialform(\mlvar{serial-forms},\lexenv,\dynenv,k)$ on $\outcome$, do the following:</dt>
+ <dd>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$.</dd>
+ <!-- if-form -->
+ <dt>To evaluate <code class="bg">(if $\mlvar{test-form}$ $\mlvar{then-form}$ $\mlvar{else-form}$)</code> with respect to $\lexenv$, $\dynenv$, and $k$, do the following:</dt>
+ <dd>Evaluate $\mlvar{test-form}$ with respect to an $\iftestform$ continuation capturing $\mlvar{then-form}$, $\mlvar{else-form}$, $\lexenv$, $\dynenv$, and $k$.</dd>
+ <dt>To invoke the continuation $\iftestform(\mlvar{then-form},\mlvar{else-form},\lexenv,\dynenv,k)$ on $\outcome$, do the following:</dt>
+ <dd>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 <code>error</code>. If $\mlvar{test}$ is the boolean <code>#t</code>, then evaluate $\mlvar{then-form}$ with respect to $\lexenv$, $\dynenv$, and $k$. If $\mlvar{test}$ is the boolean <code>#f</code>, then evaluate $\mlvar{else-form}$ with respect to $\lexenv$, $\dynenv$, and $k$.</dd>
+ <!-- lambda abstractions -->
+ <dt>To evaluate <code class="bg">(_vlambda $\mlvar{parameter-list}$ $\mlvar{body}$)</code> with respect to $\lexenv$, $\dynenv$, and $k$, do the following:</dt>
+ <dt>To evaluate <code class="bg">(_mlambda $\mlvar{parameter-list}$ $\mlvar{body}$)</code> with respect to $\lexenv$, $\dynenv$, and $k$, do the following:</dt>
+ <dt>To evaluate <code class="bg">(_flambda $\mlvar{parameter-list}$ $\mlvar{body}$)</code> with respect to $\lexenv$, $\dynenv$, and $k$, do the following:</dt>
+ <dt>To evaluate <code class="bg">(_dlambda $\mlvar{parameter-list}$ $\mlvar{body}$)</code> with respect to $\lexenv$, $\dynenv$, and $k$, do the following:</dt>
+ <dd>Invoke $k$ on a closure recording the lambda abstraction and $\lexenv$.</dd>
+ <!-- variable references -->
+ <dt>To evaluate <code class="bg">(vref $\mlvar{variable}$)</code> with respect to $\lexenv$, $\dynenv$, and $k$, do the following:</dt>
+ <dt>To evaluate <code class="bg">(fref $\mlvar{variable}$)</code> with respect to $\lexenv$, $\dynenv$, and $k$, do the following:</dt>
+ <dt>To evaluate <code class="bg">(dref $\mlvar{variable}$)</code> with respect to $\lexenv$, $\dynenv$, and $k$, do the following:</dt>
+ <dd>If a binding exists for $\mlvar{variable}$, then invoke $k$ on its value. Otherwise, invoke $k$ on an abrupt completion reason of type <code>error</code>.</dd>
+ <!-- variable assignments -->
+ <dt>To evaluate <code class="bg">(vset! $\mlvar{variable}$ $\mlvar{value-form}$)</code> with respect to $\lexenv$, $\dynenv$, and $k$, do the following:</dt>
+ <dt>To evaluate <code class="bg">(fset! $\mlvar{variable}$ $\mlvar{value-form}$)</code> with respect to $\lexenv$, $\dynenv$, and $k$, do the following:</dt>
+ <dt>To evaluate <code class="bg">(dset! $\mlvar{variable}$ $\mlvar{value-form}$)</code> with respect to $\lexenv$, $\dynenv$, and $k$, do the following:</dt>
+ <dd>Evaluate $\mlvar{value-form}$ with respect to a $\setvalueform$ continuation capturing $\mlvar{variable}$, $\lexenv$, $\dynenv$, and $k$.</dd>
+ <dt>To invoke the continuation $\setvalueform(\mlvar{variable},\lexenv,\dynenv,k)$ on $\outcome$, do the following:</dt>
+ <dd>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}$.</dd>
+ <!-- block-form -->
+ <dt>To evaluate <code class="bg">(block $\mlvar{block-name}$ $\mlvar{serial-forms}$)</code> with respect to $\lexenv$, $\dynenv$, and $k$, do the following:</dt>
+ <dd>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 <code>#v</code>, and $k$.</dd>
+ <dt>To invoke the continuation $\blockserialforms(\mlvar{exit-tag},\lexenv,\dynenv,k)$ on $\outcome$, do the following:</dt>
+ <dd>If $result$ is an abrupt completion reason of type <code>nonlocal-exit</code> carrying an exit tag <code>eq?</code> to $\mlvar{exit-tag}$, then invoke $k$ on the values carried by $\outcome$. Otherwise, invoke $k$ on $\outcome$.</dd>
+ <!-- return-from-form -->
+ <dt>To evaluate <code class="bg">(return-from $\mlvar{block-name}$ $\mlvar{values-form}$)</code> with respect to $\lexenv$, $\dynenv$, and $k$, do the following:</dt>
+ <dd>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 <code>error</code>. 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 <code>error</code>. Otherwise, evaluate $\mlvar{values-form}$ with respect to $\lexenv$, $\dynenv$, and a $\returnfromvaluesform$ continuation capturing $\mlvar{exit-tag}$, $\lexenv$, $\dynenv$, and $k$.</dd>
+ <dt>To invoke the continuation $\returnfromvaluesform(\mlvar{exit-tag},\lexenv,\dynenv,k)$ on $\outcome$, do the following:</dt>
+ <dd>If $\outcome$ is an abrupt completion reason, then invoke $k$ on $\outcome$. Otherwise, invoke $k$ on an abrupt completion reason of type <code>nonlocal-exit</code> carrying $\mlvar{exit-tag}$ and $\outcome$.</dd>
+ <!-- catch-form -->
+ <dt>To evaluate <code class="bg">(catch $\mlvar{exit-tag-form}$ $\mlvar{serial-forms}$)</code> with respect to $\lexenv$, $\dynenv$, and $k$, do the following:</dt>
+ <dd>Evaluate $\mlvar{exit-tag-form}$ with respect to a $\catchexittagform$ continuation capturing $\mlvar{serial-forms}$, $\lexenv$, $\dynenv$, and $k$.</dd>
+ <dt>To invoke the continuation $\catchexittagform(\mlvar{serial-forms},\lexenv,\dynenv,k)$ on $\outcome$, do the following:</dt>
+ <dd>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 <code>error</code>. 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 <code>#v</code>, and $k$.</dd>
+ <dt>To invoke the continuation $\catchserialforms(\mlvar{exit-tag},\lexenv,\dynenv,k)$ on $\outcome$, do the following:</dt>
+ <dd>If $result$ is an abrupt completion reason of type <code>nonlocal-exit</code> carrying an exit tag <code>eq?</code> to $\mlvar{exit-tag}$, then invoke $k$ on the values carried by $\outcome$. Otherwise, invoke $k$ on $\outcome$.</dd>
+ <!-- throw-form -->
+ <dt>To evaluate <code class="bg">(throw $\mlvar{exit-tag-form}$ $\mlvar{values-form}$)</code> with respect to $\lexenv$, $\dynenv$, and $k$, do the following:</dt>
+ <dd>Evaluate $\mlvar{exit-tag-form}$ with respect to a $\throwexittagform$ continuation capturing $\mlvar{values-form}$, $\lexenv$, $\dynenv$, and $k$.</dd>
+ <dt>To invoke the continuation $\throwexittagform(\mlvar{values-form},\lexenv,\dynenv,k)$ on $\outcome$, do the following:</dt>
+ <dd>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 <code>error</code>. 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 <code>error</code>. Otherwise, evaluate $\mlvar{values-form}$ with respect to a $\throwvaluesform$ continuation capturing $\mlvar{exit-tag}$, $\lexenv$, $\dynenv$, and $k$.</dd>
+ <dt>To invoke the continuation $\throwvaluesform(\mlvar{exit-tag},\lexenv,\dynenv,k)$ on $\outcome$, do the following:</dt>
+ <dd>If $\outcome$ is an abrupt completion reason, then invoke $k$ on $\outcome$. Otherwise, invoke $k$ on an abrupt completion reason of type <code>nonlocal-exit</code> carrying $\mlvar{exit-tag}$ and $\outcome$.</dd>
+ <!-- _handler-bind-form -->
+ <dt>To evaluate <code class="bg">(_handler-bind $\mlvar{handler-form}$ $\mlvar{serial-forms}$)</code> with respect to $\lexenv$, $\dynenv$, and $k$, do the following:</dt>
+ <dd>Evaluate $\mlvar{handler-form}$ with respect to a $\handlerbindhandlerform$ continuation capturing $\mlvar{serial-forms}$, $\lexenv$, $\dynenv$, and $k$.</dd>
+ <dt>To invoke the continuation $\handlerbindhandlerform(\mlvar{serial-forms},\lexenv,\dynenv,k)$ on $\outcome$, do the following:</dt>
+ <dd>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 <code>error</code>. Otherwise, invoke the auxiliary function $\evalserialforms$ on $\mlvar{serial-forms}$ and a $\handlerbindserialforms$ continuation capturing $\mlvar{handler}$, $\lexenv$, $\dynenv$, and $k$.</dd>
+ <dt>To invoke the continuation $\handlerbindserialforms(\mlvar{handler},\lexenv,\dynenv,k)$ on $\outcome$, do the following:</dt>
+ <dd>If $\outcome$ is an abrupt completion reason of type <code>error</code>, then invoke the auxiliary function $\invoke$ on $\mlvar{handler}$, the string carried by $\outcome$, $\dynenv$, and $k$. Otherwise, invoke $k$ on $\outcome$.</dd>
+ <!-- unwind-protect-form -->
+ <dt>To evaluate <code class="bg">(unwind-protect $\mlvar{protected-form}$ $\mlvar{cleanup-forms}$)</code> with respect to $\lexenv$, $\dynenv$, and $k$, do the following:</dt>
+ <dd>Evaluate $\mlvar{protected-form}$ with respect to an $\unwindprotectprotectedform$ continuation capturing $\mlvar{cleanup-forms}$, $\lexenv$, $\dynenv$, and $k$.</dd>
+ <dt>To invoke the continuation $\unwindprotectprotectedform(\mlvar{cleanup-forms},\lexenv,\dynenv,k)$ on $\outcome$, do the following:</dt>
+ <dd>Invoke the auxiliary function $\evalserialforms$ on $\mlvar{cleanup-forms}$ and an $\unwindprotectcleanupforms$ continuation capturing $\outcome$, $\lexenv$, $\dynenv$, and $k$.</dd>
+ <dt>To invoke the continuation $\unwindprotectcleanupforms(\mlvar{protected-form-outcome},\lexenv,\dynenv,k)$ on $\outcome$, do the following:</dt>
+ <dd>If $\outcome$ is an abrupt completion reason, then invoke $k$ on $\outcome$. Otherwise, invoke $k$ on $\mlvar{protected-form-outcome}$.</dd>
+ <!-- _for-each-form -->
+ <dt>To evaluate <code class="bg">(_for-each $\mlvar{function-form}$ $\mlvar{list-form}$)</code> with respect to $\lexenv$, $\dynenv$, and $k$, do the following:</dt>
+ <dd>Evaluate $\mlvar{function-form}$ with respect to a $\foreachfunctionform$ continuation capturing $\mlvar{list-form}$, $\lexenv$, $\dynenv$, and $k$.</dd>
+ <dt>To invoke the continuation $\foreachfunctionform(\mlvar{list-form},\lexenv,\dynenv,k)$ on $\outcome$, do the following:</dt>
+ <dd>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 <code>error</code>. Otherwise, evaluate $\mlvar{list-form}$ with respect to a $\foreachlistform$ continuation capturing $\mlvar{function}$, $\lexenv$, $\dynenv$, and $k$.</dd>
+ <dt>To invoke the continuation $\foreachlistform(\mlvar{function},\lexenv,\dynenv,k)$ on $\outcome$, do the following:</dt>
+ <dd>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 <code>error</code>. Otherwise, invoke the auxiliary function $\foreach$ on $\mlvar{function}$, $\mlvar{list}$, $\lexenv$, $\dynenv$, and $k$.</dd>
+ <dt>To invoke the auxiliary function $\foreach$ on $\mlvar{function}$, $\mlvar{list}$, $\lexenv$, $\dynenv$, and $k$, do the following:</dt>
+ <dd>If $\mlvar{list}$ is empty, then invoke $k$ on <code>#v</code>. 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$.</dd>
+ <dt>To invoke the continuation $\foreachelement(\mlvar{function},\mlvar{list},\lexenv,\dynenv,k)$ on $\outcome$, do the following:</dt>
+ <dd>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$.</dd>
+ <!-- function calls -->
+ <dt>To evaluate <code class="bg">($\mlvar{operator-form}$ $\mlvar{operand-forms}$)</code> with respect to $\lexenv$, $\dynenv$, and $k$, do the following:</dt>
+ <dt>To evaluate <code class="bg">(apply $\mlvar{operator-form}$ $\mlvar{operand-forms}$)</code> with respect to $\lexenv$, $\dynenv$, and $k$, do the following:</dt>
+ <dt>To evaluate <code class="bg">(multiple-value-call $\mlvar{operator-form}$ $\mlvar{operand-forms}$)</code> with respect to $\lexenv$, $\dynenv$, and $k$, do the following:</dt>
+ <dt>To evaluate <code class="bg">(multiple-value-apply $\mlvar{operator-form}$ $\mlvar{operand-forms}$)</code> with respect to $\lexenv$, $\dynenv$, and $k$, do the following:</dt>
+ <dd>Evaluate $\mlvar{operator-form}$ with respect to a $\functioncalloperatorform$ continuation capturing $\mlvar{operand-forms}$, $\lexenv$, $\dynenv$, and $k$.</dd>
+ <dt>To invoke the continuation $\functioncalloperatorform(\mlvar{operand-forms},\lexenv,\dynenv,k)$ on $\outcome$, do the following:</dt>
+ <dd>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 <code>error</code>. Otherwise, invoke the auxiliary function $\evaloperandforms$ on $\mlvar{operator}$, $\mlvar{operand-forms}$, $[]$, $\lexenv$, $\dynenv$, and $k$.</dd>
+ <dt>To invoke the auxiliary function $\evaloperandforms$ on $\mlvar{operator}$, $\mlvar{operand-forms}$, $\mlvar{arguments}$, $\lexenv$, $\dynenv$, and $k$, do the following:</dt>
+ <dd>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$.</dd>
+ <dt>To invoke the continuation $\functioncalloperandform(\mlvar{operator},\mlvar{operand-forms},\mlvar{arguments},\lexenv,\dynenv,k)$ on $\outcome$, do the following:</dt>
+ <dd>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$.</dd>
+ <dt>To invoke the auxiliary function $\invoke$ on $\mlvar{function}$, $\mlvar{arguments}$, $\dynenv$, and $k$, do the following:</dt>
+ <dd>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$.</dd>
+ <!-- macro call -->
+ <dt>To evaluate <code class="bg">($\mlvar{macro-operator}$ $\mlvar{macro-operands}$)</code> with respect to $\lexenv$, $\dynenv$, and $k$, do the following:</dt>
+ <dd>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$.</dd>
+ <dt>To invoke the continuation $\macro(\lexenv,\dynenv,k)$ on $\outcome$, do the following:</dt>
+ <dd>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$.</dd>
+ </dl>
</body>
</html>
<li>The evaluation can get caught in an infinite loop and never complete.</li>
</ul>
<p>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 <code>#v</code>.</p>
- <p>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 <code>error</code>, which carries a payload consisting of an object of type <code>string</code> describing the error. An abrupt completion caused by a nonlocal exit has an associated reason of type <code>exit</code>, which carries a payload described in the reference manual.</p>
+ <p>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 <code>error</code>, 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 <code>nonlocal-exit</code>, 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).</p>
<p>Forms submitted to the evaluator through a <a href="#listener-buffers">listener buffer</a>, through the <a href="#evaluate-form">Evaluate Form</a> command, or through the <a href="#load-buffer">Load Buffer</a> 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.</p>
<p>Execution of EVLambda code is achieved through interpretation or compilation.</p>
<p>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.</p>
<p>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.</p>
<p>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.</p>
<p>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.</p>
- <p>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 <code>error</code>. 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 <code>(vref $\var$)</code> or <code>(fref $\var$)</code>, depending on the context of its occurrence. Otherwise, the form is necessarily a cons and the evaluation completes abruptly with a reason of type <code>error</code> unless the form matches one of the following patterns:</p>
+ <p>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 <code>error</code>. 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 <code>(vref $\var$)</code> or <code>(fref $\var$)</code>, depending on the context of its occurrence. Otherwise, the form is necessarily a cons and the evaluation completes abruptly for a reason of type <code>error</code> unless the form matches one of the following patterns:</p>
<ol>
<li><code>(quote $\metavar{literal}$)</code></li>
<li><code>(progn $\metavar{serial-forms}$)</code></li>
<li><code>(fset! $\metavar{variable}$ $\metavar{value-form}$)</code></li>
<li><code>(dref $\metavar{variable}$)</code></li>
<li><code>(dset! $\metavar{variable}$ $\metavar{value-form}$)</code></li>
+ <li><code>(block $\metavar{block-name}$ $\metavar{serial-forms}$)</code></li>
+ <li><code>(return-from $\metavar{block-name}$ $\metavar{values-form}$)</code></li>
+ <li><code>(catch $\metavar{exit-tag-form}$ $\metavar{serial-forms}$)</code></li>
+ <li><code>(throw $\metavar{exit-tag-form}$ $\metavar{values-form}$)</code></li>
+ <li><code>(_handler-bind $\metavar{handler-form}$ $\metavar{serial-forms}$)</code></li>
+ <li><code>(unwind-protect $\metavar{protected-form}$ $\metavar{cleanup-forms}$)</code></li>
<li><code>(_for-each $\metavar{function-form}$ $\metavar{list-form}$)</code></li>
- <li><code>(_catch-errors $\metavar{try-form}$)</code></li>
<li><code>(apply $\metavar{operator-form}$ $\metavar{operand-forms}$)</code></li>
<li><code>(multiple-value-call $\metavar{operator-form}$ $\metavar{operand-forms}$)</code></li>
<li><code>(multiple-value-apply $\metavar{operator-form}$ $\metavar{operand-forms}$)</code></li>
<li>$\metavar{body}$ matches any sequence of zero or more objects</li>
<li>$\metavar{variable}$ matches any variable</li>
<li>$\metavar{value-form}$ matches any object</li>
+ <li>$\metavar{block-name}$ matches any variable</li>
+ <li>$\metavar{exit-tag-form}$ matches any object</li>
+ <li>$\metavar{values-form}$ matches any object</li>
+ <li>$\metavar{handler-form}$ matches any object</li>
+ <li>$\metavar{protected-form}$ matches any object</li>
+ <li>$\metavar{cleanup-forms}$ matches any sequence of zero or more objects</li>
<li>$\metavar{function-form}$ matches any object</li>
<li>$\metavar{list-form}$ matches any object</li>
- <li>$\metavar{try-form}$ matches any object</li>
<li>$\metavar{macro-operator}$ matches any variable naming a macro according to the lookup rule used by <code>fref</code></li>
<li>$\metavar{macro-operands}$ matches any sequence of zero or more objects</li>
<li>$\metavar{operator-form}$ matches any object</li>
</ul>
<p>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 <code>quote</code>.</p>
<p>The patterns are tried in sequence and the first matching pattern wins.</p>
- <p>A form matching one of the first eighteen patterns is called a special form and the variables <code>quote</code>, <code>progn</code>, <code>if</code>, <code>_vlambda</code>, <code>_mlambda</code>, <code>_flambda</code>, <code>_dlambda</code>, <code>vref</code>, <code>vset!</code>, <code>fref</code>, <code>fset!</code>, <code>dref</code>, <code>dset!</code>, <code>_for-each</code>, <code>_catch-all</code>, <code>apply</code>, <code>multiple-value-call</code>, and <code>multiple-value-apply</code> are called special operators.</p>
- <p>Special forms matching patterns 4 (<code>_vlambda</code>), 5 (<code>_mlambda</code>), 6 (<code>_flambda</code>), and 7 (<code>_dlambda</code>) 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 (<code>vref</code>), 10 (<code>fref</code>), and 12 (<code>dref</code>) are called variable references. Special forms matching patterns 9 (<code>vset!</code>), 11 (<code>fset!</code>), and 13 (<code>dset!</code>) are called variable assignments. Forms matching pattern 19 are called macro calls. Forms matching pattern 20 are called plain function calls.</p>
+ <p>A form matching one of the first twenty-three patterns is called a special form and the variables <code>quote</code>, <code>progn</code>, <code>if</code>, <code>_vlambda</code>, <code>_mlambda</code>, <code>_flambda</code>, <code>_dlambda</code>, <code>vref</code>, <code>vset!</code>, <code>fref</code>, <code>fset!</code>, <code>dref</code>, <code>dset!</code>, <code>block</code>, <code>return-from</code>, <code>catch</code>, <code>throw</code>, <code>_handler-bind</code>, <code>unwind-protect</code>, <code>_for-each</code>, <code>apply</code>, <code>multiple-value-call</code>, and <code>multiple-value-apply</code> are called special operators.</p>
+ <p>Special forms matching patterns 4 (<code>_vlambda</code>), 5 (<code>_mlambda</code>), 6 (<code>_flambda</code>), and 7 (<code>_dlambda</code>) 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 (<code>vref</code>), 10 (<code>fref</code>), and 12 (<code>dref</code>) are called variable references. Special forms matching patterns 9 (<code>vset!</code>), 11 (<code>fset!</code>), and 13 (<code>dset!</code>) are called variable assignments. Forms matching pattern 24 are called macro calls. Forms matching pattern 25 are called plain function calls.</p>
<p>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 <code>(fref $\var$)</code> and the function namespace is used. Otherwise, the variable is treated as an abbreviation for <code>(vref $\var$)</code> and the value namespace is used. For example, the plain function call <code>(f x)</code> would be treated as an abbreviation for <code>((fref f) (vref x))</code>. The full forms <code>(fref $\var$)</code> and <code>(vref $\var$)</code> can always be used to force the use of a specific namespace.</p>
- <p>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:</p>
+ <p>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:</p>
<ul>
- <li>The subform is evaluated with respect to the same lexical and dynamic environments as the containing form. (But see below how closures are invoked.)</li>
- <li>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 <code>_catch-errors</code>.</li>
- <li>If the evaluation of the subform does not complete, then the evaluation of the containing form does not complete either.</li>
+ <li>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.)</li>
+ <li>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 <code>block</code>, <code>catch</code>, <code>_handler-bind</code>, and <code>unwind-protect</code>, which are described in the reference manual.</li>
+ <li>If the evaluation of the direct subform does not complete, then the evaluation of the containing form does not complete either.</li>
</ul>
<p>Special forms, macro calls, and plain function calls are evaluated as follows:</p>
<dl>
<dt><code>(progn $\metavar{serial-forms}$)</code></dt>
<dd>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 <code>#v</code>.</dd>
<dt><code>(if $\metavar{test-form}$ $\metavar{then-form}$ $\metavar{else-form}$)</code></dt>
- <dd>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 <code>error</code>. If $\primval$ is the boolean <code>#t</code>, then the then-form is evaluated and the if-form evaluates to the values of the then-form. If $\primval$ is the boolean <code>#f</code>, then the else-form is evaluated and the if-form evaluates to the values of the else-form.</dd>
+ <dd>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 <code>error</code>. If $\mlvar{test}$ is the boolean <code>#t</code>, then the then-form is evaluated and the if-form evaluates to the values of the then-form. If $\mlvar{test}$ is the boolean <code>#f</code>, then the else-form is evaluated and the if-form evaluates to the values of the else-form.</dd>
<dt><code>(_vlambda $\metavar{parameter-list}$ $\metavar{body}$)</code></dt>
<dt><code>(_mlambda $\metavar{parameter-list}$ $\metavar{body}$)</code></dt>
<dt><code>(_flambda $\metavar{parameter-list}$ $\metavar{body}$)</code></dt>
<dt><code>(_dlambda $\metavar{parameter-list}$ $\metavar{body}$)</code></dt>
<dd>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.</dd>
<dt><code>(vref $\metavar{variable}$)</code></dt>
- <dd>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 <code>error</code>.</dd>
+ <dd>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 <code>error</code>.</dd>
<dt><code>(vset! $\metavar{variable}$ $\metavar{value-form}$)</code></dt>
- <dd>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$.</dd>
+ <dd>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}$.</dd>
<dt><code>(fref $\metavar{variable}$)</code></dt>
- <dd>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 <code>error</code>.</dd>
+ <dd>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 <code>error</code>.</dd>
<dt><code>(fset! $\metavar{variable}$ $\metavar{value-form}$)</code></dt>
- <dd>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$.</dd>
+ <dd>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}$.</dd>
<dt><code>(dref $\metavar{variable}$)</code></dt>
- <dd>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 <code>error</code>.</dd>
+ <dd>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 <code>error</code>.</dd>
<dt><code>(dset! $\metavar{variable}$ $\metavar{value-form}$)</code></dt>
- <dd>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$.</dd>
+ <dd>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}$.</dd>
+ <dt><code>(block $\metavar{block-name}$ $\metavar{serial-forms}$)</code></dt>
+ <dt><code>(return-from $\metavar{block-name}$ $\metavar{values-form}$)</code></dt>
+ <dt><code>(catch $\metavar{exit-tag-form}$ $\metavar{serial-forms}$)</code></dt>
+ <dt><code>(throw $\metavar{exit-tag-form}$ $\metavar{values-form}$)</code></dt>
+ <dt><code>(_handler-bind $\metavar{handler-form}$ $\metavar{serial-forms}$)</code></dt>
+ <dt><code>(unwind-protect $\metavar{protected-form}$ $\metavar{cleanup-forms}$)</code></dt>
+ <dd>These special forms, which implement advanced control structures, are described in the reference manual.</dd>
<dt><code>(_for-each $\metavar{function-form}$ $\metavar{list-form}$)</code></dt>
- <dd>This special form is described in the reference manual.</dd>
- <dt><code>(_catch-errors $\metavar{try-form}$)</code></dt>
- <dd>This special form is described in the reference manual.</dd>
+ <dd>This special form, which is a hack only needed and implemented by some of the interpreters, is described in the reference manual.</dd>
<dt><code>(apply $\metavar{operator-form}$ $\metavar{operand-forms}$)</code></dt>
<dt><code>(multiple-value-call $\metavar{operator-form}$ $\metavar{operand-forms}$)</code></dt>
<dt><code>(multiple-value-apply $\metavar{operator-form}$ $\metavar{operand-forms}$)</code></dt>
- <dd>These special forms are variants of the plain function call described below. They are described in the reference manual.</dd>
+ <dd>These special forms, which are variants of the plain function call, are described in the reference manual.</dd>
<dt><code>($\metavar{macro-operator}$ $\metavar{macro-operands}$)</code></dt>
<dd>Following the definition of a macro call, the macro-operator matches a variable naming a macro according to the lookup rule used by <code>fref</code>. 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.</dd>
<dt><code>($\metavar{operator-form}$ $\metavar{operand-forms}$)</code></dt>
- <dd>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 <code>error</code>. 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.</dd>
+ <dd>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 <code>error</code>. 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.</dd>
</dl>
<p>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:</p>
<ul>
<blockquote>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.</blockquote>
<p>A closure is invoked as follows:</p>
<blockquote>
- <p>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 <code>error</code>. (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:</p>
+ <p>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 <code>error</code>. (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:</p>
<ul>
<li>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.</li>
<li>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.</li>
<li>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$).</li>
</ul>
- <p>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.</p>
+ <p>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.</p>
</blockquote>
- <p>When the evaluation of a top-level form completes abruptly for a reason of type <code>exit</code>, that reason is immediately converted into a reason of type <code>error</code>. The three possible outcomes of the evaluation of a top-level form are thus the following:</p>
+ <p>As we will see in the reference manual, the evaluation of a top-level form cannot complete abruptly for a reason of type <code>nonlocal-exit</code>. The three possible outcomes of the evaluation of a top-level form are thus the following:</p>
<ul>
<li>The evaluation of the top-level form completes normally.</li>
<li>The evaluation of the top-level form completes abruptly for a reason of type <code>error</code>.</li>
<li>The evaluation of the top-level form does not complete.</li>
</ul>
- <p>The special operators <code>_vlambda</code>, <code>_mlambda</code>, <code>_flambda</code>, and <code>_dlambda</code> have an underscore at the beginning of their names to distinguish them from the similarly named macros <code>vlambda</code>, <code>mlambda</code>, <code>flambda</code>, and <code>dlambda</code>. The purpose of those macros is to facilitate the creation of closures accepting a variable number of arguments. The special operator <code>_for-each</code> 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 <code>_catch-errors</code> has an underscore at the beginning of its name because it will eventually be replaced by another special operator.</p>
+ <p>The special operators <code>_vlambda</code>, <code>_mlambda</code>, <code>_flambda</code>, and <code>_dlambda</code> have an underscore at the beginning of their names to distinguish them from the similarly named macros <code>vlambda</code>, <code>mlambda</code>, <code>flambda</code>, and <code>dlambda</code>. The purpose of those macros is to facilitate the creation of closures accepting a variable number of arguments. The special operator <code>_handler-bind</code> has an underscore at the beginning of its name to distinguish it from the similarly named macro <code>handler-bind</code>. The special operator <code>_for-each</code> has an underscore at the beginning of its name because it is a hack only needed and implemented by some of the interpreters.</p>
<p>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.</p>
<p>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:</p>
<ul>
<ul>
<li>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.</li>
<li>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.</li>
- <li>If the evaluation completes abruptly, then the reason is necessarily of type <code>error</code> and its payload (an object of type <code>string</code> describing the error) is printed in place of the printable representations of the (nonexisting) resulting values.</li>
+ <li>If the evaluation completes abruptly, then the reason of the abrupt completion is necessarily of type <code>error</code> and the payload of the reason (a string describing the error) is printed in place of the printable representations of the (nonexisting) resulting values.</li>
<li>If the evaluation does not complete, then you must abort the evaluation or restart the evaluator in order to get a new prompt.</li>
</ul>
<p>We will now illustrate some of the concepts introduced in the section <a href="#programming-language">Programming Language</a> 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.</p>
<pre class="repl">> (car '(1 2 3))⏎<br>1</pre>
<p>The evaluation produces a result consisting of the first element of the list <code>(1 2 3)</code>. Because lists are not self-evaluating, quoting the list is necessary.</p>
<pre class="repl">> (car (1 2 3))⏎<br>ERROR: The operator-form does not evaluate to a function.</pre>
- <p>The evaluation completes abruptly with a reason of type <code>error</code> if the list is not quoted. The explanation for this behavior is as follows: The evaluator treats the list <code>(1 2 3)</code> as a plain function call and the operator-form, the number <code>1</code>, does not evaluate to a function.</p>
+ <p>The evaluation completes abruptly for a reason of type <code>error</code> if the list is not quoted. The explanation for this behavior is as follows: The evaluator treats the list <code>(1 2 3)</code> as a plain function call and the operator-form, the number <code>1</code>, does not evaluate to a function.</p>
<pre class="repl">> (cdr '(1 2 3))⏎<br>(2 3)</pre>
<p>The evaluation produces a result consisting of the sublist of the list <code>(1 2 3)</code> obtained by omitting its first element.</p>
<pre class="repl">> (car (cdr '(1 2 3)))⏎<br>2</pre>
<pre class="repl">> (cdr (cdr (cdr '(1 2 3))))⏎<br>()</pre>
<p>The evaluation produces a result consisting of the sublist of the list <code>(1 2 3)</code> obtained by omitting its first three elements.</p>
<pre class="repl">> (car (cdr (cdr (cdr '(1 2 3)))))⏎<br>ERROR: The 1st argument is not of type EVLCons.</pre>
- <p>The evaluation completes abruptly with a reason of type <code>error</code> because the empty list is not a cons.</p>
+ <p>The evaluation completes abruptly for a reason of type <code>error</code> because the empty list is not a cons.</p>
<pre class="repl">> (disk-area 2)⏎<br>ERROR: The variable 'disk-area' is unbound in the FUNCTION namespace.</pre>
- <p>The evaluation completes abruptly with a reason of type <code>error</code> because the global function <code>disk-area</code> is undefined.</p>
+ <p>The evaluation completes abruptly for a reason of type <code>error</code> because the global function <code>disk-area</code> is undefined.</p>
<pre class="repl">> (fdef disk-area (r) (* 3.14 r r))⏎<br>disk-area</pre>
<p>The evaluation produces a result consisting of the variable <code>disk-area</code>. More importantly, the evaluation has the side effect of defining the global function <code>disk-area</code>. In its intended usage, the function accepts the radius of a disk and returns the area of the disk computed using <code>3.14</code> 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 <code>r</code> to the argument of the invocation (that is, the radius of the disk).</p>
<pre class="repl">> (disk-area 2)⏎<br>12.56</pre>
<pre class="repl">> (fdef disk-area (r) (* *pi* r r))⏎<br>disk-area</pre>
<p>The evaluation has the side effect of redefining the global function <code>disk-area</code> to compute the area of the disk using the value of the global variable <code>*pi*</code> as the value of pi. It is customary for a global or dynamic variable to have a name starting and ending with an asterisk.</p>
<pre class="repl">> (disk-area 2)⏎<br>ERROR: The variable '*pi*' is unbound in the VALUE namespace.</pre>
- <p>The evaluation completes abruptly with a reason of type <code>error</code> because the global variable <code>*pi*</code> is undefined.</p>
+ <p>The evaluation completes abruptly for a reason of type <code>error</code> because the global variable <code>*pi*</code> is undefined.</p>
<pre class="repl">> (vdef *pi* 3.141593)⏎<br>*pi*</pre>
<p>The evaluation produces a result consisting of the variable <code>*pi*</code>. More importantly, the evaluation has the side effect of defining the global variable <code>*pi*</code>.</p>
<pre class="repl">> *pi*⏎<br>3.141593</pre>
<li>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.</li>
<li>Otherwise, no form is selected for evaluation and no evaluation takes place.</li>
</ul>
- <p>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 <code>error</code> 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.</p>
+ <p>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 <code>error</code> 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.</p>
<h4 id="load-buffer">Load Buffer</h4>
<p>Evaluates the top-level forms contained inside the selected file buffer.</p>
<p>This command is only available when the selected window displays the contents of an EVLambda source file.</p>
<p>The top-level forms contained inside the selected file buffer are evaluated as if they were part of a progn-form.</p>
- <p>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 <code>error</code> 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.</p>
+ <p>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 <code>error</code> 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.</p>
<h4>Abort Evaluation</h4>
<p>Aborts the current evaluation.</p>
<h4>Restart Evaluator…</h4>