klisp

an open source interpreter for the Kernel Programming Language.
git clone http://git.hanabi.in/repos/klisp.git
Log | Files | Refs | README

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:
Mmanual/html/Combiners.html | 39+++++++++++++++++++--------------------
Mmanual/html/Environments.html | 289++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Mmanual/html/Index.html | 43+++++++++++++++++++++++++++++++------------
Mmanual/html/Pairs-and-lists.html | 8++++----
Mmanual/klisp.info | 265++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-----
Mmanual/src/combiners.texi | 21++++++++++-----------
Mmanual/src/environments.texi | 288+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Mmanual/src/pairs_lists.texi | 8++++----
8 files changed, 894 insertions(+), 67 deletions(-)

diff --git a/manual/html/Combiners.html b/manual/html/Combiners.html @@ -34,7 +34,7 @@ Up:&nbsp;<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"> -&mdash; Applicative: <b>operative?</b> (<var>operative? . objects</var>)<var><a name="index-operative_003f-98"></a></var><br> +&mdash; 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"> -&mdash; Applicative: <b>applicative?</b> (<var>applicative? . objects</var>)<var><a name="index-applicative_003f-99"></a></var><br> +&mdash; 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"> -&mdash; Operative: <b>$vau</b> (<var>$vau &lt;formals&gt; &lt;eformal&gt; . &lt;objects&gt;</var>)<var><a name="index-g_t_0024vau-100"></a></var><br> +&mdash; Operative: <b>$vau</b> (<var>$vau &lt;formals&gt; &lt;eformal&gt; . &lt;objects&gt;</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>&lt;formals&gt;</code> should be a formal parameter tree; <code>&lt;eformal&gt;</code> +should be either a symbol or <code>#ignore</code>. If <code>&lt;formals&gt;</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>&lt;eformal&gt;</code> is a symbol that also occurs in <code>&lt;formals&gt;</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>&lt;formals&gt;</code> and <code>&lt;objects&gt;</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"> -&mdash; Applicative: <b>wrap</b> (<var>wrap combiner</var>)<var><a name="index-wrap-101"></a></var><br> +&mdash; 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"> -&mdash; Applicative: <b>unwrap</b> (<var>unwrap applicative</var>)<var><a name="index-unwrap-102"></a></var><br> +&mdash; 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"> -&mdash; 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. +&mdash; Operative: <b>$lambda</b> (<var>$lambda &lt;formals&gt; . &lt;objects&gt;</var>)<var><a name="index-g_t_0024lambda-122"></a></var><br> +<blockquote><p> <code>&lt;formals&gt;</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"> -&mdash; Applicative: <b>apply</b> (<var>apply applicative object </var>[<var>environment</var>])<var><a name="index-apply-104"></a></var><br> +&mdash; 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"> -&mdash; Applicative: <b>map</b> (<var>map applicative . lists</var>)<var><a name="index-map-105"></a></var><br> +&mdash; 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"> -&mdash; Applicative: <b>combiner?</b> (<var>combiner? . objects</var>)<var><a name="index-combiner_003f-106"></a></var><br> +&mdash; 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:&nbsp;<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"> +&mdash; 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"> +&mdash; 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"> +&mdash; 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"> +&mdash; 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"> +&mdash; Operative: <b>$define!</b> (<var>$define! &lt;definiend&gt; &lt;expression&gt;</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>&lt;definiend&gt;</code> should be a formal parameter tree, as described +below; otherwise, an error is signaled. + + <p>The <code>$define!</code> operative evaluates <code>&lt;expression&gt;</code> in the +dynamic environment and matches <code>&lt;definiend&gt;</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>&lt;definiend&gt;</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"> +&mdash; Operative: <b>$let</b> (<var>$let &lt;bindings&gt; . &lt;objects&gt;</var>)<var><a name="index-g_t_0024let-100"></a></var><br> +<blockquote><!-- TODO add xref to formal parameter tree --> + <p><code>&lt;bindings&gt;</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"> +&mdash; Operative: <b>$binds?</b> (<var>$binds? &lt;exp&gt; . &lt;symbols&gt;</var>)<var><a name="index-g_t_0024binds_003f-101"></a></var><br> +<blockquote><p> Operative <code>$binds</code> evaluates <code>&lt;exp&gt;</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>&lt;symbols&gt;</code>, are visibly bound in <code>env</code>. +</p></blockquote></div> + +<div class="defun"> +&mdash; 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"> +&mdash; 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"> +&mdash; Operative: <b>$let*</b> (<var>$let* &lt;bindings&gt; . &lt;body&gt;</var>)<var><a name="index-g_t_0024let_002a-104"></a></var><br> +<blockquote><!-- TODO add xref to formal ptree --> + <p><code>&lt;bindings&gt;</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>&lt;body&gt;</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"> +&mdash; Operative: <b>$letrec</b> (<var>$letrec &lt;bindings&gt; . &lt;body&gt;</var>)<var><a name="index-g_t_0024letrec-105"></a></var><br> +<blockquote><!-- add xref for $let --> + <p><code>&lt;bindings&gt;</code> and <code>&lt;body&gt;</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"> +&mdash; Operative: <b>$letrec*</b> (<var>$letrec* &lt;bindings&gt; . &lt;body&gt;</var>)<var><a name="index-g_t_0024letrec_002a-106"></a></var><br> +<blockquote><!-- TODO add xref to $let* --> + <p><code>&lt;bindings&gt;</code> and <code>&lt;body&gt;</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"> +&mdash; Operative: <b>$let-redirect</b> (<var>$let-redirect &lt;exp&gt; &lt;bindings&gt; . &lt;body&gt;</var>)<var><a name="index-g_t_0024let_002dredirect-107"></a></var><br> +<blockquote><!-- TODO add xref to $let --> + <p><code>&lt;bindings&gt;</code> and <code>&lt;body&gt;</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"> +&mdash; Operative: <b>$let-safe</b> (<var>$let-safe &lt;bindings&gt; . &lt;body&gt;</var>)<var><a name="index-g_t_0024let_002dsafe-108"></a></var><br> +<blockquote><!-- TODO add xref to $let --> + <p><code>&lt;bindings&gt;</code> and <code>&lt;body&gt;</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"> +&mdash; Operative: <b>$remote-eval</b> (<var>$remote-eval &lt;exp1&gt; &lt;exp2&gt;</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>&lt;exp2&gt;</code> in the dynamic +environment, then evaluates <code>&lt;exp1&gt;</code> as a tail context in the +environment that must result from the first evaluation. +</p></blockquote></div> + +<div class="defun"> +&mdash; Operative: <b>(</b><var>$bindings-environment . &lt;bindings&gt;</var>)<var><a name="index-g_t_0028-110"></a></var><br> +<blockquote><!-- TODO add xref to $let --> + <p><code>&lt;bindings&gt;</code> should be as described for <code>$let</code>. + + <p>The following equivalence holds: + + <pre class="example"> ($bindings-&gt;environment . bindings) == + ($let-redirect (make-environment) bindings (get-current-environment)) +</pre> + </blockquote></div> + +<div class="defun"> +&mdash; Operative: <b>$set!</b> (<var>$set! &lt;exp1&gt; &lt;formals&gt; &lt;exp2&gt;</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>&lt;formals&gt;</code> should be as described for the <code>$define!</code> +operative. The <code>$set!</code> operative evaluates <code>&lt;exp1&gt;</code> and +<code>&lt;exp2&gt;</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>&lt;formals&gt;</code> to <code>obj</code> +in environment <code>env</code>. Thus, the symbols of <code>&lt;formals&gt;</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"> +&mdash; Operative: <b>$provide!</b> (<var>$provide! &lt;symbols&gt; . &lt;body&gt;</var>)<var><a name="index-g_t_0024provide_0021-112"></a></var><br> +<blockquote><p> <code>&lt;symbols&gt;</code> must be a finite list of symbols, containing no +duplicates. <code>&lt;body&gt;</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>&lt;body&gt;</code> +in <code>e</code>, from left to right, discarding all of the results; and +exports all of the bindings of symbols in <code>&lt;symbols&gt;</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"> +&mdash; Operative: <b>$import!</b> (<var>$import! &lt;exp&gt; . &lt;symbols&gt;</var>)<var><a name="index-g_t_0024import_0021-113"></a></var><br> +<blockquote><p> <code>&lt;symbols&gt;</code> must be a list of symbols. + + <p>The <code>$import!</code> operative evaluates <code>&lt;exp&gt;</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>&lt;symbols&gt;</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:&nbsp;<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:&nbsp;<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:&nbsp;<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:&nbsp;<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:&nbsp;<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:&nbsp;<a rel="up" accesskey="u" href="index.html#Top">Top</a> <li><a href="Symbols.html#index-symbol_002d_003estring-24"><code>symbol-&gt;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"> &mdash; 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"> &mdash; 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)