Small fixes & updates. Olin

This commit is contained in:
marting 1999-10-02 15:39:39 +00:00
parent 72b8df31c1
commit cc6c5af03f
4 changed files with 115 additions and 88 deletions

View File

@ -79,18 +79,34 @@
;;; This is carefully tuned code; do not modify casually. ;;; This is carefully tuned code; do not modify casually.
;;; - It is careful to share storage when possible; ;;; - It is careful to share storage when possible;
;;; - Side-effecting code tries not to perform redundant writes. ;;; - Side-effecting code tries not to perform redundant writes.
;;;
;;; That said, a port of this library to a specific Scheme system might wish ;;; That said, a port of this library to a specific Scheme system might wish
;;; to tune this code to exploit particulars of the implementation. In ;;; to tune this code to exploit particulars of the implementation.
;;; particular, the n-ary mapping functions are particularly slow and ;;; The single most important compiler-specific optimisation you could make
;;; cons-intensive, and are good candidates for tuning. I have coded fast ;;; to this library would be to add rewrite rules or transforms to:
;;; paths for the single-list cases, but what you really want to do is exploit ;;; - transform applications of n-ary procedures (e.g. LIST=, CONS*, APPEND,
;;; the fact that the compiler usually knows how many arguments are being ;;; LSET-UNION) into multiple applications of a primitive two-argument
;;; passed to a particular application of these functions -- they are usually ;;; variant.
;;; explicitly called, not passed around as higher-order values. If you can ;;; - transform applications of the mapping functions (MAP, FOR-EACH, FOLD,
;;; arrange to have your compiler produce custom code or custom linkages based ;;; ANY, EVERY) into open-coded loops. The killer here is that these
;;; on the number of arguments in the call, you can speed these functions up ;;; functions are n-ary. Handling the general case is quite inefficient,
;;; a *lot*. But this kind of compiler technology no longer exists in the ;;; requiring many intermediate data structures to be allocated and
;;; Scheme world as far as I can see. ;;; discarded.
;;; - transform applications of procedures that take optional arguments
;;; into calls to variants that do not take optional arguments. This
;;; eliminates unnecessary consing and parsing of the rest parameter.
;;;
;;; These transforms would provide BIG speedups. In particular, the n-ary
;;; mapping functions are particularly slow and cons-intensive, and are good
;;; candidates for tuning. I have coded fast paths for the single-list cases,
;;; but what you really want to do is exploit the fact that the compiler
;;; usually knows how many arguments are being passed to a particular
;;; application of these functions -- they are usually explicitly called, not
;;; passed around as higher-order values. If you can arrange to have your
;;; compiler produce custom code or custom linkages based on the number of
;;; arguments in the call, you can speed these functions up a *lot*. But this
;;; kind of compiler technology no longer exists in the Scheme world as far as
;;; I can see.
;;; ;;;
;;; Note that this code is, of course, dependent upon standard bindings for ;;; Note that this code is, of course, dependent upon standard bindings for
;;; the R5RS procedures -- i.e., it assumes that the variable CAR is bound ;;; the R5RS procedures -- i.e., it assumes that the variable CAR is bound
@ -1192,23 +1208,25 @@
;;; linear-time algorithm to kill the dups. Or use an algorithm based on ;;; linear-time algorithm to kill the dups. Or use an algorithm based on
;;; element-marking. The former gives you O(n lg n), the latter is linear. ;;; element-marking. The former gives you O(n lg n), the latter is linear.
(define (delete-duplicates elt= lis) (define (delete-duplicates lis . maybe-=)
(check-arg procedure? elt= delete-duplicates) (let ((elt= (:optional maybe-= equal?)))
(let recur ((lis lis)) (check-arg procedure? elt= delete-duplicates)
(if (null-list? lis) lis (let recur ((lis lis))
(let* ((x (car lis)) (if (null-list? lis) lis
(tail (cdr lis)) (let* ((x (car lis))
(new-tail (recur (delete x tail elt=)))) (tail (cdr lis))
(if (eq? tail new-tail) lis (cons x new-tail)))))) (new-tail (recur (delete x tail elt=))))
(if (eq? tail new-tail) lis (cons x new-tail)))))))
(define (delete-duplicates! elt= lis) (define (delete-duplicates! lis maybe-=)
(check-arg procedure? elt= delete-duplicates!) (let ((elt= (:optional maybe-= equal?)))
(let recur ((lis lis)) (check-arg procedure? elt= delete-duplicates!)
(if (null-list? lis) lis (let recur ((lis lis))
(let* ((x (car lis)) (if (null-list? lis) lis
(tail (cdr lis)) (let* ((x (car lis))
(new-tail (recur (delete! x tail elt=)))) (tail (cdr lis))
(if (eq? tail new-tail) lis (cons x new-tail)))))) (new-tail (recur (delete! x tail elt=))))
(if (eq? tail new-tail) lis (cons x new-tail)))))))
;;; alist stuff ;;; alist stuff
@ -1382,7 +1400,7 @@
((null? ans) lis) ; if we don't have to. ((null? ans) lis) ; if we don't have to.
((eq? lis ans) ans) ((eq? lis ans) ans)
(else (else
(fold (lambda (elt ans) (if (any (lambda (x) (= x elt))) (fold (lambda (elt ans) (if (any (lambda (x) (= x elt)) ans)
ans ans
(cons elt ans))) (cons elt ans)))
ans lis)))) ans lis))))

