281 lines
9.9 KiB
HTML
281 lines
9.9 KiB
HTML
<html>
|
|
<head>
|
|
<title>Lazy Evaluation</title>
|
|
<link rel="stylesheet" type="text/css" href="style.css">
|
|
</head>
|
|
<body>
|
|
<h1>Lazy Evaluation</h1>
|
|
<p>The 'lazy' vocabulary adds lazy lists to Factor. This provides the
|
|
ability to describe infinite structures, and to delay execution of
|
|
expressions until they are actually used.</p>
|
|
<p>Lazy lists, like normal lists, are composed of a head and tail. In
|
|
a lazy list the tail is something called a 'promise'. To convert a
|
|
'promise' into its actual value a word called 'force' is used. To
|
|
convert a value into a 'promise' the word to use is 'delay'.</p>
|
|
<p>Many of the lazy list words are named similar to the standard list
|
|
words but with an 'l' suffixed to it. Here are the commonly used
|
|
words and their equivalent list operation:</p>
|
|
<table border="1">
|
|
<tr><th>Lazy List</th><th>Normal List</th></tr>
|
|
<tr><td><a href="#lcons">lcons</a></td><td>cons</td></tr>
|
|
<tr><td><a href="#lunit">lunit</a></td><td>unit</td></tr>
|
|
<tr><td><a href="#lcar">lcar</a></td><td>car</td></tr>
|
|
<tr><td><a href="#lcdr">lcdr</a></td><td>cdr</td></tr>
|
|
<tr><td><a href="#lnth">lnth</a></td><td>nth</td></tr>
|
|
<tr><td><a href="#luncons">luncons</a></td><td>uncons</td></tr>
|
|
<tr><td><a href="#lmap">lmap</a></td><td>map</td></tr>
|
|
<tr><td><a href="#lsubset">lsubset</a></td><td>subset</td></tr>
|
|
<tr><td><a href="#leach">leach</a></td><td>each</td></tr>
|
|
<tr><td><a href="#lappend">lappend</a></td><td>append</td></tr>
|
|
</table>
|
|
<p>A few additional words specific to lazy lists are:</p>
|
|
<table border="1">
|
|
<tr><td><a href="#ltake">ltake</a></td><td>Returns a normal list containing a specified
|
|
number of items from the lazy list.</td></tr>
|
|
<tr><td><a href="#lappendstar">lappend*</a></td><td>Given a lazy list of lazy lists,
|
|
concatenate them together in a lazy manner, returning a single lazy
|
|
list.</td></tr>
|
|
<tr><td><a href="#list>llist">list>llist</a></td><td>Given a normal list, return a lazy list
|
|
that contains the same elements as the normal list.</td></tr>
|
|
</table>
|
|
<p>A couple of helper functions are also provided by the lazy
|
|
vocabulary.</p>
|
|
<table border="1">
|
|
<tr><td>curry1</td><td>Given a value and a quotation, returns a new
|
|
quotation that when called will have the value on the stack.</td></tr>
|
|
<tr><td>curry2</td><td>Given two values and a quotation, returns a new
|
|
quotation that when called will have the two values on the
|
|
stack.</td></tr>
|
|
</table>
|
|
<h2>Reference</h2>
|
|
<!-- lcons description -->
|
|
<a name="lcons">
|
|
<h3>lcons ( value promise -- lcons )</h3>
|
|
<p>Provides the same effect as 'cons' does for normal lists. It
|
|
creates a cons cell where the first element is the value given and the
|
|
second element is a promise.</p>
|
|
<a name="promise">
|
|
<p>A promise is either a value that has had 'force' called on it, or
|
|
a quotation that when 'call' is applied to it, returns the actual
|
|
value.</p>
|
|
<pre class="code">
|
|
( 1 ) 5 6 delay <a href="#lcons">lcons</a> dup .
|
|
=> [ 5 6 ]
|
|
( 2 ) dup <a href="#lcar">lcar</a> .
|
|
=> 5
|
|
( 3 ) dup <a href="#lcdr">lcdr</a> .
|
|
=> 6
|
|
</pre>
|
|
|
|
<!-- lunit description -->
|
|
<a name="lunit">
|
|
<h3>lunit ( value -- llist )</h3>
|
|
<p>Provides the same effect as 'unit' does for normal lists. It
|
|
creates a lazy list where the first element is the value given.</p>
|
|
<pre class="code">
|
|
( 1 ) 42 <a href="#lunit">lunit</a> dup .
|
|
=> [ 42 f ]
|
|
( 2 ) dup <a href="#lcar">lcar</a> .
|
|
=> 42
|
|
( 3 ) dup <a href="#lcdr">lcdr</a> .
|
|
=> f
|
|
( 4 ) [ . ] <a href="#leach">leach</a>
|
|
=> 42
|
|
</pre>
|
|
|
|
<!-- lcar description -->
|
|
<a name="lcar">
|
|
<h3>lcar ( lcons -- value )</h3>
|
|
<p>Provides the same effect as 'car' does for normal lists. It
|
|
returns the first element in a lazy cons cell.</p>
|
|
<pre class="code">
|
|
( 1 ) 42 <a href="#lunit">lunit</a> dup .
|
|
=> [ 42 f ]
|
|
( 2 ) <a href="#lcar">lcar</a> .
|
|
=> 42
|
|
</pre>
|
|
|
|
<!-- lcdr description -->
|
|
<a name="lcdr">
|
|
<h3>lcdr ( lcons -- value )</h3>
|
|
<p>Provides the same effect as 'cdr' does for normal lists. It
|
|
returns the second element in a lazy cons cell and forces it. This
|
|
causes that element to be evaluated immediately.</p>
|
|
<pre class="code">
|
|
( 1 ) 5 [ 5 6 + ] <a href="#lcons">lcons</a> dup .
|
|
=> [ 5 5 6 + ]
|
|
( 2 ) <a href="#lcdr">lcdr</a> .
|
|
=> 11
|
|
</pre>
|
|
|
|
<pre class="code">
|
|
( 1 ) 5 lfrom dup .
|
|
=> [ 5 5 succ lfrom ]
|
|
( 2 ) <a href="#lcdr">lcdr</a> dup <a href="#lcar">lcar</a> .
|
|
=> 6
|
|
( 3 ) <a href="#lcdr">lcdr</a> dup <a href="#lcar">lcar</a> .
|
|
=> 7
|
|
( 4 ) <a href="#lcdr">lcdr</a> dup <a href="#lcar">lcar</a> .
|
|
=> 8
|
|
</pre>
|
|
|
|
<!-- lnth description -->
|
|
<a name="lnth">
|
|
<h3>lnth ( n llist -- value )</h3>
|
|
<p>Provides the same effect as 'nth' does for normal lists. It
|
|
returns the nth value in the lazy list. It causes all the values up to
|
|
'n' to be evaluated.</p>
|
|
<pre class="code">
|
|
( 1 ) 1 lfrom
|
|
=> [ 1 1 succ lfrom ]
|
|
( 2 ) 5 swap <a href="#lnth">lnth</a> .
|
|
=> 6
|
|
</pre>
|
|
|
|
<!-- luncons description -->
|
|
<a name="luncons">
|
|
<h3>luncons ( lcons -- car cdr )</h3>
|
|
<p>Provides the same effect as 'uncons' does for normal lists. It
|
|
returns the car and cdr of the lazy list. Note that cdr is forced
|
|
resulting in it being evaluated.</p>
|
|
<pre class="code">
|
|
( 1 ) 5 [ 6 ] <a href="#lcons">lcons</a> dup .
|
|
=> [ 5 6 ]
|
|
( 2 ) <a href="#luncons">luncons</a> .s
|
|
=> { 5 6 }
|
|
</pre>
|
|
|
|
<!-- lmap description -->
|
|
<a name="lmap">
|
|
<h3>lmap ( llist quot -- llist )</h3>
|
|
<p>Provides the same effect as 'map' does for normal lists. It
|
|
lazily maps over a lazy list applying the quotation to each element.
|
|
A new lazy list is returned which contains the results of the
|
|
quotation.</p>
|
|
<p>When initially called <a href="#lmap">lmap</a> will only call quot on the first element
|
|
of the list. It then constructs a lazy list that performs the
|
|
next '<a href="#lmap">lmap</a>' operation on the next element when it is evaluated. This
|
|
allows mapping over infinite lists.</p>
|
|
<pre class="code">
|
|
( 1 ) 1 lfrom
|
|
=> < infinite list of incrementing numbers >
|
|
( 2 ) [ 2 * ] <a href="#lmap">lmap</a>
|
|
=> < infinite list of numbers incrementing by 2 >
|
|
( 3 ) 5 swap <a href="#ltake">ltake</a> .
|
|
=> [ 2 4 6 8 10 ]
|
|
</pre>
|
|
|
|
<!-- lsubset description -->
|
|
<a name="lsubset">
|
|
<h3>lsubset ( llist pred -- llist )</h3>
|
|
<p>Provides the same effect as 'subset' does for normal lists. It
|
|
lazily iterates over a lazy list applying the predicate quotation to each
|
|
element. If that quotation returns true, the element will be included
|
|
in the resulting lazy list. If it is false, the element will be skipped.
|
|
A new lazy list is returned which contains all elements where the
|
|
predicate returned true.</p>
|
|
<p>When initially called <a href="#lsubset">lsubset</a> will only call
|
|
the predicate quotation on the first element
|
|
of the list. It then constructs a lazy list that performs the
|
|
next '<a href="#lsubset">lsubset</a>' operation on the next element when it is evaluated. This
|
|
allows subsetting over infinite lists.</p>
|
|
<pre class="code">
|
|
( 1 ) 1 lfrom
|
|
=> < infinite list of incrementing numbers >
|
|
( 2 ) [ prime? ] <a href="#lsubset">lsubset</a>
|
|
=> < infinite list of prime numbers >
|
|
( 3 ) 5 swap <a href="#ltake">ltake</a> .
|
|
=> [ 2 3 5 7 11 ]
|
|
</pre>
|
|
|
|
<!-- leach description -->
|
|
<a name="leach">
|
|
<h3>leach ( llist quot -- )</h3>
|
|
<p>Provides the same effect as 'each' does for normal lists. It
|
|
lazily iterates over a lazy list applying the quotation to each
|
|
element. If this operation is applied to an infinite list it will
|
|
never return unless the quotation escapes out by calling a continuation.</p>
|
|
<pre class="code">
|
|
( 1 ) 1 lfrom
|
|
=> < infinite list of incrementing numbers >
|
|
( 2 ) [ 2 mod 1 = ] <a href="#lsubset">lsubset</a>
|
|
=> < infinite list of odd numbers >
|
|
( 3 ) [ . ] <a href="#leach">leach</a>
|
|
=> 1
|
|
3
|
|
5
|
|
7
|
|
... for ever ...
|
|
</pre>
|
|
|
|
<!-- ltake description -->
|
|
<a name="ltake">
|
|
<h3>ltake ( n llist -- list )</h3>
|
|
<p>Iterates over the lazy list 'n' times, appending each element to a
|
|
normal list. The normal list is returned. This provides a convenient
|
|
way of getting elements out of a lazy list.</p>
|
|
<pre class="code">
|
|
( 1 ) : ones 1 [ ones ] <a href="#lcons">lcons</a> ;
|
|
( 2 ) 5 ones <a href="#ltake">ltake</a>
|
|
=> [ 1 1 1 1 1 ]
|
|
</pre>
|
|
|
|
<!-- lappend description -->
|
|
<a name="lappend">
|
|
<h3>lappend ( llist1 llist2 -- llist )</h3>
|
|
<p>Lazily appends two lists together. The actual appending is done
|
|
lazily on iteration rather than immediately so it works very fast no
|
|
matter how large the list.</p>
|
|
<pre class="code">
|
|
( 1 ) [ 1 2 3 ] <a href="#list>llist">list>llist</a> [ 4 5 6 ] <a href="#list>llist">list>llist</a> <a href="#lappend">lappend</a>
|
|
( 2 ) [ . ] <a href="#leach">leach</a>
|
|
=> 1
|
|
2
|
|
3
|
|
4
|
|
5
|
|
6
|
|
</pre>
|
|
|
|
<!-- lappend* description -->
|
|
<a name="lappendstar">
|
|
<h3>lappend* ( llists -- llist )</h3>
|
|
<p>Given a lazy list of lazy lists, concatenate them together in a
|
|
lazy fashion. The actual appending is done lazily on iteration rather
|
|
than immediately so it works very fast no matter how large the lists.</p>
|
|
<pre class="code">
|
|
( 1 ) [ 1 2 3 ] <a href="#list>llist">list>llist</a>
|
|
( 2 ) [ 4 5 6 ] <a href="#list>llist">list>llist</a>
|
|
( 3 ) [ 7 8 9 ] <a href="#list>llist">list>llist</a>
|
|
( 4 ) 3list <a href="#list>llist">list>llist</a> <a href="#lappendstar">lappend*</a>
|
|
( 5 ) [ . ] <a href="#leach">leach</a>
|
|
=> 1
|
|
2
|
|
3
|
|
4
|
|
5
|
|
6
|
|
7
|
|
8
|
|
9
|
|
</pre>
|
|
|
|
<!-- list>llist description -->
|
|
<a name="list>llist">
|
|
<h3>list>llist ( list -- llist )</h3>
|
|
<p>Converts a normal list into a lazy list. This is done lazily so the
|
|
initial list is not iterated through immediately.</p>
|
|
<pre class="code">
|
|
( 1 ) [ 1 2 3 ] <a href="#list>llist">list>llist</a>
|
|
( 2 ) [ . ] <a href="#leach">leach</a>
|
|
=> 1
|
|
2
|
|
3
|
|
</pre>
|
|
|
|
<p class="footer">
|
|
News and updates to this software can be obtained from the authors
|
|
weblog: <a href="http://radio.weblogs.com/0102385">Chris Double</a>.</p>
|
|
<p id="copyright">Copyright (c) 2004, Chris Double. All Rights Reserved.</p>
|
|
</body> </html>
|