commit a022c503384a3334c3a5e16fa421dc6ff94531e6
parent 7aadeb3c65db6898a4a3928500c86be93859ce91
Author: Andres Navarro <canavarro82@gmail.com>
Date: Wed, 1 Jun 2011 21:20:03 -0300
Completed the environments module for the manual. All core modules done.
Diffstat:
8 files changed, 894 insertions(+), 67 deletions(-)
diff --git a/manual/html/Combiners.html b/manual/html/Combiners.html
@@ -34,7 +34,7 @@ Up: <a rel="up" accesskey="u" href="index.html#Top">Top</a>
<!-- node-name, next, previous, up -->
<h2 class="chapter">8 Combiners</h2>
-<p><a name="index-combiners-95"></a><a name="index-applicatives-96"></a><a name="index-operatives-97"></a>
+<p><a name="index-combiners-114"></a><a name="index-applicatives-115"></a><a name="index-operatives-116"></a>
There are two types of combiners in Kernel, operative and
applicative. Both types are encapsulated. All combiners are immutable.
Two applicatives are <code>eq?</code> iff their underlying combiners are
@@ -47,33 +47,33 @@ iff they are <code>eq?</code>.
<!-- TODO add xref for eq? and equal? -->
<div class="defun">
-— Applicative: <b>operative?</b> (<var>operative? . objects</var>)<var><a name="index-operative_003f-98"></a></var><br>
+— Applicative: <b>operative?</b> (<var>operative? . objects</var>)<var><a name="index-operative_003f-117"></a></var><br>
<blockquote><p> The primitive type predicate for type operative. <code>operative?</code>
returns true iff all the objects in <code>objects</code> are of type
operative.
</p></blockquote></div>
<div class="defun">
-— Applicative: <b>applicative?</b> (<var>applicative? . objects</var>)<var><a name="index-applicative_003f-99"></a></var><br>
+— Applicative: <b>applicative?</b> (<var>applicative? . objects</var>)<var><a name="index-applicative_003f-118"></a></var><br>
<blockquote><p> The primitive type predicate for type applicative.
<code>applicative?</code> returns true iff all the objects in
<code>objects</code> are of type applicative.
</p></blockquote></div>
<div class="defun">
-— Operative: <b>$vau</b> (<var>$vau <formals> <eformal> . <objects></var>)<var><a name="index-g_t_0024vau-100"></a></var><br>
+— Operative: <b>$vau</b> (<var>$vau <formals> <eformal> . <objects></var>)<var><a name="index-g_t_0024vau-119"></a></var><br>
<blockquote><!-- TODO add xref to formal parameter tree -->
- <p><code>formals</code> should be a formal parameter tree; <code>eformal</code>
-should be either a symbol or <code>#ignore</code>. If <code>formals</code> does
+ <p><code><formals></code> should be a formal parameter tree; <code><eformal></code>
+should be either a symbol or <code>#ignore</code>. If <code><formals></code> does
not have the correct form for a formal parameter tree, or if
-<code>eformal</code> is a symbol that also occurs in <code>formals</code>, an
+<code><eformal></code> is a symbol that also occurs in <code><formals></code>, an
error is signaled.
<p>A <code>vau</code> expression evaluates to an operative; an operative
created in this way is said to be compound. The environment in which
the <code>vau</code> expression was evaluated is remembered as part of the compound
operative, called the compound operative’s static environment.
-<code>formals</code> and <code>objects</code> are copied as by
+<code><formals></code> and <code><objects></code> are copied as by
<code>copy-es-immutable</code> and the copies are stored as part of the
operative being constructed. This avoids problem if these structures
are later mutated.
@@ -95,11 +95,10 @@ matched to the dynamic environment; that is, if eformal is a symbol
then that symbol is bound in the local environment to the dynamic
environment.
- <li>A stored copy of the expressions is evaluated sequentially in the
-<!-- TODO add xref to sequence -->
-local environment as if by <code>$sequence</code>. In particular, if there
-<!-- TODO add xref to tail context. -->
-is a last expression, it is evaluated in a tail context.
+ <li><!-- TODO add xref to tail context. -->
+A stored copy of the expressions is evaluated sequentially from left
+to right, with the last (if any) evaluated as a tail context, or if
+the list of expressions is empty, the result is inert.
</ol>
<p>NOTE: Because compound operatives are not a distinct type in Kernel,
@@ -111,20 +110,20 @@ operative is compound.
</p></blockquote></div>
<div class="defun">
-— Applicative: <b>wrap</b> (<var>wrap combiner</var>)<var><a name="index-wrap-101"></a></var><br>
+— Applicative: <b>wrap</b> (<var>wrap combiner</var>)<var><a name="index-wrap-120"></a></var><br>
<blockquote><p> The <code>wrap</code> applicative returns an applicative whose underlying
combiner is <code>combiner</code>.
</p></blockquote></div>
<div class="defun">
-— Applicative: <b>unwrap</b> (<var>unwrap applicative</var>)<var><a name="index-unwrap-102"></a></var><br>
+— Applicative: <b>unwrap</b> (<var>unwrap applicative</var>)<var><a name="index-unwrap-121"></a></var><br>
<blockquote><p> The <code>unwrap</code> applicative returns the underlying combiner of
<code>applicative</code>.
</p></blockquote></div>
<div class="defun">
-— Operative: <b>$lambda</b> (<var>$lambda formals . objects</var>)<var><a name="index-g_t_0024lambda-103"></a></var><br>
-<blockquote><p> <code>formals</code> should be a formal parameter tree.
+— Operative: <b>$lambda</b> (<var>$lambda <formals> . <objects></var>)<var><a name="index-g_t_0024lambda-122"></a></var><br>
+<blockquote><p> <code><formals></code> should be a formal parameter tree.
<p>The <code>$lambda</code> operative is defined by the following equivalence:
<pre class="example"> ($lambda formals . objects) ==
@@ -133,7 +132,7 @@ combiner is <code>combiner</code>.
</blockquote></div>
<div class="defun">
-— Applicative: <b>apply</b> (<var>apply applicative object </var>[<var>environment</var>])<var><a name="index-apply-104"></a></var><br>
+— Applicative: <b>apply</b> (<var>apply applicative object </var>[<var>environment</var>])<var><a name="index-apply-123"></a></var><br>
<blockquote><p> Applicative <code>apply</code> combines the underlying combiner of
<code>applicative</code> with <code>object</code> in a tail context with dynamic
environment <code>environment</code> (if the long form is used) or in an
@@ -149,7 +148,7 @@ empty environment (if the short form is used).
</blockquote></div>
<div class="defun">
-— Applicative: <b>map</b> (<var>map applicative . lists</var>)<var><a name="index-map-105"></a></var><br>
+— Applicative: <b>map</b> (<var>map applicative . lists</var>)<var><a name="index-map-124"></a></var><br>
<blockquote><p> <code>lists</code> must be a nonempty list of lists; if there are two or
<!-- TODO add xref to length -->
more, they must all have the same length. If <code>lists</code> is empty, or
@@ -178,7 +177,7 @@ times.
</p></blockquote></div>
<div class="defun">
-— Applicative: <b>combiner?</b> (<var>combiner? . objects</var>)<var><a name="index-combiner_003f-106"></a></var><br>
+— Applicative: <b>combiner?</b> (<var>combiner? . objects</var>)<var><a name="index-combiner_003f-125"></a></var><br>
<blockquote><p> The primitive type predicate for type combiner. <code>combiner?</code>
returns true iff all the objects in <code>objects</code> are of type
combiner (i.e. applicative or operative).
diff --git a/manual/html/Environments.html b/manual/html/Environments.html
@@ -35,6 +35,295 @@ Up: <a rel="up" accesskey="u" href="index.html#Top">Top</a>
<h2 class="chapter">7 Environments</h2>
<p><a name="index-environments-93"></a><a name="index-ignore-94"></a>
+ An environment consists of a set of bindings, and a list of zero or
+more references to other environments called its parents.
+<!-- TODO add xref to lookup algo & ground env -->
+Changing the set of bindings of an environment, or setting the
+referent of the reference in a binding, is a mutation of the
+environment. (Changing the parent list, or a referent in the list,
+would be a mutation of the environment too, but there is no facility
+provided to do it.) The Kernel data type environment is encapsulated.
+Among other things, there is no facility provided for enumerating all
+the variables exhibited by an environment (which is not required,
+after all, to be a finite set), and no facility for identifying the
+parents of an environment. Two environments are <code>equal?</code> iff
+they are <code>eq?</code>.
+
+ <p>An auxiliary data type used by combiners that perform binding is
+ignore. The ignore type consists of a single immutable value, having
+external representation <code>#ignore</code>. The ignore type is
+encapsulated.
+
+<div class="defun">
+— Applicative: <b>environment?</b> (<var>environment? . objects</var>)<var><a name="index-environment_003f-95"></a></var><br>
+<blockquote><p> The primitive type predicate for type environment.
+<code>environment?</code> returns true iff all the objects in <code>objects</code>
+are of type environment.
+</p></blockquote></div>
+
+<div class="defun">
+— Applicative: <b>ignore?</b> (<var>ignore? . objects</var>)<var><a name="index-ignore_003f-96"></a></var><br>
+<blockquote><p> The primitive type predicate for type ignore. <code>ignore?</code>
+returns true iff all the objects in <code>objects</code> are of type ignore.
+</p></blockquote></div>
+
+<div class="defun">
+— Applicative: <b>eval</b> (<var>eval expression environment</var>)<var><a name="index-eval-97"></a></var><br>
+<blockquote><!-- TODO add xref to tail context -->
+ <!-- TODO add xref to evaluation description -->
+ <p>The <code>eval</code> applicative evaluates <code>expression</code> as a tail
+context in <code>environment</code>, and returns the resulting value.
+</p></blockquote></div>
+
+<div class="defun">
+— Applicative: <b>make-environment</b> (<var>make-environment . environments</var>)<var><a name="index-make_002denvironment-98"></a></var><br>
+<blockquote><p> The applicative constructs and returns a new environment, with
+initially no local bindings, and parent environments the environments
+listed in <code>environments</code>. The constructed environment internally
+stores its list of parents independent of the first-class list
+<code>environments</code>, so that subsequent mutation of
+<code>environments</code> will not change the parentage of the constructed
+environment. If the provided list <code>environments</code> is cyclic, the
+constructed environment will still check each of its parents at most
+once, and signal an error if no binding is found locally or in any of
+<!-- TODO add xref to cons, mutation, eq? and equal? -->
+the parents. No two objects returned by different calls to
+<code>make-environment</code> are <code>eq?</code> to each other.
+</p></blockquote></div>
+
+<div class="defun">
+— Operative: <b>$define!</b> (<var>$define! <definiend> <expression></var>)<var><a name="index-g_t_0024define_0021-99"></a></var><br>
+<blockquote><!-- TODO move formal parameter tree definition to the intro -->
+ <!-- TODO move matching definition to the intro -->
+ <p><code><definiend></code> should be a formal parameter tree, as described
+below; otherwise, an error is signaled.
+
+ <p>The <code>$define!</code> operative evaluates <code><expression></code> in the
+dynamic environment and matches <code><definiend></code> to the result in
+the dynamic environment, binding each symbol in definiend in the
+dynamic environment to the corresponding part of the result; the
+matching process will be further described below. The ancestors of the
+dynamic environment, if any, are unaffected by the matching process,
+as are all bindings, local to the dynamic environment, of symbols not
+in <code><definiend></code>. The result returned by <code>$define!</code> is
+inert.
+
+ <p>A formal parameter tree has the following context-free structure:
+ <pre class="example"> ptree:: symbol | #ignore | () | (ptree . ptree)
+</pre>
+ <p>That is, a formal parameter tree is either a symbol, or ignore, or
+nil, or a pair whose car and cdr referents are formal parameter trees.
+A formal parameter tree must also be acyclic, and no one symbol can
+occur more than once in it. It is not an error for a pair in the tree
+to be reachable from the root by more than one path, as long as there
+is no cycle; but if any particular symbol were reachable from the root
+by more than one path, that would count as occurring more than once.
+Thus, if a pair is reachable by more than one path, there must be no
+symbols reachable from it.
+
+ <p>Matching of a formal parameter tree <code>t</code> to an object <code>o</code>
+in an environment <code>e</code> proceeds recursively as follows. If the
+matching process fails, an error is signaled.
+ <ul>
+<li>If <code>t</code> is a symbol, then <code>t</code> is bound to <code>o</code> in
+<code>e</code>.
+
+ <li>If <code>t</code> is <code>#ignore</code>, no action is taken.
+
+ <li>If <code>t</code> is nil, then <code>o</code> must be nil (else matching fails).
+
+ <li>If <code>t</code> is a pair, then <code>o</code> must be a pair (else matching
+fails). The car of <code>t</code> is matched to the car of <code>o</code> in
+<code>e</code>, and the cdr of <code>t</code> is matched to the cdr of <code>o</code> in
+<code>e</code>.
+</ul>
+ </p></blockquote></div>
+
+<div class="defun">
+— Operative: <b>$let</b> (<var>$let <bindings> . <objects></var>)<var><a name="index-g_t_0024let-100"></a></var><br>
+<blockquote><!-- TODO add xref to formal parameter tree -->
+ <p><code><bindings></code> should be a finite list of
+formal-parameter-tree/expression pairings, each of the form
+<code>(formals expression)</code>, where each <code>formals</code> is a formal
+parameter, and no symbol occurs in more than one of the
+<code>formals</code>.
+
+ <p>The following equivalence holds:
+
+ <pre class="example"> ($let ((form1 exp1) ... (formn expn)) . objects) ==
+ (($lambda (form1 ... formn) . objects) exp1 ... expn)
+</pre>
+ <!-- TODO add xref to tail context -->
+ <p>Thus, the <code>expk</code> are first evaluated in the dynamic environment,
+in any order; then a child environment <code>e</code> of the dynamic
+environment is created, with the <code>formk</code> matched in <code>e</code> to
+the results of the evaluations of the <code>expk</code>; and finally the
+subexpressions of <code>objects</code> are evaluated in <code>e</code> from left
+to right, with the last (if any) evaluated as a tail context, or if
+<code>objects</code> is empty the result is inert.
+</p></blockquote></div>
+
+<div class="defun">
+— Operative: <b>$binds?</b> (<var>$binds? <exp> . <symbols></var>)<var><a name="index-g_t_0024binds_003f-101"></a></var><br>
+<blockquote><p> Operative <code>$binds</code> evaluates <code><exp></code> in the dynamic
+environment; call the result <code>env</code>. <code>env</code> must be an
+environment. The operative is a predicate that returns true iff all
+its later operands, <code><symbols></code>, are visibly bound in <code>env</code>.
+</p></blockquote></div>
+
+<div class="defun">
+— Applicative: <b>get-current-environment</b> (<var>get-current-environment</var>)<var><a name="index-get_002dcurrent_002denvironment-102"></a></var><br>
+<blockquote><p> The <code>get-current-environment</code> applicative returns the dynamic
+environment in which it is called.
+</p></blockquote></div>
+
+<div class="defun">
+— Applicative: <b>make-kernel-standard-environment</b> (<var>make-kernel-standard-environment</var>)<var><a name="index-make_002dkernel_002dstandard_002denvironment-103"></a></var><br>
+<blockquote><!-- TODO add xref to ground environment/standard environment -->
+ <p>The <code>make-kernel-standard-environment</code> applicative returns a
+standard environment; that is, a child of the ground environment with
+no local bindings.
+</p></blockquote></div>
+
+<div class="defun">
+— Operative: <b>$let*</b> (<var>$let* <bindings> . <body></var>)<var><a name="index-g_t_0024let_002a-104"></a></var><br>
+<blockquote><!-- TODO add xref to formal ptree -->
+ <p><code><bindings></code> should be a finite list of
+formal-parameter-tree/expression pairings, each of the form
+<code>(formals expression)</code>, where each <code>formals</code> is a formal
+parameter tree; <code><body></code> should be a list of expressions.
+
+ <p>The following equivalences hold:
+
+ <pre class="example"> ($let* () . body) == ($let () . body)
+
+ ($let* ((form exp) . bindings) . body) ==
+ ($let ((form exp)) ($let* bindings . body))
+</pre>
+ </blockquote></div>
+
+<div class="defun">
+— Operative: <b>$letrec</b> (<var>$letrec <bindings> . <body></var>)<var><a name="index-g_t_0024letrec-105"></a></var><br>
+<blockquote><!-- add xref for $let -->
+ <p><code><bindings></code> and <code><body></code> should be as described for
+<code>$let</code>.
+
+ <p>The following equivalence holds:
+ <pre class="example"> ($letrec ((form1 exp1) ... (formn expn)) . body) ==
+ ($let () ($define! (form1 ... formn) (list exp1 ... expn)) . body)
+</pre>
+ </blockquote></div>
+
+<div class="defun">
+— Operative: <b>$letrec*</b> (<var>$letrec* <bindings> . <body></var>)<var><a name="index-g_t_0024letrec_002a-106"></a></var><br>
+<blockquote><!-- TODO add xref to $let* -->
+ <p><code><bindings></code> and <code><body></code> should be as described for
+<code>$let*</code>.
+
+ <p>The following equivalences hold:
+ <pre class="example"> ($letrec* () . body) == ($letrec () . body)
+
+ ($letrec* ((form exp) . bindings) . body) ==
+ ($letrec ((form exp)) ($letrec* bindings . body))
+</pre>
+ </blockquote></div>
+
+<div class="defun">
+— Operative: <b>$let-redirect</b> (<var>$let-redirect <exp> <bindings> . <body></var>)<var><a name="index-g_t_0024let_002dredirect-107"></a></var><br>
+<blockquote><!-- TODO add xref to $let -->
+ <p><code><bindings></code> and <code><body></code> should be as described for
+<code>$let</code>.
+
+ <p>The following equivalence holds:
+
+ <pre class="example"> ($let-redirect exp ((form1 exp1) ... (formn . body) expn)) ==
+ ((eval (list $lambda (form1 ... formn) body) exp) expn ... expn)
+</pre>
+ </blockquote></div>
+
+<div class="defun">
+— Operative: <b>$let-safe</b> (<var>$let-safe <bindings> . <body></var>)<var><a name="index-g_t_0024let_002dsafe-108"></a></var><br>
+<blockquote><!-- TODO add xref to $let -->
+ <p><code><bindings></code> and <code><body></code> should be as described for
+<code>$let</code>.
+
+ <p>The following equivalence holds:
+
+ <pre class="example"> ($let-safe bindings . body) ==
+ ($let-redirect (make-kernel-standard-environment) bindings . body)
+</pre>
+ </blockquote></div>
+
+<div class="defun">
+— Operative: <b>$remote-eval</b> (<var>$remote-eval <exp1> <exp2></var>)<var><a name="index-g_t_0024remote_002deval-109"></a></var><br>
+<blockquote><!-- TODO add xref to tail context -->
+ <p>Operative <code>$remote-eval</code> evaluates <code><exp2></code> in the dynamic
+environment, then evaluates <code><exp1></code> as a tail context in the
+environment that must result from the first evaluation.
+</p></blockquote></div>
+
+<div class="defun">
+— Operative: <b>(</b><var>$bindings-environment . <bindings></var>)<var><a name="index-g_t_0028-110"></a></var><br>
+<blockquote><!-- TODO add xref to $let -->
+ <p><code><bindings></code> should be as described for <code>$let</code>.
+
+ <p>The following equivalence holds:
+
+ <pre class="example"> ($bindings->environment . bindings) ==
+ ($let-redirect (make-environment) bindings (get-current-environment))
+</pre>
+ </blockquote></div>
+
+<div class="defun">
+— Operative: <b>$set!</b> (<var>$set! <exp1> <formals> <exp2></var>)<var><a name="index-g_t_0024set_0021-111"></a></var><br>
+<blockquote><!-- TODO add xref to $define! -->
+ <!-- TODO add xref to matching algo -->
+ <p><code><formals></code> should be as described for the <code>$define!</code>
+operative. The <code>$set!</code> operative evaluates <code><exp1></code> and
+<code><exp2></code> in the dynamic environment; call the results <code>env</code>
+and <code>obj</code>. If <code>env</code> is not an environment, an error is
+signaled. Then the operative matches <code><formals></code> to <code>obj</code>
+in environment <code>env</code>. Thus, the symbols of <code><formals></code> are
+bound in <code>env</code> to the corresponding parts of <code>obj</code>.
+The result returned by <code>$set!</code> is inert.
+</p></blockquote></div>
+
+<div class="defun">
+— Operative: <b>$provide!</b> (<var>$provide! <symbols> . <body></var>)<var><a name="index-g_t_0024provide_0021-112"></a></var><br>
+<blockquote><p> <code><symbols></code> must be a finite list of symbols, containing no
+duplicates. <code><body></code> must be a finite list.
+
+ <p>The <code>$provide!</code> operative constructs a child <code>e</code> of the
+dynamic environment <code>d</code>; evaluates the elements of <code><body></code>
+in <code>e</code>, from left to right, discarding all of the results; and
+exports all of the bindings of symbols in <code><symbols></code> from
+<code>e</code> to <code>d</code>, i.e., binds each symbol in <code>d</code> to the
+result of looking it up in <code>e</code>. The result returned by
+<code>$provide!</code> is inert.
+
+ <p>The following equivalence holds:
+
+ <pre class="example"> ($provide! symbols . body) ==
+ ($define! symbols ($let () ($sequence . body) (list . symbols)))
+</pre>
+ </blockquote></div>
+
+<div class="defun">
+— Operative: <b>$import!</b> (<var>$import! <exp> . <symbols></var>)<var><a name="index-g_t_0024import_0021-113"></a></var><br>
+<blockquote><p> <code><symbols></code> must be a list of symbols.
+
+ <p>The <code>$import!</code> operative evaluates <code><exp></code> in the dynamic
+environment; call the result <code>env</code>. <code>env</code> must be an
+environment. Each distinct symbol <code>s</code> in <code><symbols></code> is
+evaluated in <code>env</code>, and <code>s</code> is bound in the dynamic
+environment to the result of this evaluation.
+
+ <p>The following equivalence holds:
+
+ <pre class="example"> ($import! exp . symbols) ==
+ ($define! symbols ($remote-eval (list symbols) exp))
+</pre>
+ </blockquote></div>
<!-- *-texinfo-*- -->
</body></html>
diff --git a/manual/html/Index.html b/manual/html/Index.html
@@ -36,19 +36,32 @@ Up: <a rel="up" accesskey="u" href="index.html#Top">Top</a>
<ul class="index-fn" compact>
<li><a href="Booleans.html#index-g_t_0024and_003f-17"><code>$and?</code></a>: <a href="Booleans.html#Booleans">Booleans</a></li>
+<li><a href="Environments.html#index-g_t_0024binds_003f-101"><code>$binds?</code></a>: <a href="Environments.html#Environments">Environments</a></li>
<li><a href="Control.html#index-g_t_0024cond-31"><code>$cond</code></a>: <a href="Control.html#Control">Control</a></li>
+<li><a href="Environments.html#index-g_t_0024define_0021-99"><code>$define!</code></a>: <a href="Environments.html#Environments">Environments</a></li>
<li><a href="Control.html#index-g_t_0024if-29"><code>$if</code></a>: <a href="Control.html#Control">Control</a></li>
-<li><a href="Combiners.html#index-g_t_0024lambda-103"><code>$lambda</code></a>: <a href="Combiners.html#Combiners">Combiners</a></li>
+<li><a href="Environments.html#index-g_t_0024import_0021-113"><code>$import!</code></a>: <a href="Environments.html#Environments">Environments</a></li>
+<li><a href="Combiners.html#index-g_t_0024lambda-122"><code>$lambda</code></a>: <a href="Combiners.html#Combiners">Combiners</a></li>
+<li><a href="Environments.html#index-g_t_0024let-100"><code>$let</code></a>: <a href="Environments.html#Environments">Environments</a></li>
+<li><a href="Environments.html#index-g_t_0024let_002a-104"><code>$let*</code></a>: <a href="Environments.html#Environments">Environments</a></li>
+<li><a href="Environments.html#index-g_t_0024let_002dredirect-107"><code>$let-redirect</code></a>: <a href="Environments.html#Environments">Environments</a></li>
+<li><a href="Environments.html#index-g_t_0024let_002dsafe-108"><code>$let-safe</code></a>: <a href="Environments.html#Environments">Environments</a></li>
+<li><a href="Environments.html#index-g_t_0024letrec-105"><code>$letrec</code></a>: <a href="Environments.html#Environments">Environments</a></li>
+<li><a href="Environments.html#index-g_t_0024letrec_002a-106"><code>$letrec*</code></a>: <a href="Environments.html#Environments">Environments</a></li>
<li><a href="Booleans.html#index-g_t_0024or_003f-18"><code>$or?</code></a>: <a href="Booleans.html#Booleans">Booleans</a></li>
+<li><a href="Environments.html#index-g_t_0024provide_0021-112"><code>$provide!</code></a>: <a href="Environments.html#Environments">Environments</a></li>
+<li><a href="Environments.html#index-g_t_0024remote_002deval-109"><code>$remote-eval</code></a>: <a href="Environments.html#Environments">Environments</a></li>
<li><a href="Control.html#index-g_t_0024sequence-30"><code>$sequence</code></a>: <a href="Control.html#Control">Control</a></li>
-<li><a href="Combiners.html#index-g_t_0024vau-100"><code>$vau</code></a>: <a href="Combiners.html#Combiners">Combiners</a></li>
+<li><a href="Environments.html#index-g_t_0024set_0021-111"><code>$set!</code></a>: <a href="Environments.html#Environments">Environments</a></li>
+<li><a href="Combiners.html#index-g_t_0024vau-119"><code>$vau</code></a>: <a href="Combiners.html#Combiners">Combiners</a></li>
+<li><a href="Environments.html#index-g_t_0028-110"><code>(</code></a>: <a href="Environments.html#Environments">Environments</a></li>
<li><a href="Booleans.html#index-and_003f-15"><code>and?</code></a>: <a href="Booleans.html#Booleans">Booleans</a></li>
<li><a href="Pairs-and-lists.html#index-append-81"><code>append</code></a>: <a href="Pairs-and-lists.html#Pairs-and-lists">Pairs and lists</a></li>
<li><a href="Pairs-and-lists.html#index-append_0021-89"><code>append!</code></a>: <a href="Pairs-and-lists.html#Pairs-and-lists">Pairs and lists</a></li>
<li><a href="A-Sample-Applicative-Description.html#index-applicative-descriptions-8">applicative descriptions</a>: <a href="A-Sample-Applicative-Description.html#A-Sample-Applicative-Description">A Sample Applicative Description</a></li>
-<li><a href="Combiners.html#index-applicative_003f-99"><code>applicative?</code></a>: <a href="Combiners.html#Combiners">Combiners</a></li>
-<li><a href="Combiners.html#index-applicatives-96">applicatives</a>: <a href="Combiners.html#Combiners">Combiners</a></li>
-<li><a href="Combiners.html#index-apply-104"><code>apply</code></a>: <a href="Combiners.html#Combiners">Combiners</a></li>
+<li><a href="Combiners.html#index-applicative_003f-118"><code>applicative?</code></a>: <a href="Combiners.html#Combiners">Combiners</a></li>
+<li><a href="Combiners.html#index-applicatives-115">applicatives</a>: <a href="Combiners.html#Combiners">Combiners</a></li>
+<li><a href="Combiners.html#index-apply-123"><code>apply</code></a>: <a href="Combiners.html#Combiners">Combiners</a></li>
<li><a href="Pairs-and-lists.html#index-assoc-84"><code>assoc</code></a>: <a href="Pairs-and-lists.html#Pairs-and-lists">Pairs and lists</a></li>
<li><a href="Pairs-and-lists.html#index-assq-91"><code>assq</code></a>: <a href="Pairs-and-lists.html#Pairs-and-lists">Pairs and lists</a></li>
<li><a href="Booleans.html#index-boolean_003f-13"><code>boolean?</code></a>: <a href="Booleans.html#Booleans">Booleans</a></li>
@@ -83,8 +96,8 @@ Up: <a rel="up" accesskey="u" href="index.html#Top">Top</a>
<li><a href="Pairs-and-lists.html#index-cdddr-58"><code>cdddr</code></a>: <a href="Pairs-and-lists.html#Pairs-and-lists">Pairs and lists</a></li>
<li><a href="Pairs-and-lists.html#index-cddr-50"><code>cddr</code></a>: <a href="Pairs-and-lists.html#Pairs-and-lists">Pairs and lists</a></li>
<li><a href="Pairs-and-lists.html#index-cdr-46"><code>cdr</code></a>: <a href="Pairs-and-lists.html#Pairs-and-lists">Pairs and lists</a></li>
-<li><a href="Combiners.html#index-combiner_003f-106"><code>combiner?</code></a>: <a href="Combiners.html#Combiners">Combiners</a></li>
-<li><a href="Combiners.html#index-combiners-95">combiners</a>: <a href="Combiners.html#Combiners">Combiners</a></li>
+<li><a href="Combiners.html#index-combiner_003f-125"><code>combiner?</code></a>: <a href="Combiners.html#Combiners">Combiners</a></li>
+<li><a href="Combiners.html#index-combiners-114">combiners</a>: <a href="Combiners.html#Combiners">Combiners</a></li>
<li><a href="Pairs-and-lists.html#index-cons-39"><code>cons</code></a>: <a href="Pairs-and-lists.html#Pairs-and-lists">Pairs and lists</a></li>
<li><a href="Control.html#index-control-26">control</a>: <a href="Control.html#Control">Control</a></li>
<li><a href="Pairs-and-lists.html#index-copy_002des-90"><code>copy-es</code></a>: <a href="Pairs-and-lists.html#Pairs-and-lists">Pairs and lists</a></li>
@@ -94,19 +107,23 @@ Up: <a rel="up" accesskey="u" href="index.html#Top">Top</a>
<li><a href="Evaluation-Notation.html#index-documentation-notation-4">documentation notation</a>: <a href="Evaluation-Notation.html#Evaluation-Notation">Evaluation Notation</a></li>
<li><a href="Pairs-and-lists.html#index-empty-list-35">empty list</a>: <a href="Pairs-and-lists.html#Pairs-and-lists">Pairs and lists</a></li>
<li><a href="Pairs-and-lists.html#index-encycle_0021-77"><code>encycle!</code></a>: <a href="Pairs-and-lists.html#Pairs-and-lists">Pairs and lists</a></li>
+<li><a href="Environments.html#index-environment_003f-95"><code>environment?</code></a>: <a href="Environments.html#Environments">Environments</a></li>
<li><a href="Environments.html#index-environments-93">environments</a>: <a href="Environments.html#Environments">Environments</a></li>
<li><a href="Equivalence.html#index-eq_003f-20"><code>eq?</code></a>: <a href="Equivalence.html#Equivalence">Equivalence</a></li>
<li><a href="Equivalence.html#index-equal_003f-21"><code>equal?</code></a>: <a href="Equivalence.html#Equivalence">Equivalence</a></li>
<li><a href="Equivalence.html#index-equivalence-19">equivalence</a>: <a href="Equivalence.html#Equivalence">Equivalence</a></li>
<li><a href="Error-Messages.html#index-error-message-notation-6">error message notation</a>: <a href="Error-Messages.html#Error-Messages">Error Messages</a></li>
+<li><a href="Environments.html#index-eval-97"><code>eval</code></a>: <a href="Environments.html#Environments">Environments</a></li>
<li><a href="Evaluation-Notation.html#index-evaluation-notation-3">evaluation notation</a>: <a href="Evaluation-Notation.html#Evaluation-Notation">Evaluation Notation</a></li>
<li><a href="Pairs-and-lists.html#index-filter-83"><code>filter</code></a>: <a href="Pairs-and-lists.html#Pairs-and-lists">Pairs and lists</a></li>
<li><a href="Pairs-and-lists.html#index-finite_002dlist_003f-86"><code>finite-list?</code></a>: <a href="Pairs-and-lists.html#Pairs-and-lists">Pairs and lists</a></li>
<li><a href="Some-Terms.html#index-fonts-2">fonts</a>: <a href="Some-Terms.html#Some-Terms">Some Terms</a></li>
<li><a href="A-Sample-Applicative-Description.html#index-foo-11"><code>foo</code></a>: <a href="A-Sample-Applicative-Description.html#A-Sample-Applicative-Description">A Sample Applicative Description</a></li>
<li><a href="Control.html#index-for_002deach-32"><code>for-each</code></a>: <a href="Control.html#Control">Control</a></li>
+<li><a href="Environments.html#index-get_002dcurrent_002denvironment-102"><code>get-current-environment</code></a>: <a href="Environments.html#Environments">Environments</a></li>
<li><a href="Pairs-and-lists.html#index-get_002dlist_002dmetrics-75"><code>get-list-metrics</code></a>: <a href="Pairs-and-lists.html#Pairs-and-lists">Pairs and lists</a></li>
<li><a href="Environments.html#index-ignore-94">ignore</a>: <a href="Environments.html#Environments">Environments</a></li>
+<li><a href="Environments.html#index-ignore_003f-96"><code>ignore?</code></a>: <a href="Environments.html#Environments">Environments</a></li>
<li><a href="Control.html#index-inert-27">inert</a>: <a href="Control.html#Control">Control</a></li>
<li><a href="Control.html#index-inert_003f-28"><code>inert?</code></a>: <a href="Control.html#Control">Control</a></li>
<li><a href="Kernel-History.html#index-Kernel-history-1">Kernel history</a>: <a href="Kernel-History.html#Kernel-History">Kernel History</a></li>
@@ -117,7 +134,9 @@ Up: <a rel="up" accesskey="u" href="index.html#Top">Top</a>
<li><a href="Pairs-and-lists.html#index-list_002dref-80"><code>list-ref</code></a>: <a href="Pairs-and-lists.html#Pairs-and-lists">Pairs and lists</a></li>
<li><a href="Pairs-and-lists.html#index-list_002dtail-76"><code>list-tail</code></a>: <a href="Pairs-and-lists.html#Pairs-and-lists">Pairs and lists</a></li>
<li><a href="Pairs-and-lists.html#index-lists-36">lists</a>: <a href="Pairs-and-lists.html#Pairs-and-lists">Pairs and lists</a></li>
-<li><a href="Combiners.html#index-map-105"><code>map</code></a>: <a href="Combiners.html#Combiners">Combiners</a></li>
+<li><a href="Environments.html#index-make_002denvironment-98"><code>make-environment</code></a>: <a href="Environments.html#Environments">Environments</a></li>
+<li><a href="Environments.html#index-make_002dkernel_002dstandard_002denvironment-103"><code>make-kernel-standard-environment</code></a>: <a href="Environments.html#Environments">Environments</a></li>
+<li><a href="Combiners.html#index-map-124"><code>map</code></a>: <a href="Combiners.html#Combiners">Combiners</a></li>
<li><a href="Pairs-and-lists.html#index-map-78"><code>map</code></a>: <a href="Pairs-and-lists.html#Pairs-and-lists">Pairs and lists</a></li>
<li><a href="Pairs-and-lists.html#index-member_003f-85"><code>member?</code></a>: <a href="Pairs-and-lists.html#Pairs-and-lists">Pairs and lists</a></li>
<li><a href="Pairs-and-lists.html#index-memq_003f-92"><code>memq?</code></a>: <a href="Pairs-and-lists.html#Pairs-and-lists">Pairs and lists</a></li>
@@ -126,8 +145,8 @@ Up: <a rel="up" accesskey="u" href="index.html#Top">Top</a>
<li><a href="Pairs-and-lists.html#index-null_003f-38"><code>null?</code></a>: <a href="Pairs-and-lists.html#Pairs-and-lists">Pairs and lists</a></li>
<li><a href="A-Sample-Applicative-Description.html#index-object-descriptions-10">object descriptions</a>: <a href="A-Sample-Applicative-Description.html#A-Sample-Applicative-Description">A Sample Applicative Description</a></li>
<li><a href="A-Sample-Applicative-Description.html#index-operative-descriptions-9">operative descriptions</a>: <a href="A-Sample-Applicative-Description.html#A-Sample-Applicative-Description">A Sample Applicative Description</a></li>
-<li><a href="Combiners.html#index-operative_003f-98"><code>operative?</code></a>: <a href="Combiners.html#Combiners">Combiners</a></li>
-<li><a href="Combiners.html#index-operatives-97">operatives</a>: <a href="Combiners.html#Combiners">Combiners</a></li>
+<li><a href="Combiners.html#index-operative_003f-117"><code>operative?</code></a>: <a href="Combiners.html#Combiners">Combiners</a></li>
+<li><a href="Combiners.html#index-operatives-116">operatives</a>: <a href="Combiners.html#Combiners">Combiners</a></li>
<li><a href="Booleans.html#index-or_003f-16"><code>or?</code></a>: <a href="Booleans.html#Booleans">Booleans</a></li>
<li><a href="Pairs-and-lists.html#index-pair_003f-37"><code>pair?</code></a>: <a href="Pairs-and-lists.html#Pairs-and-lists">Pairs and lists</a></li>
<li><a href="Pairs-and-lists.html#index-pairs-33">pairs</a>: <a href="Pairs-and-lists.html#Pairs-and-lists">Pairs and lists</a></li>
@@ -139,8 +158,8 @@ Up: <a rel="up" accesskey="u" href="index.html#Top">Top</a>
<li><a href="Symbols.html#index-symbol_002d_003estring-24"><code>symbol->string</code></a>: <a href="Symbols.html#Symbols">Symbols</a></li>
<li><a href="Symbols.html#index-symbol_003f-23"><code>symbol?</code></a>: <a href="Symbols.html#Symbols">Symbols</a></li>
<li><a href="Symbols.html#index-symbols-22">symbols</a>: <a href="Symbols.html#Symbols">Symbols</a></li>
-<li><a href="Combiners.html#index-unwrap-102"><code>unwrap</code></a>: <a href="Combiners.html#Combiners">Combiners</a></li>
-<li><a href="Combiners.html#index-wrap-101"><code>wrap</code></a>: <a href="Combiners.html#Combiners">Combiners</a></li>
+<li><a href="Combiners.html#index-unwrap-121"><code>unwrap</code></a>: <a href="Combiners.html#Combiners">Combiners</a></li>
+<li><a href="Combiners.html#index-wrap-120"><code>wrap</code></a>: <a href="Combiners.html#Combiners">Combiners</a></li>
</ul><!-- Print the tables of contents -->
<div class="shortcontents">
diff --git a/manual/html/Pairs-and-lists.html b/manual/html/Pairs-and-lists.html
@@ -60,14 +60,14 @@ modulo whitespace, external representation <code>(1 2 3)</code>.
<div class="defun">
— Applicative: <b>pair?</b> (<var>pair? . objects</var>)<var><a name="index-pair_003f-37"></a></var><br>
-<blockquote><p> The primitive type predicate for type pair. <code>pair?</code>
-returns true iff all the objects in <code>objects</code> are of type pair.
+<blockquote><p> The primitive type predicate for type pair. <code>pair?</code> returns
+true iff all the objects in <code>objects</code> are of type pair.
</p></blockquote></div>
<div class="defun">
— Applicative: <b>null?</b> (<var>null? . objects</var>)<var><a name="index-null_003f-38"></a></var><br>
-<blockquote><p> The primitive type predicate for type null. <code>null?</code>
-returns true iff all the objects in <code>objects</code> are of type null.
+<blockquote><p> The primitive type predicate for type null. <code>null?</code> returns
+true iff all the objects in <code>objects</code> are of type null.
</p></blockquote></div>
<div class="defun">
diff --git a/manual/klisp.info b/manual/klisp.info
@@ -537,11 +537,11 @@ object with external representation `(1 . (2 . (3 . ())))' would be
output using, modulo whitespace, external representation `(1 2 3)'.
-- Applicative: pair? (pair? . objects)
- The primitive type predicate for type pair. `pair?' returns true
+ The primitive type predicate for type pair. `pair?' returns true
iff all the objects in `objects' are of type pair.
-- Applicative: null? (null? . objects)
- The primitive type predicate for type null. `null?' returns true
+ The primitive type predicate for type null. `null?' returns true
iff all the objects in `objects' are of type null.
-- Applicative: cons (cons object1 object2)
@@ -857,6 +857,220 @@ File: klisp.info, Node: Environments, Next: Combiners, Prev: Pairs and lists,
7 Environments
**************
+An environment consists of a set of bindings, and a list of zero or
+more references to other environments called its parents. Changing the
+set of bindings of an environment, or setting the referent of the
+reference in a binding, is a mutation of the environment. (Changing the
+parent list, or a referent in the list, would be a mutation of the
+environment too, but there is no facility provided to do it.) The
+Kernel data type environment is encapsulated. Among other things,
+there is no facility provided for enumerating all the variables
+exhibited by an environment (which is not required, after all, to be a
+finite set), and no facility for identifying the parents of an
+environment. Two environments are `equal?' iff they are `eq?'.
+
+ An auxiliary data type used by combiners that perform binding is
+ignore. The ignore type consists of a single immutable value, having
+external representation `#ignore'. The ignore type is encapsulated.
+
+ -- Applicative: environment? (environment? . objects)
+ The primitive type predicate for type environment. `environment?'
+ returns true iff all the objects in `objects' are of type
+ environment.
+
+ -- Applicative: ignore? (ignore? . objects)
+ The primitive type predicate for type ignore. `ignore?' returns
+ true iff all the objects in `objects' are of type ignore.
+
+ -- Applicative: eval (eval expression environment)
+ The `eval' applicative evaluates `expression' as a tail context in
+ `environment', and returns the resulting value.
+
+ -- Applicative: make-environment (make-environment . environments)
+ The applicative constructs and returns a new environment, with
+ initially no local bindings, and parent environments the
+ environments listed in `environments'. The constructed environment
+ internally stores its list of parents independent of the
+ first-class list `environments', so that subsequent mutation of
+ `environments' will not change the parentage of the constructed
+ environment. If the provided list `environments' is cyclic, the
+ constructed environment will still check each of its parents at
+ most once, and signal an error if no binding is found locally or
+ in any of the parents. No two objects returned by different calls
+ to `make-environment' are `eq?' to each other.
+
+ -- Operative: $define! ($define! <definiend> <expression>)
+ `<definiend>' should be a formal parameter tree, as described
+ below; otherwise, an error is signaled.
+
+ The `$define!' operative evaluates `<expression>' in the dynamic
+ environment and matches `<definiend>' to the result in the dynamic
+ environment, binding each symbol in definiend in the dynamic
+ environment to the corresponding part of the result; the matching
+ process will be further described below. The ancestors of the
+ dynamic environment, if any, are unaffected by the matching
+ process, as are all bindings, local to the dynamic environment, of
+ symbols not in `<definiend>'. The result returned by `$define!' is
+ inert.
+
+ A formal parameter tree has the following context-free structure:
+ ptree:: symbol | #ignore | () | (ptree . ptree)
+
+ That is, a formal parameter tree is either a symbol, or ignore, or
+ nil, or a pair whose car and cdr referents are formal parameter
+ trees. A formal parameter tree must also be acyclic, and no one
+ symbol can occur more than once in it. It is not an error for a
+ pair in the tree to be reachable from the root by more than one
+ path, as long as there is no cycle; but if any particular symbol
+ were reachable from the root by more than one path, that would
+ count as occurring more than once. Thus, if a pair is reachable
+ by more than one path, there must be no symbols reachable from it.
+
+ Matching of a formal parameter tree `t' to an object `o' in an
+ environment `e' proceeds recursively as follows. If the matching
+ process fails, an error is signaled.
+ * If `t' is a symbol, then `t' is bound to `o' in `e'.
+
+ * If `t' is `#ignore', no action is taken.
+
+ * If `t' is nil, then `o' must be nil (else matching fails).
+
+ * If `t' is a pair, then `o' must be a pair (else matching
+ fails). The car of `t' is matched to the car of `o' in `e',
+ and the cdr of `t' is matched to the cdr of `o' in `e'.
+
+ -- Operative: $let ($let <bindings> . <objects>)
+ `<bindings>' should be a finite list of
+ formal-parameter-tree/expression pairings, each of the form
+ `(formals expression)', where each `formals' is a formal
+ parameter, and no symbol occurs in more than one of the `formals'.
+
+ The following equivalence holds:
+
+ ($let ((form1 exp1) ... (formn expn)) . objects) ==
+ (($lambda (form1 ... formn) . objects) exp1 ... expn)
+
+ Thus, the `expk' are first evaluated in the dynamic environment,
+ in any order; then a child environment `e' of the dynamic
+ environment is created, with the `formk' matched in `e' to the
+ results of the evaluations of the `expk'; and finally the
+ subexpressions of `objects' are evaluated in `e' from left to
+ right, with the last (if any) evaluated as a tail context, or if
+ `objects' is empty the result is inert.
+
+ -- Operative: $binds? ($binds? <exp> . <symbols>)
+ Operative `$binds' evaluates `<exp>' in the dynamic environment;
+ call the result `env'. `env' must be an environment. The
+ operative is a predicate that returns true iff all its later
+ operands, `<symbols>', are visibly bound in `env'.
+
+ -- Applicative: get-current-environment (get-current-environment)
+ The `get-current-environment' applicative returns the dynamic
+ environment in which it is called.
+
+ -- Applicative: make-kernel-standard-environment
+ (make-kernel-standard-environment)
+ The `make-kernel-standard-environment' applicative returns a
+ standard environment; that is, a child of the ground environment
+ with no local bindings.
+
+ -- Operative: $let* ($let* <bindings> . <body>)
+ `<bindings>' should be a finite list of
+ formal-parameter-tree/expression pairings, each of the form
+ `(formals expression)', where each `formals' is a formal parameter
+ tree; `<body>' should be a list of expressions.
+
+ The following equivalences hold:
+
+ ($let* () . body) == ($let () . body)
+
+ ($let* ((form exp) . bindings) . body) ==
+ ($let ((form exp)) ($let* bindings . body))
+
+ -- Operative: $letrec ($letrec <bindings> . <body>)
+ `<bindings>' and `<body>' should be as described for `$let'.
+
+ The following equivalence holds:
+ ($letrec ((form1 exp1) ... (formn expn)) . body) ==
+ ($let () ($define! (form1 ... formn) (list exp1 ... expn)) . body)
+
+ -- Operative: $letrec* ($letrec* <bindings> . <body>)
+ `<bindings>' and `<body>' should be as described for `$let*'.
+
+ The following equivalences hold:
+ ($letrec* () . body) == ($letrec () . body)
+
+ ($letrec* ((form exp) . bindings) . body) ==
+ ($letrec ((form exp)) ($letrec* bindings . body))
+
+ -- Operative: $let-redirect ($let-redirect <exp> <bindings> . <body>)
+ `<bindings>' and `<body>' should be as described for `$let'.
+
+ The following equivalence holds:
+
+ ($let-redirect exp ((form1 exp1) ... (formn . body) expn)) ==
+ ((eval (list $lambda (form1 ... formn) body) exp) expn ... expn)
+
+ -- Operative: $let-safe ($let-safe <bindings> . <body>)
+ `<bindings>' and `<body>' should be as described for `$let'.
+
+ The following equivalence holds:
+
+ ($let-safe bindings . body) ==
+ ($let-redirect (make-kernel-standard-environment) bindings . body)
+
+ -- Operative: $remote-eval ($remote-eval <exp1> <exp2>)
+ Operative `$remote-eval' evaluates `<exp2>' in the dynamic
+ environment, then evaluates `<exp1>' as a tail context in the
+ environment that must result from the first evaluation.
+
+ -- Operative: ($bindings-environment . <bindings>)
+ `<bindings>' should be as described for `$let'.
+
+ The following equivalence holds:
+
+ ($bindings->environment . bindings) ==
+ ($let-redirect (make-environment) bindings (get-current-environment))
+
+ -- Operative: $set! ($set! <exp1> <formals> <exp2>)
+ `<formals>' should be as described for the `$define!' operative.
+ The `$set!' operative evaluates `<exp1>' and `<exp2>' in the
+ dynamic environment; call the results `env' and `obj'. If `env'
+ is not an environment, an error is signaled. Then the operative
+ matches `<formals>' to `obj' in environment `env'. Thus, the
+ symbols of `<formals>' are bound in `env' to the corresponding
+ parts of `obj'. The result returned by `$set!' is inert.
+
+ -- Operative: $provide! ($provide! <symbols> . <body>)
+ `<symbols>' must be a finite list of symbols, containing no
+ duplicates. `<body>' must be a finite list.
+
+ The `$provide!' operative constructs a child `e' of the dynamic
+ environment `d'; evaluates the elements of `<body>' in `e', from
+ left to right, discarding all of the results; and exports all of
+ the bindings of symbols in `<symbols>' from `e' to `d', i.e.,
+ binds each symbol in `d' to the result of looking it up in `e'.
+ The result returned by `$provide!' is inert.
+
+ The following equivalence holds:
+
+ ($provide! symbols . body) ==
+ ($define! symbols ($let () ($sequence . body) (list . symbols)))
+
+ -- Operative: $import! ($import! <exp> . <symbols>)
+ `<symbols>' must be a list of symbols.
+
+ The `$import!' operative evaluates `<exp>' in the dynamic
+ environment; call the result `env'. `env' must be an environment.
+ Each distinct symbol `s' in `<symbols>' is evaluated in `env', and
+ `s' is bound in the dynamic environment to the result of this
+ evaluation.
+
+ The following equivalence holds:
+
+ ($import! exp . symbols) ==
+ ($define! symbols ($remote-eval (list symbols) exp))
+
File: klisp.info, Node: Combiners, Next: Index, Prev: Environments, Up: Top
@@ -883,16 +1097,16 @@ combiners are `equal?' iff they are `eq?'.
applicative.
-- Operative: $vau ($vau <formals> <eformal> . <objects>)
- `formals' should be a formal parameter tree; `eformal' should be
- either a symbol or `#ignore'. If `formals' does not have the
- correct form for a formal parameter tree, or if `eformal' is a
- symbol that also occurs in `formals', an error is signaled.
+ `<formals>' should be a formal parameter tree; `<eformal>' should
+ be either a symbol or `#ignore'. If `<formals>' does not have the
+ correct form for a formal parameter tree, or if `<eformal>' is a
+ symbol that also occurs in `<formals>', an error is signaled.
A `vau' expression evaluates to an operative; an operative created
in this way is said to be compound. The environment in which the
`vau' expression was evaluated is remembered as part of the
compound operative, called the compound operative’s static
- environment. `formals' and `objects' are copied as by
+ environment. `<formals>' and `<objects>' are copied as by
`copy-es-immutable' and the copies are stored as part of the
operative being constructed. This avoids problem if these
structures are later mutated.
@@ -912,10 +1126,10 @@ combiners are `equal?' iff they are `eq?'.
that is, if eformal is a symbol then that symbol is bound in
the local environment to the dynamic environment.
- 3. A stored copy of the expressions is evaluated sequentially in
- the local environment as if by `$sequence'. In particular,
- if there is a last expression, it is evaluated in a tail
- context.
+ 3. A stored copy of the expressions is evaluated sequentially
+ from left to right, with the last (if any) evaluated as a
+ tail context, or if the list of expressions is empty, the
+ result is inert.
NOTE: Because compound operatives are not a distinct type in
Kernel, they are covered by the encapsulation of type operative.
@@ -932,8 +1146,8 @@ combiners are `equal?' iff they are `eq?'.
The `unwrap' applicative returns the underlying combiner of
`applicative'.
- -- Operative: $lambda ($lambda formals . objects)
- `formals' should be a formal parameter tree.
+ -- Operative: $lambda ($lambda <formals> . <objects>)
+ `<formals>' should be a formal parameter tree.
The `$lambda' operative is defined by the following equivalence:
($lambda formals . objects) ==
@@ -991,12 +1205,25 @@ Index
* Menu:
* $and?: Booleans. (line 28)
+* $binds?: Environments. (line 108)
* $cond: Control. (line 32)
+* $define!: Environments. (line 49)
* $if: Control. (line 15)
+* $import!: Environments. (line 207)
* $lambda: Combiners. (line 76)
+* $let: Environments. (line 89)
+* $let*: Environments. (line 124)
+* $let-redirect: Environments. (line 153)
+* $let-safe: Environments. (line 161)
+* $letrec: Environments. (line 137)
+* $letrec*: Environments. (line 144)
* $or?: Booleans. (line 41)
+* $provide!: Environments. (line 191)
+* $remote-eval: Environments. (line 169)
* $sequence: Control. (line 23)
+* $set!: Environments. (line 182)
* $vau: Combiners. (line 26)
+* (: Environments. (line 174)
* and?: Booleans. (line 20)
* append: Pairs and lists. (line 208)
* append!: Pairs and lists. (line 306)
@@ -1051,11 +1278,13 @@ Index
* documentation notation: Evaluation Notation. (line 6)
* empty list: Pairs and lists. (line 6)
* encycle!: Pairs and lists. (line 158)
+* environment?: Environments. (line 23)
* environments: Environments. (line 6)
* eq?: Equivalence. (line 12)
* equal?: Equivalence. (line 16)
* equivalence: Equivalence. (line 6)
* error message notation: Error Messages. (line 6)
+* eval: Environments. (line 32)
* evaluation notation: Evaluation Notation. (line 6)
* filter: Pairs and lists. (line 239)
* finite-list?: Pairs and lists. (line 261)
@@ -1063,8 +1292,10 @@ Index
* foo: A Sample Applicative Description.
(line 15)
* for-each: Control. (line 42)
+* get-current-environment: Environments. (line 114)
* get-list-metrics: Pairs and lists. (line 123)
* ignore: Environments. (line 6)
+* ignore?: Environments. (line 28)
* inert: Control. (line 6)
* inert?: Control. (line 11)
* Kernel history: Kernel History. (line 6)
@@ -1075,6 +1306,8 @@ Index
* list-ref: Pairs and lists. (line 198)
* list-tail: Pairs and lists. (line 147)
* lists: Pairs and lists. (line 6)
+* make-environment: Environments. (line 36)
+* make-kernel-standard-environment: Environments. (line 119)
* map <1>: Combiners. (line 96)
* map: Pairs and lists. (line 169)
* member?: Pairs and lists. (line 257)
@@ -1123,8 +1356,8 @@ Node: Equivalence16800
Node: Symbols17593
Node: Control18958
Node: Pairs and lists21275
-Node: Environments38296
-Node: Combiners38420
-Node: Index44424
+Node: Environments38298
+Node: Combiners48505
+Node: Index54533
End Tag Table
diff --git a/manual/src/combiners.texi b/manual/src/combiners.texi
@@ -34,17 +34,17 @@ operative.
@deffn Operative $vau ($vau <formals> <eformal> . <objects>)
@c TODO add xref to formal parameter tree
-@code{formals} should be a formal parameter tree; @code{eformal}
-should be either a symbol or @code{#ignore}. If @code{formals} does
+@code{<formals>} should be a formal parameter tree; @code{<eformal>}
+should be either a symbol or @code{#ignore}. If @code{<formals>} does
not have the correct form for a formal parameter tree, or if
-@code{eformal} is a symbol that also occurs in @code{formals}, an
-error is signaled.
+@code{<eformal>} is a symbol that also occurs in @code{<formals>}, an
+error is signaled.
A @code{vau} expression evaluates to an operative; an operative
created in this way is said to be compound. The environment in which
the @code{vau} expression was evaluated is remembered as part of the compound
operative, called the compound operative’s static environment.
-@code{formals} and @code{objects} are copied as by
+@code{<formals>} and @code{<objects>} are copied as by
@code{copy-es-immutable} and the copies are stored as part of the
operative being constructed. This avoids problem if these structures
are later mutated.
@@ -69,11 +69,10 @@ then that symbol is bound in the local environment to the dynamic
environment.
@item
-A stored copy of the expressions is evaluated sequentially in the
-@c TODO add xref to sequence
-local environment as if by @code{$sequence}. In particular, if there
@c TODO add xref to tail context.
-is a last expression, it is evaluated in a tail context.
+A stored copy of the expressions is evaluated sequentially from left
+to right, with the last (if any) evaluated as a tail context, or if
+the list of expressions is empty, the result is inert.
@end enumerate
NOTE: Because compound operatives are not a distinct type in Kernel,
@@ -95,8 +94,8 @@ combiner is @code{combiner}.
@code{applicative}.
@end deffn
-@deffn Operative $lambda ($lambda formals . objects)
- @code{formals} should be a formal parameter tree.
+@deffn Operative $lambda ($lambda <formals> . <objects>)
+ @code{<formals>} should be a formal parameter tree.
The @code{$lambda} operative is defined by the following equivalence:
@example
diff --git a/manual/src/environments.texi b/manual/src/environments.texi
@@ -8,3 +8,291 @@
@cindex environments
@cindex ignore
+ An environment consists of a set of bindings, and a list of zero or
+more references to other environments called its parents.
+@c TODO add xref to lookup algo & ground env
+Changing the set of bindings of an environment, or setting the
+referent of the reference in a binding, is a mutation of the
+environment. (Changing the parent list, or a referent in the list,
+would be a mutation of the environment too, but there is no facility
+provided to do it.) The Kernel data type environment is encapsulated.
+Among other things, there is no facility provided for enumerating all
+the variables exhibited by an environment (which is not required,
+after all, to be a finite set), and no facility for identifying the
+parents of an environment. Two environments are @code{equal?} iff
+they are @code{eq?}.
+
+ An auxiliary data type used by combiners that perform binding is
+ignore. The ignore type consists of a single immutable value, having
+external representation @code{#ignore}. The ignore type is
+encapsulated.
+
+@deffn Applicative environment? (environment? . objects)
+ The primitive type predicate for type environment.
+@code{environment?} returns true iff all the objects in @code{objects}
+are of type environment.
+@end deffn
+
+@deffn Applicative ignore? (ignore? . objects)
+ The primitive type predicate for type ignore. @code{ignore?}
+returns true iff all the objects in @code{objects} are of type ignore.
+@end deffn
+
+@deffn Applicative eval (eval expression environment)
+@c TODO add xref to tail context
+@c TODO add xref to evaluation description
+ The @code{eval} applicative evaluates @code{expression} as a tail
+context in @code{environment}, and returns the resulting value.
+@end deffn
+
+@deffn Applicative make-environment (make-environment . environments)
+ The applicative constructs and returns a new environment, with
+initially no local bindings, and parent environments the environments
+listed in @code{environments}. The constructed environment internally
+stores its list of parents independent of the first-class list
+@code{environments}, so that subsequent mutation of
+@code{environments} will not change the parentage of the constructed
+environment. If the provided list @code{environments} is cyclic, the
+constructed environment will still check each of its parents at most
+once, and signal an error if no binding is found locally or in any of
+@c TODO add xref to cons, mutation, eq? and equal?
+the parents. No two objects returned by different calls to
+@code{make-environment} are @code{eq?} to each other.
+@end deffn
+
+@deffn Operative $define! ($define! <definiend> <expression>)
+@c TODO move formal parameter tree definition to the intro
+@c TODO move matching definition to the intro
+ @code{<definiend>} should be a formal parameter tree, as described
+below; otherwise, an error is signaled.
+
+ The @code{$define!} operative evaluates @code{<expression>} in the
+dynamic environment and matches @code{<definiend>} to the result in
+the dynamic environment, binding each symbol in definiend in the
+dynamic environment to the corresponding part of the result; the
+matching process will be further described below. The ancestors of the
+dynamic environment, if any, are unaffected by the matching process,
+as are all bindings, local to the dynamic environment, of symbols not
+in @code{<definiend>}. The result returned by @code{$define!} is
+inert.
+
+ A formal parameter tree has the following context-free structure:
+@example
+ptree:: symbol | #ignore | () | (ptree . ptree)
+@end example
+
+ That is, a formal parameter tree is either a symbol, or ignore, or
+nil, or a pair whose car and cdr referents are formal parameter trees.
+A formal parameter tree must also be acyclic, and no one symbol can
+occur more than once in it. It is not an error for a pair in the tree
+to be reachable from the root by more than one path, as long as there
+is no cycle; but if any particular symbol were reachable from the root
+by more than one path, that would count as occurring more than once.
+Thus, if a pair is reachable by more than one path, there must be no
+symbols reachable from it.
+
+ Matching of a formal parameter tree @code{t} to an object @code{o}
+in an environment @code{e} proceeds recursively as follows. If the
+matching process fails, an error is signaled.
+@itemize @bullet
+@item
+If @code{t} is a symbol, then @code{t} is bound to @code{o} in
+@code{e}.
+
+@item
+If @code{t} is @code{#ignore}, no action is taken.
+
+@item
+If @code{t} is nil, then @code{o} must be nil (else matching fails).
+
+@item
+If @code{t} is a pair, then @code{o} must be a pair (else matching
+fails). The car of @code{t} is matched to the car of @code{o} in
+@code{e}, and the cdr of @code{t} is matched to the cdr of @code{o} in
+@code{e}.
+@end itemize
+@end deffn
+
+@deffn Operative $let ($let <bindings> . <objects>)
+@c TODO add xref to formal parameter tree
+ @code{<bindings>} should be a finite list of
+formal-parameter-tree/expression pairings, each of the form
+@code{(formals expression)}, where each @code{formals} is a formal
+parameter, and no symbol occurs in more than one of the
+@code{formals}.
+
+The following equivalence holds:
+
+@example
+($let ((form1 exp1) ... (formn expn)) . objects) @equiv{}
+ (($lambda (form1 ... formn) . objects) exp1 ... expn)
+@end example
+
+@c TODO add xref to tail context
+Thus, the @code{expk} are first evaluated in the dynamic environment,
+in any order; then a child environment @code{e} of the dynamic
+environment is created, with the @code{formk} matched in @code{e} to
+the results of the evaluations of the @code{expk}; and finally the
+subexpressions of @code{objects} are evaluated in @code{e} from left
+to right, with the last (if any) evaluated as a tail context, or if
+@code{objects} is empty the result is inert.
+@end deffn
+
+@deffn Operative $binds? ($binds? <exp> . <symbols>)
+ Operative @code{$binds} evaluates @code{<exp>} in the dynamic
+environment; call the result @code{env}. @code{env} must be an
+environment. The operative is a predicate that returns true iff all
+its later operands, @code{<symbols>}, are visibly bound in @code{env}.
+@end deffn
+
+@deffn Applicative get-current-environment (get-current-environment)
+ The @code{get-current-environment} applicative returns the dynamic
+environment in which it is called.
+@end deffn
+
+@deffn Applicative make-kernel-standard-environment (make-kernel-standard-environment)
+@c TODO add xref to ground environment/standard environment
+ The @code{make-kernel-standard-environment} applicative returns a
+standard environment; that is, a child of the ground environment with
+no local bindings.
+@end deffn
+
+@deffn Operative $let* ($let* <bindings> . <body>)
+@c TODO add xref to formal ptree
+ @code{<bindings>} should be a finite list of
+formal-parameter-tree/expression pairings, each of the form
+@code{(formals expression)}, where each @code{formals} is a formal
+parameter tree; @code{<body>} should be a list of expressions.
+
+The following equivalences hold:
+
+@example
+($let* () . body) @equiv{} ($let () . body)
+
+($let* ((form exp) . bindings) . body) @equiv{}
+ ($let ((form exp)) ($let* bindings . body))
+@end example
+@end deffn
+
+@deffn Operative $letrec ($letrec <bindings> . <body>)
+@c add xref for $let
+ @code{<bindings>} and @code{<body>} should be as described for
+@code{$let}.
+
+ The following equivalence holds:
+@example
+($letrec ((form1 exp1) ... (formn expn)) . body) @equiv{}
+ ($let () ($define! (form1 ... formn) (list exp1 ... expn)) . body)
+@end example
+@end deffn
+
+@deffn Operative $letrec* ($letrec* <bindings> . <body>)
+@c TODO add xref to $let*
+ @code{<bindings>} and @code{<body>} should be as described for
+@code{$let*}.
+
+ The following equivalences hold:
+@example
+($letrec* () . body) @equiv{} ($letrec () . body)
+
+($letrec* ((form exp) . bindings) . body) @equiv{}
+ ($letrec ((form exp)) ($letrec* bindings . body))
+@end example
+@end deffn
+
+@deffn Operative $let-redirect ($let-redirect <exp> <bindings> . <body>)
+@c TODO add xref to $let
+ @code{<bindings>} and @code{<body>} should be as described for
+@code{$let}.
+
+ The following equivalence holds:
+
+@example
+($let-redirect exp ((form1 exp1) ... (formn . body) expn)) @equiv{}
+ ((eval (list $lambda (form1 ... formn) body) exp) expn ... expn)
+@end example
+@end deffn
+
+@deffn Operative $let-safe ($let-safe <bindings> . <body>)
+@c TODO add xref to $let
+ @code{<bindings>} and @code{<body>} should be as described for
+@code{$let}.
+
+ The following equivalence holds:
+
+@example
+($let-safe bindings . body) @equiv{}
+ ($let-redirect (make-kernel-standard-environment) bindings . body)
+@end example
+@end deffn
+
+@deffn Operative $remote-eval ($remote-eval <exp1> <exp2>)
+@c TODO add xref to tail context
+ Operative @code{$remote-eval} evaluates @code{<exp2>} in the dynamic
+environment, then evaluates @code{<exp1>} as a tail context in the
+environment that must result from the first evaluation.
+@end deffn
+
+@deffn Operative ($bindings-environment . <bindings>)
+@c TODO add xref to $let
+ @code{<bindings>} should be as described for @code{$let}.
+
+ The following equivalence holds:
+
+@example
+($bindings->environment . bindings) @equiv{}
+ ($let-redirect (make-environment) bindings (get-current-environment))
+@end example
+@end deffn
+
+@deffn Operative $set! ($set! <exp1> <formals> <exp2>)
+@c TODO add xref to $define!
+@c TODO add xref to matching algo
+ @code{<formals>} should be as described for the @code{$define!}
+operative. The @code{$set!} operative evaluates @code{<exp1>} and
+@code{<exp2>} in the dynamic environment; call the results @code{env}
+and @code{obj}. If @code{env} is not an environment, an error is
+signaled. Then the operative matches @code{<formals>} to @code{obj}
+in environment @code{env}. Thus, the symbols of @code{<formals>} are
+bound in @code{env} to the corresponding parts of @code{obj}.
+The result returned by @code{$set!} is inert.
+@end deffn
+
+@deffn Operative $provide! ($provide! <symbols> . <body>)
+ @code{<symbols>} must be a finite list of symbols, containing no
+duplicates. @code{<body>} must be a finite list.
+
+ The @code{$provide!} operative constructs a child @code{e} of the
+dynamic environment @code{d}; evaluates the elements of @code{<body>}
+in @code{e}, from left to right, discarding all of the results; and
+exports all of the bindings of symbols in @code{<symbols>} from
+@code{e} to @code{d}, i.e., binds each symbol in @code{d} to the
+result of looking it up in @code{e}. The result returned by
+@code{$provide!} is inert.
+
+The following equivalence holds:
+
+@example
+($provide! symbols . body) @equiv{}
+($define! symbols ($let () ($sequence . body) (list . symbols)))
+@end example
+@end deffn
+
+@deffn Operative $import! ($import! <exp> . <symbols>)
+ @code{<symbols>} must be a list of symbols.
+
+ The @code{$import!} operative evaluates @code{<exp>} in the dynamic
+environment; call the result @code{env}. @code{env} must be an
+environment. Each distinct symbol @code{s} in @code{<symbols>} is
+evaluated in @code{env}, and @code{s} is bound in the dynamic
+environment to the result of this evaluation.
+
+The following equivalence holds:
+
+@example
+($import! exp . symbols) @equiv{}
+($define! symbols ($remote-eval (list symbols) exp))
+@end example
+@end deffn
+
+
diff --git a/manual/src/pairs_lists.texi b/manual/src/pairs_lists.texi
@@ -34,13 +34,13 @@ representation @code{(1 . (2 . (3 . ())))} would be output using,
modulo whitespace, external representation @code{(1 2 3)}.
@deffn Applicative pair? (pair? . objects)
- The primitive type predicate for type pair. @code{pair?}
-returns true iff all the objects in @code{objects} are of type pair.
+ The primitive type predicate for type pair. @code{pair?} returns
+true iff all the objects in @code{objects} are of type pair.
@end deffn
@deffn Applicative null? (null? . objects)
- The primitive type predicate for type null. @code{null?}
-returns true iff all the objects in @code{objects} are of type null.
+ The primitive type predicate for type null. @code{null?} returns
+true iff all the objects in @code{objects} are of type null.
@end deffn
@deffn Applicative cons (cons object1 object2)