316 lines
15 KiB
HTML
316 lines
15 KiB
HTML
|
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
|
||
|
<HTML>
|
||
|
<!-- HTML file produced from file: utilities.tex --
|
||
|
-- using Hyperlatex v 2.3.1 (c) Otfried Cheong--
|
||
|
-- on Emacs 19.34.1, Tue Feb 23 18:25:11 1999 -->
|
||
|
<HEAD>
|
||
|
<TITLE>Untitled</TITLE>
|
||
|
|
||
|
</HEAD><BODY>
|
||
|
|
||
|
|
||
|
<H1 ALIGN=CENTER>Scheme 48 User's Guide</H1>
|
||
|
<H2 ALIGN=CENTER>Richard A. Kelsey</H2>
|
||
|
<H3 ALIGN=CENTER>February 23, 1999</H3>
|
||
|
<H1><A NAME="1">ASCII character encoding</A></H1>
|
||
|
<P>These are in the structure <CODE>ascii</CODE>.
|
||
|
<UL><LI><CODE>(char->ascii<VAR> char</VAR>) -> <VAR>integer</VAR></CODE>
|
||
|
<LI><CODE>(ascii->char<VAR> integer</VAR>) -> <VAR>char</VAR></CODE>
|
||
|
</UL>
|
||
|
These are identical to <CODE>char->integer</CODE> and <CODE>integer->char</CODE> except that
|
||
|
they use the ASCII encoding.
|
||
|
<UL><LI><table border=0 cellspacing=0 cellpadding=0 width=80%>
|
||
|
<tr> <td><CODE>ascii-limit</CODE></td> <td align=right>integer</td></tr></table>
|
||
|
<LI><table border=0 cellspacing=0 cellpadding=0 width=80%>
|
||
|
<tr> <td><CODE>ascii-whitespaces</CODE></td> <td align=right>list of integers</td></tr></table>
|
||
|
</UL>
|
||
|
<CODE>Ascii-limit</CODE> is one more than the largest value that <CODE>char->ascii</CODE>
|
||
|
may return.
|
||
|
<CODE>Ascii-whitespaces</CODE> is a list of the ASCII values of whitespace characters
|
||
|
(space, tab, line feed, form feed, and carriage return).
|
||
|
<H1><A NAME="2">Bitwise integer operations</A></H1>
|
||
|
<P>These functions use the two's-complement representation for integers.
|
||
|
There is no limit to the number of bits in an integer.
|
||
|
They are in the structures <CODE>bitwise</CODE> and <CODE>big-scheme</CODE>.
|
||
|
<UL><LI><CODE>(bitwise-and<VAR> integer integer</VAR>) -> <VAR>integer</VAR></CODE>
|
||
|
<LI><CODE>(bitwise-ior<VAR> integer integer</VAR>) -> <VAR>integer</VAR></CODE>
|
||
|
<LI><CODE>(bitwise-xor<VAR> integer integer</VAR>) -> <VAR>integer</VAR></CODE>
|
||
|
<LI><CODE>(bitwise-not<VAR> integer</VAR>) -> <VAR>integer</VAR></CODE>
|
||
|
</UL>
|
||
|
These perform various logical operations on integers on a bit-by-bit
|
||
|
basis. `<CODE>ior</CODE>' is inclusive OR and `<CODE>xor</CODE>' is exclusive OR.
|
||
|
<UL><LI><CODE>(arithmetic-shift<VAR> integer bit-count</VAR>) -> <VAR>integer</VAR></CODE>
|
||
|
</UL>
|
||
|
Shifts the integer by the given bit count, which must be an integer,
|
||
|
shifting left for positive counts and right for negative ones.
|
||
|
Shifting preserves the integer's sign.
|
||
|
<H1><A NAME="3">Arrays</A></H1>
|
||
|
<P>These are N-dimensional, zero-based arrays and
|
||
|
are in the structure <CODE>arrays</CODE>.
|
||
|
<P>The array interface is derived from one written by Alan Bawden.
|
||
|
<UL><LI><CODE>(make-array<VAR> value dimension<I><sub>0</sub></I> ...</VAR>) -> <VAR>array</VAR></CODE>
|
||
|
<LI><CODE>(array<VAR> dimensions element<I><sub>0</sub></I> ...</VAR>) -> <VAR>array</VAR></CODE>
|
||
|
<LI><CODE>(copy-array<VAR> array</VAR>) -> <VAR>array</VAR></CODE>
|
||
|
</UL>
|
||
|
<CODE>Make-array</CODE> makes a new array with the given dimensions, each of which
|
||
|
must be a non-negative integer.
|
||
|
Every element is initially set to <CODE><VAR>value</VAR></CODE>.
|
||
|
<CODE>Array</CODE> Returns a new array with the given dimensions and elements.
|
||
|
<CODE><VAR>Dimensions</VAR></CODE> must be a list of non-negative integers,
|
||
|
The number of elements should be the equal to the product of the
|
||
|
dimensions.
|
||
|
The elements are stored in row-major order.
|
||
|
<BLOCKQUOTE><PRE>
|
||
|
(make-array 'a 2 3) <CODE>-></CODE> {Array 2 3}
|
||
|
|
||
|
(array '(2 3) 'a 'b 'c 'd 'e 'f)
|
||
|
<CODE>-></CODE> {Array 2 3}
|
||
|
</PRE></BLOCKQUOTE>
|
||
|
<P><CODE>Copy-array</CODE> returns a copy of <CODE><VAR>array</VAR></CODE>.
|
||
|
The copy is identical to the <CODE><VAR>array</VAR></CODE> but does not share storage with it.
|
||
|
<UL><LI><CODE>(array?<VAR> value</VAR>) -> <VAR>boolean</VAR></CODE>
|
||
|
</UL>
|
||
|
Returns <CODE>#t</CODE> if <CODE><VAR>value</VAR></CODE> is an array.
|
||
|
<UL><LI><CODE>(array-ref<VAR> array index<I><sub>0</sub></I> ...</VAR>) -> <VAR>value</VAR></CODE>
|
||
|
<LI><CODE>(array-set!<VAR> array value index<I><sub>0</sub></I> ...</VAR>)</CODE>
|
||
|
<LI><CODE>(array->vector<VAR> array</VAR>) -> <VAR>vector</VAR></CODE>
|
||
|
<LI><CODE>(array-dimensions<VAR> array</VAR>) -> <VAR>list</VAR></CODE>
|
||
|
</UL>
|
||
|
<CODE>Array-ref</CODE> returns the specified array element and <CODE>array-set!</CODE>
|
||
|
replaces the element with <CODE><VAR>value</VAR></CODE>.
|
||
|
<BLOCKQUOTE><PRE>
|
||
|
(let ((a (array '(2 3) 'a 'b 'c 'd 'e 'f)))
|
||
|
(let ((x (array-ref a 0 1)))
|
||
|
(array-set! a 'g 0 1)
|
||
|
(list x (array-ref a 0 1))))
|
||
|
<CODE>-></CODE> '(b g)
|
||
|
</PRE></BLOCKQUOTE>
|
||
|
<P><CODE>Array->vector</CODE> returns a vector containing the elements of <CODE><VAR>array</VAR></CODE>
|
||
|
in row-major order.
|
||
|
<CODE>Array-dimensions</CODE> returns the dimensions of
|
||
|
the array as a list.
|
||
|
<UL><LI><CODE>(make-shared-array<VAR> array linear-map dimension<I><sub>0</sub></I> ...</VAR>) -> <VAR>array</VAR></CODE>
|
||
|
</UL>
|
||
|
<CODE>Make-shared-array</CODE> makes a new array that shares storage with <CODE><VAR>array</VAR></CODE>
|
||
|
and uses <CODE><VAR>linear-map</VAR></CODE> to map indicies to elements.
|
||
|
<CODE><VAR>Linear-map</VAR></CODE> must accept as many arguments as the number of
|
||
|
<CODE><VAR>dimension</VAR></CODE>s given and must return a list of non-negative integers
|
||
|
that are valid indicies into <CODE><VAR>array</VAR></CODE>.
|
||
|
<BLOCKQUOTE><PRE>
|
||
|
(array-ref (make-shared-array a f i0 i1 ...)
|
||
|
j0 j1 ...)
|
||
|
</PRE></BLOCKQUOTE>
|
||
|
is equivalent to
|
||
|
<BLOCKQUOTE><PRE>
|
||
|
(apply array-ref a (f j0 j1 ...))
|
||
|
</PRE></BLOCKQUOTE>
|
||
|
<P>As an example, the following function makes the transpose of a two-dimensional
|
||
|
array:
|
||
|
<BLOCKQUOTE><PRE>
|
||
|
(define (transpose array)
|
||
|
(let ((dimensions (array-dimensions array)))
|
||
|
(make-shared-array array
|
||
|
(lambda (x y)
|
||
|
(list y x))
|
||
|
(cadr dimensions)
|
||
|
(car dimensions))))
|
||
|
|
||
|
(array->vector
|
||
|
(transpose
|
||
|
(array '(2 3) 'a 'b 'c 'd 'e 'f)))
|
||
|
<CODE>-></CODE> '(a d b e c f)
|
||
|
</PRE></BLOCKQUOTE>
|
||
|
<H1><A NAME="4">Records</A></H1>
|
||
|
<P>New types can be constructed using the <CODE>define-record-type</CODE> macro
|
||
|
from the <CODE>define-record-types</CODE> structure
|
||
|
The general syntax is:
|
||
|
<BLOCKQUOTE><PRE>
|
||
|
(define-record-type <CODE><VAR>tag</VAR></CODE> <CODE><VAR>type-name</VAR></CODE>
|
||
|
(<CODE><VAR>constructor-name</VAR></CODE> <CODE><VAR>field-tag</VAR></CODE> ...)
|
||
|
<CODE><VAR>predicate-name</VAR></CODE>
|
||
|
(<CODE><VAR>field-tag</VAR></CODE> <CODE><VAR>accessor-name</VAR></CODE> [<CODE><VAR>modifier-name</VAR></CODE>])
|
||
|
...)
|
||
|
</PRE></BLOCKQUOTE>
|
||
|
This makes the following definitions:
|
||
|
<UL><LI><table border=0 cellspacing=0 cellpadding=0 width=80%>
|
||
|
<tr> <td><CODE><CODE><VAR>type-name</VAR></CODE></CODE></td> <td align=right>type</td></tr></table>
|
||
|
<LI><CODE>(<CODE><VAR>constructor-name</VAR></CODE><VAR> field-init ...</VAR>) -> <VAR>type-name</VAR></CODE>
|
||
|
<LI><CODE>(<CODE><VAR>predicate-name</VAR></CODE><VAR> value</VAR>) -> <VAR>boolean</VAR></CODE>
|
||
|
<LI><CODE>(<CODE><VAR>accessor-name</VAR></CODE><VAR> type-name</VAR>) -> <VAR>value</VAR></CODE>
|
||
|
<LI><CODE>(<CODE><VAR>modifier-name</VAR></CODE><VAR> type-name value</VAR>)</CODE>
|
||
|
</UL>
|
||
|
<CODE><VAR>Type-name</VAR></CODE> is the record type itself, and can be used to
|
||
|
specify a print method (see below).
|
||
|
<CODE><VAR>Constructor-name</VAR></CODE> is a constructor that accepts values
|
||
|
for the fields whose tags are specified.
|
||
|
<CODE><VAR>Predicate-name</VAR></CODE> to a predicate that can returns <CODE>#t</CODE> for
|
||
|
elements of the type and <CODE>#f</CODE> for everything else.
|
||
|
The <CODE><VAR>accessor-name</VAR></CODE>s retrieve the values of fields,
|
||
|
and the <CODE><VAR>modifier-name</VAR></CODE>'s update them.
|
||
|
The <CODE><VAR>tag</VAR></CODE> is used in printing instances of the record type and
|
||
|
the field tags are used in the inspector and to match
|
||
|
constructor arguments with fields.
|
||
|
<UL><LI><CODE>(define-record-discloser<VAR> type discloser</VAR>)</CODE>
|
||
|
</UL>
|
||
|
<CODE>Define-record-discloser</CODE> determines how
|
||
|
records of type <CODE><VAR>type</VAR></CODE> are printed.
|
||
|
<CODE><VAR>Discloser</VAR></CODE> should be procedure which takes a single
|
||
|
record of type <CODE><VAR>type</VAR></CODE> and returns a list whose car is
|
||
|
a symbol.
|
||
|
The record will be printed as the value returned by <CODE><VAR>discloser</VAR></CODE>
|
||
|
with curly braces used instead of the usual parenthesis.
|
||
|
<P>For example
|
||
|
<BLOCKQUOTE><PRE>
|
||
|
(define-record-type pare :pare
|
||
|
(kons x y)
|
||
|
pare?
|
||
|
(x kar set-kar!)
|
||
|
(y kdr))
|
||
|
</PRE></BLOCKQUOTE>
|
||
|
defines <CODE>kons</CODE> to be a constructor, <CODE>kar</CODE> and <CODE>kdr</CODE> to be
|
||
|
accessors, <CODE>set-kar!</CODE> to be a modifier, and <CODE>pare?</CODE> to be a predicate
|
||
|
for a new type of object.
|
||
|
The type itself is named <CODE>:pare</CODE>.
|
||
|
<CODE>Pare</CODE> is a tag used in printing the new objects.
|
||
|
<P>By default, the new objects print as <CODE>#Pare</CODE>.
|
||
|
The print method can be modified using DEFINE-RECORD-DISCLOSER:
|
||
|
<BLOCKQUOTE><PRE>
|
||
|
(define-record-discloser :pare
|
||
|
(lambda (p) `(pare ,(kar p) ,(kdr p))))
|
||
|
</PRE></BLOCKQUOTE>
|
||
|
will cause the result of <CODE>(kons 1 2)</CODE> to print as
|
||
|
<CODE>#{pare 1 2}</CODE>.
|
||
|
<H1><A NAME="5">Finite record types</A></H1>
|
||
|
<P>The structure <CODE>finite-types</CODE> has
|
||
|
two macros for defining `finite' record types.
|
||
|
These are record types for which there are a fixed number of instances,
|
||
|
which are created when the record type is defined.
|
||
|
The syntax for the defining a finite type is:
|
||
|
<BLOCKQUOTE><PRE>
|
||
|
(define-finite-type <CODE><VAR>tag</VAR></CODE> <CODE><VAR>type-name</VAR></CODE>
|
||
|
(<CODE><VAR>field-tag</VAR></CODE> ...)
|
||
|
<CODE><VAR>predicate-name</VAR></CODE>
|
||
|
<CODE><VAR>vector-of-elements-name</VAR></CODE>
|
||
|
<CODE><VAR>name-accessor</VAR></CODE>
|
||
|
<CODE><VAR>index-accessor</VAR></CODE>
|
||
|
(<CODE><VAR>field-tag</VAR></CODE> <CODE><VAR>accessor-name</VAR></CODE> [<CODE><VAR>modifier-name</VAR></CODE>])
|
||
|
...
|
||
|
((<CODE><VAR>element-name</VAR></CODE> <CODE><VAR>field-value</VAR></CODE> ...)
|
||
|
...))
|
||
|
</PRE></BLOCKQUOTE>
|
||
|
This differs from <CODE>define-record-type</CODE> in the following ways:
|
||
|
<UL><LI>No name is specified for the constructor, but the field arguments
|
||
|
to the constructor are listed.
|
||
|
<LI>The <CODE><VAR>vector-of-elements-name</VAR></CODE> is added; it will be bound
|
||
|
to a vector containing all of the elements of the type.
|
||
|
These are constructed by applying the (unnamed) constructor to the
|
||
|
initial field values at the end of the form.
|
||
|
<LI>There are names for accessors for two required fields, name
|
||
|
and index.
|
||
|
These fields are not settable, and are not to be included
|
||
|
in the argument list for the constructor.
|
||
|
<LI>The form ends with the names and the initial field values for
|
||
|
the elements of the type.
|
||
|
The name must be first.
|
||
|
The remaining values must match the <CODE><VAR>field-tag</VAR></CODE>s in the constructor's
|
||
|
argument list.
|
||
|
<LI><CODE><VAR>Tag</VAR></CODE> is bound to a macro that maps <CODE><VAR>element-name</VAR></CODE>s to the
|
||
|
the corresponding element of the vector.
|
||
|
The name lookup is done at macro-expansion time.
|
||
|
</UL>
|
||
|
<BLOCKQUOTE><PRE>
|
||
|
(define-finite-type color :color
|
||
|
(red green blue)
|
||
|
color?
|
||
|
colors
|
||
|
color-name
|
||
|
color-index
|
||
|
(red color-red)
|
||
|
(green color-green)
|
||
|
(blue color-blue)
|
||
|
((white 255 255 255)
|
||
|
(black 0 0 0)
|
||
|
(yellow 255 255 0)
|
||
|
(maroon 176 48 96)))
|
||
|
|
||
|
(color-name (vector-ref colors 0)) <CODE>-></CODE> white
|
||
|
(color-name (color black)) <CODE>-></CODE> black
|
||
|
(color-index (color yellow)) <CODE>-></CODE> 2
|
||
|
(color-red (color maroon)) <CODE>-></CODE> 176
|
||
|
</PRE></BLOCKQUOTE>
|
||
|
<P>Enumerated types are finite types whose only fields are the name
|
||
|
and the index.
|
||
|
The syntax for defining an enumerated type is:
|
||
|
<BLOCKQUOTE><PRE>
|
||
|
(define-enumerated-type <CODE><VAR>tag</VAR></CODE> <CODE><VAR>type-name</VAR></CODE>
|
||
|
<CODE><VAR>predicate-name</VAR></CODE>
|
||
|
<CODE><VAR>vector-of-elements-name</VAR></CODE>
|
||
|
<CODE><VAR>name-accessor</VAR></CODE>
|
||
|
<CODE><VAR>index-accessor</VAR></CODE>
|
||
|
(<CODE><VAR>element-name</VAR></CODE> ...))
|
||
|
</PRE></BLOCKQUOTE>
|
||
|
In the absence of any additional fields, both the constructor argument
|
||
|
list and the initial field values are not required.
|
||
|
<P>The above example of a finite type can be pared down to the following
|
||
|
enumerated type:
|
||
|
<BLOCKQUOTE><PRE>
|
||
|
(define-enumerated-type color :color
|
||
|
color?
|
||
|
colors
|
||
|
color-name
|
||
|
color-index
|
||
|
(white black yellow maroon))
|
||
|
|
||
|
(color-name (vector-ref colors 0)) <CODE>-></CODE> white
|
||
|
(color-name (color black)) <CODE>-></CODE> black
|
||
|
(color-index (color yellow)) <CODE>-></CODE> 2
|
||
|
</PRE></BLOCKQUOTE>
|
||
|
<H1><A NAME="6">Hash tables</A></H1>
|
||
|
<P>These are generic hash tables, and are in the structure <CODE>tables</CODE>.
|
||
|
Strictly speaking they are more maps than tables, as every table has a
|
||
|
value for every possible key (for that type of table).
|
||
|
All but a finite number of those values are <CODE>#f</CODE>.
|
||
|
<UL><LI><CODE>(make-table<VAR></VAR>) -> <VAR>table</VAR></CODE>
|
||
|
<LI><CODE>(make-symbol-table<VAR></VAR>) -> <VAR>symbol-table</VAR></CODE>
|
||
|
<LI><CODE>(make-string-table<VAR></VAR>) -> <VAR>string-table</VAR></CODE>
|
||
|
<LI><CODE>(make-integer-table<VAR></VAR>) -> <VAR>integer-table</VAR></CODE>
|
||
|
<LI><CODE>(make-table-maker<VAR> compare-proc hash-proc</VAR>) -> <VAR>procedure</VAR></CODE>
|
||
|
<LI><CODE>(make-table-immutable!<VAR> table</VAR>)</CODE>
|
||
|
</UL>
|
||
|
The first four functions listed make various kinds of tables.
|
||
|
<CODE>Make-table</CODE> returns a table whose keys may be symbols, integer,
|
||
|
characters, booleans, or the empty list (these are also the values
|
||
|
that may be used in <CODE>case</CODE> expressions).
|
||
|
As with <CODE>case</CODE>, comparison is done using <CODE>eqv?</CODE>.
|
||
|
The comparison procedures used in symbol, string, and integer tables are
|
||
|
<CODE>eq?</CODE>, <CODE>string=?</CODE>, and <CODE>=</CODE>.
|
||
|
<P><CODE>Make-table-maker</CODE> takes two procedures as arguments and returns
|
||
|
a nullary table-making procedure.
|
||
|
<CODE><VAR>Compare-proc</VAR></CODE> should be a two-argument equality predicate.
|
||
|
<CODE><VAR>Hash-proc</VAR></CODE> should be a one argument procedure that takes a key
|
||
|
and returns a non-negative integer hash value.
|
||
|
If <CODE>(<CODE><VAR>compare-proc</VAR></CODE> <CODE><VAR>x</VAR></CODE> <CODE><VAR>y</VAR></CODE>)</CODE> returns true,
|
||
|
then <CODE>(= (<CODE><VAR>hash-proc</VAR></CODE> <CODE><VAR>x</VAR></CODE>) (<CODE><VAR>hash-proc</VAR></CODE> <CODE><VAR>y</VAR></CODE>))</CODE>
|
||
|
must also return true.
|
||
|
For example, <CODE>make-integer-table</CODE> could be defined
|
||
|
as <CODE>(make-table-maker = abs)</CODE>.
|
||
|
<P><CODE>Make-table-immutable!</CODE> prohibits future modification to its argument.
|
||
|
<UL><LI><CODE>(table?<VAR> value</VAR>) -> <VAR>boolean</VAR></CODE>
|
||
|
<LI><CODE>(table-ref<VAR> table key</VAR>) -> <VAR>value or <CODE>#f</CODE></VAR></CODE>
|
||
|
<LI><CODE>(table-set!<VAR> table key value</VAR>)</CODE>
|
||
|
<LI><CODE>(table-walk<VAR> procedure table</VAR>)</CODE>
|
||
|
</UL>
|
||
|
<CODE>Table?</CODE> is the predicate for tables.
|
||
|
<CODE>Table-ref</CODE> and <CODE>table-set!</CODE> access and modify the value of <CODE><VAR>key</VAR></CODE>
|
||
|
in <CODE><VAR>table</VAR></CODE>.
|
||
|
<CODE>Table-walk</CODE> applies <CODE><VAR>procedure</VAR></CODE>, which must accept two arguments,
|
||
|
to every associated key and non-<CODE>#f</CODE> value in <CODE>table</CODE>.
|
||
|
<UL><LI><CODE>(default-hash-function<VAR> value</VAR>) -> <VAR>integer</VAR></CODE>
|
||
|
<LI><CODE>(string-hash<VAR> string</VAR>) -> <VAR>integer</VAR></CODE>
|
||
|
</UL>
|
||
|
<CODE>default-hash-function</CODE> is the hash function used in the tables
|
||
|
returned by <CODE>make-table</CODE>, and <CODE>string-hash</CODE> it the one used
|
||
|
by <CODE>make-string-table</CODE>.
|
||
|
<HR >
|
||
|
</BODY></HTML>
|