klisp

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

commit 7aadeb3c65db6898a4a3928500c86be93859ce91
parent cf67df5db1708dc2dacd5d2f951604a270ab04ed
Author: Andres Navarro <canavarro82@gmail.com>
Date:   Wed,  1 Jun 2011 20:04:25 -0300

Completed combiners module for the manual. Manual Bugfix: added missing texi files (environments and combiners) and all missing html files (almost all sections... derp)

Diffstat:
M.hgignore | 1+
Amanual/html/Booleans.html | 102+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Amanual/html/Combiners.html | 192+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Amanual/html/Control.html | 99+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Amanual/html/Environments.html | 41+++++++++++++++++++++++++++++++++++++++++
Amanual/html/Equivalence.html | 61+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Mmanual/html/Index.html | 9+++++++++
Amanual/html/Pairs-and-lists.html | 466+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Amanual/html/Symbols.html | 75+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Mmanual/klisp.info | 129++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
Amanual/src/combiners.texi | 157+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Amanual/src/environments.texi | 10++++++++++
12 files changed, 1341 insertions(+), 1 deletion(-)

diff --git a/.hgignore b/.hgignore @@ -1,4 +1,5 @@ syntax: glob *.o +*.a klisp diff --git a/manual/html/Booleans.html b/manual/html/Booleans.html @@ -0,0 +1,102 @@ +<html lang="en"> +<head> +<title>Booleans - klisp Reference Manual</title> +<meta http-equiv="Content-Type" content="text/html"> +<meta name="description" content="klisp Reference Manual"> +<meta name="generator" content="makeinfo 4.13"> +<link title="Top" rel="start" href="index.html#Top"> +<link rel="prev" href="Introduction.html#Introduction" title="Introduction"> +<link rel="next" href="Equivalence.html#Equivalence" title="Equivalence"> +<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage"> +<meta http-equiv="Content-Style-Type" content="text/css"> +<style type="text/css"><!-- + pre.display { font-family:inherit } + pre.format { font-family:inherit } + pre.smalldisplay { font-family:inherit; font-size:smaller } + pre.smallformat { font-family:inherit; font-size:smaller } + pre.smallexample { font-size:smaller } + pre.smalllisp { font-size:smaller } + span.sc { font-variant:small-caps } + span.roman { font-family:serif; font-weight:normal; } + span.sansserif { font-family:sans-serif; font-weight:normal; } +--></style> +</head> +<body> +<div class="node"> +<a name="Booleans"></a> +<p> +Next:&nbsp;<a rel="next" accesskey="n" href="Equivalence.html#Equivalence">Equivalence</a>, +Previous:&nbsp;<a rel="previous" accesskey="p" href="Introduction.html#Introduction">Introduction</a>, +Up:&nbsp;<a rel="up" accesskey="u" href="index.html#Top">Top</a> +<hr> +</div> + +<!-- node-name, next, previous, up --> +<h2 class="chapter">2 Booleans</h2> + +<p><a name="index-booleans-12"></a> + The boolean data type consists of two values, which are called true +and false, and have respectively external representations <code>#t</code> +and <code>#f</code>. There are no possible mutations of either of these two +<!-- add encapsulated cross ref --> +values, and the boolean type is encapsulated. + +<div class="defun"> +&mdash; Applicative: <b>boolean?</b> (<var>boolean? . objects</var>)<var><a name="index-boolean_003f-13"></a></var><br> +<blockquote><p> The primitive type predicate for type boolean. <code>boolean?</code> +returns true iff all the objects in <code>objects</code> are of type boolean. +</p></blockquote></div> + +<div class="defun"> +&mdash; Applicative: <b>not?</b> (<var>not? boolean</var>)<var><a name="index-not_003f-14"></a></var><br> +<blockquote><p> Applicative <code>not?</code> is a predicate that returns the logical +negation of its argument. +</p></blockquote></div> + +<div class="defun"> +&mdash; Applicative: <b>and?</b> (<var>and? . booleans</var>)<var><a name="index-and_003f-15"></a></var><br> +<blockquote><p> Applicative <code>and?</code> is a predicate that returns true unless one +or more of its arguments are false. +</p></blockquote></div> + +<div class="defun"> +&mdash; Applicative: <b>or?</b> (<var>or? . booleans</var>)<var><a name="index-or_003f-16"></a></var><br> +<blockquote><p> Applicative <code>or?</code> is a predicate that returns false unless one +or more of its arguments are true. +</p></blockquote></div> + +<div class="defun"> +&mdash; Operative: <b>$and?</b> (<var>$and? . &lt;list&gt;</var>)<var><a name="index-g_t_0024and_003f-17"></a></var><br> +<blockquote><p> The <code>$and?</code> operative performs a &ldquo;short-circuit and&rdquo; of its +operands. It evaluates them from left to right, until either an +operand evaluates to false, or the end of the list is reached. If the +end of the list is reached (which is immediate if <code>&lt;list&gt;</code> is +<code>nil</code>), the operative returns true. If an operand evaluates to +false, no further operand evaluations are performed, and the operative +returns false. If <code>&lt;list&gt;</code> is acyclic, and the last operand is +<!-- TODO cross ref tail-contect --> +evaluated, it is evaluated as a tail context. If <code>&lt;list&gt;</code> is +cyclic, an unbounded number of operand evaluations may be +performed. If any of the operands evaluates to a non-boolean value, an +error is signaled (even if it's the last one). +</p></blockquote></div> + +<div class="defun"> +&mdash; Operative: <b>$or?</b> (<var>$or? . &lt;list&gt;</var>)<var><a name="index-g_t_0024or_003f-18"></a></var><br> +<blockquote><p> The <code>$or?</code> operative performs a &ldquo;short-circuit or&rdquo; of its +operands. It evaluates them from left to right, until either an +operand evaluates to true, or the end of the list is reached. If the +end of the list is reached (which is immediate if <code>&lt;list&gt;</code> is +<code>nil</code>), the operative returns false. If an operand evaluates to +true, no further operand evaluations are performed, and the operative +returns true. If <code>&lt;list&gt;</code> is acyclic, and the last operand is +<!-- TODO cross ref tail-context --> +evaluated, it is evaluated as a tail context. If <code>&lt;list&gt;</code> is +cyclic, an unbounded number of operand evaluations may be +performed. If any of the operands evaluates to a non-boolean value, an +error is signaled (even if it's the last one). +</p></blockquote></div> + +<!-- *-texinfo-*- --> + </body></html> + diff --git a/manual/html/Combiners.html b/manual/html/Combiners.html @@ -0,0 +1,192 @@ +<html lang="en"> +<head> +<title>Combiners - klisp Reference Manual</title> +<meta http-equiv="Content-Type" content="text/html"> +<meta name="description" content="klisp Reference Manual"> +<meta name="generator" content="makeinfo 4.13"> +<link title="Top" rel="start" href="index.html#Top"> +<link rel="prev" href="Environments.html#Environments" title="Environments"> +<link rel="next" href="Index.html#Index" title="Index"> +<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage"> +<meta http-equiv="Content-Style-Type" content="text/css"> +<style type="text/css"><!-- + pre.display { font-family:inherit } + pre.format { font-family:inherit } + pre.smalldisplay { font-family:inherit; font-size:smaller } + pre.smallformat { font-family:inherit; font-size:smaller } + pre.smallexample { font-size:smaller } + pre.smalllisp { font-size:smaller } + span.sc { font-variant:small-caps } + span.roman { font-family:serif; font-weight:normal; } + span.sansserif { font-family:sans-serif; font-weight:normal; } +--></style> +</head> +<body> +<div class="node"> +<a name="Combiners"></a> +<p> +Next:&nbsp;<a rel="next" accesskey="n" href="Index.html#Index">Index</a>, +Previous:&nbsp;<a rel="previous" accesskey="p" href="Environments.html#Environments">Environments</a>, +Up:&nbsp;<a rel="up" accesskey="u" href="index.html#Top">Top</a> +<hr> +</div> + +<!-- 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> + 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 +<code>eq?</code>. However, <code>eq?</code>-ness of operatives is only +constrained by the general rules for <code>eq?</code>, which leave +considerable leeway for variation between implementations. klisp only +considers <code>eq?</code> those operatives constructed by the same call to +a constructor (e.g. <code>$vau</code>). Two combiners are <code>equal?</code> +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> +<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> +<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> +<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 +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 +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>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. + + <!-- TODO add xref to eval or apply as example --> + <p>When the compound operative created by <code>$vau</code> is later called +with an object and an environment, here called respectively the +operand tree and the dynamic environment, the following happens: + + <ol type=1 start=1> +<li>A new, initially empty environment is created, with the static +environment as its parent. This will be called the local environment. + + <li>A stored copy of the formal parameter tree formals is matched in the +local environment to the operand tree, locally binding the symbols of +<!-- TODO add xref to matching --> +formals to the corresponding parts of the operand tree. eformal is +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. + </ol> + + <p>NOTE: Because compound operatives are not a distinct type in Kernel, +they are covered by the encapsulation of type operative. In +particular, an implementation of Kernel cannot provide a feature that +supports extracting the static environment of any given compound +operative, nor that supports determining whether or not a given +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> +<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> +<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. + + <p>The <code>$lambda</code> operative is defined by the following equivalence: + <pre class="example"> ($lambda formals . objects) == + (wrap ($vau formals #ignore . objects)) +</pre> + </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> +<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 +empty environment (if the short form is used). + + <p>The following equivalences hold: + <pre class="example"> (apply applicative object environment) == + (eval (cons (unwrap applicative) object) environment) + + (apply applicative object) == + (apply applicative object (make-environment)) +</pre> + </blockquote></div> + +<div class="defun"> +&mdash; Applicative: <b>map</b> (<var>map applicative . lists</var>)<var><a name="index-map-105"></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 +if all of its elements are not lists of the same length, an error is +signaled. + + <p>The <code>map</code> applicative applies <code>applicative</code> element-wise +to the elements of the lists in <code>lists</code> (i.e., applies it to a +list of the first elements of the <code>lists</code>, to a list of the +second elements of the <code>lists</code>, etc.), using the dynamic +environment from which <code>map</code> was called, and returns a list of +the results, in order. The applications may be performed in any order, +as long as their results occur in the resultant list in the order of +their arguments in the original <code>lists</code>. If <code>lists</code> is a +cyclic list, each argument list to which <code>applicative</code> is applied +is structurally isomorphic to <code>lists</code>. If any of the elements of +<code>lists</code> is a cyclic list, they all must be, or they wouldn’t all +have the same length. Let <code>a1...an</code> be their acyclic prefix +lengths, and <code>c1...cn</code> be their cycle lengths. The acyclic +prefix length <code>a</code> of the resultant list will be the maximum of +the <code>ak</code>, while the cycle length <code>c</code> of the resultant list +will be the least common multiple of the <code>ck</code>. In the +construction of the result, applicative is called exactly <code>a + c</code> +times. +<!-- TODO comp/xref for-each --> +</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> +<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). +</p></blockquote></div> + +<!-- appendices --> +<!-- TODO --> +<!-- *-texinfo-*- --> +<!-- TODO correct prev node --> + </body></html> + diff --git a/manual/html/Control.html b/manual/html/Control.html @@ -0,0 +1,99 @@ +<html lang="en"> +<head> +<title>Control - klisp Reference Manual</title> +<meta http-equiv="Content-Type" content="text/html"> +<meta name="description" content="klisp Reference Manual"> +<meta name="generator" content="makeinfo 4.13"> +<link title="Top" rel="start" href="index.html#Top"> +<link rel="prev" href="Symbols.html#Symbols" title="Symbols"> +<link rel="next" href="Pairs-and-lists.html#Pairs-and-lists" title="Pairs and lists"> +<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage"> +<meta http-equiv="Content-Style-Type" content="text/css"> +<style type="text/css"><!-- + pre.display { font-family:inherit } + pre.format { font-family:inherit } + pre.smalldisplay { font-family:inherit; font-size:smaller } + pre.smallformat { font-family:inherit; font-size:smaller } + pre.smallexample { font-size:smaller } + pre.smalllisp { font-size:smaller } + span.sc { font-variant:small-caps } + span.roman { font-family:serif; font-weight:normal; } + span.sansserif { font-family:sans-serif; font-weight:normal; } +--></style> +</head> +<body> +<div class="node"> +<a name="Control"></a> +<p> +Next:&nbsp;<a rel="next" accesskey="n" href="Pairs-and-lists.html#Pairs-and-lists">Pairs and lists</a>, +Previous:&nbsp;<a rel="previous" accesskey="p" href="Symbols.html#Symbols">Symbols</a>, +Up:&nbsp;<a rel="up" accesskey="u" href="index.html#Top">Top</a> +<hr> +</div> + +<!-- node-name, next, previous, up --> +<h2 class="chapter">5 Control</h2> + +<p><a name="index-control-26"></a><a name="index-inert-27"></a> The inert data type is provided for use with control combiners. It +consists of a single immutable value, having external representation +<code>#inert</code>. The inert type is encapsulated. + +<div class="defun"> +&mdash; Applicative: <b>inert?</b> (<var>inert? . objects</var>)<var><a name="index-inert_003f-28"></a></var><br> +<blockquote><p> The primitive type predicate for type inert. <code>inert?</code> +returns true iff all the objects in <code>objects</code> are of type inert. +</p></blockquote></div> + +<div class="defun"> +&mdash; Operative: <b>$if</b> (<var>$if &lt;test&gt; &lt;consequent&gt; &lt;alternative&gt;</var>)<var><a name="index-g_t_0024if-29"></a></var><br> +<blockquote><p> The <code>$if</code> operative first evaluates <code>&lt;test&gt;</code> in the +dynamic environment. If the result is not of type boolean, an error +is signaled. If the result is true, <code>&lt;consequent&gt;</code> is then +<!-- TODO add xref to tail context --> +evaluated in the dynamic environment as a tail context. Otherwise, +<code>&lt;alternative&gt;</code> is evaluated in the dynamic environment as a tail +context. +</p></blockquote></div> + +<div class="defun"> +&mdash; Operative: <b>$sequence</b> (<var>$sequence . &lt;objects&gt;</var>)<var><a name="index-g_t_0024sequence-30"></a></var><br> +<blockquote><p>The <code>$sequence</code> operative evaluates the elements of the list +<code>&lt;objects&gt;</code> in the dynamic environment, one at a time from left +to right. If <code>&lt;objects&gt;</code> is a cyclic list, element evaluation +continues indefinitely, with elements in the cycle being evaluated +repeatedly. If <code>&lt;objects&gt;</code> is a nonempty finite list, its last +<!-- TODO add xref for tail context. --> +element is evaluated as a tail context. If <code>&lt;objects&gt;</code> is the +empty list, the result is inert. +</p></blockquote></div> + +<div class="defun"> +&mdash; Operative: <b>$cond</b> (<var>$cond . &lt;clauses&gt;</var>)<var><a name="index-g_t_0024cond-31"></a></var><br> +<blockquote><p><code>&lt;clauses&gt;</code> should be a list of clause expressions, each of the +form <code>(&lt;test&gt; . &lt;body&gt;)</code>, where body is a list of expressions. + + <p>The following equivalences define +the behaviour of the <code>$cond</code> operative: + <pre class="example"> ($cond) == #inert + ($cond (&lt;test&gt; . &lt;body&gt;) . &lt;clauses&gt;) == + ($if &lt;test&gt; ($sequence . &lt;body&gt;) ($cond . &lt;clauses&gt;)) +</pre> + </blockquote></div> + +<div class="defun"> +&mdash; Applicative: <b>for-each</b> (<var>for-each . lists</var>)<var><a name="index-for_002deach-32"></a></var><br> +<blockquote><p><code>lists</code> must be a nonempty list of lists; if there are two or +more, they should all be the same length. If lists is empty, or if all +of its elements are not lists of the same length, an error is +signaled. + + <!-- TODO add xref to map --> + <p><code>for-each</code> behaves identically to <code>map</code>, except that instead +of accumulating and returning a list of the results of the +element-wise applications, the results of the applications are +discarded and the result returned by <code>for-each</code> is inert. +</p></blockquote></div> + +<!-- *-texinfo-*- --> + </body></html> + diff --git a/manual/html/Environments.html b/manual/html/Environments.html @@ -0,0 +1,41 @@ +<html lang="en"> +<head> +<title>Environments - klisp Reference Manual</title> +<meta http-equiv="Content-Type" content="text/html"> +<meta name="description" content="klisp Reference Manual"> +<meta name="generator" content="makeinfo 4.13"> +<link title="Top" rel="start" href="index.html#Top"> +<link rel="prev" href="Pairs-and-lists.html#Pairs-and-lists" title="Pairs and lists"> +<link rel="next" href="Combiners.html#Combiners" title="Combiners"> +<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage"> +<meta http-equiv="Content-Style-Type" content="text/css"> +<style type="text/css"><!-- + pre.display { font-family:inherit } + pre.format { font-family:inherit } + pre.smalldisplay { font-family:inherit; font-size:smaller } + pre.smallformat { font-family:inherit; font-size:smaller } + pre.smallexample { font-size:smaller } + pre.smalllisp { font-size:smaller } + span.sc { font-variant:small-caps } + span.roman { font-family:serif; font-weight:normal; } + span.sansserif { font-family:sans-serif; font-weight:normal; } +--></style> +</head> +<body> +<div class="node"> +<a name="Environments"></a> +<p> +Next:&nbsp;<a rel="next" accesskey="n" href="Combiners.html#Combiners">Combiners</a>, +Previous:&nbsp;<a rel="previous" accesskey="p" href="Pairs-and-lists.html#Pairs-and-lists">Pairs and lists</a>, +Up:&nbsp;<a rel="up" accesskey="u" href="index.html#Top">Top</a> +<hr> +</div> + +<!-- node-name, next, previous, up --> +<h2 class="chapter">7 Environments</h2> + +<p><a name="index-environments-93"></a><a name="index-ignore-94"></a> + +<!-- *-texinfo-*- --> + </body></html> + diff --git a/manual/html/Equivalence.html b/manual/html/Equivalence.html @@ -0,0 +1,61 @@ +<html lang="en"> +<head> +<title>Equivalence - klisp Reference Manual</title> +<meta http-equiv="Content-Type" content="text/html"> +<meta name="description" content="klisp Reference Manual"> +<meta name="generator" content="makeinfo 4.13"> +<link title="Top" rel="start" href="index.html#Top"> +<link rel="prev" href="Booleans.html#Booleans" title="Booleans"> +<link rel="next" href="Symbols.html#Symbols" title="Symbols"> +<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage"> +<meta http-equiv="Content-Style-Type" content="text/css"> +<style type="text/css"><!-- + pre.display { font-family:inherit } + pre.format { font-family:inherit } + pre.smalldisplay { font-family:inherit; font-size:smaller } + pre.smallformat { font-family:inherit; font-size:smaller } + pre.smallexample { font-size:smaller } + pre.smalllisp { font-size:smaller } + span.sc { font-variant:small-caps } + span.roman { font-family:serif; font-weight:normal; } + span.sansserif { font-family:sans-serif; font-weight:normal; } +--></style> +</head> +<body> +<div class="node"> +<a name="Equivalence"></a> +<p> +Next:&nbsp;<a rel="next" accesskey="n" href="Symbols.html#Symbols">Symbols</a>, +Previous:&nbsp;<a rel="previous" accesskey="p" href="Booleans.html#Booleans">Booleans</a>, +Up:&nbsp;<a rel="up" accesskey="u" href="index.html#Top">Top</a> +<hr> +</div> + +<!-- node-name, next, previous, up --> +<h2 class="chapter">3 Equivalence</h2> + +<p><a name="index-equivalence-19"></a> + Kernel has two general-purpose equivalence predicates (whereas R5RS +Scheme has three). The two Kernel predicates correspond to the +abstract notions of equivalence up to mutation (<code>equal</code>) and +equivalence in the presence of mutation (<code>eq?</code>). + +<div class="defun"> +&mdash; Applicative: <b>eq?</b> (<var>eq? . objects</var>)<var><a name="index-eq_003f-20"></a></var><br> +<blockquote><p> Predicate <code>eq?</code> returns true iff all of <code>objects</code> are +effectively the same object, even in the presence of mutation. +<!-- todo maybe add more content here, specifical to klisp --> +</p></blockquote></div> + +<div class="defun"> +&mdash; Applicative: <b>equal?</b> (<var>equal? . objects</var>)<var><a name="index-equal_003f-21"></a></var><br> +<blockquote><p> Predicate <code>equal?</code> returns true iff all of <code>objects</code> +&ldquo;look&rdquo; the same as long as nothing is mutated. This is a weaker +predicate than <code>eq?</code>; that is, <code>equal?</code> must return true +whenever <code>eq?</code> would return true. +<!-- todo maybe add more content here, specifical to klisp --> +</p></blockquote></div> + +<!-- *-texinfo-*- --> + </body></html> + diff --git a/manual/html/Index.html b/manual/html/Index.html @@ -38,13 +38,17 @@ Up:&nbsp;<a rel="up" accesskey="u" href="index.html#Top">Top</a> <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="Control.html#index-g_t_0024cond-31"><code>$cond</code></a>: <a href="Control.html#Control">Control</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="Booleans.html#index-g_t_0024or_003f-18"><code>$or?</code></a>: <a href="Booleans.html#Booleans">Booleans</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="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="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> @@ -79,6 +83,7 @@ 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="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> @@ -112,6 +117,7 @@ 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="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> @@ -120,6 +126,7 @@ 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="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> @@ -132,6 +139,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> </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 @@ -0,0 +1,466 @@ +<html lang="en"> +<head> +<title>Pairs and lists - klisp Reference Manual</title> +<meta http-equiv="Content-Type" content="text/html"> +<meta name="description" content="klisp Reference Manual"> +<meta name="generator" content="makeinfo 4.13"> +<link title="Top" rel="start" href="index.html#Top"> +<link rel="prev" href="Control.html#Control" title="Control"> +<link rel="next" href="Environments.html#Environments" title="Environments"> +<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage"> +<meta http-equiv="Content-Style-Type" content="text/css"> +<style type="text/css"><!-- + pre.display { font-family:inherit } + pre.format { font-family:inherit } + pre.smalldisplay { font-family:inherit; font-size:smaller } + pre.smallformat { font-family:inherit; font-size:smaller } + pre.smallexample { font-size:smaller } + pre.smalllisp { font-size:smaller } + span.sc { font-variant:small-caps } + span.roman { font-family:serif; font-weight:normal; } + span.sansserif { font-family:sans-serif; font-weight:normal; } +--></style> +</head> +<body> +<div class="node"> +<a name="Pairs-and-lists"></a> +<p> +Next:&nbsp;<a rel="next" accesskey="n" href="Environments.html#Environments">Environments</a>, +Previous:&nbsp;<a rel="previous" accesskey="p" href="Control.html#Control">Control</a>, +Up:&nbsp;<a rel="up" accesskey="u" href="index.html#Top">Top</a> +<hr> +</div> + +<!-- node-name, next, previous, up --> +<h2 class="chapter">6 Pairs and lists</h2> + +<p><a name="index-pairs-33"></a><a name="index-nil-34"></a><a name="index-empty-list-35"></a><a name="index-lists-36"></a> +A pair is an object that refers to two other objects, called its car +and cdr. The Kernel data type pair is encapsulated. + + <p>The null data type consists of a single immutable value, called nil +or the empty list and having external representation <code>()</code>, with +or without whitespace between the parentheses. It is immutable, and +the null type is encapsulated. + + <p>If <code>a</code> and <code>d</code> are external representations of +respectively the car and cdr of a pair <code>p</code>, then <code>(a . d)</code> +is an external representation of <code>p</code>. If the cdr of <code>p</code> is +nil, then <code>(a)</code> is also an external representation of +<code>p</code>. If the cdr of <code>p</code> is a pair <code>p2</code>, and <code>(r)</code> +is an external representation of <code>p2</code>, then <code>(a r)</code> is an +external representation of <code>p</code>. +<!-- add xref for write --> + When a pair is output (as by write), an external representation with +the fewest parentheses is used; in the case of a finite list, only one +set of parentheses is required beyond those used in representing the +elements of the list. For example, an object with external +representation <code>(1 . (2 . (3 . ())))</code> would be output using, +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. +</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. +</p></blockquote></div> + +<div class="defun"> +&mdash; Applicative: <b>cons</b> (<var>cons object1 object2</var>)<var><a name="index-cons-39"></a></var><br> +<blockquote><p> A new mutable pair object is constructed and returned, whose car and +cdr referents are respectively <code>object1</code> and <code>object2</code>. No +two objects returned by different calls to cons are <code>eq?</code> to each +other. +</p></blockquote></div> + +<div class="defun"> +&mdash; Applicative: <b>set-car!</b> (<var>set-car! pair object</var>)<var><a name="index-set_002dcar_0021-40"></a></var><br> +&mdash; Applicative: <b>set-cdr!</b> (<var>set-cdr! pair object</var>)<var><a name="index-set_002dcdr_0021-41"></a></var><br> +<blockquote><p> <code>pair</code> should be a mutable pair. + + <p>These applicatives set the referent of, respectively, the car +reference or the cdr reference of <code>pair</code> to <code>object</code>. The +result of the expression is inert. +</p></blockquote></div> + +<div class="defun"> +&mdash; Applicative: <b>copy-es-immutable!</b> (<var>copy-es-immutable object</var>)<var><a name="index-copy_002des_002dimmutable_0021-42"></a></var><br> +<blockquote><p> The short description of this applicative is that it returns an object +<code>equal?</code> to <code>object</code> with an immutable evaluation structure. The +&ldquo;-es-&rdquo; in the name is short for &ldquo;evaluation structure&rdquo;. + + <!-- TODO move the evaluation structure description to the intro --> + <p>The evaluation structure of an object <code>o</code> is defined to be the +set of all pairs that can be reached by following chains of references +from <code>o</code> without ever passing through a non-pair object. The +evaluation structure of a non-pair object is empty. + + <p>If <code>object</code> is not a pair, the applicative returns <code>object</code>. +Otherwise (if <code>object</code> is a pair), the applicative returns an +immutable pair whose car and cdr would be suitable results for +<code>(copy-es-immutable (car object))</code> and <code>(copy-es-immutable +(cdr object))</code>, respectively. Further, the evaluation structure of +<!-- TODO add xref for isomorphic (and add isomorphic to the intro) --> +the returned value is isomorphic to that of <code>object</code> at the time +of copying, with corresponding non-pair referents being <code>eq?</code>. + + <p>NOTE: In Kernel it's undefined whether immutable pairs are copied or +left &ldquo;as is&rdquo; in the result. klisp doesn't copy immutable pairs, but +that behaviour should not be depended upon. +</p></blockquote></div> + +<div class="defun"> +&mdash; Applicative: <b>list</b> (<var>list . objects</var>)<var><a name="index-list-43"></a></var><br> +<blockquote><p>The <code>list</code> applicative returns <code>objects</code>. + + <p>The underlying operative of <code>list</code> returns its undifferentiated +operand tree, regardless of whether that tree is or is not a list. +</p></blockquote></div> + +<div class="defun"> +&mdash; Applicative: <b>list*</b> (<var>list* . objects</var>)<var><a name="index-list_002a-44"></a></var><br> +<blockquote><p><code>objects</code> should be a finite nonempty list of arguments. + + <p>The following equivalences hold: + <pre class="example"> (list* arg1) == arg1 + (list* arg1 arg2 . args) == (cons arg1 (list* arg2 . args)) +</pre> + </blockquote></div> + +<div class="defun"> +&mdash; Applicative: <b>car</b> (<var>car pair</var>)<var><a name="index-car-45"></a></var><br> +&mdash; Applicative: <b>cdr</b> (<var>cdr pair</var>)<var><a name="index-cdr-46"></a></var><br> +<blockquote><p>These applicatives return, respectively, the car and cdr of <code>pair</code>. +</p></blockquote></div> + +<div class="defun"> +&mdash; Applicative: <b>caar</b> (<var>caar pair</var>)<var><a name="index-caar-47"></a></var><br> +&mdash; Applicative: <b>cadr</b> (<var>cadr pair</var>)<var><a name="index-cadr-48"></a></var><br> +&mdash; Applicative: <b>cdar</b> (<var>cdar pair</var>)<var><a name="index-cdar-49"></a></var><br> +&mdash; Applicative: <b>cddr</b> (<var>cddr pair</var>)<var><a name="index-cddr-50"></a></var><br> +&mdash; Applicative: <b>caaar</b> (<var>caaar pair</var>)<var><a name="index-caaar-51"></a></var><br> +&mdash; Applicative: <b>caadr</b> (<var>caadr pair</var>)<var><a name="index-caadr-52"></a></var><br> +&mdash; Applicative: <b>cadar</b> (<var>cadar pair</var>)<var><a name="index-cadar-53"></a></var><br> +&mdash; Applicative: <b>caddr</b> (<var>caddr pair</var>)<var><a name="index-caddr-54"></a></var><br> +&mdash; Applicative: <b>cdaar</b> (<var>cdaar pair</var>)<var><a name="index-cdaar-55"></a></var><br> +&mdash; Applicative: <b>cdadr</b> (<var>cdadr pair</var>)<var><a name="index-cdadr-56"></a></var><br> +&mdash; Applicative: <b>cddar</b> (<var>cddar pair</var>)<var><a name="index-cddar-57"></a></var><br> +&mdash; Applicative: <b>cdddr</b> (<var>cdddr pair</var>)<var><a name="index-cdddr-58"></a></var><br> +&mdash; Applicative: <b>caaaar</b> (<var>caaaar pair</var>)<var><a name="index-caaaar-59"></a></var><br> +&mdash; Applicative: <b>caaadr</b> (<var>caaadr pair</var>)<var><a name="index-caaadr-60"></a></var><br> +&mdash; Applicative: <b>caadar</b> (<var>caadar pair</var>)<var><a name="index-caadar-61"></a></var><br> +&mdash; Applicative: <b>caaddr</b> (<var>caaddr pair</var>)<var><a name="index-caaddr-62"></a></var><br> +&mdash; Applicative: <b>cadaar</b> (<var>cadaar pair</var>)<var><a name="index-cadaar-63"></a></var><br> +&mdash; Applicative: <b>cadadr</b> (<var>cadadr pair</var>)<var><a name="index-cadadr-64"></a></var><br> +&mdash; Applicative: <b>caddar</b> (<var>caddar pair</var>)<var><a name="index-caddar-65"></a></var><br> +&mdash; Applicative: <b>cadddr</b> (<var>cadddr pair</var>)<var><a name="index-cadddr-66"></a></var><br> +&mdash; Applicative: <b>cdaaar</b> (<var>cdaaar pair</var>)<var><a name="index-cdaaar-67"></a></var><br> +&mdash; Applicative: <b>cdaadr</b> (<var>cdaadr pair</var>)<var><a name="index-cdaadr-68"></a></var><br> +&mdash; Applicative: <b>cdadar</b> (<var>cdadar pair</var>)<var><a name="index-cdadar-69"></a></var><br> +&mdash; Applicative: <b>cdaddr</b> (<var>cdaddr pair</var>)<var><a name="index-cdaddr-70"></a></var><br> +&mdash; Applicative: <b>cddaar</b> (<var>cddaar pair</var>)<var><a name="index-cddaar-71"></a></var><br> +&mdash; Applicative: <b>cddadr</b> (<var>cddadr pair</var>)<var><a name="index-cddadr-72"></a></var><br> +&mdash; Applicative: <b>cdddar</b> (<var>cdddar pair</var>)<var><a name="index-cdddar-73"></a></var><br> +&mdash; Applicative: <b>cddddr</b> (<var>cddddr pair</var>)<var><a name="index-cddddr-74"></a></var><br> +<blockquote> + <!-- TODO add note about pronunciation --> + <p>These applicatives are compositions of <code>car</code> and <code>cdr</code>, with +the &ldquo;a’s&rdquo; and &ldquo;d’s&rdquo; in the same order as they would appear if all +the individual &ldquo;car’s&rdquo; and &ldquo;cdr’s&rdquo; were written out in prefix +order. Arbitrary compositions up to four deep are provided. There are +twenty-eight of these applicatives in all. +</p></blockquote></div> + +<div class="defun"> +&mdash; Applicative: <b>get-list-metrics</b> (<var>get-list-metrics object</var>)<var><a name="index-get_002dlist_002dmetrics-75"></a></var><br> +<blockquote><!-- TODO move definition of improper list to intro, xref data structure --> + <p>By definition, an improper list is a data structure whose objects +are its start together with all objects reachable from the start by +following the cdr references of pairs, and whose internal references +are just the cdr references of its pairs. Every object, of whatever +type, is the start of an improper list. If the start is not a pair, +the improper list consists of just that object. The acyclic prefix +length of an improper list <code>L</code> is the number of pairs of <code>L</code> +that a naive traversal of <code>L</code> would visit only once. The cycle +length of <code>L</code> is the number of pairs of <code>L</code> that a naive +traversal would visit repeatedly. Two improper lists are structurally +<!-- TODO add xref to isomorphic --> +isomorphic iff they have the same acyclic prefix length and cycle +length and, if they are terminated by non-pair objects rather than by +cycles, the non-pair objects have the same type. Applicative +<code>get-list-metrics</code> constructs and returns a list of exact +integers of the form <code>(p n a c)</code>, where <code>p</code>, <code>n</code>, +<code>a</code>, and <code>c</code> are, respectively, the number of pairs in, the +number of nil objects in, the acyclic prefix length of, and the cycle +length of, the improper list starting with <code>object</code>. <code>n</code> is +either <code>0</code> or <code>1</code>, <code>a + c = p</code>, and <code>n</code> and +<code>c</code> cannot both be non-zero. If <code>c = 0</code>, the improper list +is acyclic; if <code>n = 1</code>, the improper list is a finite list; if +<code>n = c = 0</code>, the improper list is not a list; if <code>a = c = +0</code>, <code>object</code> is not a pair. +</p></blockquote></div> + +<div class="defun"> +&mdash; Applicative: <b>list-tail</b> (<var>list-tail object k</var>)<var><a name="index-list_002dtail-76"></a></var><br> +<blockquote><p><code>object</code> must be the start of an improper list containing at +least <code>k</code> pairs. + + <p>The <code>list-tail</code> applicative follows <code>k</code> cdr references +starting from <code>object</code>. + + <p>The following equivalences hold: + <pre class="example"> (list-tail object 0) == object + (list-tail object (+ k 1)) == (list-tail (cdr object) k) +</pre> + </blockquote></div> + +<div class="defun"> +&mdash; Applicative: <b>encycle!</b> (<var>encycle! object k1 k2</var>)<var><a name="index-encycle_0021-77"></a></var><br> +<blockquote><p> The improper list starting at <code>object</code> must contain at least +<code>k1 + k2</code> pairs. + + <p>If <code>k2 = 0</code>, the applicative does nothing. If <code>k2 &gt; 0</code>, +the applicative mutates the improper list starting at <code>object</code> to +have acyclic prefix length <code>k1</code> and cycle length <code>k2</code>, by +setting the cdr of the <code>(k1+k2)</code>th pair in the list to refer to +the <code>(k1 + 1)</code>th pair in the list. The result returned by +<code>encycle!</code> is inert. +</p></blockquote></div> + +<div class="defun"> +&mdash; Applicative: <b>map</b> (<var>map applicative . lists</var>)<var><a name="index-map-78"></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. + + <p>The map applicative applies <code>applicative</code> element-wise to the +elements of the lists in lists (i.e., applies it to a list of the +first elements of the lists, to a list of the second elements of the +lists, etc.), using the dynamic environment from which map was called, +and returns a list of the results, in order. The applications may be +performed in any order, as long as their results occur in the +resultant list in the order of their arguments in the original lists. +If <code>lists</code> is a cyclic list, each argument list to which +<!-- TODO xref to ismorphic --> +<code>applicative</code> is applied is structurally isomorphic to <code>lists</code>. If +any of the elements of <code>lists</code> is a cyclic list, they all must +be, or they wouldn’t all have the same length. Let <code>a1...an</code> be +their acyclic prefix lengths, and <code>c1...cn</code> be their cycle +lengths. The acyclic prefix length <code>a</code> of the resultant list +will be the maximum of the <code>ak</code>, while the cycle length <code>c</code> +of the resultant list will be the least common multiple of the +<code>ck</code>. In the construction of the result, <code>applicative</code> is +called exactly <code>a + c</code> times. +</p></blockquote></div> + +<div class="defun"> +&mdash; Applicative: <b>length</b> (<var>length object</var>)<var><a name="index-length-79"></a></var><br> +<blockquote><!-- TODO xref improper-list --> + <p>Applicative <code>length</code> returns the (exact) improper-list length +of <code>object</code>. That is, it returns the number of consecutive cdr +references that can be followed starting from <code>object</code>. If +<code>object</code> is not a pair, it returns zero; if <code>object</code> is a +cyclic list, it returns positive infinity. +</p></blockquote></div> + +<div class="defun"> +&mdash; Applicative: <b>list-ref</b> (<var>list-ref object k</var>)<var><a name="index-list_002dref-80"></a></var><br> +<blockquote><p> The <code>list-ref</code> applicative returns the <code>car</code> of the object +obtained by following <code>k</code> cdr references starting from +<code>object</code>. + + <p>NOTE: In the current report, object is required to be a list. In +klisp, for now, we prefer the behaviour presented here, as it is more +in line with the applicative <code>list-tail</code>. That is, we define +<code>list-ref</code> by the following equivalence: + <pre class="example"> (list-ref object k) == (car (list-tail object k)) +</pre> + </blockquote></div> + +<div class="defun"> +&mdash; Applicative: <b>append</b> (<var>append . lists</var>)<var><a name="index-append-81"></a></var><br> +<blockquote><p> Here, all the elements of <code>lists</code> except the last element (if +any) must be acyclic lists. The <code>append</code> applicative returns a +freshly allocated list of the elements of all the specified +<code>lists</code>, in order, except that if there is a last specified +element of <code>lists</code>, it is not copied, but is simply referenced by +the cdr of the preceding pair (if any) in the resultant list. If +<code>lists</code> is cyclic, the cycle of the result list consists of just +the elements of the lists specified in the cycle in <code>lists</code>. In +this case, the acyclic prefix length of the result is the sum of the +lengths of the lists specified in the acyclic prefix of <code>lists</code>, +and the cycle length of the result is the sum of the lengths of the +lists specified in the cycle of <code>lists</code>. + + <p>The following equivalences hold: + <pre class="example"> (append) == () + (append h) == h + (append () h . t) == (append h . t) + (append (cons a b) h . t) == (cons a (append b h . t)) +</pre> + <!-- TODO add xref/comp to append --> + </blockquote></div> + +<div class="defun"> +&mdash; Applicative: <b>list-neighbors</b> (<var>list-neighbors list</var>)<var><a name="index-list_002dneighbors-82"></a></var><br> +<blockquote><p> The <code>list-neighbors</code> applicative constructs and returns a list +of all the consecutive sublists of <code>list</code> of length 2, in order. +If <code>list</code> is nil, the result is nil. If <code>list</code> is non-nil, +the length of the result is one less than the length of +<code>list</code>. If <code>list</code> is cyclic, the result is structurally +isomorphic to it (i.e., has the same acyclic prefix length and cycle +length). +<!-- TODO add xref to isomorphic --> + + <p>For example: + <pre class="example"> (list-neighbors (list 1 2 3 4)) &rArr; ((1 2) (2 3) (3 4)) +</pre> + </blockquote></div> + +<div class="defun"> +&mdash; Applicative: <b>filter</b> (<var>filter applicative list</var>)<var><a name="index-filter-83"></a></var><br> +<blockquote><p> Applicative <code>filter</code> passes each of the elements of <code>list</code> +as an argument to <code>applicative</code>, one at a time in no particular +order, using a fresh empty environment for each call. The result of +each call to <code>applicative</code> must be boolean, otherwise an error is +signaled. <code>filter</code> constructs and returns a list of all elements +of <code>list</code> on which <code>applicative</code> returned true, in the same +order as in <code>list</code>. <code>applicative</code> is called exactly as many +times as there are pairs in <code>list</code>. The resultant list has a +cycle containing exactly those elements accepted by <code>applicative</code> +that were in the cycle of <code>list</code>; if there were no such elements, +the result is acyclic. +</p></blockquote></div> + +<div class="defun"> +&mdash; Applicative: <b>assoc</b> (<var>assoc object pairs</var>)<var><a name="index-assoc-84"></a></var><br> +<blockquote><p> Applicative <code>assoc</code> returns the first element of <code>pairs</code> +whose car is <code>equal?</code> to <code>object</code>. If there is no such +element in <code>pairs</code>, nil is returned. +<!-- TODO add xref/comp to assq --> +<!-- TODO add xref to equal? --> +</p></blockquote></div> + +<div class="defun"> +&mdash; Applicative: <b>member?</b> (<var>member? object list</var>)<var><a name="index-member_003f-85"></a></var><br> +<blockquote><p> Applicative <code>member?</code> is a predicate that returns true iff some +element of <code>list</code> is <code>equal?</code> to <code>object</code>. +<!-- TODO add xref/comp to memq --> +<!-- TODO add xref to equal? --> +</p></blockquote></div> + +<div class="defun"> +&mdash; Applicative: <b>finite-list?</b> (<var>finite-list? . objects</var>)<var><a name="index-finite_002dlist_003f-86"></a></var><br> +<blockquote><p> This is the type predicate for type finite-list. +<code>finite-list?</code> returns true iff all the objects in +<code>objects</code> are acyclic lists. +</p></blockquote></div> + +<div class="defun"> +&mdash; Applicative: <b>countable-list?</b> (<var>countable-list? . objects</var>)<var><a name="index-countable_002dlist_003f-87"></a></var><br> +<blockquote><p>This is the type predicate for type list. <code>countable-list?</code> +returns true iff all the objects in <code>objects</code> are lists. +</p></blockquote></div> + +<div class="defun"> +&mdash; Applicative: <b>reduce</b> (<var>reduce list binary identity </var>[<var>precycle incycle postcycle</var>])<var><a name="index-reduce-88"></a></var><br> +<blockquote><p> <code>binary</code> should be an applicative. If the short form is used, +<code>list</code> should be an acyclic. If the long form is used, +<code>precycle</code>, <code>incycle</code>, and <code>postcycle</code> should be +applicatives. + + <p>If <code>list</code> is empty, applicative <code>reduce</code> returns +<code>identity</code>. If <code>list</code> is nonempty but acyclic, applicative +<code>reduce</code> uses binary operation <code>binary</code> to merge all the +elements of <code>list</code> into a single object, using any associative +grouping of the elements. That is, the sequence of objects initially +found in <code>list</code> is repeatedly decremented in length by applying +<code>binary</code> to a list of any two consecutive objects, replacing +those two objects with the result at the point in the sequence where +they occurred; and when the sequence contains only one object, that +object is returned. If <code>list</code> is cyclic, the long form must be +used. The elements of the cycle are passed, one at a time (but just +once for each position in the cycle), as arguments to unary +applicative <code>precycle</code>; the finite, cyclic sequence of results +from <code>precycle</code> is reduced using binary applicative +<code>incycle</code>; and the result from reducing the cycle is passed as an +argument to unary applicative <code>postcycle</code>. Binary operation +<code>binary</code> is used to reduce the sequence consisting of the +elements of the acyclic prefix of <code>list</code> followed by the result +returned by <code>postcycle</code>. The only constraint on the order of +calls to the applicatives is that each call must be made before its +result is needed (thus, parts of the reduction of the acyclic prefix +may occur before the contribution from the cycle has been completed). + + <p>Each call to <code>binary</code>, <code>precycle</code>, <code>incycle</code>, or +<code>postcycle</code> uses the dynamic environment of the call to +<code>reduce</code>. + + <p>If <code>list</code> is acyclic with length <code>n &gt;= 1</code>, +<code>binary</code> is called <code>n - 1</code> times. If <code>list</code> is cyclic +with acyclic prefix length <code>a</code> and cycle length <code>c</code>, +<code>binary</code> is called <code>a</code> times; <code>precycle</code>, <code>c</code> +times; <code>incycle</code>, <code>c - 1</code> times; and <code>postcycle</code>, once. +</p></blockquote></div> + +<div class="defun"> +&mdash; Applicative: <b>append!</b> (<var>append! . lists</var>)<var><a name="index-append_0021-89"></a></var><br> +<blockquote><p> <code>lists</code> must be a nonempty list; its first element must be an +acyclic nonempty list, and all of its elements except the last element +(if any) must be acyclic lists. + + <p>The <code>append!</code> applicative sets the cdr of the last pair in each +nonempty list argument to refer to the next non-nil argument, except +that if there is a last non-nil argument, it isn’t mutated. It is an +error for any two of the list arguments to have the same last pair. +The result returned by this applicative is inert. + + <p>The following equivalences hold: + <pre class="example"> (append! v) == #inert + (append! u v . w) == ($sequence (append! u v) (append! u . w)) +</pre> + </blockquote></div> + +<div class="defun"> +&mdash; Applicative: <b>copy-es</b> (<var>copy-es object</var>)<var><a name="index-copy_002des-90"></a></var><br> +<blockquote><p> Briefly, applicative <code>copy-es</code> returns an object initially +<code>equal?</code> to <code>object</code> with a freshly constructed evaluation +<!-- TODO add xref to evaluation structure --> +structure made up of mutable pairs. If <code>object</code> is not a pair, +the applicative returns <code>object</code>. If <code>object</code> is a pair, +the applicative returns a freshly constructed pair whose car and cdr +would be suitable results for <code>(copy-es (car object))</code> and +<code>(copy-es (cdr object))</code>, respectively. Further, the evaluation +<!-- TODO add xref to isomorphic --> +structure of the returned value is structurally isomorphic to that of +<code>object</code> at the time of copying, with corresponding non-pair +referents being <code>eq?</code>. +<!-- TODO add xref/comp to copy-es-immutable and the reverse too! --> +<!-- TODO add xref to eq?/equal? --> +</p></blockquote></div> + +<div class="defun"> +&mdash; Applicative: <b>assq</b> (<var>assq object pairs</var>)<var><a name="index-assq-91"></a></var><br> +<blockquote><p> Applicative <code>assq</code> returns the first element of <code>pairs</code> +whose car is <code>eq?</code> to <code>object</code>. If there is no such element +in <code>pairs</code>, nil is returned. +<!-- TODO add xref/comp to assoc --> +<!-- TODO add xref to eq? --> +</p></blockquote></div> + +<div class="defun"> +&mdash; Applicative: <b>memq?</b> (<var>memq? object list</var>)<var><a name="index-memq_003f-92"></a></var><br> +<blockquote><p> Applicative <code>memq?</code> is a predicate that returns true iff some +element of <code>list</code> is <code>eq?</code> to <code>object</code>. +<!-- TODO add xref/comp to member? --> +<!-- TODO add xref to eq? --> +</p></blockquote></div> + +<!-- *-texinfo-*- --> + </body></html> + diff --git a/manual/html/Symbols.html b/manual/html/Symbols.html @@ -0,0 +1,75 @@ +<html lang="en"> +<head> +<title>Symbols - klisp Reference Manual</title> +<meta http-equiv="Content-Type" content="text/html"> +<meta name="description" content="klisp Reference Manual"> +<meta name="generator" content="makeinfo 4.13"> +<link title="Top" rel="start" href="index.html#Top"> +<link rel="prev" href="Equivalence.html#Equivalence" title="Equivalence"> +<link rel="next" href="Control.html#Control" title="Control"> +<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage"> +<meta http-equiv="Content-Style-Type" content="text/css"> +<style type="text/css"><!-- + pre.display { font-family:inherit } + pre.format { font-family:inherit } + pre.smalldisplay { font-family:inherit; font-size:smaller } + pre.smallformat { font-family:inherit; font-size:smaller } + pre.smallexample { font-size:smaller } + pre.smalllisp { font-size:smaller } + span.sc { font-variant:small-caps } + span.roman { font-family:serif; font-weight:normal; } + span.sansserif { font-family:sans-serif; font-weight:normal; } +--></style> +</head> +<body> +<div class="node"> +<a name="Symbols"></a> +<p> +Next:&nbsp;<a rel="next" accesskey="n" href="Control.html#Control">Control</a>, +Previous:&nbsp;<a rel="previous" accesskey="p" href="Equivalence.html#Equivalence">Equivalence</a>, +Up:&nbsp;<a rel="up" accesskey="u" href="index.html#Top">Top</a> +<hr> +</div> + +<!-- node-name, next, previous, up --> +<h2 class="chapter">4 Symbols</h2> + +<p><a name="index-symbols-22"></a><!-- TODO add xref to eq?, identifiers, etc --> + Two symbols are eq? iff they have the same external +representation. Symbols are immutable, and the symbol type is +encapsulated. The external representations of symbols are usually +identifiers. However, symbols with other external representations may +<!-- TODO add xref to string->symbol --> +be created. + +<div class="defun"> +&mdash; Applicative: <b>symbol?</b> (<var>symbol? . objects</var>)<var><a name="index-symbol_003f-23"></a></var><br> +<blockquote><p> The primitive type predicate for type symbol. <code>symbol?</code> +returns true iff all the objects in <code>objects</code> are of type symbol. +</p></blockquote></div> + +<div class="defun"> +&mdash; Applicative: <b>symbol-&gt;string</b> (<var>symbol-&gt;string symbol</var>)<var><a name="index-symbol_002d_003estring-24"></a></var><br> +<blockquote><p> Applicative <code>symbol-&gt;string</code> returns the name of <code>symbol</code> +as a string. The string returned is immutable. +</p></blockquote></div> + +<div class="defun"> +&mdash; Applicative: <b>string-&gt;symbol</b> (<var>string-&gt;symbol string</var>)<var><a name="index-string_002d_003esymbol-25"></a></var><br> +<blockquote><p> Applicative <code>string-&gt;symbol</code> returns the symbol with name +<code>string</code>. The symbol is always interned, which means, that it is +always the case that: + <pre class="example"> (eq? &lt;symbol&gt; (string-&gt;symbol (symbol-&gt;string &lt;symbol&gt;))) + &rArr; #t +</pre> + <!-- TODO add xrefs for external representation --> + <p><code>string-&gt;symbol</code> can create symbols whose external +representation aren't identifiers. Right now klisp uses an output-only +representation, but in the near future it will probably include some +kind of escaping mechanism to allow arbitrary symbols to have readable +external representations as in R7RS Scheme. +</p></blockquote></div> + +<!-- *-texinfo-*- --> + </body></html> + diff --git a/manual/klisp.info b/manual/klisp.info @@ -863,6 +863,124 @@ File: klisp.info, Node: Combiners, Next: Index, Prev: Environments, Up: Top 8 Combiners *********** +There are two types of combiners in Kernel, operative and applicative. +Both types are encapsulated. All combiners are immutable. Two +applicatives are `eq?' iff their underlying combiners are `eq?'. +However, `eq?'-ness of operatives is only constrained by the general +rules for `eq?', which leave considerable leeway for variation between +implementations. klisp only considers `eq?' those operatives +constructed by the same call to a constructor (e.g. `$vau'). Two +combiners are `equal?' iff they are `eq?'. + + -- Applicative: operative? (operative? . objects) + The primitive type predicate for type operative. `operative?' + returns true iff all the objects in `objects' are of type + operative. + + -- Applicative: applicative? (applicative? . objects) + The primitive type predicate for type applicative. `applicative?' + returns true iff all the objects in `objects' are of type + 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. + + 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 + `copy-es-immutable' and the copies are stored as part of the + operative being constructed. This avoids problem if these + structures are later mutated. + + When the compound operative created by `$vau' is later called with + an object and an environment, here called respectively the operand + tree and the dynamic environment, the following happens: + + 1. A new, initially empty environment is created, with the static + environment as its parent. This will be called the local + environment. + + 2. A stored copy of the formal parameter tree formals is matched + in the local environment to the operand tree, locally binding + the symbols of formals to the corresponding parts of the + operand tree. eformal is 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. + + 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. + + NOTE: Because compound operatives are not a distinct type in + Kernel, they are covered by the encapsulation of type operative. + In particular, an implementation of Kernel cannot provide a + feature that supports extracting the static environment of any + given compound operative, nor that supports determining whether or + not a given operative is compound. + + -- Applicative: wrap (wrap combiner) + The `wrap' applicative returns an applicative whose underlying + combiner is `combiner'. + + -- Applicative: unwrap (unwrap applicative) + The `unwrap' applicative returns the underlying combiner of + `applicative'. + + -- Operative: $lambda ($lambda formals . objects) + `formals' should be a formal parameter tree. + + The `$lambda' operative is defined by the following equivalence: + ($lambda formals . objects) == + (wrap ($vau formals #ignore . objects)) + + -- Applicative: apply (apply applicative object [environment]) + Applicative `apply' combines the underlying combiner of + `applicative' with `object' in a tail context with dynamic + environment `environment' (if the long form is used) or in an + empty environment (if the short form is used). + + The following equivalences hold: + (apply applicative object environment) == + (eval (cons (unwrap applicative) object) environment) + + (apply applicative object) == + (apply applicative object (make-environment)) + + -- Applicative: map (map applicative . lists) + `lists' must be a nonempty list of lists; if there are two or + more, they must all have the same length. If `lists' is empty, or + if all of its elements are not lists of the same length, an error + is signaled. + + The `map' applicative applies `applicative' element-wise to the + elements of the lists in `lists' (i.e., applies it to a list of + the first elements of the `lists', to a list of the second + elements of the `lists', etc.), using the dynamic environment from + which `map' was called, and returns a list of the results, in + order. The applications may be performed in any order, as long as + their results occur in the resultant list in the order of their + arguments in the original `lists'. If `lists' is a cyclic list, + each argument list to which `applicative' is applied is + structurally isomorphic to `lists'. If any of the elements of + `lists' is a cyclic list, they all must be, or they wouldn’t all + have the same length. Let `a1...an' be their acyclic prefix + lengths, and `c1...cn' be their cycle lengths. The acyclic prefix + length `a' of the resultant list will be the maximum of the `ak', + while the cycle length `c' of the resultant list will be the least + common multiple of the `ck'. In the construction of the result, + applicative is called exactly `a + c' times. + + -- Applicative: combiner? (combiner? . objects) + The primitive type predicate for type combiner. `combiner?' + returns true iff all the objects in `objects' are of type combiner + (i.e. applicative or operative). +  File: klisp.info, Node: Index, Next: (dir), Prev: Combiners, Up: Top @@ -875,14 +993,18 @@ Index * $and?: Booleans. (line 28) * $cond: Control. (line 32) * $if: Control. (line 15) +* $lambda: Combiners. (line 76) * $or?: Booleans. (line 41) * $sequence: Control. (line 23) +* $vau: Combiners. (line 26) * and?: Booleans. (line 20) * append: Pairs and lists. (line 208) * append!: Pairs and lists. (line 306) * applicative descriptions: A Sample Applicative Description. (line 6) +* applicative?: Combiners. (line 21) * applicatives: Combiners. (line 6) +* apply: Combiners. (line 83) * assoc: Pairs and lists. (line 252) * assq: Pairs and lists. (line 333) * boolean?: Booleans. (line 12) @@ -917,6 +1039,7 @@ Index * cdddr: Pairs and lists. (line 100) * cddr: Pairs and lists. (line 92) * cdr: Pairs and lists. (line 86) +* combiner?: Combiners. (line 120) * combiners: Combiners. (line 6) * cons: Pairs and lists. (line 35) * control: Control. (line 6) @@ -952,6 +1075,7 @@ Index * list-ref: Pairs and lists. (line 198) * list-tail: Pairs and lists. (line 147) * lists: Pairs and lists. (line 6) +* map <1>: Combiners. (line 96) * map: Pairs and lists. (line 169) * member?: Pairs and lists. (line 257) * memq?: Pairs and lists. (line 338) @@ -962,6 +1086,7 @@ Index (line 6) * operative descriptions: A Sample Applicative Description. (line 6) +* operative?: Combiners. (line 16) * operatives: Combiners. (line 6) * or?: Booleans. (line 24) * pair?: Pairs and lists. (line 27) @@ -974,6 +1099,8 @@ Index * symbol->string: Symbols. (line 16) * symbol?: Symbols. (line 12) * symbols: Symbols. (line 6) +* unwrap: Combiners. (line 72) +* wrap: Combiners. (line 68)  @@ -998,6 +1125,6 @@ Node: Control18958 Node: Pairs and lists21275 Node: Environments38296 Node: Combiners38420 -Node: Index38528 +Node: Index44424  End Tag Table diff --git a/manual/src/combiners.texi b/manual/src/combiners.texi @@ -0,0 +1,157 @@ +@c -*-texinfo-*- +@setfilename ../src/combiners + +@node Combiners, Index, Environments, Top +@comment node-name, next, previous, up + +@chapter Combiners +@cindex combiners +@cindex applicatives +@cindex operatives + + There are two types of combiners in Kernel, operative and +applicative. Both types are encapsulated. All combiners are immutable. +Two applicatives are @code{eq?} iff their underlying combiners are +@code{eq?}. However, @code{eq?}-ness of operatives is only +constrained by the general rules for @code{eq?}, which leave +considerable leeway for variation between implementations. klisp only +considers @code{eq?} those operatives constructed by the same call to +a constructor (e.g. @code{$vau}). Two combiners are @code{equal?} +iff they are @code{eq?}. +@c TODO add xref for eq? and equal? + +@deffn Applicative operative? (operative? . objects) + The primitive type predicate for type operative. @code{operative?} +returns true iff all the objects in @code{objects} are of type +operative. +@end deffn + +@deffn Applicative applicative? (applicative? . objects) + The primitive type predicate for type applicative. +@code{applicative?} returns true iff all the objects in +@code{objects} are of type applicative. +@end deffn + +@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 +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. + + 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{copy-es-immutable} and the copies are stored as part of the +operative being constructed. This avoids problem if these structures +are later mutated. + +@c TODO add xref to eval or apply as example +When the compound operative created by @code{$vau} is later called +with an object and an environment, here called respectively the +operand tree and the dynamic environment, the following happens: + +@enumerate +@item +A new, initially empty environment is created, with the static +environment as its parent. This will be called the local environment. + +@item +A stored copy of the formal parameter tree formals is matched in the +local environment to the operand tree, locally binding the symbols of +@c TODO add xref to matching +formals to the corresponding parts of the operand tree. eformal is +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. + +@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. +@end enumerate + + NOTE: Because compound operatives are not a distinct type in Kernel, +they are covered by the encapsulation of type operative. In +particular, an implementation of Kernel cannot provide a feature that +supports extracting the static environment of any given compound +operative, nor that supports determining whether or not a given +operative is compound. +@end deffn + + +@deffn Applicative wrap (wrap combiner) + The @code{wrap} applicative returns an applicative whose underlying +combiner is @code{combiner}. +@end deffn + +@deffn Applicative unwrap (unwrap applicative) + The @code{unwrap} applicative returns the underlying combiner of +@code{applicative}. +@end deffn + +@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 +($lambda formals . objects) @equiv{} + (wrap ($vau formals #ignore . objects)) +@end example +@end deffn + +@deffn Applicative apply (apply applicative object [environment]) + Applicative @code{apply} combines the underlying combiner of +@code{applicative} with @code{object} in a tail context with dynamic +environment @code{environment} (if the long form is used) or in an +empty environment (if the short form is used). + +The following equivalences hold: +@example +(apply applicative object environment) @equiv{} + (eval (cons (unwrap applicative) object) environment) + +(apply applicative object) @equiv{} + (apply applicative object (make-environment)) +@end example +@end deffn + +@deffn Applicative map (map applicative . lists) + @code{lists} must be a nonempty list of lists; if there are two or +@c TODO add xref to length +more, they must all have the same length. If @code{lists} is empty, or +if all of its elements are not lists of the same length, an error is +signaled. + + The @code{map} applicative applies @code{applicative} element-wise +to the elements of the lists in @code{lists} (i.e., applies it to a +list of the first elements of the @code{lists}, to a list of the +second elements of the @code{lists}, etc.), using the dynamic +environment from which @code{map} was called, and returns a list of +the results, in order. The applications may be performed in any order, +as long as their results occur in the resultant list in the order of +their arguments in the original @code{lists}. If @code{lists} is a +cyclic list, each argument list to which @code{applicative} is applied +is structurally isomorphic to @code{lists}. If any of the elements of +@code{lists} is a cyclic list, they all must be, or they wouldn’t all +have the same length. Let @code{a1...an} be their acyclic prefix +lengths, and @code{c1...cn} be their cycle lengths. The acyclic +prefix length @code{a} of the resultant list will be the maximum of +the @code{ak}, while the cycle length @code{c} of the resultant list +will be the least common multiple of the @code{ck}. In the +construction of the result, applicative is called exactly @code{a + c} +times. +@c TODO comp/xref for-each +@end deffn + +@deffn Applicative combiner? (combiner? . objects) + The primitive type predicate for type combiner. @code{combiner?} +returns true iff all the objects in @code{objects} are of type +combiner (i.e. applicative or operative). +@end deffn + diff --git a/manual/src/environments.texi b/manual/src/environments.texi @@ -0,0 +1,10 @@ +@c -*-texinfo-*- +@setfilename ../src/environments + +@node Environments, Combiners, Pairs and lists, Top +@comment node-name, next, previous, up + +@chapter Environments +@cindex environments +@cindex ignore +