diff options
author | Steve Langasek <vorlon@debian.org> | 2005-01-10 08:53:33 +0000 |
---|---|---|
committer | Bryan Newbold <bnewbold@robocracy.org> | 2017-02-20 00:05:30 -0800 |
commit | e33f9eb9cf5cc29c36ce2aa7e10cd0f37ae0cc8e (patch) | |
tree | abbf06041619e445f9d0b772b0d58132009d8234 /slib_7.html | |
parent | f559c149c83da84d0b1c285f0298c84aec564af9 (diff) | |
parent | 8466d8cfa486fb30d1755c4261b781135083787b (diff) | |
download | slib-debian/3a1-4.2.tar.gz slib-debian/3a1-4.2.zip |
Import Debian changes 3a1-4.2debian/3a1-4.2
slib (3a1-4.2) unstable; urgency=low
* Non-maintainer upload.
* Add guile.init.local for use within the build dir, since otherwise we
have an (earlier unnoticed) circular build-dep due to a difference
between scm and guile.
slib (3a1-4.1) unstable; urgency=low
* Non-maintainer upload.
* Build-depend on guile-1.6 instead of scm, since the new version of
scm is wedged in unstable (closes: #281809).
slib (3a1-4) unstable; urgency=low
* Also check for expected creation on slibcat. (Closes: #240096)
slib (3a1-3) unstable; urgency=low
* Also check for /usr/share/guile/1.6/slib before installing for guile
1.6. (Closes: #239267)
slib (3a1-2) unstable; urgency=low
* Add format.scm back into slib until gnucash stops using it.
* Call guile-1.6 new-catalog (Closes: #238231)
slib (3a1-1) unstable; urgency=low
* New upstream release
* Remove Info section from doc-base file (Closes: #186950)
* Remove period from end of description (linda, lintian)
* html gen fixed upstream (Closes: #111778)
slib (2d4-2) unstable; urgency=low
* Fix url for upstream source (Closes: #144981)
* Fix typo in slib.texi (enquque->enqueue) (Closes: #147475)
* Add build depends.
slib (2d4-1) unstable; urgency=low
* New upstream.
slib (2d3-1) unstable; urgency=low
* New upstream.
* Remove texi2html call in debian/rules. Now done upstream. Add make
html instead.
* Changes to rules and doc-base to conform to upstream html gen
* Clean up upstream makefile to make sure it cleans up after itself.
Diffstat (limited to 'slib_7.html')
-rw-r--r-- | slib_7.html | 8218 |
1 files changed, 8218 insertions, 0 deletions
diff --git a/slib_7.html b/slib_7.html new file mode 100644 index 0000000..932a042 --- /dev/null +++ b/slib_7.html @@ -0,0 +1,8218 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" + "http://www.w3.org/TR/html40/loose.dtd"> +<HTML> +<!-- Created on January, 10 2005 by texi2html 1.66 --> +<!-- +Written by: Lionel Cons <Lionel.Cons@cern.ch> (original author) + Karl Berry <karl@freefriends.org> + Olaf Bachmann <obachman@mathematik.uni-kl.de> + and many others. +Maintained by: Many creative people <dev@texi2html.cvshome.org> +Send bugs and suggestions to <users@texi2html.cvshome.org> + +--> +<HEAD> +<TITLE>SLIB: Other Packages</TITLE> + +<META NAME="description" CONTENT="SLIB: Other Packages"> +<META NAME="keywords" CONTENT="SLIB: Other Packages"> +<META NAME="resource-type" CONTENT="document"> +<META NAME="distribution" CONTENT="global"> +<META NAME="Generator" CONTENT="texi2html 1.66"> + +</HEAD> + +<BODY LANG="en" BGCOLOR="#FFFFFF" TEXT="#000000" LINK="#0000FF" VLINK="#800080" ALINK="#FF0000"> + +<A NAME="SEC183"></A> +<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0> +<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_6.html#SEC182"> < </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC184"> > </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_6.html#SEC140"> << </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib.html#SEC_Top"> Up </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_8.html#SEC277"> >> </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib.html#SEC_Top">Top</A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_toc.html#SEC_Contents">Contents</A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_abt.html#SEC_About"> ? </A>]</TD> +</TR></TABLE> +<H1> 7. Other Packages </H1> +<!--docid::SEC183::--> +<P> + +<TABLE BORDER="0" CELLSPACING="0"> +<TR><TD ALIGN="left" VALIGN="TOP"><A HREF="slib_7.html#SEC184">7.1 Data Structures</A></TD><TD> </TD><TD ALIGN="left" VALIGN="TOP">Various data structures.</TD></TR> +<TR><TD ALIGN="left" VALIGN="TOP"><A HREF="slib_7.html#SEC207">7.2 Sorting and Searching</A></TD><TD> </TD><TD ALIGN="left" VALIGN="TOP"></TD></TR> +<TR><TD ALIGN="left" VALIGN="TOP"><A HREF="slib_7.html#SEC225">7.3 Procedures</A></TD><TD> </TD><TD ALIGN="left" VALIGN="TOP">Miscellaneous utility procedures.</TD></TR> +<TR><TD ALIGN="left" VALIGN="TOP"><A HREF="slib_7.html#SEC235">7.4 Standards Support</A></TD><TD> </TD><TD ALIGN="left" VALIGN="TOP">Support for Scheme Standards.</TD></TR> +<TR><TD ALIGN="left" VALIGN="TOP"><A HREF="slib_7.html#SEC263">7.5 Session Support</A></TD><TD> </TD><TD ALIGN="left" VALIGN="TOP">REPL and Debugging.</TD></TR> +<TR><TD ALIGN="left" VALIGN="TOP"><A HREF="slib_7.html#SEC269">7.6 System Interface</A></TD><TD> </TD><TD ALIGN="left" VALIGN="TOP">'system, 'getenv, and other programs.</TD></TR> +<TR><TD ALIGN="left" VALIGN="TOP"><A HREF="slib_7.html#SEC276">7.7 Extra-SLIB Packages</A></TD><TD> </TD><TD ALIGN="left" VALIGN="TOP">Outside the envelope.</TD></TR> +</TABLE> +<P> + +<A NAME="Data Structures"></A> +<HR SIZE="6"> +<A NAME="SEC184"></A> +<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0> +<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC183"> < </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC185"> > </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC183"> << </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC183"> Up </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_8.html#SEC277"> >> </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib.html#SEC_Top">Top</A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_toc.html#SEC_Contents">Contents</A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_abt.html#SEC_About"> ? </A>]</TD> +</TR></TABLE> +<H2> 7.1 Data Structures </H2> +<!--docid::SEC184::--> +<P> + +<TABLE BORDER="0" CELLSPACING="0"> +<TR><TD ALIGN="left" VALIGN="TOP"><A HREF="slib_7.html#SEC185">7.1.1 Arrays</A></TD><TD> </TD><TD ALIGN="left" VALIGN="TOP">'array</TD></TR> +<TR><TD ALIGN="left" VALIGN="TOP"><A HREF="slib_7.html#SEC186">7.1.2 Subarrays</A></TD><TD> </TD><TD ALIGN="left" VALIGN="TOP">'subarray</TD></TR> +<TR><TD ALIGN="left" VALIGN="TOP"><A HREF="slib_7.html#SEC187">7.1.3 Array Mapping</A></TD><TD> </TD><TD ALIGN="left" VALIGN="TOP">'array-for-each</TD></TR> +<TR><TD ALIGN="left" VALIGN="TOP"><A HREF="slib_7.html#SEC188">7.1.4 Association Lists</A></TD><TD> </TD><TD ALIGN="left" VALIGN="TOP">'alist</TD></TR> +<TR><TD ALIGN="left" VALIGN="TOP"><A HREF="slib_7.html#SEC189">7.1.5 Byte</A></TD><TD> </TD><TD ALIGN="left" VALIGN="TOP">'byte</TD></TR> +<TR><TD ALIGN="left" VALIGN="TOP"><A HREF="slib_7.html#SEC190">7.1.6 Byte/Number Conversions</A></TD><TD> </TD><TD ALIGN="left" VALIGN="TOP">'byte-number</TD></TR> +<TR><TD ALIGN="left" VALIGN="TOP"><A HREF="slib_7.html#SEC192">7.1.7 MAT-File Format</A></TD><TD> </TD><TD ALIGN="left" VALIGN="TOP">'matfile</TD></TR> +<TR><TD ALIGN="left" VALIGN="TOP"><A HREF="slib_7.html#SEC193">7.1.8 Portable Image Files</A></TD><TD> </TD><TD ALIGN="left" VALIGN="TOP">'pnm</TD></TR> +<TR><TD ALIGN="left" VALIGN="TOP"><A HREF="slib_7.html#SEC194">7.1.9 Collections</A></TD><TD> </TD><TD ALIGN="left" VALIGN="TOP">'collect</TD></TR> +<TR><TD ALIGN="left" VALIGN="TOP"><A HREF="slib_7.html#SEC195">7.1.10 Dynamic Data Type</A></TD><TD> </TD><TD ALIGN="left" VALIGN="TOP">'dynamic</TD></TR> +<TR><TD ALIGN="left" VALIGN="TOP"><A HREF="slib_7.html#SEC196">7.1.11 Hash Tables</A></TD><TD> </TD><TD ALIGN="left" VALIGN="TOP">'hash-table</TD></TR> +<TR><TD ALIGN="left" VALIGN="TOP"><A HREF="slib_7.html#SEC197">7.1.12 Macroless Object System</A></TD><TD> </TD><TD ALIGN="left" VALIGN="TOP">'object</TD></TR> +<TR><TD ALIGN="left" VALIGN="TOP"><A HREF="slib_7.html#SEC204">7.1.16 Priority Queues</A></TD><TD> </TD><TD ALIGN="left" VALIGN="TOP">'priority-queue</TD></TR> +<TR><TD ALIGN="left" VALIGN="TOP"><A HREF="slib_7.html#SEC205">7.1.17 Queues</A></TD><TD> </TD><TD ALIGN="left" VALIGN="TOP">'queue</TD></TR> +<TR><TD ALIGN="left" VALIGN="TOP"><A HREF="slib_7.html#SEC206">7.1.18 Records</A></TD><TD> </TD><TD ALIGN="left" VALIGN="TOP">'record</TD></TR> +</TABLE> +<P> + +<A NAME="Arrays"></A> +<HR SIZE="6"> +<A NAME="SEC185"></A> +<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0> +<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC184"> < </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC186"> > </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC183"> << </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC184"> Up </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_8.html#SEC277"> >> </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib.html#SEC_Top">Top</A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_toc.html#SEC_Contents">Contents</A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_abt.html#SEC_About"> ? </A>]</TD> +</TR></TABLE> +<H3> 7.1.1 Arrays </H3> +<!--docid::SEC185::--> +<P> + +<CODE>(require 'array)</CODE> +<A NAME="IDX1094"></A> +</P> +<P> + +<A NAME="IDX1095"></A> +</P> +<DL> +<DT><U>Function:</U> <B>array?</B> <I>obj</I> +<DD><P> + +Returns <CODE>#t</CODE> if the <VAR>obj</VAR> is an array, and <CODE>#f</CODE> if not. +</P> +</DL> +<EM>Note:</EM> Arrays are not disjoint from other Scheme types. Strings +and vectors also satisfy <CODE>array?</CODE>. A disjoint array predicate can +be written: +<P> + +<TABLE><tr><td> </td><td class=example><pre>(define (strict-array? obj) + (and (array? obj) (not (string? obj)) (not (vector? obj)))) +</pre></td></tr></table><P> + +<A NAME="IDX1096"></A> +</P> +<DL> +<DT><U>Function:</U> <B>array=?</B> <I>array1 array2</I> +<DD><P> + +Returns <CODE>#t</CODE> if <VAR>array1</VAR> and <VAR>array2</VAR> have the same rank and shape and the +corresponding elements of <VAR>array1</VAR> and <VAR>array2</VAR> are <CODE>equal?</CODE>. +</P> +<P> + +<TABLE><tr><td> </td><td class=example><pre>(array=? (create-array '#(foo) 3 3) + (create-array '#(foo) '(0 2) '(0 2))) + => #t +</pre></td></tr></table></DL> +<P> + +<A NAME="IDX1097"></A> +</P> +<DL> +<DT><U>Function:</U> <B>create-array</B> <I>prototype bound1 bound2 <small>...</small></I> +<DD><P> + +Creates and returns an array of type <VAR>prototype</VAR> with dimensions <VAR>bound1</VAR>, <VAR>bound2</VAR>, +<small>...</small> and filled with elements from <VAR>prototype</VAR>. <VAR>prototype</VAR> must be an array, +vector, or string. The implementation-dependent type of the returned +array will be the same as the type of <VAR>prototype</VAR>; except if that would be a +vector or string with non-zero origin, in which case some variety of +array will be returned. +</P> +<P> + +If the <VAR>prototype</VAR> has no elements, then the initial contents of the returned +array are unspecified. Otherwise, the returned array will be filled +with the element at the origin of <VAR>prototype</VAR>. +</P> +</DL> +These functions return a prototypical uniform-array enclosing the +optional argument (which must be of the correct type). If the +uniform-array type is supported by the implementation, then it is +returned; defaulting to the next larger precision type; resorting +finally to vector. +<P> + +<A NAME="IDX1098"></A> +</P> +<DL> +<DT><U>Function:</U> <B>ac64</B> <I>z</I> +<DD><P> + +<A NAME="IDX1099"></A> +<DT><U>Function:</U> <B>ac64</B> +<DD>Returns a high-precision complex uniform-array prototype. +</P> +</DL> +<P> + +<A NAME="IDX1100"></A> +</P> +<DL> +<DT><U>Function:</U> <B>ac32</B> <I>z</I> +<DD><P> + +<A NAME="IDX1101"></A> +<DT><U>Function:</U> <B>ac32</B> +<DD>Returns a complex uniform-array prototype. +</P> +</DL> +<P> + +<A NAME="IDX1102"></A> +</P> +<DL> +<DT><U>Function:</U> <B>ar64</B> <I>x</I> +<DD><P> + +<A NAME="IDX1103"></A> +<DT><U>Function:</U> <B>ar64</B> +<DD>Returns a high-precision real uniform-array prototype. +</P> +</DL> +<P> + +<A NAME="IDX1104"></A> +</P> +<DL> +<DT><U>Function:</U> <B>ar32</B> <I>x</I> +<DD><P> + +<A NAME="IDX1105"></A> +<DT><U>Function:</U> <B>ar32</B> +<DD>Returns a real uniform-array prototype. +</P> +</DL> +<P> + +<A NAME="IDX1106"></A> +</P> +<DL> +<DT><U>Function:</U> <B>as64</B> <I>n</I> +<DD><P> + +<A NAME="IDX1107"></A> +<DT><U>Function:</U> <B>as64</B> +<DD>Returns an exact signed integer uniform-array prototype with at least +64 bits of precision. +</P> +</DL> +<P> + +<A NAME="IDX1108"></A> +</P> +<DL> +<DT><U>Function:</U> <B>as32</B> <I>n</I> +<DD><P> + +<A NAME="IDX1109"></A> +<DT><U>Function:</U> <B>as32</B> +<DD>Returns an exact signed integer uniform-array prototype with at least +32 bits of precision. +</P> +</DL> +<P> + +<A NAME="IDX1110"></A> +</P> +<DL> +<DT><U>Function:</U> <B>as16</B> <I>n</I> +<DD><P> + +<A NAME="IDX1111"></A> +<DT><U>Function:</U> <B>as16</B> +<DD>Returns an exact signed integer uniform-array prototype with at least +16 bits of precision. +</P> +</DL> +<P> + +<A NAME="IDX1112"></A> +</P> +<DL> +<DT><U>Function:</U> <B>as8</B> <I>n</I> +<DD><P> + +<A NAME="IDX1113"></A> +<DT><U>Function:</U> <B>as8</B> +<DD>Returns an exact signed integer uniform-array prototype with at least +8 bits of precision. +</P> +</DL> +<P> + +<A NAME="IDX1114"></A> +</P> +<DL> +<DT><U>Function:</U> <B>au64</B> <I>k</I> +<DD><P> + +<A NAME="IDX1115"></A> +<DT><U>Function:</U> <B>au64</B> +<DD>Returns an exact non-negative integer uniform-array prototype with at +least 64 bits of precision. +</P> +</DL> +<P> + +<A NAME="IDX1116"></A> +</P> +<DL> +<DT><U>Function:</U> <B>au32</B> <I>k</I> +<DD><P> + +<A NAME="IDX1117"></A> +<DT><U>Function:</U> <B>au32</B> +<DD>Returns an exact non-negative integer uniform-array prototype with at +least 32 bits of precision. +</P> +</DL> +<P> + +<A NAME="IDX1118"></A> +</P> +<DL> +<DT><U>Function:</U> <B>au16</B> <I>k</I> +<DD><P> + +<A NAME="IDX1119"></A> +<DT><U>Function:</U> <B>au16</B> +<DD>Returns an exact non-negative integer uniform-array prototype with at +least 16 bits of precision. +</P> +</DL> +<P> + +<A NAME="IDX1120"></A> +</P> +<DL> +<DT><U>Function:</U> <B>au8</B> <I>k</I> +<DD><P> + +<A NAME="IDX1121"></A> +<DT><U>Function:</U> <B>au8</B> +<DD>Returns an exact non-negative integer uniform-array prototype with at +least 8 bits of precision. +</P> +</DL> +<P> + +<A NAME="IDX1122"></A> +</P> +<DL> +<DT><U>Function:</U> <B>at1</B> <I>bool</I> +<DD><P> + +<A NAME="IDX1123"></A> +<DT><U>Function:</U> <B>at1</B> +<DD>Returns a boolean uniform-array prototype. +</P> +</DL> +When constructing an array, <VAR>bound</VAR> is either an inclusive range of +indices expressed as a two element list, or an upper bound expressed as +a single integer. So +<P> + +<TABLE><tr><td> </td><td class=example><pre>(create-array '#(foo) 3 3) == (create-array '#(foo) '(0 2) '(0 2)) +</pre></td></tr></table><P> + +<A NAME="IDX1124"></A> +</P> +<DL> +<DT><U>Function:</U> <B>make-shared-array</B> <I>array mapper bound1 bound2 <small>...</small></I> +<DD><P> + +<CODE>make-shared-array</CODE> can be used to create shared subarrays of other +arrays. The <VAR>mapper</VAR> is a function that translates coordinates in +the new array into coordinates in the old array. A <VAR>mapper</VAR> must be +linear, and its range must stay within the bounds of the old array, but +it can be otherwise arbitrary. A simple example: +</P> +<P> + +<TABLE><tr><td> </td><td class=example><pre>(define fred (create-array '#(#f) 8 8)) +(define freds-diagonal + (make-shared-array fred (lambda (i) (list i i)) 8)) +(array-set! freds-diagonal 'foo 3) +(array-ref fred 3 3) + => FOO +(define freds-center + (make-shared-array fred (lambda (i j) (list (+ 3 i) (+ 3 j))) + 2 2)) +(array-ref freds-center 0 0) + => FOO +</pre></td></tr></table></DL> +<P> + +<A NAME="IDX1125"></A> +</P> +<DL> +<DT><U>Function:</U> <B>array-rank</B> <I>obj</I> +<DD><P> + +Returns the number of dimensions of <VAR>obj</VAR>. If <VAR>obj</VAR> is not an array, 0 is +returned. +</P> +</DL> +<P> + +<A NAME="IDX1126"></A> +</P> +<DL> +<DT><U>Function:</U> <B>array-shape</B> <I>array</I> +<DD><P> + +Returns a list of inclusive bounds. +</P> +<P> + +<TABLE><tr><td> </td><td class=example><pre>(array-shape (create-array '#() 3 5)) + => ((0 2) (0 4)) +</pre></td></tr></table></DL> +<P> + +<A NAME="IDX1127"></A> +</P> +<DL> +<DT><U>Function:</U> <B>array-dimensions</B> <I>array</I> +<DD><P> + +<CODE>array-dimensions</CODE> is similar to <CODE>array-shape</CODE> but replaces +elements with a 0 minimum with one greater than the maximum. +</P> +<P> + +<TABLE><tr><td> </td><td class=example><pre>(array-dimensions (create-array '#() 3 5)) + => (3 5) +</pre></td></tr></table></DL> +<P> + +<A NAME="IDX1128"></A> +</P> +<DL> +<DT><U>Function:</U> <B>array-in-bounds?</B> <I>array index1 index2 <small>...</small></I> +<DD><P> + +Returns <CODE>#t</CODE> if its arguments would be acceptable to +<CODE>array-ref</CODE>. +</P> +</DL> +<P> + +<A NAME="IDX1129"></A> +</P> +<DL> +<DT><U>Function:</U> <B>array-ref</B> <I>array index1 index2 <small>...</small></I> +<DD><P> + +Returns the (<VAR>index1</VAR>, <VAR>index2</VAR>, <small>...</small>) element of <VAR>array</VAR>. +</P> +</DL> +<P> + +<A NAME="IDX1130"></A> +</P> +<DL> +<DT><U>Procedure:</U> <B>array-set!</B> <I>array obj index1 index2 <small>...</small></I> +<DD><P> + +Stores <VAR>obj</VAR> in the (<VAR>index1</VAR>, <VAR>index2</VAR>, <small>...</small>) element of <VAR>array</VAR>. The value returned +by <CODE>array-set!</CODE> is unspecified. +</P> +</DL> +<P> + +<A NAME="Subarrays"></A> +<HR SIZE="6"> +<A NAME="SEC186"></A> +<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0> +<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC185"> < </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC187"> > </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC183"> << </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC184"> Up </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_8.html#SEC277"> >> </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib.html#SEC_Top">Top</A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_toc.html#SEC_Contents">Contents</A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_abt.html#SEC_About"> ? </A>]</TD> +</TR></TABLE> +<H3> 7.1.2 Subarrays </H3> +<!--docid::SEC186::--> +<P> + +<CODE>(require 'subarray)</CODE> +<A NAME="IDX1131"></A> +</P> +<P> + +<A NAME="IDX1132"></A> +</P> +<DL> +<DT><U>Function:</U> <B>subarray</B> <I>array select <small>...</small></I> +<DD><P> + +selects a subset of an array. For <VAR>array</VAR> of rank n, there must be at least +n <VAR>selects</VAR> arguments. For 0 <= <I>j</I> < n, <VAR>selects</VAR><I>j</I> is either an integer, a +list of two integers within the range for the <I>j</I>th index, or #f. +</P> +<P> + +When <VAR>selects</VAR><I>j</I> is a list of two integers, then the <I>j</I>th index is +restricted to that subrange in the returned array. +</P> +<P> + +When <VAR>selects</VAR><I>j</I> is #f, then the full range of the <I>j</I>th index is +accessible in the returned array. An elided argument is equivalent to #f. +</P> +<P> + +When <VAR>selects</VAR><I>j</I> is an integer, then the rank of the returned array is +less than <VAR>array</VAR>, and only elements whose <I>j</I>th index equals <VAR>selects</VAR><I>j</I> are +shared. +</P> +<P> + +<TABLE><tr><td> </td><td class=example><pre>> (define ra '#2A((a b c) (d e f))) +#<unspecified> +> (subarray ra 0 #f) +#1A(a b c) +> (subarray ra 1 #f) +#1A(d e f) +> (subarray ra #f 1) +#1A(b e) +> (subarray ra '(0 1) #f) +#2A((a b c) (d e f)) +> (subarray ra #f '(0 1)) +#2A((a b) (d e)) +> (subarray ra #f '(1 2)) +#2A((b c) (e f)) +</pre></td></tr></table></DL> +<P> + +<A NAME="IDX1133"></A> +</P> +<DL> +<DT><U>Function:</U> <B>subarray0</B> <I>array select <small>...</small></I> +<DD><P> + +Behaves like subarray, but aligns the returned array origin to +0 <small>...</small>. +</P> +</DL> +<P> + +<A NAME="IDX1134"></A> +</P> +<DL> +<DT><U>Function:</U> <B>array-align</B> <I>array coord <small>...</small></I> +<DD><P> + +Returns an array shared with <VAR>array</VAR> but with a different origin. The <VAR>coords</VAR> +are the exact integer coordinates of the new origin. Indexes +corresponding to missing or #f coordinates are not realigned. +</P> +<P> + +For example: +<TABLE><tr><td> </td><td class=example><pre>(define ra2 (create-array '#(5) '(5 9) '(-4 0))) +(array-shape ra2) => ((5 9) (-4 0)) +(array-shape (array-align ra2 0 0)) => ((0 4) (0 4)) +(array-shape (array-align ra2 0)) => ((0 4) (-4 0)) +(array-shape (array-align ra2)) => ((5 9) (-4 0)) +(array-shape (array-align ra2 0 #f)) => ((0 4) (-4 0)) +(array-shape (array-align ra2 #f 0)) => ((5 9) (0 4)) +</pre></td></tr></table></DL> + +<A NAME="IDX1135"></A> +<DL> +<DT><U>Function:</U> <B>array-trim</B> <I>array trim <small>...</small></I> +<DD><P> + +Returns a subarray sharing contents with <VAR>array</VAR> except for slices removed +from either side of each dimension. Each of the <VAR>trims</VAR> is an exact +integer indicating how much to trim. A positive <VAR>s</VAR> trims the +data from the lower end and reduces the upper bound of the result; a +negative <VAR>s</VAR> trims from the upper end and increases the lower +bound. +</P> +<P> + +For example: +<TABLE><tr><td> </td><td class=example><pre>(array-trim '#(0 1 2 3 4) 1) => #1A(1 2 3 4) ;; shape is ((0 3)) +(array-trim '#(0 1 2 3 4) -1) => #1A(0 1 2 3) ;; shape is ((1 4)) + +(require 'array-for-each) +(define (centered-difference ra) + (array-map - (array-trim ra 1) (array-trim ra -1))) +(define (forward-difference ra) + (array-map - (array-trim ra 1) ra)) +(define (backward-difference ra) + (array-map - ra (array-trim ra -1))) + +(centered-difference '#(0 1 3 5 9 22)) + => #1A(3 4 6 17) ;;shape is ((1 4)) +(backward-difference '#(0 1 3 5 9 22)) + => #1A(1 2 2 4 13) ;; shape is ((1 5)) +(forward-difference '#(0 1 3 5 9 22)) + => #(1 2 2 4 13) ;; shape is ((0 4)) +</pre></td></tr></table></DL> +<P> + +<A NAME="Array Mapping"></A> +<HR SIZE="6"> +<A NAME="SEC187"></A> +<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0> +<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC186"> < </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC188"> > </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC183"> << </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC184"> Up </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_8.html#SEC277"> >> </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib.html#SEC_Top">Top</A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_toc.html#SEC_Contents">Contents</A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_abt.html#SEC_About"> ? </A>]</TD> +</TR></TABLE> +<H3> 7.1.3 Array Mapping </H3> +<!--docid::SEC187::--> +<P> + +<CODE>(require 'array-for-each)</CODE> +<A NAME="IDX1136"></A> +</P> +<P> + +<A NAME="IDX1137"></A> +</P> +<DL> +<DT><U>Procedure:</U> <B>array-map!</B> <I>array0 proc array1 <small>...</small></I> +<DD><P> + +<VAR>array1</VAR>, <small>...</small> must have the same number of dimensions as +<VAR>array0</VAR> and have a range for each index which includes the range +for the corresponding index in <VAR>array0</VAR>. <VAR>proc</VAR> is applied to +each tuple of elements of <VAR>array1</VAR> <small>...</small> and the result is stored +as the corresponding element in <VAR>array0</VAR>. The value returned is +unspecified. The order of application is unspecified. +</P> +</DL> +<P> + +<A NAME="IDX1138"></A> +</P> +<DL> +<DT><U>Function:</U> <B>array-map</B> <I>prototype proc array1 array2 <small>...</small></I> +<DD><P> + +<VAR>array2</VAR>, <small>...</small> must have the same number of dimensions as +<VAR>array1</VAR> and have a range for each index which includes the +range for the corresponding index in <VAR>array1</VAR>. <VAR>proc</VAR> is +applied to each tuple of elements of <VAR>array1</VAR>, <VAR>array2</VAR>, +<small>...</small> and the result is stored as the corresponding element in a +new array of type <VAR>prototype</VAR>. The new array is returned. The +order of application is unspecified. +</P> +</DL> +<P> + +<A NAME="IDX1139"></A> +</P> +<DL> +<DT><U>Function:</U> <B>array-for-each</B> <I>proc array0 <small>...</small></I> +<DD><P> + +<VAR>proc</VAR> is applied to each tuple of elements of <VAR>array0</VAR> <small>...</small> +in row-major order. The value returned is unspecified. +</P> +</DL> +<P> + +<A NAME="IDX1140"></A> +</P> +<DL> +<DT><U>Function:</U> <B>array-indexes</B> <I>array</I> +<DD><P> + +Returns an array of lists of indexes for <VAR>array</VAR> such that, if +<VAR>li</VAR> is a list of indexes for which <VAR>array</VAR> is defined, +(equal? <VAR>li</VAR> (apply array-ref (array-indexes <VAR>array</VAR>) +<VAR>li</VAR>)). +</P> +</DL> +<P> + +<A NAME="IDX1141"></A> +</P> +<DL> +<DT><U>Procedure:</U> <B>array-index-map!</B> <I>array proc</I> +<DD><P> + +applies <VAR>proc</VAR> to the indices of each element of <VAR>array</VAR> in +turn, storing the result in the corresponding element. The value +returned and the order of application are unspecified. +</P> +<P> + +One can implement <VAR>array-indexes</VAR> as +<TABLE><tr><td> </td><td class=example><pre>(define (array-indexes array) + (let ((ra (apply create-array '#() (array-shape array)))) + (array-index-map! ra (lambda x x)) + ra)) +</pre></td></tr></table>Another example: +<TABLE><tr><td> </td><td class=example><pre>(define (apl:index-generator n) + (let ((v (make-vector n 1))) + (array-index-map! v (lambda (i) i)) + v)) +</pre></td></tr></table></DL> +<P> + +<A NAME="IDX1142"></A> +</P> +<DL> +<DT><U>Procedure:</U> <B>array-copy!</B> <I>source destination</I> +<DD><P> + +Copies every element from vector or array <VAR>source</VAR> to the +corresponding element of <VAR>destination</VAR>. <VAR>destination</VAR> must +have the same rank as <VAR>source</VAR>, and be at least as large in each +dimension. The order of copying is unspecified. +</P> +</DL> +<P> + +<A NAME="Association Lists"></A> +<HR SIZE="6"> +<A NAME="SEC188"></A> +<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0> +<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC187"> < </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC189"> > </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC183"> << </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC184"> Up </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_8.html#SEC277"> >> </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib.html#SEC_Top">Top</A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_toc.html#SEC_Contents">Contents</A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_abt.html#SEC_About"> ? </A>]</TD> +</TR></TABLE> +<H3> 7.1.4 Association Lists </H3> +<!--docid::SEC188::--> +<P> + +<CODE>(require 'alist)</CODE> +<A NAME="IDX1143"></A> +</P> +<P> + +Alist functions provide utilities for treating a list of key-value pairs +as an associative database. These functions take an equality predicate, +<VAR>pred</VAR>, as an argument. This predicate should be repeatable, +symmetric, and transitive. +</P> +<P> + +Alist functions can be used with a secondary index method such as hash +tables for improved performance. +</P> +<P> + +<A NAME="IDX1144"></A> +</P> +<DL> +<DT><U>Function:</U> <B>predicate->asso</B> <I>pred</I> +<DD><P> + +Returns an <EM>association function</EM> (like <CODE>assq</CODE>, <CODE>assv</CODE>, or +<A NAME="IDX1145"></A> +<CODE>assoc</CODE>) corresponding to <VAR>pred</VAR>. The returned function +returns a key-value pair whose key is <CODE>pred</CODE>-equal to its first +argument or <CODE>#f</CODE> if no key in the alist is <VAR>pred</VAR>-equal to the +first argument. +</P> +</DL> +<P> + +<A NAME="IDX1146"></A> +</P> +<DL> +<DT><U>Function:</U> <B>alist-inquirer</B> <I>pred</I> +<DD><P> + +Returns a procedure of 2 arguments, <VAR>alist</VAR> and <VAR>key</VAR>, which +returns the value associated with <VAR>key</VAR> in <VAR>alist</VAR> or <CODE>#f</CODE> if +<VAR>key</VAR> does not appear in <VAR>alist</VAR>. +</P> +</DL> +<P> + +<A NAME="IDX1147"></A> +</P> +<DL> +<DT><U>Function:</U> <B>alist-associator</B> <I>pred</I> +<DD><P> + +Returns a procedure of 3 arguments, <VAR>alist</VAR>, <VAR>key</VAR>, and +<VAR>value</VAR>, which returns an alist with <VAR>key</VAR> and <VAR>value</VAR> +associated. Any previous value associated with <VAR>key</VAR> will be +lost. This returned procedure may or may not have side effects on its +<VAR>alist</VAR> argument. An example of correct usage is: +</P> +<P> + +<TABLE><tr><td> </td><td class=example><pre>(define put (alist-associator string-ci=?)) +(define alist '()) +(set! alist (put alist "Foo" 9)) +</pre></td></tr></table></DL> +<P> + +<A NAME="IDX1148"></A> +</P> +<DL> +<DT><U>Function:</U> <B>alist-remover</B> <I>pred</I> +<DD><P> + +Returns a procedure of 2 arguments, <VAR>alist</VAR> and <VAR>key</VAR>, which +returns an alist with an association whose <VAR>key</VAR> is key removed. +This returned procedure may or may not have side effects on its +<VAR>alist</VAR> argument. An example of correct usage is: +</P> +<P> + +<TABLE><tr><td> </td><td class=example><pre>(define rem (alist-remover string-ci=?)) +(set! alist (rem alist "foo")) +</pre></td></tr></table></DL> +<P> + +<A NAME="IDX1149"></A> +</P> +<DL> +<DT><U>Function:</U> <B>alist-map</B> <I>proc alist</I> +<DD><P> + +Returns a new association list formed by mapping <VAR>proc</VAR> over the +keys and values of <VAR>alist</VAR>. <VAR>proc</VAR> must be a function of 2 +arguments which returns the new value part. +</P> +</DL> +<P> + +<A NAME="IDX1150"></A> +</P> +<DL> +<DT><U>Function:</U> <B>alist-for-each</B> <I>proc alist</I> +<DD><P> + +Applies <VAR>proc</VAR> to each pair of keys and values of <VAR>alist</VAR>. +<VAR>proc</VAR> must be a function of 2 arguments. The returned value is +unspecified. +</P> +</DL> +<P> + +<A NAME="Byte"></A> +<HR SIZE="6"> +<A NAME="SEC189"></A> +<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0> +<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC188"> < </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC190"> > </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC183"> << </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC184"> Up </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_8.html#SEC277"> >> </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib.html#SEC_Top">Top</A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_toc.html#SEC_Contents">Contents</A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_abt.html#SEC_About"> ? </A>]</TD> +</TR></TABLE> +<H3> 7.1.5 Byte </H3> +<!--docid::SEC189::--> +<P> + +<CODE>(require 'byte)</CODE> +<A NAME="IDX1151"></A> +</P> +<P> + +Some algorithms are expressed in terms of arrays of small integers. +Using Scheme strings to implement these arrays is not portable vis-a-vis +the correspondence between integers and characters and non-ascii +character sets. These functions abstract the notion of a <EM>byte</EM>. +<A NAME="IDX1152"></A> +<A NAME="IDX1153"></A> +</P> +<P> + +<A NAME="IDX1154"></A> +</P> +<DL> +<DT><U>Function:</U> <B>byte-ref</B> <I>bytes k</I> +<DD><P> + +<VAR>k</VAR> must be a valid index of <VAR>bytes</VAR>. <CODE>byte-ref</CODE> returns byte <VAR>k</VAR> of <VAR>bytes</VAR> using +zero-origin indexing. +</P> +</DL> +<P> + +<A NAME="IDX1155"></A> +</P> +<DL> +<DT><U>Procedure:</U> <B>byte-set!</B> <I>bytes k byte</I> +<DD><P> + +<VAR>k</VAR> must be a valid index of <VAR>bytes</VAR>, and <VAR>byte</VAR> must be a small +nonnegative integer. <CODE>byte-set!</CODE> stores <VAR>byte</VAR> in element <VAR>k</VAR> of <VAR>bytes</VAR> and +returns an unspecified value. +</P> +</DL> +<P> + +<A NAME="IDX1156"></A> +</P> +<DL> +<DT><U>Function:</U> <B>make-bytes</B> <I>k byte</I> +<DD><P> + +<A NAME="IDX1157"></A> +<DT><U>Function:</U> <B>make-bytes</B> <I>k</I> +<DD><CODE>make-bytes</CODE> returns a newly allocated byte-array of length <VAR>k</VAR>. If <VAR>byte</VAR> is +given, then all elements of the byte-array are initialized to <VAR>byte</VAR>, +otherwise the contents of the byte-array are unspecified. +</P> +</DL> +<P> + +<A NAME="IDX1158"></A> +</P> +<DL> +<DT><U>Function:</U> <B>bytes-length</B> <I>bytes</I> +<DD><P> + +<CODE>bytes-length</CODE> returns length of byte-array <VAR>bytes</VAR>. +</P> +</DL> +<P> + +<A NAME="IDX1159"></A> +</P> +<DL> +<DT><U>Function:</U> <B>bytes</B> <I>byte <small>...</small></I> +<DD><P> + +Returns a newly allocated byte-array composed of the small +nonnegative arguments. +</P> +</DL> +<P> + +<A NAME="IDX1160"></A> +</P> +<DL> +<DT><U>Function:</U> <B>bytes->list</B> <I>bytes</I> +<DD><P> + +<CODE>bytes->list</CODE> returns a newly allocated list of the bytes that make up the +given byte-array. +</P> +</DL> +<P> + +<A NAME="IDX1161"></A> +</P> +<DL> +<DT><U>Function:</U> <B>list->bytes</B> <I>bytes</I> +<DD><P> + +<CODE>list->bytes</CODE> returns a newly allocated byte-array formed from the small +nonnegative integers in the list <VAR>bytes</VAR>. +</P> +</DL> +<CODE>Bytes->list</CODE> and <CODE>list->bytes</CODE> are inverses so far as +<CODE>equal?</CODE> is concerned. +<A NAME="IDX1162"></A> +<P> + +<A NAME="IDX1163"></A> +</P> +<DL> +<DT><U>Function:</U> <B>bytes-copy</B> <I>bytes</I> +<DD><P> + +Returns a newly allocated copy of the given <VAR>bytes</VAR>. +</P> +</DL> +<P> + +<A NAME="IDX1164"></A> +</P> +<DL> +<DT><U>Procedure:</U> <B>bytes-reverse!</B> <I>bytes</I> +<DD><P> + +Reverses the order of byte-array <VAR>bytes</VAR>. +</P> +</DL> +<P> + +<A NAME="IDX1165"></A> +</P> +<DL> +<DT><U>Function:</U> <B>bytes-reverse</B> <I>bytes</I> +<DD><P> + +Returns a newly allocated bytes-array consisting of the elements of +<VAR>bytes</VAR> in reverse order. +</P> +</DL> +<A NAME="IDX1166"></A> +Input and output of bytes should be with ports opened in <EM>binary</EM> +<A NAME="IDX1167"></A> +mode (see section <A HREF="slib_2.html#SEC16">2.3 Input/Output</A>). Calling <CODE>open-file</CODE> with 'rb or +<A NAME="IDX1168"></A> +'wb modes argument will return a binary port if the Scheme +implementation supports it. +<P> + +<A NAME="IDX1169"></A> +</P> +<DL> +<DT><U>Function:</U> <B>write-byte</B> <I>byte port</I> +<DD><P> + +<A NAME="IDX1170"></A> +<DT><U>Function:</U> <B>write-byte</B> <I>byte</I> +<DD>Writes the byte <VAR>byte</VAR> (not an external representation of the byte) to +the given <VAR>port</VAR> and returns an unspecified value. The <VAR>port</VAR> argument may +be omitted, in which case it defaults to the value returned by +<CODE>current-output-port</CODE>. +<A NAME="IDX1171"></A> +</P> +</DL> +<P> + +<A NAME="IDX1172"></A> +</P> +<DL> +<DT><U>Function:</U> <B>read-byte</B> <I>port</I> +<DD><P> + +<A NAME="IDX1173"></A> +<DT><U>Function:</U> <B>read-byte</B> +<DD>Returns the next byte available from the input <VAR>port</VAR>, updating the <VAR>port</VAR> +to point to the following byte. If no more bytes are available, an +end-of-file object is returned. <VAR>port</VAR> may be omitted, in which case it +defaults to the value returned by <CODE>current-input-port</CODE>. +<A NAME="IDX1174"></A> +</P> +</DL> +When reading and writing binary numbers with <CODE>read-bytes</CODE> and +<CODE>write-bytes</CODE>, the sign of the length argument determines the +endianness (order) of bytes. Positive treats them as big-endian, +the first byte input or output is highest order. Negative treats +them as little-endian, the first byte input or output is the lowest +order. +<P> + +Once read in, SLIB treats byte sequences as big-endian. The +multi-byte sequences produced and used by number conversion routines +see section <A HREF="slib_7.html#SEC190">7.1.6 Byte/Number Conversions</A> are always big-endian. +</P> +<P> + +<A NAME="IDX1175"></A> +</P> +<DL> +<DT><U>Function:</U> <B>read-bytes</B> <I>n port</I> +<DD><P> + +<A NAME="IDX1176"></A> +<DT><U>Function:</U> <B>read-bytes</B> <I>n</I> +<DD><CODE>read-bytes</CODE> returns a newly allocated bytes-array filled with +<CODE>(abs <VAR>n</VAR>)</CODE> bytes read from <VAR>port</VAR>. If <VAR>n</VAR> is positive, then +the first byte read is stored at index 0; otherwise the last byte +read is stored at index 0. Note that the length of the returned +string will be less than <CODE>(abs <VAR>n</VAR>)</CODE> if <VAR>port</VAR> reaches +end-of-file. +</P> +<P> + +<VAR>port</VAR> may be omitted, in which case it defaults to the value returned +by <CODE>current-input-port</CODE>. +</P> +</DL> +<P> + +<A NAME="IDX1177"></A> +</P> +<DL> +<DT><U>Function:</U> <B>write-bytes</B> <I>bytes n port</I> +<DD><P> + +<A NAME="IDX1178"></A> +<DT><U>Function:</U> <B>write-bytes</B> <I>bytes n</I> +<DD><CODE>write-bytes</CODE> writes <CODE>(abs <VAR>n</VAR>)</CODE> bytes to output-port <VAR>port</VAR>. If <VAR>n</VAR> is +positive, then the first byte written is index 0 of <VAR>bytes</VAR>; otherwise +the last byte written is index 0 of <VAR>bytes</VAR>. <CODE>write-bytes</CODE> returns an unspecified +value. +</P> +<P> + +<VAR>port</VAR> may be omitted, in which case it defaults to the value returned +by <CODE>current-output-port</CODE>. +</P> +</DL> +<CODE>substring-read!</CODE> and <CODE>substring-write</CODE> provide +lower-level procedures for reading and writing blocks of bytes. The +relative size of <VAR>start</VAR> and <VAR>end</VAR> determines the order of +writing. +<P> + +<A NAME="IDX1179"></A> +</P> +<DL> +<DT><U>Procedure:</U> <B>substring-read!</B> <I>string start end port</I> +<DD><P> + +<A NAME="IDX1180"></A> +<DT><U>Procedure:</U> <B>substring-read!</B> <I>string start end</I> +<DD>Fills <VAR>string</VAR> with up to <CODE>(abs (- <VAR>start</VAR> <VAR>end</VAR>))</CODE> bytes +read from <VAR>port</VAR>. The first byte read is stored at index <VAR>string</VAR>. +<CODE>substring-read!</CODE> returns the number of bytes read. +</P> +<P> + +<VAR>port</VAR> may be omitted, in which case it defaults to the value returned +by <CODE>current-input-port</CODE>. +</P> +</DL> +<P> + +<A NAME="IDX1181"></A> +</P> +<DL> +<DT><U>Function:</U> <B>substring-write</B> <I>string start end port</I> +<DD><P> + +<A NAME="IDX1182"></A> +<DT><U>Function:</U> <B>substring-write</B> <I>string start end</I> +<DD><CODE>substring-write</CODE> writes <CODE>(abs (- <VAR>start</VAR> <VAR>end</VAR>))</CODE> bytes to +output-port <VAR>port</VAR>. The first byte written is index <VAR>start</VAR> of <VAR>string</VAR>. <CODE>substring-write</CODE> +returns the number of bytes written. +</P> +<P> + +<VAR>port</VAR> may be omitted, in which case it defaults to the value returned +by <CODE>current-output-port</CODE>. +</P> +</DL> +<P> + +<A NAME="Byte/Number Conversions"></A> +<HR SIZE="6"> +<A NAME="SEC190"></A> +<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0> +<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC189"> < </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC192"> > </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC183"> << </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC184"> Up </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_8.html#SEC277"> >> </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib.html#SEC_Top">Top</A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_toc.html#SEC_Contents">Contents</A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_abt.html#SEC_About"> ? </A>]</TD> +</TR></TABLE> +<H3> 7.1.6 Byte/Number Conversions </H3> +<!--docid::SEC190::--> +<P> + +<CODE>(require 'byte-number)</CODE> +<A NAME="IDX1183"></A> +</P> +<P> + +The multi-byte sequences produced and used by numeric conversion +routines are always big-endian. Endianness can be changed during +reading and writing bytes using <CODE>read-bytes</CODE> and +<CODE>write-bytes</CODE> See section <A HREF="slib_7.html#SEC189">read-bytes</A>. +</P> +<P> + +The sign of the length argument to bytes/integer conversion +procedures determines the signedness of the number. +</P> +<P> + +<A NAME="IDX1184"></A> +</P> +<DL> +<DT><U>Function:</U> <B>bytes->integer</B> <I>bytes n</I> +<DD><P> + +Converts the first <CODE>(abs <VAR>n</VAR>)</CODE> bytes of big-endian <VAR>bytes</VAR> array +to an integer. If <VAR>n</VAR> is negative then the integer coded by the +bytes are treated as two's-complement (can be negative). +</P> +<P> + +<TABLE><tr><td> </td><td class=example><pre>(bytes->integer (bytes 0 0 0 15) -4) => 15 +(bytes->integer (bytes 0 0 0 15) 4) => 15 +(bytes->integer (bytes 255 255 255 255) -4) => -1 +(bytes->integer (bytes 255 255 255 255) 4) => 4294967295 +(bytes->integer (bytes 128 0 0 0) -4) => -2147483648 +(bytes->integer (bytes 128 0 0 0) 4) => 2147483648 +</pre></td></tr></table></DL> +<P> + +<A NAME="IDX1185"></A> +</P> +<DL> +<DT><U>Function:</U> <B>integer->bytes</B> <I>n len</I> +<DD><P> + +Converts the integer <VAR>n</VAR> to a byte-array of <CODE>(abs <VAR>n</VAR>)</CODE> +bytes. If <VAR>n</VAR> and <VAR>len</VAR> are both negative, then the bytes in the +returned array are coded two's-complement. +</P> +<P> + +<TABLE><tr><td> </td><td class=example><pre>(bytes->list (integer->bytes 15 -4)) => (0 0 0 15) +(bytes->list (integer->bytes 15 4)) => (0 0 0 15) +(bytes->list (integer->bytes -1 -4)) => (255 255 255 255) +(bytes->list (integer->bytes 4294967295 4)) => (255 255 255 255) +(bytes->list (integer->bytes -2147483648 -4)) => (128 0 0 0) +(bytes->list (integer->bytes 2147483648 4)) => (128 0 0 0) +</pre></td></tr></table></DL> +<P> + +<A NAME="IDX1186"></A> +</P> +<DL> +<DT><U>Function:</U> <B>bytes->ieee-float</B> <I>bytes</I> +<DD><P> + +<VAR>bytes</VAR> must be a 4-element byte-array. <CODE>bytes->ieee-float</CODE> calculates and returns the +value of <VAR>bytes</VAR> interpreted as a big-endian IEEE 4-byte (32-bit) number. +</P> +</DL> +<TABLE><tr><td> </td><td class=example><pre>(bytes->ieee-float (bytes #x40 0 0 0)) => 2.0 +(bytes->ieee-float (bytes #x40 #xd0 0 0)) => 6.5 +(bytes->ieee-float (bytes #xc0 #xd0 0 0)) => -6.5 + +(bytes->ieee-float (bytes 0 #x80 0 0)) => 11.754943508222875e-39 +(bytes->ieee-float (bytes 0 #x40 0 0)) => 5.877471754111437e-39 +(bytes->ieee-float (bytes 0 0 0 1)) => 1.401298464324817e-45 + +(bytes->ieee-float (bytes #xff #x80 0 0)) => -1/0 +(bytes->ieee-float (bytes #x7f #x80 0 0)) => 1/0 +(bytes->ieee-float (bytes #x7f #x80 0 1)) => 0/0 +</pre></td></tr></table><P> + +<A NAME="IDX1187"></A> +</P> +<DL> +<DT><U>Function:</U> <B>bytes->ieee-double</B> <I>bytes</I> +<DD><P> + +<VAR>bytes</VAR> must be a 8-element byte-array. <CODE>bytes->ieee-double</CODE> calculates and returns the +value of <VAR>bytes</VAR> interpreted as a big-endian IEEE 8-byte (64-bit) number. +</P> +</DL> +<TABLE><tr><td> </td><td class=example><pre>(bytes->ieee-double (bytes 0 0 0 0 0 0 0 0)) => 0.0 +(bytes->ieee-double (bytes #x40 0 0 0 0 0 0 0)) => 2 +(bytes->ieee-double (bytes #x40 #x1A 0 0 0 0 0 0)) => 6.5 +(bytes->ieee-double (bytes #xC0 #x1A 0 0 0 0 0 0)) => -6.5 + +(bytes->ieee-double (bytes 0 8 0 0 0 0 0 0)) => 11.125369292536006e-309 +(bytes->ieee-double (bytes 0 4 0 0 0 0 0 0)) => 5.562684646268003e-309 +(bytes->ieee-double (bytes 0 0 0 0 0 0 0 1)) => 4.0e-324 + +(bytes->ieee-double (bytes #xFF #xF0 0 0 0 0 0 0)) => -1/0 +(bytes->ieee-double (bytes #x7F #xF0 0 0 0 0 0 0)) => 1/0 +(bytes->ieee-double (bytes #x7F #xF8 0 0 0 0 0 0)) => 0/0 +</pre></td></tr></table><P> + +<A NAME="IDX1188"></A> +</P> +<DL> +<DT><U>Function:</U> <B>ieee-float->bytes</B> <I>x</I> +<DD><P> + +Returns a 4-element byte-array encoding the IEEE single-precision +floating-point of <VAR>x</VAR>. +</P> +</DL> +<TABLE><tr><td> </td><td class=example><pre>(bytes->list (ieee-float->bytes 2.0)) => (64 0 0 0) +(bytes->list (ieee-float->bytes 6.5)) => (64 208 0 0) +(bytes->list (ieee-float->bytes -6.5)) => (192 208 0 0) + +(bytes->list (ieee-float->bytes 11.754943508222875e-39)) => ( 0 128 0 0) +(bytes->list (ieee-float->bytes 5.877471754111438e-39)) => ( 0 64 0 0) +(bytes->list (ieee-float->bytes 1.401298464324817e-45)) => ( 0 0 0 1) + +(bytes->list (ieee-float->bytes -1/0)) => (255 128 0 0) +(bytes->list (ieee-float->bytes 1/0)) => (127 128 0 0) +(bytes->list (ieee-float->bytes 0/0)) => (127 128 0 1) +</pre></td></tr></table><P> + +<A NAME="IDX1189"></A> +</P> +<DL> +<DT><U>Function:</U> <B>ieee-double->bytes</B> <I>x</I> +<DD><P> + +Returns a 8-element byte-array encoding the IEEE double-precision +floating-point of <VAR>x</VAR>. +</P> +</DL> +<TABLE><tr><td> </td><td class=example><pre>(bytes->list (ieee-double->bytes 2.0)) => (64 0 0 0 0 0 0 0) +(bytes->list (ieee-double->bytes 6.5)) => (64 26 0 0 0 0 0 0) +(bytes->list (ieee-double->bytes -6.5)) => (192 26 0 0 0 0 0 0) + +(bytes->list (ieee-double->bytes 11.125369292536006e-309)) + => ( 0 8 0 0 0 0 0 0) +(bytes->list (ieee-double->bytes 5.562684646268003e-309)) + => ( 0 4 0 0 0 0 0 0) +(bytes->list (ieee-double->bytes 4.0e-324)) + => ( 0 0 0 0 0 0 0 1) + +(bytes->list (ieee-double->bytes -1/0)) => (255 240 0 0 0 0 0 0) +(bytes->list (ieee-double->bytes 1/0)) => (127 240 0 0 0 0 0 0) +(bytes->list (ieee-double->bytes 0/0)) => (127 248 0 0 0 0 0 0) +</pre></td></tr></table><P> + +<A NAME="SEC191"></A> +<H4> Byte Collation Order </H4> +<!--docid::SEC191::--> +<P> + +The <CODE>string<?</CODE> ordering of big-endian byte-array +representations of fixed and IEEE floating-point numbers agrees with +the numerical ordering only when those numbers are non-negative. +</P> +<P> + +Straighforward modification of these formats can extend the +byte-collating order to work for their entire ranges. This +agreement enables the full range of numbers as keys in +<EM>indexed-sequential-access-method</EM> databases. +<A NAME="IDX1190"></A> +</P> +<P> + +<A NAME="IDX1191"></A> +</P> +<DL> +<DT><U>Procedure:</U> <B>integer-byte-collate!</B> <I>byte-vector</I> +<DD><P> + +Modifies sign bit of <VAR>byte-vector</VAR> so that <CODE>string<?</CODE> ordering of +two's-complement byte-vectors matches numerical order. <CODE>integer-byte-collate!</CODE> returns +<VAR>byte-vector</VAR> and is its own functional inverse. +</P> +</DL> +<P> + +<A NAME="IDX1192"></A> +</P> +<DL> +<DT><U>Function:</U> <B>integer-byte-collate</B> <I>byte-vector</I> +<DD><P> + +Returns copy of <VAR>byte-vector</VAR> with sign bit modified so that <CODE>string<?</CODE> +ordering of two's-complement byte-vectors matches numerical order. +<CODE>integer-byte-collate</CODE> is its own functional inverse. +</P> +</DL> +<P> + +<A NAME="IDX1193"></A> +</P> +<DL> +<DT><U>Procedure:</U> <B>ieee-byte-collate!</B> <I>byte-vector</I> +<DD><P> + +Modifies <VAR>byte-vector</VAR> so that <CODE>string<?</CODE> ordering of IEEE floating-point +byte-vectors matches numerical order. <CODE>ieee-byte-collate!</CODE> returns <VAR>byte-vector</VAR>. +</P> +</DL> +<P> + +<A NAME="IDX1194"></A> +</P> +<DL> +<DT><U>Procedure:</U> <B>ieee-byte-decollate!</B> <I>byte-vector</I> +<DD><P> + +Given <VAR>byte-vector</VAR> modified by <CODE>IEEE-byte-collate!</CODE>, reverses the <VAR>byte-vector</VAR> +modifications. +</P> +</DL> +<P> + +<A NAME="IDX1195"></A> +</P> +<DL> +<DT><U>Function:</U> <B>ieee-byte-collate</B> <I>byte-vector</I> +<DD><P> + +Returns copy of <VAR>byte-vector</VAR> encoded so that <CODE>string<?</CODE> ordering of IEEE +floating-point byte-vectors matches numerical order. +</P> +</DL> +<P> + +<A NAME="IDX1196"></A> +</P> +<DL> +<DT><U>Function:</U> <B>ieee-byte-decollate</B> <I>byte-vector</I> +<DD><P> + +Given <VAR>byte-vector</VAR> returned by <CODE>IEEE-byte-collate</CODE>, reverses the <VAR>byte-vector</VAR> +modifications. +</P> +</DL> +<P> + +<A NAME="MAT-File Format"></A> +<HR SIZE="6"> +<A NAME="SEC192"></A> +<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0> +<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC190"> < </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC193"> > </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC183"> << </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC184"> Up </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_8.html#SEC277"> >> </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib.html#SEC_Top">Top</A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_toc.html#SEC_Contents">Contents</A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_abt.html#SEC_About"> ? </A>]</TD> +</TR></TABLE> +<H3> 7.1.7 MAT-File Format </H3> +<!--docid::SEC192::--> +<P> + +<CODE>(require 'matfile)</CODE> +<A NAME="IDX1197"></A> +<A NAME="IDX1198"></A> +</P> +<P> + +<A HREF="http://www.mathworks.com/access/helpdesk/help/pdf_doc/matlab/matfile_format.pdf">http://www.mathworks.com/access/helpdesk/help/pdf_doc/matlab/matfile_format.pdf</A> +</P> +<P> + +This package reads MAT-File Format version 4 (MATLAB) binary data +files. MAT-files written from big-endian or little-endian computers +having IEEE format numbers are currently supported. Support for files +written from VAX or Cray machines could also be added. +</P> +<P> + +The numeric and text matrix types handled; support for <EM>sparse</EM> +<A NAME="IDX1199"></A> +matrices awaits a sample file. +</P> +<P> + +<A NAME="IDX1200"></A> +</P> +<DL> +<DT><U>Function:</U> <B>matfile:read</B> <I>filename</I> +<DD><VAR>filename</VAR> should be a string naming an existing file containing a +MATLAB Version 4 MAT-File. The <CODE>matfile:read</CODE> procedure reads matrices from the +file and returns a list of the results; a list of the name string and +array for each matrix. +</DL> +<P> + +<A NAME="IDX1201"></A> +</P> +<DL> +<DT><U>Function:</U> <B>matfile:load</B> <I>filename</I> +<DD><VAR>filename</VAR> should be a string naming an existing file containing a +MATLAB Version 4 MAT-File. The <CODE>matfile:load</CODE> procedure reads matrices from the +file and defines the <CODE>string-ci->symbol</CODE> for each matrix to its +corresponding array. <CODE>matfile:load</CODE> returns a list of the symbols defined. +</DL> +<P> + +<A NAME="Portable Image Files"></A> +<HR SIZE="6"> +<A NAME="SEC193"></A> +<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0> +<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC192"> < </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC194"> > </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC183"> << </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC184"> Up </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_8.html#SEC277"> >> </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib.html#SEC_Top">Top</A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_toc.html#SEC_Contents">Contents</A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_abt.html#SEC_About"> ? </A>]</TD> +</TR></TABLE> +<H3> 7.1.8 Portable Image Files </H3> +<!--docid::SEC193::--> +<P> + +<CODE>(require 'pnm)</CODE> +<A NAME="IDX1202"></A> +</P> +<P> + +<A NAME="IDX1203"></A> +</P> +<DL> +<DT><U>Function:</U> <B>pnm:type-dimensions</B> <I>path</I> +<DD><P> + +The string <VAR>path</VAR> must name a <EM>portable bitmap graphics</EM> file. +<A NAME="IDX1204"></A> +<CODE>pnm:type-dimensions</CODE> returns a list of 4 items: +<OL> +<LI> +A symbol describing the type of the file named by <VAR>path</VAR>. +<LI> +The image width in pixels. +<LI> +The image height in pixels. +<LI> +The maximum value of pixels assume in the file. +</OL> +<P> + +The current set of file-type symbols is: +</P> +<DL COMPACT> +<DT>pbm +<DD><DT>pbm-raw +<DD><A NAME="IDX1205"></A> +<A NAME="IDX1206"></A> +Black-and-White image; pixel values are 0 or 1. +<DT>pgm +<DD><DT>pgm-raw +<DD><A NAME="IDX1207"></A> +<A NAME="IDX1208"></A> +Gray (monochrome) image; pixel values are from 0 to <VAR>maxval</VAR> +specified in file header. +<DT>ppm +<DD><DT>ppm-raw +<DD><A NAME="IDX1209"></A> +<A NAME="IDX1210"></A> +RGB (full color) image; red, green, and blue interleaved pixel values +are from 0 to <VAR>maxval</VAR> +</DL> +</DL> +<P> + +<A NAME="IDX1211"></A> +</P> +<DL> +<DT><U>Function:</U> <B>pnm:image-file->array</B> <I>path array</I> +<DD><P> + +Reads the <EM>portable bitmap graphics</EM> file named by <VAR>path</VAR> into +<A NAME="IDX1212"></A> +<VAR>array</VAR>. <VAR>array</VAR> must be the correct size and type for +<VAR>path</VAR>. <VAR>array</VAR> is returned. +</P> +<P> + +<A NAME="IDX1213"></A> +<DT><U>Function:</U> <B>pnm:image-file->array</B> <I>path</I> +<DD></P> +<P> + +<CODE>pnm:image-file->array</CODE> creates and returns an array with the +<EM>portable bitmap graphics</EM> file named by <VAR>path</VAR> read into it. +<A NAME="IDX1214"></A> +</P> +</DL> +<P> + +<A NAME="IDX1215"></A> +</P> +<DL> +<DT><U>Function:</U> <B>pnm:array-write</B> <I>type array maxval path comment <small>...</small></I> +<DD><P> + +Writes the contents of <VAR>array</VAR> to a <VAR>type</VAR> image file named <VAR>path</VAR>. The file +will have pixel values between 0 and <VAR>maxval</VAR>, which must be compatible +with <VAR>type</VAR>. For `<SAMP>pbm</SAMP>' files, <VAR>maxval</VAR> must be `<SAMP>1</SAMP>'. +<VAR>comment</VAR>s are included in the file header. +</P> +</DL> +<P> + +<A NAME="Collections"></A> +<HR SIZE="6"> +<A NAME="SEC194"></A> +<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0> +<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC193"> < </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC195"> > </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC183"> << </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC184"> Up </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_8.html#SEC277"> >> </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib.html#SEC_Top">Top</A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_toc.html#SEC_Contents">Contents</A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_abt.html#SEC_About"> ? </A>]</TD> +</TR></TABLE> +<H3> 7.1.9 Collections </H3> +<!--docid::SEC194::--> +<P> + +<CODE>(require 'collect)</CODE> +<A NAME="IDX1216"></A> +</P> +<P> + +Routines for managing collections. Collections are aggregate data +structures supporting iteration over their elements, similar to the +Dylan(TM) language, but with a different interface. They have +<EM>elements</EM> indexed by corresponding <EM>keys</EM>, although the keys +may be implicit (as with lists). +</P> +<P> + +New types of collections may be defined as YASOS objects (see section <A HREF="slib_3.html#SEC40">3.8 Yasos</A>). +They must support the following operations: +</P> +<P> + +<UL> +<LI> +<CODE>(collection? <VAR>self</VAR>)</CODE> (always returns <CODE>#t</CODE>); +<P> + +</P> +<LI> +<CODE>(size <VAR>self</VAR>)</CODE> returns the number of elements in the collection; +<P> + +</P> +<LI> +<CODE>(print <VAR>self</VAR> <VAR>port</VAR>)</CODE> is a specialized print operation +for the collection which prints a suitable representation on the given +<VAR>port</VAR> or returns it as a string if <VAR>port</VAR> is <CODE>#t</CODE>; +<P> + +</P> +<LI> +<A NAME="IDX1217"></A> +<CODE>(gen-elts <VAR>self</VAR>)</CODE> returns a thunk which on successive +invocations yields elements of <VAR>self</VAR> in order or gives an error if +it is invoked more than <CODE>(size <VAR>self</VAR>)</CODE> times; +<P> + +</P> +<LI> +<A NAME="IDX1218"></A> +<CODE>(gen-keys <VAR>self</VAR>)</CODE> is like <CODE>gen-elts</CODE>, but yields the +collection's keys in order. +</UL> +<P> + +They might support specialized <CODE>for-each-key</CODE> and +<CODE>for-each-elt</CODE> operations. +</P> +<P> + +<A NAME="IDX1219"></A> +</P> +<DL> +<DT><U>Function:</U> <B>collection?</B> <I>obj</I> +<DD>A predicate, true initially of lists, vectors and strings. New sorts of +collections must answer <CODE>#t</CODE> to <CODE>collection?</CODE>. +</DL> +<P> + +<A NAME="IDX1220"></A> +</P> +<DL> +<DT><U>Procedure:</U> <B>map-elts</B> <I>proc collection1 <small>...</small></I> +<DD><A NAME="IDX1221"></A> +<DT><U>Procedure:</U> <B>do-elts</B> <I>proc collection1 <small>...</small></I> +<DD><VAR>proc</VAR> is a procedure taking as many arguments as there are +<VAR>collections</VAR> (at least one). The <VAR>collections</VAR> are iterated +over in their natural order and <VAR>proc</VAR> is applied to the elements +yielded by each iteration in turn. The order in which the arguments are +supplied corresponds to te order in which the <VAR>collections</VAR> appear. +<CODE>do-elts</CODE> is used when only side-effects of <VAR>proc</VAR> are of +interest and its return value is unspecified. <CODE>map-elts</CODE> returns a +collection (actually a vector) of the results of the applications of +<VAR>proc</VAR>. +<P> + +Example: +<TABLE><tr><td> </td><td class=example><pre>(map-elts + (list 1 2 3) (vector 1 2 3)) + => #(2 4 6) +</pre></td></tr></table></DL> +<P> + +<A NAME="IDX1222"></A> +</P> +<DL> +<DT><U>Procedure:</U> <B>map-keys</B> <I>proc collection1 <small>...</small></I> +<DD><A NAME="IDX1223"></A> +<DT><U>Procedure:</U> <B>do-keys</B> <I>proc collection1 <small>...</small></I> +<DD>These are analogous to <CODE>map-elts</CODE> and <CODE>do-elts</CODE>, but each +iteration is over the <VAR>collections</VAR>' <EM>keys</EM> rather than their +elements. +<P> + +Example: +<TABLE><tr><td> </td><td class=example><pre>(map-keys + (list 1 2 3) (vector 1 2 3)) + => #(0 2 4) +</pre></td></tr></table></DL> +<P> + +<A NAME="IDX1224"></A> +</P> +<DL> +<DT><U>Procedure:</U> <B>for-each-key</B> <I>collection proc</I> +<DD><A NAME="IDX1225"></A> +<DT><U>Procedure:</U> <B>for-each-elt</B> <I>collection proc</I> +<DD>These are like <CODE>do-keys</CODE> and <CODE>do-elts</CODE> but only for a single +collection; they are potentially more efficient. +</DL> +<P> + +<A NAME="IDX1226"></A> +</P> +<DL> +<DT><U>Function:</U> <B>reduce</B> <I>proc seed collection1 <small>...</small></I> +<DD>A generalization of the list-based <CODE>reduce-init</CODE> +(see section <A HREF="slib_7.html#SEC211">7.2.1.3 Lists as sequences</A>) to collections which will shadow the +list-based version if <CODE>(require 'collect)</CODE> follows +<A NAME="IDX1227"></A> +<CODE>(require 'common-list-functions)</CODE> (see section <A HREF="slib_7.html#SEC208">7.2.1 Common List Functions</A>). +<A NAME="IDX1228"></A> +<P> + +Examples: +<TABLE><tr><td> </td><td class=example><pre>(reduce + 0 (vector 1 2 3)) + => 6 +(reduce union '() '((a b c) (b c d) (d a))) + => (c b d a). +</pre></td></tr></table></DL> +<P> + +<A NAME="IDX1229"></A> +</P> +<DL> +<DT><U>Function:</U> <B>any?</B> <I>pred collection1 <small>...</small></I> +<DD>A generalization of the list-based <CODE>some</CODE> (see section <A HREF="slib_7.html#SEC211">7.2.1.3 Lists as sequences</A>) to collections. +<P> + +Example: +<TABLE><tr><td> </td><td class=example><pre>(any? odd? (list 2 3 4 5)) + => #t +</pre></td></tr></table></DL> +<P> + +<A NAME="IDX1230"></A> +</P> +<DL> +<DT><U>Function:</U> <B>every?</B> <I>pred collection1 <small>...</small></I> +<DD>A generalization of the list-based <CODE>every</CODE> +(see section <A HREF="slib_7.html#SEC211">7.2.1.3 Lists as sequences</A>) to collections. +<P> + +Example: +<TABLE><tr><td> </td><td class=example><pre>(every? collection? '((1 2) #(1 2))) + => #t +</pre></td></tr></table></DL> +<P> + +<A NAME="IDX1231"></A> +</P> +<DL> +<DT><U>Function:</U> <B>empty?</B> <I>collection</I> +<DD>Returns <CODE>#t</CODE> iff there are no elements in <VAR>collection</VAR>. +<P> + +<CODE>(empty? <VAR>collection</VAR>) == (zero? (size <VAR>collection</VAR>))</CODE> +</P> +</DL> +<P> + +<A NAME="IDX1232"></A> +</P> +<DL> +<DT><U>Function:</U> <B>size</B> <I>collection</I> +<DD>Returns the number of elements in <VAR>collection</VAR>. +</DL> +<P> + +<A NAME="IDX1233"></A> +</P> +<DL> +<DT><U>Function:</U> <B>Setter</B> <I>list-ref</I> +<DD>See <A HREF="slib_3.html#SEC43">3.8.3 Setters</A> for a definition of <EM>setter</EM>. N.B. +<CODE>(setter list-ref)</CODE> doesn't work properly for element 0 of a +list. +</DL> +<P> + +Here is a sample collection: <CODE>simple-table</CODE> which is also a +<CODE>table</CODE>. +<TABLE><tr><td> </td><td class=example><pre>(define-predicate TABLE?) +(define-operation (LOOKUP table key failure-object)) +(define-operation (ASSOCIATE! table key value)) ;; returns key +(define-operation (REMOVE! table key)) ;; returns value + +(define (MAKE-SIMPLE-TABLE) + (let ( (table (list)) ) + (object + ;; table behaviors + ((TABLE? self) #t) + ((SIZE self) (size table)) + ((PRINT self port) (format port "#<SIMPLE-TABLE>")) + ((LOOKUP self key failure-object) + (cond + ((assq key table) => cdr) + (else failure-object) + )) + ((ASSOCIATE! self key value) + (cond + ((assq key table) + => (lambda (bucket) (set-cdr! bucket value) key)) + (else + (set! table (cons (cons key value) table)) + key) + )) + ((REMOVE! self key);; returns old value + (cond + ((null? table) (slib:error "TABLE:REMOVE! Key not found: " key)) + ((eq? key (caar table)) + (let ( (value (cdar table)) ) + (set! table (cdr table)) + value) + ) + (else + (let loop ( (last table) (this (cdr table)) ) + (cond + ((null? this) + (slib:error "TABLE:REMOVE! Key not found: " key)) + ((eq? key (caar this)) + (let ( (value (cdar this)) ) + (set-cdr! last (cdr this)) + value) + ) + (else + (loop (cdr last) (cdr this))) + ) ) ) + )) + ;; collection behaviors + ((COLLECTION? self) #t) + ((GEN-KEYS self) (collect:list-gen-elts (map car table))) + ((GEN-ELTS self) (collect:list-gen-elts (map cdr table))) + ((FOR-EACH-KEY self proc) + (for-each (lambda (bucket) (proc (car bucket))) table) + ) + ((FOR-EACH-ELT self proc) + (for-each (lambda (bucket) (proc (cdr bucket))) table) + ) ) ) ) +</pre></td></tr></table><P> + +<A NAME="Dynamic Data Type"></A> +<HR SIZE="6"> +<A NAME="SEC195"></A> +<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0> +<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC194"> < </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC196"> > </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC183"> << </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC184"> Up </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_8.html#SEC277"> >> </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib.html#SEC_Top">Top</A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_toc.html#SEC_Contents">Contents</A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_abt.html#SEC_About"> ? </A>]</TD> +</TR></TABLE> +<H3> 7.1.10 Dynamic Data Type </H3> +<!--docid::SEC195::--> +<P> + +<CODE>(require 'dynamic)</CODE> +<A NAME="IDX1234"></A> +</P> +<P> + +<A NAME="IDX1235"></A> +</P> +<DL> +<DT><U>Function:</U> <B>make-dynamic</B> <I>obj</I> +<DD>Create and returns a new <EM>dynamic</EM> whose global value is <VAR>obj</VAR>. +</DL> +<P> + +<A NAME="IDX1236"></A> +</P> +<DL> +<DT><U>Function:</U> <B>dynamic?</B> <I>obj</I> +<DD>Returns true if and only if <VAR>obj</VAR> is a dynamic. No object +satisfying <CODE>dynamic?</CODE> satisfies any of the other standard type +predicates. +</DL> +<P> + +<A NAME="IDX1237"></A> +</P> +<DL> +<DT><U>Function:</U> <B>dynamic-ref</B> <I>dyn</I> +<DD>Return the value of the given dynamic in the current dynamic +environment. +</DL> +<P> + +<A NAME="IDX1238"></A> +</P> +<DL> +<DT><U>Procedure:</U> <B>dynamic-set!</B> <I>dyn obj</I> +<DD>Change the value of the given dynamic to <VAR>obj</VAR> in the current +dynamic environment. The returned value is unspecified. +</DL> +<P> + +<A NAME="IDX1239"></A> +</P> +<DL> +<DT><U>Function:</U> <B>call-with-dynamic-binding</B> <I>dyn obj thunk</I> +<DD>Invoke and return the value of the given thunk in a new, nested dynamic +environment in which the given dynamic has been bound to a new location +whose initial contents are the value <VAR>obj</VAR>. This dynamic +environment has precisely the same extent as the invocation of the thunk +and is thus captured by continuations created within that invocation and +re-established by those continuations when they are invoked. +</DL> +<P> + +The <CODE>dynamic-bind</CODE> macro is not implemented. +</P> +<P> + +<A NAME="Hash Tables"></A> +<HR SIZE="6"> +<A NAME="SEC196"></A> +<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0> +<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC195"> < </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC197"> > </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC183"> << </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC184"> Up </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_8.html#SEC277"> >> </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib.html#SEC_Top">Top</A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_toc.html#SEC_Contents">Contents</A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_abt.html#SEC_About"> ? </A>]</TD> +</TR></TABLE> +<H3> 7.1.11 Hash Tables </H3> +<!--docid::SEC196::--> +<P> + +<CODE>(require 'hash-table)</CODE> +<A NAME="IDX1240"></A> +</P> +<P> + +<A NAME="IDX1241"></A> +</P> +<DL> +<DT><U>Function:</U> <B>predicate->hash</B> <I>pred</I> +<DD><P> + +Returns a hash function (like <CODE>hashq</CODE>, <CODE>hashv</CODE>, or +<CODE>hash</CODE>) corresponding to the equality predicate <VAR>pred</VAR>. +<VAR>pred</VAR> should be <CODE>eq?</CODE>, <CODE>eqv?</CODE>, <CODE>equal?</CODE>, <CODE>=</CODE>, +<CODE>char=?</CODE>, <CODE>char-ci=?</CODE>, <CODE>string=?</CODE>, or +<CODE>string-ci=?</CODE>. +</P> +</DL> +A hash table is a vector of association lists. +<P> + +<A NAME="IDX1242"></A> +</P> +<DL> +<DT><U>Function:</U> <B>make-hash-table</B> <I>k</I> +<DD><P> + +Returns a vector of <VAR>k</VAR> empty (association) lists. +</P> +</DL> +Hash table functions provide utilities for an associative database. +These functions take an equality predicate, <VAR>pred</VAR>, as an argument. +<VAR>pred</VAR> should be <CODE>eq?</CODE>, <CODE>eqv?</CODE>, <CODE>equal?</CODE>, <CODE>=</CODE>, +<CODE>char=?</CODE>, <CODE>char-ci=?</CODE>, <CODE>string=?</CODE>, or +<CODE>string-ci=?</CODE>. +<P> + +<A NAME="IDX1243"></A> +</P> +<DL> +<DT><U>Function:</U> <B>predicate->hash-asso</B> <I>pred</I> +<DD><P> + +Returns a hash association function of 2 arguments, <VAR>key</VAR> and +<VAR>hashtab</VAR>, corresponding to <VAR>pred</VAR>. The returned function +returns a key-value pair whose key is <VAR>pred</VAR>-equal to its first +argument or <CODE>#f</CODE> if no key in <VAR>hashtab</VAR> is <VAR>pred</VAR>-equal to +the first argument. +</P> +</DL> +<P> + +<A NAME="IDX1244"></A> +</P> +<DL> +<DT><U>Function:</U> <B>hash-inquirer</B> <I>pred</I> +<DD><P> + +Returns a procedure of 2 arguments, <VAR>hashtab</VAR> and <VAR>key</VAR>, which +returns the value associated with <VAR>key</VAR> in <VAR>hashtab</VAR> or +<CODE>#f</CODE> if <VAR>key</VAR> does not appear in <VAR>hashtab</VAR>. +</P> +</DL> +<P> + +<A NAME="IDX1245"></A> +</P> +<DL> +<DT><U>Function:</U> <B>hash-associator</B> <I>pred</I> +<DD><P> + +Returns a procedure of 3 arguments, <VAR>hashtab</VAR>, <VAR>key</VAR>, and +<VAR>value</VAR>, which modifies <VAR>hashtab</VAR> so that <VAR>key</VAR> and +<VAR>value</VAR> associated. Any previous value associated with <VAR>key</VAR> +will be lost. +</P> +</DL> +<P> + +<A NAME="IDX1246"></A> +</P> +<DL> +<DT><U>Function:</U> <B>hash-remover</B> <I>pred</I> +<DD><P> + +Returns a procedure of 2 arguments, <VAR>hashtab</VAR> and <VAR>key</VAR>, which +modifies <VAR>hashtab</VAR> so that the association whose key is <VAR>key</VAR> is +removed. +</P> +</DL> +<P> + +<A NAME="IDX1247"></A> +</P> +<DL> +<DT><U>Function:</U> <B>hash-map</B> <I>proc hash-table</I> +<DD><P> + +Returns a new hash table formed by mapping <VAR>proc</VAR> over the +keys and values of <VAR>hash-table</VAR>. <VAR>proc</VAR> must be a function of 2 +arguments which returns the new value part. +</P> +</DL> +<P> + +<A NAME="IDX1248"></A> +</P> +<DL> +<DT><U>Function:</U> <B>hash-for-each</B> <I>proc hash-table</I> +<DD><P> + +Applies <VAR>proc</VAR> to each pair of keys and values of <VAR>hash-table</VAR>. +<VAR>proc</VAR> must be a function of 2 arguments. The returned value is +unspecified. +</P> +</DL> +<P> + +<A NAME="IDX1249"></A> +</P> +<DL> +<DT><U>Function:</U> <B>hash-rehasher</B> <I>pred</I> +<DD><P> + +<CODE>hash-rehasher</CODE> accepts a hash table predicate and returns a function of two +arguments <VAR>hashtab</VAR> and <VAR>new-k</VAR> which is specialized for +that predicate. +</P> +<P> + +This function is used for nondestrutively resizing a hash table. +<VAR>hashtab</VAR> should be an existing hash-table using <VAR>pred</VAR>, <VAR>new-k</VAR> +is the size of a new hash table to be returned. The new hash table +will have all of the associations of the old hash table. +</P> +</DL> +<P> + +<A NAME="Object"></A> +<HR SIZE="6"> +<A NAME="SEC197"></A> +<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0> +<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC196"> < </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC198"> > </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC183"> << </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC184"> Up </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_8.html#SEC277"> >> </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib.html#SEC_Top">Top</A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_toc.html#SEC_Contents">Contents</A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_abt.html#SEC_About"> ? </A>]</TD> +</TR></TABLE> +<H3> 7.1.12 Macroless Object System </H3> +<!--docid::SEC197::--> +<P> + +<CODE>(require 'object)</CODE> +<A NAME="IDX1250"></A> +</P> +<P> + +This is the Macroless Object System written by Wade Humeniuk +(whumeniu@datap.ca). Conceptual Tributes: <A HREF="slib_3.html#SEC40">3.8 Yasos</A>, MacScheme's +%object, CLOS, Lack of R4RS macros. +</P> +<P> + +<HR SIZE="6"> +<A NAME="SEC198"></A> +<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0> +<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC197"> < </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC199"> > </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC183"> << </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC184"> Up </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_8.html#SEC277"> >> </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib.html#SEC_Top">Top</A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_toc.html#SEC_Contents">Contents</A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_abt.html#SEC_About"> ? </A>]</TD> +</TR></TABLE> +<H3> 7.1.13 Concepts </H3> +<!--docid::SEC198::--> +<DL COMPACT> + +<DT>OBJECT +<DD>An object is an ordered association-list (by <CODE>eq?</CODE>) of methods +(procedures). Methods can be added (<CODE>make-method!</CODE>), deleted +(<CODE>unmake-method!</CODE>) and retrieved (<CODE>get-method</CODE>). Objects may +inherit methods from other objects. The object binds to the environment +it was created in, allowing closures to be used to hide private +procedures and data. +<P> + +</P> +<DT>GENERIC-METHOD +<DD>A generic-method associates (in terms of <CODE>eq?</CODE>) object's method. +This allows scheme function style to be used for objects. The calling +scheme for using a generic method is <CODE>(generic-method object param1 +param2 ...)</CODE>. +<P> + +</P> +<DT>METHOD +<DD>A method is a procedure that exists in the object. To use a method +get-method must be called to look-up the method. Generic methods +implement the get-method functionality. Methods may be added to an +object associated with any scheme obj in terms of eq? +<P> + +</P> +<DT>GENERIC-PREDICATE +<DD>A generic method that returns a boolean value for any scheme obj. +<P> + +</P> +<DT>PREDICATE +<DD>A object's method asscociated with a generic-predicate. Returns +<CODE>#t</CODE>. +</DL> +<P> + +<HR SIZE="6"> +<A NAME="SEC199"></A> +<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0> +<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC198"> < </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC200"> > </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC183"> << </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC184"> Up </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_8.html#SEC277"> >> </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib.html#SEC_Top">Top</A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_toc.html#SEC_Contents">Contents</A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_abt.html#SEC_About"> ? </A>]</TD> +</TR></TABLE> +<H3> 7.1.14 Procedures </H3> +<!--docid::SEC199::--> +<P> + +<A NAME="IDX1251"></A> +</P> +<DL> +<DT><U>Function:</U> <B>make-object</B> <I>ancestor <small>...</small></I> +<DD>Returns an object. Current object implementation is a tagged vector. +<VAR>ancestor</VAR>s are optional and must be objects in terms of object?. +<VAR>ancestor</VAR>s methods are included in the object. Multiple +<VAR>ancestor</VAR>s might associate the same generic-method with a method. +In this case the method of the <VAR>ancestor</VAR> first appearing in the +list is the one returned by <CODE>get-method</CODE>. +</DL> +<P> + +<A NAME="IDX1252"></A> +</P> +<DL> +<DT><U>Function:</U> <B>object?</B> <I>obj</I> +<DD>Returns boolean value whether <VAR>obj</VAR> was created by make-object. +</DL> +<P> + +<A NAME="IDX1253"></A> +</P> +<DL> +<DT><U>Function:</U> <B>make-generic-method</B> <I>exception-procedure</I> +<DD>Returns a procedure which be associated with an object's methods. If +<VAR>exception-procedure</VAR> is specified then it is used to process +non-objects. +</DL> +<P> + +<A NAME="IDX1254"></A> +</P> +<DL> +<DT><U>Function:</U> <B>make-generic-predicate</B> +<DD>Returns a boolean procedure for any scheme object. +</DL> +<P> + +<A NAME="IDX1255"></A> +</P> +<DL> +<DT><U>Function:</U> <B>make-method!</B> <I>object generic-method method</I> +<DD>Associates <VAR>method</VAR> to the <VAR>generic-method</VAR> in the object. The +<VAR>method</VAR> overrides any previous association with the +<VAR>generic-method</VAR> within the object. Using <CODE>unmake-method!</CODE> +will restore the object's previous association with the +<VAR>generic-method</VAR>. <VAR>method</VAR> must be a procedure. +</DL> +<P> + +<A NAME="IDX1256"></A> +</P> +<DL> +<DT><U>Function:</U> <B>make-predicate!</B> <I>object generic-preciate</I> +<DD>Makes a predicate method associated with the <VAR>generic-predicate</VAR>. +</DL> +<P> + +<A NAME="IDX1257"></A> +</P> +<DL> +<DT><U>Function:</U> <B>unmake-method!</B> <I>object generic-method</I> +<DD>Removes an object's association with a <VAR>generic-method</VAR> . +</DL> +<P> + +<A NAME="IDX1258"></A> +</P> +<DL> +<DT><U>Function:</U> <B>get-method</B> <I>object generic-method</I> +<DD>Returns the object's method associated (if any) with the +<VAR>generic-method</VAR>. If no associated method exists an error is +flagged. +</DL> +<P> + +<HR SIZE="6"> +<A NAME="SEC200"></A> +<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0> +<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC199"> < </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC201"> > </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC183"> << </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC184"> Up </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_8.html#SEC277"> >> </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib.html#SEC_Top">Top</A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_toc.html#SEC_Contents">Contents</A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_abt.html#SEC_About"> ? </A>]</TD> +</TR></TABLE> +<H3> 7.1.15 Examples </H3> +<!--docid::SEC200::--> +<P> + +<TABLE><tr><td> </td><td class=example><pre>(require 'object) +<A NAME="IDX1259"></A> +(define instantiate (make-generic-method)) + +(define (make-instance-object . ancestors) + (define self (apply make-object + (map (lambda (obj) (instantiate obj)) ancestors))) + (make-method! self instantiate (lambda (self) self)) + self) + +(define who (make-generic-method)) +(define imigrate! (make-generic-method)) +(define emigrate! (make-generic-method)) +(define describe (make-generic-method)) +(define name (make-generic-method)) +(define address (make-generic-method)) +(define members (make-generic-method)) + +(define society + (let () + (define self (make-instance-object)) + (define population '()) + (make-method! self imigrate! + (lambda (new-person) + (if (not (eq? new-person self)) + (set! population (cons new-person population))))) + (make-method! self emigrate! + (lambda (person) + (if (not (eq? person self)) + (set! population + (comlist:remove-if (lambda (member) + (eq? member person)) + population))))) + (make-method! self describe + (lambda (self) + (map (lambda (person) (describe person)) population))) + (make-method! self who + (lambda (self) (map (lambda (person) (name person)) + population))) + (make-method! self members (lambda (self) population)) + self)) + +(define (make-person %name %address) + (define self (make-instance-object society)) + (make-method! self name (lambda (self) %name)) + (make-method! self address (lambda (self) %address)) + (make-method! self who (lambda (self) (name self))) + (make-method! self instantiate + (lambda (self) + (make-person (string-append (name self) "-son-of") + %address))) + (make-method! self describe + (lambda (self) (list (name self) (address self)))) + (imigrate! self) + self) +</pre></td></tr></table><P> + +<HR SIZE="6"> +<A NAME="SEC201"></A> +<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0> +<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC200"> < </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC202"> > </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC183"> << </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC184"> Up </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_8.html#SEC277"> >> </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib.html#SEC_Top">Top</A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_toc.html#SEC_Contents">Contents</A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_abt.html#SEC_About"> ? </A>]</TD> +</TR></TABLE> +<H4> 7.1.15.1 Inverter Documentation </H4> +<!--docid::SEC201::--> +Inheritance: +<TABLE><tr><td> </td><td class=example><pre> <inverter>::(<number> <description>) +</pre></td></tr></table>Generic-methods +<TABLE><tr><td> </td><td class=example><pre> <inverter>::value => <number>::value + <inverter>::set-value! => <number>::set-value! + <inverter>::describe => <description>::describe + <inverter>::help + <inverter>::invert + <inverter>::inverter? +</pre></td></tr></table><P> + +<HR SIZE="6"> +<A NAME="SEC202"></A> +<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0> +<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC201"> < </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC203"> > </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC183"> << </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC184"> Up </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_8.html#SEC277"> >> </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib.html#SEC_Top">Top</A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_toc.html#SEC_Contents">Contents</A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_abt.html#SEC_About"> ? </A>]</TD> +</TR></TABLE> +<H4> 7.1.15.2 Number Documention </H4> +<!--docid::SEC202::--> +Inheritance +<TABLE><tr><td> </td><td class=example><pre> <number>::() +</pre></td></tr></table>Slots +<TABLE><tr><td> </td><td class=example><pre> <number>::<x> +</pre></td></tr></table>Generic Methods +<TABLE><tr><td> </td><td class=example><pre> <number>::value + <number>::set-value! +</pre></td></tr></table><P> + +<HR SIZE="6"> +<A NAME="SEC203"></A> +<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0> +<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC202"> < </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC204"> > </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC183"> << </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC184"> Up </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_8.html#SEC277"> >> </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib.html#SEC_Top">Top</A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_toc.html#SEC_Contents">Contents</A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_abt.html#SEC_About"> ? </A>]</TD> +</TR></TABLE> +<H4> 7.1.15.3 Inverter code </H4> +<!--docid::SEC203::--> +<TABLE><tr><td> </td><td class=example><pre>(require 'object) +<A NAME="IDX1260"></A> +(define value (make-generic-method (lambda (val) val))) +(define set-value! (make-generic-method)) +(define invert (make-generic-method + (lambda (val) + (if (number? val) + (/ 1 val) + (error "Method not supported:" val))))) +(define noop (make-generic-method)) +(define inverter? (make-generic-predicate)) +(define describe (make-generic-method)) +(define help (make-generic-method)) + +(define (make-number x) + (define self (make-object)) + (make-method! self value (lambda (this) x)) + (make-method! self set-value! + (lambda (this new-value) (set! x new-value))) + self) + +(define (make-description str) + (define self (make-object)) + (make-method! self describe (lambda (this) str)) + (make-method! self help (lambda (this) "Help not available")) + self) + +(define (make-inverter) + (let* ((self (make-object + (make-number 1) + (make-description "A number which can be inverted"))) + (<value> (get-method self value))) + (make-method! self invert (lambda (self) (/ 1 (<value> self)))) + (make-predicate! self inverter?) + (unmake-method! self help) + (make-method! self help + (lambda (self) + (display "Inverter Methods:") (newline) + (display " (value inverter) ==> n") (newline))) + self)) + +;;;; Try it out + +(define invert! (make-generic-method)) + +(define x (make-inverter)) + +(make-method! x invert! (lambda (x) (set-value! x (/ 1 (value x))))) + +(value x) => 1 +(set-value! x 33) => undefined +(invert! x) => undefined +(value x) => 1/33 + +(unmake-method! x invert!) => undefined + +(invert! x) error--> ERROR: Method not supported: x +</pre></td></tr></table><P> + +<A NAME="Priority Queues"></A> +<HR SIZE="6"> +<A NAME="SEC204"></A> +<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0> +<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC203"> < </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC205"> > </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC183"> << </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC184"> Up </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_8.html#SEC277"> >> </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib.html#SEC_Top">Top</A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_toc.html#SEC_Contents">Contents</A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_abt.html#SEC_About"> ? </A>]</TD> +</TR></TABLE> +<H3> 7.1.16 Priority Queues </H3> +<!--docid::SEC204::--> +<P> + +<CODE>(require 'priority-queue)</CODE> +<A NAME="IDX1261"></A> +</P> +<P> + +This algorithm for priority queues is due to +<CITE>Introduction to Algorithms</CITE> +by T. Cormen, C. Leiserson, R. Rivest. +1989 MIT Press. +</P> +<P> + +<A NAME="IDX1262"></A> +</P> +<DL> +<DT><U>Function:</U> <B>make-heap</B> <I>pred<?</I> +<DD><P> + +Returns a binary heap suitable which can be used for priority queue +operations. +</P> +</DL> +<P> + +<A NAME="IDX1263"></A> +</P> +<DL> +<DT><U>Function:</U> <B>heap-length</B> <I>heap</I> +<DD><P> + +Returns the number of elements in <VAR>heap</VAR>. +</P> +</DL> +<P> + +<A NAME="IDX1264"></A> +</P> +<DL> +<DT><U>Procedure:</U> <B>heap-insert!</B> <I>heap item</I> +<DD><P> + +Inserts <VAR>item</VAR> into <VAR>heap</VAR>. <VAR>item</VAR> can be inserted multiple +times. The value returned is unspecified. +</P> +</DL> +<P> + +<A NAME="IDX1265"></A> +</P> +<DL> +<DT><U>Procedure:</U> <B>heap-extract-max!</B> <I>heap</I> +<DD><P> + +Returns the item which is larger than all others according to the +<VAR>pred<?</VAR> argument to <CODE>make-heap</CODE>. If there are no items in +<VAR>heap</VAR>, an error is signaled. +</P> +</DL> +<P> + +<A NAME="Queues"></A> +<HR SIZE="6"> +<A NAME="SEC205"></A> +<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0> +<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC204"> < </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC206"> > </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC183"> << </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC184"> Up </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_8.html#SEC277"> >> </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib.html#SEC_Top">Top</A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_toc.html#SEC_Contents">Contents</A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_abt.html#SEC_About"> ? </A>]</TD> +</TR></TABLE> +<H3> 7.1.17 Queues </H3> +<!--docid::SEC205::--> +<P> + +<CODE>(require 'queue)</CODE> +<A NAME="IDX1266"></A> +</P> +<P> + +A <EM>queue</EM> is a list where elements can be added to both the front +<A NAME="IDX1267"></A> +and rear, and removed from the front (i.e., they are what are often +called <EM>dequeues</EM>). A queue may also be used like a stack. +<A NAME="IDX1268"></A> +</P> +<P> + +<A NAME="IDX1269"></A> +</P> +<DL> +<DT><U>Function:</U> <B>make-queue</B> +<DD><P> + +Returns a new, empty queue. +</P> +</DL> +<P> + +<A NAME="IDX1270"></A> +</P> +<DL> +<DT><U>Function:</U> <B>queue?</B> <I>obj</I> +<DD><P> + +Returns <CODE>#t</CODE> if <VAR>obj</VAR> is a queue. +</P> +</DL> +<P> + +<A NAME="IDX1271"></A> +</P> +<DL> +<DT><U>Function:</U> <B>queue-empty?</B> <I>q</I> +<DD><P> + +Returns <CODE>#t</CODE> if the queue <VAR>q</VAR> is empty. +</P> +</DL> +<P> + +<A NAME="IDX1272"></A> +</P> +<DL> +<DT><U>Procedure:</U> <B>queue-push!</B> <I>q datum</I> +<DD><P> + +Adds <VAR>datum</VAR> to the front of queue <VAR>q</VAR>. +</P> +</DL> +<P> + +<A NAME="IDX1273"></A> +</P> +<DL> +<DT><U>Procedure:</U> <B>enqueue!</B> <I>q datum</I> +<DD><P> + +Adds <VAR>datum</VAR> to the rear of queue <VAR>q</VAR>. +</P> +</DL> +<P> + +<A NAME="IDX1274"></A> +</P> +<DL> +<DT><U>Procedure:</U> <B>dequeue!</B> <I>q</I> +<DD><P> + +<A NAME="IDX1275"></A> +<DT><U>Procedure:</U> <B>queue-pop!</B> <I>q</I> +<DD>Both of these procedures remove and return the datum at the front of +the queue. <CODE>queue-pop!</CODE> is used to suggest that the queue is +being used like a stack. +</P> +</DL> +All of the following functions raise an error if the queue <VAR>q</VAR> +is empty. +<P> + +<A NAME="IDX1276"></A> +</P> +<DL> +<DT><U>Procedure:</U> <B>dequeue-all!</B> <I>q</I> +<DD><P> + +Removes and returns (the list) of all contents of queue <VAR>q</VAR>. +</P> +</DL> +<P> + +<A NAME="IDX1277"></A> +</P> +<DL> +<DT><U>Function:</U> <B>queue-front</B> <I>q</I> +<DD><P> + +Returns the datum at the front of the queue <VAR>q</VAR>. +</P> +</DL> +<P> + +<A NAME="IDX1278"></A> +</P> +<DL> +<DT><U>Function:</U> <B>queue-rear</B> <I>q</I> +<DD><P> + +Returns the datum at the rear of the queue <VAR>q</VAR>. +</P> +</DL> +<P> + +<A NAME="Records"></A> +<HR SIZE="6"> +<A NAME="SEC206"></A> +<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0> +<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC205"> < </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC207"> > </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC183"> << </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC184"> Up </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_8.html#SEC277"> >> </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib.html#SEC_Top">Top</A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_toc.html#SEC_Contents">Contents</A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_abt.html#SEC_About"> ? </A>]</TD> +</TR></TABLE> +<H3> 7.1.18 Records </H3> +<!--docid::SEC206::--> +<P> + +<CODE>(require 'record)</CODE> +<A NAME="IDX1279"></A> +</P> +<P> + +The Record package provides a facility for user to define their own +record data types. +</P> +<P> + +<A NAME="IDX1280"></A> +</P> +<DL> +<DT><U>Function:</U> <B>make-record-type</B> <I>type-name field-names</I> +<DD>Returns a <EM>record-type descriptor</EM>, a value representing a new data +type disjoint from all others. The <VAR>type-name</VAR> argument must be a +string, but is only used for debugging purposes (such as the printed +representation of a record of the new type). The <VAR>field-names</VAR> +argument is a list of symbols naming the <EM>fields</EM> of a record of the +new type. It is an error if the list contains any duplicates. It is +unspecified how record-type descriptors are represented. +</DL> +<P> + +<A NAME="IDX1281"></A> +</P> +<DL> +<DT><U>Function:</U> <B>record-constructor</B> <I>rtd [field-names]</I> +<DD>Returns a procedure for constructing new members of the type represented +by <VAR>rtd</VAR>. The returned procedure accepts exactly as many arguments +as there are symbols in the given list, <VAR>field-names</VAR>; these are +used, in order, as the initial values of those fields in a new record, +which is returned by the constructor procedure. The values of any +fields not named in that list are unspecified. The <VAR>field-names</VAR> +argument defaults to the list of field names in the call to +<CODE>make-record-type</CODE> that created the type represented by <VAR>rtd</VAR>; +if the <VAR>field-names</VAR> argument is provided, it is an error if it +contains any duplicates or any symbols not in the default list. +</DL> +<P> + +<A NAME="IDX1282"></A> +</P> +<DL> +<DT><U>Function:</U> <B>record-predicate</B> <I>rtd</I> +<DD>Returns a procedure for testing membership in the type represented by +<VAR>rtd</VAR>. The returned procedure accepts exactly one argument and +returns a true value if the argument is a member of the indicated record +type; it returns a false value otherwise. +</DL> +<P> + +<A NAME="IDX1283"></A> +</P> +<DL> +<DT><U>Function:</U> <B>record-accessor</B> <I>rtd field-name</I> +<DD>Returns a procedure for reading the value of a particular field of a +member of the type represented by <VAR>rtd</VAR>. The returned procedure +accepts exactly one argument which must be a record of the appropriate +type; it returns the current value of the field named by the symbol +<VAR>field-name</VAR> in that record. The symbol <VAR>field-name</VAR> must be a +member of the list of field-names in the call to <CODE>make-record-type</CODE> +that created the type represented by <VAR>rtd</VAR>. +</DL> +<P> + +<A NAME="IDX1284"></A> +</P> +<DL> +<DT><U>Function:</U> <B>record-modifier</B> <I>rtd field-name</I> +<DD>Returns a procedure for writing the value of a particular field of a +member of the type represented by <VAR>rtd</VAR>. The returned procedure +accepts exactly two arguments: first, a record of the appropriate type, +and second, an arbitrary Scheme value; it modifies the field named by +the symbol <VAR>field-name</VAR> in that record to contain the given value. +The returned value of the modifier procedure is unspecified. The symbol +<VAR>field-name</VAR> must be a member of the list of field-names in the call +to <CODE>make-record-type</CODE> that created the type represented by +<VAR>rtd</VAR>. +</DL> +<P> + +In May of 1996, as a product of discussion on the <CODE>rrrs-authors</CODE> +mailing list, I rewrote `<TT>record.scm</TT>' to portably implement type +disjointness for record data types. +</P> +<P> + +As long as an implementation's procedures are opaque and the +<CODE>record</CODE> code is loaded before other programs, this will give +disjoint record types which are unforgeable and incorruptible by R4RS +procedures. +</P> +<P> + +As a consequence, the procedures <CODE>record?</CODE>, +<CODE>record-type-descriptor</CODE>, <CODE>record-type-name</CODE>.and +<CODE>record-type-field-names</CODE> are no longer supported. +</P> +<P> + +<A NAME="Sorting and Searching"></A> +<HR SIZE="6"> +<A NAME="SEC207"></A> +<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0> +<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC206"> < </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC208"> > </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC183"> << </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC183"> Up </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_8.html#SEC277"> >> </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib.html#SEC_Top">Top</A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_toc.html#SEC_Contents">Contents</A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_abt.html#SEC_About"> ? </A>]</TD> +</TR></TABLE> +<H2> 7.2 Sorting and Searching </H2> +<!--docid::SEC207::--> +<P> + +<TABLE BORDER="0" CELLSPACING="0"> +<TR><TD ALIGN="left" VALIGN="TOP"><A HREF="slib_7.html#SEC208">7.2.1 Common List Functions</A></TD><TD> </TD><TD ALIGN="left" VALIGN="TOP">'common-list-functions</TD></TR> +<TR><TD ALIGN="left" VALIGN="TOP"><A HREF="slib_7.html#SEC214">7.2.2 Tree operations</A></TD><TD> </TD><TD ALIGN="left" VALIGN="TOP">'tree</TD></TR> +<TR><TD ALIGN="left" VALIGN="TOP"><A HREF="slib_7.html#SEC215">7.2.3 Chapter Ordering</A></TD><TD> </TD><TD ALIGN="left" VALIGN="TOP">'chapter-order</TD></TR> +<TR><TD ALIGN="left" VALIGN="TOP"><A HREF="slib_7.html#SEC216">7.2.4 Sorting</A></TD><TD> </TD><TD ALIGN="left" VALIGN="TOP">'sort</TD></TR> +<TR><TD ALIGN="left" VALIGN="TOP"><A HREF="slib_7.html#SEC217">7.2.5 Topological Sort</A></TD><TD> </TD><TD ALIGN="left" VALIGN="TOP">Keep your socks on.</TD></TR> +<TR><TD ALIGN="left" VALIGN="TOP"><A HREF="slib_7.html#SEC218">7.2.6 Hashing</A></TD><TD> </TD><TD ALIGN="left" VALIGN="TOP">'hash</TD></TR> +<TR><TD ALIGN="left" VALIGN="TOP"><A HREF="slib_7.html#SEC219">7.2.7 Space-Filling Curves</A></TD><TD> </TD><TD ALIGN="left" VALIGN="TOP">'hilbert and 'sierpinski</TD></TR> +<TR><TD ALIGN="left" VALIGN="TOP"><A HREF="slib_7.html#SEC222">7.2.8 Soundex</A></TD><TD> </TD><TD ALIGN="left" VALIGN="TOP">Dimension Reduction of Last Names</TD></TR> +<TR><TD ALIGN="left" VALIGN="TOP"><A HREF="slib_7.html#SEC223">7.2.9 String Search</A></TD><TD> </TD><TD ALIGN="left" VALIGN="TOP">Also Search from a Port.</TD></TR> +<TR><TD ALIGN="left" VALIGN="TOP"><A HREF="slib_7.html#SEC224">7.2.10 Sequence Comparison</A></TD><TD> </TD><TD ALIGN="left" VALIGN="TOP">'diff and longest-common-subsequence</TD></TR> +</TABLE> +<P> + +<A NAME="Common List Functions"></A> +<HR SIZE="6"> +<A NAME="SEC208"></A> +<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0> +<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC207"> < </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC209"> > </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC183"> << </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC207"> Up </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_8.html#SEC277"> >> </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib.html#SEC_Top">Top</A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_toc.html#SEC_Contents">Contents</A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_abt.html#SEC_About"> ? </A>]</TD> +</TR></TABLE> +<H3> 7.2.1 Common List Functions </H3> +<!--docid::SEC208::--> +<P> + +<CODE>(require 'common-list-functions)</CODE> +<A NAME="IDX1285"></A> +</P> +<P> + +The procedures below follow the Common LISP equivalents apart from +optional arguments in some cases. +</P> +<P> + +<TABLE BORDER="0" CELLSPACING="0"> +<TR><TD ALIGN="left" VALIGN="TOP"><A HREF="slib_7.html#SEC209">7.2.1.1 List construction</A></TD><TD> </TD><TD ALIGN="left" VALIGN="TOP"></TD></TR> +<TR><TD ALIGN="left" VALIGN="TOP"><A HREF="slib_7.html#SEC210">7.2.1.2 Lists as sets</A></TD><TD> </TD><TD ALIGN="left" VALIGN="TOP"></TD></TR> +<TR><TD ALIGN="left" VALIGN="TOP"><A HREF="slib_7.html#SEC211">7.2.1.3 Lists as sequences</A></TD><TD> </TD><TD ALIGN="left" VALIGN="TOP"></TD></TR> +<TR><TD ALIGN="left" VALIGN="TOP"><A HREF="slib_7.html#SEC212">7.2.1.4 Destructive list operations</A></TD><TD> </TD><TD ALIGN="left" VALIGN="TOP"></TD></TR> +<TR><TD ALIGN="left" VALIGN="TOP"><A HREF="slib_7.html#SEC213">7.2.1.5 Non-List functions</A></TD><TD> </TD><TD ALIGN="left" VALIGN="TOP"></TD></TR> +</TABLE> +<P> + +<A NAME="List construction"></A> +<HR SIZE="6"> +<A NAME="SEC209"></A> +<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0> +<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC208"> < </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC210"> > </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC183"> << </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC208"> Up </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_8.html#SEC277"> >> </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib.html#SEC_Top">Top</A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_toc.html#SEC_Contents">Contents</A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_abt.html#SEC_About"> ? </A>]</TD> +</TR></TABLE> +<H4> 7.2.1.1 List construction </H4> +<!--docid::SEC209::--> +<P> + +<A NAME="IDX1286"></A> +</P> +<DL> +<DT><U>Function:</U> <B>make-list</B> <I>k</I> +<DD><A NAME="IDX1287"></A> +<DT><U>Function:</U> <B>make-list</B> <I>k init</I> +<DD><CODE>make-list</CODE> creates and returns a list of <VAR>k</VAR> elements. If +<VAR>init</VAR> is included, all elements in the list are initialized to +<VAR>init</VAR>. +<P> + +Example: +<TABLE><tr><td> </td><td class=example><pre>(make-list 3) + => (#<unspecified> #<unspecified> #<unspecified>) +(make-list 5 'foo) + => (foo foo foo foo foo) +</pre></td></tr></table></DL> +<P> + +<A NAME="IDX1288"></A> +</P> +<DL> +<DT><U>Function:</U> <B>list*</B> <I>obj1 obj2 <small>...</small></I> +<DD>Works like <CODE>list</CODE> except that the cdr of the last pair is the last +argument unless there is only one argument, when the result is just that +argument. Sometimes called <CODE>cons*</CODE>. E.g.: +<P> + +<TABLE><tr><td> </td><td class=example><pre>(list* 1) + => 1 +(list* 1 2 3) + => (1 2 . 3) +(list* 1 2 '(3 4)) + => (1 2 3 4) +(list* <VAR>args</VAR> '()) + == (list <VAR>args</VAR>) +</pre></td></tr></table></DL> +<P> + +<A NAME="IDX1289"></A> +</P> +<DL> +<DT><U>Function:</U> <B>copy-list</B> <I>lst</I> +<DD><CODE>copy-list</CODE> makes a copy of <VAR>lst</VAR> using new pairs and returns +it. Only the top level of the list is copied, i.e., pairs forming +elements of the copied list remain <CODE>eq?</CODE> to the corresponding +elements of the original; the copy is, however, not <CODE>eq?</CODE> to the +original, but is <CODE>equal?</CODE> to it. +<P> + +Example: +<TABLE><tr><td> </td><td class=example><pre>(copy-list '(foo foo foo)) + => (foo foo foo) +(define q '(foo bar baz bang)) +(define p q) +(eq? p q) + => #t +(define r (copy-list q)) +(eq? q r) + => #f +(equal? q r) + => #t +(define bar '(bar)) +(eq? bar (car (copy-list (list bar 'foo)))) +=> #t +</pre></td></tr></table></DL> +<P> + +<A NAME="Lists as sets"></A> +<HR SIZE="6"> +<A NAME="SEC210"></A> +<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0> +<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC209"> < </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC211"> > </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC183"> << </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC208"> Up </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_8.html#SEC277"> >> </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib.html#SEC_Top">Top</A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_toc.html#SEC_Contents">Contents</A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_abt.html#SEC_About"> ? </A>]</TD> +</TR></TABLE> +<H4> 7.2.1.2 Lists as sets </H4> +<!--docid::SEC210::--> +<P> + +<CODE>eqv?</CODE> is used to test for membership by procedures which treat +lists as sets. +</P> +<P> + +<A NAME="IDX1290"></A> +</P> +<DL> +<DT><U>Function:</U> <B>adjoin</B> <I>e l</I> +<DD><CODE>adjoin</CODE> returns the adjoint of the element <VAR>e</VAR> and the list +<VAR>l</VAR>. That is, if <VAR>e</VAR> is in <VAR>l</VAR>, <CODE>adjoin</CODE> returns +<VAR>l</VAR>, otherwise, it returns <CODE>(cons <VAR>e</VAR> <VAR>l</VAR>)</CODE>. +<P> + +Example: +<TABLE><tr><td> </td><td class=example><pre>(adjoin 'baz '(bar baz bang)) + => (bar baz bang) +(adjoin 'foo '(bar baz bang)) + => (foo bar baz bang) +</pre></td></tr></table></DL> +<P> + +<A NAME="IDX1291"></A> +</P> +<DL> +<DT><U>Function:</U> <B>union</B> <I>l1 l2</I> +<DD><CODE>union</CODE> returns a list of all elements that are in <VAR>l1</VAR> or +<VAR>l2</VAR>. Duplicates between <VAR>l1</VAR> and <VAR>l2</VAR> are culled. +Duplicates within <VAR>l1</VAR> or within <VAR>l2</VAR> may or may not be +removed. +<P> + +Example: +<TABLE><tr><td> </td><td class=example><pre>(union '(1 2 3 4) '(5 6 7 8)) + => (1 2 3 4 5 6 7 8) +(union '(0 1 2 3 4) '(3 4 5 6)) + => (5 6 0 1 2 3 4) +</pre></td></tr></table></DL> +<P> + +<A NAME="IDX1292"></A> +</P> +<DL> +<DT><U>Function:</U> <B>intersection</B> <I>l1 l2</I> +<DD><CODE>intersection</CODE> returns a list of all elements that are in both +<VAR>l1</VAR> and <VAR>l2</VAR>. +<P> + +Example: +<TABLE><tr><td> </td><td class=example><pre>(intersection '(1 2 3 4) '(3 4 5 6)) + => (3 4) +(intersection '(1 2 3 4) '(5 6 7 8)) + => () +</pre></td></tr></table></DL> +<P> + +<A NAME="IDX1293"></A> +</P> +<DL> +<DT><U>Function:</U> <B>set-difference</B> <I>l1 l2</I> +<DD><CODE>set-difference</CODE> returns a list of all elements that are in +<VAR>l1</VAR> but not in <VAR>l2</VAR>. +<P> + +Example: +<TABLE><tr><td> </td><td class=example><pre>(set-difference '(1 2 3 4) '(3 4 5 6)) + => (1 2) +(set-difference '(1 2 3 4) '(1 2 3 4 5 6)) + => () +</pre></td></tr></table></DL> +<P> + +<A NAME="IDX1294"></A> +</P> +<DL> +<DT><U>Function:</U> <B>subset?</B> <I>list1 list2</I> +<DD>Returns <CODE>#t</CODE> if every element of <VAR>list1</VAR> is <CODE>eqv?</CODE> an +element of <VAR>list2</VAR>; otherwise returns <CODE>#f</CODE>. +<P> + +Example: +<TABLE><tr><td> </td><td class=example><pre>(subset? '(1 2 3 4) '(3 4 5 6)) + => #f +(subset? '(1 2 3 4) '(6 5 4 3 2 1 0)) + => #t +</pre></td></tr></table></DL> +<P> + +<A NAME="IDX1295"></A> +</P> +<DL> +<DT><U>Function:</U> <B>member-if</B> <I>pred lst</I> +<DD><CODE>member-if</CODE> returns the list headed by the first element of +<VAR>lst</VAR> to satisfy <CODE>(<VAR>pred</VAR> <VAR>element</VAR>)</CODE>. +<CODE>Member-if</CODE> returns <CODE>#f</CODE> if <VAR>pred</VAR> returns <CODE>#f</CODE> for +every <VAR>element</VAR> in <VAR>lst</VAR>. +<P> + +Example: +<TABLE><tr><td> </td><td class=example><pre>(member-if vector? '(a 2 b 4)) + => #f +(member-if number? '(a 2 b 4)) + => (2 b 4) +</pre></td></tr></table></DL> +<P> + +<A NAME="IDX1296"></A> +</P> +<DL> +<DT><U>Function:</U> <B>some</B> <I>pred lst1 lst2 <small>...</small></I> +<DD><VAR>pred</VAR> is a boolean function of as many arguments as there are list +arguments to <CODE>some</CODE> i.e., <VAR>lst</VAR> plus any optional arguments. +<VAR>pred</VAR> is applied to successive elements of the list arguments in +order. <CODE>some</CODE> returns <CODE>#t</CODE> as soon as one of these +applications returns <CODE>#t</CODE>, and is <CODE>#f</CODE> if none returns +<CODE>#t</CODE>. All the lists should have the same length. +<P> + +Example: +<TABLE><tr><td> </td><td class=example><pre>(some odd? '(1 2 3 4)) + => #t + +(some odd? '(2 4 6 8)) + => #f + +(some > '(1 3) '(2 4)) + => #f +</pre></td></tr></table></DL> +<P> + +<A NAME="IDX1297"></A> +</P> +<DL> +<DT><U>Function:</U> <B>every</B> <I>pred lst1 lst2 <small>...</small></I> +<DD><CODE>every</CODE> is analogous to <CODE>some</CODE> except it returns <CODE>#t</CODE> if +every application of <VAR>pred</VAR> is <CODE>#t</CODE> and <CODE>#f</CODE> +otherwise. +<P> + +Example: +<TABLE><tr><td> </td><td class=example><pre>(every even? '(1 2 3 4)) + => #f + +(every even? '(2 4 6 8)) + => #t + +(every > '(2 3) '(1 4)) + => #f +</pre></td></tr></table></DL> +<P> + +<A NAME="IDX1298"></A> +</P> +<DL> +<DT><U>Function:</U> <B>notany</B> <I>pred lst1 <small>...</small></I> +<DD><CODE>notany</CODE> is analogous to <CODE>some</CODE> but returns <CODE>#t</CODE> if no +application of <VAR>pred</VAR> returns <CODE>#t</CODE> or <CODE>#f</CODE> as soon as any +one does. +</DL> +<P> + +<A NAME="IDX1299"></A> +</P> +<DL> +<DT><U>Function:</U> <B>notevery</B> <I>pred lst1 <small>...</small></I> +<DD><CODE>notevery</CODE> is analogous to <CODE>some</CODE> but returns <CODE>#t</CODE> as soon +as an application of <VAR>pred</VAR> returns <CODE>#f</CODE>, and <CODE>#f</CODE> +otherwise. +<P> + +Example: +<TABLE><tr><td> </td><td class=example><pre>(notevery even? '(1 2 3 4)) + => #t + +(notevery even? '(2 4 6 8)) + => #f +</pre></td></tr></table></DL> +<P> + +<A NAME="IDX1300"></A> +</P> +<DL> +<DT><U>Function:</U> <B>list-of??</B> <I>predicate</I> +<DD>Returns a predicate which returns true if its argument is a list every +element of which satisfies <VAR>predicate</VAR>. +<P> + +<A NAME="IDX1301"></A> +<DT><U>Function:</U> <B>list-of??</B> <I>predicate low-bound high-bound</I> +<DD><VAR>low-bound</VAR> and <VAR>high-bound</VAR> are non-negative integers. +<CODE>list-of??</CODE> returns a predicate which returns true if its argument +is a list of length between <VAR>low-bound</VAR> and <VAR>high-bound</VAR> +(inclusive); every element of which satisfies <VAR>predicate</VAR>. +</P> +<P> + +<A NAME="IDX1302"></A> +<DT><U>Function:</U> <B>list-of??</B> <I>predicate bound</I> +<DD><VAR>bound</VAR> is an integer. If <VAR>bound</VAR> is negative, <CODE>list-of??</CODE> +returns a predicate which returns true if its argument is a list of +length greater than <CODE>(- <VAR>bound</VAR>)</CODE>; every element of which +satisfies <VAR>predicate</VAR>. Otherwise, <CODE>list-of??</CODE> returns a +predicate which returns true if its argument is a list of length less +than or equal to <VAR>bound</VAR>; every element of which satisfies +<VAR>predicate</VAR>. +</P> +</DL> +<P> + +<A NAME="IDX1303"></A> +</P> +<DL> +<DT><U>Function:</U> <B>find-if</B> <I>pred lst</I> +<DD><CODE>find-if</CODE> searches for the first <VAR>element</VAR> in <VAR>lst</VAR> such +that <CODE>(<VAR>pred</VAR> <VAR>element</VAR>)</CODE> returns <CODE>#t</CODE>. If it finds +any such <VAR>element</VAR> in <VAR>lst</VAR>, <VAR>element</VAR> is returned. +Otherwise, <CODE>#f</CODE> is returned. +<P> + +Example: +<TABLE><tr><td> </td><td class=example><pre>(find-if number? '(foo 1 bar 2)) + => 1 + +(find-if number? '(foo bar baz bang)) + => #f + +(find-if symbol? '(1 2 foo bar)) + => foo +</pre></td></tr></table></DL> +<P> + +<A NAME="IDX1304"></A> +</P> +<DL> +<DT><U>Function:</U> <B>remove</B> <I>elt lst</I> +<DD><CODE>remove</CODE> removes all occurrences of <VAR>elt</VAR> from <VAR>lst</VAR> using +<CODE>eqv?</CODE> to test for equality and returns everything that's left. +N.B.: other implementations (Chez, Scheme->C and T, at least) use +<CODE>equal?</CODE> as the equality test. +<P> + +Example: +<TABLE><tr><td> </td><td class=example><pre>(remove 1 '(1 2 1 3 1 4 1 5)) + => (2 3 4 5) + +(remove 'foo '(bar baz bang)) + => (bar baz bang) +</pre></td></tr></table></DL> +<P> + +<A NAME="IDX1305"></A> +</P> +<DL> +<DT><U>Function:</U> <B>remove-if</B> <I>pred lst</I> +<DD><CODE>remove-if</CODE> removes all <VAR>element</VAR>s from <VAR>lst</VAR> where +<CODE>(<VAR>pred</VAR> <VAR>element</VAR>)</CODE> is <CODE>#t</CODE> and returns everything +that's left. +<P> + +Example: +<TABLE><tr><td> </td><td class=example><pre>(remove-if number? '(1 2 3 4)) + => () + +(remove-if even? '(1 2 3 4 5 6 7 8)) + => (1 3 5 7) +</pre></td></tr></table></DL> +<P> + +<A NAME="IDX1306"></A> +</P> +<DL> +<DT><U>Function:</U> <B>remove-if-not</B> <I>pred lst</I> +<DD><CODE>remove-if-not</CODE> removes all <VAR>element</VAR>s from <VAR>lst</VAR> for which +<CODE>(<VAR>pred</VAR> <VAR>element</VAR>)</CODE> is <CODE>#f</CODE> and returns everything that's +left. +<P> + +Example: +<TABLE><tr><td> </td><td class=example><pre>(remove-if-not number? '(foo bar baz)) + => () +(remove-if-not odd? '(1 2 3 4 5 6 7 8)) + => (1 3 5 7) +</pre></td></tr></table></DL> +<P> + +<A NAME="IDX1307"></A> +</P> +<DL> +<DT><U>Function:</U> <B>has-duplicates?</B> <I>lst</I> +<DD>returns <CODE>#t</CODE> if 2 members of <VAR>lst</VAR> are <CODE>equal?</CODE>, <CODE>#f</CODE> +otherwise. +<P> + +Example: +<TABLE><tr><td> </td><td class=example><pre>(has-duplicates? '(1 2 3 4)) + => #f + +(has-duplicates? '(2 4 3 4)) + => #t +</pre></td></tr></table></DL> +<P> + +The procedure <CODE>remove-duplicates</CODE> uses <CODE>member</CODE> (rather than +<CODE>memv</CODE>). +</P> +<P> + +<A NAME="IDX1308"></A> +</P> +<DL> +<DT><U>Function:</U> <B>remove-duplicates</B> <I>lst</I> +<DD>returns a copy of <VAR>lst</VAR> with its duplicate members removed. +Elements are considered duplicate if they are <CODE>equal?</CODE>. +<P> + +Example: +<TABLE><tr><td> </td><td class=example><pre>(remove-duplicates '(1 2 3 4)) + => (1 2 3 4) + +(remove-duplicates '(2 4 3 4)) + => (2 4 3) +</pre></td></tr></table></DL> +<P> + +<A NAME="Lists as sequences"></A> +<HR SIZE="6"> +<A NAME="SEC211"></A> +<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0> +<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC210"> < </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC212"> > </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC183"> << </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC208"> Up </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_8.html#SEC277"> >> </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib.html#SEC_Top">Top</A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_toc.html#SEC_Contents">Contents</A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_abt.html#SEC_About"> ? </A>]</TD> +</TR></TABLE> +<H4> 7.2.1.3 Lists as sequences </H4> +<!--docid::SEC211::--> +<P> + +<A NAME="IDX1309"></A> +</P> +<DL> +<DT><U>Function:</U> <B>position</B> <I>obj lst</I> +<DD><CODE>position</CODE> returns the 0-based position of <VAR>obj</VAR> in <VAR>lst</VAR>, +or <CODE>#f</CODE> if <VAR>obj</VAR> does not occur in <VAR>lst</VAR>. +<P> + +Example: +<TABLE><tr><td> </td><td class=example><pre>(position 'foo '(foo bar baz bang)) + => 0 +(position 'baz '(foo bar baz bang)) + => 2 +(position 'oops '(foo bar baz bang)) + => #f +</pre></td></tr></table></DL> +<P> + +<A NAME="IDX1310"></A> +</P> +<DL> +<DT><U>Function:</U> <B>reduce</B> <I>p lst</I> +<DD><CODE>reduce</CODE> combines all the elements of a sequence using a binary +operation (the combination is left-associative). For example, using +<CODE>+</CODE>, one can add up all the elements. <CODE>reduce</CODE> allows you to +apply a function which accepts only two arguments to more than 2 +objects. Functional programmers usually refer to this as <EM>foldl</EM>. +<CODE>collect:reduce</CODE> (see section <A HREF="slib_7.html#SEC194">7.1.9 Collections</A>) provides a version of +<CODE>collect</CODE> generalized to collections. +<P> + +Example: +<TABLE><tr><td> </td><td class=example><pre>(reduce + '(1 2 3 4)) + => 10 +(define (bad-sum . l) (reduce + l)) +(bad-sum 1 2 3 4) + == (reduce + (1 2 3 4)) + == (+ (+ (+ 1 2) 3) 4) +=> 10 +(bad-sum) + == (reduce + ()) + => () +(reduce string-append '("hello" "cruel" "world")) + == (string-append (string-append "hello" "cruel") "world") + => "hellocruelworld" +(reduce anything '()) + => () +(reduce anything '(x)) + => x +</pre></td></tr></table><P> + +What follows is a rather non-standard implementation of <CODE>reverse</CODE> +in terms of <CODE>reduce</CODE> and a combinator elsewhere called +<EM>C</EM>. +</P> +<P> + +<TABLE><tr><td> </td><td class=example><pre>;;; Contributed by Jussi Piitulainen (jpiitula @ ling.helsinki.fi) + +(define commute + (lambda (f) + (lambda (x y) + (f y x)))) + +(define reverse + (lambda (args) + (reduce-init (commute cons) '() args))) +</pre></td></tr></table></DL> +<P> + +<A NAME="IDX1311"></A> +</P> +<DL> +<DT><U>Function:</U> <B>reduce-init</B> <I>p init lst</I> +<DD><CODE>reduce-init</CODE> is the same as reduce, except that it implicitly +inserts <VAR>init</VAR> at the start of the list. <CODE>reduce-init</CODE> is +preferred if you want to handle the null list, the one-element, and +lists with two or more elements consistently. It is common to use the +operator's idempotent as the initializer. Functional programmers +usually call this <EM>foldl</EM>. +<P> + +Example: +<TABLE><tr><td> </td><td class=example><pre>(define (sum . l) (reduce-init + 0 l)) +(sum 1 2 3 4) + == (reduce-init + 0 (1 2 3 4)) + == (+ (+ (+ (+ 0 1) 2) 3) 4) + => 10 +(sum) + == (reduce-init + 0 '()) + => 0 + +(reduce-init string-append "@" '("hello" "cruel" "world")) +== +(string-append (string-append (string-append "@" "hello") + "cruel") + "world") +=> "@hellocruelworld" +</pre></td></tr></table><P> + +Given a differentiation of 2 arguments, <CODE>diff</CODE>, the following will +differentiate by any number of variables. +<TABLE><tr><td> </td><td class=example><pre>(define (diff* exp . vars) + (reduce-init diff exp vars)) +</pre></td></tr></table><P> + +Example: +<TABLE><tr><td> </td><td class=example><pre>;;; Real-world example: Insertion sort using reduce-init. + +(define (insert l item) + (if (null? l) + (list item) + (if (< (car l) item) + (cons (car l) (insert (cdr l) item)) + (cons item l)))) +(define (insertion-sort l) (reduce-init insert '() l)) + +(insertion-sort '(3 1 4 1 5) + == (reduce-init insert () (3 1 4 1 5)) + == (insert (insert (insert (insert (insert () 3) 1) 4) 1) 5) + == (insert (insert (insert (insert (3)) 1) 4) 1) 5) + == (insert (insert (insert (1 3) 4) 1) 5) + == (insert (insert (1 3 4) 1) 5) + == (insert (1 1 3 4) 5) + => (1 1 3 4 5) +</pre></td></tr></table></DL> +<P> + +<A NAME="IDX1312"></A> +</P> +<DL> +<DT><U>Function:</U> <B>last</B> <I>lst n</I> +<DD><CODE>last</CODE> returns the last <VAR>n</VAR> elements of <VAR>lst</VAR>. <VAR>n</VAR> +must be a non-negative integer. +<P> + +Example: +<TABLE><tr><td> </td><td class=example><pre>(last '(foo bar baz bang) 2) + => (baz bang) +(last '(1 2 3) 0) + => 0 +</pre></td></tr></table></DL> +<P> + +<A NAME="IDX1313"></A> +</P> +<DL> +<DT><U>Function:</U> <B>butlast</B> <I>lst n</I> +<DD><CODE>butlast</CODE> returns all but the last <VAR>n</VAR> elements of +<VAR>lst</VAR>. +<P> + +Example: +<TABLE><tr><td> </td><td class=example><pre>(butlast '(a b c d) 3) + => (a) +(butlast '(a b c d) 4) + => () +</pre></td></tr></table></DL> +<P> + +<CODE>last</CODE> and <CODE>butlast</CODE> split a list into two parts when given +identical arugments. +<TABLE><tr><td> </td><td class=example><pre>(last '(a b c d e) 2) + => (d e) +(butlast '(a b c d e) 2) + => (a b c) +</pre></td></tr></table><P> + +<A NAME="IDX1314"></A> +</P> +<DL> +<DT><U>Function:</U> <B>nthcdr</B> <I>n lst</I> +<DD><CODE>nthcdr</CODE> takes <VAR>n</VAR> <CODE>cdr</CODE>s of <VAR>lst</VAR> and returns the +result. Thus <CODE>(nthcdr 3 <VAR>lst</VAR>)</CODE> == <CODE>(cdddr +<VAR>lst</VAR>)</CODE> +<P> + +Example: +<TABLE><tr><td> </td><td class=example><pre>(nthcdr 2 '(a b c d)) + => (c d) +(nthcdr 0 '(a b c d)) + => (a b c d) +</pre></td></tr></table></DL> +<P> + +<A NAME="IDX1315"></A> +</P> +<DL> +<DT><U>Function:</U> <B>butnthcdr</B> <I>n lst</I> +<DD><CODE>butnthcdr</CODE> returns all but the nthcdr <VAR>n</VAR> elements of +<VAR>lst</VAR>. +<P> + +Example: +<TABLE><tr><td> </td><td class=example><pre>(butnthcdr 3 '(a b c d)) + => (a b c) +(butnthcdr 4 '(a b c d)) + => (a b c d) +</pre></td></tr></table></DL> +<P> + +<CODE>nthcdr</CODE> and <CODE>butnthcdr</CODE> split a list into two parts when +given identical arugments. +<TABLE><tr><td> </td><td class=example><pre>(nthcdr 2 '(a b c d e)) + => (c d e) +(butnthcdr 2 '(a b c d e)) + => (a b) +</pre></td></tr></table><P> + +<A NAME="Destructive list operations"></A> +<HR SIZE="6"> +<A NAME="SEC212"></A> +<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0> +<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC211"> < </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC213"> > </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC183"> << </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC208"> Up </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_8.html#SEC277"> >> </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib.html#SEC_Top">Top</A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_toc.html#SEC_Contents">Contents</A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_abt.html#SEC_About"> ? </A>]</TD> +</TR></TABLE> +<H4> 7.2.1.4 Destructive list operations </H4> +<!--docid::SEC212::--> +<P> + +These procedures may mutate the list they operate on, but any such +mutation is undefined. +</P> +<P> + +<A NAME="IDX1316"></A> +</P> +<DL> +<DT><U>Procedure:</U> <B>nconc</B> <I>args</I> +<DD><CODE>nconc</CODE> destructively concatenates its arguments. (Compare this +with <CODE>append</CODE>, which copies arguments rather than destroying them.) +Sometimes called <CODE>append!</CODE> (see section <A HREF="slib_7.html#SEC239">7.4.4 Rev2 Procedures</A>). +<P> + +Example: You want to find the subsets of a set. Here's the obvious way: +</P> +<P> + +<TABLE><tr><td> </td><td class=example><pre>(define (subsets set) + (if (null? set) + '(()) + (append (map (lambda (sub) (cons (car set) sub)) + (subsets (cdr set))) + (subsets (cdr set))))) +</pre></td></tr></table>But that does way more consing than you need. Instead, you could +replace the <CODE>append</CODE> with <CODE>nconc</CODE>, since you don't have any +need for all the intermediate results. +<P> + +Example: +<TABLE><tr><td> </td><td class=example><pre>(define x '(a b c)) +(define y '(d e f)) +(nconc x y) + => (a b c d e f) +x + => (a b c d e f) +</pre></td></tr></table><P> + +<CODE>nconc</CODE> is the same as <CODE>append!</CODE> in `<TT>sc2.scm</TT>'. +</P> +</DL> +<P> + +<A NAME="IDX1317"></A> +</P> +<DL> +<DT><U>Procedure:</U> <B>nreverse</B> <I>lst</I> +<DD><CODE>nreverse</CODE> reverses the order of elements in <VAR>lst</VAR> by mutating +<CODE>cdr</CODE>s of the list. Sometimes called <CODE>reverse!</CODE>. +<P> + +Example: +<TABLE><tr><td> </td><td class=example><pre>(define foo '(a b c)) +(nreverse foo) + => (c b a) +foo + => (a) +</pre></td></tr></table><P> + +Some people have been confused about how to use <CODE>nreverse</CODE>, +thinking that it doesn't return a value. It needs to be pointed out +that +</P> +<P> + +<TABLE><tr><td> </td><td class=example><pre>(set! lst (nreverse lst)) +</pre></td></tr></table>is the proper usage, not +<TABLE><tr><td> </td><td class=example><pre>(nreverse lst) +</pre></td></tr></table>The example should suffice to show why this is the case. +</DL> +<P> + +<A NAME="IDX1318"></A> +</P> +<DL> +<DT><U>Procedure:</U> <B>delete</B> <I>elt lst</I> +<DD><A NAME="IDX1319"></A> +<DT><U>Procedure:</U> <B>delete-if</B> <I>pred lst</I> +<DD><A NAME="IDX1320"></A> +<DT><U>Procedure:</U> <B>delete-if-not</B> <I>pred lst</I> +<DD>Destructive versions of <CODE>remove</CODE> <CODE>remove-if</CODE>, and +<CODE>remove-if-not</CODE>. +<P> + +Example: +<TABLE><tr><td> </td><td class=example><pre>(define lst (list 'foo 'bar 'baz 'bang)) +(delete 'foo lst) + => (bar baz bang) +lst + => (foo bar baz bang) + +(define lst (list 1 2 3 4 5 6 7 8 9)) +(delete-if odd? lst) + => (2 4 6 8) +lst + => (1 2 4 6 8) +</pre></td></tr></table><P> + +Some people have been confused about how to use <CODE>delete</CODE>, +<CODE>delete-if</CODE>, and <CODE>delete-if</CODE>, thinking that they don't return +a value. It needs to be pointed out that +</P> +<P> + +<TABLE><tr><td> </td><td class=example><pre>(set! lst (delete el lst)) +</pre></td></tr></table>is the proper usage, not +<TABLE><tr><td> </td><td class=example><pre>(delete el lst) +</pre></td></tr></table>The examples should suffice to show why this is the case. +</DL> +<P> + +<A NAME="Non-List functions"></A> +<HR SIZE="6"> +<A NAME="SEC213"></A> +<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0> +<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC212"> < </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC214"> > </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC183"> << </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC208"> Up </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_8.html#SEC277"> >> </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib.html#SEC_Top">Top</A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_toc.html#SEC_Contents">Contents</A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_abt.html#SEC_About"> ? </A>]</TD> +</TR></TABLE> +<H4> 7.2.1.5 Non-List functions </H4> +<!--docid::SEC213::--> +<P> + +<A NAME="IDX1321"></A> +</P> +<DL> +<DT><U>Function:</U> <B>and?</B> <I>arg1 <small>...</small></I> +<DD><CODE>and?</CODE> checks to see if all its arguments are true. If they are, +<CODE>and?</CODE> returns <CODE>#t</CODE>, otherwise, <CODE>#f</CODE>. (In contrast to +<CODE>and</CODE>, this is a function, so all arguments are always evaluated +and in an unspecified order.) +<P> + +Example: +<TABLE><tr><td> </td><td class=example><pre>(and? 1 2 3) + => #t +(and #f 1 2) + => #f +</pre></td></tr></table></DL> +<P> + +<A NAME="IDX1322"></A> +</P> +<DL> +<DT><U>Function:</U> <B>or?</B> <I>arg1 <small>...</small></I> +<DD><CODE>or?</CODE> checks to see if any of its arguments are true. If any is +true, <CODE>or?</CODE> returns <CODE>#t</CODE>, and <CODE>#f</CODE> otherwise. (To +<CODE>or</CODE> as <CODE>and?</CODE> is to <CODE>and</CODE>.) +<P> + +Example: +<TABLE><tr><td> </td><td class=example><pre>(or? 1 2 #f) + => #t +(or? #f #f #f) + => #f +</pre></td></tr></table></DL> +<P> + +<A NAME="IDX1323"></A> +</P> +<DL> +<DT><U>Function:</U> <B>atom?</B> <I>object</I> +<DD>Returns <CODE>#t</CODE> if <VAR>object</VAR> is not a pair and <CODE>#f</CODE> if it is +pair. (Called <CODE>atom</CODE> in Common LISP.) +<TABLE><tr><td> </td><td class=example><pre>(atom? 1) + => #t +(atom? '(1 2)) + => #f +(atom? #(1 2)) ; dubious! + => #t +</pre></td></tr></table></DL> +<P> + +<A NAME="Tree Operations"></A> +<HR SIZE="6"> +<A NAME="SEC214"></A> +<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0> +<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC213"> < </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC215"> > </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC183"> << </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC207"> Up </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_8.html#SEC277"> >> </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib.html#SEC_Top">Top</A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_toc.html#SEC_Contents">Contents</A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_abt.html#SEC_About"> ? </A>]</TD> +</TR></TABLE> +<H3> 7.2.2 Tree operations </H3> +<!--docid::SEC214::--> +<P> + +<CODE>(require 'tree)</CODE> +<A NAME="IDX1324"></A> +</P> +<P> + +These are operations that treat lists a representations of trees. +</P> +<P> + +<A NAME="IDX1325"></A> +</P> +<DL> +<DT><U>Function:</U> <B>subst</B> <I>new old tree</I> +<DD><A NAME="IDX1326"></A> +<DT><U>Function:</U> <B>substq</B> <I>new old tree</I> +<DD><A NAME="IDX1327"></A> +<DT><U>Function:</U> <B>substv</B> <I>new old tree</I> +<DD><P> + +<A NAME="IDX1328"></A> +<DT><U>Function:</U> <B>subst</B> <I>new old tree equ?</I> +<DD><CODE>subst</CODE> makes a copy of <VAR>tree</VAR>, substituting <VAR>new</VAR> for +every subtree or leaf of <VAR>tree</VAR> which is <CODE>equal?</CODE> to <VAR>old</VAR> +and returns a modified tree. The original <VAR>tree</VAR> is unchanged, but +may share parts with the result. +</P> +<P> + +<CODE>substq</CODE> and <CODE>substv</CODE> are similar, but test against <VAR>old</VAR> +using <CODE>eq?</CODE> and <CODE>eqv?</CODE> respectively. If <CODE>subst</CODE> is +called with a fourth argument, <VAR>equ?</VAR> is the equality predicate. +</P> +<P> + +Examples: +<TABLE><tr><td> </td><td class=example><pre>(substq 'tempest 'hurricane '(shakespeare wrote (the hurricane))) + => (shakespeare wrote (the tempest)) +(substq 'foo '() '(shakespeare wrote (twelfth night))) + => (shakespeare wrote (twelfth night . foo) . foo) +(subst '(a . cons) '(old . pair) + '((old . spice) ((old . shoes) old . pair) (old . pair))) + => ((old . spice) ((old . shoes) a . cons) (a . cons)) +</pre></td></tr></table></DL> +<P> + +<A NAME="IDX1329"></A> +</P> +<DL> +<DT><U>Function:</U> <B>copy-tree</B> <I>tree</I> +<DD><P> + +Makes a copy of the nested list structure <VAR>tree</VAR> using new pairs and +returns it. All levels are copied, so that none of the pairs in the +tree are <CODE>eq?</CODE> to the original ones -- only the leaves are. +</P> +<P> + +Example: +<TABLE><tr><td> </td><td class=example><pre>(define bar '(bar)) +(copy-tree (list bar 'foo)) + => ((bar) foo) +(eq? bar (car (copy-tree (list bar 'foo)))) + => #f +</pre></td></tr></table></DL> +<P> + +<A NAME="Chapter Ordering"></A> +<HR SIZE="6"> +<A NAME="SEC215"></A> +<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0> +<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC214"> < </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC216"> > </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC183"> << </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC207"> Up </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_8.html#SEC277"> >> </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib.html#SEC_Top">Top</A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_toc.html#SEC_Contents">Contents</A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_abt.html#SEC_About"> ? </A>]</TD> +</TR></TABLE> +<H3> 7.2.3 Chapter Ordering </H3> +<!--docid::SEC215::--> +<P> + +<CODE>(require 'chapter-order)</CODE> +<A NAME="IDX1330"></A> +</P> +<P> + +The `<SAMP>chap:</SAMP>' functions deal with strings which are ordered like +chapter numbers (or letters) in a book. Each section of the string +consists of consecutive numeric or consecutive aphabetic characters of +like case. +</P> +<P> + +<A NAME="IDX1331"></A> +</P> +<DL> +<DT><U>Function:</U> <B>chap:string<?</B> <I>string1 string2</I> +<DD><P> + +Returns #t if the first non-matching run of alphabetic upper-case or +the first non-matching run of alphabetic lower-case or the first +non-matching run of numeric characters of <VAR>string1</VAR> is +<CODE>string<?</CODE> than the corresponding non-matching run of +characters of <VAR>string2</VAR>. +</P> +<P> + +<TABLE><tr><td> </td><td class=example><pre>(chap:string<? "a.9" "a.10") => #t +(chap:string<? "4c" "4aa") => #t +(chap:string<? "Revised^{3.99}" "Revised^{4}") => #t +</pre></td></tr></table></DL> +<P> + +<A NAME="IDX1332"></A> +</P> +<DL> +<DT><U>Function:</U> <B>chap:string>?</B> <I>string1 string2</I> +<DD><A NAME="IDX1333"></A> +<DT><U>Function:</U> <B>chap:string<=?</B> <I>string1 string2</I> +<DD><A NAME="IDX1334"></A> +<DT><U>Function:</U> <B>chap:string>=?</B> <I>string1 string2</I> +<DD><P> + +Implement the corresponding chapter-order predicates. +</P> +</DL> +<P> + +<A NAME="IDX1335"></A> +</P> +<DL> +<DT><U>Function:</U> <B>chap:next-string</B> <I>string</I> +<DD><P> + +Returns the next string in the <EM>chapter order</EM>. If <VAR>string</VAR> +has no alphabetic or numeric characters, +<CODE>(string-append <VAR>string</VAR> "0")</CODE> is returnd. The argument to +chap:next-string will always be <CODE>chap:string<?</CODE> than the result. +</P> +<P> + +<TABLE><tr><td> </td><td class=example><pre>(chap:next-string "a.9") => "a.10" +(chap:next-string "4c") => "4d" +(chap:next-string "4z") => "4aa" +(chap:next-string "Revised^{4}") => "Revised^{5}" + +</pre></td></tr></table></DL> +<P> + +<A NAME="Sorting"></A> +<HR SIZE="6"> +<A NAME="SEC216"></A> +<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0> +<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC215"> < </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC217"> > </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC183"> << </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC207"> Up </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_8.html#SEC277"> >> </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib.html#SEC_Top">Top</A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_toc.html#SEC_Contents">Contents</A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_abt.html#SEC_About"> ? </A>]</TD> +</TR></TABLE> +<H3> 7.2.4 Sorting </H3> +<!--docid::SEC216::--> +<P> + +<CODE>(require 'sort)</CODE> +<A NAME="IDX1336"></A> +</P> +<P> + +Many Scheme systems provide some kind of sorting functions. They do +not, however, always provide the <EM>same</EM> sorting functions, and +those that I have had the opportunity to test provided inefficient ones +(a common blunder is to use quicksort which does not perform well). +</P> +<P> + +Because <CODE>sort</CODE> and <CODE>sort!</CODE> are not in the standard, there is +very little agreement about what these functions look like. For +example, Dybvig says that Chez Scheme provides +<TABLE><tr><td> </td><td class=example><pre>(merge predicate list1 list2) +(merge! predicate list1 list2) +(sort predicate list) +(sort! predicate list) +</pre></td></tr></table>while MIT Scheme 7.1, following Common LISP, offers unstable +<TABLE><tr><td> </td><td class=example><pre>(sort list predicate) +</pre></td></tr></table>TI PC Scheme offers +<TABLE><tr><td> </td><td class=example><pre>(sort! list/vector predicate?) +</pre></td></tr></table>and Elk offers +<TABLE><tr><td> </td><td class=example><pre>(sort list/vector predicate?) +(sort! list/vector predicate?) +</pre></td></tr></table><P> + +Here is a comprehensive catalogue of the variations I have found. +</P> +<P> + +<OL> +<LI> +Both <CODE>sort</CODE> and <CODE>sort!</CODE> may be provided. +<LI> +<CODE>sort</CODE> may be provided without <CODE>sort!</CODE>. +<LI> +<CODE>sort!</CODE> may be provided without <CODE>sort</CODE>. +<LI> +Neither may be provided. +<LI> +The sequence argument may be either a list or a vector. +<LI> +The sequence argument may only be a list. +<LI> +The sequence argument may only be a vector. +<LI> +The comparison function may be expected to behave like <CODE><</CODE>. +<LI> +The comparison function may be expected to behave like <CODE><=</CODE>. +<LI> +The interface may be <CODE>(sort predicate? sequence)</CODE>. +<LI> +The interface may be <CODE>(sort sequence predicate?)</CODE>. +<LI> +The interface may be <CODE>(sort sequence &optional (predicate? <))</CODE>. +<LI> +The sort may be stable. +<LI> +The sort may be unstable. +</OL> +<P> + +All of this variation really does not help anybody. A nice simple merge +sort is both stable and fast (quite a lot faster than <EM>quick</EM> sort). +</P> +<P> + +I am providing this source code with no restrictions at all on its use +(but please retain D.H.D.Warren's credit for the original idea). You +may have to rename some of these functions in order to use them in a +system which already provides incompatible or inferior sorts. For each +of the functions, only the top-level define needs to be edited to do +that. +</P> +<P> + +I could have given these functions names which would not clash with any +Scheme that I know of, but I would like to encourage implementors to +converge on a single interface, and this may serve as a hint. The +argument order for all functions has been chosen to be as close to +Common LISP as made sense, in order to avoid NIH-itis. +</P> +<P> + +Each of the five functions has a required <EM>last</EM> parameter which is +a comparison function. A comparison function <CODE>f</CODE> is a function of +2 arguments which acts like <CODE><</CODE>. For example, +</P> +<P> + +<TABLE><tr><td> </td><td class=example><pre>(not (f x x)) +(and (f x y) (f y z)) == (f x z) +</pre></td></tr></table><P> + +The standard functions <CODE><</CODE>, <CODE>></CODE>, <CODE>char<?</CODE>, <CODE>char>?</CODE>, +<CODE>char-ci<?</CODE>, <CODE>char-ci>?</CODE>, <CODE>string<?</CODE>, <CODE>string>?</CODE>, +<CODE>string-ci<?</CODE>, and <CODE>string-ci>?</CODE> are suitable for use as +comparison functions. Think of <CODE>(less? x y)</CODE> as saying when +<CODE>x</CODE> must <EM>not</EM> precede <CODE>y</CODE>. +</P> +<P> + +<A NAME="IDX1337"></A> +</P> +<DL> +<DT><U>Function:</U> <B>sorted?</B> <I>sequence less?</I> +<DD>Returns <CODE>#t</CODE> when the sequence argument is in non-decreasing order +according to <VAR>less?</VAR> (that is, there is no adjacent pair <CODE><small>...</small> x +y <small>...</small></CODE> for which <CODE>(less? y x)</CODE>). +<P> + +Returns <CODE>#f</CODE> when the sequence contains at least one out-of-order +pair. It is an error if the sequence is not a list, vector, or +string. +</P> +</DL> +<P> + +<A NAME="IDX1338"></A> +</P> +<DL> +<DT><U>Function:</U> <B>merge</B> <I>list1 list2 less?</I> +<DD>This merges two lists, producing a completely new list as result. I +gave serious consideration to producing a Common-LISP-compatible +version. However, Common LISP's <CODE>sort</CODE> is our <CODE>sort!</CODE> (well, +in fact Common LISP's <CODE>stable-sort</CODE> is our <CODE>sort!</CODE>, merge sort +is <EM>fast</EM> as well as stable!) so adapting CL code to Scheme takes a +bit of work anyway. I did, however, appeal to CL to determine the +<EM>order</EM> of the arguments. +</DL> +<P> + +<A NAME="IDX1339"></A> +</P> +<DL> +<DT><U>Procedure:</U> <B>merge!</B> <I>list1 list2 less?</I> +<DD>Merges two lists, re-using the pairs of <VAR>list1</VAR> and <VAR>list2</VAR> to +build the result. If the code is compiled, and <VAR>less?</VAR> constructs +no new pairs, no pairs at all will be allocated. The first pair of the +result will be either the first pair of <VAR>list1</VAR> or the first pair of +<VAR>list2</VAR>, but you can't predict which. +<P> + +The code of <CODE>merge</CODE> and <CODE>merge!</CODE> could have been quite a bit +simpler, but they have been coded to reduce the amount of work done per +iteration. (For example, we only have one <CODE>null?</CODE> test per +iteration.) +</P> +<P> + +</P> +</DL> +<P> + +<A NAME="IDX1340"></A> +</P> +<DL> +<DT><U>Function:</U> <B>sort</B> <I>sequence less?</I> +<DD>Accepts either a list, vector, or string; and returns a new sequence +which is sorted. The new sequence is the same type as the input. +Always <CODE>(sorted? (sort sequence less?) less?)</CODE>. The original +sequence is not altered in any way. The new sequence shares its +<EM>elements</EM> with the old one; no elements are copied. +</DL> +<P> + +<A NAME="IDX1341"></A> +</P> +<DL> +<DT><U>Procedure:</U> <B>sort!</B> <I>sequence less?</I> +<DD>Returns its sorted result in the original boxes. If the original +sequence is a list, no new storage is allocated at all. If the +original sequence is a vector or string, the sorted elements are put +back in the same vector or string. +<P> + +Some people have been confused about how to use <CODE>sort!</CODE>, thinking +that it doesn't return a value. It needs to be pointed out that +<TABLE><tr><td> </td><td class=example><pre>(set! slist (sort! slist <)) +</pre></td></tr></table>is the proper usage, not +<TABLE><tr><td> </td><td class=example><pre>(sort! slist <) +</pre></td></tr></table></DL> +<P> + +Note that these functions do <EM>not</EM> accept a CL-style `<SAMP>:key</SAMP>' +argument. A simple device for obtaining the same expressiveness is to +define +</P> +<P> + +<TABLE><tr><td> </td><td class=example><pre>(define (keyed less? key) + (lambda (x y) (less? (key x) (key y)))) +</pre></td></tr></table>and then, when you would have written +<TABLE><tr><td> </td><td class=example><pre>(sort a-sequence #'my-less :key #'my-key) +</pre></td></tr></table>in Common LISP, just write +<TABLE><tr><td> </td><td class=example><pre>(sort! a-sequence (keyed my-less? my-key)) +</pre></td></tr></table>in Scheme. +<P> + +<A NAME="Topological Sort"></A> +<HR SIZE="6"> +<A NAME="SEC217"></A> +<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0> +<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC216"> < </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC218"> > </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC183"> << </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC207"> Up </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_8.html#SEC277"> >> </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib.html#SEC_Top">Top</A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_toc.html#SEC_Contents">Contents</A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_abt.html#SEC_About"> ? </A>]</TD> +</TR></TABLE> +<H3> 7.2.5 Topological Sort </H3> +<!--docid::SEC217::--> +<P> + +<CODE>(require 'topological-sort)</CODE> or <CODE>(require 'tsort)</CODE> +<A NAME="IDX1342"></A> +<A NAME="IDX1343"></A> +</P> +<P> + +The algorithm is inspired by Cormen, Leiserson and Rivest (1990) +<CITE>Introduction to Algorithms</CITE>, chapter 23. +</P> +<P> + +<A NAME="IDX1344"></A> +</P> +<DL> +<DT><U>Function:</U> <B>tsort</B> <I>dag pred</I> +<DD><P> + +<A NAME="IDX1345"></A> +<DT><U>Function:</U> <B>topological-sort</B> <I>dag pred</I> +<DD>where +</P> +<DL COMPACT> +<DT><VAR>dag</VAR> +<DD>is a list of sublists. The car of each sublist is a vertex. The cdr is +the adjacency list of that vertex, i.e. a list of all vertices to which +there exists an edge from the car vertex. +<DT><VAR>pred</VAR> +<DD>is one of <CODE>eq?</CODE>, <CODE>eqv?</CODE>, <CODE>equal?</CODE>, <CODE>=</CODE>, +<CODE>char=?</CODE>, <CODE>char-ci=?</CODE>, <CODE>string=?</CODE>, or <CODE>string-ci=?</CODE>. +</DL> +<P> + +Sort the directed acyclic graph <VAR>dag</VAR> so that for every edge from +vertex <VAR>u</VAR> to <VAR>v</VAR>, <VAR>u</VAR> will come before <VAR>v</VAR> in the +resulting list of vertices. +</P> +<P> + +Time complexity: O (|V| + |E|) +</P> +<P> + +Example (from Cormen): +<BLOCKQUOTE> +Prof. Bumstead topologically sorts his clothing when getting +dressed. The first argument to <CODE>tsort</CODE> describes which +garments he needs to put on before others. (For example, +Prof Bumstead needs to put on his shirt before he puts on his +tie or his belt.) <CODE>tsort</CODE> gives the correct order of dressing: +</BLOCKQUOTE> +<P> + +<TABLE><tr><td> </td><td class=example><pre>(require 'tsort) +<A NAME="IDX1346"></A>(tsort '((shirt tie belt) + (tie jacket) + (belt jacket) + (watch) + (pants shoes belt) + (undershorts pants shoes) + (socks shoes)) + eq?) +=> +(socks undershorts pants shoes watch shirt belt tie jacket) +</pre></td></tr></table></DL> +<P> + +<A NAME="Hashing"></A> +<HR SIZE="6"> +<A NAME="SEC218"></A> +<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0> +<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC217"> < </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC219"> > </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC183"> << </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC207"> Up </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_8.html#SEC277"> >> </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib.html#SEC_Top">Top</A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_toc.html#SEC_Contents">Contents</A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_abt.html#SEC_About"> ? </A>]</TD> +</TR></TABLE> +<H3> 7.2.6 Hashing </H3> +<!--docid::SEC218::--> +<P> + +<CODE>(require 'hash)</CODE> +<A NAME="IDX1347"></A> +</P> +<P> + +These hashing functions are for use in quickly classifying objects. +Hash tables use these functions. +</P> +<P> + +<A NAME="IDX1348"></A> +</P> +<DL> +<DT><U>Function:</U> <B>hashq</B> <I>obj k</I> +<DD><A NAME="IDX1349"></A> +<DT><U>Function:</U> <B>hashv</B> <I>obj k</I> +<DD><A NAME="IDX1350"></A> +<DT><U>Function:</U> <B>hash</B> <I>obj k</I> +<DD>Returns an exact non-negative integer less than <VAR>k</VAR>. For each +non-negative integer less than <VAR>k</VAR> there are arguments <VAR>obj</VAR> for +which the hashing functions applied to <VAR>obj</VAR> and <VAR>k</VAR> returns +that integer. +<P> + +For <CODE>hashq</CODE>, <CODE>(eq? obj1 obj2)</CODE> implies <CODE>(= (hashq obj1 k) +(hashq obj2))</CODE>. +</P> +<P> + +For <CODE>hashv</CODE>, <CODE>(eqv? obj1 obj2)</CODE> implies <CODE>(= (hashv obj1 k) +(hashv obj2))</CODE>. +</P> +<P> + +For <CODE>hash</CODE>, <CODE>(equal? obj1 obj2)</CODE> implies <CODE>(= (hash obj1 k) +(hash obj2))</CODE>. +</P> +<P> + +<CODE>hash</CODE>, <CODE>hashv</CODE>, and <CODE>hashq</CODE> return in time bounded by a +constant. Notice that items having the same <CODE>hash</CODE> implies the +items have the same <CODE>hashv</CODE> implies the items have the same +<CODE>hashq</CODE>. +</P> +</DL> +<P> + +<A NAME="Space-Filling Curves"></A> +<HR SIZE="6"> +<A NAME="SEC219"></A> +<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0> +<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC218"> < </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC220"> > </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC183"> << </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC207"> Up </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_8.html#SEC277"> >> </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib.html#SEC_Top">Top</A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_toc.html#SEC_Contents">Contents</A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_abt.html#SEC_About"> ? </A>]</TD> +</TR></TABLE> +<H3> 7.2.7 Space-Filling Curves </H3> +<!--docid::SEC219::--> +<P> + +<TABLE BORDER="0" CELLSPACING="0"> +<TR><TD ALIGN="left" VALIGN="TOP"><A HREF="slib_7.html#SEC220">7.2.7.1 Peano-Hilbert Space-Filling Curve</A></TD><TD> </TD><TD ALIGN="left" VALIGN="TOP"></TD></TR> +<TR><TD ALIGN="left" VALIGN="TOP"><A HREF="slib_7.html#SEC221">7.2.7.2 Sierpinski Curve</A></TD><TD> </TD><TD ALIGN="left" VALIGN="TOP"></TD></TR> +</TABLE> +<P> + +<A NAME="Peano-Hilbert Space-Filling Curve"></A> +<HR SIZE="6"> +<A NAME="SEC220"></A> +<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0> +<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC219"> < </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC221"> > </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC183"> << </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC219"> Up </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_8.html#SEC277"> >> </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib.html#SEC_Top">Top</A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_toc.html#SEC_Contents">Contents</A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_abt.html#SEC_About"> ? </A>]</TD> +</TR></TABLE> +<H4> 7.2.7.1 Peano-Hilbert Space-Filling Curve </H4> +<!--docid::SEC220::--> +<P> + +<CODE>(require 'hilbert-fill)</CODE> +<A NAME="IDX1351"></A> +</P> +<P> + +<A NAME="IDX1352"></A> +<A NAME="IDX1353"></A> +<A NAME="IDX1354"></A> +The <EM>Peano-Hilbert Space-Filling Curve</EM> is a one-to-one mapping +<A NAME="IDX1355"></A> +between a unit line segment and an <VAR>n</VAR>-dimensional unit cube. +</P> +<P> + +The integer procedures map the non-negative integers to an +arbitrarily large <VAR>n</VAR>-dimensional cube with its corner at the +origin and all coordinates are non-negative. +</P> +<P> + +For any exact nonnegative integers <VAR>scalar</VAR> and <VAR>rank</VAR>, +</P> +<P> + +<TABLE><tr><td> </td><td class=example><pre>(= <VAR>scalar</VAR> (hilbert-coordinates->integer + (integer->hilbert-coordinates <VAR>scalar</VAR> <VAR>rank</VAR>))) + => #t +</pre></td></tr></table><P> + +<A NAME="IDX1356"></A> +</P> +<DL> +<DT><U>Function:</U> <B>integer->hilbert-coordinates</B> <I>scalar rank</I> +<DD><P> + +Returns a list of <VAR>rank</VAR> integer coordinates corresponding to exact +non-negative integer <VAR>scalar</VAR>. The lists returned by <CODE>integer->hilbert-coordinates</CODE> for <VAR>scalar</VAR> arguments +0 and 1 will differ in the first element. +</P> +</DL> +<P> + +<A NAME="IDX1357"></A> +</P> +<DL> +<DT><U>Function:</U> <B>hilbert-coordinates->integer</B> <I>coords</I> +<DD><P> + +Returns an exact non-negative integer corresponding to <VAR>coords</VAR>, a list +of non-negative integer coordinates. +</P> +</DL> +<P> + +<A NAME="Sierpinski Curve"></A> +<HR SIZE="6"> +<A NAME="SEC221"></A> +<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0> +<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC220"> < </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC222"> > </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC183"> << </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC219"> Up </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_8.html#SEC277"> >> </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib.html#SEC_Top">Top</A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_toc.html#SEC_Contents">Contents</A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_abt.html#SEC_About"> ? </A>]</TD> +</TR></TABLE> +<H4> 7.2.7.2 Sierpinski Curve </H4> +<!--docid::SEC221::--> +<P> + +<CODE>(require 'sierpinski)</CODE> +<A NAME="IDX1358"></A> +</P> +<P> + +<A NAME="IDX1359"></A> +</P> +<DL> +<DT><U>Function:</U> <B>make-sierpinski-indexer</B> <I>max-coordinate</I> +<DD>Returns a procedure (eg hash-function) of 2 numeric arguments which +preserves <EM>nearness</EM> in its mapping from NxN to N. +<P> + +<VAR>max-coordinate</VAR> is the maximum coordinate (a positive integer) of a +population of points. The returned procedures is a function that takes +the x and y coordinates of a point, (non-negative integers) and returns +an integer corresponding to the relative position of that point along a +Sierpinski curve. (You can think of this as computing a (pseudo-) +inverse of the Sierpinski spacefilling curve.) +</P> +<P> + +Example use: Make an indexer (hash-function) for integer points lying in +square of integer grid points [0,99]x[0,99]: +<TABLE><tr><td> </td><td class=example><pre>(define space-key (make-sierpinski-indexer 100)) +</pre></td></tr></table>Now let's compute the index of some points: +<TABLE><tr><td> </td><td class=example><pre>(space-key 24 78) => 9206 +(space-key 23 80) => 9172 +</pre></td></tr></table><P> + +Note that locations (24, 78) and (23, 80) are near in index and +therefore, because the Sierpinski spacefilling curve is continuous, we +know they must also be near in the plane. Nearness in the plane does +not, however, necessarily correspond to nearness in index, although it +<EM>tends</EM> to be so. +</P> +<P> + +Example applications: +<UL> + +<LI> +Sort points by Sierpinski index to get heuristic solution to +<EM>travelling salesman problem</EM>. For details of performance, +see L. Platzman and J. Bartholdi, "Spacefilling curves and the +Euclidean travelling salesman problem", JACM 36(4):719--737 +(October 1989) and references therein. +<P> + +</P> +<LI> +Use Sierpinski index as key by which to store 2-dimensional data +in a 1-dimensional data structure (such as a table). Then +locations that are near each other in 2-d space will tend to +be near each other in 1-d data structure; and locations that +are near in 1-d data structure will be near in 2-d space. This +can significantly speed retrieval from secondary storage because +contiguous regions in the plane will tend to correspond to +contiguous regions in secondary storage. (This is a standard +technique for managing CAD/CAM or geographic data.) +<P> + +</UL> +</DL> +<P> + +<A NAME="Soundex"></A> +<HR SIZE="6"> +<A NAME="SEC222"></A> +<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0> +<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC221"> < </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC223"> > </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC183"> << </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC207"> Up </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_8.html#SEC277"> >> </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib.html#SEC_Top">Top</A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_toc.html#SEC_Contents">Contents</A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_abt.html#SEC_About"> ? </A>]</TD> +</TR></TABLE> +<H3> 7.2.8 Soundex </H3> +<!--docid::SEC222::--> +<P> + +<CODE>(require 'soundex)</CODE> +<A NAME="IDX1360"></A> +</P> +<P> + +<A NAME="IDX1361"></A> +</P> +<DL> +<DT><U>Function:</U> <B>soundex</B> <I>name</I> +<DD>Computes the <EM>soundex</EM> hash of <VAR>name</VAR>. Returns a string of an +initial letter and up to three digits between 0 and 6. Soundex +supposedly has the property that names that sound similar in normal +English pronunciation tend to map to the same key. +<P> + +Soundex was a classic algorithm used for manual filing of personal +records before the advent of computers. It performs adequately for +English names but has trouble with other languages. +</P> +<P> + +See Knuth, Vol. 3 <CITE>Sorting and searching</CITE>, pp 391--2 +</P> +<P> + +To manage unusual inputs, <CODE>soundex</CODE> omits all non-alphabetic +characters. Consequently, in this implementation: +</P> +<P> + +<TABLE><tr><td> </td><td class=example><pre>(soundex <string of blanks>) => "" +(soundex "") => "" +</pre></td></tr></table><P> + +Examples from Knuth: +</P> +<P> + +<TABLE><tr><td> </td><td class=example><pre>(map soundex '("Euler" "Gauss" "Hilbert" "Knuth" + "Lloyd" "Lukasiewicz")) + => ("E460" "G200" "H416" "K530" "L300" "L222") + +(map soundex '("Ellery" "Ghosh" "Heilbronn" "Kant" + "Ladd" "Lissajous")) + => ("E460" "G200" "H416" "K530" "L300" "L222") +</pre></td></tr></table><P> + +Some cases in which the algorithm fails (Knuth): +</P> +<P> + +<TABLE><tr><td> </td><td class=example><pre>(map soundex '("Rogers" "Rodgers")) => ("R262" "R326") + +(map soundex '("Sinclair" "St. Clair")) => ("S524" "S324") + +(map soundex '("Tchebysheff" "Chebyshev")) => ("T212" "C121") +</pre></td></tr></table></DL> +<P> + +<A NAME="String Search"></A> +<HR SIZE="6"> +<A NAME="SEC223"></A> +<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0> +<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC222"> < </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC224"> > </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC183"> << </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC207"> Up </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_8.html#SEC277"> >> </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib.html#SEC_Top">Top</A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_toc.html#SEC_Contents">Contents</A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_abt.html#SEC_About"> ? </A>]</TD> +</TR></TABLE> +<H3> 7.2.9 String Search </H3> +<!--docid::SEC223::--> +<P> + +<CODE>(require 'string-search)</CODE> +<A NAME="IDX1362"></A> +</P> +<P> + +<A NAME="IDX1363"></A> +</P> +<DL> +<DT><U>Procedure:</U> <B>string-index</B> <I>string char</I> +<DD><A NAME="IDX1364"></A> +<DT><U>Procedure:</U> <B>string-index-ci</B> <I>string char</I> +<DD>Returns the index of the first occurence of <VAR>char</VAR> within +<VAR>string</VAR>, or <CODE>#f</CODE> if the <VAR>string</VAR> does not contain a +character <VAR>char</VAR>. +</DL> +<P> + +<A NAME="IDX1365"></A> +</P> +<DL> +<DT><U>Procedure:</U> <B>string-reverse-index</B> <I>string char</I> +<DD><A NAME="IDX1366"></A> +<DT><U>Procedure:</U> <B>string-reverse-index-ci</B> <I>string char</I> +<DD>Returns the index of the last occurence of <VAR>char</VAR> within +<VAR>string</VAR>, or <CODE>#f</CODE> if the <VAR>string</VAR> does not contain a +character <VAR>char</VAR>. +</DL> +<P> + +<A NAME="IDX1367"></A> +</P> +<DL> +<DT><U>Procedure:</U> <B>substring?</B> <I>pattern string</I> +<DD><A NAME="IDX1368"></A> +<DT><U>Procedure:</U> <B>substring-ci?</B> <I>pattern string</I> +<DD>Searches <VAR>string</VAR> to see if some substring of <VAR>string</VAR> is equal +to <VAR>pattern</VAR>. <CODE>substring?</CODE> returns the index of the first +character of the first substring of <VAR>string</VAR> that is equal to +<VAR>pattern</VAR>; or <CODE>#f</CODE> if <VAR>string</VAR> does not contain +<VAR>pattern</VAR>. +<P> + +<TABLE><tr><td> </td><td class=example><pre>(substring? "rat" "pirate") => 2 +(substring? "rat" "outrage") => #f +(substring? "" any-string) => 0 +</pre></td></tr></table></DL> +<P> + +<A NAME="IDX1369"></A> +</P> +<DL> +<DT><U>Procedure:</U> <B>find-string-from-port?</B> <I>str in-port max-no-chars</I> +<DD>Looks for a string <VAR>str</VAR> within the first <VAR>max-no-chars</VAR> chars +of the input port <VAR>in-port</VAR>. +<P> + +<A NAME="IDX1370"></A> +<DT><U>Procedure:</U> <B>find-string-from-port?</B> <I>str in-port</I> +<DD>When called with two arguments, the search span is limited by the end of +the input stream. +</P> +<P> + +<A NAME="IDX1371"></A> +<DT><U>Procedure:</U> <B>find-string-from-port?</B> <I>str in-port char</I> +<DD>Searches up to the first occurrence of character <VAR>char</VAR> in +<VAR>str</VAR>. +</P> +<P> + +<A NAME="IDX1372"></A> +<DT><U>Procedure:</U> <B>find-string-from-port?</B> <I>str in-port proc</I> +<DD>Searches up to the first occurrence of the procedure <VAR>proc</VAR> +returning non-false when called with a character (from <VAR>in-port</VAR>) +argument. +</P> +<P> + +When the <VAR>str</VAR> is found, <CODE>find-string-from-port?</CODE> returns the +number of characters it has read from the port, and the port is set to +read the first char after that (that is, after the <VAR>str</VAR>) The +function returns <CODE>#f</CODE> when the <VAR>str</VAR> isn't found. +</P> +<P> + +<CODE>find-string-from-port?</CODE> reads the port <EM>strictly</EM> +sequentially, and does not perform any buffering. So +<CODE>find-string-from-port?</CODE> can be used even if the <VAR>in-port</VAR> is +open to a pipe or other communication channel. +</P> +</DL> +<P> + +<A NAME="IDX1373"></A> +</P> +<DL> +<DT><U>Function:</U> <B>string-subst</B> <I>txt old1 new1 <small>...</small></I> +<DD>Returns a copy of string <VAR>txt</VAR> with all occurrences of string +<VAR>old1</VAR> in <VAR>txt</VAR> replaced with <VAR>new1</VAR>; then <VAR>old2</VAR> +replaced with <VAR>new2</VAR> <small>...</small>. Matches are found from the left. +Matches do not overlap. +</DL> +<P> + +<A NAME="IDX1374"></A> +</P> +<DL> +<DT><U>Function:</U> <B>count-newlines</B> <I>str</I> +<DD>Returns the number of `<SAMP>#\newline</SAMP>' characters in string <VAR>str</VAR>. +</DL> +<P> + +<A NAME="Sequence Comparison"></A> +<HR SIZE="6"> +<A NAME="SEC224"></A> +<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0> +<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC223"> < </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC225"> > </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC183"> << </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC207"> Up </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_8.html#SEC277"> >> </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib.html#SEC_Top">Top</A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_toc.html#SEC_Contents">Contents</A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_abt.html#SEC_About"> ? </A>]</TD> +</TR></TABLE> +<H3> 7.2.10 Sequence Comparison </H3> +<!--docid::SEC224::--> +<P> + +<CODE>(require 'diff)</CODE> +<A NAME="IDX1375"></A> +<A NAME="IDX1376"></A> +</P> +<P> + +<CODE>diff:edit-length</CODE> implements the algorithm: +</P> +<P> + +<TABLE><tr><td> </td><td class=example><pre>S. Wu, E. Myers, U. Manber, and W. Miller, + "An O(NP) Sequence Comparison Algorithm," + Information Processing Letters 35, 6 (1990), 317-323. + <A HREF="http://www.cs.arizona.edu/people/gene/vita.html">http://www.cs.arizona.edu/people/gene/vita.html</A> +</pre></td></tr></table>S. Wu, <A HREF="http://www.cs.arizona.edu/people/gene/vita.html"> +E. Myers,</A> U. Manber, and W. Miller, +<A HREF="http://www.cs.arizona.edu/people/gene/PAPERS/np_diff.ps"> +"An O(NP) Sequence Comparison Algorithm,"</A> +Information Processing Letters 35, 6 (1990), 317-323. +<P> + +The values returned by <CODE>diff:edit-length</CODE> can be used to gauge +the degree of match between two sequences. +</P> +<P> + +Surprisingly, "An O(NP) Sequence Comparison Algorithm" does not +derive the edit sequence; only the sequence length. Developing this +linear-space sub-quadratic-time algorithm for computing the edit +sequence required hundreds of hours of work. I have submitted a +paper describing the algorithm to the Journal of Computational +Biology. +</P> +<P> + +If the items being sequenced are text lines, then the computed +edit-list is equivalent to the output of the <EM>diff</EM> utility +<A NAME="IDX1377"></A> +program. If the items being sequenced are words, then it is like the +lesser known <EM>spiff</EM> program. +<A NAME="IDX1378"></A> +</P> +<P> + +<A NAME="IDX1379"></A> +</P> +<DL> +<DT><U>Function:</U> <B>diff:longest-common-subsequence</B> <I>array1 array2 =? p-lim</I> +<DD><P> + +<A NAME="IDX1380"></A> +<DT><U>Function:</U> <B>diff:longest-common-subsequence</B> <I>array1 array2 =?</I> +<DD><VAR>array1</VAR> and <VAR>array2</VAR> are one-dimensional arrays. The procedure <VAR>=?</VAR> is used +to compare sequence tokens for equality. +</P> +<P> + +The non-negative integer <VAR>p-lim</VAR>, if provided, is maximum number of +deletions of the shorter sequence to allow. <CODE>diff:longest-common-subsequence</CODE> will return <CODE>#f</CODE> +if more deletions would be necessary. +</P> +<P> + +<CODE>diff:longest-common-subsequence</CODE> returns a one-dimensional array of length <CODE>(quotient (- (+ +len1 len2) (diff:edit-length <VAR>array1</VAR> <VAR>array2</VAR>)) 2)</CODE> holding the longest sequence +common to both <VAR>array</VAR>s. +</P> +</DL> +<P> + +<A NAME="IDX1381"></A> +</P> +<DL> +<DT><U>Function:</U> <B>diff:edits</B> <I>array1 array2 =? p-lim</I> +<DD><P> + +<A NAME="IDX1382"></A> +<DT><U>Function:</U> <B>diff:edits</B> <I>array1 array2 =?</I> +<DD><VAR>array1</VAR> and <VAR>array2</VAR> are one-dimensional arrays. The procedure <VAR>=?</VAR> is used +to compare sequence tokens for equality. +</P> +<P> + +The non-negative integer <VAR>p-lim</VAR>, if provided, is maximum number of +deletions of the shorter sequence to allow. <CODE>diff:edits</CODE> will return <CODE>#f</CODE> +if more deletions would be necessary. +</P> +<P> + +<CODE>diff:edits</CODE> returns a vector of length <CODE>(diff:edit-length <VAR>array1</VAR> <VAR>array2</VAR>)</CODE> composed +of a shortest sequence of edits transformaing <VAR>array1</VAR> to <VAR>array2</VAR>. +</P> +<P> + +Each edit is an integer: +</P> +<DL COMPACT> +<DT><VAR>k</VAR> > 0 +<DD>Inserts <CODE>(array-ref <VAR>array1</VAR> (+ -1 <VAR>j</VAR>))</CODE> into the sequence. +<DT><VAR>k</VAR> < 0 +<DD>Deletes <CODE>(array-ref <VAR>array2</VAR> (- -1 <VAR>k</VAR>))</CODE> from the sequence. +</DL> +</DL> +<P> + +<A NAME="IDX1383"></A> +</P> +<DL> +<DT><U>Function:</U> <B>diff:edit-length</B> <I>array1 array2 =? p-lim</I> +<DD><P> + +<A NAME="IDX1384"></A> +<DT><U>Function:</U> <B>diff:edit-length</B> <I>array1 array2 =?</I> +<DD><VAR>array1</VAR> and <VAR>array2</VAR> are one-dimensional arrays. The procedure <VAR>=?</VAR> is used +to compare sequence tokens for equality. +</P> +<P> + +The non-negative integer <VAR>p-lim</VAR>, if provided, is maximum number of +deletions of the shorter sequence to allow. <CODE>diff:edit-length</CODE> will return <CODE>#f</CODE> +if more deletions would be necessary. +</P> +<P> + +<CODE>diff:edit-length</CODE> returns the length of the shortest sequence of edits transformaing +<VAR>array1</VAR> to <VAR>array2</VAR>. +</P> +</DL> +<TABLE><tr><td> </td><td class=example><pre>(diff:longest-common-subsequence "fghiejcklm" "fgehijkpqrlm" eqv?) +=> "fghijklm" + +(diff:edit-length "fghiejcklm" "fgehijkpqrlm" eqv?) +=> 6 + +(diff:edits "fghiejcklm" "fgehijkpqrlm" eqv?) +=> #As32(3 -5 -7 8 9 10) + ; e c h p q r +</pre></td></tr></table><P> + +<A NAME="Procedures"></A> +<HR SIZE="6"> +<A NAME="SEC225"></A> +<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0> +<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC224"> < </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC226"> > </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC183"> << </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC183"> Up </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_8.html#SEC277"> >> </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib.html#SEC_Top">Top</A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_toc.html#SEC_Contents">Contents</A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_abt.html#SEC_About"> ? </A>]</TD> +</TR></TABLE> +<H2> 7.3 Procedures </H2> +<!--docid::SEC225::--> +<P> + +Anything that doesn't fall neatly into any of the other categories winds +up here. +</P> +<P> + +<TABLE BORDER="0" CELLSPACING="0"> +<TR><TD ALIGN="left" VALIGN="TOP"><A HREF="slib_7.html#SEC226">7.3.1 Type Coercion</A></TD><TD> </TD><TD ALIGN="left" VALIGN="TOP">'coerce</TD></TR> +<TR><TD ALIGN="left" VALIGN="TOP"><A HREF="slib_7.html#SEC227">7.3.2 String-Case</A></TD><TD> </TD><TD ALIGN="left" VALIGN="TOP">'string-case</TD></TR> +<TR><TD ALIGN="left" VALIGN="TOP"><A HREF="slib_7.html#SEC228">7.3.3 String Ports</A></TD><TD> </TD><TD ALIGN="left" VALIGN="TOP">'string-port</TD></TR> +<TR><TD ALIGN="left" VALIGN="TOP"><A HREF="slib_7.html#SEC229">7.3.4 Line I/O</A></TD><TD> </TD><TD ALIGN="left" VALIGN="TOP">'line-i/o</TD></TR> +<TR><TD ALIGN="left" VALIGN="TOP"><A HREF="slib_7.html#SEC230">7.3.5 Multi-Processing</A></TD><TD> </TD><TD ALIGN="left" VALIGN="TOP">'process</TD></TR> +<TR><TD ALIGN="left" VALIGN="TOP"><A HREF="slib_7.html#SEC231">7.3.6 Metric Units</A></TD><TD> </TD><TD ALIGN="left" VALIGN="TOP">Portable manifest types for numeric values.</TD></TR> +</TABLE> +<P> + +<A NAME="Type Coercion"></A> +<HR SIZE="6"> +<A NAME="SEC226"></A> +<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0> +<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC225"> < </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC227"> > </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC183"> << </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC225"> Up </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_8.html#SEC277"> >> </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib.html#SEC_Top">Top</A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_toc.html#SEC_Contents">Contents</A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_abt.html#SEC_About"> ? </A>]</TD> +</TR></TABLE> +<H3> 7.3.1 Type Coercion </H3> +<!--docid::SEC226::--> +<CODE>(require 'coerce)</CODE> +<A NAME="IDX1385"></A> +<P> + +<A NAME="IDX1386"></A> +</P> +<DL> +<DT><U>Function:</U> <B>type-of</B> <I>obj</I> +<DD><P> + +Returns a symbol name for the type of <VAR>obj</VAR>. +</P> +</DL> +<P> + +<A NAME="IDX1387"></A> +</P> +<DL> +<DT><U>Function:</U> <B>coerce</B> <I>obj result-type</I> +<DD><P> + +Converts and returns <VAR>obj</VAR> of type <CODE>char</CODE>, <CODE>number</CODE>, +<CODE>string</CODE>, <CODE>symbol</CODE>, <CODE>list</CODE>, or <CODE>vector</CODE> to +<VAR>result-type</VAR> (which must be one of these symbols). +</P> +</DL> +<P> + +<A NAME="String-Case"></A> +<HR SIZE="6"> +<A NAME="SEC227"></A> +<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0> +<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC226"> < </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC228"> > </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC183"> << </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC225"> Up </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_8.html#SEC277"> >> </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib.html#SEC_Top">Top</A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_toc.html#SEC_Contents">Contents</A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_abt.html#SEC_About"> ? </A>]</TD> +</TR></TABLE> +<H3> 7.3.2 String-Case </H3> +<!--docid::SEC227::--> +<P> + +<CODE>(require 'string-case)</CODE> +<A NAME="IDX1388"></A> +</P> +<P> + +<A NAME="IDX1389"></A> +</P> +<DL> +<DT><U>Procedure:</U> <B>string-upcase</B> <I>str</I> +<DD><A NAME="IDX1390"></A> +<DT><U>Procedure:</U> <B>string-downcase</B> <I>str</I> +<DD><A NAME="IDX1391"></A> +<DT><U>Procedure:</U> <B>string-capitalize</B> <I>str</I> +<DD>The obvious string conversion routines. These are non-destructive. +</DL> +<P> + +<A NAME="IDX1392"></A> +</P> +<DL> +<DT><U>Function:</U> <B>string-upcase!</B> <I>str</I> +<DD><A NAME="IDX1393"></A> +<DT><U>Function:</U> <B>string-downcase!</B> <I>str</I> +<DD><A NAME="IDX1394"></A> +<DT><U>Function:</U> <B>string-capitalize!</B> <I>str</I> +<DD>The destructive versions of the functions above. +</DL> +<P> + +<A NAME="IDX1395"></A> +</P> +<DL> +<DT><U>Function:</U> <B>string-ci->symbol</B> <I>str</I> +<DD>Converts string <VAR>str</VAR> to a symbol having the same case as if the +symbol had been <CODE>read</CODE>. +</DL> +<P> + +<A NAME="IDX1396"></A> +</P> +<DL> +<DT><U>Function:</U> <B>symbol-append</B> <I>obj1 <small>...</small></I> +<DD>Converts <VAR>obj1</VAR> <small>...</small> to strings, appends them, and converts to a +symbol which is returned. Strings and numbers are converted to read's +symbol case; the case of symbol characters is not changed. #f is +converted to the empty string (symbol). +</DL> +<P> + +<A NAME="IDX1397"></A> +</P> +<DL> +<DT><U>Function:</U> <B>StudlyCapsExpand</B> <I>str delimiter</I> +<DD><A NAME="IDX1398"></A> +<DT><U>Function:</U> <B>StudlyCapsExpand</B> <I>str</I> +<DD><VAR>delimiter</VAR> must be a string or character. If absent, +<VAR>delimiter</VAR> defaults to `<SAMP>-</SAMP>'. <CODE>StudlyCapsExpand</CODE> returns a +copy of <VAR>str</VAR> where <VAR>delimiter</VAR> is inserted between each +lower-case character immediately followed by an upper-case character; +and between two upper-case characters immediately followed by a +lower-case character. +<P> + +<TABLE><tr><td> </td><td class=example><pre>(StudlyCapsExpand "aX" " ") => "a X" +(StudlyCapsExpand "aX" "..") => "a..X" +(StudlyCapsExpand "AX") => "AX" +(StudlyCapsExpand "Ax") => "Ax" +(StudlyCapsExpand "AXLE") => "AXLE" +(StudlyCapsExpand "aAXACz") => "a-AXA-Cz" +(StudlyCapsExpand "AaXACz") => "Aa-XA-Cz" +(StudlyCapsExpand "AAaXACz") => "A-Aa-XA-Cz" +(StudlyCapsExpand "AAaXAC") => "A-Aa-XAC" +</pre></td></tr></table><P> + +</P> +</DL> +<P> + +<A NAME="String Ports"></A> +<HR SIZE="6"> +<A NAME="SEC228"></A> +<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0> +<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC227"> < </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC229"> > </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC183"> << </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC225"> Up </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_8.html#SEC277"> >> </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib.html#SEC_Top">Top</A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_toc.html#SEC_Contents">Contents</A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_abt.html#SEC_About"> ? </A>]</TD> +</TR></TABLE> +<H3> 7.3.3 String Ports </H3> +<!--docid::SEC228::--> +<P> + +<CODE>(require 'string-port)</CODE> +<A NAME="IDX1399"></A> +</P> +<P> + +<A NAME="IDX1400"></A> +</P> +<DL> +<DT><U>Procedure:</U> <B>call-with-output-string</B> <I>proc</I> +<DD><VAR>proc</VAR> must be a procedure of one argument. This procedure calls +<VAR>proc</VAR> with one argument: a (newly created) output port. When the +function returns, the string composed of the characters written into the +port is returned. +</DL> +<P> + +<A NAME="IDX1401"></A> +</P> +<DL> +<DT><U>Procedure:</U> <B>call-with-input-string</B> <I>string proc</I> +<DD><VAR>proc</VAR> must be a procedure of one argument. This procedure calls +<VAR>proc</VAR> with one argument: an (newly created) input port from which +<VAR>string</VAR>'s contents may be read. When <VAR>proc</VAR> returns, the port +is closed and the value yielded by the procedure <VAR>proc</VAR> is +returned. +</DL> +<P> + +<A NAME="Line I/O"></A> +<HR SIZE="6"> +<A NAME="SEC229"></A> +<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0> +<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC228"> < </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC230"> > </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC183"> << </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC225"> Up </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_8.html#SEC277"> >> </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib.html#SEC_Top">Top</A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_toc.html#SEC_Contents">Contents</A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_abt.html#SEC_About"> ? </A>]</TD> +</TR></TABLE> +<H3> 7.3.4 Line I/O </H3> +<!--docid::SEC229::--> +<P> + +<CODE>(require 'line-i/o)</CODE> +<A NAME="IDX1402"></A> +</P> +<P> + +<A NAME="IDX1403"></A> +</P> +<DL> +<DT><U>Function:</U> <B>read-line</B> +<DD><P> + +<A NAME="IDX1404"></A> +<DT><U>Function:</U> <B>read-line</B> <I>port</I> +<DD>Returns a string of the characters up to, but not including a +newline or end of file, updating <VAR>port</VAR> to point to the +character following the newline. If no characters are available, an +end of file object is returned. The <VAR>port</VAR> argument may be +omitted, in which case it defaults to the value returned by +<CODE>current-input-port</CODE>. +</P> +</DL> +<P> + +<A NAME="IDX1405"></A> +</P> +<DL> +<DT><U>Procedure:</U> <B>read-line!</B> <I>string</I> +<DD><P> + +<A NAME="IDX1406"></A> +<DT><U>Procedure:</U> <B>read-line!</B> <I>string port</I> +<DD>Fills <VAR>string</VAR> with characters up to, but not including a newline or end +of file, updating the <VAR>port</VAR> to point to the last character read +or following the newline if it was read. If no characters are +available, an end of file object is returned. If a newline or end +of file was found, the number of characters read is returned. +Otherwise, <CODE>#f</CODE> is returned. The <VAR>port</VAR> argument may be +omitted, in which case it defaults to the value returned by +<CODE>current-input-port</CODE>. +</P> +</DL> +<P> + +<A NAME="IDX1407"></A> +</P> +<DL> +<DT><U>Function:</U> <B>write-line</B> <I>string</I> +<DD><P> + +<A NAME="IDX1408"></A> +<DT><U>Function:</U> <B>write-line</B> <I>string port</I> +<DD>Writes <VAR>string</VAR> followed by a newline to the given <VAR>port</VAR> and returns +an unspecified value. The <VAR>Port</VAR> argument may be omitted, in +which case it defaults to the value returned by +<CODE>current-input-port</CODE>. +</P> +</DL> +<P> + +<A NAME="IDX1409"></A> +</P> +<DL> +<DT><U>Function:</U> <B>system->line</B> <I>command tmp</I> +<DD><P> + +<A NAME="IDX1410"></A> +<DT><U>Function:</U> <B>system->line</B> <I>command</I> +<DD><VAR>command</VAR> must be a string. The string <VAR>tmp</VAR>, if supplied, is a path to use as +a temporary file. <CODE>system->line</CODE> calls <CODE>system</CODE> with <VAR>command</VAR> as argument, +redirecting stdout to file <VAR>tmp</VAR>. <CODE>system->line</CODE> returns a string containing the +first line of output from <VAR>tmp</VAR>. +</P> +</DL> +<P> + +<A NAME="Multi-Processing"></A> +<HR SIZE="6"> +<A NAME="SEC230"></A> +<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0> +<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC229"> < </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC231"> > </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC183"> << </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC225"> Up </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_8.html#SEC277"> >> </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib.html#SEC_Top">Top</A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_toc.html#SEC_Contents">Contents</A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_abt.html#SEC_About"> ? </A>]</TD> +</TR></TABLE> +<H3> 7.3.5 Multi-Processing </H3> +<!--docid::SEC230::--> +<P> + +<CODE>(require 'process)</CODE> +<A NAME="IDX1411"></A> +</P> +<P> + +This module implements asynchronous (non-polled) time-sliced +multi-processing in the SCM Scheme implementation using procedures +<CODE>alarm</CODE> and <CODE>alarm-interrupt</CODE>. +<A NAME="IDX1412"></A> +<A NAME="IDX1413"></A> +Until this is ported to another implementation, consider it an example +of writing schedulers in Scheme. +</P> +<P> + +<A NAME="IDX1414"></A> +</P> +<DL> +<DT><U>Procedure:</U> <B>add-process!</B> <I>proc</I> +<DD>Adds proc, which must be a procedure (or continuation) capable of +accepting accepting one argument, to the <CODE>process:queue</CODE>. The +value returned is unspecified. The argument to <VAR>proc</VAR> should be +ignored. If <VAR>proc</VAR> returns, the process is killed. +</DL> +<P> + +<A NAME="IDX1415"></A> +</P> +<DL> +<DT><U>Procedure:</U> <B>process:schedule!</B> +<DD>Saves the current process on <CODE>process:queue</CODE> and runs the next +process from <CODE>process:queue</CODE>. The value returned is +unspecified. +</DL> +<P> + +<A NAME="IDX1416"></A> +</P> +<DL> +<DT><U>Procedure:</U> <B>kill-process!</B> +<DD>Kills the current process and runs the next process from +<CODE>process:queue</CODE>. If there are no more processes on +<CODE>process:queue</CODE>, <CODE>(slib:exit)</CODE> is called (see section <A HREF="slib_2.html#SEC17">2.4 System</A>). +</DL> +<P> + +<A NAME="Metric Units"></A> +<HR SIZE="6"> +<A NAME="SEC231"></A> +<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0> +<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC230"> < </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC232"> > </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC183"> << </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC225"> Up </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_8.html#SEC277"> >> </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib.html#SEC_Top">Top</A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_toc.html#SEC_Contents">Contents</A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_abt.html#SEC_About"> ? </A>]</TD> +</TR></TABLE> +<H3> 7.3.6 Metric Units </H3> +<!--docid::SEC231::--> +<P> + +<CODE>(require 'metric-units)</CODE> +<A NAME="IDX1417"></A> +</P> +<P> + +<A HREF="http://swissnet.ai.mit.edu/~jaffer/MIXF.html">http://swissnet.ai.mit.edu/~jaffer/MIXF.html</A> +</P> +<P> + +<EM>Metric Interchange Format</EM> is a character string encoding for +numerical values and units which: +</P> +<P> + +<UL> +<LI> +is unambiguous in all locales; +<P> + +</P> +<LI> +uses only [TOG] "Portable Character Set" characters matching "Basic +Latin" characters in Plane 0 of the Universal Character Set [UCS]; +<P> + +</P> +<LI> +is transparent to [UTF-7] and [UTF-8] UCS transformation formats; +<P> + +</P> +<LI> +is human readable and writable; +<P> + +</P> +<LI> +is machine readable and writable; +<P> + +</P> +<LI> +incorporates SI prefixes and units; +<P> + +</P> +<LI> +incorporates [ISO 6093] numbers; and +<P> + +</P> +<LI> +incorporates [IEC 60027-2] binary prefixes. +</UL> +<P> + +In the expression for the value of a quantity, the unit symbol is placed +after the numerical value. A dot (PERIOD, `<SAMP>.</SAMP>') is placed between +the numerical value and the unit symbol. +</P> +<P> + +Within a compound unit, each of the base and derived symbols can +optionally have an attached SI prefix. +</P> +<P> + +Unit symbols formed from other unit symbols by multiplication are +indicated by means of a dot (PERIOD, `<SAMP>.</SAMP>') placed between them. +</P> +<P> + +Unit symbols formed from other unit symbols by division are indicated by +means of a SOLIDUS (`<SAMP>/</SAMP>') or negative exponents. The SOLIDUS must +not be repeated in the same compound unit unless contained within a +parenthesized subexpression. +</P> +<P> + +The grouping formed by a prefix symbol attached to a unit symbol +constitutes a new inseparable symbol (forming a multiple or submultiple +of the unit concerned) which can be raised to a positive or negative +power and which can be combined with other unit symbols to form compound +unit symbols. +</P> +<P> + +The grouping formed by surrounding compound unit symbols with +parentheses (`<SAMP>(</SAMP>' and `<SAMP>)</SAMP>') constitutes a new inseparable symbol +which can be raised to a positive or negative power and which can be +combined with other unit symbols to form compound unit symbols. +</P> +<P> + +Compound prefix symbols, that is, prefix symbols formed by the +juxtaposition of two or more prefix symbols, are not permitted. +</P> +<P> + +Prefix symbols are not used with the time-related unit symbols min +(minute), h (hour), d (day). No prefix symbol may be used with dB +(decibel). Only submultiple prefix symbols may be used with the unit +symbols L (liter), Np (neper), o (degree), oC (degree Celsius), rad +(radian), and sr (steradian). Submultiple prefix symbols may not be +used with the unit symbols t (metric ton), r (revolution), or Bd (baud). +</P> +<P> + +A unit exponent follows the unit, separated by a CIRCUMFLEX (`<SAMP>^</SAMP>'). +Exponents may be positive or negative. Fractional exponents must be +parenthesized. +</P> +<P> + +<HR SIZE="6"> +<A NAME="SEC232"></A> +<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0> +<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC231"> < </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC233"> > </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC183"> << </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC225"> Up </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_8.html#SEC277"> >> </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib.html#SEC_Top">Top</A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_toc.html#SEC_Contents">Contents</A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_abt.html#SEC_About"> ? </A>]</TD> +</TR></TABLE> +<H4> 7.3.6.1 SI Prefixes </H4> +<!--docid::SEC232::--> +<TABLE><tr><td> </td><td class=example><pre> Factor Name Symbol | Factor Name Symbol + ====== ==== ====== | ====== ==== ====== + 1e24 yotta Y | 1e-1 deci d + 1e21 zetta Z | 1e-2 centi c + 1e18 exa E | 1e-3 milli m + 1e15 peta P | 1e-6 micro u + 1e12 tera T | 1e-9 nano n + 1e9 giga G | 1e-12 pico p + 1e6 mega M | 1e-15 femto f + 1e3 kilo k | 1e-18 atto a + 1e2 hecto h | 1e-21 zepto z + 1e1 deka da | 1e-24 yocto y +</pre></td></tr></table><P> + +<HR SIZE="6"> +<A NAME="SEC233"></A> +<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0> +<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC232"> < </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC234"> > </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC183"> << </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC225"> Up </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_8.html#SEC277"> >> </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib.html#SEC_Top">Top</A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_toc.html#SEC_Contents">Contents</A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_abt.html#SEC_About"> ? </A>]</TD> +</TR></TABLE> +<H4> 7.3.6.2 Binary Prefixes </H4> +<!--docid::SEC233::--> +<P> + +These binary prefixes are valid only with the units B (byte) and bit. +However, decimal prefixes can also be used with bit; and decimal +multiple (not submultiple) prefixes can also be used with B (byte). +</P> +<P> + +<TABLE><tr><td> </td><td class=example><pre> Factor (power-of-2) Name Symbol + ====== ============ ==== ====== + 1.152921504606846976e18 (2^60) exbi Ei + 1.125899906842624e15 (2^50) pebi Pi + 1.099511627776e12 (2^40) tebi Ti + 1.073741824e9 (2^30) gibi Gi + 1.048576e6 (2^20) mebi Mi + 1.024e3 (2^10) kibi Ki +</pre></td></tr></table><P> + +<HR SIZE="6"> +<A NAME="SEC234"></A> +<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0> +<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC233"> < </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC235"> > </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC183"> << </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC225"> Up </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_8.html#SEC277"> >> </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib.html#SEC_Top">Top</A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_toc.html#SEC_Contents">Contents</A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_abt.html#SEC_About"> ? </A>]</TD> +</TR></TABLE> +<H4> 7.3.6.3 Unit Symbols </H4> +<!--docid::SEC234::--> +<P> + +<TABLE><tr><td> </td><td class=example><pre> Type of Quantity Name Symbol Equivalent + ================ ==== ====== ========== +time second s +time minute min = 60.s +time hour h = 60.min +time day d = 24.h +frequency hertz Hz s^-1 +signaling rate baud Bd s^-1 +length meter m +volume liter L dm^3 +plane angle radian rad +solid angle steradian sr rad^2 +plane angle revolution * r = 6.283185307179586.rad +plane angle degree * o = 2.777777777777778e-3.r +information capacity bit bit +information capacity byte, octet B = 8.bit +mass gram g +mass ton t Mg +mass unified atomic mass unit u = 1.66053873e-27.kg +amount of substance mole mol +catalytic activity katal kat mol/s +thermodynamic temperature kelvin K +centigrade temperature degree Celsius oC +luminous intensity candela cd +luminous flux lumen lm cd.sr +illuminance lux lx lm/m^2 +force newton N m.kg.s^-2 +pressure, stress pascal Pa N/m^2 +energy, work, heat joule J N.m +energy electronvolt eV = 1.602176462e-19.J +power, radiant flux watt W J/s +logarithm of power ratio neper Np +logarithm of power ratio decibel * dB = 0.1151293.Np +electric current ampere A +electric charge coulomb C s.A +electric potential, EMF volt V W/A +capacitance farad F C/V +electric resistance ohm Ohm V/A +electric conductance siemens S A/V +magnetic flux weber Wb V.s +magnetic flux density tesla T Wb/m^2 +inductance henry H Wb/A +radionuclide activity becquerel Bq s^-1 +absorbed dose energy gray Gy m^2.s^-2 +dose equivalent sievert Sv m^2.s^-2 +</pre></td></tr></table><P> + +* The formulas are: +</P> +<P> + +<UL> +<LI> +r/rad = 8 * atan(1) +<LI> +o/r = 1 / 360 +<LI> +db/Np = ln(10) / 20 +</UL> +<P> + +<A NAME="IDX1418"></A> +</P> +<DL> +<DT><U>Function:</U> <B>si:conversion-factor</B> <I>to-unit from-unit</I> +<DD>If the strings <VAR>from-unit</VAR> and <VAR>to-unit</VAR> express valid unit +expressions for quantities of the same unit-dimensions, then the value +returned by <CODE>si:conversion-factor</CODE> will be such that multiplying a +numerical value expressed in <VAR>from-unit</VAR>s by the returned conversion +factor yields the numerical value expressed in <VAR>to-unit</VAR>s. +<P> + +Otherwise, <CODE>si:conversion-factor</CODE> returns: +</P> +<P> + +</P> +<DL COMPACT> +<DT>-3 +<DD>if neither <VAR>from-unit</VAR> nor <VAR>to-unit</VAR> is a syntactically valid +unit. +<DT>-2 +<DD>if <VAR>from-unit</VAR> is not a syntactically valid unit. +<DT>-1 +<DD>if <VAR>to-unit</VAR> is not a syntactically valid unit. +<DT>0 +<DD>if linear conversion (by a factor) is not possible. +</DL> +<P> + +</P> +</DL> +<P> + +<TABLE><tr><td> </td><td class=example><pre>(si:conversion-factor "km/s" "m/s" ) => 0.001 +(si:conversion-factor "N" "m/s" ) => 0 +(si:conversion-factor "moC" "oC" ) => 1000 +(si:conversion-factor "mK" "oC" ) => 0 +(si:conversion-factor "rad" "o" ) => 0.0174533 +(si:conversion-factor "K" "o" ) => 0 +(si:conversion-factor "K" "K" ) => 1 +(si:conversion-factor "oK" "oK" ) => -3 +(si:conversion-factor "" "s/s" ) => 1 +(si:conversion-factor "km/h" "mph" ) => -2 +</pre></td></tr></table><P> + +<A NAME="Standards Support"></A> +<HR SIZE="6"> +<A NAME="SEC235"></A> +<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0> +<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC234"> < </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC236"> > </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC183"> << </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC183"> Up </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_8.html#SEC277"> >> </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib.html#SEC_Top">Top</A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_toc.html#SEC_Contents">Contents</A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_abt.html#SEC_About"> ? </A>]</TD> +</TR></TABLE> +<H2> 7.4 Standards Support </H2> +<!--docid::SEC235::--> +<P> + +<TABLE BORDER="0" CELLSPACING="0"> +<TR><TD ALIGN="left" VALIGN="TOP"><A HREF="slib_7.html#SEC236">7.4.1 RnRS</A></TD><TD> </TD><TD ALIGN="left" VALIGN="TOP">Revised Reports on Scheme</TD></TR> +<TR><TD ALIGN="left" VALIGN="TOP"><A HREF="slib_7.html#SEC237">7.4.2 With-File</A></TD><TD> </TD><TD ALIGN="left" VALIGN="TOP">'with-file</TD></TR> +<TR><TD ALIGN="left" VALIGN="TOP"><A HREF="slib_7.html#SEC238">7.4.3 Transcripts</A></TD><TD> </TD><TD ALIGN="left" VALIGN="TOP">'transcript</TD></TR> +<TR><TD ALIGN="left" VALIGN="TOP"><A HREF="slib_7.html#SEC239">7.4.4 Rev2 Procedures</A></TD><TD> </TD><TD ALIGN="left" VALIGN="TOP">'rev2-procedures</TD></TR> +<TR><TD ALIGN="left" VALIGN="TOP"><A HREF="slib_7.html#SEC240">7.4.5 Rev4 Optional Procedures</A></TD><TD> </TD><TD ALIGN="left" VALIGN="TOP">'rev4-optional-procedures</TD></TR> +<TR><TD ALIGN="left" VALIGN="TOP"><A HREF="slib_7.html#SEC241">7.4.6 Multi-argument / and -</A></TD><TD> </TD><TD ALIGN="left" VALIGN="TOP">'multiarg/and-</TD></TR> +<TR><TD ALIGN="left" VALIGN="TOP"><A HREF="slib_7.html#SEC242">7.4.7 Multi-argument Apply</A></TD><TD> </TD><TD ALIGN="left" VALIGN="TOP">'multiarg-apply</TD></TR> +<TR><TD ALIGN="left" VALIGN="TOP"><A HREF="slib_7.html#SEC243">7.4.8 Rationalize</A></TD><TD> </TD><TD ALIGN="left" VALIGN="TOP">'rationalize</TD></TR> +<TR><TD ALIGN="left" VALIGN="TOP"><A HREF="slib_7.html#SEC244">7.4.9 Promises</A></TD><TD> </TD><TD ALIGN="left" VALIGN="TOP">'delay</TD></TR> +<TR><TD ALIGN="left" VALIGN="TOP"><A HREF="slib_7.html#SEC245">7.4.10 Dynamic-Wind</A></TD><TD> </TD><TD ALIGN="left" VALIGN="TOP">'dynamic-wind</TD></TR> +<TR><TD ALIGN="left" VALIGN="TOP"><A HREF="slib_7.html#SEC246">7.4.11 Eval</A></TD><TD> </TD><TD ALIGN="left" VALIGN="TOP">'eval</TD></TR> +<TR><TD ALIGN="left" VALIGN="TOP"><A HREF="slib_7.html#SEC247">7.4.12 Values</A></TD><TD> </TD><TD ALIGN="left" VALIGN="TOP">'values</TD></TR> +<TR><TD ALIGN="left" VALIGN="TOP"><A HREF="slib_7.html#SEC248">7.4.13 SRFI</A></TD><TD> </TD><TD ALIGN="left" VALIGN="TOP">'http://srfi.schemers.org/srfi-0/srfi-0.html</TD></TR> +</TABLE> +<P> + +<A NAME="RnRS"></A> +<HR SIZE="6"> +<A NAME="SEC236"></A> +<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0> +<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC235"> < </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC237"> > </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC183"> << </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC235"> Up </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_8.html#SEC277"> >> </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib.html#SEC_Top">Top</A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_toc.html#SEC_Contents">Contents</A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_abt.html#SEC_About"> ? </A>]</TD> +</TR></TABLE> +<H3> 7.4.1 RnRS </H3> +<!--docid::SEC236::--> +<P> + +The <CODE>r2rs</CODE>, <CODE>r3rs</CODE>, <CODE>r4rs</CODE>, and <CODE>r5rs</CODE> features +attempt to provide procedures and macros to bring a Scheme +implementation to the desired version of Scheme. +</P> +<P> + +<A NAME="IDX1419"></A> +</P> +<DL> +<DT><U>Feature:</U> <B>r2rs</B> +<DD><A NAME="IDX1420"></A> +Requires features implementing procedures and optional procedures +specified by <CITE>Revised^2 Report on the Algorithmic Language Scheme</CITE>; +namely <CODE>rev3-procedures</CODE> and <CODE>rev2-procedures</CODE>. +</DL> +<P> + +<A NAME="IDX1421"></A> +</P> +<DL> +<DT><U>Feature:</U> <B>r3rs</B> +<DD><A NAME="IDX1422"></A> +Requires features implementing procedures and optional procedures +specified by <CITE>Revised^3 Report on the Algorithmic Language Scheme</CITE>; +namely <CODE>rev3-procedures</CODE>. +<P> + +<EM>Note:</EM> SLIB already mandates the <CODE>r3rs</CODE> procedures which can +be portably implemented in <CODE>r4rs</CODE> implementations. +</P> +</DL> +<P> + +<A NAME="IDX1423"></A> +</P> +<DL> +<DT><U>Feature:</U> <B>r4rs</B> +<DD><A NAME="IDX1424"></A> +Requires features implementing procedures and optional procedures +specified by <CITE>Revised^4 Report on the Algorithmic Language Scheme</CITE>; +namely <CODE>rev4-optional-procedures</CODE>. +</DL> +<P> + +<A NAME="IDX1425"></A> +</P> +<DL> +<DT><U>Feature:</U> <B>r5rs</B> +<DD><A NAME="IDX1426"></A> +Requires features implementing procedures and optional procedures +specified by <CITE>Revised^5 Report on the Algorithmic Language Scheme</CITE>; +namely <CODE>values</CODE>, <CODE>macro</CODE>, and <CODE>eval</CODE>. +</DL> +<P> + +<A NAME="With-File"></A> +<HR SIZE="6"> +<A NAME="SEC237"></A> +<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0> +<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC236"> < </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC238"> > </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC183"> << </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC235"> Up </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_8.html#SEC277"> >> </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib.html#SEC_Top">Top</A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_toc.html#SEC_Contents">Contents</A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_abt.html#SEC_About"> ? </A>]</TD> +</TR></TABLE> +<H3> 7.4.2 With-File </H3> +<!--docid::SEC237::--> +<P> + +<CODE>(require 'with-file)</CODE> +<A NAME="IDX1427"></A> +</P> +<P> + +<A NAME="IDX1428"></A> +</P> +<DL> +<DT><U>Function:</U> <B>with-input-from-file</B> <I>file thunk</I> +<DD><A NAME="IDX1429"></A> +<DT><U>Function:</U> <B>with-output-to-file</B> <I>file thunk</I> +<DD>Description found in R4RS. +</DL> +<P> + +<A NAME="Transcripts"></A> +<HR SIZE="6"> +<A NAME="SEC238"></A> +<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0> +<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC237"> < </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC239"> > </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC183"> << </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC235"> Up </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_8.html#SEC277"> >> </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib.html#SEC_Top">Top</A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_toc.html#SEC_Contents">Contents</A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_abt.html#SEC_About"> ? </A>]</TD> +</TR></TABLE> +<H3> 7.4.3 Transcripts </H3> +<!--docid::SEC238::--> +<P> + +<CODE>(require 'transcript)</CODE> +<A NAME="IDX1430"></A> +</P> +<P> + +<A NAME="IDX1431"></A> +</P> +<DL> +<DT><U>Function:</U> <B>transcript-on</B> <I>filename</I> +<DD><A NAME="IDX1432"></A> +<DT><U>Function:</U> <B>transcript-off</B> <I>filename</I> +<DD>Redefines <CODE>read-char</CODE>, <CODE>read</CODE>, <CODE>write-char</CODE>, +<CODE>write</CODE>, <CODE>display</CODE>, and <CODE>newline</CODE>. +</DL> +<P> + +<A NAME="Rev2 Procedures"></A> +<HR SIZE="6"> +<A NAME="SEC239"></A> +<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0> +<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC238"> < </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC240"> > </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC183"> << </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC235"> Up </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_8.html#SEC277"> >> </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib.html#SEC_Top">Top</A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_toc.html#SEC_Contents">Contents</A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_abt.html#SEC_About"> ? </A>]</TD> +</TR></TABLE> +<H3> 7.4.4 Rev2 Procedures </H3> +<!--docid::SEC239::--> +<P> + +<CODE>(require 'rev2-procedures)</CODE> +<A NAME="IDX1433"></A> +</P> +<P> + +The procedures below were specified in the <CITE>Revised^2 Report on +Scheme</CITE>. <STRONG>N.B.</STRONG>: The symbols <CODE>1+</CODE> and <CODE>-1+</CODE> are not +<CITE>R4RS</CITE> syntax. Scheme->C, for instance, chokes on this +module. +</P> +<P> + +<A NAME="IDX1434"></A> +</P> +<DL> +<DT><U>Procedure:</U> <B>substring-move-left!</B> <I>string1 start1 end1 string2 start2</I> +<DD><A NAME="IDX1435"></A> +<DT><U>Procedure:</U> <B>substring-move-right!</B> <I>string1 start1 end1 string2 start2</I> +<DD><VAR>string1</VAR> and <VAR>string2</VAR> must be a strings, and <VAR>start1</VAR>, +<VAR>start2</VAR> and <VAR>end1</VAR> must be exact integers satisfying +<P> + +<TABLE><tr><td> </td><td class=display><pre style="font-family: serif">0 <= <VAR>start1</VAR> <= <VAR>end1</VAR> <= (string-length <VAR>string1</VAR>) +0 <= <VAR>start2</VAR> <= <VAR>end1</VAR> - <VAR>start1</VAR> + <VAR>start2</VAR> <= (string-length <VAR>string2</VAR>) +</pre></td></tr></table><P> + +<CODE>substring-move-left!</CODE> and <CODE>substring-move-right!</CODE> store +characters of <VAR>string1</VAR> beginning with index <VAR>start1</VAR> +(inclusive) and ending with index <VAR>end1</VAR> (exclusive) into +<VAR>string2</VAR> beginning with index <VAR>start2</VAR> (inclusive). +</P> +<P> + +<CODE>substring-move-left!</CODE> stores characters in time order of +increasing indices. <CODE>substring-move-right!</CODE> stores characters in +time order of increasing indeces. +</P> +</DL> +<P> + +<A NAME="IDX1436"></A> +</P> +<DL> +<DT><U>Procedure:</U> <B>substring-fill!</B> <I>string start end char</I> +<DD>Fills the elements <VAR>start</VAR>--<VAR>end</VAR> of <VAR>string</VAR> with the +character <VAR>char</VAR>. +</DL> +<P> + +<A NAME="IDX1437"></A> +</P> +<DL> +<DT><U>Function:</U> <B>string-null?</B> <I>str</I> +<DD>== <CODE>(= 0 (string-length <VAR>str</VAR>))</CODE> +</DL> +<P> + +<A NAME="IDX1438"></A> +</P> +<DL> +<DT><U>Procedure:</U> <B>append!</B> <I>pair1 <small>...</small></I> +<DD>Destructively appends its arguments. Equivalent to <CODE>nconc</CODE>. +</DL> +<P> + +<A NAME="IDX1439"></A> +</P> +<DL> +<DT><U>Function:</U> <B>1+</B> <I>n</I> +<DD>Adds 1 to <VAR>n</VAR>. +</DL> +<P> + +<A NAME="IDX1440"></A> +</P> +<DL> +<DT><U>Function:</U> <B>-1+</B> <I>n</I> +<DD>Subtracts 1 from <VAR>n</VAR>. +</DL> +<P> + +<A NAME="IDX1441"></A> +</P> +<DL> +<DT><U>Function:</U> <B><?</B> +<DD><A NAME="IDX1442"></A> +<DT><U>Function:</U> <B><=?</B> +<DD><A NAME="IDX1443"></A> +<DT><U>Function:</U> <B>=?</B> +<DD><A NAME="IDX1444"></A> +<DT><U>Function:</U> <B>>?</B> +<DD><A NAME="IDX1445"></A> +<DT><U>Function:</U> <B>>=?</B> +<DD>These are equivalent to the procedures of the same name but without the +trailing `<SAMP>?</SAMP>'. +</DL> +<P> + +<A NAME="Rev4 Optional Procedures"></A> +<HR SIZE="6"> +<A NAME="SEC240"></A> +<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0> +<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC239"> < </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC241"> > </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC183"> << </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC235"> Up </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_8.html#SEC277"> >> </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib.html#SEC_Top">Top</A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_toc.html#SEC_Contents">Contents</A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_abt.html#SEC_About"> ? </A>]</TD> +</TR></TABLE> +<H3> 7.4.5 Rev4 Optional Procedures </H3> +<!--docid::SEC240::--> +<P> + +<CODE>(require 'rev4-optional-procedures)</CODE> +<A NAME="IDX1446"></A> +</P> +<P> + +For the specification of these optional procedures, +See section `Standard procedures' in <CITE>Revised(4) Scheme</CITE>. +</P> +<P> + +<A NAME="IDX1447"></A> +</P> +<DL> +<DT><U>Function:</U> <B>list-tail</B> <I>l p</I> +<DD></DL> +<P> + +<A NAME="IDX1448"></A> +</P> +<DL> +<DT><U>Function:</U> <B>string->list</B> <I>s</I> +<DD></DL> +<P> + +<A NAME="IDX1449"></A> +</P> +<DL> +<DT><U>Function:</U> <B>list->string</B> <I>l</I> +<DD></DL> +<P> + +<A NAME="IDX1450"></A> +</P> +<DL> +<DT><U>Function:</U> <B>string-copy</B> +<DD></DL> +<P> + +<A NAME="IDX1451"></A> +</P> +<DL> +<DT><U>Procedure:</U> <B>string-fill!</B> <I>s obj</I> +<DD></DL> +<P> + +<A NAME="IDX1452"></A> +</P> +<DL> +<DT><U>Function:</U> <B>list->vector</B> <I>l</I> +<DD></DL> +<P> + +<A NAME="IDX1453"></A> +</P> +<DL> +<DT><U>Function:</U> <B>vector->list</B> <I>s</I> +<DD></DL> +<P> + +<A NAME="IDX1454"></A> +</P> +<DL> +<DT><U>Procedure:</U> <B>vector-fill!</B> <I>s obj</I> +<DD></DL> +<P> + +<A NAME="Multi-argument / and -"></A> +<HR SIZE="6"> +<A NAME="SEC241"></A> +<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0> +<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC240"> < </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC242"> > </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC183"> << </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC235"> Up </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_8.html#SEC277"> >> </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib.html#SEC_Top">Top</A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_toc.html#SEC_Contents">Contents</A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_abt.html#SEC_About"> ? </A>]</TD> +</TR></TABLE> +<H3> 7.4.6 Multi-argument / and - </H3> +<!--docid::SEC241::--> +<P> + +<CODE>(require 'multiarg/and-)</CODE> +<A NAME="IDX1455"></A> +</P> +<P> + +For the specification of these optional forms, See section `Numerical operations' in <CITE>Revised(4) Scheme</CITE>. +</P> +<P> + +<A NAME="IDX1456"></A> +</P> +<DL> +<DT><U>Function:</U> <B>/</B> <I>dividend divisor1 <small>...</small></I> +<DD></DL> +<P> + +<A NAME="IDX1457"></A> +</P> +<DL> +<DT><U>Function:</U> <B>-</B> <I>minuend subtrahend1 <small>...</small></I> +<DD></DL> +<P> + +<A NAME="Multi-argument Apply"></A> +<HR SIZE="6"> +<A NAME="SEC242"></A> +<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0> +<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC241"> < </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC243"> > </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC183"> << </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC235"> Up </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_8.html#SEC277"> >> </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib.html#SEC_Top">Top</A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_toc.html#SEC_Contents">Contents</A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_abt.html#SEC_About"> ? </A>]</TD> +</TR></TABLE> +<H3> 7.4.7 Multi-argument Apply </H3> +<!--docid::SEC242::--> +<P> + +<CODE>(require 'multiarg-apply)</CODE> +<A NAME="IDX1458"></A> +</P> +<P> + +For the specification of this optional form, +See section `Control features' in <CITE>Revised(4) Scheme</CITE>. +</P> +<P> + +<A NAME="IDX1459"></A> +</P> +<DL> +<DT><U>Function:</U> <B>apply</B> <I>proc arg1 <small>...</small></I> +<DD></DL> +<P> + +<A NAME="Rationalize"></A> +<HR SIZE="6"> +<A NAME="SEC243"></A> +<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0> +<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC242"> < </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC244"> > </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC183"> << </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC235"> Up </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_8.html#SEC277"> >> </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib.html#SEC_Top">Top</A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_toc.html#SEC_Contents">Contents</A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_abt.html#SEC_About"> ? </A>]</TD> +</TR></TABLE> +<H3> 7.4.8 Rationalize </H3> +<!--docid::SEC243::--> +<P> + +<CODE>(require 'rationalize)</CODE> +<A NAME="IDX1460"></A> +</P> +<P> + +<A NAME="IDX1461"></A> +</P> +<DL> +<DT><U>Function:</U> <B>rationalize</B> <I>x e</I> +<DD><P> + +Computes the correct result for exact arguments (provided the +implementation supports exact rational numbers of unlimited precision); +and produces a reasonable answer for inexact arguments when inexact +arithmetic is implemented using floating-point. +</P> +<P> + +</P> +</DL> +<CODE>Rationalize</CODE> has limited use in implementations lacking exact +(non-integer) rational numbers. The following procedures return a list +of the numerator and denominator. +<P> + +<A NAME="IDX1462"></A> +</P> +<DL> +<DT><U>Function:</U> <B>find-ratio</B> <I>x e</I> +<DD><P> + +<CODE>find-ratio</CODE> returns the list of the <EM>simplest</EM> +numerator and denominator whose quotient differs from <VAR>x</VAR> by no more +than <VAR>e</VAR>. +</P> +<P> + +<TABLE><tr><td> </td><td class=display><pre style="font-family: serif"><TT>(find-ratio 3/97 .0001) => (3 97) +(find-ratio 3/97 .001) => (1 32) +</TT> +</pre></td></tr></table></DL> +<P> + +<A NAME="IDX1463"></A> +</P> +<DL> +<DT><U>Function:</U> <B>find-ratio-between</B> <I>x y</I> +<DD><P> + +<CODE>find-ratio-between</CODE> returns the list of the <EM>simplest</EM> +numerator and denominator between <VAR>x</VAR> and <VAR>y</VAR>. +</P> +<P> + +<TABLE><tr><td> </td><td class=display><pre style="font-family: serif"><TT>(find-ratio-between 2/7 3/5) => (1 2) +(find-ratio-between -3/5 -2/7) => (-1 2) +</TT> +</pre></td></tr></table></DL> +<P> + +<A NAME="Promises"></A> +<HR SIZE="6"> +<A NAME="SEC244"></A> +<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0> +<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC243"> < </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC245"> > </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC183"> << </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC235"> Up </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_8.html#SEC277"> >> </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib.html#SEC_Top">Top</A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_toc.html#SEC_Contents">Contents</A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_abt.html#SEC_About"> ? </A>]</TD> +</TR></TABLE> +<H3> 7.4.9 Promises </H3> +<!--docid::SEC244::--> +<P> + +<CODE>(require 'promise)</CODE> +<A NAME="IDX1464"></A> +</P> +<P> + +<A NAME="IDX1465"></A> +</P> +<DL> +<DT><U>Function:</U> <B>make-promise</B> <I>proc</I> +<DD></DL> +<P> + +<A NAME="IDX1466"></A> +</P> +<DL> +<DT><U>Function:</U> <B>force</B> <I>promise</I> +<DD></DL> +<P> + +<CODE>(require 'delay)</CODE> provides <CODE>force</CODE> and <CODE>delay</CODE>: +</P> +<P> + +<A NAME="IDX1467"></A> +</P> +<DL> +<DT><U>Macro:</U> <B>delay</B> <I>obj</I> +<DD>Change occurrences of <CODE>(delay <VAR>expression</VAR>)</CODE> to +<P> + +<TABLE><tr><td> </td><td class=example><pre>(make-promise (lambda () <VAR>expression</VAR>)) +</pre></td></tr></table><P> + +</P> +</DL> +<P> + +(see section `Control features' in <CITE>Revised(4) Scheme</CITE>). +</P> +<P> + +<A NAME="Dynamic-Wind"></A> +<HR SIZE="6"> +<A NAME="SEC245"></A> +<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0> +<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC244"> < </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC246"> > </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC183"> << </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC235"> Up </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_8.html#SEC277"> >> </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib.html#SEC_Top">Top</A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_toc.html#SEC_Contents">Contents</A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_abt.html#SEC_About"> ? </A>]</TD> +</TR></TABLE> +<H3> 7.4.10 Dynamic-Wind </H3> +<!--docid::SEC245::--> +<P> + +<CODE>(require 'dynamic-wind)</CODE> +<A NAME="IDX1468"></A> +</P> +<P> + +This facility is a generalization of Common LISP <CODE>unwind-protect</CODE>, +designed to take into account the fact that continuations produced by +<CODE>call-with-current-continuation</CODE> may be reentered. +</P> +<P> + +<A NAME="IDX1469"></A> +</P> +<DL> +<DT><U>Procedure:</U> <B>dynamic-wind</B> <I>thunk1 thunk2 thunk3</I> +<DD>The arguments <VAR>thunk1</VAR>, <VAR>thunk2</VAR>, and <VAR>thunk3</VAR> must all be +procedures of no arguments (thunks). +<P> + +<CODE>dynamic-wind</CODE> calls <VAR>thunk1</VAR>, <VAR>thunk2</VAR>, and then +<VAR>thunk3</VAR>. The value returned by <VAR>thunk2</VAR> is returned as the +result of <CODE>dynamic-wind</CODE>. <VAR>thunk3</VAR> is also called just before +control leaves the dynamic context of <VAR>thunk2</VAR> by calling a +continuation created outside that context. Furthermore, <VAR>thunk1</VAR> is +called before reentering the dynamic context of <VAR>thunk2</VAR> by calling +a continuation created inside that context. (Control is inside the +context of <VAR>thunk2</VAR> if <VAR>thunk2</VAR> is on the current return stack). +</P> +<P> + +<STRONG>Warning:</STRONG> There is no provision for dealing with errors or +interrupts. If an error or interrupt occurs while using +<CODE>dynamic-wind</CODE>, the dynamic environment will be that in effect at +the time of the error or interrupt. +</P> +</DL> +<P> + +<A NAME="Eval"></A> +<HR SIZE="6"> +<A NAME="SEC246"></A> +<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0> +<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC245"> < </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC247"> > </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC183"> << </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC235"> Up </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_8.html#SEC277"> >> </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib.html#SEC_Top">Top</A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_toc.html#SEC_Contents">Contents</A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_abt.html#SEC_About"> ? </A>]</TD> +</TR></TABLE> +<H3> 7.4.11 Eval </H3> +<!--docid::SEC246::--> +<P> + +<CODE>(require 'eval)</CODE> +<A NAME="IDX1470"></A> +</P> +<P> + +<A NAME="IDX1471"></A> +</P> +<DL> +<DT><U>Function:</U> <B>eval</B> <I>expression environment-specifier</I> +<DD><P> + +Evaluates <VAR>expression</VAR> in the specified environment and returns its +value. <VAR>Expression</VAR> must be a valid Scheme expression represented +as data, and <VAR>environment-specifier</VAR> must be a value returned by one +of the three procedures described below. Implementations may extend +<CODE>eval</CODE> to allow non-expression programs (definitions) as the first +argument and to allow other values as environments, with the restriction +that <CODE>eval</CODE> is not allowed to create new bindings in the +environments associated with <CODE>null-environment</CODE> or +<CODE>scheme-report-environment</CODE>. +</P> +<P> + +<TABLE><tr><td> </td><td class=example><pre>(eval '(* 7 3) (scheme-report-environment 5)) + => 21 + +(let ((f (eval '(lambda (f x) (f x x)) + (null-environment)))) + (f + 10)) + => 20 +</pre></td></tr></table></DL> +<P> + +<A NAME="IDX1472"></A> +</P> +<DL> +<DT><U>Function:</U> <B>scheme-report-environment</B> <I>version</I> +<DD><A NAME="IDX1473"></A> +<DT><U>Function:</U> <B>null-environment</B> <I>version</I> +<DD><A NAME="IDX1474"></A> +<DT><U>Function:</U> <B>null-environment</B> +<DD><P> + +<VAR>Version</VAR> must be an exact non-negative integer <VAR>n</VAR> +corresponding to a version of one of the Revised^<VAR>n</VAR> Reports on +Scheme. <CODE>Scheme-report-environment</CODE> returns a specifier for an +environment that contains the set of bindings specified in the +corresponding report that the implementation supports. +<CODE>Null-environment</CODE> returns a specifier for an environment that +contains only the (syntactic) bindings for all the syntactic keywords +defined in the given version of the report. +</P> +<P> + +Not all versions may be available in all implementations at all times. +However, an implementation that conforms to version <VAR>n</VAR> of the +Revised^<VAR>n</VAR> Reports on Scheme must accept version <VAR>n</VAR>. An error +is signalled if the specified version is not available. +</P> +<P> + +The effect of assigning (through the use of <CODE>eval</CODE>) a variable +bound in a <CODE>scheme-report-environment</CODE> (for example <CODE>car</CODE>) is +unspecified. Thus the environments specified by +<CODE>scheme-report-environment</CODE> may be immutable. +</P> +<P> + +</P> +</DL> +<P> + +<A NAME="IDX1475"></A> +</P> +<DL> +<DT><U>Function:</U> <B>interaction-environment</B> +<DD><P> + +This optional procedure returns a specifier for the environment that +contains implementation-defined bindings, typically a superset of those +listed in the report. The intent is that this procedure will return the +environment in which the implementation would evaluate expressions +dynamically typed by the user. +</P> +</DL> +<P> + +Here are some more <CODE>eval</CODE> examples: +</P> +<P> + +<TABLE><tr><td> </td><td class=example><pre>(require 'eval) +=> #<unspecified> +(define car 'volvo) +=> #<unspecified> +car +=> volvo +(eval 'car (interaction-environment)) +=> volvo +(eval 'car (scheme-report-environment 5)) +=> #<primitive-procedure car> +(eval '(eval 'car (interaction-environment)) + (scheme-report-environment 5)) +=> volvo +(eval '(eval '(set! car 'buick) (interaction-environment)) + (scheme-report-environment 5)) +=> #<unspecified> +car +=> buick +(eval 'car (scheme-report-environment 5)) +=> #<primitive-procedure car> +(eval '(eval 'car (interaction-environment)) + (scheme-report-environment 5)) +=> buick +</pre></td></tr></table><P> + +<A NAME="Values"></A> +<HR SIZE="6"> +<A NAME="SEC247"></A> +<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0> +<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC246"> < </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC248"> > </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC183"> << </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC235"> Up </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_8.html#SEC277"> >> </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib.html#SEC_Top">Top</A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_toc.html#SEC_Contents">Contents</A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_abt.html#SEC_About"> ? </A>]</TD> +</TR></TABLE> +<H3> 7.4.12 Values </H3> +<!--docid::SEC247::--> +<P> + +<CODE>(require 'values)</CODE> +<A NAME="IDX1476"></A> +</P> +<P> + +<A NAME="IDX1477"></A> +</P> +<DL> +<DT><U>Function:</U> <B>values</B> <I>obj <small>...</small></I> +<DD><CODE>values</CODE> takes any number of arguments, and passes (returns) them +to its continuation. +</DL> +<P> + +<A NAME="IDX1478"></A> +</P> +<DL> +<DT><U>Function:</U> <B>call-with-values</B> <I>thunk proc</I> +<DD><VAR>thunk</VAR> must be a procedure of no arguments, and <VAR>proc</VAR> must be +a procedure. <CODE>call-with-values</CODE> calls <VAR>thunk</VAR> with a +continuation that, when passed some values, calls <VAR>proc</VAR> with those +values as arguments. +<P> + +Except for continuations created by the <CODE>call-with-values</CODE> +procedure, all continuations take exactly one value, as now; the effect +of passing no value or more than one value to continuations that were +not created by the <CODE>call-with-values</CODE> procedure is +unspecified. +</P> +</DL> +<P> + +<A NAME="SRFI"></A> +<HR SIZE="6"> +<A NAME="SEC248"></A> +<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0> +<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC247"> < </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC249"> > </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC183"> << </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC235"> Up </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_8.html#SEC277"> >> </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib.html#SEC_Top">Top</A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_toc.html#SEC_Contents">Contents</A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_abt.html#SEC_About"> ? </A>]</TD> +</TR></TABLE> +<H3> 7.4.13 SRFI </H3> +<!--docid::SEC248::--> +<P> + +<CODE>(require 'srfi)</CODE> +<A NAME="IDX1479"></A> +</P> +<P> + +Implements <EM>Scheme Request For Implementation</EM> (SRFI) as +<A NAME="IDX1480"></A> +described at <A HREF="http://srfi.schemers.org/">http://srfi.schemers.org/</A> +</P> +<P> + +The Copyright terms of each SRFI states: +<BLOCKQUOTE> +"However, this document itself may not be modified in any way, ..." +</BLOCKQUOTE> +<P> + +Therefore, the specification of SRFI constructs must not be +quoted without including the complete SRFI document containing +discussion and a sample implementation program. +</P> +<P> + +<A NAME="IDX1481"></A> +</P> +<DL> +<DT><U>Macro:</U> <B>cond-expand</B> <I><clause1> <clause2> <small>...</small></I> +<DD><P> + +<EM>Syntax:</EM> +Each <clause> should be of the form +</P> +<P> + +<TABLE><tr><td> </td><td class=display><pre style="font-family: serif"><TT>(<feature> <expression1> <small>...</small>)</TT> +</pre></td></tr></table><P> + +where <feature> is a boolean expression composed of symbols and +`and', `or', and `not' of boolean expressions. The last <clause> +may be an "else clause," which has the form +</P> +<P> + +<TABLE><tr><td> </td><td class=display><pre style="font-family: serif"><TT>(else <expression1> <expression2> <small>...</small>).</TT> +</pre></td></tr></table><P> + +The first clause whose feature expression is satisfied is expanded. +If no feature expression is satisfied and there is no else clause, an +error is signaled. +</P> +<P> + +SLIB <CODE>cond-expand</CODE> is an extension of SRFI-0, +<A HREF="http://srfi.schemers.org/srfi-0/srfi-0.html">http://srfi.schemers.org/srfi-0/srfi-0.html</A>. +</P> +</DL> +<P> + +<TABLE BORDER="0" CELLSPACING="0"> +<TR><TD ALIGN="left" VALIGN="TOP"><A HREF="slib_7.html#SEC249">7.4.13.1 SRFI-1</A></TD><TD> </TD><TD ALIGN="left" VALIGN="TOP">list-processing</TD></TR> +<TR><TD ALIGN="left" VALIGN="TOP"><A HREF="slib_7.html#SEC260">7.4.13.2 SRFI-2</A></TD><TD> </TD><TD ALIGN="left" VALIGN="TOP">guarded LET* special form</TD></TR> +<TR><TD ALIGN="left" VALIGN="TOP"><A HREF="slib_7.html#SEC261">7.4.13.3 SRFI-8</A></TD><TD> </TD><TD ALIGN="left" VALIGN="TOP">Binding to multiple values</TD></TR> +<TR><TD ALIGN="left" VALIGN="TOP"><A HREF="slib_7.html#SEC262">7.4.13.4 SRFI-9</A></TD><TD> </TD><TD ALIGN="left" VALIGN="TOP">Defining Record Types</TD></TR> +</TABLE> +<P> + +<A NAME="SRFI-1"></A> +<HR SIZE="6"> +<A NAME="SEC249"></A> +<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0> +<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC248"> < </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC260"> > </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC183"> << </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC248"> Up </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_8.html#SEC277"> >> </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib.html#SEC_Top">Top</A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_toc.html#SEC_Contents">Contents</A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_abt.html#SEC_About"> ? </A>]</TD> +</TR></TABLE> +<H4> 7.4.13.1 SRFI-1 </H4> +<!--docid::SEC249::--> +<P> + +<CODE>(require 'srfi-1)</CODE> +<A NAME="IDX1482"></A> +</P> +<P> + +Implements the <EM>SRFI-1</EM> <EM>list-processing library</EM> as described +<A NAME="IDX1483"></A> +<A NAME="IDX1484"></A> +at <A HREF="http://srfi.schemers.org/srfi-1/srfi-1.html">http://srfi.schemers.org/srfi-1/srfi-1.html</A> +</P> +<P> + +<A NAME="SEC250"></A> +<H3> Constructors </H3> +<!--docid::SEC250::--> +<P> + +<A NAME="IDX1485"></A> +</P> +<DL> +<DT><U>Function:</U> <B>xcons</B> <I>d a</I> +<DD><CODE>(define (xcons d a) (cons a d))</CODE>. +</DL> +<P> + +<A NAME="IDX1486"></A> +</P> +<DL> +<DT><U>Function:</U> <B>list-tabulate</B> <I>len proc</I> +<DD>Returns a list of length <VAR>len</VAR>. Element <VAR>i</VAR> is <CODE>(<VAR>proc</VAR> +<VAR>i</VAR>)</CODE> for 0 <= <VAR>i</VAR> < <VAR>len</VAR>. +</DL> +<P> + +<A NAME="IDX1487"></A> +</P> +<DL> +<DT><U>Function:</U> <B>cons*</B> <I>obj1 obj2</I> +<DD><P> + +</P> +</DL> +<P> + +<A NAME="IDX1488"></A> +</P> +<DL> +<DT><U>Function:</U> <B>list-copy</B> <I>flist</I> +<DD><P> + +</P> +</DL> +<P> + +<A NAME="IDX1489"></A> +</P> +<DL> +<DT><U>Function:</U> <B>iota</B> <I>count start step</I> +<DD><P> + +<A NAME="IDX1490"></A> +<DT><U>Function:</U> <B>iota</B> <I>count start</I> +<DD></P> +<P> + +<A NAME="IDX1491"></A> +<DT><U>Function:</U> <B>iota</B> <I>count</I> +<DD>Returns a list of <VAR>count</VAR> numbers: (<VAR>start</VAR>, <VAR>start</VAR>+<VAR>step</VAR>, <small>...</small>, <VAR>start</VAR>+(<VAR>count</VAR>-1)*<VAR>step</VAR>). +</P> +</DL> +<P> + +<A NAME="IDX1492"></A> +</P> +<DL> +<DT><U>Function:</U> <B>circular-list</B> <I>obj1 obj2 <small>...</small></I> +<DD><P> + +Returns a circular list of <VAR>obj1</VAR>, <VAR>obj2</VAR>, <small>...</small>. +</P> +</DL> +<A NAME="SEC251"></A> +<H3> Predicates </H3> +<!--docid::SEC251::--> +<P> + +<A NAME="IDX1493"></A> +</P> +<DL> +<DT><U>Function:</U> <B>proper-list?</B> <I>obj</I> +<DD><P> + +</P> +</DL> +<P> + +<A NAME="IDX1494"></A> +</P> +<DL> +<DT><U>Function:</U> <B>circular-list?</B> <I>x</I> +<DD><P> + +</P> +</DL> +<P> + +<A NAME="IDX1495"></A> +</P> +<DL> +<DT><U>Function:</U> <B>dotted-list?</B> <I>obj</I> +<DD><P> + +</P> +</DL> +<P> + +<A NAME="IDX1496"></A> +</P> +<DL> +<DT><U>Function:</U> <B>null-list?</B> <I>obj</I> +<DD><P> + +</P> +</DL> +<P> + +<A NAME="IDX1497"></A> +</P> +<DL> +<DT><U>Function:</U> <B>not-pair?</B> <I>obj</I> +<DD><P> + +</P> +</DL> +<P> + +<A NAME="IDX1498"></A> +</P> +<DL> +<DT><U>Function:</U> <B>list=</B> <I>=pred list <small>...</small></I> +<DD><P> + +</P> +</DL> +<A NAME="SEC252"></A> +<H3> Selectors </H3> +<!--docid::SEC252::--> +<P> + +<A NAME="IDX1499"></A> +</P> +<DL> +<DT><U>Function:</U> <B>first</B> <I>pair</I> +<DD><P> + +</P> +</DL> +<P> + +<A NAME="IDX1500"></A> +</P> +<DL> +<DT><U>Function:</U> <B>second</B> <I>pair</I> +<DD><P> + +</P> +</DL> +<P> + +<A NAME="IDX1501"></A> +</P> +<DL> +<DT><U>Function:</U> <B>third</B> <I>pair</I> +<DD><P> + +</P> +</DL> +<P> + +<A NAME="IDX1502"></A> +</P> +<DL> +<DT><U>Function:</U> <B>fourth</B> <I>pair</I> +<DD><P> + +</P> +</DL> +<P> + +<A NAME="IDX1503"></A> +</P> +<DL> +<DT><U>Function:</U> <B>fifth</B> <I>pair</I> +<DD><A NAME="IDX1504"></A> +<DT><U>Function:</U> <B>sixth</B> <I>obj</I> +<DD><A NAME="IDX1505"></A> +<DT><U>Function:</U> <B>seventh</B> <I>obj</I> +<DD><A NAME="IDX1506"></A> +<DT><U>Function:</U> <B>eighth</B> <I>obj</I> +<DD><A NAME="IDX1507"></A> +<DT><U>Function:</U> <B>ninth</B> <I>obj</I> +<DD><A NAME="IDX1508"></A> +<DT><U>Function:</U> <B>tenth</B> <I>obj</I> +<DD><P> + +</P> +</DL> +<P> + +<A NAME="IDX1509"></A> +</P> +<DL> +<DT><U>Function:</U> <B>car+cdr</B> <I>pair</I> +<DD><P> + +</P> +</DL> +<P> + +<A NAME="IDX1510"></A> +</P> +<DL> +<DT><U>Function:</U> <B>drop</B> <I>lst k</I> +<DD><A NAME="IDX1511"></A> +<DT><U>Function:</U> <B>take</B> <I>lst k</I> +<DD><P> + +</P> +</DL> +<P> + +<A NAME="IDX1512"></A> +</P> +<DL> +<DT><U>Procedure:</U> <B>take!</B> <I>lst k</I> +<DD><P> + +</P> +</DL> +<P> + +<A NAME="IDX1513"></A> +</P> +<DL> +<DT><U>Function:</U> <B>take-right</B> <I>lst k</I> +<DD><P> + +</P> +</DL> +<P> + +<A NAME="IDX1514"></A> +</P> +<DL> +<DT><U>Function:</U> <B>drop-right</B> <I>lst k</I> +<DD><P> + +</P> +</DL> +<P> + +<A NAME="IDX1515"></A> +</P> +<DL> +<DT><U>Procedure:</U> <B>drop-right!</B> <I>lst k</I> +<DD><P> + +</P> +</DL> +<P> + +<A NAME="IDX1516"></A> +</P> +<DL> +<DT><U>Function:</U> <B>split-at</B> <I>lst k</I> +<DD><P> + +</P> +</DL> +<P> + +<A NAME="IDX1517"></A> +</P> +<DL> +<DT><U>Procedure:</U> <B>split-at!</B> <I>lst k</I> +<DD><P> + +</P> +</DL> +<P> + +<A NAME="IDX1518"></A> +</P> +<DL> +<DT><U>Function:</U> <B>last</B> <I>lst</I> +<DD><P> + +(car (last-pair lst)) +</P> +</DL> +<A NAME="SEC253"></A> +<H3> Miscellaneous </H3> +<!--docid::SEC253::--> +<P> + +<A NAME="IDX1519"></A> +</P> +<DL> +<DT><U>Function:</U> <B>length+</B> <I>obj</I> +<DD><P> + +</P> +</DL> +<P> + +<A NAME="IDX1520"></A> +</P> +<DL> +<DT><U>Function:</U> <B>concatenate</B> <I>lists</I> +<DD><A NAME="IDX1521"></A> +<DT><U>Function:</U> <B>concatenate!</B> <I>lists</I> +<DD><P> + +</P> +</DL> +<P> + +<A NAME="IDX1522"></A> +</P> +<DL> +<DT><U>Procedure:</U> <B>reverse!</B> <I>lst</I> +<DD><P> + +</P> +</DL> +<P> + +<A NAME="IDX1523"></A> +</P> +<DL> +<DT><U>Function:</U> <B>append-reverse</B> <I>rev-head tail</I> +<DD><A NAME="IDX1524"></A> +<DT><U>Function:</U> <B>append-reverse!</B> <I>rev-head tail</I> +<DD><P> + +</P> +</DL> +<P> + +<A NAME="IDX1525"></A> +</P> +<DL> +<DT><U>Function:</U> <B>zip</B> <I>list1 list2 <small>...</small></I> +<DD><P> + +</P> +</DL> +<P> + +<A NAME="IDX1526"></A> +</P> +<DL> +<DT><U>Function:</U> <B>unzip1</B> <I>lst</I> +<DD><A NAME="IDX1527"></A> +<DT><U>Function:</U> <B>unzip2</B> <I>lst</I> +<DD><A NAME="IDX1528"></A> +<DT><U>Function:</U> <B>unzip3</B> <I>lst</I> +<DD><A NAME="IDX1529"></A> +<DT><U>Function:</U> <B>unzip4</B> <I>lst</I> +<DD><A NAME="IDX1530"></A> +<DT><U>Function:</U> <B>unzip5</B> <I>lst</I> +<DD><P> + +</P> +</DL> +<P> + +<A NAME="IDX1531"></A> +</P> +<DL> +<DT><U>Function:</U> <B>count</B> <I>pred list1 list2 <small>...</small></I> +<DD><P> + +</P> +</DL> +<A NAME="SEC254"></A> +<H3> Fold and Unfold </H3> +<!--docid::SEC254::--> +<P> + +<A NAME="IDX1532"></A> +</P> +<DL> +<DT><U>Procedure:</U> <B>map!</B> <I>f list1 clist2 <small>...</small></I> +<DD><P> + +</P> +</DL> +<P> + +<A NAME="IDX1533"></A> +</P> +<DL> +<DT><U>Function:</U> <B>pair-for-each</B> <I>f clist1 clist2 <small>...</small></I> +<DD><P> + +</P> +</DL> +<A NAME="SEC255"></A> +<H3> Filtering and Partitioning </H3> +<!--docid::SEC255::--> +<P> + +<A NAME="IDX1534"></A> +</P> +<DL> +<DT><U>Function:</U> <B>filter</B> <I>pred lis</I> +<DD><P> + +</P> +</DL> +<P> + +<A NAME="IDX1535"></A> +</P> +<DL> +<DT><U>Procedure:</U> <B>filter!</B> <I>pred l</I> +<DD><P> + +</P> +</DL> +<P> + +<A NAME="IDX1536"></A> +</P> +<DL> +<DT><U>Function:</U> <B>partition</B> <I>pred list</I> +<DD><P> + +</P> +</DL> +<A NAME="SEC256"></A> +<H3> Searching </H3> +<!--docid::SEC256::--> +<P> + +<A NAME="IDX1537"></A> +</P> +<DL> +<DT><U>Function:</U> <B>find</B> <I>pred list</I> +<DD><P> + +</P> +</DL> +<P> + +<A NAME="IDX1538"></A> +</P> +<DL> +<DT><U>Function:</U> <B>find-tail</B> <I>pred list</I> +<DD><P> + +</P> +</DL> +<P> + +<A NAME="IDX1539"></A> +</P> +<DL> +<DT><U>Function:</U> <B>remove</B> <I>pred l</I> +<DD><P> + +</P> +</DL> +<P> + +<A NAME="IDX1540"></A> +</P> +<DL> +<DT><U>Procedure:</U> <B>remove!</B> <I>pred l</I> +<DD><P> + +</P> +</DL> +<P> + +<A NAME="IDX1541"></A> +</P> +<DL> +<DT><U>Function:</U> <B>any</B> <I>pred clist1 clist2 <small>...</small></I> +<DD><P> + +</P> +</DL> +<P> + +<A NAME="IDX1542"></A> +</P> +<DL> +<DT><U>Function:</U> <B>list-index</B> <I>pred clist1 clist2 <small>...</small></I> +<DD><P> + +</P> +</DL> +<P> + +<A NAME="IDX1543"></A> +</P> +<DL> +<DT><U>Function:</U> <B>span</B> <I>pred list</I> +<DD><P> + +</P> +</DL> +<P> + +<A NAME="IDX1544"></A> +</P> +<DL> +<DT><U>Function:</U> <B>member</B> <I>obj list pred</I> +<DD><P> + +<A NAME="IDX1545"></A> +<DT><U>Function:</U> <B>member</B> <I>obj list</I> +<DD></P> +<P> + +<CODE>member</CODE> returns the first sublist of <VAR>list</VAR> whose car is <VAR>obj</VAR>, where the sublists +of <VAR>list</VAR> are the non-empty lists returned by <TT>(list-tail <VAR>list</VAR> <VAR>k</VAR>)</TT> +for <VAR>k</VAR> less than the length of <VAR>list</VAR>. If <VAR>obj</VAR> does not occur in <VAR>list</VAR>, +then <TT>#f</TT> (not the empty list) is returned. The procedure <VAR>pred</VAR> is +used for testing equality. If <VAR>pred</VAR> is not provided, `<SAMP>equal?</SAMP>' is +used. +</P> +</DL> +<A NAME="SEC257"></A> +<H3> Deleting </H3> +<!--docid::SEC257::--> +<P> + +<A NAME="SEC258"></A> +<H3> Association lists </H3> +<!--docid::SEC258::--> +<P> + +<A NAME="IDX1546"></A> +</P> +<DL> +<DT><U>Function:</U> <B>assoc</B> <I>obj alist pred</I> +<DD><P> + +<A NAME="IDX1547"></A> +<DT><U>Function:</U> <B>assoc</B> <I>obj alist</I> +<DD></P> +<P> + +<VAR>alist</VAR> (for "association list") must be a list of pairs. These +procedures find the first pair in <VAR>alist</VAR> whose car field is <VAR>obj</VAR>, and +returns that pair. If no pair in <VAR>alist</VAR> has <VAR>obj</VAR> as its car, then <TT>#f</TT> +(not the empty list) is returned. The procedure <VAR>pred</VAR> is used for +testing equality. If <VAR>pred</VAR> is not provided, `<SAMP>equal?</SAMP>' is used. +</P> +</DL> +<A NAME="SEC259"></A> +<H3> Set operations </H3> +<!--docid::SEC259::--> +<P> + +<A NAME="SRFI-2"></A> +<HR SIZE="6"> +<A NAME="SEC260"></A> +<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0> +<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC249"> < </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC261"> > </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC183"> << </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC248"> Up </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_8.html#SEC277"> >> </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib.html#SEC_Top">Top</A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_toc.html#SEC_Contents">Contents</A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_abt.html#SEC_About"> ? </A>]</TD> +</TR></TABLE> +<H4> 7.4.13.2 SRFI-2 </H4> +<!--docid::SEC260::--> +<P> + +<CODE>(require 'srfi-2)</CODE> +<A NAME="IDX1548"></A> +</P> +<P> + +<A NAME="IDX1549"></A> +</P> +<DL> +<DT><U>Macro:</U> <B>and-let*</B> <I>claws body <small>...</small></I> +<DD><P> + +<A HREF="http://srfi.schemers.org/srfi-2/srfi-2.html">http://srfi.schemers.org/srfi-2/srfi-2.html</A> +</P> +</DL> +<P> + +<A NAME="SRFI-8"></A> +<HR SIZE="6"> +<A NAME="SEC261"></A> +<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0> +<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC260"> < </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC262"> > </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC183"> << </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC248"> Up </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_8.html#SEC277"> >> </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib.html#SEC_Top">Top</A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_toc.html#SEC_Contents">Contents</A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_abt.html#SEC_About"> ? </A>]</TD> +</TR></TABLE> +<H4> 7.4.13.3 SRFI-8 </H4> +<!--docid::SEC261::--> +<P> + +<CODE>(require 'srfi-8)</CODE> +<A NAME="IDX1550"></A> +</P> +<P> + +<A NAME="IDX1551"></A> +</P> +<DL> +<DT><U>Special Form:</U> <B>receive</B> <I>formals expression body <small>...</small></I> +<DD><P> + +<A HREF="http://srfi.schemers.org/srfi-8/srfi-8.html">http://srfi.schemers.org/srfi-8/srfi-8.html</A> +</P> +</DL> +<P> + +<A NAME="SRFI-9"></A> +<HR SIZE="6"> +<A NAME="SEC262"></A> +<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0> +<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC261"> < </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC263"> > </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC183"> << </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC248"> Up </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_8.html#SEC277"> >> </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib.html#SEC_Top">Top</A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_toc.html#SEC_Contents">Contents</A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_abt.html#SEC_About"> ? </A>]</TD> +</TR></TABLE> +<H4> 7.4.13.4 SRFI-9 </H4> +<!--docid::SEC262::--> +<P> + +<CODE>(require 'srfi-9)</CODE> +<A NAME="IDX1552"></A> +</P> +<P> + +<A HREF="http://srfi.schemers.org/srfi-9/srfi-9.html">http://srfi.schemers.org/srfi-9/srfi-9.html</A> +</P> +<P> + +<A NAME="IDX1553"></A> +</P> +<DL> +<DT><U>Special Form:</U> <B>define-record-type</B> <I><type-name> (<constructor-name> <field-tag> ...) <predicate-name> <field spec> ...</I> +<DD><P> + +Where +<TABLE><tr><td> </td><td class=example><pre><field-spec> == (<field-tag> <accessor-name>) + == (<field-tag> <accessor-name> <modifier-name>) + +</pre></td></tr></table><P> + +<CODE>define-record-type</CODE> is a syntax wrapper for the SLIB +<CODE>record</CODE> module. +</P> +</DL> +<P> + +<A NAME="Session Support"></A> +<HR SIZE="6"> +<A NAME="SEC263"></A> +<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0> +<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC262"> < </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC264"> > </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC183"> << </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC183"> Up </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_8.html#SEC277"> >> </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib.html#SEC_Top">Top</A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_toc.html#SEC_Contents">Contents</A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_abt.html#SEC_About"> ? </A>]</TD> +</TR></TABLE> +<H2> 7.5 Session Support </H2> +<!--docid::SEC263::--> +<P> + +<TABLE BORDER="0" CELLSPACING="0"> +<TR><TD ALIGN="left" VALIGN="TOP"><A HREF="slib_7.html#SEC264">7.5.1 Repl</A></TD><TD> </TD><TD ALIGN="left" VALIGN="TOP">Macros at top-level</TD></TR> +<TR><TD ALIGN="left" VALIGN="TOP"><A HREF="slib_7.html#SEC265">7.5.2 Quick Print</A></TD><TD> </TD><TD ALIGN="left" VALIGN="TOP">Loop-safe Output</TD></TR> +<TR><TD ALIGN="left" VALIGN="TOP"><A HREF="slib_7.html#SEC266">7.5.3 Debug</A></TD><TD> </TD><TD ALIGN="left" VALIGN="TOP">To err is human ...</TD></TR> +<TR><TD ALIGN="left" VALIGN="TOP"><A HREF="slib_7.html#SEC267">7.5.4 Breakpoints</A></TD><TD> </TD><TD ALIGN="left" VALIGN="TOP">Pause execution</TD></TR> +<TR><TD ALIGN="left" VALIGN="TOP"><A HREF="slib_7.html#SEC268">7.5.5 Tracing</A></TD><TD> </TD><TD ALIGN="left" VALIGN="TOP">'trace</TD></TR> +</TABLE> +<P> + +<A NAME="Repl"></A> +<HR SIZE="6"> +<A NAME="SEC264"></A> +<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0> +<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC263"> < </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC265"> > </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC183"> << </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC263"> Up </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_8.html#SEC277"> >> </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib.html#SEC_Top">Top</A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_toc.html#SEC_Contents">Contents</A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_abt.html#SEC_About"> ? </A>]</TD> +</TR></TABLE> +<H3> 7.5.1 Repl </H3> +<!--docid::SEC264::--> +<P> + +<CODE>(require 'repl)</CODE> +<A NAME="IDX1554"></A> +</P> +<P> + +Here is a read-eval-print-loop which, given an eval, evaluates forms. +</P> +<P> + +<A NAME="IDX1555"></A> +</P> +<DL> +<DT><U>Procedure:</U> <B>repl:top-level</B> <I>repl:eval</I> +<DD><CODE>read</CODE>s, <CODE>repl:eval</CODE>s and <CODE>write</CODE>s expressions from +<CODE>(current-input-port)</CODE> to <CODE>(current-output-port)</CODE> until an +end-of-file is encountered. <CODE>load</CODE>, <CODE>slib:eval</CODE>, +<CODE>slib:error</CODE>, and <CODE>repl:quit</CODE> dynamically bound during +<CODE>repl:top-level</CODE>. +</DL> +<P> + +<A NAME="IDX1556"></A> +</P> +<DL> +<DT><U>Procedure:</U> <B>repl:quit</B> +<DD>Exits from the invocation of <CODE>repl:top-level</CODE>. +</DL> +<P> + +The <CODE>repl:</CODE> procedures establish, as much as is possible to do +portably, a top level environment supporting macros. +<CODE>repl:top-level</CODE> uses <CODE>dynamic-wind</CODE> to catch error conditions +and interrupts. If your implementation supports this you are all set. +</P> +<P> + +Otherwise, if there is some way your implementation can catch error +conditions and interrupts, then have them call <CODE>slib:error</CODE>. It +will display its arguments and reenter <CODE>repl:top-level</CODE>. +<CODE>slib:error</CODE> dynamically bound by <CODE>repl:top-level</CODE>. +</P> +<P> + +To have your top level loop always use macros, add any interrupt +catching lines and the following lines to your Scheme init file: +<TABLE><tr><td> </td><td class=example><pre>(require 'macro) +<A NAME="IDX1557"></A>(require 'repl) +<A NAME="IDX1558"></A>(repl:top-level macro:eval) +</pre></td></tr></table><P> + +<A NAME="Quick Print"></A> +<HR SIZE="6"> +<A NAME="SEC265"></A> +<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0> +<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC264"> < </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC266"> > </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC183"> << </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC263"> Up </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_8.html#SEC277"> >> </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib.html#SEC_Top">Top</A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_toc.html#SEC_Contents">Contents</A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_abt.html#SEC_About"> ? </A>]</TD> +</TR></TABLE> +<H3> 7.5.2 Quick Print </H3> +<!--docid::SEC265::--> +<P> + +<CODE>(require 'qp)</CODE> +<A NAME="IDX1559"></A> +</P> +<P> + +When displaying error messages and warnings, it is paramount that the +output generated for circular lists and large data structures be +limited. This section supplies a procedure to do this. It could be +much improved. +</P> +<P> + +<BLOCKQUOTE> +Notice that the neccessity for truncating output eliminates +Common-Lisp's <A HREF="slib_4.html#SEC53">4.2 Format (version 3.0)</A> from consideration; even when variables +<CODE>*print-level*</CODE> and <CODE>*print-level*</CODE> are set, huge strings and +bit-vectors are <EM>not</EM> limited. +</BLOCKQUOTE> +<P> + +<A NAME="IDX1560"></A> +</P> +<DL> +<DT><U>Procedure:</U> <B>qp</B> <I>arg1 <small>...</small></I> +<DD><A NAME="IDX1561"></A> +<DT><U>Procedure:</U> <B>qpn</B> <I>arg1 <small>...</small></I> +<DD><A NAME="IDX1562"></A> +<DT><U>Procedure:</U> <B>qpr</B> <I>arg1 <small>...</small></I> +<DD><CODE>qp</CODE> writes its arguments, separated by spaces, to +<CODE>(current-output-port)</CODE>. <CODE>qp</CODE> compresses printing by +substituting `<SAMP>...</SAMP>' for substructure it does not have sufficient +room to print. <CODE>qpn</CODE> is like <CODE>qp</CODE> but outputs a newline +before returning. <CODE>qpr</CODE> is like <CODE>qpn</CODE> except that it returns +its last argument. +</DL> +<P> + +<A NAME="IDX1563"></A> +</P> +<DL> +<DT><U>Variable:</U> <B>*qp-width*</B> +<DD><VAR>*qp-width*</VAR> is the largest number of characters that <CODE>qp</CODE> +should use. If <VAR>*qp-width*</VAR> is #f, then all items will be +<CODE>write</CODE>n. If <VAR>*qp-width*</VAR> is 0, then all items except +procedures will be <CODE>write</CODE>n; procedures will be indicated by +`<SAMP>#[proc]</SAMP>'. +</DL> +<P> + +<A NAME="Debug"></A> +<HR SIZE="6"> +<A NAME="SEC266"></A> +<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0> +<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC265"> < </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC267"> > </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC183"> << </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC263"> Up </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_8.html#SEC277"> >> </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib.html#SEC_Top">Top</A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_toc.html#SEC_Contents">Contents</A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_abt.html#SEC_About"> ? </A>]</TD> +</TR></TABLE> +<H3> 7.5.3 Debug </H3> +<!--docid::SEC266::--> +<P> + +<CODE>(require 'debug)</CODE> +<A NAME="IDX1564"></A> +</P> +<P> + +Requiring <CODE>debug</CODE> automatically requires <CODE>trace</CODE> and +<CODE>break</CODE>. +</P> +<P> + +An application with its own datatypes may want to substitute its own +printer for <CODE>qp</CODE>. This example shows how to do this: +</P> +<P> + +<TABLE><tr><td> </td><td class=example><pre>(define qpn (lambda args) <small>...</small>) +(provide 'qp) +(require 'debug) +<A NAME="IDX1565"></A></pre></td></tr></table><P> + +<A NAME="IDX1566"></A> +</P> +<DL> +<DT><U>Procedure:</U> <B>trace-all</B> <I>file <small>...</small></I> +<DD>Traces (see section <A HREF="slib_7.html#SEC268">7.5.5 Tracing</A>) all procedures <CODE>define</CODE>d at top-level in +`<TT>file</TT>' <small>...</small>. +<P> + +<A NAME="IDX1567"></A> +<DT><U>Procedure:</U> <B>track-all</B> <I>file <small>...</small></I> +<DD>Tracks (see section <A HREF="slib_7.html#SEC268">7.5.5 Tracing</A>) all procedures <CODE>define</CODE>d at top-level in +`<TT>file</TT>' <small>...</small>. +</P> +<P> + +<A NAME="IDX1568"></A> +<DT><U>Procedure:</U> <B>stack-all</B> <I>file <small>...</small></I> +<DD>Stacks (see section <A HREF="slib_7.html#SEC268">7.5.5 Tracing</A>) all procedures <CODE>define</CODE>d at top-level in +`<TT>file</TT>' <small>...</small>. +</P> +</DL> +<P> + +<A NAME="IDX1569"></A> +</P> +<DL> +<DT><U>Procedure:</U> <B>break-all</B> <I>file <small>...</small></I> +<DD>Breakpoints (see section <A HREF="slib_7.html#SEC267">7.5.4 Breakpoints</A>) all procedures <CODE>define</CODE>d at +top-level in `<TT>file</TT>' <small>...</small>. +</DL> +<P> + +<A NAME="Breakpoints"></A> +<HR SIZE="6"> +<A NAME="SEC267"></A> +<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0> +<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC266"> < </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC268"> > </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC183"> << </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC263"> Up </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_8.html#SEC277"> >> </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib.html#SEC_Top">Top</A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_toc.html#SEC_Contents">Contents</A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_abt.html#SEC_About"> ? </A>]</TD> +</TR></TABLE> +<H3> 7.5.4 Breakpoints </H3> +<!--docid::SEC267::--> +<P> + +<CODE>(require 'break)</CODE> +<A NAME="IDX1570"></A> +</P> +<P> + +<A NAME="IDX1571"></A> +</P> +<DL> +<DT><U>Function:</U> <B>init-debug</B> +<DD>If your Scheme implementation does not support <CODE>break</CODE> or +<CODE>abort</CODE>, a message will appear when you <CODE>(require 'break)</CODE> or +<A NAME="IDX1572"></A> +<CODE>(require 'debug)</CODE> telling you to type <CODE>(init-debug)</CODE>. This +<A NAME="IDX1573"></A> +is in order to establish a top-level continuation. Typing +<CODE>(init-debug)</CODE> at top level sets up a continuation for +<CODE>break</CODE>. +</DL> +<P> + +<A NAME="IDX1574"></A> +</P> +<DL> +<DT><U>Function:</U> <B>breakpoint</B> <I>arg1 <small>...</small></I> +<DD>Returns from the top level continuation and pushes the continuation from +which it was called on a continuation stack. +</DL> +<P> + +<A NAME="IDX1575"></A> +</P> +<DL> +<DT><U>Function:</U> <B>continue</B> +<DD>Pops the topmost continuation off of the continuation stack and returns +an unspecified value to it. +<P> + +<A NAME="IDX1576"></A> +<DT><U>Function:</U> <B>continue</B> <I>arg1 <small>...</small></I> +<DD>Pops the topmost continuation off of the continuation stack and returns +<VAR>arg1</VAR> <small>...</small> to it. +</P> +</DL> +<P> + +<A NAME="IDX1577"></A> +</P> +<DL> +<DT><U>Macro:</U> <B>break</B> <I>proc1 <small>...</small></I> +<DD>Redefines the top-level named procedures given as arguments so that +<CODE>breakpoint</CODE> is called before calling <VAR>proc1</VAR> <small>...</small>. +<A NAME="IDX1578"></A> +<DT><U>Macro:</U> <B>break</B> +<DD>With no arguments, makes sure that all the currently broken identifiers +are broken (even if those identifiers have been redefined) and returns a +list of the broken identifiers. +</DL> +<P> + +<A NAME="IDX1579"></A> +</P> +<DL> +<DT><U>Macro:</U> <B>unbreak</B> <I>proc1 <small>...</small></I> +<DD>Turns breakpoints off for its arguments. +<A NAME="IDX1580"></A> +<DT><U>Macro:</U> <B>unbreak</B> +<DD>With no arguments, unbreaks all currently broken identifiers and returns +a list of these formerly broken identifiers. +</DL> +<P> + +These are <EM>procedures</EM> for breaking. If defmacros are not natively +supported by your implementation, these might be more convenient to use. +</P> +<P> + +<A NAME="IDX1581"></A> +</P> +<DL> +<DT><U>Function:</U> <B>breakf</B> <I>proc</I> +<DD><A NAME="IDX1582"></A> +<DT><U>Function:</U> <B>breakf</B> <I>proc name</I> +<DD>To break, type +<TABLE><tr><td> </td><td class=example><pre>(set! <VAR>symbol</VAR> (breakf <VAR>symbol</VAR>)) +</pre></td></tr></table>or +<TABLE><tr><td> </td><td class=example><pre>(set! <VAR>symbol</VAR> (breakf <VAR>symbol</VAR> '<VAR>symbol</VAR>)) +</pre></td></tr></table>or +<TABLE><tr><td> </td><td class=example><pre>(define <VAR>symbol</VAR> (breakf <VAR>function</VAR>)) +</pre></td></tr></table>or +<TABLE><tr><td> </td><td class=example><pre>(define <VAR>symbol</VAR> (breakf <VAR>function</VAR> '<VAR>symbol</VAR>)) +</pre></td></tr></table></DL> +<P> + +<A NAME="IDX1583"></A> +</P> +<DL> +<DT><U>Function:</U> <B>unbreakf</B> <I>proc</I> +<DD>To unbreak, type +<TABLE><tr><td> </td><td class=example><pre>(set! <VAR>symbol</VAR> (unbreakf <VAR>symbol</VAR>)) +</pre></td></tr></table></DL> +<P> + +<A NAME="Trace"></A> +<HR SIZE="6"> +<A NAME="SEC268"></A> +<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0> +<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC267"> < </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC269"> > </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC183"> << </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC263"> Up </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_8.html#SEC277"> >> </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib.html#SEC_Top">Top</A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_toc.html#SEC_Contents">Contents</A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_abt.html#SEC_About"> ? </A>]</TD> +</TR></TABLE> +<H3> 7.5.5 Tracing </H3> +<!--docid::SEC268::--> +<P> + +<CODE>(require 'trace)</CODE> +<A NAME="IDX1584"></A> +</P> +<P> + +This feature provides three ways to monitor procedure invocations: +</P> +<P> + +</P> +<DL COMPACT> +<DT>stack +<DD>Pushes the procedure-name when the procedure is called; pops when it +returns. +<DT>track +<DD>Pushes the procedure-name and arguments when the procedure is called; +pops when it returns. +<DT>trace +<DD>Pushes the procedure-name and prints `<SAMP>CALL <VAR>procedure-name</VAR> +<VAR>arg1</VAR> <small>...</small></SAMP>' when the procdure is called; pops and prints +`<SAMP>RETN <VAR>procedure-name</VAR> <VAR>value</VAR></SAMP>' when the procedure returns. +</DL> +<P> + +<A NAME="IDX1585"></A> +</P> +<DL> +<DT><U>Variable:</U> <B>debug:max-count</B> +<DD>If a traced procedure calls itself or untraced procedures which call it, +stack, track, and trace will limit the number of stack pushes to +<VAR>debug:max-count</VAR>. +</DL> +<P> + +<A NAME="IDX1586"></A> +</P> +<DL> +<DT><U>Function:</U> <B>print-call-stack</B> +<DD><A NAME="IDX1587"></A> +<DT><U>Function:</U> <B>print-call-stack</B> <I>port</I> +<DD>Prints the call-stack to <VAR>port</VAR> or the current-error-port. +</DL> +<P> + +<A NAME="IDX1588"></A> +</P> +<DL> +<DT><U>Macro:</U> <B>trace</B> <I>proc1 <small>...</small></I> +<DD>Traces the top-level named procedures given as arguments. +<A NAME="IDX1589"></A> +<DT><U>Macro:</U> <B>trace</B> +<DD>With no arguments, makes sure that all the currently traced identifiers +are traced (even if those identifiers have been redefined) and returns a +list of the traced identifiers. +</DL> +<P> + +<A NAME="IDX1590"></A> +</P> +<DL> +<DT><U>Macro:</U> <B>track</B> <I>proc1 <small>...</small></I> +<DD>Traces the top-level named procedures given as arguments. +<A NAME="IDX1591"></A> +<DT><U>Macro:</U> <B>track</B> +<DD>With no arguments, makes sure that all the currently tracked identifiers +are tracked (even if those identifiers have been redefined) and returns +a list of the tracked identifiers. +</DL> +<P> + +<A NAME="IDX1592"></A> +</P> +<DL> +<DT><U>Macro:</U> <B>stack</B> <I>proc1 <small>...</small></I> +<DD>Traces the top-level named procedures given as arguments. +<A NAME="IDX1593"></A> +<DT><U>Macro:</U> <B>stack</B> +<DD>With no arguments, makes sure that all the currently stacked identifiers +are stacked (even if those identifiers have been redefined) and returns +a list of the stacked identifiers. +</DL> +<P> + +<A NAME="IDX1594"></A> +</P> +<DL> +<DT><U>Macro:</U> <B>untrace</B> <I>proc1 <small>...</small></I> +<DD>Turns tracing, tracking, and off for its arguments. +<A NAME="IDX1595"></A> +<DT><U>Macro:</U> <B>untrace</B> +<DD>With no arguments, untraces all currently traced identifiers and returns +a list of these formerly traced identifiers. +</DL> +<P> + +<A NAME="IDX1596"></A> +</P> +<DL> +<DT><U>Macro:</U> <B>untrack</B> <I>proc1 <small>...</small></I> +<DD>Turns tracing, tracking, and off for its arguments. +<A NAME="IDX1597"></A> +<DT><U>Macro:</U> <B>untrack</B> +<DD>With no arguments, untracks all currently tracked identifiers and returns +a list of these formerly tracked identifiers. +</DL> +<P> + +<A NAME="IDX1598"></A> +</P> +<DL> +<DT><U>Macro:</U> <B>unstack</B> <I>proc1 <small>...</small></I> +<DD>Turns tracing, stacking, and off for its arguments. +<A NAME="IDX1599"></A> +<DT><U>Macro:</U> <B>unstack</B> +<DD>With no arguments, unstacks all currently stacked identifiers and returns +a list of these formerly stacked identifiers. +</DL> +<P> + +These are <EM>procedures</EM> for tracing. If defmacros are not natively +supported by your implementation, these might be more convenient to use. +</P> +<P> + +<A NAME="IDX1600"></A> +</P> +<DL> +<DT><U>Function:</U> <B>tracef</B> <I>proc</I> +<DD><A NAME="IDX1601"></A> +<DT><U>Function:</U> <B>tracef</B> <I>proc name</I> +<DD><A NAME="IDX1602"></A> +<DT><U>Function:</U> <B>trackf</B> <I>proc</I> +<DD><A NAME="IDX1603"></A> +<DT><U>Function:</U> <B>trackf</B> <I>proc name</I> +<DD><A NAME="IDX1604"></A> +<DT><U>Function:</U> <B>stackf</B> <I>proc</I> +<DD><A NAME="IDX1605"></A> +<DT><U>Function:</U> <B>stackf</B> <I>proc name</I> +<DD>To trace, type +<TABLE><tr><td> </td><td class=example><pre>(set! <VAR>symbol</VAR> (tracef <VAR>symbol</VAR>)) +</pre></td></tr></table>or +<TABLE><tr><td> </td><td class=example><pre>(set! <VAR>symbol</VAR> (tracef <VAR>symbol</VAR> '<VAR>symbol</VAR>)) +</pre></td></tr></table>or +<TABLE><tr><td> </td><td class=example><pre>(define <VAR>symbol</VAR> (tracef <VAR>function</VAR>)) +</pre></td></tr></table>or +<TABLE><tr><td> </td><td class=example><pre>(define <VAR>symbol</VAR> (tracef <VAR>function</VAR> '<VAR>symbol</VAR>)) +</pre></td></tr></table></DL> +<P> + +<A NAME="IDX1606"></A> +</P> +<DL> +<DT><U>Function:</U> <B>untracef</B> <I>proc</I> +<DD>Removes tracing, tracking, or stacking for <VAR>proc</VAR>. +To untrace, type +<TABLE><tr><td> </td><td class=example><pre>(set! <VAR>symbol</VAR> (untracef <VAR>symbol</VAR>)) +</pre></td></tr></table></DL> +<P> + +<A NAME="System Interface"></A> +<HR SIZE="6"> +<A NAME="SEC269"></A> +<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0> +<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC268"> < </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC270"> > </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC183"> << </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC183"> Up </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_8.html#SEC277"> >> </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib.html#SEC_Top">Top</A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_toc.html#SEC_Contents">Contents</A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_abt.html#SEC_About"> ? </A>]</TD> +</TR></TABLE> +<H2> 7.6 System Interface </H2> +<!--docid::SEC269::--> +<P> + +If <CODE>(provided? 'getenv)</CODE>: +</P> +<P> + +<A NAME="IDX1607"></A> +</P> +<DL> +<DT><U>Function:</U> <B>getenv</B> <I>name</I> +<DD>Looks up <VAR>name</VAR>, a string, in the program environment. If <VAR>name</VAR> is +found a string of its value is returned. Otherwise, <CODE>#f</CODE> is returned. +</DL> +<P> + +If <CODE>(provided? 'system)</CODE>: +</P> +<P> + +<A NAME="IDX1608"></A> +</P> +<DL> +<DT><U>Function:</U> <B>system</B> <I>command-string</I> +<DD>Executes the <VAR>command-string</VAR> on the computer and returns the +integer status code. +</DL> +<P> + +<TABLE BORDER="0" CELLSPACING="0"> +<TR><TD ALIGN="left" VALIGN="TOP"><A HREF="slib_7.html#SEC270">7.6.1 Directories</A></TD><TD> </TD><TD ALIGN="left" VALIGN="TOP"></TD></TR> +<TR><TD ALIGN="left" VALIGN="TOP"><A HREF="slib_7.html#SEC271">7.6.2 Transactions</A></TD><TD> </TD><TD ALIGN="left" VALIGN="TOP"></TD></TR> +<TR><TD ALIGN="left" VALIGN="TOP"><A HREF="slib_7.html#SEC275">7.6.3 CVS</A></TD><TD> </TD><TD ALIGN="left" VALIGN="TOP"></TD></TR> +</TABLE> +<P> + +<A NAME="Directories"></A> +<HR SIZE="6"> +<A NAME="SEC270"></A> +<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0> +<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC269"> < </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC271"> > </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC183"> << </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC269"> Up </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_8.html#SEC277"> >> </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib.html#SEC_Top">Top</A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_toc.html#SEC_Contents">Contents</A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_abt.html#SEC_About"> ? </A>]</TD> +</TR></TABLE> +<H3> 7.6.1 Directories </H3> +<!--docid::SEC270::--> +<P> + +<CODE>(require 'directory)</CODE> +<A NAME="IDX1609"></A> +</P> +<P> + +<A NAME="IDX1610"></A> +</P> +<DL> +<DT><U>Function:</U> <B>current-directory</B> +<DD><P> + +<CODE>current-directory</CODE> returns a string containing the absolute file +name representing the current working directory. If this string +cannot be obtained, #f is returned. +</P> +<P> + +If <CODE>current-directory</CODE> cannot be supported by the platform, then #f is returned. +</P> +</DL> +<P> + +<A NAME="IDX1611"></A> +</P> +<DL> +<DT><U>Function:</U> <B>make-directory</B> <I>name</I> +<DD><P> + +Creates a sub-directory <VAR>name</VAR> of the current-directory. If +successful, <CODE>make-directory</CODE> returns #t; otherwise #f. +</P> +</DL> +<P> + +<A NAME="IDX1612"></A> +</P> +<DL> +<DT><U>Function:</U> <B>directory-for-each</B> <I>proc directory</I> +<DD><P> + +<VAR>proc</VAR> must be a procedure taking one argument. +`<SAMP>Directory-For-Each</SAMP>' applies <VAR>proc</VAR> to the (string) name of +each file in <VAR>directory</VAR>. The dynamic order in which <VAR>proc</VAR> is +applied to the filenames is unspecified. The value returned by +`<SAMP>directory-for-each</SAMP>' is unspecified. +</P> +<P> + +<A NAME="IDX1613"></A> +<DT><U>Function:</U> <B>directory-for-each</B> <I>proc directory pred</I> +<DD>Applies <VAR>proc</VAR> only to those filenames for which the procedure +<VAR>pred</VAR> returns a non-false value. +</P> +<P> + +<A NAME="IDX1614"></A> +<DT><U>Function:</U> <B>directory-for-each</B> <I>proc directory match</I> +<DD>Applies <VAR>proc</VAR> only to those filenames for which +<CODE>(filename:match?? <VAR>match</VAR>)</CODE> would return a non-false value +(see section `Filenames' in <CITE>SLIB</CITE>). +</P> +<P> + +<TABLE><tr><td> </td><td class=example><pre>(require 'directory) +(directory-for-each print "." "[A-Z]*.scm") +-| +"Bev2slib.scm" +"Template.scm" +</pre></td></tr></table></DL> +<P> + +<A NAME="Transactions"></A> +<HR SIZE="6"> +<A NAME="SEC271"></A> +<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0> +<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC270"> < </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC275"> > </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC183"> << </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC269"> Up </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_8.html#SEC277"> >> </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib.html#SEC_Top">Top</A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_toc.html#SEC_Contents">Contents</A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_abt.html#SEC_About"> ? </A>]</TD> +</TR></TABLE> +<H3> 7.6.2 Transactions </H3> +<!--docid::SEC271::--> +<P> + +If <CODE>system</CODE> is provided by the Scheme implementation, the +<EM>transact</EM> package provides functions for file-locking and +file-replacement transactions. +</P> +<P> + +<CODE>(require 'transact)</CODE> +<A NAME="IDX1615"></A> +</P> +<P> + +<A NAME="SEC272"></A> +<H4> File Locking </H4> +<!--docid::SEC272::--> +<P> + +Unix file-locking is focussed on write permissions for segments of a +existing file. While this might be employed for (binary) database +access, it is not used for everyday contention (between users) for +text files. +</P> +<P> + +Microsoft has several file-locking protocols. Their model denies +write access to a file if any reader has it open. This is too +restrictive. Write access is denied even when the reader has +reached end-of-file. And tracking read access (which is much more +common than write access) causes havoc when remote hosts crash or +disconnect. +</P> +<P> + +It is bizarre that the concept of multi-user contention for +modifying files has not been adequately addressed by either of the +large operating system development efforts. There is further irony +that both camps support contention detection and resolution only +through weak conventions of some their document editing programs. +</P> +<P> + +<A NAME="IDX1616"></A> +The <EM>file-lock</EM> procedures implement a transaction method for file +<A NAME="IDX1617"></A> +replacement compatible with the methods used by the GNU <EM>emacs</EM> +<A NAME="IDX1618"></A> +text editor on Unix systems and the Microsoft <EM>Word</EM> editor. +<A NAME="IDX1619"></A> +<A NAME="IDX1620"></A> +</P> +<P> + +<A NAME="IDX1621"></A> +Both protocols employ what I term a <EM>certificate</EM> containing the +<A NAME="IDX1622"></A> +user, hostname, time, and (on Unix) process-id. +Intent to replace <VAR>file</VAR> is indicated by adding to <VAR>file</VAR>'s +directory a certificate object whose name is derived from +<VAR>file</VAR>. +</P> +<P> + +The Microsoft Word certificate is contained in a 162 byte file named +for the visited <VAR>file</VAR> with a `<SAMP>~$</SAMP>' prefix. +Emacs/Unix creates a symbolic link to a certificate named for the +visited <VAR>file</VAR> prefixed with `<SAMP>.#</SAMP>'. +Because Unix systems can import Microsoft file systems, these +routines maintain and check both Emacs and Word certificates. +</P> +<P> + +<A NAME="IDX1623"></A> +</P> +<DL> +<DT><U>Function:</U> <B>file-lock-owner</B> <I>path</I> +<DD><P> + +Returns the string `<SAMP><VAR>user</VAR>@<VAR>hostname</VAR></SAMP>' associated with +the lock owner of file <VAR>path</VAR> if locked; and #f otherwise. +</P> +</DL> +<P> + +<A NAME="IDX1624"></A> +</P> +<DL> +<DT><U>Procedure:</U> <B>file-lock!</B> <I>path email</I> +<DD><P> + +<A NAME="IDX1625"></A> +<DT><U>Procedure:</U> <B>file-lock!</B> <I>path</I> +<DD></P> +<P> + +<VAR>path</VAR> must be a string naming the file to be locked. If supplied, <VAR>email</VAR> +must be a string formatted as `<SAMP><VAR>user</VAR>@<VAR>hostname</VAR></SAMP>'. If +absent, <VAR>email</VAR> defaults to the value returned by <CODE>user-email-address</CODE>. +</P> +<P> + +If <VAR>path</VAR> is already locked, then <CODE>file-lock!</CODE> returns `<SAMP>#f</SAMP>'. If <VAR>path</VAR> is +unlocked, then <CODE>file-lock!</CODE> returns the certificate string associated with the +new lock for file <VAR>path</VAR>. +</P> +</DL> +<P> + +<A NAME="IDX1626"></A> +</P> +<DL> +<DT><U>Procedure:</U> <B>file-unlock!</B> <I>path certificate</I> +<DD><P> + +<VAR>path</VAR> must be a string naming the file to be unlocked. <VAR>certificate</VAR> must be the +string returned by <CODE>file-lock!</CODE> for <VAR>path</VAR>. +</P> +<P> + +If <VAR>path</VAR> is locked with <VAR>certificate</VAR>, then <CODE>file-unlock!</CODE> removes the locks and returns +`<SAMP>#t</SAMP>'. Otherwise, <CODE>file-unlock!</CODE> leaves the file system unaltered and returns +`<SAMP>#f</SAMP>'. +</P> +</DL> +<A NAME="SEC273"></A> +<H4> File Transactions </H4> +<!--docid::SEC273::--> +<P> + +<A NAME="IDX1627"></A> +</P> +<DL> +<DT><U>Function:</U> <B>emacs:backup-name</B> <I>path backup-style</I> +<DD><P> + +<VAR>path</VAR> must be a string. <VAR>backup-style</VAR> must be a symbol. Depending on <VAR>backup-style</VAR>, <CODE>emacs:backup-name</CODE> +returns: +</P> +<DL COMPACT> +<DT>none +<DD>#f +<DT>simple +<DD>the string "<VAR>path</VAR>~" +<DT>numbered +<DD>the string "<VAR>path</VAR>.~<VAR>n</VAR>~", where <VAR>n</VAR> is one greater than the +highest number appearing in a filename matching "<VAR>path</VAR>.~*~". <VAR>n</VAR> +defauls to 1 when no filename matches. +<DT>existing +<DD>the string "<VAR>path</VAR>.~<VAR>n</VAR>~" if a numbered backup already exists in +this directory; otherwise. "<VAR>path</VAR>~" +<DT>orig +<DD>the string "<VAR>path</VAR>.orig" +<DT>bak +<DD>the string "<VAR>path</VAR>.bak" +</DL> +</DL> +<P> + +<A NAME="IDX1628"></A> +</P> +<DL> +<DT><U>Function:</U> <B>transact-file-replacement</B> <I>proc path backup-style certificate</I> +<DD><P> + +<A NAME="IDX1629"></A> +<DT><U>Function:</U> <B>transact-file-replacement</B> <I>proc path backup-style</I> +<DD></P> +<P> + +<A NAME="IDX1630"></A> +<DT><U>Function:</U> <B>transact-file-replacement</B> <I>proc path</I> +<DD></P> +<P> + +<VAR>path</VAR> must be a string naming an existing file. <VAR>backup-style</VAR> is one of the +symbols none, simple, numbered, existing, orig, +bak or #f; with meanings described above; or a string naming +the location of a backup file. <VAR>backup-style</VAR> defaults to #f. If supplied, +<VAR>certificate</VAR> is the certificate with which <VAR>path</VAR> is locked. +</P> +<P> + +<VAR>proc</VAR> must be a procedure taking two string arguments: +<UL> +<LI> +<VAR>path</VAR>, the original filename (to be read); and +<LI> +a temporary file-name. +</UL> +<P> + +If <VAR>path</VAR> is locked by other than <VAR>certificate</VAR>, or if <VAR>certificate</VAR> is supplied and <VAR>path</VAR> is not +locked, then <CODE>transact-file-replacement</CODE> returns #f. If <VAR>certificate</VAR> is not supplied, then, <CODE>transact-file-replacement</CODE> creates +temporary (Emacs and Word) locks for <VAR>path</VAR> during the transaction. The +lock status of <VAR>path</VAR> will be restored before <CODE>transact-file-replacement</CODE> returns. +</P> +<P> + +<CODE>transact-file-replacement</CODE> calls <VAR>proc</VAR> with <VAR>path</VAR> (which should not be modified) and a temporary +file path to be written. +If <VAR>proc</VAR> returns any value other than #t, then the file named by <VAR>path</VAR> +is not altered and <CODE>transact-file-replacement</CODE> returns #f. +Otherwise, <CODE>emacs:backup-name</CODE> is called with <VAR>path</VAR> and <VAR>backup-style</VAR>. If it +returns a string, then <VAR>path</VAR> is renamed to it. +</P> +<P> + +Finally, the temporary file is renamed <VAR>path</VAR>. +<CODE>transact-file-replacement</CODE> returns #t if <VAR>path</VAR> was successfully replaced; and #f otherwise. +</P> +</DL> +<A NAME="SEC274"></A> +<H4> Identification </H4> +<!--docid::SEC274::--> +<P> + +<A NAME="IDX1631"></A> +</P> +<DL> +<DT><U>Function:</U> <B>user-email-address</B> +<DD><P> + +<CODE>user-email-address</CODE> returns a string of the form `<SAMP>username@hostname</SAMP>'. If +this e-mail address cannot be obtained, #f is returned. +</P> +</DL> +<P> + +<A NAME="CVS"></A> +<HR SIZE="6"> +<A NAME="SEC275"></A> +<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0> +<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC271"> < </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC276"> > </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC183"> << </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC269"> Up </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_8.html#SEC277"> >> </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib.html#SEC_Top">Top</A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_toc.html#SEC_Contents">Contents</A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_abt.html#SEC_About"> ? </A>]</TD> +</TR></TABLE> +<H3> 7.6.3 CVS </H3> +<!--docid::SEC275::--> +<P> + +<CODE>(require 'cvs)</CODE> +<A NAME="IDX1632"></A> +</P> +<P> + +<A NAME="IDX1633"></A> +</P> +<DL> +<DT><U>Function:</U> <B>cvs-files</B> <I>directory/</I> +<DD>Returns a list of the local pathnames (with prefix <VAR>directory/</VAR>) of all +CVS controlled files in <VAR>directory/</VAR> and in <VAR>directory/</VAR>'s subdirectories. +</DL> +<P> + +<A NAME="IDX1634"></A> +</P> +<DL> +<DT><U>Function:</U> <B>cvs-directories</B> <I>directory/</I> +<DD>Returns a list of all of <VAR>directory/</VAR> and all <VAR>directory/</VAR>'s CVS controlled +subdirectories. +</DL> +<P> + +<A NAME="IDX1635"></A> +</P> +<DL> +<DT><U>Function:</U> <B>cvs-root</B> <I>path/</I> +<DD>Returns the (string) contents of <VAR>path/</VAR>CVS/Root; +or <CODE>(getenv "CVSROOT")</CODE> if Root doesn't exist. +</DL> +<P> + +<A NAME="IDX1636"></A> +</P> +<DL> +<DT><U>Function:</U> <B>cvs-repository</B> <I>directory/</I> +<DD>Returns the (string) contents of <VAR>directory/</VAR>CVS/Root appended +with <VAR>directory/</VAR>CVS/Repository; or #f if <VAR>directory/</VAR>CVS/Repository +doesn't exist. +</DL> +<P> + +<A NAME="IDX1637"></A> +</P> +<DL> +<DT><U>Procedure:</U> <B>cvs-set-root!</B> <I>new-root directory/</I> +<DD><P> + +Writes <VAR>new-root</VAR> to file CVS/Root of <VAR>directory/</VAR> and all its subdirectories. +</P> +</DL> +<P> + +<A NAME="IDX1638"></A> +</P> +<DL> +<DT><U>Function:</U> <B>cvs-vet</B> <I>directory/</I> +<DD><P> + +Signals an error if CVS/Repository or CVS/Root files in <VAR>directory/</VAR> or any +subdirectory do not match. +</P> +</DL> +<P> + +<A NAME="Extra-SLIB Packages"></A> +<HR SIZE="6"> +<A NAME="SEC276"></A> +<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0> +<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC275"> < </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_8.html#SEC277"> > </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC183"> << </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC183"> Up </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_8.html#SEC277"> >> </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib.html#SEC_Top">Top</A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_toc.html#SEC_Contents">Contents</A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_abt.html#SEC_About"> ? </A>]</TD> +</TR></TABLE> +<H2> 7.7 Extra-SLIB Packages </H2> +<!--docid::SEC276::--> +<P> + +Several Scheme packages have been written using SLIB. There are several +reasons why a package might not be included in the SLIB distribution: +<UL> +<LI> +Because it requires special hardware or software which is not universal. +<LI> +Because it is large and of limited interest to most Scheme users. +<LI> +Because it has copying terms different enough from the other SLIB +packages that its inclusion would cause confusion. +<LI> +Because it is an application program, rather than a library module. +<LI> +Because I have been too busy to integrate it. +</UL> +<P> + +Once an optional package is installed (and an entry added to +<CODE>*catalog*</CODE>, the <CODE>require</CODE> mechanism allows it to be called up +and used as easily as any other SLIB package. Some optional packages +(for which <CODE>*catalog*</CODE> already has entries) available from SLIB +sites are: +</P> +<P> + +</P> +<DL COMPACT> +<DT>SLIB-PSD +<DD>is a portable debugger for Scheme (requires emacs editor). +<P> + +<A HREF="http://swissnet.ai.mit.edu/ftpdir/scm/slib-psd1-3.tar.gz"> +http://swissnet.ai.mit.edu/ftpdir/scm/slib-psd1-3.tar.gz +</A> +</P> +<P> + +swissnet.ai.mit.edu:/pub/scm/slib-psd1-3.tar.gz +</P> +<P> + +ftp.maths.tcd.ie:pub/bosullvn/jacal/slib-psd1-3.tar.gz +</P> +<P> + +ftp.cs.indiana.edu:/pub/scheme-repository/utl/slib-psd1-3.tar.gz +</P> +<P> + +With PSD, you can run a Scheme program in an Emacs buffer, set +breakpoints, single step evaluation and access and modify the program's +variables. It works by instrumenting the original source code, so it +should run with any R4RS compliant Scheme. It has been tested with SCM, +Elk 1.5, and the sci interpreter in the Scheme->C system, but should +work with other Schemes with a minimal amount of porting, if at +all. Includes documentation and user's manual. Written by Pertti +Kellom\"aki, pk @ cs.tut.fi. The Lisp Pointers article describing PSD +(Lisp Pointers VI(1):15-23, January-March 1993) is available as +<A HREF="http://www.cs.tut.fi/staff/pk/scheme/psd/article/article.html"> +http://www.cs.tut.fi/staff/pk/scheme/psd/article/article.html +</A> +</P> +<P> + +</P> +<DT>SCHELOG +<DD>is an embedding of Prolog in Scheme.<BR> +<A HREF="http://www.ccs.neu.edu/~dorai/schelog/schelog.html"> +http://www.ccs.neu.edu/~dorai/schelog/schelog.html +</A> +<P> + +</P> +<DT>JFILTER +<DD>is a Scheme program which converts text among the JIS, EUC, and +Shift-JIS Japanese character sets.<BR> +<A HREF="http://www.sci.toyama-u.ac.jp/~iwao/Scheme/Jfilter/index.html"> +http://www.sci.toyama-u.ac.jp/~iwao/Scheme/Jfilter/index.html +</A> +</DL> +<P> + +<A NAME="About SLIB"></A> +<HR SIZE="6"> +<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0> +<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_7.html#SEC183"> << </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_8.html#SEC277"> >> </A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib.html#SEC_Top">Top</A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_toc.html#SEC_Contents">Contents</A>]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[Index]</TD> +<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="slib_abt.html#SEC_About"> ? </A>]</TD> +</TR></TABLE> +<BR> +<FONT SIZE="-1"> +This document was generated +by <I>Steve Langasek</I> on <I>January, 10 2005</I> +using <A HREF="http://texi2html.cvshome.org"><I>texi2html</I></A> +</FONT> + +</BODY> +</HTML> |