<!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>