commit a3c2b0657eb1ddf392e3f18f67f4535971c4272d
parent be06d132f32d56bd585b295cc176dcf1da3a5ceb
Author: Andres Navarro <canavarro82@gmail.com>
Date: Fri, 3 Jun 2011 13:38:06 -0300
Completed module promises in the manual.
Diffstat:
11 files changed, 272 insertions(+), 28 deletions(-)
diff --git a/manual/html/Characters.html b/manual/html/Characters.html
@@ -34,7 +34,7 @@ Up: <a rel="up" accesskey="u" href="index.html#Top">Top</a>
<!-- node-name, next, previous, up -->
<h2 class="chapter">15 Characters</h2>
-<p><a name="index-characters-146"></a>
+<p><a name="index-characters-150"></a>
<!-- *-texinfo-*- -->
</body></html>
diff --git a/manual/html/Index.html b/manual/html/Index.html
@@ -42,6 +42,7 @@ Up: <a rel="up" accesskey="u" href="index.html#Top">Top</a>
<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="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="Promises.html#index-g_t_0024lazy-143"><code>$lazy</code></a>: <a href="Promises.html#Promises">Promises</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>
@@ -99,7 +100,7 @@ Up: <a rel="up" accesskey="u" href="index.html#Top">Top</a>
<li><a href="Pairs-and-lists.html#index-cdddr-58"><code>cdddr</code></a>: <a href="Pairs-and-lists.html#Pairs-and-lists">Pairs and lists</a></li>
<li><a href="Pairs-and-lists.html#index-cddr-50"><code>cddr</code></a>: <a href="Pairs-and-lists.html#Pairs-and-lists">Pairs and lists</a></li>
<li><a href="Pairs-and-lists.html#index-cdr-46"><code>cdr</code></a>: <a href="Pairs-and-lists.html#Pairs-and-lists">Pairs and lists</a></li>
-<li><a href="Characters.html#index-characters-146">characters</a>: <a href="Characters.html#Characters">Characters</a></li>
+<li><a href="Characters.html#index-characters-150">characters</a>: <a href="Characters.html#Characters">Characters</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>
@@ -131,6 +132,7 @@ Up: <a rel="up" accesskey="u" href="index.html#Top">Top</a>
<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="Promises.html#index-force-142"><code>force</code></a>: <a href="Promises.html#Promises">Promises</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="Continuations.html#index-guard_002dcontinuation-130"><code>guard-continuation</code></a>: <a href="Continuations.html#Continuations">Continuations</a></li>
@@ -140,9 +142,9 @@ Up: <a rel="up" accesskey="u" href="index.html#Top">Top</a>
<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>
-<li><a href="Keyed-Variables.html#index-keyed-dynamic-variables-142">keyed dynamic variables</a>: <a href="Keyed-Variables.html#Keyed-Variables">Keyed Variables</a></li>
-<li><a href="Keyed-Variables.html#index-keyed-static-variables-143">keyed static variables</a>: <a href="Keyed-Variables.html#Keyed-Variables">Keyed Variables</a></li>
-<li><a href="Keyed-Variables.html#index-keyed-variables-141">keyed variables</a>: <a href="Keyed-Variables.html#Keyed-Variables">Keyed Variables</a></li>
+<li><a href="Keyed-Variables.html#index-keyed-dynamic-variables-146">keyed dynamic variables</a>: <a href="Keyed-Variables.html#Keyed-Variables">Keyed Variables</a></li>
+<li><a href="Keyed-Variables.html#index-keyed-static-variables-147">keyed static variables</a>: <a href="Keyed-Variables.html#Keyed-Variables">Keyed Variables</a></li>
+<li><a href="Keyed-Variables.html#index-keyed-variables-145">keyed variables</a>: <a href="Keyed-Variables.html#Keyed-Variables">Keyed Variables</a></li>
<li><a href="Pairs-and-lists.html#index-length-79"><code>length</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-43"><code>list</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_002a-44"><code>list*</code></a>: <a href="Pairs-and-lists.html#Pairs-and-lists">Pairs and lists</a></li>
@@ -156,11 +158,12 @@ Up: <a rel="up" accesskey="u" href="index.html#Top">Top</a>
<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="Promises.html#index-memoize-144"><code>memoize</code></a>: <a href="Promises.html#Promises">Promises</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>
<li><a href="Pairs-and-lists.html#index-nil-34">nil</a>: <a href="Pairs-and-lists.html#Pairs-and-lists">Pairs and lists</a></li>
<li><a href="Booleans.html#index-not_003f-14"><code>not?</code></a>: <a href="Booleans.html#Booleans">Booleans</a></li>
<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="Numbers.html#index-numbers-144">numbers</a>: <a href="Numbers.html#Numbers">Numbers</a></li>
+<li><a href="Numbers.html#index-numbers-148">numbers</a>: <a href="Numbers.html#Numbers">Numbers</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-117"><code>operative?</code></a>: <a href="Combiners.html#Combiners">Combiners</a></li>
@@ -168,15 +171,16 @@ Up: <a rel="up" accesskey="u" href="index.html#Top">Top</a>
<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>
-<li><a href="Ports.html#index-ports-147">ports</a>: <a href="Ports.html#Ports">Ports</a></li>
+<li><a href="Ports.html#index-ports-151">ports</a>: <a href="Ports.html#Ports">Ports</a></li>
<li><a href="Printing-Notation.html#index-printing-notation-5">printing notation</a>: <a href="Printing-Notation.html#Printing-Notation">Printing Notation</a></li>
+<li><a href="Promises.html#index-promise_003f-141"><code>promise?</code></a>: <a href="Promises.html#Promises">Promises</a></li>
<li><a href="Promises.html#index-promises-140">promises</a>: <a href="Promises.html#Promises">Promises</a></li>
<li><a href="Pairs-and-lists.html#index-reduce-88"><code>reduce</code></a>: <a href="Pairs-and-lists.html#Pairs-and-lists">Pairs and lists</a></li>
<li><a href="Continuations.html#index-root_002dcontinuation-132"><code>root-continuation</code></a>: <a href="Continuations.html#Continuations">Continuations</a></li>
<li><a href="Pairs-and-lists.html#index-set_002dcar_0021-40"><code>set-car!</code></a>: <a href="Pairs-and-lists.html#Pairs-and-lists">Pairs and lists</a></li>
<li><a href="Pairs-and-lists.html#index-set_002dcdr_0021-41"><code>set-cdr!</code></a>: <a href="Pairs-and-lists.html#Pairs-and-lists">Pairs and lists</a></li>
<li><a href="Symbols.html#index-string_002d_003esymbol-25"><code>string->symbol</code></a>: <a href="Symbols.html#Symbols">Symbols</a></li>
-<li><a href="Strings.html#index-strings-145">strings</a>: <a href="Strings.html#Strings">Strings</a></li>
+<li><a href="Strings.html#index-strings-149">strings</a>: <a href="Strings.html#Strings">Strings</a></li>
<li><a href="Symbols.html#index-symbol_002d_003estring-24"><code>symbol->string</code></a>: <a href="Symbols.html#Symbols">Symbols</a></li>
<li><a href="Symbols.html#index-symbol_003f-23"><code>symbol?</code></a>: <a href="Symbols.html#Symbols">Symbols</a></li>
<li><a href="Symbols.html#index-symbols-22">symbols</a>: <a href="Symbols.html#Symbols">Symbols</a></li>
diff --git a/manual/html/Keyed-Variables.html b/manual/html/Keyed-Variables.html
@@ -34,7 +34,7 @@ Up: <a rel="up" accesskey="u" href="index.html#Top">Top</a>
<!-- node-name, next, previous, up -->
<h2 class="chapter">12 Keyed Variables</h2>
-<p><a name="index-keyed-variables-141"></a><a name="index-keyed-dynamic-variables-142"></a><a name="index-keyed-static-variables-143"></a>
+<p><a name="index-keyed-variables-145"></a><a name="index-keyed-dynamic-variables-146"></a><a name="index-keyed-static-variables-147"></a>
<!-- *-texinfo-*- -->
</body></html>
diff --git a/manual/html/Numbers.html b/manual/html/Numbers.html
@@ -34,7 +34,7 @@ Up: <a rel="up" accesskey="u" href="index.html#Top">Top</a>
<!-- node-name, next, previous, up -->
<h2 class="chapter">13 Numbers</h2>
-<p><a name="index-numbers-144"></a>
+<p><a name="index-numbers-148"></a>
<!-- *-texinfo-*- -->
</body></html>
diff --git a/manual/html/Ports.html b/manual/html/Ports.html
@@ -34,7 +34,7 @@ Up: <a rel="up" accesskey="u" href="index.html#Top">Top</a>
<!-- node-name, next, previous, up -->
<h2 class="chapter">16 Ports</h2>
-<p><a name="index-ports-147"></a>
+<p><a name="index-ports-151"></a>
<!-- appendices -->
<!-- TODO -->
diff --git a/manual/html/Promises.html b/manual/html/Promises.html
@@ -35,6 +35,90 @@ Up: <a rel="up" accesskey="u" href="index.html#Top">Top</a>
<h2 class="chapter">11 Promises</h2>
<p><a name="index-promises-140"></a>
+<!-- TODO xref to $lazy, memoize, force -->
+A promise is an object that represents the potential to determine a
+value. The value may be the result of an arbitrary computation that
+will not be performed until the value must be determined (constructor
+<code>$lazy</code>); or, in advanced usage, the value may be determined
+before the promise is constructed (constructor <code>memoize</code>).
+
+ <p>The value determined by a promise is obtained by forcing it
+(applicative <code>force</code>). A given promise cannot determine
+different values on different occasions that it is forced. Also, if a
+promise determines its value by computation, and that computation has
+already been completed, forcing the promise again will produce the
+previously determined result without re-initiating the computation to
+determine it.
+
+ <p>The Kernel data type promise is encapsulated.
+
+<!-- TODO add xref to eq? and equal? -->
+ <p>The general rules for predicate <code>eq?</code> only require it to
+distinguish promises if they can exhibit different behavior; the
+resulting leeway for variation between implementations is similar, in
+both cause and effect, to that for <code>eq?</code>-ness of operatives. For
+example, if two promises, constructed on different occasions, would
+perform the same computation to determine their values, and that
+computation has no side-effects and must always return the same value,
+the promises may or may not be <code>eq?</code>. Two promises are
+<code>equal?</code> iff they are <code>eq?</code>.
+
+<div class="defun">
+— Applicative: <b>promise?</b> (<var>promise? . objects</var>)<var><a name="index-promise_003f-141"></a></var><br>
+<blockquote><p> The primitive type predicate for type promise. <code>promise?</code>
+returns true iff all the objects in <code>objects</code> are of type
+promise.
+</p></blockquote></div>
+
+<div class="defun">
+— Applicative: <b>force</b> (<var>force object</var>)<var><a name="index-force-142"></a></var><br>
+<blockquote><p> If <code>object</code> is a promise, applicative <code>force</code> returns the
+value determined by promise; otherwise, it returns <code>object</code>.
+
+ <p>The means used to force a promise depend on how the promise was
+constructed. The description of each promise constructor specifies
+how to force promises constructed by that constructor.
+</p></blockquote></div>
+
+<div class="defun">
+— Operative: <b>$lazy</b> (<var>$lazy expression</var>)<var><a name="index-g_t_0024lazy-143"></a></var><br>
+<blockquote><p> Operative <code>$lazy</code> constructs and returns a new object of type
+promise, representing potential evaluation of expression in the
+dynamic environment from which <code>$lazy</code> was called.
+
+ <p>When the promise is forced, if a value has not previously been
+determined for it, <code>expression</code> is evaluated in the dynamic
+environment of the constructing call to <code>$lazy</code>. If, when the
+evaluation returns a result, a value is found to have been determined
+for the promise during the evaluation, the result is discarded in
+favor of the previously determined value; otherwise, the result is
+forced, and the value returned by that forcing becomes the value
+determined by the promise.
+
+ <!-- TODO add xref to tail context -->
+ <p>Forcing an undetermined lazy promise (i.e., a promise constructed by
+$lazy for which no value has yet been determined) may cause a
+sequential series of evaluations, each of which returns a promise that
+is forced and thus initiates the next evaluation in the series. The
+implementation must support series of this kind with unbounded length
+(i.e., unbounded number of sequential evaluations).
+
+ <!-- TODO add xref to eq? -->
+ <p>Note that forcing concerns the value determined by a given promise,
+not the result of evaluating a given expression in a given
+environment. Distinct promises (judged by <code>eq?</code> represent
+different occasions of evaluation; so, even if they do represent
+evaluation of the same expression in the same environment, forcing one
+does not necessarily determine the value for the other, and actual
+evaluation will take place the first time each of them is forced.
+</p></blockquote></div>
+
+<div class="defun">
+— Applicative: <b>memoize</b> (<var>memoize object</var>)<var><a name="index-memoize-144"></a></var><br>
+<blockquote><p> Applicative <code>memoize</code> constructs and returns a new object of
+type promise, representing memoization of <code>object</code>. Whenever the
+promise is forced, it determines <code>object</code>.
+</p></blockquote></div>
<!-- *-texinfo-*- -->
</body></html>
diff --git a/manual/html/Strings.html b/manual/html/Strings.html
@@ -34,7 +34,7 @@ Up: <a rel="up" accesskey="u" href="index.html#Top">Top</a>
<!-- node-name, next, previous, up -->
<h2 class="chapter">14 Strings</h2>
-<p><a name="index-strings-145"></a>
+<p><a name="index-strings-149"></a>
<!-- *-texinfo-*- -->
</body></html>
diff --git a/manual/html/Symbols.html b/manual/html/Symbols.html
@@ -44,7 +44,7 @@ be created.
<div class="defun">
— 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>
+<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>
diff --git a/manual/klisp.info b/manual/klisp.info
@@ -446,7 +446,7 @@ external representations of symbols are usually identifiers. However,
symbols with other external representations may be created.
-- Applicative: symbol? (symbol? . objects)
- The primitive type predicate for type symbol. `symbol?' returns
+ The primitive type predicate for type symbol. `symbol?' returns
true iff all the objects in `objects' are of type symbol.
-- Applicative: symbol->string (symbol->string symbol)
@@ -1412,6 +1412,78 @@ File: klisp.info, Node: Promises, Next: Keyed Variables, Prev: Encapsulations
11 Promises
***********
+A promise is an object that represents the potential to determine a
+value. The value may be the result of an arbitrary computation that
+will not be performed until the value must be determined (constructor
+`$lazy'); or, in advanced usage, the value may be determined before the
+promise is constructed (constructor `memoize').
+
+ The value determined by a promise is obtained by forcing it
+(applicative `force'). A given promise cannot determine different
+values on different occasions that it is forced. Also, if a promise
+determines its value by computation, and that computation has already
+been completed, forcing the promise again will produce the previously
+determined result without re-initiating the computation to determine it.
+
+ The Kernel data type promise is encapsulated.
+
+ The general rules for predicate `eq?' only require it to distinguish
+promises if they can exhibit different behavior; the resulting leeway
+for variation between implementations is similar, in both cause and
+effect, to that for `eq?'-ness of operatives. For example, if two
+promises, constructed on different occasions, would perform the same
+computation to determine their values, and that computation has no
+side-effects and must always return the same value, the promises may or
+may not be `eq?'. Two promises are `equal?' iff they are `eq?'.
+
+ -- Applicative: promise? (promise? . objects)
+ The primitive type predicate for type promise. `promise?' returns
+ true iff all the objects in `objects' are of type promise.
+
+ -- Applicative: force (force object)
+ If `object' is a promise, applicative `force' returns the value
+ determined by promise; otherwise, it returns `object'.
+
+ The means used to force a promise depend on how the promise was
+ constructed. The description of each promise constructor specifies
+ how to force promises constructed by that constructor.
+
+ -- Operative: $lazy ($lazy expression)
+ Operative `$lazy' constructs and returns a new object of type
+ promise, representing potential evaluation of expression in the
+ dynamic environment from which `$lazy' was called.
+
+ When the promise is forced, if a value has not previously been
+ determined for it, `expression' is evaluated in the dynamic
+ environment of the constructing call to `$lazy'. If, when the
+ evaluation returns a result, a value is found to have been
+ determined for the promise during the evaluation, the result is
+ discarded in favor of the previously determined value; otherwise,
+ the result is forced, and the value returned by that forcing
+ becomes the value determined by the promise.
+
+ Forcing an undetermined lazy promise (i.e., a promise constructed
+ by $lazy for which no value has yet been determined) may cause a
+ sequential series of evaluations, each of which returns a promise
+ that is forced and thus initiates the next evaluation in the
+ series. The implementation must support series of this kind with
+ unbounded length (i.e., unbounded number of sequential
+ evaluations).
+
+ Note that forcing concerns the value determined by a given promise,
+ not the result of evaluating a given expression in a given
+ environment. Distinct promises (judged by `eq?' represent
+ different occasions of evaluation; so, even if they do represent
+ evaluation of the same expression in the same environment, forcing
+ one does not necessarily determine the value for the other, and
+ actual evaluation will take place the first time each of them is
+ forced.
+
+ -- Applicative: memoize (memoize object)
+ Applicative `memoize' constructs and returns a new object of type
+ promise, representing memoization of `object'. Whenever the
+ promise is forced, it determines `object'.
+
File: klisp.info, Node: Keyed Variables, Next: Numbers, Prev: Promises, Up: Top
@@ -1458,6 +1530,7 @@ Index
* $if: Control. (line 15)
* $import!: Environments. (line 207)
* $lambda: Combiners. (line 76)
+* $lazy: Promises. (line 43)
* $let: Environments. (line 89)
* $let*: Environments. (line 124)
* $let-redirect: Environments. (line 153)
@@ -1550,6 +1623,7 @@ Index
* foo: A Sample Applicative Description.
(line 15)
* for-each: Control. (line 42)
+* force: Promises. (line 35)
* get-current-environment: Environments. (line 114)
* get-list-metrics: Pairs and lists. (line 123)
* guard-continuation: Continuations. (line 63)
@@ -1575,6 +1649,7 @@ Index
* map <1>: Combiners. (line 96)
* map: Pairs and lists. (line 169)
* member?: Pairs and lists. (line 257)
+* memoize: Promises. (line 74)
* memq?: Pairs and lists. (line 338)
* nil: Pairs and lists. (line 6)
* not?: Booleans. (line 16)
@@ -1591,6 +1666,7 @@ Index
* pairs: Pairs and lists. (line 6)
* ports: Ports. (line 6)
* printing notation: Printing Notation. (line 6)
+* promise?: Promises. (line 31)
* promises: Promises. (line 6)
* reduce: Pairs and lists. (line 270)
* root-continuation: Continuations. (line 104)
@@ -1623,18 +1699,18 @@ Node: Acknowledgements14338
Node: Booleans14724
Node: Equivalence17266
Node: Symbols18059
-Node: Control19424
-Node: Pairs and lists21741
-Node: Environments38764
-Node: Combiners48971
-Node: Continuations55007
-Node: Encapsulations63181
-Node: Promises64634
-Node: Keyed Variables64753
-Node: Numbers64879
-Node: Strings64988
-Node: Characters65092
-Node: Ports65200
-Node: Index65296
+Node: Control19425
+Node: Pairs and lists21742
+Node: Environments38765
+Node: Combiners48972
+Node: Continuations55008
+Node: Encapsulations63182
+Node: Promises64635
+Node: Keyed Variables68558
+Node: Numbers68684
+Node: Strings68793
+Node: Characters68897
+Node: Ports69005
+Node: Index69101
End Tag Table
diff --git a/manual/src/promises.texi b/manual/src/promises.texi
@@ -7,3 +7,83 @@
@chapter Promises
@cindex promises
+@c TODO xref to $lazy, memoize, force
+A promise is an object that represents the potential to determine a
+value. The value may be the result of an arbitrary computation that
+will not be performed until the value must be determined (constructor
+@code{$lazy}); or, in advanced usage, the value may be determined
+before the promise is constructed (constructor @code{memoize}).
+
+ The value determined by a promise is obtained by forcing it
+(applicative @code{force}). A given promise cannot determine
+different values on different occasions that it is forced. Also, if a
+promise determines its value by computation, and that computation has
+already been completed, forcing the promise again will produce the
+previously determined result without re-initiating the computation to
+determine it.
+
+ The Kernel data type promise is encapsulated.
+
+@c TODO add xref to eq? and equal?
+ The general rules for predicate @code{eq?} only require it to
+distinguish promises if they can exhibit different behavior; the
+resulting leeway for variation between implementations is similar, in
+both cause and effect, to that for @code{eq?}-ness of operatives. For
+example, if two promises, constructed on different occasions, would
+perform the same computation to determine their values, and that
+computation has no side-effects and must always return the same value,
+the promises may or may not be @code{eq?}. Two promises are
+@code{equal?} iff they are @code{eq?}.
+
+@deffn Applicative promise? (promise? . objects)
+ The primitive type predicate for type promise. @code{promise?}
+returns true iff all the objects in @code{objects} are of type
+promise.
+@end deffn
+
+@deffn Applicative force (force object)
+ If @code{object} is a promise, applicative @code{force} returns the
+value determined by promise; otherwise, it returns @code{object}.
+
+ The means used to force a promise depend on how the promise was
+constructed. The description of each promise constructor specifies
+how to force promises constructed by that constructor.
+@end deffn
+
+@deffn Operative $lazy ($lazy expression)
+ Operative @code{$lazy} constructs and returns a new object of type
+promise, representing potential evaluation of expression in the
+dynamic environment from which @code{$lazy} was called.
+
+ When the promise is forced, if a value has not previously been
+determined for it, @code{expression} is evaluated in the dynamic
+environment of the constructing call to @code{$lazy}. If, when the
+evaluation returns a result, a value is found to have been determined
+for the promise during the evaluation, the result is discarded in
+favor of the previously determined value; otherwise, the result is
+forced, and the value returned by that forcing becomes the value
+determined by the promise.
+
+@c TODO add xref to tail context
+ Forcing an undetermined lazy promise (i.e., a promise constructed by
+$lazy for which no value has yet been determined) may cause a
+sequential series of evaluations, each of which returns a promise that
+is forced and thus initiates the next evaluation in the series. The
+implementation must support series of this kind with unbounded length
+(i.e., unbounded number of sequential evaluations).
+
+@c TODO add xref to eq?
+ Note that forcing concerns the value determined by a given promise,
+not the result of evaluating a given expression in a given
+environment. Distinct promises (judged by @code{eq?} represent
+different occasions of evaluation; so, even if they do represent
+evaluation of the same expression in the same environment, forcing one
+does not necessarily determine the value for the other, and actual
+evaluation will take place the first time each of them is forced.
+@end deffn
+
+@deffn Applicative memoize (memoize object)
+ Applicative @code{memoize} constructs and returns a new object of
+type promise, representing memoization of @code{object}. Whenever the
+promise is forced, it determines @code{object}.
+@end deffn
diff --git a/manual/src/symbols.texi b/manual/src/symbols.texi
@@ -15,7 +15,7 @@ identifiers. However, symbols with other external representations may
be created.
@deffn Applicative symbol? (symbol? . objects)
- The primitive type predicate for type symbol. @code{symbol?}
+ The primitive type predicate for type symbol. @code{symbol?}
returns true iff all the objects in @code{objects} are of type symbol.
@end deffn