View File

@ -60,7 +60,7 @@
;; list-copy lis ;; list-copy lis
(list-copy (proc (:value) :value)) (list-copy (proc (:value) :value))
(circular-list (proc (:value &opt :value) :pair)) (circular-list (proc (:value &rest :value) :pair))
; ((:iota iota:) ; ((:iota iota:)
; (proc (:number &opt :number :number) :value)) ; (proc (:number &opt :number :number) :value))
@ -102,7 +102,7 @@
(unzip4 (proc (:value) (some-values :value :value :value :value))) (unzip4 (proc (:value) (some-values :value :value :value :value)))
(unzip5 (proc (:value) (some-values :value :value :value :value :value))) (unzip5 (proc (:value) (some-values :value :value :value :value :value)))
(count (proc ((proc (:value) :boolean) :value) :exact-integer)) (count (proc ((proc (:value &rest :value) :boolean) :value) :exact-integer))
((fold fold-right) ((fold fold-right)
(proc ((proc (:value :value &rest :value) :value) (proc ((proc (:value :value &rest :value) :value)

View File

@ -1,8 +1,7 @@
<!doctype html public '-//W3C//DTD HTML 4.0//EN' <!doctype html public '-//W3C//DTD HTML 4.0//EN'
'http://www.w3.org/TR/REC-html40/strict.dtd'> 'http://www.w3.org/TR/REC-html40/strict.dtd'>
<!-- insert p tags <!-- Is there a portable way to write an em-dash?
Is there a portable way to write an em-dash?
Can I have bangs, plusses, or slashes in #tags? Spaces? Can I have bangs, plusses, or slashes in #tags? Spaces?
Yes: plus, bang, star No: space Yes: slash, question, ampersand Yes: plus, bang, star No: space Yes: slash, question, ampersand
You can't put sharp in a path, so anything goes, really. You can't put sharp in a path, so anything goes, really.
@ -86,7 +85,7 @@
/* R5RS proc names are in italic; extended R5RS names /* R5RS proc names are in italic; extended R5RS names
** in italic boldface. ** in italic boldface.
*/ */
span.r5rs-proc { font-style: italic; } span.r5rs-proc { font-weight: bold; }
span.r5rs-procx { font-style: italic; font-weight: bold; } span.r5rs-procx { font-style: italic; font-weight: bold; }
/* Spread out bibliographic lists. */ /* Spread out bibliographic lists. */
@ -111,9 +110,13 @@
** here. Perhaps, one day, when these rendering bugs are fixed, ** here. Perhaps, one day, when these rendering bugs are fixed,
** this gross hackery can be removed. ** this gross hackery can be removed.
*/ */
dt.proc-def1 { margin-top: 2ex; margin-bottom: 0ex; } dt.proc-def1 { margin-top: 3ex; margin-bottom: 0ex; }
dt.proc-defi { margin-top: 0ex; margin-bottom: 0ex; } dt.proc-defi { margin-top: 0ex; margin-bottom: 0ex; }
dt.proc-defn { margin-top: 0ex; margin-bottom: 0.5ex; } dt.proc-defn { margin-top: 0ex; margin-bottom: 0.5ex; }
dt.proc-def { margin-top: 3ex; margin-bottom: 0.5ex; }
pre { margin-top: 1ex; }
dd.proc-def { margin-bottom: 2ex; margin-top: 0.5ex; } dd.proc-def { margin-bottom: 2ex; margin-top: 0.5ex; }
/* For the index of procedures. /* For the index of procedures.
@ -123,7 +126,7 @@
pre.proc-index { margin-top: 0ex; } pre.proc-index { margin-top: 0ex; }
/* Spread out bibliographic lists. */ /* Spread out bibliographic lists. */
dt.biblio { margin-bottom: 0ex; } dt.biblio { margin-top: 3ex; margin-bottom: 0ex; }
dd.biblio { margin-bottom: 1ex; } dd.biblio { margin-bottom: 1ex; }
</style> </style>
</head> </head>
@ -218,7 +221,7 @@ of the other big, full-featured Schemes. The complete list of list-processing
systems I checked is: systems I checked is:
<div class=indent> <div class=indent>
<abbr title="Revised^4 Report on Scheme">R4RS</abbr>/<abbr title="Revised^5 Report on Scheme"><a href="#R5RS">R5RS</a></abbr> Scheme, MIT Scheme, Gambit, RScheme, MzScheme, slib, <abbr title="Revised^4 Report on Scheme">R4RS</abbr>/<abbr title="Revised^5 Report on Scheme"><a href="#R5RS">R5RS</a></abbr> Scheme, MIT Scheme, Gambit, RScheme, MzScheme, slib,
<a href="#CLtL2">Common Lisp</a>, Bigloo, guile, T, APL and the SML standard basis <a href="#CommonLisp">Common Lisp</a>, Bigloo, guile, T, APL and the SML standard basis
</div> </div>
<p> <p>
As a result, the library I am proposing is fairly rich. As a result, the library I am proposing is fairly rich.
@ -250,8 +253,7 @@ implementation. I have placed this source on the Net with an unencumbered,
</ul> </ul>
<li>It is written for clarity and well-commented. The current source is <li>It is written for clarity and well-commented. The current source is
1436 lines of text, of which 690 are source code; the rest being comments 706 lines of source code and 818 lines of comments and white space.
and blank lines.
<li>It is written for efficiency. Fast paths are provided for common <li>It is written for efficiency. Fast paths are provided for common
cases. Side-effecting procedures such as <code>filter!</code> avoid unnecessary, cases. Side-effecting procedures such as <code>filter!</code> avoid unnecessary,
@ -277,7 +279,7 @@ library and get good results with it.
<p> <p>
Here is a short list of the procedures provided by the list-lib package. Here is a short list of the procedures provided by the list-lib package.
<a href="#R5RS">R5RS</a></abbr> procedures are shown in <a href="#R5RS">R5RS</a></abbr> procedures are shown in
<span class=r5rs-proc>italic</span class=r5rs-proc>; <span class=r5rs-proc>bold</span class=r5rs-proc>;
extended <a href="#R5RS">R5RS</a></abbr> extended <a href="#R5RS">R5RS</a></abbr>
procedures, in <span class=r5rs-procx>bold italic</span>. procedures, in <span class=r5rs-procx>bold italic</span>.
<div class=indent> <div class=indent>
@ -658,7 +660,7 @@ The following items are not in this library:
<li>Tree-processing routines <li>Tree-processing routines
</ul> </ul>
<p> <p>
They shound have their own <abbr title="Scheme Request for Implementation">SRFI</abbr> specs. They should have their own <abbr title="Scheme Request for Implementation">SRFI</abbr> specs.
<p> <p>
@ -688,16 +690,15 @@ The templates given below obey the following conventions for procedure formals:
<td> A natural number (an integer &gt;= 0) <td> A natural number (an integer &gt;= 0)
<tr valign=baseline><th align=left> <var>proc</var> <tr valign=baseline><th align=left> <var>proc</var>
<td> A procedure <td> A procedure
<tr valign=baseline><th align=left> <var>pred</var>
<td> A procedure whose return value is treated as a boolean
<tr valign=baseline><th align=left> <var>=</var> <tr valign=baseline><th align=left> <var>=</var>
<td> A boolean procedure taking two arguments <td> A boolean procedure taking two arguments
<tr valign=baseline><th align=left> <var>pred</var>
<td> A boolean procedure taking one argument
</table> </table>
<p> <p>
It is an error to pass a circular or dotted list to a procedure not It is an error to pass a circular or dotted list to a procedure not
defined to accept such an argument. Such a procedure may either signal defined to accept such an argument.
an error or diverge when passed a circular list.
<!--========================================================================--> <!--========================================================================-->
<h2><a name="Constructors">Constructors</a></h2> <h2><a name="Constructors">Constructors</a></h2>
@ -771,7 +772,7 @@ an error or diverge when passed a circular list.
<div class=indent><code> <div class=indent><code>
(cons <var>elt<sub>1</sub></var> (cons <var>elt<sub>2</sub></var> (cons ... <var>elt<sub>n</sub></var>))) (cons <var>elt<sub>1</sub></var> (cons <var>elt<sub>2</sub></var> (cons ... <var>elt<sub>n</sub></var>)))
</code></div> </code></div>
This function is called <code>list*</code> in <a href="#CLtL2">Common Lisp</a> and about This function is called <code>list*</code> in <a href="#CommonLisp">Common Lisp</a> and about
half of the Schemes that provide it, half of the Schemes that provide it,
and <code>cons*</code> in the other half. and <code>cons*</code> in the other half.
<pre class=code-example> <pre class=code-example>
@ -783,7 +784,7 @@ an error or diverge when passed a circular list.
==== make-list ==== make-list
============================================================================--> ============================================================================-->
<a name="make-list"></a> <a name="make-list"></a>
<dt class=proc-def> <code class=proc-def>make-list <var>n [fill] -&gt; list</var></code> <dt class=proc-def> <code class=proc-def>make-list</code> <var>n [fill] -&gt; list</var>
<dd class=proc-def> <dd class=proc-def>
Returns an <var>n</var>-element list, Returns an <var>n</var>-element list,
whose elements are all the value <var>fill</var>. whose elements are all the value <var>fill</var>.
@ -870,7 +871,7 @@ partition the entire universe of Scheme values.
Note that this definition rules out circular lists. This Note that this definition rules out circular lists. This
function is required to detect this case and return false. function is required to detect this case and return false.
<p> <p>
Nil-terminated lists are called "proper" lists by <abbr title="Revised^5 Report on Scheme"><a href="#R5RS">R5RS</a></abbr> and <a href="#CLtL2">Common Lisp</a>. Nil-terminated lists are called "proper" lists by <abbr title="Revised^5 Report on Scheme"><a href="#R5RS">R5RS</a></abbr> and <a href="#CommonLisp">Common Lisp</a>.
The opposite of proper is improper. The opposite of proper is improper.
<p> <p>
<abbr title="Revised^5 Report on Scheme"><a href="#R5RS">R5RS</a></abbr> binds this function to the variable <code>list?</code>. <abbr title="Revised^5 Report on Scheme"><a href="#R5RS">R5RS</a></abbr> binds this function to the variable <code>list?</code>.
@ -1011,7 +1012,8 @@ partition the entire universe of Scheme values.
<code>(eq? <var>x</var> <var>y</var>)</code> => <code>(<var>elt=</var> <var>x</var> <var>y</var>)</code>. <code>(eq? <var>x</var> <var>y</var>)</code> => <code>(<var>elt=</var> <var>x</var> <var>y</var>)</code>.
</div> </div>
Note that this implies that two lists which are <code>eq?</code> Note that this implies that two lists which are <code>eq?</code>
are always <var>list=</var>, as well. are always <var>list=</var>, as well; implementations may exploit this
fact to "short-cut" the element-by-element comparisons.
<pre class=code-example> <pre class=code-example>
(list= eq?) => #t ; Trivial cases (list= eq?) => #t ; Trivial cases
(list= eq? '(a)) => #t (list= eq? '(a)) => #t
@ -1318,6 +1320,8 @@ partition the entire universe of Scheme values.
<pre class=code-example> <pre class=code-example>
(append '(a b) '(c . d)) => (a b c . d) (append '(a b) '(c . d)) => (a b c . d)
(append '() 'a) => a (append '() 'a) => a
(append '(x y)) => (x y)
(append) => ()
</pre> </pre>
<code>append!</code> is the "linear-update" variant of <code>append</code> <code>append!</code> is the "linear-update" variant of <code>append</code>
@ -1565,7 +1569,8 @@ partition the entire universe of Scheme values.
(pair-fold <var>kons</var> (<var>kons</var> <var>lis</var> <var>knil</var>) tail)) (pair-fold <var>kons</var> (<var>kons</var> <var>lis</var> <var>knil</var>) tail))
(pair-fold <var>kons</var> <var>knil</var> <code>'()</code>) = <var>knil</var> (pair-fold <var>kons</var> <var>knil</var> <code>'()</code>) = <var>knil</var>
</pre> </pre>
The <var>kons</var> function may reliably apply <code>set-cdr!</code> to the pairs it is given For finite lists, the <var>kons</var> function may reliably apply
<code>set-cdr!</code> to the pairs it is given
without altering the sequence of execution. without altering the sequence of execution.
<p> <p>
Example: Example:
@ -1754,10 +1759,10 @@ Otherwise, return <code>(fold <var>f</var> (car <var>list</var>) (cdr <var>li
<pre class=code-example> <pre class=code-example>
;; List of squares: 1^2 ... 10^2 ;; List of squares: 1^2 ... 10^2
(unfold (lambda (x) (&gt; x 10)) (unfold-right (lambda (x) (&gt; x 10))
(lambda (x) (* x x)) (lambda (x) (* x x))
(lambda (x) (+ x 1)) (lambda (x) (+ x 1))
1) 1)
(unfold-right null-list? car cdr lis) ; Copy a proper list. (unfold-right null-list? car cdr lis) ; Copy a proper list.
@ -1870,10 +1875,7 @@ Otherwise, return <code>(fold <var>f</var> (car <var>list</var>) (cdr <var>li
specification to allow the arguments to be of unequal length; specification to allow the arguments to be of unequal length;
it terminates when the shortest list runs out. it terminates when the shortest list runs out.
<p> <p>
At least one of the argument lists must be finite: At least one of the argument lists must be finite.
<pre class=code-example>
(map + '(3 1 4 1) (circular-list 1 0)) => (4 1 5 1)
</pre>
<!-- <!--
==== append-map! ==== append-map!
@ -2110,7 +2112,7 @@ these procedures work when applied to different kinds of lists:
satisfying the search criteria. satisfying the search criteria.
</dl> </dl>
<p> <p>
Here are some examples, using the <code>find</code> and <code>any</code> procedures as a canonical Here are some examples, using the <code>find</code> and <code>any</code> procedures as canonical
representatives: representatives:
<pre class=code-example> <pre class=code-example>
;; Proper list -- success ;; Proper list -- success
@ -2950,8 +2952,8 @@ assistance.
<p> <p>
I am also grateful the authors, implementors and documentors of all the systems I am also grateful the authors, implementors and documentors of all the systems
mentioned in the introduction. Aubrey Jaffer and Kent Pitman should be noted mentioned in the introduction. Aubrey Jaffer and Kent Pitman should be noted
for their work in producing Web-accessible versions of the R5RS and Common for their work in producing Web-accessible versions of the R5RS and
Lisp spec, which was a tremendous aid. <a href="#CommonLisp">Common Lisp</a> spec, which was a tremendous aid.
<p> <p>
This is not to imply that these individuals necessarily endorse the final This is not to imply that these individuals necessarily endorse the final
results, of course. results, of course.
@ -2998,11 +3000,17 @@ results, of course.
<p> <p>
<dl> <dl>
<dt class=biblio><strong><a name="CLtL2">[CLtL2]</a></strong></dt> <dt class=biblio><strong><a name="CommonLisp">[CommonLisp]</a></strong></dt>
<dd><em>Common Lisp: the Language</em><br> <dd><em>Common Lisp: the Language</em><br>
Guy L. Steele Jr. (editor).<br> Guy L. Steele Jr. (editor).<br>
Digital Press, Maynard, Mass., second edition 1990.<br> Digital Press, Maynard, Mass., second edition 1990.<br>
Available at <a href="http://www.harlequin.com/education/books/HyperSpec/"> Available at <a href="http://www.elwood.com/alu/table/references.htm#cltl2">
http://www.elwood.com/alu/table/references.htm#cltl2</a>.
<p>
The Common Lisp "HyperSpec," produced by Kent Pitman, is essentially
the ANSI spec for Common Lisp:
<a href="http://www.harlequin.com/education/books/HyperSpec/">
http://www.harlequin.com/education/books/HyperSpec/</a>. http://www.harlequin.com/education/books/HyperSpec/</a>.
<dt class=biblio><strong><a name="R5RS">[R5RS]</a></strong></dt> <dt class=biblio><strong><a name="R5RS">[R5RS]</a></strong></dt>

View File

@ -1,13 +1,9 @@
The SRFI-1 list library -*- outline -*- The SRFI-1 list library -*- outline -*-
Olin Shivers Olin Shivers
98/10/16 98/10/16
Last Update: 99/9/11 Last Update: 99/10/2
Todo: carefully proofread. Emacs should display this document in outline mode. Say c-h m for
Netscape prints with insufficient space between proc specs --
see list=, for example. Mess about with css some more.
Emacs should display this document is in outline mode. Say c-h m for
instructions on how to move through it by sections (e.g., c-c c-n, c-c c-p). instructions on how to move through it by sections (e.g., c-c c-n, c-c c-p).
During the SRFI discussion period, the current draft may be found at During the SRFI discussion period, the current draft may be found at
ftp://ftp.ai.mit.edu/people/shivers/srfi/srfi-1/srfi-1.txt ftp://ftp.ai.mit.edu/people/shivers/srfi/srfi-1/srfi-1.txt
@ -97,8 +93,7 @@ implementation. I have placed this source on the Net with an unencumbered,
- Use of a simple CHECK-ARG procedure for argument checking. - Use of a simple CHECK-ARG procedure for argument checking.
- It is written for clarity and well-commented. The current source is - It is written for clarity and well-commented. The current source is
1436 lines of text, of which 690 are source code; the rest being comments 706 lines of source code and 818 lines of comments and white space.
and blank lines.
- It is written for efficiency. Fast paths are provided for common - It is written for efficiency. Fast paths are provided for common
cases. Side-effecting procedures such as FILTER! avoid unnecessary, cases. Side-effecting procedures such as FILTER! avoid unnecessary,
@ -424,7 +419,7 @@ The following items are not in this library:
- Sort routines - Sort routines
- Destructuring/pattern-matching macro - Destructuring/pattern-matching macro
- Tree-processing routines - Tree-processing routines
They shound have their own SRFI specs. They should have their own SRFI specs.
@ -442,12 +437,11 @@ The templates given below obey the following conventions for procedure formals:
object, value Any value object, value Any value
n, i A natural number (an integer >= 0) n, i A natural number (an integer >= 0)
proc A procedure proc A procedure
pred A procedure whose return value is treated as a boolean
= A boolean procedure taking two arguments = A boolean procedure taking two arguments
pred A boolean procedure taking one argument
It is an error to pass a circular or dotted list to a procedure not It is an error to pass a circular or dotted list to a procedure not
defined to accept such an argument. Such a procedure may either signal defined to accept such an argument.
an error or diverge when passed a circular list.
** Constructors ** Constructors
=============== ===============
@ -614,7 +608,8 @@ list= elt= list1 ... -> boolean
it must be the case that it must be the case that
(eq? x y) => (elt= x y). (eq? x y) => (elt= x y).
Note that this implies that two lists which are EQ? are always LIST=, Note that this implies that two lists which are EQ? are always LIST=,
as well. as well; implementations may exploit this fact to "short-cut" the
element-by-element comparisons.
(list= eq?) => #t ; Trivial cases (list= eq?) => #t ; Trivial cases
(list= eq? '(a)) => #t (list= eq? '(a)) => #t
@ -776,6 +771,8 @@ append! list1 ... -> value
(append '(a b) '(c . d)) ==> (a b c . d) (append '(a b) '(c . d)) ==> (a b c . d)
(append '() 'a) ==> a (append '() 'a) ==> a
(append '(x y)) ==> (x y)
(append) ==> ()
APPEND! is the "linear-update" variant of APPEND -- it is allowed, but APPEND! is the "linear-update" variant of APPEND -- it is allowed, but
not required, to alter cons cells in the argument lists to construct not required, to alter cons cells in the argument lists to construct
@ -932,8 +929,8 @@ pair-fold kons knil clist1 clist2 ... -> value
(pair-fold kons knil '()) = knil (pair-fold kons knil '()) = knil
The KONS function may reliably apply SET-CDR! to the pairs it is given For finite lists, the KONS function may reliably apply SET-CDR! to the
without altering the sequence of execution. pairs it is given without altering the sequence of execution.
Example: Example:
;;; Destructively reverse a list. ;;; Destructively reverse a list.
@ -1130,8 +1127,7 @@ for-each proc clist1 clist2 ... -> unspecified R5RS+
to allow the arguments to be of unequal length; it terminates to allow the arguments to be of unequal length; it terminates
when the shortest list runs out. when the shortest list runs out.
At least one of the argument lists must be finite: At least one of the argument lists must be finite.
(map + '(3 1 4 1) (circular-list 1 0)) => (4 1 5 1)
append-map f clist1 clist2 ... -> value append-map f clist1 clist2 ... -> value
append-map! f clist1 clist2 ... -> value append-map! f clist1 clist2 ... -> value
@ -1279,7 +1275,7 @@ these procedures work when applied to different kinds of lists:
successful* -- that is, if the list contains an element successful* -- that is, if the list contains an element
satisfying the search criteria. satisfying the search criteria.
Here are some examples, using the FIND and ANY procedures as a canonical Here are some examples, using the FIND and ANY procedures as canonical
representatives: representatives:
;; Proper list -- success ;; Proper list -- success
(find even? '(1 2 3)) => 2 (find even? '(1 2 3)) => 2
@ -1324,7 +1320,7 @@ find pred clist -> value
FIND -- FIND-TAIL has no such ambiguity: FIND -- FIND-TAIL has no such ambiguity:
(cond ((find-tail pred lis) => (lambda (pair) ...)) ; Handle (CAR PAIR) (cond ((find-tail pred lis) => (lambda (pair) ...)) ; Handle (CAR PAIR)
(else ...)) ; Search failed. (else ...)) ; Search failed.
find-tail pred clist -> pair or false find-tail pred clist -> pair or false
Return the first pair of CLIST whose car satisfies PRED. If no pair does, Return the first pair of CLIST whose car satisfies PRED. If no pair does,
return false. return false.
@ -1843,11 +1839,15 @@ SRFI web site:
http://srfi.schemers.org/ http://srfi.schemers.org/
[CLtL2] [CommonLisp]
Common Lisp: the Language Common Lisp: the Language
Guy L. Steele Jr. (editor). Guy L. Steele Jr. (editor).
Digital Press, Maynard, Mass., second edition 1990. Digital Press, Maynard, Mass., second edition 1990.
Available at http://www.harlequin.com/education/books/HyperSpec/ Available at http://www.elwood.com/alu/table/references.htm#cltl2
The Common Lisp "HyperSpec," produced by Kent Pitman, is essentially
the ANSI spec for Common Lisp:
http://www.harlequin.com/education/books/HyperSpec/
[R5RS] [R5RS]
Revised^5 Report on the Algorithmic Language Scheme, Revised^5 Report on the Algorithmic Language Scheme,
@ -1905,8 +1905,9 @@ Ispell dumps "buffer local" words here. Please ignore.
LocalWords: arg LISTi pred cond LISTn ANY's EVERY's Uniquifying lg ridentity LocalWords: arg LISTi pred cond LISTn ANY's EVERY's Uniquifying lg ridentity
LocalWords: eq netnews generalise Maciej Stachowiak al Bewig LocalWords ELTi LocalWords: eq netnews generalise Maciej Stachowiak al Bewig LocalWords ELTi
LocalWords: anamorphism apomorphism CLISTi ALIST's url ceteris eltn caar KNULL LocalWords: anamorphism apomorphism CLISTi ALIST's url ceteris eltn caar KNULL
LocalWords: deconstructor RIGHT's KAR KDR kar kdr knull HTML CLtL Clinger LocalWords: deconstructor RIGHT's KAR KDR kar kdr knull HTML CLtL Clinger gen
LocalWords: Rees Bawden Blandy Bornstein Bothner Carrico Currie Dybvig LocalWords: Rees Bawden Blandy Bornstein Bothner Carrico Currie Dybvig expt
LocalWords: Egorov Feeley Matthias Felleisen Flatt Hilsdale Hukriede LocalWords: Egorov Feeley Matthias Felleisen Flatt Hilsdale Hukriede CLISTs
LocalWords: Kolbly Shriram Krishnamurthi Jussi Piitulainen Pokorny Joerg LocalWords: Kolbly Shriram Krishnamurthi Jussi Piitulainen Pokorny Joerg Todo
LocalWords: Sperber Wittenberger documentors Jaffer LocalWords: Sperber Wittenberger documentors Jaffer initialised consed IE
LocalWords: disarranging SIGPLAN CommonLisp cltl HyperSpec