From f124d975bc61f08a351bb67379cae2693563b2e3 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Rapha=C3=ABl=20Van=20Dyck?= Date: Mon, 26 Jan 2026 19:11:30 +0100 Subject: [PATCH] revise user manual, tutorial, and reference manual --- system-files/REFERENCE-MANUAL | 77 ++++++++++++++++++++++++++++++----- system-files/TUTORIAL | 16 ++++++-- system-files/USER-MANUAL | 52 +++++++++++++---------- 3 files changed, 110 insertions(+), 35 deletions(-) diff --git a/system-files/REFERENCE-MANUAL b/system-files/REFERENCE-MANUAL index 77f389a..bed00c3 100644 --- a/system-files/REFERENCE-MANUAL +++ b/system-files/REFERENCE-MANUAL @@ -13,13 +13,14 @@ $\newcommand{\unicode}[1]{U{+}\code{#1}}$ $\DeclareMathOperator{\lex}{lex}$ $\DeclareMathOperator{\pat}{pat}$ + $\DeclareMathOperator{\spread}{spread}$

Reference Manual

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

Syntax

Introduction

Listener Buffers

-

Let's examine what happens when the form (+ 123 456) is evaluated in a listener buffer:

+

Let us examine what happens when the form (+ 123 456) is evaluated in a listener buffer:

> (+ 123 456)
579

The process can be broken down into the following five steps:

Step 1 The sequence of characters (+ 123 456) is read from the listener buffer.

@@ -550,13 +551,13 @@ hash-left-parenthesis {$\metavar{xml-markup}$* $\metavar{object}$}* $\metavar{xml-markup}$* right-parenthesis -

Let us denote by $\mathcal{M}$ the function assigning a meaning to a derivation tree. The function $\mathcal{M}$ is defined by specifying, for each production rule, how the meaning of the nonterminal symbol on the left-hand side is computed from (1) the meanings of the nonterminal symbols on the right-hand side and (2) the terminal symbols on the right-hand side. Here is the definition of the function $\mathcal{M}$ (pairs of angle brackets denote sequence formation and $\|$ denotes sequence concatenation):

+

Let us denote by $\mathcal{M}$ the function assigning a meaning to a derivation tree. The function $\mathcal{M}$ is defined by specifying, for each production rule, how the meaning of the nonterminal symbol on the left-hand side is computed from (1) the meanings of the nonterminal symbols on the right-hand side and (2) the terminal symbols on the right-hand side. Here is the definition of the function $\mathcal{M}$, where a pair of square brackets denotes sequence formation and $\|$ denotes sequence concatenation):

$\metavar{input}\Coloneq$ $\metavar{object}$
-
$\mathcal{M}(\metavar{input})=\langle\mathcal{M}(\metavar{object})\rangle$
+
$\mathcal{M}(\metavar{input})=[\mathcal{M}(\metavar{object})]$
$\metavar{input}\Coloneq$ $\metavarn{object}{1}\ldots\metavarn{object}{n\geq0}$
-
$\mathcal{M}(\metavar{input})=\langle\mathcal{M}(\metavarn{object}{1}),\ldots,\mathcal{M}(\metavarn{object}{n})\rangle$
+
$\mathcal{M}(\metavar{input})=[\mathcal{M}(\metavarn{object}{1}),\ldots,\mathcal{M}(\metavarn{object}{n})]$
$\metavar{input}\Coloneq$ $\metavar{xml-comment}$* $\metavar{xml-element}$ $\metavar{xml-comment}$*
$\mathcal{M}(\metavar{input})=\mathcal{M}(\metavar{xml-element})$
@@ -568,15 +569,15 @@
$\metavar{xml-element}\Coloneq$ xml-start-tag $\metavarn{xml-element-content}{1}\ldots\metavarn{xml-element-content}{n\geq0}$ xml-end-tag
$\mathcal{M}(\metavar{xml-element})=\mathcal{M}(\metavarn{xml-element-content}{1})\|\cdots\|\mathcal{M}(\metavarn{xml-element-content}{n})$
$\metavar{xml-element}\Coloneq$ xml-empty-element-tag
-
$\mathcal{M}(\metavar{xml-element})=\langle\rangle$
+
$\mathcal{M}(\metavar{xml-element})=[]$
$\metavar{xml-element-content}\Coloneq$ $\metavar{xml-markup}$
$\mathcal{M}(\metavar{xml-element-content})=\mathcal{M}(\metavar{xml-markup})$
$\metavar{xml-element-content}\Coloneq$ $\metavar{object}$
-
$\mathcal{M}(\metavar{xml-element-content})=\langle\mathcal{M}(\metavar{object})\rangle$
+
$\mathcal{M}(\metavar{xml-element-content})=[\mathcal{M}(\metavar{object})]$
$\metavar{xml-comment}\Coloneq$ xml-comment
-
$\mathcal{M}(\metavar{xml-comment})=\langle\rangle$
+
$\mathcal{M}(\metavar{xml-comment})=[]$
$\metavar{object}\Coloneq$ void
$\mathcal{M}(\metavar{object})=$ the value of the token of category void
@@ -1020,6 +1021,13 @@ $\metavar{plain-function-call}$ | $\metavar{apply-form}$ | $\metavar{multiple-value-call-form}$ | $\metavar{multiple-value-apply-form}$ +

The parameters of a parameter list fall into two categories: the required parameters, of which there can be any number, and the rest parameters, of which there can be zero or one. Here are the required and rest parameters for the different forms of parameter lists:

+ + + + + +
Parameter listRequired parametersRest parameters
$\var$none$\var$
($\var_1\ldots\var_{n\ge0}$)$\var_1,\ldots,\var_n$none
($\var_1\ldots\var_{n\ge1}$ . $\var_{n+1}$)$\var_1,\ldots,\var_n$$\var_{n+1}$

The variables quasiquote, unquote, and unquote-splicing are not special operators. The variable quasiquote is the name of a global macro and the variables unquote and unquote-splicing are variables having special meanings in the context of a call to the global macro quasiquote.

A form consisting of a variable $\var$ is treated as an abbreviation. If it appears in operator position, then it is treated as an abbreviation for the special form (fref $\var$). Otherwise, it is treated as an abbreviation for the special form (vref $\var$).

Classifying a form is the first step in evaluating a form. If the classification fails, then the evaluation fails.

@@ -1059,7 +1067,7 @@
  • Arguments named $\variable$, with or without a subscript, must be of type variable.
  • Arguments named $\cons$, with or without a subscript, must be of type cons.
  • -

    If any argument is not of its required type, then the invocation of the primitive function completes abnormally.

    +

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

    Primitive Data Types

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

    object
    |-void
    |-boolean
    |-number
    |-character
    |-string
    |-symbol
    | |-keyword
    | |-variable
    |-list
    | |-empty-list
    | |-cons
    |-vector
    |-function
    | |-primitive-function
    | |-closure
    @@ -1083,7 +1091,7 @@
    The primitive function returns #t if $\object$ is of type boolean and #f otherwise.

    Primitive Data Type number and Related Primitive Functions

    -

    Objects of type number represent mathematical numbers using the floating-point format IEEE 754 binary 64. +

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

    (number? $\object$)
    The primitive function returns #t if $\object$ is of type number and #f otherwise.
    @@ -1110,6 +1118,7 @@
    (>= $\number_1$ $\number_2$)
    The primitive function returns #t if $\number_1$ is numerically greater than or equal to $\number_2$ and #f otherwise.
    +

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

    Primitive Data Type character and Related Primitive Functions

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

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

    Forms

    +

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

    +

    Special Form _for-each

    +

    The special form _for-each is evaluated as follows:

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

    Special Form _catch-errors

    +

    The special form _catch-errors is evaluated as follows:

    +
    +
    (_catch-errors $\metavar{try-form}$)
    +
    The try-form is evaluated. If the evaluation of the try-form completes abruptly for a reason of type error, then the evaluation of the _catch-errors-form completes normally and the _catch-errors-form evaluates to #v. Otherwise, if the evaluation of the try-form completes abruptly for a reason of type exit, then the evaluation of the _catch-errors-form completes abruptly for the same reason. Otherwise, if the evaluation of the try-form does not complete, then the evaluation of the _catch-errors-form does not complete either. Otherwise, the _catch-errors-form evaluates to the values of the try-form.
    +
    +

    Function Calls

    +

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

    +

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

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

    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 and the arguments are paired 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 and the arguments are paired depends on the absence or presence of a rest parameter:

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

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

    + + + + + + + + + + +
    Parameter listArgumentsBindings
    (a b)$[\code{1},\code{2},\code{3}]$N/A (error: too many arguments)
    (a b c)$[\code{1},\code{2},\code{3}]$$[\vbinding{a}{1},\vbinding{b}{2},\vbinding{c}{3}]$
    (a b c d)$[\code{1},\code{2},\code{3}]$N/A (error: too few arguments)
    a$[\code{1},\code{2},\code{3}]$$[\vbinding{a}{(1 2 3)}]$
    (a . b)$[\code{1},\code{2},\code{3}]$$[\vbinding{a}{1},\vbinding{b}{(2 3)}]$
    (a b . c)$[\code{1},\code{2},\code{3}]$$[\vbinding{a}{1},\vbinding{b}{2},\vbinding{c}{(3)}]$
    (a b c . d)$[\code{1},\code{2},\code{3}]$$[\vbinding{a}{1},\vbinding{b}{2},\vbinding{c}{3},\vbinding{d}{()}]$
    (a b c d . e)$[\code{1},\code{2},\code{3}]$N/A (error: too few arguments)
    +

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

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

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

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

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

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

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

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

    > ((_vlambda (a b c d . e) (list a b c d e)) 1 2 3)
    ERROR: Too few arguments.
    diff --git a/system-files/TUTORIAL b/system-files/TUTORIAL index eafb2ff..fab0c2e 100644 --- a/system-files/TUTORIAL +++ b/system-files/TUTORIAL @@ -168,12 +168,22 @@
    The purpose of the macro is to define a global macro by ensuring that the variable is bound in the function namespace of the global environment to the closure resulting from the evaluation of the _mlambda-form (_mlambda $\metavar{parameter-list}$ $\metavar{body}$). The macro call evaluates to the variable.

    Evaluation and Invocation Traces

    -

    An evaluation trace is a structured recording of some or all of the evaluations, invocations, and various steps performed by the evaluator to evaluate a form. It is assumed that the evaluation of the form completes normally, which implies that all evaluations and invocations entailed by the evaluation of the form also complete normally. Evaluation traces have the following format:

    +

    An evaluation trace is a structured recording of some or all of the evaluations, invocations, and various steps performed by the evaluator to evaluate a form. Evaluation traces have the following format: