This site is a static rendering of the Trac instance that was used by R7RS-WG1 for its work on R7RS-small (PDF), which was ratified in 2013. For more information, see Home.

Source for wiki LazySequencesCowan version 13

author

cowan

comment


    

ipnr

127.11.51.1

name

LazySequencesCowan

readonly

0

text

 `
{{{
#!html
<h1>Table of contents</h1>

<ul id="toc-table">
<li><a href="#Abstract">Abstract</a>
</li><li><a href="#Rationale">Rationale</a>
</li><li><a href="#ProcedureIndex">Procedure index</a>
<li><a href="#Quotation">Quotation</a></li>
<li><a href="#TheProcedures">The procedures</a>
  <ul>
  <li><a href="#Constructors">Constructors</a>
  </li><li><a href="#Predicates">Predicates</a>
  </li><li><a href="#Selectors">Selectors</a>
  </li><li><a href="#Whole">The whole lazy sequence</a>
  </li><li><a href="#FoldingMapping">Folding and mapping</a>
  </li><li><a href="#FilteringPartitioning">Filtering and partitioning</a>
  </li><li><a href="#Searching">Searching</a>
  </li><li><a href="#Deletion">Deletion</a>
  </li><li><a href="#LazyAssociationLists">Lazy association lists</a>
  </li><li><a href="#Conversion">Conversion</a>
  </li><li><a href="#Comparators">Comparators</a>
  </li><li><a href="#Realization">Realization</a>
  </li></ul>
</li><li><a href="#SampleImplementation">Sample Implementation</a>
</li><li><a href="#Acknowledgements">Acknowledgements</a>
</li><li><a href="#ReferencesLinks">References &amp; links</a>
</li><li><a href="#Copyright">Copyright</a>
</li></ul>


<!--========================================================================-->
<h1><a name="Abstract">Abstract</a></h1>
<p>
ABSTRACT</p>

<h1><a name="Rationale">Rationale</a></h1>
<p>RATIONALE</p>
<p>
Note:  In the prose, lazy sequences are known as lseqs throughout.
</p>
<!--========================================================================-->
<h1><a name="ProcedureIndex">Procedure Index</a></h1>
<p>
Here is a short list of the procedures provided by this SRFI.

</p><div class="indent">
<dl>
<dt class="proc-index"> Constructors
</dt><dd class="proc-index">
<pre class="proc-index"><a href="#lseq-cons">lseq-cons</a>     <a href="#lseq">lseq</a>         <a href="#lseq*">lseq*</a>
<a href="#list->lseq">list->lseq</a>    <a href="#vector->lseq">vector->lseq</a>
<a href="#string->lseq">string->lseq</a>  <a href="#generator->lseq">generator->lseq</a> 
<a href="#lseq-unfold">lseq-unfold</a>   <a href="#lseq-unfold-right">lseq-unfold-right</a>
</pre>

</dd><dt class="proc-index"> Predicates
</dt><dd class="proc-index">
<pre class="proc-index">
<a href="#lseq-p">lseq?</a>         <a href="#null-lseq-p">null-lseq?</a>   <a href="#lseq=">lseq=</a>
</pre>

</dd><dt class="proc-index"> Selectors
</dt><dd class="proc-index">
<pre class="proc-index">
<a href="#lseq-first">lseq-first</a> <a href="#lseq-second">lseq-second</a>  <a href="#lseq-third">lseq-third</a> <a href="#lseq-fourth">lseq-fourth</a> <a href="#lseq-fifth">lseq-fifth</a>
<a href="#lseq-sixth">lseq-sixth</a> <a href="#lseq-seventh">lseq-seventh</a> <a href="#lseq-eighth">lseq-eighth</a> <a href="#lseq-ninth">lseq-ninth</a> <a href="#lseq-tenth">lseq-tenth</a>
<a href="#lseq-last">lseq-last</a>  <a href="#lseq-rest">lseq-rest</a>    <a href="#lseq-ref">lseq-ref</a>
<a href="#lseq-take">lseq-take</a>       <a href="#lseq-drop">lseq-drop</a>
<a href="#lseq-take-right">lseq-take-right</a> <a href="#lseq-drop-right">lseq-drop-right</a>
<a href="#lseq-split-at">isplit-at</a>   
</pre>

</dd><dt class="proc-index"> The whole lazy sequence
</dt><dd class="proc-index">
<pre class="proc-index"><a href="#lseq-length">lseq-length</a> 
<a href="#lseq-append">lseq-append</a>  <a href="#lseq-concatenate">lseq-concatenate</a>  <a href="#lseq-reverse">lseq-reverse</a>
<a href="#lseq-zip">lseq-zip</a>     <a href="#lseq-unzip1">lseq-unzip1</a>       <a href="#lseq-unzip2">lseq-unzip2</a>
<a href="#lseq-unzip3">lseq-unzip3</a>  <a href="#lseq-unzip4">lseq-unzip4</a>       <a href="#lseq-unzip5">lseq-unzip5</a>
<a href="#lseq-count">lseq-count</a>
</pre>

</dd><dt class="proc-index"> Folding and mapping
</dt><dd class="proc-index">
<pre class="proc-index"><a href="#lseq-map">lseq-map</a>        <a href="#lseq-for-each">lseq-for-each</a>
<a href="#lseq-fold">lseq-fold</a>       <a href="#lseq-fold-right">lseq-fold-right</a>
<a href="#lseq-fold-subseq">lseq-fold</a>       <a href="#lseq-fold-subseq-right">lseq-fold-right</a>
<a href="#lseq-reduce">lseq-reduce</a>     <a href="#lseq-reduce-right">lseq-reduce-right</a> 
</pre>

</dd><dt class="proc-index"> Filtering and partitioning
</dt><dd class="proc-index">
<pre class="proc-index"><a href="#lseq-filter">lseq-filter</a>     <a href="#lseq-remove">lseq-remove</a>      <a href="#lseq-partition">lseq-partition</a>
</pre>

</dd><dt class="proc-index"> Searching
</dt><dd class="proc-index"><pre class="proc-index">
<a href="#lseq-member">lseq-member</a>       <a href="#lseq-memq">lseq-memq</a>     <a href="#lseq-memv">lseq-memv</a>
<a href="#lseq-find">lseq-find</a>         <a href="#lseq-find-rest">lseq-find-rest</a> 
<a href="#lseq-any">lseq-any</a>          <a href="#lseq-every">lseq-every</a>
<a href="#lseq-index">lseq-index</a>
<a href="#lseq-take-while">lseq-take-while</a>   <a href="#lseq-drop-while">lseq-drop-while</a>
<a href="#lseq-span">lseq-span</a>         <a href="#lseq-break">lseq-break</a>
</pre>

</dd><dt class="proc-index"> Deleting
</dt><dd class="proc-index">
<pre class="proc-index"><a href="#lseq-delete">lseq-delete</a>       <a href="#lseq-delete-neighbor-dups">lseq-delete-neighbor-dups</a> 

</pre>

</dd><dt class="proc-index"> Lazy association lists
</dt><dd class="proc-index">
<pre class="proc-index"><a href="#lseq-assoc">lseq-assoc</a>        <a href="#lseq-assq">lseq-assq</a>       <a href="#lseq-assv">lseq-assv</a>
<a href="#lseq-alist-cons">lseq-alist-cons</a>   <a href="#lseq-alist-delete">lseq-alist-delete</a>
</pre>

</dd><dt class="proc-index"> Conversion
</dt><dd class="proc-index">
<pre class="proc-index"><a href="#lseq->list">lseq->list</a>        <a href="#lseq->vector">lseq-vector</a>
<a href="#lseq->string">lseq->string</a>      <a href="lseq->generator">lseq->generator</a>
</pre>

</dd><dt class="proc-index"> Comparators
</dt><dd class="proc-index">
<pre class="proc-index"><a href="#lseq-comparator">lseq-comparator</a>   <a href="#make-lseq-comparator">make-lseq-comparator</a>
</pre>

</dd><dt class="proc-index"> Realization
</dt><dd class="proc-index">
<pre class="proc-index"><a href="#lseq-realize">lseq-realize!</a>              <a href="#lseq-realize-once">lseq-realize-once!</a>
<a href="#lseq-realize-steps">lseq-realize-steps!</a>        <a href="#lseq-realize-until">lseq-realize-until!</a>
</pre>

</dd></dl>
</div>

<h1><a name="Quotation">Quotation</a></h1>
<p>The syntax keyword <code>lq</code> is
provided as part of this SRFI.  It is analogous to <code>quote</code>,
taking an arbitrary number of literals and constructing an lseq from them.
It is useful for providing constant lazy sequences.</p>


<!--========================================================================-->
<h1><a name="TheProcedures">The procedures</a></h1>
<p>
The templates given below obey the following conventions for procedure formals:
</p><table>
<tbody><tr valign="baseline"><th align="left"> <var>lseq</var>	
    </th><td> A lazy sequence
</td></tr><tr valign="baseline">
    <th align="left"> <var>x</var>, <var>y</var>, <var>d</var>, <var>a</var>
    </th><td> Any value
</td></tr><tr valign="baseline"><th align="left"> <var>object</var>, <var>value</var>
    </th><td> Any value
</td></tr><tr valign="baseline"><th align="left"> <var>n</var>, <var>i</var>
    </th><td> A natural number (an integer &gt;= 0)
</td></tr><tr valign="baseline"><th align="left"> <var>proc</var>
    </th><td> A procedure
</td></tr><tr valign="baseline"><th align="left"> <var>pred</var>
    </th><td> A procedure whose return value is treated as a boolean
</td></tr><tr valign="baseline"><th align="left"> <var>generator</var>
    </th><td> A procedure with no arguments that returns a sequence of values
</td></tr><tr valign="baseline"><th align="left"> <var>=</var>
    </th><td> A boolean procedure taking two arguments
</td></tr></tbody></table>

<p>To interpret the examples, pretend that they are executed on a Scheme that prints lazy sequences with the syntax of lists.

<!--========================================================================-->
</p><h2><a name="Constructors">Constructors</a></h2>
<p>

</p><dl>

<!--
==== lseq-cons
============================================================================-->
<a name="lseq-cons"></a>
</dd><dt class="proc-def"><code class="proc-def">lseq*</code><var> elt lseq -&gt; lseq</var>
</dt><dd class="proc-def">

    <p>Returns a newly allocated lseq whose members are <var>elt</i>
    followed by the elements of <var>lseq</var>.</p>
       
<pre class="code-example">(lseq-cons 1 (lseq 2 3 4)) =&gt; (1 2 3 4)
</pre>

<!--
==== lseq
============================================================================-->
</dd><dt class="proc-def">
<a name="lseq"></a>
<code class="proc-def">lseq</code> <var>object ... -&gt; lseq</var>
</dt><dd class="proc-def">
    
    <p>Returns a newly allocated lseq of its arguments.</p>
<pre class="code-example">(lseq 'a (+ 3 4) 'c) =&gt;  (a 7 c)
(lseq)               =&gt;  ()
</pre>

<!--
==== lseq*
============================================================================-->
<a name="lseq*"></a>
</dd><dt class="proc-def"><code class="proc-def">lseq*</code><var> elt<sub>1</sub> elt<sub>2</sub> ... -&gt; lseq</var>
</dt><dd class="proc-def">

    <p>Like <code>lseq</code>, 
    but the last argument is an lseq.  This procedure is potentially more efficient
    then calling <code>lseq-cons</code> repeatedly.</p>
       
<pre class="code-example">(lseq* 1 2 3 (lseq 4)) =&gt; (1 2 3 4)
</pre>

<!--
==== list->lseq, vector->lseq, string->lseq, generator->lseq
============================================================================-->
<a name="list->lseq"></a>
</dd><dt class="proc-def1"> <code class="proc-def">list->lseq</code> <var>list -&gt; lseq</var>
<a name="vector->lseq"></a>
</dd><dt class="proc-defn"> <code class="proc-def">vector->lseq</code> <var>vector -&gt; lseq</var>
<a name="string->lseq"></a>
</dd><dt class="proc-defn"> <code class="proc-def">string->lseq</code> <var>string -&gt; lseq</var>
<a name="generator->lseq"></a>
</dd><dt class="proc-def"> <code class="proc-def">generator->lseq</code> <var>generator -&gt; lseq</var>
</dt><dd class="proc-def">
    <p>Returns an lseq
    whose elements are the elements of <var>list, vector, string</var>,
    or the values generated by <var>generator</var>.</p>
<pre class="code-example">
(list->lseq '(c c c c c)) =&gt; (c c c c)
(vector->lseq #(c c c c c)) =&gt; (c c c c)
(string->lseq "cccc") =&gt; (#\c #\c #\c #\c)
(generator->lseq (circular-generator 'c)) =&gt; (c c c ...)
</pre>

<!--
==== lseq-unfold
============================================================================-->
</dd><dt class="proc-def">
<a name="lseq-unfold"></a>
<code class="proc-def">lseq-unfold</code><var> stop? mapper successor seed -&gt; lseq</var>
</dt><dd class="proc-def"><p>
Creates a newly allocated lseq, and performs the following algorithm with the current seed set to <var>seed</var>:

</p><p>If the result of applying the predicate <var>stop?</var> to the current seed is true, return the lseq. Otherwise, apply the procedure <var>mapper</var> to the current seed, returning a value which is appended to the lseq. Then get a new seed by applying the procedure <var>successor</var> to the current seed, and repeat this algorithm. 

</p><pre class="code-example">;; Lseq of squares: 1^2 ... 10^2
(lseq-unfold (lambda (x) (&gt; x 10))
        (lambda (x) (* x x))
	(lambda (x) (+ x 1))
	1)
</pre>
		
<!--
==== lseq-unfold-right
============================================================================-->
</dd><dt class="proc-def">
<a name="lseq-unfold-right"></a>
<code class="proc-def">lseq-unfold-right</code><var> stop? mapper successor seed -&gt; lseq</var>
</dt><dd class="proc-def"><p>
Creates a newly allocated lseq, and performs the following algorithm with the current seed set to <var>seed</var>:

</p><p>If the result of applying the predicate <var>stop?</var> to the current seed is true, return the lseq. Otherwise, apply the procedure <var>mapper</var> to the current seed, returning a value which is prepended to the lseq. Then get a new seed by applying the procedure <var>successor</var> to the current seed, and repeat this algorithm. 

</p><pre class="code-example">;; Lseq of squares: 10^2 ... 1^2
(lseq-unfold (lambda (x) (&gt; x 10))
        (lambda (x) (* x x))
	(lambda (x) (+ x 1))
	1)
</pre>
</dd></dl>
<!--========================================================================-->
<h2><a name="Predicates">Predicates</a></h2>
<dl>
<!--
==== lseq?
============================================================================-->
<dt class="proc-def">
<code class="proc-def">lseq?</code><var> x -&gt; boolean</var>
<a name="lseq-p"></a>
</dt><dd class="proc-def">
    <p>Returns <code>#t</code> iff <var>x</var> is an lseq, otherwise <code>#f</code>.</p>


<!--
==== null-lseq?
============================================================================-->
<a name="null-lseq-p"></a>
</dd><dt class="proc-def"><code class="proc-def">null-lseq?</code><var> lseq -&gt; boolean</var>
</dt><dd class="proc-def">
    <p>This procedure returns <code>#t</code> if
    the argument is an empty lseq, and <code>#f</code> otherwise.</p>

<!--
==== lseq=
============================================================================-->
</dd><dt class="proc-def">
<a name="list="></a>
<code class="proc-def">lseq=</code><var> elt= lseq<sub>1</sub> ... -&gt; boolean</var>
</dt><dd class="proc-def">
    <p>Determines lseq equality, given an element-equality procedure.
    The lseq <var>A</var> equals the lseq <var>B</var> 
    if they are of the same length,
    and their corresponding elements are equal, 
    as determined by <var>elt=</var>. 
    If the element-comparison procedure's first argument is
    from <var>lseq<sub>i</sub></var>, 
    then its second argument is from <var>lseq<sub>i+1</sub></var>, 
    <em>i.e.</em> it is always called as
        <code>(<var>elt=</var> <var>a</var> <var>b</var>)</code>
    for <var>a</var> an element of lseq <var>A</var>, 
    and <var>b</var> an element of lseq <var>B</var>.</p>
<p>
    In the <var>n</var>-ary case, 
    every <var>lseq<sub>i</sub></var> is compared to 
    <var>lseq<sub>i+1</sub></var> 
    (as opposed, for example, to comparing 
    <var>lseq<sub>1</sub></var> to    <var>lseq<sub>i</sub></var>, 
    for <var>i</var>&gt;1). 
    If there are no lseq arguments at all, 
    <code>lseq=</code> simply returns true.
</p><p>
    Note that the dynamic order in which the <var>elt=</var> procedure is
    applied to pairs of elements is not specified. 
    For example, if <code>lseq=</code> is applied
    to three lseqs, <var>A</var>, <var>B</var>, and <var>C</var>, 
    it may first completely compare <var>A</var> to <var>B</var>,
    then compare <var>B</var> to <var>C</var>, 
    or it may compare the first elements of <var>A</var> and <var>B</var>,
    then the first elements of <var>B</var> and <var>C</var>, 
    then the second elements of <var>A</var> and <var>B</var>, and so forth.
</p><p>
    The equality procedure must be consistent with <code>eq?</code>. 
    That is, it must be the case that
</p><div class="indent">
        <code>(eq? <var>x</var> <var>y</var>)</code> =&gt; <code>(<var>elt=</var> <var>x</var> <var>y</var>)</code>.
</div>
    <p>Note that this implies that two lseqs which are <code>eq?</code> 
    are always <code>lseq=</code>, as well; implementations may exploit this
    fact to "short-cut" the element-by-element comparisons.</p>
<pre class="code-example">(lseq= eq?) =&gt; #t       ; Trivial cases
(lseq= eq? (lq a)) =&gt; #t
</pre>

</dd></dl>


<!--========================================================================-->
<h2><a name="Selectors">Selectors</a></h2>
<dl>

<!--
==== lseq-tenth
==== lseq-ninth
==== lseq-eighth
==== lseq-seventh
==== lseq-sixth
==== lseq-fifth
==== lseq-fourth
==== lseq-third
==== lseq-second
==== lseq-first
============================================================================-->
</dd><dt class="proc-def1">
<a name="lseq-first"></a>
<code class="proc-def">lseq-first&nbsp;&nbsp;&nbsp;</code><var>lseq -&gt; object </var>
</dt><dt class="proc-defi">
<a name="lseq-second"></a>
<code class="proc-def">lseq-second&nbsp;&nbsp;</code><var>lseq -&gt; object </var>
</dt><dt class="proc-defi">
<a name="lseq-third"></a>
<code class="proc-def">lseq-third&nbsp;&nbsp;&nbsp;</code><var>lseq -&gt; object </var>
</dt><dt class="proc-defi">
<a name="lseq-fourth"></a>
<code class="proc-def">lseq-fourth&nbsp;&nbsp;</code><var>lseq -&gt; object </var>
</dt><dt class="proc-defi">
<a name="lseq-fifth"></a>
<code class="proc-def">lseq-fifth&nbsp;&nbsp;&nbsp;</code><var>lseq -&gt; object </var>
</dt><dt class="proc-defi">
<a name="lseq-sixth"></a>
<code class="proc-def">lseq-sixth&nbsp;&nbsp;&nbsp;</code><var>lseq -&gt; object </var>
</dt><dt class="proc-defi">
<a name="lseq-seventh"></a>
<code class="proc-def">lseq-seventh&nbsp;</code><var>lseq -&gt; object </var>
</dt><dt class="proc-defi">
<a name="lseq-eighth"></a>
<code class="proc-def">lseq-eighth&nbsp;&nbsp;</code><var>lseq -&gt; object </var>
</dt><dt class="proc-defi">
<a name="lseq-ninth"></a>
<code class="proc-def">lseq-ninth&nbsp;&nbsp;&nbsp;</code><var>lseq -&gt; object </var>
</dt><dt class="proc-defi">
<a name="lseq-tenth"></a>
<code class="proc-def">lseq-tenth&nbsp;&nbsp;&nbsp;</code><var>lseq -&gt; object  </var>
</dt><dt class="proc-defn">
<a name="lseq-last"></a>
<code class="proc-def">lseq-last&nbsp;&nbsp;&nbsp;</code><var>lseq -&gt; object  </var>
</dt><dd class="proc-def">
    <p>Returns the first, second, ..., tenth, last element of <var>lseq</var>.</p> 

<pre class="code-example">(lseq-third (lq a b c d e)) =&gt; c
</pre>

<!--
==== lseq-rest
============================================================================-->
<a name="lseq-rest"></a>
<dt class="proc-def"><code class="proc-def">lseq-rest</code><var> lseq -&gt; lseq</var>
</dt><dd class="proc-def">
    
    <p>Returns an lseq with the contents of <var>lseq</i> except for the
    first element.
    Note that it is an error to apply it to an empty lseq.</p>
<pre class="code-example">
(lseq-first (lq a b c))       =&gt;  a        (lseq-rest (lq a b c))         =&gt;  (b c)  
(lseq-first (lq (a) b c d))   =&gt;  (a)	      (lseq-rest (lq (a) b c d))     =&gt;  (b c d)
(lseq-first (lseq-pair 1 2))  =&gt;  1	      (lseq-rest (lseq-pair 1 2))    =&gt;  2      
(lseq-first '())              =&gt;  *error*  (lseq-rest '())                =&gt;  *error*
</pre>



<!--
==== lseq-ref
============================================================================-->
<a name="lseq-ref"></a>
</dd><dt class="proc-def"><code class="proc-def">lseq-ref</code><var> lseq i -&gt; value</var>
</dt><dd class="proc-def">
    
    <p>Returns the <var>i</var>th element of <var>lseq</var>.  
    (This is the same as 
        <code>(lseq-first (lseq-drop <var>lseq</var> <var>i</var>))</code>.)
    It is an error if <var>i</var> &gt;= <var>n</var>, 
    where <var>n</var> is the length of <var>lseq</var>.</p>
<pre class="code-example">    
(lseq-ref (lq a b c d) 2) =&gt; c
</pre>    

<!--
==== lseq-drop
==== lseq-take
============================================================================-->
</dd><dt class="proc-def1">
<a name="lseq-take"></a>
<code class="proc-def">lseq-take</code><var> lseq i -&gt; lseq</var>
</dt><dt class="proc-defi">
<a name="lseq-drop"></a>
<code class="proc-def">lseq-drop</code><var> lseq i -&gt; object</var>
</dt><dt class="proc-def">
</dt><dd class="proc-def">
    <p><code>lseq-take</code> returns the first <var>i</var> elements of <var>lseq</var>.<br/>
    <code>lseq-drop</code> returns all but the first <var>i</var> elements of <var>lseq</var>.<br/></p>
<pre class="code-example">(lseq-take (lq a b c d e)  2) =&gt; (a b)
(lseq-drop (lq a b c d e)  2) =&gt; (c d e)
</pre>
    <p>For a legal <var>i</var>, <code>lseq-take</code> and <code>lseq-drop</code> partition <var>lseq</var> in a manner which
    can be inverted with <code>lseq-append</code>:</p>
<pre class="code-example">(lseq-append (lseq-take <var>lseq</var> <var>i</var>) (lseq-drop <var>lseq</var> <var>i</var>)) = <var>lseq</var>
</pre>
    <p><code>lseq-drop</code> is exactly equivalent to performing <var>i</var> <code>lseq-rest</code> operations on <var>lseq</var>.</p>


<!--
==== lseq-drop-right
==== lseq-take-right
============================================================================-->
</dd><dt class="proc-def1">
<a name="lseq-take-right"></a>
<code class="proc-def">lseq-take-right</code><var> lseq i -&gt; object</var>
</dt><dt class="proc-defn">
<a name="lseq-drop-right"></a>
<code class="proc-def">lseq-drop-right</code><var> lseq i -&gt; lseq</var>
</dt><dd class="proc-def">
    <p><code>lseq-take-right</code> returns the last <var>i</var> elements of <var>lseq</var>.<br/>
    <code>lseq-drop-right</code> returns all but the last <var>i</var> elements of <var>lseq</var>.</p>
<pre class="code-example">(lseq-take-right (lq a b c d e) 2) =&gt; (d e)
(lseq-drop-right (lq a b c d e) 2) =&gt; (a b c)
</pre>
    <p>For a legal <var>i</var>, <code>lseq-take-right</code> and <code>lseq-drop-right</code> partition <var>lseq</var> in a manner 
    which can be inverted with <code>lseq-append</code>:</p>
<pre class="code-example">(lseq-append (lseq-take <var>lseq</var> <var>i</var>) (lseq-drop <var>lseq</var> <var>i</var>)) = <var>lseq</var>
</pre>
    <p><code>lseq-take-right</code>'s return value is guaranteed to share a common tail with <var>lseq</var>.</p>

 
<!--
==== lseq-split-at
============================================================================-->
</dd><dt class="proc-def">
<a name="lseq-split-at"></a>
<code class="proc-def">lseq-split-at&nbsp;</code><var> lseq i -&gt; [lseq object]</var>
</dt><dd class="proc-def">
    <p>Splits the lseq <var>lseq</var> 
    at index <var>i</var>, returning two values, an lseq of the 
    first <var>i</var> elements, and an lseq of the remaining elements. It is equivalent
    to</p>
<pre class="code-example">(values (lseq-take lseq i) (lseq-drop lseq i))
</pre>
</dd></dl>

<!--========================================================================-->
<h2><a name="Whole">The whole lazy sequence</a></h2>

<dl>
<!--
==== lseq-length
============================================================================-->
<dt class="proc-def">
<a name="lseq-length"></a>
<code class="proc-def">lseq-length&nbsp;&nbsp;</code><var>lseq -&gt; integer</var>
</dt><dd class="proc-def">
    <p>Returns the length of its argument, which is the non-negative integer <var>n</var> such that <code>lseq-last</code> 
    applied <var>n</var> times to the lseq produces an empty lseq.</p>


<!--
==== lseq-append
============================================================================-->
</p></dd><dt class="proc-def">
<a name="lseq-append"></a>
<code class="proc-def">lseq-append&nbsp;</code><var> lseq<sub>1</sub> ... -&gt; lseq</var>
</dt><dd class="proc-def">
    
    <p>Returns an lseq consisting of the elements 
    of <var>lseq<sub>1</sub></var>
    followed by the elements of the other lseq parameters.</p>
<pre class="code-example">(lseq-append (lq x) (lq y))        =&gt;  (x y)
(lseq-append (lq a) (lq b c d))    =&gt;  (a b c d)
(lseq-append (lq a (b)) (lq (c)))  =&gt;  (a (b) (c))
</pre>
    <p>The resulting lseq is always newly allocated, except that it
    shares structure with the final <var>lseq<sub>i</sub></var> argument.</p>
<pre class="code-example">(lseq-append (lq a b) (lseq-pair 'c 'd))  =&gt;  (a b c . d)
(lseq-append '() 'a)           =&gt;  a
(lseq-append (lq x y))         =&gt;  (x y)
(lseq-append)                  =&gt;  ()
</pre>

<!--
==== lseq-concatenate 
============================================================================-->
</dd><dt class="proc-def">
<a name="lseq-concatenate"></a>
<code class="proc-def">lseq-concatenate&nbsp;</code><var> list-of-lseqs -&gt; value</var>
</dt><dd class="proc-def">
    <p>Appends the elements of its argument together.</p> 
<p>
    Note that some Scheme implementations do not support passing more than a
    certain number (<em>e.g.</em>, 64) of arguments to an n-ary procedure.  
    In these implementations, the <code>(apply lseq-append ...)</code> idiom
    would fail when applied to long lists, 
    but <code>lseq-concatenate</code> would continue to function properly.

<!--
==== lseq-reverse
============================================================================-->
</p></dd><dt class="proc-def">
<a name="lseq-reverse"></a>
<code class="proc-def">lseq-reverse&nbsp;</code><var> lseq -&gt; lseq</var>
</dt><dd class="proc-def">
    

    <p>Returns a newly allocated lseq consisting of
    the elements of <var>lseq</var> in reverse order.</p>
<pre class="code-example">(lseq-reverse (lq a b c)) =&gt;  (c b a)
(lseq-reverse (lq a (b c) d (e (f))))
    =&gt;  ((e (f)) d (b c) a)
</pre>


<!--
==== lseq-append-reverse
============================================================================-->
</dd><dt class="proc-def">
<a name="lseq-append-reverse"></a>
<code class="proc-def">lseq-append-reverse&nbsp;&nbsp;</code><var>rev-head tail -&gt; lseq</var>
</dt><dd class="proc-def">
    <p><code>lseq-append-reverse</code> returns
	<code>(lseq-append (lseq-reverse <var>rev-head</var>) <var>tail</var>)</code>.
    It is provided because it is a common operation — a common
    list-processing style calls for this exact operation to transfer values
    accumulated in reverse order onto the front of another lseq, and because
    the implementation is significantly more efficient than the simple
    composition it replaces. (But note that this pattern of iterative 
    computation followed by a reverse can frequently be rewritten as a 
    recursion, dispensing with the <code>reverse</code> and <code>lseq-append-reverse</code> steps, and 
    shifting temporary, intermediate storage from the heap to the stack, 
    which is typically a win for reasons of cache locality and eager storage 
    reclamation.)</p>


<!--
==== lseq-zip
============================================================================-->
<a name="lseq-zip"></a>
</dd><dt class="proc-def"><code class="proc-def">lseq-zip</code> <var>lseq<sub>1</sub> lseq<sub>2</sub> ... -&gt; lseq</var>
</dt><dd class="proc-def">
    <p>If <code>lseq-zip</code> is passed <var>n</var> lseqs, it returns an lseq as long as the shortest
    of these lseqs, each element of which is an <var>n</var>-element list comprised
    of the corresponding elements from the arguments.</p>

<pre class="code-example">(lseq-zip (lq one two three) 
     (lq 1 2 3)
     (lq odd even odd even odd even odd even))
    =&gt; ((one 1 odd) (two 2 even) (three 3 odd))

(lseq-zip (lq 1 2 3)) =&gt; ((1) (2) (3))
</pre>
    
<!--
==== lseq-unzip5
==== lseq-unzip4
==== lseq-unzip3
==== lseq-unzip2
==== lseq-unzip1
============================================================================-->
<a name="lseq-unzip1"></a>
</dd><dt class="proc-def1">  <code class="proc-def">lseq-unzip1</code><var> list-of-lseqs -&gt; lseq</var>
<a name="lseq-unzip2"></a>
</dt><dt class="proc-defi"> <code class="proc-def">lseq-unzip2</code><var> list-of-lseqs -&gt; [lseq lseq]</var>
<a name="lseq-unzip3"></a>
</dt><dt class="proc-defi"> <code class="proc-def">lseq-unzip3</code><var> list-of-lseqs -&gt; [lseq lseq lseq]</var>
<a name="lseq-unzip4"></a>
</dt><dt class="proc-defi"> <code class="proc-def">lseq-unzip4</code><var> list-of-lseqs -&gt; [lseq lseq lseq lseq]</var>
<a name="lseq-unzip5"></a>
</dt><dt class="proc-defn"> <code class="proc-def">lseq-unzip5</code><var> lslist-of-lseqs eq -&gt; [lseq lseq lseq lseq lseq]</var>
</dt><dd class="proc-def">
    <p><code>lseq-unzip1</code> takes a list of lseqs, 
    where every lseq must contain at least one element, 
    and returns an lseq containing the initial element of each such lseq. 
    That is, it returns <code>(lseq-map lseq-first lseqs)</code>.  
    <code>lseq-unzip2</code> takes a list of lseqs, where every lseq must contain at least
    two elements, and returns two values: an lseq of the first elements,
    and an lseq of the second elements. <code>lseq-unzip3</code> does the same for the first
    three elements of the lseqs, and so forth.</p>

<pre class="code-example">(lseq-unzip2 (list (lq 1 one) (lq 2 two) (lq 3 three))) =&gt;
    (1 2 3) 
    (one two three)
</pre>

<!--
==== lseq-count
============================================================================-->
</dd><dt class="proc-def">
<a name="lseq-count"></a>
<code class="proc-def">lseq-count</code><var> pred lseq<sub>1</sub> lseq<sub>2</sub> ... -&gt; integer</var>
</dt><dd class="proc-def">
    <p><var>pred</var> is a procedure taking as many arguments as there
    are lseqs and returning a single value. It is applied 
    element-wise to the elements of the <var>lseq</var>s, and a count is
    tallied of the number of elements that produce a true value. This count
    is returned. <code>count</code> is "iterative" in that it is guaranteed
    to apply <var>pred</var> to the <var>lseq</var> elements in a
    left-to-right order.
    The counting stops when the shortest lseq expires.
<pre class="code-example">(count even? (lq 3 1 4 1 5 9 2 5 6)) =&gt; 3
(count &lt; (lq 1 2 4 8) (lq 2 4 6 8 10 12 14 16)) =&gt; 3
</pre>
    
</dd></dl>

<!--========================================================================-->
<h2><a name="FoldingMapping">Folding and mapping</a></h2>
<dl>
<!--
==== lseq-fold
============================================================================-->
<dt class="proc-def">
<a name="lseq-fold"></a>
<code class="proc-def">lseq-fold</code><var> kons knil lseq<sub>1</sub> lseq<sub>2</sub> ... -&gt; value</var>
</dt><dd class="proc-def">
    <p>The fundamental lseq iterator. 
</p><p>
    First, consider the single lseq-parameter case. If <var>lseq<sub>1</sub></var> = (<var>e<sub>1</sub></var> <var>e<sub>2</sub></var> ... <var>e<sub>n</sub></var>),
    then this procedure returns
</p><div class="indent">
<code>(<var>kons</var> <var>e<sub>n</sub></var> ... (<var>kons</var> <var>e<sub>2</sub></var> (<var>kons</var> <var>e<sub>1</sub></var> <var>knil</var>)) ... )</code>
</div>
    <p>That is, it obeys the (tail) recursion</p>
<pre class="code-example">(lseq-fold <var>kons</var> <var>knil</var> <var>lis</var>) = (lseq-fold <var>kons</var> (<var>kons</var> (lseq-first <var>lis</var>) <var>knil</var>) (lseq-last <var>lis</var>))
(lseq-fold <var>kons</var> <var>knil</var> '()) = <var>knil</var>
</pre>

    Examples:
<pre class="code-example">(lseq-fold + 0 lis)			; Add up the elements of LIS.

(lseq-fold lseq* (lseq) lseq)		; Reverse lseq.

(lseq-fold lseq* tail rev-head)	; See append-reverse.

;; How many symbols in LIS?
(lseq-fold (lambda (x count) (if (symbol? x) (+ count 1) count))
      0
      lseq)

;; Length of the longest string in lseq:
(lseq-fold (lambda (s max-len) (max max-len (string-length s)))
      0
      lseq)
</pre>

    <p>If <var>n</var> lseq arguments are provided, then the <var>kons</var> function must take
    <var>n</var>+1 parameters: one element from each lseq, and the "seed" or fold
    state, which is initially <var>knil</var>. The fold operation terminates when
    the shortest lseq runs out of values:</p>
<pre class="code-example">(lseq-fold lseq* '() (lq a b c) (lq 1 2 3 4 5)) =&gt; (c 3 b 2 a 1)
</pre>
   
<!--
==== lseq-fold-right
============================================================================-->
</dd><dt class="proc-def">
<a name="lseq-fold-right"></a>
<code class="proc-def">lseq-fold-right</code><var> kons knil lseq<sub>1</sub> lseq<sub>2</sub> ... -&gt; value</var>
</dt><dd class="proc-def"><p>
    The fundamental lseq recursion operator. 
</p><p>
    First, consider the single lseq-parameter case. If <var>lseq<sub>1</sub></var> = <code>(<var>e<sub>1</sub></var> <var>e<sub>2</sub></var> ... <var>e<sub>n</sub></var>)</code>, 
    then this procedure returns
</p><div class="indent"><code>
(<var>kons</var> <var>e<sub>1</sub></var> (<var>kons</var> <var>e<sub>2</sub></var> ... (<var>kons</var> <var>e<sub>n</sub></var> <var>knil</var>)))
</code></div>
    <p>That is, it obeys the recursion</p>
<pre class="code-example">(lseq-fold-right <var>kons</var> <var>knil</var> <var>lis</var>) = (<var>kons</var> (lseq-first <var>lis</var>) (lseq-fold-right <var>kons</var> <var>knil</var> (lseq-last <var>lis</var>)))
(lseq-fold-right <var>kons</var> <var>knil</var> '()) = <var>knil</var>
</pre>
        
    Examples:
;; Filter the even numbers out of lseq.
(lseq-fold-right (lambda (x l) (if (even? x) (lseq-cons x l) l)) '() lseq))
</pre>

    <p>If <var>n</var> lseq arguments are provided, then the <var>kons</var> procedure must take
    <var>n</var>+1 parameters: one element from each lseq, and the "seed" or fold
    state, which is initially <var>knil</var>. The fold operation terminates when
    the shortest lseq runs out of values:</p>
<pre class="code-example">(lseq-fold-right lseq* '() (lq a b c) (lq 1 2 3 4 5)) =&gt; (a 1 b 2 c 3)
</pre>
 
<!--
==== lseq-reduce
============================================================================-->
</dd><dt class="proc-def">
<a name="lseq-reduce"></a>
<code class="proc-def">lseq-reduce</code><var> f ridentity lseq -&gt; value</var>
</dt><dd class="proc-def">
    <p><code>lseq-reduce</code> is a variant of <code>lseq-fold</code>. 
</p><p>
    <var>ridentity</var> should be a "right identity" of the procedure <var>f</var> — that is, 
    for any value <var>x</var> acceptable to <var>f</var>,
</p><pre class="code-example">(<var>f</var> <var>x</var> <var>ridentity</var>) = <var>x</var>
</pre>
    
    <p><code>lseq-reduce</code> has the following definition:
<div class="indent">
If <var>lseq</var> = (),  return <var>ridentity</var>;<br/>
Otherwise,    return <code>(lseq-fold <var>f</var> (lseq-first <var>lseq</var>) (lseq-last <var>lseq</var>))</code>.
</div>
    ...in other words, we compute 
    <code>(lseq-fold <var>f</var> <var>ridentity</var> <var>lseq</var>)</code>.</p>
<p>
    Note that <var>ridentity</var> is used <em>only</em> in an empty-lseq case.
    You typically use <code>lseq-reduce</code> when applying <var>f</var> is expensive and you'd
    like to avoid the extra application incurred when <code>lseq-fold</code> applies
    <var>f</var> to the head of <var>lseq</var> and the identity value,
    redundantly producing the same value passed in to <var>f</var>. 
    For example, if <var>f</var> involves searching a file directory or 
    performing a database query, this can be significant. 
    In general, however, <code>lseq-fold</code> is useful
    in many contexts where <code>lseq-reduce</code> is not
    (consider the examples given in the <code>lseq-fold</code> definition — only one of the
    folds uses a function with a right identity. 
    The other four may not be performed with <code>lseq-reduce</code>).

</p><pre class="code-example">;; take the max of an lseq of non-negative integers.
(lseq-reduce max 0 nums)
</pre>

<!--
==== lseq-reduce-right
============================================================================-->
</dd><dt class="proc-def">
<a name="lseq-reduce-right"></a>
<code class="proc-def">lseq-reduce-right</code><var> f ridentity lseq -&gt; value</var>
</dt><dd class="proc-def">
    <p><code>lseq-reduce-right</code> is the fold-right variant of <code>lseq-reduce</code>.
    It obeys the following definition:</p>
<pre class="code-example">(lseq-reduce-right <var>f</var> <var>ridentity</var> '()) = <var>ridentity</var>
(lseq-reduce-right <var>f</var> <var>ridentity</var> (lq <var>e<sub>1</sub></var>)) = (<var>f</var> <var>e<sub>1</sub></var> <var>ridentity</var>) = <var>e<sub>1</sub></var>
(lseq-reduce-right <var>f</var> <var>ridentity</var> (lq <var>e<sub>1</sub></var> <var>e<sub>2</sub></var> ...)) =
    (<var>f</var> <var>e<sub>1</sub></var> (lseq-reduce <var>f</var> <var>ridentity</var> (<var>e<sub>2</sub></var> ...)))
</pre>
    <p>...in other words, we compute 
    <code>(lseq-fold-right <var>f</var> <var>ridentity</var> <var>lseq</var>)</code>.</p>
    
<pre class="code-example">;; Append a bunch of lseqs together.
(lseq-reduce-right lseq-append '() lseq-of-lseqs)
</pre>

<!--
==== lseq-map
============================================================================-->
</dd><dt class="proc-def">
<a name="lseq-map"></a>
<code class="proc-def">lseq-map</code><var> proc lseq<sub>1</sub> lseq<sub>2</sub> ... -&gt; lseq</var>
</dt><dd class="proc-def">
    

     <p><var>proc</var> is a procedure taking as many arguments 
     as there are lseq arguments and returning a single value.  
     <code>lseq-map</code> applies <var>proc</var> element-wise to the elements
     of the lseqs and returns an lseq of the results, 
     in order.  
     The dynamic order in which <var>proc</var> 
     is applied to the elements of the lseqs is unspecified.</p>
    
<pre class="code-example">(lseq-map icadr (lq (a b) (d e) (g h))) =&gt;  (b e h)

(lseq-map (lambda (n) (expt n n))
     (lq 1 2 3 4 5))
    =&gt;  (1 4 27 256 3125)

(lseq-map + (lq 1 2 3) (lq 4 5 6)) =&gt;  (5 7 9)

(let ((count 0))
  (lseq-map (lambda (lseq-gnored)
         (set! count (+ count 1))
         count)
       (lq a b))) =&gt;  (1 2) <em>or</em> (2 1)
</pre>

 <p>
    
<!--
==== lseq-for-each
============================================================================-->
</p></dd><dt class="proc-def">
<a name="lseq-for-each"></a>
<code class="proc-def">lseq-for-each</code><var> proc lseq<sub>1</sub> lseq<sub>2</sub> ... -&gt; unspecified</var>
</dt><dd class="proc-def">
     

     <p>The arguments to <code>lseq-for-each</code> are like the arguments to 
     <code>lseq-map</code>, but
     <code>lseq-for-each</code> calls <var>proc</var> for its side effects rather
     than for its values.  
     Unlike <code>lseq-map</code>, <code>lseq-for-each</code> is guaranteed to call 
     <var>proc</var> on the elements of the lseqs in order from the first
     element(s) to the last, 
     and the value returned by <code>lseq-for-each</code> is unspecified.</p>
<pre class="code-example">(let ((v (make-vector 5)))
  (lseq-for-each (lambda (lseq-)
              (vector-set! v i (* i i)))
            (lq 0 1 2 3 4))
  v)  =&gt;  #(0 1 4 9 16)
</pre>
 <p>
  
<!--
==== lseq-append-map
============================================================================-->
</p></dd><dt class="proc-def">
<a name="lseq-append-map"></a>
<code class="proc-def">lseq-append-map&nbsp;&nbsp;</code><var>f lseq<sub>1</sub> lseq<sub>2</sub> ... -&gt; value</var>
</dt><dd class="proc-def">
    <p>Map <var>f</var> over the elements of the lseqs, just as in the <code>lseq-map</code> function.
    However, the results of the applications are appended together (using <code>lseq-append</code>) to
    make the final result. 
<p>
    The dynamic order in which the various applications of <var>f</var> are made is
    not specified.
</p><p>
    Example:
</p><pre class="code-example">(lseq-append-map (lambda (x) (lseq x (- x))) (lq 1 3 8))
    =&gt; (1 -1 3 -3 8 -8)
</pre>

</dd></dl>

<!--========================================================================-->
<h2><a name="FilteringPartitioning">Filtering &amp; partitioning</a></h2>
<dl>

<!--
==== lseq-filter
============================================================================-->
<dt class="proc-def">
<a name="lseq-filter"></a>
<code class="proc-def">lseq-filter</code><var> pred lseq -&gt; lseq</var>
</dt><dd class="proc-def">
    <p>Return all the elements of <var>lseq</var> that satisfy predicate <var>pred</var>.
    The lseq is not disordered — elements that appear in the result lseq
    occur in the same order as they occur in the argument lseq.
    The returned lseq may share a common tail with the argument lseq.
    The dynamic order in which the various applications of <var>pred</var> are made is
    not specified.</p>
    
<pre class="code-example">(lseq-filter even? (lq 0 7 8 8 43 -4)) =&gt; (0 8 8 -4)
</pre>

<!--
==== lseq-remove
============================================================================-->
</dd><dt class="proc-def">
<a name="lseq-remove"></a>
<code class="proc-def">lseq-remove</code><var> pred lseq -&gt; lseq</var>
</dt><dd class="proc-def">
    Returns <var>lseq</var> without the elements that satisfy predicate <var>pred</var>:
<pre class="code-example">(lambda (pred lseq) (lseq-filter (lambda (x) (not (pred x))) lseq))
</pre>
    <p>The lseq is not disordered — elements that appear in the result lseq
    occur in the same order as they occur in the argument lseq.
    The returned lseq may share a common tail with the argument lseq.
    The dynamic order in which the various applications of <var>pred</var> are made is 
    not specified.</p>
    
<pre class="code-example">(lseq-remove even? (lq 0 7 8 8 43 -4)) =&gt; (7 43)
</pre>

<!--
==== lseq-partition
============================================================================-->
</dd><dt class="proc-def">
<a name="lseq-partition"></a>
<code class="proc-def">lseq-partition</code><var> pred lseq -&gt; [lseq lseq]</var>
</dt><dd class="proc-def">
    <p>Partitions the elements of <var>lseq</var> with predicate <var>pred</var>, and returns two
    values: the lseq of in-elements and the lseq of out-elements.
    The lseq is not disordered — elements occur in the result lseqs
    in the same order as they occur in the argument lseq.
    The dynamic order in which the various applications of <var>pred</var> are made is
    not specified. One of the returned lseqs may share a common tail with the
    argument lseq.</p>

<pre class="code-example">(lseq-partition symbol? (lq one 2 3 four five 6)) =&gt; 
    (one four five)
    (2 3 6)
</pre>


<!--========================================================================-->
</dd></dl><h2><a name="Searching">Searching</a></h2>
<p>

The following procedures all search lseqs for the leftmost element satisfying
some criteria. 

<!--
==== lseq-find
============================================================================-->
<dt class="proc-def">
<a name="lseq-find"></a>
<code class="proc-def">lseq-find</code><var> pred lseq -&gt; value</var>
</dt><dd class="proc-def">
    <p>Return the first element of <var>lseq</var> that satisfies predicate <var>pred</var>;
    false if no element does.</p>

<pre class="code-example">(lseq-find even? (lq 3 1 4 1 5 9)) =&gt; 4
</pre>

    <p>Note that <code>lseq-find</code> has an ambiguity in its lookup semantics — if <code>lseq-find</code>
    returns <code>#f</code>, you cannot tell (in general) if it found a <code>#f</code> element
    that satisfied <var>pred</var>, or if it did not find any element at all. In
    many situations, this ambiguity cannot arise — either the lseq being
    searched is known not to contain any <code>#f</code> elements, or the lseq is
    guaranteed to have an element satisfying <var>pred</var>. However, in cases
    where this ambiguity can arise, you should use <code>lseq-find-tail</code> instead of
    <code>lseq-find</code> — <code>lseq-find-tail</code> has no such ambiguity:</p>
<pre class="code-example">(cond ((lseq-find-tail pred lseq) =&gt; (lambda (lseq) ...))
      (else ...)) ; Search failed.
</pre>

<!--
==== lseq-find-tail
============================================================================-->
</dd><dt class="proc-def">
<a name="lseq-find-tail"></a>
<code class="proc-def">lseq-find-tail</code><var> pred lseq -&gt; lseq or false</var>
</dt><dd class="proc-def">
    <p>Return the longest tail of <var>lseq</var> whose first element satisfies <var>pred</var>. If no element does,
    return false.
</p><p>
    <code>lseq-find-tail</code> can be viewed as a general-predicate variant of the <code>lseq-member</code>
    function.
</p><p>
    Examples: 
</p><pre class="code-example">(lseq-find-tail even? (lq 3 1 37 -8 -5 0 0)) =&gt; (-8 -5 0 0)
(lseq-find-tail even? (lq 3 1 37 -5)) =&gt; #f

;; imember x lseq:
(lseq-find-tail (lambda (elt) (equal? x elt)) lseq)
</pre>

<p>
    <code>lseq-find-tail</code> is essentially <code>lseq-drop-while</code>, 
    where the sense of the predicate is inverted: 
    <code>lseq-find-tail</code> searches until it finds an element satisfying
    the predicate; <code>lseq-drop-while</code> searches until it finds an 
    element that <em>doesn't</em> satisfy the predicate.

<!--
==== lseq-take-while
============================================================================-->
</p></dd><dt class="proc-def">
<a name="lseq-take-while"></a>
<code class="proc-def">lseq-take-while&nbsp;</code><var> pred lseq -&gt; lseq</var>
</dt><dd class="proc-def">

<p>Returns the longest initial prefix of <var>lseq</var> whose elements all
satisfy the predicate <var>pred</var>.</p>

<pre class="code-example">(lseq-take-while even? (lq 2 18 3 10 22 9)) =&gt; (2 18)
</pre>

<!--
==== lseq-drop-while
============================================================================-->
</dd><dt class="proc-def">
<a name="lseq-drop-while"></a>
<code class="proc-def">lseq-drop-while</code><var> pred lseq -&gt; lseq</var>
</dt><dd class="proc-def">
<p>Drops the longest initial prefix of <var>lseq</var> whose elements all
satisfy the predicate <var>pred</var>, and returns the rest of the lseq.</p>

<pre class="code-example">(lseq-drop-while even? (lq 2 18 3 10 22 9)) =&gt; (3 10 22 9)
</pre>

<!--
==== lseq-span ibreak
============================================================================-->
</dd><dt class="proc-def1">
<a name="lseq-span"></a>
<code class="proc-def">lseq-span&nbsp;&nbsp;</code><var> pred lseq -&gt; [lseq lseq]</var>
</dt><dt class="proc-defn">
<a name="lseq-break"></a>
<code class="proc-def">lseq-break&nbsp;</code><var> pred lseq -&gt; [lseq lseq]</var>
</dt><dd class="proc-def">

<p><code>lseq-span</code> splits the lseq into the longest initial prefix whose
elements all satisfy <var>pred</var>, and the remaining tail. 
<code>lseq-break</code> inverts the sense of the predicate: 
the tail commences with the first element of the input lseq
that satisfies the predicate.</p>

<p>
In other words: 
<code>lseq-span</code> finds the initial span of elements 
satisfying <var>pred</var>, 
and <code>lseq-break</code> breaks the lseq at the first element satisfying 
<var>pred</var>.

</p><p>
<code>lseq-span</code> is equivalent to 
</p><pre class="code-example">(values (lseq-take-while <var>pred</var> <var>lseq</var>) 
        (lseq-drop-while <var>pred</var> <var>lseq</var>))
</pre>

<p>
</p><pre class="code-example">(lseq-span even? (lq 2 18 3 10 22 9)) =&gt;
  (2 18)
  (3 10 22 9)

(lseq-break even? (lq 3 1 4 1 5 9)) =&gt;
  (3 1)
  (4 1 5 9)
</pre>


<!--
==== lseq-any
============================================================================-->
</dd><dt class="proc-def">
<a name="lseq-any"></a>
<code class="proc-def">lseq-any</code><var> pred lseq<sub>1</sub> lseq<sub>2</sub> ... -&gt; value</var>
</dt><dd class="proc-def">
    <p>Applies the predicate across the lseqs, returning true if the predicate
    returns true on any application.
</p><p>
    If there are <var>n</var> lseq arguments <var>lseq<sub>1</sub></var> ... <var>lseq<sub>n</sub></var>, then <var>pred</var> must be a
    procedure taking <var>n</var> arguments and returning a boolean result.
</p><p>
    <code>lseq-any</code> applies <var>pred</var> to the first elements of the <var>lseq<sub>i</sub></var> parameters.
    If this application returns a true value, <code>lseq-any</code> immediately returns
    that value. Otherwise, it iterates, applying <var>pred</var> to the second
    elements of the <var>lseq<sub>i</sub></var> parameters, then the third, and so forth.
    The iteration stops when a true value is produced or one of the lseqs runs
    out of values; in
    the latter case, <code>lseq-any</code> returns <code>#f</code>. 
    The application of <var>pred</var> to the last element of the
    lseqs is a tail call.
</p><p>
    Note the difference between <code>lseq-find</code> and <code>lseq-any</code> — <code>lseq-find</code> returns the element
    that satisfied the predicate; <code>lseq-any</code> returns the true value that the
    predicate produced.
</p><p>
    Like <code>lseq-every</code>, <code>lseq-any</code>'s name does not end with a question mark — this is to
    indicate that it does not return a simple boolean (<code>#t</code> or <code>#f</code>), but a
    general value.

</p><pre class="code-example">(lseq-any integer? (lq a 3 b 2.7))   =&gt; #t
(lseq-any integer? (lq a 3.1 b 2.7)) =&gt; #f
(lseq-any &lt; (lq 3 1 4 1 5)
       (lq 2 7 1 8 2)) =&gt; #t
</pre>

<!--
==== lseq-every
============================================================================-->
</dd><dt class="proc-def">
<a name="lseq-every"></a>
<code class="proc-def">lseq-every</code><var> pred lseq<sub>1</sub> lseq<sub>2</sub> ... -&gt; value</var>
</dt><dd class="proc-def">
    <p>Applies the predicate across the lseqs, returning true if the predicate
    returns true on every application.
</p><p>
    If there are <var>n</var> lseq arguments <var>lseq<sub>1</sub></var> ... <var>lseq<sub>n</sub></var>, then <var>pred</var> must be a
    procedure taking <var>n</var> arguments and returning a boolean result.
</p><p>
    <code>lseq-every</code> applies <var>pred</var> to the first elements of the <var>lseq<sub>i</sub></var> parameters.
    If this application returns false, <code>lseq-every</code> immediately returns false.
    Otherwise, it iterates, applying <var>pred</var> to the second elements of the
    <var>lseq<sub>i</sub></var> parameters, then the third, and so forth. The iteration stops
    when a false value is produced or one of the lseqs runs out of values.
    In the latter case, <code>lseq-every</code> returns
    the true value produced by its final application of <var>pred</var>. 
    The application of <var>pred</var> to the last element of the lseqs 
    is a tail call.
</p><p>
    If one of the <var>lseq<sub>i</sub></var> has no elements, <code>lseq-every</code> simply returns <code>#t</code>.
</p><p>
    Like <code>lseq-any</code>, <code>lseq-every</code>'s name does not end with a question mark — this is to
    indicate that it does not return a simple boolean (<code>#t</code> or <code>#f</code>), but a
    general value.

<!--
==== lseq-index
============================================================================-->
</p></dd><dt class="proc-def">
<a name="lseq-index"></a>
<code class="proc-def">lseq-index</code><var> pred lseq<sub>1</sub> lseq<sub>2</sub> ... -&gt; integer or false</var>
</dt><dd class="proc-def">
    <p>Return the index of the leftmost element that satisfies <var>pred</var>.
</p><p>
    If there are <var>n</var> lseq arguments <var>lseq<sub>1</sub></var> ... <var>lseq<sub>n</sub></var>, then <var>pred</var> must be a
    function taking <var>n</var> arguments and returning a boolean result.
</p><p>
    <code>lseq-index</code> applies <var>pred</var> to the first elements of the <var>lseq<sub>i</sub></var> parameters.
    If this application returns true, <code>lseq-index</code> immediately returns zero.
    Otherwise, it iterates, applying <var>pred</var> to the second elements of the
    <var>lseq<sub>i</sub></var> parameters, then the third, and so forth. When it finds a tuple of
    lseq elements that cause <var>pred</var> to return true, it stops and returns the
    zero-based index of that position in the lseqs.
</p><p>
    The iteration stops when one of the lseqs runs out of values; in this
    case, <code>lseq-index</code> returns <code>#f</code>.

</p><pre class="code-example">(lseq-index even? (lq 3 1 4 1 5 9)) =&gt; 2
(lseq-index &lt; (lq 3 1 4 1 5 9 2 5 6) (lq 2 7 1 8 2)) =&gt; 1
(lseq-index = (lq 3 1 4 1 5 9 2 5 6) (lq 2 7 1 8 2)) =&gt; #f
</pre>

<!--
==== lseq-member lseq-memq lseq-memv
============================================================================-->
</dd><dt class="proc-def1">
<a name="lseq-member"></a>
<code class="proc-def">lseq-member</code><var> x lseq [=] -&gt; lseq</var>
</dt><dt class="proc-defi">
<a name="lseq-memq"></a>
<code class="proc-def">lseq-memq</code><var> x lseq -&gt; lseq</var>
</dt><dt class="proc-defn">
<a name="lseq-memv"></a>
<code class="proc-def">lseq-memv</code><var> x lseq -&gt; lseq</var>
</dt><dd class="proc-def">
     

    <p>These procedures return the longest tail of <var>lseq</var> whose first element is
    <var>x</var>, where the tails of <var>lseq</var> are the 
    non-empty lseqs returned by 
        <code>(lseq-drop <var>lseq</var> <var>i</var>)</code>
    for <var>i</var> less than the length of <var>lseq</var>.  
    If <var>x</var> does
    not occur in <var>lseq</var>, then <code>#f</code> is returned.  
    <code>lseq-memq</code> uses <code>eq?</code> to compare <var>x</var>
    with the elements of <var>lseq</var>, 
    while <code>lseq-memv</code> uses <code>eqv?</code>, and
    <code>lseq-member</code> uses <var>=</var>, which defaults to <code>equal?</code>.</p>

<pre class="code-example">    (lseq-memq 'a (lq a b c))           =&gt;  (a b c)
    (lseq-memq 'b (lq a b c))           =&gt;  (b c)
    (lseq-memq 'a (lq b c d))           =&gt;  #f
    (lseq-memq (lseq 'a) (lq b (a) c)) =&gt;  #f
    (lseq-member (lseq 'a)
            (lq b (a) c))           =&gt;  ((a) c)
    (lseq-memq 101 (lq 100 101 102))    =&gt;  *unspecified*
    (lseq-memv 101 (lq 100 101 102))    =&gt;  (101 102)
</pre>

    
<p>
    The comparison procedure is used to compare the elements <var>e<sub>i</sub></var> of <var>lseq</var>
    to the key <var>x</var> in this way:
</p><div class="indent"><code>
(= <var>x</var> <var>e<sub>i</sub></var>)		; lseq is (E1 ... En)
</code></div>
    <p>That is, the first argument is always <var>x</var>, and the second argument is
    one of the lseq elements. Thus one can reliably find the first element
    of <var>lseq</var> that is greater than five with
	<code>(lseq-member 5 <var>lseq</var> &lt;)</code>

</p><p>
    Note that fully general lseq searching may be performed with
    the <code>lseq-find-tail</code> and <code>lseq-find</code> procedures, <em>e.g.</em>
</p><pre class="code-example">(lseq-find-tail even? lseq) ; Find the first elt with an even key.
</pre>

</dd></dl>

<!--========================================================================-->
<h2><a name="Deletion">Deletion</a></h2>
<p>

</p><dl>
<!--
==== lseq-delete
============================================================================-->
<dt class="proc-def">
<a name="lseq-delete"></a>
<code class="proc-def">lseq-delete&nbsp;&nbsp;</code><var>x lseq [=] -&gt; lseq</var>
</dt><dd class="proc-def">
    <p><code>lseq-delete</code> uses the comparison procedure =,
    which defaults to <code>equal?</code>, to find
    all elements of <var>lseq</var> that are equal to <var>x</var>, and deletes them from <var>lseq</var>. The
    dynamic order in which the various applications of <var>=</var> are made is not
    specified.

<p>
    The lseq is not disordered — elements that appear in the result lseq
    occur in the same order as they occur in the argument lseq.
    The result may share a common tail with the argument lseq.

</p><p>
    Note that fully general element deletion can be performed with the <code>lseq-remove</code>
    procedures, <em>e.g.</em>:
</p><pre class="code-example">;; delete all the even elements from lseq:
(lseq-remove even? lseq)
</pre>

    <p>The comparison procedure is used in this way:
	<code>(= <var>x</var> <var>e<sub>i</sub></var>)</code>.
    That is, <var>x</var> is always the first argument, 
    and an lseq element is always the
    second argument. The comparison procedure will be used to compare each
    element of <var>lseq</var> exactly once; the order in which it is applied to the
    various <var>e<sub>i</sub></var> is not specified.  Thus, one can reliably remove all the
    numbers greater than five from an lseq with
	<code>(lseq-delete 5 lseq &lt;)</code></p>


<!--
==== lseq-delete-neighbor-dups
============================================================================-->
</dd><dt class="proc-def">
<a name="lseq-delete-neighbor-dups"></a>
<code class="proc-def">lseq-delete-neighbor-dups&nbsp;&nbsp;</code><var>lseq [=] -&gt; lseq</var>
</dt><dd class="proc-def">
    <p><code>lseq-delete-neighbor-dups</code> removes consecutive duplicate elements from the
    lseq argument.
    If there are multiple equal elements in the argument lseq, the result lseq
    only contains the first or leftmost of these elements.
    The order of these surviving elements is the same as in the original
    lseq — <code>lseq-delete-duplicates</code> does not disorder the lseq (hence it is useful
    for "cleaning up" lazy association lists).
</p><p>
    The <var>=</var> parameter is used to compare the elements of the lseq; it defaults
    to <code>equal?</code>. If <var>x</var> comes before <var>y</var> in <var>lseq</var>,
    then the comparison is performed 
	<code>(= <var>x</var> <var>y</var>)</code>.
    The comparison procedure will be used to compare each pair of elements in 
    <var>lseq</var> no more than once; 
    the order in which it is applied to the various pairs is not specified.
</p><p>
    Implementations of <code>lseq-delete-duplicates</code>
    are allowed to share common tails
    between argument and result lseqs — for example, if the lseq argument
    contains only unique elements, it may simply return exactly
    this lseq.
</p>
<pre class="code-example">(lseq-delete-duplicates (lq a b a c a b c z)) =&gt; (a b c z)

;; Clean up an lazy alist:
(lseq-delete-neighbor-dups (lq (a . 3) (b . 7) (a . 9) (c . 1))
                   (lambda (x y) (eq? (lseq-first x) (lseq-first y))))
    =&gt; ((a . 3) (b . 7) (c . 1))
</pre>
</dd></dl>

<!--========================================================================-->
<h2><a name="LazyAssociationLists">Lazy association lists</a></h2>
<p>
An "lazy association list" (or "lazy alist") is an lseq of pairs. The car of each pair
contains a key value, and the cdr contains the associated data value. They can
be used to construct simple look-up tables in Scheme.
Note that lazy alists are probably inappropriate for performance-critical use on large data;
in these cases, immutable maps or some other alternative should be employed.

</p><dl>
<!--
==== lseq-assoc lseq-assq lseq-assv
============================================================================-->
<dt class="proc-def1">
<a name="lseq-assoc"></a>
<code class="proc-def">lseq-assoc</code><var> key lazy-alist [=] -&gt; lseq or #f</var>
</dt><dt class="proc-defi">
<a name="lseq-assq"></a>
<code class="proc-def">lseq-assq</code><var> key lazy-alist -&gt; lseq or #f</var>
</dt><dt class="proc-defn">
<a name="lseq-assv"></a>
<code class="proc-def">lseq-assv</code><var> key lazy-alist -&gt; lseq or #f</var>
</dt><dd class="proc-def">

  
    <p>These procedures
    find the first pair in <var>lazy-alist</var> whose car field is <var>key</var>, 
    and returns that pair.  
    If no pair in <var>lazy-alist</var> has <var>key</var> as its icar, 
    then <code>#f</code> is returned.  
    <code>lseq-assq</code> uses <code>eq?</code> to compare <var>key</var> 
    with the car fields of the ipairs in <var>lazy-alist</var>, 
    while <code>lseq-assv</code> uses <code>eqv?</code> 
    and <code>lseq-assoc</code> uses <var>=</var>, which defaults to <code>equal?</code>.</p>

<pre class="code-example">(define e (lq (a 1) (b 2) (c 3)))
(lseq-assq 'a e)                              =&gt;  (a 1)
(lseq-assq 'b e)                              =&gt;  (b 2)
(lseq-assq 'd e)                              =&gt;  #f
(lseq-assq (lseq 'a) (lq ((a)) ((b)) ((c))))  =&gt;  #f
(lseq-assoc (lseq 'a) (lq ((a)) ((b)) ((c)))) =&gt;  ((a))
(lseq-assq 5 (lq (2 3) (5 7) (11 13)))	      =&gt;  *unspecified*
(lseq-assv 5 (lq (2 3) (5 7) (11 13)))	      =&gt;  (5 7)
</pre>
<p>
    The comparison procedure is used to compare the elements <var>e<sub>i</sub></var> of <var>lseq</var>
    to the <var>key</var> parameter in this way:
</p><div class="indent"><code>
(= <var>key</var> (lseq-first <var>e<sub>i</sub></var>))	; lseq is (E1 ... En)
</code></div>
    That is, the first argument is always <var>key</var>, 
    and the second argument is one of the lseq elements. 
    Thus one can reliably find the first entry
    of <var>lazy alist</var> whose key is greater than five with
	<code>(lseq-assoc 5 <var>lazy alist</var> &lt;)</code>
     
</p><p>
    Note that fully general lazy alist searching may be performed with
    the <code>lseq-find-tail</code> and <code>lseq-find</code> procedures, <em>e.g.</em>
</p><pre class="code-example">;; Look up the first association in <var>lazy alist</var> with an even key:
(lseq-find (lambda (a) (even? (lseq-first a))) lazy alist)
</pre>


<!--
==== lseq-alist-cons
============================================================================-->
</dd><dt class="proc-def">
<a name="lseq-alist-cons"></a>
<code class="proc-def">lseq-alist-cons</code><var> key datum lazy-alist -&gt; lazy alist</var>
</dt><dd class="proc-def">
<pre>(lambda (key datum lazy-alist) (lseq* (cons key datum) lazy-alist))
</pre>
    <p>Construct a new lazy alist entry mapping <var>key</var> -&gt; <var>datum</var>
    in front of <var>lazy alist</var>.</p>

<!--
==== lseq-alist-delete
============================================================================-->
</dd><dt class="proc-def">
<a name="lseq-alist-delete"></a>
<code class="proc-def">lseq-alist-delete&nbsp;&nbsp;</code><var>key lazy-alist [=] -&gt; lazy alist</var>
</dt><dd class="proc-def">
    <p><code>lseq-alist-delete</code> deletes all associations from <var>lazy-alist</var> with the given <var>key</var>, 
    using key-comparison procedure <var>=</var>, which defaults to <code>equal?</code>. 
    The dynamic order in which the various applications of <var>=</var> are made is not 
    specified. 
</p><p>
    Return values may share common tails with the <var>lazy-alist</var> argument.
    The lazy alist is not disordered — elements that appear in the result lazy alist
    occur in the same order as they occur in the argument lazy alist.
</p><p>
    The comparison procedure is used to compare the element keys <var>k<sub>i</sub></var> of <var>lazy alist</var>'s
    entries to the <var>key</var> parameter in this way:
	<code>(= <var>key</var> <var>k<sub>i</sub></var>)</code>.
    Thus, one can reliably remove all entries of <var>lazy alist</var> whose key is greater
    than five with
	<code>(lseq-alist-delete 5 <var>lazy alist</var> &lt;)</code>
</p></dd></dl>


<!--========================================================================-->
<h2><a name="Conversion">Conversion</a></h2>
<p>
These procedures convert between mutable and immutable pair structures.

</p><dl>
<!--
==== lseq->list lseq->vector lseq->string lseq->enerator
============================================================================-->
</dd><dt class="proc-def1">
<a name="lseq->list"></a>
<code class="proc-def">lseq->list</code><var> lseq -&gt; list</var>
</dd><dt class="proc-defi">
<a name="lseq->vector"></a>
<code class="proc-def">lseq->vector</code><var> lseq -&gt; vector</var>
</dd><dt class="proc-defi">
<a name="lseq->string"></a>
<code class="proc-def">lseq->string</code><var> lseq -&gt; string</var>
</dd><dt class="proc-defn">
<a name="lseq->generator"></a>
<code class="proc-def">lseq->generator</code><var> lseq -&gt; generator</var>
</dt><dd class="proc-def">
     
     <p>These procedures return a list, a vector, a string, or a generator that have the same
     elements as the argument.</p>

</dd></dl>
<!--========================================================================-->
<h2><a name="Comparators">Comparators</a></h2>

<dl>
<dt class="proc-def">
<a name="lseq-comparator"></a>
<code class="proc-def">lseq-pair-comparator</code>
</dt><dd class="proc-def">
     
     <p>The <code>lseq-comparator</code> object is a SRFI-114 comparator suitable for comparing lseqs.
     Note that it is <em>not</em> a procedure.
     It compares lseqs using <code>default-comparator</code> on their first elements.  If they are not equal, that value is returned.  If they are equal, <code>lseq-comparator</code> is used on the <code>lseq-rest</code> of the lseqs and that value is returned.</p>
</dd>
 
<dt class="proc-def">
<a name="make-lseq-comparator"></a>
<code class="proc-def">make-lseq-comparator</code><var> comparator -&gt; comparator</var>
</dt><dd class="proc-def">
     
     <p>The <code>make-lseq-comparator</code> procedure returns a comparator suitable for comparing lseqs
     using <var>element-comparator</var> to compare the elements.</p>
</dd>
 
</dl>
 
<!--========================================================================-->
<h2><a name="Realization">Realization</a></h2>

<p>These procedures have no directly visible effects on their lseq arguments.
However, they force the generator inside the lazy sequence to produce all its
arguments and store them internally, which means that later operations may be
faster, particularly if the generator is slow.  They return an unspecified value.</p>

<dl>
<dt class="proc-def">
<a name="realize"></a>
<code class="proc-def">realize!</code><var> lseq</var>
</dt><dd class="proc-def">
     
     <p>Realizes all the values of <var>lseq</var>.</p>
</dd>
 
<dt class="proc-def">
<a name="realize"></a>
<code class="proc-def">realize-once!</code><var> lseq</var>
</dt><dd class="proc-def">
     
     <p>Realizes exactly one additional value of <var>lseq</var>.  If no additional
values are available, does nothing.</p>
</dd>
 
<dt class="proc-def">
<a name="realize"></a>
<code class="proc-def">realize-steps!</code><var> lseq n</var>
</dt><dd class="proc-def">
     
     <p>Realizes at most <var>n</var> values of <var>lseq</var>.</p>
</dd>
 
<dt class="proc-def">
<a name="realize"></a>
<code class="proc-def">realize-until!</code><var> lseq pred</var>
</dt><dd class="proc-def">
     
     <p>Realizes values of <var>lseq</var> until at least one value satisfies <var>pred</var>.</p>
</dd>
 
</dl>
 
<!--========================================================================-->
<h1><a name="SampleImplementation">Sample Implementation</a></h1>
<p>An lseq is a <a href="http://srfi.schemers.org/srfi-117/srfi-117.html">SRFI 117</a> queue plus a generator. Queues can be shared between lseqs, which means that you are not allowed to remove anything from them, and the only addition operation is <code>lseq-realize-once!</code>, which realizes one value and adds it to the back of the queue.</p>
<p>The sample implementation of this SRFI depends on SRFI 9 (or R7RS) records.  The files in the implementation are as follows:</p>

<p>FIXME</p>



<!--========================================================================-->
<h1><a name="Acknowledgements">Acknowledgements</a></h1>
<p>
Without the work of Olin Shivers on <a href="http://srfi.schemers.org/srfi-1/srfi-1.html">SRFI 1</a>,
this SRFI would not exist. Everyone acknowledged there is transitively acknowledged here.
This is not to imply that either Olin or anyone else necessarily endorses the final
results, of course. 


}}}

time

2015-01-11 05:53:31

version

13