too big to edit comfortably.
-# $Id: Makefile.in,v 1.6 2003/02/14 19:22:43 cph Exp $
+# $Id: Makefile.in,v 1.7 2003/04/15 03:29:18 cph Exp $
#
# Copyright 2000,2001,2002,2003 Massachusetts Institute of Technology
#
pdfdir = @pdfdir@
psdir = @psdir@
+SOURCES = \
+ scheme.texinfo \
+ associations.texi \
+ bit-strings.texi \
+ characters.texi \
+ environments.texi \
+ equivalence.texi \
+ error.texi \
+ gfdl.texinfo \
+ graphics.texi \
+ io.texi \
+ lists.texi \
+ misc-datatypes.texi \
+ numbers.texi \
+ os-interface.texi \
+ overview.texi \
+ procedures.texi \
+ special-forms.texi \
+ strings.texi \
+ vectors.texi \
+ win32-packaging.texi
+
INFO_TARGET = mit-scheme-ref.info
all: $(INFO_TARGET) scheme.html scheme.pdf scheme.ps
-$(INFO_TARGET): scheme.texinfo gfdl.texinfo
+$(INFO_TARGET): $(SOURCES)
rm -f $(INFO_TARGET)*
makeinfo --output=$(INFO_TARGET) scheme.texinfo
-scheme.html: scheme.texinfo gfdl.texinfo
+scheme.html: $(SOURCES)
rm -f scheme*.html
texi2html -split_chapter scheme.texinfo
-scheme.pdf: scheme.texinfo gfdl.texinfo
+scheme.pdf: $(SOURCES)
texi2pdf scheme.texinfo
scheme.ps: scheme.dvi
dvips -o $@ $^
-scheme.dvi: scheme.texinfo gfdl.texinfo
+scheme.dvi: $(SOURCES)
texi2dvi scheme.texinfo
AUX_SUFFIXES = aux log toc
--- /dev/null
+@c This file is part of the MIT/GNU Scheme Reference Manual.
+@c $Id: associations.texi,v 1.1 2003/04/15 03:29:22 cph Exp $
+
+@c Copyright 1991,1992,1993,1994,1995 Massachusetts Institute of Technology
+@c Copyright 1996,1997,1999,2000,2001 Massachusetts Institute of Technology
+@c Copyright 2002,2003 Massachusetts Institute of Technology
+@c See file scheme.texinfo for copying conditions.
+
+@node Associations, Procedures, Miscellaneous Datatypes, Top
+@chapter Associations
+
+MIT/GNU Scheme provides several mechanisms for associating objects with
+one another. Each of these mechanisms creates a link between one or
+more objects, called @dfn{keys}, and some other object, called a
+@dfn{datum}. Beyond this common idea, however, each of the mechanisms
+has various different properties that make it appropriate in different
+situations:
+
+@itemize @bullet
+@item
+@dfn{Association lists} are one of Lisp's oldest association mechanisms.
+Because they are made from ordinary pairs, they are easy to build and
+manipulate, and very flexible in use. However, the average lookup time
+for an association list is linear in the number of associations.
+
+@item
+@dfn{1D tables} have a very simple interface, making them easy to use,
+and offer the feature that they do not prevent their keys from being
+reclaimed by the garbage collector. Like association lists, their
+average lookup time is linear in the number of associations; but 1D
+tables aren't as flexible.
+
+@item
+@cindex property list
+@dfn{The association table} is MIT/GNU Scheme's equivalent to the
+@dfn{property lists} of Lisp. It has the advantages that the keys may
+be any type of object and that it does not prevent the keys from being
+reclaimed by the garbage collector. However, two linear-time lookups
+must be performed, one for each key, whereas for traditional property
+lists only one lookup is required for both keys.
+
+@item
+@dfn{Hash tables} are a powerful mechanism with constant-time access to
+large amounts of data. Hash tables are not as flexible as association
+lists, but because their access times are independent of the number of
+associations in the table, for most applications they are the mechanism
+of choice.
+
+@item
+@dfn{Balanced binary trees} are another association mechanism that is
+useful for applications in which the keys are ordered. Binary trees
+have access times that are proportional to the logarithm of the number
+of associations in the tree. While they aren't as fast as hash tables,
+they offer the advantage that the contents of the tree can be converted
+to a sorted alist in linear time. Additionally, two trees can be
+compared for equality in worst-case linear time.
+
+@item
+@dfn{Red-Black trees} are a kind of balanced binary tree. The
+implementation supports destructive insertion and deletion operations
+with a good constant factor.
+
+@item
+@dfn{Weight-Balanced trees} are a kind of balanced binary tree. The
+implementation provides non-destructive operations. There is a
+comprehensive set of operations, including: a constant-time size
+operation; many high-level operations such as the set operations union,
+intersection and difference; and indexing of elements by position.
+
+@end itemize
+
+@menu
+* Association Lists::
+* 1D Tables::
+* The Association Table::
+* Hash Tables::
+* Object Hashing::
+* Red-Black Trees::
+* Weight-Balanced Trees::
+@end menu
+
+@node Association Lists, 1D Tables, Associations, Associations
+@section Association Lists
+
+@comment **** begin CLTL ****
+@cindex association list (defn)
+@cindex list, association (defn)
+@cindex alist (defn)
+@cindex key, of association list element (defn)
+An @dfn{association list}, or @dfn{alist}, is a data structure used very
+frequently in Scheme. An alist is a list of pairs, each of which is
+called an @dfn{association}. The car of an association is called the
+@dfn{key}.
+
+An advantage of the alist representation is that an alist can be
+incrementally augmented simply by adding new entries to the front.
+Moreover, because the searching procedures @code{assv} et al.@: search the
+alist in order, new entries can ``shadow'' old entries. If an alist is
+viewed as a mapping from keys to data, then the mapping can be not only
+augmented but also altered in a non-destructive manner by adding new
+entries to the front of the alist.@footnote{This introduction is taken
+from @cite{Common Lisp, The Language}, second edition, p.@: 431.}
+@comment **** end CLTL ****
+
+@deffn procedure alist? object
+@cindex type predicate, for alist
+@findex list?
+Returns @code{#t} if @var{object} is an association list (including the
+empty list); otherwise returns @code{#f}. Any @var{object} satisfying this
+predicate also satisfies @code{list?}.
+@end deffn
+
+@deffn procedure assq object alist
+@deffnx procedure assv object alist
+@deffnx procedure assoc object alist
+@cindex searching, of alist
+@findex eq?
+@findex eqv?
+@findex equal?
+These procedures find the first pair in @var{alist} whose car field is
+@var{object}, and return that pair; the returned pair is always an
+@emph{element} of @var{alist}, @emph{not} one of the pairs from which
+@var{alist} is composed. If no pair in @var{alist} has @var{object} as
+its car, @code{#f} (n.b.: not the empty list) is returned. @code{assq}
+uses @code{eq?} to compare @var{object} with the car fields of the pairs
+in @var{alist}, while @code{assv} uses @code{eqv?} and @code{assoc} uses
+@code{equal?}.@footnote{Although they are often used as predicates,
+@code{assq}, @code{assv}, and @code{assoc} do not have question marks in
+their names because they return useful values rather than just @code{#t}
+or @code{#f}.}
+
+@example
+@group
+(define e '((a 1) (b 2) (c 3)))
+(assq 'a e) @result{} (a 1)
+(assq 'b e) @result{} (b 2)
+(assq 'd e) @result{} #f
+(assq (list 'a) '(((a)) ((b)) ((c)))) @result{} #f
+(assoc (list 'a) '(((a)) ((b)) ((c)))) @result{} ((a))
+(assq 5 '((2 3) (5 7) (11 13))) @result{} @r{unspecified}
+(assv 5 '((2 3) (5 7) (11 13))) @result{} (5 7)
+@end group
+@end example
+@end deffn
+
+@deffn procedure association-procedure predicate selector
+Returns an association procedure that is similar to @code{assv}, except
+that @var{selector} (a procedure of one argument) is used to select the
+key from the association, and @var{predicate} (an equivalence predicate)
+is used to compare the key to the given item. This can be used to make
+association lists whose elements are, say, vectors instead of pairs
+(also @pxref{Searching Lists}).
+
+For example, here is how @code{assv} could be implemented:
+
+@example
+(define assv (association-procedure eqv? car))
+@end example
+
+Another example is a ``reverse association'' procedure:
+
+@example
+(define rassv (association-procedure eqv? cdr))
+@end example
+@end deffn
+
+@deffn procedure del-assq object alist
+@deffnx procedure del-assv object alist
+@deffnx procedure del-assoc object alist
+@cindex deletion, of alist element
+@findex eq?
+@findex eqv?
+@findex equal?
+These procedures return a newly allocated copy of @var{alist} in which
+all associations with keys equal to @var{object} have been removed.
+Note that while the returned copy is a newly allocated list, the
+association pairs that are the elements of the list are shared with
+@var{alist}, not copied. @code{del-assq} uses @code{eq?} to compare
+@var{object} with the keys, while @code{del-assv} uses @code{eqv?} and
+@code{del-assoc} uses @code{equal?}.
+
+@example
+@group
+(define a
+ '((butcher . "231 e22nd St.")
+ (baker . "515 w23rd St.")
+ (hardware . "988 Lexington Ave.")))
+
+(del-assq 'baker a)
+ @result{}
+ ((butcher . "231 e22nd St.")
+ (hardware . "988 Lexington Ave."))
+@end group
+@end example
+@end deffn
+
+@deffn procedure del-assq! object alist
+@deffnx procedure del-assv! object alist
+@deffnx procedure del-assoc! object alist
+@findex eq?
+@findex eqv?
+@findex equal?
+These procedures remove from @var{alist} all associations with keys
+equal to @var{object}. They return the resulting list.
+@code{del-assq!} uses @code{eq?} to compare @var{object} with the keys,
+while @code{del-assv!} uses @code{eqv?} and @code{del-assoc!} uses
+@code{equal?}. These procedures are like @code{del-assq},
+@code{del-assv}, and @code{del-assoc}, respectively, except that they
+destructively modify @var{alist}.
+@end deffn
+
+@deffn procedure delete-association-procedure deletor predicate selector
+@findex list-deletor
+@findex list-deletor!
+This returns a deletion procedure similar to @code{del-assv} or
+@code{del-assq!}. The @var{predicate} and @var{selector} arguments are
+the same as those for @code{association-procedure}, while the
+@var{deletor} argument should be either the procedure
+@code{list-deletor} (for non-destructive deletions), or the procedure
+@code{list-deletor!} (for destructive deletions).
+
+For example, here is a possible implementation of @code{del-assv}:
+
+@example
+@group
+(define del-assv
+ (delete-association-procedure list-deletor eqv? car))
+@end group
+@end example
+@end deffn
+
+@deffn procedure alist-copy alist
+@cindex copying, of alist
+@findex list-copy
+Returns a newly allocated copy of @var{alist}. This is similar to
+@code{list-copy} except that the ``association'' pairs, i.e.@: the
+elements of the list @var{alist}, are also copied. @code{alist-copy}
+could have been implemented like this:
+
+@example
+@group
+(define (alist-copy alist)
+ (if (null? alist)
+ '()
+ (cons (cons (car (car alist)) (cdr (car alist)))
+ (alist-copy (cdr alist)))))
+@end group
+@end example
+@end deffn
+
+@node 1D Tables, The Association Table, Association Lists, Associations
+@section 1D Tables
+
+@cindex 1D table (defn)
+@cindex one-dimensional table (defn)
+@cindex table, one-dimensional (defn)
+@cindex weak pair, and 1D table
+@dfn{1D tables} (``one-dimensional'' tables) are similar to association
+lists. In a 1D table, unlike an association list, the keys of the table
+are held @dfn{weakly}: if a key is garbage-collected, its associated
+value in the table is removed. 1D tables compare their keys for
+equality using @code{eq?}.
+
+@cindex property list
+1D tables can often be used as a higher-performance alternative to the
+two-dimensional association table (@pxref{The Association Table}). If
+one of the keys being associated is a compound object such as a vector,
+a 1D table can be stored in one of the vector's slots. Under these
+circumstances, accessing items in a 1D table will be comparable in
+performance to using a property list in a conventional Lisp.
+
+@deffn procedure make-1d-table
+Returns a newly allocated empty 1D table.
+@end deffn
+
+@deffn procedure 1d-table? object
+@cindex type predicate, for 1D table
+@findex list?
+Returns @code{#t} if @var{object} is a 1D table, otherwise returns
+@code{#f}. Any object that satisfies this predicate also satisfies
+@code{list?}.
+@end deffn
+
+@deffn procedure 1d-table/put! 1d-table key datum
+Creates an association between @var{key} and @var{datum} in
+@var{1d-table}. Returns an unspecified value.
+@end deffn
+
+@deffn procedure 1d-table/remove! 1d-table key
+Removes any association for @var{key} in @var{1d-table} and returns an
+unspecified value.
+@end deffn
+
+@deffn procedure 1d-table/get 1d-table key default
+Returns the @var{datum} associated with @var{key} in @var{1d-table}. If
+there is no association for @var{key}, @var{default} is returned.
+@end deffn
+
+@deffn procedure 1d-table/lookup 1d-table key if-found if-not-found
+@var{If-found} must be a procedure of one argument, and
+@var{if-not-found} must be a procedure of no arguments. If
+@var{1d-table} contains an association for @var{key}, @var{if-found} is
+invoked on the @var{datum} of the association. Otherwise,
+@var{if-not-found} is invoked with no arguments. In either case, the
+result of the invoked procedure is returned as the result of
+@code{1d-table/lookup}.
+@end deffn
+
+@deffn procedure 1d-table/alist 1d-table
+Returns a newly allocated association list that contains the same
+information as @var{1d-table}.
+@end deffn
+
+@node The Association Table, Hash Tables, 1D Tables, Associations
+@section The Association Table
+
+@cindex association table (defn)
+@cindex table, association (defn)
+@cindex property list
+@findex eq?
+MIT/GNU Scheme provides a generalization of the property-list mechanism
+found in most other implementations of Lisp: a global two-dimensional
+@dfn{association table}. This table is indexed by two keys, called
+@var{x-key} and @var{y-key} in the following procedure descriptions.
+These keys and the datum associated with them can be arbitrary objects.
+@code{eq?} is used to discriminate keys.
+
+Think of the association table as a matrix: a single datum can be
+accessed using both keys, a column using @var{x-key} only, and a row
+using @var{y-key} only.
+
+@deffn procedure 2d-put! x-key y-key datum
+Makes an entry in the association table that associates @var{datum} with
+@var{x-key} and @var{y-key}. Returns an unspecified result.
+@end deffn
+
+@deffn procedure 2d-remove! x-key y-key
+If the association table has an entry for @var{x-key} and @var{y-key},
+it is removed. Returns an unspecified result.
+@end deffn
+
+@deffn procedure 2d-get x-key y-key
+Returns the @var{datum} associated with @var{x-key} and @var{y-key}.
+Returns @code{#f} if no such association exists.
+@end deffn
+
+@deffn procedure 2d-get-alist-x x-key
+Returns an association list of all entries in the association table that
+are associated with @var{x-key}. The result is a list of
+@code{(@var{y-key} . @var{datum})} pairs. Returns the empty list if no
+entries for @var{x-key} exist.
+
+@example
+@group
+(2d-put! 'foo 'bar 5)
+(2d-put! 'foo 'baz 6)
+(2d-get-alist-x 'foo) @result{} ((baz . 6) (bar . 5))
+@end group
+@end example
+@end deffn
+
+@deffn procedure 2d-get-alist-y y-key
+Returns an association list of all entries in the association table that
+are associated with @var{y-key}. The result is a list of
+@code{(@var{x-key} . @var{datum})} pairs. Returns the empty list if no
+entries for @var{y-key} exist.
+
+@example
+@group
+(2d-put! 'bar 'foo 5)
+(2d-put! 'baz 'foo 6)
+(2d-get-alist-y 'foo) @result{} ((baz . 6) (bar . 5))
+@end group
+@end example
+@end deffn
+
+@node Hash Tables, Object Hashing, The Association Table, Associations
+@section Hash Tables
+
+@cindex hash table
+Hash tables are a fast, powerful mechanism for storing large numbers of
+associations. MIT/GNU Scheme's hash tables feature automatic resizing,
+customizable growth parameters, and customizable hash procedures.
+
+The average times for the insertion, deletion, and lookup operations on
+a hash table are bounded by a constant. The space required by the table
+is proportional to the number of associations in the table; the
+constant of proportionality is described below (@pxref{Resizing of Hash
+Tables}).
+
+(Previously, the hash-table implementation was a run-time-loadable
+option, but as of release 7.7.0 it is loaded by default. It's no longer
+necessary to call @code{load-option} prior to using hash tables.)
+
+@menu
+* Construction of Hash Tables::
+* Basic Hash Table Operations::
+* Resizing of Hash Tables::
+* Address Hashing::
+* Low-Level Hash Table Operations::
+@end menu
+
+@node Construction of Hash Tables, Basic Hash Table Operations, Hash Tables, Hash Tables
+@subsection Construction of Hash Tables
+
+@cindex construction, of hash table
+The next few procedures are hash-table constructors. All hash table
+constructors are procedures that accept one optional argument,
+@var{initial-size}, and return a newly allocated hash table. If
+@var{initial-size} is given, it must be an exact non-negative integer or
+@code{#f}. The meaning of @var{initial-size} is discussed below
+(@pxref{Resizing of Hash Tables}).
+
+@cindex equivalence predicate, of hash table
+@cindex strongly held keys, of hash table
+@cindex weakly held keys, of hash table
+Hash tables are normally characterized by two things: the equivalence
+predicate that is used to compare keys, and whether or not the table
+allows its keys to be reclaimed by the garbage collector. If a table
+prevents its keys from being reclaimed by the garbage collector, it is
+said to hold its keys @dfn{strongly}; otherwise it holds its keys
+@dfn{weakly} (@pxref{Weak Pairs}).
+
+@deffn procedure make-eq-hash-table [initial-size]
+@findex eq?
+Returns a newly allocated hash table that accepts arbitrary objects as
+keys, and compares those keys with @code{eq?}. The keys are held
+weakly. These are the fastest of the standard hash tables.
+@end deffn
+
+@deffn procedure make-eqv-hash-table [initial-size]
+@findex eqv?
+Returns a newly allocated hash table that accepts arbitrary objects as
+keys, and compares those keys with @code{eqv?}. The keys are held
+weakly, except that booleans, characters, and numbers are held strongly.
+These hash tables are a little slower than those made by
+@code{make-eq-hash-table}.
+@end deffn
+
+@deffn procedure make-equal-hash-table [initial-size]
+@findex equal?
+Returns a newly allocated hash table that accepts arbitrary objects as
+keys, and compares those keys with @code{equal?}. The keys are held
+strongly. These hash tables are quite a bit slower than those made by
+@code{make-eq-hash-table}.
+@end deffn
+
+@deffn procedure make-string-hash-table [initial-size]
+@findex string=?
+Returns a newly allocated hash table that accepts character strings as
+keys, and compares them with @code{string=?}. The keys are held
+strongly.
+@end deffn
+
+The next two procedures are used to create new hash-table constructors.
+All of the above hash table constructors, with the exception of
+@code{make-eqv-hash-table}, could have been created by calls to these
+``constructor-constructors''; see the examples below.
+
+@deffn procedure strong-hash-table/constructor key-hash key=? [rehash-after-gc?]
+@deffnx procedure weak-hash-table/constructor key-hash key=? [rehash-after-gc?]
+@cindex hashing, of key in hash table
+@cindex modulus, of hashing procedure
+Each of these procedures accepts two arguments and returns a hash-table
+constructor. The @var{key=?} argument is an equivalence predicate for
+the keys of the hash table. The @var{key-hash} argument is a procedure
+that computes a hash number. Specifically, @var{key-hash} accepts two
+arguments, a key and an exact positive integer (the @dfn{modulus}), and
+returns an exact non-negative integer that is less than the modulus.
+
+The optional argument @var{rehash-after-gc?}, if true, says that the
+values returned by @var{key-hash} might change after a garbage
+collection. If so, the hash-table implementation arranges for the table
+to be rehashed when necessary. (@xref{Address Hashing}, for
+information about hash procedures that have this property.) Otherwise,
+it is assumed that @var{key-hash} always returns the same value for the
+same arguments. The default value of this argument is @code{#f}.
+
+The constructors returned by @code{strong-hash-table/constructor} make
+hash tables that hold their keys strongly. The constructors returned by
+@code{weak-hash-table/constructor} make hash tables that hold their keys
+weakly.
+@end deffn
+
+Some examples showing how some standard hash-table constructors could have
+been defined:
+
+@findex eq-hash-mod
+@findex eq?
+@findex equal-hash-mod
+@findex equal?
+@findex string-hash-mod
+@findex string=?
+@example
+@group
+(define make-eq-hash-table
+ (weak-hash-table/constructor eq-hash-mod eq? #t))
+
+(define make-equal-hash-table
+ (strong-hash-table/constructor equal-hash-mod equal? #t))
+
+(define make-string-hash-table
+ (strong-hash-table/constructor string-hash-mod string=? #f))
+@end group
+@end example
+
+The following procedure is sometimes useful in conjunction with weak
+hash tables. Normally it is not needed, because such hash tables clean
+themselves automatically as they are used.
+
+@deffn procedure hash-table/clean! hash-table
+If @var{hash-table} is a type of hash table that holds its @var{key}s
+weakly, this procedure recovers any space that was being used to record
+associations for objects that have been reclaimed by the garbage
+collector. Otherwise, this procedure does nothing. In either case, it
+returns an unspecified result.
+@end deffn
+
+@node Basic Hash Table Operations, Resizing of Hash Tables, Construction of Hash Tables, Hash Tables
+@subsection Basic Hash Table Operations
+
+The procedures described in this section are the basic operations on
+hash tables. They provide the functionality most often needed by
+programmers. Subsequent sections describe other operations that provide
+additional functionality needed by some applications.
+
+@deffn procedure hash-table? object
+@cindex type predicate, for hash table
+Returns @code{#t} if @var{object} is a hash table, otherwise returns
+@code{#f}.
+@end deffn
+
+@deffn procedure hash-table/put! hash-table key datum
+Associates @var{datum} with @var{key} in @var{hash-table} and returns an
+unspecified result. The average time required by this operation is
+bounded by a constant.
+@end deffn
+
+@deffn procedure hash-table/get hash-table key default
+Returns the datum associated with @var{key} in @var{hash-table}. If
+there is no association for @var{key}, @var{default} is returned. The
+average time required by this operation is bounded by a constant.
+@end deffn
+
+@deffn procedure hash-table/remove! hash-table key
+If @var{hash-table} has an association for @var{key}, removes it.
+Returns an unspecified result. The average time required by this
+operation is bounded by a constant.
+@end deffn
+
+@deffn procedure hash-table/clear! hash-table
+Removes all associations in @var{hash-table} and returns an unspecified
+result. The average and worst-case times required by this operation are
+bounded by a constant.
+@end deffn
+
+@deffn procedure hash-table/count hash-table
+Returns the number of associations in @var{hash-table} as an exact
+non-negative integer. If @var{hash-table} holds its keys weakly, this
+is a conservative upper bound that may count some associations whose
+keys have recently been reclaimed by the garbage collector. The average
+and worst-case times required by this operation are bounded by a
+constant.
+@end deffn
+
+@deffn procedure hash-table->alist hash-table
+Returns the contents of @var{hash-table} as a newly allocated alist.
+Each element of the alist is a pair @code{(@var{key} . @var{datum})}
+where @var{key} is one of the keys of @var{hash-table}, and @var{datum}
+is its associated datum. The average and worst-case times required by
+this operation are linear in the number of associations
+in the table.
+@end deffn
+
+@deffn procedure hash-table/key-list hash-table
+Returns a newly allocated list of the keys in @var{hash-table}. The
+average and worst-case times required by this operation are linear in
+the number of associations in the table.
+@end deffn
+
+@deffn procedure hash-table/datum-list hash-table
+Returns a newly allocated list of the datums in @var{hash-table}. Each
+element of the list corresponds to one of the associations in
+@var{hash-table}; if the table contains multiple associations with the
+same datum, so will this list. The average and worst-case times
+required by this operation are linear in the number of associations in
+the table.
+@end deffn
+
+@deffn procedure hash-table/for-each hash-table procedure
+@var{Procedure} must be a procedure of two arguments. Invokes
+@var{procedure} once for each association in @var{hash-table}, passing
+the association's @var{key} and @var{datum} as arguments, in that order.
+Returns an unspecified result. @var{Procedure} must not modify
+@var{hash-table}, with one exception: it is permitted to call
+@code{hash-table/remove!} to remove the association being processed.
+@end deffn
+
+The following procedure is an alternate form of @code{hash-table/get}
+that is useful in some situations. Usually, @code{hash-table/get} is
+preferable because it is faster.
+
+@deffn procedure hash-table/lookup hash-table key if-found if-not-found
+@var{If-found} must be a procedure of one argument, and
+@var{if-not-found} must be a procedure of no arguments. If
+@var{hash-table} contains an association for @var{key}, @var{if-found}
+is invoked on the datum of the association. Otherwise,
+@var{if-not-found} is invoked with no arguments. In either case, the
+result yielded by the invoked procedure is returned as the result of
+@code{hash-table/lookup} (@code{hash-table/lookup} @emph{reduces} into
+the invoked procedure, i.e.@: calls it tail-recursively). The average
+time required by this operation is bounded by a constant.
+@end deffn
+
+@node Resizing of Hash Tables, Address Hashing, Basic Hash Table Operations, Hash Tables
+@subsection Resizing of Hash Tables
+
+@cindex resizing, of hash table
+@cindex size, of hash table (defn)
+Normally, hash tables automatically resize themselves according to need.
+Because of this, the programmer need not be concerned with management of
+the table's size. However, some limited control over the table's size
+is provided, which will be discussed below. This discussion involves
+two concepts, @dfn{usable size} and @dfn{physical size}, which we will
+now define.
+
+@cindex usable size, of hash table (defn)
+The @dfn{usable size} of a hash table is the number of associations that
+the table can hold at a given time. If the number of associations in
+the table exceeds the usable size, the table will automatically grow,
+increasing the usable size to a new value that is sufficient to hold the
+associations.
+
+@cindex physical size, of hash table (defn)
+The @dfn{physical size} is an abstract measure of a hash table that
+specifies how much space is allocated to hold the associations of the
+table. The physical size is always greater than or equal to the usable
+size. The physical size is not interesting in itself; it is interesting
+only for its effect on the performance of the hash table. While the
+average performance of a hash-table lookup is bounded by a constant, the
+worst-case performance is not. For a table containing a given number of
+associations, increasing the physical size of the table decreases the
+probability that worse-than-average performance will occur.
+
+The physical size of a hash table is statistically related to the number
+of associations. However, it is possible to place bounds on the
+physical size, and from this to estimate the amount of space used by the
+table:
+
+@example
+@group
+(define (hash-table-space-bounds count rehash-size rehash-threshold)
+ (let ((tf (/ 1 rehash-threshold)))
+ (values (if (exact-integer? rehash-size)
+ (- (* count (+ 4 tf))
+ (* tf (+ rehash-size rehash-size)))
+ (* count (+ 4 (/ tf (* rehash-size rehash-size)))))
+ (* count (+ 4 tf)))))
+@end group
+@end example
+
+@noindent
+What this formula shows is that, for a ``normal'' rehash size (that is,
+not an exact integer), the amount of space used by the hash table is
+proportional to the number of associations in the table. The constant
+of proportionality varies statistically, with the low bound being
+
+@example
+(+ 4 (/ (/ 1 rehash-threshold) (* rehash-size rehash-size)))
+@end example
+
+@noindent
+and the high bound being
+
+@example
+(+ 4 (/ 1 rehash-threshold))
+@end example
+
+@noindent
+which, for the default values of these parameters, are @code{4.25} and
+@code{5}, respectively. Reducing the rehash size will tighten these
+bounds, but increases the amount of time spent resizing, so you can see
+that the rehash size gives some control over the time-space tradeoff of
+the table.
+
+The programmer can control the size of a hash table by means of three
+parameters:
+
+@itemize @bullet
+@item
+Each table's @var{initial-size} may be specified when the table is
+created.
+
+@item
+Each table has a @dfn{rehash size} that specifies how the size of the
+table is changed when it is necessary to grow or shrink the table.
+
+@item
+Each table has a @dfn{rehash threshold} that specifies the relationship
+of the table's physical size to its usable size.
+@end itemize
+
+@cindex initial size, of hash table
+If the programmer knows that the table will initially contain a specific
+number of items, @var{initial-size} can be given when the table is
+created. If @var{initial-size} is an exact non-negative integer, it
+specifies the initial usable size of the hash table; the table will not
+change size until the number of items in the table exceeds
+@var{initial-size}, after which automatic resizing is enabled and
+@var{initial-size} no longer has any effect. Otherwise, if
+@var{initial-size} is not given or is @code{#f}, the table is
+initialized to an unspecified size and automatic resizing is immediately
+enabled.
+
+@cindex rehash size, of hash table (defn)
+The @dfn{rehash size} specifies how much to increase the usable size of
+the hash table when it becomes full. It is either an exact positive
+integer, or a real number greater than one. If it is an integer, the
+new size is the sum of the old size and the rehash size. Otherwise, it
+is a real number, and the new size is the product of the old size and
+the rehash size. Increasing the rehash size decreases the average cost
+of an insertion, but increases the average amount of space used by the
+table. The rehash size of a table may be altered dynamically by the
+application in order to optimize the resizing of the table; for example,
+if the table will grow quickly for a known period and afterwards will
+not change size, performance might be improved by using a large rehash
+size during the growth phase and a small one during the static phase.
+The default rehash size of a newly constructed hash table is @code{2.0}.
+
+@strong{Warning}: The use of an exact positive integer for a rehash
+size is almost always undesirable; this option is provided solely for
+compatibility with the Common Lisp hash-table mechanism. The reason for
+this has to do with the time penalty for resizing the hash table. The
+time needed to resize a hash table is proportional to the
+number of associations in the table. This resizing cost is
+@dfn{amortized} across the insertions required to fill the table to the
+point where it needs to grow again. If the table grows by an amount
+proportional to the number of associations, then the cost of
+resizing and the increase in size are both proportional to the
+number of associations, so the @dfn{amortized cost} of an insertion
+operation is still bounded by a constant. However, if the table grows
+by a constant amount, this is not true: the amortized cost of an
+insertion is not bounded by a constant. Thus, using a constant rehash
+size means that the average cost of an insertion increases
+proportionally to the number of associations in the hash table.
+
+@cindex rehash threshold, of hash table (defn)
+The @dfn{rehash threshold} is a real number, between zero exclusive and
+one inclusive, that specifies the ratio between a hash table's usable
+size and its physical size. Decreasing the rehash threshold decreases
+the probability of worse-than-average insertion, deletion, and lookup
+times, but increases the physical size of the table for a given usable
+size. The default rehash threshold of a newly constructed hash table is
+@code{1}.
+
+@deffn procedure hash-table/size hash-table
+Returns the usable size of @var{hash-table} as an exact positive
+integer. This is the number of associations that @var{hash-table} can
+hold before it will grow.
+@end deffn
+
+@deffn procedure hash-table/rehash-size hash-table
+Returns the rehash size of @var{hash-table}.
+@end deffn
+
+@deffn procedure set-hash-table/rehash-size! hash-table x
+@var{X} must be either an exact positive integer, or a real number that
+is greater than one. Sets the rehash size of @var{hash-table} to
+@var{x} and returns an unspecified result. This operation adjusts the
+``shrink threshold'' of the table; the table might shrink if the number
+of associations is less than the new threshold.
+@end deffn
+
+@deffn procedure hash-table/rehash-threshold hash-table
+Returns the rehash threshold of @var{hash-table}.
+@end deffn
+
+@deffn procedure set-hash-table/rehash-threshold! hash-table x
+@var{X} must be a real number between zero exclusive and one inclusive.
+Sets the rehash threshold of @var{hash-table} to @var{x} and returns an
+unspecified result. This operation does not change the usable size of
+the table, but it usually changes the physical size of the table, which
+causes the table to be rehashed.
+@end deffn
+
+@node Address Hashing, Low-Level Hash Table Operations, Resizing of Hash Tables, Hash Tables
+@subsection Address Hashing
+@cindex address hashing
+
+The procedures described in this section may be used to make very
+efficient key-hashing procedures for arbitrary objects. All of these
+procedures are based on @dfn{address hashing}, which uses the address of
+an object as its hash number. The great advantage of address hashing is
+that converting an arbitrary object to a hash number is extremely fast
+and takes the same amount of time for any object.
+
+The disadvantage of address hashing is that the garbage collector
+changes the addresses of most objects. The hash-table implementation
+compensates for this disadvantage by automatically rehashing tables that
+use address hashing when garbage collections occur. Thus, in order to
+use these procedures for key hashing, it is necessary to tell the
+hash-table implementation (by means of the @var{rehash-after-gc?}
+argument to the ``constructor-constructor'' procedure) that the hash
+numbers computed by your key-hashing procedure must be recomputed after
+a garbage collection.
+
+@deffn procedure eq-hash object
+@deffnx procedure eqv-hash object
+@deffnx procedure equal-hash object
+These procedures return a hash number for @var{object}. The result is
+always a non-negative integer, and in the case of @code{eq-hash}, a
+non-negative fixnum. Two objects that are equivalent according to
+@code{eq?}, @code{eqv?}, or @code{equal?}, respectively, will produce the
+same hash number when passed as arguments to these procedures, provided
+that the garbage collector does not run during or between the two calls.
+@end deffn
+
+The following procedures are the key-hashing procedures used by the
+standard address-hash-based hash tables.
+
+@deffn procedure eq-hash-mod object modulus
+This procedure is the key-hashing procedure used by
+@code{make-eq-hash-table}.
+@end deffn
+
+@deffn procedure eqv-hash-mod object modulus
+This procedure is the key-hashing procedure used by
+@code{make-eqv-hash-table}.
+@end deffn
+
+@deffn procedure equal-hash-mod object modulus
+This procedure is the key-hashing procedure used by
+@code{make-equal-hash-table}.
+@end deffn
+
+@node Low-Level Hash Table Operations, , Address Hashing, Hash Tables
+@subsection Low-Level Hash Table Operations
+
+The procedures in this section allow the programmer to control some of
+the internal structure of a hash table. Normally, hash tables maintain
+associations between keys and datums using pairs or weak pairs. These
+procedures allow the programmer to specify the use of some other data
+structure to maintain the association. In this section, the data
+structure that represents an association in a hash table is called an
+@dfn{entry}.
+
+@deffn procedure hash-table/constructor key-hash key=? make-entry entry-valid? entry-key entry-datum set-entry-datum! [rehash-after-gc?]
+Creates and returns a hash-table constructor procedure
+(@pxref{Construction of Hash Tables}). The arguments define the
+characteristics of the hash table as follows:
+
+@table @var
+@item key-hash
+The hashing procedure. A procedure that accepts two arguments, a key and
+an exact positive integer (the @dfn{modulus}), and returns an exact
+non-negative integer that is less than the modulus.
+
+@item key=?
+A equivalence predicate that accepts two keys and is true iff they are
+the same key. If this predicate is true of two keys, then
+@var{key-hash} must return the same value for each of these keys (given
+the same modulus in both cases).
+
+@item make-entry
+A procedure that accepts a key and a datum as arguments and returns a
+newly allocated entry.
+
+@item entry-valid?
+A procedure that accepts an entry and returns @code{#f} iff the entry's
+key has been reclaimed by the garbage collector. Instead of a
+procedure, this may be @code{#t}, which is equivalent to @code{(lambda
+(entry) #t)}.
+@findex weak-pair/car?
+
+@item entry-key
+A procedure that accepts an entry as an argument and returns the entry's
+key.
+
+@item entry-datum
+A procedure that accepts an entry as an argument and returns the entry's
+datum.
+
+@item set-entry-datum!
+A procedure that accepts an entry and an object as arguments, modifies
+the entry's datum to be the object, and returns an unspecified
+result.
+
+@item rehash-after-gc?
+An optional argument that, if true, says the values returned by
+@var{key-hash} might change after a garbage collection. If so, the
+hash-table implementation arranges for the table to be rehashed when
+necessary. (@xref{Address Hashing}, for information about hash
+procedures that have this property.) Otherwise, it is assumed that
+@var{key-hash} always returns the same value for the same arguments.
+The default value of this argument is @code{#f}.
+@end table
+@end deffn
+
+@noindent
+For example, here is how the constructors for ordinary hash tables could
+be defined:
+
+@example
+@group
+(define (strong-hash-table/constructor key-hash key=?
+ #!optional rehash-after-gc?)
+ (hash-table/constructor key-hash key=?
+ cons #t car cdr set-cdr!
+ (if (default-object? rehash-after-gc?)
+ #f
+ rehash-after-gc?)))
+@end group
+
+@group
+(define (weak-hash-table/constructor key-hash key=?
+ #!optional rehash-after-gc?)
+ (hash-table/constructor key-hash key=? weak-cons weak-pair/car?
+ weak-car weak-cdr weak-set-cdr!
+ (if (default-object? rehash-after-gc?)
+ #f
+ rehash-after-gc?)))
+@end group
+@end example
+
+@deffn procedure hash-table/key-hash hash-table
+@deffnx procedure hash-table/key=? hash-table
+@deffnx procedure hash-table/make-entry hash-table
+@deffnx procedure hash-table/entry-valid? hash-table
+@deffnx procedure hash-table/entry-key hash-table
+@deffnx procedure hash-table/entry-datum hash-table
+@deffnx procedure hash-table/set-entry-datum! hash-table
+Each procedure returns the value of the corresponding argument that was
+used to construct @var{hash-table}.
+@end deffn
+
+The following procedures return the contents of a hash table as a
+collection of entries. While the data structure holding the entries is
+newly allocated, the entries themselves are not copied. Since hash
+table operations can modify these entries, the entries should be copied
+if it is desired to keep them while continuing to modify the table.
+
+@deffn procedure hash-table/entries-list hash-table
+Returns a newly allocated list of the entries in @var{hash-table}.
+@end deffn
+
+@deffn procedure hash-table/entries-vector hash-table
+Returns a newly allocated vector of the entries in @var{hash-table}.
+Equivalent to
+
+@example
+(list->vector (hash-table/entries-list @var{hash-table}))
+@end example
+@end deffn
+
+@node Object Hashing, Red-Black Trees, Hash Tables, Associations
+@section Object Hashing
+
+@cindex object hashing
+@cindex hashing, of object
+The MIT/GNU Scheme object-hashing facility provides a mechanism for
+generating a unique hash number for an arbitrary object. This hash
+number, unlike an object's address, is unchanged by garbage collection.
+The object-hashing facility is useful in conjunction with hash tables,
+but it may be used for other things as well. In particular, it is used
+in the generation of the written representation for many objects
+(@pxref{Custom Output}).
+
+All of these procedures accept an optional argument called @var{table};
+this table contains the object-integer associations. If given, this
+argument must be an object-hash table as constructed by
+@code{hash-table/make} (see below). If not given, a default table is
+used.
+
+@deffn procedure hash object [table]
+@findex eq?
+@code{hash} associates an exact non-negative integer with @var{object}
+and returns that integer. If @code{hash} was previously called with
+@var{object} as its argument, the integer returned is the same as was
+returned by the previous call. @code{hash} guarantees that distinct
+objects (in the sense of @code{eq?}) are associated with distinct
+integers.
+@end deffn
+
+@deffn procedure unhash k [table]
+@code{unhash} takes an exact non-negative integer @var{k} and returns
+the object associated with that integer. If there is no object
+associated with @var{k}, or if the object previously associated with
+@var{k} has been reclaimed by the garbage collector, an error of type
+@code{condition-type:bad-range-argument} is signalled. In other words,
+if @code{hash} previously returned @var{k} for some object, and that
+object has not been reclaimed, it is the value of the call to
+@code{unhash}.
+@findex condition-type:bad-range-argument
+@end deffn
+
+An object that is passed to @code{hash} as an argument is not protected
+from being reclaimed by the garbage collector. If all other references
+to that object are eliminated, the object will be reclaimed.
+Subsequently calling @code{unhash} with the hash number of the (now
+reclaimed) object will signal an error.
+
+@example
+@group
+(define x (cons 0 0)) @result{} @r{unspecified}
+(hash x) @result{} 77
+(eqv? (hash x) (hash x)) @result{} #t
+(define x 0) @result{} @r{unspecified}
+(gc-flip) @r{;force a garbage collection}
+(unhash 77) @error{}
+@end group
+@end example
+
+@deffn procedure object-hashed? object [table]
+This predicate is true if @var{object} has an associated hash number.
+Otherwise it is false.
+@end deffn
+
+@deffn procedure valid-hash-number? k [table]
+This predicate is true if @var{k} is the hash number associated with
+some object. Otherwise it is false.
+@end deffn
+
+The following two procedures provide a lower-level interface to the
+object-hashing mechanism.
+
+@deffn procedure object-hash object [table [insert?]]
+@findex eq?
+@code{object-hash} is like @code{hash}, except that it accepts an
+additional optional argument, @var{insert?}. If @var{insert?}@: is
+supplied and is @code{#f}, @code{object-hash} will return an integer for
+@var{object} only if there is already an association in the table;
+otherwise, it will return @code{#f}. If @var{insert?} is not supplied,
+or is not @code{#f}, @code{object-hash} always returns an integer,
+creating an association in the table if necessary.
+
+@code{object-hash} additionally treats @code{#f} differently than does
+@code{hash}. Calling @code{object-hash} with @code{#f} as its argument
+will return an integer that, when passed to @code{unhash}, will signal
+an error rather than returning @code{#f}. Likewise,
+@code{valid-hash-number?} will return @code{#f} for this integer.
+@end deffn
+
+@deffn procedure object-unhash k [table]
+@code{object-unhash} is like @code{unhash}, except that when @var{k} is
+not associated with any object or was previously associated with an
+object that has been reclaimed, @code{object-unhash} returns @code{#f}.
+This means that there is an ambiguity in the value returned by
+@code{object-unhash}: if @code{#f} is returned, there is no way to
+tell if @var{k} is associated with @code{#f} or is not associated with
+any object at all.
+@end deffn
+
+Finally, this procedure makes new object-hash tables:
+
+@deffn procedure hash-table/make
+This procedure creates and returns a new, empty object-hash table that
+is suitable for use as the optional @var{table} argument to the above
+procedures. The returned table contains no associations.
+@end deffn
+
+@node Red-Black Trees, Weight-Balanced Trees, Object Hashing, Associations
+@section Red-Black Trees
+
+@cindex trees, balanced binary
+@cindex balanced binary trees
+@cindex binary trees
+@cindex red-black binary trees
+Balanced binary trees are a useful data structure for maintaining large
+sets of associations whose keys are ordered. While most applications
+involving large association sets should use hash tables, some
+applications can benefit from the use of binary trees. Binary trees
+have two advantages over hash tables:
+
+@itemize @bullet
+@item
+The contents of a binary tree can be converted to an alist, sorted by
+key, in time proportional to the number of associations in the
+tree. A hash table can be converted into an unsorted alist in linear
+time; sorting it requires additional time.
+
+@item
+Two binary trees can be compared for equality in linear time. Hash
+tables, on the other hand, cannot be compared at all; they must be
+converted to alists before comparison can be done, and alist comparison
+is quadratic unless the alists are sorted.
+@end itemize
+
+MIT/GNU Scheme provides an implementation of @dfn{red-black} trees. The
+red-black tree-balancing algorithm provides generally good performance
+because it doesn't try to keep the tree very closely balanced. At any
+given node in the tree, one side of the node can be twice as high as the
+other in the worst case. With typical data the tree will remain fairly
+well balanced anyway.
+
+A red-black tree takes space that is proportional to the number of
+associations in the tree. For the current implementation, the constant
+of proportionality is eight words per association.
+
+Red-black trees hold their keys @dfn{strongly}. In other words, if a
+red-black tree contains an association for a given key, that key cannot
+be reclaimed by the garbage collector.
+
+@cindex run-time-loadable option
+@cindex option, run-time-loadable
+The red-black tree implementation is a run-time-loadable option. To use
+red-black trees, execute
+
+@example
+(load-option 'rb-tree)
+@end example
+@findex load-option
+
+@noindent
+once before calling any of the procedures defined here.
+
+@deffn procedure make-rb-tree key=? key<?
+This procedure creates and returns a newly allocated red-black tree.
+The tree contains no associations. @var{Key=?} and @var{key<?} are
+predicates that compare two keys and determine whether they are equal to
+or less than one another, respectively. For any two keys, at most one
+of these predicates is true.
+@end deffn
+
+@deffn procedure rb-tree? object
+Returns @code{#t} if @var{object} is a red-black tree, otherwise
+returns @code{#f}.
+@end deffn
+
+@deffn procedure rb-tree/insert! rb-tree key datum
+Associates @var{datum} with @var{key} in @var{rb-tree} and returns an
+unspecified value. If @var{rb-tree} already has an association for
+@var{key}, that association is replaced. The average and worst-case
+times required by this operation are proportional to the logarithm of
+the number of assocations in @var{rb-tree}.
+@end deffn
+
+@deffn procedure rb-tree/lookup rb-tree key default
+Returns the datum associated with @var{key} in @var{rb-tree}. If
+@var{rb-tree} doesn't contain an association for @var{key},
+@var{default} is returned. The average and worst-case times required by
+this operation are proportional to the logarithm of the number of
+assocations in @var{rb-tree}.
+@end deffn
+
+@deffn procedure rb-tree/delete! rb-tree key
+If @var{rb-tree} contains an association for @var{key}, removes it.
+Returns an unspecified value. The average and worst-case times required
+by this operation are proportional to the logarithm of the number of
+assocations in @var{rb-tree}.
+@end deffn
+
+@deffn procedure rb-tree->alist rb-tree
+Returns the contents of @var{rb-tree} as a newly allocated alist. Each
+element of the alist is a pair @code{(@var{key} . @var{datum})} where
+@var{key} is one of the keys of @var{rb-tree}, and @var{datum} is its
+associated datum. The alist is sorted by key according to the
+@var{key<?} argument used to construct @var{rb-tree}. The
+time required by this operation is proportional to the
+number of associations in the tree.
+@end deffn
+
+@deffn procedure rb-tree/key-list rb-tree
+Returns a newly allocated list of the keys in @var{rb-tree}. The list
+is sorted by key according to the @var{key<?} argument used to construct
+@var{rb-tree}. The time required by this
+operation is proportional to the number of associations in the tree.
+@end deffn
+
+@deffn procedure rb-tree/datum-list rb-tree
+Returns a newly allocated list of the datums in @var{rb-tree}. Each
+element of the list corresponds to one of the associations in
+@var{rb-tree}, so if the tree contains multiple associations with the
+same datum, so will this list. The list is sorted by the keys of the
+associations, even though they do not appear in the result. The time required by this operation is proportional to the
+number of associations in the tree.
+
+This procedure is equivalent to:
+
+@example
+(lambda (rb-tree) (map cdr (rb-tree->alist rb-tree)))
+@end example
+@end deffn
+
+@deffn procedure rb-tree/equal? rb-tree-1 rb-tree-2 datum=?
+Compares @var{rb-tree-1} and @var{rb-tree-2} for equality, returning
+@code{#t} iff they are equal and @code{#f} otherwise. The trees must
+have been constructed with the same equality and order predicates (same
+in the sense of @code{eq?}). The keys of the trees are compared using
+the @var{key=?} predicate used to build the trees, while the datums of
+the trees are compared using the equivalence predicate @var{datum=?}.
+The worst-case time required by this operation is proportional to the
+number of associations in the tree.
+@end deffn
+
+@deffn procedure rb-tree/empty? rb-tree
+Returns @code{#t} iff @var{rb-tree} contains no associations. Otherwise
+returns @code{#f}.
+@end deffn
+
+@deffn procedure rb-tree/size rb-tree
+Returns the number of associations in @var{rb-tree}, an exact
+non-negative integer. The average and worst-case times required by this
+operation are proportional to the number of associations in the tree.
+@end deffn
+
+@deffn procedure rb-tree/height rb-tree
+Returns the height of @var{rb-tree}, an exact non-negative integer.
+This is the length of the longest path from a leaf of the tree to the
+root. The average and worst-case times required by this operation are
+proportional to the number of associations in the tree.
+
+The returned value satisfies the following:
+
+@example
+@group
+(lambda (rb-tree)
+ (let ((size (rb-tree/size rb-tree))
+ (lg (lambda (x) (/ (log x) (log 2)))))
+ (<= (lg size)
+ (rb-tree/height rb-tree)
+ (* 2 (lg (+ size 1))))))
+@end group
+@end example
+@end deffn
+
+@deffn procedure rb-tree/copy rb-tree
+Returns a newly allocated copy of @var{rb-tree}. The copy is identical
+to @var{rb-tree} in all respects, except that changes to @var{rb-tree}
+do not affect the copy, and vice versa. The time required by this
+operation is proportional to the number of associations in the tree.
+@end deffn
+
+@deffn procedure alist->rb-tree alist key=? key<?
+Returns a newly allocated red-black tree that contains the same
+associations as @var{alist}. This procedure is equivalent to:
+
+@example
+@group
+(lambda (alist key=? key<?)
+ (let ((tree (make-rb-tree key=? key<?)))
+ (for-each (lambda (association)
+ (rb-tree/insert! tree
+ (car association)
+ (cdr association)))
+ alist)
+ tree))
+@end group
+@end example
+@end deffn
+
+The following operations provide access to the smallest and largest
+members in a red/black tree. They are useful for implementing priority
+queues.
+
+@deffn procedure rb-tree/min rb-tree default
+Returns the smallest key in @var{rb-tree}, or @var{default} if the tree
+is empty.
+@end deffn
+
+@deffn procedure rb-tree/min-datum rb-tree default
+Returns the datum associated with the smallest key in @var{rb-tree}, or
+@var{default} if the tree is empty.
+@end deffn
+
+@deffn procedure rb-tree/min-pair rb-tree
+Finds the smallest key in @var{rb-tree} and returns a pair containing
+that key and its associated datum. If the tree is empty, returns
+@code{#f}.
+@end deffn
+
+@deffn procedure rb-tree/max rb-tree default
+Returns the largest key in @var{rb-tree}, or @var{default} if the tree
+is empty.
+@end deffn
+
+@deffn procedure rb-tree/max-datum rb-tree default
+Returns the datum associated with the largest key in @var{rb-tree}, or
+@var{default} if the tree is empty.
+@end deffn
+
+@deffn procedure rb-tree/max-pair rb-tree
+Finds the largest key in @var{rb-tree} and returns a pair containing
+that key and its associated datum. If the tree is empty, returns
+@code{#f}.
+@end deffn
+
+@deffn procedure rb-tree/delete-min! rb-tree default
+@deffnx procedure rb-tree/delete-min-datum! rb-tree default
+@deffnx procedure rb-tree/delete-min-pair! rb-tree
+@deffnx procedure rb-tree/delete-max! rb-tree default
+@deffnx procedure rb-tree/delete-max-datum! rb-tree default
+@deffnx procedure rb-tree/delete-max-pair! rb-tree
+These operations are exactly like the accessors above, in that they
+return information associated with the smallest or largest key, except
+that they simultaneously delete that key.
+@end deffn
+
+@node Weight-Balanced Trees, , Red-Black Trees, Associations
+@section Weight-Balanced Trees
+
+@cindex trees, balanced binary
+@cindex balanced binary trees
+@cindex binary trees
+@cindex weight-balanced binary trees
+Balanced binary trees are a useful data structure for maintaining large
+sets of ordered objects or sets of associations whose keys are ordered.
+MIT/GNU Scheme has a comprehensive implementation of weight-balanced binary
+trees which has several advantages over the other data structures for
+large aggregates:
+
+@itemize @bullet
+@item
+In addition to the usual element-level operations like insertion,
+deletion and lookup, there is a full complement of collection-level
+operations, like set intersection, set union and subset test, all of
+which are implemented with good orders of growth in time and space.
+This makes weight-balanced trees ideal for rapid prototyping of
+functionally derived specifications.
+
+@item
+An element in a tree may be indexed by its position under the ordering
+of the keys, and the ordinal position of an element may be determined,
+both with reasonable efficiency.
+
+@item
+Operations to find and remove minimum element make weight-balanced trees
+simple to use for priority queues.
+
+@item
+The implementation is @emph{functional} rather than @emph{imperative}.
+This means that operations like `inserting' an association in a tree do
+not destroy the old tree, in much the same way that @code{(+ 1 x)}
+modifies neither the constant 1 nor the value bound to @code{x}. The
+trees are referentially transparent thus the programmer need not worry
+about copying the trees. Referential transparency allows space
+efficiency to be achieved by sharing subtrees.
+@end itemize
+
+These features make weight-balanced trees suitable for a wide range of
+applications, especially those that require large numbers of sets or
+discrete maps. Applications that have a few global databases and/or
+concentrate on element-level operations like insertion and lookup are
+probably better off using hash tables or red-black trees.
+
+The @emph{size} of a tree is the number of associations that it
+contains. Weight-balanced binary trees are balanced to keep the sizes
+of the subtrees of each node within a constant factor of each other.
+This ensures logarithmic times for single-path operations (like lookup
+and insertion). A weight-balanced tree takes space that is proportional
+to the number of associations in the tree. For the current
+implementation, the constant of proportionality is six words per
+association.
+
+@cindex binary trees, as sets
+@cindex binary trees, as discrete maps
+@cindex sets, using binary trees
+@cindex discrete maps, using binary trees
+Weight-balanced trees can be used as an implementation for either
+discrete sets or discrete maps (associations). Sets are implemented by
+ignoring the datum that is associated with the key. Under this scheme
+if an association exists in the tree this indicates that the key of the
+association is a member of the set. Typically a value such as
+@code{()}, @code{#t} or @code{#f} is associated with the key.
+
+Many operations can be viewed as computing a result that, depending on
+whether the tree arguments are thought of as sets or maps, is known by
+two different names. An example is @code{wt-tree/member?}, which, when
+regarding the tree argument as a set, computes the set membership
+operation, but, when regarding the tree as a discrete map,
+@code{wt-tree/member?} is the predicate testing if the map is defined at
+an element in its domain. Most names in this package have been chosen
+based on interpreting the trees as sets, hence the name
+@code{wt-tree/member?} rather than @code{wt-tree/defined-at?}.
+
+@cindex run-time-loadable option
+@cindex option, run-time-loadable
+The weight-balanced tree implementation is a run-time-loadable option.
+To use weight-balanced trees, execute
+
+@example
+(load-option 'wt-tree)
+@end example
+@findex load-option
+
+@noindent
+once before calling any of the procedures defined here.
+
+@menu
+* Construction of Weight-Balanced Trees::
+* Basic Operations on Weight-Balanced Trees::
+* Advanced Operations on Weight-Balanced Trees::
+* Indexing Operations on Weight-Balanced Trees::
+@end menu
+
+@node Construction of Weight-Balanced Trees, Basic Operations on Weight-Balanced Trees, Weight-Balanced Trees, Weight-Balanced Trees
+@subsection Construction of Weight-Balanced Trees
+
+Binary trees require there to be a total order on the keys used to
+arrange the elements in the tree. Weight-balanced trees are organized
+by @emph{types}, where the type is an object encapsulating the ordering
+relation. Creating a tree is a two-stage process. First a tree type
+must be created from the predicate that gives the ordering. The tree type
+is then used for making trees, either empty or singleton trees or trees
+from other aggregate structures like association lists. Once created, a
+tree `knows' its type and the type is used to test compatibility between
+trees in operations taking two trees. Usually a small number of tree
+types are created at the beginning of a program and used many times
+throughout the program's execution.
+
+@deffn procedure make-wt-tree-type key<?
+This procedure creates and returns a new tree type based on the ordering
+predicate @var{key<?}.
+@var{Key<?} must be a total ordering, having the property that for all
+key values @code{a}, @code{b} and @code{c}:
+
+@example
+@group
+(key<? a a) @result{} #f
+(and (key<? a b) (key<? b a)) @result{} #f
+(if (and (key<? a b) (key<? b c))
+ (key<? a c)
+ #t) @result{} #t
+@end group
+@end example
+
+@noindent
+Two key values are assumed to be equal if neither is less than the other
+by @var{key<?}.
+
+Each call to @code{make-wt-tree-type} returns a distinct value, and
+trees are only compatible if their tree types are @code{eq?}. A
+consequence is that trees that are intended to be used in binary-tree
+operations must all be created with a tree type originating from the
+same call to @code{make-wt-tree-type}.
+@end deffn
+
+@defvr variable number-wt-type
+A standard tree type for trees with numeric keys. @code{Number-wt-type}
+could have been defined by
+
+@example
+(define number-wt-type (make-wt-tree-type <))
+@end example
+@end defvr
+
+@defvr variable string-wt-type
+A standard tree type for trees with string keys. @code{String-wt-type}
+could have been defined by
+
+@example
+(define string-wt-type (make-wt-tree-type string<?))
+@end example
+@end defvr
+
+@deffn procedure make-wt-tree wt-tree-type
+This procedure creates and returns a newly allocated weight-balanced
+tree. The tree is empty, i.e. it contains no associations.
+@var{Wt-tree-type} is a weight-balanced tree type obtained by calling
+@code{make-wt-tree-type}; the returned tree has this type.
+@end deffn
+
+@deffn procedure singleton-wt-tree wt-tree-type key datum
+This procedure creates and returns a newly allocated weight-balanced
+tree. The tree contains a single association, that of @var{datum} with
+@var{key}. @var{Wt-tree-type} is a weight-balanced tree type obtained
+by calling @code{make-wt-tree-type}; the returned tree has this type.
+@end deffn
+
+@deffn procedure alist->wt-tree tree-type alist
+Returns a newly allocated weight-balanced tree that contains the same
+associations as @var{alist}. This procedure is equivalent to:
+
+@example
+@group
+(lambda (type alist)
+ (let ((tree (make-wt-tree type)))
+ (for-each (lambda (association)
+ (wt-tree/add! tree
+ (car association)
+ (cdr association)))
+ alist)
+ tree))
+@end group
+@end example
+@end deffn
+
+@node Basic Operations on Weight-Balanced Trees, Advanced Operations on Weight-Balanced Trees, Construction of Weight-Balanced Trees, Weight-Balanced Trees
+@subsection Basic Operations on Weight-Balanced Trees
+
+This section describes the basic tree operations on weight-balanced
+trees. These operations are the usual tree operations for insertion,
+deletion and lookup, some predicates and a procedure for determining the
+number of associations in a tree.
+
+@deffn procedure wt-tree? object
+Returns @code{#t} if @var{object} is a weight-balanced tree, otherwise
+returns @code{#f}.
+@end deffn
+
+@deffn procedure wt-tree/empty? wt-tree
+Returns @code{#t} if @var{wt-tree} contains no associations, otherwise
+returns @code{#f}.
+@end deffn
+
+@deffn procedure wt-tree/size wt-tree
+Returns the number of associations in @var{wt-tree}, an exact
+non-negative integer. This operation takes constant time.
+@end deffn
+
+@deffn procedure wt-tree/add wt-tree key datum
+Returns a new tree containing all the associations in @var{wt-tree} and
+the association of @var{datum} with @var{key}. If @var{wt-tree} already
+had an association for @var{key}, the new association overrides the old.
+The average and worst-case times required by this operation are
+proportional to the logarithm of the number of associations in
+@var{wt-tree}.
+@end deffn
+
+@deffn procedure wt-tree/add! wt-tree key datum
+Associates @var{datum} with @var{key} in @var{wt-tree} and returns an
+unspecified value. If @var{wt-tree} already has an association for
+@var{key}, that association is replaced. The average and worst-case
+times required by this operation are proportional to the logarithm of
+the number of associations in @var{wt-tree}.
+@end deffn
+
+@deffn procedure wt-tree/member? key wt-tree
+Returns @code{#t} if @var{wt-tree} contains an association for
+@var{key}, otherwise returns @code{#f}. The average and worst-case
+times required by this operation are proportional to the logarithm of
+the number of associations in @var{wt-tree}.
+@end deffn
+
+@deffn procedure wt-tree/lookup wt-tree key default
+Returns the datum associated with @var{key} in @var{wt-tree}. If
+@var{wt-tree} doesn't contain an association for @var{key},
+@var{default} is returned. The average and worst-case times required by
+this operation are proportional to the logarithm of the number of
+associations in @var{wt-tree}.
+@end deffn
+
+@deffn procedure wt-tree/delete wt-tree key
+Returns a new tree containing all the associations in @var{wt-tree},
+except that if @var{wt-tree} contains an association for @var{key}, it
+is removed from the result. The average and worst-case times required
+by this operation are proportional to the logarithm of the number of
+associations in @var{wt-tree}.
+@end deffn
+
+@deffn procedure wt-tree/delete! wt-tree key
+If @var{wt-tree} contains an association for @var{key} the association
+is removed. Returns an unspecified value. The average and worst-case
+times required by this operation are proportional to the logarithm of
+the number of associations in @var{wt-tree}.
+@end deffn
+
+@node Advanced Operations on Weight-Balanced Trees, Indexing Operations on Weight-Balanced Trees, Basic Operations on Weight-Balanced Trees, Weight-Balanced Trees
+@subsection Advanced Operations on Weight-Balanced Trees
+
+In the following the @emph{size} of a tree is the number of associations
+that the tree contains, and a @emph{smaller} tree contains fewer
+associations.
+
+@deffn procedure wt-tree/split< wt-tree bound
+Returns a new tree containing all and only the associations in
+@var{wt-tree} that have a key that is less than @var{bound} in the
+ordering relation of the tree type of @var{wt-tree}. The average and
+worst-case times required by this operation are proportional to the
+logarithm of the size of @var{wt-tree}.
+@end deffn
+
+@deffn procedure wt-tree/split> wt-tree bound
+Returns a new tree containing all and only the associations in
+@var{wt-tree} that have a key that is greater than @var{bound} in the
+ordering relation of the tree type of @var{wt-tree}. The average and
+worst-case times required by this operation are proportional to the
+logarithm of the size of @var{wt-tree}.
+@end deffn
+
+@deffn procedure wt-tree/union wt-tree-1 wt-tree-2
+Returns a new tree containing all the associations from both trees.
+This operation is asymmetric: when both trees have an association for
+the same key, the returned tree associates the datum from @var{wt-tree-2}
+with the key. Thus if the trees are viewed as discrete maps then
+@code{wt-tree/union} computes the map override of @var{wt-tree-1} by
+@var{wt-tree-2}. If the trees are viewed as sets the result is the set
+union of the arguments.
+The worst-case time required by this operation
+is proportional to the sum of the sizes of both trees.
+If the minimum key of one tree is greater than the maximum key of
+the other tree then the worst-case time required is proportional to
+the logarithm of the size of the larger tree.
+@end deffn
+
+@deffn procedure wt-tree/intersection wt-tree-1 wt-tree-2
+Returns a new tree containing all and only those associations from
+@var{wt-tree-1} that have keys appearing as the key of an association
+in @var{wt-tree-2}. Thus the associated data in the result are those
+from @var{wt-tree-1}. If the trees are being used as sets the result is
+the set intersection of the arguments. As a discrete map operation,
+@code{wt-tree/intersection} computes the domain restriction of
+@var{wt-tree-1} to (the domain of) @var{wt-tree-2}.
+The worst-case time required by this operation is proportional to
+the sum of the sizes of the trees.
+@end deffn
+
+@deffn procedure wt-tree/difference wt-tree-1 wt-tree-2
+Returns a new tree containing all and only those associations from
+@var{wt-tree-1} that have keys that @emph{do not} appear as the key of
+an association in @var{wt-tree-2}. If the trees are viewed as sets the
+result is the asymmetric set difference of the arguments. As a discrete
+map operation, it computes the domain restriction of @var{wt-tree-1} to
+the complement of (the domain of) @var{wt-tree-2}.
+The worst-case time required by this operation is proportional to
+the sum of the sizes of the trees.
+@end deffn
+
+@deffn procedure wt-tree/subset? wt-tree-1 wt-tree-2
+Returns @code{#t} iff the key of each association in @var{wt-tree-1} is
+the key of some association in @var{wt-tree-2}, otherwise returns @code{#f}.
+Viewed as a set operation, @code{wt-tree/subset?} is the improper subset
+predicate.
+A proper subset predicate can be constructed:
+
+@example
+@group
+(define (proper-subset? s1 s2)
+ (and (wt-tree/subset? s1 s2)
+ (< (wt-tree/size s1) (wt-tree/size s2))))
+@end group
+@end example
+
+As a discrete map operation, @code{wt-tree/subset?} is the subset
+test on the domain(s) of the map(s). In the worst-case the time
+required by this operation is proportional to the size of
+@var{wt-tree-1}.
+@end deffn
+
+@deffn procedure wt-tree/set-equal? wt-tree-1 wt-tree-2
+Returns @code{#t} iff for every association in @var{wt-tree-1} there is
+an association in @var{wt-tree-2} that has the same key, and @emph{vice
+versa}.
+
+Viewing the arguments as sets, @code{wt-tree/set-equal?} is the set
+equality predicate. As a map operation it determines if two maps are
+defined on the same domain.
+
+This procedure is equivalent to
+
+@example
+@group
+(lambda (wt-tree-1 wt-tree-2)
+ (and (wt-tree/subset? wt-tree-1 wt-tree-2
+ (wt-tree/subset? wt-tree-2 wt-tree-1)))
+@end group
+@end example
+
+In the worst case the time required by this operation is proportional to
+the size of the smaller tree.
+@end deffn
+
+@deffn procedure wt-tree/fold combiner initial wt-tree
+This procedure reduces @var{wt-tree} by combining all the associations,
+using an reverse in-order traversal, so the associations are visited in
+reverse order. @var{Combiner} is a procedure of three arguments: a key,
+a datum and the accumulated result so far. Provided @var{combiner}
+takes time bounded by a constant, @code{wt-tree/fold} takes time
+proportional to the size of @var{wt-tree}.
+
+A sorted association list can be derived simply:
+
+@example
+@group
+(wt-tree/fold (lambda (key datum list)
+ (cons (cons key datum) list))
+ '()
+ @var{wt-tree}))
+@end group
+@end example
+
+The data in the associations can be summed like this:
+
+@example
+@group
+(wt-tree/fold (lambda (key datum sum) (+ sum datum))
+ 0
+ @var{wt-tree})
+@end group
+@end example
+@end deffn
+
+@deffn procedure wt-tree/for-each action wt-tree
+This procedure traverses @var{wt-tree} in order, applying @var{action} to
+each association.
+The associations are processed in increasing order of their keys.
+@var{Action} is a procedure of two arguments that takes the key and
+datum respectively of the association.
+Provided @var{action} takes time bounded by a constant,
+@code{wt-tree/for-each} takes time proportional to the size of
+@var{wt-tree}.
+The example prints the tree:
+
+@example
+@group
+(wt-tree/for-each (lambda (key value)
+ (display (list key value)))
+ @var{wt-tree}))
+@end group
+@end example
+@end deffn
+
+@deffn procedure wt-tree/union-merge wt-tree-1 wt-tree-2 merge
+Returns a new tree containing all the associations from both trees. If
+both trees have an association for the same key, the datum associated
+with that key in the result tree is computed by applying the procedure
+@var{merge} to the key, the value from @var{wt-tree-1} and the value
+from @var{wt-tree-2}. @var{Merge} is of the form
+
+@example
+(lambda (@var{key} @var{datum-1} @var{datum-2}) @dots{})
+@end example
+
+If some key occurs only in one tree, that association will appear in the
+result tree without being processed by @var{merge}, so for this
+operation to make sense, either @var{merge} must have both a right and
+left identity that correspond to the association being absent in one of
+the trees, or some guarantee must be made, for example, all the keys in
+one tree are known to occur in the other.
+
+These are all reasonable procedures for @var{merge}
+
+@example
+@group
+(lambda (key val1 val2) (+ val1 val2))
+(lambda (key val1 val2) (append val1 val2))
+(lambda (key val1 val2) (wt-tree/union val1 val2))
+@end group
+@end example
+
+However, a procedure like
+
+@example
+(lambda (key val1 val2) (- val1 val2))
+@end example
+
+would result in a subtraction of the data for all associations with keys
+occuring in both trees but associations with keys occuring in only the
+second tree would be copied, not negated, as is presumably be intent.
+The programmer might ensure that this never happens.
+
+This procedure has the same time behavior as @code{wt-tree/union} but
+with a slightly worse constant factor. Indeed, @code{wt-tree/union}
+might have been defined like this:
+
+@example
+@group
+(define (wt-tree/union tree1 tree2)
+ (wt-tree/union-merge tree1 tree2
+ (lambda (key val1 val2) val2)))
+@end group
+@end example
+@end deffn
+
+The @var{merge} procedure takes the @var{key} as a parameter in case the
+data are not independent of the key.
+
+
+@node Indexing Operations on Weight-Balanced Trees, , Advanced Operations on Weight-Balanced Trees, Weight-Balanced Trees
+@subsection Indexing Operations on Weight-Balanced Trees
+
+Weight-balanced trees support operations that view the tree as sorted
+sequence of associations. Elements of the sequence can be accessed by
+position, and the position of an element in the sequence can be
+determined, both in logarthmic time.
+
+@deffn procedure wt-tree/index wt-tree index
+@deffnx procedure wt-tree/index-datum wt-tree index
+@deffnx procedure wt-tree/index-pair wt-tree index
+Returns the 0-based @var{index}th association of @var{wt-tree} in the
+sorted sequence under the tree's ordering relation on the keys.
+@code{wt-tree/index} returns the @var{index}th key,
+@code{wt-tree/index-datum} returns the datum associated with the
+@var{index}th key and @code{wt-tree/index-pair} returns a new pair
+@code{(@var{key} . @var{datum})} which is the @code{cons} of the
+@var{index}th key and its datum. The average and worst-case times
+required by this operation are proportional to the logarithm of the
+number of associations in the tree.
+
+These operations signal a condition of type
+@code{condition-type:bad-range-argument} if @var{index}@code{<0} or if
+@var{index} is greater than or equal to the number of associations in
+the tree. If the tree is empty, they signal an anonymous error.
+
+Indexing can be used to find the median and maximum keys in the tree as
+follows:
+
+@example
+@group
+median: (wt-tree/index @var{wt-tree}
+ (quotient (wt-tree/size @var{wt-tree})
+ 2))
+maximum: (wt-tree/index @var{wt-tree}
+ (- (wt-tree/size @var{wt-tree})
+ 1))
+@end group
+@end example
+@end deffn
+
+@deffn procedure wt-tree/rank wt-tree key
+Determines the 0-based position of @var{key} in the sorted sequence of
+the keys under the tree's ordering relation, or @code{#f} if the tree
+has no association with for @var{key}. This procedure returns either an
+exact non-negative integer or @code{#f}. The average and worst-case
+times required by this operation are proportional to the logarithm of
+the number of associations in the tree.
+@end deffn
+
+@deffn procedure wt-tree/min wt-tree
+@deffnx procedure wt-tree/min-datum wt-tree
+@deffnx procedure wt-tree/min-pair wt-tree
+Returns the association of @var{wt-tree} that has the least key under the tree's ordering relation.
+@code{wt-tree/min} returns the least key,
+@code{wt-tree/min-datum} returns the datum associated with the
+least key and @code{wt-tree/min-pair} returns a new pair
+@code{(key . datum)} which is the @code{cons} of the minimum key and its datum.
+The average and worst-case times required by this operation are
+proportional to the logarithm of the number of associations in the tree.
+
+These operations signal an error if the tree is empty.
+They could have been written
+
+@example
+@group
+(define (wt-tree/min tree)
+ (wt-tree/index tree 0))
+(define (wt-tree/min-datum tree)
+ (wt-tree/index-datum tree 0))
+(define (wt-tree/min-pair tree)
+ (wt-tree/index-pair tree 0))
+@end group
+@end example
+@end deffn
+
+@deffn procedure wt-tree/delete-min wt-tree
+Returns a new tree containing all of the associations in @var{wt-tree}
+except the association with the least key under the @var{wt-tree}'s
+ordering relation. An error is signalled if the tree is empty. The
+average and worst-case times required by this operation are proportional
+to the logarithm of the number of associations in the tree. This
+operation is equivalent to
+
+@example
+(wt-tree/delete @var{wt-tree} (wt-tree/min @var{wt-tree}))
+@end example
+@end deffn
+
+@deffn procedure wt-tree/delete-min! wt-tree
+Removes the association with the least key under the @var{wt-tree}'s
+ordering relation. An error is signalled if the tree is empty. The
+average and worst-case times required by this operation are proportional
+to the logarithm of the number of associations in the tree. This
+operation is equivalent to
+
+@example
+(wt-tree/delete! @var{wt-tree} (wt-tree/min @var{wt-tree}))
+@end example
+@end deffn
--- /dev/null
+@c This file is part of the MIT/GNU Scheme Reference Manual.
+@c $Id: bit-strings.texi,v 1.1 2003/04/15 03:29:26 cph Exp $
+
+@c Copyright 1991,1992,1993,1994,1995 Massachusetts Institute of Technology
+@c Copyright 1996,1997,1999,2000,2001 Massachusetts Institute of Technology
+@c Copyright 2002,2003 Massachusetts Institute of Technology
+@c See file scheme.texinfo for copying conditions.
+
+@node Bit Strings, Miscellaneous Datatypes, Vectors, Top
+@chapter Bit Strings
+
+@cindex bit string (defn)
+@cindex string, of bits (defn)
+A @dfn{bit string} is a sequence of bits. Bit strings can be used to
+represent sets or to manipulate binary data. The elements of a bit
+string are numbered from zero up to the number of bits in the string
+less one, in @emph{right to left order}, (the rightmost bit is numbered
+zero). When you convert from a bit string to an integer, the zero-th
+bit is associated with the zero-th power of two, the first bit is
+associated with the first power, and so on.
+
+Bit strings are encoded very densely in memory. Each bit occupies
+exactly one bit of storage, and the overhead for the entire bit string
+is bounded by a small constant. However, accessing a bit in a bit
+string is slow compared to accessing an element of a vector or character
+string. If performance is of overriding concern, it is better to use
+character strings to store sets of boolean values even though they
+occupy more space.
+
+@cindex length, of bit string (defn)
+@cindex index, of bit string (defn)
+@cindex valid index, of bit string (defn)
+@cindex bit string length (defn)
+@cindex bit string index (defn)
+The @dfn{length} of a bit string is the number of bits that it contains.
+This number is an exact non-negative integer that is fixed when the bit
+string is created. The @dfn{valid indexes} of a bit string are the
+exact non-negative integers less than the length of the bit string.
+
+@cindex external representation, for bit string
+@cindex #* as external representation
+@cindex asterisk, as external representation
+Bit strings may contain zero or more bits. They are not limited by the
+length of a machine word. In the printed representation of a bit
+string, the contents of the bit string are preceded by @samp{#*}. The
+contents are printed starting with the most significant bit (highest
+index).
+
+Note that the external representation of bit strings uses a bit ordering
+that is the reverse of the representation for bit strings in Common
+Lisp. It is likely that MIT/GNU Scheme's representation will be
+changed in the future, to be compatible with Common Lisp. For the time
+being this representation should be considered a convenience for viewing
+bit strings rather than a means of entering them as data.
+
+@example
+@group
+#*11111
+#*1010
+#*00000000
+#*
+@end group
+@end example
+
+All of the bit-string procedures are MIT/GNU Scheme extensions.
+
+@menu
+* Construction of Bit Strings::
+* Selecting Bit String Components::
+* Cutting and Pasting Bit Strings::
+* Bitwise Operations on Bit Strings::
+* Modification of Bit Strings::
+* Integer Conversions of Bit Strings::
+@end menu
+
+@node Construction of Bit Strings, Selecting Bit String Components, Bit Strings, Bit Strings
+@section Construction of Bit Strings
+@cindex construction, of bit string
+
+@deffn procedure make-bit-string k initialization
+Returns a newly allocated bit string of length @var{k}. If
+@var{initialization} is @code{#f}, the bit string is filled with 0 bits;
+otherwise, the bit string is filled with 1 bits.
+
+@example
+(make-bit-string 7 #f) @result{} #*0000000
+@end example
+@end deffn
+
+@deffn procedure bit-string-allocate k
+Returns a newly allocated bit string of length @var{k}, but does not
+initialize it.
+@end deffn
+
+@deffn procedure bit-string-copy bit-string
+@cindex copying, of bit string
+Returns a newly allocated copy of @var{bit-string}.
+@end deffn
+
+@node Selecting Bit String Components, Cutting and Pasting Bit Strings, Construction of Bit Strings, Bit Strings
+@section Selecting Bit String Components
+
+@deffn procedure bit-string? object
+@cindex type predicate, for bit string
+Returns @code{#t} if @var{object} is a bit string; otherwise returns
+@code{#f}.
+@end deffn
+
+@deffn procedure bit-string-length bit-string
+@cindex length, of bit string
+Returns the length of @var{bit-string}.
+@end deffn
+
+@deffn procedure bit-string-ref bit-string k
+@cindex selection, of bit string component
+@cindex component selection, of bit string
+Returns @code{#t} if the @var{k}th bit is 1; otherwise returns
+@code{#f}. @var{K} must be a valid index of @var{bit-string}.
+@end deffn
+
+@deffn procedure bit-string-set! bit-string k
+Sets the @var{k}th bit in @var{bit-string} to 1 and returns an
+unspecified value. @var{K} must be a valid index of @var{bit-string}.
+@end deffn
+
+@deffn procedure bit-string-clear! bit-string k
+Sets the @var{k}th bit in @var{bit-string} to 0 and returns an
+unspecified value. @var{K} must be a valid index of @var{bit-string}.
+@end deffn
+
+@deffn procedure bit-substring-find-next-set-bit bit-string start end
+@cindex searching, of bit string
+Returns the index of the first occurrence of a set bit in the substring
+of @var{bit-string} from @var{start} (inclusive) to @var{end}
+(exclusive). If none of the bits in the substring are set @code{#f} is
+returned. The index returned is relative to the whole bit string, not
+substring.
+
+The following procedure uses @code{bit-substring-find-next-set-bit} to
+find all the set bits and display their indexes:
+
+@example
+@group
+(define (scan-bitstring bs)
+ (let ((end (bit-string-length bs)))
+ (let loop ((start 0))
+ (let ((next
+ (bit-substring-find-next-set-bit bs start end)))
+ (if next
+ (begin
+ (write-line next)
+ (if (< next end)
+ (loop (+ next 1)))))))))
+@end group
+@end example
+@end deffn
+
+@node Cutting and Pasting Bit Strings, Bitwise Operations on Bit Strings, Selecting Bit String Components, Bit Strings
+@section Cutting and Pasting Bit Strings
+@cindex cutting, of bit string
+@cindex pasting, of bit strings
+
+@deffn procedure bit-string-append bit-string-1 bit-string-2
+@cindex appending, of bit strings
+Appends the two bit string arguments, returning a newly allocated bit
+string as its result. In the result, the bits copied from
+@var{bit-string-1} are less significant (smaller indices) than those
+copied from @var{bit-string-2}.
+@end deffn
+
+@deffn procedure bit-substring bit-string start end
+@cindex substring, of bit string
+Returns a newly allocated bit string whose bits are copied from
+@var{bit-string}, starting at index @var{start} (inclusive) and ending
+at @var{end} (exclusive).
+@end deffn
+
+@node Bitwise Operations on Bit Strings, Modification of Bit Strings, Cutting and Pasting Bit Strings, Bit Strings
+@section Bitwise Operations on Bit Strings
+
+@deffn procedure bit-string-zero? bit-string
+Returns @code{#t} if @var{bit-string} contains only 0 bits; otherwise
+returns @code{#f}.
+@end deffn
+
+@deffn procedure bit-string=? bit-string-1 bit-string-2
+@cindex equivalence predicate, for bit strings
+@cindex comparison, of bit strings
+Compares the two bit string arguments and returns @code{#t} if they are the
+same length and contain the same bits; otherwise returns @code{#f}.
+@end deffn
+
+@deffn procedure bit-string-not bit-string
+@cindex inverse, of bit string
+Returns a newly allocated bit string that is the bitwise-logical
+negation of @var{bit-string}.
+@end deffn
+
+@deffn procedure bit-string-movec! target-bit-string bit-string
+The destructive version of @code{bit-string-not}. The arguments
+@var{target-bit-string} and @var{bit-string} must be bit strings of the
+same length. The bitwise-logical negation of @var{bit-string} is
+computed and the result placed in @var{target-bit-string}. The value of
+this procedure is unspecified.
+@end deffn
+
+@deffn procedure bit-string-and bit-string-1 bit-string-2
+Returns a newly allocated bit string that is the bitwise-logical ``and''
+of the arguments. The arguments must be bit strings of identical
+length.
+@end deffn
+
+@deffn procedure bit-string-andc bit-string-1 bit-string-2
+Returns a newly allocated bit string that is the bitwise-logical ``and''
+of @var{bit-string-1} with the bitwise-logical negation of
+@var{bit-string-2}. The arguments must be bit strings of identical
+length.
+@end deffn
+
+@deffn procedure bit-string-or bit-string-1 bit-string-2
+Returns a newly allocated bit string that is the bitwise-logical
+``inclusive or'' of the arguments. The arguments must be bit strings of
+identical length.
+@end deffn
+
+@deffn procedure bit-string-xor bit-string-1 bit-string-2
+Returns a newly allocated bit string that is the bitwise-logical
+``exclusive or'' of the arguments. The arguments must be bit strings of
+identical length.
+@end deffn
+
+@deffn procedure bit-string-and! target-bit-string bit-string
+@deffnx procedure bit-string-or! target-bit-string bit-string
+@deffnx procedure bit-string-xor! target-bit-string bit-string
+@deffnx procedure bit-string-andc! target-bit-string bit-string
+These are destructive versions of the above operations. The arguments
+@var{target-bit-string} and @var{bit-string} must be bit strings of the
+same length. Each of these procedures performs the corresponding
+bitwise-logical operation on its arguments, places the result into
+@var{target-bit-string}, and returns an unspecified result.
+@end deffn
+
+@node Modification of Bit Strings, Integer Conversions of Bit Strings, Bitwise Operations on Bit Strings, Bit Strings
+@section Modification of Bit Strings
+@cindex modification, of bit string
+@cindex filling, of bit string
+@cindex moving, of bit string elements
+
+@deffn procedure bit-string-fill! bit-string initialization
+Fills @var{bit-string} with zeroes if @var{initialization} is @code{#f};
+otherwise fills @var{bit-string} with ones. Returns an unspecified
+value.
+@end deffn
+
+@deffn procedure bit-string-move! target-bit-string bit-string
+Moves the contents of @var{bit-string} into @var{target-bit-string}. Both
+arguments must be bit strings of the same length. The results of the
+operation are undefined if the arguments are the same bit string.
+@end deffn
+
+@deffn procedure bit-substring-move-right! bit-string-1 start1 end1 bit-string-2 start2
+Destructively copies the bits of @var{bit-string-1}, starting at index
+@var{start1} (inclusive) and ending at @var{end1} (exclusive), into
+@var{bit-string-2} starting at index @var{start2} (inclusive).
+@var{Start1} and @var{end1} must be valid substring indices for
+@var{bit-string-1}, and @var{start2} must be a valid index for
+@var{bit-string-2}. The length of the source substring must not exceed
+the length of @var{bit-string-2} minus the index @var{start2}.
+
+The bits are copied starting from the MSB and working towards the LSB; the
+direction of copying only matters when @var{bit-string-1} and
+@var{bit-string-2} are @code{eqv?}.
+@end deffn
+
+@need 1000
+@node Integer Conversions of Bit Strings, , Modification of Bit Strings, Bit Strings
+@section Integer Conversions of Bit Strings
+@cindex integer, converting to bit string
+
+@deffn procedure unsigned-integer->bit-string length integer
+Both @var{length} and @var{integer} must be exact non-negative integers.
+Converts @var{integer} into a newly allocated bit string of @var{length}
+bits. Signals an error of type @code{condition-type:bad-range-argument}
+if @var{integer} is too large to be represented in @var{length} bits.
+@findex condition-type:bad-range-argument
+@end deffn
+
+@deffn procedure signed-integer->bit-string length integer
+@var{Length} must be an exact non-negative integer, and @var{integer}
+may be any exact integer. Converts @var{integer} into a newly allocated
+bit string of @var{length} bits, using two's complement encoding for
+negative numbers. Signals an error of type
+@code{condition-type:bad-range-argument} if @var{integer} is too large
+to be represented in @var{length} bits.
+@findex condition-type:bad-range-argument
+@end deffn
+
+@deffn procedure bit-string->unsigned-integer bit-string
+@deffnx procedure bit-string->signed-integer bit-string
+Converts @var{bit-string} into an exact integer.
+@code{bit-string->signed-integer} regards @var{bit-string} as a two's
+complement representation of a signed integer, and produces an integer
+of like sign and absolute value. @code{bit-string->unsigned-integer}
+regards @var{bit-string} as an unsigned quantity and converts to an
+integer accordingly.
+@end deffn
--- /dev/null
+@c This file is part of the MIT/GNU Scheme Reference Manual.
+@c $Id: characters.texi,v 1.1 2003/04/15 03:29:29 cph Exp $
+
+@c Copyright 1991,1992,1993,1994,1995 Massachusetts Institute of Technology
+@c Copyright 1996,1997,1999,2000,2001 Massachusetts Institute of Technology
+@c Copyright 2002,2003 Massachusetts Institute of Technology
+@c See file scheme.texinfo for copying conditions.
+
+@node Characters, Strings, Numbers, Top
+@chapter Characters
+
+@cindex character (defn)
+Characters are objects that represent printed characters, such as
+letters and digits.@footnote{Some of the details in this section depend
+on the fact that the underlying operating system uses the
+@acronym{ASCII} character set. This may change when someone ports MIT/GNU
+Scheme to a non-@acronym{ASCII} operating system.}
+
+@menu
+* External Representation of Characters::
+* Comparison of Characters::
+* Miscellaneous Character Operations::
+* Internal Representation of Characters::
+* ISO-8859-1 Characters::
+* Character Sets::
+* Unicode::
+@end menu
+
+@node External Representation of Characters, Comparison of Characters, Characters, Characters
+@section External Representation of Characters
+@cindex external representation, for character
+
+@cindex #\ as external representation
+@findex #\
+Characters are written using the notation @code{#\@var{character}} or
+@code{#\@var{character-name}}. For example:
+
+@example
+@group
+#\a @r{; lowercase letter}
+#\A @r{; uppercase letter}
+#\( @r{; left parenthesis}
+#\space @r{; the space character}
+#\newline @r{; the newline character}
+@end group
+@end example
+@findex #\space
+@findex #\newline
+
+@noindent
+Case is significant in @code{#\@var{character}}, but not in
+@code{#\@var{character-name}}. If @var{character} in
+@code{#\@var{character}} is a letter, @var{character} must be followed
+by a delimiter character such as a space or parenthesis. Characters
+written in the @code{#\} notation are self-evaluating; you don't need to
+quote them.
+
+@cindex bucky bit, prefix (defn)
+@cindex control, bucky bit prefix (defn)
+@cindex meta, bucky bit prefix (defn)
+@cindex super, bucky bit prefix (defn)
+@cindex hyper, bucky bit prefix (defn)
+@cindex top, bucky bit prefix (defn)
+A character name may include one or more @dfn{bucky bit} prefixes to
+indicate that the character includes one or more of the keyboard shift
+keys Control, Meta, Super, Hyper, or Top (note that the Control bucky
+bit prefix is not the same as the @acronym{ASCII} control key). The
+bucky bit prefixes and their meanings are as follows (case is not
+significant):
+
+@example
+@group
+Key Bucky bit prefix Bucky bit
+--- ---------------- ---------
+
+Meta M- or Meta- 1
+Control C- or Control- 2
+Super S- or Super- 4
+Hyper H- or Hyper- 8
+Top T- or Top- 16
+@end group
+@end example
+
+@noindent
+For example,
+
+@example
+@group
+#\c-a @r{; Control-a}
+#\meta-b @r{; Meta-b}
+#\c-s-m-h-a @r{; Control-Meta-Super-Hyper-A}
+@end group
+@end example
+
+@cindex character, named (defn)
+@cindex name, of character
+The following @var{character-name}s are supported, shown here with their
+@acronym{ASCII} equivalents:
+
+@example
+@group
+Character Name ASCII Name
+-------------- ----------
+
+altmode ESC
+backnext US
+backspace BS
+call SUB
+linefeed LF
+page FF
+return CR
+rubout DEL
+space
+tab HT
+@end group
+@end example
+@findex #\altmode
+@findex #\backnext
+@findex #\backspace
+@findex #\call
+@findex #\linefeed
+@findex #\page
+@findex #\return
+@findex #\rubout
+@findex #\space
+@findex #\tab
+
+@noindent
+@cindex newline character (defn)
+@findex #\newline
+In addition, @code{#\newline} is the same as @code{#\linefeed} (but this
+may change in the future, so you should not depend on it). All of the
+standard @acronym{ASCII} names for non-printing characters are supported:
+
+@example
+@group
+NUL SOH STX ETX EOT ENQ ACK BEL
+BS HT LF VT FF CR SO SI
+DLE DC1 DC2 DC3 DC4 NAK SYN ETB
+CAN EM SUB ESC FS GS RS US
+DEL
+@end group
+@end example
+
+@deffn procedure char->name char [slashify?]
+Returns a string corresponding to the printed representation of
+@var{char}. This is the @var{character} or @var{character-name}
+component of the external representation, combined with the appropriate
+bucky bit prefixes.
+
+@example
+@group
+(char->name #\a) @result{} "a"
+(char->name #\space) @result{} "Space"
+(char->name #\c-a) @result{} "C-a"
+(char->name #\control-a) @result{} "C-a"
+@end group
+@end example
+
+@findex read
+@var{Slashify?}, if specified and true, says to insert the necessary
+backslash characters in the result so that @code{read} will parse it
+correctly. In other words, the following generates the external
+representation of @var{char}:
+
+@example
+(string-append "#\\" (char->name @var{char} #t))
+@end example
+
+@noindent
+If @var{slashify?} is not specified, it defaults to @code{#f}.
+@end deffn
+
+@deffn procedure name->char string
+Converts a string that names a character into the character specified.
+If @var{string} does not name any character, @code{name->char} signals
+an error.
+
+@example
+@group
+(name->char "a") @result{} #\a
+(name->char "space") @result{} #\Space
+(name->char "c-a") @result{} #\C-a
+(name->char "control-a") @result{} #\C-a
+@end group
+@end example
+@end deffn
+
+@node Comparison of Characters, Miscellaneous Character Operations, External Representation of Characters, Characters
+@section Comparison of Characters
+@cindex ordering, of characters
+@cindex comparison, of characters
+@cindex equivalence predicates, for characters
+
+@deffn procedure char=? char1 char2
+@deffnx procedure char<? char1 char2
+@deffnx procedure char>? char1 char2
+@deffnx procedure char<=? char1 char2
+@deffnx procedure char>=? char1 char2
+@deffnx {procedure} char-ci=? char1 char2
+@deffnx {procedure} char-ci<? char1 char2
+@deffnx {procedure} char-ci>? char1 char2
+@deffnx {procedure} char-ci<=? char1 char2
+@deffnx {procedure} char-ci>=? char1 char2
+@cindex equivalence predicate, for characters
+Returns @code{#t} if the specified characters are have the appropriate
+order relationship to one another; otherwise returns @code{#f}. The
+@code{-ci} procedures don't distinguish uppercase and lowercase letters.
+
+Character ordering follows these rules:
+
+@itemize @bullet
+@item
+The digits are in order; for example, @code{(char<? #\0 #\9)} returns
+@code{#t}.
+
+@item
+The uppercase characters are in order; for example, @code{(char<? #\A
+#\B)} returns @code{#t}.
+
+@item
+The lowercase characters are in order; for example, @code{(char<? #\a
+#\b)} returns @code{#t}.
+@end itemize
+
+@cindex standard character
+@cindex character, standard
+@findex char-standard?
+In addition, MIT/GNU Scheme orders those characters that satisfy
+@code{char-standard?} the same way that @acronym{ISO-8859-1} does.
+
+Characters are ordered by first comparing their bucky bits part and then
+their code part. In particular, characters without bucky bits come
+before characters with bucky bits.
+@end deffn
+
+@node Miscellaneous Character Operations, Internal Representation of Characters, Comparison of Characters, Characters
+@section Miscellaneous Character Operations
+
+@deffn procedure char? object
+@cindex type predicate, for character
+Returns @code{#t} if @var{object} is a character; otherwise returns
+@code{#f}.
+@end deffn
+
+@deffn procedure char-upcase char
+@deffnx procedure char-downcase char
+@cindex uppercase, character conversion
+@cindex lowercase, character conversion
+@cindex case conversion, of character
+@findex char-ci=?
+Returns the uppercase or lowercase equivalent of @var{char} if
+@var{char} is a letter; otherwise returns @var{char}. These procedures
+return a character @var{char2} such that @code{(char-ci=? @var{char}
+@var{char2})}.
+@end deffn
+
+@deffn procedure char->digit char [radix]
+If @var{char} is a character representing a digit in the given
+@var{radix}, returns the corresponding integer value. If you specify
+@var{radix} (which must be an exact integer between 2 and 36 inclusive),
+the conversion is done in that base, otherwise it is done in base 10.
+If @var{char} doesn't represent a digit in base @var{radix},
+@code{char->digit} returns @code{#f}.
+
+Note that this procedure is insensitive to the alphabetic case of
+@var{char}.
+
+@example
+@group
+(char->digit #\8) @result{} 8
+(char->digit #\e 16) @result{} 14
+(char->digit #\e) @result{} #f
+@end group
+@end example
+@end deffn
+
+@deffn procedure digit->char digit [radix]
+Returns a character that represents @var{digit} in the radix given by
+@var{radix}. @var{Radix} must be an exact integer between 2 and 36
+(inclusive), and defaults to 10. @var{Digit}, which must be an
+exact non-negative integer, should be less than @var{radix}; if
+@var{digit} is greater than or equal to @var{radix}, @code{digit->char}
+returns @code{#f}.
+
+@example
+@group
+(digit->char 8) @result{} #\8
+(digit->char 14 16) @result{} #\E
+@end group
+@end example
+@end deffn
+
+@node Internal Representation of Characters, ISO-8859-1 Characters, Miscellaneous Character Operations, Characters
+@section Internal Representation of Characters
+@cindex internal representation, for character
+
+@cindex character code (defn)
+@cindex character bits (defn)
+@cindex code, of character (defn)
+@cindex bucky bit, of character (defn)
+@cindex ASCII character
+An MIT/GNU Scheme character consists of a @dfn{code} part and a @dfn{bucky
+bits} part. The MIT/GNU Scheme set of characters can represent more
+characters than @acronym{ASCII} can; it includes characters with Super,
+Hyper, and Top bucky bits, as well as Control and Meta. Every
+@acronym{ASCII} character corresponds to some MIT/GNU Scheme character, but not
+vice versa.@footnote{Note that the Control bucky bit is different from
+the @acronym{ASCII} control key. This means that @code{#\SOH} (@acronym{ASCII}
+ctrl-A) is different from @code{#\C-A}. In fact, the Control bucky bit
+is completely orthogonal to the @acronym{ASCII} control key, making possible
+such characters as @code{#\C-SOH}.}
+
+MIT/GNU Scheme uses a 16-bit character code with 5 bucky bits. Normally,
+Scheme uses the least significant 8 bits of the character code to
+contain the @acronym{ISO-8859-1} representation for the character. The
+representation is expanded in order to allow for the use of
+@acronym{UTF-16} in the future.
+
+@deffn procedure make-char code bucky-bits
+@cindex construction, of character
+Builds a character from @var{code} and @var{bucky-bits}. Both
+@var{code} and @var{bucky-bits} must be exact non-negative integers in
+the appropriate range. Use @code{char-code} and @code{char-bits} to
+extract the code and bucky bits from the character. If @code{0} is
+specified for @var{bucky-bits}, @code{make-char} produces an ordinary
+character; otherwise, the appropriate bits are turned on as follows:
+
+@example
+@group
+1 Meta
+2 Control
+4 Super
+8 Hyper
+16 Top
+@end group
+@end example
+
+For example,
+
+@example
+@group
+(make-char 97 0) @result{} #\a
+(make-char 97 1) @result{} #\M-a
+(make-char 97 2) @result{} #\C-a
+(make-char 97 3) @result{} #\C-M-a
+@end group
+@end example
+@end deffn
+
+@deffn procedure char-bits char
+@cindex selection, of character component
+@cindex component selection, of character
+Returns the exact integer representation of @var{char}'s bucky bits.
+For example,
+
+@example
+@group
+(char-bits #\a) @result{} 0
+(char-bits #\m-a) @result{} 1
+(char-bits #\c-a) @result{} 2
+(char-bits #\c-m-a) @result{} 3
+@end group
+@end example
+@end deffn
+
+@deffn procedure char-code char
+Returns the character code of @var{char}, an exact integer. For
+example,
+
+@example
+@group
+(char-code #\a) @result{} 97
+(char-code #\c-a) @result{} 97
+@end group
+@end example
+@end deffn
+
+@defvr variable char-code-limit
+@defvrx variable char-bits-limit
+These variables define the (exclusive) upper limits for the character
+code and bucky bits (respectively). The character code and bucky bits
+are always exact non-negative integers, and are strictly less than the
+value of their respective limit variable.
+@end defvr
+
+@deffn procedure char->integer char
+@deffnx procedure integer->char k
+@code{char->integer} returns the character code representation for
+@var{char}. @code{integer->char} returns the character whose character
+code representation is @var{k}.
+
+@findex char-ascii?
+@findex char->ascii
+In MIT/GNU Scheme, if @code{(char-ascii? @var{char})} is true, then
+
+@example
+(eqv? (char->ascii @var{char}) (char->integer @var{char}))
+@end example
+
+@noindent
+However, this behavior is not required by the Scheme standard, and
+code that depends on it is not portable to other implementations.
+
+@findex char<=?
+@findex <=
+These procedures implement order isomorphisms between the set of
+characters under the @code{char<=?} ordering and some subset of the
+integers under the @code{<=} ordering. That is, if
+
+@example
+(char<=? a b) @result{} #t @r{and} (<= x y) @result{} #t
+@end example
+
+and @code{x} and @code{y} are in the range of @code{char->integer},
+then
+
+@example
+@group
+(<= (char->integer a)
+ (char->integer b)) @result{} #t
+(char<=? (integer->char x)
+ (integer->char y)) @result{} #t
+@end group
+@end example
+
+Note: If the argument to @code{char->integer} or @code{integer->char} is
+a constant, the compiler will constant-fold the call, replacing it with
+the corresponding result. This is a very useful way to denote unusual
+character constants or @acronym{ASCII} codes.
+@end deffn
+
+@defvr variable char-integer-limit
+The range of @code{char->integer} is defined to be the exact
+non-negative integers that are less than the value of this variable
+(exclusive).
+@end defvr
+
+@node ISO-8859-1 Characters, Character Sets, Internal Representation of Characters, Characters
+@section ISO-8859-1 Characters
+
+MIT/GNU Scheme internally uses @acronym{ISO-8859-1} codes for
+@acronym{I/O}, and stores character objects in a fashion that makes it
+convenient to convert between @acronym{ISO-8859-1} codes and
+characters. Also, character strings are implemented as byte vectors
+whose elements are @acronym{ISO-8859-1} codes; these codes are
+converted to character objects when accessed. For these reasons it is
+sometimes desirable to be able to convert between @acronym{ISO-8859-1}
+codes and characters.
+
+@cindex ISO-8859-1 character (defn)
+@cindex character, ISO-8859-1 (defn)
+Not all characters can be represented as @acronym{ISO-8859-1} codes. A
+character that has an equivalent @acronym{ISO-8859-1} representation is
+called an @dfn{ISO-8859-1 character}.
+
+For historical reasons, the procedures that manipulate
+@acronym{ISO-8859-1} characters use the word ``@acronym{ASCII}'' rather
+than ``@acronym{ISO-8859-1}''.
+
+@deffn procedure char-ascii? char
+Returns the @acronym{ISO-8859-1} code for @var{char} if @var{char} has an
+@acronym{ISO-8859-1} representation; otherwise returns @code{#f}.
+
+In the current implementation, the characters that satisfy this
+predicate are those in which the bucky bits are turned off, and for
+which the character code is less than 256.
+@end deffn
+
+@deffn procedure char->ascii char
+Returns the @acronym{ISO-8859-1} code for @var{char}. An error
+@code{condition-type:bad-range-argument} is signalled if @var{char}
+doesn't have an @acronym{ISO-8859-1} representation.
+@findex condition-type:bad-range-argument
+@end deffn
+
+@deffn procedure ascii->char code
+@var{Code} must be the exact integer representation of an
+@acronym{ISO-8859-1} code. This procedure returns the character
+corresponding to @var{code}.
+@end deffn
+
+@node Character Sets, Unicode, ISO-8859-1 Characters, Characters
+@section Character Sets
+@cindex character set
+@cindex set, of characters
+
+MIT/GNU Scheme's character-set abstraction is used to represent groups of
+characters, such as the letters or digits. Character sets may contain
+only @acronym{ISO-8859-1} characters; in the future this may be changed
+to allow the full range of characters.
+
+There is no meaningful external representation for character sets; use
+@code{char-set-members} to examine their contents. There is (at
+present) no specific equivalence predicate for character sets; use
+@code{equal?} for this purpose.
+
+@deffn procedure char-set? object
+@cindex type predicate, for character set
+Returns @code{#t} if @var{object} is a character set; otherwise returns
+@code{#f}.
+@end deffn
+
+@defvr variable char-set:upper-case
+@defvrx variable char-set:lower-case
+@defvrx variable char-set:alphabetic
+@defvrx variable char-set:numeric
+@defvrx variable char-set:alphanumeric
+@defvrx variable char-set:whitespace
+@defvrx variable char-set:not-whitespace
+@defvrx variable char-set:graphic
+@defvrx variable char-set:not-graphic
+@defvrx variable char-set:standard
+These variables contain predefined character sets.
+To see the contents of one of these sets, use @code{char-set-members}.
+
+@cindex alphabetic character (defn)
+@cindex character, alphabetic (defn)
+@cindex numeric character (defn)
+@cindex character, numeric (defn)
+@cindex alphanumeric character (defn)
+@cindex character, alphanumeric (defn)
+@cindex whitespace character (defn)
+@cindex character, whitespace (defn)
+@cindex graphic character (defn)
+@cindex character, graphic (defn)
+@cindex standard character (defn)
+@cindex character, standard (defn)
+@findex #\space
+@findex #\tab
+@findex #\page
+@findex #\linefeed
+@findex #\return
+@findex #\newline
+@dfn{Alphabetic} characters are the 52 upper and lower case letters.
+@dfn{Numeric} characters are the 10 decimal digits. @dfn{Alphanumeric}
+characters are those in the union of these two sets. @dfn{Whitespace}
+characters are @code{#\space}, @code{#\tab}, @code{#\page},
+@code{#\linefeed}, and @code{#\return}. @var{Graphic} characters are
+the printing characters and @code{#\space}. @var{Standard} characters
+are the printing characters, @code{#\space}, and @code{#\newline}.
+These are the printing characters:
+
+@example
+@group
+! " # $ % & ' ( ) * + , - . /
+0 1 2 3 4 5 6 7 8 9
+: ; < = > ? @@
+A B C D E F G H I J K L M N O P Q R S T U V W X Y Z
+[ \ ] ^ _ `
+a b c d e f g h i j k l m n o p q r s t u v w x y z
+@{ | @} ~
+@end group
+@end example
+@end defvr
+
+@deffn {procedure} char-upper-case? char
+@deffnx {procedure} char-lower-case? char
+@deffnx {procedure} char-alphabetic? char
+@deffnx {procedure} char-numeric? char
+@deffnx procedure char-alphanumeric? char
+@deffnx {procedure} char-whitespace? char
+@deffnx procedure char-graphic? char
+@deffnx procedure char-standard? object
+These predicates are defined in terms of the respective character sets
+defined above.
+@end deffn
+
+@deffn procedure char-set-members char-set
+Returns a newly allocated list of the characters in @var{char-set}.
+@end deffn
+
+@deffn procedure char-set-member? char-set char
+Returns @code{#t} if @var{char} is in @var{char-set}; otherwise returns
+@code{#f}.
+@end deffn
+
+@deffn procedure char-set char @dots{}
+@cindex construction, of character set
+Returns a character set consisting of the specified @acronym{ISO-8859-1}
+characters. With no arguments, @code{char-set} returns an empty
+character set.
+@end deffn
+
+@deffn procedure chars->char-set chars
+Returns a character set consisting of @var{chars}, which must be a list
+of @acronym{ISO-8859-1} characters. This is equivalent to @code{(apply
+char-set @var{chars})}.
+@end deffn
+
+@deffn procedure string->char-set string
+Returns a character set consisting of all the characters that occur in
+@var{string}.
+@end deffn
+
+@deffn procedure ascii-range->char-set lower upper
+@var{Lower} and @var{upper} must be exact non-negative integers
+representing @acronym{ISO-8859-1} character codes, and @var{lower} must
+be less than or equal to @var{upper}. This procedure creates and
+returns a new character set consisting of the characters whose
+@acronym{ISO-8859-1} codes are between @var{lower} (inclusive) and
+@var{upper} (exclusive).
+
+For historical reasons, the name of this procedure refers to
+``@acronym{ASCII}'' rather than ``@acronym{ISO-8859-1}''.
+@end deffn
+
+@deffn procedure predicate->char-set predicate
+@var{Predicate} must be a procedure of one argument.
+@code{predicate->char-set} creates and returns a character set
+consisting of the @acronym{ISO-8859-1} characters for which
+@var{predicate} is true.
+@end deffn
+
+@deffn procedure char-set-difference char-set1 char-set2
+Returns a character set consisting of the characters that are in
+@var{char-set1} but aren't in @var{char-set2}.
+@end deffn
+
+@deffn procedure char-set-intersection char-set @dots{}
+Returns a character set consisting of the characters that are in all of
+the @var{char-set}s.
+@end deffn
+
+@deffn procedure char-set-union char-set @dots{}
+Returns a character set consisting of the characters that are in at
+least one o the @var{char-set}s.
+@end deffn
+
+@deffn procedure char-set-invert char-set
+Returns a character set consisting of the @acronym{ISO-8859-1}
+characters that are not in @var{char-set}.
+@end deffn
+
+@node Unicode, , Character Sets, Characters
+@section Unicode
+
+@cindex Unicode
+MIT/GNU Scheme provides rudimentary support for Unicode characters. In an
+ideal world, Unicode would be the base character set for MIT/GNU Scheme,
+but this implementation predates the invention of Unicode. And
+converting an application of this size is a considerable undertaking.
+So for the time being, the base character set is @acronym{ISO-8859-1}
+and Unicode support is grafted on.
+
+This Unicode support was implemented as a part of the @acronym{XML}
+parser (@pxref{XML Parser}) implementation. @acronym{XML} uses
+Unicode as its base character set, and any @acronym{XML}
+implementation @emph{must} support Unicode.
+
+The Unicode implementation consists of two parts: @acronym{I/O}
+procedures that read and write @acronym{UTF-8} characters, and an
+@dfn{alphabet} abstraction, which is an efficient implementation of
+sets of Unicode code points (similar to the @code{char-set}
+abstraction).
+
+@cindex Code point, Unicode
+The basic unit in a Unicode implementation is the @dfn{code point}.
+
+@deffn procedure unicode-code-point? object
+Returns @code{#t} if @var{object} is a Unicode code point. Code
+points are implemented as exact non-negative integers. Code points
+are further limited, by the Unicode standard, to be strictly less than
+@code{#x80000000}.
+@end deffn
+
+The next few procedures do @acronym{I/O} on code points.
+
+@deffn procedure read-utf8-code-point port
+Reads and returns a @acronym{UTF-8}-encoded code point from
+@var{port}. Returns an end-of-file object if there are no more
+characters available from @var{port}. Signals an error if the input
+stream isn't a valid @acronym{UTF-8} encoding.
+@end deffn
+
+@deffn procedure write-utf8-code-point code-point port
+Writes @var{code-point} to @var{port} in the @acronym{UTF-8} encoding.
+@end deffn
+
+@deffn procedure utf8-string->code-point string
+Reads and returns a @acronym{UTF-8}-encoded code point from
+@var{string}. Equivalent to
+
+@example
+(read-utf8-code-point (string->input-port @var{string}))
+@end example
+@end deffn
+
+@deffn procedure code-point->utf8-string code-point
+Returns a newly-allocated string containing the @acronym{UTF-8}
+encoding of @var{code-point}. Equivalent to
+
+@example
+@group
+(with-string-output-port
+ (lambda (port)
+ (write-utf8-code-point @var{code-point} port)))
+@end group
+@end example
+@end deffn
+
+@cindex Alphabet, Unicode
+Applications often need to manipulate sets of characters, such as the
+set of alphabetic characters or the set of whitespace characters. The
+@dfn{alphabet} abstraction provides an efficient implementation of
+sets of Unicode code points.
+
+@deffn procedure alphabet? object
+Returns @code{#t} if @var{object} is a Unicode alphabet, otherwise
+returns @code{#f}.
+@end deffn
+
+@deffn procedure code-points->alphabet items
+Returns a Unicode alphabet containing the code points described by
+@var{items}. @var{Items} must satisfy
+@code{well-formed-code-points-list?}.
+@end deffn
+
+@deffn procedure alphabet->code-points alphabet
+Returns a well-formed code-points list that describes the code points
+represented by @var{alphabet}.
+@end deffn
+
+@deffn procedure well-formed-code-points-list? object
+Returns @code{#t} if @var{object} is a well-formed code-points list,
+otherwise returns @code{#f}. A well-formed code-points list is a
+proper list, each element of which is either a code point or a pair of
+code points. A pair of code points represents a contiguous range of
+code points. The @sc{car} of the pair is the lower limit, and the
+@sc{cdr} is the upper limit. Both limits are inclusive, and the lower
+limit must be strictly less than the upper limit.
+@end deffn
+
+@deffn procedure code-point-in-alphabet? code-point alphabet
+Returns @code{#t} if @var{code-point} is a member of @var{alphabet},
+otherwise returns @code{#f}.
+@end deffn
+
+@deffn procedure char-in-alphabet? char alphabet
+Returns @code{#t} if @var{char} is a member of @var{alphabet},
+otherwise returns @code{#f}. Equivalent to
+
+@example
+(code-point-in-alphabet? (char-code @var{char}) @var{alphabet})
+@end example
+@end deffn
+
+Character sets and alphabets can be converted to one another, provided
+that the alphabet contains only 8-bit code points. This is true
+because 8-bit code points in Unicode map directly to
+@acronym{ISO-8859-1} characters, which is what character sets contain.
+
+@deffn procedure char-set->alphabet char-set
+Returns a Unicode alphabet containing the code points that correspond
+to characters that are members of @var{char-set}.
+@end deffn
+
+@deffn procedure alphabet->char-set alphabet
+Returns a character set containing the characters that correspond to
+8-bit code points that are members of @var{alphabet}. (Code points
+outside the 8-bit range are ignored.)
+@end deffn
+
+@deffn procedure string->alphabet string
+Returns a Unicode alphabet containing the code points corresponding to
+the characters in @var{string}. Equivalent to
+
+@example
+(char-set->alphabet (string->char-set @var{string}))
+@end example
+@end deffn
+
+@deffn procedure alphabet->string alphabet
+Returns a newly-allocated string containing the characters
+corresponding to the 8-bit code points in @var{alphabet}. (Code
+points outside the 8-bit range are ignored.)
+@end deffn
+
+@deffn procedure 8-bit-alphabet? alphabet
+Returns @code{#t} if @var{alphabet} contains only 8-bit code points,
+otherwise returns @code{#f}.
+@end deffn
+
+@deffn procedure alphabet+ alphabet @dots{}
+Returns a Unicode alphabet that contains each code point that is a
+member of any of the @var{alphabet} arguments.
+@end deffn
+
+@deffn procedure alphabet- alphabet1 alphabet2
+Returns a Unicode alphabet that contains each code point that is a
+member of @var{alphabet1} and is not a member of @var{alphabet2}.
+@end deffn
--- /dev/null
+@c This file is part of the MIT/GNU Scheme Reference Manual.
+@c $Id: environments.texi,v 1.1 2003/04/15 03:29:32 cph Exp $
+
+@c Copyright 1991,1992,1993,1994,1995 Massachusetts Institute of Technology
+@c Copyright 1996,1997,1999,2000,2001 Massachusetts Institute of Technology
+@c Copyright 2002,2003 Massachusetts Institute of Technology
+@c See file scheme.texinfo for copying conditions.
+
+@node Environments, Input/Output, Procedures, Top
+@chapter Environments
+
+@menu
+* Environment Operations::
+* Environment Variables::
+* REPL Environment::
+* Top-level Environments::
+@end menu
+
+@node Environment Operations, Environment Variables, Environments, Environments
+@section Environment Operations
+
+Environments are first-class objects in MIT/GNU Scheme. An environment
+consists of some bindings and possibly a parent environment, from which
+other bindings are inherited. The operations in this section reveal the
+frame-like structure of environments by permitting you to examine the
+bindings of a particular environment separately from those of its
+parent.
+
+@cindex variable binding
+@cindex binding, variable
+@cindex unassigned binding
+@cindex binding, unassigned
+@findex condition-type:unassigned-variable
+There are several types of bindings that can occur in an environment.
+The most common is the simple variable binding, which associates a value
+(any Scheme object) with an identifier (a symbol). A variable binding
+can also be @dfn{unassigned}, which means that it has no value. An
+unassigned variable is bound, in that is will shadow other bindings of
+the same name in ancestor environments, but a reference to that variable
+will signal an error of type @code{condition-type:unassigned-variable}.
+An unassigned variable can be @dfn{assigned} (using @code{set!} or
+@code{environment-assign!}) to give it a value.
+
+@cindex keyword binding
+@cindex syntactic keyword binding
+@cindex binding, syntactic keyword
+@findex condition-type:macro-binding
+In addition to variable bindings, an environment can also have
+@dfn{keyword bindings}. A keyword binding associates a syntactic
+keyword (usually a macro transformer) with an identifier. Keyword
+bindings are special in that they are considered ``bound'', but ordinary
+variable references don't work on them. So an attempt to reference or
+assign a keyword binding results in an error of type
+@code{condition-type:macro-binding}. However, keyword bindings can be
+redefined using @code{define} or @code{environment-define}.
+
+@deffn procedure environment? object
+@cindex type predicate, for environment
+Returns @code{#t} if @var{object} is an environment; otherwise returns
+@code{#f}.
+@end deffn
+
+@deffn procedure environment-has-parent? environment
+Returns @code{#t} if @var{environment} has a parent environment;
+otherwise returns @code{#f}.
+@end deffn
+
+@deffn procedure environment-parent environment
+Returns the parent environment of @var{environment}. It is an error if
+@var{environment} has no parent.
+@end deffn
+
+@deffn procedure environment-bound-names environment
+Returns a newly allocated list of the names (symbols) that are bound by
+@var{environment}. This does not include the names that are bound by
+the parent environment of @var{environment}. It does include names that
+are unassigned or keywords in @var{environment}.
+@end deffn
+
+@deffn procedure environment-macro-names environment
+Returns a newly allocated list of the names (symbols) that are bound to
+syntactic keywords in @var{environment}.
+@end deffn
+
+@deffn procedure environment-bindings environment
+Returns a newly allocated list of the bindings of @var{environment};
+does not include the bindings of the parent environment. Each element
+of this list takes one of two forms: @code{(@var{symbol})} indicates
+that @var{symbol} is bound but unassigned, while @code{(@var{symbol}
+@var{object})} indicates that @var{symbol} is bound, and its value is
+@var{object}.
+@end deffn
+
+@deffn procedure environment-reference-type environment symbol
+Returns a symbol describing the @dfn{reference type} of @var{symbol} in
+@var{environment} or one of its ancestor environments. The result is
+one of the following:
+
+@table @code
+@item normal
+means @var{symbol} is a variable binding with a normal value.
+
+@item unassigned
+means @var{symbol} is a variable binding with no value.
+
+@item macro
+means @var{symbol} is a keyword binding.
+
+@item unbound
+means @var{symbol} has no associated binding.
+@end table
+@end deffn
+
+@deffn procedure environment-bound? environment symbol
+Returns @code{#t} if @var{symbol} is bound in @var{environment} or one
+of its ancestor environments; otherwise returns @code{#f}. This is
+equivalent to
+
+@example
+(not (eq? 'unbound
+ (environment-reference-type @var{environment} @var{symbol})))
+@end example
+@end deffn
+
+@deffn procedure environment-assigned? environment symbol
+Returns @code{#t} if @var{symbol} is bound in @var{environment} or one
+of its ancestor environments, and has a normal value. Returns @code{#f}
+if it is bound but unassigned. Signals an error if it is unbound or is
+bound to a keyword.
+@end deffn
+
+@deffn procedure environment-lookup environment symbol
+@var{Symbol} must be bound to a normal value in @var{environment} or one
+of its ancestor environments. Returns the value to which it is bound.
+Signals an error if unbound, unassigned, or a keyword.
+@end deffn
+
+@deffn procedure environment-lookup-macro environment symbol
+If @var{symbol} is a keyword binding in @var{environment} or one of its
+ancestor environments, returns the value of the binding. Otherwise,
+returns @code{#f}. Does not signal any errors other than argument-type
+errors.
+@end deffn
+
+@deffn procedure environment-assignable? environment symbol
+@var{Symbol} must be bound in @var{environment} or one of its ancestor
+environments. Returns @code{#t} if the binding may be modified by side
+effect.
+@end deffn
+
+@deffn procedure environment-assign! environment symbol object
+@var{Symbol} must be bound in @var{environment} or one of its ancestor
+environments, and must be assignable. Modifies the binding to have
+@var{object} as its value, and returns an unspecified result.
+@end deffn
+
+@deffn procedure environment-definable? environment symbol
+Returns @code{#t} if @var{symbol} is definable in @var{environment}, and
+@code{#f} otherwise. At present, this is false for environments
+generated by application of compiled procedures, and true for all other
+environments.
+@end deffn
+
+@deffn procedure environment-define environment symbol object
+Defines @var{symbol} to be bound to @var{object} in @var{environment},
+and returns an unspecified value. Signals an error if @var{symbol}
+isn't definable in @var{environment}.
+@end deffn
+
+@deffn procedure environment-define-macro environment symbol transformer
+Defines @var{symbol} to be a keyword bound to @var{transformer} in
+@var{environment}, and returns an unspecified value. Signals an error
+if @var{symbol} isn't definable in @var{environment}. The type of
+@var{transformer} is defined by the syntax engine and is not checked by
+this procedure. If the type is incorrect this will subsequently signal
+an error during syntax expansion.
+@end deffn
+
+@deffn procedure eval expression environment
+@cindex s-expression
+@cindex evaluation, of s-expression
+Evaluates @var{expression}, a list-structure representation (sometimes
+called s-expression representation) of a Scheme expression, in
+@var{environment}. You rarely need @code{eval} in ordinary programs; it
+is useful mostly for evaluating expressions that have been created ``on
+the fly'' by a program. @code{eval} is relatively expensive because it
+must convert @var{expression} to an internal form before it is executed.
+
+@example
+@group
+(define foo (list '+ 1 2))
+(eval foo (the-environment)) @result{} 3
+@end group
+@end example
+@end deffn
+
+@node Environment Variables, REPL Environment, Environment Operations, Environments
+@section Environment Variables
+
+@findex define
+The @code{user-initial-environment} is where the top-level
+read-eval-print (@acronym{REP}) loop evaluates expressions and binds
+definitions. It is a child of @code{system-global-environment}, which
+is where all of the Scheme system definitions are bound. All of the
+bindings in @code{system-global-environment} are available when the
+current environment is @code{user-initial-environment}. However, any
+new bindings that you create in the @acronym{REP} loop (with
+@code{define} forms or by loading files containing @code{define} forms)
+occur in @code{user-initial-environment}.
+
+@defvr variable system-global-environment
+The variable @code{system-global-environment} is bound to the
+distinguished environment that's the ancestor of most other environments
+(except for those created by @code{make-root-top-level-environment}).
+It is the parent environment of @code{user-initial-environment}.
+Primitives, system procedures, and most syntactic keywords are bound
+(and sometimes closed) in this environment.
+@end defvr
+
+@defvr variable user-initial-environment
+The variable @code{user-initial-environment} is bound to the default
+environment in which typed expressions are evaluated by the top-level
+@acronym{REP} loop.
+
+Although all bindings in @code{system-global-environment} are visible to
+the @acronym{REP} loop, definitions that are typed at, or loaded by, the
+@acronym{REP} loop occur in the @code{user-initial-environment}. This
+is partly a safety measure: if you enter a definition that happens to
+have the same name as a critical system procedure, your definition will
+be visible only to the procedures you define in the
+@code{user-initial-environment}; the MIT/GNU Scheme system procedures, which
+are defined in @code{system-global-environment}, will continue to see
+the original definition.
+@end defvr
+
+@node REPL Environment, Top-level Environments, Environment Variables, Environments
+@section REPL Environment
+
+@deffn procedure nearest-repl/environment
+@findex user-initial-environment
+Returns the current @acronym{REP} loop environment (i.e.@: the current
+environment of the closest enclosing @acronym{REP} loop). When Scheme
+first starts up, this is the same as @code{user-initial-environment}.
+@end deffn
+
+@deffn procedure ge environment
+Changes the current @acronym{REP} loop environment to @var{environment}.
+@var{Environment} can be either an environment or a procedure object.
+If it's a procedure, the environment in which that procedure was closed
+is the new environment.
+@end deffn
+
+@node Top-level Environments, , REPL Environment, Environments
+@section Top-level Environments
+
+@cindex top-level environment
+@cindex interpreter environment
+@cindex environment, top-level
+@cindex environment, interpreter
+The operations in this section manipulate @dfn{top-level environments},
+as opposed to environments created by the application of procedures.
+For historical reasons, top-level environments are referred to as
+@dfn{interpreter environments}.
+
+@deffn {special form} the-environment
+@cindex current environment
+@cindex environment, current
+Returns the current environment. This form may only be evaluated in a
+top-level environment. An error is signalled if it appears elsewhere.
+@end deffn
+
+@deffn procedure top-level-environment? object
+@deffnx procedure interpreter-environment? object
+@cindex type predicate, for top-level environment
+Returns @code{#t} if @var{object} is an top-level environment; otherwise
+returns @code{#f}.
+
+@code{interpreter-environment?} is an alias for
+@code{top-level-environment?}.
+@end deffn
+
+@deffn procedure extend-top-level-environment environment [names [values]]
+@deffnx procedure make-root-top-level-environment [names [values]]
+Returns a newly allocated top-level environment.
+@code{extend-top-level-environment} creates an environment that has
+parent @var{environment}, while @code{make-root-top-level-environment}
+creates an environment that has no parent.
+
+The optional arguments @var{names} and @var{values} are used to specify
+initial bindings in the new environment. If specified, @var{names} must
+be a list of symbols, and @var{values} must be a list of objects. If
+only @var{names} is specified, each name in @var{names} will be bound in
+the environment, but unassigned. If @var{names} and @var{values} are
+both specified, they must be the same length, and each name in
+@var{names} will be bound to the corresponding value in @var{values}.
+If neither @var{names} nor @var{values} is specified, the environment
+will have no initial bindings.
+@end deffn
+
+@deffn procedure link-variables environment1 symbol1 environment2 symbol2
+Defines @var{symbol1} in @var{environment1} to have the same binding as
+@var{symbol2} in @var{environment2}, and returns an unspecified value.
+Prior to the call, @var{symbol2} must be bound in @var{environment2},
+but the type of binding is irrelevant; it may be a normal binding, an
+unassigned binding, or a keyword binding. Signals an error if
+@var{symbol1} isn't definable in @var{environment1}, or if @var{symbol2}
+is unbound in @var{environment2}.
+
+By ``the same binding'', we mean that the value cell is shared between
+the two environments. If a value is assigned to @var{symbol1} in
+@var{environment1}, a subsequent reference to @var{symbol2} in
+@var{environment2} will see that value, and vice versa.
+@end deffn
+
+@deffn procedure unbind-variable environment symbol
+If @var{symbol} is bound in @var{environment} or one of its ancestor
+environments, removes the binding, so that subsequent accesses to that
+symbol behave as if the binding never existed. Returns @code{#t} if there
+was a binding prior to the call, and @code{#f} if there wasn't.
+@end deffn
--- /dev/null
+@c This file is part of the MIT/GNU Scheme Reference Manual.
+@c $Id: equivalence.texi,v 1.1 2003/04/15 03:29:35 cph Exp $
+
+@c Copyright 1991,1992,1993,1994,1995 Massachusetts Institute of Technology
+@c Copyright 1996,1997,1999,2000,2001 Massachusetts Institute of Technology
+@c Copyright 2002,2003 Massachusetts Institute of Technology
+@c See file scheme.texinfo for copying conditions.
+
+@node Equivalence Predicates, Numbers, Special Forms, Top
+@chapter Equivalence Predicates
+
+@cindex predicate (defn)
+@cindex predicate, equivalence (defn)
+@cindex equivalence predicate (defn)
+@cindex comparison, for equivalence
+@findex eq?
+@findex eqv?
+@findex equal?
+A @dfn{predicate} is a procedure that always returns a boolean value
+(@code{#t} or @code{#f}). An @dfn{equivalence predicate} is the
+computational analogue of a mathematical equivalence relation (it is
+symmetric, reflexive, and transitive). Of the equivalence predicates
+described in this section, @code{eq?} is the finest or most
+discriminating, and @code{equal?} is the coarsest. @code{eqv?} is
+slightly less discriminating than @code{eq?}.
+
+@deffn procedure eqv? obj1 obj2
+The @code{eqv?} procedure defines a useful equivalence relation on
+objects. Briefly, it returns @code{#t} if @var{obj1} and @var{obj2}
+should normally be regarded as the same object.
+
+The @code{eqv?} procedure returns @code{#t} if:
+
+@itemize @bullet
+@item
+@var{obj1} and @var{obj2} are both @code{#t} or both @code{#f}.
+
+@item
+@var{obj1} and @var{obj2} are both interned symbols and
+
+@example
+@group
+(string=? (symbol->string @var{obj1})
+ (symbol->string @var{obj2}))
+ @result{} #t
+@end group
+@end example
+@findex string=?
+@findex symbol->string
+
+@item
+@var{obj1} and @var{obj2} are both numbers, are numerically equal
+according to the @code{=} procedure, and are either both exact or both
+inexact (@pxref{Numbers}).
+@findex =
+
+@item
+@var{obj1} and @var{obj2} are both characters and are the same character
+according to the @code{char=?} procedure (@pxref{Characters}).
+@findex char=?
+
+@item
+both @var{obj1} and @var{obj2} are the empty list.
+
+@item
+@var{obj1} and @var{obj2} are procedures whose location tags are equal.
+
+@item
+@var{obj1} and @var{obj2} are pairs, vectors, strings, bit strings,
+records, cells, or weak pairs that denote the same locations in the
+store.
+@end itemize
+
+@noindent
+The @code{eqv?} procedure returns @code{#f} if:
+
+@itemize @bullet
+@item
+@var{obj1} and @var{obj2} are of different types.
+
+@item
+one of @var{obj1} and @var{obj2} is @code{#t} but the other is
+@code{#f}.
+
+@item
+@var{obj1} and @var{obj2} are symbols but
+
+@example
+@group
+(string=? (symbol->string @var{obj1})
+ (symbol->string @var{obj2}))
+ @result{} #f
+@end group
+@end example
+@findex string=?
+@findex symbol->string
+
+@item
+one of @var{obj1} and @var{obj2} is an exact number but the other is an
+inexact number.
+
+@item
+@var{obj1} and @var{obj2} are numbers for which the @code{=} procedure
+returns @code{#f}.
+@findex =
+
+@item
+@var{obj1} and @var{obj2} are characters for which the @code{char=?}
+procedure returns @code{#f}.
+@findex char=?
+
+@item
+one of @var{obj1} and @var{obj2} is the empty list but the other is not.
+
+@item
+@var{obj1} and @var{obj2} are procedures that would behave differently
+(return a different value or have different side effects) for some
+arguments.
+
+@item
+@var{obj1} and @var{obj2} are pairs, vectors, strings, bit strings,
+records, cells, or weak pairs that denote distinct locations.
+@end itemize
+
+Some examples:
+
+@example
+@group
+(eqv? 'a 'a) @result{} #t
+(eqv? 'a 'b) @result{} #f
+(eqv? 2 2) @result{} #t
+(eqv? '() '()) @result{} #t
+(eqv? 100000000 100000000) @result{} #t
+(eqv? (cons 1 2) (cons 1 2)) @result{} #f
+(eqv? (lambda () 1)
+ (lambda () 2)) @result{} #f
+(eqv? #f 'nil) @result{} #f
+(let ((p (lambda (x) x)))
+ (eqv? p p)) @result{} #t
+@end group
+@end example
+
+The following examples illustrate cases in which the above rules do not
+fully specify the behavior of @code{eqv?}. All that can be said about
+such cases is that the value returned by @code{eqv?} must be a boolean.
+
+@example
+@group
+(eqv? "" "") @result{} @r{unspecified}
+(eqv? '#() '#()) @result{} @r{unspecified}
+(eqv? (lambda (x) x)
+ (lambda (x) x)) @result{} @r{unspecified}
+(eqv? (lambda (x) x)
+ (lambda (y) y)) @result{} @r{unspecified}
+@end group
+@end example
+
+The next set of examples shows the use of @code{eqv?} with procedures
+that have local state. @code{gen-counter} must return a distinct
+procedure every time, since each procedure has its own internal counter.
+@code{gen-loser}, however, returns equivalent procedures each time,
+since the local state does not affect the value or side effects of the
+procedures.
+
+@example
+@group
+(define gen-counter
+ (lambda ()
+ (let ((n 0))
+ (lambda () (set! n (+ n 1)) n))))
+(let ((g (gen-counter)))
+ (eqv? g g)) @result{} #t
+(eqv? (gen-counter) (gen-counter))
+ @result{} #f
+@end group
+
+@group
+(define gen-loser
+ (lambda ()
+ (let ((n 0))
+ (lambda () (set! n (+ n 1)) 27))))
+(let ((g (gen-loser)))
+ (eqv? g g)) @result{} #t
+(eqv? (gen-loser) (gen-loser))
+ @result{} @r{unspecified}
+@end group
+
+@group
+(letrec ((f (lambda () (if (eqv? f g) 'both 'f)))
+ (g (lambda () (if (eqv? f g) 'both 'g)))
+ (eqv? f g))
+ @result{} @r{unspecified}
+
+(letrec ((f (lambda () (if (eqv? f g) 'f 'both)))
+ (g (lambda () (if (eqv? f g) 'g 'both)))
+ (eqv? f g))
+ @result{} #f
+@end group
+@end example
+
+Objects of distinct types must never be regarded as the same object.
+
+Since it is an error to modify constant objects (those returned by
+literal expressions), the implementation may share structure between
+constants where appropriate. Thus the value of @code{eqv?} on constants
+is sometimes unspecified.
+
+@example
+@group
+(let ((x '(a)))
+ (eqv? x x)) @result{} #t
+(eqv? '(a) '(a)) @result{} @r{unspecified}
+(eqv? "a" "a") @result{} @r{unspecified}
+(eqv? '(b) (cdr '(a b))) @result{} @r{unspecified}
+@end group
+@end example
+
+Rationale: The above definition of @code{eqv?} allows implementations
+latitude in their treatment of procedures and literals: implementations
+are free either to detect or to fail to detect that two procedures or
+two literals are equivalent to each other, and can decide whether or not
+to merge representations of equivalent objects by using the same pointer
+or bit pattern to represent both.
+@end deffn
+
+@page
+@deffn procedure eq? obj1 obj2
+@code{eq?} is similar to @code{eqv?} except that in some cases it is
+capable of discerning distinctions finer than those detectable by
+@code{eqv?}.
+
+@code{eq?} and @code{eqv?} are guaranteed to have the same behavior on
+symbols, booleans, the empty list, pairs, records, and non-empty strings
+and vectors. @code{eq?}'s behavior on numbers and characters is
+implementation-dependent, but it will always return either true or
+false, and will return true only when @code{eqv?} would also return
+true. @code{eq?} may also behave differently from @code{eqv?} on empty
+vectors and empty strings.
+
+@example
+@group
+(eq? 'a 'a) @result{} #t
+(eq? '(a) '(a)) @result{} @r{unspecified}
+(eq? (list 'a) (list 'a)) @result{} #f
+(eq? "a" "a") @result{} @r{unspecified}
+(eq? "" "") @result{} @r{unspecified}
+(eq? '() '()) @result{} #t
+(eq? 2 2) @result{} @r{unspecified}
+(eq? #\A #\A) @result{} @r{unspecified}
+(eq? car car) @result{} #t
+(let ((n (+ 2 3)))
+ (eq? n n)) @result{} @r{unspecified}
+(let ((x '(a)))
+ (eq? x x)) @result{} #t
+(let ((x '#()))
+ (eq? x x)) @result{} #t
+(let ((p (lambda (x) x)))
+ (eq? p p)) @result{} #t
+@end group
+@end example
+
+Rationale: It will usually be possible to implement @code{eq?} much more
+efficiently than @code{eqv?}, for example, as a simple pointer
+comparison instead of as some more complicated operation. One reason is
+that it may not be possible to compute @code{eqv?} of two numbers in
+constant time, whereas @code{eq?} implemented as pointer comparison will
+always finish in constant time. @code{eq?} may be used like @code{eqv?}
+in applications using procedures to implement objects with state since
+it obeys the same constraints as @code{eqv?}.
+@end deffn
+
+@page
+@deffn procedure equal? obj1 obj2
+@cindex circular structure
+@code{equal?} recursively compares the contents of pairs, vectors, and
+strings, applying @code{eqv?} on other objects such as numbers, symbols,
+and records. A rule of thumb is that objects are generally
+@code{equal?} if they print the same. @code{equal?} may fail to
+terminate if its arguments are circular data structures.
+
+@example
+@group
+(equal? 'a 'a) @result{} #t
+(equal? '(a) '(a)) @result{} #t
+(equal? '(a (b) c)
+ '(a (b) c)) @result{} #t
+(equal? "abc" "abc") @result{} #t
+(equal? 2 2) @result{} #t
+(equal? (make-vector 5 'a)
+ (make-vector 5 'a)) @result{} #t
+(equal? (lambda (x) x)
+ (lambda (y) y)) @result{} @r{unspecified}
+@end group
+@end example
+@end deffn
--- /dev/null
+@c This file is part of the MIT/GNU Scheme Reference Manual.
+@c $Id: error.texi,v 1.1 2003/04/15 03:29:39 cph Exp $
+
+@c Copyright 1991,1992,1993,1994,1995 Massachusetts Institute of Technology
+@c Copyright 1996,1997,1999,2000,2001 Massachusetts Institute of Technology
+@c Copyright 2002,2003 Massachusetts Institute of Technology
+@c See file scheme.texinfo for copying conditions.
+
+@node Error System, Graphics, Operating-System Interface, Top
+@chapter Error System
+
+@findex error
+The MIT/GNU Scheme error system provides a uniform mechanism for the
+signalling of errors and other exceptional conditions. The simplest and
+most generally useful procedures in the error system are:
+
+@table @code
+@item error
+is used to signal simple errors, specifying a message and some irritant
+objects (@pxref{Condition Signalling}). Errors are usually handled by
+stopping the computation and putting the user in an error @sc{repl}.
+
+@item warn
+is used to signal warnings (@pxref{Condition Signalling}). Warnings are
+usually handled by printing a message on the console and continuing the
+computation normally.
+
+@item ignore-errors
+is used to suppress the normal handling of errors within a given dynamic
+extent (@pxref{Condition Handling}). Any error that occurs within the
+extent is trapped, returning immediately to the caller of
+@code{ignore-errors}.
+@end table
+
+More demanding applications require more powerful facilities. To give a
+concrete example, suppose you want floating-point division to return a very
+large number whenever the denominator is zero. This behavior can be
+implemented using the error system.
+
+The Scheme arithmetic system can signal many different kinds of errors,
+including floating-point divide by zero. In our example, we would like to
+handle this particular condition specially, allowing the system to handle
+other arithmetic errors in its usual way.
+
+The error system supports this kind of application by providing
+mechanisms for distinguishing different types of error conditions and
+for specifying where control should be transferred should a given
+condition arise. In this example, there is a specific object that
+represents the ``floating-point divide by zero'' condition type, and it
+is possible to dynamically specify an arbitrary Scheme procedure to be
+executed when a condition of that type is signalled. This procedure
+then finds the stack frame containing the call to the division operator,
+and returns the appropriate value from that frame.
+
+Another useful kind of behavior is the ability to specify uniform
+handling for related classes of conditions. For example, it might be
+desirable, when opening a file for input, to gracefully handle a variety of
+different conditions associated with the file system. One such condition
+might be that the file does not exist, in which case the program will try
+some other action, perhaps opening a different file instead. Another
+related condition is that the file exists, but is read protected, so it
+cannot be opened for input. If these or any other related conditions
+occur, the program would like to skip this operation and move on to
+something else.
+
+At the same time, errors unrelated to the file system should be treated in
+their usual way. For example, calling @code{car} on the argument @code{3}
+should signal an error. Or perhaps the name given for the file is
+syntactically incorrect, a condition that probably wants to be handled
+differently from the case of the file not existing.
+
+@cindex taxonomical link, of condition type (defn)
+@cindex specialization, of condition types (defn)
+@cindex generalization, of condition types (defn)
+To facilitate the handling of classes of conditions, the error system
+taxonomically organizes all condition types. The types are related to one
+another by @dfn{taxonomical links}, which specify that one type is a ``kind
+of'' another type. If two types are linked this way, one is considered to
+be a @dfn{specialization} of the other; or vice-versa, the second is a
+@dfn{generalization} of the first. In our example, all of the errors
+associated with opening an input file would be specializations of the
+condition type ``cannot open input file''.
+
+@vindex condition-type:simple-condition
+@vindex condition-type:warning
+@vindex condition-type:breakpoint
+@vindex condition-type:serious-condition
+The taxonomy of condition types permits any condition type to have no
+more than one immediate generalization. Thus, the condition types form
+a forest (set of trees). While users can create new trees, the standard
+taxonomy (@pxref{Taxonomy}) is rooted at
+@code{condition-type:serious-condition}, @code{condition-type:warning},
+@code{condition-type:simple-condition}, and
+@code{condition-type:breakpoint}; users are encouraged to add new
+subtypes to these condition types rather than create new trees in the
+forest.
+
+To summarize, the error system provides facilities for the following tasks.
+The sections that follow will describe these facilities in more
+detail.
+
+@table @asis
+@item Signalling a condition
+@findex signal-condition
+A condition may be signalled in a number of different ways. Simple
+errors may be signalled, without explicitly defining a condition type,
+using @code{error}. The @code{signal-condition} procedure provides the
+most general signalling mechanism.
+
+@item Handling a condition
+@findex bind-condition-handler
+The programmer can dynamically specify handlers for particular condition
+types or for classes of condition types, by means of the
+@code{bind-condition-handler} procedure. Individual handlers have
+complete control over the handling of a condition, and additionally may
+decide not to handle a particular condition, passing it on to previously
+bound handlers.
+
+@item Restarting from a handler
+@findex with-restart
+The @code{with-restart} procedure provides a means for
+condition-signalling code to communicate to condition-handling code what
+must be done to proceed past the condition. Handlers can examine the
+restarts in effect when a condition was signalled, allowing a structured
+way to continue an interrupted computation.
+
+@item Packaging condition state
+Each condition is represented by an explicit object. Condition objects
+contain information about the nature of the condition, information that
+describes the state of the computation from which the condition arose,
+and information about the ways the computation can be restarted.
+
+@item Classification of conditions
+@cindex condition type
+@cindex type, condition
+@cindex specialization, of condition types
+@cindex generalization, of condition types
+Each condition has a type, represented by a condition type object. Each
+condition type may be a specialization of some other condition types. A
+group of types that share a common generalization can be handled
+uniformly by specifying a handler for the generalization.
+@end table
+
+@menu
+* Condition Signalling::
+* Error Messages::
+* Condition Handling::
+* Restarts::
+* Condition Instances::
+* Condition Types::
+* Taxonomy::
+@end menu
+
+@node Condition Signalling, Error Messages, Error System, Error System
+@section Condition Signalling
+
+@cindex condition signalling (defn)
+@cindex signalling, of condition (defn)
+@findex make-condition
+Once a condition instance has been created using @code{make-condition}
+(or any condition constructor), it can be @dfn{signalled}. The act of
+signalling a condition is separated from the act of creating the
+condition to allow more flexibility in how conditions are handled. For
+example, a condition instance could be returned as the value of a
+procedure, indicating that something unusual has happened, to allow the
+caller to clean up some state. The caller could then signal the
+condition once it is ready.
+
+A more important reason for having a separate condition-signalling
+mechanism is that it allows @emph{resignalling}. When a signalled
+condition has been caught by a particular handler, and the handler decides
+that it doesn't want to process that particular condition, it can signal
+the condition again. This is one way to allow other handlers to get a
+chance to see the condition.
+
+@deffn procedure error reason argument @dots{}
+@cindex REP loop
+@findex signal-condition
+@findex warn
+This is the simplest and most common way to signal a condition that
+requires intervention before a computation can proceed (when
+intervention is not required, @code{warn} is more appropriate).
+@code{error} signals a condition (using @code{signal-condition}), and if
+no handler for that condition alters the flow of control (by invoking a
+restart, for example) it calls the procedure
+@code{standard-error-handler}, which normally prints an error message
+and stops the computation, entering an error @sc{repl}. Under normal
+circumstances @code{error} will not return a value (although an
+interactive debugger can be used to force this to occur).
+
+@findex make-condition
+@vindex condition-type:simple-error
+Precisely what condition is signalled depends on the first argument to
+@code{error}. If @var{reason} is a condition, then that condition is
+signalled and the @var{argument}s are ignored. If @var{reason} is a
+condition type, then a new instance of this type is generated and
+signalled; the @var{argument}s are used to generate the values of the
+fields for this condition type (they are passed as the @var{field-plist}
+argument to @code{make-condition}). In the most common case, however,
+@var{reason} is neither a condition nor a condition type, but rather a
+string or symbol. In this case a condition of type
+@code{condition-type:simple-error} is created with the @var{message}
+field containing the @var{reason} and the @var{irritants} field
+containing the @var{argument}s.
+@end deffn
+
+@deffn procedure warn reason argument @dots{}
+@findex error
+@findex signal-condition
+@vindex condition-type:simple-warning
+When a condition is not severe enough to warrant intervention, it is
+appropriate to signal the condition with @code{warn} rather than
+@code{error}. As with @code{error}, @code{warn} first calls
+@code{signal-condition}; the condition that is signalled is chosen
+exactly as in @code{error} except that a condition of type
+@code{condition-type:simple-warning} is signalled if @var{reason} is
+neither a condition nor a condition type. If the condition is not
+handled, @code{warn} calls the procedure
+@code{standard-warning-handler}, which normally prints a warning message
+and continues the computation by returning from @code{warn}.
+
+@findex muffle-warning
+@code{warn} establishes a restart named @code{muffle-warning} before
+calling @code{signal-condition}. This allows a signal handler to
+prevent the generation of the warning message by calling
+@code{muffle-warning}. The value of a call to @code{warn} is
+unspecified.
+@end deffn
+
+@deffn procedure signal-condition condition
+@cindex generalization, of condition types
+@cindex specialization, of condition types
+@findex break-on-signals
+@findex bind-default-condition-handler
+@findex bind-condition-handler
+This is the fundamental operation for signalling a condition. The
+precise operation of @code{signal-condition} depends on the condition
+type of which @var{condition} is an instance, the condition types set by
+@code{break-on-signals}, and the handlers established by
+@code{bind-condition-handler} and @code{bind-default-condition-handler}.
+
+@cindex REP loop
+If the @var{condition} is an instance of a type that is a specialization
+of any of the types specified by @code{break-on-signals}, then a
+breakpoint @sc{repl} is initiated. Otherwise (or when that @sc{repl}
+returns), the handlers established by @code{bind-condition-handler} are
+checked, most recent first. Each applicable handler is invoked, and the
+search for a handler continues if the handler returns normally. If all
+applicable handlers return, then the applicable handlers established by
+@code{bind-default-condition-handler} are checked, again most recent
+first. Finally, if no handlers apply (or all return in a normal
+manner), @code{signal-condition} returns an unspecified value.
+
+@emph{Note:} unlike many other systems, the MIT/GNU Scheme runtime library
+does @emph{not} establish handlers of any kind. (However, the Edwin
+text editor uses condition handlers extensively.) Thus, calls to
+@code{signal-condition} will return to the caller unless there are user
+supplied condition handlers, as the following example shows:
+
+@example
+@group
+(signal-condition
+ (make-condition
+ condition-type:error
+ (call-with-current-continuation (lambda (x) x))
+ '() @r{; no restarts}
+ '())) @r{; no fields}
+@result{} @r{unspecified}
+@end group
+@end example
+@end deffn
+
+@node Error Messages, Condition Handling, Condition Signalling, Error System
+@section Error Messages
+
+@cindex error messages, conventions
+@cindex conventions for error messages
+By convention, error messages (and in general, the reports generated by
+@code{write-condition-report}) should consist of one or more complete
+sentences. The usual rules for sentences should be followed: the first
+word of the sentence should be capitalized, and the sentence should be
+terminated by a period. The message should not contain extraneous
+whitespace such as line breaks or indentation.
+
+
+The error system provides a simple formatting language that allows the
+programmer to have some control over the printing of error messages.
+This formatting language will probably be redesigned in a future
+release.
+
+@findex display
+@findex write
+Error messages typically consist of a string describing the error,
+followed by some irritant objects. The string is printed using
+@code{display}, and the irritants are printed using @code{write},
+typically with a space between each irritant. To allow simple
+formatting, we introduce a @dfn{noise} object, printed using
+@code{display}. The irritant list may contain ordinary objects
+interspersed with noise objects. Each noise object is printed using
+@code{display}, with no extra whitespace, while each normal object is
+printed using @code{write}, prefixed by a single space character.
+
+Here is an example:
+
+@example
+@group
+(define (error-within-procedure message irritant procedure)
+ (error message
+ irritant
+ (error-irritant/noise "within procedure")
+ procedure
+ (error-irritant/noise ".")))
+@end group
+@end example
+
+@noindent
+This would format as follows:
+
+@example
+@group
+(error-within-procedure "Bad widget" 'widget-32 'invert-widget) @error{}
+
+Bad widget widget-32 within procedure invert-widget.
+@end group
+@end example
+
+Here are the operations supporting error messages:
+
+@deffn procedure format-error-message message irritants port
+@var{Message} is typically a string (although this is not required),
+@var{irritants} a list of irritant objects, and @var{port} an output
+port. Formats @var{message} and @var{irritants} to @var{port} in the
+standard way. Note that, during the formatting process, the depth and
+breadth to which lists are printed are each limited to small numbers, to
+guarantee that the output from each irritant is not arbitrarily large.
+@end deffn
+
+@deffn procedure error-irritant/noise value
+Creates and returns a noise object whose value is @var{value}.
+@end deffn
+
+@node Condition Handling, Restarts, Error Messages, Error System
+@section Condition Handling
+
+@cindex handler, condition (defn)
+@cindex condition handler (defn)
+@findex bind-condition-handler
+@findex bind-default-condition-handler
+The occurrence of a condition is signalled using
+@code{signal-condition}. @code{signal-condition} attempts to locate and
+invoke a @dfn{condition handler} that is prepared to deal with the type
+of condition that has occurred. A condition handler is a procedure of
+one parameter, the condition that is being signalled. A procedure is
+installed as a condition handler by calling
+@code{bind-condition-handler} (to establish a handler that is in effect
+only while a particular thunk is executing) or
+@code{bind-default-condition-handler} (to establish a handler that is in
+effect permanently). As implied by the name, handlers created by
+@code{bind-default-condition-handler} are invoked only after all other
+applicable handlers have been invoked.
+
+A @var{handler} may process a signal in any way it deems appropriate,
+but the common patterns are:
+
+@table @asis
+@item Ignore the condition.
+By returning from the handler in the usual manner.
+
+@item Handle the condition.
+By doing some processing and then invoking a restart (or, less
+preferably, a continuation) that was established at some point prior to
+the call to @code{signal-condition}.
+
+@item Resignal a condition.
+By doing some processing and calling @code{signal-condition} with either
+the same condition or a newly created one. In order to support this,
+@code{signal-condition} runs @var{handler} in such a way that a
+subsequent call to @code{signal-condition} sees only the handlers that
+were established prior to this one.
+@end table
+
+@cindex REP loop
+@findex break-on-signals
+As an aid to debugging condition handlers, Scheme maintains a set of
+condition types that will cause an interactive breakpoint to occur prior
+to normal condition signalling. That is, @code{signal-condition}
+creates a new @sc{repl} prior to its normal operation when its argument
+is a condition that is a specialization of any of these types. The
+procedure @code{break-on-signals} establishes this set of condition
+types.
+
+@deffn procedure ignore-errors thunk
+@findex error
+@vindex condition-type:error
+Executes @var{thunk} with a condition handler that intercepts the
+signalling of any specialization of @code{condition-type:error}
+(including those produced by calls to @code{error}) and immediately
+terminates the execution of @var{thunk} and returns from the call to
+@code{ignore-errors} with the signalled condition as its value. If
+@var{thunk} returns normally, its value is returned from
+@code{ignore-errors}.
+
+Notice that @code{ignore-errors} does not ``turn off signalling'' or
+condition handling. Condition handling takes place in the normal manner
+but conditions specialized from @code{condition-type:error} are trapped
+rather than propogated as they would be by default.
+@end deffn
+
+@deffn procedure bind-condition-handler condition-types handler thunk
+@findex signal-condition
+Invokes @var{thunk} after adding @var{handler} as a condition handler
+for the conditions specified by @var{condition-types}.
+@var{Condition-types} must be a list of condition types; signalling a
+condition whose type is a specialization of any of these types will
+cause the @var{handler} to be invoked. See @code{signal-condition} for
+a description of the mechanism used to invoke handlers.
+
+By special extension, if @var{condition-types} is the empty list then
+the @var{handler} is called for all conditions.
+@end deffn
+
+@deffn procedure bind-default-condition-handler condition-types handler
+@findex signal-condition
+Installs @var{handler} as a (permanent) condition handler for the
+conditions specified by @var{condition-types}. @var{Condition-types}
+must be a list of condition types; signalling a condition whose type is
+a specialization of any of these types will cause the @var{handler} to
+be invoked. See @code{signal-condition} for a description of the
+mechanism used to invoke handlers.
+
+By special extension, if @var{condition-types} is the empty list then
+the @var{handler} is called for all conditions.
+@end deffn
+
+@deffn procedure break-on-signals condition-types
+@findex signal-condition
+@cindex REP loop
+Arranges for @code{signal-condition} to create an interactive @sc{repl}
+before it signals a condition that is a specialization of any of the
+types in the list of @var{condition-types}. This can be extremely
+helpful when trying to debug code that uses custom condition handlers.
+In order to create a @sc{repl} when @emph{any} condition type is
+signalled it is best to actually put a breakpoint on entry to
+@code{signal-condition}.
+@end deffn
+
+@deffn procedure standard-error-handler condition
+@findex error
+@findex ignore-error
+@vindex standard-error-hook
+@cindex REP loop
+Called internally by @code{error} after it calls
+@code{signal-condition}. Normally creates creates a new @sc{repl} with
+the prompt @code{"error>"} (but see @code{standard-error-hook}). In
+order to simulate the effect of calling @code{error}, code may call
+@code{signal-condition} directly and then call
+@code{standard-error-handler} if @code{signal-condition} returns.
+@end deffn
+
+@defvr variable standard-error-hook
+@findex standard-error-handler
+@cindex fluid binding
+@cindex dynamic binding
+@cindex REP loop
+This variable controls the behavior of the procedure
+@code{standard-error-handler}, and hence @code{error}. It is intended
+to be bound with @code{fluid-let} and is normally @code{#f}. It may be
+changed to a procedure of one argument and will then be invoked (with
+@code{standard-error-hook} rebound to @code{#f}) by
+@code{standard-error-handler} just prior to starting the error
+@sc{repl}. It is passed one argument, the condition being signalled.
+@end defvr
+
+@deffn procedure standard-warning-handler condition
+@vindex standard-warning-hook
+@findex signal-condition
+@findex notification-output-port
+@findex write-condition-report
+This is the procedure called internally by @code{warn} after it calls
+@code{signal-condition}. The normal behavior of
+@code{standard-warning-handler} is to print a message (but see
+@code{standard-warning-hook}). More precisely, the message is printed
+to the port returned by @code{notification-output-port}. The message is
+formed by first printing the string @code{"Warning: "} to this port, and
+then calling @code{write-condition-report} on @var{condition} and the port.
+
+@findex muffle-warning
+In order to simulate the effect of calling @code{warn}, code may call
+@code{signal-condition} directly and then call
+@code{standard-warning-handler} if @code{signal-condition} returns.
+(This is not sufficient to implement the @code{muffle-warning} protocol,
+however. For that purpose an explicit restart must be provided.)
+@end deffn
+
+@defvr variable standard-warning-hook
+@findex standard-warning-handler
+@cindex fluid binding
+@cindex dynamic binding
+This variable controls the behavior of the procedure
+@code{standard-warning-handler}, and hence @code{warn}. It is intended
+to be bound with @code{fluid-let} and is normally @code{#f}. It may be
+changed to a procedure of one argument and will then be invoked (with
+@code{standard-warning-hook} rebound to @code{#f}) by
+@code{standard-warning-handler} in lieu of writing the warning message.
+It is passed one argument, the condition being signalled.
+@end defvr
+
+@node Restarts, Condition Instances, Condition Handling, Error System
+@section Restarts
+
+@cindex restart effector (defn)
+@cindex effector, restart (defn)
+@cindex restart (defn)
+@findex with-restart
+@findex with-simple-restart
+The Scheme error system provides a mechanism, known as @dfn{restarts},
+that helps coordinate condition-signalling code with condition-handling
+code. A module of code that detects and signals conditions can provide
+procedures (using @code{with-simple-restart} or @code{with-restart}) to
+be invoked by handlers that wish to continue, abort, or restart the
+computation. These procedures, called @dfn{restart effectors}, are
+encapsulated in restart objects.
+
+@findex find-restart
+@findex invoke-restart
+@findex invoke-restart-interactively
+When a condition object is created, it contains a set of restart
+objects, each of which contains a restart effector. Condition handlers
+can inspect the condition they are handling (using @code{find-restart}
+to find restarts by name, or @code{condition/restarts} to see the entire
+set), and they can invoke the associated effectors (using
+@code{invoke-restart} or @code{invoke-restart-interactively}).
+Effectors can take arguments, and these may be computed directly by the
+condition-handling code or by gathering them interactively from the
+user.
+
+@findex abort
+@findex continue
+@findex muffle-warning
+@findex retry
+@findex store-value
+@findex use-value
+@cindex protocol, restart (defn)
+@cindex restart protocol
+The names of restarts can be chosen arbitrarily, but the choice of name
+is significant. These names are used to coordinate between the
+signalling code (which supplies names for restarts) and the handling
+code (which typically chooses a restart effector by the name of its
+restart). Thus, the names specify the @dfn{restart protocol}
+implemented by the signalling code and invoked by the handling code.
+The protocol indicates the number of arguments required by the effector
+code as well as the semantics of the arguments.
+
+Scheme provides a conventional set of names (hence, protocols) for
+common use. By choosing the names of restarts from this set, signalling
+code can indicate that it is able to perform a small set of fairly
+common actions (@code{abort}, @code{continue}, @code{muffle-warning},
+@code{retry}, @code{store-value}, @code{use-value}). In turn, simple
+condition-handling code can look for the kind of action it wishes to
+perform and simply invoke it by name. All of Scheme's conventional
+names are symbols, although in general restart names are not restricted
+to any particular data type. In addition, the object @code{#f} is
+reserved to indicate the ``not for automated use'' protocol: these
+restarts should be activated only under human control.
+
+@findex with-simple-restart
+Restarts themselves are first-class objects. They encapsulate their
+name, a procedure (known as the @var{effector}) to be executed if they
+are invoked, and a thunk (known as the @var{reporter}) that can be
+invoked to display a description of the restart (used, for example, by
+the interactive debugger). Invoking a restart is an indication that a
+handler has chosen to accept control for a condition; as a consequence,
+the @var{effector} of the restart should not return, since this would
+indicate that the handler declined to handle the condition. Thus, the
+@var{effector} should call a continuation captured before the
+condition-signalling process began. The most common pattern of usage by
+signalling code is encapsulated in @code{with-simple-restart}.
+
+Within this chapter, a parameter named @var{restarts} will accept any of
+the following values:
+
+@itemize @bullet
+@item
+A list of restart objects.
+
+@item
+A condition. The procedure @code{condition/restarts} is called on the
+condition, and the resulting list of restarts is used in place of the
+condition.
+
+@item
+The symbol @code{bound-restarts}. The procedure @code{bound-restarts}
+is called (with no arguments), and the resulting list of restarts is
+used in place of the symbol.
+
+@item
+If the @var{restarts} parameter is optional and is not supplied, it is
+equivalent to having specified the symbol @code{bound-restarts}.
+@end itemize
+
+@menu
+* Establishing Restart Code::
+* Invoking Standard Restart Code::
+* Finding and Invoking General Restart Code::
+* The Named Restart Abstraction::
+@end menu
+
+@node Establishing Restart Code, Invoking Standard Restart Code, Restarts, Restarts
+@subsection Establishing Restart Code
+
+@deffn procedure with-simple-restart name reporter thunk
+Invokes @var{thunk} in a dynamic environment created by adding a restart
+named @var{name} to the existing named restarts. @var{Reporter} may be
+used during the execution of @var{thunk} to produce a description of the
+newly created restart; it must either be a procedure of one argument (a
+port) or a string. By convention, the description generated by
+@var{reporter} should be a short complete sentence, with first word
+capitalized and terminated by a period. The sentence should fit on one
+line with a little room to spare (see the examples below); usually this
+means that the sentence should be 70 characters or less in length.
+
+If the restart created by @code{with-simple-restart} is invoked it
+simply aborts the computation in progress by returning an unspecified
+value from the call to @code{with-simple-restart}. Otherwise
+@code{with-simple-restart} returns the value computed by @var{thunk}.
+@end deffn
+
+@example
+@group
+(with-simple-restart 'george "This restart is named george."
+ (lambda () 3)) @result{} 3
+
+(with-simple-restart 'george "This restart is named george."
+ (lambda ()
+ (invoke-restart (find-restart 'george)))) @result{} @code{unspecific}
+
+(with-simple-restart 'george "This restart is named george."
+ (lambda () (car 3)))
+;The object 3, passed as the first argument to car,
+; is not the correct type.
+;To continue, call RESTART with an option number:
+; (RESTART 3) => Specify an argument to use in its place.
+; (RESTART 2) => This restart is named george.
+; (RESTART 1) => Return to read-eval-print level 1.
+@end group
+@end example
+
+@deffn procedure with-restart name reporter effector interactor thunk
+@findex invoke-restart
+Invokes @var{thunk} in a dynamic environment created by adding a restart
+named @var{name} to the existing named restarts. @var{Reporter} may be
+used during the execution of @var{thunk} to produce a description of the
+newly created restart; it must either be a procedure of one argument (a
+port) or a string. @var{Effector} is a procedure which will be called
+when the restart is invoked by @code{invoke-restart}. @var{Interactor}
+specifies the arguments that are to be passed to @var{effector} when it
+is invoked interactively; it may be either a procedure of no arguments,
+or @code{#f}. If @var{interactor} is @code{#f}, this restart is not
+meant to be invoked interactively.
+
+The value returned by @code{with-restart} is the value returned by
+@var{thunk}. Should the restart be invoked by a condition handler,
+however, the @var{effector} will not return back to the handler that
+invoked it. Instead, the @var{effector} should call a continuation
+created before the condition-signalling process began, and
+@code{with-restart} will therefore not return in the normal manner.
+@end deffn
+
+@example
+@group
+(define (by-george! thunk)
+ @r{; This code handles conditions that arise while executing @var{thunk}}
+ @r{; by invoking the GEORGE restart, passing 1 and 2 to the restart's}
+ @r{; @var{effector} code.}
+ (bind-condition-handler '() ; All conditions
+ (lambda (condition)
+ (invoke-restart (find-restart 'george) 1 2))
+ thunk))
+@end group
+
+@group
+(define (can-george! thunk)
+ @r{; This code provides a way of handling errors: the GEORGE restart.}
+ @r{; In order to GEORGE you must supply two values.}
+ (lambda ()
+ (call-with-current-continuation
+ (lambda (kappa)
+ (with-restart
+ 'george @r{; Name}
+ "This restart is named george." @r{; Reporter}
+ (lambda (a b) @r{; Effector}
+ (kappa (list 'george a b)))
+ values @r{; Interactor}
+ thunk))))) @r{; Thunk}
+@end group
+
+@group
+(by-george! (can-george! (lambda () -3)) @result{} -3
+(by-george! (can-george! (lambda () (car 'x)))) @result{} (george 1 2)
+@end group
+@end example
+
+@node Invoking Standard Restart Code, Finding and Invoking General Restart Code, Establishing Restart Code, Restarts
+@subsection Invoking Standard Restart Code
+
+Scheme supports six standard protocols for restarting from a condition,
+each encapsulated using a named restart (for use by condition-signalling
+code) and a simple procedure (for use by condition-handling code).
+Unless otherwise specified, if one of these procedures is unable to find
+its corresponding restart, it returns immediately with an unspecified
+value.
+
+Each of these procedures accepts an optional argument @var{restarts},
+which is described above in @ref{Restarts}.
+
+@deffn procedure abort [restarts]
+@cindex REP loop
+Abort the computation, using the restart named @code{abort}. The
+corresponding effector takes no arguments and abandons the current line
+of computation. This is the restart provided by Scheme's @sc{repl}.
+
+@vindex condition-type:no-such-restart
+If there is no restart named @code{abort}, this procedure signals an
+error of type @code{condition-type:no-such-restart}.
+@end deffn
+
+@deffn procedure continue [restarts]
+Continue the current computation, using the restart named
+@code{continue}. The corresponding effector takes no arguments and
+continues the computation beyond the point at which the condition was
+signalled.
+@end deffn
+
+@deffn procedure muffle-warning [restarts]
+@findex warn
+Continue the current computation, using the restart named
+@code{muffle-warning}. The corresponding effector takes no arguments
+and continues the computation beyond the point at which any warning
+message resulting from the condition would be presented to the user.
+The procedure @code{warn} establishes a @code{muffle-warning} restart
+for this purpose.
+
+@vindex condition-type:no-such-restart
+If there is no restart named @code{muffle-warning}, this procedure
+signals an error of type @code{condition-type:no-such-restart}.
+@end deffn
+
+@deffn procedure retry [restarts]
+Retry the current computation, using the restart named @code{retry}.
+The corresponding effector takes no arguments and simply retries the
+same computation that triggered the condition. The condition may
+reoccur, of course, if the root cause has not been eliminated. The code
+that signals a ``file does not exist'' error can be expected to supply a
+@code{retry} restart. The restart would be invoked after first creating
+the missing file, since the computation is then likely to succeed if it
+is simply retried.
+@end deffn
+
+@deffn procedure store-value new-value [restarts]
+Retry the current computation, using the restart named
+@code{store-value}, after first storing @var{new-value}. The
+corresponding effector takes one argument, @var{new-value}, and stores
+it away in a restart-dependent location, then retries the same
+computation that triggered the condition. The condition may reoccur, of
+course, if the root cause has not been eliminated. The code that
+signals an ``unassigned variable'' error can be expected to supply a
+@code{store-value} restart; this would store the value in the variable
+and continue the computation.
+@end deffn
+
+@deffn procedure use-value new-value [restarts]
+@findex retry
+@findex store-value
+Retry the current computation, using the restart named @code{use-value},
+but substituting @var{new-value} for a value that previously caused a
+failure. The corresponding effector takes one argument,
+@var{new-value}, and retries the same computation that triggered the
+condition with the new value substituted for the failing value. The
+condition may reoccur, of course, if the new value also induces the
+condition.
+
+The code that signals an ``unassigned variable'' error can be expected
+to supply a @code{use-value} restart; this would simply continue the
+computation with @var{new-value} instead of the value of the variable.
+Contrast this with the @code{retry} and @code{store-value} restarts. If
+the @code{retry} restart is used it will fail because the variable still
+has no value. The @code{store-value} restart could be used, but it
+would alter the value of the variable, so that future references to the
+variable would not be detected.
+@end deffn
+
+@node Finding and Invoking General Restart Code, The Named Restart Abstraction, Invoking Standard Restart Code, Restarts
+@subsection Finding and Invoking General Restart Code
+
+@findex with-restart
+@findex with-simple-restart
+@findex bound-restart
+@findex find-restart
+@findex invoke-restart
+@findex invoke-restart-interactively
+Restarts are a general mechanism for establishing a protocol between
+condition-signalling and condition-handling code. The Scheme error
+system provides ``packaging'' for a number of common protocols. It also
+provides lower-level hooks that are intended for implementing customized
+protocols. The mechanism used by signalling code (@code{with-restart}
+and @code{with-simple-restart}) is used for both purposes.
+
+Four additional operations are provided for the use of
+condition-handling code. Two operations (@code{bound-restarts} and
+@code{find-restart}) allow condition-handling code to locate active
+restarts. The other two operations (@code{invoke-restart} and
+@code{invoke-restart-interactively}) allow restart effectors to be
+invoked once the restart object has been located.
+
+In addition, there is a data abstraction that provides access to the
+information encapsulated in restart objects.
+
+@deffn procedure bound-restarts
+Returns a list of all currently active restart objects, most recently
+installed first. @code{bound-restarts} should be used with caution by
+condition-handling code, since it reveals all restarts that are active
+at the time it is called, rather than at the time the condition was
+signalled. It is useful, however, for collecting the list of restarts
+for inclusion in newly generated condition objects or for inspecting the
+current state of the system.
+@end deffn
+
+@deffn procedure find-restart name [restarts]
+Returns the first restart object named @var{name} in the list of
+@var{restarts} (permissible values for @var{restarts} are described
+above in @ref{Restarts}). When used in a condition handler,
+@code{find-restart} is usually passed the name of a particular restart
+@emph{and} the condition object that has been signalled. In this way
+the handler finds only restarts that were available when the condition
+was created (usually the same as when it was signalled). If
+@var{restarts} is omitted, the currently active restarts would be used,
+and these often include restarts added after the condition ocurred.
+@end deffn
+
+@deffn procedure invoke-restart restart argument @dots{}
+@findex invoke-restart-interactively
+Calls the restart effector encapsulated in @var{restart}, passing the
+specified @var{argument}s to it. @code{invoke-restart} is intended for
+use by condition-handling code that understands the protocol implemented
+by @var{restart}, and can therefore calculate and pass an appropriate
+set of arguments.
+
+If a condition handler needs to interact with a user to gather the
+arguments for an effector (e.g.@: if it does not understand the protocol
+implemented by @var{restart}) @code{invoke-restart-interactively} should
+be used instead of @code{invoke-restart}.
+@end deffn
+
+@deffn procedure invoke-restart-interactively restart
+First calls the interactor encapsulated in @var{restart} to
+interactively gather the arguments needed for @var{restart}'s effector.
+It then calls the effector, passing these arguments to it.
+
+@findex restart/interactor
+@code{invoke-restart-interactively} is intended for calling interactive
+restarts (those for which @code{restart/interactor} is not @code{#f}).
+For convenience, @code{invoke-restart-interactively} will call the
+restart's effector with no arguments if the restart has no interactor;
+this behavior may change in the future.
+@end deffn
+
+@node The Named Restart Abstraction, , Finding and Invoking General Restart Code, Restarts
+@subsection The Named Restart Abstraction
+
+A restart object is very simple, since it encapsulates only a name,
+effector, interactor, and description.
+
+@deffn procedure restart? object
+Returns @code{#f} if and only if @var{object} is not a restart.
+@end deffn
+
+@deffn procedure restart/name restart
+@findex eq?
+Returns the name of @var{restart}. While the Scheme error system uses
+only symbols and the object @code{#f} for its predefined names, programs
+may use arbitrary objects (name equivalence is tested using @code{eq?}).
+@end deffn
+
+@deffn procedure restart/effector restart
+@findex invoke-restart
+@findex invoke-restart-interactively
+Returns the effector encapsulated in @var{restart}. Normally this
+procedure is not used since @code{invoke-restart} and
+@code{invoke-restart-interactively} capture the most common invocation
+patterns.
+@end deffn
+
+@deffn procedure restart/interactor restart
+@findex invoke-restart-interactively
+Returns the interactor encapsulated in @var{restart}. This is either a
+procedure of no arguments or the object @code{#f}. Normally this
+procedure is not used since @code{invoke-restart-interactively} captures
+the most common usage. Thus @code{restart/interactor} is most useful as
+a predicate to determine if @var{restart} is intended to be invoked
+interactively.
+@end deffn
+
+@deffn procedure write-restart-report restart port
+Writes a description of @var{restart} to @var{port}. This works by
+either displaying (if it is a string) or calling (if it is a procedure)
+the @var{reporter} that was supplied when the restart was created.
+@end deffn
+
+@node Condition Instances, Condition Types, Restarts, Error System
+@section Condition Instances
+
+@cindex condition (defn)
+@cindex condition instance (defn)
+@cindex instance, of condition (defn)
+A @dfn{condition}, in addition to the information associated with its
+type, usually contains other information that is not shared with other
+conditions of the same type. For example, the condition type associated
+with ``unbound variable'' errors does not specify the name of the
+variable that was unbound. The additional information is captured in a
+@dfn{condition} object, also called a @dfn{condition instance}.
+
+In addition to information that is specific to a given type of condition
+(such as the variable name for ``unbound variable'' conditions), every
+condition instance also contains a continuation that encapsulates the
+state of the computation in which the condition occurred. This
+continuation is used for analyzing the computation to learn more about
+the context in which the condition occurred. It is @emph{not} intended
+to provide a mechanism for continuing the computation; that mechanism is
+provided by restarts.
+
+@menu
+* Generating Operations on Conditions::
+* Condition State::
+* Simple Condition Instance Operations::
+@end menu
+
+@node Generating Operations on Conditions, Condition State, Condition Instances, Condition Instances
+@subsection Generating Operations on Conditions
+
+@findex condition-constructor
+@findex condition-accessor
+@findex condition-signaller
+@findex condition-predicate
+Scheme provides four procedures that take a condition type as input and
+produce operations on the corresponding condition object. These are
+reminiscent of the operations on record types that produce record
+operators (@pxref{Records}). Given a condition type it is possible to
+generate: a constructor for instances of the type (using
+@code{condition-constructor}); an accessor to extract the contents of a
+field in instances of the type (using @code{condition-accessor}); a
+predicate to test for instances of the type (using
+@code{condition-predicate}); and a procedure to create and signal an
+instance of the type (using @code{condition-signaller}).
+
+Notice that the creation of a condition object is distinct from
+signalling an occurrence of the condition. Condition objects are
+first-class; they may be created and never signalled, or they may be
+signalled more than once. Further notice that there are no procedures
+for modifying conditions; once created, a condition cannot be altered.
+
+@deffn procedure condition-constructor condition-type field-names
+@findex condition/restarts
+@cindex bound-restarts
+@cindex restarts, bound
+Returns a constructor procedure that takes as arguments values for the
+fields specified in @var{field-names} and creates a condition of type
+@var{condition-type}. @var{Field-names} must be a list of symbols that
+is a subset of the @var{field-names} in @var{condition-type}. The
+constructor procedure returned by @code{condition-constructor} has
+signature
+
+@example
+(lambda (@var{continuation} @var{restarts} . @var{field-values}) @dots{})
+@end example
+
+@noindent
+where the @var{field-names} correspond to the @var{field-values}. The
+constructor argument @var{restarts} is described in @ref{Restarts}.
+Conditions created by the constructor procedure have @code{#f} for the
+values of all fields other than those specified by @var{field-names}.
+
+For example, the following procedure @code{make-simple-warning}
+constructs a condition of type @code{condition-type:simple-warning}
+given a continuation (where the condition occurred), a description of
+the restarts to be made available, a warning message, and a list of
+irritants that caused the warning:
+
+@example
+@group
+(define make-simple-warning
+ (condition-constructor condition-type:simple-warning
+ '(message irritants)))
+@end group
+@end example
+@end deffn
+
+@deffn procedure condition-accessor condition-type field-name
+@cindex specialization, of condition types
+Returns a procedure that takes as input a condition object of type
+@var{condition-type} and extracts the contents of the specified
+@var{field-name}. @code{condition-accessor} signals
+@code{error:bad-range-argument} if the @var{field-name} isn't one of the
+named fields of @var{condition-type}; the returned procedure will signal
+@code{error:wrong-type-argument} if passed an object other than a
+condition of type @var{condition-type} or one of its specializations.
+
+@findex access-condition
+If it is known in advance that a particular field of a condition will be
+accessed repeatedly it is worth constructing an accessor for the field
+using @code{condition-accessor} rather than using the (possibly more
+convenient, but slower) @code{access-condition} procedure.
+@end deffn
+
+@deffn procedure condition-predicate condition-type
+@cindex specialization, of condition types
+Returns a predicate procedure for testing whether an object is a
+condition of type @var{condition-type} or one of its specializations
+(there is no predefined way to test for a condition of a given type but
+@emph{not} a specialization of that type).
+@end deffn
+
+@deffn procedure condition-signaller condition-type field-names default-handler
+Returns a signalling procedure with parameters @var{field-names}. When
+the signalling procedure is called it creates and signals a condition of
+type @var{condition-type}. If the condition isn't handled (i.e.@: if no
+handler is invoked that causes an escape from the current continuation)
+the signalling procedure reduces to a call to @var{default-handler} with
+the condition as its argument.
+
+There are several standard procedures that are conventionally used for
+@var{default-handler}. If @var{condition-type} is a specialization of
+@code{condition-type:error}, @var{default-handler} should be the
+procedure@* @code{standard-error-handler}. If @var{condition-type} is a
+specialization of @code{condition-type:warning}, @var{default-handler}
+should be the procedure @code{standard-warning-handler}. If
+@var{condition-type} is a specialization of
+@code{condition-type:breakpoint}, @var{default-handler} should be the
+procedure @code{standard-breakpoint-handler}.
+@end deffn
+
+@node Condition State, Simple Condition Instance Operations, Generating Operations on Conditions, Condition Instances
+@subsection Condition Abstraction
+
+The condition data type is abstracted through a predicate
+@code{condition?} and a set of accessor procedures.
+
+@deffn procedure condition? object
+Returns @code{#f} if and only if @var{object} is not a condition.
+@end deffn
+
+@deffn procedure condition/type condition
+Returns the condition type of which @var{condition} is an instance.
+@end deffn
+
+@deffn procedure condition/error? condition
+@vindex condition-type:error
+@cindex specialization, of condition types
+Returns @code{#t} if the @var{condition} is an instance of condition
+type @code{condition-type:error} or a specialization of it, @code{#f}
+otherwise.
+@end deffn
+
+@deffn procedure condition/restarts condition
+Returns the list of restarts specified when @var{condition} was created.
+@end deffn
+
+@deffn procedure condition/continuation condition
+Returns the continuation specified when @var{condition} was created.
+This is provided for inspecting the state of the system when the
+condition occurred, @emph{not} for continuing or restarting the
+computation.
+@end deffn
+
+@deffn procedure write-condition-report condition port
+Writes a description of @var{condition} to @var{port}, using the
+reporter function from the condition type associated with
+@var{condition}. See also @code{condition/report-string}.
+@end deffn
+
+@node Simple Condition Instance Operations, , Condition State, Condition Instances
+@subsection Simple Operations on Condition Instances
+
+The simple procedures described in this section are built on top of the
+more detailed abstraction of condition objects described above. While
+these procedures are sometimes easier to use, they are often less
+efficient.
+
+@deffn procedure make-condition condition-type continuation restarts field-plist
+@findex condition/restarts
+@cindex bound-restarts
+@cindex restarts, bound
+Create a new condition object as an instance of @var{condition-type},
+associated with @var{continuation}. The @var{continuation} is provided
+for inspection purposes only, @emph{not} for restarting the computation.
+The @var{restarts} argument is described in @ref{Restarts}. The
+@var{field-plist} is an alternating list of field names and values for
+those fields, where the field names are those that would be returned by
+@code{(condition-type/field-names @var{condition-type})}. It is used to
+provide values for fields in the condition object; fields with no value
+specified are set to @code{#f}. Once a condition object has been
+created there is no way to alter the values of these fields.
+@end deffn
+
+@deffn procedure access-condition condition field-name
+@findex condition-accessor
+Returns the value stored in the field @var{field-name} within
+@var{condition}. @var{Field-name} must be one of the names returned by
+@code{(condition-type/field-names (condition/type @var{condition}))}.
+@code{access-condition} looks up the @var{field-name} at runtime, so it
+is more efficient to use @code{condition-accessor} to create an access
+function if the same field is to be extracted from several instances of
+the same condition type.
+@end deffn
+
+@deffn procedure condition/report-string condition
+@findex write-condition-report
+Returns a string containing a report of the @var{condition}. This is
+generated by calling @code{write-condition-report} on @var{condition}
+and a string output port, and returning the output collected by the port
+as a string.
+@end deffn
+
+@node Condition Types, Taxonomy, Condition Instances, Error System
+@section Condition Types
+
+@cindex condition type
+@cindex type, of condition
+Each condition has a @dfn{condition type} object associated with it.
+These objects are used as a means of focusing on related classes of
+conditions, first by concentrating all of the information about a
+specific class of condition in a single place, and second by specifying
+an inheritance relationship between types. This inheritance
+relationship forms the taxonomic structure of the condition hierarchy
+(@pxref{Taxonomy}).
+
+The following procedures consititute the abstraction for condition
+types.
+
+@deffn procedure make-condition-type name generalization field-names reporter
+@cindex generalization, of condition types
+Creates and returns a (new) condition type that is a specialization of
+@var{generalization} (if it is a condition type) or is the root of a new
+tree of condition types (if @var{generalization} is @code{#f}). For
+debugging purposes, the condition type has a @var{name}, and instances
+of this type contain storage for the fields specified by
+@var{field-names} (a list of symbols) in addition to the fields common
+to all conditions (@var{type}, @var{continuation} and @var{restarts}).
+
+@var{Reporter} is used to produce a description of a particular
+condition of this type. It may be a string describing the condition, a
+procedure of arity two (the first argument will be a condition of this
+type and the second a port) that will @code{write} the message to the
+given port, or @code{#f} to specify that the reporter should be taken
+from the condition type @var{generalization} (or produce an
+``undocumented condition of type @dots{}'' message if @var{generalization}
+is @code{#f}). The conventions used to form descriptions are spelled
+out in @ref{Error Messages}.
+@end deffn
+
+@deffn procedure condition-type/error? condition-type
+@vindex condition-type:error
+@cindex specialization, of condition types
+Returns @code{#t} if the @var{condition-type} is
+@code{condition-type:error} or a specialization of it, @code{#f}
+otherwise.
+@end deffn
+
+@deffn procedure condition-type/field-names condition-type
+@cindex generalization, of condition types
+Returns a list of all of the field names for a condition of type
+@var{condition-type}. This is the set union of the fields specified
+when this @var{condition-type} was created with the
+@code{condition-type/field-names} of the generalization of this
+@var{condition-type}.
+@end deffn
+
+@deffn procedure condition-type/generalizations condition-type
+@cindex generalization, of condition types
+Returns a list of all of the generalizations of @var{condition-type}.
+Notice that every condition type is considered a generalization of
+itself.
+@end deffn
+
+@deffn procedure condition-type? object
+Returns @code{#f} if and only if @var{object} is not a condition type.
+@end deffn
+
+@node Taxonomy, , Condition Types, Error System
+@section Condition-Type Taxonomy
+
+The MIT/GNU Scheme error system provides a rich set of predefined condition
+types. These are organized into a forest through taxonomic links
+providing the relationships for ``specializes'' and ``generalizes''.
+The chart appearing below shows these relationships by indenting all the
+specializations of a given type relative to the type. Note that the
+variables that are bound to these condition types are prefixed by
+@samp{condition-type:}; for example, the type appearing in the following
+table as @samp{simple-error} is stored in the variable
+@code{condition-type:simple-error}. Users are encouraged to add new
+condition types by creating specializations of existing ones.
+
+Following the chart are detailed descriptions of the predefined
+condition types. Some of these types are marked as @dfn{abstract}
+types. Abstract types are not intended to be used directly as the type
+of a condition; they are to be used as generalizations of other types,
+and for binding condition handlers. Types that are not marked as
+abstract are @dfn{concrete}; they are intended to be explicitly used as
+a condition's type.
+
+@page
+@example
+@group
+serious-condition
+ error
+ simple-error
+ illegal-datum
+ wrong-type-datum
+ wrong-type-argument
+ wrong-number-of-arguments
+ datum-out-of-range
+ bad-range-argument
+ inapplicable-object
+ file-error
+ file-operation-error
+ derived-file-error
+ port-error
+ derived-port-error
+ variable-error
+ unbound-variable
+ unassigned-variable
+ arithmetic-error
+ divide-by-zero
+ floating-point-overflow
+ floating-point-underflow
+ control-error
+ no-such-restart
+ not-loading
+ primitive-procedure-error
+ system-call-error
+warning
+ simple-warning
+simple-condition
+breakpoint
+@end group
+@end example
+
+@deffn {condition type} condition-type:serious-condition
+This is an abstract type. All serious conditions that require some form
+of intervention should inherit from this type. In particular, all
+errors inherit from this type.
+@end deffn
+
+@deffn {condition type} condition-type:error
+This is an abstract type. All errors should inherit from this type.
+@end deffn
+
+@deffn {condition type} condition-type:simple-error message irritants
+This is the condition generated by the @code{error} procedure when its
+first argument is not a condition or condition type. The fields
+@var{message} and @var{irritants} are taken directly from the arguments
+to @code{error}; @var{message} contains an object (usually a string) and
+@var{irritants} contains a list of objects. The reporter for this type
+uses @code{format-error-message} to generate its output from
+@var{message} and @var{irritants}.
+@end deffn
+
+@deffn {condition type} condition-type:illegal-datum datum
+This is an abstract type. This type indicates the class of errors in
+which a program discovers an object that lacks specific required
+properties. Most commonly, the object is of the wrong type or is
+outside a specific range. The @var{datum} field contains the offending
+object.
+@end deffn
+
+@deffn {condition type} condition-type:wrong-type-datum datum type
+This type indicates the class of errors in which a program discovers an
+object that is of the wrong type. The @var{type} field contains a
+string describing the type that was expected, and the @var{datum} field
+contains the object that is of the wrong type.
+@end deffn
+
+@example
+@group
+(error:wrong-type-datum 3.4 "integer") @error{}
+;The object 3.4 is not an integer.
+;To continue, call RESTART with an option number:
+; (RESTART 1) => Return to read-eval-print level 1.
+@end group
+@end example
+
+@deffn procedure error:wrong-type-datum datum type
+This procedure signals a condition of type
+@code{condition-type:wrong-type-datum}. The @var{datum} and @var{type}
+fields of the condition are filled in from the corresponding arguments
+to the procedure.
+@end deffn
+
+@deffn {condition type} condition-type:wrong-type-argument datum type operator operand
+This type indicates that a procedure was passed an argument of the wrong
+type. The @var{operator} field contains the procedure (or a symbol
+naming the procedure), the @var{operand} field indicates the argument
+position that was involved (this field contains either a symbol, a
+non-negative integer, or @code{#f}), the @var{type} field contains a
+string describing the type that was expected, and the @var{datum} field
+contains the offending argument.
+@end deffn
+
+@example
+@group
+(+ 'a 3) @error{}
+;The object a, passed as the first argument to integer-add,
+; is not the correct type.
+;To continue, call RESTART with an option number:
+; (RESTART 2) => Specify an argument to use in its place.
+; (RESTART 1) => Return to read-eval-print level 1.
+@end group
+
+@group
+(list-copy 3)
+;The object 3, passed as an argument to list-copy, is not a list.
+;To continue, call RESTART with an option number:
+; (RESTART 1) => Return to read-eval-print level 1.
+@end group
+@end example
+
+@deffn procedure error:wrong-type-argument datum type operator
+This procedure signals a condition of type
+@code{condition-type:wrong-type-argument}. The @var{datum}, @var{type}
+and @var{operator} fields of the condition are filled in from the
+corresponding arguments to the procedure; the @var{operand} field of the
+condition is set to @code{#f}.
+@end deffn
+
+@deffn {condition type} condition-type:wrong-number-of-arguments datum type operands
+This type indicates that a procedure was called with the wrong number of
+arguments. The @var{datum} field contains the procedure being called,
+the @var{type} field contains the number of arguments that the procedure
+accepts, and the @var{operands} field contains a list of the arguments
+that were passed to the procedure.
+@end deffn
+
+@example
+@group
+(car 3 4) @error{}
+;The procedure car has been called with 2 arguments;
+; it requires exactly 1 argument.
+;To continue, call RESTART with an option number:
+; (RESTART 1) => Return to read-eval-print level 1.
+@end group
+@end example
+
+@deffn procedure error:wrong-number-of-arguments datum type operands
+This procedure signals a condition of type
+@code{condition-type:wrong-number-of-arguments}. The @var{datum},
+@var{type} and @var{operands} fields of the condition are filled in from
+the corresponding arguments to the procedure.
+@end deffn
+
+@deffn {condition type} condition-type:datum-out-of-range datum
+This type indicates the class of errors in which a program discovers an
+object that is of the correct type but is otherwise out of range. Most
+often, this type indicates that an index to some data structure is
+outside of the range of indices for that structure. The @var{datum}
+field contains the offending object.
+@end deffn
+
+@example
+@group
+(error:datum-out-of-range 3) @error{}
+;The object 3 is not in the correct range.
+;To continue, call RESTART with an option number:
+; (RESTART 1) => Return to read-eval-print level 1.
+@end group
+@end example
+
+@deffn procedure error:datum-out-of-range datum
+This procedure signals a condition of type
+@code{condition-type:datum-out-of-range}. The @var{datum} field of the
+condition is filled in from the corresponding argument to the procedure.
+@end deffn
+
+@deffn {condition type} condition-type:bad-range-argument datum operator operand
+This type indicates that a procedure was passed an argument that is of
+the correct type but is otherwise out of range. Most often, this type
+indicates that an index to some data structure is outside of the range
+of indices for that structure. The @var{operator} field contains the
+procedure (or a symbol naming the procedure), the @var{operand} field
+indicates the argument position that was involved (this field contains
+either a symbol, a non-negative integer, or @code{#f}), and the
+@var{datum} field is the offending argument.
+@end deffn
+
+@example
+@group
+(string-ref "abc" 3) @error{}
+;The object 3, passed as the second argument to string-ref,
+; is not in the correct range.
+;To continue, call RESTART with an option number:
+; (RESTART 2) => Specify an argument to use in its place.
+; (RESTART 1) => Return to read-eval-print level 1.
+@end group
+@end example
+
+@deffn procedure error:bad-range-argument datum operator
+This procedure signals a condition of type
+@code{condition-type:bad-range-argument}. The @var{datum} and
+@var{operator} fields of the condition are filled in from the
+corresponding arguments to the procedure; the @var{operand} field of the
+condition is set to @code{#f}.
+@end deffn
+
+@deffn {condition type} condition-type:inapplicable-object datum operands
+This type indicates an error in which a program attempted to apply an
+object that is not a procedure. The object being applied is saved in
+the @var{datum} field, and the arguments being passed to the object are
+saved as a list in the @var{operands} field.
+@end deffn
+
+@example
+@group
+(3 4) @error{}
+;The object 3 is not applicable.
+;To continue, call RESTART with an option number:
+; (RESTART 2) => Specify a procedure to use in its place.
+; (RESTART 1) => Return to read-eval-print level 1.
+@end group
+@end example
+
+@deffn {condition type} condition-type:file-error filename
+This is an abstract type. It indicates that an error associated with a
+file has occurred. For example, attempting to delete a nonexistent file
+will signal an error. The @var{filename} field contains a filename or
+pathname associated with the operation that failed.
+@end deffn
+
+@deffn {condition type} condition-type:file-operation-error filename verb noun reason operator operands
+This is the most common condition type for file system errors. The
+@var{filename} field contains the filename or pathname that was being
+operated on. The @var{verb} field contains a string which is the verb
+or verb phrase describing the operation being performed, and the
+@var{noun} field contains a string which is a noun or noun phrase
+describing the object being operated on. The @var{reason} field
+contains a string describing the error that occurred. The
+@var{operator} field contains the procedure performing the operation (or
+a symbol naming that procedure), and the @var{operands} field contains a
+list of the arguments that were passed to that procedure. For example,
+an attempt to delete a nonexistent file would have the following field
+values:
+
+@example
+@group
+filename "/zu/cph/tmp/no-such-file"
+verb "delete"
+noun "file"
+reason "no such file or directory"
+operator file-remove
+operands ("/zu/cph/tmp/no-such-file")
+@end group
+@end example
+
+@noindent
+and would generate a message like this:
+
+@example
+@group
+(delete-file "/zu/cph/tmp/no-such-file") @error{}
+;Unable to delete file "/zu/cph/tmp/no-such-file" because:
+; No such file or directory.
+;To continue, call RESTART with an option number:
+; (RESTART 3) => Try to delete the same file again.
+; (RESTART 2) => Try to delete a different file.
+; (RESTART 1) => Return to read-eval-print level 1.
+@end group
+@end example
+@end deffn
+
+@deffn procedure error:file-operation-error filename verb noun reason operator operands
+This procedure signals a condition of type
+@code{condition-type:file-operation-error}. The fields of the condition
+are filled in from the corresponding arguments to the procedure.
+@end deffn
+
+@deffn {condition type} condition-type:derived-file-error filename condition
+This is another kind of file error, which is generated by obscure
+file-system errors that do not fit into the standard categories. The
+@var{filename} field contains the filename or pathname that was being
+operated on, and the @var{condition} field contains a condition
+describing the error in more detail. Usually the @var{condition} field
+contains a condition of type @code{condition-type:system-call-error}.
+@end deffn
+
+@deffn procedure error:derived-file filename condition
+This procedure signals a condition of type
+@code{condition-type:derived-file-error}. The @var{filename} and
+@var{condition} fields of the condition are filled in from the
+corresponding arguments to the procedure.
+@end deffn
+
+@deffn {condition type} condition-type:port-error port
+This is an abstract type. It indicates that an error associated with a
+I/O port has occurred. For example, writing output to a file port can
+signal an error if the disk containing the file is full; that error
+would be signalled as a port error. The @var{port} field contains the
+associated port.
+@end deffn
+
+@deffn {condition type} condition-type:derived-port-error port condition
+This is a concrete type that is signalled when port errors occur. The
+@var{port} field contains the port associated with the error, and the
+@var{condition} field contains a condition object that describes the
+error in more detail. Usually the @var{condition} field contains a
+condition of type @code{condition-type:system-call-error}.
+@end deffn
+
+@deffn procedure error:derived-port port condition
+This procedure signals a condition of type
+@code{condition-type:derived-port-error}. The @var{port} and
+@var{condition} fields of the condition are filled in from the
+corresponding arguments to the procedure.
+@end deffn
+
+@deffn {condition type} condition-type:variable-error location environment
+This is an abstract type. It indicates that an error associated with a
+variable has occurred. The @var{location} field contains the name of
+the variable, and the @var{environment} field contains the environment
+in which the variable was referenced.
+@end deffn
+
+@deffn {condition type} condition-type:unbound-variable location environment
+This type is generated when a program attempts to access or modify a
+variable that is not bound. The @var{location} field contains the name
+of the variable, and the @var{environment} field contains the
+environment in which the reference occurred.
+@end deffn
+
+@example
+@group
+foo @error{}
+;Unbound variable: foo
+;To continue, call RESTART with an option number:
+; (RESTART 3) => Specify a value to use instead of foo.
+; (RESTART 2) => Define foo to a given value.
+; (RESTART 1) => Return to read-eval-print level 1.
+@end group
+@end example
+
+@deffn {condition type} condition-type:unassigned-variable location environment
+This type is generated when a program attempts to access a variable that
+is not assigned. The @var{location} field contains the name of the
+variable, and the @var{environment} field contains the environment in
+which the reference occurred.
+@end deffn
+
+@example
+@group
+foo @error{}
+;Unassigned variable: foo
+;To continue, call RESTART with an option number:
+; (RESTART 3) => Specify a value to use instead of foo.
+; (RESTART 2) => Set foo to a given value.
+; (RESTART 1) => Return to read-eval-print level 1.
+@end group
+@end example
+
+@deffn {condition type} condition-type:arithmetic-error operator operands
+This is an abstract type. It indicates that a numerical operation was
+unable to complete because of an arithmetic error. (For example,
+division by zero.) The @var{operator} field contains the procedure that
+implements the operation (or a symbol naming the procedure), and the
+@var{operands} field contains a list of the arguments that were passed
+to the procedure.
+@end deffn
+
+@deffn {condition type} condition-type:divide-by-zero operator operands
+This type is generated when a program attempts to divide by zero. The
+@var{operator} field contains the procedure that implements the failing
+operation (or a symbol naming the procedure), and the @var{operands}
+field contains a list of the arguments that were passed to the
+procedure.
+@end deffn
+
+@example
+@group
+(/ 1 0)
+;Division by zero signalled by /.
+;To continue, call RESTART with an option number:
+; (RESTART 1) => Return to read-eval-print level 1.
+@end group
+@end example
+
+@deffn procedure error:divide-by-zero operator operands
+This procedure signals a condition of type
+@code{condition-type:divide-by-zero}. The @var{operator} and
+@var{operands} fields of the condition are filled in from the
+corresponding arguments to the procedure.
+@end deffn
+
+@deffn {condition type} condition-type:floating-point-overflow operator operands
+This type is generated when a program performs an arithmetic operation
+that results in a floating-point overflow. The @var{operator} field
+contains the procedure that implements the operation (or a symbol naming
+the procedure), and the @var{operands} field contains a list of the
+arguments that were passed to the procedure.
+@end deffn
+
+@deffn {condition type} condition-type:floating-point-underflow operator operands
+This type is generated when a program performs an arithmetic operation
+that results in a floating-point underflow. The @var{operator} field
+contains the procedure that implements the operation (or a symbol naming
+the procedure), and the @var{operands} field contains a list of the
+arguments that were passed to the procedure.
+@end deffn
+
+@deffn {condition type} condition-type:primitive-procedure-error operator operands
+This is an abstract type. It indicates that an error was generated by a
+primitive procedure call. Primitive procedures are distinguished from
+ordinary procedures in that they are not written in Scheme but instead
+in the underlying language of the Scheme implementation. The
+@var{operator} field contains the procedure that implements the
+operation (or a symbol naming the procedure), and the @var{operands}
+field contains a list of the arguments that were passed to the
+procedure.
+@end deffn
+
+@deffn {condition type} condition-type:system-call-error operator operands system-call error-type
+This is the most common condition type generated by primitive
+procedures. A condition of this type indicates that the primitive made
+a system call to the operating system, and that the system call
+signalled an error. The system-call error is reflected back to Scheme
+as a condition of this type, except that many common system-call errors
+are automatically translated by the Scheme implementation into more
+useful forms; for example, a system-call error that occurs while trying
+to delete a file will be translated into a condition of type
+@code{condition-type:file-operation-error}. The @var{operator} field
+contains the procedure that implements the operation (or a symbol naming
+the procedure), and the @var{operands} field contains a list of the
+arguments that were passed to the procedure. The @var{system-call} and
+@var{error-type} fields contain symbols that describe the specific
+system call that was being made and the error that occurred,
+respectively; these symbols are completely operating-system dependent.
+@end deffn
+
+@deffn {condition type} condition-type:control-error
+This is an abstract type. It describes a class of errors relating to
+program control flow.
+@end deffn
+
+@deffn {condition type} condition-type:no-such-restart name
+This type indicates that a named restart was not active when it was
+expected to be. Conditions of this type are signalled by several
+procedures that look for particular named restarts, for example
+@code{muffle-warning}. The @var{name} field contains the name that was
+being searched for.
+@end deffn
+
+@example
+@group
+(muffle-warning) @error{}
+;The restart named muffle-warning is not bound.
+;To continue, call RESTART with an option number:
+; (RESTART 1) => Return to read-eval-print level 1.
+@end group
+@end example
+
+@deffn procedure error:no-such-restart name
+This procedure signals a condition of type
+@code{condition-type:no-such-restart}. The @var{name} field of the
+condition is filled in from the corresponding argument to the procedure.
+@end deffn
+
+@deffn {condition type} condition-type:not-loading
+A condition of this type is generated when the procedure
+@code{current-load-pathname} is called from somewhere other than inside
+a file being loaded.
+@end deffn
+
+@example
+@group
+(current-load-pathname) @error{}
+;No file being loaded.
+;To continue, call RESTART with an option number:
+; (RESTART 1) => Return to read-eval-print level 1.
+@end group
+@end example
+
+@deffn {condition type} condition-type:warning
+This is an abstract type. All warnings should inherit from this type.
+Warnings are a class of conditions that are usually handled by informing
+the user of the condition and proceeding the computation normally.
+@end deffn
+
+@deffn {condition type} condition-type:simple-warning message irritants
+This is the condition generated by the @code{warn} procedure. The
+fields @var{message} and @var{irritants} are taken directly from the
+arguments to @code{warn}; @var{message} contains an object (usually a
+string) and @var{irritants} contains a list of objects. The reporter
+for this type uses @code{format-error-message} to generate its output
+from @var{message} and @var{irritants}.
+@end deffn
+
+@deffn {condition type} condition-type:simple-condition message irritants
+This is an unspecialized condition that does not fall into any of the
+standard condition classes. The @var{message} field contains an object
+(usually a string) and @var{irritants} contains a list of objects. The
+reporter for this type uses @code{format-error-message} to generate its
+output from @var{message} and @var{irritants}.
+@end deffn
+
+@deffn {condition type} condition-type:breakpoint environment message prompt
+A condition of this type is generated by the breakpoint mechanism. The
+contents of its fields are beyond the scope of this document.
+@end deffn
--- /dev/null
+@c This file is part of the MIT/GNU Scheme Reference Manual.
+@c $Id: graphics.texi,v 1.1 2003/04/15 03:29:42 cph Exp $
+
+@c Copyright 1991,1992,1993,1994,1995 Massachusetts Institute of Technology
+@c Copyright 1996,1997,1999,2000,2001 Massachusetts Institute of Technology
+@c Copyright 2002,2003 Massachusetts Institute of Technology
+@c See file scheme.texinfo for copying conditions.
+
+@node Graphics, Win32 Package Reference, Error System, Top
+@chapter Graphics
+@cindex graphics
+
+MIT/GNU Scheme has a simple two-dimensional line-graphics interface
+that is suitable for many graphics applications. In particular it is
+often used for plotting data points from experiments. The interface is
+generic in that it can support different types of graphics devices in a
+uniform manner. At the present time only one type of graphics device
+is implemented on each operating system.
+
+Procedures are available for drawing points, lines, and text; defining
+the coordinate system; clipping graphics output; controlling some of the
+drawing characteristics; and controlling the output buffer (for devices
+that perform buffering). Additionally, devices may support custom
+operations, such as control of colors.
+
+There are some constraints on the arguments to the procedures described
+in this chapter. Any argument named @var{graphics-device} must be a
+graphics device object that was returned from a call to
+@code{make-graphics-device}. Any argument that is a coordinate must be
+either an exact integer or an inexact real.
+
+@menu
+* Opening and Closing of Graphics Devices::
+* Coordinates for Graphics::
+* Drawing Graphics::
+* Characteristics of Graphics Output::
+* Buffering of Graphics Output::
+* Clipping of Graphics Output::
+* Custom Graphics Operations::
+* Images::
+* X Graphics:: Graphics on the X Window System
+* Win32 Graphics:: Graphics on Microsoft Windows and Windows NT
+* OS/2 Graphics:: Graphics on IBM OS/2
+@end menu
+
+@node Opening and Closing of Graphics Devices, Coordinates for Graphics, Graphics, Graphics
+@section Opening and Closing of Graphics Devices
+@cindex graphics, opening and closing devices
+
+@deffn procedure graphics-type-available? graphics-device-type
+This predicate returns @code{#t} if the graphics system named by the
+symbol @var{graphics-device-type} is implemented by the Scheme system.
+Otherwise it returns @code{#f}, in which case it is an error to attempt
+to make a graphics device using @var{graphics-device-type}.
+@end deffn
+
+@deffn procedure enumerate-graphics-types
+This procedure returns a list of symbols which are the names of all the
+graphics device types that are supported by the Scheme system. The
+result is useful in deciding what additional arguments to supply to
+@code{make-graphics-device}, as each device type typically has a unique
+way of specifying the initial size, shape and other attributes.
+@end deffn
+
+@deffn procedure make-graphics-device graphics-device-type object @dots{}
+This operation creates and returns a graphics device object.
+@var{Graphics-device-type} is a symbol naming a graphics device type,
+and both the number and the meaning of the remaining arguments is
+determined by that type (see the description of each device type for
+details); @var{graphics-device-type} must satisfy
+@code{graphics-type-available?}. @var{Graphics-device-type} may also be
+@code{#f}, in which case the graphics device type is chosen by the
+system from what is available. This allows completely portable graphics
+programs to be written provided no custom graphics operations are used.
+When @var{graphics-device-type} is @code{#f} no further arguments may be
+given; each graphics device type will use some ``sensible'' defaults.
+If more control is required then the program should use one of the two
+procedures above to dispatch on the available types.
+
+This procedure opens and initializes the device, which remains valid
+until explicitly closed by the procedure @code{graphics-close}.
+Depending on the implementation of the graphics device, if this object
+is reclaimed by the garbage collector, the graphics device may remain
+open or it may be automatically closed. While a graphics device remains
+open the resources associated with it are not released.
+@end deffn
+
+@deffn procedure graphics-close graphics-device
+Closes @var{graphics-device}, releasing its resources. Subsequently it
+is an error to use @var{graphics-device}.
+@end deffn
+
+@node Coordinates for Graphics, Drawing Graphics, Opening and Closing of Graphics Devices, Graphics
+@section Coordinates for Graphics
+@cindex graphics, coordinate systems
+
+@cindex coordinates, graphics
+@cindex device coordinates, graphics (defn)
+@cindex graphics, device coordinates (defn)
+@cindex virtual coordinates, graphics (defn)
+@cindex graphics, virtual coordinates (defn)
+Each graphics device has two different coordinate systems associated
+with it: @dfn{device coordinates} and @dfn{virtual coordinates}. Device
+coordinates are generally defined by low-level characteristics of the
+device itself, and often cannot be changed. Most device coordinate
+systems are defined in terms of pixels, and usually the upper-left-hand
+corner is the origin of the coordinate system, with @var{x} coordinates
+increasing to the right and @var{y} coordinates increasing downwards.
+
+In contrast, virtual coordinates are more flexible in the units
+employed, the position of the origin, and even the direction in which
+the coordinates increase. A virtual coordinate system is defined by
+assigning coordinates to the edges of a device. Because these edge
+coordinates are arbitrary real numbers, any Cartesian coordinate system
+can be defined.
+
+All graphics procedures that use coordinates are defined on virtual
+coordinates. For example, to draw a line at a particular place on a
+device, the virtual coordinates for the endpoints of that line are
+given.
+
+When a graphics device is initialized, its virtual coordinate system is
+reset so that the left edge corresponds to an x-coordinate of @code{-1},
+the right edge to x-coordinate @code{1}, the bottom edge to y-coordinate
+@code{-1}, and the top edge to y-coordinate @code{1}.
+
+@deffn procedure graphics-device-coordinate-limits graphics-device
+Returns (as multiple values) the device coordinate limits for
+@var{graphics-device}. The values, which are exact non-negative
+integers, are: @var{x-left}, @var{y-bottom}, @var{x-right}, and
+@var{y-top}.
+@end deffn
+
+@deffn procedure graphics-coordinate-limits graphics-device
+Returns (as multiple values) the virtual coordinate limits for
+@var{graphics-device}. The values, which are real numbers, are:
+@var{x-left}, @var{y-bottom}, @var{x-right}, and @var{y-top}.
+@end deffn
+
+@deffn procedure graphics-set-coordinate-limits graphics-device x-left y-bottom x-right y-top
+Changes the virtual coordinate limits of @var{graphics-device} to the
+given arguments. @var{X-left}, @var{y-bottom}, @var{x-right}, and
+@var{y-top} must be real numbers. Subsequent calls to
+@code{graphics-coordinate-limits} will return the new limits. This
+operation has no effect on the device's displayed contents.
+
+Note: This operation usually resets the clip rectangle, although it is
+not guaranteed to do so. If a clip rectangle is in effect when this
+procedure is called, it is necessary to redefine the clip rectangle
+afterwards.
+@end deffn
+
+@node Drawing Graphics, Characteristics of Graphics Output, Coordinates for Graphics, Graphics
+@section Drawing Graphics
+@cindex graphics, drawing
+
+The procedures in this section provide the basic drawing capabilities of
+Scheme's graphics system.
+
+@deffn procedure graphics-clear graphics-device
+Clears the display of @var{graphics-device}. Unaffected by the current
+drawing mode.
+@end deffn
+
+@deffn procedure graphics-draw-point graphics-device x y
+Draws a single point on @var{graphics-device} at the virtual coordinates
+given by @var{x} and @var{y}, using the current drawing mode.
+@end deffn
+
+@deffn procedure graphics-erase-point graphics-device x y
+Erases a single point on @var{graphics-device} at the virtual
+coordinates given by @var{x} and @var{y}. This procedure is unaffected
+by the current drawing mode.
+@end deffn
+
+@noindent
+This is equivalent to
+
+@example
+@group
+(lambda (device x y)
+ (graphics-bind-drawing-mode device 0
+ (lambda ()
+ (graphics-draw-point device x y))))
+@end group
+@end example
+
+@deffn procedure graphics-draw-line graphics-device x-start y-start x-end y-end
+@var{X-start}, @var{y-start}, @var{x-end}, and @var{y-end} must be real
+numbers. Draws a line on @var{graphics-device} that connects the points
+(@var{x-start}, @var{y-start}) and (@var{x-end}, @var{y-end}). The line
+is drawn using the current drawing mode and line style.
+@end deffn
+
+@deffn procedure graphics-draw-text graphics-device x y string
+Draws the characters of @var{string} at the point (@var{x}, @var{y}) on
+@var{graphics-device}, using the current drawing mode. The
+characteristics of the characters drawn are device-dependent, but all
+devices are initialized so that the characters are drawn upright, from
+left to right, with the leftmost edge of the leftmost character at
+@var{x}, and the baseline of the characters at @var{y}.
+@end deffn
+
+@cindex graphics, cursor (defn)
+@cindex cursor, graphics (defn)
+The following two procedures provide an alternate mechanism for drawing
+lines, which is more akin to using a plotter. They maintain a
+@dfn{cursor}, which can be positioned to a particular point and then
+dragged to another point, producing a line. Sequences of connected line
+segments can be drawn by dragging the cursor from point to point.
+
+Many graphics operations have an unspecified effect on the cursor. The
+following exceptions are guaranteed to leave the cursor unaffected:
+
+@example
+@group
+graphics-device-coordinate-limits
+graphics-coordinate-limits
+graphics-enable-buffering
+graphics-disable-buffering
+graphics-flush
+graphics-bind-drawing-mode
+graphics-set-drawing-mode
+graphics-bind-line-style
+graphics-set-line-style
+@end group
+@end example
+
+The initial state of the cursor is unspecified.
+
+@deffn procedure graphics-move-cursor graphics-device x y
+Moves the cursor for @var{graphics-device} to the point (@var{x},
+@var{y}). The contents of the device's display are unchanged.
+@end deffn
+
+@deffn procedure graphics-drag-cursor graphics-device x y
+Draws a line from @var{graphics-device}'s cursor to the point (@var{x},
+@var{y}), simultaneously moving the cursor to that point. The line is
+drawn using the current drawing mode and line style.
+@end deffn
+
+@node Characteristics of Graphics Output, Buffering of Graphics Output, Drawing Graphics, Graphics
+@section Characteristics of Graphics Output
+
+@cindex graphics, output characteristics
+Two characteristics of graphics output are so useful that they are
+supported uniformly by all graphics devices: @dfn{drawing mode} and
+@dfn{line style}. A third characteristic, @dfn{color}, is equally
+useful (if not more so), but implementation restrictions prohibit a
+uniform interface.
+
+@cindex drawing mode, graphics (defn)
+@cindex graphics, drawing mode (defn)
+The @dfn{drawing mode}, an exact integer in the range @code{0} to
+@code{15} inclusive, determines how the figure being drawn is combined
+with the background over which it is drawn to generate the final result.
+Initially the drawing mode is set to ``source'', so that the new output
+overwrites whatever appears in that place. Useful alternative drawing
+modes can, for example, erase what was already there, or invert it.
+
+Altogether 16 boolean operations are available for combining the source
+(what is being drawn) and the destination (what is being drawn over).
+The source and destination are combined by the device on a
+pixel-by-pixel basis as follows:
+
+@example
+@group
+Mode Meaning
+---- -------
+0 ZERO @r{[erase; use background color]}
+1 source AND destination
+2 source AND (NOT destination)
+3 source
+4 (NOT source) AND destination
+5 destination
+6 source XOR destination
+7 source OR destination
+8 NOT (source OR destination)
+9 NOT (source XOR destination)
+10 NOT destination
+11 source OR (NOT destination)
+12 NOT source
+13 (NOT source) OR destination
+14 (NOT source) OR (NOT destination)
+15 ONE @r{[use foreground color]}
+@end group
+@end example
+
+@cindex line style, graphics (defn)
+@cindex graphics, line style (defn)
+The @dfn{line style}, an exact integer in the range @code{0} to @code{7}
+inclusive, determines which parts of a line are drawn in the foreground
+color, and which in the background color. The default line style,
+``solid'', draws the entire line in the foreground color.
+Alternatively, the ``dash'' style alternates between foreground and
+background colors to generate a dashed line. This capability is useful
+for plotting several things on the same graph.
+
+Here is a table showing the name and approximate pattern of the
+different styles. A @samp{1} in the pattern represents a foreground
+pixel, while a @samp{-} represents a background pixel. Note that the
+precise output for each style will vary from device to device. The only
+style that is guaranteed to be the same for every device is ``solid''.
+
+@example
+@group
+Style Name Pattern
+----- ------- -------
+0 solid 1111111111111111
+1 dash 11111111--------
+2 dot 1-1-1-1-1-1-1-1-
+3 dash dot 1111111111111-1-
+4 dash dot dot 11111111111-1-1-
+5 long dash 11111111111-----
+6 center dash 111111111111-11-
+7 center dash dash 111111111-11-11-
+@end group
+@end example
+
+@deffn procedure graphics-bind-drawing-mode graphics-device drawing-mode thunk
+@deffnx procedure graphics-bind-line-style graphics-device line-style thunk
+These procedures bind the drawing mode or line style, respectively, of
+@var{graphics-device}, invoke the procedure @var{thunk} with no
+arguments, then undo the binding when @var{thunk} returns. The value of
+each procedure is the value returned by @var{thunk}. Graphics
+operations performed during @var{thunk}'s dynamic extent will see the
+newly bound mode or style as current.
+@end deffn
+
+@deffn procedure graphics-set-drawing-mode graphics-device drawing-mode
+@deffnx procedure graphics-set-line-style graphics-device line-style
+These procedures change the drawing mode or line style, respectively, of
+@var{graphics-device}. The mode or style will remain in effect until
+subsequent changes or bindings.
+@end deffn
+
+@node Buffering of Graphics Output, Clipping of Graphics Output, Characteristics of Graphics Output, Graphics
+@section Buffering of Graphics Output
+@cindex buffering, of graphics output
+@cindex graphics, buffering of output
+
+To improve performance of graphics output, most graphics devices provide
+some form of buffering. By default, Scheme's graphics procedures flush
+this buffer after every drawing operation. The procedures in this
+section allow the user to control the flushing of the output
+buffer.
+
+@deffn procedure graphics-enable-buffering graphics-device
+Enables buffering for @var{graphics-device}. In other words, after this
+procedure is called, graphics operations are permitted to buffer their
+drawing requests. This usually means that the drawing is delayed until
+the buffer is flushed explicitly by the user, or until it fills up and
+is flushed by the system.
+@end deffn
+
+@deffn procedure graphics-disable-buffering graphics-device
+Disables buffering for @var{graphics-device}. By default, all graphics
+devices are initialized with buffering disabled. After this procedure
+is called, all drawing operations perform their output immediately,
+before returning.
+
+Note: @code{graphics-disable-buffering} flushes the output buffer if
+necessary.
+@end deffn
+
+@deffn procedure graphics-flush graphics-device
+Flushes the graphics output buffer for @var{graphics-device}. This
+operation has no effect for devices that do not support buffering, or if
+buffering is disabled for the device.
+@end deffn
+
+@node Clipping of Graphics Output, Custom Graphics Operations, Buffering of Graphics Output, Graphics
+@section Clipping of Graphics Output
+@cindex graphics, clipping
+@cindex clipping, of graphics
+
+@cindex clip rectangle, graphics (defn)
+Scheme provides a rudimentary mechanism for restricting graphics output
+to a given rectangular subsection of a graphics device. By default,
+graphics output that is drawn anywhere within the device's virtual
+coordinate limits will appear on the device. When a @dfn{clip
+rectangle} is specified, however, output that would have appeared
+outside the clip rectangle is not drawn.
+
+Note that changing the virtual coordinate limits for a device will
+usually reset the clip rectangle for that device, as will any operation
+that affects the size of the device (such as a window resizing
+operation). However, programs should not depend on this.
+
+@deffn procedure graphics-set-clip-rectangle graphics-device x-left y-bottom x-right y-top
+Specifies the clip rectangle for @var{graphics-device} in virtual
+coordinates. @var{X-left}, @var{y-bottom}, @var{x-right}, and
+@var{y-top} must be real numbers. Subsequent graphics output is clipped
+to the intersection of this rectangle and the device's virtual
+coordinate limits.
+@end deffn
+
+@deffn procedure graphics-reset-clip-rectangle graphics-device
+Eliminates the clip rectangle for @var{graphics-device}. Subsequent
+graphics output is clipped to the virtual coordinate limits of the
+device.
+@end deffn
+
+@node Custom Graphics Operations, Images, Clipping of Graphics Output, Graphics
+@section Custom Graphics Operations
+@cindex custom operations, on graphics device
+@cindex graphics, custom operations
+
+In addition to the standard operations, a graphics device may support
+@dfn{custom operations}. For example, most devices have custom
+operations to control color. @code{graphics-operation} is used to
+invoke custom operations.
+
+@deffn procedure graphics-operation graphics-device name object @dots{}
+Invokes the graphics operation on @var{graphics-device} whose name is
+the symbol @var{name}, passing it the remaining arguments. This
+procedure can be used to invoke the standard operations, as well as
+custom operations that are specific to a particular graphics device
+type. The names of the standard graphics operations are formed by
+removing the @code{graphics-} prefix from the corresponding procedure.
+For example, the following are equivalent:
+
+@example
+@group
+(graphics-draw-point device x y)
+(graphics-operation device 'draw-point x y)
+@end group
+@end example
+
+For information on the custom operations for a particular device, see
+the documentation for its type.
+@end deffn
+
+@node Images, X Graphics, Custom Graphics Operations, Graphics
+@section Images
+@cindex graphics, images
+@cindex images, graphics
+@cindex graphics, bitmaps
+@cindex bitmaps, graphics
+
+Some graphics device types support images, which are rectangular pieces
+of picture that may be drawn into a graphics device. Images are often
+called something else in the host graphics system, such as bitmaps or
+pixmaps. The operations supported vary between devices, so look under
+the different device types to see what operations are available. All
+devices that support images support the following operations.
+
+@defop operation graphics-device create-image width height
+Images are created using the @code{create-image} graphics operation,
+specifying the @var{width} and @var{height} of the image in device
+coordinates (pixels).
+
+@example
+(graphics-operation device 'create-image 200 100)
+@end example
+
+@noindent
+The initial contents of an image are unspecified.
+
+@code{create-image} is a graphics operation rather than a procedure
+because the kind of image returned depends on the kind of graphics
+device used and the options specified in its creation. The image may be
+used freely with other graphics devices created with the same
+attributes, but the effects of using an image with a graphics device
+with different attributes (for example, different colors) is undefined.
+Under X, the image is display dependent.
+@end defop
+
+@defop operation graphics-device draw-image x y image
+The image is copied into the graphics device at the specified position.
+@end defop
+
+@defop operation graphics-device draw-subimage x y image im-x im-y w h
+Part of the image is copied into the graphics device at the specified
+(@var{x}, @var{y}) position. The part of the image that is copied is the
+rectangular region at @var{im-x} and @var{im-y} and of width @var{w} and
+height @var{h}. These four numbers are given in device coordinates
+(pixels).
+@end defop
+
+@deffn procedure image? object
+Returns @code{#t} if @var{object} is an image, otherwise returns
+@code{#f}.
+@end deffn
+
+@deffn procedure image/destroy image
+This procedure destroys @var{image}, returning storage to the system.
+Programs should destroy images after they have been used because even
+modest images may use large amounts of memory. Images are reclaimed by
+the garbage collector, but they may be implemented using memory outside
+of Scheme's heap. If an image is reclaimed before being destroyed, the
+implementation might not deallocate that non-heap memory, which can
+cause a subsequent call to @code{create-image} to fail because it is
+unable to allocate enough memory.
+@end deffn
+
+@c @deffn procedure image/descriptor image
+@c The procedure returns the implementation dependent image. Its use is
+@c discouraged as it is non-portable.
+@c @end deffn
+
+@deffn procedure image/height image
+Returns the height of the image in device coordinates.
+@end deffn
+
+@deffn procedure image/width image
+Returns the width of the image in device coordinates.
+@end deffn
+
+@deffn procedure image/fill-from-byte-vector image bytes
+The contents of @var{image} are set in a device-dependent way, using one
+byte per pixel from @var{bytes} (a string). Pixels are filled row by
+row from the top of the image to the bottom, with each row being filled
+from left to right. There must be at least @code{(* (image/height
+@var{image}) (image/width @var{image}))} bytes in @var{bytes}.
+@end deffn
+
+@node X Graphics, Win32 Graphics, Images, Graphics
+@section X Graphics
+@cindex X graphics
+
+@cindex X window system
+MIT/GNU Scheme supports graphics in the X window system (version 11).
+Arbitrary numbers of displays may be opened, and arbitrary numbers of
+graphics windows may be created for each display. A variety of
+operations is available to manipulate various aspects of the windows, to
+control their size, position, colors, and mapping. The X graphics
+device type supports images, which are implemented as Xlib @code{XImage}
+objects. X display, window, and image objects are automatically closed
+if they are reclaimed by the garbage collector.
+
+@menu
+* X Graphics Type::
+* Utilities for X Graphics::
+* Custom Operations on X Graphics Devices::
+@end menu
+
+@node X Graphics Type, Utilities for X Graphics, X Graphics, X Graphics
+@subsection X Graphics Type
+
+
+A graphics device for X windows is created by passing the symbol
+@code{x} as the graphics device type name to
+@code{make-graphics-device}:
+
+@example
+(make-graphics-device 'x #!optional @var{display} @var{geometry} @var{suppress-map?})
+@end example
+
+@noindent
+where @var{display} is either a display object, @code{#f}, or a string;
+@var{geometry} is either @code{#f} or a string; and @var{suppress-map?}
+is a boolean or a vector (see below). A new window is created on the
+appropriate display, and a graphics device representing that window is
+returned.
+
+@findex x-open-display
+@var{Display} specifies which X display the window is to be opened on;
+if it is @code{#f} or a string, it is passed as an argument to
+@code{x-open-display}, and the value returned by that procedure is used
+in place of the original argument. @var{Geometry} is an X geometry
+string, or @code{#f} which means to use the default geometry (which is
+specified as a resource).
+
+@var{Suppress-map?}, if given, may take two forms. First, it may be a
+boolean: if @code{#f} (the default), the window is automatically mapped
+after it is created; otherwise, @code{#t} means to suppress this
+automatic mapping. The second form is a vector of three elements. The
+first element is a boolean with the same meaning as the boolean form of
+@var{suppress-map?}. The second element is a string, which specifies an
+alternative resource name to be used for looking up the window's
+resources. The third element is also a string, which specifies a class
+name for looking up the window's resources. The default value for
+@var{suppress-map?} is @code{#f}.
+
+The default resource and class names are @code{"schemeGraphics"} and
+@code{"SchemeGraphics"} respectively.
+
+@cindex resources, X graphics
+@cindex X resources, graphics
+The window is initialized using the resource and class names specified
+by @var{suppress-map?}, and is sensitive to the following resource
+properties:
+
+@example
+@group
+Property Class Default
+-------- ----- -------
+geometry Geometry 512x384+0+0
+font Font fixed
+borderWidth BorderWidth 2
+internalBorder BorderWidth @r{[border width]}
+background Background white
+foreground Foreground black
+borderColor BorderColor @r{[foreground color]}
+cursorColor Foreground @r{[foreground color]}
+pointerColor Foreground @r{[foreground color]}
+@end group
+@end example
+
+The window is created with a @code{backing_store} attribute of
+@code{Always}. The window's name and icon name are initialized to
+@code{"scheme-graphics"}.
+
+
+@node Utilities for X Graphics, Custom Operations on X Graphics Devices, X Graphics Type, X Graphics
+@subsection Utilities for X Graphics
+
+@deffn procedure x-graphics/open-display display-name
+@cindex display, X graphics
+@cindex X display, graphics
+Opens a connection to the display whose name is @var{display-name},
+returning a display object. If unable to open a connection, @code{#f}
+is returned. @var{Display-name} is normally a string, which is an X
+display name in the usual form; however, @code{#f} is also allowed,
+meaning to use the value of the unix environment variable
+@code{DISPLAY}.
+@end deffn
+
+@deffn procedure x-graphics/close-display display
+Closes @var{display}; after calling this procedure, it is an error to
+use @var{display} for any purpose. Any windows that were previously
+opened on @var{display} are destroyed and their resources returned to
+the operating system.
+@end deffn
+
+@deffn procedure x-close-all-displays
+Closes all open connections to X displays. Equivalent to calling
+@code{x-close-display} on all open displays.
+@end deffn
+
+@deffn procedure x-geometry-string x y width height
+@cindex geometry string, X graphics
+@cindex X geometry string, graphics
+This procedure creates and returns a standard X geometry string from the
+given arguments. @var{X} and @var{y} must be either exact integers or
+@code{#f}, while @var{width} and @var{height} must be either exact
+non-negative integers or @code{#f}. Usually either @var{x} and @var{y}
+are both specified or both @code{#f}; similarly for @var{width} and
+@var{height}. If only one of the elements of such a pair is specified,
+it is ignored.
+
+Examples:
+
+@example
+@group
+(x-geometry-string #f #f 100 200) @result{} "100x200"
+(x-geometry-string 2 -3 100 200) @result{} "100x200+2-3"
+(x-geometry-string 2 -3 #f #f) @result{} "+2-3"
+@end group
+@end example
+
+Note that the @var{x} and @var{y} arguments cannot distinguish between
+@code{+0} and @code{-0}, even though these have different meanings in X.
+If either of those arguments is @code{0}, it means @code{+0} in X
+terminology. If you need to distinguish these two cases you must create
+your own geometry string using Scheme's string and number primitives.
+@end deffn
+
+@node Custom Operations on X Graphics Devices, , Utilities for X Graphics, X Graphics
+@subsection Custom Operations on X Graphics Devices
+
+Custom operations are invoked using the procedure
+@code{graphics-operation}. For example,
+
+@example
+(graphics-operation device 'set-foreground-color "blue")
+@end example
+
+@defop operation x-graphics-device set-background-color color-name
+@defopx operation x-graphics-device set-foreground-color color-name
+@defopx operation x-graphics-device set-border-color color-name
+@defopx operation x-graphics-device set-mouse-color color-name
+@findex graphics-clear
+These operations change the colors associated with a window.
+@var{Color-name} must be a string, which is the X server's name for the
+desired color. @code{set-border-color} and @code{set-mouse-color}
+immediately change the border and mouse-cursor colors.
+@code{set-background-color} and @code{set-foreground-color} change the
+colors to be used when drawing, but have no effect on anything drawn
+prior to their invocation. Because changing the background color
+affects the entire window, we recommend calling @code{graphics-clear} on
+the window's device afterwards. Color names include both mnemonic
+names, like @code{"red"}, and intensity names specified in the
+@code{"#@var{rrggbb}"} notation.
+@end defop
+
+@defop operation x-graphics-device draw-arc x y radius-x radius-y angle-start angle-sweep fill?
+@cindex drawing arcs and circles, graphics
+@cindex graphics, drawing arcs and circles
+@cindex circles, drawing
+@findex draw-arc
+
+Operation @code{draw-arc} draws or fills an arc. An arc is a segment of
+a circle, which may have been stretched along the x- or y- axis to form
+an ellipse.
+
+The parameters @var{x}, @var{y}, @var{radius-x} and @var{radius-y}
+describe the circle and @var{angle-start} and @var{angle-sweep} choose
+which part of the circle is drawn. The arc is drawn on the graphics
+device with the center of the circle at the virtual coordinates given by
+@var{x} and @var{y}. @var{radius-x} and @var{radius-y} determine the
+size of the circle in virtual coordinate units.
+
+The parameter @var{angle-start} determines where the arc starts. It is
+measured in degrees in an anti-clockwise direction, starting at 3
+o'clock. @var{angle-sweep} determines how much of the circle is drawn.
+It too is measured anti-clockwise in degrees. A negative value means
+the measurement is in a clockwise direction.
+
+Note that the angles are determined on a unit circle before it is
+stretched into an ellipse, so the actual angles that you will see on the
+computer screen depends on all of: @var{radius-x} and @var{radius-y},
+the window size, and the virtual coordinates.
+
+If @var{fill?} is @code{#f} then just the segment of the circle is
+drawn, otherwise the arc is filled in a pie-slice fashion.
+
+This draws a quarter circle pie slice, standing on its point, with point
+at virtual coordinates (3,5):
+
+@example
+(graphics-opereration g 'draw-arc 3 5 .5 .5 45 90 #t)
+@end example
+
+@end defop
+
+@defop operation x-graphics-device draw-circle x y radius
+@defopx operation x-graphics-device fill-circle x y radius
+@cindex drawing arcs and circles, graphics
+@cindex graphics, drawing arcs and circles
+@cindex circles, drawing
+@findex draw-circle
+@findex fill-circle
+These operations draw a circle (outline) or a filled circle (solid) at
+on the graphics device at the virtual coordinates given by @var{x} and
+@var{y}. These operations could be implemented trivially interms of the
+@code{draw-arc} operation.
+@end defop
+
+@defop operation x-graphics-device set-border-width width
+@defopx operation x-graphics-device set-internal-border-width width
+@findex graphics-clear
+These operations change the external and internal border widths of a
+window. @var{Width} must be an exact non-negative integer, specified in
+pixels. The change takes place immediately. Note that changing the
+internal border width can cause displayed graphics to be garbled; we
+recommend calling @code{graphics-clear} on the window's device after
+doing so.
+@end defop
+
+@defop operation x-graphics-device set-font font-name
+Changes the font used when drawing text in a window. @var{Font-name}
+must be a string that is a font name known to the X server. This
+operation does not affect text drawn prior to its invocation.
+@end defop
+
+@defop operation x-graphics-device set-mouse-shape shape-number
+Changes the shape of the mouse cursor. @var{Shape-number} is an exact
+non-negative integer that is used as an index into the mouse-shape font;
+when multiplied by 2 this number corresponds to an index in the file@*
+@file{/usr/include/X11/cursorfont.h}.
+@end defop
+
+@defop operation x-graphics-device map-window
+@defopx operation x-graphics-device withdraw-window
+These operations control the mapping of windows. They correspond
+directly to Xlib's @code{XMapWindow} and @code{XWithdrawWindow}.
+@end defop
+
+@defop operation x-graphics-device resize-window width height
+Changes the size of a window. @var{Width} and @var{height} must be
+exact non-negative integers. The operation corresponds directly to
+Xlib's @code{XResizeWindow}.
+
+This operation resets the virtual coordinate system and the clip
+rectangle.
+@end defop
+
+@defop operation x-graphics-device move-window x y
+Changes the position of a window on the display. @var{X} and @var{y}
+must be exact integers. The operation corresponds directly to Xlib's
+@code{XMoveWindow}. Note that the coordinates @var{x} and @var{y} do
+not take the external border into account, and therefore will not
+position the window as you might like. The only reliable way to
+position a window is to ask a window manager to do it for you.
+@end defop
+
+@defop operation x-graphics-device get-default resource property
+This operation corresponds directly to Xlib's @code{XGetDefault}.
+@var{Resource} and @var{property} must be strings. The operation
+returns the character string corresponding to the association of
+@var{resource} and @var{property}; if no such association exists,
+@code{#f} is returned.
+@end defop
+
+@defop operation x-graphics-device copy-area source-x-left source-y-top width height destination-x-left destination-y-top
+This operation copies the contents of the rectangle specified by
+@var{source-x-left}, @var{source-y-top}, @var{width}, and @var{height} to
+the rectangle of the same dimensions at @var{destination-x-left} and
+@var{destination-y-top}.
+@end defop
+
+@defop operation x-graphics-device font-structure font-name
+Returns a Scheme equivalent of the X font structure for the font named
+@var{font-name}. If the string @var{font-name} does not name a font
+known to the X server, or names a 16-bit font, @code{#f} is returned.
+@end defop
+
+@deffn procedure x-font-structure/name font-structure
+@deffnx procedure x-font-structure/direction font-structure
+@deffnx procedure x-font-structure/all-chars-exist font-structure
+@deffnx procedure x-font-structure/default-char font-structure
+@deffnx procedure x-font-structure/min-bounds font-structure
+@deffnx procedure x-font-structure/max-bounds font-structure
+@deffnx procedure x-font-structure/start-index font-structure
+@deffnx procedure x-font-structure/character-bounds font-structure
+@deffnx procedure x-font-structure/max-ascent font-structure
+@deffnx procedure x-font-structure/max-descent font-structure
+These procedures extract the components of the font description
+structure returned by the X graphics operation @code{font-structure}. A
+more complete description of these components appears in documentation
+of the @code{XLoadQueryFont} Xlib call. @code{start-index} is the index
+of the first character available in the font. The @code{min-bounds} and
+@code{max-bounds} components are structures of type
+@code{x-character-bounds}, and the @code{character-bounds} component is
+a vector of the same type.
+@end deffn
+
+@deffn procedure x-character-bounds/lbearing character-bounds
+@deffnx procedure x-character-bounds/rbearing character-bounds
+@deffnx procedure x-character-bounds/width character-bounds
+@deffnx procedure x-character-bounds/ascent character-bounds
+@deffnx procedure x-character-bounds/descent character-bounds
+These procedures extract components of objects of type
+@code{x-character-bounds}. A more complete description of them appears
+in documentation of the@* @code{XLoadQueryFont} Xlib call.
+@end deffn
+
+@node Win32 Graphics, OS/2 Graphics, X Graphics, Graphics
+@section Win32 Graphics
+@cindex Win32 graphics
+
+MIT/GNU Scheme supports graphics on Microsoft Windows 95, Windows 98, and
+Windows NT. In addition to the usual operations, there are operations
+to control the size, position and colors of a graphics window. Win32
+devices support images, which are implemented as device independent
+bitmaps (@sc{dib}s).
+
+The Win32 graphics device type is implemented as a top level window.
+@code{graphics-enable-buffering} is implemented and gives a 2x to 4x
+speedup on many graphics operations. As a convenience, when buffering
+is enabled clicking on the graphics window's title bar effects a
+@code{graphics-flush} operation. The user has the benefit of the
+increased performance and the ability to view the progress in drawing at
+the click of a mouse button.
+
+
+@menu
+* Win32 Graphics Type::
+* Custom Operations for Win32 Graphics:: Custom Operations for Win32 Graphics Devices
+@end menu
+
+@node Win32 Graphics Type, Custom Operations for Win32 Graphics, Win32 Graphics, Win32 Graphics
+@subsection Win32 Graphics Type
+
+Win32 graphics devices are created by specifying the symbol @code{win32}
+as the @var{graphics-device-type} argument to
+@code{make-graphics-device}. The Win32 graphics device type is
+implemented as a top-level window and supports color drawing in addition
+to the standard Scheme graphics operations.
+
+Graphics devices are opened as follows:
+
+@example
+(make-graphics-device 'win32 #!optional @var{width} @var{height} @var{palette})
+@end example
+
+@noindent
+where @var{width} and @var{height} specify the size, in pixels, of the
+drawing area in the graphics window (i.e.@: excluding the frame).
+@var{Palette} determines the colors available for drawing in the window.
+
+When a color is specified for drawing, the nearest color available in
+the palette is used. Permitted values for @var{palette} are
+
+@table @asis
+@item @code{'grayscale}
+The window allocates colors from a grayscale palette
+of approximately 236 shades of gray.
+
+@item @code{'grayscale-128}
+The window allocates colors from a grayscale palette of 128 shades of
+gray.
+
+@item @code{'standard}
+The standard palette has good selection of colors and grays.
+
+@item @code{#f} or @code{'system}
+The colors available are those in the system palette. There are usually
+16 to 20 colors in the system palette and these are usually sufficent
+for simple applications like line drawings and x-vs-y graphs of
+mathematical functions. Drawing with the system palette can be more
+efficient.
+
+@end table
+@noindent
+If @var{palette} is not specified then the @code{standard} palette is
+used.
+
+
+
+@node Custom Operations for Win32 Graphics, , Win32 Graphics Type, Win32 Graphics
+@subsection Custom Operations for Win32 Graphics
+
+Custom operations are invoked using the procedure
+@code{graphics-operation}. For example,
+
+@example
+(graphics-operation device 'set-foreground-color "blue")
+@end example
+
+@defop operation win32-graphics-device set-background-color color-name
+@defopx operation win32-graphics-device set-foreground-color color-name
+@findex set-background-color
+@findex set-foreground-color
+@cindex color
+These operations change the colors associated with a window.
+@var{Color-name} must be of one of the valid color specification forms
+listed below. @code{set-background-color} and
+@code{set-foreground-color} change the colors to be used when drawing,
+but have no effect on anything drawn prior to their invocation. Because
+changing the background color affects the entire window, we recommend
+calling @code{graphics-clear} on the window's device afterwards.
+
+The foreground color affects the drawing of text, points, lines,
+ellipses and filled polygons.
+
+Colors are specified in one of three ways:
+
+@table @asis
+@item An integer
+This is the Win32 internal RGB value.
+
+@item By name
+A limited number of names are understood by the system.
+Names are strings, e.g.@: @code{"red"}, @code{"blue"}, @code{"black"}.
+More names can be registered with the @code{define-color} operation.
+
+@item RGB (Red-Green-Blue) triples
+A triple is either a vector or list of three integers in the range
+0--255 inclusive which specify the intensity of the red, green and blue
+components of the color. Thus @code{#(0 0 0)} is black, @code{(0 0
+128)} is dark blue and @code{#(255 255 255)} is white.
+@end table
+
+@noindent
+If the color is not available in the graphics device then the nearest
+available color is used instead.
+@end defop
+
+
+@defop operation win32-graphics-device define-color name spec
+Define the string @var{name} to be the color specified by @var{spec}.
+@var{Spec} may be any acceptable color specification. Note that the
+color names defined this way are available to any Win32 graphics device,
+and the names do @emph{not} have to be defined for each device.
+
+
+Color names defined by this interface may also be used when setting the
+colors of the Scheme console window, or the colors of Edwin editor
+windows.
+@end defop
+
+@defop operation win32-graphics-device find-color name
+Looks up a color previously defined by @code{define-color}. This returns
+the color in its most efficient form for operations
+@code{set-foreground-color} or @code{set-background-color}.
+@end defop
+
+
+@defop operation win32-graphics-device draw-ellipse left top right bottom
+@cindex ellipse, graphics
+@cindex circle, graphics
+@cindex graphics, ellipse
+@cindex graphics, circle
+Draw an ellipse. @var{Left}, @var{top}, @var{right} and @var{bottom}
+indicate the coordinates of the bounding rectangle of the ellipse.
+Circles are merely ellipses with equal width and height. Note that the
+bounding rectangle has horizontal and vertical sides. Ellipses with
+rotated axes cannot be drawn. The rectangle applies to the center of the
+line used to draw the ellipse; if the line width has been set to greater
+than 1 then the ellipse will spill outside the bounding rectange by half
+of the line width.
+@end defop
+
+
+@defop operation win32-graphics-device fill-polygon points
+@findex fill-polygon
+Draws a filled polygon using the current foreground color.
+@var{Points} is a vector of real numbers.
+The numbers are in the order x1 y1 x2 y2 @dots{} xn yn.
+For example,
+
+@example
+(graphics-operation device 'fill-polygon #(0 0 0 1 1 0))
+@end example
+
+@noindent
+draws a solid triangular region between the points (0, 0), (0, 1) and
+(1, 0).
+@end defop
+
+
+@defop operation win32-graphics-device load-bitmap pathname
+@cindex bitmaps
+The graphics device contents and size are initialized from the windows
+bitmap file specified by @var{pathname}. If no file type is supplied
+then a @code{".BMP"} extension is added. If a clip rectangle is in
+effect when this procedure is called, it is necessary to redefine the
+clip rectangle afterwards.
+@end defop
+
+@defop operation win32-graphics-device save-bitmap pathname
+@cindex printing graphics output
+The graphics device contents are saved as a bitmap to the file specified
+by @var{pathname}. If no file type is supplied then a @code{".BMP"}
+extension is added. The saved bitmap may be incorporated into documents
+or printed.
+@end defop
+
+@defop operation win32-graphics-device move-window x y
+The graphics device window is moved to the screen position specified by
+@var{x} and @var{y}.
+@end defop
+
+@defop operation win32-graphics-device resize-window width height
+The graphics device window is resized to the specified @var{width} and
+@var{height} in device coordinates (pixels). If a clip rectangle is in effect
+when this procedure is called, it is necessary to redefine the clip
+rectangle afterwards.
+@end defop
+
+@defop operation win32-graphics-device set-line-width width
+This operation sets the line width for future drawing of lines, points
+and ellipses. It does not affect existing lines and has no effect on
+filled polygons. The line width is specified in device units. The
+default and initial value of this parameter is 1 pixel.
+@end defop
+
+@defop operation win32-graphics-device set-window-name name
+This sets the window title to the string @var{name}. The window is
+given the name @code{"Scheme Graphics"} at creation.
+@end defop
+
+@defop operation win32-graphics-device set-font handle
+Sets the font for drawing text. Currently not well supported. If you
+can get a Win32 font handle it can be used here.
+@end defop
+
+@defop operation win32-graphics-device copy-area source-x-left source-y-top width height destination-x-left destination-y-top
+This operation copies the contents of the rectangle specified by
+@var{source-x-left}, @var{source-y-top}, @var{width}, and @var{height}
+to the rectangle of the same dimensions at @var{destination-x-left} and
+@var{destination-y-top}.
+@end defop
+
+@node OS/2 Graphics, , Win32 Graphics, Graphics
+@section OS/2 Graphics
+@cindex OS/2 graphics
+
+MIT/GNU Scheme supports graphics under the OS/2 Presentation Manager in
+OS/2 version 2.1 and later. The OS/2 graphics device type is
+implemented as a top level window. In addition to the usual operations,
+there are operations to control the size, position, and colors of a
+graphics window. OS/2 graphics devices support images, which are
+implemented as memory presentation spaces.
+
+The custom graphics operations defined in this section are invoked using
+the procedure @code{graphics-operation}. For example,
+
+@example
+(graphics-operation device 'set-foreground-color "blue")
+@end example
+
+@menu
+* OS/2 Graphics Type::
+* Color Operations for OS/2 Graphics::
+* Window Operations for OS/2 Graphics::
+* Event Operations for OS/2 Graphics::
+* Miscellaneous Operations for OS/2 Graphics::
+@end menu
+
+@node OS/2 Graphics Type, Color Operations for OS/2 Graphics, OS/2 Graphics, OS/2 Graphics
+@subsection OS/2 Graphics Type
+
+OS/2 graphics devices are created by specifying the symbol
+@code{os/2} as the @var{graphics-device-type} argument to
+@code{make-graphics-device}. The OS/2 graphics device type is
+implemented as a top-level window and supports color drawing in addition
+to the standard Scheme graphics operations.
+
+Graphics devices are opened as follows:
+
+@example
+(make-graphics-device 'os/2 #!optional @var{width} @var{height})
+@end example
+
+@noindent
+where @var{width} and @var{height} specify the size, in pixels, of the
+drawing area in the graphics window (i.e.@: excluding the frame).
+
+@node Color Operations for OS/2 Graphics, Window Operations for OS/2 Graphics, OS/2 Graphics Type, OS/2 Graphics
+@subsection Color Operations for OS/2 Graphics
+
+These operations control the colors used when drawing on an OS/2
+graphics device.
+
+@defop operation os2-graphics-device color?
+@findex color?
+This operation returns @code{#t} if the display supports color.
+@end defop
+
+@defop operation os2-graphics-device set-background-color color-name
+@defopx operation os2-graphics-device set-foreground-color color-name
+@findex set-background-color
+@findex set-foreground-color
+@cindex color
+These operations change the colors associated with a window.
+@var{Color-name} must be one of the valid color specification forms
+listed below. @code{set-background-color} and
+@code{set-foreground-color} change the colors to be used when drawing,
+but have no effect on anything drawn prior to their invocation. Because
+changing the background color affects the entire window, we recommend
+calling @code{graphics-clear} on the window's device afterwards.
+
+The foreground color affects the drawing of text, points, and lines.
+Colors are specified in one of these ways:
+
+@table @asis
+@item An integer between @code{0} and @code{#xffffff} inclusive
+This is the OS/2 internal RGB value.
+
+@item By name
+A limited number of names are understood by the system. Names are
+strings, e.g.@: @code{"red"}, @code{"blue"}, @code{"black"}. More names
+can be registered with the @code{define-color} operation.
+
+@item RGB (Red-Green-Blue) triples
+A triple is a list of three integers between @code{0} and @code{#xff}
+inclusive which specify the intensity of the red, green and blue
+components of the color. Thus @code{(0 0 0)} is black, @code{(0 0 128)}
+is dark blue and @code{(255 255 255)} is white.
+@end table
+
+@noindent
+If the color is not available in the graphics device then the nearest
+available color is used instead.
+@end defop
+
+@defop operation os2-graphics-device define-color name spec
+Define the string @var{name} to be the color specified by @var{spec}.
+@var{Spec} may be any acceptable color specification. Note that the
+color names defined this way are available to any OS/2 graphics
+device, and the names do @emph{not} have to be defined for each device.
+
+Color names defined by this interface may also be used when setting the
+colors of the Scheme console window, or the colors of Edwin editor
+windows.
+@end defop
+
+@defop operation os2-graphics-device find-color name
+Looks up a color previously defined by @code{define-color}. This
+returns the color in its most efficient form for operations
+@code{set-foreground-color} or @code{set-background-color}.
+@end defop
+
+@node Window Operations for OS/2 Graphics, Event Operations for OS/2 Graphics, Color Operations for OS/2 Graphics, OS/2 Graphics
+@subsection Window Operations for OS/2 Graphics
+
+These operations control the window that contains the OS/2 graphics
+device. They provide facilities to change the window's size and
+position; to raise and lower the window relative to other windows on the
+desktop; to hide or minimize the window, and to restore it from the
+hidden or minimized state; to activate or deactivate the window (that
+is, control the keyboard focus); and to control the text that appears in
+the window's title bar.
+
+@defop operation os2-graphics-device window-position
+This operation returns the position of the graphics-device window on the
+desktop. The position is returned as two values
+(@pxref{Continuations}), which are the x and y coordinates of the
+position. These coordinates are in units of pels (pixels), and measure
+the distance between the lower left hand corner of the desktop and the
+lower left hand corner of the graphics device window's frame.
+@end defop
+
+@defop operation os2-graphics-device set-window-position x y
+The graphics-device window is moved to the screen position specified by
+@var{x} and @var{y}. The coordinates @var{x} and @var{y} are in units
+of pels (pixels), and measure the distance between the lower left hand
+corner of the desktop and the lower left hand corner of the graphics
+device window's frame.
+@end defop
+
+@defop operation os2-graphics-device window-size
+This operation returns the size of the client area of the
+graphics-device window. The client area is the part of the window that
+you draw on; it does not include the window frame, title bar, etc. The
+size is returned as two values (@pxref{Continuations}), which are the
+width and height of the client area in units of pels (pixels).
+@end defop
+
+@defop operation os2-graphics-device set-window-size width height
+This operation sets the size of the client area of the graphics-device
+window to the specified @var{width} and @var{height}, which are in units
+of pels (pixels). The client area is the part of the window that you
+draw on; it does not include the window frame, title bar, etc.
+@end defop
+
+@defop operation os2-graphics-device window-frame-size
+This operation returns the size of the graphics-device window's frame.
+This includes the client area, as well as the border, title bar, etc.
+The size is returned as two values (@pxref{Continuations}), which are
+the width and height of the frame in units of pels (pixels).
+
+The frame size is useful in conjunction with the window position and the
+desktop size to determine relative placement of the window or to
+guarantee that the entire window is visible on the desktop.
+@end defop
+
+@defop operation os2-graphics-device desktop-size
+This operation returns the size of the OS/2 desktop. The size is
+returned as two values (@pxref{Continuations}), which are the width and
+height of the frame in units of pels (pixels).
+@end defop
+
+@defop operation os2-graphics-device raise-window
+This operation raises the graphics-device window so that it is on top of
+any other windows on the desktop.
+@end defop
+
+@defop operation os2-graphics-device lower-window
+This operation lowers the graphics-device window so that it is below all
+other windows on the desktop.
+@end defop
+
+@defop operation os2-graphics-device hide-window
+This operation hides the graphics-device window. The window disappears
+from the desktop, but still appears in the window list.
+@end defop
+
+@defop operation os2-graphics-device minimize-window
+This operation minimizes the graphics-device window. The window
+disappears from the desktop, but still appears in the window list.
+Depending on how you have configured your desktop, the window may appear
+as an icon, either on the desktop or in the minimized window viewer.
+@end defop
+
+@defop operation os2-graphics-device maximize-window
+This operation maximizes the graphics-device window. This causes the
+window to fill the entire desktop.
+@end defop
+
+@defop operation os2-graphics-device restore-window
+This operation restores the graphics-device window to its normal state.
+If the window is hidden or minimized, it is shown again, at its former
+position on the desktop. If the window is maximized, it is returned to
+its normal size.
+@end defop
+
+@defop operation os2-graphics-device activate-window
+This operation makes the graphics-device window be the active window.
+This causes the window to be put in front of all other windows on the
+desktop, highlights its frame, and gives it the keyboard focus.
+@end defop
+
+@defop operation os2-graphics-device deactivate-window
+This operation deactivates the graphics-device window if it was active
+(otherwise it has no effect). This causes some other window to be
+chosen to be active in its place.
+@end defop
+
+@defop operation os2-graphics-device set-window-title title
+This operation changes the text that appears in the graphics device
+window's title bar. The new text is given by @var{title}, which must be
+a string.
+@end defop
+
+@node Event Operations for OS/2 Graphics, Miscellaneous Operations for OS/2 Graphics, Window Operations for OS/2 Graphics, OS/2 Graphics
+@subsection Event Operations for OS/2 Graphics
+
+These operations allow you to read some of the events that are generated
+by the Presentation Manager and put in the message queue of a
+graphics-device window.
+
+@defop operation os2-graphics-device read-button
+This operation waits for the user to push a mouse button inside the
+client area of the graphics-device window. It then returns four values
+(@pxref{Continuations}) which are: the button number; the x and y
+coordinates of the mouse pointer at the time the button was pressed, in
+pels (pixels) relative to the lower left hand corner of the client area;
+and the graphics device that the mouse pointer was over at the time the
+button was pressed.
+
+Note that this operation only works when button events are selected
+(which is the default).
+@end defop
+
+@defop operation os2-graphics-device select-user-events mask
+This operation sets the event-selection mask for the graphics device to
+@var{mask}. The event-selection mask is an exact non-negative integer
+that specifies which types of incoming events are to be saved in the
+user-event queue for later retrieval by the @code{read-user-event}
+operation. The mask is specified by setting the bits corresponding to
+the event types that you are interested in, as follows:
+
+@example
+@group
+Number Mask Description
+------ ----- -----------
+0 #x001 Button press/release
+1 #x002 Close (close the window) [WM_CLOSE]
+2 #x004 Focus change [WM_SETFOCUS]
+3 #x008 Key press/release [WM_CHAR]
+4 #x010 Paint [WM_PAINT]
+5 #x020 Size change [WM_SIZE]
+6 #x040 Visibility change [WM_SHOW]
+7 #x080 Command [WM_COMMAND]
+8 #x100 Help [WM_HELP]
+9 #x200 Mouse-move [WM_MOUSEMOVE]
+@end group
+@end example
+
+@noindent
+Note that this operation does not affect any events that are already in
+the user-event queue. Changing the mask only affects what events will
+be added to the queue in the future.
+@end defop
+
+@defop operation os2-graphics-device read-user-event
+This operation returns the next user event available from the user-event
+queue. If there are no events in the queue, the operation waits for an
+event to arrive before returning.
+@end defop
+
+An event is a vector whose first element is the event-type number, whose
+second element is the graphics device that the event refers to, and
+whose remaining elements provide information about the event. Here is a
+table of the possible event types and their vector layout:
+
+@table @code
+@item #(0 @var{device} @var{number} @var{type} @var{x} @var{y} @var{flags})
+A button event. @var{Number} is the button number, for example button
+number @code{0} is usually the left mouse button, @code{1} is usually
+the right button, etc. @var{Type} specifies what occurred: @code{0}
+means the button was pressed, @code{1} means the button was released,
+@code{2} means the button was clicked, and @code{3} means the button was
+double clicked. @var{X} and @var{y} are the position of the mouse
+pointer at the time of the event, in units of pels (pixels) measured
+from the lower left corner of the client area of the associated window.
+Finally, @var{flags} specifies what shift keys were pressed at the time
+of the button event; it is a mask word created by combining zero or more
+of the following flags: @code{#x08} means the shift key was pressed,
+@code{#x10} means the control key was pressed, and @code{#x20} means the
+alt key was pressed.
+
+@item #(1 @var{device})
+A close event. The user has selected the close button from the system
+menu, or typed @key{Alt-f4}.
+
+@item #(2 @var{device} @var{gained?})
+A focus event. If @var{gained?} is @code{#t}, the keyboard focus is
+being gained, and if @var{gained?} is @code{#f}, it is being lost.
+
+@item #(3 @var{device} @var{code} @var{flags} @var{repeat})
+A keyboard event. This is much too complicated to describe here. See
+the OS/2 toolkit documentation for details.
+
+@item #(4 @var{device} @var{xl} @var{xh} @var{yl} @var{yh})
+A paint event. Part of the graphics-device window that was obscured has
+been revealed and the Presentation Manager is informing the window that
+it must repaint that area. Scheme will take care of the painting for
+you, so this event isn't very useful.
+
+@item #(5 @var{device} @var{width} @var{height})
+A size-change event. The size of the graphics-device window has
+changed, and @var{width} and @var{height} specify the new size in pels
+(pixels).
+
+@item #(6 @var{device} @var{shown?})
+A visibility event. Indicates that the graphics-device window has been
+hidden or revealed. If @var{shown?} is @code{#f}, the window is hidden,
+and if it is @code{#t}, the window is shown.
+
+@item #(7 @var{device} @var{source} @var{mouse?})
+@itemx #(8 @var{device} @var{source} @var{mouse?})
+A menu command. @var{Source} specifies which menu item was selected to
+cause this event, and @var{mouse?} is a boolean indicating whether the
+item was selected with the mouse or the keyboard. The event-type number
+@code{7} indicates a command from a @samp{WM_COMMAND} message, while
+@code{8} is a command from a @samp{WM_HELP} message.
+
+@item #(9 @var{device} @var{x} @var{y} @var{hit-test} @var{flags})
+The mouse was moved. @var{X} and @var{y} specify the position of the
+mouse, @var{hit-test} contains the hit-test information, and @var{flags}
+specifies the modifier keys that were pressed at the time.
+@end table
+
+@defop operation os2-graphics-device discard-events
+This operation discards any events that are in the user-event queue.
+This is sometimes useful when you want to prompt the user for some input
+and don't want to consider any previous input.
+@end defop
+
+@node Miscellaneous Operations for OS/2 Graphics, , Event Operations for OS/2 Graphics, OS/2 Graphics
+@subsection Miscellaneous Operations for OS/2 Graphics
+
+These operations allow you to: change the font used for drawing text in
+a graphics-device window; take a snapshot of a graphics-device window
+and return it as an image object; and draw multiple lines efficiently.
+
+@defop operation os2-graphics-device set-font font-name
+This operation sets the font used for drawing text in the
+graphics-device window. @var{Font-name} is a string describing the
+font; this string is in the form "<point-size>.<family-name>", for
+example, @code{"10.Courier"}. You may specify any fixed-pitch font
+family, in any point size that is supported for that font family. This
+includes both image fonts and outline fonts.
+@end defop
+
+@defop operation os2-graphics-device capture-image x-left y-bottom x-right y-top
+This operation creates and returns an image that contains part of the
+client area of the graphics-device window. The portion of the client
+area that is selected is specified by the four coordinate arguments,
+which are given in the current virtual coordinates for the device.
+@xref{Images}, for more information about manipulating images.
+@end defop
+
+@defop operation os2-graphics-device draw-lines xv yv
+This operation draws multiple disjoint lines; it is like multiple calls
+to @code{graphics-draw-line} but much faster. The arguments @var{xv}
+and @var{yv} are vectors of coordinates; these vectors must be the same
+length, and the length must be a multiple of two. The contents of the
+vectors are alternating start/end pairs. For example, the following are
+equivalent:
+
+@example
+@group
+(graphics-draw-line device xs ys xe ye)
+(graphics-operation device 'draw-lines
+ (vector xs xe)
+ (vector ys ye))
+@end group
+@end example
+@end defop
--- /dev/null
+@c This file is part of the MIT/GNU Scheme Reference Manual.
+@c $Id: io.texi,v 1.1 2003/04/15 03:29:46 cph Exp $
+
+@c Copyright 1991,1992,1993,1994,1995 Massachusetts Institute of Technology
+@c Copyright 1996,1997,1999,2000,2001 Massachusetts Institute of Technology
+@c Copyright 2002,2003 Massachusetts Institute of Technology
+@c See file scheme.texinfo for copying conditions.
+
+@node Input/Output, Operating-System Interface, Environments, Top
+@chapter Input/Output
+
+@cindex input
+@cindex output
+@cindex port
+This chapter describes the procedures that are used for input and
+output (@acronym{I/O}). The chapter first describes @dfn{ports} and
+how they are manipulated, then describes the @acronym{I/O} operations.
+Finally, some low-level procedures are described that permit the
+implementation of custom ports and high-performance @acronym{I/O}.
+
+@menu
+* Ports::
+* File Ports::
+* String Ports::
+* Input Procedures::
+* Output Procedures::
+* Format::
+* Custom Output::
+* Prompting::
+* Port Primitives::
+* Parser Buffers::
+* Parser Language::
+* XML Parser::
+@end menu
+
+@node Ports, File Ports, Input/Output, Input/Output
+@section Ports
+
+@cindex port (defn)
+@findex console-i/o-port
+Scheme uses ports for @acronym{I/O}. A @dfn{port}, which can be
+treated like any other Scheme object, serves as a source or sink for
+data. A port must be open before it can be read from or written to.
+The standard @acronym{I/O} port, @code{console-i/o-port}, is opened
+automatically when you start Scheme. When you use a file for input or
+output, you need to explicitly open and close a port to the file (with
+procedures described in this chapter). Additional procedures let you
+open ports to strings.
+
+@cindex current input port (defn)
+@cindex input port, current (defn)
+@cindex port, current
+@findex read-char
+@findex read
+Many input procedures, such as @code{read-char} and @code{read}, read
+data from the current input port by default, or from a port that you
+specify. The current input port is initially @code{console-i/o-port},
+but Scheme provides procedures that let you change the current input
+port to be a file or string.
+
+@cindex current output port (defn)
+@cindex output port, current (defn)
+@findex write-char
+@findex display
+Similarly, many output procedures, such as @code{write-char} and
+@code{display}, write data to the current output port by default, or to
+a port that you specify. The current output port is initially
+@code{console-i/o-port}, but Scheme provides procedures that let you
+change the current output port to be a file or string.
+
+All ports read or write only @acronym{ISO-8859-1} characters.
+
+Every port is either an input port, an output port, or both. The
+following predicates distinguish all of the possible cases.
+
+@deffn procedure port? object
+@cindex type predicate, for port
+Returns @code{#t} if @var{object} is a port, otherwise returns
+@code{#f}.
+@end deffn
+
+@deffn procedure input-port? object
+Returns @code{#t} if @var{object} is an input port, otherwise returns
+@code{#f}. Any object satisfying this predicate also satisfies
+@code{port?}.
+@end deffn
+
+@deffn procedure output-port? object
+Returns @code{#t} if @var{object} is an output port, otherwise returns
+@code{#f}. Any object satisfying this predicate also satisfies
+@code{port?}.
+@end deffn
+
+@deffn procedure i/o-port? object
+Returns @code{#t} if @var{object} is both an input port and an output
+port, otherwise returns @code{#f}. Any object satisfying this predicate
+also satisfies @code{port?}, @code{input-port?}, and
+@code{output-port?}.
+@end deffn
+
+@deffn procedure guarantee-port object
+@deffnx procedure guarantee-input-port object
+@deffnx procedure guarantee-output-port object
+@deffnx procedure guarantee-i/o-port object
+These procedures check the type of @var{object}, signalling an error
+of type@* @code{condition-type:wrong-type-argument} if it is not a
+port, input port, output port, or @acronym{I/O} port, respectively.
+Otherwise they return @var{object}.
+@findex condition-type:wrong-type-argument
+@end deffn
+
+@cindex standard ports
+The next five procedures return the runtime system's @dfn{standard
+ports}. All of the standard ports are dynamically bound by the
+@acronym{REP} loop; this means that when a new @acronym{REP} loop is
+started, for example by an error, each of these ports is dynamically
+bound to the @acronym{I/O} port of the @acronym{REP} loop. When the
+@acronym{REP} loop exits, the ports revert to their original values.
+
+@deffn procedure current-input-port
+@findex console-input-port
+Returns the current input port. This is the default port used by many
+input procedures. Initially, @code{current-input-port} returns the
+value of @code{console-i/o-port}.
+@end deffn
+
+@deffn procedure current-output-port
+@findex console-output-port
+Returns the current output port. This is the default port used by many
+output procedures. Initially, @code{current-output-port} returns the
+value of @code{console-i/o-port}.
+@end deffn
+
+@deffn procedure notification-output-port
+Returns an output port suitable for generating ``notifications'', that
+is, messages to the user that supply interesting information about the
+execution of a program. For example, the @code{load} procedure writes
+messages to this port informing the user that a file is being loaded.
+Initially, @code{notification-output-port} returns the value of
+@code{console-i/o-port}.
+@end deffn
+
+@deffn procedure trace-output-port
+Returns an output port suitable for generating ``tracing'' information
+about a program's execution. The output generated by the @code{trace}
+procedure is sent to this port. Initially, @code{trace-output-port}
+returns the value of @code{console-i/o-port}.
+@end deffn
+
+@deffn procedure interaction-i/o-port
+Returns an @acronym{I/O} port suitable for querying or prompting the
+user. The standard prompting procedures use this port by default
+(@pxref{Prompting}). Initially, @code{interaction-i/o-port} returns
+the value of @code{console-i/o-port}.
+@end deffn
+
+@deffn procedure with-input-from-port input-port thunk
+@deffnx procedure with-output-to-port output-port thunk
+@deffnx procedure with-notification-output-port output-port thunk
+@deffnx procedure with-trace-output-port output-port thunk
+@deffnx procedure with-interaction-i/o-port i/o-port thunk
+@var{Thunk} must be a procedure of no arguments. Each of these
+procedures binds one of the standard ports to its first argument, calls
+@var{thunk} with no arguments, restores the port to its original value,
+and returns the result that was yielded by @var{thunk}. This temporary
+binding is performed the same way as dynamic binding of a variable,
+including the behavior in the presence of continuations (@pxref{Dynamic
+Binding}).
+
+@code{with-input-from-port} binds the current input port,
+@code{with-output-to-port} binds the current output port,
+@code{with-notification-output-port} binds the ``notification'' output
+port, @code{with-trace-output-port} binds the ``trace'' output port,
+and @code{with-interaction-i/o-port} binds the ``interaction''
+@acronym{I/O} port.
+@end deffn
+
+@deffn procedure set-current-input-port! input-port
+@deffnx procedure set-current-output-port! output-port
+@deffnx procedure set-notification-output-port! output-port
+@deffnx procedure set-trace-output-port! output-port
+@deffnx procedure set-interaction-i/o-port! i/o-port
+Each of these procedures alters the binding of one of the standard ports
+and returns an unspecified value. The binding that is modified
+corresponds to the name of the procedure.
+@end deffn
+
+@defvr variable console-i/o-port
+@cindex port, console
+@cindex console, port
+@cindex input port, console
+@cindex output port, console
+@code{console-i/o-port} is an @acronym{I/O} port that communicates
+with the ``console''. Under unix, the console is the controlling
+terminal of the Scheme process. Under Windows and OS/2, the console
+is the window that is created when Scheme starts up.
+
+This variable is rarely used; instead programs should use one of the
+standard ports defined above. This variable should not be modified.
+@end defvr
+
+@deffn procedure close-port port
+@cindex closing, of port
+Closes @var{port} and returns an unspecified value. If @var{port} is a
+file port, the file is closed.
+@end deffn
+
+@deffn procedure close-input-port port
+Closes @var{port} and returns an unspecified value. @var{Port} must
+be an input port or an @acronym{I/O} port; if it is an @acronym{I/O}
+port, then only the input side of the port is closed.
+@end deffn
+
+@deffn procedure close-output-port port
+Closes @var{port} and returns an unspecified value. @var{Port} must
+be an output port or an @acronym{I/O} port; if it is an @acronym{I/O}
+port, then only the output side of the port is closed.
+@end deffn
+
+@node File Ports, String Ports, Ports, Input/Output
+@section File Ports
+
+@cindex file, input and output ports
+@cindex port, file
+@cindex input port, file
+@cindex output port, file
+@cindex I/O, to files
+Before Scheme can access a file for reading or writing, it is necessary
+to open a port to the file. This section describes procedures used to
+open ports to files. Such ports are closed (like any other port) by
+@code{close-port}. File ports are automatically closed if and when they
+are reclaimed by the garbage collector.
+
+@findex merge-pathnames
+Before opening a file for input or output, by whatever method, the
+@var{filename} argument is converted to canonical form by calling the
+procedure @code{merge-pathnames} with @var{filename} as its sole
+argument. Thus, @var{filename} can be either a string or a pathname,
+and it is merged with the current pathname defaults to produce the
+pathname that is then opened.
+
+@cindex binary file ports
+@cindex newline translation
+Any file can be opened in one of two modes, @dfn{normal} or
+@dfn{binary}. Normal mode is for accessing text files, and binary mode
+is for accessing other files. Unix does not distinguish these modes,
+but Windows and OS/2 do: in normal mode, their file ports perform
+@dfn{newline translation}, mapping between the carriage-return/linefeed
+sequence that terminates text lines in files, and the @code{#\newline}
+that terminates lines in Scheme. In binary mode, such ports do not
+perform newline translation. Unless otherwise mentioned, the procedures
+in this section open files in normal mode.
+
+@deffn procedure open-input-file filename
+@cindex construction, of file input port
+Takes a filename referring to an existing file and returns an input port
+capable of delivering characters from the file. If the file cannot be
+opened, an error of type @code{condition-type:file-operation-error} is
+signalled.
+@findex condition-type:file-operation-error
+@end deffn
+
+@deffn procedure open-output-file filename [append?]
+@cindex construction, of file output port
+Takes a filename referring to an output file to be created and returns
+an output port capable of writing characters to a new file by that name.
+If the file cannot be opened, an error of type
+@code{condition-type:file-operation-error} is signalled.
+@findex condition-type:file-operation-error
+
+@cindex appending, to output file
+The optional argument @var{append?} is an MIT/GNU Scheme extension. If
+@var{append?} is given and not @code{#f}, the file is opened in
+@dfn{append} mode. In this mode, the contents of the file are not
+overwritten; instead any characters written to the file are appended to
+the end of the existing contents. If the file does not exist, append
+mode creates the file and writes to it in the normal way.
+@end deffn
+
+@deffn procedure open-i/o-file filename
+@cindex construction, of file input port
+Takes a filename referring to an existing file and returns an
+@acronym{I/O} port capable of both reading and writing the file. If
+the file cannot be opened, an error of type
+@code{condition-type:file-operation-error} is signalled.
+@findex condition-type:file-operation-error
+
+This procedure is often used to open special files. For example, under
+unix this procedure can be used to open terminal device files, @sc{pty}
+device files, and named pipes.
+@end deffn
+
+@deffn procedure open-binary-input-file filename
+@deffnx procedure open-binary-output-file filename [append?]
+@deffnx procedure open-binary-i/o-file filename
+These procedures open files in binary mode. In all other respects they
+are identical to @code{open-input-file}, @code{open-output-file}, and
+@code{open-i/o-file}, respectively.
+@end deffn
+
+@deffn procedure close-all-open-files
+@cindex closing, of file port
+This procedure closes all file ports that are open at the time that it
+is called, and returns an unspecified value.
+@end deffn
+
+@deffn procedure call-with-input-file filename procedure
+@deffnx procedure call-with-output-file filename procedure
+These procedures call @var{procedure} with one argument: the port
+obtained by opening the named file for input or output, respectively.
+If the file cannot be opened, an error of type
+@code{condition-type:file-operation-error} is signalled. If
+@var{procedure} returns, then the port is closed automatically and the
+value yielded by @var{procedure} is returned. If @var{procedure} does
+not return, then the port will not be closed automatically unless it is
+reclaimed by the garbage collector.@footnote{Because Scheme's escape
+procedures have unlimited extent, it is possible to escape from the
+current continuation but later to escape back in. If implementations
+were permitted to close the port on any escape from the current
+continuation, then it would be impossible to write portable code using
+both @code{call-with-current-continuation} and
+@code{call-with-input-file} or @code{call-with-output-file}.}
+@end deffn
+
+@deffn procedure call-with-binary-input-file filename procedure
+@deffnx procedure call-with-binary-output-file filename procedure
+These procedures open files in binary mode. In all other respects they
+are identical to @code{call-with-input-file} and
+@code{call-with-output-file}, respectively.
+@end deffn
+
+@deffn procedure with-input-from-file filename thunk
+@deffnx procedure with-output-to-file filename thunk
+@cindex current input port, rebinding
+@cindex current output port, rebinding
+@findex current-input-port
+@findex current-output-port
+@var{Thunk} must be a procedure of no arguments.
+The file is opened for input or output, an input or output port
+connected to it is made the default value returned by
+@code{current-input-port} or @code{current-output-port}, and the
+@var{thunk} is called with no arguments. When the @var{thunk} returns,
+the port is closed and the previous default is restored.
+@code{with-input-from-file} and @code{with-output-to-file} return the
+value yielded by @var{thunk}. If an escape procedure is used to escape
+from the continuation of these procedures, their behavior is
+implementation-dependent; in that situation MIT/GNU Scheme leaves the files
+open.
+@end deffn
+
+@deffn procedure with-input-from-binary-file filename thunk
+@deffnx procedure with-output-to-binary-file filename thunk
+These procedures open files in binary mode. In all other respects they
+are identical to @code{with-input-from-file} and
+@code{with-output-to-file}, respectively.
+@end deffn
+
+@node String Ports, Input Procedures, File Ports, Input/Output
+@section String Ports
+
+@cindex string, input and output ports
+@cindex port, string
+@cindex input port, string
+@cindex output port, string
+@cindex I/O, to strings
+This section describes the simplest kinds of ports: input ports that
+read their input from given strings, and output ports that accumulate
+their output and return it as a string. It also describes
+``truncating'' output ports, which can limit the length of the resulting
+string to a given value.
+
+@deffn procedure string->input-port string [start [end]]
+@cindex string, converting to input port
+@cindex construction, of string input port
+Returns a new string port that delivers characters from @var{string}.
+The optional arguments @var{start} and @var{end} may be used to specify
+that the string port delivers characters from a substring of
+@var{string}; if not given, @var{start} defaults to @code{0} and
+@var{end} defaults to @code{(string-length @var{string})}.
+@end deffn
+
+@deffn procedure with-input-from-string string thunk
+@cindex current input port, rebinding
+@var{Thunk} must be a procedure of no arguments.
+@code{with-input-from-string} creates a new input port that reads from
+@var{string}, makes that port the current input port, and calls
+@var{thunk}. When @var{thunk} returns, @code{with-input-from-string}
+restores the previous current input port and returns the result yielded
+by @var{thunk}.
+
+@example
+(with-input-from-string "(a b c) (d e f)" read) @result{} (a b c)
+@end example
+
+Note: this procedure is equivalent to:
+
+@example
+(with-input-from-port (string->input-port @var{string}) @var{thunk})
+@end example
+@end deffn
+
+@deffn procedure with-string-output-port procedure
+@var{Procedure} is called with one argument, an output port. The value
+yielded by @var{procedure} is ignored. When @var{procedure} returns,
+@code{with-string-output-port} returns the port's accumulated output as
+a newly allocated string.
+@end deffn
+
+@deffn procedure with-output-to-string thunk
+@cindex current output port, rebinding
+@cindex construction, of string output port
+@findex current-output-port
+@var{Thunk} must be a procedure of no arguments.
+@code{with-output-to-string} creates a new output port that accumulates
+output, makes that port the default value returned by
+@code{current-output-port}, and calls @var{thunk} with no arguments.
+When @var{thunk} returns, @code{with-output-to-string} restores the
+previous default and returns the accumulated output as a newly allocated
+string.
+
+@example
+@group
+(with-output-to-string
+ (lambda ()
+ (write 'abc))) @result{} "abc"
+@end group
+@end example
+
+Note: this procedure is equivalent to:
+
+@example
+@group
+(with-string-output-port
+ (lambda (port)
+ (with-output-to-port port @var{thunk})))
+@end group
+@end example
+@end deffn
+
+@deffn procedure with-output-to-truncated-string k thunk
+Similar to @code{with-output-to-string}, except that the output is
+limited to @var{k} characters. If @var{thunk} attempts to write more
+than @var{k} characters, it will be aborted by invoking an escape
+procedure that returns from @code{with-output-to-truncated-string}.
+
+The value of this procedure is a pair; the car of the pair is @code{#t}
+if @var{thunk} attempted to write more than @var{k} characters, and
+@code{#f} otherwise. The cdr of the pair is a newly allocated string
+containing the accumulated output.
+
+This procedure is helpful for displaying circular lists, as shown in this
+example:
+
+@example
+@group
+(define inf (list 'inf))
+(with-output-to-truncated-string 40
+ (lambda ()
+ (write inf))) @result{} (#f . "(inf)")
+(set-cdr! inf inf)
+(with-output-to-truncated-string 40
+ (lambda ()
+ (write inf)))
+ @result{} (#t . "(inf inf inf inf inf inf inf inf inf inf")
+@end group
+@end example
+@end deffn
+
+@deffn procedure write-to-string object [k]
+Writes @var{object} to a string output port, and returns the resulting
+newly allocated string. If @var{k} is supplied and not @code{#f}, this
+procedure is equivalent to
+
+@example
+@group
+(with-output-to-truncated-string @var{k}
+ (lambda ()
+ (write @var{object})))
+@end group
+@end example
+
+otherwise it is equivalent to
+
+@example
+@group
+(with-output-to-string
+ (lambda ()
+ (write @var{object})))
+@end group
+@end example
+@end deffn
+
+@node Input Procedures, Output Procedures, String Ports, Input/Output
+@section Input Procedures
+@cindex input operations
+
+This section describes the procedures that read input. Input procedures
+can read either from the current input port or from a given port.
+Remember that to read from a file, you must first open a port to the
+file.
+
+@cindex interactive input ports (defn)
+Input ports can be divided into two types, called @dfn{interactive} and
+@dfn{non-interactive}. Interactive input ports are ports that read
+input from a source that is time-dependent; for example, a port that
+reads input from a terminal or from another program. Non-interactive
+input ports read input from a time-independent source, such as an
+ordinary file or a character string.
+
+All optional arguments called @var{input-port}, if not supplied, default
+to the current input port.
+
+@deffn procedure read-char [input-port]
+@cindex character, input from port
+Returns the next character available from @var{input-port}, updating
+@var{input-port} to point to the following character. If no more
+characters are available, an end-of-file object is returned.
+
+In MIT/GNU Scheme, if @var{input-port} is an interactive input port and no
+characters are immediately available, @code{read-char} will hang waiting
+for input, even if the port is in non-blocking mode.
+@end deffn
+
+@deffn procedure peek-char [input-port]
+Returns the next character available from @var{input-port},
+@emph{without} updating @var{input-port} to point to the following
+character. If no more characters are available, an end-of-file object
+is returned.@footnote{The value returned by a call to @code{peek-char}
+is the same as the value that would have been returned by a call to
+@code{read-char} on the same port. The only difference is that the very
+next call to @code{read-char} or @code{peek-char} on that
+@var{input-port} will return the value returned by the preceding call to
+@code{peek-char}. In particular, a call to @code{peek-char} on an
+interactive port will hang waiting for input whenever a call to
+@code{read-char} would have hung.}
+
+In MIT/GNU Scheme, if @var{input-port} is an interactive input port and no
+characters are immediately available, @code{peek-char} will hang waiting
+for input, even if the port is in non-blocking mode.
+@end deffn
+
+@deffn procedure char-ready? [input-port]
+@findex read-char
+Returns @code{#t} if a character is ready on @var{input-port} and
+returns @code{#f} otherwise. If @code{char-ready?} returns @code{#t}
+then the next @code{read-char} operation on @var{input-port} is
+guaranteed not to hang. If @var{input-port} is a file port at end of
+file then @code{char-ready?} returns
+@code{#t}.@footnote{@code{char-ready?} exists to make it possible for a
+program to accept characters from interactive ports without getting
+stuck waiting for input. Any input editors associated with such ports
+must make sure that characters whose existence has been asserted by
+@code{char-ready?} cannot be rubbed out. If @code{char-ready?} were to
+return @code{#f} at end of file, a port at end of file would be
+indistinguishable from an interactive port that has no ready
+characters.}
+@end deffn
+
+@deffn procedure read [input-port]
+@cindex expression, input from port
+@cindex external representation, parsing
+@cindex parsing, of external representation
+Converts external representations of Scheme objects into the objects
+themselves. @code{read} returns the next object parsable from
+@var{input-port}, updating @var{input-port} to point to the first
+character past the end of the written representation of the object. If
+an end of file is encountered in the input before any characters are
+found that can begin an object, @code{read} returns an end-of-file
+object. The @var{input-port} remains open, and further attempts to read
+will also return an end-of-file object. If an end of file is
+encountered after the beginning of an object's written representation,
+but the written representation is incomplete and therefore not parsable,
+an error is signalled.
+@end deffn
+
+@deffn procedure eof-object? object
+@cindex type predicate, for EOF object
+@cindex EOF object, predicate for
+@cindex end of file object (see EOF object)
+@cindex file, end-of-file marker (see EOF object)
+Returns @code{#t} if @var{object} is an end-of-file object; otherwise
+returns @code{#f}.
+@end deffn
+
+@deffn procedure read-char-no-hang [input-port]
+If @var{input-port} can deliver a character without blocking, this
+procedure acts exactly like @code{read-char}, immediately returning that
+character. Otherwise, @code{#f} is returned, unless @var{input-port} is
+a file port at end of file, in which case an end-of-file object is
+returned. In no case will this procedure block waiting for input.
+@end deffn
+
+@deffn procedure read-string char-set [input-port]
+@cindex string, input from port
+Reads characters from @var{input-port} until it finds a terminating
+character that is a member of @var{char-set} (@pxref{Character Sets}) or
+encounters end of file. The port is updated to point to the terminating
+character, or to end of file if no terminating character was found.
+@code{read-string} returns the characters, up to but excluding the
+terminating character, as a newly allocated string.
+
+This procedure ignores the blocking mode of the port, blocking
+unconditionally until it sees either a delimiter or eof of file. If end
+of file is encountered before any characters are read, an end-of-file
+object is returned.
+
+@findex read-char
+On many input ports, this operation is significantly faster than the
+following equivalent code using @code{peek-char} and @code{read-char}:
+
+@example
+@group
+(define (read-string char-set input-port)
+ (let ((char (peek-char input-port)))
+ (if (eof-object? char)
+ char
+ (list->string
+ (let loop ((char char))
+ (if (or (eof-object? char)
+ (char-set-member? char-set char))
+ '()
+ (begin
+ (read-char input-port)
+ (cons char
+ (loop (peek-char input-port))))))))))
+@end group
+@end example
+@end deffn
+
+@deffn procedure read-line [input-port]
+@code{read-line} reads a single line of text from @var{input-port}, and
+returns that line as a newly allocated string. The @code{#\newline}
+terminating the line, if any, is discarded and does not appear in the
+returned string.
+
+This procedure ignores the blocking mode of the port, blocking
+unconditionally until it has read an entire line. If end of file is
+encountered before any characters are read, an end-of-file object is
+returned.
+@end deffn
+
+@deffn procedure read-string! string [input-port]
+@deffnx procedure read-substring! string start end [input-port]
+@code{read-string!} and @code{read-substring!} fill the specified region
+of @var{string} with characters read from @var{input-port} until the
+region is full or else there are no more characters available from the
+port. For @code{read-string!}, the region is all of @var{string}, and
+for @code{read-substring!}, the region is that part of @var{string}
+specified by @var{start} and @var{end}.
+
+The returned value is the number of characters filled into the region.
+However, there are several interesting cases to consider:
+
+@itemize @bullet
+@item
+If @code{read-string!} (@code{read-substring!}) is called when
+@var{input-port} is at ``end-of-file'', then the returned value is
+@code{0}. Note that ``end-of-file'' can mean a file port that is at the
+file's end, a string port that is at the string's end, or any other port
+that will never produce more characters.
+
+@item
+If @var{input-port} is an interactive port (e.g.@: a terminal), and one
+or more characters are immediately available, the region is filled using
+the available characters. The procedure then returns immediately,
+without waiting for further characters, even if the number of available
+characters is less than the size of the region. The returned value is
+the number of characters actually filled in.
+
+@item
+If @var{input-port} is an interactive port and no characters are
+immediately available, the result of the operation depends on the
+blocking mode of the port. If the port is in non-blocking mode,
+@code{read-string!} (@code{read-substring!}) immediately returns the
+value @code{#f}. Otherwise, the operation blocks until a character is
+available. As soon as at least one character is available, the region
+is filled using the available characters. The procedure then returns
+immediately, without waiting for further characters, even if the number
+of available characters is less than the size of the region. The
+returned value is the number of characters actually filled in.
+@end itemize
+
+The importance of @code{read-string!} and @code{read-substring!} are
+that they are both flexible and extremely fast, especially for large
+amounts of data.
+@end deffn
+
+The following variables may be dynamically bound to change the behavior
+of the @code{read} procedure.
+
+@defvr variable *parser-radix*
+This variable defines the radix used by the reader when it parses
+numbers. This is similar to passing a radix argument to
+@code{string->number}. The value of this variable must be one of
+@code{2}, @code{8}, @code{10}, or @code{16}; any other value is ignored,
+and the reader uses radix @code{10}.
+
+Note that much of the number syntax is invalid for radixes other than
+@code{10}. The reader detects cases where such invalid syntax is used
+and signals an error. However, problems can still occur when
+@code{*parser-radix*} is set to @code{16}, because syntax that normally
+denotes symbols can now denote numbers (e.g.@: @code{abc}). Because of
+this, it is usually undesirable to set this variable to anything other
+than the default.
+
+The default value of this variable is @code{10}.
+@end defvr
+
+@defvr variable *parser-canonicalize-symbols?*
+This variable controls how the parser handles case-sensitivity of
+symbols. If it is bound to its default value of @code{#t}, symbols read
+by the parser are converted to lower case before being interned.
+Otherwise, symbols are interned without case conversion.
+
+In general, it is a bad idea to use this feature, as it doesn't really
+make Scheme case-sensitive, and therefore can break features of the
+Scheme runtime that depend on case-insensitive symbols.
+@end defvr
+
+@node Output Procedures, Format, Input Procedures, Input/Output
+@section Output Procedures
+@cindex output procedures
+
+@cindex buffering, of output
+@cindex flushing, of buffered output
+Output ports may or may not support @dfn{buffering} of output, in which
+output characters are collected together in a buffer and then sent to
+the output device all at once. (Most of the output ports implemented by
+the runtime system support buffering.) Sending all of the characters in
+the buffer to the output device is called @dfn{flushing} the buffer. In
+general, output procedures do not flush the buffer of an output port
+unless the buffer is full.
+
+@cindex discretionary flushing, of buffered output
+@findex discretionary-flush-output
+However, the standard output procedures described in this section
+perform what is called @dfn{discretionary} flushing of the buffer.
+Discretionary output flushing works as follows. After a procedure
+performs its output (writing characters to the output buffer), it checks
+to see if the port implements an operation called
+@code{discretionary-flush-output}. If so, then that operation is
+invoked to flush the buffer. At present, only the console port defines
+@code{discretionary-flush-output}; this is used to guarantee that output
+to the console appears immediately after it is written, without
+requiring calls to @code{flush-output}.
+
+All optional arguments called @var{output-port}, if not supplied,
+default to the current output port.
+
+@deffn procedure write-char char [output-port]
+@cindex character, output to port
+Writes @var{char} (the character itself, not a written representation of
+the character) to @var{output-port}, performs discretionary output
+flushing, and returns an unspecified value.
+@end deffn
+
+@deffn procedure write-string string [output-port]
+@cindex string, output to port
+Writes @var{string} to @var{output-port}, performs discretionary output
+flushing, and returns an unspecified value. This is equivalent to
+writing the contents of @var{string}, one character at a time using
+@code{write-char}, except that it is usually much faster.
+@end deffn
+
+@deffn procedure write-substring string start end [output-port]
+@cindex string, output to port
+Writes the substring defined by @var{string}, @var{start}, and @var{end}
+to @var{output-port}, performs discretionary output flushing, and
+returns an unspecified value. This is equivalent to writing the
+contents of the substring, one character at a time using
+@code{write-char}, except that it is usually much faster.
+@end deffn
+
+@deffn procedure write object [output-port]
+@cindex expression, output to port
+Writes a written representation of @var{object} to @var{output-port},
+and returns an unspecified value. If @var{object} has a standard
+external representation, then the written representation generated by
+@code{write} shall be parsable by @code{read} into an equivalent object.
+Thus strings that appear in the written representation are enclosed in
+doublequotes, and within those strings backslash and doublequote are
+escaped by backslashes. @code{write} performs discretionary output
+flushing and returns an unspecified value.
+@end deffn
+
+@deffn procedure display object [output-port]
+@cindex external representation, generating
+@cindex generating, external representation
+Writes a representation of @var{object} to @var{output-port}. Strings
+appear in the written representation as if written by
+@code{write-string} instead of by @code{write}. Character objects
+appear in the representation as if written by @code{write-char} instead
+of by @code{write}. @code{display} performs discretionary output
+flushing and returns an unspecified value.@footnote{@code{write} is
+intended for producing machine-readable output and @code{display} is for
+producing human-readable output.}
+@end deffn
+
+@deffn procedure newline [output-port]
+@cindex newline character, output to port
+Writes an end-of-line to @var{output-port}, performs discretionary
+output flushing, and returns an unspecified value. Equivalent to
+@code{(write-char #\newline @var{output-port})}.
+@end deffn
+
+@deffn procedure fresh-line [output-port]
+Most output ports are able to tell whether or not they are at the
+beginning of a line of output. If @var{output-port} is such a port,
+this procedure writes an end-of-line to the port only if the port is not
+already at the beginning of a line. If @var{output-port} is not such a
+port, this procedure is identical to @code{newline}. In either case,
+@code{fresh-line} performs discretionary output flushing and returns an
+unspecified value.
+@end deffn
+
+@deffn procedure write-line object [output-port]
+Like @code{write}, except that it writes an end-of-line to
+@var{output-port} after writing @var{object}'s representation. This
+procedure performs discretionary output flushing and returns an
+unspecified value.
+@end deffn
+
+@deffn procedure flush-output [output-port]
+If @var{output-port} is buffered, this causes the contents of its buffer
+to be written to the output device. Otherwise it has no effect.
+Returns an unspecified value.
+@end deffn
+
+@deffn procedure beep [output-port]
+@cindex console, ringing the bell
+@cindex ringing the console bell
+@cindex bell, ringing on console
+Performs a ``beep'' operation on @var{output-port}, performs
+discretionary output flushing, and returns an unspecified value. On the
+console port, this usually causes the console bell to beep, but more
+sophisticated interactive ports may take other actions, such as flashing
+the screen. On most output ports, e.g.@: file and string output ports,
+this does nothing.
+@end deffn
+
+@deffn procedure clear [output-port]
+@cindex console, clearing
+@cindex display, clearing
+@cindex screen, clearing
+@cindex terminal screen, clearing
+@cindex clearing the console screen
+``Clears the screen'' of @var{output-port}, performs discretionary
+output flushing, and returns an unspecified value. On a terminal or
+window, this has a well-defined effect. On other output ports, e.g.@:
+file and string output ports, this does nothing.
+@end deffn
+
+@deffn procedure pp object [output-port [as-code?]]
+@cindex pretty printer
+@code{pp} prints @var{object} in a visually appealing and structurally
+revealing manner on @var{output-port}. If object is a procedure,
+@code{pp} attempts to print the source text. If the optional argument
+@var{as-code?} is true, @code{pp} prints lists as Scheme code, providing
+appropriate indentation; by default this argument is false. @code{pp}
+performs discretionary output flushing and returns an unspecified value.
+@end deffn
+
+The following variables may be dynamically bound to change the behavior
+of the @code{write} and @code{display} procedures.
+
+@defvr variable *unparser-radix*
+This variable specifies the default radix used to print numbers. Its
+value must be one of the exact integers @code{2}, @code{8}, @code{10},
+or @code{16}; the default is @code{10}. If @code{*unparser-radix*} is
+not @code{10}, numbers are prefixed to indicate their radix.
+@end defvr
+
+@defvr variable *unparser-list-breadth-limit*
+This variable specifies a limit on the length of the printed
+representation of a list or vector; for example, if the limit is
+@code{4}, only the first four elements of any list are printed, followed
+by ellipses to indicate any additional elements. The value of this
+variable must be an exact non-negative integer, or @code{#f} meaning no
+limit; the default is @code{#f}.
+
+@example
+@group
+(fluid-let ((*unparser-list-breadth-limit* 4))
+ (write-to-string '(a b c d)))
+ @result{} "(a b c d)"
+(fluid-let ((*unparser-list-breadth-limit* 4))
+ (write-to-string '(a b c d e)))
+ @result{} "(a b c d ...)"
+@end group
+@end example
+@end defvr
+
+@defvr variable *unparser-list-depth-limit*
+This variable specifies a limit on the nesting of lists and vectors in
+the printed representation. If lists (or vectors) are more deeply
+nested than the limit, the part of the representation that exceeds the
+limit is replaced by ellipses. The value of this variable must be an
+exact non-negative integer, or @code{#f} meaning no limit; the default
+is @code{#f}.
+
+@example
+@group
+(fluid-let ((*unparser-list-depth-limit* 4))
+ (write-to-string '((((a))) b c d)))
+ @result{} "((((a))) b c d)"
+(fluid-let ((*unparser-list-depth-limit* 4))
+ (write-to-string '(((((a)))) b c d)))
+ @result{} "((((...))) b c d)"
+@end group
+@end example
+@end defvr
+
+@defvr variable *unparser-string-length-limit*
+This variable specifies a limit on the length of the printed
+representation of strings. If a string's length exceeds this limit, the
+part of the printed representation for the characters exceeding the
+limit is replaced by ellipses. The value of this variable must be an
+exact non-negative integer, or @code{#f} meaning no limit; the default
+is @code{#f}.
+
+@example
+@group
+(fluid-let ((*unparser-string-length-limit* 4))
+ (write-to-string "abcd"))
+ @result{} "\"abcd\""
+(fluid-let ((*unparser-string-length-limit* 4))
+ (write-to-string "abcde"))
+ @result{} "\"abcd...\""
+@end group
+@end example
+@end defvr
+
+@defvr variable *unparse-with-maximum-readability?*
+This variable, which takes a boolean value, tells the printer to use a
+special printed representation for objects that normally print in a form
+that cannot be recognized by @code{read}. These objects are printed
+using the representation @code{#@@@var{n}}, where @var{n} is the result
+of calling @code{hash} on the object to be printed. The reader
+recognizes this syntax, calling @code{unhash} on @var{n} to get back the
+original object. Note that this printed representation can only be
+recognized by the Scheme program in which it was generated, because
+these hash numbers are different for each invocation of Scheme.
+@end defvr
+
+@node Format, Custom Output, Output Procedures, Input/Output
+@section Format
+
+@comment **** begin CLTL ****
+
+The procedure @code{format} is very useful for producing nicely
+formatted text, producing good-looking messages, and so on. MIT/GNU
+Scheme's implementation of @code{format} is similar to that of Common
+Lisp, except that Common Lisp defines many more
+directives.@footnote{This description of @code{format} is adapted from
+@cite{Common Lisp, The Language}, second edition, section 22.3.3.}
+
+@cindex run-time-loadable option
+@cindex option, run-time-loadable
+@code{format} is a run-time-loadable option. To use it, execute
+
+@example
+(load-option 'format)
+@end example
+@findex load-option
+
+@noindent
+once before calling it.
+
+@deffn procedure format destination control-string argument @dots{}
+@findex write-string
+@cindex format directive (defn)
+@cindex directive, format (defn)
+Writes the characters of @var{control-string} to @var{destination},
+except that a tilde (@code{~}) introduces a @dfn{format directive}. The
+character after the tilde, possibly preceded by prefix parameters and
+modifiers, specifies what kind of formatting is desired. Most
+directives use one or more @var{argument}s to create their output; the
+typical directive puts the next @var{argument} into the output,
+formatted in some special way. It is an error if no argument remains
+for a directive requiring an argument, but it is not an error if one or
+more arguments remain unprocessed by a directive.
+
+The output is sent to @var{destination}. If @var{destination} is
+@code{#f}, a string is created that contains the output; this string is
+returned as the value of the call to @code{format}. In all other cases
+@code{format} returns an unspecified value. If @var{destination} is
+@code{#t}, the output is sent to the current output port. Otherwise,
+@var{destination} must be an output port, and the output is sent there.
+
+This procedure performs discretionary output flushing (@pxref{Output
+Procedures}).
+
+A @code{format} directive consists of a tilde (@code{~}), optional
+prefix parameters separated by commas, optional colon (@code{:}) and
+at-sign (@code{@@}) modifiers, and a single character indicating what
+kind of directive this is. The alphabetic case of the directive
+character is ignored. The prefix parameters are generally integers,
+notated as optionally signed decimal numbers. If both the colon and
+at-sign modifiers are given, they may appear in either order.
+
+@cindex V as format parameter
+@cindex # as format parameter
+In place of a prefix parameter to a directive, you can put the letter
+@samp{V} (or @samp{v}), which takes an @var{argument} for use as a
+parameter to the directive. Normally this should be an exact integer.
+This feature allows variable-width fields and the like. You can also
+use the character @samp{#} in place of a parameter; it represents the
+number of arguments remaining to be processed.
+
+It is an error to give a format directive more parameters than it is
+described here as accepting. It is also an error to give colon or
+at-sign modifiers to a directive in a combination not specifically
+described here as being meaningful.
+
+@table @code
+@item ~A
+The next @var{argument}, which may be any object, is printed as if by
+@code{display}. @code{~@var{mincol}A} inserts spaces on the right, if
+necessary, to make the width at least @var{mincol} columns. The
+@code{@@} modifier causes the spaces to be inserted on the left rather
+than the right.
+
+@item ~S
+The next @var{argument}, which may be any object, is printed as if by
+@code{write}. @code{~@var{mincol}S} inserts spaces on the right, if
+necessary, to make the width at least @var{mincol} columns. The
+@code{@@} modifier causes the spaces to be inserted on the left rather
+than the right.
+
+@item ~%
+This outputs a @code{#\newline} character. @code{~@var{n}%} outputs
+@var{n} newlines. No @var{argument} is used. Simply putting a newline
+in @var{control-string} would work, but @code{~%} is often used because
+it makes the control string look nicer in the middle of a program.
+
+@item ~~
+This outputs a tilde. @code{~@var{n}~} outputs @var{n} tildes.
+
+@item ~@var{newline}
+Tilde immediately followed by a newline ignores the newline and any
+following non-newline whitespace characters. With an @code{@@}, the
+newline is left in place, but any following whitespace is ignored. This
+directive is typically used when @var{control-string} is too long to fit
+nicely into one line of the program:
+
+@example
+@group
+(define (type-clash-error procedure arg spec actual)
+ (format
+ #t
+ "~%Procedure ~S~%requires its %A argument ~
+ to be of type ~S,~%but it was called with ~
+ an argument of type ~S.~%"
+ procedure arg spec actual))
+@end group
+@end example
+
+@example
+@group
+(type-clash-error 'vector-ref
+ "first"
+ 'integer
+ 'vector)
+
+@r{prints}
+
+Procedure vector-ref
+requires its first argument to be of type integer,
+but it was called with an argument of type vector.
+@end group
+@end example
+
+@noindent
+Note that in this example newlines appear in the output only as
+specified by the @code{~%} directives; the actual newline characters in
+the control string are suppressed because each is preceded by a tilde.
+@end table
+@end deffn
+
+@comment **** end CLTL ****
+
+@node Custom Output, Prompting, Format, Input/Output
+@section Custom Output
+
+MIT/GNU Scheme provides hooks for specifying that certain kinds of objects
+have special written representations. There are no restrictions on the
+written representations, but only a few kinds of objects may have custom
+representation specified for them, specifically: records
+(@pxref{Records}), vectors that have special tags in their zero-th
+elements (@pxref{Vectors}), and pairs that have special tags in their
+car fields (@pxref{Lists}). There is a different procedure for
+specifying the written representation of each of these types.
+
+@deffn procedure set-record-type-unparser-method! record-type unparser-method
+Changes the unparser method of the type represented by @var{record-type}
+to be @var{unparser-method}, and returns an unspecified value.
+Subsequently, when the unparser encounters a record of this type, it
+will invoke @var{unparser-method} to generate the written
+representation.
+@end deffn
+
+@deffn procedure unparser/set-tagged-vector-method! tag unparser-method
+Changes the unparser method of the vector type represented by @var{tag}
+to be @var{unparser-method}, and returns an unspecified value.
+Subsequently, when the unparser encounters a vector with @var{tag} as
+its zero-th element, it will invoke @var{unparser-method} to generate
+the written representation.
+@end deffn
+
+@deffn procedure unparser/set-tagged-pair-method! tag unparser-method
+Changes the unparser method of the pair type represented by @var{tag} to
+be @var{unparser-method}, and returns an unspecified value.
+Subsequently, when the unparser encounters a pair with @var{tag} in its
+car field, it will invoke @var{unparser-method} to generate the written
+representation.
+@end deffn
+
+@cindex unparser method (defn)
+@cindex method, unparser (defn)
+An @dfn{unparser method} is a procedure that is invoked with two
+arguments: an unparser state and an object. An unparser method
+generates a written representation for the object, writing it to the
+output port specified by the unparser state. The value yielded by an
+unparser method is ignored. Note that an unparser state is not an
+output port, rather it is an object that contains an output port as one
+of its components. Application programs generally do not construct or
+examine unparser state objects, but just pass them along.
+
+There are two ways to create an unparser method (which is then
+registered by one of the above procedures). The first, and easiest, is
+to use @code{standard-unparser-method}. The second is to define your
+own method using the procedure @code{with-current-unparser-state}. We
+encourage the use of the first method, as it results in a more uniform
+appearance for objects. Many predefined datatypes, for example
+procedures and environments, already have this appearance.
+
+@deffn procedure standard-unparser-method name procedure
+Returns a standard unparser method. @var{Name} may be any object, and
+is used as the name of the type with which the unparser method is
+associated; @var{name} is usually a symbol. @var{Procedure} must be
+@code{#f} or a procedure of two arguments.
+
+@cindex #[ as external representation
+If @var{procedure} is @code{#f}, the returned method generates an
+external representation of this form:
+
+@example
+#[@var{name} @var{hash}]
+@end example
+
+@noindent
+@findex write
+@findex write-string
+@findex hash
+Here @var{name} is the external representation of the argument
+@var{name}, as generated by @code{write},@footnote{Except that if the
+argument @var{name} is a string, its external representation is
+generated by @code{write-string}.} and @var{hash} is the external
+representation of an exact non-negative integer unique to the object
+being printed (specifically, it is the result of calling @code{hash} on
+the object). Subsequently, the expression
+
+@example
+#@@@var{hash}
+@end example
+
+@noindent
+is notation for the object.
+
+If @var{procedure} is supplied, the returned method generates a slightly
+different external representation:
+
+@example
+#[@var{name} @var{hash} @var{output}]
+@end example
+
+@noindent
+Here @var{name} and @var{hash} are as above, and @var{output} is the
+output generated by @var{procedure}. The representation is constructed
+in three stages:
+
+@enumerate
+@item
+The first part of the format (up to @var{output}) is written to the
+output port specified by the unparser state. This is @code{"#["},
+@var{name}, @code{" "}, and @var{hash}.
+
+@item
+@var{Procedure} is invoked on two arguments: the object and an output
+port.
+
+@item
+The closing bracket is written to the output port.
+@end enumerate
+@end deffn
+
+The following procedure is useful for writing more general kinds of
+unparser methods.
+
+@deffn procedure with-current-unparser-state unparser-state procedure
+This procedure calls @var{procedure} with one argument, the output port
+from @var{unparser-state}. Additionally, it arranges for the remaining
+components of @var{unparser-state} to be given to the printer when they
+are needed. The @var{procedure} generates some output by writing to the
+output port using the usual output operations, and the value yielded by
+@var{procedure} is returned from @code{with-current-unparser-state}.
+
+The port passed to @var{procedure} should only be used within the
+dynamic extent of @var{procedure}.
+@end deffn
+
+@node Prompting, Port Primitives, Custom Output, Input/Output
+@section Prompting
+@cindex prompting
+
+This section describes procedures that prompt the user for input. Why
+should the programmer use these procedures when it is possible to do
+prompting using ordinary input and output procedures? One reason is
+that the prompting procedures are more succinct. However, a second and
+better reason is that the prompting procedures can be separately
+customized for each user interface, providing more natural interaction.
+The interfaces for Edwin and for GNU Emacs have already been customized
+in this fashion; because Edwin and Emacs are very similar editors, their
+customizations provide very similar behavior.
+
+@findex interaction-i/o-port
+Each of these procedure accepts an optional argument called
+@var{port}, which if given must be an @acronym{I/O} port. If not
+given, this port defaults to the value of
+@code{(interaction-i/o-port)}; this is initially the console
+@acronym{I/O} port.
+
+@deffn procedure prompt-for-command-expression prompt [port]
+Prompts the user for an expression that is to be executed as a command.
+This is the procedure called by the @acronym{REP} loop to read the
+user's expressions.
+
+If @var{prompt} is a string, it is used verbatim as the prompt string.
+Otherwise, it must be a pair whose car is @code{standard} and whose cdr
+is a string; in this case the prompt string is formed by prepending to
+the string the current @acronym{REP} loop ``level number'' and a space.
+Also, a space is appended to the string, unless it already ends in a
+space or is an empty string.
+
+The default behavior of this procedure is to print a fresh line, a
+newline, and the prompt string; flush the output buffer; then read an
+object and return it.
+
+Under Edwin and Emacs, before the object is read, the interaction buffer
+is put into a mode that allows expressions to be edited and submitted
+for input using specific editor commands. The first expression that is
+submitted is returned as the value of this procedure.
+@end deffn
+
+@deffn procedure prompt-for-command-char prompt [port]
+@findex char-graphic?
+Prompts the user for a single character that is to be executed as a
+command; the returned character is guaranteed to satisfy
+@code{char-graphic?}. If at all possible, the character is read from
+the user interface using a mode that reads the character as a single
+keystroke; in other words, it should not be necessary for the user to
+follow the character with a carriage return or something similar.
+
+@findex debug
+@findex where
+This is the procedure called by @code{debug} and @code{where} to read
+the user's commands.
+
+If @var{prompt} is a string, it is used verbatim as the prompt string.
+Otherwise, it must be a pair whose car is @code{standard} and whose cdr
+is a string; in this case the prompt string is formed by prepending to
+the string the current @acronym{REP} loop ``level number'' and a space.
+Also, a space is appended to the string, unless it already ends in a
+space or is an empty string.
+
+The default behavior of this procedure is to print a fresh line, a
+newline, and the prompt string; flush the output buffer; read a
+character in raw mode, echo that character, and return it.
+
+Under Edwin and Emacs, instead of reading a character, the interaction
+buffer is put into a mode in which graphic characters submit themselves
+as input. After this mode change, the first such character submitted is
+returned as the value of this procedure.
+@end deffn
+
+@deffn procedure prompt-for-expression prompt [port]
+Prompts the user for an expression.
+
+The prompt string is formed by appending a colon and a space to
+@var{prompt}, unless @var{prompt} already ends in a space or is the null
+string.
+
+The default behavior of this procedure is to print a fresh line, a
+newline, and the prompt string; flush the output buffer; then read an
+object and return it.
+
+Under Edwin and Emacs, the expression is read in the minibuffer.
+@end deffn
+
+@deffn procedure prompt-for-evaluated-expression prompt [environment [port]]
+Prompts the user for an evaluated expression. Calls
+@code{prompt-for-expression} to read an expression, then evaluates the
+expression using @var{environment}; if @var{environment} is not given,
+the @acronym{REP} loop environment is used.
+@end deffn
+
+@deffn procedure prompt-for-confirmation prompt [port]
+Prompts the user for confirmation. The result yielded by this procedure
+is a boolean.
+
+The prompt string is formed by appending the string @code{" (y or n)? "}
+to @var{prompt}, unless @var{prompt} already ends in a space or is the
+null string.
+
+The default behavior of this procedure is to print a fresh line, a
+newline, and the prompt string; flush the output buffer; then read a
+character in raw mode. If the character is @code{#\y}, @code{#\Y}, or
+@code{#\space}, the procedure returns @code{#t}; If the character is
+@code{#\n}, @code{#\N}, or @code{#\rubout}, the procedure returns
+@code{#f}. Otherwise the prompt is repeated.
+
+Under Edwin or Emacs, the confirmation is read in the minibuffer.
+@end deffn
+
+@node Port Primitives, Parser Buffers, Prompting, Input/Output
+@section Port Primitives
+@cindex port primitives
+
+This section describes the low-level operations that can be used to
+build and manipulate @acronym{I/O} ports.
+
+The purpose of these operations is twofold: to allow programmers to
+construct new kinds of @acronym{I/O} ports, and to provide faster
+@acronym{I/O} operations than those supplied by the standard high
+level procedures. The latter is useful because the standard
+@acronym{I/O} operations provide defaulting and error checking, and
+sometimes other features, which are often unnecessary. This interface
+provides the means to bypass such features, thus improving
+performance.
+
+The abstract model of an @acronym{I/O} port, as implemented here, is a
+combination of a set of named operations and a state. The state is an
+arbitrary object, the meaning of which is determined by the
+operations. The operations are defined by a mapping from names to
+procedures.
+
+@cindex port type
+The set of named operations is represented by an object called a
+@dfn{port type}. A port type is constructed from a set of named
+operations, and is subsequently used to construct a port. The port type
+completely specifies the behavior of the port. Port types also support
+a simple form of inheritance, allowing you to create new ports that are
+similar to existing ports.
+
+The port operations are divided into two classes:
+
+@table @asis
+@item Standard operations
+There is a specific set of standard operations for input ports, and a
+different set for output ports. Applications can assume that the
+standard input operations are implemented for all input ports, and
+likewise the standard output operations are implemented for all output
+ports.
+@cindex standard operations, on port
+
+@item Custom operations
+Some ports support additional operations. For example, ports that
+implement output to terminals (or windows) may define an operation named
+@code{y-size} that returns the height of the terminal in characters.
+Because only some ports will implement these operations, programs that
+use custom operations must test each port for their existence, and be
+prepared to deal with ports that do not implement them.
+@cindex custom operations, on port
+@findex y-size
+@end table
+
+@menu
+* Port Types::
+* Constructors and Accessors for Ports::
+* Input Port Operations::
+* Output Port Operations::
+* Blocking Mode::
+* Terminal Mode::
+@end menu
+
+@node Port Types, Constructors and Accessors for Ports, Port Primitives, Port Primitives
+@subsection Port Types
+
+The procedures in this section provide means for constructing port types
+with standard and custom operations, and accessing their operations.
+
+@deffn procedure make-port-type operations port-type
+@cindex construction, of port type
+Creates and returns a new port type.
+@var{Operations} must be a list; each element is a list of two elements,
+the name of the operation (a symbol) and the procedure that implements
+it. @var{Port-type} is either @code{#f} or a port type; if it is a port
+type, any operations implemented by @var{port-type} but not specified in
+@var{operations} will be implemented by the resulting port type.
+
+@var{Operations} need not contain definitions for all of the standard
+operations; the procedure will provide defaults for any standard
+operations that are not defined. At a minimum, the following operations
+must be defined: for input ports, @code{read-char} and @code{peek-char};
+for output ports, either @code{write-char} or @code{write-substring}.
+@acronym{I/O} ports must supply the minimum operations for both input and
+output.
+
+If an operation in @var{operations} is defined to be @code{#f}, then the
+corresponding operation in @var{port-type} is @emph{not} inherited.
+
+If @code{read-char} is defined in @var{operations}, then any standard
+input operations defined in @var{port-type} are ignored. Likewise, if
+@code{write-char} or @code{write-substring} is defined in
+@var{operations}, then any standard output operations defined in
+@var{port-type} are ignored. This feature allows overriding the
+standard operations without having to enumerate them.
+@end deffn
+
+@deffn procedure port-type? object
+@deffnx procedure input-port-type? object
+@deffnx procedure output-port-type? object
+@deffnx procedure i/o-port-type? object
+These predicates return @code{#t} if @var{object} is a port type,
+input-port type, output-port type, or @acronym{I/O}-port type,
+respectively. Otherwise, they return @code{#f}.
+@end deffn
+
+@deffn procedure port-type/operations port-type
+Returns a newly allocated list containing all of the operations
+implemented by @var{port-type}. Each element of the list is a list of
+two elements --- the name and its associated operation.
+@end deffn
+
+@deffn procedure port-type/operation-names port-type
+Returns a newly allocated list whose elements are the names of the
+operations implemented by @var{port-type}.
+@end deffn
+
+@deffn procedure port-type/operation port-type symbol
+Returns the operation named @var{symbol} in @var{port-type}. If
+@var{port-type} has no such operation, returns @code{#f}.
+@end deffn
+
+@node Constructors and Accessors for Ports, Input Port Operations, Port Types, Port Primitives
+@subsection Constructors and Accessors for Ports
+
+The procedures in this section provide means for constructing ports,
+accessing the type of a port, and manipulating the state of a port.
+
+@deffn procedure make-port port-type state
+Returns a new port with type @var{port-type} and the given
+@var{state}. The port will be an input, output, or @acronym{I/O} port
+according to @var{port-type}.
+@end deffn
+
+@deffn procedure port/type port
+Returns the port type of @var{port}.
+@end deffn
+
+@deffn procedure port/state port
+Returns the state component of @var{port}.
+@end deffn
+
+@deffn procedure set-port/state! port object
+Changes the state component of @var{port} to be @var{object}.
+Returns an unspecified value.
+@end deffn
+
+@deffn procedure port/operation port symbol
+Equivalent to
+
+@example
+(port-type/operation (port/type @var{port}) @var{symbol})
+@end example
+@end deffn
+
+@deffn procedure port/operation-names port
+Equivalent to
+
+@example
+(port-type/operation-names (port/type @var{port}))
+@end example
+@end deffn
+
+@deffn procedure make-eof-object input-port
+@cindex EOF object, construction
+@cindex construction, of EOF object
+@findex eof-object?
+Returns an object that satisfies the predicate @code{eof-object?}. This
+is sometimes useful when building input ports.
+@end deffn
+
+@node Input Port Operations, Output Port Operations, Constructors and Accessors for Ports, Port Primitives
+@subsection Input Port Operations
+@cindex input port operations
+
+This section describes the standard operations on input ports.
+Following that, some useful custom operations are described.
+
+@defop operation {input port} read-char input-port
+@cindex character, input from port
+Removes the next character available from @var{input-port} and returns
+it. If @var{input-port} has no more characters and will never have any
+(e.g.@: at the end of an input file), this operation returns an
+end-of-file object. If @var{input-port} has no more characters but will
+eventually have some more (e.g.@: a terminal where nothing has been
+typed recently), and it is in non-blocking mode, @code{#f} is returned;
+otherwise the operation hangs until input is available.
+@end defop
+
+@defop operation {input port} peek-char input-port
+Reads the next character available from @var{input-port} and returns it.
+The character is @emph{not} removed from @var{input-port}, and a
+subsequent attempt to read from the port will get that character again.
+In other respects this operation behaves like @code{read-char}.
+@end defop
+
+@defop operation {input port} discard-char input-port
+Discards the next character available from @var{input-port} and returns
+an unspecified value. In other respects this operation behaves like
+@code{read-char}.
+@end defop
+
+@defop operation {input port} char-ready? input-port k
+@code{char-ready?} returns @code{#t} if at least one character is
+available to be read from @var{input-port}. If no characters are
+available, the operation waits up to @var{k} milliseconds before
+returning @code{#f}, returning immediately if any characters become
+available while it is waiting.
+@end defop
+
+@defop operation {input port} read-string input-port char-set
+@defopx operation {input port} discard-chars input-port char-set
+@cindex string, input from port
+These operations are like @code{read-char} and @code{discard-char},
+except that they read or discard multiple characters at once. This can
+have a marked performance improvement on buffered input ports. All
+characters up to, but excluding, the first character in @var{char-set}
+(or end of file) are read from @var{input-port}. @code{read-string}
+returns these characters as a newly allocated string, while
+@code{discard-chars} discards them and returns an unspecified value.
+These operations hang until sufficient input is available, even if
+@var{input-port} is in non-blocking mode. If end of file is encountered
+before any input characters, @code{read-string} returns an end-of-file
+object.
+@end defop
+
+@defop operation {input port} read-substring input-port string start end
+Reads characters from @var{input-port} into the substring defined by
+@var{string}, @var{start}, and @var{end} until either the substring has
+been filled or there are no more characters available. Returns the
+number of characters written to the substring.
+
+If @var{input-port} is an interactive port, and at least one character
+is immediately available, the available characters are written to the
+substring and this operation returns immediately. If no characters are
+available, and @var{input-port} is in blocking mode, the operation
+blocks until at least one character is available. Otherwise, the
+operation returns @code{#f} immediately.
+
+This is an extremely fast way to read characters from a port.
+@end defop
+
+@deffn procedure input-port/read-char input-port
+@deffnx procedure input-port/peek-char input-port
+@deffnx procedure input-port/discard-char input-port
+@deffnx procedure input-port/char-ready? input-port k
+@deffnx procedure input-port/read-string input-port char-set
+@deffnx procedure input-port/discard-chars input-port char-set
+@deffnx procedure input-port/read-substring input-port string start end
+Each of these procedures invokes the respective operation on
+@var{input-port}. For example, the following are equivalent:
+
+@example
+@group
+(input-port/read-char @var{input-port})
+((input-port/operation @var{input-port} 'read-char) @var{input-port})
+@end group
+@end example
+@end deffn
+
+The following custom operations are implemented for input ports to
+files, and will also work with some other kinds of input ports:
+
+@defop operation {input port} eof? input-port
+Returns @code{#t} if @var{input-port} is known to be at end of file,
+otherwise it returns @code{#f}.
+@end defop
+
+@defop operation {input port} chars-remaining input-port
+Returns an estimate of the number of characters remaining to be read
+from @var{input-port}. This is useful only when @var{input-port} is a
+file port in binary mode; in other cases, it returns @code{#f}.
+@end defop
+
+@defop operation {input port} buffered-input-chars input-port
+Returns the number of unread characters that are stored in
+@var{input-port}'s buffer. This will always be less than or equal to
+the buffer's size.
+@end defop
+
+@defop operation {input port} input-buffer-size input-port
+Returns the maximum number of characters that @var{input-port}'s buffer
+can hold.
+@end defop
+
+@defop operation {input port} set-input-buffer-size input-port size
+Resizes @var{input-port}'s buffer so that it can hold at most @var{size}
+characters. Characters in the buffer are discarded. @var{Size} must be
+an exact non-negative integer.
+@end defop
+
+@node Output Port Operations, Blocking Mode, Input Port Operations, Port Primitives
+@subsection Output Port Operations
+@cindex output port operations
+
+This section describes the standard operations on output ports.
+Following that, some useful custom operations are described.
+
+@defop operation {output port} write-char output-port char
+@cindex character, output to port
+Writes @var{char} to @var{output-port} and returns an unspecified value.
+@end defop
+
+@defop operation {output port} write-substring output-port string start end
+@cindex substring, output to port
+Writes the substring specified by @var{string}, @var{start}, and
+@var{end} to @var{output-port} and returns an unspecified value.
+Equivalent to writing the characters of the substring, one by one, to
+@var{output-port}, but is implemented very efficiently.
+@end defop
+
+@defop operation {output port} fresh-line output-port
+Most output ports are able to tell whether or not they are at the
+beginning of a line of output. If @var{output-port} is such a port,
+end-of-line is written to the port only if the port is not already at
+the beginning of a line. If @var{output-port} is not such a port, an
+end-of-line is unconditionally written to the port. Returns an
+unspecified value.
+@end defop
+
+@defop operation {output port} flush-output output-port
+If @var{output-port} is buffered, this causes its buffer to be written
+out. Otherwise it has no effect. Returns an unspecified value.
+@end defop
+
+@defop operation {output port} discretionary-flush-output output-port
+Normally, this operation does nothing. However, ports that support
+discretionary output flushing implement this operation identically to @code{flush-output}.
+@end defop
+
+@deffn procedure output-port/write-char output-port char
+@deffnx procedure output-port/write-substring output-port string start end
+@deffnx procedure output-port/fresh-line output-port
+@deffnx procedure output-port/flush-output output-port
+@deffnx procedure output-port/discretionary-flush-output output-port
+Each of these procedures invokes the respective operation on
+@var{output-port}. For example, the following are equivalent:
+
+@example
+@group
+(output-port/write-char @var{output-port} @var{char})
+((output-port/operation @var{output-port} 'write-char)
+ @var{output-port} @var{char})
+@end group
+@end example
+@end deffn
+
+@deffn procedure output-port/write-string output-port string
+Writes @var{string} to @var{output-port}. Equivalent to
+
+@example
+@group
+(output-port/write-substring @var{output-port}
+ @var{string}
+ 0
+ (string-length @var{string}))
+@end group
+@end example
+@end deffn
+
+The following custom operations are generally useful.
+
+@defop operation {output port} buffered-output-chars output-port
+Returns the number of unwritten characters that are stored in
+@var{output-port}'s buffer. This will always be less than or equal to
+the buffer's size.
+@end defop
+
+@defop operation {output port} output-buffer-size output-port
+Returns the maximum number of characters that @var{output-port}'s buffer
+can hold.
+@end defop
+
+@defop operation {output port} set-output-buffer-size output-port size
+Resizes @var{output-port}'s buffer so that it can hold at most @var{size}
+characters. Characters in the buffer are discarded. @var{Size} must be
+an exact non-negative integer.
+@end defop
+
+@defop operation {output port} x-size output-port
+Returns an exact positive integer that is the width of @var{output-port}
+in characters. If @var{output-port} has no natural width, e.g.@: if it is
+a file port, @code{#f} is returned.
+@end defop
+
+@defop operation {output port} y-size output-port
+Returns an exact positive integer that is the height of
+@var{output-port} in characters. If @var{output-port} has no natural
+height, e.g.@: if it is a file port, @code{#f} is returned.
+@end defop
+
+@deffn procedure output-port/x-size output-port
+This procedure invokes the custom operation whose name is the symbol
+@code{x-size}, if it exists. If the @code{x-size} operation is both
+defined and returns a value other than @code{#f}, that value is returned
+as the result of this procedure. Otherwise, @code{output-port/x-size}
+returns a default value (currently @code{80}).
+
+@code{output-port/x-size} is useful for programs that tailor their
+output to the width of the display (a fairly common practice). If the
+output device is not a display, such programs normally want some
+reasonable default width to work with, and this procedure provides
+exactly that.
+@end deffn
+
+@deffn procedure output-port/y-size output-port
+This procedure invokes the custom operation whose name is the symbol
+@code{y-size}, if it exists. If the @code{y-size} operation is defined,
+the value it returns is returned as the result of this procedure;
+otherwise, @code{#f} is returned.
+@end deffn
+
+@node Blocking Mode, Terminal Mode, Output Port Operations, Port Primitives
+@subsection Blocking Mode
+
+@cindex blocking mode, of port
+An interactive port is always in one of two modes: @dfn{blocking} or
+@dfn{non-blocking}. This mode is independent of the terminal mode:
+each can be changed independent of the other. Furthermore, if it is
+an interactive @acronym{I/O} port, there are separate blocking modes
+for input and for output.
+
+If an input port is in blocking mode, attempting to read from it when no
+input is available will cause Scheme to ``block'', i.e.@: suspend
+itself, until input is available. If an input port is in non-blocking
+mode, attempting to read from it when no input is available will cause
+the reading procedure to return immediately, indicating the lack of
+input in some way (exactly how this situation is indicated is separately
+specified for each procedure or operation).
+
+An output port in blocking mode will block if the output device is not
+ready to accept output. In non-blocking mode it will return immediately
+after performing as much output as the device will allow (again, each
+procedure or operation reports this situation in its own way).
+
+Interactive ports are initially in blocking mode; this can be changed at
+any time with the procedures defined in this section.
+
+These procedures represent blocking mode by the symbol @code{blocking},
+and non-blocking mode by the symbol @code{nonblocking}. An argument
+called @var{mode} must be one of these symbols. A @var{port} argument
+to any of these procedures may be any port, even if that port does not
+support blocking mode; in that case, the port is not modified in any
+way.
+
+@deffn procedure port/input-blocking-mode port
+Returns the input blocking mode of @var{port}.
+@end deffn
+
+@deffn procedure port/set-input-blocking-mode port mode
+Changes the input blocking mode of @var{port} to be @var{mode}. Returns
+an unspecified value.
+@end deffn
+
+@deffn procedure port/with-input-blocking-mode port mode thunk
+@var{Thunk} must be a procedure of no arguments.
+@code{port/with-input-blocking-mode}
+binds the input blocking mode of @var{port} to be @var{mode}, executes
+@var{thunk}, restores the input blocking mode of @var{port} to what it
+was when @code{port/with-input-blocking-mode} was called, and returns
+the value that was yielded by @var{thunk}. This binding is performed
+by @code{dynamic-wind}, which guarantees that the input blocking mode is
+restored if @var{thunk} escapes from its continuation.
+@end deffn
+
+@deffn procedure port/output-blocking-mode port
+Returns the output blocking mode of @var{port}.
+@end deffn
+
+@deffn procedure port/set-output-blocking-mode port mode
+Changes the output blocking mode of @var{port} to be @var{mode}.
+Returns an unspecified value.
+@end deffn
+
+@deffn procedure port/with-output-blocking-mode port mode thunk
+@var{Thunk} must be a procedure of no arguments.
+@code{port/with-output-blocking-mode}
+binds the output blocking mode of @var{port} to be @var{mode}, executes
+@var{thunk}, restores the output blocking mode of @var{port} to what it
+was when @code{port/with-output-blocking-mode} was called, and returns
+the value that was yielded by @var{thunk}. This binding is performed
+by @code{dynamic-wind}, which guarantees that the output blocking mode
+is restored if @var{thunk} escapes from its continuation.
+@end deffn
+
+@node Terminal Mode, , Blocking Mode, Port Primitives
+@subsection Terminal Mode
+
+@cindex terminal mode, of port
+A port that reads from or writes to a terminal has a @dfn{terminal
+mode}; this is either @dfn{cooked} or @dfn{raw}. This mode is
+independent of the blocking mode: each can be changed independent of
+the other. Furthermore, a terminal @acronym{I/O} port has independent
+terminal modes both for input and for output.
+
+@cindex cooked mode, of terminal port
+A terminal port in cooked mode provides some standard processing to make
+the terminal easy to communicate with. For example, under unix, cooked
+mode on input reads from the terminal a line at a time and provides
+rubout processing within the line, while cooked mode on output might
+translate linefeeds to carriage-return/linefeed pairs. In general, the
+precise meaning of cooked mode is operating-system dependent, and
+furthermore might be customizable by means of operating system
+utilities. The basic idea is that cooked mode does whatever is
+necessary to make the terminal handle all of the usual user-interface
+conventions for the operating system, while keeping the program's
+interaction with the port as normal as possible.
+
+@cindex raw mode, of terminal port
+A terminal port in raw mode disables all of that processing. In raw
+mode, characters are directly read from and written to the device
+without any translation or interpretation by the operating system. On
+input, characters are available as soon as they are typed, and are not
+echoed on the terminal by the operating system. In general, programs
+that put ports in raw mode have to know the details of interacting with
+the terminal. In particular, raw mode is used for writing programs such
+as text editors.
+
+Terminal ports are initially in cooked mode; this can be changed at any
+time with the procedures defined in this section.
+
+These procedures represent cooked mode by the symbol @code{cooked}, and
+raw mode by the symbol @code{raw}. Additionally, the value @code{#f}
+represents ``no mode''; it is the terminal mode of a port that is not a
+terminal. An argument called @var{mode} must be one of these three
+values. A @var{port} argument to any of these procedures may be any
+port, even if that port does not support terminal mode; in that case,
+the port is not modified in any way.
+
+@deffn procedure port/input-terminal-mode port
+Returns the input terminal mode of @var{port}.
+@end deffn
+
+@deffn procedure port/set-input-terminal-mode port mode
+Changes the input terminal mode of @var{port} to be @var{mode}.
+Returns an unspecified value.
+@end deffn
+
+@deffn procedure port/with-input-terminal-mode port mode thunk
+@var{Thunk} must be a procedure of no arguments.
+@code{port/with-input-terminal-mode}
+binds the input terminal mode of @var{port} to be @var{mode}, executes
+@var{thunk}, restores the input terminal mode of @var{port} to what it
+was when @code{port/with-input-terminal-mode} was called, and returns
+the value that was yielded by @var{thunk}. This binding is performed
+by @code{dynamic-wind}, which guarantees that the input terminal mode is
+restored if @var{thunk} escapes from its continuation.
+@end deffn
+
+@deffn procedure port/output-terminal-mode port
+Returns the output terminal mode of @var{port}.
+@end deffn
+
+@deffn procedure port/set-output-terminal-mode port mode
+Changes the output terminal mode of @var{port} to be @var{mode}.
+Returns an unspecified value.
+@end deffn
+
+@deffn procedure port/with-output-terminal-mode port mode thunk
+@var{Thunk} must be a procedure of no arguments.
+@code{port/with-output-terminal-mode}
+binds the output terminal mode of @var{port} to be @var{mode}, executes
+@var{thunk}, restores the output terminal mode of @var{port} to what it
+was when @code{port/with-output-terminal-mode} was called, and returns
+the value that was yielded by @var{thunk}. This binding is performed
+by @code{dynamic-wind}, which guarantees that the output terminal mode is
+restored if @var{thunk} escapes from its continuation.
+@end deffn
+
+@node Parser Buffers, Parser Language, Port Primitives, Input/Output
+@section Parser Buffers
+
+@cindex Parser buffer
+The @dfn{parser buffer} mechanism facilitates construction of parsers
+for complex grammars. It does this by providing an input stream with
+unbounded buffering and backtracking. The amount of buffering is
+under program control. The stream can backtrack to any position in
+the buffer.
+
+@cindex Parser-buffer pointer
+The mechanism defines two data types: the @dfn{parser buffer} and the
+@dfn{parser-buffer pointer}. A parser buffer is like an input port
+with buffering and backtracking. A parser-buffer pointer is a pointer
+into the stream of characters provided by a parser buffer.
+
+Note that all of the procedures defined here consider a parser buffer
+to contain a stream of 8-bit characters in the @acronym{ISO-8859-1}
+character set, except for @code{match-utf8-char-in-alphabet} which
+treats it as a stream of Unicode characters encoded as 8-bit bytes in
+the @acronym{UTF-8} encoding.
+
+There are several constructors for parser buffers:
+
+@deffn procedure input-port->parser-buffer port
+Returns a parser buffer that buffers characters read from @var{port}.
+@end deffn
+
+@deffn procedure substring->parser-buffer string start end
+Returns a parser buffer that buffers the characters in the argument
+substring. This is equivalent to creating a string input port and
+calling @code{input-port->parser-buffer}, but it runs faster and uses
+less memory.
+@end deffn
+
+@deffn procedure string->parser-buffer string
+Like @code{substring->parser-buffer} but buffers the entire string.
+@end deffn
+
+@deffn procedure source->parser-buffer source
+Returns a parser buffer that buffers the characters returned by
+calling @var{source}. @var{Source} is a procedure of three arguments:
+a string, a start index, and an end index (in other words, a substring
+specifier). Each time @var{source} is called, it writes some
+characters in the substring, and returns the number of characters
+written. When there are no more characters available, it returns
+zero. It must not return zero in any other circumstance.
+@end deffn
+
+Parser buffers and parser-buffer pointers may be distinguished from
+other objects:
+
+@deffn procedure parser-buffer? object
+Returns @code{#t} if @var{object} is a parser buffer, otherwise
+returns @code{#f}.
+@end deffn
+
+@deffn procedure parser-buffer-pointer? object
+Returns @code{#t} if @var{object} is a parser-buffer pointer,
+otherwise returns @code{#f}.
+@end deffn
+
+Characters can be read from a parser buffer much as they can be read
+from an input port. The parser buffer maintains an internal pointer
+indicating its current position in the input stream. Additionally,
+the buffer remembers all characters that were previously read, and can
+look at characters arbitrarily far ahead in the stream. It is this
+buffering capability that facilitates complex matching and
+backtracking.
+
+@deffn procedure read-parser-buffer-char buffer
+Returns the next character in @var{buffer}, advancing the internal
+pointer past that character. If there are no more characters
+available, returns @code{#f} and leaves the internal pointer
+unchanged.
+@end deffn
+
+@deffn procedure peek-parser-buffer-char buffer
+Returns the next character in @var{buffer}, or @code{#f} if no
+characters are available. Leaves the internal pointer unchanged.
+@end deffn
+
+@deffn procedure parser-buffer-ref buffer index
+Returns a character in @var{buffer}. @var{Index} is a non-negative
+integer specifying the character to be returned. If @var{index} is
+zero, returns the next available character; if it is one, returns the
+character after that, and so on. If @var{index} specifies a position
+after the last character in @var{buffer}, returns @code{#f}. Leaves
+the internal pointer unchanged.
+@end deffn
+
+The internal pointer of a parser buffer can be read or written:
+
+@deffn procedure get-parser-buffer-pointer buffer
+Returns a parser-buffer pointer object corresponding to the internal
+pointer of @var{buffer}.
+@end deffn
+
+@deffn procedure set-parser-buffer-pointer! buffer pointer
+Sets the internal pointer of @var{buffer} to the position specified by
+@var{pointer}. @var{Pointer} must have been returned from a previous
+call of @code{get-parser-buffer-pointer} on @var{buffer}.
+Additionally, if some of @var{buffer}'s characters have been discarded
+by @code{discard-parser-buffer-head!}, @var{pointer} must be outside
+the range that was discarded.
+@end deffn
+
+@deffn procedure get-parser-buffer-tail buffer pointer
+Returns a newly-allocated string consisting of all of the characters
+in @var{buffer} that fall between @var{pointer} and @var{buffer}'s
+internal pointer. @var{Pointer} must have been returned from a
+previous call of @code{get-parser-buffer-pointer} on @var{buffer}.
+Additionally, if some of @var{buffer}'s characters have been discarded
+by @code{discard-parser-buffer-head!}, @var{pointer} must be outside
+the range that was discarded.
+@end deffn
+
+@deffn procedure discard-parser-buffer-head! buffer
+Discards all characters in @var{buffer} that have already been read;
+in other words, all characters prior to the internal pointer. After
+this operation has completed, it is no longer possible to move the
+internal pointer backwards past the current position by calling
+@code{set-parser-buffer-pointer!}.
+@end deffn
+
+The next rather large set of procedures does conditional matching
+against the contents of a parser buffer. All matching is performed
+relative to the buffer's internal pointer, so the first character to
+be matched against is the next character that would be returned by
+@code{peek-parser-buffer-char}. The returned value is always
+@code{#t} for a successful match, and @code{#f} otherwise. For
+procedures whose names do not end in @samp{-no-advance}, a successful
+match also moves the internal pointer of the buffer forward to the end
+of the matched text; otherwise the internal pointer is unchanged.
+
+@deffn procedure match-parser-buffer-char buffer char
+@deffnx procedure match-parser-buffer-char-ci buffer char
+@deffnx procedure match-parser-buffer-not-char buffer char
+@deffnx procedure match-parser-buffer-not-char-ci buffer char
+@deffnx procedure match-parser-buffer-char-no-advance buffer char
+@deffnx procedure match-parser-buffer-char-ci-no-advance buffer char
+@deffnx procedure match-parser-buffer-not-char-no-advance buffer char
+@deffnx procedure match-parser-buffer-not-char-ci-no-advance buffer char
+Each of these procedures compares a single character in @var{buffer}
+to @var{char}. The basic comparison @code{match-parser-buffer-char}
+compares the character to @var{char} using @code{char=?}. The
+procedures whose names contain the @samp{-ci} modifier do
+case-insensitive comparison (i.e.@: they use @code{char-ci=?}). The
+procedures whose names contain the @samp{not-} modifier are successful
+if the character @emph{doesn't} match @var{char}.
+@end deffn
+
+@deffn procedure match-parser-buffer-char-in-set buffer char-set
+@deffnx procedure match-parser-buffer-char-in-set-no-advance buffer char-set
+These procedures compare the next character in @var{buffer} against
+@var{char-set} using @code{char-set-member?}.
+@end deffn
+
+@deffn procedure match-parser-buffer-string buffer string
+@deffnx procedure match-parser-buffer-string-ci buffer string
+@deffnx procedure match-parser-buffer-string-no-advance buffer string
+@deffnx procedure match-parser-buffer-string-ci-no-advance buffer string
+These procedures match @var{string} against @var{buffer}'s contents.
+The @samp{-ci} procedures do case-insensitive matching.
+@end deffn
+
+@deffn procedure match-parser-buffer-substring buffer string start end
+@deffnx procedure match-parser-buffer-substring-ci buffer string start end
+@deffnx procedure match-parser-buffer-substring-no-advance buffer string start end
+@deffnx procedure match-parser-buffer-substring-ci-no-advance buffer string start end
+These procedures match the specified substring against @var{buffer}'s
+contents. The @samp{-ci} procedures do case-insensitive matching.
+@end deffn
+
+@deffn procedure match-utf8-char-in-alphabet buffer alphabet
+This procedure treats @var{buffer}'s contents as @acronym{UTF-8}
+encoded Unicode characters and matches the next such character against
+@var{alphabet}, which must be a Unicode alphabet (@pxref{Unicode}).
+@acronym{UTF-8} represents characters with 1 to 6 bytes, so a
+successful match can move the internal pointer forward by as many as 6
+bytes.
+@end deffn
+
+The remaining procedures provide information that can be used to
+identify locations in a parser buffer's stream.
+
+@deffn procedure parser-buffer-position-string pointer
+Returns a string describing the location of @var{pointer} in terms of
+its character and line indexes. This resulting string is meant to be
+presented to an end user in order to direct their attention to a
+feature in the input stream. In this string, the indexes are
+presented as one-based numbers.
+
+@var{Pointer} may alternatively be a parser buffer, in which case it
+is equivalent to having specified the buffer's internal pointer.
+@end deffn
+
+@deffn procedure parser-buffer-pointer-index pointer
+@deffnx procedure parser-buffer-pointer-line pointer
+Returns the character or line index, respectively, of @var{pointer}.
+Both indexes are zero-based.
+@end deffn
+
+@node Parser Language, XML Parser, Parser Buffers, Input/Output
+@section Parser Language
+
+@cindex Parser language
+Although it is possible to write parsers using the parser-buffer
+abstraction (@pxref{Parser Buffers}), it is tedious. The problem is
+that the abstraction isn't closely matched to the way that people
+think about syntactic structures. In this section, we introduce a
+higher-level mechanism that greatly simplifies the implementation of a
+parser.
+
+The @dfn{parser language} described here allows the programmer to
+write @acronym{BNF}-like specifications that are translated into
+efficient Scheme code at compile time. The language is declarative,
+but it can be freely mixed with Scheme code; this allows the parsing
+of grammars that aren't conveniently described in the language.
+
+@cindex Backtracking, in parser language
+The language also provides backtracking. For example, this expression
+matches any sequence of alphanumeric characters followed by a single
+alphabetic character:
+
+@example
+@group
+(*matcher
+ (seq (* (char-set char-set:alphanumeric))
+ (char-set char-set:alphabetic)))
+@end group
+@end example
+
+@noindent
+The way that this works is that the matcher matches alphanumeric
+characters in the input stream until it finds a non-alphanumeric
+character. It then tries to match an alphabetic character, which of
+course fails. At this point, if it matched at least one alphanumeric
+character, it @emph{backtracks}: the last matched alphanumeric is
+``unmatched'', and it again attempts to match an alphabetic
+character. The backtracking can be arbitrarily deep; the matcher will
+continue to back up until it finds a way to match the remainder of the
+expression.
+
+So far, this sounds a lot like regular-expression matching
+(@pxref{Regular Expressions}). However, there are some important
+differences.
+
+@itemize @bullet
+@item
+The parser language uses a Scheme-like syntax that is easier to read
+and write than regular-expression notation.
+
+@item
+The language provides macros so that common syntactic constructs can
+be abstracted.
+
+@item
+The language mixes easily with Scheme code, allowing the full power of
+Scheme to be applied to program around limitations in the parser
+language.
+
+@item
+The language provides expressive facilities for converting syntax into
+parsed structure. It also makes it easy to convert parsed strings
+into meaningful objects (e.g.@: numbers).
+
+@item
+The language is compiled into machine language; regular expressions
+are usually interpreted.
+@end itemize
+
+Here is an example that shows off several of the features of the
+parser language. The example is a parser for @acronym{XML} start
+tags:
+
+@anchor{with-pointer example}
+@example
+@group
+(*parser
+ (with-pointer p
+ (seq "<"
+ parse-name
+ parse-attribute-list
+ (alt (match ">")
+ (match "/>")
+ (sexp
+ (lambda (b)
+ (error
+ (string-append
+ "Unterminated start tag at "
+ (parser-buffer-position-string p)))))))))
+@end group
+@end example
+
+@noindent
+This shows that the basic description of a start tag is very similar
+to its @acronym{BNF}. Non-terminal symbols @code{parse-name} and
+@code{parse-attribute-list} do most of the work, and the noise strings
+@code{"<"} and @code{">"} are the syntactic markers delimiting the
+form. There are two alternate endings for start tags, and if the
+parser doesn't find either of the endings, the Scheme code (wrapped in
+@code{sexp}) is run to signal an error. The error procedure
+@code{perror} takes a pointer @code{p}, which it uses to indicate the
+position in the input stream at which the error occurred. In this
+case, that is the beginning of the start tag, i.e.@: the position of
+the leading @code{"<"} marker.
+
+This example still looks pretty complicated, mostly due to the
+error-signalling code. In practice, this is abstracted into a macro,
+after which the expression is quite succinct:
+
+@example
+@group
+(*parser
+ (bracket "start tag"
+ (seq (noise (string "<")) parse-name)
+ (match (alt (string ">") (string "/>")))
+ parse-attribute-list))
+@end group
+@end example
+
+@noindent
+The @code{bracket} macro captures the pattern of a bracketed item, and
+hides much of the detail.
+
+The parser language actually consists of two languages: one for
+defining matchers, and one for defining parsers. The languages are
+intentionally very similar, and are meant to be used together. Each
+sub-language is described below in its own section.
+
+@cindex run-time-loadable option
+@cindex option, run-time-loadable
+The parser language is a run-time-loadable option; to use it, execute
+
+@example
+(load-option '*parser)
+@end example
+@findex load-option
+
+@noindent
+once before compiling any code that uses the language.
+
+@menu
+* *Matcher::
+* *Parser::
+* Parser-language Macros::
+@end menu
+
+@node *Matcher, *Parser, Parser Language, Parser Language
+@subsection *Matcher
+
+@cindex Matcher language
+@cindex Matcher procedure
+The @dfn{matcher language} is a declarative language for specifying a
+@dfn{matcher procedure}. A matcher procedure is a procedure that
+accepts a single parser-buffer argument and returns a boolean value
+indicating whether the match it performs was successful. If the match
+succeeds, the internal pointer of the parser buffer is moved forward
+over the matched text. If the match fails, the internal pointer is
+unchanged.
+
+For example, here is a matcher procedure that matches the character
+@samp{a}:
+
+@example
+(lambda (b) (match-parser-buffer-char b #\a))
+@end example
+
+@noindent
+Here is another example that matches two given characters, @var{c1}
+and @var{c2}, in sequence:
+
+@example
+@group
+(lambda (b)
+ (let ((p (get-parser-buffer-pointer b)))
+ (if (match-parser-buffer-char b @var{c1})
+ (if (match-parser-buffer-char b @var{c2})
+ #t
+ (begin
+ (set-parser-buffer-pointer! b p)
+ #f))
+ #f)))
+@end group
+@end example
+
+@noindent
+This is code is clear, but has lots of details that get in the way of
+understanding what it is doing. Here is the same example in the
+matcher language:
+
+@example
+(*matcher (seq (char @var{c1}) (char @var{c2})))
+@end example
+
+@noindent
+This is much simpler and more intuitive. And it generates virtually
+the same code:
+
+@example
+@group
+(pp (*matcher (seq (char c1) (char c2))))
+@print{} (lambda (#[b1])
+@print{} (let ((#[p1] (get-parser-buffer-pointer #[b1])))
+@print{} (and (match-parser-buffer-char #[b1] c1)
+@print{} (if (match-parser-buffer-char #[b1] c2)
+@print{} #t
+@print{} (begin
+@print{} (set-parser-buffer-pointer! #[b1] #[p1])
+@print{} #f)))))
+@end group
+@end example
+
+Now that we have seen an example of the language, it's time to look at
+the detail. The @code{*matcher} special form is the interface between
+the matcher language and Scheme.
+
+@deffn {special form} *matcher mexp
+The operand @var{mexp} is an expression in the matcher language. The
+@code{*matcher} expression expands into Scheme code that implements a
+matcher procedure.
+@end deffn
+
+Here are the predefined matcher expressions. New matcher expressions
+can be defined using the macro facility (@pxref{Parser-language
+Macros}). We will start with the primitive expressions.
+
+@deffn {matcher expression} char expression
+@deffnx {matcher expression} char-ci expression
+@deffnx {matcher expression} not-char expression
+@deffnx {matcher expression} not-char-ci expression
+These expressions match a given character. In each case, the
+@var{expression} operand is a Scheme expression that must evaluate to
+a character at run time. The @samp{-ci} expressions do
+case-insensitive matching. The @samp{not-} expressions match any
+character other than the given one.
+@end deffn
+
+@deffn {matcher expression} string expression
+@deffnx {matcher expression} string-ci expression
+These expressions match a given string. The @var{expression} operand
+is a Scheme expression that must evaluate to a string at run time.
+The @code{string-ci} expression does case-insensitive matching.
+@end deffn
+
+@deffn {matcher expression} char-set expression
+These expressions match a single character that is a member of a given
+character set. The @var{expression} operand is a Scheme expression
+that must evaluate to a character set at run time.
+@end deffn
+
+@deffn {matcher expression} alphabet expression
+These expressions match a single character that is a member of a given
+Unicode alphabet (@pxref{Unicode}). The @var{expression} operand is a
+Scheme expression that must evaluate to an alphabet at run time.
+@end deffn
+
+@deffn {matcher expression} end-of-input
+The @code{end-of-input} expression is successful only when there are
+no more characters available to be matched.
+@end deffn
+
+@deffn {matcher expression} discard-matched
+The @code{discard-matched} expression always successfully matches the
+null string. However, it isn't meant to be used as a matching
+expression; it is used for its effect. @code{discard-matched} causes
+all of the buffered text prior to this point to be discarded (i.e.@:
+it calls @code{discard-parser-buffer-head!} on the parser buffer).
+
+Note that @code{discard-matched} may not be used in certain places in
+a matcher expression. The reason for this is that it deliberately
+discards information needed for backtracking, so it may not be used in
+a place where subsequent backtracking will need to back over it. As a
+rule of thumb, use @code{discard-matched} only in the last operand of
+a @code{seq} or @code{alt} expression (including any @code{seq} or
+@code{alt} expressions in which it is indirectly contained).
+@end deffn
+
+In addition to the above primitive expressions, there are two
+convenient abbreviations. A character literal (e.g.@: @samp{#\A}) is
+a legal primitive expression, and is equivalent to a @code{char}
+expression with that literal as its operand (e.g.@: @samp{(char
+#\A)}). Likewise, a string literal is equivalent to a @code{string}
+expression (e.g.@: @samp{(string "abc")}).
+
+Next there are several combinator expressions. These closely
+correspond to similar combinators in regular expressions. Parameters
+named @var{mexp} are arbitrary expressions in the matcher language.
+
+@deffn {matcher expression} seq mexp @dots{}
+This matches each @var{mexp} operand in sequence. For example,
+
+@example
+@group
+(seq (char-set char-set:alphabetic)
+ (char-set char-set:numeric))
+@end group
+@end example
+
+@noindent
+matches an alphabetic character followed by a numeric character, such
+as @samp{H4}.
+
+Note that if there are no @var{mexp} operands, the @code{seq}
+expression successfully matches the null string.
+@end deffn
+
+@deffn {matcher expression} alt mexp @dots{}
+This attempts to match each @var{mexp} operand in order from left to
+right. The first one that successfully matches becomes the match for
+the entire @code{alt} expression.
+
+The @code{alt} expression participates in backtracking. If one of the
+@var{mexp} operands matches, but the overall match in which this
+expression is embedded fails, the backtracking mechanism will cause
+the @code{alt} expression to try the remaining @var{mexp} operands.
+For example, if the expression
+
+@example
+(seq (alt "ab" "a") "b")
+@end example
+
+@noindent
+is matched against the text @samp{abc}, the @code{alt} expression will
+initially match its first operand. But it will then fail to match the
+second operand of the @code{seq} expression. This will cause the
+@code{alt} to be restarted, at which time it will match @samp{a}, and
+the overall match will succeed.
+
+Note that if there are no @var{mexp} operands, the @code{alt} match
+will always fail.
+@end deffn
+
+@deffn {matcher expression} * mexp
+This matches zero or more occurrences of the @var{mexp} operand.
+(Consequently this match always succeeds.)
+
+The @code{*} expression participates in backtracking; if it matches
+@var{N} occurrences of @var{mexp}, but the overall match fails, it
+will backtrack to @var{N-1} occurrences and continue. If the overall
+match continues to fail, the @code{*} expression will continue to
+backtrack until there are no occurrences left.
+@end deffn
+
+@deffn {matcher expression} + mexp
+This matches one or more occurrences of the @var{mexp} operand. It is
+equivalent to
+
+@example
+(seq @var{mexp} (* @var{mexp}))
+@end example
+@end deffn
+
+@deffn {matcher expression} ? mexp
+This matches zero or one occurrences of the @var{mexp} operand. It is
+equivalent to
+
+@example
+(alt @var{mexp} (seq))
+@end example
+@end deffn
+
+@deffn {matcher expression} sexp expression
+The @code{sexp} expression allows arbitrary Scheme code to be embedded
+inside a matcher. The @var{expression} operand must evaluate to a
+matcher procedure at run time; the procedure is called to match the
+parser buffer. For example,
+
+@example
+@group
+(*matcher
+ (seq "a"
+ (sexp parse-foo)
+ "b"))
+@end group
+@end example
+
+@noindent
+expands to
+
+@example
+@group
+(lambda (#[b1])
+ (let ((#[p1] (get-parser-buffer-pointer #[b1])))
+ (and (match-parser-buffer-char #[b1] #\a)
+ (if (parse-foo #[b1])
+ (if (match-parser-buffer-char #[b1] #\b)
+ #t
+ (begin
+ (set-parser-buffer-pointer! #[b1] #[p1])
+ #f))
+ (begin
+ (set-parser-buffer-pointer! #[b1] #[p1])
+ #f)))))
+@end group
+@end example
+
+The case in which @var{expression} is a symbol is so common that it
+has an abbreviation: @samp{(sexp @var{symbol})} may be abbreviated as
+just @var{symbol}.
+@end deffn
+
+@deffn {matcher expression} with-pointer identifier mexp
+The @code{with-pointer} expression fetches the parser buffer's
+internal pointer (using @code{get-parser-buffer-pointer}), binds it to
+@var{identifier}, and then matches the pattern specified by
+@var{mexp}. @var{Identifier} must be a symbol.
+
+This is meant to be used on conjunction with @code{sexp}, as a way to
+capture a pointer to a part of the input stream that is outside the
+@code{sexp} expression. An example of the use of @code{with-pointer}
+appears above (@pxref{with-pointer example}).
+@end deffn
+
+@node *Parser, Parser-language Macros, *Matcher, Parser Language
+@subsection *Parser
+
+@cindex Parser language
+@cindex Parser procedure
+The @dfn{parser language} is a declarative language for specifying a
+@dfn{parser procedure}. A parser procedure is a procedure that
+accepts a single parser-buffer argument and parses some of the input
+from the buffer. If the parse is successful, the procedure returns a
+vector of objects that are the result of the parse, and the internal
+pointer of the parser buffer is advanced past the input that was
+parsed. If the parse fails, the procedure returns @code{#f} and the
+internal pointer is unchanged. This interface is much like that of a
+matcher procedure, except that on success the parser procedure returns
+a vector of values rather than @code{#t}.
+
+The @code{*parser} special form is the interface between the parser
+language and Scheme.
+
+@deffn {special form} *parser pexp
+The operand @var{pexp} is an expression in the parser language. The
+@code{*parser} expression expands into Scheme code that implements a
+parser procedure.
+@end deffn
+
+There are several primitive expressions in the parser language. The
+first two provide a bridge to the matcher language (@pxref{*Matcher}):
+
+@deffn {parser expression} match mexp
+The @code{match} expression performs a match on the parser buffer.
+The match to be performed is specified by @var{mexp}, which is an
+expression in the matcher language. If the match is successful, the
+result of the @code{match} expression is a vector of one element: a
+string containing that text.
+@end deffn
+
+@deffn {parser expression} noise mexp
+The @code{noise} expression performs a match on the parser buffer.
+The match to be performed is specified by @var{mexp}, which is an
+expression in the matcher language. If the match is successful, the
+result of the @code{noise} expression is a vector of zero elements.
+(In other words, the text is matched and then thrown away.)
+
+The @var{mexp} operand is often a known character or string, so in the
+case that @var{mexp} is a character or string literal, the
+@code{noise} expression can be abbreviated as the literal. In other
+words, @samp{(noise "foo")} can be abbreviated just @samp{"foo"}.
+@end deffn
+
+@deffn {parser expression} values expression @dots{}
+Sometimes it is useful to be able to insert arbitrary values into the
+parser result. The @code{values} expression supports this. The
+@var{expression} arguments are arbitrary Scheme expressions that are
+evaluated at run time and returned in a vector. The @code{values}
+expression always succeeds and never modifies the internal pointer of
+the parser buffer.
+@end deffn
+
+@deffn {parser expression} discard-matched
+The @code{discard-matched} expression always succeeds, returning a
+vector of zero elements. In all other respects it is identical to the
+@code{discard-matched} expression in the matcher language.
+@end deffn
+
+Next there are several combinator expressions. Parameters named
+@var{pexp} are arbitrary expressions in the parser language. The
+first few combinators are direct equivalents of those in the matcher
+language.
+
+@deffn {parser expression} seq pexp @dots{}
+The @code{seq} expression parses each of the @var{pexp} operands in
+order. If all of the @var{pexp} operands successfully match, the
+result is the concatenation of their values (by @code{vector-append}).
+@end deffn
+
+@deffn {parser expression} alt pexp @dots{}
+The @code{alt} expression attempts to parse each @var{pexp} operand in
+order from left to right. The first one that successfully parses
+produces the result for the entire @code{alt} expression.
+
+Like the @code{alt} expression in the matcher language, this
+expression participates in backtracking.
+@end deffn
+
+@deffn {parser expression} * pexp
+The @code{*} expression parses zero or more occurrences of @var{pexp}.
+The results of the parsed occurrences are concatenated together (by
+@code{vector-append}) to produce the expression's result.
+
+Like the @code{*} expression in the matcher language, this expression
+participates in backtracking.
+@end deffn
+
+@deffn {parser expression} + pexp
+The @code{*} expression parses one or more occurrences of @var{pexp}.
+It is equivalent to
+
+@example
+(seq @var{pexp} (* @var{pexp}))
+@end example
+@end deffn
+
+@deffn {parser expression} ? pexp
+The @code{*} expression parses zero or one occurrences of @var{pexp}.
+It is equivalent to
+
+@example
+(alt @var{pexp} (seq))
+@end example
+@end deffn
+
+The next three expressions do not have equivalents in the matcher
+language. Each accepts a single @var{pexp} argument, which is parsed
+in the usual way. These expressions perform transformations on the
+returned values of a successful match.
+
+@deffn {parser expression} transform expression pexp
+The @code{transform} expression performs an arbitrary transformation
+of the values returned by parsing @var{pexp}. @var{Expression} is a
+Scheme expression that must evaluate to a procedure at run time. If
+@var{pexp} is successfully parsed, the procedure is called with the
+vector of values as its argument, and must return a vector or
+@code{#f}. If it returns a vector, the parse is successful, and those
+are the resulting values. If it returns @code{#f}, the parse fails
+and the internal pointer of the parser buffer is returned to what it
+was before @var{pexp} was parsed.
+
+For example:
+
+@example
+(transform (lambda (v) (if (= 0 (vector-length v)) #f v)) @dots{})
+@end example
+@end deffn
+
+@deffn {parser expression} encapsulate expression pexp
+The @code{encapsulate} expression transforms the values returned by
+parsing @var{pexp} into a single value. @var{Expression} is a Scheme
+expression that must evaluate to a procedure at run time. If
+@var{pexp} is successfully parsed, the procedure is called with the
+vector of values as its argument, and may return any Scheme object.
+The result of the @code{encapsulate} expression is a vector of length
+one containing that object. (And consequently @code{encapsulate}
+doesn't change the success or failure of @var{pexp}, only its value.)
+
+For example:
+
+@example
+(encapsulate vector->list @dots{})
+@end example
+@end deffn
+
+@deffn {parser expression} map expression pexp
+The @code{map} expression performs a per-element transform on the
+values returned by parsing @var{pexp}. @var{Expression} is a Scheme
+expression that must evaluate to a procedure at run time. If
+@var{pexp} is successfully parsed, the procedure is mapped (by
+@code{vector-map}) over the values returned from the parse. The
+mapped values are returned as the result of the @code{map} expression.
+(And consequently @code{map} doesn't change the success or failure of
+@var{pexp}, nor the number of values returned.)
+
+For example:
+
+@example
+(map string->symbol @dots{})
+@end example
+@end deffn
+
+Finally, as in the matcher language, we have @code{sexp} and
+@code{with-pointer} to support embedding Scheme code in the parser.
+
+@deffn {parser expression} sexp expression
+The @code{sexp} expression allows arbitrary Scheme code to be embedded
+inside a parser. The @var{expression} operand must evaluate to a
+parser procedure at run time; the procedure is called to parse the
+parser buffer. This is the parser-language equivalent of the
+@code{sexp} expression in the matcher language.
+
+The case in which @var{expression} is a symbol is so common that it
+has an abbreviation: @samp{(sexp @var{symbol})} may be abbreviated as
+just @var{symbol}.
+@end deffn
+
+@deffn {parser expression} with-pointer identifier pexp
+The @code{with-pointer} expression fetches the parser buffer's
+internal pointer (using @code{get-parser-buffer-pointer}), binds it to
+@var{identifier}, and then parses the pattern specified by @var{pexp}.
+@var{Identifier} must be a symbol. This is the parser-language
+equivalent of the @code{with-pointer} expression in the matcher
+language.
+@end deffn
+
+@node Parser-language Macros, , *Parser, Parser Language
+@subsection Parser-language Macros
+
+The parser and matcher languages provide a macro facility so that
+common patterns can be abstracted. The macro facility allows new
+expression types to be independently defined in the two languages.
+The macros are defined in heirarchically organized tables, so that
+different applications can have private macro bindings.
+
+@deffn {special form} define-*matcher-macro formals expression
+@deffnx {special form} define-*parser-macro formals expression
+These special forms are used to define macros in the matcher and
+parser language, respectively. @var{Formals} is like the
+@var{formals} list of a @code{define} special form, and
+@var{expression} is a Scheme expression.
+
+If @var{formals} is a list (or improper list) of symbols, the first
+symbol in the list is the name of the macro, and the remaining symbols
+are interpreted as the @var{formals} of a lambda expression. A lambda
+expression is formed by combining the latter @var{formals} with the
+@var{expression}, and this lambda expression, when evaluated, becomes
+the @dfn{expander}. The defined macro accepts the same number of
+operands as the expander. A macro instance is expanded by applying
+the expander to the list of operands; the result of the application is
+interpreted as a replacement expression for the macro instance.
+
+If @var{formals} is a symbol, it is the name of the macro. In this
+case, the expander is a procedure of no arguments whose body is
+@var{expression}. When the @var{formals} symbol appears by itself as
+an expression in the language, the expander is called with no
+arguments, and the result is interpreted as a replacement expression
+for the symbol.
+@end deffn
+
+@deffn procedure define-*matcher-expander identifier expander
+@deffnx procedure define-*parser-expander identifier expander
+These procedures provide a procedural interface to the
+macro-definition mechanism. @var{Identifier} must be a symbol, and
+@var{expander} must be an expander procedure, as defined above.
+Instances of the @code{define-*matcher-macro} and
+@code{define-*parser-macro} special forms expand into calls to these
+procedures.
+@end deffn
+
+The remaining procedures define the interface to the parser-macros
+table abstraction. Each parser-macro table has a separate binding
+space for macros in the matcher and parser languages. However, the
+table inherits bindings from one specified table; it's not possible to
+inherit matcher-language bindings from one table and parser-language
+bindings from another.
+
+@deffn procedure make-parser-macros parent-table
+Create and return a new parser-macro table that inherits from
+@var{parent-table}. @var{Parent-table} must be either a parser-macro
+table, or @code{#f}; usually it is specified as the value of
+@code{global-parser-macros}.
+@end deffn
+
+@deffn procedure parser-macros? object
+This is a predicate for parser-macro tables.
+@end deffn
+
+@deffn procedure global-parser-macros
+Return the global parser-macro table. This table is predefined and
+contains all of the bindings documented here.
+@end deffn
+
+There is a ``current'' table at all times, and macro definitions are
+always placed in this table. By default, the current table is the
+global macro table, but the following procedures allow this to be
+changed.
+
+@deffn procedure current-parser-macros
+Return the current parser-macro table.
+@end deffn
+
+@deffn procedure set-current-parser-macros! table
+Change the current parser-macro table to @var{table}, which must
+satisfy @code{parser-macros?}.
+@end deffn
+
+@deffn procedure with-current-parser-macros table thunk
+Bind the current parser-macro table to @var{table}, call @var{thunk}
+with no arguments, then restore the original table binding. The value
+returned by @var{thunk} is the returned as the value of this
+procedure. @var{Table} must satisfy @code{parser-macros?}, and
+@var{thunk} must be a procedure of no arguments.
+@end deffn
+
+@node XML Parser, , Parser Language, Input/Output
+@section XML Parser
+
+@cindex XML parser
+@cindex parser, XML
+MIT/GNU Scheme provides a simple non-validating @acronym{XML} parser.
+This parser is mostly conformant, with the exception that it doesn't
+support @acronym{UTF-16}. The parser also does not support external
+document type declarations (@acronym{DTD}s). The output of the parser
+is a record tree that closely reflects the structure of the
+@acronym{XML} document.
+
+@cindex XML output
+@cindex output, XML
+There is also an output mechanism that writes an @acronym{XML} record
+tree to a port. There is no guarantee that parsing an @acronym{XML}
+document and writing it back out will make a verbatim copy of the
+document. The output will be semantically identical but may have
+small syntactic differences. For example, comments are discarded by
+the parser, and entities are substituted during the parsing process.
+
+The purpose of the @acronym{XML} support is to provide a mechanism for
+reading and writing simple @acronym{XML} documents. In the future
+this support may be further developed to support a standard interface
+such as @acronym{DOM} or @acronym{SAX}.
+
+@cindex run-time-loadable option
+@cindex option, run-time-loadable
+The @acronym{XML} support is a run-time-loadable option; to use it,
+execute
+
+@example
+(load-option 'xml)
+@end example
+@findex load-option
+
+@noindent
+once before compiling any code that uses it.
+
+The @acronym{XML} interface consists of an input procedure, an output
+procedure, and a set of record types.
+
+@deffn procedure parse-xml-document buffer
+This procedure parses an @acronym{XML} input stream and returns a
+newly-allocated @acronym{XML} record tree. The @var{buffer} argument
+must be a parser buffer (@pxref{Parser Buffers}). Most errors in the
+input stream are detected and signalled, with information identifying
+the location of the error where possible. Note that the input stream
+is assumed to be @acronym{UTF-8}.
+@end deffn
+
+@deffn procedure write-xml xml-document port
+This procedure writes an @acronym{XML} record tree to @var{port}. The
+@var{xml-document} argument must be a record of type
+@code{xml-document}, which is the root record of an @acronym{XML}
+record tree. The output is encoded in @acronym{UTF-8}.
+@end deffn
+
+@cindex XML names
+@cindex names, XML
+@acronym{XML} names are represented in memory as symbols. All symbols
+appearing within @acronym{XML} records are @acronym{XML} names.
+Because @acronym{XML} names are case sensitive, there is a procedure
+to intern these symbols:
+
+@deffn procedure xml-intern string
+@cindex XML name
+Returns the @acronym{XML} name called @var{string}. @acronym{XML}
+names are represented as symbols, but unlike ordinary Scheme symbols,
+they are case sensitive. The following is true for any two strings
+@var{string1} and @var{string2}:
+
+@example
+@group
+(let ((name1 (xml-intern @var{string1}))
+ (name2 (xml-intern @var{string2})))
+ (if (string=? @var{string1} @var{string2})
+ (eq? name1 name2)
+ (not (eq? name1 name2))))
+@end group
+@end example
+@end deffn
+
+The output from the @acronym{XML} parser and the input to the
+@acronym{XML} output procedure is a complex data structure composed of
+a heirarchy of typed components. Each component is a record whose
+fields correspond to parts of the @acronym{XML} structure that the
+record represents. There are no special operations on these records;
+each is a tuple with named subparts. The root record type is
+@code{xml-document}, which represents a complete @acronym{XML}
+document.
+
+Each record type @var{type} has the following associated bindings:
+
+@table @code
+@item <@var{type}>
+is a variable bound to the record-type descriptor for @var{type}. The
+record-type descriptor may be used as a specializer in @acronym{SOS}
+method definitions, which greatly simplifies code to dispatch on these
+types.
+
+@item @var{type}?
+is a predicate for records of type @var{type}. It accepts one
+argument, which can be any object, and returns @code{#t} if the object
+is a record of this type, or @code{#f} otherwise.
+
+@item make-@var{type}
+is a constructor for records of type @var{type}. It accepts one
+argument for each field of @var{type}, in the same order that they are
+written in the type description, and returns a newly-allocated record
+of that type.
+
+@item @var{type}-@var{field}
+is an accessor procedure for the field @var{field} in records of type
+@var{type}. It accepts one argument, which must be a record of that
+type, and returns the contents of the corresponding field in the
+record.
+
+@item set-@var{type}-@var{field}!
+is a modifier procedure for the field @var{field} in records of type
+@var{type}. It accepts two arguments: the first must be a record of
+that type, and the second is a new value for the corresponding field.
+The record's field is modified to have the new value.
+@end table
+
+@deftp {record type} xml-document declaration misc-1 dtd misc-2 root misc-3
+@vindex <xml-document>
+@findex xml-document?
+@findex make-xml-document
+@findex xml-document-declaration
+@findex xml-document-misc-1
+@findex xml-document-dtd
+@findex xml-document-misc-2
+@findex xml-document-root
+@findex xml-document-misc-3
+@findex set-xml-document-declaration!
+@findex set-xml-document-misc-1!
+@findex set-xml-document-dtd!
+@findex set-xml-document-misc-2!
+@findex set-xml-document-root!
+@findex set-xml-document-misc-3!
+The @code{xml-document} record is the top-level record representing a
+complete @acronym{XML} document. @var{Declaration} is either an
+@code{xml-declaration} object or @code{#f}. @var{Dtd} is either an
+@code{xml-dtd} object or @code{#f}. @var{Root} is an @code{xml-element}
+object. @var{Misc-1}, @var{misc-2}, and @var{misc-3} are lists of
+miscellaneous items; a miscellaneous item is either an
+@code{xml-comment} object, an @code{xml-processing-instructions} object,
+or a string of whitespace.
+@end deftp
+
+@deftp {record type} xml-declaration version encoding standalone
+@vindex <xml-declaration>
+@findex xml-declaration?
+@findex make-xml-declaration
+@findex xml-declaration-version
+@findex xml-declaration-encoding
+@findex xml-declaration-standalone
+@findex set-xml-declaration-version!
+@findex set-xml-declaration-encoding!
+@findex set-xml-declaration-standalone!
+The @code{xml-declaration} record represents the @samp{<?xml @dots{}
+?>} declaration that optionally appears at the beginning of an
+@acronym{XML} document. @var{Version} is a version string, typically
+@code{"1.0"}. @var{Encoding} is either an encoding string or
+@code{#f}. @var{Standalone} is either @code{"yes"}, @code{"no"}, or
+@code{#f}.
+@end deftp
+
+@deftp {record type} xml-element name attributes contents
+@vindex <xml-element>
+@findex xml-element?
+@findex make-xml-element
+@findex xml-element-name
+@findex xml-element-attributes
+@findex xml-element-contents
+@findex set-xml-element-name!
+@findex set-xml-element-attributes!
+@findex set-xml-element-contents!
+The @code{xml-element} record represents general @acronym{XML}
+elements; the bulk of a typical @acronym{XML} document consists of
+these elements. @var{Name} is the element name (a symbol).
+@var{Attributes} is a list of attributes; each attribute is a pair
+whose @sc{car} is the attribute name (a symbol), and whose @sc{cdr} is
+the attribute value (a string). @var{Contents} is a list of the
+contents of the element. Each element of this list is either a
+string, an @code{xml-element} record, an
+@code{xml-processing-instructions} record, or an
+@code{xml-uninterpreted} record.
+@end deftp
+
+@deftp {record type} xml-processing-instructions name text
+@vindex <xml-processing-instructions>
+@findex xml-processing-instructions?
+@findex make-xml-processing-instructions
+@findex xml-processing-instructions-name
+@findex xml-processing-instructions-text
+@findex set-xml-processing-instructions-name!
+@findex set-xml-processing-instructions-text!
+The @code{xml-processing-instructions} record represents processing
+instructions, which have the form @samp{<?@var{name} @dots{} ?>}.
+These instructions are intended to contain non-@acronym{XML} data that
+will be processed by another interpreter; for example they might
+contain @acronym{PHP} programs. The @var{name} field is the processor
+name (a symbol), and the @var{text} field is the body of the
+instructions (a string).
+@end deftp
+
+@deftp {record type} xml-uninterpreted text
+@vindex <xml-uninterpreted>
+@findex xml-uninterpreted?
+@findex make-xml-uninterpreted
+@findex xml-uninterpreted-text
+@findex set-xml-uninterpreted-text!
+Some documents contain entity references that can't be expanded by the
+parser, perhaps because the document requires an external
+@acronym{DTD}. Such references are left uninterpreted in the output
+by wrapping them in @code{xml-uninterpreted} records. In some
+situations, for example when they are embedded in attribute values,
+the surrounding text is also included in the @code{xml-uninterpreted}
+record. The @var{text} field contains the uninterpreted @acronym{XML}
+text (a string).
+@end deftp
+
+@deftp {record type} xml-dtd root external internal
+@vindex <xml-dtd>
+@findex xml-dtd?
+@findex make-xml-dtd
+@findex xml-dtd-root
+@findex xml-dtd-external
+@findex xml-dtd-internal
+@findex set-xml-dtd-root!
+@findex set-xml-dtd-external!
+@findex set-xml-dtd-internal!
+The @code{xml-dtd} record represents a document type declaration. The
+@var{root} field is an @acronym{XML} name for the root element of the
+document. @var{External} is either an @code{xml-external-id} record
+or @code{#f}. @var{Internal} is a list of @acronym{DTD} element
+records (e.g.@: @code{xml-!element}, @code{xml-!attlist}, etc.).
+@end deftp
+
+The remaining record types are valid only within a @acronym{DTD}.
+
+@deftp {record type} xml-!element name content-type
+@vindex <xml-!element>
+@findex xml-!element?
+@findex make-xml-!element
+@findex xml-!element-name
+@findex xml-!element-content-type
+@findex set-xml-!element-name!
+@findex set-xml-!element-content-type!
+The @code{xml-!element} record represents an element-type
+declaration. @var{Name} is the @acronym{XML} name of the type being
+declared (a symbol). @var{Content-type} describes the type and can
+have several different values, as follows:
+
+@itemize @bullet
+@item
+The @acronym{XML} names @samp{EMPTY} and @samp{ANY} correspond to the
+@acronym{XML} keywords of the same name.
+
+@item
+A list @samp{(MIX @var{type} @dots{})} corresponds to the
+@samp{(#PCDATA | @var{type} | @dots{})} syntax.
+@end itemize
+@end deftp
+
+@deftp {record type} xml-!attlist name definitions
+@vindex <xml-!attlist>
+@findex xml-!attlist?
+@findex make-xml-!attlist
+@findex xml-!attlist-name
+@findex xml-!attlist-definitions
+@findex set-xml-!attlist-name!
+@findex set-xml-!attlist-definitions!
+The @code{xml-!attlist} record represents an attribute-list
+declaration. @var{Name} is the @acronym{XML} name of the type for
+which attributes are being declared (a symbol). @var{Definitions} is
+a list of attribute definitions, each of which is a list of three
+elements @code{(@var{name} @var{type} @var{default})}. @var{Name} is
+an @acronym{XML} name for the name of the attribute (a symbol).
+@var{Type} describes the attribute type, and can have one of the
+following values:
+
+@itemize @bullet
+@item
+The @acronym{XML} names @samp{CDATA}, @samp{IDREFS}, @samp{IDREF},
+@samp{ID}, @samp{ENTITY}, @samp{ENTITIES}, @samp{NMTOKENS}, and
+@samp{NMTOKEN} correspond to the @acronym{XML} keywords of the same
+names.
+
+@item
+A list @samp{(NOTATION @var{name1} @var{name2} @dots{})} corresponds
+to the @samp{NOTATION (@var{name1} | @var{name2} @dots{})} syntax.
+
+@item
+A list @samp{(ENUMERATED @var{name1} @var{name2} @dots{})} corresponds
+to the @samp{(@var{name1} | @var{name2} @dots{})} syntax.
+@end itemize
+
+@var{Default} describes the default value for the attribute, and can
+have one of the following values:
+
+@itemize @bullet
+@item
+The @acronym{XML} names @samp{#REQUIRED} and @samp{#IMPLIED}
+correspond to the @acronym{XML} keywords of the same names.
+
+@item
+A list @samp{(#FIXED @var{value})} corresponds to the @samp{#FIXED
+"@var{value}"} syntax. @var{Value} is represented as a string, but
+might also be an @code{xml-uninterpreted} record.
+
+@item
+A list @samp{(DEFAULT @var{value})} corresponds to the
+@samp{"@var{value}"} syntax. @var{Value} is represented as a string,
+but might also be an @code{xml-uninterpreted} record.
+@end itemize
+@end deftp
+
+@deftp {record type} xml-!entity name value
+@vindex <xml-!entity>
+@findex xml-!entity?
+@findex make-xml-!entity
+@findex xml-!entity-name
+@findex xml-!entity-value
+@findex set-xml-!entity-name!
+@findex set-xml-!entity-value!
+The @code{xml-!entity} record represents a general entity
+declaration. @var{Name} is an @acronym{XML} name for the entity.
+@var{Value} is the entity's value, either a string, an
+@code{xml-uninterpreted} record, or an @code{xml-external-id} record.
+@end deftp
+
+@deftp {record type} xml-parameter-!entity name value
+@vindex <xml-parameter-!entity>
+@findex xml-parameter-!entity?
+@findex make-xml-parameter-!entity
+@findex xml-parameter-!entity-name
+@findex xml-parameter-!entity-value
+@findex set-xml-parameter-!entity-name!
+@findex set-xml-parameter-!entity-value!
+The @code{xml-parameter-!entity} record represents a parameter entity
+declaration. @var{Name} is an @acronym{XML} name for the entity.
+@var{Value} is the entity's value, either a string, an
+@code{xml-uninterpreted} record, or an @code{xml-external-id} record.
+@end deftp
+
+@deftp {record type} xml-unparsed-!entity name id notation
+@vindex <xml-unparsed-!entity>
+@findex xml-unparsed-!entity?
+@findex make-xml-unparsed-!entity
+@findex xml-unparsed-!entity-name
+@findex xml-unparsed-!entity-id
+@findex xml-unparsed-!entity-notation
+@findex set-xml-unparsed-!entity-name!
+@findex set-xml-unparsed-!entity-id!
+@findex set-xml-unparsed-!entity-notation!
+The @code{xml-unparsed-!entity} record represents an unparsed entity
+declaration. @code{Name} is an @acronym{XML} name for the entity.
+@var{Id} is an @code{xml-external-id} record. @var{Notation} is an
+@acronym{XML} name for the notation.
+@end deftp
+
+@deftp {record type} xml-!notation name id
+@vindex <xml-!notation>
+@findex xml-!notation?
+@findex make-xml-!notation
+@findex xml-!notation-name
+@findex xml-!notation-id
+@findex set-xml-!notation-name!
+@findex set-xml-!notation-id!
+The @code{xml-!notation} record represents a notation declaration.
+@code{Name} is an @acronym{XML} name for the notation. @var{Id} is an
+@code{xml-external-id} record.
+@end deftp
+
+@deftp {record type} xml-external-id id uri
+@vindex <xml-external-id>
+@findex xml-external-id?
+@findex make-xml-external-id
+@findex xml-external-id-id
+@findex xml-external-id-uri
+@findex set-xml-external-id-id!
+@findex set-xml-external-id-uri!
+The @code{xml-external-id} record is a reference to an external
+@acronym{DTD}. This reference consists of two parts: @var{id} is a
+public @acronym{ID} literal, corresponding to the @samp{PUBLIC}
+keyword, while @var{uri} is a system literal, corresponding to the
+@samp{SYSTEM} keyword. Either or both may be present, depending on
+the context. Each is represented as a string.
+@end deftp
--- /dev/null
+@c This file is part of the MIT/GNU Scheme Reference Manual.
+@c $Id: lists.texi,v 1.1 2003/04/15 03:29:50 cph Exp $
+
+@c Copyright 1991,1992,1993,1994,1995 Massachusetts Institute of Technology
+@c Copyright 1996,1997,1999,2000,2001 Massachusetts Institute of Technology
+@c Copyright 2002,2003 Massachusetts Institute of Technology
+@c See file scheme.texinfo for copying conditions.
+
+@node Lists, Vectors, Strings, Top
+@chapter Lists
+
+@cindex pair (defn)
+@cindex dotted pair (see pair)
+@cindex car field, of pair (defn)
+@cindex cdr field, of pair (defn)
+A @dfn{pair} (sometimes called a @dfn{dotted pair}) is a data structure
+with two fields called the @dfn{car} and @dfn{cdr} fields (for
+historical reasons). Pairs are created by the procedure @code{cons}.
+The car and cdr fields are accessed by the procedures @code{car} and
+@code{cdr}. The car and cdr fields are assigned by the procedures
+@code{set-car!} and @code{set-cdr!}.
+
+@cindex list (defn)
+Pairs are used primarily to represent @dfn{lists}. A list can be
+defined recursively as either the empty list or a pair whose cdr is
+a list. More precisely, the set of lists is defined as the smallest set
+@var{X} such that
+
+@itemize @bullet
+@item
+The empty list is in @var{X}.
+
+@item
+If @var{list} is in @var{X}, then any pair whose cdr field contains
+@var{list} is also in @var{X}.
+@end itemize
+
+@cindex element, of list (defn)
+@cindex length, of list (defn)
+@cindex empty list (defn)
+The objects in the car fields of successive pairs of a list are the
+@dfn{elements} of the list. For example, a two-element list is a pair
+whose car is the first element and whose cdr is a pair whose car is the
+second element and whose cdr is the empty list. The @dfn{length} of a
+list is the number of elements, which is the same as the number of
+pairs. The @dfn{empty list} is a special object of its own type (it is
+not a pair); it has no elements and its length is zero.@footnote{The
+above definitions imply that all lists have finite length and are
+terminated by the empty list.}
+
+@cindex dotted notation, for pair (defn)
+@cindex notation, dotted (defn)
+@cindex external representation, for pair
+@cindex pair, external representation
+@cindex ( as external representation
+@cindex ) as external representation
+@cindex . as external representation
+@cindex parenthesis, as external representation
+@cindex dot, as external representation
+@cindex period, as external representation
+@findex (
+@findex )
+@findex .
+The most general notation (external representation) for Scheme pairs is
+the ``dotted'' notation @code{(@var{c1} . @var{c2})} where @var{c1} is
+the value of the car field and @var{c2} is the value of the cdr field.
+For example, @code{(4 . 5)} is a pair whose car is @code{4} and whose
+cdr is @code{5}. Note that @code{(4 . 5)} is the external
+representation of a pair, not an expression that evaluates to a pair.
+
+@cindex external representation, for list
+@cindex list, external representation
+@cindex external representation, for empty list
+@cindex empty list, external representation
+@findex ()
+A more streamlined notation can be used for lists: the elements of the
+list are simply enclosed in parentheses and separated by spaces. The
+empty list is written @code{()}. For example, the following are
+equivalent notations for a list of symbols:
+
+@example
+@group
+(a b c d e)
+(a . (b . (c . (d . (e . ())))))
+@end group
+@end example
+
+@findex set-cdr!
+Whether a given pair is a list depends upon what is stored in the cdr
+field. When the @code{set-cdr!} procedure is used, an object can be a
+list one moment and not the next:
+
+@example
+@group
+(define x (list 'a 'b 'c))
+(define y x)
+y @result{} (a b c)
+(list? y) @result{} #t
+(set-cdr! x 4) @result{} @r{unspecified}
+x @result{} (a . 4)
+(eqv? x y) @result{} #t
+y @result{} (a . 4)
+(list? y) @result{} #f
+(set-cdr! x x) @result{} @r{unspecified}
+(list? y) @result{} #f
+@end group
+@end example
+
+@cindex improper list (defn)
+@cindex list, improper (defn)
+A chain of pairs that doesn't end in the empty list is called an
+@dfn{improper list}. Note that an improper list is not a list. The
+list and dotted notations can be combined to represent improper lists,
+as the following equivalent notations show:
+
+@example
+@group
+(a b c . d)
+(a . (b . (c . d)))
+@end group
+@end example
+
+@findex quote
+@findex quasiquote
+@findex unquote
+@findex unquote-splicing
+@findex '
+@findex `
+@findex ,
+@findex ,@@
+@findex read
+Within literal expressions and representations of objects read by the
+@code{read} procedure, the forms @code{'@var{datum}},
+@code{`@var{datum}}, @code{,@var{datum}}, and @code{,@@@var{datum}}
+denote two-element lists whose first elements are the symbols
+@code{quote}, @code{quasiquote}, @code{unquote}, and
+@code{unquote-splicing}, respectively. The second element in each case
+is @var{datum}. This convention is supported so that arbitrary Scheme
+programs may be represented as lists. Among other things, this permits
+the use of the @code{read} procedure to parse Scheme programs.
+
+@menu
+* Pairs::
+* Construction of Lists::
+* Selecting List Components::
+* Cutting and Pasting Lists::
+* Filtering Lists::
+* Searching Lists::
+* Mapping of Lists::
+* Reduction of Lists::
+* Miscellaneous List Operations::
+@end menu
+
+@node Pairs, Construction of Lists, Lists, Lists
+@section Pairs
+
+This section describes the simple operations that are available for
+constructing and manipulating arbitrary graphs constructed from pairs.
+
+@deffn procedure pair? object
+@cindex type predicate, for pair
+Returns @code{#t} if @var{object} is a pair; otherwise returns
+@code{#f}.
+
+@example
+@group
+(pair? '(a . b)) @result{} #t
+(pair? '(a b c)) @result{} #t
+(pair? '()) @result{} #f
+(pair? '#(a b)) @result{} #f
+@end group
+@end example
+@end deffn
+
+@deffn procedure cons obj1 obj2
+@cindex construction, of pair
+@findex eqv?
+Returns a newly allocated pair whose car is @var{obj1} and whose cdr is
+@var{obj2}. The pair is guaranteed to be different (in the sense of
+@code{eqv?}) from every previously existing object.
+
+@example
+@group
+(cons 'a '()) @result{} (a)
+(cons '(a) '(b c d)) @result{} ((a) b c d)
+(cons "a" '(b c)) @result{} ("a" b c)
+(cons 'a 3) @result{} (a . 3)
+(cons '(a b) 'c) @result{} ((a b) . c)
+@end group
+@end example
+@end deffn
+
+@deffn procedure car pair
+@cindex selection, of pair component
+@cindex component selection, of pair
+Returns the contents of the car field of @var{pair}. Note that it is an
+error to take the @code{car} of the empty list.
+
+@example
+@group
+(car '(a b c)) @result{} a
+(car '((a) b c d)) @result{} (a)
+(car '(1 . 2)) @result{} 1
+(car '()) @error{} Illegal datum
+@end group
+@end example
+@end deffn
+
+@deffn procedure cdr pair
+Returns the contents of the cdr field of @var{pair}. Note that it is an
+error to take the @code{cdr} of the empty list.
+
+@example
+@group
+(cdr '((a) b c d)) @result{} (b c d)
+(cdr '(1 . 2)) @result{} 2
+(cdr '()) @error{} Illegal datum
+@end group
+@end example
+@end deffn
+
+@deffn procedure set-car! pair object
+Stores @var{object} in the car field of @var{pair}. The value returned
+by @code{set-car!} is unspecified.
+
+@example
+@group
+(define (f) (list 'not-a-constant-list))
+(define (g) '(constant-list))
+(set-car! (f) 3) @result{} @r{unspecified}
+(set-car! (g) 3) @error{} Illegal datum
+@end group
+@end example
+@end deffn
+
+@deffn procedure set-cdr! pair object
+Stores @var{object} in the cdr field of @var{pair}. The value returned
+by @code{set-cdr!} is unspecified.
+@end deffn
+
+@deffn procedure caar pair
+@deffnx procedure cadr pair
+@deffnx procedure cdar pair
+@deffnx procedure cddr pair
+@deffnx procedure caaar pair
+@deffnx procedure caadr pair
+@deffnx procedure cadar pair
+@deffnx procedure caddr pair
+@deffnx procedure cdaar pair
+@deffnx procedure cdadr pair
+@deffnx procedure cddar pair
+@deffnx procedure cdddr pair
+@deffnx procedure caaaar pair
+@deffnx procedure caaadr pair
+@deffnx procedure caadar pair
+@deffnx procedure caaddr pair
+@deffnx procedure cadaar pair
+@deffnx procedure cadadr pair
+@deffnx procedure caddar pair
+@deffnx procedure cadddr pair
+@deffnx procedure cdaaar pair
+@deffnx procedure cdaadr pair
+@deffnx procedure cdadar pair
+@deffnx procedure cdaddr pair
+@deffnx procedure cddaar pair
+@deffnx procedure cddadr pair
+@deffnx procedure cdddar pair
+@deffnx procedure cddddr pair
+These procedures are compositions of @code{car} and @code{cdr}; for
+example, @code{caddr} could be defined by
+
+@example
+(define caddr (lambda (x) (car (cdr (cdr x)))))
+@end example
+@end deffn
+
+@deffn procedure general-car-cdr object path
+This procedure is a generalization of @code{car} and @code{cdr}.
+@var{Path} encodes a particular sequence of @code{car} and @code{cdr}
+operations, which @code{general-car-cdr} executes on @var{object}.
+@var{Path} is an exact non-negative integer that encodes the operations
+in a bitwise fashion: a zero bit represents a @code{cdr} operation, and
+a one bit represents a @code{car}. The bits are executed LSB to MSB,
+and the most significant one bit, rather than being interpreted as an
+operation, signals the end of the sequence.@footnote{Note that
+@var{path} is restricted to a machine-dependent range, usually the size
+of a machine word. On many machines, this means that the maximum length
+of @var{path} will be 30 operations (32 bits, less the sign bit and the
+``end-of-sequence'' bit).}
+
+For example, the following are equivalent:
+@example
+@group
+(general-car-cdr @var{object} #b1011)
+(cdr (car (car @var{object})))
+@end group
+@end example
+
+Here is a partial table of path/operation equivalents:
+
+@example
+@group
+#b10 cdr
+#b11 car
+#b100 cddr
+#b101 cdar
+#b110 cadr
+#b111 caar
+#b1000 cdddr
+@end group
+@end example
+@end deffn
+
+@deffn procedure tree-copy tree
+@cindex copying, of tree
+@cindex tree, copying
+This copies an arbitrary @var{tree} constructed from pairs, copying both
+the car and cdr elements of every pair. This could have been defined by
+
+@example
+@group
+(define (tree-copy tree)
+ (let loop ((tree tree))
+ (if (pair? tree)
+ (cons (loop (car tree)) (loop (cdr tree)))
+ tree)))
+@end group
+@end example
+@end deffn
+
+@node Construction of Lists, Selecting List Components, Pairs, Lists
+@section Construction of Lists
+@cindex construction, of list
+
+@deffn procedure list object @dots{}
+Returns a list of its arguments.
+
+@example
+@group
+(list 'a (+ 3 4) 'c) @result{} (a 7 c)
+(list) @result{} ()
+@end group
+@end example
+
+These expressions are equivalent:
+
+@example
+@group
+(list @var{obj1} @var{obj2} @dots{} @var{objN})
+(cons @var{obj1} (cons @var{obj2} @dots{} (cons @var{objN} '()) @dots{}))
+@end group
+@end example
+@end deffn
+
+@deffn procedure make-list k [element]
+This procedure returns a newly allocated list of length @var{k},
+whose elements are all @var{element}. If @var{element} is not supplied,
+it defaults to the empty list.
+@end deffn
+
+@deffn procedure cons* object object @dots{}
+@findex list
+@code{cons*} is similar to @code{list}, except that @code{cons*} conses
+together the last two arguments rather than consing the last argument
+with the empty list. If the last argument is not a list the result is
+an improper list. If the last argument is a list, the result is a list
+consisting of the initial arguments and all of the items in the final
+argument. If there is only one argument, the result is the argument.
+
+@example
+@group
+(cons* 'a 'b 'c) @result{} (a b . c)
+(cons* 'a 'b '(c d)) @result{} (a b c d)
+(cons* 'a) @result{} a
+@end group
+@end example
+
+These expressions are equivalent:
+
+@example
+@group
+(cons* @var{obj1} @var{obj2} @dots{} @var{objN-1} @var{objN})
+(cons @var{obj1} (cons @var{obj2} @dots{} (cons @var{objN-1} @var{objN}) @dots{}))
+@end group
+@end example
+@end deffn
+
+@deffn procedure list-copy list
+Returns a newly allocated copy of @var{list}. This copies each of the
+pairs comprising @var{list}. This could have been defined by
+
+@example
+@group
+(define (list-copy list)
+ (if (null? list)
+ '()
+ (cons (car list)
+ (list-copy (cdr list)))))
+@end group
+@end example
+@end deffn
+
+@deffn procedure vector->list vector
+@deffnx procedure subvector->list vector start end
+@cindex vector, converting to list
+@findex list->vector
+@code{vector->list} returns a newly allocated list of the elements of
+@var{vector}.@* @code{subvector->list} returns a newly allocated list of
+the elements of the given subvector. The inverse of @code{vector->list}
+is @code{list->vector}.
+
+@example
+(vector->list '#(dah dah didah)) @result{} (dah dah didah)
+@end example
+@end deffn
+
+@deffn {procedure} string->list string
+@deffnx {procedure} substring->list string start end
+@cindex string, converting to list
+@findex list->string
+@code{string->list} returns a newly allocated list of the character
+elements of @var{string}.@*
+@code{substring->list} returns a newly allocated list of the character
+elements of the given substring. The inverse of @code{string->list} is
+@code{list->string}.
+
+@example
+@group
+(string->list "abcd") @result{} (#\a #\b #\c #\d)
+(substring->list "abcdef" 1 3) @result{} (#\b #\c)
+@end group
+@end example
+@end deffn
+
+@node Selecting List Components, Cutting and Pasting Lists, Construction of Lists, Lists
+@section Selecting List Components
+@cindex selection, of list component
+@cindex component selection, of list
+
+@deffn procedure list? object
+@cindex type predicate, for list
+@cindex circular list
+Returns @code{#t} if @var{object} is a list, otherwise returns
+@code{#f}. By definition, all lists have finite length and are
+terminated by the empty list. This procedure returns an answer even for
+circular structures.
+
+@findex pair?
+@findex null?
+Any @var{object} satisfying this predicate will also satisfy exactly one
+of @code{pair?} or @code{null?}.
+
+@example
+@group
+(list? '(a b c)) @result{} #t
+(list? '()) @result{} #t
+(list? '(a . b)) @result{} #f
+(let ((x (list 'a)))
+ (set-cdr! x x)
+ (list? x)) @result{} #f
+@end group
+@end example
+@end deffn
+
+@deffn procedure length list
+Returns the length of @var{list}. Signals an error if @var{list} isn't
+a proper list.
+
+@example
+@group
+(length '(a b c)) @result{} 3
+(length '(a (b) (c d e))) @result{} 3
+(length '()) @result{} 0
+@end group
+@end example
+@end deffn
+
+@deffn procedure null? object
+@cindex type predicate, for empty list
+@cindex empty list, predicate for
+Returns @code{#t} if @var{object} is the empty list; otherwise returns
+@code{#f} (but @pxref{True and False}).
+
+@example
+@group
+(null? '(a . b)) @result{} #f
+(null? '(a b c)) @result{} #f
+(null? '()) @result{} #t
+@end group
+@end example
+@end deffn
+
+@deffn procedure list-ref list k
+@cindex index, of list (defn)
+@cindex valid index, of list (defn)
+@cindex list index (defn)
+Returns the @var{k}th element of @var{list}, using zero-origin indexing.
+The @dfn{valid indexes} of a list are the exact non-negative integers
+less than the length of the list. The first element of a list has index
+@code{0}, the second has index @code{1}, and so on.
+
+@example
+@group
+(list-ref '(a b c d) 2) @result{} c
+(list-ref '(a b c d)
+ (inexact->exact (round 1.8)))
+ @result{} c
+@end group
+@end example
+
+@findex list-tail
+@code{(list-ref @var{list} @var{k})} is equivalent to @code{(car
+(list-tail @var{list} @var{k}))}.
+@end deffn
+
+@deffn procedure first list
+@deffnx procedure second list
+@deffnx procedure third list
+@deffnx procedure fourth list
+@deffnx procedure fifth list
+@deffnx procedure sixth list
+@deffnx procedure seventh list
+@deffnx procedure eighth list
+@deffnx procedure ninth list
+@deffnx procedure tenth list
+Returns the specified element of @var{list}. It is an error if
+@var{list} is not long enough to contain the specified element (for
+example, if the argument to @code{seventh} is a list that contains only
+six elements).
+@end deffn
+
+@node Cutting and Pasting Lists, Filtering Lists, Selecting List Components, Lists
+@section Cutting and Pasting Lists
+@cindex cutting, of list
+@cindex pasting, of lists
+
+@deffn procedure sublist list start end
+@var{Start} and @var{end} must be exact integers satisfying
+
+@example
+0 <= @var{start} <= @var{end} <= (length @var{list})
+@end example
+
+@code{sublist} returns a newly allocated list formed from the elements
+of @var{list} beginning at index @var{start} (inclusive) and ending at
+@var{end} (exclusive).
+@end deffn
+
+@deffn procedure list-head list k
+Returns a newly allocated list consisting of the first @var{k} elements of
+@var{list}. @var{K} must not be greater than the length of
+@var{list}.
+
+We could have defined @code{list-head} this way:
+
+@example
+@group
+(define (list-head list k)
+ (sublist list 0 k))
+@end group
+@end example
+@end deffn
+
+@deffn procedure list-tail list k
+Returns the sublist of @var{list} obtained by omitting the first @var{k}
+elements. The result, if it is not the empty list, shares structure
+with @var{list}. @var{K} must not be greater than the length of
+@var{list}.
+@end deffn
+
+@deffn {procedure} append list @dots{}
+@cindex appending, of lists
+Returns a list consisting of the elements of the first @var{list}
+followed by the elements of the other @var{list}s.
+
+@example
+@group
+(append '(x) '(y)) @result{} (x y)
+(append '(a) '(b c d)) @result{} (a b c d)
+(append '(a (b)) '((c))) @result{} (a (b) (c))
+(append) @result{} ()
+@end group
+@end example
+
+The resulting list is always newly allocated, except that it shares
+structure with the last @var{list} argument. The last argument may
+actually be any object; an improper list results if the last argument is
+not a proper list.
+
+@example
+@group
+(append '(a b) '(c . d)) @result{} (a b c . d)
+(append '() 'a) @result{} a
+@end group
+@end example
+@end deffn
+
+@deffn procedure append! list @dots{}
+Returns a list that is the argument @var{list}s concatenated together.
+The arguments are changed rather than copied. (Compare this with
+@code{append}, which copies arguments rather than destroying them.) For
+example:
+
+@example
+@group
+(define x '(a b c))
+(define y '(d e f))
+(define z '(g h))
+(append! x y z) @result{} (a b c d e f g h)
+x @result{} (a b c d e f g h)
+y @result{} (d e f g h)
+z @result{} (g h)
+@end group
+@end example
+@end deffn
+
+@deffn procedure last-pair list
+Returns the last pair in @var{list}, which may be an improper list.
+@code{last-pair} could have been defined this way:
+
+@example
+@group
+(define last-pair
+ (lambda (x)
+ (if (pair? (cdr x))
+ (last-pair (cdr x))
+ x)))
+@end group
+@end example
+@end deffn
+
+@deffn procedure except-last-pair list
+@deffnx procedure except-last-pair! list
+These procedures remove the last pair from @var{list}. @var{List} may
+be an improper list, except that it must consist of at least one pair.
+@code{except-last-pair} returns a newly allocated copy of @var{list}
+that omits the last pair. @code{except-last-pair!} destructively
+removes the last pair from @var{list} and returns @var{list}. If the
+cdr of @var{list} is not a pair, the empty list is returned by either
+procedure.
+@end deffn
+
+@node Filtering Lists, Searching Lists, Cutting and Pasting Lists, Lists
+@section Filtering Lists
+@cindex filtering, of list
+@cindex deletion, of list element
+
+@deffn procedure keep-matching-items list predicate
+@deffnx procedure delete-matching-items list predicate
+These procedures return a newly allocated copy of @var{list} containing
+only the elements for which @var{predicate} is (respectively) true or
+false. @var{Predicate} must be a procedure of one argument.
+
+@example
+@group
+(keep-matching-items '(1 2 3 4 5) odd?) @result{} (1 3 5)
+(delete-matching-items '(1 2 3 4 5) odd?) @result{} (2 4)
+@end group
+@end example
+
+@findex list-transform-positive
+@findex list-transform-negative
+For compatibility, the procedure @code{list-transform-positive} is an
+alias for @code{keep-matching-items}, and @code{list-transform-negative}
+is an alias for @code{delete-matching-items}.
+@end deffn
+
+@deffn procedure keep-matching-items! list predicate
+@deffnx procedure delete-matching-items! list predicate
+These procedures are exactly like @code{keep-matching-items} and
+@code{delete-matching-items}, respectively, except that they
+destructively modify the @var{list} argument rather than allocating a
+new result.
+@end deffn
+
+@deffn procedure delq element list
+@deffnx procedure delv element list
+@deffnx procedure delete element list
+@findex eq?
+@findex eqv?
+@findex equal?
+Returns a newly allocated copy of @var{list} with all entries equal to
+@var{element} removed. @code{delq} uses @code{eq?} to compare
+@var{element} with the entries in @var{list}, @code{delv} uses
+@code{eqv?}, and @code{delete} uses @code{equal?}.
+@end deffn
+
+@deffn procedure delq! element list
+@deffnx procedure delv! element list
+@deffnx procedure delete! element list
+@findex eq?
+@findex eqv?
+@findex equal?
+Returns a list consisting of the top-level elements of @var{list} with
+all entries equal to @var{element} removed. These procedures are like
+@code{delq}, @code{delv}, and @code{delete} except that they
+destructively modify @var{list}. @code{delq!} uses @code{eq?} to
+compare element with the entries in @var{list}, @code{delv!} uses
+@code{eqv?}, and @code{delete!} uses @code{equal?}. Because the result
+may not be @code{eq?} to @var{list}, it is desirable to do something
+like @code{(set! x (delete! x))}.
+
+@example
+@group
+(define x '(a b c b))
+(delete 'b x) @result{} (a c)
+x @result{} (a b c b)
+
+(define x '(a b c b))
+(delete! 'b x) @result{} (a c)
+x @result{} (a c)
+@r{;; Returns correct result:}
+(delete! 'a x) @result{} (c)
+
+@r{;; Didn't modify what x points to:}
+x @result{} (a c)
+@end group
+@end example
+@end deffn
+
+@deffn procedure delete-member-procedure deletor predicate
+@findex list-deletor
+@findex list-deletor!
+@findex delv
+@findex delete!
+Returns a deletion procedure similar to @code{delv} or @code{delete!}.
+@var{Deletor} should be one of the procedures @code{list-deletor} or
+@code{list-deletor!}. @var{Predicate} must be an equivalence predicate.
+The returned procedure accepts exactly two arguments: first, an object
+to be deleted, and second, a list of objects from which it is to be
+deleted. If @var{deletor} is @code{list-deletor}, the procedure
+returns a newly allocated copy of the given list in which all entries
+equal to the given object have been removed. If @var{deletor} is
+@code{list-deletor!}, the procedure returns a list consisting of the
+top-level elements of the given list with all entries equal to the given
+object removed; the given list is destructively modified to produce the
+result. In either case @var{predicate} is used to compare the given
+object to the elements of the given list.
+
+Here are some examples that demonstrate how
+@code{delete-member-procedure} could have been used to implement
+@code{delv} and @code{delete!}:
+
+@example
+@group
+(define delv
+ (delete-member-procedure list-deletor eqv?))
+(define delete!
+ (delete-member-procedure list-deletor! equal?))
+@end group
+@end example
+@end deffn
+
+@deffn procedure list-deletor predicate
+@deffnx procedure list-deletor! predicate
+These procedures each return a procedure that deletes elements from
+lists. @var{Predicate} must be a procedure of one argument. The
+returned procedure accepts exactly one argument, which must be a proper
+list, and applies @var{predicate} to each of the elements of the
+argument, deleting those for which it is true.
+
+The procedure returned by @code{list-deletor} deletes elements
+non-destructively, by returning a newly allocated copy of the argument
+with the appropriate elements removed. The procedure returned by
+@code{list-deletor!} performs a destructive deletion.
+@end deffn
+
+@node Searching Lists, Mapping of Lists, Filtering Lists, Lists
+@section Searching Lists
+@cindex searching, of list
+
+@deffn procedure find-matching-item list predicate
+Returns the first element in @var{list} for which @var{predicate} is
+true; returns @code{#f} if it doesn't find such an element. (This means
+that if @var{predicate} is true for @code{#f}, it may be impossible to
+distinguish a successful result from an unsuccessful one.)
+@var{Predicate} must be a procedure of one argument.
+
+@findex list-search-positive
+@findex list-search-negative
+For compatibility, @code{list-search-positive} is an alias for
+@code{find-matching-item}. @code{list-search-negative} is similar but
+the sense of the predicate is reversed.
+@end deffn
+
+@deffn procedure memq object list
+@deffnx procedure memv object list
+@deffnx procedure member object list
+@findex eq?
+@findex eqv?
+@findex equal?
+These procedures return the first pair of @var{list} whose car is
+@var{object}; the returned pair is always one from which @var{list} is
+composed. If @var{object} does not occur in @var{list}, @code{#f}
+(n.b.: not the empty list) is returned. @code{memq} uses @code{eq?} to
+compare @var{object} with the elements of @var{list}, while @code{memv}
+uses @code{eqv?} and @code{member} uses @code{equal?}.@footnote{Although
+they are often used as predicates, @code{memq}, @code{memv}, and
+@code{member} do not have question marks in their names because they
+return useful values rather than just @code{#t} or @code{#f}.}
+
+@example
+@group
+(memq 'a '(a b c)) @result{} (a b c)
+(memq 'b '(a b c)) @result{} (b c)
+(memq 'a '(b c d)) @result{} #f
+(memq (list 'a) '(b (a) c)) @result{} #f
+(member (list 'a) '(b (a) c)) @result{} ((a) c)
+(memq 101 '(100 101 102)) @result{} @r{unspecified}
+(memv 101 '(100 101 102)) @result{} (101 102)
+@end group
+@end example
+@end deffn
+
+@deffn procedure member-procedure predicate
+Returns a procedure similar to @code{memq}, except that @var{predicate},
+which must be an equivalence predicate, is used instead of @code{eq?}.
+This could be used to define @code{memv} as follows:
+
+@example
+(define memv (member-procedure eqv?))
+@end example
+@end deffn
+
+@need 1000
+@node Mapping of Lists, Reduction of Lists, Searching Lists, Lists
+@section Mapping of Lists
+@cindex mapping, of list
+
+@deffn {procedure} map procedure list list @dots{}
+@var{Procedure} must be a procedure taking as many arguments as there
+are @var{list}s. If more than one @var{list} is given, then they must
+all be the same length. @code{map} applies @var{procedure} element-wise
+to the elements of the @var{list}s and returns a list of the results, in
+order from left to right. The dynamic order in which @var{procedure} is
+applied to the elements of the @var{list}s is unspecified; use
+@code{for-each} to sequence side effects.
+
+@example
+@group
+(map cadr '((a b) (d e) (g h))) @result{} (b e h)
+(map (lambda (n) (expt n n)) '(1 2 3 4)) @result{} (1 4 27 256)
+(map + '(1 2 3) '(4 5 6)) @result{} (5 7 9)
+(let ((count 0))
+ (map (lambda (ignored)
+ (set! count (+ count 1))
+ count)
+ '(a b c))) @result{} @r{unspecified}
+@end group
+@end example
+@end deffn
+
+@deffn procedure map* initial-value procedure list1 list2 @dots{}
+Similar to @code{map}, except that the resulting list is terminated by
+@var{initial-value} rather than the empty list. The following are
+equivalent:
+
+@example
+@group
+(map @var{procedure} @var{list} @var{list} @dots{})
+(map* '() @var{procedure} @var{list} @var{list} @dots{})
+@end group
+@end example
+@end deffn
+
+@deffn procedure append-map procedure list list @dots{}
+@deffnx procedure append-map* initial-value procedure list list @dots{}
+@findex append
+Similar to @code{map} and @code{map*}, respectively, except that the
+results of applying @var{procedure} to the elements of @var{list}s are
+concatenated together by @code{append} rather than by @code{cons}. The
+following are equivalent, except that the former is more efficient:
+
+@example
+@group
+(append-map @var{procedure} @var{list} @var{list} @dots{})
+(apply append (map @var{procedure} @var{list} @var{list} @dots{}))
+@end group
+@end example
+@end deffn
+
+@deffn procedure append-map! procedure list list @dots{}
+@deffnx procedure append-map*! initial-value procedure list list @dots{}
+@findex append!
+Similar to @code{map} and @code{map*}, respectively, except that the
+results of applying @var{procedure} to the elements of @var{list}s are
+concatenated together by @code{append!} rather than by @code{cons}. The
+following are equivalent, except that the former is more efficient:
+
+@example
+@group
+(append-map! @var{procedure} @var{list} @var{list} @dots{})
+(apply append! (map @var{procedure} @var{list} @var{list} @dots{}))
+@end group
+@end example
+@end deffn
+
+@deffn {procedure} for-each procedure list list @dots{}
+The arguments to @code{for-each} are like the arguments to @code{map},
+but @code{for-each} calls @var{procedure} for its side effects rather
+than for its values. Unlike @code{map}, @code{for-each} is guaranteed
+to call @var{procedure} on the elements of the @var{list}s in order from
+the first element to the last, and the value returned by @code{for-each}
+is unspecified.
+
+@example
+@group
+(let ((v (make-vector 5)))
+ (for-each (lambda (i)
+ (vector-set! v i (* i i)))
+ '(0 1 2 3 4))
+ v) @result{} #(0 1 4 9 16)
+@end group
+@end example
+@end deffn
+
+@node Reduction of Lists, Miscellaneous List Operations, Mapping of Lists, Lists
+@section Reduction of Lists
+@cindex reduction, of list
+
+@deffn procedure reduce procedure initial list
+Combines all the elements of @var{list} using the binary operation
+@var{procedure}. For example, using @code{+} one can add up all the
+elements:
+
+@example
+(reduce + 0 list-of-numbers)
+@end example
+
+The argument @var{initial} is used only if @var{list} is empty; in this
+case @var{initial} is the result of the call to @code{reduce}. If
+@var{list} has a single argument, it is returned. Otherwise, the arguments
+are reduced in a left-associative fashion. For example:
+
+@example
+@group
+(reduce + 0 '(1 2 3 4)) @result{} 10
+(reduce + 0 '(1 2)) @result{} 3
+(reduce + 0 '(1)) @result{} 1
+(reduce + 0 '()) @result{} 0
+(reduce + 0 '(foo)) @result{} foo
+(reduce list '() '(1 2 3 4)) @result{} (((1 2) 3) 4)
+@end group
+@end example
+@end deffn
+
+@deffn procedure reduce-right procedure initial list
+Like @code{reduce} except that it is right-associative.
+
+@example
+(reduce-right list '() '(1 2 3 4)) @result{} (1 (2 (3 4)))
+@end example
+@end deffn
+
+@deffn procedure fold-right procedure initial list
+Combines all of the elements of @var{list} using the binary operation
+@var{procedure}. Unlike @code{reduce} and @code{reduce-right},
+@var{initial} is always used:
+
+@example
+@group
+(fold-right + 0 '(1 2 3 4)) @result{} 10
+(fold-right + 0 '(foo)) @error{} Illegal datum
+(fold-right list '() '(1 2 3 4)) @result{} (1 (2 (3 (4 ()))))
+@end group
+@end example
+
+@code{Fold-right} has interesting properties because it establishes a
+homomorphism between (@code{cons}, @code{()}) and (@var{procedure},
+@var{initial}). It can be thought of as replacing the pairs in the
+spine of the list with @var{procedure} and replacing the @code{()} at
+the end with @var{initial}. Many of the classical list-processing
+procedures can be expressed in terms of @code{fold-right}, at least for
+the simple versions that take a fixed number of arguments:
+
+@example
+@group
+(define (copy-list list)
+ (fold-right cons '() list))
+
+(define (append list1 list2)
+ (fold-right cons list2 list1))
+
+(define (map p list)
+ (fold-right (lambda (x r) (cons (p x) r)) '() list))
+
+(define (reverse items)
+ (fold-right (lambda (x r) (append r (list x))) '() items))
+@end group
+@end example
+@end deffn
+
+@deffn procedure fold-left procedure initial list
+Combines all the elements of @var{list} using the binary operation
+@var{procedure}. Elements are combined starting with @var{initial} and
+then the elements of @var{list} from left to right. Whereas
+@code{fold-right} is recursive in nature, capturing the essence of
+@code{cdr}-ing down a list and then computing a result, @var{fold-left}
+is iterative in nature, combining the elements as the list is traversed.
+
+@example
+@group
+(fold-left list '() '(1 2 3 4)) @result{} ((((() 1) 2) 3) 4)
+
+(define (length list)
+ (fold-left (lambda (sum element) (+ sum 1)) 0 list))
+
+(define (reverse items)
+ (fold-left (lambda (x y) (cons y x)) () items))
+@end group
+@end example
+@end deffn
+
+@deffn procedure there-exists? list predicate
+@var{Predicate} must be a procedure of one argument. Applies
+@var{predicate} to each element of @var{list}, in order from left to
+right. If @var{predicate} is true for any element of @var{list}, the
+value yielded by @var{predicate} is immediately returned as the value of
+@code{there-exists?}; @var{predicate} will not be applied to the
+remaining elements of @var{list}. If @var{predicate} returns @code{#f}
+for all of the elements of @var{list}, then @code{#f} is returned.
+@end deffn
+
+@deffn procedure for-all? list predicate
+@var{Predicate} must be a procedure of one argument. Applies
+@var{predicate} to each element of @var{list}, in order from left to
+right. If @var{predicate} returns @code{#f} for any element of
+@var{list}, @code{#f} is immediately returned as the value of
+@code{for-all?}; @var{predicate} will not be applied to the remaining
+elements of @var{list}. If @var{predicate} is true for all of the
+elements of @var{list}, then @code{#t} is returned.
+@end deffn
+
+@node Miscellaneous List Operations, , Reduction of Lists, Lists
+@section Miscellaneous List Operations
+
+@deffn procedure circular-list object @dots{}
+@deffnx procedure make-circular-list k [element]
+@cindex circular list
+@cindex construction, of circular list
+@findex list
+@findex make-list
+These procedures are like @code{list} and @code{make-list},
+respectively, except that the returned lists are circular.
+@code{circular-list} could have been defined like this:
+
+@example
+@group
+(define (circular-list . objects)
+ (append! objects objects))
+@end group
+@end example
+@end deffn
+
+@deffn procedure reverse list
+@cindex reversal, of list
+Returns a newly allocated list consisting of the top-level elements of
+@var{list} in reverse order.
+
+@example
+@group
+(reverse '(a b c)) @result{} (c b a)
+(reverse '(a (b c) d (e (f)))) @result{} ((e (f)) d (b c) a)
+@end group
+@end example
+@end deffn
+
+@deffn procedure reverse! list
+Returns a list consisting of the top-level elements of @var{list} in
+reverse order. @code{reverse!} is like @code{reverse}, except that it
+destructively modifies @var{list}. Because the result may not be
+@code{eqv?} to @var{list}, it is desirable to do something like
+@code{(set! x (reverse! x))}.
+@end deffn
+
+@deffn procedure sort sequence procedure
+@deffnx procedure merge-sort sequence procedure
+@deffnx procedure quick-sort sequence procedure
+@cindex total ordering (defn)
+@var{Sequence} must be either a list or a vector. @var{Procedure} must be a
+procedure of two arguments that defines a @dfn{total ordering} on the
+elements of @var{sequence}. In other words, if @var{x} and @var{y} are two
+distinct elements of @var{sequence}, then it must be the case that
+
+@example
+@group
+(and (@var{procedure} @var{x} @var{y})
+ (@var{procedure} @var{y} @var{x}))
+ @result{} #f
+@end group
+@end example
+
+If @var{sequence} is a list (vector), @code{sort} returns a newly
+allocated list (vector) whose elements are those of @var{sequence},
+except that they are rearranged to be sorted in the order defined by
+@var{procedure}. So, for example, if the elements of @var{sequence} are
+numbers, and @var{procedure} is @code{<}, then the resulting elements
+are sorted in monotonically nondecreasing order. Likewise, if
+@var{procedure} is @code{>}, the resulting elements are sorted in
+monotonically nonincreasing order. To be precise, if @var{x} and
+@var{y} are any two adjacent elements in the result, where @var{x}
+precedes @var{y}, it is the case that
+
+@example
+@group
+(@var{procedure} @var{y} @var{x})
+ @result{} #f
+@end group
+@end example
+
+Two sorting algorithms are implemented: @code{merge-sort} and
+@code{quick-sort}. The procedure @code{sort} is an alias for
+@code{merge-sort}.
+
+See also the definition of @code{sort!}.
+@end deffn
--- /dev/null
+@c This file is part of the MIT/GNU Scheme Reference Manual.
+@c $Id: misc-datatypes.texi,v 1.1 2003/04/15 03:29:53 cph Exp $
+
+@c Copyright 1991,1992,1993,1994,1995 Massachusetts Institute of Technology
+@c Copyright 1996,1997,1999,2000,2001 Massachusetts Institute of Technology
+@c Copyright 2002,2003 Massachusetts Institute of Technology
+@c See file scheme.texinfo for copying conditions.
+
+@node Miscellaneous Datatypes, Associations, Bit Strings, Top
+@chapter Miscellaneous Datatypes
+
+@menu
+* Booleans::
+* Symbols::
+* Cells::
+* Records::
+* Promises::
+* Streams::
+* Weak Pairs::
+@end menu
+
+@node Booleans, Symbols, Miscellaneous Datatypes, Miscellaneous Datatypes
+@section Booleans
+
+@findex #t
+@findex #f
+@cindex #t as external representation
+@cindex #f as external representation
+@cindex boolean object (defn)
+@cindex true, boolean object (defn)
+@cindex false, boolean object (defn)
+The @dfn{boolean objects} are @dfn{true} and @dfn{false}. The boolean
+constant true is written as @samp{#t}, and the boolean constant false is
+written as @samp{#f}.
+
+@findex if
+@findex cond
+@findex and
+@findex or
+The primary use for boolean objects is in the conditional expressions
+@code{if}, @code{cond}, @code{and}, and @code{or}; the behavior of these
+expressions is determined by whether objects are true or false. These
+expressions count only @code{#f} as false. They count everything else,
+including @code{#t}, pairs, symbols, numbers, strings, vectors, and
+procedures as true (but @pxref{True and False}).
+
+@findex t
+@findex nil
+Programmers accustomed to other dialects of Lisp should note that Scheme
+distinguishes @code{#f} and the empty list from the symbol @code{nil}.
+Similarly, @code{#t} is distinguished from the symbol @code{t}. In
+fact, the boolean objects (and the empty list) are not symbols at all.
+
+Boolean constants evaluate to themselves, so you don't need to quote
+them.
+
+@example
+@group
+#t @result{} #t
+#f @result{} #f
+'#f @result{} #f
+t @error{} Unbound variable
+@end group
+@end example
+
+@defvr variable false
+@defvrx variable true
+These variables are bound to the objects @code{#f} and @code{#t}
+respectively. The compiler, given the @code{usual-integrations}
+declaration, replaces references to these variables with their
+respective values.
+
+Note that the symbol @code{true} is not equivalent to @code{#t}, and the
+symbol @code{false} is not equivalent to @code{#f}.
+@end defvr
+
+@deffn procedure boolean? object
+@cindex type predicate, for boolean
+Returns @code{#t} if @var{object} is either @code{#t} or @code{#f};
+otherwise returns @code{#f}.
+
+@example
+@group
+(boolean? #f) @result{} #t
+(boolean? 0) @result{} #f
+@end group
+@end example
+@end deffn
+
+@deffn procedure not object
+@deffnx procedure false? object
+@cindex false, predicate for
+@cindex inverse, of boolean object
+These procedures return @code{#t} if @var{object} is false; otherwise
+they return @code{#f}. In other words they @emph{invert} boolean
+values. These two procedures have identical semantics; their names are
+different to give different connotations to the test.
+
+@example
+@group
+(not #t) @result{} #f
+(not 3) @result{} #f
+(not (list 3)) @result{} #f
+(not #f) @result{} #t
+@end group
+@end example
+@end deffn
+
+@deffn procedure boolean=? obj1 obj2
+@cindex boolean object, equivalence predicate
+@cindex equivalence predicate, for boolean objects
+@cindex comparison, of boolean objects
+This predicate is true iff @var{obj1} and @var{obj2} are either both true
+or both false.
+@end deffn
+
+@deffn procedure boolean/and object @dots{}
+This procedure returns @code{#t} if none of its arguments are @code{#f}.
+Otherwise it returns @code{#f}.
+@end deffn
+
+@deffn procedure boolean/or object @dots{}
+This procedure returns @code{#f} if all of its arguments are @code{#f}.
+Otherwise it returns @code{#t}.
+@end deffn
+
+@node Symbols, Cells, Booleans, Miscellaneous Datatypes
+@section Symbols
+
+@cindex symbol (defn)
+@cindex interned symbol (defn)
+@cindex uninterned symbol (defn)
+@cindex property list, of symbol
+@cindex disembodied property list
+@findex read
+MIT/GNU Scheme provides two types of symbols: @dfn{interned} and
+@dfn{uninterned}. Interned symbols are far more common than uninterned
+symbols, and there are more ways to create them. Interned symbols have
+an external representation that is recognized by the procedure
+@code{read}; uninterned symbols do not.@footnote{In older dialects of
+Lisp, uninterned symbols were fairly important. This was true because
+symbols were complicated data structures: in addition to having value
+cells (and sometimes, function cells), these structures contained
+@dfn{property lists}. Because of this, uninterned symbols were often
+used merely for their property lists --- sometimes an uninterned symbol
+used this way was referred to as a @dfn{disembodied property list}. In
+MIT/GNU Scheme, symbols do not have property lists, or any other components
+besides their names. There is a different data structure similar to
+disembodied property lists: one-dimensional tables (@pxref{1D Tables}).
+For these reasons, uninterned symbols are not very useful in MIT/GNU Scheme.
+In fact, their primary purpose is to simplify the generation of unique
+variable names in programs that generate Scheme code.}
+
+@findex string=?
+@findex eq?
+Interned symbols have an extremely useful property: any two interned
+symbols whose names are the same, in the sense of @code{string=?}, are
+the same object (i.e.@: they are @code{eq?} to one another). The term
+@dfn{interned} refers to the process of @dfn{interning} by which this is
+accomplished. Uninterned symbols do not share this property.
+
+@cindex case, of interned symbol
+@cindex alphabetic case, of interned symbol
+@findex write
+The names of interned symbols are not distinguished by their alphabetic
+case. Because of this, MIT/GNU Scheme converts all alphabetic
+characters in the name of an interned symbol to a specific case (lower
+case) when the symbol is created. When the name of an interned symbol
+is referenced (using @code{symbol->string}) or written (using
+@code{write}) it appears in this case. It is a bad idea to depend on
+the name being lower case. In fact, it is preferable to take this one
+step further: don't depend on the name of a symbol being in a uniform
+case.
+
+@cindex external representation, for symbol
+@findex read
+@findex write
+The rules for writing an interned symbol are the same as the rules for
+writing an identifier (@pxref{Identifiers}). Any interned symbol that
+has been returned as part of a literal expression, or read using the
+@code{read} procedure and subsequently written out using the
+@code{write} procedure, will read back in as the identical symbol (in
+the sense of @code{eq?}).
+
+Usually it is also true that reading in an interned symbol that was
+previously written out produces the same symbol. An exception are
+symbols created by the procedures @code{string->symbol} and
+@code{intern}; they can create symbols for which this write/read
+invariance may not hold because the symbols' names contain special
+characters or letters in the non-standard case.@footnote{MIT/GNU Scheme
+reserves a specific set of interned symbols for its own use. If you use
+these reserved symbols it is possible that you could break specific
+pieces of software that depend on them. The reserved symbols all have
+names beginning with the characters @samp{#[} and ending with the
+character @samp{]}; thus none of these symbols can be read by the
+procedure @code{read} and hence are not likely to be used by accident.
+For example, @code{(intern "#[unnamed-procedure]")} produces a reserved
+symbol.}
+
+@findex read
+The external representation for uninterned symbols is special, to
+distinguish them from interned symbols and prevent them from being
+recognized by the @code{read} procedure:
+
+@example
+@group
+(string->uninterned-symbol "foo")
+ @result{} #[uninterned-symbol 30 foo]
+@end group
+@end example
+
+In this section, the procedures that return symbols as values will
+either always return interned symbols, or always return uninterned
+symbols. The procedures that accept symbols as arguments will always
+accept either interned or uninterned symbols, and do not distinguish the
+two.
+
+@deffn procedure symbol? object
+@cindex type predicate, for symbol
+Returns @code{#t} if @var{object} is a symbol, otherwise returns
+@code{#f}.
+
+@example
+@group
+(symbol? 'foo) @result{} #t
+(symbol? (car '(a b))) @result{} #t
+(symbol? "bar") @result{} #f
+@end group
+@end example
+@end deffn
+
+@deffn procedure symbol->string symbol
+@cindex name, of symbol
+@cindex print name, of symbol
+@findex string=?
+@findex string-set!
+Returns the name of @var{symbol} as a string. If @var{symbol} was
+returned by @code{string->symbol}, the value of this procedure will be
+identical (in the sense of @code{string=?}) to the string that was
+passed to @code{string->symbol}. It is an error to apply mutation
+procedures such as @code{string-set!} to strings returned by this
+procedure.
+
+@example
+@group
+(symbol->string 'flying-fish) @result{} "flying-fish"
+(symbol->string 'Martin) @result{} "martin"
+(symbol->string (string->symbol "Malvina"))
+ @result{} "Malvina"
+@end group
+@end example
+
+Note that two distinct uninterned symbols can have the same name.
+@end deffn
+
+@deffn procedure intern string
+@cindex interning, of symbols
+@cindex construction, of symbols
+Returns the interned symbol whose name is @var{string}. Converts
+@var{string} to the standard alphabetic case before generating the
+symbol. This is the preferred way to create interned symbols, as it
+guarantees the following independent of which case the implementation
+uses for symbols' names:
+
+@example
+(eq? 'bitBlt (intern "bitBlt")) @result{} #t
+@end example
+
+The user should take care that @var{string} obeys the rules for
+identifiers (@pxref{Identifiers}), otherwise the resulting symbol cannot
+be read as itself.
+@end deffn
+
+@deffn procedure intern-soft string
+Returns the interned symbol whose name is @var{string}. Converts
+@var{string} to the standard alphabetic case before generating the
+symbol. If no such interned symbol exists, returns @code{#f}.
+
+This is exactly like @code{intern}, except that it will not create an
+interned symbol, but only returns symbols that already exist.
+@end deffn
+
+@deffn procedure string->symbol string
+@cindex string, interning as symbol
+Returns the interned symbol whose name is @var{string}. Although you
+can use this procedure to create symbols with names containing special
+characters or lowercase letters, it's usually a bad idea to create such
+symbols because they cannot be read as themselves. See
+@code{symbol->string}.
+
+@example
+@group
+(eq? 'mISSISSIppi 'mississippi) @result{} #t
+(string->symbol "mISSISSIppi")
+ @result{} @r{the symbol with the name} "mISSISSIppi"
+(eq? 'bitBlt (string->symbol "bitBlt")) @result{} #f
+(eq? 'JollyWog
+ (string->symbol
+ (symbol->string 'JollyWog))) @result{} #t
+(string=? "K. Harper, M.D."
+ (symbol->string
+ (string->symbol
+ "K. Harper, M.D."))) @result{} #t
+@end group
+@end example
+@end deffn
+
+@deffn procedure string->uninterned-symbol string
+Returns a newly allocated uninterned symbol whose name is @var{string}.
+It is unimportant what case or characters are used in
+@var{string}.
+
+Note: this is the fastest way to make a symbol.
+@end deffn
+
+@deffn procedure generate-uninterned-symbol [object]
+@cindex gensym (see uninterned symbol)
+@findex eq?
+Returns a newly allocated uninterned symbol that is guaranteed to be
+different from any other object. The symbol's name consists of a prefix
+string followed by the (exact non-negative integer) value of an internal
+counter. The counter is initially zero, and is incremented after each
+call to this procedure.
+
+The optional argument @var{object} is used to control how the symbol is
+generated. It may take one of the following values:
+
+@itemize @bullet
+@item
+If @var{object} is omitted or @code{#f}, the prefix is @code{"G"}.
+
+@item
+If @var{object} is an exact non-negative integer, the internal counter
+is set to that integer prior to generating the result.
+
+@item
+If @var{object} is a string, it is used as the prefix.
+
+@item
+If @var{object} is a symbol, its name is used as the prefix.
+@end itemize
+
+@example
+@group
+(generate-uninterned-symbol)
+ @result{} #[uninterned-symbol 31 G0]
+(generate-uninterned-symbol)
+ @result{} #[uninterned-symbol 32 G1]
+(generate-uninterned-symbol 'this)
+ @result{} #[uninterned-symbol 33 this2]
+(generate-uninterned-symbol)
+ @result{} #[uninterned-symbol 34 G3]
+(generate-uninterned-symbol 100)
+ @result{} #[uninterned-symbol 35 G100]
+(generate-uninterned-symbol)
+ @result{} #[uninterned-symbol 36 G101]
+@end group
+@end example
+@end deffn
+
+@deffn procedure symbol-append symbol @dots{}
+@cindex appending, of symbols
+@cindex pasting, of symbols
+Returns the interned symbol whose name is formed by concatenating the
+names of the given symbols. This procedure preserves the case of the
+names of its arguments, so if one or more of the arguments' names has
+non-standard case, the result will also have non-standard case.
+
+@example
+@group
+(symbol-append 'foo- 'bar) @result{} foo-bar
+@r{;; the arguments may be uninterned:}
+(symbol-append 'foo- (string->uninterned-symbol "baz"))
+ @result{} foo-baz
+@r{;; the result has the same case as the arguments:}
+(symbol-append 'foo- (string->symbol "BAZ")) @result{} foo-BAZ
+@end group
+@end example
+@end deffn
+
+@deffn procedure symbol-hash symbol
+@cindex hashing, of symbol
+@findex string-hash
+Returns a hash number for @var{symbol}, which is computed by calling
+@code{string-hash} on @var{symbol}'s name. The hash number is an exact
+non-negative integer.
+@end deffn
+
+@deffn procedure symbol-hash-mod symbol modulus
+@var{Modulus} must be an exact positive integer. Equivalent to
+
+@example
+@group
+(modulo (symbol-hash @var{symbol}) @var{modulus})
+@end group
+@end example
+
+This procedure is provided for convenience in constructing hash tables.
+However, it is normally preferable to use @code{make-eq-hash-table} to
+build hash tables keyed by symbols, because @code{eq?} hash tables are
+much faster.
+@end deffn
+
+@deffn procedure symbol<? symbol1 symbol2
+This procedure computes a total order on symbols. It is equivalent to
+
+@example
+@group
+(string<? (symbol->string @var{symbol1})
+ (symbol->string @var{symbol2}))
+@end group
+@end example
+@end deffn
+
+@node Cells, Records, Symbols, Miscellaneous Datatypes
+@section Cells
+
+@cindex cell (defn)
+@dfn{Cells} are data structures similar to pairs except that they have
+only one element. They are useful for managing state.
+
+@deffn procedure cell? object
+@cindex type predicate, for cell
+Returns @code{#t} if @var{object} is a cell; otherwise returns
+@code{#f}.
+@end deffn
+
+@deffn procedure make-cell object
+@cindex construction, of cell
+Returns a newly allocated cell whose contents is @var{object}.
+@end deffn
+
+@deffn procedure cell-contents cell
+@cindex selection, of cell component
+@cindex component selection, of cell
+Returns the current contents of @var{cell}.
+@end deffn
+
+@deffn procedure set-cell-contents! cell object
+Alters the contents of @var{cell} to be @var{object}. Returns an
+unspecified value.
+@end deffn
+
+@deffn procedure bind-cell-contents! cell object thunk
+Alters the contents of @var{cell} to be @var{object}, calls @var{thunk}
+with no arguments, then restores the original contents of @var{cell} and
+returns the value returned by @var{thunk}. This is completely
+equivalent to dynamic binding of a variable, including the behavior when
+continuations are used (@pxref{Dynamic Binding}).
+@end deffn
+
+@node Records, Promises, Cells, Miscellaneous Datatypes
+@section Records
+
+MIT/GNU Scheme provides a @dfn{record} abstraction, which is a simple and
+flexible mechanism for building structures with named components.
+Records can be defined and accessed using the procedures defined in this
+section. A less flexible but more concise way to manipulate records is
+to use the @code{define-structure} special form (@pxref{Structure
+Definitions}).
+@findex define-structure
+
+@deffn procedure make-record-type type-name field-names
+@cindex record-type descriptor (defn)
+Returns a @dfn{record-type descriptor}, a value representing a new data
+type, disjoint from all others. The @var{type-name} 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}
+argument is a list of symbols naming the @dfn{fields} 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.
+@end deffn
+
+@deffn procedure record-constructor record-type [field-names]
+Returns a procedure for constructing new members of the type represented
+by @var{record-type}. The returned procedure accepts exactly as many
+arguments as there are symbols in the given list, @var{field-names};
+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 the list of @var{field-names} are unspecified.
+The @var{field-names} argument defaults to the list of field-names in
+the call to @code{make-record-type} that created the type represented by
+@var{record-type}; if the @var{field-names} argument is provided, it is
+an error if it contains any duplicates or any symbols not in the default
+list.
+@end deffn
+
+@deffn procedure record-predicate record-type
+Returns a procedure for testing membership in the type represented by
+@var{record-type}. The returned procedure accepts exactly one argument
+and returns @code{#t} if the argument is a member of the indicated
+record type; it returns @code{#f} otherwise.
+@end deffn
+
+@deffn procedure record-accessor record-type field-name
+Returns a procedure for reading the value of a particular field of a
+member of the type represented by @var{record-type}. 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} in that record. The symbol @var{field-name}
+must be a member of the list of field names in the call to
+@code{make-record-type} that created the type represented by
+@var{record-type}.
+@end deffn
+
+@deffn procedure record-modifier record-type field-name
+Returns a procedure for writing the value of a particular field of a
+member of the type represented by @var{record-type}. 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} in that record to contain the
+given value. The returned value of the modifier procedure is
+unspecified. The symbol @var{field-name} must be a member of the list
+of field names in the call to @code{make-record-type} that created the
+type represented by @var{record-type}.
+@end deffn
+
+@deffn procedure record? object
+@cindex type predicate, for record
+Returns @code{#t} if @var{object} is a record of any type and @code{#f}
+otherwise. Note that @code{record?} may be true of any Scheme value; of
+course, if it returns @code{#t} for some particular value, then
+@code{record-type-descriptor} is applicable to that value and returns an
+appropriate descriptor.
+@end deffn
+
+@deffn procedure record-type-descriptor record
+Returns the record-type descriptor representing the type of
+@var{record}. That is, for example, if the returned descriptor were
+passed to @code{record-predicate}, the resulting predicate would return
+@code{#t} when passed @var{record}. Note that it is not necessarily the
+case that the returned descriptor is the one that was passed to
+@code{record-constructor} in the call that created the constructor
+procedure that created @var{record}.
+@end deffn
+
+@deffn procedure record-type? object
+@cindex type predicate, for record type
+Returns @code{#t} if @var{object} is a record-type descriptor; otherwise
+returns @code{#f}.
+@end deffn
+
+@deffn procedure record-type-name record-type
+Returns the type name associated with the type represented by
+@var{record-type}. The returned value is @code{eqv?} to the
+@var{type-name} argument given in the call to @code{make-record-type}
+that created the type represented by @var{record-type}.
+@end deffn
+
+@deffn procedure record-type-field-names record-type
+Returns a list of the symbols naming the fields in members of the type
+represented by @var{record-type}. The returned value is @code{equal?}
+to the @var{field-names} argument given in the call to
+@code{make-record-type} that created the type represented by
+@var{record-type}.@footnote{In MIT/GNU Scheme, the returned list is always
+newly allocated.}
+@end deffn
+
+@node Promises, Streams, Records, Miscellaneous Datatypes
+@section Promises
+
+@deffn {special form} delay expression
+@cindex promise (defn)
+@cindex promise, construction
+@cindex construction, of promise
+@cindex lazy evaluation (defn)
+@cindex call by need evaluation (defn)
+@cindex evaluation, lazy (defn)
+@cindex evaluation, call by need (defn)
+The @code{delay} construct is used together with the procedure
+@code{force} to implement @dfn{lazy evaluation} or @dfn{call by need}.
+@code{(delay @var{expression})} returns an object called a @dfn{promise}
+which at some point in the future may be asked (by the @code{force}
+procedure) to evaluate @var{expression} and deliver the resulting value.
+@end deffn
+
+@deffn procedure force promise
+@cindex promise, forcing
+@cindex forcing, of promise
+@cindex memoization, of promise
+Forces the value of @emph{promise}. If no value has been computed for
+the promise, then a value is computed and returned. The value of the
+promise is cached (or ``memoized'') so that if it is forced a second
+time, the previously computed value is returned without any
+recomputation.
+
+@example
+@group
+(force (delay (+ 1 2))) @result{} 3
+
+(let ((p (delay (+ 1 2))))
+ (list (force p) (force p))) @result{} (3 3)
+@end group
+
+@group
+(define head car)
+
+(define tail
+ (lambda (stream)
+ (force (cdr stream))))
+@end group
+
+@group
+(define a-stream
+ (letrec ((next
+ (lambda (n)
+ (cons n (delay (next (+ n 1)))))))
+ (next 0)))
+
+(head (tail (tail a-stream))) @result{} 2
+@end group
+@end example
+@end deffn
+
+@deffn procedure promise? object
+@cindex type predicate, for promise
+Returns @code{#t} if @var{object} is a promise; otherwise returns
+@code{#f}.
+@end deffn
+
+@deffn procedure promise-forced? promise
+Returns @code{#t} if @var{promise} has been forced and its value cached;
+otherwise returns @code{#f}.
+@end deffn
+
+@deffn procedure promise-value promise
+If @var{promise} has been forced and its value cached, this procedure
+returns the cached value. Otherwise, an error is signalled.
+@end deffn
+
+@code{force} and @code{delay} are mainly intended for programs written
+in functional style. The following examples should not be considered to
+illustrate good programming style, but they illustrate the property that
+the value of a promise is computed at most once.
+
+@example
+@group
+(define count 0)
+
+(define p
+ (delay
+ (begin
+ (set! count (+ count 1))
+ (* x 3))))
+
+(define x 5)
+@end group
+
+@group
+count @result{} 0
+p @result{} #[promise 54]
+(force p) @result{} 15
+p @result{} #[promise 54]
+count @result{} 1
+(force p) @result{} 15
+count @result{} 1
+@end group
+@end example
+
+Here is a possible implementation of @code{delay} and @code{force}. We
+define the expression
+
+@example
+(delay @var{expression})
+@end example
+
+@noindent
+to have the same meaning as the procedure call
+
+@example
+(make-promise (lambda () @var{expression}))
+@end example
+
+@noindent
+where @code{make-promise} is defined as follows:
+
+@example
+@group
+(define make-promise
+ (lambda (proc)
+ (let ((already-run? #f)
+ (result #f))
+ (lambda ()
+ (cond ((not already-run?)
+ (set! result (proc))
+ (set! already-run? #t)))
+ result))))
+@end group
+@end example
+
+Promises are implemented here as procedures of no arguments, and
+@code{force} simply calls its argument.
+
+@example
+@group
+(define force
+ (lambda (promise)
+ (promise)))
+@end group
+@end example
+
+Various extensions to this semantics of @code{delay} and @code{force}
+are supported in some implementations (none of these are currently
+supported in MIT/GNU Scheme):
+
+@itemize @bullet
+@item
+Calling @code{force} on an object that is not a promise may simply
+return the object.
+
+@item
+It may be the case that there is no means by which a promise can be
+operationally distinguished from its forced value. That is, expressions
+like the following may evaluate to either @code{#t} or @code{#f},
+depending on the implementation:
+
+@example
+@group
+(eqv? (delay 1) 1) @result{} @r{unspecified}
+(pair? (delay (cons 1 2))) @result{} @r{unspecified}
+@end group
+@end example
+
+@item
+Some implementations will implement ``implicit forcing'', where the
+value of a promise is forced by primitive procedures like @code{car} and
+@code{+}:
+
+@example
+(+ (delay (* 3 7)) 13) @result{} 34
+@end example
+@end itemize
+
+@node Streams, Weak Pairs, Promises, Miscellaneous Datatypes
+@section Streams
+
+@cindex stream (defn)
+In addition to promises, MIT/GNU Scheme supports a higher-level abstraction
+called @dfn{streams}. Streams are similar to lists, except that the
+tail of a stream is not computed until it is referred to.
+This allows streams to be used to represent infinitely long lists.
+
+@deffn procedure stream object @dots{}
+@cindex construction, of stream
+Returns a newly allocated stream whose elements are the arguments. Note
+that the expression @code{(stream)} returns the empty stream, or
+end-of-stream marker.
+@end deffn
+
+@deffn procedure list->stream list
+@cindex list, converting to stream
+Returns a newly allocated stream whose elements are the elements of
+@var{list}. Equivalent to @code{(apply stream @var{list})}.
+@end deffn
+
+@deffn procedure stream->list stream
+@cindex stream, converting to list
+Returns a newly allocated list whose elements are the elements of
+@var{stream}. If @var{stream} has infinite length this procedure will
+not terminate. This could have been defined by
+
+@example
+@group
+(define (stream->list stream)
+ (if (stream-null? stream)
+ '()
+ (cons (stream-car stream)
+ (stream->list (stream-cdr stream)))))
+@end group
+@end example
+@end deffn
+
+@deffn {special form} cons-stream object expression
+Returns a newly allocated stream pair. Equivalent to @code{(cons
+@var{object} (delay @var{expression}))}.
+@end deffn
+
+@deffn procedure stream-pair? object
+@cindex type predicate, for stream pair
+Returns @code{#t} if @var{object} is a pair whose cdr contains a
+promise. Otherwise returns @code{#f}. This could have been defined by
+
+@example
+@group
+(define (stream-pair? object)
+ (and (pair? object)
+ (promise? (cdr object))))
+@end group
+@end example
+@end deffn
+
+@deffn procedure stream-car stream
+@deffnx procedure stream-first stream
+@findex car
+Returns the first element in @var{stream}. @code{stream-car} is
+equivalent to @code{car}. @code{stream-first} is a synonym for
+@code{stream-car}.
+@end deffn
+
+@deffn procedure stream-cdr stream
+@deffnx procedure stream-rest stream
+@findex force
+@findex cdr
+Returns the first tail of @var{stream}. Equivalent to @code{(force (cdr
+@var{stream}))}. @code{stream-rest} is a synonym for @code{stream-cdr}.
+@end deffn
+
+@deffn procedure stream-null? stream
+@cindex empty stream, predicate for
+@findex null?
+Returns @code{#t} if @var{stream} is the end-of-stream marker; otherwise
+returns @code{#f}. This is equivalent to @code{null?}, but should be
+used whenever testing for the end of a stream.
+@end deffn
+
+@deffn procedure stream-length stream
+@cindex length, of stream
+Returns the number of elements in @var{stream}. If @var{stream} has an
+infinite number of elements this procedure will not terminate. Note
+that this procedure forces all of the promises that comprise
+@var{stream}.
+@end deffn
+
+@deffn procedure stream-ref stream k
+@cindex selecting, of stream component
+@cindex component selection, of stream
+Returns the element of @var{stream} that is indexed by @var{k}; that is,
+the @var{k}th element. @var{K} must be an exact non-negative integer
+strictly less than the length of @var{stream}.
+@end deffn
+
+@deffn procedure stream-head stream k
+Returns the first @var{k} elements of @var{stream} as a list. @var{K}
+must be an exact non-negative integer strictly less than the length of
+@var{stream}.
+@end deffn
+
+@deffn procedure stream-tail stream k
+Returns the tail of @var{stream} that is indexed by @var{k}; that is,
+the @var{k}th tail. This is equivalent to performing @code{stream-cdr}
+@var{k} times. @var{K} must be an exact non-negative integer strictly
+less than the length of @var{stream}.
+@end deffn
+
+@deffn procedure stream-map procedure stream stream @dots{}
+@cindex mapping, of stream
+Returns a newly allocated stream, each element being the result of
+invoking @var{procedure} with the corresponding elements of the
+@var{stream}s as its arguments.
+@end deffn
+
+@node Weak Pairs, , Streams, Miscellaneous Datatypes
+@section Weak Pairs
+
+@cindex weak pair (defn)
+@cindex pair, weak (defn)
+@dfn{Weak pairs} are a mechanism for building data structures that point
+at objects without protecting them from garbage collection. The car of
+a weak pair holds its pointer weakly, while the cdr holds its pointer in
+the normal way. If the object in the car of a weak pair is not held
+normally by any other data structure, it will be garbage-collected.
+
+@findex pair?
+Note: weak pairs are @emph{not} pairs; that is, they do not satisfy the
+predicate @code{pair?}.
+
+@deffn procedure weak-pair? object
+@cindex type predicate, for weak pair
+Returns @code{#t} if @var{object} is a weak pair; otherwise returns
+@code{#f}.
+@end deffn
+
+@deffn procedure weak-cons car cdr
+@cindex construction, of weak pair
+Allocates and returns a new weak pair, with components @var{car} and
+@var{cdr}. The @var{car} component is held weakly.
+@end deffn
+
+@deffn procedure weak-pair/car? weak-pair
+This predicate returns @code{#f} if the car of @var{weak-pair} has been
+garbage-collected; otherwise returns @code{#t}. In other words, it is
+true if @var{weak-pair} has a valid car component.
+@end deffn
+
+@deffn procedure weak-car weak-pair
+@cindex selection, of weak pair component
+@cindex component selection, of weak pair
+Returns the car component of @var{weak-pair}. If the car component has
+been garbage-collected, this operation returns @code{#f}, but it can
+also return @code{#f} if that is the value that was stored in the car.
+@end deffn
+
+Normally, @code{weak-pair/car?} is used to determine if @code{weak-car}
+would return a valid value. An obvious way of doing this would be:
+
+@example
+@group
+(if (weak-pair/car? x)
+ (weak-car x)
+ @dots{})
+@end group
+@end example
+
+@noindent
+However, since a garbage collection could occur between the call to
+@code{weak-pair/car?} and @code{weak-car}, this would not always work
+correctly. Instead, the following should be used, which always works:
+
+@example
+@group
+(or (weak-car x)
+ (and (not (weak-pair/car? x))
+ @dots{}))
+@end group
+@end example
+
+The reason that the latter expression works is that @code{weak-car}
+returns @code{#f} in just two instances: when the car component is
+@code{#f}, and when the car component has been garbage-collected. In
+the former case, if a garbage collection happens between the two calls,
+it won't matter, because @code{#f} will never be garbage-collected. And
+in the latter case, it also won't matter, because the car component no
+longer exists and cannot be affected by the garbage collector.
+
+@deffn procedure weak-set-car! weak-pair object
+Sets the car component of @var{weak-pair} to @var{object} and returns an
+unspecified result.
+@end deffn
+
+@deffn procedure weak-cdr weak-pair
+Returns the cdr component of @var{weak-cdr}.
+@end deffn
+
+@deffn procedure weak-set-cdr! weak-pair object
+Sets the cdr component of @var{weak-pair} to @var{object} and returns an
+unspecified result.
+@end deffn
--- /dev/null
+@c This file is part of the MIT/GNU Scheme Reference Manual.
+@c $Id: numbers.texi,v 1.1 2003/04/15 03:29:56 cph Exp $
+
+@c Copyright 1991,1992,1993,1994,1995 Massachusetts Institute of Technology
+@c Copyright 1996,1997,1999,2000,2001 Massachusetts Institute of Technology
+@c Copyright 2002,2003 Massachusetts Institute of Technology
+@c See file scheme.texinfo for copying conditions.
+
+@node Numbers, Characters, Equivalence Predicates, Top
+@chapter Numbers
+@cindex number
+
+(This section is largely taken from the @cite{Revised^4 Report on the
+Algorithmic Language Scheme}.)
+
+Numerical computation has traditionally been neglected by the Lisp
+community. Until Common Lisp there was no carefully thought out
+strategy for organizing numerical computation, and with the exception of
+the MacLisp system little effort was made to execute numerical code
+efficiently. This report recognizes the excellent work of the Common
+Lisp committee and accepts many of their recommendations. In some ways
+this report simplifies and generalizes their proposals in a manner
+consistent with the purposes of Scheme.
+
+It is important to distinguish between the mathematical numbers, the
+Scheme numbers that attempt to model them, the machine representations
+used to implement the Scheme numbers, and notations used to write
+numbers. This report uses the types @emph{number}, @emph{complex},
+@emph{real}, @emph{rational}, and @emph{integer} to refer to both
+mathematical numbers and Scheme numbers. Machine representations such
+as fixed point and floating point are referred to by names such as
+@emph{fixnum} and @emph{flonum}.
+
+@menu
+* Numerical types::
+* Exactness::
+* Implementation restrictions::
+* Syntax of numerical constants::
+* Numerical operations::
+* Numerical input and output::
+* Fixnum and Flonum Operations::
+* Random Numbers::
+@end menu
+
+@node Numerical types, Exactness, Numbers, Numbers
+@section Numerical types
+@cindex numerical types
+
+Mathematically, numbers may be arranged into a tower of subtypes in
+which each level is a subset of the level above it:
+
+@display
+@group
+number
+complex
+real
+rational
+integer
+@end group
+@end display
+
+For example, 3 is an integer. Therefore 3 is also a rational, a real,
+and a complex. The same is true of the Scheme numbers that model 3.
+For Scheme numbers, these types are defined by the predicates
+@code{number?}, @code{complex?}, @code{real?}, @code{rational?}, and
+@code{integer?}.
+
+There is no simple relationship between a number's type and its
+representation inside a computer. Although most implementations of
+Scheme will offer at least two different representations of 3, these
+different representations denote the same integer.
+
+Scheme's numerical operations treat numbers as abstract data, as
+independent of their representation as possible. Although an
+implementation of Scheme may use fixnum, flonum, and perhaps other
+representations for numbers, this should not be apparent to a casual
+programmer writing simple programs.
+
+It is necessary, however, to distinguish between numbers that are
+represented exactly and those that may not be. For example, indexes
+into data structures must be known exactly, as must some polynomial
+coefficients in a symbolic algebra system. On the other hand, the
+results of measurements are inherently inexact, and irrational numbers
+may be approximated by rational and therefore inexact approximations.
+In order to catch uses of inexact numbers where exact numbers are
+required, Scheme explicitly distinguishes exact from inexact numbers.
+This distinction is orthogonal to the dimension of type.
+
+@node Exactness, Implementation restrictions, Numerical types, Numbers
+@section Exactness
+@cindex exactness
+
+Scheme numbers are either @emph{exact} or @emph{inexact}. A number is
+exact if it was written as an exact constant or was derived from exact
+numbers using only exact operations. A number is inexact if it was
+written as an inexact constant, if it was derived using inexact
+ingredients, or if it was derived using inexact operations. Thus
+inexactness is a contagious property of a number.
+
+If two implementations produce exact results for a computation that did
+not involve inexact intermediate results, the two ultimate results will
+be mathematically equivalent. This is generally not true of
+computations involving inexact numbers since approximate methods such as
+floating point arithmetic may be used, but it is the duty of each
+implementation to make the result as close as practical to the
+mathematically ideal result.
+
+@findex +
+Rational operations such as @code{+} should always produce exact results
+when given exact arguments. If the operation is unable to produce an
+exact result, then it may either report the violation of an
+implementation restriction or it may silently coerce its result to an
+inexact value. @xref{Implementation restrictions}.
+
+@findex inexact->exact
+With the exception of @code{inexact->exact}, the operations described in
+this section must generally return inexact results when given any
+inexact arguments. An operation may, however, return an exact result if
+it can prove that the value of the result is unaffected by the
+inexactness of its arguments. For example, multiplication of any number
+by an exact zero may produce an exact zero result, even if the other
+argument is inexact.
+
+@node Implementation restrictions, Syntax of numerical constants, Exactness, Numbers
+@section Implementation restrictions
+@cindex implementation restriction
+
+Implementations of Scheme are not required to implement the whole tower
+of subtypes (@pxref{Numerical types}), but they must implement a
+coherent subset consistent with both the purposes of the implementation
+and the spirit of the Scheme language. For example, an implementation
+in which all numbers are real may still be quite useful.@footnote{MIT/GNU
+Scheme implements the whole tower of numerical types. It has
+unlimited-precision exact integers and exact rationals. Flonums are
+used to implement all inexact reals; on machines that support @sc{ieee}
+floating-point arithmetic these are double-precision floating-point
+numbers.}
+
+Implementations may also support only a limited range of numbers of any
+type, subject to the requirements of this section. The supported range
+for exact numbers of any type may be different from the supported range
+for inexact numbers of that type. For example, an implementation that
+uses flonums to represent all its inexact real numbers may support a
+practically unbounded range of exact integers and rationals while
+limiting the range of inexact reals (and therefore the range of inexact
+integers and rationals) to the dynamic range of the flonum format.
+Furthermore the gaps between the representable inexact integers and
+rationals are likely to be very large in such an implementation as the
+limits of this range are approached.
+
+@findex length
+@findex vector-length
+@findex string-length
+An implementation of Scheme must support exact integers throughout the
+range of numbers that may be used for indexes of lists, vectors, and
+strings or that may result from computing the length of a list, vector,
+or string. The @code{length}, @code{vector-length}, and
+@code{string-length} procedures must return an exact integer, and it is
+an error to use anything but an exact integer as an index. Furthermore
+any integer constant within the index range, if expressed by an exact
+integer syntax, will indeed be read as an exact integer, regardless of
+any implementation restrictions that may apply outside this range.
+Finally, the procedures listed below will always return an exact integer
+result provided all their arguments are exact integers and the
+mathematically expected result is representable as an exact integer
+within the implementation:
+
+@example
+@group
+* gcd modulo
++ imag-part numerator
+- inexact->exact quotient
+abs lcm rationalize
+angle magnitude real-part
+ceiling make-polar remainder
+denominator make-rectangular round
+expt max truncate
+floor min
+@end group
+@end example
+
+@findex /
+Implementations are encouraged, but not required, to support exact
+integers and exact rationals of practically unlimited size and
+precision, and to implement the above procedures and the @code{/}
+procedure in such a way that they always return exact results when given
+exact arguments. If one of these procedures is unable to deliver an
+exact result when given exact arguments, then it may either report a
+violation of an implementation restriction or it may silently coerce its
+result to an inexact number. Such a coercion may cause an error
+later.
+
+An implementation may use floating point and other approximate
+representation strategies for inexact numbers. This report recommends,
+but does not require, that the @sc{ieee} 32-bit and 64-bit floating
+point standards be followed by implementations that use flonum
+representations, and that implementations using other representations
+should match or exceed the precision achievable using these floating
+point standards.
+
+@findex sqrt
+In particular, implementations that use flonum representations must
+follow these rules: A flonum result must be represented with at least as
+much precision as is used to express any of the inexact arguments to
+that operation. It is desirable (but not required) for potentially
+inexact operations such as @code{sqrt}, when applied to exact arguments,
+to produce exact answers whenever possible (for example the square root
+of an exact 4 ought to be an exact 2). If, however, an exact number is
+operated upon so as to produce an inexact result (as by @code{sqrt}),
+and if the result is represented as a flonum, then the most precise
+flonum format available must be used; but if the result is represented
+in some other way then the representation must have at least as much
+precision as the most precise flonum format available.
+
+Although Scheme allows a variety of written notations for numbers, any
+particular implementation may support only some of them.@footnote{MIT/GNU
+Scheme implements all of the written notations for numbers.} For
+example, an implementation in which all numbers are real need not
+support the rectangular and polar notations for complex numbers. If an
+implementation encounters an exact numerical constant that it cannot
+represent as an exact number, then it may either report a violation of
+an implementation restriction or it may silently represent the constant
+by an inexact number.
+
+@node Syntax of numerical constants, Numerical operations, Implementation restrictions, Numbers
+@section Syntax of numerical constants
+@cindex number, external representation
+@cindex external representation, for number
+
+@findex #b
+@findex #o
+@findex #d
+@findex #x
+@cindex #b as external representation
+@cindex #o as external representation
+@cindex #d as external representation
+@cindex #x as external representation
+A number may be written in binary, octal, decimal, or hexadecimal by the
+use of a radix prefix. The radix prefixes are @code{#b} (binary),
+@code{#o} (octal), @code{#d} (decimal), and @code{#x} (hexadecimal).
+With no radix prefix, a number is assumed to be expressed in
+decimal.
+
+@findex #e
+@findex #i
+@findex #
+@cindex #e as external representation
+@cindex #i as external representation
+@cindex # in external representation of number
+A numerical constant may be specified to be either exact or inexact by a
+prefix. The prefixes are @code{#e} for exact, and @code{#i} for
+inexact. An exactness prefix may appear before or after any radix
+prefix that is used. If the written representation of a number has no
+exactness prefix, the constant may be either inexact or exact. It is
+inexact if it contains a decimal point, an exponent, or a @code{#}
+character in the place of a digit, otherwise it is exact.
+
+@cindex s, as exponent marker in number
+@cindex f, as exponent marker in number
+@cindex d, as exponent marker in number
+@cindex l, as exponent marker in number
+@cindex e, as exponent marker in number
+@cindex exponent marker (defn)
+@cindex precision, of inexact number
+@cindex numeric precision, inexact
+@cindex internal representation, for inexact number
+@cindex short precision, of inexact number
+@cindex single precision, of inexact number
+@cindex double precision, of inexact number
+@cindex long precision, of inexact number
+In systems with inexact numbers of varying precisions it may be useful
+to specify the precision of a constant. For this purpose, numerical
+constants may be written with an @dfn{exponent marker} that indicates
+the desired precision of the inexact representation. The letters
+@code{s}, @code{f}, @code{d}, and @code{l} specify the use of
+@emph{short}, @emph{single}, @emph{double}, and @emph{long} precision,
+respectively. (When fewer than four internal inexact representations
+exist, the four size specifications are mapped onto those available.
+For example, an implementation with two internal representations may map
+short and single together and long and double together.) In addition,
+the exponent marker @code{e} specifies the default precision for the
+implementation. The default precision has at least as much precision as
+@emph{double}, but implementations may wish to allow this default to be
+set by the user.
+
+@example
+@group
+3.14159265358979F0
+ @r{Round to single ---} 3.141593
+0.6L0
+ @r{Extend to long ---} .600000000000000
+@end group
+@end example
+
+@node Numerical operations, Numerical input and output, Syntax of numerical constants, Numbers
+@section Numerical operations
+@cindex numerical operations
+
+@xref{Entry Format}, for a summary of the naming conventions used to
+specify restrictions on the types of arguments to numerical routines.
+The examples used in this section assume that any numerical constant
+written using an exact notation is indeed represented as an exact
+number. Some examples also assume that certain numerical constants
+written using an inexact notation can be represented without loss of
+accuracy; the inexact constants were chosen so that this is likely to be
+true in implementations that use flonums to represent inexact
+numbers.
+
+@deffn procedure number? object
+@deffnx procedure complex? object
+@deffnx procedure real? object
+@deffnx procedure rational? object
+@deffnx procedure integer? object
+@cindex type predicate, for number
+These numerical type predicates can be applied to any kind of argument,
+including non-numbers. They return @code{#t} if the object is of the
+named type, and otherwise they return @code{#f}. In general, if a type
+predicate is true of a number then all higher type predicates are also
+true of that number. Consequently, if a type predicate is false of a
+number, then all lower type predicates are also false of that
+number.@footnote{In MIT/GNU Scheme the @code{rational?} procedure is the
+same as @code{real?}, and the @code{complex?} procedure is the same as
+@code{number?}.}
+
+@findex zero?
+@findex =
+If @var{z} is an inexact complex number, then @code{(real? @var{z})} is
+true if and only if @code{(zero? (imag-part @var{z}))} is true. If
+@var{x} is an inexact real number, then @code{(integer? @var{x})} is
+true if and only if @code{(= @var{x} (round @var{x}))}.
+
+@example
+@group
+(complex? 3+4i) @result{} #t
+(complex? 3) @result{} #t
+(real? 3) @result{} #t
+(real? -2.5+0.0i) @result{} #t
+(real? #e1e10) @result{} #t
+(rational? 6/10) @result{} #t
+(rational? 6/3) @result{} #t
+(integer? 3+0i) @result{} #t
+(integer? 3.0) @result{} #t
+(integer? 8/4) @result{} #t
+@end group
+@end example
+
+Note: The behavior of these type predicates on inexact numbers is
+unreliable, since any inaccuracy may affect the result.
+
+@end deffn
+
+@deffn procedure exact? z
+@deffnx procedure inexact? z
+These numerical predicates provide tests for the exactness of a
+quantity. For any Scheme number, precisely one of these predicates is
+true.
+@end deffn
+
+@deffn procedure exact-integer? object
+@deffnx procedure exact-nonnegative-integer? object
+@deffnx procedure exact-rational? object
+These procedures test for some very common types of numbers. These
+tests could be written in terms of simpler predicates, but are more
+efficient.
+@end deffn
+
+@deffn procedure = z1 z2 z3 @dots{}
+@deffnx procedure < x1 x2 x3 @dots{}
+@deffnx procedure > x1 x2 x3 @dots{}
+@deffnx procedure <= x1 x2 x3 @dots{}
+@deffnx procedure >= x1 x2 x3 @dots{}
+@cindex ordering, of numbers
+@cindex comparison, of numbers
+@cindex equivalence predicate, for numbers
+These procedures return @code{#t} if their arguments are (respectively):
+equal, monotonically increasing, monotonically decreasing, monotonically
+nondecreasing, or monotonically nonincreasing.
+
+These predicates are transitive. Note that the traditional
+implementations of these predicates in Lisp-like languages are not
+transitive.
+
+Note: While it is not an error to compare inexact numbers using these
+predicates, the results may be unreliable because a small inaccuracy may
+affect the result; this is especially true of @code{=} and @code{zero?}.
+When in doubt, consult a numerical analyst.
+@end deffn
+
+@deffn procedure zero? z
+@deffnx procedure positive? x
+@deffnx procedure negative? x
+@deffnx procedure odd? x
+@deffnx procedure even? x
+@cindex zero
+@cindex positive number
+@cindex negative number
+@cindex odd number
+@cindex even number
+These numerical predicates test a number for a particular property,
+returning @code{#t} or @code{#f}. See note above regarding inexact
+numbers.
+@end deffn
+
+@deffn procedure max x1 x2 @dots{}
+@deffnx procedure min x1 x2 @dots{}
+@cindex minimum, of numbers
+@cindex maximum, of numbers
+These procedures return the maximum or minimum of their
+arguments.
+
+@example
+@group
+(max 3 4) @result{} 4 @r{; exact}
+(max 3.9 4) @result{} 4.0 @r{; inexact}
+@end group
+@end example
+
+Note: If any argument is inexact, then the result will also be inexact
+(unless the procedure can prove that the inaccuracy is not large enough
+to affect the result, which is possible only in unusual
+implementations). If @code{min} or @code{max} is used to compare
+numbers of mixed exactness, and the numerical value of the result cannot
+be represented as an inexact number without loss of accuracy, then the
+procedure may report a violation of an implementation
+restriction.@footnote{MIT/GNU Scheme signals an error of type
+@code{condition-type:bad-range-argument} in this case.}
+@findex condition-type:bad-range-argument
+@end deffn
+
+@deffn procedure + z1 @dots{}
+@deffnx procedure * z1 @dots{}
+@cindex addition, of numbers
+@cindex sum, of numbers
+@cindex identity, additive
+@cindex multiplication, of numbers
+@cindex product, of numbers
+@cindex identity, multiplicative
+These procedures return the sum or product of their arguments.
+
+@example
+@group
+(+ 3 4) @result{} 7
+(+ 3) @result{} 3
+(+) @result{} 0
+(* 4) @result{} 4
+(*) @result{} 1
+@end group
+@end example
+@end deffn
+
+@deffn procedure - z1 z2 @dots{}
+@deffnx procedure / z1 z2 @dots{}
+@cindex subtraction, of numbers
+@cindex difference, of numbers
+@cindex inverse, additive, of number
+@cindex division, of numbers
+@cindex quotient, of numbers
+@cindex inverse, multiplicative, of number
+With two or more arguments, these procedures return the difference or
+quotient of their arguments, associating to the left. With one
+argument, however, they return the additive or multiplicative inverse of
+their argument.
+
+@example
+@group
+(- 3 4) @result{} -1
+(- 3 4 5) @result{} -6
+(- 3) @result{} -3
+(/ 3 4 5) @result{} 3/20
+(/ 3) @result{} 1/3
+@end group
+@end example
+@end deffn
+
+@deffn procedure 1+ z
+@deffnx procedure -1+ z
+@code{(1+ z)} is equivalent to @code{(+ z 1)}; @code{(-1+ z)} is
+equivalent to @code{(- z 1)}.
+@end deffn
+
+@deffn procedure abs x
+@cindex absolute value, of number
+@cindex magnitude, of real number
+@code{abs} returns the magnitude of its argument.
+
+@example
+(abs -7) @result{} 7
+@end example
+@end deffn
+
+@deffn procedure quotient n1 n2
+@deffnx procedure remainder n1 n2
+@deffnx procedure modulo n1 n2
+@cindex division, of integers
+@cindex quotient, of integers
+@cindex remainder, of integers
+@cindex modulus, of integers
+@cindex integer division
+These procedures implement number-theoretic (integer) division: for
+positive integers @var{n1} and @var{n2}, if @var{n3} and @var{n4} are
+integers such that
+@tex
+$$n_1=n_2n_3+n_4$$
+$$0\leq n_4<n_2$$
+@end tex
+@ifinfo
+
+@example
+@group
+@var{n1} = (@var{n2} * @var{n3}) + @var{n4}
+
+0 <= @var{n4} < @var{n2}
+@end group
+@end example
+
+@end ifinfo
+@noindent
+then
+
+@example
+@group
+(quotient @var{n1} @var{n2}) @result{} @var{n3}
+(remainder @var{n1} @var{n2}) @result{} @var{n4}
+(modulo @var{n1} @var{n2}) @result{} @var{n4}
+@end group
+@end example
+
+@noindent
+For integers @var{n1} and @var{n2} with @var{n2} not equal to 0,
+
+@example
+@group
+(= @var{n1}
+ (+ (* @var{n2} (quotient @var{n1} @var{n2}))
+ (remainder @var{n1} @var{n2})))
+ @result{} #t
+@end group
+@end example
+
+@noindent
+provided all numbers involved in that computation are exact.
+
+The value returned by @code{quotient} always has the sign of the product
+of its arguments. @code{remainder} and @code{modulo} differ on negative
+arguments --- the @code{remainder} always has the sign of the dividend,
+the @code{modulo} always has the sign of the divisor:
+
+@example
+@group
+(modulo 13 4) @result{} 1
+(remainder 13 4) @result{} 1
+
+(modulo -13 4) @result{} 3
+(remainder -13 4) @result{} -1
+
+(modulo 13 -4) @result{} -3
+(remainder 13 -4) @result{} 1
+
+(modulo -13 -4) @result{} -1
+(remainder -13 -4) @result{} -1
+
+(remainder -13 -4.0) @result{} -1.0 @r{; inexact}
+@end group
+@end example
+
+@findex integer-truncate
+Note that @code{quotient} is the same as @code{integer-truncate}.
+@end deffn
+
+@deffn procedure integer-floor n1 n2
+@deffnx procedure integer-ceiling n1 n2
+@deffnx procedure integer-truncate n1 n2
+@deffnx procedure integer-round n1 n2
+These procedures combine integer division with rounding. For example,
+the following are equivalent:
+
+@example
+@group
+(integer-floor @var{n1} @var{n2})
+(floor (/ @var{n1} @var{n2}))
+@end group
+@end example
+
+@noindent
+However, the former is faster and does not produce an intermediate
+result.
+
+@findex quotient
+Note that @code{integer-truncate} is the same as @code{quotient}.
+@end deffn
+
+@deffn procedure integer-divide n1 n2
+@deffnx procedure integer-divide-quotient qr
+@deffnx procedure integer-divide-remainder qr
+@findex quotient
+@findex remainder
+@code{integer-divide} is equivalent to performing both @code{quotient}
+and @code{remainder} at once. The result of @code{integer-divide} is an
+object with two components; the procedures
+@code{integer-divide-quotient} and @code{integer-divide-remainder}
+select those components. These procedures are useful when both the
+quotient and remainder are needed; often computing both of these numbers
+simultaneously is much faster than computing them separately.
+
+For example, the following are equivalent:
+
+@example
+@group
+(lambda (n d)
+ (cons (quotient n d)
+ (remainder n d)))
+
+(lambda (n d)
+ (let ((qr (integer-divide n d)))
+ (cons (integer-divide-quotient qr)
+ (integer-divide-remainder qr))))
+@end group
+@end example
+@end deffn
+
+@deffn procedure gcd n1 @dots{}
+@deffnx procedure lcm n1 @dots{}
+@cindex greatest common divisor, of numbers
+@cindex least common multiple, of numbers
+These procedures return the greatest common divisor or least common
+multiple of their arguments. The result is always non-negative.
+
+@example
+@group
+(gcd 32 -36) @result{} 4
+(gcd) @result{} 0
+
+(lcm 32 -36) @result{} 288
+(lcm 32.0 -36) @result{} 288.0 @r{; inexact}
+(lcm) @result{} 1
+@end group
+@end example
+@end deffn
+
+@deffn procedure numerator q
+@deffnx procedure denominator q
+These procedures return the numerator or denominator of their argument;
+the result is computed as if the argument was represented as a fraction
+in lowest terms. The denominator is always positive. The denominator
+of 0 is defined to be 1.
+
+@example
+@group
+(numerator (/ 6 4)) @result{} 3
+(denominator (/ 6 4)) @result{} 2
+(denominator (exact->inexact (/ 6 4))) @result{} 2.0
+@end group
+@end example
+@end deffn
+
+@deffn procedure floor x
+@deffnx procedure ceiling x
+@deffnx procedure truncate x
+@deffnx procedure round x
+These procedures return integers. @code{floor} returns the largest
+integer not larger than @var{x}. @code{ceiling} returns the smallest
+integer not smaller than @var{x}. @code{truncate} returns the integer
+closest to @var{x} whose absolute value is not larger than the absolute
+value of @var{x}. @code{round} returns the closest integer to @var{x},
+rounding to even when @var{x} is halfway between two integers.
+
+Rationale: @code{round} rounds to even for consistency with the rounding
+modes required by the @sc{ieee} floating point standard.
+
+Note: If the argument to one of these procedures is inexact, then the
+result will also be inexact. If an exact value is needed, the result
+should be passed to the @code{inexact->exact} procedure (or use one of
+the procedures below).
+
+@example
+@group
+(floor -4.3) @result{} -5.0
+(ceiling -4.3) @result{} -4.0
+(truncate -4.3) @result{} -4.0
+(round -4.3) @result{} -4.0
+
+(floor 3.5) @result{} 3.0
+(ceiling 3.5) @result{} 4.0
+(truncate 3.5) @result{} 3.0
+(round 3.5) @result{} 4.0 @r{; inexact}
+
+(round 7/2) @result{} 4 @r{; exact}
+(round 7) @result{} 7
+@end group
+@end example
+@end deffn
+
+@deffn procedure floor->exact x
+@deffnx procedure ceiling->exact x
+@deffnx procedure truncate->exact x
+@deffnx procedure round->exact x
+These procedures are similar to the preceding procedures except that
+they always return an exact result. For example, the following are
+equivalent
+
+@example
+@group
+(floor->exact x)
+(inexact->exact (floor x))
+@end group
+@end example
+
+@noindent
+except that the former is faster and has fewer range restrictions.
+@end deffn
+
+@deffn procedure rationalize x y
+@deffnx procedure rationalize->exact x y
+@cindex simplest rational (defn)
+@cindex rational, simplest (defn)
+@code{rationalize} returns the @emph{simplest} rational number differing
+from @var{x} by no more than @var{y}. A rational number @var{r1} is
+@emph{simpler} than another rational number @var{r2} if
+@t{@var{r1}=@var{p1}/@var{q1}} and @t{@var{r2}=@var{p2}/@var{q2}} (both
+in lowest terms) and @t{|@var{p1}|<=|@var{p2}|} and
+@t{|@var{q1}|<=|@var{q2}|}. Thus @t{3/5} is simpler than @t{4/7}.
+Although not all rationals are comparable in this ordering (consider
+@t{2/7} and @t{3/5}) any interval contains a rational number that is
+simpler than every other rational number in that interval (the simpler
+@t{2/5} lies between @t{2/7} and @t{3/5}). Note that @t{0=0/1} is the
+simplest rational of all.
+
+@example
+@group
+(rationalize (inexact->exact .3) 1/10) @result{} 1/3 @r{; exact}
+(rationalize .3 1/10) @result{} #i1/3 @r{; inexact}
+@end group
+@end example
+
+@code{rationalize->exact} is similar to @code{rationalize} except that
+it always returns an exact result.
+@end deffn
+
+@deffn procedure simplest-rational x y
+@deffnx procedure simplest-exact-rational x y
+@code{simplest-rational} returns the simplest rational number between
+@var{x} and @var{y} inclusive; @code{simplest-exact-rational} is similar
+except that it always returns an exact result.
+
+These procedures implement the same functionality as @code{rationalize}
+and @code{rationalize->exact}, except that they specify the input range
+by its endpoints; @code{rationalize} specifies the range by its center
+point and its (half-) width.
+@end deffn
+
+@deffn procedure exp z
+@deffnx procedure log z
+@deffnx procedure sin z
+@deffnx procedure cos z
+@deffnx procedure tan z
+@deffnx procedure asin z
+@deffnx procedure acos z
+@deffnx procedure atan z
+@deffnx procedure atan y x
+@findex angle
+@findex make-rectangular
+These procedures compute the usual transcendental functions. @code{log}
+computes the natural logarithm of @var{z} (not the base ten logarithm).
+@code{asin}, @code{acos}, and @code{atan} compute arcsine, arccosine,
+and arctangent, respectively. The two-argument variant of @code{atan}
+computes @code{(angle (make-rectangular @var{x} @var{y}))} (see
+below).
+
+In general, the mathematical functions log, arcsine, arccosine, and
+arctangent are multiply defined. For nonzero real @var{x}, the value of
+log @var{x} is defined to be the one whose imaginary part lies in the
+range minus @var{pi} (exclusive) to @var{pi} (inclusive). log 0 is
+undefined. The value of log @var{z} when @var{z} is complex is defined
+according to the formula
+@tex
+$$\log z = \log {\rm magnitude}(z) + i {\rm angle} (z)$$
+@end tex
+@ifinfo
+
+@example
+log @var{z} = log magnitude(@var{z}) + i angle(@var{z})
+@end example
+
+@end ifinfo
+With log defined this way, the values of arcsine, arccosine, and
+arctangent are according to the following formulae:
+@tex
+$$\sin^{-1} z = -i \log (i z + \sqrt{1 - z^2})$$
+$$\cos^{-1} z = \pi / 2 - \sin^{-1} z$$
+$$\tan^{-1} z = (\log (1 + i z) - \log (1 - i z)) / (2 i)$$
+@end tex
+@ifinfo
+
+@example
+@group
+arcsin(@var{z}) = -i log(i @var{z} + sqrt(1 - @var{z}^2))
+arccos(@var{z}) = pi/2 - arcsin(@var{z})
+arctan(@var{z}) = (log(1 + i @var{z}) + log(1 - i @var{z})) / (2 i)
+@end group
+@end example
+
+@end ifinfo
+The above specification follows @cite{Common Lisp: the Language}, which
+in turn cites @cite{Principal Values and Branch Cuts in Complex APL};
+refer to these sources for more detailed discussion of branch cuts,
+boundary conditions, and implementation of these functions. When it is
+possible these procedures produce a real result from a real
+argument.
+@end deffn
+
+@deffn procedure sqrt z
+Returns the principal square root of @var{z}. The result will have
+either positive real part, or zero real part and non-negative imaginary
+part.
+@end deffn
+
+@deffn procedure expt z1 z2
+Returns @var{z1} raised to the power @var{z2}:
+@tex
+$${z_1}^{z_2} = e^{z_2 \log {z_1}}$$
+$0^0$ is defined to be equal to 1.
+@end tex
+@ifinfo
+
+@example
+@var{z1}^@var{z2} = e^(@var{z2} log @var{z1})
+@end example
+
+@noindent
+0^0 is defined to be equal to 1.
+@end ifinfo
+@end deffn
+
+@deffn procedure make-rectangular x1 x2
+@deffnx procedure make-polar x3 x4
+@deffnx procedure real-part z
+@deffnx procedure imag-part z
+@deffnx procedure magnitude z
+@deffnx procedure angle z
+@deffnx procedure conjugate z
+Suppose @var{x1}, @var{x2}, @var{x3}, and @var{x4} are real numbers and
+@var{z} is a complex number such that
+@tex
+ $$ z = x_1 + x_2\hbox{$i$}
+ = x_3 \cdot e^{{\displaystyle{\hbox{$i$}} x_4}}$$
+@end tex
+@ifinfo
+
+@example
+@var{z} = @var{x1} + @var{x2} i = @var{x3} e^(i @var{x4})
+@end example
+
+@end ifinfo
+@noindent
+Then @code{make-rectangular} and @code{make-polar} return @var{z},
+@code{real-part} returns @var{x1}, @code{imag-part} returns @var{x2},
+@code{magnitude} returns @var{x3}, and @code{angle} returns @var{x4}.
+In the case of @code{angle}, whose value is not uniquely determined by
+the preceding rule, the value returned will be the one in the range
+minus @var{pi} (exclusive) to @var{pi} (inclusive).
+
+@code{conjugate} returns the complex conjugate of @var{z}.
+@end deffn
+
+@deffn procedure exact->inexact z
+@deffnx procedure inexact->exact z
+@code{exact->inexact} returns an inexact representation of @var{z}. The
+value returned is the inexact number that is numerically closest to the
+argument. If an exact argument has no reasonably close inexact
+equivalent, then a violation of an implementation restriction may be
+reported; MIT/GNU Scheme signals an error of type
+@code{condition-type:bad-range-argument} in this case.
+@findex condition-type:bad-range-argument
+
+@code{inexact->exact} returns an exact representation of @var{z}. The
+value returned is the exact number that is numerically closest to the
+argument. If an inexact argument has no reasonably close exact
+equivalent, then a violation of an implementation restriction may be
+reported; in MIT/GNU Scheme this case does not occur because all inexact
+numbers are representable as exact numbers.
+
+These procedures implement the natural one-to-one correspondence between
+exact and inexact integers throughout an implementation-dependent range.
+@xref{Implementation restrictions}.
+@end deffn
+
+@node Numerical input and output, Fixnum and Flonum Operations, Numerical operations, Numbers
+@section Numerical input and output
+@cindex numerical input and output
+
+@deffn procedure number->string number [radix]
+@var{Radix} must be an exact integer, either 2, 8, 10, or 16. If
+omitted, @var{radix} defaults to 10. The procedure
+@code{number->string} takes a number and a radix and returns as a string
+an external representation of the given number in the given radix such
+that
+
+@example
+@group
+(let ((number @var{number})
+ (radix @var{radix}))
+ (eqv? number
+ (string->number (number->string number radix)
+ radix)))
+@end group
+@end example
+
+@noindent
+is true. It is an error if no possible result makes this expression
+true.
+
+If @var{number} is inexact, the radix is 10, and the above expression
+can be satisfied by a result that contains a decimal point, then the
+result contains a decimal point and is expressed using the minimum
+number of digits (exclusive of exponent and trailing zeroes) needed to
+make the above expression true; otherwise the format of the result is
+unspecified.
+
+The result returned by @code{number->string} never contains an explicit
+radix prefix.
+
+Note: The error case can occur only when @var{number} is not a complex
+number or is a complex number with an non-rational real or imaginary
+part.
+
+Rationale: If @var{number} is an inexact number represented using
+flonums, and the radix is 10, then the above expression is normally
+satisfied by a result containing a decimal point. The unspecified case
+allows for infinities, NaNs, and non-flonum representations.
+@end deffn
+
+@defvr variable flonum-parser-fast?
+This variable controls the behavior of @code{string->number} when
+parsing inexact numbers. Specifically, it allows the user to trade off
+accuracy against speed.
+
+When set to its default value, @code{#f}, the parser provides maximal
+accuracy, as required by the Scheme standard. If set to @code{#t}, the
+parser uses faster algorithms that will sometimes introduce small errors
+in the result. The errors affect a few of the least-significant bits of
+the result, and consequently can be tolerated by many applications.
+@end defvr
+
+@defvr variable flonum-unparser-cutoff
+This variable controls the action of @code{number->string} when
+@var{number} is a flonum (and consequently controls all printing of
+flonums). The value of this variable is normally a list of three items:
+
+@table @var
+@item rounding-type
+One of the following symbols: @code{normal}, @code{relative}, or
+@code{absolute}. The symbol @code{normal} means that the number should
+be printed with full precision. The symbol @code{relative} means that
+the number should be rounded to a specific number of digits. The symbol
+@code{absolute} means that the number should be rounded so that there
+are a specific number of digits to the right of the decimal point.
+
+@item precision
+An exact integer. If @var{rounding-type} is @code{normal},
+@var{precision} is ignored. If @var{rounding-type} is @code{relative},
+@var{precision} must be positive, and it specifies the number of digits
+to which the printed representation will be rounded. If
+@var{rounding-type} is @code{absolute}, the printed representation will
+be rounded @var{precision} digits to the right of the decimal point; if
+@var{precision} is negative, the representation is rounded @code{(-
+@var{precision})} digits to the left of the decimal point.
+
+@item format-type
+One of the symbols: @code{normal}, @code{scientific}, or
+@code{engineering}. This specifies the format in which the number will
+be printed.@* @code{scientific} specifies that the number will be printed
+using scientific notation: @code{@var{x}.@var{xxx}e@var{yyy}}. In other
+words, the number is printed as a mantissa between zero inclusive and
+ten exclusive, and an exponent. @code{engineering} is like
+@code{scientific}, except that the exponent is always a power of three,
+and the mantissa is constrained to be between zero inclusive and 1000
+exclusive. If @code{normal} is specified, the number will be printed in
+positional notation if it is ``small enough'', otherwise it is printed
+in scientific notation. A number is ``small enough'' when the number of
+digits that would be printed using positional notation does not exceed
+the number of digits of precision in the underlying floating-point
+number representation; @sc{ieee} double-precision floating-point numbers
+have 17 digits of precision.
+@end table
+
+@noindent
+This three-element list may be abbreviated in two ways. First, the
+symbol @code{normal} may be used, which is equivalent to the list
+@code{(normal 0 normal)}. Second, the third element of the list,
+@var{format-type}, may be omitted, in which case it defaults to
+@code{normal}.
+
+@noindent
+The default value for @code{flonum-unparser-cutoff} is @code{normal}.
+If it is bound to a value different from those described here,
+@code{number->string} issues a warning and acts as though the value had
+been @code{normal}.
+@end defvr
+
+@noindent
+Some examples of @code{flonum-unparser-cutoff}:
+
+@example
+(number->string (* 4 (atan 1 1)))
+ @result{} "3.141592653589793"
+(fluid-let ((flonum-unparser-cutoff '(relative 5)))
+ (number->string (* 4 (atan 1 1))))
+ @result{} "3.1416"
+(fluid-let ((flonum-unparser-cutoff '(relative 5)))
+ (number->string (* 4000 (atan 1 1))))
+ @result{} "3141.6"
+(fluid-let ((flonum-unparser-cutoff '(relative 5 scientific)))
+ (number->string (* 4000 (atan 1 1))))
+ @result{} "3.1416e3"
+(fluid-let ((flonum-unparser-cutoff '(relative 5 scientific)))
+ (number->string (* 40000 (atan 1 1))))
+ @result{} "3.1416e4"
+(fluid-let ((flonum-unparser-cutoff '(relative 5 engineering)))
+ (number->string (* 40000 (atan 1 1))))
+ @result{} "31.416e3"
+(fluid-let ((flonum-unparser-cutoff '(absolute 5)))
+ (number->string (* 4 (atan 1 1))))
+ @result{} "3.14159"
+(fluid-let ((flonum-unparser-cutoff '(absolute 5)))
+ (number->string (* 4000 (atan 1 1))))
+ @result{} "3141.59265"
+(fluid-let ((flonum-unparser-cutoff '(absolute -4)))
+ (number->string (* 4e10 (atan 1 1))))
+ @result{} "31415930000."
+(fluid-let ((flonum-unparser-cutoff '(absolute -4 scientific)))
+ (number->string (* 4e10 (atan 1 1))))
+ @result{} "3.141593e10"
+(fluid-let ((flonum-unparser-cutoff '(absolute -4 engineering)))
+ (number->string (* 4e10 (atan 1 1))))
+ @result{} "31.41593e9"
+(fluid-let ((flonum-unparser-cutoff '(absolute -5)))
+ (number->string (* 4e10 (atan 1 1))))
+ @result{} "31415900000."
+@end example
+
+@deffn procedure string->number string [radix]
+Returns a number of the maximally precise representation expressed by
+the given @var{string}. @var{Radix} must be an exact integer, either 2,
+8, 10, or 16. If supplied, @var{radix} is a default radix that may be
+overridden by an explicit radix prefix in @var{string} (e.g.@:
+@code{"#o177"}). If @var{radix} is not supplied, then the default radix
+is 10. If @var{string} is not a syntactically valid notation for a
+number, then @code{string->number} returns @code{#f}.
+
+@example
+@group
+(string->number "100") @result{} 100
+(string->number "100" 16) @result{} 256
+(string->number "1e2") @result{} 100.0
+(string->number "15##") @result{} 1500.0
+@end group
+@end example
+
+@noindent
+Note that a numeric representation using a decimal point or an exponent
+marker is not recognized unless @var{radix} is @code{10}.
+@end deffn
+
+@node Fixnum and Flonum Operations, Random Numbers, Numerical input and output, Numbers
+@section Fixnum and Flonum Operations
+
+This section describes numerical operations that are restricted forms of
+the operations described above. These operations are useful because
+they compile very efficiently. However, care should be exercised: if
+used improperly, these operations can return incorrect answers, or even
+malformed objects that confuse the garbage collector.
+
+@menu
+* Fixnum Operations::
+* Flonum Operations::
+@end menu
+
+@node Fixnum Operations, Flonum Operations, Fixnum and Flonum Operations, Fixnum and Flonum Operations
+@subsection Fixnum Operations
+
+@cindex fixnum (defn)
+A @dfn{fixnum} is an exact integer that is small enough to fit in a
+machine word. In MIT/GNU Scheme, fixnums are typically 24 or 26 bits,
+depending on the machine; it is reasonable to assume that fixnums are at
+least 24 bits. Fixnums are signed; they are encoded using 2's
+complement.
+
+All exact integers that are small enough to be encoded as fixnums are
+always encoded as fixnums --- in other words, any exact integer that is
+not a fixnum is too big to be encoded as such. For this reason, small
+constants such as @code{0} or @code{1} are guaranteed to be fixnums.
+
+@deffn procedure fix:fixnum? object
+@cindex type predicate, for fixnum
+Returns @code{#t} if @var{object} is a fixnum; otherwise returns
+@code{#f}.
+@end deffn
+
+Here is an expression that determines the largest fixnum:
+
+@example
+@group
+(let loop ((n 1))
+ (if (fix:fixnum? n)
+ (loop (* n 2))
+ (- n 1)))
+@end group
+@end example
+
+@noindent
+A similar expression determines the smallest fixnum.
+
+@deffn procedure fix:= fixnum fixnum
+@deffnx procedure fix:< fixnum fixnum
+@deffnx procedure fix:> fixnum fixnum
+@deffnx procedure fix:<= fixnum fixnum
+@deffnx procedure fix:>= fixnum fixnum
+@cindex equivalence predicate, for fixnums
+These are the standard order and equality predicates on fixnums. When
+compiled, they do not check the types of their arguments.
+@end deffn
+
+@deffn procedure fix:zero? fixnum
+@deffnx procedure fix:positive? fixnum
+@deffnx procedure fix:negative? fixnum
+These procedures compare their argument to zero. When compiled, they do
+not check the type of their argument. The code produced by the
+following expressions is identical:
+
+@example
+@group
+(fix:zero? @var{fixnum})
+(fix:= @var{fixnum} 0)
+@end group
+@end example
+
+@noindent
+Similarly, @code{fix:positive?} and @code{fix:negative?} produce code
+identical to equivalent expressions using @code{fix:>} and @code{fix:<}.
+@end deffn
+
+@deffn procedure fix:+ fixnum fixnum
+@deffnx procedure fix:- fixnum fixnum
+@deffnx procedure fix:* fixnum fixnum
+@deffnx procedure fix:quotient fixnum fixnum
+@deffnx procedure fix:remainder fixnum fixnum
+@deffnx procedure fix:gcd fixnum fixnum
+@deffnx procedure fix:1+ fixnum
+@deffnx procedure fix:-1+ fixnum
+These procedures are the standard arithmetic operations on fixnums.
+When compiled, they do not check the types of their arguments.
+Furthermore, they do not check to see if the result can be encoded as a
+fixnum. If the result is too large to be encoded as a fixnum, a
+malformed object is returned, with potentially disastrous effect on the
+garbage collector.
+@end deffn
+
+@deffn procedure fix:divide fixnum fixnum
+@findex integer-divide
+@findex integer-divide-quotient
+@findex integer-divide-remainder
+This procedure is like @code{integer-divide}, except that its arguments
+and its results must be fixnums. It should be used in conjunction with
+@code{integer-divide-quotient} and @code{integer-divide-remainder}.
+@end deffn
+
+@cindex logical operations, on fixnums
+@cindex bitwise-logical operations, on fixnums
+The following are @dfn{bitwise-logical} operations on fixnums.
+
+@deffn procedure fix:not fixnum
+This returns the bitwise-logical inverse of its argument. When
+compiled, it does not check the type of its argument.
+
+@example
+@group
+(fix:not 0) @result{} -1
+(fix:not -1) @result{} 0
+(fix:not 1) @result{} -2
+(fix:not -34) @result{} 33
+@end group
+@end example
+@end deffn
+
+@deffn procedure fix:and fixnum fixnum
+This returns the bitwise-logical ``and'' of its arguments. When
+compiled, it does not check the types of its arguments.
+
+@example
+@group
+(fix:and #x43 #x0f) @result{} 3
+(fix:and #x43 #xf0) @result{} #x40
+@end group
+@end example
+@end deffn
+
+@deffn procedure fix:andc fixnum fixnum
+Returns the bitwise-logical ``and'' of the first argument with the
+bitwise-logical inverse of the second argument. When compiled, it does
+not check the types of its arguments.
+
+@example
+@group
+(fix:andc #x43 #x0f) @result{} #x40
+(fix:andc #x43 #xf0) @result{} 3
+@end group
+@end example
+@end deffn
+
+@deffn procedure fix:or fixnum fixnum
+This returns the bitwise-logical ``inclusive or'' of its arguments.
+When compiled, it does not check the types of its arguments.
+
+@example
+@group
+(fix:or #x40 3) @result{} #x43
+(fix:or #x41 3) @result{} #x43
+@end group
+@end example
+@end deffn
+
+@deffn procedure fix:xor fixnum fixnum
+This returns the bitwise-logical ``exclusive or'' of its arguments.
+When compiled, it does not check the types of its arguments.
+
+@example
+@group
+(fix:xor #x40 3) @result{} #x43
+(fix:xor #x41 3) @result{} #x42
+@end group
+@end example
+@end deffn
+
+@deffn procedure fix:lsh fixnum1 fixnum2
+This procedure returns the result of logically shifting @var{fixnum1} by
+@var{fixnum2} bits. If @var{fixnum2} is positive, @var{fixnum1} is
+shifted left; if negative, it is shifted right. When compiled, it does
+not check the types of its arguments, nor the validity of its result.
+
+@example
+@group
+(fix:lsh 1 10) @result{} #x400
+(fix:lsh #x432 -10) @result{} 1
+(fix:lsh -1 3) @result{} -8
+(fix:lsh -128 -4) @result{} #x3FFFF8
+@end group
+@end example
+@end deffn
+
+@node Flonum Operations, , Fixnum Operations, Fixnum and Flonum Operations
+@subsection Flonum Operations
+
+@cindex flonum (defn)
+A @dfn{flonum} is an inexact real number that is implemented as a
+floating-point number. In MIT/GNU Scheme, all inexact real numbers are
+flonums. For this reason, constants such as @code{0.} and @code{2.3}
+are guaranteed to be flonums.
+
+@deffn procedure flo:flonum? object
+@cindex type predicate, for flonum
+Returns @code{#t} if @var{object} is a flonum; otherwise returns @code{#f}.
+@end deffn
+
+@deffn procedure flo:= flonum1 flonum2
+@deffnx procedure flo:< flonum1 flonum2
+@deffnx procedure flo:> flonum1 flonum2
+@cindex equivalence predicate, for flonums
+These procedures are the standard order and equality predicates on
+flonums. When compiled, they do not check the types of their arguments.
+@end deffn
+
+@deffn procedure flo:zero? flonum
+@deffnx procedure flo:positive? flonum
+@deffnx procedure flo:negative? flonum
+Each of these procedures compares its argument to zero. When compiled,
+they do not check the type of their argument.
+@end deffn
+
+@deffn procedure flo:+ flonum1 flonum2
+@deffnx procedure flo:- flonum1 flonum2
+@deffnx procedure flo:* flonum1 flonum2
+@deffnx procedure flo:/ flonum1 flonum2
+These procedures are the standard arithmetic operations on flonums.
+When compiled, they do not check the types of their arguments.
+@end deffn
+
+@deffn procedure flo:finite? flonum
+@vindex +inf
+@vindex -inf
+@vindex NaN
+@cindex positive infinity (@code{+inf})
+@cindex negative infinity (@code{-inf})
+@cindex not a number (@code{NaN})
+The @acronym{IEEE} floating-point number specification supports three
+special ``numbers'': positive infinity (@code{+inf}), negative infinity
+(@code{-inf}), and not-a-number (@code{NaN}). This predicate returns
+@code{#f} if @var{flonum} is one of these objects, and @code{#t} if it
+is any other floating-point number.
+@end deffn
+
+@deffn procedure flo:negate flonum
+This procedure returns the negation of its argument. When compiled, it
+does not check the type of its argument. Equivalent to @code{(flo:- 0.
+@var{flonum})}.
+@end deffn
+
+@deffn procedure flo:abs flonum
+@deffnx procedure flo:exp flonum
+@deffnx procedure flo:log flonum
+@deffnx procedure flo:sin flonum
+@deffnx procedure flo:cos flonum
+@deffnx procedure flo:tan flonum
+@deffnx procedure flo:asin flonum
+@deffnx procedure flo:acos flonum
+@deffnx procedure flo:atan flonum
+@deffnx procedure flo:sqrt flonum
+@deffnx procedure flo:expt flonum1 flonum2
+@deffnx procedure flo:floor flonum
+@deffnx procedure flo:ceiling flonum
+@deffnx procedure flo:truncate flonum
+@deffnx procedure flo:round flonum
+@deffnx procedure flo:floor->exact flonum
+@deffnx procedure flo:ceiling->exact flonum
+@deffnx procedure flo:truncate->exact flonum
+@deffnx procedure flo:round->exact flonum
+These procedures are flonum versions of the corresponding procedures.
+When compiled, they do not check the types of their arguments.
+@end deffn
+
+@deffn procedure flo:atan2 flonum1 flonum2
+@findex atan
+This is the flonum version of @code{atan} with two arguments. When
+compiled, it does not check the types of its arguments.
+@end deffn
+
+@node Random Numbers, , Fixnum and Flonum Operations, Numbers
+@section Random Numbers
+@cindex random number
+@cindex pseudo-random number
+@cindex number, pseudo-random
+
+MIT/GNU Scheme provides a facility for generating pseudo-random numbers.
+The current implementation is a ``subtract-with-carry'' random-number
+generator, based on the algorithm from @cite{A New Class of Random
+Number Generators}, George Marsaglia and Arif Zaman, @cite{The Annals of
+Applied Probability}, Vol.@: 1, No.@: 3, 1991. At the time it was
+implemented, this was a good algorithm for general purposes, but the
+state of the art in random-number generation is constantly changing. If
+necessary, the implementation will be updated to use a new algorithm
+while retaining the same interface.
+
+The interface described here is very similar to that of Common Lisp.
+
+@deffn procedure random modulus [state]
+@var{Modulus} must be a positive real number. @code{random} returns a
+pseudo-random number between zero (inclusive) and @var{modulus}
+(exclusive). The exactness of the returned number is the same as the
+exactness of @var{modulus}. Additionally, if @var{modulus} is an exact
+integer, the returned number will be also. Usually, @var{modulus} is
+either an exact integer or an inexact real; the current implementation
+has been tuned to make these two cases fast.
+
+If @var{state} is given and not @code{#f}, it must be a random-state
+object; otherwise, it defaults to the value of the variable
+@code{*random-state*}. This object is used to maintain the state of the
+pseudo-random-number generator and is altered as a side effect of the
+@code{random} procedure.
+
+@example
+@group
+(random 1.0) @result{} .32744744667719056
+(random 1.0) @result{} .01668326768172354
+(random 10) @result{} 3
+(random 10) @result{} 8
+(random 100) @result{} 38
+(random 100) @result{} 63
+(random 100/3) @result{} 130501475769920525/6755399441055744
+(random 100/3) @result{} 170571694016427575/13510798882111488
+@end group
+@end example
+@end deffn
+
+@deffn procedure flo:random-unit state
+@var{State} must be a random-state object. @code{flo:random-unit}
+returns a pseudo-random number between zero inclusive and one exclusive;
+the returned number is always a flonum and therefore an inexact real
+number. @code{flo:random-unit} is equivalent to @code{random} with a
+@var{modulus} of @code{1.0}, except that it is faster.
+@end deffn
+
+The next three definitions concern random-state objects. In addition to
+these definitions, it is important to know that random-state objects are
+specifically designed so that they can be saved to disk using the
+@code{fasdump} procedure, and later restored using the @code{fasload}
+procedure. This allows a particular random-state object to be saved in
+order to replay a particular pseudo-random sequence.
+
+@defvr variable *random-state*
+This variable holds a data structure, a random-state object, that
+encodes the internal state of the random-number generator that
+@code{random} uses by default. A call to @code{random} will perform a
+side effect on this data structure. This variable may be changed, using
+@code{set!} or @code{fluid-let}, to hold a new random-state object.
+@end defvr
+
+@deffn procedure make-random-state [state]
+This procedure returns a new random-state object, suitable for use as
+the value of the variable @code{*random-state*}, or as the @var{state}
+argument to @code{random}. If @var{state} is not given or @code{#f},
+@code{make-random-state} returns a @emph{copy} of the current
+random-number state object (the value of the variable
+@code{*random-state*}). If @var{state} is a random-state object, a copy
+of that object is returned. If @var{state} is @code{#t}, then a new
+random-state object is returned that has been ``randomly'' initialized
+by some means (such as by a time-of-day clock).
+@end deffn
+
+@deffn procedure random-state? object
+Returns @code{#t} if @var{object} is a random-state object, otherwise
+returns @code{#f}.
+@end deffn
--- /dev/null
+@c This file is part of the MIT/GNU Scheme Reference Manual.
+@c $Id: os-interface.texi,v 1.1 2003/04/15 03:30:00 cph Exp $
+
+@c Copyright 1991,1992,1993,1994,1995 Massachusetts Institute of Technology
+@c Copyright 1996,1997,1999,2000,2001 Massachusetts Institute of Technology
+@c Copyright 2002,2003 Massachusetts Institute of Technology
+@c See file scheme.texinfo for copying conditions.
+
+@node Operating-System Interface, Error System, Input/Output, Top
+@chapter Operating-System Interface
+@cindex Operating-System Interface
+
+The Scheme standard provides a simple mechanism for reading and writing
+files: file ports. MIT/GNU Scheme provides additional tools for
+dealing with other aspects of the operating system:
+
+@itemize @bullet
+@item
+@dfn{Pathnames} are a reasonably operating-system independent tool for
+manipulating the component parts of file names. This can be useful for
+implementing defaulting of file name components.
+@cindex pathname
+
+@item
+Control over the @dfn{current working directory}: the place in the file
+system from which relative file names are interpreted.
+@cindex current working directory
+
+@item
+Procedures that rename, copy, delete, and test for the existence of
+files. Also, procedures that return detailed information about a
+particular file, such as its type (directory, link, etc.) or length.
+
+@item
+Procedures for reading the contents of a directory.
+
+@item
+Procedures for obtaining times in various formats, converting between
+the formats, and generating human-readable time strings.
+
+@item
+Procedures to run other programs as subprocesses of Scheme, to read
+their output, and write input to them.
+
+@item
+A means to determine the operating system Scheme is running under.
+@end itemize
+
+@menu
+* Pathnames::
+* Working Directory::
+* File Manipulation::
+* Directory Reader::
+* Date and Time::
+* Machine Time::
+* Subprocesses::
+* TCP Sockets::
+* Miscellaneous OS Facilities::
+@end menu
+
+@node Pathnames, Working Directory, Operating-System Interface, Operating-System Interface
+@section Pathnames
+
+@comment **** begin CLTL ****
+@cindex file name
+MIT/GNU Scheme programs need to use names to designate files. The main
+difficulty in dealing with names of files is that different file systems
+have different naming formats for files. For example, here is a table
+of several file systems (actually, operating systems that provide file
+systems) and what equivalent file names might look like for each one:
+
+@example
+@group
+System File Name
+------ ---------
+TOPS-20 <LISPIO>FORMAT.FASL.13
+TOPS-10 FORMAT.FAS[1,4]
+ITS LISPIO;FORMAT FASL
+MULTICS >udd>LispIO>format.fasl
+TENEX <LISPIO>FORMAT.FASL;13
+VAX/VMS [LISPIO]FORMAT.FAS;13
+UNIX /usr/lispio/format.fasl
+DOS C:\USR\LISPIO\FORMAT.FAS
+@end group
+@end example
+
+@cindex filename (defn)
+@cindex pathname (defn)
+It would be impossible for each program that deals with file names to
+know about each different file name format that exists; a new operating
+system to which Scheme was ported might use a format different from any
+of its predecessors. Therefore, MIT/GNU Scheme provides @emph{two} ways to
+represent file names: @dfn{filenames} (also called @dfn{namestrings}),
+which are strings in the implementation-dependent form customary for the
+file system, and @dfn{pathnames}, which are special abstract data
+objects that represent file names in an implementation-independent way.
+Procedures are provided to convert between these two representations,
+and all manipulations of files can be expressed in machine-independent
+terms by using pathnames.
+
+@cindex host, in filename
+In order to allow MIT/GNU Scheme programs to operate in a network
+environment that may have more than one kind of file system, the
+pathname facility allows a file name to specify which file system is to
+be used. In this context, each file system is called a @dfn{host}, in
+keeping with the usual networking terminology.@footnote{This
+introduction is adapted from @cite{Common Lisp, The Language}, second
+edition, section 23.1.}
+@comment **** end CLTL ****
+
+Note that the examples given in this section are specific to unix
+pathnames. Pathnames for other operating systems have different
+external representations.
+
+@menu
+* Filenames and Pathnames::
+* Components of Pathnames::
+* Operations on Pathnames::
+* Miscellaneous Pathnames::
+@end menu
+
+@node Filenames and Pathnames, Components of Pathnames, Pathnames, Pathnames
+@subsection Filenames and Pathnames
+
+Pathname objects are usually created by parsing filenames (character
+strings) into component parts. MIT/GNU Scheme provides operations that
+convert filenames into pathnames and vice versa.
+
+@deffn procedure ->pathname object
+@cindex construction, of pathname
+Returns a pathname that is the equivalent of @var{object}. @var{Object}
+must be a pathname or a string. If @var{object} is a pathname, it is
+returned. If @var{object} is a string, this procedure returns the
+pathname that corresponds to the string; in this case it is equivalent
+to @code{(parse-namestring @var{object} #f #f)}.
+
+@example
+@group
+(->pathname "foo") @result{} #[pathname 65 "foo"]
+(->pathname "/usr/morris") @result{} #[pathname 66 "/usr/morris"]
+@end group
+@end example
+@end deffn
+
+
+@deffn procedure parse-namestring thing [host [defaults]]
+@cindex construction, of pathname
+This turns @var{thing} into a pathname.
+@var{Thing} must be a pathname or a string.
+If @var{thing} is a pathname, it is returned. If @var{thing} is a
+string, this procedure returns the pathname that corresponds to the
+string, parsed according to the syntax of the file system specified by
+@var{host}.
+
+This procedure @emph{does not} do defaulting of pathname components.
+
+The optional arguments are used to determine what syntax should be used
+for parsing the string. In general this is only really useful if your
+implementation of MIT/GNU Scheme supports more than one file system,
+otherwise you would use @code{->pathname}. If given, @var{host} must be
+a host object or @code{#f}, and @var{defaults} must be a pathname.
+@var{Host} specifies the syntax used to parse the string. If @var{host}
+is not given or @code{#f}, the host component from @var{defaults} is
+used instead; if @var{defaults} is not given, the host component from
+@code{*default-pathname-defaults*} is used.
+@end deffn
+
+@deffn procedure ->namestring pathname
+@cindex conversion, pathname to string
+@code{->namestring} returns a newly allocated string that is the
+filename corresponding to @var{pathname}.
+@example
+@group
+(->namestring (->pathname "/usr/morris/minor.van"))
+ @result{} "/usr/morris/minor.van"
+@end group
+@end example
+@end deffn
+
+
+@deffn procedure pathname-simplify pathname
+@cindex simplification, of pathname
+Returns a pathname that locates the same file or directory as
+@var{pathname}, but is in some sense simpler. Note that
+@code{pathname-simplify} might not always be able to simplify the
+pathname, e.g.@: on unix with symbolic links the directory
+@file{/usr/morris/../} need not be the same as @file{/usr/}. In cases
+of uncertainty the behavior is conservative, returning the original or a
+partly simplified pathname.
+
+@example
+@group
+(pathname-simplify "/usr/morris/../morris/dance")
+ @result{} #[pathname "/usr/morris/dance"]
+@end group
+@end example
+@end deffn
+
+@node Components of Pathnames, Operations on Pathnames, Filenames and Pathnames, Pathnames
+@subsection Components of Pathnames
+@cindex components, of pathname
+@cindex pathname components
+
+@comment **** begin CLTL ****
+A pathname object always has six components, described below. These
+components are the common interface that allows programs to work the
+same way with different file systems; the mapping of the pathname
+components into the concepts peculiar to each file system is taken care
+of by the Scheme implementation.
+
+@table @var
+@item host
+The name of the file system on which the file resides. In the current
+implementation, this component is always a host object that is filled in
+automatically by the runtime system. When specifying the host
+component, use either @code{#f} or the value of the variable
+@code{local-host}.
+@cindex host, pathname component
+
+@item device
+Corresponds to the ``device'' or ``file structure'' concept in many host
+file systems: the name of a (logical or physical) device containing
+files. This component is the drive letter for PC file systems, and is
+unused for unix file systems.
+@cindex device, pathname component
+
+@item directory
+Corresponds to the ``directory'' concept in many host file systems: the
+name of a group of related files (typically those belonging to a single
+user or project). This component is always used for all file systems.
+@cindex directory, pathname component
+
+@item name
+The name of a group of files that can be thought of as conceptually the
+``same'' file. This component is always used for all file systems.
+@cindex name, pathname component
+
+@item type
+Corresponds to the ``filetype'' or ``extension'' concept in many host
+file systems. This says what kind of file this is. Files with the same
+name but different type are usually related in some specific way, such
+as one being a source file, another the compiled form of that source,
+and a third the listing of error messages from the compiler. This
+component is currently used for all file systems, and is formed by
+taking the characters that follow the last dot in the namestring.
+@cindex type, pathname component
+
+@item version
+Corresponds to the ``version number'' concept in many host file systems.
+Typically this is a number that is incremented every time the file is
+modified. This component is currently unused for all file systems.
+@cindex version, pathname component
+@end table
+
+Note that a pathname is not necessarily the name of a specific file.
+Rather, it is a specification (possibly only a partial specification) of
+how to access a file. A pathname need not correspond to any file that
+actually exists, and more than one pathname can refer to the same file.
+For example, the pathname with a version of @code{newest} may refer to
+the same file as a pathname with the same components except a certain
+number as the version. Indeed, a pathname with version @code{newest}
+may refer to different files as time passes, because the meaning of such
+a pathname depends on the state of the file system. In file systems
+with such facilities as ``links'', multiple file names, logical devices,
+and so on, two pathnames that look quite different may turn out to
+address the same file. To access a file given a pathname, one must do a
+file-system operation such as @code{open-input-file}.
+
+Two important operations involving pathnames are @dfn{parsing} and
+@dfn{merging}. Parsing is the conversion of a filename (which might be
+something supplied interactively by the users when asked to supply the
+name of a file) into a pathname object. This operation is
+implementation-dependent, because the format of filenames is
+implementation-dependent. Merging takes a pathname with missing
+components and supplies values for those components from a source of
+default values.
+
+Not all of the components of a pathname need to be specified. If a
+component of a pathname is missing, its value is @code{#f}.
+Before the file system interface can do anything interesting with a
+file, such as opening the file, all the missing components of a pathname
+must be filled in. Pathnames with missing components are used
+internally for various purposes; in particular, parsing a namestring
+that does not specify certain components will result in a pathname with
+missing components.
+
+Any component of a pathname may be the symbol @code{unspecific}, meaning
+that the component simply does not exist, for file systems in which such
+a value makes no sense. For example, unix, Windows, and OS/2 file
+systems usually do not support version numbers, so the version component
+for such a host might be @code{unspecific}.@footnote{This description is
+adapted from @cite{Common Lisp, The Language}, second edition, section
+23.1.1.}
+@comment **** end CLTL ****
+
+In addition to @code{#f} and @code{unspecific}, the components of a
+pathname may take on the following meaningful values:
+
+@table @var
+@item host
+An implementation-defined type which may be tested for using the
+@code{host?} predicate.
+
+@item device
+On systems that support this component (Windows and OS/2), it may be
+specified as a string containing a single alphabetic character, for
+which the alphabetic case is ignored.
+
+@item directory
+A non-empty list, which represents a @dfn{directory path}: a sequence of
+directories, each of which has a name in the previous directory, the
+last of which is the directory specified by the entire path. Each
+element in such a path specifies the name of the directory relative to
+the directory specified by the elements to its left. The first element
+of the list is either the symbol @code{absolute} or the symbol
+@code{relative}. If the first element in the list is the symbol
+@code{absolute}, then the directory component (and subsequently the
+pathname) is @dfn{absolute}; the first component in the sequence is to
+be found at the ``root'' of the file system. If the directory is
+@dfn{relative} then the first component is to be found in some as yet
+unspecified directory; typically this is later specified to be the
+@dfn{current working directory}.
+@cindex root, as pathname component
+@cindex directory path (defn)
+@cindex path, directory (defn)
+
+@cindex up, as pathname component
+@cindex parent, of directory
+Aside from @code{absolute} and @code{relative}, which may only appear as
+the first element of the list, each subsequent element in the list is
+either: a string, which is a literal component; the symbol @code{wild},
+meaningful only when used in conjunction with the directory reader; or
+the symbol @code{up}, meaning the next directory is the ``parent'' of
+the previous one. @code{up} corresponds to the file @file{..} in unix
+and PC file systems.
+
+(The following note does not refer to any file system currently
+supported by MIT/GNU Scheme, but is included for completeness.) In file
+systems that do not have ``hierarchical'' structure, a specified
+directory component will always be a list whose first element is
+@code{absolute}. If the system does not support directories other than
+a single global directory, the list will have no other elements. If the
+system supports ``flat'' directories, i.e.@: a global set of directories
+with no subdirectories, then the list will contain a second element,
+which is either a string or @code{wild}. In other words, a
+non-hierarchical file system is treated as if it were hierarchical, but
+the hierarchical features are unused. This representation is somewhat
+inconvenient for such file systems, but it discourages programmers from
+making code depend on the lack of a file hierarchy.
+
+@item name
+A string, which is a literal component; or the symbol @code{wild},
+meaningful only when used in conjunction with the directory reader.
+
+@item type
+A string, which is a literal component; or the symbol @code{wild},
+meaningful only when used in conjunction with the directory reader.
+
+@item version
+An exact positive integer, which is a literal component; the symbol
+@code{newest}, which means to choose the largest available version
+number for that file; the symbol @code{oldest}, which means to choose
+the smallest version number; or the symbol @code{wild}, meaningful only
+when used in conjunction with the directory reader. In the future some
+other possible values may be added, e.g.@: @code{installed}. Note that
+currently no file systems support version numbers; thus this component
+is not used and should be specified as @code{#f}.
+@cindex newest, as pathname component
+@cindex oldest, as pathname component
+@cindex installed, as pathname component
+@end table
+
+@deffn procedure make-pathname host device directory name type version
+@cindex construction, of pathname
+Returns a pathname object whose components are the respective arguments.
+Each argument must satisfy the restrictions for the corresponding
+component, which were outlined above.
+
+@example
+@group
+(make-pathname #f
+ #f
+ '(absolute "usr" "morris")
+ "foo"
+ "scm"
+ #f)
+ @result{} #[pathname 67 "/usr/morris/foo.scm"]
+@end group
+@end example
+@end deffn
+
+@deffn procedure pathname-host pathname
+@deffnx procedure pathname-device pathname
+@deffnx procedure pathname-directory pathname
+@deffnx procedure pathname-name pathname
+@deffnx procedure pathname-type pathname
+@deffnx procedure pathname-version pathname
+Returns a particular component of @var{pathname}.
+
+@example
+@group
+(define x (->pathname "/usr/morris/foo.scm"))
+(pathname-host x) @result{} #[host 1]
+(pathname-device x) @result{} unspecific
+(pathname-directory x) @result{} (absolute "usr" "morris")
+(pathname-name x) @result{} "foo"
+(pathname-type x) @result{} "scm"
+(pathname-version x) @result{} unspecific
+@end group
+@end example
+@end deffn
+
+@deffn procedure pathname-new-device pathname device
+@deffnx procedure pathname-new-directory pathname directory
+@deffnx procedure pathname-new-name pathname name
+@deffnx procedure pathname-new-type pathname type
+@deffnx procedure pathname-new-version pathname version
+Returns a new copy of @var{pathname} with the respective component
+replaced by the second argument. @var{Pathname} is unchanged.
+Portable programs should not explicitly replace a component with
+@code{unspecific} because this might not be permitted in some
+situations.
+
+@example
+@group
+(define p (->pathname "/usr/blisp/rel15"))
+p
+ @result{} #[pathname 71 "/usr/blisp/rel15"]
+(pathname-new-name p "rel100")
+ @result{} #[pathname 72 "/usr/blisp/rel100"]
+(pathname-new-directory p '(relative "test" "morris"))
+ @result{} #[pathname 73 "test/morris/rel15"]
+p
+ @result{} #[pathname 71 "/usr/blisp/rel15"]
+@end group
+@end example
+@end deffn
+
+@deffn procedure pathname-default-device pathname device
+@deffnx procedure pathname-default-directory pathname directory
+@deffnx procedure pathname-default-name pathname name
+@deffnx procedure pathname-default-type pathname type
+@deffnx procedure pathname-default-version pathname version
+These operations are similar to the @code{pathname-new-@var{component}}
+operations, except that they only change the specified @var{component}
+if it has the value @code{#f} in @var{pathname}.
+@end deffn
+
+@node Operations on Pathnames, Miscellaneous Pathnames, Components of Pathnames, Pathnames
+@subsection Operations on Pathnames
+
+@deffn procedure pathname? object
+@cindex type predicate, for pathname
+Returns @code{#t} if @var{object} is a pathname; otherwise returns
+@code{#f}.
+@end deffn
+
+@deffn procedure pathname=? pathname1 pathname2
+@cindex equivalence predicate, for pathnames
+Returns @code{#t} if @var{pathname1} is equivalent to @var{pathname2};
+otherwise returns @code{#f}.
+Pathnames are equivalent if all of their components are equivalent,
+hence two pathnames that are equivalent must identify the same file or
+equivalent partial pathnames.
+However, the converse is not true: non-equivalent pathnames may specify
+the same file (e.g.@: via absolute and relative directory components),
+and pathnames that specify no file at all (e.g.@: name and directory
+components unspecified) may be equivalent.
+@end deffn
+
+@deffn procedure pathname-absolute? pathname
+Returns @code{#t} if @var{pathname} is an absolute rather than relative
+pathname object; otherwise returns @code{#f}. Specifically, this
+procedure returns @code{#t} when the directory component of
+@var{pathname} is a list starting with the symbol @code{absolute}, and
+returns @code{#f} in all other cases. All pathnames are either absolute
+or relative, so if this procedure returns @code{#f}, the argument is a
+relative pathname.
+@end deffn
+
+@deffn procedure directory-pathname? pathname
+Returns @code{#t} if @var{pathname} has only directory components and no
+file components. This is roughly equivalent to
+
+@example
+@group
+(define (directory-pathname? pathname)
+ (string-null? (file-namestring pathname)))
+@end group
+@end example
+
+@noindent
+except that it is faster.
+@end deffn
+
+@deffn procedure pathname-wild? pathname
+Returns @code{#t} if @var{pathname} contains any wildcard components;
+otherwise returns @code{#f}.
+@end deffn
+
+@deffn procedure merge-pathnames pathname [defaults [default-version]]
+@cindex merging, of pathnames
+@cindex defaulting, of pathname
+Returns a pathname whose components are obtained by combining those of
+@var{pathname} and @var{defaults}. @var{Defaults} defaults to the value
+of @code{*default-pathname-defaults*} and @var{default-version} defaults
+to @code{newest}.
+
+The pathnames are combined by components: if @var{pathname} has a
+non-missing component, that is the resulting component, otherwise the
+component from @var{defaults} is used.
+The default version can be @code{#f} to preserve the information that
+the component was missing from @var{pathname}.
+The directory component is handled specially: if both pathnames have
+directory components that are lists, and the directory component from
+@var{pathname} is relative (i.e.@: starts with @code{relative}), then the
+resulting directory component is formed by appending @var{pathname}'s
+component to @var{defaults}'s component.
+For example:
+
+@example
+@group
+(define path1 (->pathname "scheme/foo.scm"))
+(define path2 (->pathname "/usr/morris"))
+path1
+ @result{} #[pathname 74 "scheme/foo.scm"]
+path2
+ @result{} #[pathname 75 "/usr/morris"]
+(merge-pathnames path1 path2)
+ @result{} #[pathname 76 "/usr/scheme/foo.scm"]
+(merge-pathnames path2 path1)
+ @result{} #[pathname 77 "/usr/morris.scm"]
+@end group
+@end example
+
+The merging rules for the version are more complex and depend on whether
+@var{pathname} specifies a name. If @var{pathname} does not specify a
+name, then the version, if not provided, will come from @var{defaults}.
+However, if @var{pathname} does specify a name then the version is not
+affected by @var{defaults}. The reason is that the version ``belongs
+to'' some other file name and is unlikely to have anything to do with
+the new one. Finally, if this process leaves the version missing, then
+@var{default-version} is used.
+
+The net effect is that if the user supplies just a name, then the host,
+device, directory and type will come from @var{defaults}, but the
+version will come from @var{default-version}. If the user supplies
+nothing, or just a directory, the name, type and version will come over
+from @var{defaults} together.
+@end deffn
+
+@defvr variable *default-pathname-defaults*
+@cindex defaulting, of pathname
+This is the default pathname-defaults pathname; if any pathname
+primitive that needs a set of defaults is not given one, it uses this
+one. @code{set-working-directory-pathname!} sets this variable to a new
+value, computed by merging the new working directory with the variable's
+old value.
+@end defvr
+
+@deffn procedure pathname-default pathname device directory name type version
+This procedure defaults all of the components of @var{pathname}
+simultaneously. It could have been defined by:
+
+@example
+@group
+(define (pathname-default pathname
+ device directory name type version)
+ (make-pathname (pathname-host pathname)
+ (or (pathname-device pathname) device)
+ (or (pathname-directory pathname) directory)
+ (or (pathname-name pathname) name)
+ (or (pathname-type pathname) type)
+ (or (pathname-version pathname) version)))
+@end group
+@end example
+@end deffn
+
+@deffn procedure file-namestring pathname
+@deffnx procedure directory-namestring pathname
+@deffnx procedure host-namestring pathname
+@deffnx procedure enough-namestring pathname [defaults]
+@cindex conversion, pathname to string
+These procedures return a string corresponding to a subset of the
+@var{pathname} information. @code{file-namestring} returns a string
+representing just the @var{name}, @var{type} and @var{version}
+components of @var{pathname}; the result of @code{directory-namestring}
+represents just the @var{host}, @var{device}, and @var{directory}
+components; and @code{host-namestring} returns a string for just the
+@var{host} portion.
+
+@code{enough-namestring} takes another argument, @var{defaults}.
+It returns an abbreviated namestring that is just sufficient to identify
+the file named by @var{pathname} when considered relative to the
+@var{defaults} (which defaults to @code{*default-pathname-defaults*}).
+
+@example
+@group
+(file-namestring "/usr/morris/minor.van")
+ @result{} "minor.van"
+(directory-namestring "/usr/morris/minor.van")
+ @result{} "/usr/morris/"
+(enough-namestring "/usr/morris/men")
+ @result{} "men" @r{;perhaps}
+@end group
+@end example
+@end deffn
+
+@deffn procedure file-pathname pathname
+@deffnx procedure directory-pathname pathname
+@deffnx procedure enough-pathname pathname [defaults]
+@cindex selection, components of pathname
+These procedures return a pathname corresponding to a subset of the
+@var{pathname} information.
+@code{file-pathname} returns a pathname with just the
+@var{name}, @var{type} and @var{version} components of @var{pathname}.
+The result of @code{directory-pathname} is a pathname containing the
+@var{host}, @var{device} and @var{directory} components of @var{pathname}.
+
+@code{enough-pathname} takes another argument, @var{defaults}.
+It returns an abbreviated pathname that is just sufficient to identify
+the file named by @var{pathname} when considered relative to the
+@var{defaults} (which defaults to @code{*default-pathname-defaults*}).
+
+These procedures are similar to @code{file-namestring},
+@code{directory-namestring} and @code{enough-namestring}, but they
+return pathnames instead of strings.
+@end deffn
+
+@deffn procedure directory-pathname-as-file pathname
+@cindex file, converting pathname directory to
+Returns a pathname that is equivalent to @var{pathname}, but in which
+the directory component is represented as a file.
+The last directory is removed from the directory component and converted
+into name and type components.
+This is the inverse operation to @code{pathname-as-directory}.
+
+@example
+@group
+(directory-pathname-as-file (->pathname "/usr/blisp/"))
+ @result{} #[pathname "/usr/blisp"]
+@end group
+@end example
+@end deffn
+
+@deffn procedure pathname-as-directory pathname
+@cindex directory, converting pathname to
+Returns a pathname that is equivalent to @var{pathname}, but in which
+any file components have been converted to a directory component. If
+@var{pathname} does not have name, type, or version components, it is
+returned without modification. Otherwise, these file components are
+converted into a string, and the string is added to the end of the list
+of directory components. This is the inverse operation to
+@code{directory-pathname-as-file}.
+
+@example
+@group
+(pathname-as-directory (->pathname "/usr/blisp/rel5"))
+ @result{} #[pathname "/usr/blisp/rel5/"]
+@end group
+@end example
+@end deffn
+
+
+@node Miscellaneous Pathnames, , Operations on Pathnames, Pathnames
+@subsection Miscellaneous Pathname Procedures
+@cindex directory, reading
+
+This section gives some standard operations on host objects, and some
+procedures that return some useful pathnames.
+
+@defvr variable local-host
+This variable has as its value the host object that describes the local
+host's file system.
+@end defvr
+
+@deffn procedure host? object
+@cindex type predicate, for pathname host
+Returns @code{#t} if @var{object} is a pathname host; otherwise returns
+@code{#f}.
+@end deffn
+
+@deffn procedure host=? host1 host2
+@cindex equivalence predicate, for pathname host
+Returns @code{#t} if @var{host1} and @var{host2} denote the same
+pathname host; otherwise returns @code{#f}.
+@end deffn
+
+@deffn procedure init-file-pathname [host]
+@cindex home directory, as pathname
+Returns a pathname for the user's initialization file on @var{host}.
+The @var{host} argument defaults to the value of @code{local-host}. If
+the initialization file does not exist this procedure returns @code{#f}.
+
+Under unix, the init file is called @file{.scheme.init}; under Windows
+and OS/2, the init file is called @file{scheme.ini}. In either
+case, it is located in the user's home directory, which is computed by
+@code{user-homedir-pathname}.
+@end deffn
+
+@deffn procedure user-homedir-pathname [host]
+@cindex home directory, as pathname
+Returns a pathname for the user's ``home directory'' on @var{host}. The
+@var{host} argument defaults to the value of @code{local-host}. The
+concept of a ``home directory'' is itself somewhat
+implementation-dependent, but it should be the place where the user
+keeps personal files, such as initialization files and mail.
+
+Under unix, the user's home directory is specified by the @code{HOME}
+environment variable. If this variable is undefined, the user name is
+computed using the @code{getlogin} system call, or if that fails, the
+@code{getuid} system call. The resulting user name is passed to the
+@code{getpwnam} system call to obtain the home directory.
+
+Under OS/2, several heuristics are tried to find the user's home
+directory. First, if the environment variable @code{HOME} is defined,
+that is the home directory. If @code{HOME} is undefined, but the
+@code{USERDIR} and @code{USER} environment variables are defined and
+the directory @file{%USERDIR%\%USER%} exists, then it is used. Failing
+that, if the directory @file{%USER%} exists on the OS/2 system
+drive, then it is used. As a last resort, the OS/2 system drive is
+the home directory.
+
+Like OS/2, the Windows implementation uses heuristics based on
+environment variables. The user's home directory is computed by
+examining several environment variables, in the following order:
+
+@itemize @bullet
+@item
+@code{HOMEDRIVE} and @code{HOMEPATH} are both defined and
+@file{%HOMEDRIVE%%HOMEPATH%} is an existing directory. (These variables
+are automatically defined by Windows NT.)
+
+@item
+@code{HOME} is defined and @file{%HOME%} is an existing directory.
+
+@item
+@code{USERDIR} and @code{USERNAME} are defined and
+@file{%USERDIR%\%USERNAME%} is an existing directory.
+
+@item
+@code{USERDIR} and @code{USER} are defined and
+@file{%USERDIR%\%USER%} is an existing directory.
+
+@item
+@code{USERNAME} is defined and @file{%USERNAME%} is an existing
+directory on the Windows system drive.
+
+@item
+@code{USER} is defined and @file{%USER%} is an existing directory on the
+Windows system drive.
+
+@item
+Finally, if all else fails, the Windows system drive is used as the home
+directory.
+@end itemize
+@end deffn
+
+@deffn procedure system-library-pathname pathname
+@cindex library, system pathname
+Locates @var{pathname} in MIT/GNU Scheme's system library directory. An
+error of type @code{condition-type:file-operation-error} is signalled if
+@var{pathname} cannot be located on the library search path.
+@findex condition-type:file-operation-error
+
+@example
+@group
+(system-library-pathname "compiler.com")
+ @result{} #[pathname 45 "/usr/local/lib/mit-scheme/compiler.com"]
+@end group
+@end example
+@end deffn
+
+@deffn procedure system-library-directory-pathname pathname
+@cindex library, system pathname
+Locates the pathname of an MIT/GNU Scheme system library directory. An
+error of type @code{condition-type:file-operation-error} is signalled if
+@var{pathname} cannot be located on the library search path.
+
+@example
+@group
+(system-library-directory-pathname "options")
+ @result{} #[pathname 44 "/usr/local/lib/mit-scheme/options/"]
+@end group
+@end example
+@end deffn
+
+@node Working Directory, File Manipulation, Pathnames, Operating-System Interface
+@section Working Directory
+
+@cindex absolute pathname (defn)
+@cindex pathname, absolute (defn)
+@cindex relative pathname (defn)
+@cindex pathname, relative (defn)
+@cindex directory, current working (defn)
+@cindex current working directory (defn)
+@cindex working directory (see current working directory)
+When MIT/GNU Scheme is started, the @dfn{current working directory} (or
+simply, @dfn{working directory}) is initialized in an operating-system
+dependent manner; usually, it is the directory in which Scheme was
+invoked. The working directory can be determined from within Scheme by
+calling the @code{pwd} procedure, and changed by calling the @code{cd}
+procedure. Each @acronym{REP} loop has its own working directory, and
+inferior @acronym{REP} loops initialize their working directory from the
+value in effect in their superior at the time they are created.
+
+@deffn procedure working-directory-pathname
+@deffnx procedure pwd
+Returns the current working directory as a pathname that has no name,
+type, or version components, just host, device, and directory
+components. @code{pwd} is an alias for
+@code{working-directory-pathname}; the long name is intended for
+programs and the short name for interactive use.
+@end deffn
+
+@deffn procedure set-working-directory-pathname! filename
+@deffnx procedure cd filename
+@findex ->pathname
+@findex pathname-as-directory
+Makes @var{filename} the current working directory and returns the new
+current working directory as a pathname. @var{Filename} is coerced to a
+pathname using @code{pathname-as-directory}. @code{cd} is an alias for
+@code{set-working-directory-pathname!}; the long name is intended for
+programs and the short name for interactive use.
+
+Additionally, @code{set-working-directory-pathname!} modifies the value
+of@* @code{*default-pathname-defaults*} by merging the new working
+directory into it.
+
+When this procedure is executed in the top-level @acronym{REP} loop, it
+changes the working directory of the running Scheme executable.
+
+@example
+@group
+(set-working-directory-pathname! "/usr/morris/blisp")
+ @result{} #[pathname "/usr/morris/blisp/"]
+(set-working-directory-pathname! "~")
+ @result{} #[pathname "/usr/morris/"]
+@end group
+@end example
+
+This procedure signals an error if @var{filename} does not refer to an
+existing directory.
+
+If @var{filename} describes a relative rather than absolute pathname,
+this procedure interprets it as relative to the current working
+directory, before changing the working directory.
+
+@example
+@group
+(working-directory-pathname)
+ @result{} #[pathname "/usr/morris/"]
+(set-working-directory-pathname! "foo")
+ @result{} #[pathname "/usr/morris/foo/"]
+@end group
+@end example
+@end deffn
+
+@deffn procedure with-working-directory-pathname filename thunk
+This procedure temporarily rebinds the current working directory to
+@var{filename}, invokes @var{thunk} (a procedure of no arguments), then
+restores the previous working directory and returns the value yielded by
+@var{thunk}. @var{Filename} is coerced to a pathname using
+@code{pathname-as-directory}. In addition to binding the working
+directory, @code{with-working-directory-pathname} also binds the
+variable @code{*default-pathname-defaults*}, merging the old value of
+that variable with the new working directory pathname. Both bindings
+are performed in exactly the same way as dynamic binding of a variable
+(@pxref{Dynamic Binding}).
+@end deffn
+
+@node File Manipulation, Directory Reader, Working Directory, Operating-System Interface
+@section File Manipulation
+
+This section describes procedures that manipulate files and directories.
+Any of these procedures can signal a number of errors for many reasons.
+The specifics of these errors are much too operating-system dependent to
+document here. However, if such an error is signalled by one of
+these procedures, it will be of type
+@code{condition-type:file-operation-error}.
+@findex condition-type:file-operation-error
+
+@deffn procedure file-exists? filename
+@deffnx procedure file-exists-direct? filename
+@deffnx procedure file-exists-indirect? filename
+@cindex existence, testing of file
+These procedures return @code{#t} if @var{filename} is an existing file
+or directory; otherwise they return @code{#f}. In operating systems
+that support symbolic links, if the file is a symbolic link,
+@code{file-exists-direct?} tests for the existence of the link, while
+@code{file-exists-indirect?} and @code{file-exists?} test for the
+existence of the file pointed to by the link.
+@end deffn
+
+@deffn procedure copy-file source-filename target-filename
+@cindex copying, of file
+Makes a copy of the file named by @var{source-filename}. The copy is
+performed by creating a new file called @var{target-filename}, and
+filling it with the same data as @var{source-filename}.
+@end deffn
+
+@deffn procedure rename-file source-filename target-filename
+@cindex renaming, of file
+@cindex name, of file
+Changes the name of @var{source-filename} to be @var{target-filename}.
+In the unix implementation, this will not rename across file systems.
+@end deffn
+
+@deffn procedure delete-file filename
+@cindex deletion, of file
+Deletes the file named @var{filename}.
+@end deffn
+
+@deffn procedure delete-file-no-errors filename
+Like @code{delete-file}, but returns a boolean value indicating whether
+an error occurred during the deletion. If no errors occurred, @code{#t}
+is returned. If an error of type @code{condition-type:file-error} or
+@code{condition-type:port-error} is signalled, @code{#f} is returned.
+@end deffn
+
+@deffn procedure hard-link-file source-filename target-filename
+@cindex linking (hard), of file
+@cindex hard linking, of file
+Makes a hard link from @var{source-filename} to @var{target-filename}.
+This operation gives the file specified by @var{source-filename} a new
+name, in addition to the old name.
+
+This currently works only on unix systems. It is further restricted to
+work only when @var{source-filename} and @var{target-filename} refer to
+names in the same file system.
+@end deffn
+
+@deffn procedure soft-link-file source-filename target-filename
+@cindex linking (soft), of file
+@cindex soft linking, of file
+@cindex symbolic linking, of file
+Creates a new soft link called @var{target-filename} that points at the
+file @var{source-filename}. (Soft links are also sometimes called
+@dfn{symbolic} links.) Note that @var{source-filename} will be
+interpreted as a string (although you may specify it as a pathname
+object, if you wish). The contents of this string will be stored in the
+file system as the soft link. When a file operation attempts to open
+the link, the contents of the link are interpreted relative to the
+link's location at that time.
+
+This currently works only on unix systems.
+@end deffn
+
+@deffn procedure make-directory filename
+Creates a new directory named @var{filename}. Signals an error if
+@var{filename} already exists, or if the directory cannot be created.
+@end deffn
+
+@deffn procedure delete-directory filename
+Deletes the directory named @var{filename}. Signals an error if
+the directory does not exist, is not a directory, or contains any files
+or subdirectories.
+@end deffn
+
+@deffn procedure ->truename filename
+@cindex truename, of input file
+This procedure attempts to discover and return the ``true name'' of the
+file associated with @var{filename} within the file system. An error of
+type @code{condition-type:file-operation-error} is signalled if the
+appropriate file cannot be located within the file system.
+@findex condition-type:file-operation-error
+@end deffn
+
+@deffn procedure call-with-temporary-file-pathname procedure
+Calls @code{temporary-file-pathname} to create a temporary file, then
+calls @var{procedure} with one argument, the pathname referring to that
+file. When @var{procedure} returns, if the temporary file still exists,
+it is deleted; then, the value yielded by @var{procedure} is returned.
+If @var{procedure} escapes from its continuation, and the file still
+exists, it is deleted.
+@end deffn
+
+@deffn procedure temporary-file-pathname [directory]
+Creates a new empty temporary file and returns a pathname referring to
+it. The temporary file is created with Scheme's default permissions, so
+barring unusual circumstances it can be opened for input and/or output
+without error. The temporary file will remain in existence until
+explicitly deleted. If the file still exists when the Scheme process
+terminates, it will be deleted.
+
+If @var{directory} is specified, the temporary file will be stored
+there. If it is not specified, or if it is @code{#f}, the temporary
+file will be stored in the directory returned by
+@code{temporary-directory-pathname}.
+@end deffn
+
+@deffn procedure temporary-directory-pathname
+Returns the pathname of an existing directory that can be used to store
+temporary files. These directory names are tried, in order, until a
+writeable directory is found:
+
+@itemize @bullet
+@item
+The directories specified by the environment variables @code{TMPDIR},
+@code{TEMP}, or @code{TMP}.
+
+@item
+Under unix, the directories @file{/var/tmp}, @file{/usr/tmp}, or
+@file{/tmp}.
+
+@item
+Under OS/2 or Windows, the following directories on the system drive:
+@file{\temp}, @file{\tmp}, or @file{\}.
+
+@item
+Under OS/2 or Windows, the current directory, as specified by
+@code{*default-pathname-defaults*}.
+@end itemize
+@end deffn
+
+@deffn procedure file-directory? filename
+@cindex directory, predicate for
+Returns @code{#t} if the file named @var{filename} exists and is a
+directory. Otherwise returns @code{#f}. In operating systems that
+support symbolic links, if @var{filename} names a symbolic link, this
+examines the file linked to, not the link itself.
+
+This is equivalent to
+
+@example
+(eq? 'directory (file-type-indirect @var{filename}))
+@end example
+@end deffn
+
+@deffn procedure file-regular? filename
+@cindex file (regular), predicate for
+@cindex regular file, predicate for
+Returns @code{#t} if the file named @var{filename} exists and is a
+regular file (i.e.@: not a directory, symbolic link, device file, etc.).
+Otherwise returns @code{#f}. In operating systems that support symbolic
+links, if @var{filename} names a symbolic link, this examines the file
+linked to, not the link itself.
+
+This is equivalent to
+
+@example
+(eq? 'regular (file-type-indirect @var{filename}))
+@end example
+@end deffn
+
+@deffn procedure file-symbolic-link? filename
+@cindex symbolic link, predicate for
+In operating systems that support symbolic links, if the file named
+@var{filename} exists and is a symbolic link, this procedure returns the
+contents of the symbolic link as a newly allocated string. The returned
+value is the name of the file that the symbolic link points to and must
+be interpreted relative to the directory of @var{filename}. If
+@var{filename} either does not exist or is not a symbolic link, or if
+the operating system does not support symbolic links, this procedure
+returns @code{#f}.
+@end deffn
+
+@deffn procedure file-type-direct filename
+@deffnx procedure file-type-indirect filename
+@cindex file type, procedure for
+If the file named @var{filename} exists, @code{file-type-direct} returns
+a symbol specifying what type of file it is. For example, if
+@var{filename} refers to a directory, the symbol @code{directory} is
+returned. If @var{filename} doesn't refer to an existing file,
+@code{#f} is returned.
+
+If @var{filename} refers to a symbolic link, @code{file-type-direct}
+returns the type of the link itself, while @code{file-type-indirect}
+returns the type of the file linked to.
+
+At this time, the symbols that can be returned are the following. The
+names are intended to be self-explanatory. Most of these names can only
+be returned on particular operating systems, and so the operating-system
+name is prefixed to the name.
+
+@example
+regular
+directory
+unix-symbolic-link
+unix-character-device
+unix-block-device
+unix-named-pipe
+unix-socket
+os2-named-pipe
+win32-named-pipe
+@end example
+@end deffn
+
+@deffn procedure file-readable? filename
+Returns @code{#t} if @var{filename} names a file that can be opened for
+input; i.e.@: a @dfn{readable} file. Otherwise returns @code{#f}.
+@end deffn
+
+@deffn procedure file-writeable? filename
+Returns @code{#t} if @var{filename} names a file that can be opened for
+output; i.e.@: a @dfn{writeable} file. Otherwise returns @code{#f}.
+@end deffn
+
+@deffn procedure file-executable? filename
+Returns @code{#t} if @var{filename} names a file that can be executed.
+Otherwise returns @code{#f}. Under unix, an executable file is
+identified by its mode bits. Under OS/2, an executable file has
+one of the file extensions @file{.exe}, @file{.com}, @file{.cmd}, or
+@file{.bat}. Under Windows, an executable file has one of the file
+extensions @file{.exe}, @file{.com}, or @file{.bat}.
+@end deffn
+
+@deffn procedure file-access filename mode
+@var{Mode} must be an exact integer between @code{0} and @code{7}
+inclusive; it is a bitwise-encoded predicate selector with @code{1}
+meaning ``executable'', @code{2} meaning ``writeable'', and @code{4}
+meaning ``readable''. @code{file-access} returns @code{#t} if
+@var{filename} exists and satisfies the predicates selected by
+@var{mode}. For example, if @var{mode} is @code{5}, then @var{filename}
+must be both readable and executable. If @var{filename} doesn't exist,
+or if it does not satisfy the selected predicates, @code{#f} is
+returned.
+@end deffn
+
+@deffn procedure file-eq? filename1 filename2
+Determines whether @var{filename1} and @var{filename2} refer to the same
+file. Under unix, this is done by comparing the inodes and devices of
+the two files. Under OS/2 and Windows, this is done by comparing
+the filename strings.
+@end deffn
+
+@deffn procedure file-modes filename
+If @var{filename} names an existing file, @code{file-modes} returns an
+exact non-negative integer encoding the file's permissions. The
+encoding of this integer is operating-system dependent. Under unix, it
+is the least-significant 12 bits of the @code{st_mode} element of the
+@code{struct stat} structure. Under OS/2 and Windows, it is the file
+attribute bits, which are described below. If @var{filename} does not
+name an existing file, @code{#f} is returned.
+@end deffn
+
+@deffn procedure set-file-modes! filename modes
+@var{Filename} must name an existing file. @var{Modes} must be an exact
+non-negative integer that could have been returned by a call to
+@code{file-modes}. @code{set-file-modes!} modifies the file's
+permissions to be those encoded by @var{modes}.
+@end deffn
+
+@defvr variable os2-file-mode/read-only
+@defvrx variable os2-file-mode/hidden
+@defvrx variable os2-file-mode/system
+@defvrx variable os2-file-mode/directory
+@defvrx variable os2-file-mode/archived
+The values of these variables are the ``mode bits'' that comprise the
+value returned by @code{file-modes} under OS/2. These bits are small
+integers that are combined by adding to form a complete set of modes.
+The integer zero represents a set of modes in which none of these bits
+are set.
+@end defvr
+
+@defvr variable nt-file-mode/read-only
+@defvrx variable nt-file-mode/hidden
+@defvrx variable nt-file-mode/system
+@defvrx variable nt-file-mode/directory
+@defvrx variable nt-file-mode/archive
+@defvrx variable nt-file-mode/normal
+@defvrx variable nt-file-mode/temporary
+@defvrx variable nt-file-mode/compressed
+The values of these variables are the ``mode bits'' that comprise the
+value returned by @code{file-modes} under Windows. These bits are small
+integers that are combined by adding to form a complete set of modes.
+The integer zero represents a set of modes in which none of these bits
+are set.
+@end defvr
+
+@deffn procedure file-modification-time filename
+@cindex modification time, of file
+Returns the modification time of @var{filename} as an exact non-negative
+integer. The result may be compared to other file times using ordinary
+integer arithmetic. If @var{filename} names a file that does not exist,
+@code{file-modification-time} returns @code{#f}.
+
+@findex file-modification-time-direct
+@findex file-modification-time-indirect
+In operating systems that support symbolic links, if @var{filename}
+names a symbolic link, @code{file-modification-time} returns the
+modification time of the file linked to. An alternate procedure,
+@code{file-modification-time-direct}, returns the modification time of
+the link itself; in all other respects it is identical to
+@code{file-modification-time}. For symmetry,
+@code{file-modification-time-indirect} is a synonym of
+@code{file-modification-time}.
+@end deffn
+
+@deffn procedure file-access-time filename
+@cindex access time, of file
+Returns the access time of @var{filename} as an exact non-negative
+integer. The result may be compared to other file times using ordinary
+integer arithmetic. If @var{filename} names a file that does not exist,
+@code{file-access-time} returns @code{#f}.
+
+@findex file-access-time-direct
+@findex file-access-time-indirect
+In operating systems that support symbolic links, if @var{filename}
+names a symbolic link, @code{file-access-time} returns the access time
+of the file linked to. An alternate procedure,
+@code{file-access-time-direct}, returns the access time of the link
+itself; in all other respects it is identical to
+@code{file-access-time}. For symmetry, @code{file-access-time-indirect}
+is a synonym of @code{file-access-time}.
+@end deffn
+
+@deffn procedure set-file-times! filename access-time modification-time
+@var{Filename} must name an existing file, while @var{access-time} and
+@var{modification-time} must be valid file times that might have been
+returned by @code{file-access-time} and @code{file-modification-time},
+respectively. @code{set-file-times!} alters the access and modification
+times of the file specified by @var{filename} to the values given by
+@var{access-time} and @var{modification-time}, respectively. For
+convenience, either of the time arguments may be specified as @code{#f};
+in this case the corresponding time is not changed.
+@code{set-file-times!} returns an unspecified value.
+@end deffn
+
+@deffn procedure current-file-time
+Returns the current time as an exact non-negative integer, in the same
+format used by the above file-time procedures. This number can be
+compared to other file times using ordinary arithmetic operations.
+@end deffn
+
+@deffn procedure file-touch filename
+@dfn{Touches} the file named @var{filename}. If the file already
+exists, its modification time is set to the current file time and
+@code{#f} is returned. Otherwise, the file is created and @code{#t} is
+returned. This is an atomic test-and-set operation, so it is useful as
+a synchronization mechanism.
+@end deffn
+
+@deffn procedure file-length filename
+Returns the length, in bytes, of the file named @var{filename} as an
+exact non-negative integer.
+@end deffn
+
+@deffn procedure file-attributes filename
+@cindex attribute, of file
+This procedure determines if the file named @var{filename} exists, and
+returns information about it if so; if the file does not exist, it
+returns @code{#f}.
+
+@findex file-attributes-direct
+@findex file-attributes-indirect
+In operating systems that support symbolic links, if @var{filename}
+names a symbolic link, @code{file-attributes} returns the attributes of
+the link itself. An alternate procedure,
+@code{file-attributes-indirect}, returns the attributes of the file
+linked to; in all other respects it is identical to
+@code{file-attributes}. For symmetry, @code{file-attributes-direct} is
+a synonym of @code{file-attributes}.
+@end deffn
+
+The information returned by @code{file-attributes} is decoded by
+accessor procedures. The following accessors are defined in all
+operating systems:
+
+@deffn procedure file-attributes/type attributes
+The file type: @code{#t} if the file is a directory, a character string
+(the name linked to) if a symbolic link, or @code{#f} for all other
+types of file.
+@end deffn
+
+@deffn procedure file-attributes/access-time attributes
+The last access time of the file, an exact non-negative integer.
+@end deffn
+
+@deffn procedure file-attributes/modification-time attributes
+The last modification time of the file, an exact non-negative integer.
+@end deffn
+
+@deffn procedure file-attributes/change-time attributes
+The last change time of the file, an exact non-negative integer.
+@end deffn
+
+@deffn procedure file-attributes/length attributes
+The length of the file in bytes.
+@end deffn
+
+@deffn procedure file-attributes/mode-string attributes
+The mode string of the file, a newly allocated string showing the file's
+mode bits. Under unix, this string is in unix format. Under OS/2 and
+Windows, this string shows the standard ``DOS'' attributes in their
+usual format.
+@end deffn
+
+@deffn procedure file-attributes/n-links attributes
+The number of links to the file, an exact positive integer. Under
+Windows and OS/2, this is always @code{1}.
+@end deffn
+
+The following additional accessors are defined under unix:
+
+@deffn procedure file-attributes/uid attributes
+The user id of the file's owner, an exact non-negative integer.
+@end deffn
+
+@deffn procedure file-attributes/gid attributes
+The group id of the file's group, an exact non-negative integer.
+@end deffn
+
+@deffn procedure file-attributes/inode-number attributes
+The inode number of the file, an exact non-negative integer.
+@end deffn
+
+The following additional accessor is defined under OS/2 and Windows:
+
+@deffn procedure file-attributes/modes attributes
+The attribute bits of the file. This is an exact non-negative integer
+containing the file's attribute bits, exactly as specified by the
+operating system's API.
+@end deffn
+
+The following additional accessor is defined under OS/2:
+
+@deffn procedure file-attributes/allocated-length attributes
+The allocated length of the file, which can be larger than the length of
+the file due to fixed-length allocation units.
+@end deffn
+
+@node Directory Reader, Date and Time, File Manipulation, Operating-System Interface
+@section Directory Reader
+@cindex directory, reading
+
+@deffn procedure directory-read directory [sort?]
+@var{Directory} must be an object that can be converted into a pathname
+by@* @code{->pathname}. The directory specified by @var{directory} is
+read, and the contents of the directory is returned as a newly allocated
+list of absolute pathnames. The result is sorted according to the usual
+sorting conventions for directories, unless @var{sort?} is specified as
+@code{#f}. If @var{directory} has name, type, or version components,
+the returned list contains only those pathnames whose name, type, and
+version components match those of @var{directory}; @code{wild} or
+@code{#f} as one of these components means ``match anything''.
+
+The OS/2 and Windows implementations support ``globbing'', in which the
+characters @code{*} and @code{?} are interpreted to mean ``match
+anything'' and ``match any character'', respectively. This ``globbing''
+is supported only in the file part of @var{directory}.
+@end deffn
+
+@node Date and Time, Machine Time, Directory Reader, Operating-System Interface
+@section Date and Time
+
+MIT/GNU Scheme provides a simple set of procedures for manipulating date
+and time information. There are four time representations, each of
+which serves a different purpose. Each representation may be
+converted to any of the others.
+
+@cindex universal time
+@cindex time, universal
+The primary time representation, @dfn{universal time}, is an exact
+non-negative integer counting the number of seconds that have elapsed
+since midnight January 1, 1900 UTC. (UTC stands for @dfn{Coordinated
+Universal Time}, and is the modern name for Greenwich Mean Time.) This
+format is produced by @code{get-universal-time} and
+@code{decoded-time->universal-time}.
+
+@cindex decoded time
+@cindex time, decoded
+The second representation, @dfn{decoded time}, is a record structure in
+which the time is broken down into components, such as month, minute,
+etc. Decoded time is always relative to a particular time zone, which
+is a component of the structure. This format is produced by
+@code{global-decoded-time} and @code{local-decoded-time}.
+
+@cindex file time
+@cindex time, file
+The third representation, @dfn{file time}, is an exact non-negative
+integer that is larger for increasing time. Unlike universal time,
+this representation is operating-system dependent. This format is
+produced by all of the file-attribute procedures, for example
+@code{file-modification-time} and @code{file-attributes}.
+
+@cindex time, string
+The fourth representation, the @dfn{time string}, is an external
+representation for time. This format is defined by RFC-822,
+@cite{Standard for the format of ARPA Internet text messages}, with the
+modification that years are represented as four-digit numbers rather
+than two-digit numbers. This format is the standard format for Internet
+email and numerous other network protocols.
+
+Within this section, argument variables named @var{universal-time},
+@var{decoded-time}, @var{file-time}, and @var{time-string} are
+respectively required to be of the corresponding format.
+
+@menu
+* Universal Time::
+* Decoded Time::
+* File Time::
+* Time-Format Conversion::
+* External Representation of Time::
+@end menu
+
+@node Universal Time, Decoded Time, Date and Time, Date and Time
+@subsection Universal Time
+
+@deffn procedure get-universal-time
+Return the current time in universal format.
+
+@example
+(get-universal-time) @result{} 3131453078
+@end example
+@end deffn
+
+@defvr variable epoch
+@code{epoch} is the representation of midnight January 1, 1970 UTC in
+universal-time format.
+
+@example
+epoch @result{} 2208988800
+@end example
+@end defvr
+
+@node Decoded Time, File Time, Universal Time, Date and Time
+@subsection Decoded Time
+
+Objects representing standard time components, such as seconds and
+minutes, are required to be exact non-negative integers. Seconds and
+minutes must be inclusively between @code{0} and @code{59}; hours
+between @code{0} and @code{23}; days between @code{1} and @code{31};
+months between @code{1} and @code{12}; years are represented in
+``four-digit'' form, in which 1999 is represented as @code{1999} ---
+@emph{not} @code{99}.
+
+@deffn procedure local-decoded-time
+Return the current time in decoded format. The decoded time is
+represented in the local time zone.
+
+@example
+@group
+(pp (local-decoded-time))
+@print{} #[decoded-time 76]
+@print{} (second 2)
+@print{} (minute 12)
+@print{} (hour 11)
+@print{} (day 27)
+@print{} (month 4)
+@print{} (year 1999)
+@print{} (day-of-week 1)
+@print{} (daylight-savings-time 1)
+@print{} (zone 5)
+@end group
+@end example
+@end deffn
+
+@deffn procedure global-decoded-time
+Return the current time in decoded format. The decoded time is
+represented in UTC.
+
+@example
+@group
+(pp (global-decoded-time))
+@print{} #[decoded-time 77]
+@print{} (second 8)
+@print{} (minute 12)
+@print{} (hour 15)
+@print{} (day 27)
+@print{} (month 4)
+@print{} (year 1999)
+@print{} (day-of-week 1)
+@print{} (daylight-savings-time 0)
+@print{} (zone 0)
+@end group
+@end example
+@end deffn
+
+@deffn procedure make-decoded-time second minute hour day month year [zone]
+Return a new decoded-time object representing the given time. The
+arguments must be valid components according to the above rules, and
+must form a valid date.
+
+If @var{zone} is not supplied or is @code{#f}, the resulting decoded
+time will be represented in the local time zone. Otherwise, @var{zone}
+must be a valid time zone, and the result will be represented in that
+zone.
+
+@strong{Warning}: because this procedure depends on the operating
+system's runtime library, it is not capable of representing all dates.
+In particular, on most unix systems, it is not possible to encode dates
+that occur prior to midnight, January 1, 1970 UTC. Attempting to do
+this will signal an error.
+
+@example
+@group
+(pp (make-decoded-time 0 9 11 26 3 1999))
+@print{} #[decoded-time 19]
+@print{} (second 0)
+@print{} (minute 9)
+@print{} (hour 11)
+@print{} (day 26)
+@print{} (month 3)
+@print{} (year 1999)
+@print{} (day-of-week 4)
+@print{} (daylight-savings-time 0)
+@print{} (zone 5)
+@end group
+
+@group
+(pp (make-decoded-time 0 9 11 26 3 1999 3))
+@print{} #[decoded-time 80]
+@print{} (second 0)
+@print{} (minute 9)
+@print{} (hour 11)
+@print{} (day 26)
+@print{} (month 3)
+@print{} (year 1999)
+@print{} (day-of-week 4)
+@print{} (daylight-savings-time 0)
+@print{} (zone 3)
+@end group
+@end example
+@end deffn
+
+@deffn procedure decoded-time/second decoded-time
+@deffnx procedure decoded-time/minute decoded-time
+@deffnx procedure decoded-time/hour decoded-time
+@deffnx procedure decoded-time/day decoded-time
+@deffnx procedure decoded-time/month decoded-time
+@deffnx procedure decoded-time/year decoded-time
+Return the corresponding component of @var{decoded-time}.
+
+@example
+@group
+(decoded-time/second (local-decoded-time)) @result{} 17
+(decoded-time/year (local-decoded-time)) @result{} 1999
+(decoded-time/day (local-decoded-time)) @result{} 26
+@end group
+@end example
+@end deffn
+
+@deffn procedure decoded-time/day-of-week decoded-time
+Return the day of the week on which @var{decoded-time} falls, encoded
+as an exact integer between @code{0} (Monday) and @code{6} (Sunday),
+inclusive.
+
+@example
+(decoded-time/day-of-week (local-decoded-time)) @result{} 4
+@end example
+@end deffn
+
+@deffn procedure decoded-time/daylight-savings-time? decoded-time
+Return @code{#t} if @var{decoded-time} is represented using daylight
+savings time. Otherwise return @code{#f}.
+
+@example
+(decoded-time/daylight-savings-time? (local-decoded-time))
+ @result{} #f
+@end example
+@end deffn
+
+@deffn procedure decoded-time/zone decoded-time
+Return the time zone in which @var{decoded-time} is represented. This
+is an exact rational number between @code{-24} and @code{+24} inclusive,
+that when multiplied by @code{3600} is an integer. The value is the
+number of hours west of UTC.
+
+@example
+(decoded-time/zone (local-decoded-time)) @result{} 5
+@end example
+@end deffn
+
+@deffn procedure time-zone? object
+Returns @code{#t} if @var{object} is an exact number between @code{-24}
+and @code{+24} inclusive, that when multiplied by @code{3600} is an
+integer.
+
+@example
+@group
+(time-zone? -5) @result{} #t
+(time-zone? 11/2) @result{} #t
+(time-zone? 11/7) @result{} #f
+@end group
+@end example
+@end deffn
+
+@deffn procedure month/max-days month
+Returns the maximum number of days possible in @var{month}. @var{Month}
+must be an exact integer between @code{1} and @code{12} inclusive.
+
+@example
+@group
+(month/max-days 2) @result{} 29
+(month/max-days 3) @result{} 31
+(month/max-days 4) @result{} 30
+@end group
+@end example
+@end deffn
+
+@node File Time, Time-Format Conversion, Decoded Time, Date and Time
+@subsection File Time
+
+As stated above, file time is operating-system dependent. As of this
+writing, two formats are used. For unix and Windows systems, file time
+is the number of seconds since midnight January 1, 1970 UTC (the
+standard unix time convention).
+
+OS/2 represents file time as a 32-bit unsigned integer, in which the
+time components are broken down into unsigned bit fields. The
+components are always stated in local time. The fields, from MSB to
+LSB, are:
+
+@itemize @bullet
+@item
+7 bits representing the year, relative to 1900.
+
+@item
+4 bits representing the month, numbered 1 to 12.
+
+@item
+5 bits representing the day of the month, numbered 1 to 31.
+
+@item
+5 bits representing the hour of the day, numbered 0 to 23.
+
+@item
+6 bits representing the minute, numbered 0 to 59.
+
+@item
+5 bits representing the second. This field is unusual in that it counts
+units of two seconds, so it is a number between 0 and 29, representing
+second counts corresponding to 0 through 58.
+@end itemize
+
+The following procedures generate their results in file-time format:
+
+@example
+@group
+file-access-time
+file-access-time-direct
+file-access-time-indirect
+file-modification-time
+file-modification-time-direct
+file-modification-time-indirect
+file-attributes/access-time
+file-attributes/modification-time
+file-attributes/change-time
+@end group
+@end example
+
+@noindent
+Additionally, @code{set-file-times!} accepts its time arguments in
+file-time format.
+
+@node Time-Format Conversion, External Representation of Time, File Time, Date and Time
+@subsection Time-Format Conversion
+
+The procedures described in this section convert times from one format
+to another.
+
+@deffn procedure universal-time->local-decoded-time universal-time
+@deffnx procedure universal-time->global-decoded-time universal-time
+Converts an argument in universal-time format to decoded-time format.
+The result is in the local time zone or UTC, respectively.
+
+@example
+@group
+(pp (universal-time->local-decoded-time (get-universal-time)))
+@print{} #[decoded-time 21]
+@print{} (second 23)
+@print{} (minute 57)
+@print{} (hour 17)
+@print{} (day 29)
+@print{} (month 4)
+@print{} (year 1999)
+@print{} (day-of-week 3)
+@print{} (daylight-savings-time 1)
+@print{} (zone 5)
+@end group
+
+@group
+(pp (universal-time->global-decoded-time
+ (get-universal-time)))
+@print{} #[decoded-time 22]
+@print{} (second 27)
+@print{} (minute 57)
+@print{} (hour 21)
+@print{} (day 29)
+@print{} (month 4)
+@print{} (year 1999)
+@print{} (day-of-week 3)
+@print{} (daylight-savings-time 0)
+@print{} (zone 0)
+@end group
+@end example
+@end deffn
+
+@deffn procedure universal-time->file-time universal-time
+Converts an argument in universal-time format to file-time format.
+
+@example
+@group
+(universal-time->file-time (get-universal-time))
+ @result{} 925422988
+@end group
+@end example
+@end deffn
+
+@deffn procedure universal-time->local-time-string universal-time
+@deffnx procedure universal-time->global-time-string universal-time
+Converts an argument in universal-time format to a time string. The
+result is in the local time zone or UTC, respectively.
+
+@example
+@group
+(universal-time->local-time-string (get-universal-time))
+ @result{} "Thu, 29 Apr 1999 17:55:31 -0400"
+(universal-time->global-time-string (get-universal-time))
+ @result{} "Thu, 29 Apr 1999 21:55:51 +0000"
+@end group
+@end example
+@end deffn
+
+@deffn procedure decoded-time->universal-time decoded-time
+Converts an argument in decoded-time format to universal-time format.
+
+@example
+@group
+(decoded-time->universal-time (local-decoded-time))
+ @result{} 3134411942
+(decoded-time->universal-time (global-decoded-time))
+ @result{} 3134411947
+@end group
+@end example
+@end deffn
+
+@deffn procedure decoded-time->file-time decoded-time
+Converts an argument in decoded-time format to file-time format.
+
+@example
+@group
+(decoded-time->file-time (local-decoded-time))
+ @result{} 925423191
+(decoded-time->file-time (global-decoded-time))
+ @result{} 925423195
+@end group
+@end example
+@end deffn
+
+@deffn procedure decoded-time->string decoded-time
+Convert an argument in decoded-time format to a time string.
+
+@example
+@group
+(decoded-time->string (local-decoded-time))
+ @result{} "Thu, 29 Apr 1999 18:00:43 -0400"
+(decoded-time->string (global-decoded-time))
+ @result{} "Thu, 29 Apr 1999 22:00:46 +0000"
+@end group
+@end example
+@end deffn
+
+@deffn procedure file-time->universal-time file-time
+Converts an argument in universal-time format to file-time format.
+
+@example
+@group
+(file-time->universal-time (file-modification-time "/"))
+ @result{} 3133891907
+@end group
+@end example
+@end deffn
+
+@deffn procedure file-time->local-decoded-time file-time
+@deffnx procedure file-time->global-decoded-time file-time
+Converts an argument in file-time format to decoded-time format. The
+result is in the local time zone or UTC, respectively.
+
+@example
+@group
+(pp (file-time->local-decoded-time
+ (file-modification-time "/")))
+@print{} #[decoded-time 26]
+@print{} (second 47)
+@print{} (minute 31)
+@print{} (hour 17)
+@print{} (day 23)
+@print{} (month 4)
+@print{} (year 1999)
+@print{} (day-of-week 4)
+@print{} (daylight-savings-time 1)
+@print{} (zone 5)
+@end group
+
+@group
+(pp (file-time->global-decoded-time
+ (file-modification-time "/")))
+@print{} #[decoded-time 27]
+@print{} (second 47)
+@print{} (minute 31)
+@print{} (hour 21)
+@print{} (day 23)
+@print{} (month 4)
+@print{} (year 1999)
+@print{} (day-of-week 4)
+@print{} (daylight-savings-time 0)
+@print{} (zone 0)
+@end group
+@end example
+@end deffn
+
+@deffn procedure file-time->local-time-string file-time
+@deffnx procedure file-time->global-time-string file-time
+Converts an argument in file-time format to a time string. The result
+is in the local time zone or UTC, respectively.
+
+@example
+@group
+(file-time->local-time-string (file-modification-time "/"))
+ @result{} "Fri, 23 Apr 1999 17:31:47 -0400"
+(file-time->global-time-string (file-modification-time "/"))
+ @result{} "Fri, 23 Apr 1999 21:31:47 +0000"
+@end group
+@end example
+@end deffn
+
+@deffn procedure string->universal-time time-string
+Converts a time-string argument to universal-time format.
+
+@example
+@group
+(string->universal-time "Fri, 23 Apr 1999 21:31:47 +0000")
+ @result{} 3133888307
+(string->universal-time "Fri, 23 Apr 1999 17:31:47 -0400")
+ @result{} 3133888307
+@end group
+@end example
+@end deffn
+
+@deffn procedure string->decoded-time time-string
+Converts a time-string argument to decoded-time format.
+
+@example
+@group
+(pp (string->decoded-time "Fri, 23 Apr 1999 17:31:47 -0400"))
+@print{} #[decoded-time 30]
+@print{} (second 47)
+@print{} (minute 31)
+@print{} (hour 17)
+@print{} (day 23)
+@print{} (month 4)
+@print{} (year 1999)
+@print{} (day-of-week 4)
+@print{} (daylight-savings-time 0)
+@print{} (zone 4)
+@end group
+@end example
+@end deffn
+
+@deffn procedure string->file-time time-string
+Converts a time-string argument to file-time format.
+
+@example
+@group
+(string->file-time "Fri, 23 Apr 1999 17:31:47 -0400")
+ @result{} 924899507
+@end group
+@end example
+@end deffn
+
+@node External Representation of Time, , Time-Format Conversion, Date and Time
+@subsection External Representation of Time
+
+The normal external representation for time is the time string, as
+described above. The procedures in this section generate alternate
+external representations of time which are more verbose and may be more
+suitable for presentation to human readers.
+
+@deffn procedure decoded-time/date-string decoded-time
+@deffnx procedure decoded-time/time-string decoded-time
+These procedures return strings containing external representations of
+the date and time, respectively, represented by @var{decoded-time}. The
+results are implicitly in local time.
+
+@example
+@group
+(decoded-time/date-string (local-decoded-time))
+ @result{} "Tuesday March 30, 1999"
+(decoded-time/time-string (local-decoded-time))
+ @result{} "11:22:38 AM"
+@end group
+@end example
+@end deffn
+
+@deffn procedure day-of-week/long-string day-of-week
+@deffnx procedure day-of-week/short-string day-of-week
+Returns a string representing the given @var{day-of-week}. The argument
+must be an exact non-negative integer between @code{0} and @code{6}
+inclusive. @code{day-of-week/long-string} returns a long string that
+fully spells out the name of the day. @code{day-of-week/short-string}
+returns a shortened string that abbreviates the day to three letters.
+
+@example
+@group
+(day-of-week/long-string 0) @result{} "Monday"
+(day-of-week/short-string 0) @result{} "Mon"
+(day-of-week/short-string 3) @result{} "Thu"
+@end group
+@end example
+@end deffn
+
+@deffn procedure month/long-string month
+@deffnx procedure month/short-string month
+Returns a string representing the given @var{month}. The argument must
+be an exact non-negative integer between @code{1} and @code{12}
+inclusive. @code{month/long-string} returns a long string that fully
+spells out the name of the month. @code{month/short-string} returns a
+shortened string that abbreviates the month to three letters.
+
+@example
+@group
+(month/long-string 1) @result{} "January"
+(month/short-string 1) @result{} "Jan"
+(month/short-string 10) @result{} "Oct"
+@end group
+@end example
+@end deffn
+
+@deffn procedure time-zone->string
+Returns a string corresponding to the given time zone. This string is
+the same string that is used to generate RFC-822 time strings.
+
+@example
+@group
+(time-zone->string 5) @result{} "-0500"
+(time-zone->string -4) @result{} "+0400"
+(time-zone->string 11/2) @result{} "-0530"
+@end group
+@end example
+@end deffn
+
+@node Machine Time, Subprocesses, Date and Time, Operating-System Interface
+@section Machine Time
+
+The previous section dealt with procedures that manipulate clock time.
+This section describes procedures that deal with computer time: elapsed
+CPU time, elapsed real time, and so forth. These procedures are useful
+for measuring the amount of time it takes to execute code.
+
+@cindex tick
+Some of the procedures in this section manipulate a time representation
+called @dfn{ticks}. A tick is a unit of time that is unspecified here
+but can be converted to and from seconds by supplied procedures. A
+count in ticks is represented as an exact integer. At present each tick
+is one millisecond, but this may change in the future.
+
+@deffn procedure process-time-clock
+Returns the amount of process time, in ticks, that has elapsed since
+Scheme was started. Process time is measured by the operating system
+and is time during which the Scheme process is computing. It does not
+include time in system calls, but depending on the operating system it
+may include time used by subprocesses.
+
+@example
+(process-time-clock) @result{} 21290
+@end example
+@end deffn
+
+@deffn procedure real-time-clock
+Returns the amount of real time, in ticks, that has elapsed since Scheme
+was started. Real time is the time measured by an ordinary clock.
+
+@example
+(real-time-clock) @result{} 33474836
+@end example
+@end deffn
+
+@deffn procedure internal-time/ticks->seconds ticks
+Returns the number of seconds corresponding to @var{ticks}. The result
+is always a real number.
+
+@example
+@group
+(internal-time/ticks->seconds 21290) @result{} 21.29
+(internal-time/ticks->seconds 33474836) @result{} 33474.836
+@end group
+@end example
+@end deffn
+
+@deffn procedure internal-time/seconds->ticks seconds
+Returns the number of ticks corresponding to @var{seconds}.
+@var{Seconds} must be a real number.
+
+@example
+@group
+(internal-time/seconds->ticks 20.88) @result{} 20880
+(internal-time/seconds->ticks 20.83) @result{} 20830
+@end group
+@end example
+@end deffn
+
+@deffn procedure system-clock
+Returns the amount of process time, in seconds, that has elapsed since
+Scheme was started. Roughly equivalent to:
+
+@example
+(internal-time/ticks->seconds (process-time-clock))
+@end example
+
+@noindent
+Example:
+
+@example
+(system-clock) @result{} 20.88
+@end example
+@end deffn
+
+@deffn procedure runtime
+Returns the amount of process time, in seconds, that has elapsed since
+Scheme was started. However, it does not include time spent in garbage
+collection.
+
+@example
+(runtime) @result{} 20.83
+@end example
+@end deffn
+
+@deffn procedure with-timings thunk receiver
+Calls @var{thunk} with no arguments. After @var{thunk} returns,
+@var{receiver} is called with three arguments describing the time spent
+while computing @var{thunk}: the elapsed run time, the amount of time
+spent in the garbage collector, and the elapsed real time. All three
+times are in ticks.
+
+This procedure is most useful for doing performance measurements, and is
+designed to have relatively low overhead.
+
+@example
+@group
+(with-timings
+ (lambda () @r{@dots{} hairy computation @dots{}})
+ (lambda (run-time gc-time real-time)
+ (write (internal-time/ticks->seconds run-time))
+ (write-char #\space)
+ (write (internal-time/ticks->seconds gc-time))
+ (write-char #\space)
+ (write (internal-time/ticks->seconds real-time))
+ (newline)))
+@end group
+@end example
+@end deffn
+
+@deffn procedure measure-interval runtime? procedure
+Calls @var{procedure}, passing it the current process time, in seconds,
+as an argument. The result of this call must be another procedure.
+When @var{procedure} returns, the resulting procedure is
+tail-recursively called with the ending time, in seconds, as an
+argument.
+
+If @var{runtime?} is @code{#f}, the elapsed time is deducted from the
+elapsed system time returned by @code{runtime}.
+
+While this procedure can be used for time measurement, its interface is
+somewhat clumsy for that purpose. We recommend that you use
+@code{with-timings} instead, because it is more convenient and has lower
+overhead.
+
+@example
+@group
+(measure-interval #t
+ (lambda (start-time)
+ (let ((v @r{@dots{} hairy computation @dots{}}))
+ (lambda (end-time)
+ (write (- end-time start-time))
+ (newline)
+ v))))
+@end group
+@end example
+@end deffn
+
+@node Subprocesses, TCP Sockets, Machine Time, Operating-System Interface
+@section Subprocesses
+
+@cindex subprocess
+@cindex synchronous subprocess
+MIT/GNU Scheme provides the ability to run and control subprocesses. This
+support is divided into two parts: a low-level set of primitives that
+maps onto the underlying operating system's process-control primitives,
+and a high-level set of procedures for starting a subprocess and running
+it to completion in a single call. Subprocesses that are run in the
+latter fashion are referred to as @dfn{synchronous}, because they are
+started and stopped in synchrony with a Scheme procedure call.
+
+This chapter documents Scheme's high-level synchronous-subprocess
+support. The low-level support is not documented but is available for
+those who are willing to read the source code.
+
+Synchronous-subprocess support is a run-time-loadable option. To use
+it, execute
+
+@example
+(load-option 'synchronous-subprocess)
+@end example
+
+@noindent
+once before calling it.
+
+@menu
+* Subprocess Procedures::
+* Subprocess Conditions::
+* Subprocess Options::
+@end menu
+
+@node Subprocess Procedures, Subprocess Conditions, Subprocesses, Subprocesses
+@subsection Subprocess Procedures
+
+There are two commands for running synchronous subprocesses under
+Scheme. @code{run-shell-command} is very simple to use, provides access
+to all shell features, and is to be preferred in most situations.
+@code{run-synchronous-subprocess} allows direct execution of a program
+and precise control of the command-line arguments passed to the program,
+but does not provide file globbing, I/O redirection, or other shell
+features.
+
+@deffn procedure run-shell-command command option @dots{}
+Runs @var{command}, which must be a string. @var{Command} is passed to
+a command shell for interpretation; how the shell is chosen is detailed
+below.
+
+The @var{option}s are a sequence of keyword/value pairs that specify
+optional behavior. See below for more information about options.
+
+@code{run-shell-command} waits until the subprocess completes its
+execution and returns the exit code from the subprocess. If the
+subprocess is killed or stopped, an error is signalled and the procedure
+does not return.
+@end deffn
+
+@deffn procedure run-synchronous-subprocess program arguments option @dots{}
+Runs @var{program}, passing it the given command-line @var{arguments}.
+@var{Program} must be either the name of a program on the path, or else
+a pathname to a specific program. @var{Arguments} must be a list of
+strings; each string is a single command-line argument to the program.
+
+The @var{option}s are a sequence of keyword/value pairs that specify
+optional behavior. See below for more information about options.
+
+@code{run-synchronous-subprocess} waits until the subprocess completes
+its execution and returns the exit code from the subprocess. If the
+subprocess is killed or stopped, an error is signalled and the procedure
+does not return.
+@end deffn
+
+@node Subprocess Conditions, Subprocess Options, Subprocess Procedures, Subprocesses
+@subsection Subprocess Conditions
+
+If a subprocess spawned by one of the above procedures is killed or
+suspended, then one of the following errors will be signalled.
+
+@deffn {condition type} condition-type:subprocess-signalled subprocess reason
+This condition type is a subtype of
+@code{condition-type:subprocess-abnormal-termination}. It is signalled
+when the subprocess is killed.
+
+@var{Subprocess} is an object that represents the subprocess involved.
+The internals of this object can be accessed but the interface is not
+documented at this time; see the source code for details.
+
+@var{Reason} is interesting only on unix systems, where it is the signal
+that killed the process. On other systems it has a fixed value that
+conveys no useful information.
+@end deffn
+
+@deffn {condition type} condition-type:subprocess-stopped subprocess reason
+This condition type is a subtype of
+@code{condition-type:subprocess-abnormal-termination}. It is signalled
+when the subprocess is stopped or suspended.
+
+@var{Subprocess} is an object that represents the subprocess involved.
+The internals of this object can be accessed but the interface is not
+documented at this time; see the source code for details.
+
+@var{Reason} is interesting only on unix systems, where it is the signal
+that stopped the process. On other systems it has a fixed value that
+conveys no useful information.
+@end deffn
+
+@deffn {condition type} condition-type:subprocess-abnormal-termination subprocess reason
+This condition type is a subtype of @code{condition-type:error}. This
+is an abstract type that is never signalled. It is provided so that
+condition handlers can be bound to it.
+@end deffn
+
+@node Subprocess Options, , Subprocess Conditions, Subprocesses
+@subsection Subprocess Options
+
+The following subprocess options may be passed to
+@code{run-shell-command} or @code{run-synchronous-subprocess}. These
+options are passed as alternating keyword/value pairs, for example:
+
+@example
+@group
+(run-shell-command "ls /"
+ 'output my-output-port
+ 'output-buffer-size 8192)
+@end group
+@end example
+
+@noindent
+The example shows a shell command being run with two options specified:
+@code{output} and @code{output-buffer-size}.
+
+@deffn {subprocess option} input port
+Specifies the standard input of the subprocess. @var{Port} may be an
+input port, in which case characters are read from @var{port} and fed to
+the subprocess until @var{port} reaches end-of-file. Alternatively,
+@var{port} may be @code{#f}, indicating that the subprocess has no
+standard input.
+
+The default value of this option is @code{#f}.
+
+@example
+@group
+(call-with-input-file "foo.in"
+ (lambda (port)
+ (run-shell-command "cat > /dev/null" 'input port)))
+@end group
+@end example
+@end deffn
+
+@deffn {subprocess option} input-line-translation line-ending
+Specifies how line-endings should be translated when writing characters
+to the subprocess. Ignored if the @code{input} option is @code{#f}.
+@var{Line-ending} must be either a string specifying the line ending, or
+the symbol @code{default}, meaning to use the operating system's
+standard line ending. In either case, newline characters to be written
+to the @code{input} port are translated to the specified line ending
+before being written.
+
+The default value of this option is @code{default}.
+
+@example
+@group
+(call-with-input-file "foo.in"
+ (lambda (port)
+ (run-shell-command "cat > /dev/null"
+ 'input port
+ 'input-line-translation "\r\n")))
+@end group
+@end example
+@end deffn
+
+@deffn {subprocess option} input-buffer-size n
+Specifies the size of the input buffer for the standard input of the
+subprocess. (This is the buffer on the Scheme side, and has nothing to
+do with any buffering done on the subprocess side.) Ignored if the
+@code{input} option is @code{#f}. @var{N} must be an exact positive
+integer specifying the number of characters the buffer can hold.
+
+The default value of this option is @code{512}.
+
+@example
+@group
+(call-with-input-file "foo.in"
+ (lambda (port)
+ (run-shell-command "cat > /dev/null"
+ 'input port
+ 'input-buffer-size 4096)))
+@end group
+@end example
+@end deffn
+
+@deffn {subprocess option} output port
+Specifies the standard output and standard error of the subprocess.
+@var{Port} may be an output port, in which case characters are read from
+the subprocess and fed to @var{port} until the subprocess finishes.
+Alternatively, @var{port} may be @code{#f}, indicating that the
+subprocess has no standard output or standard error.
+
+The default value of this option is the value of
+@code{(current-output-port)}.
+
+@example
+@group
+(call-with-output-file "foo.out"
+ (lambda (port)
+ (run-shell-command "ls -la /etc" 'output port)))
+@end group
+@end example
+@end deffn
+
+@deffn {subprocess option} output-line-translation line-ending
+Specifies how line-endings should be translated when reading characters
+from the standard output of the subprocess. Ignored if the
+@code{output} option is @code{#f}. @var{Line-ending} must be either a
+string specifying the line ending, or the symbol @code{default}, meaning
+to use the operating system's standard line ending. In either case,
+newline characters read from the subprocess port are translated to the
+specified line ending.
+
+The default value of this option is @code{default}.
+
+@example
+@group
+(call-with-output-file "foo.out"
+ (lambda (port)
+ (run-shell-command "ls -la /etc"
+ 'output port
+ 'output-line-translation "\r\n")))
+@end group
+@end example
+@end deffn
+
+@deffn {subprocess option} output-buffer-size n
+Specifies the size of the output buffer for the standard output of the
+subprocess. (This is the buffer on the Scheme side, and has nothing to
+do with any buffering done on the subprocess side.) Ignored if the
+@code{output} option is @code{#f}. @var{N} must be an exact positive
+integer specifying the number of characters the buffer can hold.
+
+The default value of this option is @code{512}.
+
+@example
+@group
+(call-with-output-file "foo.out"
+ (lambda (port)
+ (run-shell-command "ls -la /etc"
+ 'output port
+ 'output-buffer-size 4096)))
+@end group
+@end example
+@end deffn
+
+@deffn {subprocess option} redisplay-hook thunk
+Specifies that @var{thunk} is to be run periodically when output from
+the subprocess is available. @var{Thunk} must be a procedure of no
+arguments, or @code{#f} indicating that no hook is supplied. This
+option is mostly useful for interactive systems. For example, the Edwin
+text editor uses this to update output buffers when running some
+subprocesses.
+
+The default value of this option is @code{#f}.
+
+@example
+@group
+(run-shell-command "ls -la /etc"
+ 'redisplay-hook
+ (lambda ()
+ (update-buffer-contents buffer)))
+@end group
+@end example
+@end deffn
+
+@deffn {subprocess option} environment environment
+Specifies the environment variables that are to be used for the
+subprocess. @var{Environment} must be either a vector of strings or
+@code{#f} indicating the default environment. If it is a vector of
+strings, each string must be a name/value pair where the name and value
+are separated by an equal sign, for example, @code{"foo=bar"}. To
+define a variable with no value, just omit the value, as in @code{"foo="}.
+
+@vindex scheme-subprocess-environment
+Note that the variable @code{scheme-subprocess-environment} is bound to
+the default subprocess environment.
+
+The default value of this option is @code{#f}.
+
+@example
+@group
+(run-shell-command "ls -la /etc"
+ 'environment
+ (let* ((v scheme-subprocess-environment)
+ (n (vector-length v))
+ (v (vector-grow v (+ n 1))))
+ (vector-set! v n "TERM=none")
+ v))
+@end group
+@end example
+@end deffn
+
+@deffn {subprocess option} working-directory pathname
+Specifies the working directory in which the subprocess will run.
+
+The default value of this option is @code{(working-directory-pathname)}.
+
+@example
+@group
+(run-shell-command "ls -la" 'working-directory "/etc/")
+@end group
+@end example
+@end deffn
+
+@deffn {subprocess option} use-pty? boolean
+This option is meaningful only on unix systems; on other systems it is
+ignored. Specifies whether to communicate with the subprocess using
+@sc{pty} devices; if true, @sc{pty}s will be used, otherwise pipes will
+be used.
+
+The default value of this option is @code{#f}.
+
+@example
+@group
+(run-shell-command "ls -la /etc" 'use-pty? #t)
+@end group
+@end example
+@end deffn
+
+@deffn {subprocess option} shell-file-name pathname
+Specifies the shell program to use for @code{run-shell-command}.
+
+The default value of this option is @code{(os/shell-file-name)}. This
+is the value of the environment variable @code{SHELL}, or if
+@code{SHELL} is not set, the value is operating-system dependent as
+follows:
+
+@itemize @bullet
+@item
+On unix systems, @file{/bin/sh} is used.
+
+@item
+On OS/2 systems, the value of the environment variable @code{COMSPEC} is
+used, or if that is not set, @file{cmd.exe} on the current path.
+
+@item
+On Windows systems, the value of the environment variable @code{COMSPEC}
+is used. If that is not set, @file{cmd.exe} is used for Windows NT, or
+@file{command.com} is used for Windows 9x; in each case the shell is
+found by searching the path.
+@end itemize
+
+@example
+@group
+(run-shell-command "ls -la /etc"
+ 'shell-file-name "/usr/local/bin/bash")
+@end group
+@end example
+@end deffn
+
+@node TCP Sockets, Miscellaneous OS Facilities, Subprocesses, Operating-System Interface
+@section TCP Sockets
+
+@cindex socket
+MIT/GNU Scheme provides access to @dfn{sockets}, which are a mechanism for
+inter-process communication. @sc{tcp} stream sockets are supported,
+which communicate between computers over a @sc{tcp/ip} network.
+@sc{tcp} sockets are supported on all operating systems.
+
+@cindex client socket
+@cindex server socket
+@sc{tcp} sockets have two distinct interfaces: one interface to
+implement a @dfn{client} and another to implement a @dfn{server}. The
+basic protocol is that servers set up a listening port and wait for
+connections from clients. Implementation of clients is simpler and will
+be treated first.
+
+@cindex hostname, TCP
+The socket procedures accept two special arguments, called
+@var{host-name} and @var{service}. @var{Host-name} is a string which
+must be the name of an internet host. It is looked up using the
+ordinary lookup rules for your computer. For example, if your host is
+@code{foo.mit.edu} and @var{host-name} is @code{"bar"}, then it
+specifies @code{bar.mit.edu}.
+
+@cindex service, TCP
+@cindex port number, TCP
+@var{Service} specifies the service to which you will connect. A
+networked computer normally provides several different services, such as
+telnet or @acronym{FTP}. Each service is associated with a unique
+@dfn{port number}; for example, the @code{"www"} service is associated
+with port @code{80}. The @var{service} argument specifies the port
+number, either as a string, or directly as an exact non-negative
+integer. Port strings are decoded by the operating system using a
+table; for example, on unix the table is in @file{/etc/services}.
+Usually you will use a port string rather than a number.
+
+@deffn procedure open-tcp-stream-socket host-name service [buffer-size [line-translation]]
+@code{open-tcp-stream-socket} opens a connection to the host specified
+by @var{host-name}. @var{Host-name} is looked up using the ordinary
+lookup rules for your computer. The connection is established to the
+service specified by @var{service}. The returned value is an
+@acronym{I/O} port, to which you can read and write characters using
+ordinary Scheme @acronym{I/O} procedures such as @code{read-char} and
+@code{write-char}.
+
+@var{Buffer-size} specifies the size of the read and write buffers used
+by the port; if this is unspecified or @code{#f}, the buffers will hold
+@code{4096} bytes.
+
+@var{Line-translation} specifies how end-of-line characters will be
+translated when reading or writing to the socket. If this is
+unspecified or @code{#f}, then lines will be terminated by @sc{cr-lf},
+which is the standard for most internet protocols. Otherwise, it must
+be a string, which specifies the line-ending character sequence to use.
+
+When you wish to close the connection, just use @code{close-port}.
+
+As an example, here is how you can open a connection to a web server:
+
+@example
+(open-tcp-stream-socket "web.mit.edu" "www")
+@end example
+@end deffn
+
+@cindex server socket
+Next we will treat setting up a @sc{tcp} server, which is slightly more
+complicated. Creating a server is a two-part process. First, you must
+open a @dfn{server socket}, which causes the operating system to listen
+to the network on a port that you specify. Once the server socket is
+opened, the operating system will allow clients to connect to your
+computer on that port.
+
+In the second step of the process, you @dfn{accept} the connection,
+which completes the connection initiated by the client, and allows you
+to communicate with the client. Accepting a connection does not affect
+the server socket; it continues to listen for additional client
+connections. You can have multiple client connections to the same
+server socket open simultaneously.
+
+@deffn procedure open-tcp-server-socket service [address]
+This procedure opens a server socket that listens for connections to
+@var{service}; the socket will continue to listen until you close it.
+The returned value is a server socket object.
+
+An error is signalled if another process is already listening on the
+service. Additionally, ports whose number is less than @code{1024} are
+privileged on many operating systems, and cannot be used by
+non-privileged processes; if @var{service} specifies such a port and you
+do not have administrative privileges, an error may be signalled.
+
+The optional argument @var{address} specifies the @acronym{IP} address
+on which the socket will listen. If this argument is not supplied or is
+given as @code{#f}, then the socket listens on all @acronym{IP}
+addresses for this machine. (This is equivalent to passing the result
+of calling @code{host-address-any}.)
+@end deffn
+
+@deffn procedure tcp-server-connection-accept server-socket block? peer-address [line-translation]
+Checks to see if a client has connected to @var{server-socket}. If
+so, an @acronym{I/O} port is returned. The returned port can be read
+and written using ordinary Scheme @acronym{I/O} procedures such as
+@code{read-char} and @code{write-char}.
+
+The argument @var{block?} says what to do if no client has connected at
+the time of the call. If @code{#f}, it says to return immediately with
+two values of @code{#f}. Otherwise, the call waits until a client
+connects.
+
+The argument @var{peer-address} is either @code{#f} or an @acronym{IP}
+address as allocated by @code{allocate-host-address}. If it is an
+@acronym{IP} address, the address is modified to be the address of the
+client making the connection.
+
+The optional argument @var{line-translation} specifies how end-of-line
+characters will be translated when reading or writing to the returned
+socket. If this is unspecified or @code{#f}, then lines will be
+terminated by @sc{cr-lf}, which is the standard for most internet
+protocols. Otherwise, it must be a string, which specifies the
+line-ending character sequence to use.
+
+Note that closing the port returned by this procedure does not affect
+@var{server-socket}; it just closes the particular client connection
+that was opened by the call. To close @var{server-socket}, use
+@code{close-tcp-server-socket}.
+@end deffn
+
+@deffn procedure close-tcp-server-socket server-socket
+Closes the server socket @var{server-socket}. The operating system will
+cease listening for network connections to that service. Client
+connections to @var{server-socket} that have already been accepted will
+not be affected.
+@end deffn
+
+@node Miscellaneous OS Facilities, , TCP Sockets, Operating-System Interface
+@section Miscellaneous OS Facilities
+
+This section contains assorted operating-system facilities that don't
+fit into other categories.
+
+@defvr variable microcode-id/operating-system
+@defvrx variable microcode-id/operating-system-name
+@code{microcode-id/operating-system} is bound to a symbol that specifies
+the type of operating system that Scheme is running under. There are
+three possible values: @code{unix}, @code{os/2}, or @code{nt}.
+
+@code{microcode-id/operating-system-name} is a string containing the
+same name as @code{microcode-id/operating-system}; the latter is created
+by interning the former as a symbol.
+@end defvr
+
+@defvr variable microcode-id/operating-system-variant
+This variable is a string that identifies the particular variant of the
+operating system that Scheme is running under. Here are some of the
+possible values:
+
+@example
+@group
+"GNU/Linux"
+"FreeBSD"
+"HP-UX"
+"SunOS"
+"OS/2 2.1"
+"OS/2 4.0"
+"Microsoft Windows NT 4.0 (Build 1381; Service Pack 3)"
+"Microsoft Windows 98 (Build 410)"
+@end group
+@end example
+
+@noindent
+For Windows systems, it is recommended that you match on the prefix of
+this string and ignore the @code{"Build"} suffix. This is because the
+suffix may contain information about service packs or fixes, while the
+prefix will be constant for a particular version of Windows.
+@end defvr
+
+The next few procedures provide access to the @dfn{domain name service}
+(@acronym{DNS}), which maintains associations between internet host
+names such as @code{"www.swiss.ai.mit.edu"} and @acronym{IP} addresses,
+such as @code{18.23.0.16}. In MIT/GNU Scheme, we represent an internet host
+name as a string, and an @acronym{IP} address as a byte vector of length
+4 (byte vectors are just character strings that are accessed using
+@code{vector-8b-ref} rather than @code{string-ref}). The bytes in an
+@acronym{IP} address read in the same order as they do when written out:
+
+@example
+(get-host-by-name "www.swiss") @result{} #("\022\027\000\020")
+@end example
+
+@deffn procedure get-host-by-name host-name
+Looks up the internet host name @var{host-name} using the @acronym{DNS},
+returning a vector of @acronym{IP} addresses for the corresponding host,
+or @code{#f} if there is no such host. Usually the returned vector has
+only one element, but if a host has more than one network interface, the
+vector might have more than one element.
+
+@example
+(get-host-by-name "www.swiss") @result{} #("\022\027\000\020")
+@end example
+@end deffn
+
+@deffn procedure get-host-by-address ip-address
+Does a reverse @acronym{DNS} lookup on @var{ip-address}, returning the
+internet host name corresponding to that address, or @code{#f} if there
+is no such host.
+
+@example
+(get-host-by-address "\022\027\000\020") @result{} "swissnet.ai.mit.edu"
+@end example
+@end deffn
+
+@deffn procedure canonical-host-name host-name
+Finds the ``canonical'' internet host name for @var{host-name}. For
+example:
+
+@example
+@group
+(canonical-host-name "zurich") @result{} "zurich.ai.mit.edu"
+(canonical-host-name "www.swiss") @result{} "swissnet.ai.mit.edu"
+@end group
+@end example
+
+@noindent
+In both examples, the default internet domain @samp{ai.mit.edu} is added
+to @var{host-name}. In the second example, @code{"www.swiss"} is an
+alias for another computer named @code{"swissnet"}.
+@end deffn
+
+@deffn procedure get-host-name
+Returns the string that identifies the computer that MIT/GNU Scheme is
+running on. Usually this is an unqualified internet host name, i.e.@:
+the host name without the domain suffix:
+
+@example
+(get-host-name) @result{} "aarau"
+@end example
+@end deffn
+
+@deffn procedure os/hostname
+Returns the canonical internet host name of the computer that MIT/GNU Scheme
+is running on. So, in contrast to the example for @code{get-host-name}:
+
+@example
+(os/hostname) @result{} "aarau.ai.mit.edu"
+@end example
+@end deffn
+
+@deffn procedure allocate-host-address
+Allocates and returns an @acronym{IP} address object. This is just a
+string of a fixed length (current 4 bytes) into which an @acronym{IP}
+address may be stored. This procedure is used to generate an
+appropriate argument to be passed to
+@code{tcp-server-connection-accept}.
+
+@example
+(allocate-host-address) @result{} "Xe\034\241"
+@end example
+@end deffn
+
+@deffn procedure host-address-any
+Return an @acronym{IP} address object that specifies ``any host''. This
+object is useful only when passed as the @var{address} argument to
+@code{open-tcp-server-socket}.
+
+@example
+(host-address-any) @result{} "\000\000\000\000"
+@end example
+@end deffn
+
+@deffn procedure host-address-loopback
+@cindex loopback interface
+Return an @acronym{IP} address object that specifies the local
+@dfn{loopback} network interface. The loopback interface is a software
+network interface that can be used only for communicating between
+processes on the same computer. This address object is useful only when
+passed as the @var{address} argument to @code{open-tcp-server-socket}.
+
+@example
+(host-address-loopback) @result{} "\177\000\000\001"
+@end example
+@end deffn
--- /dev/null
+@c This file is part of the MIT/GNU Scheme Reference Manual.
+@c $Id: overview.texi,v 1.1 2003/04/15 03:30:04 cph Exp $
+
+@c Copyright 1991,1992,1993,1994,1995 Massachusetts Institute of Technology
+@c Copyright 1996,1997,1999,2000,2001 Massachusetts Institute of Technology
+@c Copyright 2002,2003 Massachusetts Institute of Technology
+@c See file scheme.texinfo for copying conditions.
+
+@node Overview, Special Forms, Acknowledgements, Top
+@chapter Overview
+
+@cindex runtime system
+This manual is a detailed description of the MIT/GNU Scheme runtime system.
+It is intended to be a reference document for programmers. It does not
+describe how to run Scheme or how to interact with it --- that is the
+subject of the @cite{MIT/GNU Scheme User's Manual}.
+
+This chapter summarizes the semantics of Scheme, briefly describes the
+MIT/GNU Scheme programming environment, and explains the syntactic and
+lexical conventions of the language. Subsequent chapters describe
+special forms, numerous data abstractions, and facilities for input and
+output.
+
+@cindex standard Scheme (defn)
+@cindex Scheme standard
+@cindex R4RS
+Throughout this manual, we will make frequent references to
+@dfn{standard Scheme}, which is the language defined by the document
+@cite{Revised^4 Report on the Algorithmic Language Scheme}, by William
+Clinger, Jonathan Rees, et al.@:, or by @sc{ieee} Std.@: 1178-1990,
+@cite{IEEE Standard for the Scheme Programming Language} (in fact,
+several parts of this document are copied from the @cite{Revised
+Report}). MIT/GNU Scheme is an extension of standard Scheme.
+
+These are the significant semantic characteristics of the Scheme
+language:
+
+@table @asis
+@item Variables are statically scoped
+@cindex static scoping (defn)
+@cindex scope (see region)
+Scheme is a @dfn{statically scoped} programming language, which means that
+each use of a variable is associated with a lexically apparent binding
+of that variable. Algol is another statically scoped language.
+
+@item Types are latent
+@cindex latent types (defn)
+@cindex manifest types (defn)
+@cindex weak types (defn)
+@cindex strong types (defn)
+@cindex dynamic types (defn)
+@cindex static types (defn)
+@cindex types, latent (defn)
+@cindex types, manifest (defn)
+Scheme has @dfn{latent} types as opposed to @dfn{manifest} types, which
+means that Scheme associates types with values (or objects) rather than
+with variables. Other languages with latent types (also referred to as
+@dfn{weakly} typed or @dfn{dynamically} typed languages) include APL,
+Snobol, and other dialects of Lisp. Languages with manifest types
+(sometimes referred to as @dfn{strongly} typed or @dfn{statically} typed
+languages) include Algol 60, Pascal, and C.
+
+@item Objects have unlimited extent
+@cindex extent, of objects
+All objects created during a Scheme computation, including procedures
+and continuations, have unlimited extent; no Scheme object is ever
+destroyed. The system doesn't run out of memory because the garbage
+collector reclaims the storage occupied by an object when the object
+cannot possibly be needed by a future computation. Other languages in
+which most objects have unlimited extent include APL and other Lisp
+dialects.
+
+@item Proper tail recursion
+@cindex proper tail recursion (defn)
+@cindex tail recursion (defn)
+@cindex recursion (see tail recursion)
+Scheme is @dfn{properly tail-recursive}, which means that iterative
+computation can occur in constant space, even if the iterative
+computation is described by a syntactically recursive procedure. With a
+tail-recursive implementation, you can express iteration using the
+ordinary procedure-call mechanics; special iteration expressions are
+provided only for syntactic convenience.
+
+@item Procedures are objects
+Scheme procedures are objects, which means that you can create them
+dynamically, store them in data structures, return them as the results
+of other procedures, and so on. Other languages with such procedure
+objects include Common Lisp and ML.
+
+@item Continuations are explicit
+In most other languages, continuations operate behind the scenes. In
+Scheme, continuations are objects; you can use continuations for
+implementing a variety of advanced control constructs, including
+non-local exits, backtracking, and coroutines.
+
+@item Arguments are passed by value
+Arguments to Scheme procedures are passed by value, which means that
+Scheme evaluates the argument expressions before the procedure gains
+control, whether or not the procedure needs the result of the
+evaluations. ML, C, and APL are three other languages that pass
+arguments by value. In languages such as SASL and Algol 60, argument
+expressions are not evaluated unless the values are needed by the
+procedure.
+@end table
+
+@findex read
+Scheme uses a parenthesized-list Polish notation to describe programs
+and (other) data. The syntax of Scheme, like that of most Lisp
+dialects, provides for great expressive power, largely due to its
+simplicity. An important consequence of this simplicity is the
+susceptibility of Scheme programs and data to uniform treatment by other
+Scheme programs. As with other Lisp dialects, the @code{read} primitive
+parses its input; that is, it performs syntactic as well as lexical
+decomposition of what it reads.
+
+@menu
+* Notational Conventions::
+* Scheme Concepts::
+* Lexical Conventions::
+* Expressions::
+@end menu
+
+@node Notational Conventions, Scheme Concepts, Overview, Overview
+@section Notational Conventions
+@cindex notational conventions
+@cindex conventions, notational
+
+This section details the notational conventions used throughout the rest
+of this document.
+
+@menu
+* Errors::
+* Examples::
+* Entry Format::
+@end menu
+
+@node Errors, Examples, Notational Conventions, Notational Conventions
+@subsection Errors
+@cindex errors, notational conventions
+
+@cindex signal an error (defn)
+@cindex must be, notational convention
+@findex error
+When this manual uses the phrase ``an error will be signalled,'' it
+means that Scheme will call @code{error}, which normally halts execution
+of the program and prints an error message.
+
+When this manual uses the phrase ``it is an error,'' it means that the
+specified action is not valid in Scheme, but the system may or may not
+signal the error. When this manual says that something ``must be,'' it
+means that violating the requirement is an error.
+
+@node Examples, Entry Format, Errors, Notational Conventions
+@subsection Examples
+@cindex examples
+
+@cindex => notational convention
+@cindex result of evaluation, in examples
+@cindex evaluation, in examples
+@cindex specified result, in examples
+This manual gives many examples showing the evaluation of expressions.
+The examples have a common format that shows the expression being
+evaluated on the left hand side, an ``arrow'' in the middle, and the
+value of the expression written on the right. For example:
+
+@example
+(+ 1 2) @result{} 3
+@end example
+
+Sometimes the arrow and value will be moved under the expression, due to
+lack of space. Occasionally we will not care what the value is, in
+which case both the arrow and the value are omitted.
+
+@cindex error--> notational convention
+@cindex error, in examples
+If an example shows an evaluation that results in an error, an error
+message is shown, prefaced by @samp{@error{}}:
+
+@example
+(+ 1 'foo) @error{} Illegal datum
+@end example
+
+@cindex -| notational convention
+@cindex printed output, in examples
+An example that shows printed output marks it with @samp{@print{}}:
+
+@example
+@group
+(begin (write 'foo) 'bar)
+ @print{} foo
+ @result{} bar
+@end group
+@end example
+
+@cindex unspecified result (defn)
+@cindex result, unspecified (defn)
+When this manual indicates that the value returned by some expression is
+@dfn{unspecified}, it means that the expression will evaluate to some
+object without signalling an error, but that programs should not depend
+on the value in any way.
+
+@node Entry Format, , Examples, Notational Conventions
+@subsection Entry Format
+@cindex entry format
+@cindex format, entry
+
+Each description of an MIT/GNU Scheme variable, special form, or
+procedure begins with one or more header lines in this format:
+
+@deffn @var{category} @var{template}
+@end deffn
+
+@noindent
+where @var{category} specifies the kind of item (``variable'',
+``special form'', or ``procedure''). The form of @var{template} is
+interpreted depending on @var{category}.
+
+@table @asis
+@item Variable
+@var{Template} consists of the variable's name.
+@cindex variable, entry category
+
+@item Special Form
+@var{Template} starts with the syntactic keyword of the special form,
+followed by a description of the special form's syntax. The description
+is written using the following conventions.
+@cindex special form, entry category
+
+@findex else
+@findex cond
+Named components are italicized in the printed manual, and uppercase in
+the Info file. ``Noise'' keywords, such as the @code{else} keyword in
+the @code{cond} special form, are set in a fixed width font in the
+printed manual; in the Info file they are not distinguished.
+Parentheses indicate themselves.
+
+@cindex ellipsis, in entries
+@cindex ... in entries
+A horizontal ellipsis (@dots{}) is describes repeated components.
+Specifically,
+
+@display
+@var{thing} @dots{}
+@end display
+
+@noindent
+indicates @emph{zero} or more occurrences of @var{thing}, while
+
+@display
+@var{thing} @var{thing} @dots{}
+@end display
+
+@noindent
+indicates @emph{one} or more occurrences of @var{thing}.
+
+@cindex bracket, in entries
+@cindex [ in entries
+@cindex ] in entries
+@cindex optional component, in entries
+Brackets, @code{[ ]}, enclose optional components.
+
+@cindex body, of special form (defn)
+@findex lambda
+Several special forms (e.g.@: @code{lambda}) have an internal component
+consisting of a series of expressions; usually these expressions are
+evaluated sequentially under conditions that are specified in the
+description of the special form. This sequence of expressions is commonly
+referred to as the @dfn{body} of the special form.
+
+@item Procedure
+@var{Template} starts with the name of the variable to which the
+procedure is bound, followed by a description of the procedure's
+arguments. The arguments are described using ``lambda list'' notation
+(@pxref{Lambda Expressions}), except that brackets are used to denote
+optional arguments, and ellipses are used to denote ``rest'' arguments.
+@cindex procedure, entry format
+
+The names of the procedure's arguments are italicized in the printed
+manual, and uppercase in the Info file.
+
+When an argument names a Scheme data type, it indicates that the
+argument must be that type of data object. For example,
+
+@deffn procedure cdr pair
+@end deffn
+
+@noindent
+indicates that the standard Scheme procedure @code{cdr} takes one argument,
+which must be a pair.
+
+Many procedures signal an error when an argument is of the wrong type;
+usually this error is a condition of type
+@code{condition-type:wrong-type-argument}.
+@findex condition-type:wrong-type-argument
+
+In addition to the standard data-type names (@var{pair}, @var{list},
+@var{boolean}, @var{string}, etc.), the following names as arguments
+also imply type restrictions:
+
+@itemize @bullet
+@item
+@var{object}: any object
+@item
+@var{thunk}: a procedure of no arguments
+@item
+@var{x}, @var{y}: real numbers
+@item
+@var{q}, @var{n}: integers
+@item
+@var{k}: an exact non-negative integer
+@end itemize
+@end table
+
+Some examples:
+
+@deffn procedure list object @dots{}
+@end deffn
+
+@noindent
+indicates that the standard Scheme procedure @code{list} takes zero or
+more arguments, each of which may be any Scheme object.
+
+@deffn procedure write-char char [output-port]
+@end deffn
+
+@noindent
+indicates that the standard Scheme procedure @code{write-char} must be
+called with a character, @var{char}, and may also be called with a
+character and an output port.
+
+@node Scheme Concepts, Lexical Conventions, Notational Conventions, Overview
+@section Scheme Concepts
+@cindex scheme concepts
+
+@menu
+* Variable Bindings::
+* Environment Concepts::
+* Initial and Current Environments::
+* Static Scoping::
+* True and False::
+* External Representations::
+* Disjointness of Types::
+* Storage Model::
+@end menu
+
+@node Variable Bindings, Environment Concepts, Scheme Concepts, Scheme Concepts
+@subsection Variable Bindings
+@cindex variable binding
+@cindex binding, of variable
+
+@cindex bound variable (defn)
+@cindex value, of variable (defn)
+@cindex name, of value (defn)
+@cindex location, of variable
+Any identifier that is not a syntactic keyword may be used as a variable
+(@pxref{Identifiers}). A variable may name a location where a value can
+be stored. A variable that does so is said to be @dfn{bound} to the
+location. The value stored in the location to which a variable is bound
+is called the variable's @dfn{value}. (The variable is sometimes said
+to @dfn{name} the value or to be @dfn{bound to} the value.)
+
+@cindex unassigned variable (defn)
+@cindex error, unassigned variable
+A variable may be bound but still not have a value; such a variable is
+said to be @dfn{unassigned}. Referencing an unassigned variable is an
+error. When this error is signalled, it is a condition of type
+@code{condition-type:unassigned-variable}; sometimes the compiler does
+not generate code to signal the error. Unassigned variables are useful
+only in combination with side effects (@pxref{Assignments}).
+@findex condition-type:unassigned-variable
+
+@node Environment Concepts, Initial and Current Environments, Variable Bindings, Scheme Concepts
+@subsection Environment Concepts
+
+@cindex environment (defn)
+@cindex unbound variable (defn)
+@cindex error, unbound variable (defn)
+An @dfn{environment} is a set of variable bindings. If an environment
+has no binding for a variable, that variable is said to be @dfn{unbound}
+in that environment. Referencing an unbound variable signals a
+condition of type @code{condition-type:unbound-variable}.
+@findex condition-type:unbound-variable
+
+@cindex extension, of environment (defn)
+@cindex environment, extension (defn)
+@cindex shadowing, of variable binding (defn)
+@cindex parent, of environment (defn)
+@cindex child, of environment (defn)
+@cindex inheritance, of environment bindings (defn)
+A new environment can be created by @dfn{extending} an existing
+environment with a set of new bindings. Note that ``extending an
+environment'' does @strong{not} modify the environment; rather, it
+creates a new environment that contains the new bindings and the old
+ones. The new bindings @dfn{shadow} the old ones; that is, if an
+environment that contains a binding for @code{x} is extended with a new
+binding for @code{x}, then only the new binding is seen when @code{x} is
+looked up in the extended environment. Sometimes we say that the
+original environment is the @dfn{parent} of the new one, or that the new
+environment is a @dfn{child} of the old one, or that the new environment
+@dfn{inherits} the bindings in the old one.
+
+@findex let
+@findex let*
+@findex letrec
+@findex do
+@findex define
+Procedure calls extend an environment, as do @code{let}, @code{let*},
+@code{letrec}, and @code{do} expressions. Internal definitions
+(@pxref{Internal Definitions}) also extend an environment. (Actually,
+all the constructs that extend environments can be expressed in terms of
+procedure calls, so there is really just one fundamental mechanism for
+environment extension.) A top-level definition (@pxref{Top-Level
+Definitions}) may add a binding to an existing environment.
+
+@node Initial and Current Environments, Static Scoping, Environment Concepts, Scheme Concepts
+@subsection Initial and Current Environments
+
+@cindex initial environment (defn)
+@cindex environment, initial (defn)
+MIT/GNU Scheme provides an @dfn{initial environment} that contains all
+of the variable bindings described in this manual. Most environments
+are ultimately extensions of this initial environment. In Scheme, the
+environment in which your programs execute is actually a child
+(extension) of the environment containing the system's bindings. Thus,
+system names are visible to your programs, but your names do not
+interfere with system programs.
+
+@cindex current environment (defn)
+@cindex environment, current (defn)
+@cindex REP loop (defn)
+@cindex REP loop, environment of
+@findex user-initial-environment
+@findex ge
+The environment in effect at some point in a program is called the
+@dfn{current environment} at that point. In particular, every
+@acronym{REP} loop has a current environment. (@acronym{REP} stands for
+``read-eval-print''; the @acronym{REP} loop is the Scheme program that
+reads your input, evaluates it, and prints the result.) The environment
+of the top-level @acronym{REP} loop (the one you are in when Scheme
+starts up) starts as @code{user-initial-environment}, although it can be
+changed by the @code{ge} procedure. When a new @acronym{REP} loop is
+created, its environment is determined by the program that creates it.
+
+@node Static Scoping, True and False, Initial and Current Environments, Scheme Concepts
+@subsection Static Scoping
+@cindex scoping, static
+@cindex static scoping
+
+@cindex dynamic binding, versus static scoping
+Scheme is a statically scoped language with block structure. In this
+respect, it is like Algol and Pascal, and unlike most other dialects of
+Lisp except for Common Lisp.
+
+@cindex binding expression (defn)
+@cindex expression, binding (defn)
+The fact that Scheme is statically scoped (rather than
+dynamically bound) means that the environment that is extended (and
+becomes current) when a procedure is called is the environment in which
+the procedure was created (i.e.@: in which the procedure's defining
+lambda expression was evaluated), not the environment in which the
+procedure is called. Because all the other Scheme @dfn{binding
+expressions} can be expressed in terms of procedures, this determines
+how all bindings behave.
+
+Consider the following definitions, made at the top-level @acronym{REP}
+loop (in the initial environment):
+
+@example
+@group
+(define x 1)
+(define (f x) (g 2))
+(define (g y) (+ x y))
+(f 5) @result{} 3 @r{; not} 7
+@end group
+@end example
+
+Here @code{f} and @code{g} are bound to procedures created in the
+initial environment. Because Scheme is statically scoped, the call to
+@code{g} from @code{f} extends the initial environment (the one in which
+@code{g} was created) with a binding of @code{y} to @code{2}. In this
+extended environment, @code{y} is @code{2} and @code{x} is @code{1}.
+(In a dynamically bound Lisp, the call to @code{g} would extend the
+environment in effect during the call to @code{f}, in which @code{x} is
+bound to @code{5} by the call to @code{f}, and the answer would be
+@code{7}.)
+
+@cindex lexical scoping (defn)
+@cindex scoping, lexical (defn)
+@cindex region, of variable binding (defn)
+@cindex variable, binding region (defn)
+@findex lambda
+Note that with static scoping, you can tell what binding a variable
+reference refers to just from looking at the text of the program; the
+referenced binding cannot depend on how the program is used. That is,
+the nesting of environments (their parent-child relationship)
+corresponds to the nesting of binding expressions in program text.
+(Because of this connection to the text of the program, static scoping
+is also called @dfn{lexical} scoping.) For each place where a variable
+is bound in a program there is a corresponding @dfn{region} of the
+program text within which the binding is effective. For example, the
+region of a binding established by a @code{lambda} expression is the
+entire body of the @code{lambda} expression. The documentation of each
+binding expression explains what the region of the bindings it makes is.
+A use of a variable (that is, a reference to or assignment of a
+variable) refers to the innermost binding of that variable whose region
+contains the variable use. If there is no such region, the use refers
+to the binding of the variable in the global environment (which is an
+ancestor of all other environments, and can be thought of as a region in
+which all your programs are contained).
+
+@node True and False, External Representations, Static Scoping, Scheme Concepts
+@subsection True and False
+
+@cindex boolean object
+@cindex true, boolean object
+@cindex false, boolean object
+@findex #t
+@findex #f
+In Scheme, the boolean values true and false are denoted by @code{#t}
+and @code{#f}. However, any Scheme value can be treated as a boolean
+for the purpose of a conditional test. This manual uses the word
+@dfn{true} to refer to any Scheme value that counts as true, and the
+word @dfn{false} to refer to any Scheme value that counts as false. In
+conditional tests, all values count as true except for @code{#f}, which
+counts as false (@pxref{Conditionals}).
+
+Implementation note: In MIT/GNU Scheme, @code{#f} and the empty list are the
+same object, and the printed representation of @code{#f} is always
+@samp{()}. As this contradicts the Scheme standard, MIT/GNU Scheme will be
+changed to make @code{#f} and the empty list different objects.
+
+@node External Representations, Disjointness of Types, True and False, Scheme Concepts
+@subsection External Representations
+
+@cindex external representation (defn)
+@cindex representation, external (defn)
+An important concept in Scheme is that of the
+@dfn{external representation} of an object as a sequence of characters.
+For example, an external representation of the integer 28 is the
+sequence of characters @samp{28}, and an external representation of a
+list consisting of the integers 8 and 13 is the sequence of characters
+@samp{(8 13)}.
+
+The external representation of an object is not necessarily unique. The
+integer 28 also has representations @samp{#e28.000} and @samp{#x1c}, and
+the list in the previous paragraph also has the representations @samp{(
+08 13 )} and @samp{(8 . (13 . ( )))}.
+
+Many objects have standard external representations, but some, such as
+procedures and circular data structures, do not have standard
+representations (although particular implementations may define
+representations for them).
+
+An external representation may be written in a program to obtain the
+corresponding object (@pxref{Quoting}).
+
+@findex read
+@findex write
+External representations can also be used for input and output. The
+procedure @code{read} parses external representations, and the procedure
+@code{write} generates them. Together, they provide an elegant and
+powerful input/output facility.
+
+Note that the sequence of characters @samp{(+ 2 6)} is @emph{not} an
+external representation of the integer 8, even though it @emph{is} an
+expression that evaluates to the integer 8; rather, it is an external
+representation of a three-element list, the elements of which are the
+symbol @code{+} and the integers @code{2} and @code{6}. Scheme's syntax
+has the property that any sequence of characters that is an expression
+is also the external representation of some object. This can lead to
+confusion, since it may not be obvious out of context whether a given
+sequence of characters is intended to denote data or program, but it is
+also a source of power, since it facilitates writing programs such as
+interpreters and compilers that treat programs as data or data as
+programs.
+
+@node Disjointness of Types, Storage Model, External Representations, Scheme Concepts
+@subsection Disjointness of Types
+
+Every object satisfies at most one of the following predicates (but see
+@ref{True and False}, for an exception):
+
+@example
+@group
+bit-string? environment? port? symbol?
+boolean? null? procedure? vector?
+cell? number? promise? weak-pair?
+char? pair? string?
+condition?
+@end group
+@end example
+
+@node Storage Model, , Disjointness of Types, Scheme Concepts
+@subsection Storage Model
+
+This section describes a model that can be used to understand Scheme's
+use of storage.
+
+@cindex location
+@findex string-set!
+Variables and objects such as pairs, vectors, and strings implicitly
+denote locations or sequences of locations. A string, for example,
+denotes as many locations as there are characters in the string. (These
+locations need not correspond to a full machine word.) A new value may
+be stored into one of these locations using the @code{string-set!}
+procedure, but the string continues to denote the same locations as
+before.
+
+@findex car
+@findex vector-ref
+@findex string-ref
+@findex eqv?
+An object fetched from a location, by a variable reference or by a
+procedure such as @code{car}, @code{vector-ref}, or @code{string-ref},
+is equivalent in the sense of @code{eqv?} to the object last stored in
+the location before the fetch.
+
+Every location is marked to show whether it is in use. No variable or
+object ever refers to a location that is not in use. Whenever this
+document speaks of storage being allocated for a variable or object,
+what is meant is that an appropriate number of locations are chosen from
+the set of locations that are not in use, and the chosen locations are
+marked to indicate that they are now in use before the variable or
+object is made to denote them.
+
+@cindex constant
+@cindex mutable
+@cindex immutable
+@findex symbol->string
+In many systems it is desirable for constants (i.e.@: the values of
+literal expressions) to reside in read-only memory. To express this, it
+is convenient to imagine that every object that denotes locations is
+associated with a flag telling whether that object is mutable or
+immutable. The constants and the strings returned by
+@code{symbol->string} are then the immutable objects, while all objects
+created by other procedures are mutable. It is an error to attempt to
+store a new value into a location that is denoted by an immutable
+object. Note that the MIT/GNU Scheme compiler takes advantage of this
+property to share constants, but that these constants are not immutable.
+Instead, two constants that are @code{equal?} may be @code{eq?} in
+compiled code.
+
+@node Lexical Conventions, Expressions, Scheme Concepts, Overview
+@section Lexical Conventions
+@cindex lexical conventions
+@cindex conventions, lexical
+
+This section describes Scheme's lexical conventions.
+
+@menu
+* Whitespace::
+* Delimiters::
+* Identifiers::
+* Uppercase and Lowercase::
+* Naming Conventions::
+* Comments::
+* Additional Notations::
+@end menu
+
+@node Whitespace, Delimiters, Lexical Conventions, Lexical Conventions
+@subsection Whitespace
+
+@cindex whitespace, in programs (defn)
+@cindex token, in programs (defn)
+@dfn{Whitespace} characters are spaces, newlines, tabs, and page breaks.
+Whitespace is used to improve the readability of your programs and to
+separate tokens from each other, when necessary. (A @dfn{token} is an
+indivisible lexical unit such as an identifier or number.) Whitespace
+is otherwise insignificant. Whitespace may occur between any two
+tokens, but not within a token. Whitespace may also occur inside a
+string, where it is significant.
+
+@node Delimiters, Identifiers, Whitespace, Lexical Conventions
+@subsection Delimiters
+
+@cindex delimiter, in programs (defn)
+All whitespace characters are @dfn{delimiters}. In addition, the
+following characters act as delimiters:
+
+@example
+( ) ; " ' ` |
+@end example
+
+Finally, these next characters act as delimiters, despite the fact that
+Scheme does not define any special meaning for them:
+
+@example
+[ ] @{ @}
+@end example
+
+For example, if the value of the variable @code{name} is
+@code{"max"}:
+
+@example
+(list"Hi"name(+ 1 2)) @result{} ("Hi" "max" 3)
+@end example
+
+@node Identifiers, Uppercase and Lowercase, Delimiters, Lexical Conventions
+@subsection Identifiers
+
+@cindex identifier (defn)
+An @dfn{identifier} is a sequence of one or more non-delimiter
+characters. Identifiers are used in several ways in Scheme
+programs:
+
+@itemize @bullet
+@item
+An identifier can be used as a variable or as a syntactic keyword.
+@cindex variable, identifier as
+@cindex syntactic keyword, identifier as
+
+@item
+When an identifier appears as a literal or within a literal, it denotes
+a symbol.
+@cindex literal, identifier as
+@end itemize
+
+Scheme accepts most of the identifiers that other programming languages
+allow. MIT/GNU Scheme allows all of the identifiers that standard
+Scheme does, plus many more.
+
+MIT/GNU Scheme defines a potential identifier to be a sequence of
+non-delimiter characters that does not begin with either of the
+characters @samp{#} or @samp{,}. Any such sequence of characters that
+is not a syntactically valid number (@pxref{Numbers}) is considered to
+be a valid identifier. Note that, although it is legal for @samp{#} and
+@samp{,} to appear in an identifier (other than in the first character
+position), it is poor programming practice.
+
+Here are some examples of identifiers:
+
+@example
+@group
+lambda q
+list->vector soup
++ V17a
+<=? a34kTMNs
+the-word-recursion-has-many-meanings
+@end group
+@end example
+
+@node Uppercase and Lowercase, Naming Conventions, Identifiers, Lexical Conventions
+@subsection Uppercase and Lowercase
+@cindex uppercase
+@cindex lowercase
+
+@cindex alphabetic case-insensitivity of programs (defn)
+@cindex case-insensitivity of programs (defn)
+@cindex sensitivity, to case in programs (defn)
+@cindex insensitivity, to case in programs (defn)
+Scheme doesn't distinguish uppercase and lowercase forms of a letter
+except within character and string constants; in other words, Scheme is
+@dfn{case-insensitive}. For example, @samp{Foo} is the same identifier
+as @samp{FOO}, and @samp{#x1AB} is the same number as @samp{#X1ab}. But
+@samp{#\a} and @samp{#\A} are different characters.
+
+@node Naming Conventions, Comments, Uppercase and Lowercase, Lexical Conventions
+@subsection Naming Conventions
+@cindex naming conventions
+@cindex conventions, naming
+
+@cindex predicate (defn)
+@cindex ? in predicate names
+A @dfn{predicate} is a procedure that always returns a boolean value
+(@code{#t} or @code{#f}). By convention, predicates usually have names
+that end in @samp{?}.
+
+@cindex mutation procedure (defn)
+@cindex ! in mutation procedure names
+A @dfn{mutation procedure} is a procedure that alters a data structure.
+By convention, mutation procedures usually have names that end in
+@samp{!}.
+
+@node Comments, Additional Notations, Naming Conventions, Lexical Conventions
+@subsection Comments
+
+@cindex comment, in programs (defn)
+@cindex semicolon, as external representation
+@cindex ; as external representation
+The beginning of a comment is indicated with a semicolon (@code{;}).
+Scheme ignores everything on a line in which a semicolon appears, from
+the semicolon until the end of the line. The entire comment, including
+the newline character that terminates it, is treated as
+whitespace.
+
+@cindex extended comment, in programs (defn)
+@cindex comment, extended, in programs (defn)
+@cindex #| as external representation
+An alternative form of comment (sometimes called an @dfn{extended
+comment}) begins with the characters @samp{#|} and ends with the
+characters @samp{|#}. This alternative form is an MIT/GNU Scheme extension.
+As with ordinary comments, all of the characters in an extended comment,
+including the leading @samp{#|} and trailing @samp{|#}, are treated as
+whitespace. Comments of this form may extend over multiple lines, and
+additionally may be nested (unlike the comments of the programming
+language C, which have a similar syntax).
+
+@example
+@group
+;;; This is a comment about the FACT procedure. Scheme
+;;; ignores all of this comment. The FACT procedure computes
+;;; the factorial of a non-negative integer.
+@end group
+
+@group
+#|
+This is an extended comment.
+Such comments are useful for commenting out code fragments.
+|#
+@end group
+
+@group
+(define fact
+ (lambda (n)
+ (if (= n 0) ;This is another comment:
+ 1 ;Base case: return 1
+ (* n (fact (- n 1))))))
+@end group
+@end example
+
+@node Additional Notations, , Comments, Lexical Conventions
+@subsection Additional Notations
+
+@cindex characters, special, in programs
+@cindex special characters, in programs
+The following list describes additional notations used in Scheme.
+@xref{Numbers}, for a description of the notations used for numbers.
+
+@table @code
+@item + - .
+The plus sign, minus sign, and period are used in numbers, and may also
+occur in an identifier. A delimited period (not occurring within a
+number or identifier) is used in the notation for pairs and to indicate
+a ``rest'' parameter in a formal parameter list
+(@pxref{Lambda Expressions}).
+
+@item ( )
+Parentheses are used for grouping and to notate lists (@pxref{Lists}).
+
+@item "
+The double quote delimits strings (@pxref{Strings}).
+
+@item \
+The backslash is used in the syntax for character constants
+(@pxref{Characters}) and as an escape character within string constants
+(@pxref{Strings}).
+
+@item ;
+The semicolon starts a comment.
+
+@item '
+The single quote indicates literal data; it suppresses evaluation
+(@pxref{Quoting}).
+
+@item `
+The backquote indicates almost-constant data (@pxref{Quoting}).
+
+@item ,
+The comma is used in conjunction with the backquote (@pxref{Quoting}).
+
+@item ,@@
+A comma followed by an at-sign is used in conjunction with the backquote
+(@pxref{Quoting}).
+
+@item #
+The sharp (or pound) sign has different uses, depending on the character
+that immediately follows it:
+
+@item #t #f
+These character sequences denote the boolean constants
+(@pxref{Booleans}).
+
+@item #\
+This character sequence introduces a character constant
+(@pxref{Characters}).
+
+@item #(
+This character sequence introduces a vector constant (@pxref{Vectors}).
+A close parenthesis, @samp{)}, terminates a vector constant.
+
+@item #e #i #b #o #d #l #s #x
+These character sequences are used in the notation for numbers
+(@pxref{Numbers}).
+
+@item #|
+This character sequence introduces an extended comment. The comment is
+terminated by the sequence @samp{|#}. This notation is an MIT/GNU Scheme
+extension.
+
+@item #!
+This character sequence is used to denote a small set of named
+constants. Currently there are only two of these, @code{#!optional} and
+@code{#!rest}, both of which are used in the @code{lambda} special form
+to mark certain parameters as being ``optional'' or ``rest'' parameters.
+This notation is an MIT/GNU Scheme extension.
+@findex #!optional
+@findex #!rest
+@findex lambda
+
+@item #*
+This character sequence introduces a bit string (@pxref{Bit Strings}).
+This notation is an MIT/GNU Scheme extension.
+
+@item #[
+This character sequence is used to denote objects that do not have a
+readable external representation (@pxref{Custom Output}). A close
+bracket, @samp{]}, terminates the object's notation. This notation is
+an MIT/GNU Scheme extension.
+
+@item #@@
+This character sequence is a convenient shorthand used to refer to
+objects by their hash number (@pxref{Custom Output}). This notation is
+an MIT/GNU Scheme extension.
+
+@item #=
+@itemx ##
+These character sequences introduce a notation used to show circular
+structures in printed output, or to denote them in input. The notation
+works much like that in Common Lisp, and is an MIT/GNU Scheme extension.
+@end table
+
+@node Expressions, , Lexical Conventions, Overview
+@section Expressions
+
+@cindex expression (defn)
+A Scheme @dfn{expression} is a construct that returns a value. An
+expression may be a @emph{literal}, a @emph{variable reference}, a
+@emph{special form}, or a @emph{procedure call}.
+
+@menu
+* Literal Expressions::
+* Variable References::
+* Special Form Syntax::
+* Procedure Call Syntax::
+@end menu
+
+@node Literal Expressions, Variable References, Expressions, Expressions
+@subsection Literal Expressions
+
+@cindex literal expression (defn)
+@cindex constant expression (defn)
+@cindex expression, literal (defn)
+@cindex expression, constant (defn)
+@dfn{Literal} constants may be written by using an external
+representation of the data. In general, the external representation
+must be @emph{quoted} (@pxref{Quoting}); but some external
+representations can be used without quotation.
+
+@example
+@group
+"abc" @result{} "abc"
+145932 @result{} 145932
+#t @result{} #t
+#\a @result{} #\a
+@end group
+@end example
+
+The external representation of numeric constants, string constants,
+character constants, and boolean constants evaluate to the constants
+themselves. Symbols, pairs, lists, and vectors require quoting.
+
+@node Variable References, Special Form Syntax, Literal Expressions, Expressions
+@subsection Variable References
+
+@cindex variable reference (defn)
+@cindex reference, variable (defn)
+@cindex unbound variable
+@cindex unassigned variable
+An expression consisting of an identifier (@pxref{Identifiers}) is a
+@dfn{variable reference}; the identifier is the name of the variable
+being referenced. The value of the variable reference is the value
+stored in the location to which the variable is bound. An error is
+signalled if the referenced variable is unbound or unassigned.
+
+@example
+@group
+(define x 28)
+x @result{} 28
+@end group
+@end example
+
+@node Special Form Syntax, Procedure Call Syntax, Variable References, Expressions
+@subsection Special Form Syntax
+
+@example
+(@var{keyword} @var{component} @dots{})
+@end example
+
+@cindex expression, special form (defn)
+@cindex special form (defn)
+@cindex form, special (defn)
+@cindex keyword, of special form (defn)
+@cindex syntactic keyword (defn)
+A parenthesized expression that starts with a @dfn{syntactic keyword} is
+a @dfn{special form}. Each special form has its own syntax, which is
+described later in the manual.
+
+Note that syntactic keywords and variable bindings share the same
+namespace. A local variable binding may shadow a syntactic keyword, and
+a local syntactic-keyword definition may shadow a variable binding.
+
+The following list contains all of the syntactic keywords that are
+defined when MIT/GNU Scheme is initialized:
+
+@multitable @columnfractions .33 .33 .33
+@item access
+@tab and
+@tab begin
+@item case
+@tab cond
+@tab cons-stream
+@item declare
+@tab default-object?
+@tab define
+@item define-integrable
+@tab define-structure
+@tab define-syntax
+@item delay
+@tab do
+@tab er-macro-transformer
+@item fluid-let
+@tab if
+@tab lambda
+@item let
+@tab let*
+@tab let*-syntax
+@item let-syntax
+@tab letrec
+@tab letrec-syntax
+@item local-declare
+@tab named-lambda
+@tab non-hygienic-macro-transformer
+@item or
+@tab quasiquote
+@tab quote
+@item rsc-macro-transformer
+@tab sc-macro-transformer
+@tab set!
+@item syntax-rules
+@tab the-environment
+@end multitable
+
+@node Procedure Call Syntax, , Special Form Syntax, Expressions
+@subsection Procedure Call Syntax
+
+@example
+(@var{operator} @var{operand} @dots{})
+@end example
+
+@cindex expression, procedure call (defn)
+@cindex procedure call (defn)
+@cindex operator, of procedure call (defn)
+@cindex operand, of procedure call (defn)
+A @dfn{procedure call} is written by simply enclosing in parentheses
+expressions for the procedure to be called (the @dfn{operator}) and the
+arguments to be passed to it (the @dfn{operands}). The @var{operator}
+and @var{operand} expressions are evaluated and the resulting procedure
+is passed the resulting arguments. @xref{Lambda Expressions}, for a
+more complete description of this.
+
+@cindex combination (defn)
+Another name for the procedure call expression is @dfn{combination}.
+This word is more specific in that it always refers to the expression;
+``procedure call'' sometimes refers to the @emph{process} of calling a
+procedure.
+
+@cindex order, of argument evaluation
+@cindex evaluation order, of arguments
+@cindex argument evaluation order
+Unlike some other dialects of Lisp, Scheme always evaluates the operator
+expression and the operand expressions with the same evaluation rules,
+and the order of evaluation is unspecified.
+
+@example
+@group
+(+ 3 4) @result{} 7
+((if #f = *) 3 4) @result{} 12
+@end group
+@end example
+
+@findex +
+@findex *
+@findex lambda
+A number of procedures are available as the values of variables in the
+initial environment; for example, the addition and multiplication
+procedures in the above examples are the values of the variables
+@code{+} and @code{*}. New procedures are created by evaluating
+@code{lambda} expressions.
+
+@cindex syntactic keyword
+If the @var{operator} is a syntactic keyword, then the expression is not
+treated as a procedure call: it is a special form.
--- /dev/null
+@c This file is part of the MIT/GNU Scheme Reference Manual.
+@c $Id: procedures.texi,v 1.1 2003/04/15 03:30:08 cph Exp $
+
+@c Copyright 1991,1992,1993,1994,1995 Massachusetts Institute of Technology
+@c Copyright 1996,1997,1999,2000,2001 Massachusetts Institute of Technology
+@c Copyright 2002,2003 Massachusetts Institute of Technology
+@c See file scheme.texinfo for copying conditions.
+
+@node Procedures, Environments, Associations, Top
+@chapter Procedures
+
+@cindex procedure
+@cindex primitive procedure (defn)
+@cindex built-in procedure
+@findex lambda
+@cindex application hook (defn)
+@cindex hook, application (defn)
+Procedures are created by evaluating @code{lambda} expressions
+(@pxref{Lambda Expressions}); the @code{lambda} may either be explicit
+or may be implicit as in a ``procedure @code{define}''
+(@pxref{Definitions}). Also there are special built-in procedures,
+called @dfn{primitive procedures}, such as @code{car}; these procedures
+are not written in Scheme but in the language used to implement the
+Scheme system. MIT/GNU Scheme also provides @dfn{application hooks}, which
+support the construction of data structures that act like procedures.
+
+@cindex procedure, type
+@cindex procedure, primitive
+@cindex procedure, interpreted
+@cindex procedure, compiled
+@cindex type, of procedure
+@cindex primitive, procedure type
+@cindex interpreted, procedure type
+@cindex compiled, procedure type
+@cindex external representation, for procedure
+In MIT/GNU Scheme, the written representation of a procedure tells you
+the type of the procedure (compiled, interpreted, or primitive):
+
+@example
+@group
+pp
+ @result{} #[compiled-procedure 56 ("pp" #x2) #x10 #x307578]
+(lambda (x) x)
+ @result{} #[compound-procedure 57]
+(define (foo x) x)
+foo
+ @result{} #[compound-procedure 58 foo]
+car
+ @result{} #[primitive-procedure car]
+(call-with-current-continuation (lambda (x) x))
+ @result{} #[continuation 59]
+@end group
+@end example
+
+@noindent
+@cindex compound procedure
+@cindex procedure, compound
+Note that interpreted procedures are called ``compound'' procedures
+(strictly speaking, compiled procedures are also compound procedures).
+The written representation makes this distinction for historical
+reasons, and may eventually change.
+
+@menu
+* Procedure Operations::
+* Primitive Procedures::
+* Continuations::
+* Application Hooks::
+@end menu
+
+@node Procedure Operations, Primitive Procedures, Procedures, Procedures
+@section Procedure Operations
+
+@deffn procedure apply procedure object object @dots{}
+@cindex application, of procedure
+Calls @var{procedure} with the elements of the following list as
+arguments:
+
+@example
+(cons* @var{object} @var{object} @dots{})
+@end example
+
+@noindent
+The initial @var{object}s may be any objects, but the last @var{object}
+(there must be at least one @var{object}) must be a list.
+
+@example
+@group
+(apply + (list 3 4 5 6)) @result{} 18
+(apply + 3 4 '(5 6)) @result{} 18
+
+(define compose
+ (lambda (f g)
+ (lambda args
+ (f (apply g args)))))
+((compose sqrt *) 12 75) @result{} 30
+@end group
+@end example
+@end deffn
+
+@deffn procedure procedure? object
+@cindex type predicate, for procedure
+Returns @code{#t} if @var{object} is a procedure; otherwise returns
+@code{#f}. If @code{#t} is returned, exactly one of the following
+predicates is satisfied by @var{object}: @code{compiled-procedure?},
+@code{compound-procedure?}, or @code{primitive-procedure?}.
+@end deffn
+
+@deffn procedure compiled-procedure? object
+@cindex type predicate, for compiled procedure
+Returns @code{#t} if @var{object} is a compiled procedure; otherwise
+returns @code{#f}.
+@end deffn
+
+@deffn procedure compound-procedure? object
+@cindex type predicate, for compound procedure
+Returns @code{#t} if @var{object} is a compound (i.e.@: interpreted)
+procedure; otherwise returns @code{#f}.
+@end deffn
+
+@deffn procedure primitive-procedure? object
+@cindex type predicate, for primitive procedure
+Returns @code{#t} if @var{object} is a primitive procedure; otherwise
+returns @code{#f}.
+@end deffn
+
+The following two procedures test the @dfn{arity} of a procedure, that
+is, the number of arguments that the procedure accepts. The results of
+the test may be less restrictive than the effect of calling the
+procedure. In other words, these procedures may indicate that the
+procedure will accept a given number of arguments, but if you call the
+procedure it may signal a
+@code{condition-type:wrong-number-of-arguments} error. This is because
+these procedures examine the apparent arity of a procedure. For
+example, here is a procedure that appears to accept any number of
+arguments, but when called will signal an error if the number of
+arguments is not one:
+@findex condition-type:wrong-number-of-arguments
+
+@example
+(lambda arguments (apply car arguments))
+@end example
+
+@deffn procedure procedure-arity-valid? procedure k
+Returns @code{#t} if @var{procedure} accepts @var{k} arguments;
+otherwise returns @code{#f}.
+@end deffn
+
+@deffn procedure procedure-arity procedure
+Returns a description of the number of arguments that @var{procedure}
+accepts. The result is a newly allocated pair whose car field is the
+minimum number of arguments, and whose cdr field is the maximum
+number of arguments. The minimum is an exact non-negative integer. The
+maximum is either an exact non-negative integer, or @code{#f} meaning
+that the procedure has no maximum number of arguments.
+
+@example
+@group
+(procedure-arity (lambda () 3)) @result{} (0 . 0)
+(procedure-arity (lambda (x) x)) @result{} (1 . 1)
+(procedure-arity car) @result{} (1 . 1)
+(procedure-arity (lambda x x)) @result{} (0 . #f)
+(procedure-arity (lambda (x . y) x)) @result{} (1 . #f)
+(procedure-arity (lambda (x #!optional y) x))
+ @result{} (1 . 2)
+@end group
+@end example
+@end deffn
+
+@deffn procedure procedure-environment procedure
+Returns the closing environment of @var{procedure}. Signals an error if
+@var{procedure} is a primitive procedure, or if @var{procedure} is a
+compiled procedure for which the debugging information is unavailable.
+@end deffn
+
+@node Primitive Procedures, Continuations, Procedure Operations, Procedures
+@section Primitive Procedures
+
+@deffn procedure make-primitive-procedure name [arity]
+@var{Name} must be a symbol. @var{Arity} must be an exact non-negative
+integer, @code{-1}, @code{#f}, or @code{#t}; if not supplied it defaults
+to @code{#f}. Returns the primitive procedure called @var{name}. May
+perform further actions depending on @var{arity}:
+
+@table @asis
+@item @code{#f}
+If the primitive procedure is not implemented, signals an error.
+
+@item @code{#t}
+If the primitive procedure is not implemented, returns @code{#f}.
+
+@item integer
+If the primitive procedure is implemented, signals an error if its arity
+is not equal to @var{arity}. If the primitive procedure is not
+implemented, returns an unimplemented primitive procedure object that
+accepts @var{arity} arguments. An @var{arity} of @code{-1} means it
+accepts any number of arguments.
+@end table
+@end deffn
+
+@deffn procedure primitive-procedure-name primitive-procedure
+Returns the name of @var{primitive-procedure}, a symbol.
+
+@example
+(primitive-procedure-name car) @result{} car
+@end example
+@end deffn
+
+@deffn procedure implemented-primitive-procedure? primitive-procedure
+Returns @code{#t} if @var{primitive-procedure} is implemented; otherwise
+returns @code{#f}. Useful because the code that implements a particular
+primitive procedure is not necessarily linked into the executable Scheme
+program.
+@end deffn
+
+@node Continuations, Application Hooks, Primitive Procedures, Procedures
+@section Continuations
+
+@deffn procedure call-with-current-continuation procedure
+@cindex continuation
+@cindex construction, of continuation
+@cindex procedure, escape (defn)
+@cindex escape procedure (defn)
+@var{Procedure} must be a procedure of one argument. Packages up the
+current continuation (see below) as an @dfn{escape procedure} and passes
+it as an argument to @var{procedure}. The escape procedure is a Scheme
+procedure of one argument that, if it is later passed a value, will
+ignore whatever continuation is in effect at that later time and will
+give the value instead to the continuation that was in effect when the
+escape procedure was created. The escape procedure created by
+@code{call-with-current-continuation} has unlimited extent just like any
+other procedure in Scheme. It may be stored in variables or data
+structures and may be called as many times as desired.
+
+The following examples show only the most common uses of this procedure.
+If all real programs were as simple as these examples, there would be no
+need for a procedure with the power of
+@code{call-with-current-continuation}.
+
+@example
+@group
+(call-with-current-continuation
+ (lambda (exit)
+ (for-each (lambda (x)
+ (if (negative? x)
+ (exit x)))
+ '(54 0 37 -3 245 19))
+ #t)) @result{} -3
+@end group
+
+@group
+(define list-length
+ (lambda (obj)
+ (call-with-current-continuation
+ (lambda (return)
+ (letrec ((r
+ (lambda (obj)
+ (cond ((null? obj) 0)
+ ((pair? obj) (+ (r (cdr obj)) 1))
+ (else (return #f))))))
+ (r obj))))))
+(list-length '(1 2 3 4)) @result{} 4
+(list-length '(a b . c)) @result{} #f
+@end group
+@end example
+
+@cindex non-local exit
+@cindex exit, non-local
+A common use of @code{call-with-current-continuation} is for structured,
+non-local exits from loops or procedure bodies, but in fact
+@code{call-with-current-continuation} is quite useful for implementing a
+wide variety of advanced control structures.
+
+Whenever a Scheme expression is evaluated a continuation exists that
+wants the result of the expression. The continuation represents an
+entire (default) future for the computation. If the expression is
+evaluated at top level, for example, the continuation will take the
+result, print it on the screen, prompt for the next input, evaluate it,
+and so on forever. Most of the time the continuation includes actions
+specified by user code, as in a continuation that will take the result,
+multiply it by the value stored in a local variable, add seven, and give
+the answer to the top-level continuation to be printed. Normally these
+ubiquitous continuations are hidden behind the scenes and programmers
+don't think much about them. On the rare occasions that you may need to
+deal explicitly with continuations,
+@code{call-with-current-continuation} lets you do so by creating a
+procedure that acts just like the current continuation.
+@end deffn
+
+@deffn procedure continuation? object
+@cindex type predicate, for continuation
+Returns @code{#t} if @var{object} is a continuation; otherwise returns
+@code{#f}.
+@end deffn
+
+@deffn procedure within-continuation continuation thunk
+@cindex continuation, alternate invocation
+@cindex escape procedure, alternate invocation
+@var{Thunk} must be a procedure of no arguments. Conceptually,@*
+@code{within-continuation} invokes @var{continuation} on the result of
+invoking @var{thunk}, but @var{thunk} is executed in the dynamic context
+of @var{continuation}. In other words, the ``current'' continuation is
+abandoned before @var{thunk} is invoked.
+@end deffn
+
+@deffn procedure dynamic-wind before thunk after
+Calls @var{thunk} without arguments, returning the result(s) of this
+call. @var{Before} and @var{after} are called, also without arguments,
+as required by the following rules (note that in the absence of calls to
+continuations captured using @code{call-with-current-continuation} the
+three arguments are called once each, in order). @var{Before} is called
+whenever execution enters the dynamic extent of the call to @var{thunk}
+and @var{after} is called whenever it exits that dynamic extent. The
+dynamic extent of a procedure call is the period between when the call
+is initiated and when it returns. In Scheme, because of
+@code{call-with-current-continuation}, the dynamic extent of a call may
+not be a single, connected time period. It is defined as follows:
+
+@itemize @bullet
+@item
+The dynamic extent is entered when execution of the body of the called
+procedure begins.
+
+@item
+The dynamic extent is also entered when execution is not within the
+dynamic extent and a continuation is invoked that was captured (using
+@code{call-with-current-continuation}) during the dynamic extent.
+
+@item
+It is exited when the called procedure returns.
+
+@item
+It is also exited when execution is within the dynamic extent and a
+continuation is invoked that was captured while not within the dynamic
+extent.
+@end itemize
+
+If a second call to @code{dynamic-wind} occurs within the dynamic extent
+of the call to @var{thunk} and then a continuation is invoked in such a
+way that the @var{after}s from these two invocations of
+@code{dynamic-wind} are both to be called, then the @var{after}
+associated with the second (inner) call to @code{dynamic-wind} is called
+first.
+
+If a second call to @code{dynamic-wind} occurs within the dynamic extent
+of the call to @var{thunk} and then a continuation is invoked in such a
+way that the @var{before}s from these two invocations of
+@code{dynamic-wind} are both to be called, then the @var{before}
+associated with the first (outer) call to @code{dynamic-wind} is called
+first.
+
+If invoking a continuation requires calling the @var{before} from one
+call to @code{dynamic-wind} and the @var{after} from another, then the
+@var{after} is called first.
+
+The effect of using a captured continuation to enter or exit the dynamic
+extent of a call to @var{before} or @var{after} is undefined.
+
+@example
+@group
+(let ((path '())
+ (c #f))
+ (let ((add (lambda (s)
+ (set! path (cons s path)))))
+ (dynamic-wind
+ (lambda () (add 'connect))
+ (lambda ()
+ (add (call-with-current-continuation
+ (lambda (c0)
+ (set! c c0)
+ 'talk1))))
+ (lambda () (add 'disconnect)))
+ (if (< (length path) 4)
+ (c 'talk2)
+ (reverse path))))
+
+@result{} (connect talk1 disconnect connect talk2 disconnect)
+@end group
+@end example
+@end deffn
+
+The following two procedures support multiple values.
+
+@deffn procedure call-with-values thunk procedure
+@cindex multiple values, from procedure
+@cindex values, multiple
+@var{Thunk} must be a procedure of no arguments, and @var{procedure}
+must be a procedure. @var{Thunk} is invoked with a continuation that
+expects to receive multiple values; specifically, the continuation
+expects to receive the same number of values that @var{procedure}
+accepts as arguments. @var{Thunk} must return multiple values using the
+@code{values} procedure. Then @var{procedure} is called with the
+multiple values as its arguments. The result yielded by @var{procedure}
+is returned as the result of @code{call-with-values}.
+@end deffn
+
+@deffn procedure values object @dots{}
+Returns multiple values. The continuation in effect when this procedure
+is called must be a multiple-value continuation that was created by
+@code{call-with-values}. Furthermore it must accept as many values as
+there are @var{object}s.
+@end deffn
+
+@node Application Hooks, , Continuations, Procedures
+@section Application Hooks
+
+@cindex application hook (defn)
+@cindex procedure, of application hook
+@cindex extra object, of application hook
+@dfn{Application hooks} are objects that can be applied like procedures.
+Each application hook has two parts: a @dfn{procedure} that specifies
+what to do when the application hook is applied, and an arbitrary
+object, called @dfn{extra}. Often the procedure uses the extra object
+to determine what to do.
+
+@cindex apply hook (defn)
+@cindex entity (defn)
+There are two kinds of application hooks, which differ in what arguments
+are passed to the procedure. When an @dfn{apply hook} is applied, the
+procedure is passed exactly the same arguments that were passed to the
+apply hook. When an @dfn{entity} is applied, the entity itself is
+passed as the first argument, followed by the other arguments that were
+passed to the entity.
+
+Both apply hooks and entities satisfy the predicate @code{procedure?}.
+Each satisfies either @code{compiled-procedure?},
+@code{compound-procedure?}, or @code{primitive-procedure?}, depending on
+its procedure component. An apply hook is considered to accept the same
+number of arguments as its procedure, while an entity is considered to
+accept one less argument than its procedure.
+
+@deffn procedure make-apply-hook procedure object
+Returns a newly allocated apply hook with a procedure component of
+@var{procedure} and an extra component of @var{object}.
+@end deffn
+
+@deffn procedure apply-hook? object
+@cindex type predicate, for apply hook
+Returns @code{#t} if @var{object} is an apply hook; otherwise returns
+@code{#f}.
+@end deffn
+
+@deffn procedure apply-hook-procedure apply-hook
+Returns the procedure component of @var{apply-hook}.
+@end deffn
+
+@deffn procedure set-apply-hook-procedure! apply-hook procedure
+Changes the procedure component of @var{apply-hook} to be
+@var{procedure}. Returns an unspecified value.
+@end deffn
+
+@deffn procedure apply-hook-extra apply-hook
+Returns the extra component of @var{apply-hook}.
+@end deffn
+
+@deffn procedure set-apply-hook-extra! apply-hook object
+Changes the extra component of @var{apply-hook} to be @var{object}.
+Returns an unspecified value.
+@end deffn
+
+@deffn procedure make-entity procedure object
+Returns a newly allocated entity with a procedure component of
+@var{procedure} and an extra component of @var{object}.
+@end deffn
+
+@deffn procedure entity? object
+@cindex type predicate, for entity
+Returns @code{#t} if @var{object} is an entity; otherwise returns
+@code{#f}.
+@end deffn
+
+@deffn procedure entity-procedure entity
+Returns the procedure component of @var{entity}.
+@end deffn
+
+@deffn procedure set-entity-procedure! entity procedure
+Changes the procedure component of @var{entity} to be @var{procedure}.
+Returns an unspecified value.
+@end deffn
+
+@deffn procedure entity-extra entity
+Returns the extra component of @var{entity}.
+@end deffn
+
+@deffn procedure set-entity-extra! entity object
+Changes the extra component of @var{entity} to be @var{object}. Returns
+an unspecified value.
+@end deffn
@iftex
@finalout
@end iftex
-@comment $Id: scheme.texinfo,v 1.122 2003/03/08 02:10:44 cph Exp $
+@comment $Id: scheme.texinfo,v 1.123 2003/04/15 03:30:11 cph Exp $
@comment %**start of header (This is for running Texinfo on a region.)
@setfilename scheme.info
@settitle MIT/GNU Scheme Reference
@ifinfo
This file documents the MIT/GNU Scheme system.
-Copyright @copyright{} 1988-2002 Massachusetts Institute of Technology
+Copyright @copyright{} 1991,1992,1993,1994,1995 Massachusetts Institute of Technology
+Copyright @copyright{} 1996,1997,1999,2000,2001 Massachusetts Institute of Technology
+Copyright @copyright{} 2002,2003 Massachusetts Institute of Technology
Permission is granted to copy, distribute and/or modify this document
under the terms of the GNU Free Documentation License, Version 1.2 or
@titlepage
@title{MIT/GNU Scheme Reference Manual}
-@subtitle Edition 1.98
-@subtitle for Scheme Release 7.7.2
-@subtitle 7 March 2003
+@subtitle Edition 1.99
+@subtitle for Scheme Release 7.8.0
+@subtitle 14 April 2003
@author by Chris Hanson
@author the MIT Scheme Team
@author and a cast of thousands
@page
@vskip 0pt plus 1filll
-Copyright @copyright{} 1988-2002 Massachusetts Institute of Technology
+Copyright @copyright{} 1991,1992,1993,1994,1995 Massachusetts Institute of Technology
+Copyright @copyright{} 1996,1997,1999,2000,2001 Massachusetts Institute of Technology
+Copyright @copyright{} 2002,2003 Massachusetts Institute of Technology
Permission is granted to copy, distribute and/or modify this document
under the terms of the GNU Free Documentation License, Version 1.2 or
provided in part by the Advanced Research Projects Agency of the
Department of Defense and by the National Science Foundation.
-@node Overview, Special Forms, Acknowledgements, Top
-@chapter Overview
-
-@cindex runtime system
-This manual is a detailed description of the MIT/GNU Scheme runtime system.
-It is intended to be a reference document for programmers. It does not
-describe how to run Scheme or how to interact with it --- that is the
-subject of the @cite{MIT/GNU Scheme User's Manual}.
-
-This chapter summarizes the semantics of Scheme, briefly describes the
-MIT/GNU Scheme programming environment, and explains the syntactic and
-lexical conventions of the language. Subsequent chapters describe
-special forms, numerous data abstractions, and facilities for input and
-output.
-
-@cindex standard Scheme (defn)
-@cindex Scheme standard
-@cindex R4RS
-Throughout this manual, we will make frequent references to
-@dfn{standard Scheme}, which is the language defined by the document
-@cite{Revised^4 Report on the Algorithmic Language Scheme}, by William
-Clinger, Jonathan Rees, et al.@:, or by @sc{ieee} Std.@: 1178-1990,
-@cite{IEEE Standard for the Scheme Programming Language} (in fact,
-several parts of this document are copied from the @cite{Revised
-Report}). MIT/GNU Scheme is an extension of standard Scheme.
-
-These are the significant semantic characteristics of the Scheme
-language:
-
-@table @asis
-@item Variables are statically scoped
-@cindex static scoping (defn)
-@cindex scope (see region)
-Scheme is a @dfn{statically scoped} programming language, which means that
-each use of a variable is associated with a lexically apparent binding
-of that variable. Algol is another statically scoped language.
-
-@item Types are latent
-@cindex latent types (defn)
-@cindex manifest types (defn)
-@cindex weak types (defn)
-@cindex strong types (defn)
-@cindex dynamic types (defn)
-@cindex static types (defn)
-@cindex types, latent (defn)
-@cindex types, manifest (defn)
-Scheme has @dfn{latent} types as opposed to @dfn{manifest} types, which
-means that Scheme associates types with values (or objects) rather than
-with variables. Other languages with latent types (also referred to as
-@dfn{weakly} typed or @dfn{dynamically} typed languages) include APL,
-Snobol, and other dialects of Lisp. Languages with manifest types
-(sometimes referred to as @dfn{strongly} typed or @dfn{statically} typed
-languages) include Algol 60, Pascal, and C.
-
-@item Objects have unlimited extent
-@cindex extent, of objects
-All objects created during a Scheme computation, including procedures
-and continuations, have unlimited extent; no Scheme object is ever
-destroyed. The system doesn't run out of memory because the garbage
-collector reclaims the storage occupied by an object when the object
-cannot possibly be needed by a future computation. Other languages in
-which most objects have unlimited extent include APL and other Lisp
-dialects.
-
-@item Proper tail recursion
-@cindex proper tail recursion (defn)
-@cindex tail recursion (defn)
-@cindex recursion (see tail recursion)
-Scheme is @dfn{properly tail-recursive}, which means that iterative
-computation can occur in constant space, even if the iterative
-computation is described by a syntactically recursive procedure. With a
-tail-recursive implementation, you can express iteration using the
-ordinary procedure-call mechanics; special iteration expressions are
-provided only for syntactic convenience.
-
-@item Procedures are objects
-Scheme procedures are objects, which means that you can create them
-dynamically, store them in data structures, return them as the results
-of other procedures, and so on. Other languages with such procedure
-objects include Common Lisp and ML.
-
-@item Continuations are explicit
-In most other languages, continuations operate behind the scenes. In
-Scheme, continuations are objects; you can use continuations for
-implementing a variety of advanced control constructs, including
-non-local exits, backtracking, and coroutines.
-
-@item Arguments are passed by value
-Arguments to Scheme procedures are passed by value, which means that
-Scheme evaluates the argument expressions before the procedure gains
-control, whether or not the procedure needs the result of the
-evaluations. ML, C, and APL are three other languages that pass
-arguments by value. In languages such as SASL and Algol 60, argument
-expressions are not evaluated unless the values are needed by the
-procedure.
-@end table
-
-@findex read
-Scheme uses a parenthesized-list Polish notation to describe programs
-and (other) data. The syntax of Scheme, like that of most Lisp
-dialects, provides for great expressive power, largely due to its
-simplicity. An important consequence of this simplicity is the
-susceptibility of Scheme programs and data to uniform treatment by other
-Scheme programs. As with other Lisp dialects, the @code{read} primitive
-parses its input; that is, it performs syntactic as well as lexical
-decomposition of what it reads.
-
-@menu
-* Notational Conventions::
-* Scheme Concepts::
-* Lexical Conventions::
-* Expressions::
-@end menu
-
-@node Notational Conventions, Scheme Concepts, Overview, Overview
-@section Notational Conventions
-@cindex notational conventions
-@cindex conventions, notational
-
-This section details the notational conventions used throughout the rest
-of this document.
-
-@menu
-* Errors::
-* Examples::
-* Entry Format::
-@end menu
-
-@node Errors, Examples, Notational Conventions, Notational Conventions
-@subsection Errors
-@cindex errors, notational conventions
-
-@cindex signal an error (defn)
-@cindex must be, notational convention
-@findex error
-When this manual uses the phrase ``an error will be signalled,'' it
-means that Scheme will call @code{error}, which normally halts execution
-of the program and prints an error message.
-
-When this manual uses the phrase ``it is an error,'' it means that the
-specified action is not valid in Scheme, but the system may or may not
-signal the error. When this manual says that something ``must be,'' it
-means that violating the requirement is an error.
-
-@node Examples, Entry Format, Errors, Notational Conventions
-@subsection Examples
-@cindex examples
-
-@cindex => notational convention
-@cindex result of evaluation, in examples
-@cindex evaluation, in examples
-@cindex specified result, in examples
-This manual gives many examples showing the evaluation of expressions.
-The examples have a common format that shows the expression being
-evaluated on the left hand side, an ``arrow'' in the middle, and the
-value of the expression written on the right. For example:
-
-@example
-(+ 1 2) @result{} 3
-@end example
-
-Sometimes the arrow and value will be moved under the expression, due to
-lack of space. Occasionally we will not care what the value is, in
-which case both the arrow and the value are omitted.
-
-@cindex error--> notational convention
-@cindex error, in examples
-If an example shows an evaluation that results in an error, an error
-message is shown, prefaced by @samp{@error{}}:
-
-@example
-(+ 1 'foo) @error{} Illegal datum
-@end example
-
-@cindex -| notational convention
-@cindex printed output, in examples
-An example that shows printed output marks it with @samp{@print{}}:
-
-@example
-@group
-(begin (write 'foo) 'bar)
- @print{} foo
- @result{} bar
-@end group
-@end example
-
-@cindex unspecified result (defn)
-@cindex result, unspecified (defn)
-When this manual indicates that the value returned by some expression is
-@dfn{unspecified}, it means that the expression will evaluate to some
-object without signalling an error, but that programs should not depend
-on the value in any way.
-
-@node Entry Format, , Examples, Notational Conventions
-@subsection Entry Format
-@cindex entry format
-@cindex format, entry
-
-Each description of an MIT/GNU Scheme variable, special form, or
-procedure begins with one or more header lines in this format:
-
-@deffn @var{category} @var{template}
-@end deffn
-
-@noindent
-where @var{category} specifies the kind of item (``variable'',
-``special form'', or ``procedure''). The form of @var{template} is
-interpreted depending on @var{category}.
-
-@table @asis
-@item Variable
-@var{Template} consists of the variable's name.
-@cindex variable, entry category
-
-@item Special Form
-@var{Template} starts with the syntactic keyword of the special form,
-followed by a description of the special form's syntax. The description
-is written using the following conventions.
-@cindex special form, entry category
-
-@findex else
-@findex cond
-Named components are italicized in the printed manual, and uppercase in
-the Info file. ``Noise'' keywords, such as the @code{else} keyword in
-the @code{cond} special form, are set in a fixed width font in the
-printed manual; in the Info file they are not distinguished.
-Parentheses indicate themselves.
-
-@cindex ellipsis, in entries
-@cindex ... in entries
-A horizontal ellipsis (@dots{}) is describes repeated components.
-Specifically,
-
-@display
-@var{thing} @dots{}
-@end display
-
-@noindent
-indicates @emph{zero} or more occurrences of @var{thing}, while
-
-@display
-@var{thing} @var{thing} @dots{}
-@end display
-
-@noindent
-indicates @emph{one} or more occurrences of @var{thing}.
-
-@cindex bracket, in entries
-@cindex [ in entries
-@cindex ] in entries
-@cindex optional component, in entries
-Brackets, @code{[ ]}, enclose optional components.
-
-@cindex body, of special form (defn)
-@findex lambda
-Several special forms (e.g.@: @code{lambda}) have an internal component
-consisting of a series of expressions; usually these expressions are
-evaluated sequentially under conditions that are specified in the
-description of the special form. This sequence of expressions is commonly
-referred to as the @dfn{body} of the special form.
-
-@item Procedure
-@var{Template} starts with the name of the variable to which the
-procedure is bound, followed by a description of the procedure's
-arguments. The arguments are described using ``lambda list'' notation
-(@pxref{Lambda Expressions}), except that brackets are used to denote
-optional arguments, and ellipses are used to denote ``rest'' arguments.
-@cindex procedure, entry format
-
-The names of the procedure's arguments are italicized in the printed
-manual, and uppercase in the Info file.
-
-When an argument names a Scheme data type, it indicates that the
-argument must be that type of data object. For example,
-
-@deffn procedure cdr pair
-@end deffn
-
-@noindent
-indicates that the standard Scheme procedure @code{cdr} takes one argument,
-which must be a pair.
-
-Many procedures signal an error when an argument is of the wrong type;
-usually this error is a condition of type
-@code{condition-type:wrong-type-argument}.
-@findex condition-type:wrong-type-argument
-
-In addition to the standard data-type names (@var{pair}, @var{list},
-@var{boolean}, @var{string}, etc.), the following names as arguments
-also imply type restrictions:
-
-@itemize @bullet
-@item
-@var{object}: any object
-@item
-@var{thunk}: a procedure of no arguments
-@item
-@var{x}, @var{y}: real numbers
-@item
-@var{q}, @var{n}: integers
-@item
-@var{k}: an exact non-negative integer
-@end itemize
-@end table
-
-Some examples:
-
-@deffn procedure list object @dots{}
-@end deffn
-
-@noindent
-indicates that the standard Scheme procedure @code{list} takes zero or
-more arguments, each of which may be any Scheme object.
-
-@deffn procedure write-char char [output-port]
-@end deffn
-
-@noindent
-indicates that the standard Scheme procedure @code{write-char} must be
-called with a character, @var{char}, and may also be called with a
-character and an output port.
-
-@node Scheme Concepts, Lexical Conventions, Notational Conventions, Overview
-@section Scheme Concepts
-@cindex scheme concepts
-
-@menu
-* Variable Bindings::
-* Environment Concepts::
-* Initial and Current Environments::
-* Static Scoping::
-* True and False::
-* External Representations::
-* Disjointness of Types::
-* Storage Model::
-@end menu
-
-@node Variable Bindings, Environment Concepts, Scheme Concepts, Scheme Concepts
-@subsection Variable Bindings
-@cindex variable binding
-@cindex binding, of variable
-
-@cindex bound variable (defn)
-@cindex value, of variable (defn)
-@cindex name, of value (defn)
-@cindex location, of variable
-Any identifier that is not a syntactic keyword may be used as a variable
-(@pxref{Identifiers}). A variable may name a location where a value can
-be stored. A variable that does so is said to be @dfn{bound} to the
-location. The value stored in the location to which a variable is bound
-is called the variable's @dfn{value}. (The variable is sometimes said
-to @dfn{name} the value or to be @dfn{bound to} the value.)
-
-@cindex unassigned variable (defn)
-@cindex error, unassigned variable
-A variable may be bound but still not have a value; such a variable is
-said to be @dfn{unassigned}. Referencing an unassigned variable is an
-error. When this error is signalled, it is a condition of type
-@code{condition-type:unassigned-variable}; sometimes the compiler does
-not generate code to signal the error. Unassigned variables are useful
-only in combination with side effects (@pxref{Assignments}).
-@findex condition-type:unassigned-variable
-
-@node Environment Concepts, Initial and Current Environments, Variable Bindings, Scheme Concepts
-@subsection Environment Concepts
-
-@cindex environment (defn)
-@cindex unbound variable (defn)
-@cindex error, unbound variable (defn)
-An @dfn{environment} is a set of variable bindings. If an environment
-has no binding for a variable, that variable is said to be @dfn{unbound}
-in that environment. Referencing an unbound variable signals a
-condition of type @code{condition-type:unbound-variable}.
-@findex condition-type:unbound-variable
-
-@cindex extension, of environment (defn)
-@cindex environment, extension (defn)
-@cindex shadowing, of variable binding (defn)
-@cindex parent, of environment (defn)
-@cindex child, of environment (defn)
-@cindex inheritance, of environment bindings (defn)
-A new environment can be created by @dfn{extending} an existing
-environment with a set of new bindings. Note that ``extending an
-environment'' does @strong{not} modify the environment; rather, it
-creates a new environment that contains the new bindings and the old
-ones. The new bindings @dfn{shadow} the old ones; that is, if an
-environment that contains a binding for @code{x} is extended with a new
-binding for @code{x}, then only the new binding is seen when @code{x} is
-looked up in the extended environment. Sometimes we say that the
-original environment is the @dfn{parent} of the new one, or that the new
-environment is a @dfn{child} of the old one, or that the new environment
-@dfn{inherits} the bindings in the old one.
-
-@findex let
-@findex let*
-@findex letrec
-@findex do
-@findex define
-Procedure calls extend an environment, as do @code{let}, @code{let*},
-@code{letrec}, and @code{do} expressions. Internal definitions
-(@pxref{Internal Definitions}) also extend an environment. (Actually,
-all the constructs that extend environments can be expressed in terms of
-procedure calls, so there is really just one fundamental mechanism for
-environment extension.) A top-level definition (@pxref{Top-Level
-Definitions}) may add a binding to an existing environment.
-
-@node Initial and Current Environments, Static Scoping, Environment Concepts, Scheme Concepts
-@subsection Initial and Current Environments
-
-@cindex initial environment (defn)
-@cindex environment, initial (defn)
-MIT/GNU Scheme provides an @dfn{initial environment} that contains all
-of the variable bindings described in this manual. Most environments
-are ultimately extensions of this initial environment. In Scheme, the
-environment in which your programs execute is actually a child
-(extension) of the environment containing the system's bindings. Thus,
-system names are visible to your programs, but your names do not
-interfere with system programs.
-
-@cindex current environment (defn)
-@cindex environment, current (defn)
-@cindex REP loop (defn)
-@cindex REP loop, environment of
-@findex user-initial-environment
-@findex ge
-The environment in effect at some point in a program is called the
-@dfn{current environment} at that point. In particular, every
-@acronym{REP} loop has a current environment. (@acronym{REP} stands for
-``read-eval-print''; the @acronym{REP} loop is the Scheme program that
-reads your input, evaluates it, and prints the result.) The environment
-of the top-level @acronym{REP} loop (the one you are in when Scheme
-starts up) starts as @code{user-initial-environment}, although it can be
-changed by the @code{ge} procedure. When a new @acronym{REP} loop is
-created, its environment is determined by the program that creates it.
-
-@node Static Scoping, True and False, Initial and Current Environments, Scheme Concepts
-@subsection Static Scoping
-@cindex scoping, static
-@cindex static scoping
-
-@cindex dynamic binding, versus static scoping
-Scheme is a statically scoped language with block structure. In this
-respect, it is like Algol and Pascal, and unlike most other dialects of
-Lisp except for Common Lisp.
-
-@cindex binding expression (defn)
-@cindex expression, binding (defn)
-The fact that Scheme is statically scoped (rather than
-dynamically bound) means that the environment that is extended (and
-becomes current) when a procedure is called is the environment in which
-the procedure was created (i.e.@: in which the procedure's defining
-lambda expression was evaluated), not the environment in which the
-procedure is called. Because all the other Scheme @dfn{binding
-expressions} can be expressed in terms of procedures, this determines
-how all bindings behave.
-
-Consider the following definitions, made at the top-level @acronym{REP}
-loop (in the initial environment):
-
-@example
-@group
-(define x 1)
-(define (f x) (g 2))
-(define (g y) (+ x y))
-(f 5) @result{} 3 @r{; not} 7
-@end group
-@end example
-
-Here @code{f} and @code{g} are bound to procedures created in the
-initial environment. Because Scheme is statically scoped, the call to
-@code{g} from @code{f} extends the initial environment (the one in which
-@code{g} was created) with a binding of @code{y} to @code{2}. In this
-extended environment, @code{y} is @code{2} and @code{x} is @code{1}.
-(In a dynamically bound Lisp, the call to @code{g} would extend the
-environment in effect during the call to @code{f}, in which @code{x} is
-bound to @code{5} by the call to @code{f}, and the answer would be
-@code{7}.)
-
-@cindex lexical scoping (defn)
-@cindex scoping, lexical (defn)
-@cindex region, of variable binding (defn)
-@cindex variable, binding region (defn)
-@findex lambda
-Note that with static scoping, you can tell what binding a variable
-reference refers to just from looking at the text of the program; the
-referenced binding cannot depend on how the program is used. That is,
-the nesting of environments (their parent-child relationship)
-corresponds to the nesting of binding expressions in program text.
-(Because of this connection to the text of the program, static scoping
-is also called @dfn{lexical} scoping.) For each place where a variable
-is bound in a program there is a corresponding @dfn{region} of the
-program text within which the binding is effective. For example, the
-region of a binding established by a @code{lambda} expression is the
-entire body of the @code{lambda} expression. The documentation of each
-binding expression explains what the region of the bindings it makes is.
-A use of a variable (that is, a reference to or assignment of a
-variable) refers to the innermost binding of that variable whose region
-contains the variable use. If there is no such region, the use refers
-to the binding of the variable in the global environment (which is an
-ancestor of all other environments, and can be thought of as a region in
-which all your programs are contained).
-
-@node True and False, External Representations, Static Scoping, Scheme Concepts
-@subsection True and False
-
-@cindex boolean object
-@cindex true, boolean object
-@cindex false, boolean object
-@findex #t
-@findex #f
-In Scheme, the boolean values true and false are denoted by @code{#t}
-and @code{#f}. However, any Scheme value can be treated as a boolean
-for the purpose of a conditional test. This manual uses the word
-@dfn{true} to refer to any Scheme value that counts as true, and the
-word @dfn{false} to refer to any Scheme value that counts as false. In
-conditional tests, all values count as true except for @code{#f}, which
-counts as false (@pxref{Conditionals}).
-
-Implementation note: In MIT/GNU Scheme, @code{#f} and the empty list are the
-same object, and the printed representation of @code{#f} is always
-@samp{()}. As this contradicts the Scheme standard, MIT/GNU Scheme will be
-changed to make @code{#f} and the empty list different objects.
-
-@node External Representations, Disjointness of Types, True and False, Scheme Concepts
-@subsection External Representations
-
-@cindex external representation (defn)
-@cindex representation, external (defn)
-An important concept in Scheme is that of the
-@dfn{external representation} of an object as a sequence of characters.
-For example, an external representation of the integer 28 is the
-sequence of characters @samp{28}, and an external representation of a
-list consisting of the integers 8 and 13 is the sequence of characters
-@samp{(8 13)}.
-
-The external representation of an object is not necessarily unique. The
-integer 28 also has representations @samp{#e28.000} and @samp{#x1c}, and
-the list in the previous paragraph also has the representations @samp{(
-08 13 )} and @samp{(8 . (13 . ( )))}.
-
-Many objects have standard external representations, but some, such as
-procedures and circular data structures, do not have standard
-representations (although particular implementations may define
-representations for them).
-
-An external representation may be written in a program to obtain the
-corresponding object (@pxref{Quoting}).
-
-@findex read
-@findex write
-External representations can also be used for input and output. The
-procedure @code{read} parses external representations, and the procedure
-@code{write} generates them. Together, they provide an elegant and
-powerful input/output facility.
-
-Note that the sequence of characters @samp{(+ 2 6)} is @emph{not} an
-external representation of the integer 8, even though it @emph{is} an
-expression that evaluates to the integer 8; rather, it is an external
-representation of a three-element list, the elements of which are the
-symbol @code{+} and the integers @code{2} and @code{6}. Scheme's syntax
-has the property that any sequence of characters that is an expression
-is also the external representation of some object. This can lead to
-confusion, since it may not be obvious out of context whether a given
-sequence of characters is intended to denote data or program, but it is
-also a source of power, since it facilitates writing programs such as
-interpreters and compilers that treat programs as data or data as
-programs.
-
-@node Disjointness of Types, Storage Model, External Representations, Scheme Concepts
-@subsection Disjointness of Types
-
-Every object satisfies at most one of the following predicates (but see
-@ref{True and False}, for an exception):
-
-@example
-@group
-bit-string? environment? port? symbol?
-boolean? null? procedure? vector?
-cell? number? promise? weak-pair?
-char? pair? string?
-condition?
-@end group
-@end example
-
-@node Storage Model, , Disjointness of Types, Scheme Concepts
-@subsection Storage Model
-
-This section describes a model that can be used to understand Scheme's
-use of storage.
-
-@cindex location
-@findex string-set!
-Variables and objects such as pairs, vectors, and strings implicitly
-denote locations or sequences of locations. A string, for example,
-denotes as many locations as there are characters in the string. (These
-locations need not correspond to a full machine word.) A new value may
-be stored into one of these locations using the @code{string-set!}
-procedure, but the string continues to denote the same locations as
-before.
-
-@findex car
-@findex vector-ref
-@findex string-ref
-@findex eqv?
-An object fetched from a location, by a variable reference or by a
-procedure such as @code{car}, @code{vector-ref}, or @code{string-ref},
-is equivalent in the sense of @code{eqv?} to the object last stored in
-the location before the fetch.
-
-Every location is marked to show whether it is in use. No variable or
-object ever refers to a location that is not in use. Whenever this
-document speaks of storage being allocated for a variable or object,
-what is meant is that an appropriate number of locations are chosen from
-the set of locations that are not in use, and the chosen locations are
-marked to indicate that they are now in use before the variable or
-object is made to denote them.
-
-@cindex constant
-@cindex mutable
-@cindex immutable
-@findex symbol->string
-In many systems it is desirable for constants (i.e.@: the values of
-literal expressions) to reside in read-only memory. To express this, it
-is convenient to imagine that every object that denotes locations is
-associated with a flag telling whether that object is mutable or
-immutable. The constants and the strings returned by
-@code{symbol->string} are then the immutable objects, while all objects
-created by other procedures are mutable. It is an error to attempt to
-store a new value into a location that is denoted by an immutable
-object. Note that the MIT/GNU Scheme compiler takes advantage of this
-property to share constants, but that these constants are not immutable.
-Instead, two constants that are @code{equal?} may be @code{eq?} in
-compiled code.
-
-@node Lexical Conventions, Expressions, Scheme Concepts, Overview
-@section Lexical Conventions
-@cindex lexical conventions
-@cindex conventions, lexical
-
-This section describes Scheme's lexical conventions.
-
-@menu
-* Whitespace::
-* Delimiters::
-* Identifiers::
-* Uppercase and Lowercase::
-* Naming Conventions::
-* Comments::
-* Additional Notations::
-@end menu
-
-@node Whitespace, Delimiters, Lexical Conventions, Lexical Conventions
-@subsection Whitespace
-
-@cindex whitespace, in programs (defn)
-@cindex token, in programs (defn)
-@dfn{Whitespace} characters are spaces, newlines, tabs, and page breaks.
-Whitespace is used to improve the readability of your programs and to
-separate tokens from each other, when necessary. (A @dfn{token} is an
-indivisible lexical unit such as an identifier or number.) Whitespace
-is otherwise insignificant. Whitespace may occur between any two
-tokens, but not within a token. Whitespace may also occur inside a
-string, where it is significant.
-
-@node Delimiters, Identifiers, Whitespace, Lexical Conventions
-@subsection Delimiters
-
-@cindex delimiter, in programs (defn)
-All whitespace characters are @dfn{delimiters}. In addition, the
-following characters act as delimiters:
-
-@example
-( ) ; " ' ` |
-@end example
-
-Finally, these next characters act as delimiters, despite the fact that
-Scheme does not define any special meaning for them:
-
-@example
-[ ] @{ @}
-@end example
-
-For example, if the value of the variable @code{name} is
-@code{"max"}:
-
-@example
-(list"Hi"name(+ 1 2)) @result{} ("Hi" "max" 3)
-@end example
-
-@node Identifiers, Uppercase and Lowercase, Delimiters, Lexical Conventions
-@subsection Identifiers
-
-@cindex identifier (defn)
-An @dfn{identifier} is a sequence of one or more non-delimiter
-characters. Identifiers are used in several ways in Scheme
-programs:
-
-@itemize @bullet
-@item
-An identifier can be used as a variable or as a syntactic keyword.
-@cindex variable, identifier as
-@cindex syntactic keyword, identifier as
-
-@item
-When an identifier appears as a literal or within a literal, it denotes
-a symbol.
-@cindex literal, identifier as
-@end itemize
-
-Scheme accepts most of the identifiers that other programming languages
-allow. MIT/GNU Scheme allows all of the identifiers that standard
-Scheme does, plus many more.
-
-MIT/GNU Scheme defines a potential identifier to be a sequence of
-non-delimiter characters that does not begin with either of the
-characters @samp{#} or @samp{,}. Any such sequence of characters that
-is not a syntactically valid number (@pxref{Numbers}) is considered to
-be a valid identifier. Note that, although it is legal for @samp{#} and
-@samp{,} to appear in an identifier (other than in the first character
-position), it is poor programming practice.
-
-Here are some examples of identifiers:
-
-@example
-@group
-lambda q
-list->vector soup
-+ V17a
-<=? a34kTMNs
-the-word-recursion-has-many-meanings
-@end group
-@end example
-
-@node Uppercase and Lowercase, Naming Conventions, Identifiers, Lexical Conventions
-@subsection Uppercase and Lowercase
-@cindex uppercase
-@cindex lowercase
-
-@cindex alphabetic case-insensitivity of programs (defn)
-@cindex case-insensitivity of programs (defn)
-@cindex sensitivity, to case in programs (defn)
-@cindex insensitivity, to case in programs (defn)
-Scheme doesn't distinguish uppercase and lowercase forms of a letter
-except within character and string constants; in other words, Scheme is
-@dfn{case-insensitive}. For example, @samp{Foo} is the same identifier
-as @samp{FOO}, and @samp{#x1AB} is the same number as @samp{#X1ab}. But
-@samp{#\a} and @samp{#\A} are different characters.
-
-@node Naming Conventions, Comments, Uppercase and Lowercase, Lexical Conventions
-@subsection Naming Conventions
-@cindex naming conventions
-@cindex conventions, naming
-
-@cindex predicate (defn)
-@cindex ? in predicate names
-A @dfn{predicate} is a procedure that always returns a boolean value
-(@code{#t} or @code{#f}). By convention, predicates usually have names
-that end in @samp{?}.
-
-@cindex mutation procedure (defn)
-@cindex ! in mutation procedure names
-A @dfn{mutation procedure} is a procedure that alters a data structure.
-By convention, mutation procedures usually have names that end in
-@samp{!}.
-
-@node Comments, Additional Notations, Naming Conventions, Lexical Conventions
-@subsection Comments
-
-@cindex comment, in programs (defn)
-@cindex semicolon, as external representation
-@cindex ; as external representation
-The beginning of a comment is indicated with a semicolon (@code{;}).
-Scheme ignores everything on a line in which a semicolon appears, from
-the semicolon until the end of the line. The entire comment, including
-the newline character that terminates it, is treated as
-whitespace.
-
-@cindex extended comment, in programs (defn)
-@cindex comment, extended, in programs (defn)
-@cindex #| as external representation
-An alternative form of comment (sometimes called an @dfn{extended
-comment}) begins with the characters @samp{#|} and ends with the
-characters @samp{|#}. This alternative form is an MIT/GNU Scheme extension.
-As with ordinary comments, all of the characters in an extended comment,
-including the leading @samp{#|} and trailing @samp{|#}, are treated as
-whitespace. Comments of this form may extend over multiple lines, and
-additionally may be nested (unlike the comments of the programming
-language C, which have a similar syntax).
-
-@example
-@group
-;;; This is a comment about the FACT procedure. Scheme
-;;; ignores all of this comment. The FACT procedure computes
-;;; the factorial of a non-negative integer.
-@end group
-
-@group
-#|
-This is an extended comment.
-Such comments are useful for commenting out code fragments.
-|#
-@end group
-
-@group
-(define fact
- (lambda (n)
- (if (= n 0) ;This is another comment:
- 1 ;Base case: return 1
- (* n (fact (- n 1))))))
-@end group
-@end example
-
-@node Additional Notations, , Comments, Lexical Conventions
-@subsection Additional Notations
-
-@cindex characters, special, in programs
-@cindex special characters, in programs
-The following list describes additional notations used in Scheme.
-@xref{Numbers}, for a description of the notations used for numbers.
-
-@table @code
-@item + - .
-The plus sign, minus sign, and period are used in numbers, and may also
-occur in an identifier. A delimited period (not occurring within a
-number or identifier) is used in the notation for pairs and to indicate
-a ``rest'' parameter in a formal parameter list
-(@pxref{Lambda Expressions}).
-
-@item ( )
-Parentheses are used for grouping and to notate lists (@pxref{Lists}).
-
-@item "
-The double quote delimits strings (@pxref{Strings}).
-
-@item \
-The backslash is used in the syntax for character constants
-(@pxref{Characters}) and as an escape character within string constants
-(@pxref{Strings}).
-
-@item ;
-The semicolon starts a comment.
-
-@item '
-The single quote indicates literal data; it suppresses evaluation
-(@pxref{Quoting}).
-
-@item `
-The backquote indicates almost-constant data (@pxref{Quoting}).
-
-@item ,
-The comma is used in conjunction with the backquote (@pxref{Quoting}).
-
-@item ,@@
-A comma followed by an at-sign is used in conjunction with the backquote
-(@pxref{Quoting}).
-
-@item #
-The sharp (or pound) sign has different uses, depending on the character
-that immediately follows it:
-
-@item #t #f
-These character sequences denote the boolean constants
-(@pxref{Booleans}).
-
-@item #\
-This character sequence introduces a character constant
-(@pxref{Characters}).
-
-@item #(
-This character sequence introduces a vector constant (@pxref{Vectors}).
-A close parenthesis, @samp{)}, terminates a vector constant.
-
-@item #e #i #b #o #d #l #s #x
-These character sequences are used in the notation for numbers
-(@pxref{Numbers}).
-
-@item #|
-This character sequence introduces an extended comment. The comment is
-terminated by the sequence @samp{|#}. This notation is an MIT/GNU Scheme
-extension.
-
-@item #!
-This character sequence is used to denote a small set of named
-constants. Currently there are only two of these, @code{#!optional} and
-@code{#!rest}, both of which are used in the @code{lambda} special form
-to mark certain parameters as being ``optional'' or ``rest'' parameters.
-This notation is an MIT/GNU Scheme extension.
-@findex #!optional
-@findex #!rest
-@findex lambda
-
-@item #*
-This character sequence introduces a bit string (@pxref{Bit Strings}).
-This notation is an MIT/GNU Scheme extension.
-
-@item #[
-This character sequence is used to denote objects that do not have a
-readable external representation (@pxref{Custom Output}). A close
-bracket, @samp{]}, terminates the object's notation. This notation is
-an MIT/GNU Scheme extension.
-
-@item #@@
-This character sequence is a convenient shorthand used to refer to
-objects by their hash number (@pxref{Custom Output}). This notation is
-an MIT/GNU Scheme extension.
-
-@item #=
-@itemx ##
-These character sequences introduce a notation used to show circular
-structures in printed output, or to denote them in input. The notation
-works much like that in Common Lisp, and is an MIT/GNU Scheme extension.
-@end table
-
-@node Expressions, , Lexical Conventions, Overview
-@section Expressions
-
-@cindex expression (defn)
-A Scheme @dfn{expression} is a construct that returns a value. An
-expression may be a @emph{literal}, a @emph{variable reference}, a
-@emph{special form}, or a @emph{procedure call}.
-
-@menu
-* Literal Expressions::
-* Variable References::
-* Special Form Syntax::
-* Procedure Call Syntax::
-@end menu
-
-@node Literal Expressions, Variable References, Expressions, Expressions
-@subsection Literal Expressions
-
-@cindex literal expression (defn)
-@cindex constant expression (defn)
-@cindex expression, literal (defn)
-@cindex expression, constant (defn)
-@dfn{Literal} constants may be written by using an external
-representation of the data. In general, the external representation
-must be @emph{quoted} (@pxref{Quoting}); but some external
-representations can be used without quotation.
-
-@example
-@group
-"abc" @result{} "abc"
-145932 @result{} 145932
-#t @result{} #t
-#\a @result{} #\a
-@end group
-@end example
-
-The external representation of numeric constants, string constants,
-character constants, and boolean constants evaluate to the constants
-themselves. Symbols, pairs, lists, and vectors require quoting.
-
-@node Variable References, Special Form Syntax, Literal Expressions, Expressions
-@subsection Variable References
-
-@cindex variable reference (defn)
-@cindex reference, variable (defn)
-@cindex unbound variable
-@cindex unassigned variable
-An expression consisting of an identifier (@pxref{Identifiers}) is a
-@dfn{variable reference}; the identifier is the name of the variable
-being referenced. The value of the variable reference is the value
-stored in the location to which the variable is bound. An error is
-signalled if the referenced variable is unbound or unassigned.
-
-@example
-@group
-(define x 28)
-x @result{} 28
-@end group
-@end example
-
-@node Special Form Syntax, Procedure Call Syntax, Variable References, Expressions
-@subsection Special Form Syntax
-
-@example
-(@var{keyword} @var{component} @dots{})
-@end example
-
-@cindex expression, special form (defn)
-@cindex special form (defn)
-@cindex form, special (defn)
-@cindex keyword, of special form (defn)
-@cindex syntactic keyword (defn)
-A parenthesized expression that starts with a @dfn{syntactic keyword} is
-a @dfn{special form}. Each special form has its own syntax, which is
-described later in the manual.
-
-Note that syntactic keywords and variable bindings share the same
-namespace. A local variable binding may shadow a syntactic keyword, and
-a local syntactic-keyword definition may shadow a variable binding.
-
-The following list contains all of the syntactic keywords that are
-defined when MIT/GNU Scheme is initialized:
-
-@multitable @columnfractions .33 .33 .33
-@item access
-@tab and
-@tab begin
-@item case
-@tab cond
-@tab cons-stream
-@item declare
-@tab default-object?
-@tab define
-@item define-integrable
-@tab define-structure
-@tab define-syntax
-@item delay
-@tab do
-@tab er-macro-transformer
-@item fluid-let
-@tab if
-@tab lambda
-@item let
-@tab let*
-@tab let*-syntax
-@item let-syntax
-@tab letrec
-@tab letrec-syntax
-@item local-declare
-@tab named-lambda
-@tab non-hygienic-macro-transformer
-@item or
-@tab quasiquote
-@tab quote
-@item rsc-macro-transformer
-@tab sc-macro-transformer
-@tab set!
-@item syntax-rules
-@tab the-environment
-@end multitable
-
-@node Procedure Call Syntax, , Special Form Syntax, Expressions
-@subsection Procedure Call Syntax
-
-@example
-(@var{operator} @var{operand} @dots{})
-@end example
-
-@cindex expression, procedure call (defn)
-@cindex procedure call (defn)
-@cindex operator, of procedure call (defn)
-@cindex operand, of procedure call (defn)
-A @dfn{procedure call} is written by simply enclosing in parentheses
-expressions for the procedure to be called (the @dfn{operator}) and the
-arguments to be passed to it (the @dfn{operands}). The @var{operator}
-and @var{operand} expressions are evaluated and the resulting procedure
-is passed the resulting arguments. @xref{Lambda Expressions}, for a
-more complete description of this.
-
-@cindex combination (defn)
-Another name for the procedure call expression is @dfn{combination}.
-This word is more specific in that it always refers to the expression;
-``procedure call'' sometimes refers to the @emph{process} of calling a
-procedure.
-
-@cindex order, of argument evaluation
-@cindex evaluation order, of arguments
-@cindex argument evaluation order
-Unlike some other dialects of Lisp, Scheme always evaluates the operator
-expression and the operand expressions with the same evaluation rules,
-and the order of evaluation is unspecified.
-
-@example
-@group
-(+ 3 4) @result{} 7
-((if #f = *) 3 4) @result{} 12
-@end group
-@end example
-
-@findex +
-@findex *
-@findex lambda
-A number of procedures are available as the values of variables in the
-initial environment; for example, the addition and multiplication
-procedures in the above examples are the values of the variables
-@code{+} and @code{*}. New procedures are created by evaluating
-@code{lambda} expressions.
-
-@cindex syntactic keyword
-If the @var{operator} is a syntactic keyword, then the expression is not
-treated as a procedure call: it is a special form.
-
-@node Special Forms, Equivalence Predicates, Overview, Top
-@chapter Special Forms
-
-@cindex special form
-A special form is an expression that follows special evaluation rules.
-This chapter describes the basic Scheme special forms.
-
-@menu
-* Lambda Expressions::
-* Lexical Binding::
-* Dynamic Binding::
-* Definitions::
-* Assignments::
-* Quoting::
-* Conditionals::
-* Sequencing::
-* Iteration::
-* Structure Definitions::
-* Macros::
-* SRFI syntax::
-@end menu
-
-@node Lambda Expressions, Lexical Binding, Special Forms, Special Forms
-@section Lambda Expressions
-
-@deffn {special form} lambda formals expression expression @dots{}
-@cindex lambda expression (defn)
-@cindex procedure, construction
-@cindex procedure, closing environment (defn)
-@cindex procedure, invocation environment (defn)
-@cindex construction, of procedure
-@cindex closing environment, of procedure (defn)
-@cindex invocation environment, of procedure (defn)
-@cindex environment, of procedure
-@cindex environment, procedure closing (defn)
-@cindex environment, procedure invocation (defn)
-A @code{lambda} expression evaluates to a procedure. The environment in
-effect when the @code{lambda} expression is evaluated is remembered as
-part of the procedure; it is called the @dfn{closing environment}. When
-the procedure is later called with some arguments, the closing
-environment is extended by binding the variables in the formal parameter
-list to fresh locations, and the locations are filled with the arguments
-according to rules about to be given. The new environment created by
-this process is referred to as the @dfn{invocation environment}.
-
-@cindex region of variable binding, lambda
-@cindex variable binding, lambda
-Once the invocation environment has been constructed, the
-@var{expression}s in the body of the @code{lambda} expression are
-evaluated sequentially in it. This means that the region of the
-variables bound by the @code{lambda} expression is all of the
-@var{expression}s in the body. The result of evaluating the last
-@var{expression} in the body is returned as the result of the procedure
-call.
-
-@cindex lambda list (defn)
-@cindex parameter list, of lambda (defn)
-@cindex formal parameter list, of lambda (defn)
-@var{Formals}, the formal parameter list, is often referred to as a
-@dfn{lambda list}.
-
-The process of matching up formal parameters with arguments is somewhat
-involved. There are three types of parameters, and the matching treats
-each in sequence:
-
-@need 1000
-@table @asis
-@item Required
-All of the @dfn{required} parameters are matched against the arguments
-first. If there are fewer arguments than required parameters, an error
-of type @code{condition-type:wrong-number-of-arguments} is signalled;
-this error is also signalled if there are more arguments than required
-parameters and there are no further parameters.
-@cindex required parameter (defn)
-@cindex parameter, required (defn)
-@findex condition-type:wrong-number-of-arguments
-
-@item Optional
-Once the required parameters have all been matched, the @dfn{optional}
-parameters are matched against the remaining arguments. If there are
-fewer arguments than optional parameters, the unmatched parameters are
-bound to special objects called @dfn{default objects}. If there are
-more arguments than optional parameters, and there are no further
-parameters, an error of type
-@code{condition-type:wrong-number-of-arguments} is signalled.
-@cindex optional parameter (defn)
-@cindex parameter, optional (defn)
-@cindex default object (defn)
-@findex condition-type:wrong-number-of-arguments
-
-@findex default-object?
-The predicate @code{default-object?}, which is true only of default
-objects, can be used to determine which optional parameters were
-supplied, and which were defaulted.
-
-@item Rest
-Finally, if there is a @dfn{rest} parameter (there can only be one), any
-remaining arguments are made into a list, and the list is bound to the
-rest parameter. (If there are no remaining arguments, the rest
-parameter is bound to the empty list.)
-@cindex rest parameter (defn)
-@cindex parameter, rest (defn)
-
-In Scheme, unlike some other Lisp implementations, the list to which a
-rest parameter is bound is always freshly allocated. It has infinite
-extent and may be modified without affecting the procedure's caller.
-@end table
-
-@findex #!optional
-@findex #!rest
-Specially recognized keywords divide the @var{formals} parameters into
-these three classes. The keywords used here are @samp{#!optional},
-@samp{.}, and @samp{#!rest}. Note that only @samp{.} is defined by
-standard Scheme --- the other keywords are MIT/GNU Scheme extensions.
-@samp{#!rest} has the same meaning as @samp{.} in @var{formals}.
-
-The use of these keywords is best explained by means of examples. The
-following are typical lambda lists, followed by descriptions of which
-parameters are required, optional, and rest. We will use @samp{#!rest}
-in these examples, but anywhere it appears @samp{.} could be used
-instead.
-
-@table @code
-@item (a b c)
-@code{a}, @code{b}, and @code{c} are all required. The procedure must
-be passed exactly three arguments.
-
-@item (a b #!optional c)
-@code{a} and @code{b} are required, @code{c} is optional. The procedure
-may be passed either two or three arguments.
-
-@item (#!optional a b c)
-@code{a}, @code{b}, and @code{c} are all optional. The procedure may be
-passed any number of arguments between zero and three, inclusive.
-
-@item a
-@itemx (#!rest a)
-These two examples are equivalent. @code{a} is a rest parameter. The
-procedure may be passed any number of arguments. Note: this is the only
-case in which @samp{.} cannot be used in place of @samp{#!rest}.
-
-@item (a b #!optional c d #!rest e)
-@code{a} and @code{b} are required, @code{c} and @code{d} are optional,
-and @code{e} is rest. The procedure may be passed two or more
-arguments.
-@end table
-
-Some examples of @code{lambda} expressions:
-
-@example
-@group
-(lambda (x) (+ x x)) @result{} #[compound-procedure 53]
-
-((lambda (x) (+ x x)) 4) @result{} 8
-
-(define reverse-subtract
- (lambda (x y)
- (- y x)))
-(reverse-subtract 7 10) @result{} 3
-
-(define foo
- (let ((x 4))
- (lambda (y) (+ x y))))
-(foo 6) @result{} 10
-@end group
-@end example
-@end deffn
-
-@deffn {special form} named-lambda formals expression expression @dots{}
-@cindex named lambda (defn)
-The @code{named-lambda} special form is similar to @code{lambda}, except
-that the first ``required parameter'' in @var{formals} is not a
-parameter but the @dfn{name} of the resulting procedure; thus
-@var{formals} must have at least one required parameter. This name has
-no semantic meaning, but is included in the external representation of
-the procedure, making it useful for debugging. In MIT/GNU Scheme,
-@code{lambda} is implemented as @code{named-lambda}, with a special name
-that means ``unnamed''.
-
-@example
-@group
-(named-lambda (f x) (+ x x)) @result{} #[compound-procedure 53 f]
-((named-lambda (f x) (+ x x)) 4) @result{} 8
-@end group
-@end example
-@end deffn
-
-@node Lexical Binding, Dynamic Binding, Lambda Expressions, Special Forms
-@section Lexical Binding
-
-@cindex lexical binding expression
-@cindex binding expression, lexical
-@cindex block structure
-The three binding constructs @code{let}, @code{let*}, and @code{letrec},
-give Scheme block structure. The syntax of the three constructs is
-identical, but they differ in the regions they establish for their
-variable bindings. In a @code{let} expression, the initial values are
-computed before any of the variables become bound. In a @code{let*}
-expression, the evaluations and bindings are sequentially interleaved.
-And in a @code{letrec} expression, all the bindings are in effect while
-the initial values are being computed (thus allowing mutually recursive
-definitions).
-
-@deffn {special form} let ((@var{variable} @var{init}) @dots{}) expression expression @dots{}
-@cindex region of variable binding, let
-@cindex variable binding, let
-The @var{init}s are evaluated in the current environment (in some
-unspecified order), the @var{variable}s are bound to fresh locations
-holding the results, the @var{expression}s are evaluated sequentially in
-the extended environment, and the value of the last @var{expression} is
-returned. Each binding of a @var{variable} has the @var{expression}s as
-its region.
-
-MIT/GNU Scheme allows any of the @var{init}s to be omitted, in which
-case the corresponding @var{variable}s are unassigned.
-
-@cindex lambda, implicit in let
-Note that the following are equivalent:
-
-@example
-@group
-(let ((@var{variable} @var{init}) @dots{}) @var{expression} @var{expression} @dots{})
-((lambda (@var{variable} @dots{}) @var{expression} @var{expression} @dots{}) @var{init} @dots{})
-@end group
-@end example
-
-Some examples:
-
-@example
-@group
-(let ((x 2) (y 3))
- (* x y)) @result{} 6
-@end group
-
-@group
-(let ((x 2) (y 3))
- (let ((foo (lambda (z) (+ x y z)))
- (x 7))
- (foo 4))) @result{} 9
-@end group
-@end example
-
-@xref{Iteration}, for information on ``named @code{let}''.
-@end deffn
-
-@deffn {special form} let* ((@var{variable} @var{init}) @dots{}) expression expression @dots{}
-@cindex region of variable binding, let*
-@cindex variable binding, let*
-@code{let*} is similar to @code{let}, but the bindings are performed
-sequentially from left to right, and the region of a binding is that
-part of the @code{let*} expression to the right of the binding. Thus
-the second binding is done in an environment in which the first binding
-is visible, and so on.
-
-Note that the following are equivalent:
-
-@example
-@group
-(let* ((@var{variable1} @var{init1})
- (@var{variable2} @var{init2})
- @dots{}
- (@var{variableN} @var{initN}))
- @var{expression}
- @var{expression} @dots{})
-@end group
-
-@group
-(let ((@var{variable1} @var{init1}))
- (let ((@var{variable2} @var{init2}))
- @dots{}
- (let ((@var{variableN} @var{initN}))
- @var{expression}
- @var{expression} @dots{})
- @dots{}))
-@end group
-@end example
-
-An example:
-
-@example
-@group
-(let ((x 2) (y 3))
- (let* ((x 7)
- (z (+ x y)))
- (* z x))) @result{} 70
-@end group
-@end example
-@end deffn
-
-@deffn {special form} letrec ((@var{variable} @var{init}) @dots{}) expression expression @dots{}
-@cindex region of variable binding, letrec
-@cindex variable binding, letrec
-The @var{variable}s are bound to fresh locations holding unassigned
-values, the @var{init}s are evaluated in the extended environment (in
-some unspecified order), each @var{variable} is assigned to the result
-of the corresponding @var{init}, the @var{expression}s are evaluated
-sequentially in the extended environment, and the value of the last
-@var{expression} is returned. Each binding of a @var{variable} has the
-entire @code{letrec} expression as its region, making it possible to
-define mutually recursive procedures.
-
-MIT/GNU Scheme allows any of the @var{init}s to be omitted, in which
-case the corresponding @var{variable}s are unassigned.
-
-@example
-@group
-(letrec ((even?
- (lambda (n)
- (if (zero? n)
- #t
- (odd? (- n 1)))))
- (odd?
- (lambda (n)
- (if (zero? n)
- #f
- (even? (- n 1))))))
- (even? 88)) @result{} #t
-@end group
-@end example
-
-@findex lambda
-@findex delay
-One restriction on @code{letrec} is very important: it shall be possible
-to evaluated each @var{init} without assigning or referring to the value
-of any @var{variable}. If this restriction is violated, then it is an
-error. The restriction is necessary because Scheme passes arguments by
-value rather than by name. In the most common uses of @code{letrec},
-all the @var{init}s are @code{lambda} or @code{delay} expressions and
-the restriction is satisfied automatically.
-@end deffn
-
-@node Dynamic Binding, Definitions, Lexical Binding, Special Forms
-@section Dynamic Binding
-
-@deffn {special form} fluid-let ((@var{variable} @var{init}) @dots{}) expression expression @dots{}
-@cindex binding expression, dynamic (or fluid)
-@cindex fluid binding
-@cindex dynamic binding
-@cindex variable binding, fluid-let
-The @var{init}s are evaluated in the current environment (in some
-unspecified order), the current values of the @var{variable}s are saved,
-the results are assigned to the @var{variable}s, the @var{expression}s
-are evaluated sequentially in the current environment, the
-@var{variable}s are restored to their original values, and the value of
-the last @var{expression} is returned.
-
-@findex let
-The syntax of this special form is similar to that of @code{let}, but
-@code{fluid-let} temporarily rebinds existing variables. Unlike
-@code{let}, @code{fluid-let} creates no new bindings; instead it
-@emph{assigns} the value of each @var{init} to the binding (determined
-by the rules of lexical scoping) of its corresponding @var{variable}.
-
-@cindex unassigned variable, and dynamic bindings
-MIT/GNU Scheme allows any of the @var{init}s to be omitted, in which
-case the corresponding @var{variable}s are temporarily unassigned.
-
-An error of type @code{condition-type:unbound-variable} is signalled if
-any of the @var{variable}s are unbound. However, because
-@code{fluid-let} operates by means of side effects, it is valid for any
-@var{variable} to be unassigned when the form is entered.
-@findex condition-type:unbound-variable
-
-Here is an example showing the difference between @code{fluid-let} and
-@code{let}. First see how @code{let} affects the binding of a variable:
-
-@example
-@group
-(define variable #t)
-(define (access-variable) variable)
-variable @result{} #t
-(let ((variable #f))
- (access-variable)) @result{} #t
-variable @result{} #t
-@end group
-@end example
-
-@code{access-variable} returns @code{#t} in this case because it
-is defined in an environment with @code{variable} bound to
-@code{#t}. @code{fluid-let}, on the other hand, temporarily reuses an
-existing variable:
-
-@example
-@group
-variable @result{} #t
-(fluid-let ((variable #f)) @r{;reuses old binding}
- (access-variable)) @result{} #f
-variable @result{} #t
-@end group
-@end example
-
-@cindex extent, of dynamic binding (defn)
-The @dfn{extent} of a dynamic binding is defined to be the time period
-during which the variable contains the new value. Normally this time
-period begins when the body is entered and ends when it is exited; on a
-sequential machine it is normally a contiguous time period. However,
-because Scheme has first-class continuations, it is possible to leave
-the body and then reenter it, as many times as desired. In this
-situation, the extent becomes non-contiguous.
-
-@cindex dynamic binding, and continuations
-@cindex continuation, and dynamic binding
-When the body is exited by invoking a continuation, the new value is
-saved, and the variable is set to the old value. Then, if the body is
-reentered by invoking a continuation, the old value is saved, and the
-variable is set to the new value. In addition, side effects to the
-variable that occur both inside and outside of body are preserved, even
-if continuations are used to jump in and out of body repeatedly.
-@end deffn
-
-Here is a complicated example that shows the interaction between dynamic
-binding and continuations:
-
-@example
-@group
-(define (complicated-dynamic-binding)
- (let ((variable 1)
- (inside-continuation))
- (write-line variable)
- (call-with-current-continuation
- (lambda (outside-continuation)
- (fluid-let ((variable 2))
- (write-line variable)
- (set! variable 3)
- (call-with-current-continuation
- (lambda (k)
- (set! inside-continuation k)
- (outside-continuation #t)))
- (write-line variable)
- (set! inside-continuation #f))))
- (write-line variable)
- (if inside-continuation
- (begin
- (set! variable 4)
- (inside-continuation #f)))))
-@end group
-@end example
-
-@noindent
-Evaluating @samp{(complicated-dynamic-binding)} writes the following on
-the console:
-
-@example
-@group
-1
-2
-1
-3
-4
-@end group
-@end example
-
-@noindent
-Commentary: the first two values written are the initial binding of
-@code{variable} and its new binding after the @code{fluid-let}'s body is
-entered. Immediately after they are written, @code{variable} is set to
-@samp{3}, and then @code{outside-continuation} is invoked, causing us to
-exit the body. At this point, @samp{1} is written, demonstrating that
-the original value of @code{variable} has been restored, because we have
-left the body. Then we set @code{variable} to @samp{4} and reenter the
-body by invoking @code{inside-continuation}. At this point, @samp{3} is
-written, indicating that the side effect that previously occurred within
-the body has been preserved. Finally, we exit body normally, and write
-@samp{4}, demonstrating that the side effect that occurred outside of
-the body was also preserved.
-
-@node Definitions, Assignments, Dynamic Binding, Special Forms
-@section Definitions
-@cindex definition
-
-@deffn {special form} define variable [expression]
-@deffnx {special form} define @var{formals} expression expression @dots{}
-@cindex variable, adding to environment
-@cindex definition, top-level (defn)
-@cindex definition, internal (defn)
-@cindex top-level definition (defn)
-@cindex internal definition (defn)
-@findex lambda
-@findex let
-@findex let*
-@findex letrec
-@findex fluid-let
-Definitions are valid in some but not all contexts where expressions are
-allowed. Definitions may only occur at the top level of a program and
-at the beginning of a lambda body (that is, the body of a @code{lambda},
-@code{let}, @code{let*}, @code{letrec}, @code{fluid-let}, or ``procedure
-@code{define}'' expression). A definition that occurs at the top level
-of a program is called a @dfn{top-level definition}, and a definition
-that occurs at the beginning of a body is called an @dfn{internal
-definition}.
-
-@cindex lambda, implicit in define
-@cindex procedure define (defn)
-@cindex define, procedure (defn)
-@findex named-lambda
-In the second form of @code{define} (called ``@dfn{procedure
-@code{define}}''), the component @var{formals} is identical to the
-component of the same name in a @code{named-lambda} expression. In
-fact, these two expressions are equivalent:
-
-@example
-@group
-(define (@var{name1} @var{name2} @dots{})
- @var{expression}
- @var{expression} @dots{})
-@end group
-
-@group
-(define @var{name1}
- (named-lambda (@var{name1} @var{name2} @dots{})
- @var{expression}
- @var{expression} @dots{}))
-@end group
-@end example
-@end deffn
-
-@menu
-* Top-Level Definitions::
-* Internal Definitions::
-@end menu
-
-@node Top-Level Definitions, Internal Definitions, Definitions, Definitions
-@subsection Top-Level Definitions
-@cindex top-level definition
-@cindex definition, top-level
-
-@cindex variable binding, top-level definition
-A top-level definition,
-
-@example
-(define @var{variable} @var{expression})
-@end example
-
-@noindent
-has essentially the same effect as this assignment expression, if
-@var{variable} is bound:
-
-@example
-(set! @var{variable} @var{expression})
-@end example
-
-@cindex unassigned variable, and definition
-@findex set!
-If @var{variable} is not bound, however, @code{define} binds
-@var{variable} to a new location in the current environment before
-performing the assignment (it is an error to perform a @code{set!} on an
-unbound variable). If you omit @var{expression}, the variable becomes
-unassigned; an attempt to reference such a variable is an error.
-
-@example
-@group
-(define add3
- (lambda (x) (+ x 3))) @result{} @r{unspecified}
-(add3 3) @result{} 6
-
-(define first car) @result{} @r{unspecified}
-(first '(1 2)) @result{} 1
-
-(define bar) @result{} @r{unspecified}
-bar @error{} Unassigned variable
-@end group
-@end example
-
-@node Internal Definitions, , Top-Level Definitions, Definitions
-@subsection Internal Definitions
-
-@cindex internal definition
-@cindex definition, internal
-@cindex region of variable binding, internal definition
-@cindex variable binding, internal definition
-@findex lambda
-@findex let
-@findex let*
-@findex letrec
-@findex fluid-let
-@findex define
-An @dfn{internal definition} is a definition that occurs at the
-beginning of a @var{body} (that is, the body of a @code{lambda},
-@code{let}, @code{let*}, @code{letrec}, @code{fluid-let}, or ``procedure
-@code{define}'' expression), rather than at the top level of a program.
-The variable defined by an internal definition is local to the
-@var{body}. That is, @var{variable} is bound rather than assigned, and
-the region of the binding is the entire @var{body}. For example,
-
-@example
-@group
-(let ((x 5))
- (define foo (lambda (y) (bar x y)))
- (define bar (lambda (a b) (+ (* a b) a)))
- (foo (+ x 3))) @result{} 45
-@end group
-@end example
-
-@findex letrec
-A @var{body} containing internal definitions can always be converted
-into a completely equivalent @code{letrec} expression. For example, the
-@code{let} expression in the above example is equivalent to
-
-@cindex letrec, implicit in define
-@example
-@group
-(let ((x 5))
- (letrec ((foo (lambda (y) (bar x y)))
- (bar (lambda (a b) (+ (* a b) a))))
- (foo (+ x 3))))
-@end group
-@end example
-
-@need 1000
-@node Assignments, Quoting, Definitions, Special Forms
-@section Assignments
-@cindex assignment
-
-@deffn {special form} set! variable [expression]
-@cindex variable, assigning values to
-@cindex unassigned variable, and assignment
-If @var{expression} is specified, evaluates @var{expression} and stores
-the resulting value in the location to which @var{variable} is bound.
-If @var{expression} is omitted, @var{variable} is altered to be
-unassigned; a subsequent reference to such a @var{variable} is an error.
-In either case, the value of the @code{set!} expression is unspecified.
-
-@var{Variable} must be bound either in some region enclosing the
-@code{set!} expression, or at the top level. However, @var{variable} is
-permitted to be unassigned when the @code{set!} form is entered.
-
-@example
-@group
-(define x 2) @result{} @r{unspecified}
-(+ x 1) @result{} 3
-(set! x 4) @result{} @r{unspecified}
-(+ x 1) @result{} 5
-@end group
-@end example
-
-@cindex access, used with set!
-@findex access
-@var{Variable} may be an @code{access} expression
-(@pxref{Environments}). This allows you to assign variables in an
-arbitrary environment. For example,
-
-@example
-@group
-(define x (let ((y 0)) (the-environment)))
-(define y 'a)
-y @result{} a
-(access y x) @result{} 0
-(set! (access y x) 1) @result{} @r{unspecified}
-y @result{} a
-(access y x) @result{} 1
-@end group
-@end example
-@end deffn
-
-@node Quoting, Conditionals, Assignments, Special Forms
-@section Quoting
-@cindex quoting
-
-This section describes the expressions that are used to modify or
-prevent the evaluation of objects.
-
-@deffn {special form} quote datum
-@cindex external representation, and quote
-@cindex literal, and quote
-@cindex constant, and quote
-@code{(quote @var{datum})} evaluates to @var{datum}. @var{Datum} may be
-any external representation of a Scheme object
-(@pxref{External Representations}).
-Use @code{quote} to include literal constants in
-Scheme code.
-
-@example
-@group
-(quote a) @result{} a
-(quote #(a b c)) @result{} #(a b c)
-(quote (+ 1 2)) @result{} (+ 1 2)
-@end group
-@end example
-
-@cindex ' as external representation
-@cindex apostrophe, as external representation
-@cindex quote, as external representation
-@findex '
-@code{(quote @var{datum})} may be abbreviated as @code{'@var{datum}}.
-The two notations are equivalent in all respects.
-
-@example
-@group
-'a @result{} a
-'#(a b c) @result{} #(a b c)
-'(+ 1 2) @result{} (+ 1 2)
-'(quote a) @result{} (quote a)
-''a @result{} (quote a)
-@end group
-@end example
-
-Numeric constants, string constants, character constants, and boolean
-constants evaluate to themselves, so they don't need to be quoted.
-
-@example
-@group
-'"abc" @result{} "abc"
-"abc" @result{} "abc"
-'145932 @result{} 145932
-145932 @result{} 145932
-'#t @result{} #t
-#t @result{} #t
-'#\a @result{} #\a
-#\a @result{} #\a
-@end group
-@end example
-@end deffn
-
-@deffn {special form} quasiquote template
-@cindex external representation, and quasiquote
-@cindex literal, and quasiquote
-@cindex constant, and quasiquote
-@findex equal?
-``Backquote'' or ``quasiquote'' expressions are useful for constructing
-a list or vector structure when most but not all of the desired
-structure is known in advance. If no commas appear within the
-@var{template}, the result of evaluating @code{`@var{template}} is
-equivalent (in the sense of @code{equal?}) to the result of evaluating
-@code{'@var{template}}. If a comma appears within the @var{template},
-however, the expression following the comma is evaluated (``unquoted'')
-and its result is inserted into the structure instead of the comma and
-the expression. If a comma appears followed immediately by an at-sign
-(@@), then the following expression shall evaluate to a list; the
-opening and closing parentheses of the list are then ``stripped away''
-and the elements of the list are inserted in place of the comma at-sign
-expression sequence.
-
-@example
-@group
-`(list ,(+ 1 2) 4) @result{} (list 3 4)
-
-(let ((name 'a)) `(list ,name ',name)) @result{} (list a 'a)
-
-`(a ,(+ 1 2) ,@@(map abs '(4 -5 6)) b) @result{} (a 3 4 5 6 b)
-
-`((foo ,(- 10 3)) ,@@(cdr '(c)) . ,(car '(cons)))
- @result{} ((foo 7) . cons)
-
-`#(10 5 ,(sqrt 4) ,@@(map sqrt '(16 9)) 8)
- @result{} #(10 5 2 4 3 8)
-
-`,(+ 2 3) @result{} 5
-@end group
-@end example
-
-@cindex nesting, of quasiquote expressions
-Quasiquote forms may be nested. Substitutions are made only for
-unquoted components appearing at the same nesting level as the outermost
-backquote. The nesting level increases by one inside each successive
-quasiquotation, and decreases by one inside each unquotation.
-
-@example
-@group
-`(a `(b ,(+ 1 2) ,(foo ,(+ 1 3) d) e) f)
- @result{} (a `(b ,(+ 1 2) ,(foo 4 d) e) f)
-
-(let ((name1 'x)
- (name2 'y))
- `(a `(b ,,name1 ,',name2 d) e))
- @result{} (a `(b ,x ,'y d) e)
-@end group
-@end example
-
-@cindex backquote, as external representation
-@cindex ` as external representation
-@cindex comma, as external representation
-@cindex , as external representation
-@cindex ,@@ as external representation
-@findex unquote
-@findex unquote-splicing
-@findex `
-@findex ,
-@findex ,@@
-The notations @code{`@var{template}} and (@code{quasiquote
-@var{template}}) are identical in all respects.
-@code{,@var{expression}} is identical to @code{(unquote
-@var{expression})} and @code{,@@@var{expression}} is identical to
-@code{(unquote-splicing @var{expression})}.
-
-@example
-@group
-(quasiquote (list (unquote (+ 1 2)) 4))
- @result{} (list 3 4)
-
-'(quasiquote (list (unquote (+ 1 2)) 4))
- @result{} `(list ,(+ 1 2) 4)
- @emph{i.e.,} (quasiquote (list (unquote (+ 1 2)) 4))
-@end group
-@end example
-
-Unpredictable behavior can result if any of the symbols
-@code{quasiquote}, @code{unquote}, or @code{unquote-splicing} appear in
-a @var{template} in ways otherwise than as described above.
-@end deffn
-
-@node Conditionals, Sequencing, Quoting, Special Forms
-@section Conditionals
-
-@cindex expression, conditional (defn)
-@cindex conditional expression (defn)
-@cindex true, in conditional expression (defn)
-@cindex false, in conditional expression (defn)
-@findex #f
-@findex #t
-The behavior of the @dfn{conditional expressions} is determined by
-whether objects are true or false. The conditional expressions count
-only @code{#f} as false. They count everything else, including
-@code{#t}, pairs, symbols, numbers, strings, vectors, and procedures as
-true (but @pxref{True and False}).
-
-In the descriptions that follow, we say that an object has ``a true
-value'' or ``is true'' when the conditional expressions treat it as
-true, and we say that an object has ``a false value'' or ``is false''
-when the conditional expressions treat it as false.
-
-@deffn {special form} if predicate consequent [alternative]
-@var{Predicate}, @var{consequent}, and @var{alternative} are
-expressions. An @code{if} expression is evaluated as follows: first,
-@var{predicate} is evaluated. If it yields a true value, then
-@var{consequent} is evaluated and its value is returned. Otherwise
-@var{alternative} is evaluated and its value is returned. If
-@var{predicate} yields a false value and no @var{alternative} is
-specified, then the result of the expression is unspecified.
-
-An @code{if} expression evaluates either @var{consequent} or
-@var{alternative}, never both. Programs should not depend on the value
-of an @code{if} expression that has no @var{alternative}.
-
-@example
-@group
-(if (> 3 2) 'yes 'no) @result{} yes
-(if (> 2 3) 'yes 'no) @result{} no
-(if (> 3 2)
- (- 3 2)
- (+ 3 2)) @result{} 1
-@end group
-@end example
-@end deffn
-
-@deffn {special form} cond clause clause @dots{}
-@cindex cond clause
-@cindex clause, of cond expression
-Each @var{clause} has this form:
-
-@example
-(@var{predicate} @var{expression} @dots{})
-@end example
-
-@noindent
-@cindex else clause, of cond expression (defn)
-@findex else
-where @var{predicate} is any expression. The last @var{clause} may be
-an @dfn{@code{else} clause}, which has the form:
-
-@example
-(else @var{expression} @var{expression} @dots{})
-@end example
-
-A @code{cond} expression does the following:
-
-@enumerate
-@item
-Evaluates the @var{predicate} expressions of successive @var{clause}s in
-order, until one of the @var{predicate}s evaluates to a true
-value.
-
-@item
-When a @var{predicate} evaluates to a true value, @code{cond} evaluates
-the @var{expression}s in the associated @var{clause} in left to right
-order, and returns the result of evaluating the last @var{expression} in
-the @var{clause} as the result of the entire @code{cond} expression.
-
-If the selected @var{clause} contains only the @var{predicate} and no
-@var{expression}s, @code{cond} returns the value of the @var{predicate}
-as the result.
-
-@item
-If all @var{predicate}s evaluate to false values, and there is no
-@code{else} clause, the result of the conditional expression is
-unspecified; if there is an @code{else} clause, @code{cond} evaluates
-its @var{expression}s (left to right) and returns the value of the last
-one.
-@end enumerate
-
-@example
-@group
-(cond ((> 3 2) 'greater)
- ((< 3 2) 'less)) @result{} greater
-
-(cond ((> 3 3) 'greater)
- ((< 3 3) 'less)
- (else 'equal)) @result{} equal
-@end group
-@end example
-
-Normally, programs should not depend on the value of a @code{cond}
-expression that has no @code{else} clause. However, some Scheme
-programmers prefer to write @code{cond} expressions in which at least
-one of the @var{predicate}s is always true. In this style, the final
-@var{clause} is equivalent to an @code{else} clause.
-
-@cindex => in cond clause
-@findex =>
-Scheme supports an alternative @var{clause} syntax:
-
-@example
-(@var{predicate} => @var{recipient})
-@end example
-
-@noindent
-where @var{recipient} is an expression. If @var{predicate} evaluates to
-a true value, then @var{recipient} is evaluated. Its value must be a
-procedure of one argument; this procedure is then invoked on the value
-of the @var{predicate}.
-
-@example
-@group
-(cond ((assv 'b '((a 1) (b 2))) => cadr)
- (else #f)) @result{} 2
-@end group
-@end example
-@end deffn
-
-@deffn {special form} case key clause clause @dots{}
-@cindex case clause
-@cindex clause, of case expression
-@var{Key} may be any expression. Each @var{clause} has this
-form:
-
-@example
-((@var{object} @dots{}) @var{expression} @var{expression} @dots{})
-@end example
-
-@cindex else clause, of case expression (defn)
-@findex else
-No @var{object} is evaluated, and all the @var{object}s must be
-distinct. The last @var{clause} may be an @dfn{@code{else} clause},
-which has the form:
-
-@example
-(else @var{expression} @var{expression} @dots{})
-@end example
-
-A @code{case} expression does the following:
-
-@enumerate
-@item
-Evaluates @var{key} and compares the result with each
-@var{object}.
-
-@item
-If the result of evaluating @var{key} is equivalent (in the sense of
-@code{eqv?}; @pxref{Equivalence Predicates}) to an @var{object},
-@code{case} evaluates the @var{expression}s in the corresponding
-@var{clause} from left to right and returns the result of evaluating the
-last @var{expression} in the @var{clause} as the result of the
-@code{case} expression.
-@findex eqv?
-
-@item
-If the result of evaluating @var{key} is different from every
-@var{object}, and if there's an @code{else} clause, @code{case}
-evaluates its @var{expression}s and returns the result of the last one
-as the result of the @code{case} expression. If there's no @code{else}
-clause, @code{case} returns an unspecified result. Programs should not
-depend on the value of a @code{case} expression that has no @code{else}
-clause.
-@end enumerate
-
-For example,
-
-@example
-@group
-(case (* 2 3)
- ((2 3 5 7) 'prime)
- ((1 4 6 8 9) 'composite)) @result{} composite
-
-(case (car '(c d))
- ((a) 'a)
- ((b) 'b)) @result{} @r{unspecified}
-
-(case (car '(c d))
- ((a e i o u) 'vowel)
- ((w y) 'semivowel)
- (else 'consonant)) @result{} consonant
-@end group
-@end example
-@end deffn
-
-@deffn {special form} and expression @dots{}
-The @var{expression}s are evaluated from left to right, and the value of
-the first @var{expression} that evaluates to a false value is returned.
-Any remaining @var{expression}s are not evaluated. If all the
-@var{expression}s evaluate to true values, the value of the last
-@var{expression} is returned. If there are no @var{expression}s then
-@code{#t} is returned.
-
-@example
-@group
-(and (= 2 2) (> 2 1)) @result{} #t
-(and (= 2 2) (< 2 1)) @result{} #f
-(and 1 2 'c '(f g)) @result{} (f g)
-(and) @result{} #t
-@end group
-@end example
-@end deffn
-
-@deffn {special form} or expression @dots{}
-The @var{expression}s are evaluated from left to right, and the value of
-the first @var{expression} that evaluates to a true value is returned.
-Any remaining @var{expression}s are not evaluated. If all
-@var{expression}s evaluate to false values, the value of the last
-@var{expression} is returned. If there are no @var{expression}s then
-@code{#f} is returned.
-
-@example
-@group
-(or (= 2 2) (> 2 1)) @result{} #t
-(or (= 2 2) (< 2 1)) @result{} #t
-(or #f #f #f) @result{} #f
-(or (memq 'b '(a b c)) (/ 3 0)) @result{} (b c)
-@end group
-@end example
-@end deffn
-
-@node Sequencing, Iteration, Conditionals, Special Forms
-@section Sequencing
-@cindex sequencing expressions
-
-The @code{begin} special form is used to evaluate expressions in a
-particular order.
-
-@deffn {special form} begin expression expression @dots{}
-The @var{expression}s are evaluated sequentially from left to right, and
-the value of the last @var{expression} is returned. This expression
-type is used to sequence side effects such as input and output.
-
-@example
-@group
-(define x 0)
-(begin (set! x 5)
- (+ x 1)) @result{} 6
-
-(begin (display "4 plus 1 equals ")
- (display (+ 4 1)))
- @print{} 4 plus 1 equals 5
- @result{} @r{unspecified}
-@end group
-@end example
-
-@cindex implicit begin
-Often the use of @code{begin} is unnecessary, because many special forms
-already support sequences of expressions (that is, they have an implicit
-@code{begin}). Some of these special forms are:
-
-@example
-@group
-case
-cond
-define @r{;``procedure @code{define}'' only}
-do
-fluid-let
-lambda
-let
-let*
-letrec
-named-lambda
-@end group
-@end example
-@findex case
-@findex cond
-@findex define
-@findex do
-@findex fluid-let
-@findex lambda
-@findex let
-@findex let*
-@findex letrec
-@findex named-lambda
-
-@findex sequence
-The obsolete special form @code{sequence} is identical to @code{begin}.
-It should not be used in new code.
-@end deffn
-
-@node Iteration, Structure Definitions, Sequencing, Special Forms
-@section Iteration
-
-@cindex expression, iteration (defn)
-@cindex iteration expression (defn)
-@cindex looping (see iteration expressions)
-@cindex tail recursion, vs. iteration expression
-The @dfn{iteration expressions} are: ``named @code{let}'' and @code{do}.
-They are also binding expressions, but are more commonly referred to as
-iteration expressions. Because Scheme is properly tail-recursive, you
-don't need to use these special forms to express iteration; you can
-simply use appropriately written ``recursive'' procedure calls.
-
-@deffn {special form} let name ((@var{variable} @var{init}) @dots{}) expression expression @dots{}
-@cindex named let (defn)
-MIT/GNU Scheme permits a variant on the syntax of @code{let} called
-``named @code{let}'' which provides a more general looping construct
-than @code{do}, and may also be used to express recursions.
-
-Named @code{let} has the same syntax and semantics as ordinary
-@code{let} except that @var{name} is bound within the @var{expression}s
-to a procedure whose formal arguments are the @var{variable}s and whose
-body is the @var{expression}s. Thus the execution of the
-@var{expression}s may be repeated by invoking the procedure named by
-@var{name}.
-
-@cindex unassigned variable, and named let
-MIT/GNU Scheme allows any of the @var{init}s to be omitted, in which
-case the corresponding @var{variable}s are unassigned.
-
-Note: the following expressions are equivalent:
-
-@example
-@group
-(let @var{name} ((@var{variable} @var{init}) @dots{})
- @var{expression}
- @var{expression} @dots{})
-
-((letrec ((@var{name}
- (named-lambda (@var{name} @var{variable} @dots{})
- @var{expression}
- @var{expression} @dots{})))
- @var{name})
- @var{init} @dots{})
-@end group
-@end example
-
-Here is an example:
-
-@example
-@group
-(let loop
- ((numbers '(3 -2 1 6 -5))
- (nonneg '())
- (neg '()))
- (cond ((null? numbers)
- (list nonneg neg))
- ((>= (car numbers) 0)
- (loop (cdr numbers)
- (cons (car numbers) nonneg)
- neg))
- (else
- (loop (cdr numbers)
- nonneg
- (cons (car numbers) neg)))))
-
- @result{} ((6 1 3) (-5 -2))
-@end group
-@end example
-@end deffn
-
-@deffn {special form} do ((@var{variable} @var{init} @var{step}) @dots{}) (@var{test} @var{expression} @dots{}) command @dots{}
-@code{do} is an iteration construct. It specifies a set of variables to
-be bound, how they are to be initialized at the start, and how they are
-to be updated on each iteration. When a termination condition is met,
-the loop exits with a specified result value.
-
-@code{do} expressions are evaluated as follows: The @var{init}
-expressions are evaluated (in some unspecified order), the
-@var{variable}s are bound to fresh locations, the results of the
-@var{init} expressions are stored in the bindings of the
-@var{variable}s, and then the iteration phase begins.
-
-Each iteration begins by evaluating @var{test}; if the result is false,
-then the @var{command} expressions are evaluated in order for effect,
-the @var{step} expressions are evaluated in some unspecified order, the
-@var{variable}s are bound to fresh locations, the results of the
-@var{step}s are stored in the bindings of the @var{variable}s, and the
-next iteration begins.
-
-If @var{test} evaluates to a true value, then the @var{expression}s are
-evaluated from left to right and the value of the last @var{expression}
-is returned as the value of the @code{do} expression. If no
-@var{expression}s are present, then the value of the @code{do}
-expression is unspecified in standard Scheme; in MIT/GNU Scheme, the
-value of @var{test} is returned.
-
-@cindex region of variable binding, do
-@cindex variable binding, do
-The region of the binding of a @var{variable} consists of the entire
-@code{do} expression except for the @var{init}s. It is an error for a
-@var{variable} to appear more than once in the list of @code{do}
-variables.
-
-A @var{step} may be omitted, in which case the effect is the same as if
-@code{(@var{variable} @var{init} @var{variable})} had been written
-instead of @code{(@var{variable} @var{init})}.
-
-@example
-@group
-(do ((vec (make-vector 5))
- (i 0 (+ i 1)))
- ((= i 5) vec)
- (vector-set! vec i i)) @result{} #(0 1 2 3 4)
-@end group
-
-@group
-(let ((x '(1 3 5 7 9)))
- (do ((x x (cdr x))
- (sum 0 (+ sum (car x))))
- ((null? x) sum))) @result{} 25
-@end group
-@end example
-@end deffn
-
-@node Structure Definitions, Macros, Iteration, Special Forms
-@section Structure Definitions
-
-This section provides examples and describes the options and syntax of
-@code{define-structure}, an MIT/GNU Scheme macro that is very similar to
-@code{defstruct} in Common Lisp. The differences between them are
-summarized at the end of this section. For more information, see
-Steele's Common Lisp book.
-
-@deffn {special form} define-structure (name structure-option @dots{}) slot-description @dots{}
-Each @var{slot-description} takes one of the following forms:
-
-@example
-@group
-@var{slot-name}
-(@var{slot-name} @var{default-init} [@var{slot-option} @var{value}]*)
-@end group
-@end example
-
-@cindex keyword constructor
-@cindex BOA constructor
-The fields @var{name} and @var{slot-name} must both be symbols. The
-field @var{default-init} is an expression for the initial value of the
-slot. It is evaluated each time a new instance is constructed. If it
-is not specified, the initial content of the slot is undefined. Default
-values are only useful with a @sc{boa} constructor with argument list or
-a keyword constructor (see below).
-
-Evaluation of a @code{define-structure} expression defines a structure
-descriptor and a set of procedures to manipulate instances of the
-structure. These instances are represented as records by default
-(@pxref{Records}) but may alternately be lists or vectors. The
-accessors and modifiers are marked with compiler declarations so that
-calls to them are automatically transformed into appropriate references.
-Often, no options are required, so a simple call to
-@code{define-structure} looks like:
-
-@example
-(define-structure foo a b c)
-@end example
-
-This defines a type descriptor @code{foo}, a constructor
-@code{make-foo}, a predicate @code{foo?}, accessors @code{foo-a},
-@code{foo-b}, and @code{foo-c}, and modifiers @code{set-foo-a!},
-@code{set-foo-b!}, and @code{set-foo-c!}.
-
-In general, if no options are specified, @code{define-structure} defines
-the following (using the simple call above as an example):
-
-@table @asis
-@item type descriptor
-The name of the type descriptor is the same as the name of the
-structure, e.g.@: @samp{foo}. The type descriptor satisfies the
-predicate @code{record-type?}.
-
-@item constructor
-The name of the constructor is @code{"make-"} followed by the name of
-the structure, e.g.@: @samp{make-foo}. The number of arguments accepted
-by the constructor is the same as the number of slots; the arguments are
-the initial values for the slots, and the order of the arguments matches
-the order of the slot definitions.
-
-@item predicate
-The name of the predicate is the name of the structure followed by
-@code{"?"}, e.g.@: @samp{foo?}. The predicate is a procedure of one
-argument, which returns @code{#t} if its argument is a record of the
-type defined by this structure definition, and @code{#f} otherwise.
-
-@item accessors
-For each slot, an accessor is defined. The name of the accessor is
-formed by appending the name of the structure, a hyphen, and the name of
-the slot, e.g.@: @samp{foo-a}. The accessor is a procedure of one
-argument, which must be a record of the type defined by this structure
-definition. The accessor extracts the contents of the corresponding
-slot in that record and returns it.
-
-@item modifiers
-For each slot, a modifier is defined. The name of the modifier is
-formed by appending @code{"set-"}, the name of the accessor, and
-@code{"!"}, e.g.@: @samp{set-foo-a!}. The modifier is a procedure of
-two arguments, the first of which must be a record of the type defined
-by this structure definition, and the second of which may be any object.
-The modifier modifies the contents of the corresponding slot in that
-record to be that object, and returns an unspecified value.
-@end table
-
-When options are not supplied, @code{(@var{name})} may be abbreviated to
-@var{name}. This convention holds equally for @var{structure-options}
-and @var{slot-options}. Hence, these are equivalent:
-
-@example
-@group
-(define-structure foo a b c)
-(define-structure (foo) (a) b (c))
-@end group
-@end example
-
-@noindent
-as are
-
-@example
-@group
-(define-structure (foo keyword-constructor) a b c)
-(define-structure (foo (keyword-constructor)) a b c)
-@end group
-@end example
-
-When specified as option values, @code{false} and @code{nil} are
-equivalent to @code{#f}, and @code{true} and @code{t} are equivalent to
-@code{#t}.
-@end deffn
-
-Possible @var{slot-options} are:
-
-@deffn {slot option} read-only value
-When given a @var{value} other than @code{#f}, this specifies that no
-modifier should be created for the slot.
-@end deffn
-
-@deffn {slot option} type type-descriptor
-This is accepted but not presently used.
-@end deffn
-
-Possible @var{structure-options} are:
-
-@deffn {structure option} predicate [name]
-This option controls the definition of a predicate procedure for the
-structure. If @var{name} is not given, the predicate is defined with
-the default name (see above). If @var{name} is @code{#f}, the predicate
-is not defined at all. Otherwise, @var{name} must be a symbol, and
-the predicate is defined with that symbol as its name.
-@end deffn
-
-@deffn {structure option} copier [name]
-This option controls the definition of a procedure to copy instances of
-the structure. This is a procedure of one argument, a structure
-instance, that makes a newly allocated copy of the structure and returns
-it. If @var{name} is not given, the copier is defined, and the name
-of the copier is @code{"copy-"} followed by the structure name (e.g.@:
-@samp{copy-foo}). If @var{name} is @code{#f}, the copier is not
-defined. Otherwise, @var{name} must be a symbol, and the copier is
-defined with that symbol as its name.
-@end deffn
-
-@deffn {structure option} print-procedure expression
-Evaluating @var{expression} must yield a procedure of two arguments,
-which is used to print instances of the structure. The procedure is an
-@dfn{unparser method} (@pxref{Custom Output}). If the structure
-instances are records, this option has the same effect as calling
-@code{set-record-type-unparser-method!}.
-@findex set-record-type-unparser-method!
-@end deffn
-
-@deffn {structure option} constructor [name [argument-list]]
-@cindex BOA constructor (defn)
-This option controls the definition of constructor procedures. These
-constructor procedures are called ``@sc{boa} constructors'', for ``By
-Order of Arguments'', because the arguments to the constructor specify
-the initial contents the structure's slots by the order in which they
-are given. This is as opposed to ``keyword constructors'', which
-specify the initial contents using keywords, and in which the order of
-arguments is irrelevant.
-
-If @var{name} is not given, a constructor is defined with the default
-name and arguments (see above). If @var{name} is @code{#f}, no
-constructor is defined; @var{argument-list} may not be specified in this
-case. Otherwise, @var{name} must be a symbol, and a constructor is
-defined with that symbol as its name. If @var{name} is a symbol,
-@var{argument-list} is optionally allowed; if it is omitted, the
-constructor accepts one argument for each slot in the structure
-definition, in the same order in which the slots appear in the
-definition. Otherwise, @var{argument-list} must be a lambda list
-(@pxref{Lambda Expressions}), and each of the parameters of the lambda
-list must be the name of a slot in the structure. The arguments
-accepted by the constructor are defined by this lambda list. Any slot
-that is not specified by the lambda list is initialized to the
-@var{default-init} as specified above; likewise for any slot specified
-as an optional parameter when the corresponding argument is not
-supplied.
-
-If the @code{constructor} option is specified, the default constructor
-is not defined. Additionally, the @code{constructor} option may be
-specified multiple times to define multiple constructors with
-different names and argument lists.
-
-@example
-@group
-(define-structure (foo
- (constructor make-foo (#!optional a b)))
- (a 6 read-only #t)
- (b 9))
-@end group
-@end example
-@end deffn
-
-@deffn {structure option} keyword-constructor [name]
-@cindex keyword constructor (defn)
-This option controls the definition of keyword constructor procedures.
-A @dfn{keyword constructor} is a procedure that accepts arguments that
-are alternating slot names and values. If @var{name} is omitted, a
-keyword constructor is defined, and the name of the constructor is
-@code{"make-"} followed by the name of the structure (e.g.@:
-@samp{make-foo}). Otherwise, @var{name} must be a symbol, and a keyword
-constructor is defined with this symbol as its name.
-
-If the @code{keyword-constructor} option is specified, the default
-constructor is not defined. Additionally, the
-@code{keyword-constructor} option may be specified multiple times to
-define multiple keyword constructors; this is usually not done since
-such constructors would all be equivalent.
-
-@example
-@group
-(define-structure (foo (keyword-constructor make-bar)) a b)
-(foo-a (make-bar 'b 20 'a 19)) @result{} 19
-@end group
-@end example
-@end deffn
-
-@deffn {structure option} type-descriptor name
-This option cannot be used with the @code{type} or @code{named} options.
-
-By default, structures are implemented as records. The name of the
-structure is defined to hold the type descriptor of the record defined
-by the structure. The @code{type-descriptor} option specifies a
-different name to hold the type descriptor.
-
-@example
-@group
-(define-structure foo a b)
-foo @result{} #[record-type 18]
-
-(define-structure (bar (type-descriptor <bar>)) a b)
-bar @error{} Unbound variable: bar
-<bar> @result{} #[record-type 19]
-@end group
-@end example
-@end deffn
-
-@deffn {structure option} conc-name [name]
-By default, the prefix for naming accessors and modifiers is the name of
-the structure followed by a hyphen. The @code{conc-name} option can be
-used to specify an alternative. If @var{name} is not given, the prefix
-is the name of the structure followed by a hyphen (the default). If
-@var{name} is @code{#f}, the slot names are used directly, without
-prefix. Otherwise, @var{name} must a symbol, and that symbol is used as
-the prefix.
-
-@example
-@code{(define-structure (foo (conc-name moby/)) a b)}
-@end example
-
-@noindent
-defines accessors @code{moby/a} and @code{moby/b}, and modifiers
-@code{set-moby/a!} and @code{set-moby/b!}.
-
-@example
-@code{(define-structure (foo (conc-name #f)) a b)}
-@end example
-
-@noindent
-defines accessors @code{a} and @code{b}, and modifiers @code{set-a!} and
-@code{set-b!}.
-@end deffn
-
-@deffn {structure option} type representation-type
-This option cannot be used with the @code{type-descriptor} option.
-
-By default, structures are implemented as records. The @code{type}
-option overrides this default, allowing the programmer to specify that
-the structure be implemented using another data type. The option value
-@var{representation-type} specifies the alternate data type; it is
-allowed to be one of the symbols @code{vector} or @code{list}, and the
-data type used is the one corresponding to the symbol.
-
-If this option is given, and the @code{named} option is not specified,
-the representation will not be tagged, and neither a predicate nor a
-type descriptor will be defined; also, the @code{print-procedure}
-option may not be given.
-
-@example
-@group
-(define-structure (foo (type list)) a b)
-(make-foo 1 2) @result{} (1 2)
-@end group
-@end example
-@end deffn
-
-@deffn {structure option} named [expression]
-This is valid only in conjunction with the @code{type} option and
-specifies that the structure instances be tagged to make them
-identifiable as instances of this structure type. This option cannot be
-used with the @code{type-descriptor} option.
-
-In the usual case, where @var{expression} is not given, the @code{named}
-option causes a type descriptor and predicate to be defined for the
-structure (recall that the @code{type} option without @code{named}
-suppresses their definition), and also defines a default unparser method
-for the structure instances (which can be overridden by the
-@code{print-procedure} option). If the default unparser method is not
-wanted then the @code{print-procedure} option should be specified as
-@code{#F}. This causes the structure to be printed in its native
-representation, as a list or vector, which includes the type descriptor.
-The type descriptor is a unique object, @emph{not} a record type, that
-describes the structure instances and is additionally stored in the
-structure instances to identify them: if the representation type is
-@code{vector}, the type descriptor is stored in the zero-th slot of the
-vector, and if the representation type is @code{list}, it is stored as
-the first element of the list.
-
-
-@example
-@group
-(define-structure (foo (type vector) named) a b c)
-(vector-ref (make-foo 1 2 3) 0) @result{} #[structure-type 52]
-@end group
-@end example
-
-If @var{expression} is specified, it is an expression that is evaluated
-to yield a tag object. The @var{expression} is evaluated once when the
-structure definition is evaluated (to specify the unparser method), and
-again whenever a predicate or constructor is called. Because of this,
-@var{expression} is normally a variable reference or a constant. The
-value yielded by @var{expression} may be any object at all. That object
-is stored in the structure instances in the same place that the type
-descriptor is normally stored, as described above. If @var{expression}
-is specified, no type descriptor is defined, only a predicate.
-
-@example
-@group
-(define-structure (foo (type vector) (named 'foo)) a b c)
-(vector-ref (make-foo 1 2 3) 0) @result{} foo
-@end group
-@end example
-@end deffn
-
-@deffn {structure option} safe-accessors [boolean]
-This option allows the programmer to have some control over the safety
-of the slot accessors (and modifiers) generated by
-@code{define-structure}. If @code{safe-accessors} is not specified, or
-if @var{boolean} is @code{#f}, then the accessors are optimized for
-speed at the expense of safety; when compiled, the accessors will turn
-into very fast inline sequences, usually one to three machine
-instructions in length. However, if @code{safe-accessors} is specified
-and @var{boolean} is either omitted or @code{#t}, then the accessors are
-optimized for safety, will check the type and structure of their
-argument, and will be close-coded.
-
-@example
-@group
-(define-structure (foo safe-accessors) a b c)
-@end group
-@end example
-@end deffn
-
-@deffn {structure option} initial-offset offset
-This is valid only in conjunction with the @code{type} option.
-@var{Offset} must be an exact non-negative integer and specifies the
-number of slots to leave open at the beginning of the structure instance
-before the specified slots are allocated. Specifying an @var{offset} of
-zero is equivalent to omitting the @code{initial-offset} option.
-
-If the @code{named} option is specified, the structure tag appears in
-the first slot, followed by the ``offset'' slots, and then the regular
-slots. Otherwise, the ``offset'' slots come first, followed by the
-regular slots.
-
-@example
-@group
-(define-structure (foo (type vector) (initial-offset 3))
- a b c)
-(make-foo 1 2 3) @result{} #(() () () 1 2 3)
-@end group
-@end example
-@end deffn
-
-The essential differences between MIT/GNU Scheme's @code{define-structure}
-and Common Lisp's @code{defstruct} are:
-
-@itemize @bullet
-@item
-The default constructor procedure takes positional arguments, in the
-same order as specified in the definition of the structure. A keyword
-constructor may be specified by giving the option
-@code{keyword-constructor}.
-
-@item
-@sc{boa} constructors are described using Scheme lambda lists. Since there
-is nothing corresponding to @code{&aux} in Scheme lambda lists, this
-functionality is not implemented.
-
-@item
-By default, no @code{copier} procedure is defined.
-
-@item
-The side-effect procedure corresponding to the accessor @code{foo} is
-given the name @code{set-foo!}.
-
-@item
-Keywords are ordinary symbols -- use @code{foo} instead of @code{:foo}.
-
-@item
-The option values @code{false}, @code{nil}, @code{true}, and @code{t}
-are treated as if the appropriate boolean constant had been specified
-instead.
-
-@item
-The @code{print-function} option is named @code{print-procedure}. Its
-argument is a procedure of two arguments (the unparser state and the
-structure instance) rather than three as in Common Lisp.
-
-@item
-By default, named structures are tagged with a unique object of some
-kind. In Common Lisp, the structures are tagged with symbols. This
-depends on the Common Lisp package system to help generate unique tags;
-MIT/GNU Scheme has no such way to generate unique symbols.
-
-@item
-The @code{named} option may optionally take an argument, which is
-normally the name of a variable (any expression may be used, but it is
-evaluated whenever the tag name is needed). If used, structure
-instances will be tagged with that variable's value. The variable must
-be defined when @code{define-structure} is evaluated.
-
-@item
-The @code{type} option is restricted to the values @code{vector} and
-@code{list}.
-
-@item
-The @code{include} option is not implemented.
-@end itemize
-
-@node Macros, SRFI syntax, Structure Definitions, Special Forms
-@section Macros
-
-(This section is largely taken from the @cite{Revised^4 Report on the
-Algorithmic Language Scheme}. The section on Syntactic Closures is
-derived from a document written by Chris Hanson. The section on
-Explicit Renaming is derived from a document written by William
-Clinger.)
-
-@cindex macro
-Scheme programs can define and use new derived expression types, called
-@dfn{macros}. Program-defined expression types have the syntax
-
-@example
-(@var{keyword} @var{datum} @dots{})
-@end example
-
-@noindent
-@cindex syntactic keyword
-@cindex keyword
-@cindex macro keyword
-where @var{keyword} is an identifier that uniquely determines the
-expression type. This identifier is called the @dfn{syntactic keyword},
-or simply @dfn{keyword}, of the macro. The number of the @var{datum}s,
-and their syntax, depends on the expression type.
-
-@cindex macro use
-@cindex macro transformer
-Each instance of a macro is called a @dfn{use} of the macro. The set of
-rules that specifies how a use of a macro is transcribed into a more
-primitive expression is called the @dfn{transformer} of the macro.
-
-@cindex anonymous syntactic keyword
-MIT/GNU Scheme also supports @dfn{anonymous syntactic keywords}. This means
-that it's not necessary to bind a macro transformer to a syntactic
-keyword before it is used. Instead, any macro-transformer expression
-can appear as the first element of a form, and the form will be expanded
-by the transformer.
-
-The macro definition facility consists of these parts:
-
-@itemize @bullet
-@item
-A set of expressions used to establish that certain identifiers are
-macro keywords, associate them with macro transformers, and control the
-scope within which a macro is defined.
-
-@item
-A standard high-level pattern language for specifying macro
-transformers, introduced by the @code{syntax-rules} special form.
-
-@item
-Two non-standard low-level languages for specifying macro transformers,
-@dfn{syntactic closures} and @dfn{explicit renaming}.
-@end itemize
-
-@cindex hygienic
-@cindex referentially transparent
-The syntactic keyword of a macro may shadow variable bindings, and local
-variable bindings may shadow keyword bindings. All macros defined using
-the pattern language are ``hygienic'' and ``referentially transparent''
-and thus preserve Scheme's lexical scoping:
-
-@itemize @bullet
-@item
-If a macro transformer inserts a binding for an identifier (variable or
-keyword), the identifier will in effect be renamed throughout its scope
-to avoid conflicts with other identifiers.
-
-@item
-If a macro transformer inserts a free reference to an identifier, the
-reference refers to the binding that was visible where the transformer
-was specified, regardless of any local bindings that may surround the
-use of the macro.
-@end itemize
-
-@menu
-* Syntactic Binding Constructs::
-* Pattern Language::
-* Syntactic Closures::
-* Explicit Renaming::
-@end menu
-
-@node Syntactic Binding Constructs, Pattern Language, Macros, Macros
-@subsection Binding Constructs for Syntactic Keywords
-
-@code{let-syntax}, @code{letrec-syntax}, @code{let*-syntax} and
-@code{define-syntax} are analogous to @code{let}, @code{letrec},
-@code{let*} and @code{define}, but they bind syntactic keywords to macro
-transformers instead of binding variables to locations that contain
-values.
-
-@deffn {special form} let-syntax bindings expression expression @dots{}
-@var{Bindings} should have the form
-
-@example
-((@var{keyword} @var{transformer-spec}) @dots{})
-@end example
-
-@noindent
-Each @var{keyword} is an identifier, each @var{transformer-spec} is a
-a macro-transformer expression, and the body is a sequence of
-one or more expressions. It is an error for a @var{keyword} to appear
-more than once in the list of keywords being bound.
-
-The @var{expression}s are expanded in the syntactic environment obtained
-by extending the syntactic environment of the @code{let-syntax}
-expression with macros whose keywords are the @var{keyword}s, bound to
-the specified transformers. Each binding of a @var{keyword} has the
-@var{expression}s as its region.
-
-@example
-@group
-(let-syntax ((when (syntax-rules ()
- ((when test stmt1 stmt2 ...)
- (if test
- (begin stmt1
- stmt2 ...))))))
- (let ((if #t))
- (when if (set! if 'now))
- if)) @result{} now
-
-(let ((x 'outer))
- (let-syntax ((m (syntax-rules () ((m) x))))
- (let ((x 'inner))
- (m)))) @result{} outer
-@end group
-@end example
-@end deffn
-
-@deffn {special form} letrec-syntax bindings expression expression @dots{}
-The syntax of @code{letrec-syntax} is the same as for @code{let-syntax}.
-
-The @var{expression}s are expanded in the syntactic environment obtained
-by extending the syntactic environment of the @code{letrec-syntax}
-expression with macros whose keywords are the @var{keyword}s, bound to
-the specified transformers. Each binding of a @var{keyword} has the
-@var{bindings} as well as the @var{expression}s within its region, so
-the transformers can transcribe expressions into uses of the macros
-introduced by the @code{letrec-syntax} expression.
-
-@example
-@group
-(letrec-syntax
- ((my-or (syntax-rules ()
- ((my-or) #f)
- ((my-or e) e)
- ((my-or e1 e2 ...)
- (let ((temp e1))
- (if temp
- temp
- (my-or e2 ...)))))))
- (let ((x #f)
- (y 7)
- (temp 8)
- (let odd?)
- (if even?))
- (my-or x
- (let temp)
- (if y)
- y))) @result{} 7
-@end group
-@end example
-@end deffn
-
-@deffn {special form} let*-syntax bindings expression expression @dots{}
-The syntax of @code{let*-syntax} is the same as for @code{let-syntax}.
-
-The @var{expression}s are expanded in the syntactic environment obtained
-by extending the syntactic environment of the @code{letrec-syntax}
-expression with macros whose keywords are the @var{keyword}s, bound to
-the specified transformers. Each binding of a @var{keyword} has the
-subsequent @var{bindings} as well as the @var{expression}s within its
-region. Thus
-
-@example
-@group
-(let*-syntax
- ((a (syntax-rules @dots{}))
- (b (syntax-rules @dots{})))
- @dots{})
-@end group
-@end example
-
-@noindent
-is equivalent to
-
-@example
-@group
-(let-syntax ((a (syntax-rules @dots{})))
- (let-syntax ((b (syntax-rules @dots{})))
- @dots{}))
-@end group
-@end example
-@end deffn
-
-@deffn {special form} define-syntax keyword transformer-spec
-@var{Keyword} is an identifier, and @var{transformer-spec} is a macro
-transformer expression. The syntactic environment is extended by
-binding the @var{keyword} to the specified transformer.
-
-The region of the binding introduced by @code{define-syntax} is the
-entire block in which it appears. However, the @var{keyword} may only
-be used after it has been defined.
-
-MIT/GNU Scheme permits @code{define-syntax} to appear both at top level and
-within @code{lambda} bodies. The Revised^4 Report permits only
-top-level uses of @code{define-syntax}.
-
-When compiling a program, a top-level instance of @code{define-syntax}
-both defines the syntactic keyword and generates code that will redefine
-the keyword when the program is loaded. This means that the same syntax
-can be used for defining macros that will be used during compilation
-and for defining macros to be used at run time.
-
-Although macros may expand into definitions and syntax definitions in
-any context that permits them, it is an error for a definition or syntax
-definition to shadow a syntactic keyword whose meaning is needed to
-determine whether some form in the group of forms that contains the
-shadowing definition is in fact a definition, or, for internal definitions,
-is needed to determine the boundary between the group and the expressions
-that follow the group. For example, the following are errors:
-
-@example
-(define define 3)
-
-(begin (define begin list))
-
-(let-syntax
- ((foo (syntax-rules ()
- ((foo (proc args ...) body ...)
- (define proc
- (lambda (args ...)
- body ...))))))
- (let ((x 3))
- (foo (plus x y) (+ x y))
- (define foo x)
- (plus foo x)))
-@end example
-@end deffn
-
-@node Pattern Language, Syntactic Closures, Syntactic Binding Constructs, Macros
-@subsection Pattern Language
-
-MIT/GNU Scheme supports a high-level pattern language for specifying macro
-transformers. This pattern language is defined by the Revised^4 Report
-and is portable to other conforming Scheme implementations. To use the
-pattern language, specify a @var{transformer-spec} as a
-@code{syntax-rules} form:
-
-@deffn {special form} syntax-rules literals syntax-rule @dots{}
-@var{Literals} is a list of identifiers and each @var{syntax-rule}
-should be of the form
-
-@example
-(@var{pattern} @var{template})
-@end example
-
-The @var{pattern} in a @var{syntax-rule} is a list @var{pattern} that
-begins with the keyword for the macro.
-
-A @var{pattern} is either an identifier, a constant, or one of the
-following
-
-@example
-(@var{pattern} @dots{})
-(@var{pattern} @var{pattern} @dots{} . @var{pattern})
-(@var{pattern} @dots{} @var{pattern} @var{ellipsis})
-@end example
-
-@noindent
-and a template is either an identifier, a constant, or one of the
-following
-
-@example
-(@var{element} @dots{})
-(@var{element} @var{element} @dots{} . @var{template})
-@end example
-
-@vindex ...
-where an @var{element} is a @var{template} optionally followed by an
-@var{ellipsis} and an @var{ellipsis} is the identifier @samp{...} (which
-cannot be used as an identifier in either a template or a pattern).
-
-An instance of @code{syntax-rules} produces a new macro transformer by
-specifying a sequence of hygienic rewrite rules. A use of a macro whose
-keyword is associated with a transformer specified by
-@code{syntax-rules} is matched against the patterns contained in the
-@var{syntax-rule}s, beginning with the leftmost @var{syntax-rule}. When
-a match is found, the macro use is transcribed hygienically according to
-the template.
-
-An identifier that appears in the pattern of a @var{syntax-rule} is a
-@dfn{pattern-variable}, unless it is the keyword that begins the
-pattern, is listed in @var{literals}, or is the identifier @samp{...}.
-Pattern variables match arbitrary input elements and are used to refer
-to elements of the input in the template. It is an error for the same
-pattern variable to appear more than once in a @var{pattern}.
-
-The keyword at the beginning of the pattern in a @var{syntax-rule} is
-not involved in the matching and is not considered a pattern variable or
-literal identifier.
-
-Identifiers that appear in @var{literals} are interpreted as literal
-identifiers to be matched against corresponding subforms of the input.
-A subform in the input matches a literal identifier if and only if it is
-an identifier and either both its occurrence in the macro expression and
-its occurrence in the macro definition have the same lexical binding, or
-the two identifiers are equal and both have no lexical binding.
-
-A subpattern followed by @samp{...} can match zero or more elements of
-the input. It is an error for @samp{...} to appear in @var{literals}.
-Within a pattern the identifier @samp{...} must follow the last element
-of a nonempty sequence of subpatterns.
-
-More formally, an input form @var{F} matches a pattern @var{P} if and
-only if:
-
-@itemize @bullet
-@item
-@var{P} is a non-literal identifier; or
-
-@item
-@var{P} is a literal identifier and @var{F} is an identifier with the
-same binding; or
-
-@item
-@var{P} is a list @code{(@var{P_1} @dots{} @var{P_n})} and @var{F} is a
-list of @var{n} forms that match @var{P_1} through @var{P_n},
-respectively; or
-
-@item
-@var{P} is an improper list @code{(@var{P_1} @var{P_2} @dots{} @var{P_n}
-. @var{P_n+1})} and @var{F} is a list or improper list of @var{n} or
-more forms that match @var{P_1} through @var{P_n}, respectively, and
-whose @var{n}th ``cdr'' matches @var{P_n+1}; or
-
-@item
-@var{P} is of the form @code{(@var{P_1} @dots{} @var{P_n} @var{P_n+1}
-@var{ellipsis})} where @var{ellipsis} is the identifier @samp{...} and
-@var{F} is a proper list of at least @var{n} forms, the first @var{n} of
-which match @var{P_1} through @var{P_n}, respectively, and each
-remaining element of @var{F} matches @var{P_n+1}; or
-
-@item
-@var{P} is a datum and @var{F} is equal to @var{P} in the sense of the
-@code{equal?} procedure.
-@end itemize
-
-It is an error to use a macro keyword, within the scope of its
-binding, in an expression that does not match any of the patterns.
-
-When a macro use is transcribed according to the template of the
-matching @var{syntax rule}, pattern variables that occur in the template
-are replaced by the subforms they match in the input. Pattern variables
-that occur in subpatterns followed by one or more instances of the
-identifier @samp{...} are allowed only in subtemplates that are followed
-by as many instances of @samp{...}. They are replaced in the output by
-all of the subforms they match in the input, distributed as indicated.
-It is an error if the output cannot be built up as specified.
-
-Identifiers that appear in the template but are not pattern variables or
-the identifier @samp{...} are inserted into the output as literal
-identifiers. If a literal identifier is inserted as a free identifier
-then it refers to the binding of that identifier within whose scope the
-instance of @code{syntax-rules} appears. If a literal identifier is
-inserted as a bound identifier then it is in effect renamed to prevent
-inadvertent captures of free identifiers.
-
-@example
-@group
-(let ((=> #f))
- (cond (#t => 'ok))) @result{} ok
-@end group
-@end example
-
-The macro transformer for @code{cond} recognizes @code{=>}
-as a local variable, and hence an expression, and not as the
-top-level identifier @code{=>}, which the macro transformer treats
-as a syntactic keyword. Thus the example expands into
-
-@example
-@group
-(let ((=> #f))
- (if #t (begin => 'ok)))
-@end group
-@end example
-
-instead of
-
-@example
-@group
-(let ((=> #f))
- (let ((temp #t))
- (if temp
- ('ok temp))))
-@end group
-@end example
-
-which would result in an invalid procedure call.
-@end deffn
-
-@node Syntactic Closures, Explicit Renaming, Pattern Language, Macros
-@subsection Syntactic Closures
-
-@cindex syntactic closures
-MIT/GNU Scheme's syntax-transformation engine is an implementation of
-@dfn{syntactic closures}, a mechanism invented by Alan Bawden and
-Jonathan Rees. The main feature of the syntactic-closures mechanism is
-its simplicity and its close relationship to the environment models
-commonly used with Scheme. Using the mechanism to write macro
-transformers is somewhat cumbersome and can be confusing for the newly
-initiated, but it is easily mastered.
-
-@menu
-* Syntax Terminology::
-* SC Transformer Definition::
-* SC Identifiers::
-@end menu
-
-@node Syntax Terminology, SC Transformer Definition, Syntactic Closures, Syntactic Closures
-@subsubsection Syntax Terminology
-
-This section defines the concepts and data types used by the syntactic
-closures facility.
-
-@itemize @bullet
-@item
-@cindex form
-@dfn{Forms} are the syntactic entities out of which programs are
-recursively constructed. A form is any expression, any definition, any
-syntactic keyword, or any syntactic closure. The variable name that
-appears in a @code{set!} special form is also a form. Examples of
-forms:
-
-@example
-@group
-17
-#t
-car
-(+ x 4)
-(lambda (x) x)
-(define pi 3.14159)
-if
-define
-@end group
-@end example
-
-@item
-@cindex alias
-@cindex identifier
-@cindex synthetic identifier
-An @dfn{alias} is an alternate name for a given symbol. It can appear
-anywhere in a form that the symbol could be used, and when quoted it is
-replaced by the symbol; however, it does not satisfy the predicate
-@code{symbol?}. Macro transformers rarely distinguish symbols from
-aliases, referring to both as @dfn{identifiers}. Another name for an
-alias is @dfn{synthetic identifier}; this document uses both names.
-
-@item
-@cindex syntactic environment
-A @dfn{syntactic environment} maps identifiers to their meanings. More
-precisely, it determines whether an identifier is a syntactic keyword
-or a variable. If it is a keyword, the meaning is an interpretation
-for the form in which that keyword appears. If it is a variable, the
-meaning identifies which binding of that variable is referenced. In
-short, syntactic environments contain all of the contextual information
-necessary for interpreting the meaning of a particular form.
-
-@item
-@cindex syntactic closure
-A @dfn{syntactic closure} consists of a form, a syntactic environment,
-and a list of identifiers. All identifiers in the form take their
-meaning from the syntactic environment, except those in the given list.
-The identifiers in the list are to have their meanings determined
-later.
-
-A syntactic closure may be used in any context in which its form could
-have been used. Since a syntactic closure is also a form, it may not
-be used in contexts where a form would be illegal. For example, a form
-may not appear as a clause in the @code{cond} special form.
-
-A syntactic closure appearing in a quoted structure is replaced by its
-form.
-@end itemize
-
-@node SC Transformer Definition, SC Identifiers, Syntax Terminology, Syntactic Closures
-@subsubsection Transformer Definition
-
-This section describes the special forms for defining syntactic-closures
-macro transformers, and the associated procedures for manipulating
-syntactic closures and syntactic environments.
-
-@deffn {special form} sc-macro-transformer expression
-The @var{expression} is expanded in the syntactic environment of the
-@code{sc-macro-transformer} expression, and the expanded expression is
-evaluated in the transformer environment to yield a macro transformer as
-described below. This macro transformer is bound to a macro keyword by
-the special form in which the @code{transformer} expression appears (for
-example, @code{let-syntax}).
-
-@cindex macro transformer
-@cindex input form
-@cindex usage environment
-@cindex output form
-@cindex transformer environment
-In the syntactic closures facility, a @dfn{macro transformer} is a
-procedure that takes two arguments, a form and a syntactic environment,
-and returns a new form. The first argument, the @dfn{input form}, is
-the form in which the macro keyword occurred. The second argument, the
-@dfn{usage environment}, is the syntactic environment in which the input
-form occurred. The result of the transformer, the @dfn{output form}, is
-automatically closed in the @dfn{transformer environment}, which is the
-syntactic environment in which the @code{transformer} expression
-occurred.
-
-For example, here is a definition of a @code{push} macro using
-@code{syntax-rules}:
-
-@example
-@group
-(define-syntax push
- (syntax-rules ()
- ((push item list)
- (set! list (cons item list)))))
-@end group
-@end example
-
-@noindent
-Here is an equivalent definition using @code{sc-macro-transformer}:
-
-@example
-@group
-(define-syntax push
- (sc-macro-transformer
- (lambda (exp env)
- (let ((item (make-syntactic-closure env '() (cadr exp)))
- (list (make-syntactic-closure env '() (caddr exp))))
- `(set! ,list (cons ,item ,list))))))
-@end group
-@end example
-
-@noindent
-In this example, the identifiers @code{set!} and @code{cons} are closed
-in the transformer environment, and thus will not be affected by the
-meanings of those identifiers in the usage environment @code{env}.
-
-Some macros may be non-hygienic by design. For example, the following
-defines a @code{loop} macro that implicitly binds @code{exit} to an
-escape procedure. The binding of @code{exit} is intended to capture
-free references to @code{exit} in the body of the loop, so @code{exit}
-must be left free when the body is closed:
-
-@example
-@group
-(define-syntax loop
- (sc-macro-transformer
- (lambda (exp env)
- (let ((body (cdr exp)))
- `(call-with-current-continuation
- (lambda (exit)
- (let f ()
- ,@@(map (lambda (exp)
- (make-syntactic-closure env '(exit)
- exp))
- body)
- (f))))))))
-@end group
-@end example
-@end deffn
-
-@deffn {special form} rsc-macro-transformer expression
-This form is an alternative way to define a syntactic-closures macro
-transformer. Its syntax and usage are identical to
-@code{sc-macro-transformer}, except that the roles of the usage
-environment and transformer environment are reversed. (Hence
-@acronym{RSC} stands for @dfn{Reversed Syntactic Closures}.) In other
-words, the procedure specified by @var{expression} still accepts two
-arguments, but its second argument will be the transformer environment
-rather than the usage environment, and the returned expression is closed
-in the usage environment rather than the transformer environment.
-
-The advantage of this arrangement is that it allows a simpler definition
-style in some situations. For example, here is the @code{push} macro
-from above, rewritten in this style:
-
-@example
-@group
-(define-syntax push
- (rsc-macro-transformer
- (lambda (exp env)
- `(,(make-syntactic-closure env '() 'SET!)
- ,(caddr exp)
- (,(make-syntactic-closure env '() 'CONS)
- ,(cadr exp)
- ,(caddr exp))))))
-@end group
-@end example
-
-@noindent
-In this style only the introduced keywords are closed, while everything
-else remains open.
-
-Note that @code{rsc-macro-transformer} and @code{sc-macro-transformer}
-are easily interchangeable. Here is how to emulate
-@code{rsc-macro-transformer} using @code{sc-macro-transformer}. (This
-technique can be used to effect the opposite emulation as well.)
-
-@example
-@group
-(define-syntax push
- (sc-macro-transformer
- (lambda (exp usage-env)
- (capture-syntactic-environment
- (lambda (env)
- (make-syntactic-closure usage-env '()
- `(,(make-syntactic-closure env '() 'SET!)
- ,(caddr exp)
- (,(make-syntactic-closure env '() 'CONS)
- ,(cadr exp)
- ,(caddr exp)))))))))
-@end group
-@end example
-@end deffn
-
-To assign meanings to the identifiers in a form, use
-@code{make-syntactic-closure} to close the form in a syntactic
-environment.
-
-@deffn procedure make-syntactic-closure environment free-names form
-@var{Environment} must be a syntactic environment, @var{free-names}
-must be a list of identifiers, and @var{form} must be a form.
-@code{make-syntactic-closure} constructs and returns a syntactic
-closure of @var{form} in @var{environment}, which can be used anywhere
-that @var{form} could have been used. All the identifiers used in
-@var{form}, except those explicitly excepted by @var{free-names},
-obtain their meanings from @var{environment}.
-
-Here is an example where @var{free-names} is something other than the
-empty list. It is instructive to compare the use of @var{free-names}
-in this example with its use in the @code{loop} example above: the
-examples are similar except for the source of the identifier being left
-free.
-
-@example
-@group
-(define-syntax let1
- (sc-macro-transformer
- (lambda (exp env)
- (let ((id (cadr exp))
- (init (caddr exp))
- (exp (cadddr exp)))
- `((lambda (,id)
- ,(make-syntactic-closure env (list id) exp))
- ,(make-syntactic-closure env '() init))))))
-@end group
-@end example
-
-@noindent
-@code{let1} is a simplified version of @code{let} that only binds a
-single identifier, and whose body consists of a single expression.
-When the body expression is syntactically closed in its original
-syntactic environment, the identifier that is to be bound by
-@code{let1} must be left free, so that it can be properly captured by
-the @code{lambda} in the output form.
-@end deffn
-
-In most situations, the @var{free-names} argument to
-@code{make-syntactic-closure} is the empty list. In those cases, the
-more succinct @code{close-syntax} can be used:
-
-@deffn procedure close-syntax form environment
-@var{Environment} must be a syntactic environment and @var{form} must be
-a form. Returns a new syntactic closure of @var{form} in
-@var{environment}, with no free names. Entirely equivalent to
-
-@example
-(make-syntactic-closure @var{environment} '() @var{form})
-@end example
-@end deffn
-
-To obtain a syntactic environment other than the usage environment,
-use @code{capture-syntactic-environment}.
-
-@deffn procedure capture-syntactic-environment procedure
-@code{capture-syntactic-environment} returns a form that will, when
-transformed, call @var{procedure} on the current syntactic environment.
-@var{Procedure} should compute and return a new form to be transformed,
-in that same syntactic environment, in place of the form.
-
-An example will make this clear. Suppose we wanted to define a simple
-@code{loop-until} keyword equivalent to
-
-@example
-@group
-(define-syntax loop-until
- (syntax-rules ()
- ((loop-until id init test return step)
- (letrec ((loop
- (lambda (id)
- (if test return (loop step)))))
- (loop init)))))
-@end group
-@end example
-
-@noindent
-The following attempt at defining @code{loop-until} has a subtle
-bug:
-
-@example
-@group
-(define-syntax loop-until
- (sc-macro-transformer
- (lambda (exp env)
- (let ((id (cadr exp))
- (init (caddr exp))
- (test (cadddr exp))
- (return (cadddr (cdr exp)))
- (step (cadddr (cddr exp)))
- (close
- (lambda (exp free)
- (make-syntactic-closure env free exp))))
- `(letrec ((loop
- (lambda (,id)
- (if ,(close test (list id))
- ,(close return (list id))
- (loop ,(close step (list id)))))))
- (loop ,(close init '())))))))
-@end group
-@end example
-
-@noindent
-This definition appears to take all of the proper precautions to
-prevent unintended captures. It carefully closes the subexpressions in
-their original syntactic environment and it leaves the @code{id}
-identifier free in the @code{test}, @code{return}, and @code{step}
-expressions, so that it will be captured by the binding introduced by
-the @code{lambda} expression. Unfortunately it uses the identifiers
-@code{if} and @code{loop} @emph{within} that @code{lambda} expression,
-so if the user of @code{loop-until} just happens to use, say, @code{if}
-for the identifier, it will be inadvertently captured.
-
-The syntactic environment that @code{if} and @code{loop} want to be
-exposed to is the one just outside the @code{lambda} expression: before
-the user's identifier is added to the syntactic environment, but after
-the identifier @code{loop} has been added.
-@code{capture-syntactic-environment} captures exactly that environment
-as follows:
-
-@example
-@group
-(define-syntax loop-until
- (sc-macro-transformer
- (lambda (exp env)
- (let ((id (cadr exp))
- (init (caddr exp))
- (test (cadddr exp))
- (return (cadddr (cdr exp)))
- (step (cadddr (cddr exp)))
- (close
- (lambda (exp free)
- (make-syntactic-closure env free exp))))
- `(letrec ((loop
- ,(capture-syntactic-environment
- (lambda (env)
- `(lambda (,id)
- (,(make-syntactic-closure env '() `if)
- ,(close test (list id))
- ,(close return (list id))
- (,(make-syntactic-closure env '() `loop)
- ,(close step (list id)))))))))
- (loop ,(close init '())))))))
-@end group
-@end example
-
-@noindent
-In this case, having captured the desired syntactic environment, it is
-convenient to construct syntactic closures of the identifiers @code{if}
-and the @code{loop} and use them in the body of the
-@code{lambda}.
-
-A common use of @code{capture-syntactic-environment} is to get the
-transformer environment of a macro transformer:
-
-@example
-@group
-(sc-macro-transformer
- (lambda (exp env)
- (capture-syntactic-environment
- (lambda (transformer-env)
- @dots{}))))
-@end group
-@end example
-@end deffn
-
-@node SC Identifiers, , SC Transformer Definition, Syntactic Closures
-@subsubsection Identifiers
-
-This section describes the procedures that create and manipulate
-identifiers. The identifier data type extends the syntactic closures
-facility to be compatible with the high-level @code{syntax-rules}
-facility.
-
-@cindex alias
-As discussed earlier, an identifier is either a symbol or an
-@dfn{alias}. An alias is implemented as a syntactic closure whose
-@var{form} is an identifier:
-
-@example
-@group
-(make-syntactic-closure env '() 'a) @result{} @r{an alias}
-@end group
-@end example
-
-@noindent
-Aliases are implemented as syntactic closures because they behave just
-like syntactic closures most of the time. The difference is that an
-alias may be bound to a new value (for example by @code{lambda} or
-@code{let-syntax}); other syntactic closures may not be used this way.
-If an alias is bound, then within the scope of that binding it is looked
-up in the syntactic environment just like any other identifier.
-
-Aliases are used in the implementation of the high-level facility
-@code{syntax-rules}. A macro transformer created by @code{syntax-rules}
-uses a template to generate its output form, substituting subforms of
-the input form into the template. In a syntactic closures
-implementation, all of the symbols in the template are replaced by
-aliases closed in the transformer environment, while the output form
-itself is closed in the usage environment. This guarantees that the
-macro transformation is hygienic, without requiring the transformer to
-know the syntactic roles of the substituted input subforms.
-
-@deffn procedure identifier? object
-Returns @code{#t} if @var{object} is an identifier, otherwise returns
-@code{#f}. Examples:
-
-@example
-@group
-(identifier? 'a) @result{} #t
-(identifier? (make-syntactic-closure env '() 'a))
- @result{} #t
-
-(identifier? "a") @result{} #f
-(identifier? #\a) @result{} #f
-(identifier? 97) @result{} #f
-(identifier? #f) @result{} #f
-(identifier? '(a)) @result{} #f
-(identifier? '#(a)) @result{} #f
-@end group
-@end example
-@end deffn
-
-The predicate @code{eq?} is used to determine if two identifers are
-``the same''. Thus @code{eq?} can be used to compare identifiers
-exactly as it would be used to compare symbols. Often, though, it is
-useful to know whether two identifiers ``mean the same thing''. For
-example, the @code{cond} macro uses the symbol @code{else} to identify
-the final clause in the conditional. A macro transformer for
-@code{cond} cannot just look for the symbol @code{else}, because the
-@code{cond} form might be the output of another macro transformer that
-replaced the symbol @code{else} with an alias. Instead the transformer
-must look for an identifier that ``means the same thing'' in the usage
-environment as the symbol @code{else} means in the transformer
-environment.
-
-@deffn procedure identifier=? environment1 identifier1 environment2 identifier2
-@var{Environment1} and @var{environment2} must be syntactic
-environments, and @var{identifier1} and @var{identifier2} must be
-identifiers. @code{identifier=?} returns @code{#t} if the meaning of
-@var{identifier1} in @var{environment1} is the same as that of
-@var{identifier2} in @var{environment2}, otherwise it returns @code{#f}.
-Examples:
-
-@example
-@group
-(let-syntax
- ((foo
- (sc-macro-transformer
- (lambda (form env)
- (capture-syntactic-environment
- (lambda (transformer-env)
- (identifier=? transformer-env 'x env 'x)))))))
- (list (foo)
- (let ((x 3))
- (foo))))
- @result{} (#t #f)
-@end group
-
-@group
-(let-syntax ((bar foo))
- (let-syntax
- ((foo
- (sc-macro-transformer
- (lambda (form env)
- (capture-syntactic-environment
- (lambda (transformer-env)
- (identifier=? transformer-env 'foo
- env (cadr form))))))))
- (list (foo foo)
- (foo bar))))
- @result{} (#f #t)
-@end group
-@end example
-@end deffn
-
-Sometimes it is useful to be able to introduce a new identifier that is
-guaranteed to be different from any existing identifier, similarly to
-the way that @code{generate-uninterned-symbol} is used.
-
-@deffn procedure make-synthetic-identifier identifier
-Creates and returns and new synthetic identifier (alias) that is
-guaranteed to be different from all existing identifiers.
-@var{Identifier} is any existing identifier, which is used in deriving
-the name of the new identifier.
-
-This is implemented by syntactically closing @var{identifier} in a
-special empty environment.
-@end deffn
-
-@node Explicit Renaming, , Syntactic Closures, Macros
-@subsection Explicit Renaming
-
-@cindex explicit renaming
-@dfn{Explicit renaming} is an alternative facility for defining macro
-transformers. In the MIT/GNU Scheme implementation, explicit-renaming
-transformers are implemented as an abstraction layer on top of syntactic
-closures. An explicit-renaming macro transformer is defined by an
-instance of the @code{er-macro-transformer} keyword:
-
-@deffn {special form} er-macro-transformer expression
-The @var{expression} is expanded in the syntactic environment of the
-@code{er-macro-transformer} expression, and the expanded expression is
-evaluated in the transformer environment to yield a macro transformer as
-described below. This macro transformer is bound to a macro keyword by
-the special form in which the @code{transformer} expression appears (for
-example, @code{let-syntax}).
-
-@cindex macro transformer
-@cindex input form, to macro
-In the explicit-renaming facility, a @dfn{macro transformer} is a
-procedure that takes three arguments, a form, a renaming procedure, and
-a comparison predicate, and returns a new form. The first argument, the
-@dfn{input form}, is the form in which the macro keyword occurred.
-
-@cindex renaming procedure
-The second argument to a transformation procedure is a @dfn{renaming
-procedure} that takes the representation of an identifier as its
-argument and returns the representation of a fresh identifier that
-occurs nowhere else in the program. For example, the transformation
-procedure for a simplified version of the @code{let} macro might be
-written as
-
-@example
-@group
-(lambda (exp rename compare)
- (let ((vars (map car (cadr exp)))
- (inits (map cadr (cadr exp)))
- (body (cddr exp)))
- `((lambda ,vars ,@@body)
- ,@@inits)))
-@end group
-@end example
-
-@noindent
-This would not be hygienic, however. A hygienic @code{let} macro must
-rename the identifier @code{lambda} to protect it from being captured by
-a local binding. The renaming effectively creates an fresh alias for
-@code{lambda}, one that cannot be captured by any subsequent binding:
-
-@example
-@group
-(lambda (exp rename compare)
- (let ((vars (map car (cadr exp)))
- (inits (map cadr (cadr exp)))
- (body (cddr exp)))
- `((,(rename 'lambda) ,vars ,@@body)
- ,@@inits)))
-@end group
-@end example
-
-The expression returned by the transformation procedure will be expanded
-in the syntactic environment obtained from the syntactic environment of
-the macro application by binding any fresh identifiers generated by the
-renaming procedure to the denotations of the original identifiers in the
-syntactic environment in which the macro was defined. This means that a
-renamed identifier will denote the same thing as the original identifier
-unless the transformation procedure that renamed the identifier placed
-an occurrence of it in a binding position.
-
-The renaming procedure acts as a mathematical function in the sense that
-the identifiers obtained from any two calls with the same argument will
-be the same in the sense of @code{eqv?}. It is an error if the renaming
-procedure is called after the transformation procedure has returned.
-
-@cindex comparison predicate
-The third argument to a transformation procedure is a @dfn{comparison
-predicate} that takes the representations of two identifiers as its
-arguments and returns true if and only if they denote the same thing in
-the syntactic environment that will be used to expand the transformed
-macro application. For example, the transformation procedure for a
-simplified version of the @code{cond} macro can be written as
-
-@example
-@group
-(lambda (exp rename compare)
- (let ((clauses (cdr exp)))
- (if (null? clauses)
- `(,(rename 'quote) unspecified)
- (let* ((first (car clauses))
- (rest (cdr clauses))
- (test (car first)))
- (cond ((and (identifier? test)
- (compare test (rename 'else)))
- `(,(rename 'begin) ,@@(cdr first)))
- (else `(,(rename 'if)
- ,test
- (,(rename 'begin) ,@@(cdr first))
- (cond ,@@rest))))))))))
-@end group
-@end example
-
-@noindent
-In this example the identifier @code{else} is renamed before being passed
-to the comparison predicate, so the comparison will be true if and
-only if the test expression is an identifier that denotes the same
-thing in the syntactic environment of the expression being transformed
-as @code{else} denotes in the syntactic environment in which the @code{cond}
-macro was defined. If @code{else} were not renamed before being passed to
-the comparison predicate, then it would match a local variable that
-happened to be named @code{else}, and the macro would not be hygienic.
-
-Some macros are non-hygienic by design. For example, the following
-defines a @code{loop} macro that implicitly binds @code{exit} to an
-escape procedure. The binding of @code{exit} is intended to capture
-free references to @code{exit} in the body of the loop, so @code{exit}
-is not renamed.
-
-@example
-@group
-(define-syntax loop
- (er-macro-transformer
- (lambda (x r c)
- (let ((body (cdr x)))
- `(,(r 'call-with-current-continuation)
- (,(r 'lambda) (exit)
- (,(r 'let) ,(r 'f) () ,@@body (,(r 'f)))))))))
-@end group
-@end example
-
-Suppose a @code{while} macro is implemented using @code{loop}, with the
-intent that @code{exit} may be used to escape from the @code{while}
-loop. The @code{while} macro cannot be written as
-
-@example
-@group
-(define-syntax while
- (syntax-rules ()
- ((while test body ...)
- (loop (if (not test) (exit #f))
- body ...))))
-@end group
-@end example
-
-@noindent
-because the reference to @code{exit} that is inserted by the
-@code{while} macro is intended to be captured by the binding of
-@code{exit} that will be inserted by the @code{loop} macro. In other
-words, this @code{while} macro is not hygienic. Like @code{loop}, it
-must be written using the @code{er-macro-transformer} syntax:
-
-@example
-@group
-(define-syntax while
- (er-macro-transformer
- (lambda (x r c)
- (let ((test (cadr x))
- (body (cddr x)))
- `(,(r 'loop)
- (,(r 'if) (,(r 'not) ,test) (exit #f))
- ,@@body)))))
-@end group
-@end example
-@end deffn
-
-@node SRFI syntax, , Macros, Special Forms
-@section SRFI syntax
-
-@cindex SRFI syntax
-Several special forms have been introduced to support some of the
-@uref{http://srfi.schemers.org/,Scheme Requests for Implementation}
-(@acronym{SRFI}). Note that MIT/GNU Scheme has for some time supported
-@uref{http://srfi.schemers.org/srfi-23/srfi-23.html,@acronym{SRFI} 23}
-(error-reporting mechanism) and
-@uref{http://srfi.schemers.org/srfi-30/srfi-30.html,@acronym{SRFI} 30}
-(nested multi-line comments), since these @acronym{SRFI}s reflect
-existing practice rather than introducing new functionality.
-
-@menu
-* cond-expand (SRFI 0)::
-* receive (SRFI 8)::
-* define-record-type (SRFI 9)::
-@end menu
-
-@node cond-expand (SRFI 0), receive (SRFI 8), SRFI syntax, SRFI syntax
-@subsection cond-expand (SRFI 0)
-
-@cindex SRFI 0
-@uref{http://srfi.schemers.org/srfi-0/srfi-0.html,@acronym{SRFI} 0}
-is a mechanism for portably determining the availability of
-@uref{http://srfi.schemers.org/,@acronym{SRFI}} @dfn{features}.
-The @code{cond-expand} special form conditionally expands according to
-the features available.
-
-@deffn {special form} cond-expand clause clause dots{}
-Each @var{clause} has the form
-
-@example
-(@var{feature-requirement} @var{expression} @dots{})
-@end example
-
-where @var{feature-requirement} can have one of the following forms:
-
-@example
-@group
-@var{feature-identifier}
-(and @var{feature-requirement} @dots{})
-(or @var{feature-requirement} @dots{})
-(not @var{feature-requirement})
-else
-@end group
-@end example
-
-(Note that at most one @code{else} clause may be present, and it must
-always be the last clause.)
-
-The @code{cond-expand} special form tests for the existence of features
-at macro-expansion time. It either expands into the body of one of its
-@var{clause}s or signals an error during syntactic processing.
-@code{cond-expand} expands into the body of the first @var{clause} whose
-@var{feature-requirement} is currently satisfied (an @code{else}
-@var{clause}, if present, is selected if none of the previous
-@var{clauses} is selected).
-
-A @var{feature-requirement} has an obvious interpretation as a logical
-formula, where the @var{feature-identifier} variables have meaning true
-if the feature corresponding to the @var{feature-identifier}, as
-specified in the @acronym{SRFI} registry, is in effect at the location
-of the @code{cond-expand} form, and false otherwise. A
-@var{feature-requirement} is satisfied if its formula is true under this
-interpretation.
-
-@example
-@group
-(cond-expand
- ((and srfi-1 srfi-10)
- (write 1))
- ((or srfi-1 srfi-10)
- (write 2))
- (else))
-
-(cond-expand
- (command-line
- (define (program-name) (car (argv)))))
-@end group
-@end example
-
-The second example assumes that @code{command-line} is an alias for some
-feature which gives access to command line arguments. Note that an
-error will be signaled at macro-expansion time if this feature is not
-present.
-
-Note that MIT/GNU Scheme allows @code{cond-expand} in any context where a
-special form is allowed. This is an extension of the semantics defined
-by @acronym{SRFI 0}, which only allows @code{cond-expand} at top level.
-@end deffn
-
-@node receive (SRFI 8), define-record-type (SRFI 9), cond-expand (SRFI 0), SRFI syntax
-@subsection receive (SRFI 8)
-
-@cindex SRFI 8
-@uref{http://srfi.schemers.org/srfi-8/srfi-8.html,@acronym{SRFI} 8}
-defines a convenient syntax to bind an identifier to each of the values
-of a multiple-valued expression and then evaluate an expression in the
-scope of the bindings. As an instance of this pattern, consider the
-following excerpt from a @samp{quicksort} procedure:
-
-@example
-@group
-(call-with-values
- (lambda ()
- (partition (precedes pivot) others))
- (lambda (fore aft)
- (append (qsort fore) (cons pivot (qsort aft)))))
-@end group
-@end example
-
-Here @samp{partition} is a multiple-valued procedure that takes two
-arguments, a predicate and a list, and returns two lists, one comprising
-the list elements that satisfy the predicate, the other those that do
-not. The purpose of the expression shown is to partition the list
-@samp{others}, sort each of the sublists, and recombine the results into
-a sorted list.
-
-For our purposes, the important step is the binding of the identifiers
-@samp{fore} and @samp{aft} to the values returned by @samp{partition}.
-Expressing the construction and use of these bindings with the
-call-by-values primitive is cumbersome: One must explicitly embed the
-expression that provides the values for the bindings in a parameterless
-procedure, and one must explicitly embed the expression to be evaluated
-in the scope of those bindings in another procedure, writing as its
-parameters the identifiers that are to be bound to the values received.
-
-These embeddings are boilerplate, exposing the underlying binding
-mechanism but not revealing anything relevant to the particular program
-in which it occurs. So the use of a syntactic abstraction that exposes
-only the interesting parts -- the identifiers to be bound, the
-multiple-valued expression that supplies the values, and the body of the
-receiving procedure -- makes the code more concise and more readable:
-
-@example
-@group
-(receive (fore aft) (partition (precedes pivot) others)
- (append (qsort fore) (cons pivot (qsort aft))))
-@end group
-@end example
-
-The advantages are similar to those of a @samp{let} expression over a
-procedure call with a @samp{lambda} expression as its operator. In both
-cases, cleanly separating a ``header'' in which the bindings are
-established from a ``body'' in which they are used makes it easier to
-follow the code.
-
-@deffn {special form} receive formals expression body
-@var{Formals} and @var{body} are defined as for @samp{lambda}
-(@pxref{Lambda Expressions}). Specifically, @var{formals} can have the
-following forms (the use of @samp{#!optional} and @samp{#!rest} is also
-allowed in @var{formals} but is omitted for brevity):
-
-@table @samp
-@item (@var{ident1} @dots{} @var{identN})
-The environment in which the @samp{receive} expression is evaluated is
-extended by binding @var{ident1}, @dots{}, @var{identN} to fresh
-locations. The @var{expression} is evaluated, and its values are stored
-into those locations. (It is an error if @var{expression} does not have
-exactly @var{N} values.)
-
-@item @var{ident}
-The environment in which the @samp{receive} expression is evaluated is
-extended by binding @var{ident} to a fresh location. The
-@var{expression} is evaluated, its values are converted into a newly
-allocated list, and the list is stored in the location bound to
-@var{ident}.
-
-@item (@var{ident1} @dots{} @var{identN} . @var{identN+1})
-The environment in which the @samp{receive} expression is evaluated is
-extended by binding @var{ident1}, @dots{}, @var{identN+1} to fresh
-locations. The @var{expression} is evaluated. Its first @var{N} values
-are stored into the locations bound to @var{ident1} @dots{} @var{identN}.
-Any remaining values are converted into a newly allocated list, which is
-stored into the location bound to @var{identN+1}. (It is an error if
-@var{expression} does not have at least @var{N} values.)
-@end table
-
-In any case, the expressions in @var{body} are evaluated sequentially in
-the extended environment. The results of the last expression in the
-body are the values of the @samp{receive} expression.
-@end deffn
-
-@node define-record-type (SRFI 9), , receive (SRFI 8), SRFI syntax
-@subsection define-record-type (SRFI 9)
-
-@cindex SRFI 9
-The @samp{define-record-type} syntax described in
-@uref{http://srfi.schemers.org/srfi-9/srfi-9.html,@acronym{SRFI} 9} is a
-slight simplification of one written for Scheme 48 by Jonathan Rees.
-Unlike many record-defining special forms, it does not create any new
-identifiers. Instead, the names of the record type, predicate,
-constructor, and so on are all listed explicitly in the source. This
-has the following advantages:
-
-@itemize @bullet
-@item
-It can be defined using a simple macro in Scheme implementations that
-provide a procedural interface for creating record types.
-
-@item
-It does not restrict users to a particular naming convention.
-
-@item
-Tools like @command{grep} and the GNU Emacs tag facility will see the
-defining occurance of each identifier.
-@end itemize
-
-@deffn {special form} define-record-type type-name (constructor-name field-tag @dots{}) predicate-name field-spec @dots{}
-@var{Type-name}, @var{contructor-name}, @var{field-tag}, and
-@var{predicate-name} are identifiers. @var{Field-spec} has one of these
-two forms:
-
-@example
-@group
-(@var{field-tag} @var{accessor-name})
-(@var{field-tag} @var{accessor-name} @var{modifier-name})
-@end group
-@end example
-
-@noindent
-where @var{field-tag}, @var{accessor-name}, and @var{modifier-name} are
-each identifiers.
-
-@code{define-record-type} is generative: each use creates a new record
-type that is distinct from all existing types, including other record
-types and Scheme's predefined types. Record-type definitions may only
-occur at top-level (there are two possible semantics for ``internal''
-record-type definitions, generative and nongenerative, and no consensus
-as to which is better).
-
-An instance of @code{define-record-type} is equivalent to the following
-definitions:
-
-@itemize @bullet
-@item
-@var{Type-name} is bound to a representation of the record type itself.
-Operations on record types, such as defining print methods, reflection,
-etc.@: are left to other SRFIs.
-
-@item
-@var{constructor-name} is bound to a procedure that takes as many
-arguments as there are @var{field-tag}s in the (@var{constructor-name}
-@dots{}) subform and returns a new @var{type-name} record. Fields whose
-tags are listed with @var{constructor-name} have the corresponding
-argument as their initial value. The initial values of all other fields
-are unspecified.
-
-@item
-@var{predicate-name} is a predicate that returns @code{#t} when given a
-value returned by @var{constructor-name} and @code{#f} for everything
-else.
-
-@item
-Each @var{accessor-name} is a procedure that takes a record of type
-@var{type-name} and returns the current value of the corresponding
-field. It is an error to pass an accessor a value which is not a record
-of the appropriate type.
-
-@item
-Each @var{modifier-name} is a procedure that takes a record of type
-@var{type-name} and a value which becomes the new value of the
-corresponding field; an unspecified value is returned. It is an error
-to pass a modifier a first argument which is not a record of the
-appropriate type.
-@end itemize
-
-Assigning the value of any of these identifiers has no effect on the
-behavior of any of their original values.
-@end deffn
-
-The following
-
-@example
-@group
-(define-record-type :pare
- (kons x y)
- pare?
- (x kar set-kar!)
- (y kdr))
-@end group
-@end example
-
-@noindent
-defines @samp{kons} to be a constructor, @samp{kar} and @samp{kdr} to be
-accessors, @samp{set-kar!} to be a modifier, and @samp{pare?} to be a
-predicate for objects of type @samp{:pare}.
-
-@example
-@group
-(pare? (kons 1 2)) @result{} #t
-(pare? (cons 1 2)) @result{} #f
-(kar (kons 1 2)) @result{} 1
-(kdr (kons 1 2)) @result{} 2
-(let ((k (kons 1 2)))
- (set-kar! k 3)
- (kar k)) @result{} 3
-@end group
-@end example
-
-@node Equivalence Predicates, Numbers, Special Forms, Top
-@chapter Equivalence Predicates
-
-@cindex predicate (defn)
-@cindex predicate, equivalence (defn)
-@cindex equivalence predicate (defn)
-@cindex comparison, for equivalence
-@findex eq?
-@findex eqv?
-@findex equal?
-A @dfn{predicate} is a procedure that always returns a boolean value
-(@code{#t} or @code{#f}). An @dfn{equivalence predicate} is the
-computational analogue of a mathematical equivalence relation (it is
-symmetric, reflexive, and transitive). Of the equivalence predicates
-described in this section, @code{eq?} is the finest or most
-discriminating, and @code{equal?} is the coarsest. @code{eqv?} is
-slightly less discriminating than @code{eq?}.
-
-@deffn procedure eqv? obj1 obj2
-The @code{eqv?} procedure defines a useful equivalence relation on
-objects. Briefly, it returns @code{#t} if @var{obj1} and @var{obj2}
-should normally be regarded as the same object.
-
-The @code{eqv?} procedure returns @code{#t} if:
-
-@itemize @bullet
-@item
-@var{obj1} and @var{obj2} are both @code{#t} or both @code{#f}.
-
-@item
-@var{obj1} and @var{obj2} are both interned symbols and
-
-@example
-@group
-(string=? (symbol->string @var{obj1})
- (symbol->string @var{obj2}))
- @result{} #t
-@end group
-@end example
-@findex string=?
-@findex symbol->string
-
-@item
-@var{obj1} and @var{obj2} are both numbers, are numerically equal
-according to the @code{=} procedure, and are either both exact or both
-inexact (@pxref{Numbers}).
-@findex =
-
-@item
-@var{obj1} and @var{obj2} are both characters and are the same character
-according to the @code{char=?} procedure (@pxref{Characters}).
-@findex char=?
-
-@item
-both @var{obj1} and @var{obj2} are the empty list.
-
-@item
-@var{obj1} and @var{obj2} are procedures whose location tags are equal.
-
-@item
-@var{obj1} and @var{obj2} are pairs, vectors, strings, bit strings,
-records, cells, or weak pairs that denote the same locations in the
-store.
-@end itemize
-
-@noindent
-The @code{eqv?} procedure returns @code{#f} if:
-
-@itemize @bullet
-@item
-@var{obj1} and @var{obj2} are of different types.
-
-@item
-one of @var{obj1} and @var{obj2} is @code{#t} but the other is
-@code{#f}.
-
-@item
-@var{obj1} and @var{obj2} are symbols but
-
-@example
-@group
-(string=? (symbol->string @var{obj1})
- (symbol->string @var{obj2}))
- @result{} #f
-@end group
-@end example
-@findex string=?
-@findex symbol->string
-
-@item
-one of @var{obj1} and @var{obj2} is an exact number but the other is an
-inexact number.
-
-@item
-@var{obj1} and @var{obj2} are numbers for which the @code{=} procedure
-returns @code{#f}.
-@findex =
-
-@item
-@var{obj1} and @var{obj2} are characters for which the @code{char=?}
-procedure returns @code{#f}.
-@findex char=?
-
-@item
-one of @var{obj1} and @var{obj2} is the empty list but the other is not.
-
-@item
-@var{obj1} and @var{obj2} are procedures that would behave differently
-(return a different value or have different side effects) for some
-arguments.
-
-@item
-@var{obj1} and @var{obj2} are pairs, vectors, strings, bit strings,
-records, cells, or weak pairs that denote distinct locations.
-@end itemize
-
-Some examples:
-
-@example
-@group
-(eqv? 'a 'a) @result{} #t
-(eqv? 'a 'b) @result{} #f
-(eqv? 2 2) @result{} #t
-(eqv? '() '()) @result{} #t
-(eqv? 100000000 100000000) @result{} #t
-(eqv? (cons 1 2) (cons 1 2)) @result{} #f
-(eqv? (lambda () 1)
- (lambda () 2)) @result{} #f
-(eqv? #f 'nil) @result{} #f
-(let ((p (lambda (x) x)))
- (eqv? p p)) @result{} #t
-@end group
-@end example
-
-The following examples illustrate cases in which the above rules do not
-fully specify the behavior of @code{eqv?}. All that can be said about
-such cases is that the value returned by @code{eqv?} must be a boolean.
-
-@example
-@group
-(eqv? "" "") @result{} @r{unspecified}
-(eqv? '#() '#()) @result{} @r{unspecified}
-(eqv? (lambda (x) x)
- (lambda (x) x)) @result{} @r{unspecified}
-(eqv? (lambda (x) x)
- (lambda (y) y)) @result{} @r{unspecified}
-@end group
-@end example
-
-The next set of examples shows the use of @code{eqv?} with procedures
-that have local state. @code{gen-counter} must return a distinct
-procedure every time, since each procedure has its own internal counter.
-@code{gen-loser}, however, returns equivalent procedures each time,
-since the local state does not affect the value or side effects of the
-procedures.
-
-@example
-@group
-(define gen-counter
- (lambda ()
- (let ((n 0))
- (lambda () (set! n (+ n 1)) n))))
-(let ((g (gen-counter)))
- (eqv? g g)) @result{} #t
-(eqv? (gen-counter) (gen-counter))
- @result{} #f
-@end group
-
-@group
-(define gen-loser
- (lambda ()
- (let ((n 0))
- (lambda () (set! n (+ n 1)) 27))))
-(let ((g (gen-loser)))
- (eqv? g g)) @result{} #t
-(eqv? (gen-loser) (gen-loser))
- @result{} @r{unspecified}
-@end group
-
-@group
-(letrec ((f (lambda () (if (eqv? f g) 'both 'f)))
- (g (lambda () (if (eqv? f g) 'both 'g)))
- (eqv? f g))
- @result{} @r{unspecified}
-
-(letrec ((f (lambda () (if (eqv? f g) 'f 'both)))
- (g (lambda () (if (eqv? f g) 'g 'both)))
- (eqv? f g))
- @result{} #f
-@end group
-@end example
-
-Objects of distinct types must never be regarded as the same object.
-
-Since it is an error to modify constant objects (those returned by
-literal expressions), the implementation may share structure between
-constants where appropriate. Thus the value of @code{eqv?} on constants
-is sometimes unspecified.
-
-@example
-@group
-(let ((x '(a)))
- (eqv? x x)) @result{} #t
-(eqv? '(a) '(a)) @result{} @r{unspecified}
-(eqv? "a" "a") @result{} @r{unspecified}
-(eqv? '(b) (cdr '(a b))) @result{} @r{unspecified}
-@end group
-@end example
-
-Rationale: The above definition of @code{eqv?} allows implementations
-latitude in their treatment of procedures and literals: implementations
-are free either to detect or to fail to detect that two procedures or
-two literals are equivalent to each other, and can decide whether or not
-to merge representations of equivalent objects by using the same pointer
-or bit pattern to represent both.
-@end deffn
-
-@page
-@deffn procedure eq? obj1 obj2
-@code{eq?} is similar to @code{eqv?} except that in some cases it is
-capable of discerning distinctions finer than those detectable by
-@code{eqv?}.
-
-@code{eq?} and @code{eqv?} are guaranteed to have the same behavior on
-symbols, booleans, the empty list, pairs, records, and non-empty strings
-and vectors. @code{eq?}'s behavior on numbers and characters is
-implementation-dependent, but it will always return either true or
-false, and will return true only when @code{eqv?} would also return
-true. @code{eq?} may also behave differently from @code{eqv?} on empty
-vectors and empty strings.
-
-@example
-@group
-(eq? 'a 'a) @result{} #t
-(eq? '(a) '(a)) @result{} @r{unspecified}
-(eq? (list 'a) (list 'a)) @result{} #f
-(eq? "a" "a") @result{} @r{unspecified}
-(eq? "" "") @result{} @r{unspecified}
-(eq? '() '()) @result{} #t
-(eq? 2 2) @result{} @r{unspecified}
-(eq? #\A #\A) @result{} @r{unspecified}
-(eq? car car) @result{} #t
-(let ((n (+ 2 3)))
- (eq? n n)) @result{} @r{unspecified}
-(let ((x '(a)))
- (eq? x x)) @result{} #t
-(let ((x '#()))
- (eq? x x)) @result{} #t
-(let ((p (lambda (x) x)))
- (eq? p p)) @result{} #t
-@end group
-@end example
-
-Rationale: It will usually be possible to implement @code{eq?} much more
-efficiently than @code{eqv?}, for example, as a simple pointer
-comparison instead of as some more complicated operation. One reason is
-that it may not be possible to compute @code{eqv?} of two numbers in
-constant time, whereas @code{eq?} implemented as pointer comparison will
-always finish in constant time. @code{eq?} may be used like @code{eqv?}
-in applications using procedures to implement objects with state since
-it obeys the same constraints as @code{eqv?}.
-@end deffn
-
-@page
-@deffn procedure equal? obj1 obj2
-@cindex circular structure
-@code{equal?} recursively compares the contents of pairs, vectors, and
-strings, applying @code{eqv?} on other objects such as numbers, symbols,
-and records. A rule of thumb is that objects are generally
-@code{equal?} if they print the same. @code{equal?} may fail to
-terminate if its arguments are circular data structures.
-
-@example
-@group
-(equal? 'a 'a) @result{} #t
-(equal? '(a) '(a)) @result{} #t
-(equal? '(a (b) c)
- '(a (b) c)) @result{} #t
-(equal? "abc" "abc") @result{} #t
-(equal? 2 2) @result{} #t
-(equal? (make-vector 5 'a)
- (make-vector 5 'a)) @result{} #t
-(equal? (lambda (x) x)
- (lambda (y) y)) @result{} @r{unspecified}
-@end group
-@end example
-@end deffn
-
-@node Numbers, Characters, Equivalence Predicates, Top
-@chapter Numbers
-@cindex number
-
-(This section is largely taken from the @cite{Revised^4 Report on the
-Algorithmic Language Scheme}.)
-
-Numerical computation has traditionally been neglected by the Lisp
-community. Until Common Lisp there was no carefully thought out
-strategy for organizing numerical computation, and with the exception of
-the MacLisp system little effort was made to execute numerical code
-efficiently. This report recognizes the excellent work of the Common
-Lisp committee and accepts many of their recommendations. In some ways
-this report simplifies and generalizes their proposals in a manner
-consistent with the purposes of Scheme.
-
-It is important to distinguish between the mathematical numbers, the
-Scheme numbers that attempt to model them, the machine representations
-used to implement the Scheme numbers, and notations used to write
-numbers. This report uses the types @emph{number}, @emph{complex},
-@emph{real}, @emph{rational}, and @emph{integer} to refer to both
-mathematical numbers and Scheme numbers. Machine representations such
-as fixed point and floating point are referred to by names such as
-@emph{fixnum} and @emph{flonum}.
-
-@menu
-* Numerical types::
-* Exactness::
-* Implementation restrictions::
-* Syntax of numerical constants::
-* Numerical operations::
-* Numerical input and output::
-* Fixnum and Flonum Operations::
-* Random Numbers::
-@end menu
-
-@node Numerical types, Exactness, Numbers, Numbers
-@section Numerical types
-@cindex numerical types
-
-Mathematically, numbers may be arranged into a tower of subtypes in
-which each level is a subset of the level above it:
-
-@display
-@group
-number
-complex
-real
-rational
-integer
-@end group
-@end display
-
-For example, 3 is an integer. Therefore 3 is also a rational, a real,
-and a complex. The same is true of the Scheme numbers that model 3.
-For Scheme numbers, these types are defined by the predicates
-@code{number?}, @code{complex?}, @code{real?}, @code{rational?}, and
-@code{integer?}.
-
-There is no simple relationship between a number's type and its
-representation inside a computer. Although most implementations of
-Scheme will offer at least two different representations of 3, these
-different representations denote the same integer.
-
-Scheme's numerical operations treat numbers as abstract data, as
-independent of their representation as possible. Although an
-implementation of Scheme may use fixnum, flonum, and perhaps other
-representations for numbers, this should not be apparent to a casual
-programmer writing simple programs.
-
-It is necessary, however, to distinguish between numbers that are
-represented exactly and those that may not be. For example, indexes
-into data structures must be known exactly, as must some polynomial
-coefficients in a symbolic algebra system. On the other hand, the
-results of measurements are inherently inexact, and irrational numbers
-may be approximated by rational and therefore inexact approximations.
-In order to catch uses of inexact numbers where exact numbers are
-required, Scheme explicitly distinguishes exact from inexact numbers.
-This distinction is orthogonal to the dimension of type.
-
-@node Exactness, Implementation restrictions, Numerical types, Numbers
-@section Exactness
-@cindex exactness
-
-Scheme numbers are either @emph{exact} or @emph{inexact}. A number is
-exact if it was written as an exact constant or was derived from exact
-numbers using only exact operations. A number is inexact if it was
-written as an inexact constant, if it was derived using inexact
-ingredients, or if it was derived using inexact operations. Thus
-inexactness is a contagious property of a number.
-
-If two implementations produce exact results for a computation that did
-not involve inexact intermediate results, the two ultimate results will
-be mathematically equivalent. This is generally not true of
-computations involving inexact numbers since approximate methods such as
-floating point arithmetic may be used, but it is the duty of each
-implementation to make the result as close as practical to the
-mathematically ideal result.
-
-@findex +
-Rational operations such as @code{+} should always produce exact results
-when given exact arguments. If the operation is unable to produce an
-exact result, then it may either report the violation of an
-implementation restriction or it may silently coerce its result to an
-inexact value. @xref{Implementation restrictions}.
-
-@findex inexact->exact
-With the exception of @code{inexact->exact}, the operations described in
-this section must generally return inexact results when given any
-inexact arguments. An operation may, however, return an exact result if
-it can prove that the value of the result is unaffected by the
-inexactness of its arguments. For example, multiplication of any number
-by an exact zero may produce an exact zero result, even if the other
-argument is inexact.
-
-@node Implementation restrictions, Syntax of numerical constants, Exactness, Numbers
-@section Implementation restrictions
-@cindex implementation restriction
-
-Implementations of Scheme are not required to implement the whole tower
-of subtypes (@pxref{Numerical types}), but they must implement a
-coherent subset consistent with both the purposes of the implementation
-and the spirit of the Scheme language. For example, an implementation
-in which all numbers are real may still be quite useful.@footnote{MIT/GNU
-Scheme implements the whole tower of numerical types. It has
-unlimited-precision exact integers and exact rationals. Flonums are
-used to implement all inexact reals; on machines that support @sc{ieee}
-floating-point arithmetic these are double-precision floating-point
-numbers.}
-
-Implementations may also support only a limited range of numbers of any
-type, subject to the requirements of this section. The supported range
-for exact numbers of any type may be different from the supported range
-for inexact numbers of that type. For example, an implementation that
-uses flonums to represent all its inexact real numbers may support a
-practically unbounded range of exact integers and rationals while
-limiting the range of inexact reals (and therefore the range of inexact
-integers and rationals) to the dynamic range of the flonum format.
-Furthermore the gaps between the representable inexact integers and
-rationals are likely to be very large in such an implementation as the
-limits of this range are approached.
-
-@findex length
-@findex vector-length
-@findex string-length
-An implementation of Scheme must support exact integers throughout the
-range of numbers that may be used for indexes of lists, vectors, and
-strings or that may result from computing the length of a list, vector,
-or string. The @code{length}, @code{vector-length}, and
-@code{string-length} procedures must return an exact integer, and it is
-an error to use anything but an exact integer as an index. Furthermore
-any integer constant within the index range, if expressed by an exact
-integer syntax, will indeed be read as an exact integer, regardless of
-any implementation restrictions that may apply outside this range.
-Finally, the procedures listed below will always return an exact integer
-result provided all their arguments are exact integers and the
-mathematically expected result is representable as an exact integer
-within the implementation:
-
-@example
-@group
-* gcd modulo
-+ imag-part numerator
-- inexact->exact quotient
-abs lcm rationalize
-angle magnitude real-part
-ceiling make-polar remainder
-denominator make-rectangular round
-expt max truncate
-floor min
-@end group
-@end example
-
-@findex /
-Implementations are encouraged, but not required, to support exact
-integers and exact rationals of practically unlimited size and
-precision, and to implement the above procedures and the @code{/}
-procedure in such a way that they always return exact results when given
-exact arguments. If one of these procedures is unable to deliver an
-exact result when given exact arguments, then it may either report a
-violation of an implementation restriction or it may silently coerce its
-result to an inexact number. Such a coercion may cause an error
-later.
-
-An implementation may use floating point and other approximate
-representation strategies for inexact numbers. This report recommends,
-but does not require, that the @sc{ieee} 32-bit and 64-bit floating
-point standards be followed by implementations that use flonum
-representations, and that implementations using other representations
-should match or exceed the precision achievable using these floating
-point standards.
-
-@findex sqrt
-In particular, implementations that use flonum representations must
-follow these rules: A flonum result must be represented with at least as
-much precision as is used to express any of the inexact arguments to
-that operation. It is desirable (but not required) for potentially
-inexact operations such as @code{sqrt}, when applied to exact arguments,
-to produce exact answers whenever possible (for example the square root
-of an exact 4 ought to be an exact 2). If, however, an exact number is
-operated upon so as to produce an inexact result (as by @code{sqrt}),
-and if the result is represented as a flonum, then the most precise
-flonum format available must be used; but if the result is represented
-in some other way then the representation must have at least as much
-precision as the most precise flonum format available.
-
-Although Scheme allows a variety of written notations for numbers, any
-particular implementation may support only some of them.@footnote{MIT/GNU
-Scheme implements all of the written notations for numbers.} For
-example, an implementation in which all numbers are real need not
-support the rectangular and polar notations for complex numbers. If an
-implementation encounters an exact numerical constant that it cannot
-represent as an exact number, then it may either report a violation of
-an implementation restriction or it may silently represent the constant
-by an inexact number.
-
-@node Syntax of numerical constants, Numerical operations, Implementation restrictions, Numbers
-@section Syntax of numerical constants
-@cindex number, external representation
-@cindex external representation, for number
-
-@findex #b
-@findex #o
-@findex #d
-@findex #x
-@cindex #b as external representation
-@cindex #o as external representation
-@cindex #d as external representation
-@cindex #x as external representation
-A number may be written in binary, octal, decimal, or hexadecimal by the
-use of a radix prefix. The radix prefixes are @code{#b} (binary),
-@code{#o} (octal), @code{#d} (decimal), and @code{#x} (hexadecimal).
-With no radix prefix, a number is assumed to be expressed in
-decimal.
-
-@findex #e
-@findex #i
-@findex #
-@cindex #e as external representation
-@cindex #i as external representation
-@cindex # in external representation of number
-A numerical constant may be specified to be either exact or inexact by a
-prefix. The prefixes are @code{#e} for exact, and @code{#i} for
-inexact. An exactness prefix may appear before or after any radix
-prefix that is used. If the written representation of a number has no
-exactness prefix, the constant may be either inexact or exact. It is
-inexact if it contains a decimal point, an exponent, or a @code{#}
-character in the place of a digit, otherwise it is exact.
-
-@cindex s, as exponent marker in number
-@cindex f, as exponent marker in number
-@cindex d, as exponent marker in number
-@cindex l, as exponent marker in number
-@cindex e, as exponent marker in number
-@cindex exponent marker (defn)
-@cindex precision, of inexact number
-@cindex numeric precision, inexact
-@cindex internal representation, for inexact number
-@cindex short precision, of inexact number
-@cindex single precision, of inexact number
-@cindex double precision, of inexact number
-@cindex long precision, of inexact number
-In systems with inexact numbers of varying precisions it may be useful
-to specify the precision of a constant. For this purpose, numerical
-constants may be written with an @dfn{exponent marker} that indicates
-the desired precision of the inexact representation. The letters
-@code{s}, @code{f}, @code{d}, and @code{l} specify the use of
-@emph{short}, @emph{single}, @emph{double}, and @emph{long} precision,
-respectively. (When fewer than four internal inexact representations
-exist, the four size specifications are mapped onto those available.
-For example, an implementation with two internal representations may map
-short and single together and long and double together.) In addition,
-the exponent marker @code{e} specifies the default precision for the
-implementation. The default precision has at least as much precision as
-@emph{double}, but implementations may wish to allow this default to be
-set by the user.
-
-@example
-@group
-3.14159265358979F0
- @r{Round to single ---} 3.141593
-0.6L0
- @r{Extend to long ---} .600000000000000
-@end group
-@end example
-
-@node Numerical operations, Numerical input and output, Syntax of numerical constants, Numbers
-@section Numerical operations
-@cindex numerical operations
-
-@xref{Entry Format}, for a summary of the naming conventions used to
-specify restrictions on the types of arguments to numerical routines.
-The examples used in this section assume that any numerical constant
-written using an exact notation is indeed represented as an exact
-number. Some examples also assume that certain numerical constants
-written using an inexact notation can be represented without loss of
-accuracy; the inexact constants were chosen so that this is likely to be
-true in implementations that use flonums to represent inexact
-numbers.
-
-@deffn procedure number? object
-@deffnx procedure complex? object
-@deffnx procedure real? object
-@deffnx procedure rational? object
-@deffnx procedure integer? object
-@cindex type predicate, for number
-These numerical type predicates can be applied to any kind of argument,
-including non-numbers. They return @code{#t} if the object is of the
-named type, and otherwise they return @code{#f}. In general, if a type
-predicate is true of a number then all higher type predicates are also
-true of that number. Consequently, if a type predicate is false of a
-number, then all lower type predicates are also false of that
-number.@footnote{In MIT/GNU Scheme the @code{rational?} procedure is the
-same as @code{real?}, and the @code{complex?} procedure is the same as
-@code{number?}.}
-
-@findex zero?
-@findex =
-If @var{z} is an inexact complex number, then @code{(real? @var{z})} is
-true if and only if @code{(zero? (imag-part @var{z}))} is true. If
-@var{x} is an inexact real number, then @code{(integer? @var{x})} is
-true if and only if @code{(= @var{x} (round @var{x}))}.
-
-@example
-@group
-(complex? 3+4i) @result{} #t
-(complex? 3) @result{} #t
-(real? 3) @result{} #t
-(real? -2.5+0.0i) @result{} #t
-(real? #e1e10) @result{} #t
-(rational? 6/10) @result{} #t
-(rational? 6/3) @result{} #t
-(integer? 3+0i) @result{} #t
-(integer? 3.0) @result{} #t
-(integer? 8/4) @result{} #t
-@end group
-@end example
-
-Note: The behavior of these type predicates on inexact numbers is
-unreliable, since any inaccuracy may affect the result.
-
-@end deffn
-
-@deffn procedure exact? z
-@deffnx procedure inexact? z
-These numerical predicates provide tests for the exactness of a
-quantity. For any Scheme number, precisely one of these predicates is
-true.
-@end deffn
-
-@deffn procedure exact-integer? object
-@deffnx procedure exact-nonnegative-integer? object
-@deffnx procedure exact-rational? object
-These procedures test for some very common types of numbers. These
-tests could be written in terms of simpler predicates, but are more
-efficient.
-@end deffn
-
-@deffn procedure = z1 z2 z3 @dots{}
-@deffnx procedure < x1 x2 x3 @dots{}
-@deffnx procedure > x1 x2 x3 @dots{}
-@deffnx procedure <= x1 x2 x3 @dots{}
-@deffnx procedure >= x1 x2 x3 @dots{}
-@cindex ordering, of numbers
-@cindex comparison, of numbers
-@cindex equivalence predicate, for numbers
-These procedures return @code{#t} if their arguments are (respectively):
-equal, monotonically increasing, monotonically decreasing, monotonically
-nondecreasing, or monotonically nonincreasing.
-
-These predicates are transitive. Note that the traditional
-implementations of these predicates in Lisp-like languages are not
-transitive.
-
-Note: While it is not an error to compare inexact numbers using these
-predicates, the results may be unreliable because a small inaccuracy may
-affect the result; this is especially true of @code{=} and @code{zero?}.
-When in doubt, consult a numerical analyst.
-@end deffn
-
-@deffn procedure zero? z
-@deffnx procedure positive? x
-@deffnx procedure negative? x
-@deffnx procedure odd? x
-@deffnx procedure even? x
-@cindex zero
-@cindex positive number
-@cindex negative number
-@cindex odd number
-@cindex even number
-These numerical predicates test a number for a particular property,
-returning @code{#t} or @code{#f}. See note above regarding inexact
-numbers.
-@end deffn
-
-@deffn procedure max x1 x2 @dots{}
-@deffnx procedure min x1 x2 @dots{}
-@cindex minimum, of numbers
-@cindex maximum, of numbers
-These procedures return the maximum or minimum of their
-arguments.
-
-@example
-@group
-(max 3 4) @result{} 4 @r{; exact}
-(max 3.9 4) @result{} 4.0 @r{; inexact}
-@end group
-@end example
-
-Note: If any argument is inexact, then the result will also be inexact
-(unless the procedure can prove that the inaccuracy is not large enough
-to affect the result, which is possible only in unusual
-implementations). If @code{min} or @code{max} is used to compare
-numbers of mixed exactness, and the numerical value of the result cannot
-be represented as an inexact number without loss of accuracy, then the
-procedure may report a violation of an implementation
-restriction.@footnote{MIT/GNU Scheme signals an error of type
-@code{condition-type:bad-range-argument} in this case.}
-@findex condition-type:bad-range-argument
-@end deffn
-
-@deffn procedure + z1 @dots{}
-@deffnx procedure * z1 @dots{}
-@cindex addition, of numbers
-@cindex sum, of numbers
-@cindex identity, additive
-@cindex multiplication, of numbers
-@cindex product, of numbers
-@cindex identity, multiplicative
-These procedures return the sum or product of their arguments.
-
-@example
-@group
-(+ 3 4) @result{} 7
-(+ 3) @result{} 3
-(+) @result{} 0
-(* 4) @result{} 4
-(*) @result{} 1
-@end group
-@end example
-@end deffn
-
-@deffn procedure - z1 z2 @dots{}
-@deffnx procedure / z1 z2 @dots{}
-@cindex subtraction, of numbers
-@cindex difference, of numbers
-@cindex inverse, additive, of number
-@cindex division, of numbers
-@cindex quotient, of numbers
-@cindex inverse, multiplicative, of number
-With two or more arguments, these procedures return the difference or
-quotient of their arguments, associating to the left. With one
-argument, however, they return the additive or multiplicative inverse of
-their argument.
-
-@example
-@group
-(- 3 4) @result{} -1
-(- 3 4 5) @result{} -6
-(- 3) @result{} -3
-(/ 3 4 5) @result{} 3/20
-(/ 3) @result{} 1/3
-@end group
-@end example
-@end deffn
-
-@deffn procedure 1+ z
-@deffnx procedure -1+ z
-@code{(1+ z)} is equivalent to @code{(+ z 1)}; @code{(-1+ z)} is
-equivalent to @code{(- z 1)}.
-@end deffn
-
-@deffn procedure abs x
-@cindex absolute value, of number
-@cindex magnitude, of real number
-@code{abs} returns the magnitude of its argument.
-
-@example
-(abs -7) @result{} 7
-@end example
-@end deffn
-
-@deffn procedure quotient n1 n2
-@deffnx procedure remainder n1 n2
-@deffnx procedure modulo n1 n2
-@cindex division, of integers
-@cindex quotient, of integers
-@cindex remainder, of integers
-@cindex modulus, of integers
-@cindex integer division
-These procedures implement number-theoretic (integer) division: for
-positive integers @var{n1} and @var{n2}, if @var{n3} and @var{n4} are
-integers such that
-@tex
-$$n_1=n_2n_3+n_4$$
-$$0\leq n_4<n_2$$
-@end tex
-@ifinfo
-
-@example
-@group
-@var{n1} = (@var{n2} * @var{n3}) + @var{n4}
-
-0 <= @var{n4} < @var{n2}
-@end group
-@end example
-
-@end ifinfo
-@noindent
-then
-
-@example
-@group
-(quotient @var{n1} @var{n2}) @result{} @var{n3}
-(remainder @var{n1} @var{n2}) @result{} @var{n4}
-(modulo @var{n1} @var{n2}) @result{} @var{n4}
-@end group
-@end example
-
-@noindent
-For integers @var{n1} and @var{n2} with @var{n2} not equal to 0,
-
-@example
-@group
-(= @var{n1}
- (+ (* @var{n2} (quotient @var{n1} @var{n2}))
- (remainder @var{n1} @var{n2})))
- @result{} #t
-@end group
-@end example
-
-@noindent
-provided all numbers involved in that computation are exact.
-
-The value returned by @code{quotient} always has the sign of the product
-of its arguments. @code{remainder} and @code{modulo} differ on negative
-arguments --- the @code{remainder} always has the sign of the dividend,
-the @code{modulo} always has the sign of the divisor:
-
-@example
-@group
-(modulo 13 4) @result{} 1
-(remainder 13 4) @result{} 1
-
-(modulo -13 4) @result{} 3
-(remainder -13 4) @result{} -1
-
-(modulo 13 -4) @result{} -3
-(remainder 13 -4) @result{} 1
-
-(modulo -13 -4) @result{} -1
-(remainder -13 -4) @result{} -1
-
-(remainder -13 -4.0) @result{} -1.0 @r{; inexact}
-@end group
-@end example
-
-@findex integer-truncate
-Note that @code{quotient} is the same as @code{integer-truncate}.
-@end deffn
-
-@deffn procedure integer-floor n1 n2
-@deffnx procedure integer-ceiling n1 n2
-@deffnx procedure integer-truncate n1 n2
-@deffnx procedure integer-round n1 n2
-These procedures combine integer division with rounding. For example,
-the following are equivalent:
-
-@example
-@group
-(integer-floor @var{n1} @var{n2})
-(floor (/ @var{n1} @var{n2}))
-@end group
-@end example
-
-@noindent
-However, the former is faster and does not produce an intermediate
-result.
-
-@findex quotient
-Note that @code{integer-truncate} is the same as @code{quotient}.
-@end deffn
-
-@deffn procedure integer-divide n1 n2
-@deffnx procedure integer-divide-quotient qr
-@deffnx procedure integer-divide-remainder qr
-@findex quotient
-@findex remainder
-@code{integer-divide} is equivalent to performing both @code{quotient}
-and @code{remainder} at once. The result of @code{integer-divide} is an
-object with two components; the procedures
-@code{integer-divide-quotient} and @code{integer-divide-remainder}
-select those components. These procedures are useful when both the
-quotient and remainder are needed; often computing both of these numbers
-simultaneously is much faster than computing them separately.
-
-For example, the following are equivalent:
-
-@example
-@group
-(lambda (n d)
- (cons (quotient n d)
- (remainder n d)))
-
-(lambda (n d)
- (let ((qr (integer-divide n d)))
- (cons (integer-divide-quotient qr)
- (integer-divide-remainder qr))))
-@end group
-@end example
-@end deffn
-
-@deffn procedure gcd n1 @dots{}
-@deffnx procedure lcm n1 @dots{}
-@cindex greatest common divisor, of numbers
-@cindex least common multiple, of numbers
-These procedures return the greatest common divisor or least common
-multiple of their arguments. The result is always non-negative.
-
-@example
-@group
-(gcd 32 -36) @result{} 4
-(gcd) @result{} 0
-
-(lcm 32 -36) @result{} 288
-(lcm 32.0 -36) @result{} 288.0 @r{; inexact}
-(lcm) @result{} 1
-@end group
-@end example
-@end deffn
-
-@deffn procedure numerator q
-@deffnx procedure denominator q
-These procedures return the numerator or denominator of their argument;
-the result is computed as if the argument was represented as a fraction
-in lowest terms. The denominator is always positive. The denominator
-of 0 is defined to be 1.
-
-@example
-@group
-(numerator (/ 6 4)) @result{} 3
-(denominator (/ 6 4)) @result{} 2
-(denominator (exact->inexact (/ 6 4))) @result{} 2.0
-@end group
-@end example
-@end deffn
-
-@deffn procedure floor x
-@deffnx procedure ceiling x
-@deffnx procedure truncate x
-@deffnx procedure round x
-These procedures return integers. @code{floor} returns the largest
-integer not larger than @var{x}. @code{ceiling} returns the smallest
-integer not smaller than @var{x}. @code{truncate} returns the integer
-closest to @var{x} whose absolute value is not larger than the absolute
-value of @var{x}. @code{round} returns the closest integer to @var{x},
-rounding to even when @var{x} is halfway between two integers.
-
-Rationale: @code{round} rounds to even for consistency with the rounding
-modes required by the @sc{ieee} floating point standard.
-
-Note: If the argument to one of these procedures is inexact, then the
-result will also be inexact. If an exact value is needed, the result
-should be passed to the @code{inexact->exact} procedure (or use one of
-the procedures below).
-
-@example
-@group
-(floor -4.3) @result{} -5.0
-(ceiling -4.3) @result{} -4.0
-(truncate -4.3) @result{} -4.0
-(round -4.3) @result{} -4.0
-
-(floor 3.5) @result{} 3.0
-(ceiling 3.5) @result{} 4.0
-(truncate 3.5) @result{} 3.0
-(round 3.5) @result{} 4.0 @r{; inexact}
-
-(round 7/2) @result{} 4 @r{; exact}
-(round 7) @result{} 7
-@end group
-@end example
-@end deffn
-
-@deffn procedure floor->exact x
-@deffnx procedure ceiling->exact x
-@deffnx procedure truncate->exact x
-@deffnx procedure round->exact x
-These procedures are similar to the preceding procedures except that
-they always return an exact result. For example, the following are
-equivalent
-
-@example
-@group
-(floor->exact x)
-(inexact->exact (floor x))
-@end group
-@end example
-
-@noindent
-except that the former is faster and has fewer range restrictions.
-@end deffn
-
-@deffn procedure rationalize x y
-@deffnx procedure rationalize->exact x y
-@cindex simplest rational (defn)
-@cindex rational, simplest (defn)
-@code{rationalize} returns the @emph{simplest} rational number differing
-from @var{x} by no more than @var{y}. A rational number @var{r1} is
-@emph{simpler} than another rational number @var{r2} if
-@t{@var{r1}=@var{p1}/@var{q1}} and @t{@var{r2}=@var{p2}/@var{q2}} (both
-in lowest terms) and @t{|@var{p1}|<=|@var{p2}|} and
-@t{|@var{q1}|<=|@var{q2}|}. Thus @t{3/5} is simpler than @t{4/7}.
-Although not all rationals are comparable in this ordering (consider
-@t{2/7} and @t{3/5}) any interval contains a rational number that is
-simpler than every other rational number in that interval (the simpler
-@t{2/5} lies between @t{2/7} and @t{3/5}). Note that @t{0=0/1} is the
-simplest rational of all.
-
-@example
-@group
-(rationalize (inexact->exact .3) 1/10) @result{} 1/3 @r{; exact}
-(rationalize .3 1/10) @result{} #i1/3 @r{; inexact}
-@end group
-@end example
-
-@code{rationalize->exact} is similar to @code{rationalize} except that
-it always returns an exact result.
-@end deffn
-
-@deffn procedure simplest-rational x y
-@deffnx procedure simplest-exact-rational x y
-@code{simplest-rational} returns the simplest rational number between
-@var{x} and @var{y} inclusive; @code{simplest-exact-rational} is similar
-except that it always returns an exact result.
-
-These procedures implement the same functionality as @code{rationalize}
-and @code{rationalize->exact}, except that they specify the input range
-by its endpoints; @code{rationalize} specifies the range by its center
-point and its (half-) width.
-@end deffn
-
-@deffn procedure exp z
-@deffnx procedure log z
-@deffnx procedure sin z
-@deffnx procedure cos z
-@deffnx procedure tan z
-@deffnx procedure asin z
-@deffnx procedure acos z
-@deffnx procedure atan z
-@deffnx procedure atan y x
-@findex angle
-@findex make-rectangular
-These procedures compute the usual transcendental functions. @code{log}
-computes the natural logarithm of @var{z} (not the base ten logarithm).
-@code{asin}, @code{acos}, and @code{atan} compute arcsine, arccosine,
-and arctangent, respectively. The two-argument variant of @code{atan}
-computes @code{(angle (make-rectangular @var{x} @var{y}))} (see
-below).
-
-In general, the mathematical functions log, arcsine, arccosine, and
-arctangent are multiply defined. For nonzero real @var{x}, the value of
-log @var{x} is defined to be the one whose imaginary part lies in the
-range minus @var{pi} (exclusive) to @var{pi} (inclusive). log 0 is
-undefined. The value of log @var{z} when @var{z} is complex is defined
-according to the formula
-@tex
-$$\log z = \log {\rm magnitude}(z) + i {\rm angle} (z)$$
-@end tex
-@ifinfo
-
-@example
-log @var{z} = log magnitude(@var{z}) + i angle(@var{z})
-@end example
-
-@end ifinfo
-With log defined this way, the values of arcsine, arccosine, and
-arctangent are according to the following formulae:
-@tex
-$$\sin^{-1} z = -i \log (i z + \sqrt{1 - z^2})$$
-$$\cos^{-1} z = \pi / 2 - \sin^{-1} z$$
-$$\tan^{-1} z = (\log (1 + i z) - \log (1 - i z)) / (2 i)$$
-@end tex
-@ifinfo
-
-@example
-@group
-arcsin(@var{z}) = -i log(i @var{z} + sqrt(1 - @var{z}^2))
-arccos(@var{z}) = pi/2 - arcsin(@var{z})
-arctan(@var{z}) = (log(1 + i @var{z}) + log(1 - i @var{z})) / (2 i)
-@end group
-@end example
-
-@end ifinfo
-The above specification follows @cite{Common Lisp: the Language}, which
-in turn cites @cite{Principal Values and Branch Cuts in Complex APL};
-refer to these sources for more detailed discussion of branch cuts,
-boundary conditions, and implementation of these functions. When it is
-possible these procedures produce a real result from a real
-argument.
-@end deffn
-
-@deffn procedure sqrt z
-Returns the principal square root of @var{z}. The result will have
-either positive real part, or zero real part and non-negative imaginary
-part.
-@end deffn
-
-@deffn procedure expt z1 z2
-Returns @var{z1} raised to the power @var{z2}:
-@tex
-$${z_1}^{z_2} = e^{z_2 \log {z_1}}$$
-$0^0$ is defined to be equal to 1.
-@end tex
-@ifinfo
-
-@example
-@var{z1}^@var{z2} = e^(@var{z2} log @var{z1})
-@end example
-
-@noindent
-0^0 is defined to be equal to 1.
-@end ifinfo
-@end deffn
-
-@deffn procedure make-rectangular x1 x2
-@deffnx procedure make-polar x3 x4
-@deffnx procedure real-part z
-@deffnx procedure imag-part z
-@deffnx procedure magnitude z
-@deffnx procedure angle z
-@deffnx procedure conjugate z
-Suppose @var{x1}, @var{x2}, @var{x3}, and @var{x4} are real numbers and
-@var{z} is a complex number such that
-@tex
- $$ z = x_1 + x_2\hbox{$i$}
- = x_3 \cdot e^{{\displaystyle{\hbox{$i$}} x_4}}$$
-@end tex
-@ifinfo
-
-@example
-@var{z} = @var{x1} + @var{x2} i = @var{x3} e^(i @var{x4})
-@end example
-
-@end ifinfo
-@noindent
-Then @code{make-rectangular} and @code{make-polar} return @var{z},
-@code{real-part} returns @var{x1}, @code{imag-part} returns @var{x2},
-@code{magnitude} returns @var{x3}, and @code{angle} returns @var{x4}.
-In the case of @code{angle}, whose value is not uniquely determined by
-the preceding rule, the value returned will be the one in the range
-minus @var{pi} (exclusive) to @var{pi} (inclusive).
-
-@code{conjugate} returns the complex conjugate of @var{z}.
-@end deffn
-
-@deffn procedure exact->inexact z
-@deffnx procedure inexact->exact z
-@code{exact->inexact} returns an inexact representation of @var{z}. The
-value returned is the inexact number that is numerically closest to the
-argument. If an exact argument has no reasonably close inexact
-equivalent, then a violation of an implementation restriction may be
-reported; MIT/GNU Scheme signals an error of type
-@code{condition-type:bad-range-argument} in this case.
-@findex condition-type:bad-range-argument
-
-@code{inexact->exact} returns an exact representation of @var{z}. The
-value returned is the exact number that is numerically closest to the
-argument. If an inexact argument has no reasonably close exact
-equivalent, then a violation of an implementation restriction may be
-reported; in MIT/GNU Scheme this case does not occur because all inexact
-numbers are representable as exact numbers.
-
-These procedures implement the natural one-to-one correspondence between
-exact and inexact integers throughout an implementation-dependent range.
-@xref{Implementation restrictions}.
-@end deffn
-
-@node Numerical input and output, Fixnum and Flonum Operations, Numerical operations, Numbers
-@section Numerical input and output
-@cindex numerical input and output
-
-@deffn procedure number->string number [radix]
-@var{Radix} must be an exact integer, either 2, 8, 10, or 16. If
-omitted, @var{radix} defaults to 10. The procedure
-@code{number->string} takes a number and a radix and returns as a string
-an external representation of the given number in the given radix such
-that
-
-@example
-@group
-(let ((number @var{number})
- (radix @var{radix}))
- (eqv? number
- (string->number (number->string number radix)
- radix)))
-@end group
-@end example
-
-@noindent
-is true. It is an error if no possible result makes this expression
-true.
-
-If @var{number} is inexact, the radix is 10, and the above expression
-can be satisfied by a result that contains a decimal point, then the
-result contains a decimal point and is expressed using the minimum
-number of digits (exclusive of exponent and trailing zeroes) needed to
-make the above expression true; otherwise the format of the result is
-unspecified.
-
-The result returned by @code{number->string} never contains an explicit
-radix prefix.
-
-Note: The error case can occur only when @var{number} is not a complex
-number or is a complex number with an non-rational real or imaginary
-part.
-
-Rationale: If @var{number} is an inexact number represented using
-flonums, and the radix is 10, then the above expression is normally
-satisfied by a result containing a decimal point. The unspecified case
-allows for infinities, NaNs, and non-flonum representations.
-@end deffn
-
-@defvr variable flonum-parser-fast?
-This variable controls the behavior of @code{string->number} when
-parsing inexact numbers. Specifically, it allows the user to trade off
-accuracy against speed.
-
-When set to its default value, @code{#f}, the parser provides maximal
-accuracy, as required by the Scheme standard. If set to @code{#t}, the
-parser uses faster algorithms that will sometimes introduce small errors
-in the result. The errors affect a few of the least-significant bits of
-the result, and consequently can be tolerated by many applications.
-@end defvr
-
-@defvr variable flonum-unparser-cutoff
-This variable controls the action of @code{number->string} when
-@var{number} is a flonum (and consequently controls all printing of
-flonums). The value of this variable is normally a list of three items:
-
-@table @var
-@item rounding-type
-One of the following symbols: @code{normal}, @code{relative}, or
-@code{absolute}. The symbol @code{normal} means that the number should
-be printed with full precision. The symbol @code{relative} means that
-the number should be rounded to a specific number of digits. The symbol
-@code{absolute} means that the number should be rounded so that there
-are a specific number of digits to the right of the decimal point.
-
-@item precision
-An exact integer. If @var{rounding-type} is @code{normal},
-@var{precision} is ignored. If @var{rounding-type} is @code{relative},
-@var{precision} must be positive, and it specifies the number of digits
-to which the printed representation will be rounded. If
-@var{rounding-type} is @code{absolute}, the printed representation will
-be rounded @var{precision} digits to the right of the decimal point; if
-@var{precision} is negative, the representation is rounded @code{(-
-@var{precision})} digits to the left of the decimal point.
-
-@item format-type
-One of the symbols: @code{normal}, @code{scientific}, or
-@code{engineering}. This specifies the format in which the number will
-be printed.@* @code{scientific} specifies that the number will be printed
-using scientific notation: @code{@var{x}.@var{xxx}e@var{yyy}}. In other
-words, the number is printed as a mantissa between zero inclusive and
-ten exclusive, and an exponent. @code{engineering} is like
-@code{scientific}, except that the exponent is always a power of three,
-and the mantissa is constrained to be between zero inclusive and 1000
-exclusive. If @code{normal} is specified, the number will be printed in
-positional notation if it is ``small enough'', otherwise it is printed
-in scientific notation. A number is ``small enough'' when the number of
-digits that would be printed using positional notation does not exceed
-the number of digits of precision in the underlying floating-point
-number representation; @sc{ieee} double-precision floating-point numbers
-have 17 digits of precision.
-@end table
-
-@noindent
-This three-element list may be abbreviated in two ways. First, the
-symbol @code{normal} may be used, which is equivalent to the list
-@code{(normal 0 normal)}. Second, the third element of the list,
-@var{format-type}, may be omitted, in which case it defaults to
-@code{normal}.
-
-@noindent
-The default value for @code{flonum-unparser-cutoff} is @code{normal}.
-If it is bound to a value different from those described here,
-@code{number->string} issues a warning and acts as though the value had
-been @code{normal}.
-@end defvr
-
-@noindent
-Some examples of @code{flonum-unparser-cutoff}:
-
-@example
-(number->string (* 4 (atan 1 1)))
- @result{} "3.141592653589793"
-(fluid-let ((flonum-unparser-cutoff '(relative 5)))
- (number->string (* 4 (atan 1 1))))
- @result{} "3.1416"
-(fluid-let ((flonum-unparser-cutoff '(relative 5)))
- (number->string (* 4000 (atan 1 1))))
- @result{} "3141.6"
-(fluid-let ((flonum-unparser-cutoff '(relative 5 scientific)))
- (number->string (* 4000 (atan 1 1))))
- @result{} "3.1416e3"
-(fluid-let ((flonum-unparser-cutoff '(relative 5 scientific)))
- (number->string (* 40000 (atan 1 1))))
- @result{} "3.1416e4"
-(fluid-let ((flonum-unparser-cutoff '(relative 5 engineering)))
- (number->string (* 40000 (atan 1 1))))
- @result{} "31.416e3"
-(fluid-let ((flonum-unparser-cutoff '(absolute 5)))
- (number->string (* 4 (atan 1 1))))
- @result{} "3.14159"
-(fluid-let ((flonum-unparser-cutoff '(absolute 5)))
- (number->string (* 4000 (atan 1 1))))
- @result{} "3141.59265"
-(fluid-let ((flonum-unparser-cutoff '(absolute -4)))
- (number->string (* 4e10 (atan 1 1))))
- @result{} "31415930000."
-(fluid-let ((flonum-unparser-cutoff '(absolute -4 scientific)))
- (number->string (* 4e10 (atan 1 1))))
- @result{} "3.141593e10"
-(fluid-let ((flonum-unparser-cutoff '(absolute -4 engineering)))
- (number->string (* 4e10 (atan 1 1))))
- @result{} "31.41593e9"
-(fluid-let ((flonum-unparser-cutoff '(absolute -5)))
- (number->string (* 4e10 (atan 1 1))))
- @result{} "31415900000."
-@end example
-
-@deffn procedure string->number string [radix]
-Returns a number of the maximally precise representation expressed by
-the given @var{string}. @var{Radix} must be an exact integer, either 2,
-8, 10, or 16. If supplied, @var{radix} is a default radix that may be
-overridden by an explicit radix prefix in @var{string} (e.g.@:
-@code{"#o177"}). If @var{radix} is not supplied, then the default radix
-is 10. If @var{string} is not a syntactically valid notation for a
-number, then @code{string->number} returns @code{#f}.
-
-@example
-@group
-(string->number "100") @result{} 100
-(string->number "100" 16) @result{} 256
-(string->number "1e2") @result{} 100.0
-(string->number "15##") @result{} 1500.0
-@end group
-@end example
-
-@noindent
-Note that a numeric representation using a decimal point or an exponent
-marker is not recognized unless @var{radix} is @code{10}.
-@end deffn
-
-@node Fixnum and Flonum Operations, Random Numbers, Numerical input and output, Numbers
-@section Fixnum and Flonum Operations
-
-This section describes numerical operations that are restricted forms of
-the operations described above. These operations are useful because
-they compile very efficiently. However, care should be exercised: if
-used improperly, these operations can return incorrect answers, or even
-malformed objects that confuse the garbage collector.
-
-@menu
-* Fixnum Operations::
-* Flonum Operations::
-@end menu
-
-@node Fixnum Operations, Flonum Operations, Fixnum and Flonum Operations, Fixnum and Flonum Operations
-@subsection Fixnum Operations
-
-@cindex fixnum (defn)
-A @dfn{fixnum} is an exact integer that is small enough to fit in a
-machine word. In MIT/GNU Scheme, fixnums are typically 24 or 26 bits,
-depending on the machine; it is reasonable to assume that fixnums are at
-least 24 bits. Fixnums are signed; they are encoded using 2's
-complement.
-
-All exact integers that are small enough to be encoded as fixnums are
-always encoded as fixnums --- in other words, any exact integer that is
-not a fixnum is too big to be encoded as such. For this reason, small
-constants such as @code{0} or @code{1} are guaranteed to be fixnums.
-
-@deffn procedure fix:fixnum? object
-@cindex type predicate, for fixnum
-Returns @code{#t} if @var{object} is a fixnum; otherwise returns
-@code{#f}.
-@end deffn
-
-Here is an expression that determines the largest fixnum:
-
-@example
-@group
-(let loop ((n 1))
- (if (fix:fixnum? n)
- (loop (* n 2))
- (- n 1)))
-@end group
-@end example
-
-@noindent
-A similar expression determines the smallest fixnum.
-
-@deffn procedure fix:= fixnum fixnum
-@deffnx procedure fix:< fixnum fixnum
-@deffnx procedure fix:> fixnum fixnum
-@deffnx procedure fix:<= fixnum fixnum
-@deffnx procedure fix:>= fixnum fixnum
-@cindex equivalence predicate, for fixnums
-These are the standard order and equality predicates on fixnums. When
-compiled, they do not check the types of their arguments.
-@end deffn
-
-@deffn procedure fix:zero? fixnum
-@deffnx procedure fix:positive? fixnum
-@deffnx procedure fix:negative? fixnum
-These procedures compare their argument to zero. When compiled, they do
-not check the type of their argument. The code produced by the
-following expressions is identical:
-
-@example
-@group
-(fix:zero? @var{fixnum})
-(fix:= @var{fixnum} 0)
-@end group
-@end example
-
-@noindent
-Similarly, @code{fix:positive?} and @code{fix:negative?} produce code
-identical to equivalent expressions using @code{fix:>} and @code{fix:<}.
-@end deffn
-
-@deffn procedure fix:+ fixnum fixnum
-@deffnx procedure fix:- fixnum fixnum
-@deffnx procedure fix:* fixnum fixnum
-@deffnx procedure fix:quotient fixnum fixnum
-@deffnx procedure fix:remainder fixnum fixnum
-@deffnx procedure fix:gcd fixnum fixnum
-@deffnx procedure fix:1+ fixnum
-@deffnx procedure fix:-1+ fixnum
-These procedures are the standard arithmetic operations on fixnums.
-When compiled, they do not check the types of their arguments.
-Furthermore, they do not check to see if the result can be encoded as a
-fixnum. If the result is too large to be encoded as a fixnum, a
-malformed object is returned, with potentially disastrous effect on the
-garbage collector.
-@end deffn
-
-@deffn procedure fix:divide fixnum fixnum
-@findex integer-divide
-@findex integer-divide-quotient
-@findex integer-divide-remainder
-This procedure is like @code{integer-divide}, except that its arguments
-and its results must be fixnums. It should be used in conjunction with
-@code{integer-divide-quotient} and @code{integer-divide-remainder}.
-@end deffn
-
-@cindex logical operations, on fixnums
-@cindex bitwise-logical operations, on fixnums
-The following are @dfn{bitwise-logical} operations on fixnums.
-
-@deffn procedure fix:not fixnum
-This returns the bitwise-logical inverse of its argument. When
-compiled, it does not check the type of its argument.
-
-@example
-@group
-(fix:not 0) @result{} -1
-(fix:not -1) @result{} 0
-(fix:not 1) @result{} -2
-(fix:not -34) @result{} 33
-@end group
-@end example
-@end deffn
-
-@deffn procedure fix:and fixnum fixnum
-This returns the bitwise-logical ``and'' of its arguments. When
-compiled, it does not check the types of its arguments.
-
-@example
-@group
-(fix:and #x43 #x0f) @result{} 3
-(fix:and #x43 #xf0) @result{} #x40
-@end group
-@end example
-@end deffn
-
-@deffn procedure fix:andc fixnum fixnum
-Returns the bitwise-logical ``and'' of the first argument with the
-bitwise-logical inverse of the second argument. When compiled, it does
-not check the types of its arguments.
-
-@example
-@group
-(fix:andc #x43 #x0f) @result{} #x40
-(fix:andc #x43 #xf0) @result{} 3
-@end group
-@end example
-@end deffn
-
-@deffn procedure fix:or fixnum fixnum
-This returns the bitwise-logical ``inclusive or'' of its arguments.
-When compiled, it does not check the types of its arguments.
-
-@example
-@group
-(fix:or #x40 3) @result{} #x43
-(fix:or #x41 3) @result{} #x43
-@end group
-@end example
-@end deffn
-
-@deffn procedure fix:xor fixnum fixnum
-This returns the bitwise-logical ``exclusive or'' of its arguments.
-When compiled, it does not check the types of its arguments.
-
-@example
-@group
-(fix:xor #x40 3) @result{} #x43
-(fix:xor #x41 3) @result{} #x42
-@end group
-@end example
-@end deffn
-
-@deffn procedure fix:lsh fixnum1 fixnum2
-This procedure returns the result of logically shifting @var{fixnum1} by
-@var{fixnum2} bits. If @var{fixnum2} is positive, @var{fixnum1} is
-shifted left; if negative, it is shifted right. When compiled, it does
-not check the types of its arguments, nor the validity of its result.
-
-@example
-@group
-(fix:lsh 1 10) @result{} #x400
-(fix:lsh #x432 -10) @result{} 1
-(fix:lsh -1 3) @result{} -8
-(fix:lsh -128 -4) @result{} #x3FFFF8
-@end group
-@end example
-@end deffn
-
-@node Flonum Operations, , Fixnum Operations, Fixnum and Flonum Operations
-@subsection Flonum Operations
-
-@cindex flonum (defn)
-A @dfn{flonum} is an inexact real number that is implemented as a
-floating-point number. In MIT/GNU Scheme, all inexact real numbers are
-flonums. For this reason, constants such as @code{0.} and @code{2.3}
-are guaranteed to be flonums.
-
-@deffn procedure flo:flonum? object
-@cindex type predicate, for flonum
-Returns @code{#t} if @var{object} is a flonum; otherwise returns @code{#f}.
-@end deffn
-
-@deffn procedure flo:= flonum1 flonum2
-@deffnx procedure flo:< flonum1 flonum2
-@deffnx procedure flo:> flonum1 flonum2
-@cindex equivalence predicate, for flonums
-These procedures are the standard order and equality predicates on
-flonums. When compiled, they do not check the types of their arguments.
-@end deffn
-
-@deffn procedure flo:zero? flonum
-@deffnx procedure flo:positive? flonum
-@deffnx procedure flo:negative? flonum
-Each of these procedures compares its argument to zero. When compiled,
-they do not check the type of their argument.
-@end deffn
-
-@deffn procedure flo:+ flonum1 flonum2
-@deffnx procedure flo:- flonum1 flonum2
-@deffnx procedure flo:* flonum1 flonum2
-@deffnx procedure flo:/ flonum1 flonum2
-These procedures are the standard arithmetic operations on flonums.
-When compiled, they do not check the types of their arguments.
-@end deffn
-
-@deffn procedure flo:finite? flonum
-@vindex +inf
-@vindex -inf
-@vindex NaN
-@cindex positive infinity (@code{+inf})
-@cindex negative infinity (@code{-inf})
-@cindex not a number (@code{NaN})
-The @acronym{IEEE} floating-point number specification supports three
-special ``numbers'': positive infinity (@code{+inf}), negative infinity
-(@code{-inf}), and not-a-number (@code{NaN}). This predicate returns
-@code{#f} if @var{flonum} is one of these objects, and @code{#t} if it
-is any other floating-point number.
-@end deffn
-
-@deffn procedure flo:negate flonum
-This procedure returns the negation of its argument. When compiled, it
-does not check the type of its argument. Equivalent to @code{(flo:- 0.
-@var{flonum})}.
-@end deffn
-
-@deffn procedure flo:abs flonum
-@deffnx procedure flo:exp flonum
-@deffnx procedure flo:log flonum
-@deffnx procedure flo:sin flonum
-@deffnx procedure flo:cos flonum
-@deffnx procedure flo:tan flonum
-@deffnx procedure flo:asin flonum
-@deffnx procedure flo:acos flonum
-@deffnx procedure flo:atan flonum
-@deffnx procedure flo:sqrt flonum
-@deffnx procedure flo:expt flonum1 flonum2
-@deffnx procedure flo:floor flonum
-@deffnx procedure flo:ceiling flonum
-@deffnx procedure flo:truncate flonum
-@deffnx procedure flo:round flonum
-@deffnx procedure flo:floor->exact flonum
-@deffnx procedure flo:ceiling->exact flonum
-@deffnx procedure flo:truncate->exact flonum
-@deffnx procedure flo:round->exact flonum
-These procedures are flonum versions of the corresponding procedures.
-When compiled, they do not check the types of their arguments.
-@end deffn
-
-@deffn procedure flo:atan2 flonum1 flonum2
-@findex atan
-This is the flonum version of @code{atan} with two arguments. When
-compiled, it does not check the types of its arguments.
-@end deffn
-
-@node Random Numbers, , Fixnum and Flonum Operations, Numbers
-@section Random Numbers
-@cindex random number
-@cindex pseudo-random number
-@cindex number, pseudo-random
-
-MIT/GNU Scheme provides a facility for generating pseudo-random numbers.
-The current implementation is a ``subtract-with-carry'' random-number
-generator, based on the algorithm from @cite{A New Class of Random
-Number Generators}, George Marsaglia and Arif Zaman, @cite{The Annals of
-Applied Probability}, Vol.@: 1, No.@: 3, 1991. At the time it was
-implemented, this was a good algorithm for general purposes, but the
-state of the art in random-number generation is constantly changing. If
-necessary, the implementation will be updated to use a new algorithm
-while retaining the same interface.
-
-The interface described here is very similar to that of Common Lisp.
-
-@deffn procedure random modulus [state]
-@var{Modulus} must be a positive real number. @code{random} returns a
-pseudo-random number between zero (inclusive) and @var{modulus}
-(exclusive). The exactness of the returned number is the same as the
-exactness of @var{modulus}. Additionally, if @var{modulus} is an exact
-integer, the returned number will be also. Usually, @var{modulus} is
-either an exact integer or an inexact real; the current implementation
-has been tuned to make these two cases fast.
-
-If @var{state} is given and not @code{#f}, it must be a random-state
-object; otherwise, it defaults to the value of the variable
-@code{*random-state*}. This object is used to maintain the state of the
-pseudo-random-number generator and is altered as a side effect of the
-@code{random} procedure.
-
-@example
-@group
-(random 1.0) @result{} .32744744667719056
-(random 1.0) @result{} .01668326768172354
-(random 10) @result{} 3
-(random 10) @result{} 8
-(random 100) @result{} 38
-(random 100) @result{} 63
-(random 100/3) @result{} 130501475769920525/6755399441055744
-(random 100/3) @result{} 170571694016427575/13510798882111488
-@end group
-@end example
-@end deffn
-
-@deffn procedure flo:random-unit state
-@var{State} must be a random-state object. @code{flo:random-unit}
-returns a pseudo-random number between zero inclusive and one exclusive;
-the returned number is always a flonum and therefore an inexact real
-number. @code{flo:random-unit} is equivalent to @code{random} with a
-@var{modulus} of @code{1.0}, except that it is faster.
-@end deffn
-
-The next three definitions concern random-state objects. In addition to
-these definitions, it is important to know that random-state objects are
-specifically designed so that they can be saved to disk using the
-@code{fasdump} procedure, and later restored using the @code{fasload}
-procedure. This allows a particular random-state object to be saved in
-order to replay a particular pseudo-random sequence.
-
-@defvr variable *random-state*
-This variable holds a data structure, a random-state object, that
-encodes the internal state of the random-number generator that
-@code{random} uses by default. A call to @code{random} will perform a
-side effect on this data structure. This variable may be changed, using
-@code{set!} or @code{fluid-let}, to hold a new random-state object.
-@end defvr
-
-@deffn procedure make-random-state [state]
-This procedure returns a new random-state object, suitable for use as
-the value of the variable @code{*random-state*}, or as the @var{state}
-argument to @code{random}. If @var{state} is not given or @code{#f},
-@code{make-random-state} returns a @emph{copy} of the current
-random-number state object (the value of the variable
-@code{*random-state*}). If @var{state} is a random-state object, a copy
-of that object is returned. If @var{state} is @code{#t}, then a new
-random-state object is returned that has been ``randomly'' initialized
-by some means (such as by a time-of-day clock).
-@end deffn
-
-@deffn procedure random-state? object
-Returns @code{#t} if @var{object} is a random-state object, otherwise
-returns @code{#f}.
-@end deffn
-
-@node Characters, Strings, Numbers, Top
-@chapter Characters
-
-@cindex character (defn)
-Characters are objects that represent printed characters, such as
-letters and digits.@footnote{Some of the details in this section depend
-on the fact that the underlying operating system uses the
-@acronym{ASCII} character set. This may change when someone ports MIT/GNU
-Scheme to a non-@acronym{ASCII} operating system.}
-
-@menu
-* External Representation of Characters::
-* Comparison of Characters::
-* Miscellaneous Character Operations::
-* Internal Representation of Characters::
-* ISO-8859-1 Characters::
-* Character Sets::
-* Unicode::
-@end menu
-
-@node External Representation of Characters, Comparison of Characters, Characters, Characters
-@section External Representation of Characters
-@cindex external representation, for character
-
-@cindex #\ as external representation
-@findex #\
-Characters are written using the notation @code{#\@var{character}} or
-@code{#\@var{character-name}}. For example:
-
-@example
-@group
-#\a @r{; lowercase letter}
-#\A @r{; uppercase letter}
-#\( @r{; left parenthesis}
-#\space @r{; the space character}
-#\newline @r{; the newline character}
-@end group
-@end example
-@findex #\space
-@findex #\newline
-
-@noindent
-Case is significant in @code{#\@var{character}}, but not in
-@code{#\@var{character-name}}. If @var{character} in
-@code{#\@var{character}} is a letter, @var{character} must be followed
-by a delimiter character such as a space or parenthesis. Characters
-written in the @code{#\} notation are self-evaluating; you don't need to
-quote them.
-
-@cindex bucky bit, prefix (defn)
-@cindex control, bucky bit prefix (defn)
-@cindex meta, bucky bit prefix (defn)
-@cindex super, bucky bit prefix (defn)
-@cindex hyper, bucky bit prefix (defn)
-@cindex top, bucky bit prefix (defn)
-A character name may include one or more @dfn{bucky bit} prefixes to
-indicate that the character includes one or more of the keyboard shift
-keys Control, Meta, Super, Hyper, or Top (note that the Control bucky
-bit prefix is not the same as the @acronym{ASCII} control key). The
-bucky bit prefixes and their meanings are as follows (case is not
-significant):
-
-@example
-@group
-Key Bucky bit prefix Bucky bit
---- ---------------- ---------
-
-Meta M- or Meta- 1
-Control C- or Control- 2
-Super S- or Super- 4
-Hyper H- or Hyper- 8
-Top T- or Top- 16
-@end group
-@end example
-
-@noindent
-For example,
-
-@example
-@group
-#\c-a @r{; Control-a}
-#\meta-b @r{; Meta-b}
-#\c-s-m-h-a @r{; Control-Meta-Super-Hyper-A}
-@end group
-@end example
-
-@cindex character, named (defn)
-@cindex name, of character
-The following @var{character-name}s are supported, shown here with their
-@acronym{ASCII} equivalents:
-
-@example
-@group
-Character Name ASCII Name
--------------- ----------
-
-altmode ESC
-backnext US
-backspace BS
-call SUB
-linefeed LF
-page FF
-return CR
-rubout DEL
-space
-tab HT
-@end group
-@end example
-@findex #\altmode
-@findex #\backnext
-@findex #\backspace
-@findex #\call
-@findex #\linefeed
-@findex #\page
-@findex #\return
-@findex #\rubout
-@findex #\space
-@findex #\tab
-
-@noindent
-@cindex newline character (defn)
-@findex #\newline
-In addition, @code{#\newline} is the same as @code{#\linefeed} (but this
-may change in the future, so you should not depend on it). All of the
-standard @acronym{ASCII} names for non-printing characters are supported:
-
-@example
-@group
-NUL SOH STX ETX EOT ENQ ACK BEL
-BS HT LF VT FF CR SO SI
-DLE DC1 DC2 DC3 DC4 NAK SYN ETB
-CAN EM SUB ESC FS GS RS US
-DEL
-@end group
-@end example
-
-@deffn procedure char->name char [slashify?]
-Returns a string corresponding to the printed representation of
-@var{char}. This is the @var{character} or @var{character-name}
-component of the external representation, combined with the appropriate
-bucky bit prefixes.
-
-@example
-@group
-(char->name #\a) @result{} "a"
-(char->name #\space) @result{} "Space"
-(char->name #\c-a) @result{} "C-a"
-(char->name #\control-a) @result{} "C-a"
-@end group
-@end example
-
-@findex read
-@var{Slashify?}, if specified and true, says to insert the necessary
-backslash characters in the result so that @code{read} will parse it
-correctly. In other words, the following generates the external
-representation of @var{char}:
-
-@example
-(string-append "#\\" (char->name @var{char} #t))
-@end example
-
-@noindent
-If @var{slashify?} is not specified, it defaults to @code{#f}.
-@end deffn
-
-@deffn procedure name->char string
-Converts a string that names a character into the character specified.
-If @var{string} does not name any character, @code{name->char} signals
-an error.
-
-@example
-@group
-(name->char "a") @result{} #\a
-(name->char "space") @result{} #\Space
-(name->char "c-a") @result{} #\C-a
-(name->char "control-a") @result{} #\C-a
-@end group
-@end example
-@end deffn
-
-@node Comparison of Characters, Miscellaneous Character Operations, External Representation of Characters, Characters
-@section Comparison of Characters
-@cindex ordering, of characters
-@cindex comparison, of characters
-@cindex equivalence predicates, for characters
-
-@deffn procedure char=? char1 char2
-@deffnx procedure char<? char1 char2
-@deffnx procedure char>? char1 char2
-@deffnx procedure char<=? char1 char2
-@deffnx procedure char>=? char1 char2
-@deffnx {procedure} char-ci=? char1 char2
-@deffnx {procedure} char-ci<? char1 char2
-@deffnx {procedure} char-ci>? char1 char2
-@deffnx {procedure} char-ci<=? char1 char2
-@deffnx {procedure} char-ci>=? char1 char2
-@cindex equivalence predicate, for characters
-Returns @code{#t} if the specified characters are have the appropriate
-order relationship to one another; otherwise returns @code{#f}. The
-@code{-ci} procedures don't distinguish uppercase and lowercase letters.
-
-Character ordering follows these rules:
-
-@itemize @bullet
-@item
-The digits are in order; for example, @code{(char<? #\0 #\9)} returns
-@code{#t}.
-
-@item
-The uppercase characters are in order; for example, @code{(char<? #\A
-#\B)} returns @code{#t}.
-
-@item
-The lowercase characters are in order; for example, @code{(char<? #\a
-#\b)} returns @code{#t}.
-@end itemize
-
-@cindex standard character
-@cindex character, standard
-@findex char-standard?
-In addition, MIT/GNU Scheme orders those characters that satisfy
-@code{char-standard?} the same way that @acronym{ISO-8859-1} does.
-
-Characters are ordered by first comparing their bucky bits part and then
-their code part. In particular, characters without bucky bits come
-before characters with bucky bits.
-@end deffn
-
-@node Miscellaneous Character Operations, Internal Representation of Characters, Comparison of Characters, Characters
-@section Miscellaneous Character Operations
-
-@deffn procedure char? object
-@cindex type predicate, for character
-Returns @code{#t} if @var{object} is a character; otherwise returns
-@code{#f}.
-@end deffn
-
-@deffn procedure char-upcase char
-@deffnx procedure char-downcase char
-@cindex uppercase, character conversion
-@cindex lowercase, character conversion
-@cindex case conversion, of character
-@findex char-ci=?
-Returns the uppercase or lowercase equivalent of @var{char} if
-@var{char} is a letter; otherwise returns @var{char}. These procedures
-return a character @var{char2} such that @code{(char-ci=? @var{char}
-@var{char2})}.
-@end deffn
-
-@deffn procedure char->digit char [radix]
-If @var{char} is a character representing a digit in the given
-@var{radix}, returns the corresponding integer value. If you specify
-@var{radix} (which must be an exact integer between 2 and 36 inclusive),
-the conversion is done in that base, otherwise it is done in base 10.
-If @var{char} doesn't represent a digit in base @var{radix},
-@code{char->digit} returns @code{#f}.
-
-Note that this procedure is insensitive to the alphabetic case of
-@var{char}.
-
-@example
-@group
-(char->digit #\8) @result{} 8
-(char->digit #\e 16) @result{} 14
-(char->digit #\e) @result{} #f
-@end group
-@end example
-@end deffn
-
-@deffn procedure digit->char digit [radix]
-Returns a character that represents @var{digit} in the radix given by
-@var{radix}. @var{Radix} must be an exact integer between 2 and 36
-(inclusive), and defaults to 10. @var{Digit}, which must be an
-exact non-negative integer, should be less than @var{radix}; if
-@var{digit} is greater than or equal to @var{radix}, @code{digit->char}
-returns @code{#f}.
-
-@example
-@group
-(digit->char 8) @result{} #\8
-(digit->char 14 16) @result{} #\E
-@end group
-@end example
-@end deffn
-
-@node Internal Representation of Characters, ISO-8859-1 Characters, Miscellaneous Character Operations, Characters
-@section Internal Representation of Characters
-@cindex internal representation, for character
-
-@cindex character code (defn)
-@cindex character bits (defn)
-@cindex code, of character (defn)
-@cindex bucky bit, of character (defn)
-@cindex ASCII character
-An MIT/GNU Scheme character consists of a @dfn{code} part and a @dfn{bucky
-bits} part. The MIT/GNU Scheme set of characters can represent more
-characters than @acronym{ASCII} can; it includes characters with Super,
-Hyper, and Top bucky bits, as well as Control and Meta. Every
-@acronym{ASCII} character corresponds to some MIT/GNU Scheme character, but not
-vice versa.@footnote{Note that the Control bucky bit is different from
-the @acronym{ASCII} control key. This means that @code{#\SOH} (@acronym{ASCII}
-ctrl-A) is different from @code{#\C-A}. In fact, the Control bucky bit
-is completely orthogonal to the @acronym{ASCII} control key, making possible
-such characters as @code{#\C-SOH}.}
-
-MIT/GNU Scheme uses a 16-bit character code with 5 bucky bits. Normally,
-Scheme uses the least significant 8 bits of the character code to
-contain the @acronym{ISO-8859-1} representation for the character. The
-representation is expanded in order to allow for the use of
-@acronym{UTF-16} in the future.
-
-@deffn procedure make-char code bucky-bits
-@cindex construction, of character
-Builds a character from @var{code} and @var{bucky-bits}. Both
-@var{code} and @var{bucky-bits} must be exact non-negative integers in
-the appropriate range. Use @code{char-code} and @code{char-bits} to
-extract the code and bucky bits from the character. If @code{0} is
-specified for @var{bucky-bits}, @code{make-char} produces an ordinary
-character; otherwise, the appropriate bits are turned on as follows:
-
-@example
-@group
-1 Meta
-2 Control
-4 Super
-8 Hyper
-16 Top
-@end group
-@end example
-
-For example,
-
-@example
-@group
-(make-char 97 0) @result{} #\a
-(make-char 97 1) @result{} #\M-a
-(make-char 97 2) @result{} #\C-a
-(make-char 97 3) @result{} #\C-M-a
-@end group
-@end example
-@end deffn
-
-@deffn procedure char-bits char
-@cindex selection, of character component
-@cindex component selection, of character
-Returns the exact integer representation of @var{char}'s bucky bits.
-For example,
-
-@example
-@group
-(char-bits #\a) @result{} 0
-(char-bits #\m-a) @result{} 1
-(char-bits #\c-a) @result{} 2
-(char-bits #\c-m-a) @result{} 3
-@end group
-@end example
-@end deffn
-
-@deffn procedure char-code char
-Returns the character code of @var{char}, an exact integer. For
-example,
-
-@example
-@group
-(char-code #\a) @result{} 97
-(char-code #\c-a) @result{} 97
-@end group
-@end example
-@end deffn
-
-@defvr variable char-code-limit
-@defvrx variable char-bits-limit
-These variables define the (exclusive) upper limits for the character
-code and bucky bits (respectively). The character code and bucky bits
-are always exact non-negative integers, and are strictly less than the
-value of their respective limit variable.
-@end defvr
-
-@deffn procedure char->integer char
-@deffnx procedure integer->char k
-@code{char->integer} returns the character code representation for
-@var{char}. @code{integer->char} returns the character whose character
-code representation is @var{k}.
-
-@findex char-ascii?
-@findex char->ascii
-In MIT/GNU Scheme, if @code{(char-ascii? @var{char})} is true, then
-
-@example
-(eqv? (char->ascii @var{char}) (char->integer @var{char}))
-@end example
-
-@noindent
-However, this behavior is not required by the Scheme standard, and
-code that depends on it is not portable to other implementations.
-
-@findex char<=?
-@findex <=
-These procedures implement order isomorphisms between the set of
-characters under the @code{char<=?} ordering and some subset of the
-integers under the @code{<=} ordering. That is, if
-
-@example
-(char<=? a b) @result{} #t @r{and} (<= x y) @result{} #t
-@end example
-
-and @code{x} and @code{y} are in the range of @code{char->integer},
-then
-
-@example
-@group
-(<= (char->integer a)
- (char->integer b)) @result{} #t
-(char<=? (integer->char x)
- (integer->char y)) @result{} #t
-@end group
-@end example
-
-Note: If the argument to @code{char->integer} or @code{integer->char} is
-a constant, the compiler will constant-fold the call, replacing it with
-the corresponding result. This is a very useful way to denote unusual
-character constants or @acronym{ASCII} codes.
-@end deffn
-
-@defvr variable char-integer-limit
-The range of @code{char->integer} is defined to be the exact
-non-negative integers that are less than the value of this variable
-(exclusive).
-@end defvr
-
-@node ISO-8859-1 Characters, Character Sets, Internal Representation of Characters, Characters
-@section ISO-8859-1 Characters
-
-MIT/GNU Scheme internally uses @acronym{ISO-8859-1} codes for
-@acronym{I/O}, and stores character objects in a fashion that makes it
-convenient to convert between @acronym{ISO-8859-1} codes and
-characters. Also, character strings are implemented as byte vectors
-whose elements are @acronym{ISO-8859-1} codes; these codes are
-converted to character objects when accessed. For these reasons it is
-sometimes desirable to be able to convert between @acronym{ISO-8859-1}
-codes and characters.
-
-@cindex ISO-8859-1 character (defn)
-@cindex character, ISO-8859-1 (defn)
-Not all characters can be represented as @acronym{ISO-8859-1} codes. A
-character that has an equivalent @acronym{ISO-8859-1} representation is
-called an @dfn{ISO-8859-1 character}.
-
-For historical reasons, the procedures that manipulate
-@acronym{ISO-8859-1} characters use the word ``@acronym{ASCII}'' rather
-than ``@acronym{ISO-8859-1}''.
-
-@deffn procedure char-ascii? char
-Returns the @acronym{ISO-8859-1} code for @var{char} if @var{char} has an
-@acronym{ISO-8859-1} representation; otherwise returns @code{#f}.
-
-In the current implementation, the characters that satisfy this
-predicate are those in which the bucky bits are turned off, and for
-which the character code is less than 256.
-@end deffn
-
-@deffn procedure char->ascii char
-Returns the @acronym{ISO-8859-1} code for @var{char}. An error
-@code{condition-type:bad-range-argument} is signalled if @var{char}
-doesn't have an @acronym{ISO-8859-1} representation.
-@findex condition-type:bad-range-argument
-@end deffn
-
-@deffn procedure ascii->char code
-@var{Code} must be the exact integer representation of an
-@acronym{ISO-8859-1} code. This procedure returns the character
-corresponding to @var{code}.
-@end deffn
-
-@node Character Sets, Unicode, ISO-8859-1 Characters, Characters
-@section Character Sets
-@cindex character set
-@cindex set, of characters
-
-MIT/GNU Scheme's character-set abstraction is used to represent groups of
-characters, such as the letters or digits. Character sets may contain
-only @acronym{ISO-8859-1} characters; in the future this may be changed
-to allow the full range of characters.
-
-There is no meaningful external representation for character sets; use
-@code{char-set-members} to examine their contents. There is (at
-present) no specific equivalence predicate for character sets; use
-@code{equal?} for this purpose.
-
-@deffn procedure char-set? object
-@cindex type predicate, for character set
-Returns @code{#t} if @var{object} is a character set; otherwise returns
-@code{#f}.
-@end deffn
-
-@defvr variable char-set:upper-case
-@defvrx variable char-set:lower-case
-@defvrx variable char-set:alphabetic
-@defvrx variable char-set:numeric
-@defvrx variable char-set:alphanumeric
-@defvrx variable char-set:whitespace
-@defvrx variable char-set:not-whitespace
-@defvrx variable char-set:graphic
-@defvrx variable char-set:not-graphic
-@defvrx variable char-set:standard
-These variables contain predefined character sets.
-To see the contents of one of these sets, use @code{char-set-members}.
-
-@cindex alphabetic character (defn)
-@cindex character, alphabetic (defn)
-@cindex numeric character (defn)
-@cindex character, numeric (defn)
-@cindex alphanumeric character (defn)
-@cindex character, alphanumeric (defn)
-@cindex whitespace character (defn)
-@cindex character, whitespace (defn)
-@cindex graphic character (defn)
-@cindex character, graphic (defn)
-@cindex standard character (defn)
-@cindex character, standard (defn)
-@findex #\space
-@findex #\tab
-@findex #\page
-@findex #\linefeed
-@findex #\return
-@findex #\newline
-@dfn{Alphabetic} characters are the 52 upper and lower case letters.
-@dfn{Numeric} characters are the 10 decimal digits. @dfn{Alphanumeric}
-characters are those in the union of these two sets. @dfn{Whitespace}
-characters are @code{#\space}, @code{#\tab}, @code{#\page},
-@code{#\linefeed}, and @code{#\return}. @var{Graphic} characters are
-the printing characters and @code{#\space}. @var{Standard} characters
-are the printing characters, @code{#\space}, and @code{#\newline}.
-These are the printing characters:
-
-@example
-@group
-! " # $ % & ' ( ) * + , - . /
-0 1 2 3 4 5 6 7 8 9
-: ; < = > ? @@
-A B C D E F G H I J K L M N O P Q R S T U V W X Y Z
-[ \ ] ^ _ `
-a b c d e f g h i j k l m n o p q r s t u v w x y z
-@{ | @} ~
-@end group
-@end example
-@end defvr
-
-@deffn {procedure} char-upper-case? char
-@deffnx {procedure} char-lower-case? char
-@deffnx {procedure} char-alphabetic? char
-@deffnx {procedure} char-numeric? char
-@deffnx procedure char-alphanumeric? char
-@deffnx {procedure} char-whitespace? char
-@deffnx procedure char-graphic? char
-@deffnx procedure char-standard? object
-These predicates are defined in terms of the respective character sets
-defined above.
-@end deffn
-
-@deffn procedure char-set-members char-set
-Returns a newly allocated list of the characters in @var{char-set}.
-@end deffn
-
-@deffn procedure char-set-member? char-set char
-Returns @code{#t} if @var{char} is in @var{char-set}; otherwise returns
-@code{#f}.
-@end deffn
-
-@deffn procedure char-set char @dots{}
-@cindex construction, of character set
-Returns a character set consisting of the specified @acronym{ISO-8859-1}
-characters. With no arguments, @code{char-set} returns an empty
-character set.
-@end deffn
-
-@deffn procedure chars->char-set chars
-Returns a character set consisting of @var{chars}, which must be a list
-of @acronym{ISO-8859-1} characters. This is equivalent to @code{(apply
-char-set @var{chars})}.
-@end deffn
-
-@deffn procedure string->char-set string
-Returns a character set consisting of all the characters that occur in
-@var{string}.
-@end deffn
-
-@deffn procedure ascii-range->char-set lower upper
-@var{Lower} and @var{upper} must be exact non-negative integers
-representing @acronym{ISO-8859-1} character codes, and @var{lower} must
-be less than or equal to @var{upper}. This procedure creates and
-returns a new character set consisting of the characters whose
-@acronym{ISO-8859-1} codes are between @var{lower} (inclusive) and
-@var{upper} (exclusive).
-
-For historical reasons, the name of this procedure refers to
-``@acronym{ASCII}'' rather than ``@acronym{ISO-8859-1}''.
-@end deffn
-
-@deffn procedure predicate->char-set predicate
-@var{Predicate} must be a procedure of one argument.
-@code{predicate->char-set} creates and returns a character set
-consisting of the @acronym{ISO-8859-1} characters for which
-@var{predicate} is true.
-@end deffn
-
-@deffn procedure char-set-difference char-set1 char-set2
-Returns a character set consisting of the characters that are in
-@var{char-set1} but aren't in @var{char-set2}.
-@end deffn
-
-@deffn procedure char-set-intersection char-set @dots{}
-Returns a character set consisting of the characters that are in all of
-the @var{char-set}s.
-@end deffn
-
-@deffn procedure char-set-union char-set @dots{}
-Returns a character set consisting of the characters that are in at
-least one o the @var{char-set}s.
-@end deffn
-
-@deffn procedure char-set-invert char-set
-Returns a character set consisting of the @acronym{ISO-8859-1}
-characters that are not in @var{char-set}.
-@end deffn
-
-@node Unicode, , Character Sets, Characters
-@section Unicode
-
-@cindex Unicode
-MIT/GNU Scheme provides rudimentary support for Unicode characters. In an
-ideal world, Unicode would be the base character set for MIT/GNU Scheme,
-but this implementation predates the invention of Unicode. And
-converting an application of this size is a considerable undertaking.
-So for the time being, the base character set is @acronym{ISO-8859-1}
-and Unicode support is grafted on.
-
-This Unicode support was implemented as a part of the @acronym{XML}
-parser (@pxref{XML Parser}) implementation. @acronym{XML} uses
-Unicode as its base character set, and any @acronym{XML}
-implementation @emph{must} support Unicode.
-
-The Unicode implementation consists of two parts: @acronym{I/O}
-procedures that read and write @acronym{UTF-8} characters, and an
-@dfn{alphabet} abstraction, which is an efficient implementation of
-sets of Unicode code points (similar to the @code{char-set}
-abstraction).
-
-@cindex Code point, Unicode
-The basic unit in a Unicode implementation is the @dfn{code point}.
-
-@deffn procedure unicode-code-point? object
-Returns @code{#t} if @var{object} is a Unicode code point. Code
-points are implemented as exact non-negative integers. Code points
-are further limited, by the Unicode standard, to be strictly less than
-@code{#x80000000}.
-@end deffn
-
-The next few procedures do @acronym{I/O} on code points.
-
-@deffn procedure read-utf8-code-point port
-Reads and returns a @acronym{UTF-8}-encoded code point from
-@var{port}. Returns an end-of-file object if there are no more
-characters available from @var{port}. Signals an error if the input
-stream isn't a valid @acronym{UTF-8} encoding.
-@end deffn
-
-@deffn procedure write-utf8-code-point code-point port
-Writes @var{code-point} to @var{port} in the @acronym{UTF-8} encoding.
-@end deffn
-
-@deffn procedure utf8-string->code-point string
-Reads and returns a @acronym{UTF-8}-encoded code point from
-@var{string}. Equivalent to
-
-@example
-(read-utf8-code-point (string->input-port @var{string}))
-@end example
-@end deffn
-
-@deffn procedure code-point->utf8-string code-point
-Returns a newly-allocated string containing the @acronym{UTF-8}
-encoding of @var{code-point}. Equivalent to
-
-@example
-@group
-(with-string-output-port
- (lambda (port)
- (write-utf8-code-point @var{code-point} port)))
-@end group
-@end example
-@end deffn
-
-@cindex Alphabet, Unicode
-Applications often need to manipulate sets of characters, such as the
-set of alphabetic characters or the set of whitespace characters. The
-@dfn{alphabet} abstraction provides an efficient implementation of
-sets of Unicode code points.
-
-@deffn procedure alphabet? object
-Returns @code{#t} if @var{object} is a Unicode alphabet, otherwise
-returns @code{#f}.
-@end deffn
-
-@deffn procedure code-points->alphabet items
-Returns a Unicode alphabet containing the code points described by
-@var{items}. @var{Items} must satisfy
-@code{well-formed-code-points-list?}.
-@end deffn
-
-@deffn procedure alphabet->code-points alphabet
-Returns a well-formed code-points list that describes the code points
-represented by @var{alphabet}.
-@end deffn
-
-@deffn procedure well-formed-code-points-list? object
-Returns @code{#t} if @var{object} is a well-formed code-points list,
-otherwise returns @code{#f}. A well-formed code-points list is a
-proper list, each element of which is either a code point or a pair of
-code points. A pair of code points represents a contiguous range of
-code points. The @sc{car} of the pair is the lower limit, and the
-@sc{cdr} is the upper limit. Both limits are inclusive, and the lower
-limit must be strictly less than the upper limit.
-@end deffn
-
-@deffn procedure code-point-in-alphabet? code-point alphabet
-Returns @code{#t} if @var{code-point} is a member of @var{alphabet},
-otherwise returns @code{#f}.
-@end deffn
-
-@deffn procedure char-in-alphabet? char alphabet
-Returns @code{#t} if @var{char} is a member of @var{alphabet},
-otherwise returns @code{#f}. Equivalent to
-
-@example
-(code-point-in-alphabet? (char-code @var{char}) @var{alphabet})
-@end example
-@end deffn
-
-Character sets and alphabets can be converted to one another, provided
-that the alphabet contains only 8-bit code points. This is true
-because 8-bit code points in Unicode map directly to
-@acronym{ISO-8859-1} characters, which is what character sets contain.
-
-@deffn procedure char-set->alphabet char-set
-Returns a Unicode alphabet containing the code points that correspond
-to characters that are members of @var{char-set}.
-@end deffn
-
-@deffn procedure alphabet->char-set alphabet
-Returns a character set containing the characters that correspond to
-8-bit code points that are members of @var{alphabet}. (Code points
-outside the 8-bit range are ignored.)
-@end deffn
-
-@deffn procedure string->alphabet string
-Returns a Unicode alphabet containing the code points corresponding to
-the characters in @var{string}. Equivalent to
-
-@example
-(char-set->alphabet (string->char-set @var{string}))
-@end example
-@end deffn
-
-@deffn procedure alphabet->string alphabet
-Returns a newly-allocated string containing the characters
-corresponding to the 8-bit code points in @var{alphabet}. (Code
-points outside the 8-bit range are ignored.)
-@end deffn
-
-@deffn procedure 8-bit-alphabet? alphabet
-Returns @code{#t} if @var{alphabet} contains only 8-bit code points,
-otherwise returns @code{#f}.
-@end deffn
-
-@deffn procedure alphabet+ alphabet @dots{}
-Returns a Unicode alphabet that contains each code point that is a
-member of any of the @var{alphabet} arguments.
-@end deffn
-
-@deffn procedure alphabet- alphabet1 alphabet2
-Returns a Unicode alphabet that contains each code point that is a
-member of @var{alphabet1} and is not a member of @var{alphabet2}.
-@end deffn
-
-@node Strings, Lists, Characters, Top
-@chapter Strings
-
-@cindex string, character (defn)
-@findex char-ascii?
-A @dfn{string} is a mutable sequence of characters. In the current
-implementation of MIT/GNU Scheme, the elements of a string must all
-satisfy the predicate @code{char-ascii?}; if someone ports MIT/GNU
-Scheme to a non-@acronym{ASCII} operating system this requirement will
-change.
-
-@cindex external representation, for string
-@cindex " as external representation
-@cindex double quote, as external representation
-@cindex \ as escape character in string
-@cindex backslash, as escape character in string
-@cindex escape character, for string
-@findex "
-@findex \
-A string is written as a sequence of characters enclosed within double
-quotes @code{" "}. To include a double quote inside a string, precede
-the double quote with a backslash @code{\} (escape it), as in
-
-@example
-"The word \"recursion\" has many meanings."
-@end example
-
-@noindent
-The printed representation of this string is
-
-@example
-The word "recursion" has many meanings.
-@end example
-
-@noindent
-To include a backslash inside a string, precede it with another
-backslash; for example,
-
-@example
-"Use #\\Control-q to quit."
-@end example
-
-@noindent
-The printed representation of this string is
-
-@example
-Use #\Control-q to quit.
-@end example
-
-@findex \t
-@findex \n
-@findex \f
-@findex #\tab
-@findex #\newline
-@findex #\page
-The effect of a backslash that doesn't precede a double quote or
-backslash is unspecified in standard Scheme, but MIT/GNU Scheme specifies
-the effect for three other characters: @code{\t}, @code{\n}, and
-@code{\f}. These escape sequences are respectively translated into the
-following characters: @code{#\tab}, @code{#\newline}, and @code{#\page}.
-Finally, a backslash followed by exactly three octal digits is
-translated into the character whose @acronym{ISO-8859-1} code is those
-digits.
-
-If a string literal is continued from one line to another, the string
-will contain the newline character (@code{#\newline}) at the line break.
-Standard Scheme does not specify what appears in a string literal at a
-line break.
-
-@cindex length, of string (defn)
-@cindex index, of string (defn)
-@cindex valid index, of string (defn)
-@cindex string length (defn)
-@cindex string index (defn)
-The @dfn{length} of a string is the number of characters that it
-contains. This number is an exact non-negative integer that is
-established when the string is created
-(but @pxref{Variable-Length Strings}).
-Each character in a string has an @dfn{index}, which is a
-number that indicates the character's position in the string. The index
-of the first (leftmost) character in a string is 0, and the index of the
-last character is one less than the length of the string. The
-@dfn{valid indexes} of a string are the exact non-negative integers less
-than the length of the string.
-
-@cindex substring (defn)
-@cindex start, of substring (defn)
-@cindex end, of substring (defn)
-A number of the string procedures operate on substrings. A
-@dfn{substring} is a segment of a @var{string}, which is specified by
-two integers @var{start} and @var{end} satisfying these relationships:
-
-@example
-0 <= @var{start} <= @var{end} <= (string-length @var{string})
-@end example
-
-@noindent
-@var{Start} is the index of the first character in the substring, and
-@var{end} is one greater than the index of the last character in the
-substring. Thus if @var{start} and @var{end} are equal, they refer to
-an empty substring, and if @var{start} is zero and @var{end} is the
-length of @var{string}, they refer to all of @var{string}.
-
-@cindex case sensitivity, of string operations
-@cindex -ci, in string procedure name
-Some of the procedures that operate on strings ignore the difference
-between uppercase and lowercase. The versions that ignore case include
-@samp{-ci} (for ``case insensitive'') in their names.
-
-@menu
-* Construction of Strings::
-* Selecting String Components::
-* Comparison of Strings::
-* Alphabetic Case in Strings::
-* Cutting and Pasting Strings::
-* Searching Strings::
-* Matching Strings::
-* Regular Expressions::
-* Modification of Strings::
-* Variable-Length Strings::
-* Byte Vectors::
-@end menu
-
-@node Construction of Strings, Selecting String Components, Strings, Strings
-@section Construction of Strings
-@cindex construction, of string
-
-@deffn {procedure} make-string k [char]
-Returns a newly allocated string of length @var{k}. If you specify
-@var{char}, all elements of the string are initialized to @var{char},
-otherwise the contents of the string are unspecified. @var{Char} must
-satisfy the predicate @code{char-ascii?}.
-
-@example
-(make-string 10 #\x) @result{} "xxxxxxxxxx"
-@end example
-@end deffn
-
-@deffn procedure string char @dots{}
-Returns a newly allocated string consisting of the specified characters.
-The arguments must all satisfy @code{char-ascii?}.
-
-@example
-@group
-(string #\a) @result{} "a"
-(string #\a #\b #\c) @result{} "abc"
-(string #\a #\space #\b #\space #\c) @result{} "a b c"
-(string) @result{} ""
-@end group
-@end example
-@end deffn
-
-@deffn procedure list->string char-list
-@cindex list, converting to string
-@findex string->list
-@var{Char-list} must be a list of @acronym{ISO-8859-1} characters.
-@code{list->string} returns a newly allocated string formed from the
-elements of @var{char-list}. This is equivalent to @code{(apply string
-@var{char-list})}. The inverse of this operation is
-@code{string->list}.
-
-@example
-@group
-(list->string '(#\a #\b)) @result{} "ab"
-(string->list "Hello") @result{} (#\H #\e #\l #\l #\o)
-@end group
-@end example
-@end deffn
-
-@deffn {procedure} string-copy string
-@cindex copying, of string
-Returns a newly allocated copy of @var{string}.
-
-Note regarding variable-length strings: the maximum length of the result
-depends only on the length of @var{string}, not its maximum length. If
-you wish to copy a string and preserve its maximum length, do the
-following:
-
-@example
-@group
-(define (string-copy-preserving-max-length string)
- (let ((length))
- (dynamic-wind
- (lambda ()
- (set! length (string-length string))
- (set-string-length! string
- (string-maximum-length string)))
- (lambda ()
- (string-copy string))
- (lambda ()
- (set-string-length! string length)))))
-@end group
-@end example
-@end deffn
-
-@node Selecting String Components, Comparison of Strings, Construction of Strings, Strings
-@section Selecting String Components
-@cindex selection, of string component
-@cindex component selection, of string
-
-@deffn procedure string? object
-@cindex type predicate, for string
-Returns @code{#t} if @var{object} is a string; otherwise returns
-@code{#f}.
-
-@example
-@group
-(string? "Hi") @result{} #t
-(string? 'Hi) @result{} #f
-@end group
-@end example
-@end deffn
-
-@deffn procedure string-length string
-Returns the length of @var{string} as an exact non-negative integer.
-
-@example
-@group
-(string-length "") @result{} 0
-(string-length "The length") @result{} 10
-@end group
-@end example
-@end deffn
-
-@deffn procedure string-null? string
-@cindex empty string, predicate for
-@cindex null string, predicate for
-Returns @code{#t} if @var{string} has zero length; otherwise returns
-@code{#f}.
-
-@example
-@group
-(string-null? "") @result{} #t
-(string-null? "Hi") @result{} #f
-@end group
-@end example
-@end deffn
-
-@deffn procedure string-ref string k
-Returns character @var{k} of @var{string}. @var{K} must be a valid index
-of @var{string}.
-
-@example
-@group
-(string-ref "Hello" 1) @result{} #\e
-(string-ref "Hello" 5) @error{} 5 not in correct range
-@end group
-@end example
-@end deffn
-
-@deffn {procedure} string-set! string k char
-Stores @var{char} in element @var{k} of @var{string} and returns an
-unspecified value. @var{K} must be a valid index of @var{string}, and
-@var{char} must satisfy the predicate @code{char-ascii?}.
-
-@example
-@group
-(define str "Dog") @result{} @r{unspecified}
-(string-set! str 0 #\L) @result{} @r{unspecified}
-str @result{} "Log"
-(string-set! str 3 #\t) @error{} 3 not in correct range
-@end group
-@end example
-@end deffn
-
-@need 1000
-@node Comparison of Strings, Alphabetic Case in Strings, Selecting String Components, Strings
-@section Comparison of Strings
-@cindex ordering, of strings
-@cindex comparison, of strings
-
-@deffn procedure string=? string1 string2
-@deffnx procedure substring=? string1 start end string2 start end
-@deffnx {procedure} string-ci=? string1 string2
-@deffnx procedure substring-ci=? string1 start end string2 start end
-@cindex equivalence predicate, for strings
-Returns @code{#t} if the two strings (substrings) are the same length
-and contain the same characters in the same (relative) positions;
-otherwise returns @code{#f}. @code{string-ci=?} and
-@code{substring-ci=?} don't distinguish uppercase and lowercase letters,
-but @code{string=?} and @code{substring=?} do.
-
-@example
-@group
-(string=? "PIE" "PIE") @result{} #t
-(string=? "PIE" "pie") @result{} #f
-(string-ci=? "PIE" "pie") @result{} #t
-(substring=? "Alamo" 1 3 "cola" 2 4) @result{} #t @r{; compares "la"}
-@end group
-@end example
-@end deffn
-
-@deffn procedure string<? string1 string2
-@deffnx procedure substring<? string1 start1 end1 string2 start2 end2
-@deffnx procedure string>? string1 string2
-@deffnx procedure string<=? string1 string2
-@deffnx procedure string>=? string1 string2
-@deffnx {procedure} string-ci<? string1 string2
-@deffnx procedure substring-ci<? string1 start1 end1 string2 start2 end2
-@deffnx {procedure} string-ci>? string1 string2
-@deffnx {procedure} string-ci<=? string1 string2
-@deffnx {procedure} string-ci>=? string1 string2
-These procedures compare strings (substrings) according to the order of
-the characters they contain (also @pxref{Comparison of Characters}).
-The arguments are compared using a lexicographic (or dictionary) order.
-If two strings differ in length but are the same up to the length of the
-shorter string, the shorter string is considered to be less than the
-longer string.
-
-@example
-@group
-(string<? "cat" "dog") @result{} #t
-(string<? "cat" "DOG") @result{} #f
-(string-ci<? "cat" "DOG") @result{} #t
-(string>? "catkin" "cat") @result{} #t @r{; shorter is lesser}
-@end group
-@end example
-@end deffn
-
-@deffn procedure string-compare string1 string2 if-eq if-lt if-gt
-@deffnx procedure string-compare-ci string1 string2 if-eq if-lt if-gt
-@var{If-eq}, @var{if-lt}, and @var{if-gt} are procedures of no arguments
-(thunks). The two strings are compared; if they are equal, @var{if-eq}
-is applied, if @var{string1} is less than @var{string2}, @var{if-lt} is
-applied, else if @var{string1} is greater than @var{string2},
-@var{if-gt} is applied. The value of the procedure is the value of the
-thunk that is applied.
-
-@code{string-compare} distinguishes uppercase and lowercase letters;@*
-@code{string-compare-ci} does not.
-
-@example
-@group
-(define (cheer) (display "Hooray!"))
-(define (boo) (display "Boo-hiss!"))
-(string-compare "a" "b" cheer (lambda() 'ignore) boo)
- @print{} Hooray!
- @result{} @r{unspecified}
-@end group
-@end example
-@end deffn
-
-@deffn procedure string-hash string
-@deffnx procedure string-hash-mod string k
-@cindex hashing, of string
-@findex string=?
-@findex =
-@code{string-hash} returns an exact non-negative integer that can be used
-for storing the specified @var{string} in a hash table. Equal strings
-(in the sense of @code{string=?}) return equal (@code{=}) hash codes,
-and non-equal but similar strings are usually mapped to distinct hash
-codes.
-
-@code{string-hash-mod} is like @code{string-hash}, except that it limits
-the result to a particular range based on the exact non-negative integer
-@var{k}. The following are equivalent:
-
-@example
-@group
-(string-hash-mod @var{string} @var{k})
-(modulo (string-hash @var{string}) @var{k})
-@end group
-@end example
-@end deffn
-
-@node Alphabetic Case in Strings, Cutting and Pasting Strings, Comparison of Strings, Strings
-@section Alphabetic Case in Strings
-@cindex alphabetic case, of string
-@cindex case, of string
-@cindex capitalization, of string
-@cindex uppercase, in string
-@cindex lowercase, in string
-
-@deffn procedure string-capitalized? string
-@deffnx procedure substring-capitalized? string start end
-These procedures return @code{#t} if the first word in the string
-(substring) is capitalized, and any subsequent words are either lower
-case or capitalized. Otherwise, they return @code{#f}. A word is
-defined as a non-null contiguous sequence of alphabetic characters,
-delimited by non-alphabetic characters or the limits of the string
-(substring). A word is capitalized if its first letter is upper case
-and all its remaining letters are lower case.
-
-@example
-@group
-(map string-capitalized? '("" "A" "art" "Art" "ART"))
- @result{} (#f #t #f #t #f)
-@end group
-@end example
-@end deffn
-
-@deffn procedure string-upper-case? string
-@deffnx procedure substring-upper-case? string start end
-@deffnx procedure string-lower-case? string
-@deffnx procedure substring-lower-case? string start end
-These procedures return @code{#t} if all the letters in the string
-(substring) are of the correct case, otherwise they return @code{#f}.
-The string (substring) must contain at least one letter or the
-procedures return @code{#f}.
-
-@example
-@group
-(map string-upper-case? '("" "A" "art" "Art" "ART"))
- @result{} (#f #t #f #f #t)
-@end group
-@end example
-@end deffn
-
-@deffn procedure string-capitalize string
-@deffnx procedure string-capitalize! string
-@deffnx procedure substring-capitalize! string start end
-@code{string-capitalize} returns a newly allocated copy of @var{string}
-in which the first alphabetic character is uppercase and the remaining
-alphabetic characters are lowercase. For example, @code{"abcDEF"}
-becomes @code{"Abcdef"}. @code{string-capitalize!} is the destructive
-version of @code{string-capitalize}: it alters @var{string} and returns
-an unspecified value. @code{substring-capitalize!} destructively
-capitalizes the specified part of @var{string}.
-@end deffn
-
-@deffn procedure string-downcase string
-@deffnx procedure string-downcase! string
-@deffnx procedure substring-downcase! string start end
-@code{string-downcase} returns a newly allocated copy of @var{string} in
-which all uppercase letters are changed to lowercase.
-@code{string-downcase!} is the destructive version of
-@code{string-downcase}: it alters @var{string} and returns an
-unspecified value. @code{substring-downcase!} destructively changes the
-case of the specified part of @var{string}.
-
-@example
-@group
-(define str "ABCDEFG") @result{} @r{unspecified}
-(substring-downcase! str 3 5) @result{} @r{unspecified}
-str @result{} "ABCdeFG"
-@end group
-@end example
-@end deffn
-
-@deffn procedure string-upcase string
-@deffnx procedure string-upcase! string
-@deffnx procedure substring-upcase! string start end
-@code{string-upcase} returns a newly allocated copy of @var{string} in
-which all lowercase letters are changed to uppercase.
-@code{string-upcase!} is the destructive version of
-@code{string-upcase}: it alters @var{string} and returns an unspecified
-value. @code{substring-upcase!} destructively changes the case of the
-specified part of @var{string}.
-@end deffn
-
-@node Cutting and Pasting Strings, Searching Strings, Alphabetic Case in Strings, Strings
-@section Cutting and Pasting Strings
-@cindex cutting, of string
-@cindex pasting, of strings
-
-@deffn {procedure} string-append string @dots{}
-@cindex appending, of strings
-Returns a newly allocated string made from the concatenation of the given
-strings. With no arguments, @code{string-append} returns the empty
-string (@code{""}).
-
-@example
-@group
-(string-append) @result{} ""
-(string-append "*" "ace" "*") @result{} "*ace*"
-(string-append "" "" "") @result{} ""
-(eq? str (string-append str)) @result{} #f @r{; newly allocated}
-@end group
-@end example
-@end deffn
-
-@deffn procedure substring string start end
-Returns a newly allocated string formed from the characters of
-@var{string} beginning with index @var{start} (inclusive) and ending
-with @var{end} (exclusive).
-
-@example
-@group
-(substring "" 0 0) @result{} ""
-(substring "arduous" 2 5) @result{} "duo"
-(substring "arduous" 2 8) @error{} 8 not in correct range
-
-(define (string-copy s)
- (substring s 0 (string-length s)))
-@end group
-@end example
-@end deffn
-
-@deffn procedure string-head string end
-Returns a newly allocated copy of the initial substring of @var{string},
-up to but excluding @var{end}. It could have been defined by:
-
-@example
-@group
-(define (string-head string end)
- (substring string 0 end))
-@end group
-@end example
-@end deffn
-
-@deffn procedure string-tail string start
-Returns a newly allocated copy of the final substring of @var{string},
-starting at index @var{start} and going to the end of @var{string}. It
-could have been defined by:
-
-@example
-@group
-(define (string-tail string start)
- (substring string start (string-length string)))
-
-(string-tail "uncommon" 2) @result{} "common"
-@end group
-@end example
-@end deffn
-
-@deffn procedure string-pad-left string k [char]
-@deffnx procedure string-pad-right string k [char]
-@cindex padding, of string
-@findex #\space
-These procedures return a newly allocated string created by padding
-@var{string} out to length @var{k}, using @var{char}. If @var{char} is
-not given, it defaults to @code{#\space}. If @var{k} is less than the
-length of @var{string}, the resulting string is a truncated form of
-@var{string}. @code{string-pad-left} adds padding characters or
-truncates from the beginning of the string (lowest indices), while
-@code{string-pad-right} does so at the end of the string (highest
-indices).
-
-@example
-@group
-(string-pad-left "hello" 4) @result{} "ello"
-(string-pad-left "hello" 8) @result{} " hello"
-(string-pad-left "hello" 8 #\*) @result{} "***hello"
-(string-pad-right "hello" 4) @result{} "hell"
-(string-pad-right "hello" 8) @result{} "hello "
-@end group
-@end example
-@end deffn
-
-@deffn procedure string-trim string [char-set]
-@deffnx procedure string-trim-left string [char-set]
-@deffnx procedure string-trim-right string [char-set]
-@cindex trimming, of string
-@findex char-set:whitespace
-Returns a newly allocated string created by removing all characters that
-are not in @var{char-set} from: (@code{string-trim}) both ends of
-@var{string}; (@code{string-trim-left}) the beginning of @var{string};
-or (@code{string-trim-right}) the end of @var{string}. @var{Char-set}
-defaults to @code{char-set:not-whitespace}.
-
-@example
-@group
-(string-trim " in the end ") @result{} "in the end"
-(string-trim " ") @result{} ""
-(string-trim "100th" char-set:numeric) @result{} "100"
-(string-trim-left "-.-+-=-" (char-set #\+))
- @result{} "+-=-"
-(string-trim "but (+ x y) is" (char-set #\( #\)))
- @result{} "(+ x y)"
-@end group
-@end example
-@end deffn
-
-@node Searching Strings, Matching Strings, Cutting and Pasting Strings, Strings
-@section Searching Strings
-@cindex searching, of string
-@cindex character, searching string for
-@cindex substring, searching string for
-
-The first few procedures in this section perform @dfn{string search}, in
-which a given string (the @dfn{text}) is searched to see if it contains
-another given string (the @dfn{pattern}) as a proper substring. At
-present these procedures are implemented using a hybrid strategy. For
-short patterns of less than 4 characters, the naive string-search
-algorithm is used. For longer patterns, the Boyer-Moore string-search
-algorithm is used.
-
-@deffn procedure string-search-forward pattern string
-@deffnx procedure substring-search-forward pattern string start end
-@var{Pattern} must be a string. Searches @var{string} for the leftmost
-occurrence of the substring @var{pattern}. If successful, the index of
-the first character of the matched substring is returned; otherwise,
-@code{#f} is returned.
-
-@code{substring-search-forward} limits its search to the specified
-substring of @var{string}; @code{string-search-forward} searches all of
-@var{string}.
-
-@example
-@group
-(string-search-forward "rat" "pirate")
- @result{} 2
-(string-search-forward "rat" "pirate rating")
- @result{} 2
-(substring-search-forward "rat" "pirate rating" 4 13)
- @result{} 7
-(substring-search-forward "rat" "pirate rating" 9 13)
- @result{} #f
-@end group
-@end example
-@end deffn
-
-@deffn procedure string-search-backward pattern string
-@deffnx procedure substring-search-backward pattern string start end
-@var{Pattern} must be a string. Searches @var{string} for the rightmost
-occurrence of the substring @var{pattern}. If successful, the index to
-the right of the last character of the matched substring is returned;
-otherwise, @code{#f} is returned.
-
-@code{substring-search-backward} limits its search to the specified
-substring of @var{string}; @code{string-search-backward} searches all of
-@var{string}.
-
-@example
-@group
-(string-search-backward "rat" "pirate")
- @result{} 5
-(string-search-backward "rat" "pirate rating")
- @result{} 10
-(substring-search-backward "rat" "pirate rating" 1 8)
- @result{} 5
-(substring-search-backward "rat" "pirate rating" 9 13)
- @result{} #f
-@end group
-@end example
-@end deffn
-
-@deffn procedure string-search-all pattern string
-@deffnx procedure substring-search-all pattern string start end
-@var{Pattern} must be a string. Searches @var{string} to find all
-occurrences of the substring @var{pattern}. Returns a list of the
-occurrences; each element of the list is an index pointing to the first
-character of an occurrence.
-
-@code{substring-search-all} limits its search to the specified substring
-of @var{string}; @code{string-search-all} searches all of @var{string}.
-
-@example
-@group
-(string-search-all "rat" "pirate")
- @result{} (2)
-(string-search-all "rat" "pirate rating")
- @result{} (2 7)
-(substring-search-all "rat" "pirate rating" 4 13)
- @result{} (7)
-(substring-search-all "rat" "pirate rating" 9 13)
- @result{} ()
-@end group
-@end example
-@end deffn
-
-@deffn procedure substring? pattern string
-@var{Pattern} must be a string. Searches @var{string} to see if it
-contains the substring @var{pattern}. Returns @code{#t} if
-@var{pattern} is a substring of @var{string}, otherwise returns
-@code{#f}.
-
-@example
-@group
-(substring? "rat" "pirate") @result{} #t
-(substring? "rat" "outrage") @result{} #f
-(substring? "" any-string) @result{} #t
-(if (substring? "moon" text)
- (process-lunar text)
- 'no-moon)
-@end group
-@end example
-@end deffn
-
-@deffn procedure string-find-next-char string char
-@deffnx procedure substring-find-next-char string start end char
-@deffnx procedure string-find-next-char-ci string char
-@deffnx procedure substring-find-next-char-ci string start end char
-Returns the index of the first occurrence of @var{char} in the string
-(substring); returns @code{#f} if @var{char} does not appear in the
-string. For the substring procedures, the index returned is relative to
-the entire string, not just the substring. The @code{-ci} procedures
-don't distinguish uppercase and lowercase letters.
-
-@example
-@group
-(string-find-next-char "Adam" #\A) @result{} 0
-(substring-find-next-char "Adam" 1 4 #\A) @result{} #f
-(substring-find-next-char-ci "Adam" 1 4 #\A) @result{} 2
-@end group
-@end example
-@end deffn
-
-@deffn procedure string-find-next-char-in-set string char-set
-@deffnx procedure substring-find-next-char-in-set string start end char-set
-Returns the index of the first character in the string (or substring)
-that is also in @var{char-set}, or returns @code{#f} if none of the
-characters in @var{char-set} occur in @var{string}.
-For the substring procedure, only the substring is searched, but the
-index returned is relative to the entire string, not just the substring.
-
-@example
-@group
-(string-find-next-char-in-set my-string char-set:alphabetic)
- @result{} @r{start position of the first word in} my-string
-@r{; Can be used as a predicate:}
-(if (string-find-next-char-in-set my-string
- (char-set #\( #\) ))
- 'contains-parentheses
- 'no-parentheses)
-@end group
-@end example
-@end deffn
-
-@deffn procedure string-find-previous-char string char
-@deffnx procedure substring-find-previous-char string start end char
-@deffnx procedure string-find-previous-char-ci string char
-@deffnx procedure substring-find-previous-char-ci string start end char
-Returns the index of the last occurrence of @var{char} in the string
-(substring); returns @code{#f} if @var{char} doesn't appear in the
-string. For the substring procedures, the index returned is relative to
-the entire string, not just the substring. The @code{-ci} procedures
-don't distinguish uppercase and lowercase letters.
-@end deffn
-
-@deffn procedure string-find-previous-char-in-set string char-set
-@deffnx procedure substring-find-previous-char-in-set string start end char-set
-Returns the index of the last character in the string (substring) that
-is also in @var{char-set}. For the substring procedure, the index
-returned is relative to the entire string, not just the substring.
-@end deffn
-
-@node Matching Strings, Regular Expressions, Searching Strings, Strings
-@section Matching Strings
-@cindex matching, of strings
-
-@deffn procedure string-match-forward string1 string2
-@deffnx procedure substring-match-forward string1 start end string2 start end
-@deffnx procedure string-match-forward-ci string1 string2
-@deffnx procedure substring-match-forward-ci string1 start end string2 start end
-Compares the two strings (substrings), starting from the beginning, and
-returns the number of characters that are the same. If the two strings
-(substrings) start differently, returns 0. The @code{-ci} procedures
-don't distinguish uppercase and lowercase letters.
-
-@example
-@group
-(string-match-forward "mirror" "micro") @result{} 2 @r{; matches "mi"}
-(string-match-forward "a" "b") @result{} 0 @r{; no match}
-@end group
-@end example
-@end deffn
-
-@deffn procedure string-match-backward string1 string2
-@deffnx procedure substring-match-backward string1 start end string2 start end
-@deffnx procedure string-match-backward-ci string1 string2
-@deffnx procedure substring-match-backward-ci string1 start end string2 start end
-Compares the two strings (substrings), starting from the end and
-matching toward the front, returning the number of characters that are
-the same. If the two strings (substrings) end differently, returns 0.
-The @code{-ci} procedures don't distinguish uppercase and lowercase
-letters.
-
-@example
-@group
-(string-match-backward-ci "BULBOUS" "fractious")
- @result{} 3 @r{; matches "ous"}
-@end group
-@end example
-@end deffn
-
-@deffn procedure string-prefix? string1 string2
-@deffnx procedure substring-prefix? string1 start1 end1 string2 start2 end2
-@deffnx procedure string-prefix-ci? string1 string2
-@deffnx procedure substring-prefix-ci? string1 start1 end1 string2 start2 end2
-@cindex prefix, of string
-These procedures return @code{#t} if the first string (substring) forms
-the prefix of the second; otherwise returns @code{#f}. The @code{-ci}
-procedures don't distinguish uppercase and lowercase letters.
-
-@example
-@group
-(string-prefix? "abc" "abcdef") @result{} #t
-(string-prefix? "" any-string) @result{} #t
-@end group
-@end example
-@end deffn
-
-@deffn procedure string-suffix? string1 string2
-@deffnx procedure substring-suffix? string1 start1 end1 string2 start2 end2
-@deffnx procedure string-suffix-ci? string1 string2
-@deffnx procedure substring-suffix-ci? string1 start1 end1 string2 start2 end2
-@cindex suffix, of string
-These procedures return @code{#t} if the first string (substring) forms
-the suffix of the second; otherwise returns @code{#f}. The @code{-ci}
-procedures don't distinguish uppercase and lowercase letters.
-
-@example
-@group
-(string-suffix? "ous" "bulbous") @result{} #t
-(string-suffix? "" any-string) @result{} #t
-@end group
-@end example
-@end deffn
-
-@node Regular Expressions, Modification of Strings, Matching Strings, Strings
-@section Regular Expressions
-
-MIT/GNU Scheme provides support for using regular expressions to search and
-match strings. This manual does not define regular expressions; instead
-see @ref{Regexps, , Syntax of Regular Expressions, emacs, The Emacs
-Editor}.
-
-In addition to providing standard regular-expression support, MIT/GNU
-Scheme also provides the @acronym{REXP} abstraction. This is an
-alternative way to write regular expressions that is easier to read
-and understand than the standard notation. Regular expressions
-written in this notation can be translated into the standard
-notation.
-
-The regular-expression support is a run-time-loadable option. To use
-it, execute
-
-@example
-(load-option 'regular-expression)
-@end example
-
-@noindent
-once before calling any of the procedures defined here.
-
-@menu
-* Regular-expression procedures::
-* REXP abstraction::
-@end menu
-
-@node Regular-expression procedures, REXP abstraction, Regular Expressions, Regular Expressions
-@subsection Regular-expression procedures
-@cindex searching, for regular expression
-@cindex regular expression, searching string for
-
-Procedures that perform regular-expression match and search accept
-standardized arguments. @var{Regexp} is the regular expression; it is a
-string. @var{String} is the string being matched or searched.
-Procedures that operate on substrings also accept @var{start} and
-@var{end} index arguments with the usual meaning. The optional argument
-@var{case-fold?} says whether the match/search is case-sensitive; if
-@var{case-fold?} is @code{#f}, it is case-sensitive, otherwise it is
-case-insensitive. The optional argument @var{syntax-table} is a
-character syntax table that defines the character syntax, such as which
-characters are legal word constituents. This feature is primarily for
-Edwin, so character syntax tables will not be documented here.
-Supplying @code{#f} for (or omitting) @var{syntax-table} will select the
-default character syntax, equivalent to Edwin's @code{fundamental}
-mode.
-
-@deffn procedure re-string-match regexp string [case-fold? [syntax-table]]
-@deffnx procedure re-substring-match regexp string start end [case-fold? [syntax-table]]
-These procedures match @var{regexp} against the respective string or
-substring, returning @code{#f} for no match, or a set of match registers
-(see below) if the match succeeds. Here is an example showing how to
-extract the matched substring:
-
-@example
-@group
-(let ((r (re-substring-match @var{regexp} @var{string} @var{start} @var{end})))
- (and r
- (substring @var{string} @var{start} (re-match-end-index 0 r))))
-@end group
-@end example
-@end deffn
-
-@deffn procedure re-string-search-forward regexp string [case-fold? [syntax-table]]
-@deffnx procedure re-substring-search-forward regexp string start end [case-fold? [syntax-table]]
-Searches @var{string} for the leftmost substring matching @var{regexp}.
-Returns a set of match registers (see below) if the search is
-successful, or @code{#f} if it is unsuccessful.
-
-@code{re-substring-search-forward} limits its search to the specified
-substring of @var{string}; @code{re-string-search-forward} searches all
-of @var{string}.
-@end deffn
-
-@deffn procedure re-string-search-backward regexp string [case-fold? [syntax-table]]
-@deffnx procedure re-substring-search-backward regexp string start end [case-fold? [syntax-table]]
-Searches @var{string} for the rightmost substring matching @var{regexp}.
-Returns a set of match registers (see below) if the search is
-successful, or @code{#f} if it is unsuccessful.
-
-@code{re-substring-search-backward} limits its search to the specified
-substring of @var{string}; @code{re-string-search-backward} searches all
-of @var{string}.
-@end deffn
-
-When a successful match or search occurs, the above procedures return a
-set of @dfn{match registers}. The match registers are a set of index
-registers that record indexes into the matched string. Each index
-register corresponds to an instance of the regular-expression grouping
-operator @samp{\(}, and records the start index (inclusive) and end
-index (exclusive) of the matched group. These registers are numbered
-from @code{1} to @code{9}, corresponding left-to-right to the grouping
-operators in the expression. Additionally, register @code{0}
-corresponds to the entire substring matching the regular expression.
-
-@deffn procedure re-match-start-index n registers
-@deffnx procedure re-match-end-index n registers
-@var{N} must be an exact integer between @code{0} and @code{9}
-inclusive. @var{Registers} must be a match-registers object as returned
-by one of the regular-expression match or search procedures above.
-@code{re-match-start-index} returns the start index of the corresponding
-regular-expression register, and @code{re-match-end-index} returns the
-corresponding end index.
-@end deffn
-
-@deffn procedure re-match-extract string registers n
-@var{Registers} must be a match-registers object as returned by one of
-the regular-expression match or search procedures above. @var{String}
-must be the string that was passed as an argument to the procedure that
-returned @var{registers}. @var{N} must be an exact integer between
-@code{0} and @code{9} inclusive. If the matched regular expression
-contained @var{m} grouping operators, then the value of this procedure
-is undefined for @var{n} strictly greater than @var{m}.
-
-This procedure extracts the substring corresponding to the match
-register specified by @var{registers} and @var{n}. This is equivalent
-to the following expression:
-
-@example
-@group
-(substring @var{string}
- (re-match-start-index @var{n} @var{registers})
- (re-match-end-index @var{n} @var{registers}))
-@end group
-@end example
-@end deffn
-
-@deffn procedure regexp-group alternative @dots{}
-Each @var{alternative} must be a regular expression. The returned value
-is a new regular expression that consists of the @var{alternative}s
-combined by a grouping operator. For example:
-
-@example
-@group
-(regexp-group "foo" "bar" "baz")
- @result{} "\\(foo\\|bar\\|baz\\)"
-@end group
-@end example
-@end deffn
-
-@node REXP abstraction, , Regular-expression procedures, Regular Expressions
-@subsection REXP abstraction
-
-@cindex REXP abstraction
-In addition to providing standard regular-expression support, MIT/GNU
-Scheme also provides the @acronym{REXP} abstraction. This is an
-alternative way to write regular expressions that is easier to read
-and understand than the standard notation. Regular expressions
-written in this notation can be translated into the standard notation.
-
-The @acronym{REXP} abstraction is a set of combinators that are
-composed into a complete regular expression. Each combinator directly
-corresponds to a particular piece of regular-expression notation. For
-example, the expression @code{(rexp-any-char)} corresponds to the
-@code{.} character in standard regular-expression notation, while
-@code{(rexp* @var{rexp})} corresponds to the @code{*} character.
-
-The primary advantages of @acronym{REXP} are that it makes the nesting
-structure of regular expressions explicit, and that it simplifies the
-description of complex regular expressions by allowing them to be
-built up using straightforward combinators.
-
-@deffn procedure rexp? object
-Returns @code{#t} if @var{object} is a @acronym{REXP} expression, or
-@code{#f} otherwise. A @acronym{REXP} is one of: a string, which
-represents the pattern matching that string; a character set, which
-represents the pattern matching a character in that set; or an object
-returned by calling one of the procedures defined here.
-@end deffn
-
-@deffn procedure rexp->regexp rexp
-Converts @var{rexp} to standard regular-expression notation, returning
-a newly-allocated string.
-@end deffn
-
-@deffn procedure rexp-compile rexp
-Converts @var{rexp} to standard regular-expression notation, then
-compiles it and returns the compiled result. Equivalent to
-
-@example
-(re-compile-pattern (rexp->regexp @var{rexp}) #f)
-@end example
-@end deffn
-
-@deffn procedure rexp-any-char
-Returns a @acronym{REXP} that matches any single character except a
-newline. This is equivalent to the @code{.} construct.
-@end deffn
-
-@deffn procedure rexp-line-start
-Returns a @acronym{REXP} that matches the start of a line. This is
-equivalent to the @code{^} construct.
-@end deffn
-
-@deffn procedure rexp-line-end
-Returns a @acronym{REXP} that matches the end of a line. This is
-equivalent to the @code{$} construct.
-@end deffn
-
-@deffn procedure rexp-string-start
-Returns a @acronym{REXP} that matches the start of the text being
-matched. This is equivalent to the @code{\`} construct.
-@end deffn
-
-@deffn procedure rexp-string-end
-Returns a @acronym{REXP} that matches the end of the text being
-matched. This is equivalent to the @code{\'} construct.
-@end deffn
-
-@deffn procedure rexp-word-edge
-Returns a @acronym{REXP} that matches the start or end of a word.
-This is equivalent to the @code{\b} construct.
-@end deffn
-
-@deffn procedure rexp-not-word-edge
-Returns a @acronym{REXP} that matches anywhere that is not the start
-or end of a word. This is equivalent to the @code{\B} construct.
-@end deffn
-
-@deffn procedure rexp-word-start
-Returns a @acronym{REXP} that matches the start of a word.
-This is equivalent to the @code{\<} construct.
-@end deffn
-
-@deffn procedure rexp-word-end
-Returns a @acronym{REXP} that matches the end of a word.
-This is equivalent to the @code{\>} construct.
-@end deffn
-
-@deffn procedure rexp-word-char
-Returns a @acronym{REXP} that matches any word-constituent character.
-This is equivalent to the @code{\w} construct.
-@end deffn
-
-@deffn procedure rexp-not-word-char
-Returns a @acronym{REXP} that matches any character that isn't a word
-constituent. This is equivalent to the @code{\W} construct.
-@end deffn
-
-The next two procedures accept a @var{syntax-type} argument specifying
-the syntax class to be matched against. This argument is a symbol
-selected from the following list. Each symbol is followed by the
-equivalent character used in standard regular-expression notation.
-@code{whitespace} (space character),
-@code{punctuation} (@code{.}),
-@code{word} (@code{w}),
-@code{symbol} (@code{_}),
-@code{open} (@code{(}),
-@code{close} (@code{)}),
-@code{quote} (@code{'}),
-@code{string-delimiter} (@code{"}),
-@code{math-delimiter} (@code{$}),
-@code{escape} (@code{\}),
-@code{char-quote} (@code{/}),
-@code{comment-start} (@code{<}),
-@code{comment-end} (@code{>}).
-
-@deffn procedure rexp-syntax-char syntax-type
-Returns a @acronym{REXP} that matches any character of type
-@var{syntax-type}. This is equivalent to the @code{\s} construct.
-@end deffn
-
-@deffn procedure rexp-not-syntax-char syntax-type
-Returns a @acronym{REXP} that matches any character not of type
-@var{syntax-type}. This is equivalent to the @code{\S} construct.
-@end deffn
-
-@deffn procedure rexp-sequence rexp @dots{}
-Returns a @acronym{REXP} that matches each @var{rexp} argument in
-sequence. If no @var{rexp} argument is supplied, the result matches
-the null string. This is equivalent to concatenating the regular
-expressions corresponding to each @var{rexp} argument.
-@end deffn
-
-@deffn procedure rexp-alternatives rexp @dots{}
-Returns a @acronym{REXP} that matches any of the @var{rexp}
-arguments. This is equivalent to concatenating the regular
-expressions corresponding to each @var{rexp} argument, separating them
-by the @code{\|} construct.
-@end deffn
-
-@deffn procedure rexp-group rexp @dots{}
-@code{rexp-group} is like @code{rexp-sequence}, except that the result
-is marked as a match group. This is equivalent to the @code{\(}
-@dots{} @code{\)} construct.
-@end deffn
-
-The next three procedures in principal accept a single @acronym{REXP}
-argument. For convenience, they accept multiple arguments, which are
-converted into a single argument by @code{rexp-group}. Note, however,
-that if only one @acronym{REXP} argument is supplied, and it's very
-simple, no grouping occurs.
-
-@deffn procedure rexp* rexp @dots{}
-Returns a @acronym{REXP} that matches zero or more instances of the
-pattern matched by the @var{rexp} arguments. This is equivalent to
-the @code{*} construct.
-@end deffn
-
-@deffn procedure rexp+ rexp @dots{}
-Returns a @acronym{REXP} that matches one or more instances of the
-pattern matched by the @var{rexp} arguments. This is equivalent to
-the @code{+} construct.
-@end deffn
-
-@deffn procedure rexp-optional rexp @dots{}
-Returns a @acronym{REXP} that matches zero or one instances of the
-pattern matched by the @var{rexp} arguments. This is equivalent to
-the @code{?} construct.
-@end deffn
-
-@deffn procedure rexp-case-fold rexp
-Returns a @acronym{REXP} that matches the same pattern as @var{rexp},
-but is insensitive to character case. This has no equivalent in
-standard regular-expression notation.
-@end deffn
-
-@node Modification of Strings, Variable-Length Strings, Regular Expressions, Strings
-@section Modification of Strings
-@cindex modification, of string
-@cindex replacement, of string component
-@cindex filling, of string
-@cindex moving, of string elements
-
-@deffn procedure string-replace string char1 char2
-@deffnx procedure substring-replace string start end char1 char2
-@deffnx procedure string-replace! string char1 char2
-@deffnx procedure substring-replace! string start end char1 char2
-These procedures replace all occurrences of @var{char1} with @var{char2}
-in the original string (substring). @code{string-replace} and
-@code{substring-replace} return a newly allocated string containing the
-result. @code{string-replace!} and @code{substring-replace!}
-destructively modify @var{string} and return an unspecified value.
-
-@example
-@group
-(define str "a few words") @result{} @r{unspecified}
-(string-replace str #\space #\-) @result{} "a-few-words"
-(substring-replace str 2 9 #\space #\-) @result{} "a few-words"
-str @result{} "a few words"
-(string-replace! str #\space #\-) @result{} @r{unspecified}
-str @result{} "a-few-words"
-@end group
-@end example
-@end deffn
-
-@deffn {procedure} string-fill! string char
-Stores @var{char} in every element of @var{string} and returns an
-unspecified value.
-@end deffn
-
-@deffn procedure substring-fill! string start end char
-Stores @var{char} in elements @var{start} (inclusive) to @var{end}
-(exclusive) of @var{string} and returns an unspecified value.
-
-@example
-@group
-(define s (make-string 10 #\space)) @result{} @r{unspecified}
-(substring-fill! s 2 8 #\*) @result{} @r{unspecified}
-s @result{} " ****** "
-@end group
-@end example
-@end deffn
-
-@deffn procedure substring-move-left! string1 start1 end1 string2 start2
-@deffnx procedure substring-move-right! string1 start1 end1 string2 start2
-@findex eqv?
-Copies the characters from @var{start1} to @var{end1} of @var{string1}
-into @var{string2} at the @var{start2}-th position. The characters are
-copied as follows (note that this is only important when @var{string1}
-and @var{string2} are @code{eqv?}):
-
-@table @code
-@item substring-move-left!
-The copy starts at the left end and moves toward the right (from smaller
-indices to larger). Thus if @var{string1} and @var{string2} are the
-same, this procedure moves the characters toward the left inside the
-string.
-
-@item substring-move-right!
-The copy starts at the right end and moves toward the left (from larger
-indices to smaller). Thus if @var{string1} and @var{string2} are the
-same, this procedure moves the characters toward the right inside the
-string.
-@end table
-
-The following example shows how these procedures can be used to build up
-a string (it would have been easier to use @code{string-append}):
-@example
-@group
-(define answer (make-string 9 #\*)) @result{} @r{unspecified}
-answer @result{} "*********"
-(substring-move-left! "start" 0 5 answer 0) @result{} @r{unspecified}
-answer @result{} "start****"
-(substring-move-left! "-end" 0 4 answer 5) @result{} @r{unspecified}
-answer @result{} "start-end"
-@end group
-@end example
-@end deffn
-
-@deffn procedure reverse-string string
-@deffnx procedure reverse-substring string start end
-@deffnx procedure reverse-string! string
-@deffnx procedure reverse-substring! string start end
-Reverses the order of the characters in the given string or substring.
-@code{reverse-string} and @code{reverse-substring} return newly
-allocated strings; @code{reverse-string!} and @code{reverse-substring!}
-modify their argument strings and return an unspecified value.
-
-@example
-@group
-(reverse-string "foo bar baz") @result{} "zab rab oof"
-(reverse-substring "foo bar baz" 4 7) @result{} "rab"
-(let ((foo "foo bar baz"))
- (reverse-string! foo)
- foo) @result{} "zab rab oof"
-(let ((foo "foo bar baz"))
- (reverse-substring! foo 4 7)
- foo) @result{} "foo rab baz"
-@end group
-@end example
-@end deffn
-
-@node Variable-Length Strings, Byte Vectors, Modification of Strings, Strings
-@section Variable-Length Strings
-
-@cindex length, of string
-@cindex maximum length, of string (defn)
-MIT/GNU Scheme allows the length of a string to be dynamically adjusted in a
-limited way. When a new string is allocated, by whatever method, it has
-a specific length. At the time of allocation, it is also given a
-@dfn{maximum length}, which is guaranteed to be at least as large as the
-string's length. (Sometimes the maximum length will be slightly larger
-than the length, but it is a bad idea to count on this. Programs should
-assume that the maximum length is the same as the length at the time of
-the string's allocation.) After the string is allocated, the operation
-@code{set-string-length!} can be used to alter the string's length to
-any value between 0 and the string's maximum length, inclusive.
-
-@deffn procedure string-maximum-length string
-Returns the maximum length of @var{string}. The following is
-guaranteed:
-
-@example
-@group
-(<= (string-length string)
- (string-maximum-length string)) @result{} #t
-@end group
-@end example
-@findex string-length
-
-The maximum length of a string never changes.
-@end deffn
-
-@deffn procedure set-string-length! string k
-Alters the length of @var{string} to be @var{k}, and returns an
-unspecified value. @var{K} must be less than or equal to the maximum
-length of @var{string}. @code{set-string-length!} does not change the
-maximum length of @var{string}.
-@end deffn
-
-@node Byte Vectors, , Variable-Length Strings, Strings
-@section Byte Vectors
-@cindex byte vector
-@cindex vector, byte
-
-@findex string-ref
-MIT/GNU Scheme implements strings as packed vectors of 8-bit
-@acronym{ISO-8859-1} bytes. Most of the string operations, such as
-@code{string-ref}, coerce these 8-bit codes into character objects.
-However, some lower-level operations are made available for use.
-
-@deffn procedure vector-8b-ref string k
-Returns character @var{k} of @var{string} as an @acronym{ISO-8859-1}
-code. @var{K} must be a valid index of @var{string}.
-
-@example
-@group
-(vector-8b-ref "abcde" 2) @result{} 99 @r{;c}
-@end group
-@end example
-@end deffn
-
-@deffn procedure vector-8b-set! string k code
-Stores @var{code} in element @var{k} of @var{string} and returns an
-unspecified value. @var{K} must be a valid index of @var{string}, and
-@var{code} must be a valid @acronym{ISO-8859-1} code.
-@end deffn
-
-@deffn procedure vector-8b-fill! string start end code
-Stores @var{code} in elements @var{start} (inclusive) to @var{end}
-(exclusive) of @var{string} and returns an unspecified value.
-@var{Code} must be a valid @acronym{ISO-8859-1} code.
-@end deffn
-
-@deffn procedure vector-8b-find-next-char string start end code
-@deffnx procedure vector-8b-find-next-char-ci string start end code
-Returns the index of the first occurrence of @var{code} in the given
-substring; returns @code{#f} if @var{code} does not appear. The index
-returned is relative to the entire string, not just the substring.
-@var{Code} must be a valid @acronym{ISO-8859-1} code.
-
-@code{vector-8b-find-next-char-ci} doesn't distinguish uppercase and
-lowercase letters.
-@end deffn
-
-@deffn procedure vector-8b-find-previous-char string start end code
-@deffnx procedure vector-8b-find-previous-char-ci string start end code
-Returns the index of the last occurrence of @var{code} in the given
-substring; returns @code{#f} if @var{code} does not appear. The index
-returned is relative to the entire string, not just the substring.
-@var{Code} must be a valid @acronym{ISO-8859-1} code.
-
-@code{vector-8b-find-previous-char-ci} doesn't distinguish uppercase and
-lowercase letters.
-@end deffn
-
-@node Lists, Vectors, Strings, Top
-@chapter Lists
-
-@cindex pair (defn)
-@cindex dotted pair (see pair)
-@cindex car field, of pair (defn)
-@cindex cdr field, of pair (defn)
-A @dfn{pair} (sometimes called a @dfn{dotted pair}) is a data structure
-with two fields called the @dfn{car} and @dfn{cdr} fields (for
-historical reasons). Pairs are created by the procedure @code{cons}.
-The car and cdr fields are accessed by the procedures @code{car} and
-@code{cdr}. The car and cdr fields are assigned by the procedures
-@code{set-car!} and @code{set-cdr!}.
-
-@cindex list (defn)
-Pairs are used primarily to represent @dfn{lists}. A list can be
-defined recursively as either the empty list or a pair whose cdr is
-a list. More precisely, the set of lists is defined as the smallest set
-@var{X} such that
-
-@itemize @bullet
-@item
-The empty list is in @var{X}.
-
-@item
-If @var{list} is in @var{X}, then any pair whose cdr field contains
-@var{list} is also in @var{X}.
-@end itemize
-
-@cindex element, of list (defn)
-@cindex length, of list (defn)
-@cindex empty list (defn)
-The objects in the car fields of successive pairs of a list are the
-@dfn{elements} of the list. For example, a two-element list is a pair
-whose car is the first element and whose cdr is a pair whose car is the
-second element and whose cdr is the empty list. The @dfn{length} of a
-list is the number of elements, which is the same as the number of
-pairs. The @dfn{empty list} is a special object of its own type (it is
-not a pair); it has no elements and its length is zero.@footnote{The
-above definitions imply that all lists have finite length and are
-terminated by the empty list.}
-
-@cindex dotted notation, for pair (defn)
-@cindex notation, dotted (defn)
-@cindex external representation, for pair
-@cindex pair, external representation
-@cindex ( as external representation
-@cindex ) as external representation
-@cindex . as external representation
-@cindex parenthesis, as external representation
-@cindex dot, as external representation
-@cindex period, as external representation
-@findex (
-@findex )
-@findex .
-The most general notation (external representation) for Scheme pairs is
-the ``dotted'' notation @code{(@var{c1} . @var{c2})} where @var{c1} is
-the value of the car field and @var{c2} is the value of the cdr field.
-For example, @code{(4 . 5)} is a pair whose car is @code{4} and whose
-cdr is @code{5}. Note that @code{(4 . 5)} is the external
-representation of a pair, not an expression that evaluates to a pair.
-
-@cindex external representation, for list
-@cindex list, external representation
-@cindex external representation, for empty list
-@cindex empty list, external representation
-@findex ()
-A more streamlined notation can be used for lists: the elements of the
-list are simply enclosed in parentheses and separated by spaces. The
-empty list is written @code{()}. For example, the following are
-equivalent notations for a list of symbols:
-
-@example
-@group
-(a b c d e)
-(a . (b . (c . (d . (e . ())))))
-@end group
-@end example
-
-@findex set-cdr!
-Whether a given pair is a list depends upon what is stored in the cdr
-field. When the @code{set-cdr!} procedure is used, an object can be a
-list one moment and not the next:
-
-@example
-@group
-(define x (list 'a 'b 'c))
-(define y x)
-y @result{} (a b c)
-(list? y) @result{} #t
-(set-cdr! x 4) @result{} @r{unspecified}
-x @result{} (a . 4)
-(eqv? x y) @result{} #t
-y @result{} (a . 4)
-(list? y) @result{} #f
-(set-cdr! x x) @result{} @r{unspecified}
-(list? y) @result{} #f
-@end group
-@end example
-
-@cindex improper list (defn)
-@cindex list, improper (defn)
-A chain of pairs that doesn't end in the empty list is called an
-@dfn{improper list}. Note that an improper list is not a list. The
-list and dotted notations can be combined to represent improper lists,
-as the following equivalent notations show:
-
-@example
-@group
-(a b c . d)
-(a . (b . (c . d)))
-@end group
-@end example
-
-@findex quote
-@findex quasiquote
-@findex unquote
-@findex unquote-splicing
-@findex '
-@findex `
-@findex ,
-@findex ,@@
-@findex read
-Within literal expressions and representations of objects read by the
-@code{read} procedure, the forms @code{'@var{datum}},
-@code{`@var{datum}}, @code{,@var{datum}}, and @code{,@@@var{datum}}
-denote two-element lists whose first elements are the symbols
-@code{quote}, @code{quasiquote}, @code{unquote}, and
-@code{unquote-splicing}, respectively. The second element in each case
-is @var{datum}. This convention is supported so that arbitrary Scheme
-programs may be represented as lists. Among other things, this permits
-the use of the @code{read} procedure to parse Scheme programs.
-
-@menu
-* Pairs::
-* Construction of Lists::
-* Selecting List Components::
-* Cutting and Pasting Lists::
-* Filtering Lists::
-* Searching Lists::
-* Mapping of Lists::
-* Reduction of Lists::
-* Miscellaneous List Operations::
-@end menu
-
-@node Pairs, Construction of Lists, Lists, Lists
-@section Pairs
-
-This section describes the simple operations that are available for
-constructing and manipulating arbitrary graphs constructed from pairs.
-
-@deffn procedure pair? object
-@cindex type predicate, for pair
-Returns @code{#t} if @var{object} is a pair; otherwise returns
-@code{#f}.
-
-@example
-@group
-(pair? '(a . b)) @result{} #t
-(pair? '(a b c)) @result{} #t
-(pair? '()) @result{} #f
-(pair? '#(a b)) @result{} #f
-@end group
-@end example
-@end deffn
-
-@deffn procedure cons obj1 obj2
-@cindex construction, of pair
-@findex eqv?
-Returns a newly allocated pair whose car is @var{obj1} and whose cdr is
-@var{obj2}. The pair is guaranteed to be different (in the sense of
-@code{eqv?}) from every previously existing object.
-
-@example
-@group
-(cons 'a '()) @result{} (a)
-(cons '(a) '(b c d)) @result{} ((a) b c d)
-(cons "a" '(b c)) @result{} ("a" b c)
-(cons 'a 3) @result{} (a . 3)
-(cons '(a b) 'c) @result{} ((a b) . c)
-@end group
-@end example
-@end deffn
-
-@deffn procedure car pair
-@cindex selection, of pair component
-@cindex component selection, of pair
-Returns the contents of the car field of @var{pair}. Note that it is an
-error to take the @code{car} of the empty list.
-
-@example
-@group
-(car '(a b c)) @result{} a
-(car '((a) b c d)) @result{} (a)
-(car '(1 . 2)) @result{} 1
-(car '()) @error{} Illegal datum
-@end group
-@end example
-@end deffn
-
-@deffn procedure cdr pair
-Returns the contents of the cdr field of @var{pair}. Note that it is an
-error to take the @code{cdr} of the empty list.
-
-@example
-@group
-(cdr '((a) b c d)) @result{} (b c d)
-(cdr '(1 . 2)) @result{} 2
-(cdr '()) @error{} Illegal datum
-@end group
-@end example
-@end deffn
-
-@deffn procedure set-car! pair object
-Stores @var{object} in the car field of @var{pair}. The value returned
-by @code{set-car!} is unspecified.
-
-@example
-@group
-(define (f) (list 'not-a-constant-list))
-(define (g) '(constant-list))
-(set-car! (f) 3) @result{} @r{unspecified}
-(set-car! (g) 3) @error{} Illegal datum
-@end group
-@end example
-@end deffn
-
-@deffn procedure set-cdr! pair object
-Stores @var{object} in the cdr field of @var{pair}. The value returned
-by @code{set-cdr!} is unspecified.
-@end deffn
-
-@deffn procedure caar pair
-@deffnx procedure cadr pair
-@deffnx procedure cdar pair
-@deffnx procedure cddr pair
-@deffnx procedure caaar pair
-@deffnx procedure caadr pair
-@deffnx procedure cadar pair
-@deffnx procedure caddr pair
-@deffnx procedure cdaar pair
-@deffnx procedure cdadr pair
-@deffnx procedure cddar pair
-@deffnx procedure cdddr pair
-@deffnx procedure caaaar pair
-@deffnx procedure caaadr pair
-@deffnx procedure caadar pair
-@deffnx procedure caaddr pair
-@deffnx procedure cadaar pair
-@deffnx procedure cadadr pair
-@deffnx procedure caddar pair
-@deffnx procedure cadddr pair
-@deffnx procedure cdaaar pair
-@deffnx procedure cdaadr pair
-@deffnx procedure cdadar pair
-@deffnx procedure cdaddr pair
-@deffnx procedure cddaar pair
-@deffnx procedure cddadr pair
-@deffnx procedure cdddar pair
-@deffnx procedure cddddr pair
-These procedures are compositions of @code{car} and @code{cdr}; for
-example, @code{caddr} could be defined by
-
-@example
-(define caddr (lambda (x) (car (cdr (cdr x)))))
-@end example
-@end deffn
-
-@deffn procedure general-car-cdr object path
-This procedure is a generalization of @code{car} and @code{cdr}.
-@var{Path} encodes a particular sequence of @code{car} and @code{cdr}
-operations, which @code{general-car-cdr} executes on @var{object}.
-@var{Path} is an exact non-negative integer that encodes the operations
-in a bitwise fashion: a zero bit represents a @code{cdr} operation, and
-a one bit represents a @code{car}. The bits are executed LSB to MSB,
-and the most significant one bit, rather than being interpreted as an
-operation, signals the end of the sequence.@footnote{Note that
-@var{path} is restricted to a machine-dependent range, usually the size
-of a machine word. On many machines, this means that the maximum length
-of @var{path} will be 30 operations (32 bits, less the sign bit and the
-``end-of-sequence'' bit).}
-
-For example, the following are equivalent:
-@example
-@group
-(general-car-cdr @var{object} #b1011)
-(cdr (car (car @var{object})))
-@end group
-@end example
-
-Here is a partial table of path/operation equivalents:
-
-@example
-@group
-#b10 cdr
-#b11 car
-#b100 cddr
-#b101 cdar
-#b110 cadr
-#b111 caar
-#b1000 cdddr
-@end group
-@end example
-@end deffn
-
-@deffn procedure tree-copy tree
-@cindex copying, of tree
-@cindex tree, copying
-This copies an arbitrary @var{tree} constructed from pairs, copying both
-the car and cdr elements of every pair. This could have been defined by
-
-@example
-@group
-(define (tree-copy tree)
- (let loop ((tree tree))
- (if (pair? tree)
- (cons (loop (car tree)) (loop (cdr tree)))
- tree)))
-@end group
-@end example
-@end deffn
-
-@node Construction of Lists, Selecting List Components, Pairs, Lists
-@section Construction of Lists
-@cindex construction, of list
-
-@deffn procedure list object @dots{}
-Returns a list of its arguments.
-
-@example
-@group
-(list 'a (+ 3 4) 'c) @result{} (a 7 c)
-(list) @result{} ()
-@end group
-@end example
-
-These expressions are equivalent:
-
-@example
-@group
-(list @var{obj1} @var{obj2} @dots{} @var{objN})
-(cons @var{obj1} (cons @var{obj2} @dots{} (cons @var{objN} '()) @dots{}))
-@end group
-@end example
-@end deffn
-
-@deffn procedure make-list k [element]
-This procedure returns a newly allocated list of length @var{k},
-whose elements are all @var{element}. If @var{element} is not supplied,
-it defaults to the empty list.
-@end deffn
-
-@deffn procedure cons* object object @dots{}
-@findex list
-@code{cons*} is similar to @code{list}, except that @code{cons*} conses
-together the last two arguments rather than consing the last argument
-with the empty list. If the last argument is not a list the result is
-an improper list. If the last argument is a list, the result is a list
-consisting of the initial arguments and all of the items in the final
-argument. If there is only one argument, the result is the argument.
-
-@example
-@group
-(cons* 'a 'b 'c) @result{} (a b . c)
-(cons* 'a 'b '(c d)) @result{} (a b c d)
-(cons* 'a) @result{} a
-@end group
-@end example
-
-These expressions are equivalent:
-
-@example
-@group
-(cons* @var{obj1} @var{obj2} @dots{} @var{objN-1} @var{objN})
-(cons @var{obj1} (cons @var{obj2} @dots{} (cons @var{objN-1} @var{objN}) @dots{}))
-@end group
-@end example
-@end deffn
-
-@deffn procedure list-copy list
-Returns a newly allocated copy of @var{list}. This copies each of the
-pairs comprising @var{list}. This could have been defined by
-
-@example
-@group
-(define (list-copy list)
- (if (null? list)
- '()
- (cons (car list)
- (list-copy (cdr list)))))
-@end group
-@end example
-@end deffn
-
-@deffn procedure vector->list vector
-@deffnx procedure subvector->list vector start end
-@cindex vector, converting to list
-@findex list->vector
-@code{vector->list} returns a newly allocated list of the elements of
-@var{vector}.@* @code{subvector->list} returns a newly allocated list of
-the elements of the given subvector. The inverse of @code{vector->list}
-is @code{list->vector}.
-
-@example
-(vector->list '#(dah dah didah)) @result{} (dah dah didah)
-@end example
-@end deffn
-
-@deffn {procedure} string->list string
-@deffnx {procedure} substring->list string start end
-@cindex string, converting to list
-@findex list->string
-@code{string->list} returns a newly allocated list of the character
-elements of @var{string}.@*
-@code{substring->list} returns a newly allocated list of the character
-elements of the given substring. The inverse of @code{string->list} is
-@code{list->string}.
-
-@example
-@group
-(string->list "abcd") @result{} (#\a #\b #\c #\d)
-(substring->list "abcdef" 1 3) @result{} (#\b #\c)
-@end group
-@end example
-@end deffn
-
-@node Selecting List Components, Cutting and Pasting Lists, Construction of Lists, Lists
-@section Selecting List Components
-@cindex selection, of list component
-@cindex component selection, of list
-
-@deffn procedure list? object
-@cindex type predicate, for list
-@cindex circular list
-Returns @code{#t} if @var{object} is a list, otherwise returns
-@code{#f}. By definition, all lists have finite length and are
-terminated by the empty list. This procedure returns an answer even for
-circular structures.
-
-@findex pair?
-@findex null?
-Any @var{object} satisfying this predicate will also satisfy exactly one
-of @code{pair?} or @code{null?}.
-
-@example
-@group
-(list? '(a b c)) @result{} #t
-(list? '()) @result{} #t
-(list? '(a . b)) @result{} #f
-(let ((x (list 'a)))
- (set-cdr! x x)
- (list? x)) @result{} #f
-@end group
-@end example
-@end deffn
-
-@deffn procedure length list
-Returns the length of @var{list}. Signals an error if @var{list} isn't
-a proper list.
-
-@example
-@group
-(length '(a b c)) @result{} 3
-(length '(a (b) (c d e))) @result{} 3
-(length '()) @result{} 0
-@end group
-@end example
-@end deffn
-
-@deffn procedure null? object
-@cindex type predicate, for empty list
-@cindex empty list, predicate for
-Returns @code{#t} if @var{object} is the empty list; otherwise returns
-@code{#f} (but @pxref{True and False}).
-
-@example
-@group
-(null? '(a . b)) @result{} #f
-(null? '(a b c)) @result{} #f
-(null? '()) @result{} #t
-@end group
-@end example
-@end deffn
-
-@deffn procedure list-ref list k
-@cindex index, of list (defn)
-@cindex valid index, of list (defn)
-@cindex list index (defn)
-Returns the @var{k}th element of @var{list}, using zero-origin indexing.
-The @dfn{valid indexes} of a list are the exact non-negative integers
-less than the length of the list. The first element of a list has index
-@code{0}, the second has index @code{1}, and so on.
-
-@example
-@group
-(list-ref '(a b c d) 2) @result{} c
-(list-ref '(a b c d)
- (inexact->exact (round 1.8)))
- @result{} c
-@end group
-@end example
-
-@findex list-tail
-@code{(list-ref @var{list} @var{k})} is equivalent to @code{(car
-(list-tail @var{list} @var{k}))}.
-@end deffn
-
-@deffn procedure first list
-@deffnx procedure second list
-@deffnx procedure third list
-@deffnx procedure fourth list
-@deffnx procedure fifth list
-@deffnx procedure sixth list
-@deffnx procedure seventh list
-@deffnx procedure eighth list
-@deffnx procedure ninth list
-@deffnx procedure tenth list
-Returns the specified element of @var{list}. It is an error if
-@var{list} is not long enough to contain the specified element (for
-example, if the argument to @code{seventh} is a list that contains only
-six elements).
-@end deffn
-
-@node Cutting and Pasting Lists, Filtering Lists, Selecting List Components, Lists
-@section Cutting and Pasting Lists
-@cindex cutting, of list
-@cindex pasting, of lists
-
-@deffn procedure sublist list start end
-@var{Start} and @var{end} must be exact integers satisfying
-
-@example
-0 <= @var{start} <= @var{end} <= (length @var{list})
-@end example
-
-@code{sublist} returns a newly allocated list formed from the elements
-of @var{list} beginning at index @var{start} (inclusive) and ending at
-@var{end} (exclusive).
-@end deffn
-
-@deffn procedure list-head list k
-Returns a newly allocated list consisting of the first @var{k} elements of
-@var{list}. @var{K} must not be greater than the length of
-@var{list}.
-
-We could have defined @code{list-head} this way:
-
-@example
-@group
-(define (list-head list k)
- (sublist list 0 k))
-@end group
-@end example
-@end deffn
-
-@deffn procedure list-tail list k
-Returns the sublist of @var{list} obtained by omitting the first @var{k}
-elements. The result, if it is not the empty list, shares structure
-with @var{list}. @var{K} must not be greater than the length of
-@var{list}.
-@end deffn
-
-@deffn {procedure} append list @dots{}
-@cindex appending, of lists
-Returns a list consisting of the elements of the first @var{list}
-followed by the elements of the other @var{list}s.
-
-@example
-@group
-(append '(x) '(y)) @result{} (x y)
-(append '(a) '(b c d)) @result{} (a b c d)
-(append '(a (b)) '((c))) @result{} (a (b) (c))
-(append) @result{} ()
-@end group
-@end example
-
-The resulting list is always newly allocated, except that it shares
-structure with the last @var{list} argument. The last argument may
-actually be any object; an improper list results if the last argument is
-not a proper list.
-
-@example
-@group
-(append '(a b) '(c . d)) @result{} (a b c . d)
-(append '() 'a) @result{} a
-@end group
-@end example
-@end deffn
-
-@deffn procedure append! list @dots{}
-Returns a list that is the argument @var{list}s concatenated together.
-The arguments are changed rather than copied. (Compare this with
-@code{append}, which copies arguments rather than destroying them.) For
-example:
-
-@example
-@group
-(define x '(a b c))
-(define y '(d e f))
-(define z '(g h))
-(append! x y z) @result{} (a b c d e f g h)
-x @result{} (a b c d e f g h)
-y @result{} (d e f g h)
-z @result{} (g h)
-@end group
-@end example
-@end deffn
-
-@deffn procedure last-pair list
-Returns the last pair in @var{list}, which may be an improper list.
-@code{last-pair} could have been defined this way:
-
-@example
-@group
-(define last-pair
- (lambda (x)
- (if (pair? (cdr x))
- (last-pair (cdr x))
- x)))
-@end group
-@end example
-@end deffn
-
-@deffn procedure except-last-pair list
-@deffnx procedure except-last-pair! list
-These procedures remove the last pair from @var{list}. @var{List} may
-be an improper list, except that it must consist of at least one pair.
-@code{except-last-pair} returns a newly allocated copy of @var{list}
-that omits the last pair. @code{except-last-pair!} destructively
-removes the last pair from @var{list} and returns @var{list}. If the
-cdr of @var{list} is not a pair, the empty list is returned by either
-procedure.
-@end deffn
-
-@node Filtering Lists, Searching Lists, Cutting and Pasting Lists, Lists
-@section Filtering Lists
-@cindex filtering, of list
-@cindex deletion, of list element
-
-@deffn procedure keep-matching-items list predicate
-@deffnx procedure delete-matching-items list predicate
-These procedures return a newly allocated copy of @var{list} containing
-only the elements for which @var{predicate} is (respectively) true or
-false. @var{Predicate} must be a procedure of one argument.
-
-@example
-@group
-(keep-matching-items '(1 2 3 4 5) odd?) @result{} (1 3 5)
-(delete-matching-items '(1 2 3 4 5) odd?) @result{} (2 4)
-@end group
-@end example
-
-@findex list-transform-positive
-@findex list-transform-negative
-For compatibility, the procedure @code{list-transform-positive} is an
-alias for @code{keep-matching-items}, and @code{list-transform-negative}
-is an alias for @code{delete-matching-items}.
-@end deffn
-
-@deffn procedure keep-matching-items! list predicate
-@deffnx procedure delete-matching-items! list predicate
-These procedures are exactly like @code{keep-matching-items} and
-@code{delete-matching-items}, respectively, except that they
-destructively modify the @var{list} argument rather than allocating a
-new result.
-@end deffn
-
-@deffn procedure delq element list
-@deffnx procedure delv element list
-@deffnx procedure delete element list
-@findex eq?
-@findex eqv?
-@findex equal?
-Returns a newly allocated copy of @var{list} with all entries equal to
-@var{element} removed. @code{delq} uses @code{eq?} to compare
-@var{element} with the entries in @var{list}, @code{delv} uses
-@code{eqv?}, and @code{delete} uses @code{equal?}.
-@end deffn
-
-@deffn procedure delq! element list
-@deffnx procedure delv! element list
-@deffnx procedure delete! element list
-@findex eq?
-@findex eqv?
-@findex equal?
-Returns a list consisting of the top-level elements of @var{list} with
-all entries equal to @var{element} removed. These procedures are like
-@code{delq}, @code{delv}, and @code{delete} except that they
-destructively modify @var{list}. @code{delq!} uses @code{eq?} to
-compare element with the entries in @var{list}, @code{delv!} uses
-@code{eqv?}, and @code{delete!} uses @code{equal?}. Because the result
-may not be @code{eq?} to @var{list}, it is desirable to do something
-like @code{(set! x (delete! x))}.
-
-@example
-@group
-(define x '(a b c b))
-(delete 'b x) @result{} (a c)
-x @result{} (a b c b)
-
-(define x '(a b c b))
-(delete! 'b x) @result{} (a c)
-x @result{} (a c)
-@r{;; Returns correct result:}
-(delete! 'a x) @result{} (c)
-
-@r{;; Didn't modify what x points to:}
-x @result{} (a c)
-@end group
-@end example
-@end deffn
-
-@deffn procedure delete-member-procedure deletor predicate
-@findex list-deletor
-@findex list-deletor!
-@findex delv
-@findex delete!
-Returns a deletion procedure similar to @code{delv} or @code{delete!}.
-@var{Deletor} should be one of the procedures @code{list-deletor} or
-@code{list-deletor!}. @var{Predicate} must be an equivalence predicate.
-The returned procedure accepts exactly two arguments: first, an object
-to be deleted, and second, a list of objects from which it is to be
-deleted. If @var{deletor} is @code{list-deletor}, the procedure
-returns a newly allocated copy of the given list in which all entries
-equal to the given object have been removed. If @var{deletor} is
-@code{list-deletor!}, the procedure returns a list consisting of the
-top-level elements of the given list with all entries equal to the given
-object removed; the given list is destructively modified to produce the
-result. In either case @var{predicate} is used to compare the given
-object to the elements of the given list.
-
-Here are some examples that demonstrate how
-@code{delete-member-procedure} could have been used to implement
-@code{delv} and @code{delete!}:
-
-@example
-@group
-(define delv
- (delete-member-procedure list-deletor eqv?))
-(define delete!
- (delete-member-procedure list-deletor! equal?))
-@end group
-@end example
-@end deffn
-
-@deffn procedure list-deletor predicate
-@deffnx procedure list-deletor! predicate
-These procedures each return a procedure that deletes elements from
-lists. @var{Predicate} must be a procedure of one argument. The
-returned procedure accepts exactly one argument, which must be a proper
-list, and applies @var{predicate} to each of the elements of the
-argument, deleting those for which it is true.
-
-The procedure returned by @code{list-deletor} deletes elements
-non-destructively, by returning a newly allocated copy of the argument
-with the appropriate elements removed. The procedure returned by
-@code{list-deletor!} performs a destructive deletion.
-@end deffn
-
-@node Searching Lists, Mapping of Lists, Filtering Lists, Lists
-@section Searching Lists
-@cindex searching, of list
-
-@deffn procedure find-matching-item list predicate
-Returns the first element in @var{list} for which @var{predicate} is
-true; returns @code{#f} if it doesn't find such an element. (This means
-that if @var{predicate} is true for @code{#f}, it may be impossible to
-distinguish a successful result from an unsuccessful one.)
-@var{Predicate} must be a procedure of one argument.
-
-@findex list-search-positive
-@findex list-search-negative
-For compatibility, @code{list-search-positive} is an alias for
-@code{find-matching-item}. @code{list-search-negative} is similar but
-the sense of the predicate is reversed.
-@end deffn
-
-@deffn procedure memq object list
-@deffnx procedure memv object list
-@deffnx procedure member object list
-@findex eq?
-@findex eqv?
-@findex equal?
-These procedures return the first pair of @var{list} whose car is
-@var{object}; the returned pair is always one from which @var{list} is
-composed. If @var{object} does not occur in @var{list}, @code{#f}
-(n.b.: not the empty list) is returned. @code{memq} uses @code{eq?} to
-compare @var{object} with the elements of @var{list}, while @code{memv}
-uses @code{eqv?} and @code{member} uses @code{equal?}.@footnote{Although
-they are often used as predicates, @code{memq}, @code{memv}, and
-@code{member} do not have question marks in their names because they
-return useful values rather than just @code{#t} or @code{#f}.}
-
-@example
-@group
-(memq 'a '(a b c)) @result{} (a b c)
-(memq 'b '(a b c)) @result{} (b c)
-(memq 'a '(b c d)) @result{} #f
-(memq (list 'a) '(b (a) c)) @result{} #f
-(member (list 'a) '(b (a) c)) @result{} ((a) c)
-(memq 101 '(100 101 102)) @result{} @r{unspecified}
-(memv 101 '(100 101 102)) @result{} (101 102)
-@end group
-@end example
-@end deffn
-
-@deffn procedure member-procedure predicate
-Returns a procedure similar to @code{memq}, except that @var{predicate},
-which must be an equivalence predicate, is used instead of @code{eq?}.
-This could be used to define @code{memv} as follows:
-
-@example
-(define memv (member-procedure eqv?))
-@end example
-@end deffn
-
-@need 1000
-@node Mapping of Lists, Reduction of Lists, Searching Lists, Lists
-@section Mapping of Lists
-@cindex mapping, of list
-
-@deffn {procedure} map procedure list list @dots{}
-@var{Procedure} must be a procedure taking as many arguments as there
-are @var{list}s. If more than one @var{list} is given, then they must
-all be the same length. @code{map} applies @var{procedure} element-wise
-to the elements of the @var{list}s and returns a list of the results, in
-order from left to right. The dynamic order in which @var{procedure} is
-applied to the elements of the @var{list}s is unspecified; use
-@code{for-each} to sequence side effects.
-
-@example
-@group
-(map cadr '((a b) (d e) (g h))) @result{} (b e h)
-(map (lambda (n) (expt n n)) '(1 2 3 4)) @result{} (1 4 27 256)
-(map + '(1 2 3) '(4 5 6)) @result{} (5 7 9)
-(let ((count 0))
- (map (lambda (ignored)
- (set! count (+ count 1))
- count)
- '(a b c))) @result{} @r{unspecified}
-@end group
-@end example
-@end deffn
-
-@deffn procedure map* initial-value procedure list1 list2 @dots{}
-Similar to @code{map}, except that the resulting list is terminated by
-@var{initial-value} rather than the empty list. The following are
-equivalent:
-
-@example
-@group
-(map @var{procedure} @var{list} @var{list} @dots{})
-(map* '() @var{procedure} @var{list} @var{list} @dots{})
-@end group
-@end example
-@end deffn
-
-@deffn procedure append-map procedure list list @dots{}
-@deffnx procedure append-map* initial-value procedure list list @dots{}
-@findex append
-Similar to @code{map} and @code{map*}, respectively, except that the
-results of applying @var{procedure} to the elements of @var{list}s are
-concatenated together by @code{append} rather than by @code{cons}. The
-following are equivalent, except that the former is more efficient:
-
-@example
-@group
-(append-map @var{procedure} @var{list} @var{list} @dots{})
-(apply append (map @var{procedure} @var{list} @var{list} @dots{}))
-@end group
-@end example
-@end deffn
-
-@deffn procedure append-map! procedure list list @dots{}
-@deffnx procedure append-map*! initial-value procedure list list @dots{}
-@findex append!
-Similar to @code{map} and @code{map*}, respectively, except that the
-results of applying @var{procedure} to the elements of @var{list}s are
-concatenated together by @code{append!} rather than by @code{cons}. The
-following are equivalent, except that the former is more efficient:
-
-@example
-@group
-(append-map! @var{procedure} @var{list} @var{list} @dots{})
-(apply append! (map @var{procedure} @var{list} @var{list} @dots{}))
-@end group
-@end example
-@end deffn
-
-@deffn {procedure} for-each procedure list list @dots{}
-The arguments to @code{for-each} are like the arguments to @code{map},
-but @code{for-each} calls @var{procedure} for its side effects rather
-than for its values. Unlike @code{map}, @code{for-each} is guaranteed
-to call @var{procedure} on the elements of the @var{list}s in order from
-the first element to the last, and the value returned by @code{for-each}
-is unspecified.
-
-@example
-@group
-(let ((v (make-vector 5)))
- (for-each (lambda (i)
- (vector-set! v i (* i i)))
- '(0 1 2 3 4))
- v) @result{} #(0 1 4 9 16)
-@end group
-@end example
-@end deffn
-
-@node Reduction of Lists, Miscellaneous List Operations, Mapping of Lists, Lists
-@section Reduction of Lists
-@cindex reduction, of list
-
-@deffn procedure reduce procedure initial list
-Combines all the elements of @var{list} using the binary operation
-@var{procedure}. For example, using @code{+} one can add up all the
-elements:
-
-@example
-(reduce + 0 list-of-numbers)
-@end example
-
-The argument @var{initial} is used only if @var{list} is empty; in this
-case @var{initial} is the result of the call to @code{reduce}. If
-@var{list} has a single argument, it is returned. Otherwise, the arguments
-are reduced in a left-associative fashion. For example:
-
-@example
-@group
-(reduce + 0 '(1 2 3 4)) @result{} 10
-(reduce + 0 '(1 2)) @result{} 3
-(reduce + 0 '(1)) @result{} 1
-(reduce + 0 '()) @result{} 0
-(reduce + 0 '(foo)) @result{} foo
-(reduce list '() '(1 2 3 4)) @result{} (((1 2) 3) 4)
-@end group
-@end example
-@end deffn
-
-@deffn procedure reduce-right procedure initial list
-Like @code{reduce} except that it is right-associative.
-
-@example
-(reduce-right list '() '(1 2 3 4)) @result{} (1 (2 (3 4)))
-@end example
-@end deffn
-
-@deffn procedure fold-right procedure initial list
-Combines all of the elements of @var{list} using the binary operation
-@var{procedure}. Unlike @code{reduce} and @code{reduce-right},
-@var{initial} is always used:
-
-@example
-@group
-(fold-right + 0 '(1 2 3 4)) @result{} 10
-(fold-right + 0 '(foo)) @error{} Illegal datum
-(fold-right list '() '(1 2 3 4)) @result{} (1 (2 (3 (4 ()))))
-@end group
-@end example
-
-@code{Fold-right} has interesting properties because it establishes a
-homomorphism between (@code{cons}, @code{()}) and (@var{procedure},
-@var{initial}). It can be thought of as replacing the pairs in the
-spine of the list with @var{procedure} and replacing the @code{()} at
-the end with @var{initial}. Many of the classical list-processing
-procedures can be expressed in terms of @code{fold-right}, at least for
-the simple versions that take a fixed number of arguments:
-
-@example
-@group
-(define (copy-list list)
- (fold-right cons '() list))
-
-(define (append list1 list2)
- (fold-right cons list2 list1))
-
-(define (map p list)
- (fold-right (lambda (x r) (cons (p x) r)) '() list))
-
-(define (reverse items)
- (fold-right (lambda (x r) (append r (list x))) '() items))
-@end group
-@end example
-@end deffn
-
-@deffn procedure fold-left procedure initial list
-Combines all the elements of @var{list} using the binary operation
-@var{procedure}. Elements are combined starting with @var{initial} and
-then the elements of @var{list} from left to right. Whereas
-@code{fold-right} is recursive in nature, capturing the essence of
-@code{cdr}-ing down a list and then computing a result, @var{fold-left}
-is iterative in nature, combining the elements as the list is traversed.
-
-@example
-@group
-(fold-left list '() '(1 2 3 4)) @result{} ((((() 1) 2) 3) 4)
-
-(define (length list)
- (fold-left (lambda (sum element) (+ sum 1)) 0 list))
-
-(define (reverse items)
- (fold-left (lambda (x y) (cons y x)) () items))
-@end group
-@end example
-@end deffn
-
-@deffn procedure there-exists? list predicate
-@var{Predicate} must be a procedure of one argument. Applies
-@var{predicate} to each element of @var{list}, in order from left to
-right. If @var{predicate} is true for any element of @var{list}, the
-value yielded by @var{predicate} is immediately returned as the value of
-@code{there-exists?}; @var{predicate} will not be applied to the
-remaining elements of @var{list}. If @var{predicate} returns @code{#f}
-for all of the elements of @var{list}, then @code{#f} is returned.
-@end deffn
-
-@deffn procedure for-all? list predicate
-@var{Predicate} must be a procedure of one argument. Applies
-@var{predicate} to each element of @var{list}, in order from left to
-right. If @var{predicate} returns @code{#f} for any element of
-@var{list}, @code{#f} is immediately returned as the value of
-@code{for-all?}; @var{predicate} will not be applied to the remaining
-elements of @var{list}. If @var{predicate} is true for all of the
-elements of @var{list}, then @code{#t} is returned.
-@end deffn
-
-@node Miscellaneous List Operations, , Reduction of Lists, Lists
-@section Miscellaneous List Operations
-
-@deffn procedure circular-list object @dots{}
-@deffnx procedure make-circular-list k [element]
-@cindex circular list
-@cindex construction, of circular list
-@findex list
-@findex make-list
-These procedures are like @code{list} and @code{make-list},
-respectively, except that the returned lists are circular.
-@code{circular-list} could have been defined like this:
-
-@example
-@group
-(define (circular-list . objects)
- (append! objects objects))
-@end group
-@end example
-@end deffn
-
-@deffn procedure reverse list
-@cindex reversal, of list
-Returns a newly allocated list consisting of the top-level elements of
-@var{list} in reverse order.
-
-@example
-@group
-(reverse '(a b c)) @result{} (c b a)
-(reverse '(a (b c) d (e (f)))) @result{} ((e (f)) d (b c) a)
-@end group
-@end example
-@end deffn
-
-@deffn procedure reverse! list
-Returns a list consisting of the top-level elements of @var{list} in
-reverse order. @code{reverse!} is like @code{reverse}, except that it
-destructively modifies @var{list}. Because the result may not be
-@code{eqv?} to @var{list}, it is desirable to do something like
-@code{(set! x (reverse! x))}.
-@end deffn
-
-@deffn procedure sort sequence procedure
-@deffnx procedure merge-sort sequence procedure
-@deffnx procedure quick-sort sequence procedure
-@cindex total ordering (defn)
-@var{Sequence} must be either a list or a vector. @var{Procedure} must be a
-procedure of two arguments that defines a @dfn{total ordering} on the
-elements of @var{sequence}. In other words, if @var{x} and @var{y} are two
-distinct elements of @var{sequence}, then it must be the case that
-
-@example
-@group
-(and (@var{procedure} @var{x} @var{y})
- (@var{procedure} @var{y} @var{x}))
- @result{} #f
-@end group
-@end example
-
-If @var{sequence} is a list (vector), @code{sort} returns a newly
-allocated list (vector) whose elements are those of @var{sequence},
-except that they are rearranged to be sorted in the order defined by
-@var{procedure}. So, for example, if the elements of @var{sequence} are
-numbers, and @var{procedure} is @code{<}, then the resulting elements
-are sorted in monotonically nondecreasing order. Likewise, if
-@var{procedure} is @code{>}, the resulting elements are sorted in
-monotonically nonincreasing order. To be precise, if @var{x} and
-@var{y} are any two adjacent elements in the result, where @var{x}
-precedes @var{y}, it is the case that
-
-@example
-@group
-(@var{procedure} @var{y} @var{x})
- @result{} #f
-@end group
-@end example
-
-Two sorting algorithms are implemented: @code{merge-sort} and
-@code{quick-sort}. The procedure @code{sort} is an alias for
-@code{merge-sort}.
-
-See also the definition of @code{sort!}.
-@end deffn
-
-@node Vectors, Bit Strings, Lists, Top
-@chapter Vectors
-
-@cindex vector (defn)
-@dfn{Vectors} are heterogenous structures whose elements are indexed by
-exact non-negative integers. A vector typically occupies less space
-than a list of the same length, and the average time required to access
-a randomly chosen element is typically less for the vector than for the
-list.
-
-@cindex length, of vector (defn)
-@cindex index, of vector (defn)
-@cindex valid index, of vector (defn)
-@cindex vector length (defn)
-@cindex vector index (defn)
-The @dfn{length} of a vector is the number of elements that it contains.
-This number is an exact non-negative integer that is fixed when the
-vector is created. The @dfn{valid indexes} of a vector are the exact
-non-negative integers less than the length of the vector. The first
-element in a vector is indexed by zero, and the last element is indexed
-by one less than the length of the vector.
-
-@cindex external representation, for vector
-@cindex #( as external representation
-@cindex parenthesis, as external representation
-@findex #(
-Vectors are written using the notation @code{#(@var{object} @dots{})}.
-For example, a vector of length 3 containing the number zero in element
-0, the list @code{(2 2 2 2)} in element 1, and the string @code{"Anna"}
-in element 2 can be written as
-
-@example
-#(0 (2 2 2 2) "Anna")
-@end example
-
-@noindent
-Note that this is the external representation of a vector, not an
-expression evaluating to a vector. Like list constants, vector
-constants must be quoted:
-
-@example
-'#(0 (2 2 2 2) "Anna") @result{} #(0 (2 2 2 2) "Anna")
-@end example
-
-@cindex subvector (defn)
-@cindex start, of subvector (defn)
-@cindex end, of subvector (defn)
-@cindex index, of subvector (defn)
-@cindex valid index, of subvector (defn)
-A number of the vector procedures operate on subvectors. A
-@dfn{subvector} is a segment of a vector that is specified by two exact
-non-negative integers, @var{start} and @var{end}. @var{Start} is the
-index of the first element that is included in the subvector, and
-@var{end} is one greater than the index of the last element that is
-included in the subvector. Thus if @var{start} and @var{end} are the
-same, they refer to a null subvector, and if @var{start} is zero and
-@var{end} is the length of the vector, they refer to the entire vector.
-The @dfn{valid indexes} of a subvector are the exact integers between
-@var{start} inclusive and @var{end} exclusive.
-
-@menu
-* Construction of Vectors::
-* Selecting Vector Components::
-* Cutting Vectors::
-* Modifying Vectors::
-@end menu
-
-@node Construction of Vectors, Selecting Vector Components, Vectors, Vectors
-@section Construction of Vectors
-@cindex construction, of vector
-
-@deffn {procedure} make-vector k [object]
-Returns a newly allocated vector of @var{k} elements. If @var{object}
-is specified, @code{make-vector} initializes each element of the vector
-to @var{object}. Otherwise the initial elements of the result are
-unspecified.
-@end deffn
-
-@deffn procedure vector object @dots{}
-@findex list
-Returns a newly allocated vector whose elements are the given arguments.
-@code{vector} is analogous to @code{list}.
-
-@example
-(vector 'a 'b 'c) @result{} #(a b c)
-@end example
-@end deffn
-
-@deffn procedure vector-copy vector
-@cindex copying, of vector
-Returns a newly allocated vector that is a copy of @var{vector}.
-@end deffn
-
-@deffn procedure list->vector list
-@cindex list, converting to vector
-@findex vector->list
-Returns a newly allocated vector initialized to the elements of
-@var{list}. The inverse of @code{list->vector} is @code{vector->list}.
-
-@example
-(list->vector '(dididit dah)) @result{} #(dididit dah)
-@end example
-@end deffn
-
-@deffn procedure make-initialized-vector k initialization
-Similar to @code{make-vector}, except that the elements of the result
-are determined by calling the procedure @var{initialization} on the
-indices. For example:
-
-@example
-@group
-(make-initialized-vector 5 (lambda (x) (* x x)))
- @result{} #(0 1 4 9 16)
-@end group
-@end example
-@end deffn
-
-@deffn procedure vector-grow vector k
-@cindex growing, of vector
-@var{K} must be greater than or equal to the length of @var{vector}.
-Returns a newly allocated vector of length @var{k}. The first
-@code{(vector-length @var{vector})} elements of the result are
-initialized from the corresponding elements of @var{vector}. The
-remaining elements of the result are unspecified.
-@end deffn
-
-@deffn procedure vector-map procedure vector
-@cindex mapping, of vector
-@var{Procedure} must be a procedure of one argument. @code{vector-map}
-applies @var{procedure} element-wise to the elements of @var{vector} and
-returns a newly allocated vector of the results, in order from left to
-right. The dynamic order in which @var{procedure} is applied to the
-elements of @var{vector} is unspecified.
-
-@example
-@group
-(vector-map cadr '#((a b) (d e) (g h))) @result{} #(b e h)
-(vector-map (lambda (n) (expt n n)) '#(1 2 3 4))
- @result{} #(1 4 27 256)
-(vector-map + '#(5 7 9)) @result{} #(5 7 9)
-@end group
-@end example
-@end deffn
-
-@node Selecting Vector Components, Cutting Vectors, Construction of Vectors, Vectors
-@section Selecting Vector Components
-@cindex selection, of vector component
-@cindex component selection, of vector
-
-@deffn procedure vector? object
-@cindex type predicate, for vector
-Returns @code{#t} if @var{object} is a vector; otherwise returns
-@code{#f}.
-@end deffn
-
-@deffn procedure vector-length vector
-Returns the number of elements in @var{vector}.
-@end deffn
-
-@deffn procedure vector-ref vector k
-Returns the contents of element @var{k} of @var{vector}. @var{K} must
-be a valid index of @var{vector}.
-
-@example
-(vector-ref '#(1 1 2 3 5 8 13 21) 5) @result{} 8
-@end example
-@end deffn
-
-@deffn procedure vector-set! vector k object
-Stores @var{object} in element @var{k} of @var{vector} and returns an
-unspecified value. @var{K} must be a valid index of
-@var{vector}.
-
-@example
-@group
-(let ((vec (vector 0 '(2 2 2 2) "Anna")))
- (vector-set! vec 1 '("Sue" "Sue"))
- vec)
- @result{} #(0 ("Sue" "Sue") "Anna")
-@end group
-@end example
-@end deffn
-
-@deffn procedure vector-first vector
-@deffnx procedure vector-second vector
-@deffnx procedure vector-third vector
-@deffnx procedure vector-fourth vector
-@deffnx procedure vector-fifth vector
-@deffnx procedure vector-sixth vector
-@deffnx procedure vector-seventh vector
-@deffnx procedure vector-eighth vector
-These procedures access the first several elements of @var{vector} in
-the obvious way. It is an error if the implicit index of one of these
-procedurs is not a valid index of @var{vector}.
-@end deffn
-
-@deffn procedure vector-binary-search vector key<? unwrap-key key
-@cindex searching, of vector
-Searches @var{vector} for an element with a key matching @var{key},
-returning the element if one is found or @code{#f} if none. The
-search operation takes time proportional to the logarithm of the length
-of @var{vector}. @var{Unwrap-key} must be a procedure that maps each
-element of @var{vector} to a key. @var{Key<?} must be a procedure that
-implements a total ordering on the keys of the elements.
-
-@example
-@group
-(define (translate number)
- (vector-binary-search '#((1 . i)
- (2 . ii)
- (3 . iii)
- (6 . vi))
- < car number))
-(translate 2) @result{} (2 . ii)
-(translate 4) @result{} #F
-@end group
-@end example
-@end deffn
-
-@node Cutting Vectors, Modifying Vectors, Selecting Vector Components, Vectors
-@section Cutting Vectors
-@cindex cutting, of vector
-
-@deffn procedure subvector vector start end
-Returns a newly allocated vector that contains the elements of
-@var{vector} between index @var{start} (inclusive) and @var{end}
-(exclusive).
-@end deffn
-
-@deffn procedure vector-head vector end
-Equivalent to
-
-@example
-(subvector @var{vector} 0 @var{end})
-@end example
-@end deffn
-
-@deffn procedure vector-tail vector start
-Equivalent to
-
-@example
-(subvector @var{vector} @var{start} (vector-length @var{vector}))
-@end example
-@end deffn
-
-@node Modifying Vectors, , Cutting Vectors, Vectors
-@section Modifying Vectors
-@cindex modification, of vector
-@cindex filling, of vector
-@cindex moving, of vector elements
-
-@deffn {procedure} vector-fill! vector object
-@deffnx procedure subvector-fill! vector start end object
-Stores @var{object} in every element of the vector (subvector) and
-returns an unspecified value.
-@end deffn
-
-@deffn procedure subvector-move-left! vector1 start1 end1 vector2 start2
-@deffnx procedure subvector-move-right! vector1 start1 end1 vector2 start2
-Destructively copies the elements of @var{vector1}, starting with index
-@var{start1} (inclusive) and ending with @var{end1} (exclusive), into
-@var{vector2} starting at index @var{start2} (inclusive).
-@var{Vector1}, @var{start1}, and @var{end1} must specify a valid
-subvector, and @var{start2} must be a valid index for @var{vector2}.
-The length of the source subvector must not exceed the length of
-@var{vector2} minus the index @var{start2}.
-
-The elements are copied as follows (note that this is only important when
-@var{vector1} and @var{vector2} are @code{eqv?}):
-
-@table @code
-@item subvector-move-left!
-The copy starts at the left end and moves toward the right (from smaller
-indices to larger). Thus if @var{vector1} and @var{vector2} are the
-same, this procedure moves the elements toward the left inside the
-vector.
-
-@item subvector-move-right!
-The copy starts at the right end and moves toward the left (from larger
-indices to smaller). Thus if @var{vector1} and @var{vector2} are the
-same, this procedure moves the elements toward the right inside the
-vector.
-@end table
-@end deffn
-
-@deffn procedure sort! vector procedure
-@deffnx procedure merge-sort! vector procedure
-@deffnx procedure quick-sort! vector procedure
-@var{Procedure} must be a procedure of two arguments that defines a
-@dfn{total ordering} on the elements of @var{vector}. The elements of
-@var{vector} are rearranged so that they are sorted in the order defined
-by @var{procedure}. The elements are rearranged in place, that is,
-@var{vector} is destructively modified so that its elements are in the
-new order.
-
-@code{sort!} returns @var{vector} as its value.
-
-Two sorting algorithms are implemented: @code{merge-sort!} and
-@code{quick-sort!}. The procedure @code{sort!} is an alias for
-@code{merge-sort!}.
-
-See also the definition of @code{sort}.
-@end deffn
-
-@node Bit Strings, Miscellaneous Datatypes, Vectors, Top
-@chapter Bit Strings
-
-@cindex bit string (defn)
-@cindex string, of bits (defn)
-A @dfn{bit string} is a sequence of bits. Bit strings can be used to
-represent sets or to manipulate binary data. The elements of a bit
-string are numbered from zero up to the number of bits in the string
-less one, in @emph{right to left order}, (the rightmost bit is numbered
-zero). When you convert from a bit string to an integer, the zero-th
-bit is associated with the zero-th power of two, the first bit is
-associated with the first power, and so on.
-
-Bit strings are encoded very densely in memory. Each bit occupies
-exactly one bit of storage, and the overhead for the entire bit string
-is bounded by a small constant. However, accessing a bit in a bit
-string is slow compared to accessing an element of a vector or character
-string. If performance is of overriding concern, it is better to use
-character strings to store sets of boolean values even though they
-occupy more space.
-
-@cindex length, of bit string (defn)
-@cindex index, of bit string (defn)
-@cindex valid index, of bit string (defn)
-@cindex bit string length (defn)
-@cindex bit string index (defn)
-The @dfn{length} of a bit string is the number of bits that it contains.
-This number is an exact non-negative integer that is fixed when the bit
-string is created. The @dfn{valid indexes} of a bit string are the
-exact non-negative integers less than the length of the bit string.
-
-@cindex external representation, for bit string
-@cindex #* as external representation
-@cindex asterisk, as external representation
-Bit strings may contain zero or more bits. They are not limited by the
-length of a machine word. In the printed representation of a bit
-string, the contents of the bit string are preceded by @samp{#*}. The
-contents are printed starting with the most significant bit (highest
-index).
-
-Note that the external representation of bit strings uses a bit ordering
-that is the reverse of the representation for bit strings in Common
-Lisp. It is likely that MIT/GNU Scheme's representation will be
-changed in the future, to be compatible with Common Lisp. For the time
-being this representation should be considered a convenience for viewing
-bit strings rather than a means of entering them as data.
-
-@example
-@group
-#*11111
-#*1010
-#*00000000
-#*
-@end group
-@end example
-
-All of the bit-string procedures are MIT/GNU Scheme extensions.
-
-@menu
-* Construction of Bit Strings::
-* Selecting Bit String Components::
-* Cutting and Pasting Bit Strings::
-* Bitwise Operations on Bit Strings::
-* Modification of Bit Strings::
-* Integer Conversions of Bit Strings::
-@end menu
-
-@node Construction of Bit Strings, Selecting Bit String Components, Bit Strings, Bit Strings
-@section Construction of Bit Strings
-@cindex construction, of bit string
-
-@deffn procedure make-bit-string k initialization
-Returns a newly allocated bit string of length @var{k}. If
-@var{initialization} is @code{#f}, the bit string is filled with 0 bits;
-otherwise, the bit string is filled with 1 bits.
-
-@example
-(make-bit-string 7 #f) @result{} #*0000000
-@end example
-@end deffn
-
-@deffn procedure bit-string-allocate k
-Returns a newly allocated bit string of length @var{k}, but does not
-initialize it.
-@end deffn
-
-@deffn procedure bit-string-copy bit-string
-@cindex copying, of bit string
-Returns a newly allocated copy of @var{bit-string}.
-@end deffn
-
-@node Selecting Bit String Components, Cutting and Pasting Bit Strings, Construction of Bit Strings, Bit Strings
-@section Selecting Bit String Components
-
-@deffn procedure bit-string? object
-@cindex type predicate, for bit string
-Returns @code{#t} if @var{object} is a bit string; otherwise returns
-@code{#f}.
-@end deffn
-
-@deffn procedure bit-string-length bit-string
-@cindex length, of bit string
-Returns the length of @var{bit-string}.
-@end deffn
-
-@deffn procedure bit-string-ref bit-string k
-@cindex selection, of bit string component
-@cindex component selection, of bit string
-Returns @code{#t} if the @var{k}th bit is 1; otherwise returns
-@code{#f}. @var{K} must be a valid index of @var{bit-string}.
-@end deffn
-
-@deffn procedure bit-string-set! bit-string k
-Sets the @var{k}th bit in @var{bit-string} to 1 and returns an
-unspecified value. @var{K} must be a valid index of @var{bit-string}.
-@end deffn
-
-@deffn procedure bit-string-clear! bit-string k
-Sets the @var{k}th bit in @var{bit-string} to 0 and returns an
-unspecified value. @var{K} must be a valid index of @var{bit-string}.
-@end deffn
-
-@deffn procedure bit-substring-find-next-set-bit bit-string start end
-@cindex searching, of bit string
-Returns the index of the first occurrence of a set bit in the substring
-of @var{bit-string} from @var{start} (inclusive) to @var{end}
-(exclusive). If none of the bits in the substring are set @code{#f} is
-returned. The index returned is relative to the whole bit string, not
-substring.
-
-The following procedure uses @code{bit-substring-find-next-set-bit} to
-find all the set bits and display their indexes:
-
-@example
-@group
-(define (scan-bitstring bs)
- (let ((end (bit-string-length bs)))
- (let loop ((start 0))
- (let ((next
- (bit-substring-find-next-set-bit bs start end)))
- (if next
- (begin
- (write-line next)
- (if (< next end)
- (loop (+ next 1)))))))))
-@end group
-@end example
-@end deffn
-
-@node Cutting and Pasting Bit Strings, Bitwise Operations on Bit Strings, Selecting Bit String Components, Bit Strings
-@section Cutting and Pasting Bit Strings
-@cindex cutting, of bit string
-@cindex pasting, of bit strings
-
-@deffn procedure bit-string-append bit-string-1 bit-string-2
-@cindex appending, of bit strings
-Appends the two bit string arguments, returning a newly allocated bit
-string as its result. In the result, the bits copied from
-@var{bit-string-1} are less significant (smaller indices) than those
-copied from @var{bit-string-2}.
-@end deffn
-
-@deffn procedure bit-substring bit-string start end
-@cindex substring, of bit string
-Returns a newly allocated bit string whose bits are copied from
-@var{bit-string}, starting at index @var{start} (inclusive) and ending
-at @var{end} (exclusive).
-@end deffn
-
-@node Bitwise Operations on Bit Strings, Modification of Bit Strings, Cutting and Pasting Bit Strings, Bit Strings
-@section Bitwise Operations on Bit Strings
-
-@deffn procedure bit-string-zero? bit-string
-Returns @code{#t} if @var{bit-string} contains only 0 bits; otherwise
-returns @code{#f}.
-@end deffn
-
-@deffn procedure bit-string=? bit-string-1 bit-string-2
-@cindex equivalence predicate, for bit strings
-@cindex comparison, of bit strings
-Compares the two bit string arguments and returns @code{#t} if they are the
-same length and contain the same bits; otherwise returns @code{#f}.
-@end deffn
-
-@deffn procedure bit-string-not bit-string
-@cindex inverse, of bit string
-Returns a newly allocated bit string that is the bitwise-logical
-negation of @var{bit-string}.
-@end deffn
-
-@deffn procedure bit-string-movec! target-bit-string bit-string
-The destructive version of @code{bit-string-not}. The arguments
-@var{target-bit-string} and @var{bit-string} must be bit strings of the
-same length. The bitwise-logical negation of @var{bit-string} is
-computed and the result placed in @var{target-bit-string}. The value of
-this procedure is unspecified.
-@end deffn
-
-@deffn procedure bit-string-and bit-string-1 bit-string-2
-Returns a newly allocated bit string that is the bitwise-logical ``and''
-of the arguments. The arguments must be bit strings of identical
-length.
-@end deffn
-
-@deffn procedure bit-string-andc bit-string-1 bit-string-2
-Returns a newly allocated bit string that is the bitwise-logical ``and''
-of @var{bit-string-1} with the bitwise-logical negation of
-@var{bit-string-2}. The arguments must be bit strings of identical
-length.
-@end deffn
-
-@deffn procedure bit-string-or bit-string-1 bit-string-2
-Returns a newly allocated bit string that is the bitwise-logical
-``inclusive or'' of the arguments. The arguments must be bit strings of
-identical length.
-@end deffn
-
-@deffn procedure bit-string-xor bit-string-1 bit-string-2
-Returns a newly allocated bit string that is the bitwise-logical
-``exclusive or'' of the arguments. The arguments must be bit strings of
-identical length.
-@end deffn
-
-@deffn procedure bit-string-and! target-bit-string bit-string
-@deffnx procedure bit-string-or! target-bit-string bit-string
-@deffnx procedure bit-string-xor! target-bit-string bit-string
-@deffnx procedure bit-string-andc! target-bit-string bit-string
-These are destructive versions of the above operations. The arguments
-@var{target-bit-string} and @var{bit-string} must be bit strings of the
-same length. Each of these procedures performs the corresponding
-bitwise-logical operation on its arguments, places the result into
-@var{target-bit-string}, and returns an unspecified result.
-@end deffn
-
-@node Modification of Bit Strings, Integer Conversions of Bit Strings, Bitwise Operations on Bit Strings, Bit Strings
-@section Modification of Bit Strings
-@cindex modification, of bit string
-@cindex filling, of bit string
-@cindex moving, of bit string elements
-
-@deffn procedure bit-string-fill! bit-string initialization
-Fills @var{bit-string} with zeroes if @var{initialization} is @code{#f};
-otherwise fills @var{bit-string} with ones. Returns an unspecified
-value.
-@end deffn
-
-@deffn procedure bit-string-move! target-bit-string bit-string
-Moves the contents of @var{bit-string} into @var{target-bit-string}. Both
-arguments must be bit strings of the same length. The results of the
-operation are undefined if the arguments are the same bit string.
-@end deffn
-
-@deffn procedure bit-substring-move-right! bit-string-1 start1 end1 bit-string-2 start2
-Destructively copies the bits of @var{bit-string-1}, starting at index
-@var{start1} (inclusive) and ending at @var{end1} (exclusive), into
-@var{bit-string-2} starting at index @var{start2} (inclusive).
-@var{Start1} and @var{end1} must be valid substring indices for
-@var{bit-string-1}, and @var{start2} must be a valid index for
-@var{bit-string-2}. The length of the source substring must not exceed
-the length of @var{bit-string-2} minus the index @var{start2}.
-
-The bits are copied starting from the MSB and working towards the LSB; the
-direction of copying only matters when @var{bit-string-1} and
-@var{bit-string-2} are @code{eqv?}.
-@end deffn
-
-@need 1000
-@node Integer Conversions of Bit Strings, , Modification of Bit Strings, Bit Strings
-@section Integer Conversions of Bit Strings
-@cindex integer, converting to bit string
-
-@deffn procedure unsigned-integer->bit-string length integer
-Both @var{length} and @var{integer} must be exact non-negative integers.
-Converts @var{integer} into a newly allocated bit string of @var{length}
-bits. Signals an error of type @code{condition-type:bad-range-argument}
-if @var{integer} is too large to be represented in @var{length} bits.
-@findex condition-type:bad-range-argument
-@end deffn
-
-@deffn procedure signed-integer->bit-string length integer
-@var{Length} must be an exact non-negative integer, and @var{integer}
-may be any exact integer. Converts @var{integer} into a newly allocated
-bit string of @var{length} bits, using two's complement encoding for
-negative numbers. Signals an error of type
-@code{condition-type:bad-range-argument} if @var{integer} is too large
-to be represented in @var{length} bits.
-@findex condition-type:bad-range-argument
-@end deffn
-
-@deffn procedure bit-string->unsigned-integer bit-string
-@deffnx procedure bit-string->signed-integer bit-string
-Converts @var{bit-string} into an exact integer.
-@code{bit-string->signed-integer} regards @var{bit-string} as a two's
-complement representation of a signed integer, and produces an integer
-of like sign and absolute value. @code{bit-string->unsigned-integer}
-regards @var{bit-string} as an unsigned quantity and converts to an
-integer accordingly.
-@end deffn
-
-@node Miscellaneous Datatypes, Associations, Bit Strings, Top
-@chapter Miscellaneous Datatypes
-
-@menu
-* Booleans::
-* Symbols::
-* Cells::
-* Records::
-* Promises::
-* Streams::
-* Weak Pairs::
-@end menu
-
-@node Booleans, Symbols, Miscellaneous Datatypes, Miscellaneous Datatypes
-@section Booleans
-
-@findex #t
-@findex #f
-@cindex #t as external representation
-@cindex #f as external representation
-@cindex boolean object (defn)
-@cindex true, boolean object (defn)
-@cindex false, boolean object (defn)
-The @dfn{boolean objects} are @dfn{true} and @dfn{false}. The boolean
-constant true is written as @samp{#t}, and the boolean constant false is
-written as @samp{#f}.
-
-@findex if
-@findex cond
-@findex and
-@findex or
-The primary use for boolean objects is in the conditional expressions
-@code{if}, @code{cond}, @code{and}, and @code{or}; the behavior of these
-expressions is determined by whether objects are true or false. These
-expressions count only @code{#f} as false. They count everything else,
-including @code{#t}, pairs, symbols, numbers, strings, vectors, and
-procedures as true (but @pxref{True and False}).
-
-@findex t
-@findex nil
-Programmers accustomed to other dialects of Lisp should note that Scheme
-distinguishes @code{#f} and the empty list from the symbol @code{nil}.
-Similarly, @code{#t} is distinguished from the symbol @code{t}. In
-fact, the boolean objects (and the empty list) are not symbols at all.
-
-Boolean constants evaluate to themselves, so you don't need to quote
-them.
-
-@example
-@group
-#t @result{} #t
-#f @result{} #f
-'#f @result{} #f
-t @error{} Unbound variable
-@end group
-@end example
-
-@defvr variable false
-@defvrx variable true
-These variables are bound to the objects @code{#f} and @code{#t}
-respectively. The compiler, given the @code{usual-integrations}
-declaration, replaces references to these variables with their
-respective values.
-
-Note that the symbol @code{true} is not equivalent to @code{#t}, and the
-symbol @code{false} is not equivalent to @code{#f}.
-@end defvr
-
-@deffn procedure boolean? object
-@cindex type predicate, for boolean
-Returns @code{#t} if @var{object} is either @code{#t} or @code{#f};
-otherwise returns @code{#f}.
-
-@example
-@group
-(boolean? #f) @result{} #t
-(boolean? 0) @result{} #f
-@end group
-@end example
-@end deffn
-
-@deffn procedure not object
-@deffnx procedure false? object
-@cindex false, predicate for
-@cindex inverse, of boolean object
-These procedures return @code{#t} if @var{object} is false; otherwise
-they return @code{#f}. In other words they @emph{invert} boolean
-values. These two procedures have identical semantics; their names are
-different to give different connotations to the test.
-
-@example
-@group
-(not #t) @result{} #f
-(not 3) @result{} #f
-(not (list 3)) @result{} #f
-(not #f) @result{} #t
-@end group
-@end example
-@end deffn
-
-@deffn procedure boolean=? obj1 obj2
-@cindex boolean object, equivalence predicate
-@cindex equivalence predicate, for boolean objects
-@cindex comparison, of boolean objects
-This predicate is true iff @var{obj1} and @var{obj2} are either both true
-or both false.
-@end deffn
-
-@deffn procedure boolean/and object @dots{}
-This procedure returns @code{#t} if none of its arguments are @code{#f}.
-Otherwise it returns @code{#f}.
-@end deffn
-
-@deffn procedure boolean/or object @dots{}
-This procedure returns @code{#f} if all of its arguments are @code{#f}.
-Otherwise it returns @code{#t}.
-@end deffn
-
-@node Symbols, Cells, Booleans, Miscellaneous Datatypes
-@section Symbols
-
-@cindex symbol (defn)
-@cindex interned symbol (defn)
-@cindex uninterned symbol (defn)
-@cindex property list, of symbol
-@cindex disembodied property list
-@findex read
-MIT/GNU Scheme provides two types of symbols: @dfn{interned} and
-@dfn{uninterned}. Interned symbols are far more common than uninterned
-symbols, and there are more ways to create them. Interned symbols have
-an external representation that is recognized by the procedure
-@code{read}; uninterned symbols do not.@footnote{In older dialects of
-Lisp, uninterned symbols were fairly important. This was true because
-symbols were complicated data structures: in addition to having value
-cells (and sometimes, function cells), these structures contained
-@dfn{property lists}. Because of this, uninterned symbols were often
-used merely for their property lists --- sometimes an uninterned symbol
-used this way was referred to as a @dfn{disembodied property list}. In
-MIT/GNU Scheme, symbols do not have property lists, or any other components
-besides their names. There is a different data structure similar to
-disembodied property lists: one-dimensional tables (@pxref{1D Tables}).
-For these reasons, uninterned symbols are not very useful in MIT/GNU Scheme.
-In fact, their primary purpose is to simplify the generation of unique
-variable names in programs that generate Scheme code.}
-
-@findex string=?
-@findex eq?
-Interned symbols have an extremely useful property: any two interned
-symbols whose names are the same, in the sense of @code{string=?}, are
-the same object (i.e.@: they are @code{eq?} to one another). The term
-@dfn{interned} refers to the process of @dfn{interning} by which this is
-accomplished. Uninterned symbols do not share this property.
-
-@cindex case, of interned symbol
-@cindex alphabetic case, of interned symbol
-@findex write
-The names of interned symbols are not distinguished by their alphabetic
-case. Because of this, MIT/GNU Scheme converts all alphabetic
-characters in the name of an interned symbol to a specific case (lower
-case) when the symbol is created. When the name of an interned symbol
-is referenced (using @code{symbol->string}) or written (using
-@code{write}) it appears in this case. It is a bad idea to depend on
-the name being lower case. In fact, it is preferable to take this one
-step further: don't depend on the name of a symbol being in a uniform
-case.
-
-@cindex external representation, for symbol
-@findex read
-@findex write
-The rules for writing an interned symbol are the same as the rules for
-writing an identifier (@pxref{Identifiers}). Any interned symbol that
-has been returned as part of a literal expression, or read using the
-@code{read} procedure and subsequently written out using the
-@code{write} procedure, will read back in as the identical symbol (in
-the sense of @code{eq?}).
-
-Usually it is also true that reading in an interned symbol that was
-previously written out produces the same symbol. An exception are
-symbols created by the procedures @code{string->symbol} and
-@code{intern}; they can create symbols for which this write/read
-invariance may not hold because the symbols' names contain special
-characters or letters in the non-standard case.@footnote{MIT/GNU Scheme
-reserves a specific set of interned symbols for its own use. If you use
-these reserved symbols it is possible that you could break specific
-pieces of software that depend on them. The reserved symbols all have
-names beginning with the characters @samp{#[} and ending with the
-character @samp{]}; thus none of these symbols can be read by the
-procedure @code{read} and hence are not likely to be used by accident.
-For example, @code{(intern "#[unnamed-procedure]")} produces a reserved
-symbol.}
-
-@findex read
-The external representation for uninterned symbols is special, to
-distinguish them from interned symbols and prevent them from being
-recognized by the @code{read} procedure:
-
-@example
-@group
-(string->uninterned-symbol "foo")
- @result{} #[uninterned-symbol 30 foo]
-@end group
-@end example
-
-In this section, the procedures that return symbols as values will
-either always return interned symbols, or always return uninterned
-symbols. The procedures that accept symbols as arguments will always
-accept either interned or uninterned symbols, and do not distinguish the
-two.
-
-@deffn procedure symbol? object
-@cindex type predicate, for symbol
-Returns @code{#t} if @var{object} is a symbol, otherwise returns
-@code{#f}.
-
-@example
-@group
-(symbol? 'foo) @result{} #t
-(symbol? (car '(a b))) @result{} #t
-(symbol? "bar") @result{} #f
-@end group
-@end example
-@end deffn
-
-@deffn procedure symbol->string symbol
-@cindex name, of symbol
-@cindex print name, of symbol
-@findex string=?
-@findex string-set!
-Returns the name of @var{symbol} as a string. If @var{symbol} was
-returned by @code{string->symbol}, the value of this procedure will be
-identical (in the sense of @code{string=?}) to the string that was
-passed to @code{string->symbol}. It is an error to apply mutation
-procedures such as @code{string-set!} to strings returned by this
-procedure.
-
-@example
-@group
-(symbol->string 'flying-fish) @result{} "flying-fish"
-(symbol->string 'Martin) @result{} "martin"
-(symbol->string (string->symbol "Malvina"))
- @result{} "Malvina"
-@end group
-@end example
-
-Note that two distinct uninterned symbols can have the same name.
-@end deffn
-
-@deffn procedure intern string
-@cindex interning, of symbols
-@cindex construction, of symbols
-Returns the interned symbol whose name is @var{string}. Converts
-@var{string} to the standard alphabetic case before generating the
-symbol. This is the preferred way to create interned symbols, as it
-guarantees the following independent of which case the implementation
-uses for symbols' names:
-
-@example
-(eq? 'bitBlt (intern "bitBlt")) @result{} #t
-@end example
-
-The user should take care that @var{string} obeys the rules for
-identifiers (@pxref{Identifiers}), otherwise the resulting symbol cannot
-be read as itself.
-@end deffn
-
-@deffn procedure intern-soft string
-Returns the interned symbol whose name is @var{string}. Converts
-@var{string} to the standard alphabetic case before generating the
-symbol. If no such interned symbol exists, returns @code{#f}.
-
-This is exactly like @code{intern}, except that it will not create an
-interned symbol, but only returns symbols that already exist.
-@end deffn
-
-@deffn procedure string->symbol string
-@cindex string, interning as symbol
-Returns the interned symbol whose name is @var{string}. Although you
-can use this procedure to create symbols with names containing special
-characters or lowercase letters, it's usually a bad idea to create such
-symbols because they cannot be read as themselves. See
-@code{symbol->string}.
-
-@example
-@group
-(eq? 'mISSISSIppi 'mississippi) @result{} #t
-(string->symbol "mISSISSIppi")
- @result{} @r{the symbol with the name} "mISSISSIppi"
-(eq? 'bitBlt (string->symbol "bitBlt")) @result{} #f
-(eq? 'JollyWog
- (string->symbol
- (symbol->string 'JollyWog))) @result{} #t
-(string=? "K. Harper, M.D."
- (symbol->string
- (string->symbol
- "K. Harper, M.D."))) @result{} #t
-@end group
-@end example
-@end deffn
-
-@deffn procedure string->uninterned-symbol string
-Returns a newly allocated uninterned symbol whose name is @var{string}.
-It is unimportant what case or characters are used in
-@var{string}.
-
-Note: this is the fastest way to make a symbol.
-@end deffn
-
-@deffn procedure generate-uninterned-symbol [object]
-@cindex gensym (see uninterned symbol)
-@findex eq?
-Returns a newly allocated uninterned symbol that is guaranteed to be
-different from any other object. The symbol's name consists of a prefix
-string followed by the (exact non-negative integer) value of an internal
-counter. The counter is initially zero, and is incremented after each
-call to this procedure.
-
-The optional argument @var{object} is used to control how the symbol is
-generated. It may take one of the following values:
-
-@itemize @bullet
-@item
-If @var{object} is omitted or @code{#f}, the prefix is @code{"G"}.
-
-@item
-If @var{object} is an exact non-negative integer, the internal counter
-is set to that integer prior to generating the result.
-
-@item
-If @var{object} is a string, it is used as the prefix.
-
-@item
-If @var{object} is a symbol, its name is used as the prefix.
-@end itemize
-
-@example
-@group
-(generate-uninterned-symbol)
- @result{} #[uninterned-symbol 31 G0]
-(generate-uninterned-symbol)
- @result{} #[uninterned-symbol 32 G1]
-(generate-uninterned-symbol 'this)
- @result{} #[uninterned-symbol 33 this2]
-(generate-uninterned-symbol)
- @result{} #[uninterned-symbol 34 G3]
-(generate-uninterned-symbol 100)
- @result{} #[uninterned-symbol 35 G100]
-(generate-uninterned-symbol)
- @result{} #[uninterned-symbol 36 G101]
-@end group
-@end example
-@end deffn
-
-@deffn procedure symbol-append symbol @dots{}
-@cindex appending, of symbols
-@cindex pasting, of symbols
-Returns the interned symbol whose name is formed by concatenating the
-names of the given symbols. This procedure preserves the case of the
-names of its arguments, so if one or more of the arguments' names has
-non-standard case, the result will also have non-standard case.
-
-@example
-@group
-(symbol-append 'foo- 'bar) @result{} foo-bar
-@r{;; the arguments may be uninterned:}
-(symbol-append 'foo- (string->uninterned-symbol "baz"))
- @result{} foo-baz
-@r{;; the result has the same case as the arguments:}
-(symbol-append 'foo- (string->symbol "BAZ")) @result{} foo-BAZ
-@end group
-@end example
-@end deffn
-
-@deffn procedure symbol-hash symbol
-@cindex hashing, of symbol
-@findex string-hash
-Returns a hash number for @var{symbol}, which is computed by calling
-@code{string-hash} on @var{symbol}'s name. The hash number is an exact
-non-negative integer.
-@end deffn
-
-@deffn procedure symbol-hash-mod symbol modulus
-@var{Modulus} must be an exact positive integer. Equivalent to
-
-@example
-@group
-(modulo (symbol-hash @var{symbol}) @var{modulus})
-@end group
-@end example
-
-This procedure is provided for convenience in constructing hash tables.
-However, it is normally preferable to use @code{make-eq-hash-table} to
-build hash tables keyed by symbols, because @code{eq?} hash tables are
-much faster.
-@end deffn
-
-@deffn procedure symbol<? symbol1 symbol2
-This procedure computes a total order on symbols. It is equivalent to
-
-@example
-@group
-(string<? (symbol->string @var{symbol1})
- (symbol->string @var{symbol2}))
-@end group
-@end example
-@end deffn
-
-@node Cells, Records, Symbols, Miscellaneous Datatypes
-@section Cells
-
-@cindex cell (defn)
-@dfn{Cells} are data structures similar to pairs except that they have
-only one element. They are useful for managing state.
-
-@deffn procedure cell? object
-@cindex type predicate, for cell
-Returns @code{#t} if @var{object} is a cell; otherwise returns
-@code{#f}.
-@end deffn
-
-@deffn procedure make-cell object
-@cindex construction, of cell
-Returns a newly allocated cell whose contents is @var{object}.
-@end deffn
-
-@deffn procedure cell-contents cell
-@cindex selection, of cell component
-@cindex component selection, of cell
-Returns the current contents of @var{cell}.
-@end deffn
-
-@deffn procedure set-cell-contents! cell object
-Alters the contents of @var{cell} to be @var{object}. Returns an
-unspecified value.
-@end deffn
-
-@deffn procedure bind-cell-contents! cell object thunk
-Alters the contents of @var{cell} to be @var{object}, calls @var{thunk}
-with no arguments, then restores the original contents of @var{cell} and
-returns the value returned by @var{thunk}. This is completely
-equivalent to dynamic binding of a variable, including the behavior when
-continuations are used (@pxref{Dynamic Binding}).
-@end deffn
-
-@node Records, Promises, Cells, Miscellaneous Datatypes
-@section Records
-
-MIT/GNU Scheme provides a @dfn{record} abstraction, which is a simple and
-flexible mechanism for building structures with named components.
-Records can be defined and accessed using the procedures defined in this
-section. A less flexible but more concise way to manipulate records is
-to use the @code{define-structure} special form (@pxref{Structure
-Definitions}).
-@findex define-structure
-
-@deffn procedure make-record-type type-name field-names
-@cindex record-type descriptor (defn)
-Returns a @dfn{record-type descriptor}, a value representing a new data
-type, disjoint from all others. The @var{type-name} 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}
-argument is a list of symbols naming the @dfn{fields} 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.
-@end deffn
-
-@deffn procedure record-constructor record-type [field-names]
-Returns a procedure for constructing new members of the type represented
-by @var{record-type}. The returned procedure accepts exactly as many
-arguments as there are symbols in the given list, @var{field-names};
-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 the list of @var{field-names} are unspecified.
-The @var{field-names} argument defaults to the list of field-names in
-the call to @code{make-record-type} that created the type represented by
-@var{record-type}; if the @var{field-names} argument is provided, it is
-an error if it contains any duplicates or any symbols not in the default
-list.
-@end deffn
-
-@deffn procedure record-predicate record-type
-Returns a procedure for testing membership in the type represented by
-@var{record-type}. The returned procedure accepts exactly one argument
-and returns @code{#t} if the argument is a member of the indicated
-record type; it returns @code{#f} otherwise.
-@end deffn
-
-@deffn procedure record-accessor record-type field-name
-Returns a procedure for reading the value of a particular field of a
-member of the type represented by @var{record-type}. 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} in that record. The symbol @var{field-name}
-must be a member of the list of field names in the call to
-@code{make-record-type} that created the type represented by
-@var{record-type}.
-@end deffn
-
-@deffn procedure record-modifier record-type field-name
-Returns a procedure for writing the value of a particular field of a
-member of the type represented by @var{record-type}. 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} in that record to contain the
-given value. The returned value of the modifier procedure is
-unspecified. The symbol @var{field-name} must be a member of the list
-of field names in the call to @code{make-record-type} that created the
-type represented by @var{record-type}.
-@end deffn
-
-@deffn procedure record? object
-@cindex type predicate, for record
-Returns @code{#t} if @var{object} is a record of any type and @code{#f}
-otherwise. Note that @code{record?} may be true of any Scheme value; of
-course, if it returns @code{#t} for some particular value, then
-@code{record-type-descriptor} is applicable to that value and returns an
-appropriate descriptor.
-@end deffn
-
-@deffn procedure record-type-descriptor record
-Returns the record-type descriptor representing the type of
-@var{record}. That is, for example, if the returned descriptor were
-passed to @code{record-predicate}, the resulting predicate would return
-@code{#t} when passed @var{record}. Note that it is not necessarily the
-case that the returned descriptor is the one that was passed to
-@code{record-constructor} in the call that created the constructor
-procedure that created @var{record}.
-@end deffn
-
-@deffn procedure record-type? object
-@cindex type predicate, for record type
-Returns @code{#t} if @var{object} is a record-type descriptor; otherwise
-returns @code{#f}.
-@end deffn
-
-@deffn procedure record-type-name record-type
-Returns the type name associated with the type represented by
-@var{record-type}. The returned value is @code{eqv?} to the
-@var{type-name} argument given in the call to @code{make-record-type}
-that created the type represented by @var{record-type}.
-@end deffn
-
-@deffn procedure record-type-field-names record-type
-Returns a list of the symbols naming the fields in members of the type
-represented by @var{record-type}. The returned value is @code{equal?}
-to the @var{field-names} argument given in the call to
-@code{make-record-type} that created the type represented by
-@var{record-type}.@footnote{In MIT/GNU Scheme, the returned list is always
-newly allocated.}
-@end deffn
-
-@node Promises, Streams, Records, Miscellaneous Datatypes
-@section Promises
-
-@deffn {special form} delay expression
-@cindex promise (defn)
-@cindex promise, construction
-@cindex construction, of promise
-@cindex lazy evaluation (defn)
-@cindex call by need evaluation (defn)
-@cindex evaluation, lazy (defn)
-@cindex evaluation, call by need (defn)
-The @code{delay} construct is used together with the procedure
-@code{force} to implement @dfn{lazy evaluation} or @dfn{call by need}.
-@code{(delay @var{expression})} returns an object called a @dfn{promise}
-which at some point in the future may be asked (by the @code{force}
-procedure) to evaluate @var{expression} and deliver the resulting value.
-@end deffn
-
-@deffn procedure force promise
-@cindex promise, forcing
-@cindex forcing, of promise
-@cindex memoization, of promise
-Forces the value of @emph{promise}. If no value has been computed for
-the promise, then a value is computed and returned. The value of the
-promise is cached (or ``memoized'') so that if it is forced a second
-time, the previously computed value is returned without any
-recomputation.
-
-@example
-@group
-(force (delay (+ 1 2))) @result{} 3
-
-(let ((p (delay (+ 1 2))))
- (list (force p) (force p))) @result{} (3 3)
-@end group
-
-@group
-(define head car)
-
-(define tail
- (lambda (stream)
- (force (cdr stream))))
-@end group
-
-@group
-(define a-stream
- (letrec ((next
- (lambda (n)
- (cons n (delay (next (+ n 1)))))))
- (next 0)))
-
-(head (tail (tail a-stream))) @result{} 2
-@end group
-@end example
-@end deffn
-
-@deffn procedure promise? object
-@cindex type predicate, for promise
-Returns @code{#t} if @var{object} is a promise; otherwise returns
-@code{#f}.
-@end deffn
-
-@deffn procedure promise-forced? promise
-Returns @code{#t} if @var{promise} has been forced and its value cached;
-otherwise returns @code{#f}.
-@end deffn
-
-@deffn procedure promise-value promise
-If @var{promise} has been forced and its value cached, this procedure
-returns the cached value. Otherwise, an error is signalled.
-@end deffn
-
-@code{force} and @code{delay} are mainly intended for programs written
-in functional style. The following examples should not be considered to
-illustrate good programming style, but they illustrate the property that
-the value of a promise is computed at most once.
-
-@example
-@group
-(define count 0)
-
-(define p
- (delay
- (begin
- (set! count (+ count 1))
- (* x 3))))
-
-(define x 5)
-@end group
-
-@group
-count @result{} 0
-p @result{} #[promise 54]
-(force p) @result{} 15
-p @result{} #[promise 54]
-count @result{} 1
-(force p) @result{} 15
-count @result{} 1
-@end group
-@end example
-
-Here is a possible implementation of @code{delay} and @code{force}. We
-define the expression
-
-@example
-(delay @var{expression})
-@end example
-
-@noindent
-to have the same meaning as the procedure call
-
-@example
-(make-promise (lambda () @var{expression}))
-@end example
-
-@noindent
-where @code{make-promise} is defined as follows:
-
-@example
-@group
-(define make-promise
- (lambda (proc)
- (let ((already-run? #f)
- (result #f))
- (lambda ()
- (cond ((not already-run?)
- (set! result (proc))
- (set! already-run? #t)))
- result))))
-@end group
-@end example
-
-Promises are implemented here as procedures of no arguments, and
-@code{force} simply calls its argument.
-
-@example
-@group
-(define force
- (lambda (promise)
- (promise)))
-@end group
-@end example
-
-Various extensions to this semantics of @code{delay} and @code{force}
-are supported in some implementations (none of these are currently
-supported in MIT/GNU Scheme):
-
-@itemize @bullet
-@item
-Calling @code{force} on an object that is not a promise may simply
-return the object.
-
-@item
-It may be the case that there is no means by which a promise can be
-operationally distinguished from its forced value. That is, expressions
-like the following may evaluate to either @code{#t} or @code{#f},
-depending on the implementation:
-
-@example
-@group
-(eqv? (delay 1) 1) @result{} @r{unspecified}
-(pair? (delay (cons 1 2))) @result{} @r{unspecified}
-@end group
-@end example
-
-@item
-Some implementations will implement ``implicit forcing'', where the
-value of a promise is forced by primitive procedures like @code{car} and
-@code{+}:
-
-@example
-(+ (delay (* 3 7)) 13) @result{} 34
-@end example
-@end itemize
-
-@node Streams, Weak Pairs, Promises, Miscellaneous Datatypes
-@section Streams
-
-@cindex stream (defn)
-In addition to promises, MIT/GNU Scheme supports a higher-level abstraction
-called @dfn{streams}. Streams are similar to lists, except that the
-tail of a stream is not computed until it is referred to.
-This allows streams to be used to represent infinitely long lists.
-
-@deffn procedure stream object @dots{}
-@cindex construction, of stream
-Returns a newly allocated stream whose elements are the arguments. Note
-that the expression @code{(stream)} returns the empty stream, or
-end-of-stream marker.
-@end deffn
-
-@deffn procedure list->stream list
-@cindex list, converting to stream
-Returns a newly allocated stream whose elements are the elements of
-@var{list}. Equivalent to @code{(apply stream @var{list})}.
-@end deffn
-
-@deffn procedure stream->list stream
-@cindex stream, converting to list
-Returns a newly allocated list whose elements are the elements of
-@var{stream}. If @var{stream} has infinite length this procedure will
-not terminate. This could have been defined by
-
-@example
-@group
-(define (stream->list stream)
- (if (stream-null? stream)
- '()
- (cons (stream-car stream)
- (stream->list (stream-cdr stream)))))
-@end group
-@end example
-@end deffn
-
-@deffn {special form} cons-stream object expression
-Returns a newly allocated stream pair. Equivalent to @code{(cons
-@var{object} (delay @var{expression}))}.
-@end deffn
-
-@deffn procedure stream-pair? object
-@cindex type predicate, for stream pair
-Returns @code{#t} if @var{object} is a pair whose cdr contains a
-promise. Otherwise returns @code{#f}. This could have been defined by
-
-@example
-@group
-(define (stream-pair? object)
- (and (pair? object)
- (promise? (cdr object))))
-@end group
-@end example
-@end deffn
-
-@deffn procedure stream-car stream
-@deffnx procedure stream-first stream
-@findex car
-Returns the first element in @var{stream}. @code{stream-car} is
-equivalent to @code{car}. @code{stream-first} is a synonym for
-@code{stream-car}.
-@end deffn
-
-@deffn procedure stream-cdr stream
-@deffnx procedure stream-rest stream
-@findex force
-@findex cdr
-Returns the first tail of @var{stream}. Equivalent to @code{(force (cdr
-@var{stream}))}. @code{stream-rest} is a synonym for @code{stream-cdr}.
-@end deffn
-
-@deffn procedure stream-null? stream
-@cindex empty stream, predicate for
-@findex null?
-Returns @code{#t} if @var{stream} is the end-of-stream marker; otherwise
-returns @code{#f}. This is equivalent to @code{null?}, but should be
-used whenever testing for the end of a stream.
-@end deffn
-
-@deffn procedure stream-length stream
-@cindex length, of stream
-Returns the number of elements in @var{stream}. If @var{stream} has an
-infinite number of elements this procedure will not terminate. Note
-that this procedure forces all of the promises that comprise
-@var{stream}.
-@end deffn
-
-@deffn procedure stream-ref stream k
-@cindex selecting, of stream component
-@cindex component selection, of stream
-Returns the element of @var{stream} that is indexed by @var{k}; that is,
-the @var{k}th element. @var{K} must be an exact non-negative integer
-strictly less than the length of @var{stream}.
-@end deffn
-
-@deffn procedure stream-head stream k
-Returns the first @var{k} elements of @var{stream} as a list. @var{K}
-must be an exact non-negative integer strictly less than the length of
-@var{stream}.
-@end deffn
-
-@deffn procedure stream-tail stream k
-Returns the tail of @var{stream} that is indexed by @var{k}; that is,
-the @var{k}th tail. This is equivalent to performing @code{stream-cdr}
-@var{k} times. @var{K} must be an exact non-negative integer strictly
-less than the length of @var{stream}.
-@end deffn
-
-@deffn procedure stream-map procedure stream stream @dots{}
-@cindex mapping, of stream
-Returns a newly allocated stream, each element being the result of
-invoking @var{procedure} with the corresponding elements of the
-@var{stream}s as its arguments.
-@end deffn
-
-@node Weak Pairs, , Streams, Miscellaneous Datatypes
-@section Weak Pairs
-
-@cindex weak pair (defn)
-@cindex pair, weak (defn)
-@dfn{Weak pairs} are a mechanism for building data structures that point
-at objects without protecting them from garbage collection. The car of
-a weak pair holds its pointer weakly, while the cdr holds its pointer in
-the normal way. If the object in the car of a weak pair is not held
-normally by any other data structure, it will be garbage-collected.
-
-@findex pair?
-Note: weak pairs are @emph{not} pairs; that is, they do not satisfy the
-predicate @code{pair?}.
-
-@deffn procedure weak-pair? object
-@cindex type predicate, for weak pair
-Returns @code{#t} if @var{object} is a weak pair; otherwise returns
-@code{#f}.
-@end deffn
-
-@deffn procedure weak-cons car cdr
-@cindex construction, of weak pair
-Allocates and returns a new weak pair, with components @var{car} and
-@var{cdr}. The @var{car} component is held weakly.
-@end deffn
-
-@deffn procedure weak-pair/car? weak-pair
-This predicate returns @code{#f} if the car of @var{weak-pair} has been
-garbage-collected; otherwise returns @code{#t}. In other words, it is
-true if @var{weak-pair} has a valid car component.
-@end deffn
-
-@deffn procedure weak-car weak-pair
-@cindex selection, of weak pair component
-@cindex component selection, of weak pair
-Returns the car component of @var{weak-pair}. If the car component has
-been garbage-collected, this operation returns @code{#f}, but it can
-also return @code{#f} if that is the value that was stored in the car.
-@end deffn
-
-Normally, @code{weak-pair/car?} is used to determine if @code{weak-car}
-would return a valid value. An obvious way of doing this would be:
-
-@example
-@group
-(if (weak-pair/car? x)
- (weak-car x)
- @dots{})
-@end group
-@end example
-
-@noindent
-However, since a garbage collection could occur between the call to
-@code{weak-pair/car?} and @code{weak-car}, this would not always work
-correctly. Instead, the following should be used, which always works:
-
-@example
-@group
-(or (weak-car x)
- (and (not (weak-pair/car? x))
- @dots{}))
-@end group
-@end example
-
-The reason that the latter expression works is that @code{weak-car}
-returns @code{#f} in just two instances: when the car component is
-@code{#f}, and when the car component has been garbage-collected. In
-the former case, if a garbage collection happens between the two calls,
-it won't matter, because @code{#f} will never be garbage-collected. And
-in the latter case, it also won't matter, because the car component no
-longer exists and cannot be affected by the garbage collector.
-
-@deffn procedure weak-set-car! weak-pair object
-Sets the car component of @var{weak-pair} to @var{object} and returns an
-unspecified result.
-@end deffn
-
-@deffn procedure weak-cdr weak-pair
-Returns the cdr component of @var{weak-cdr}.
-@end deffn
-
-@deffn procedure weak-set-cdr! weak-pair object
-Sets the cdr component of @var{weak-pair} to @var{object} and returns an
-unspecified result.
-@end deffn
-
-@node Associations, Procedures, Miscellaneous Datatypes, Top
-@chapter Associations
-
-MIT/GNU Scheme provides several mechanisms for associating objects with
-one another. Each of these mechanisms creates a link between one or
-more objects, called @dfn{keys}, and some other object, called a
-@dfn{datum}. Beyond this common idea, however, each of the mechanisms
-has various different properties that make it appropriate in different
-situations:
-
-@itemize @bullet
-@item
-@dfn{Association lists} are one of Lisp's oldest association mechanisms.
-Because they are made from ordinary pairs, they are easy to build and
-manipulate, and very flexible in use. However, the average lookup time
-for an association list is linear in the number of associations.
-
-@item
-@dfn{1D tables} have a very simple interface, making them easy to use,
-and offer the feature that they do not prevent their keys from being
-reclaimed by the garbage collector. Like association lists, their
-average lookup time is linear in the number of associations; but 1D
-tables aren't as flexible.
-
-@item
-@cindex property list
-@dfn{The association table} is MIT/GNU Scheme's equivalent to the
-@dfn{property lists} of Lisp. It has the advantages that the keys may
-be any type of object and that it does not prevent the keys from being
-reclaimed by the garbage collector. However, two linear-time lookups
-must be performed, one for each key, whereas for traditional property
-lists only one lookup is required for both keys.
-
-@item
-@dfn{Hash tables} are a powerful mechanism with constant-time access to
-large amounts of data. Hash tables are not as flexible as association
-lists, but because their access times are independent of the number of
-associations in the table, for most applications they are the mechanism
-of choice.
-
-@item
-@dfn{Balanced binary trees} are another association mechanism that is
-useful for applications in which the keys are ordered. Binary trees
-have access times that are proportional to the logarithm of the number
-of associations in the tree. While they aren't as fast as hash tables,
-they offer the advantage that the contents of the tree can be converted
-to a sorted alist in linear time. Additionally, two trees can be
-compared for equality in worst-case linear time.
-
-@item
-@dfn{Red-Black trees} are a kind of balanced binary tree. The
-implementation supports destructive insertion and deletion operations
-with a good constant factor.
-
-@item
-@dfn{Weight-Balanced trees} are a kind of balanced binary tree. The
-implementation provides non-destructive operations. There is a
-comprehensive set of operations, including: a constant-time size
-operation; many high-level operations such as the set operations union,
-intersection and difference; and indexing of elements by position.
-
-@end itemize
-
-@menu
-* Association Lists::
-* 1D Tables::
-* The Association Table::
-* Hash Tables::
-* Object Hashing::
-* Red-Black Trees::
-* Weight-Balanced Trees::
-@end menu
-
-@node Association Lists, 1D Tables, Associations, Associations
-@section Association Lists
-
-@comment **** begin CLTL ****
-@cindex association list (defn)
-@cindex list, association (defn)
-@cindex alist (defn)
-@cindex key, of association list element (defn)
-An @dfn{association list}, or @dfn{alist}, is a data structure used very
-frequently in Scheme. An alist is a list of pairs, each of which is
-called an @dfn{association}. The car of an association is called the
-@dfn{key}.
-
-An advantage of the alist representation is that an alist can be
-incrementally augmented simply by adding new entries to the front.
-Moreover, because the searching procedures @code{assv} et al.@: search the
-alist in order, new entries can ``shadow'' old entries. If an alist is
-viewed as a mapping from keys to data, then the mapping can be not only
-augmented but also altered in a non-destructive manner by adding new
-entries to the front of the alist.@footnote{This introduction is taken
-from @cite{Common Lisp, The Language}, second edition, p.@: 431.}
-@comment **** end CLTL ****
-
-@deffn procedure alist? object
-@cindex type predicate, for alist
-@findex list?
-Returns @code{#t} if @var{object} is an association list (including the
-empty list); otherwise returns @code{#f}. Any @var{object} satisfying this
-predicate also satisfies @code{list?}.
-@end deffn
-
-@deffn procedure assq object alist
-@deffnx procedure assv object alist
-@deffnx procedure assoc object alist
-@cindex searching, of alist
-@findex eq?
-@findex eqv?
-@findex equal?
-These procedures find the first pair in @var{alist} whose car field is
-@var{object}, and return that pair; the returned pair is always an
-@emph{element} of @var{alist}, @emph{not} one of the pairs from which
-@var{alist} is composed. If no pair in @var{alist} has @var{object} as
-its car, @code{#f} (n.b.: not the empty list) is returned. @code{assq}
-uses @code{eq?} to compare @var{object} with the car fields of the pairs
-in @var{alist}, while @code{assv} uses @code{eqv?} and @code{assoc} uses
-@code{equal?}.@footnote{Although they are often used as predicates,
-@code{assq}, @code{assv}, and @code{assoc} do not have question marks in
-their names because they return useful values rather than just @code{#t}
-or @code{#f}.}
-
-@example
-@group
-(define e '((a 1) (b 2) (c 3)))
-(assq 'a e) @result{} (a 1)
-(assq 'b e) @result{} (b 2)
-(assq 'd e) @result{} #f
-(assq (list 'a) '(((a)) ((b)) ((c)))) @result{} #f
-(assoc (list 'a) '(((a)) ((b)) ((c)))) @result{} ((a))
-(assq 5 '((2 3) (5 7) (11 13))) @result{} @r{unspecified}
-(assv 5 '((2 3) (5 7) (11 13))) @result{} (5 7)
-@end group
-@end example
-@end deffn
-
-@deffn procedure association-procedure predicate selector
-Returns an association procedure that is similar to @code{assv}, except
-that @var{selector} (a procedure of one argument) is used to select the
-key from the association, and @var{predicate} (an equivalence predicate)
-is used to compare the key to the given item. This can be used to make
-association lists whose elements are, say, vectors instead of pairs
-(also @pxref{Searching Lists}).
-
-For example, here is how @code{assv} could be implemented:
-
-@example
-(define assv (association-procedure eqv? car))
-@end example
-
-Another example is a ``reverse association'' procedure:
-
-@example
-(define rassv (association-procedure eqv? cdr))
-@end example
-@end deffn
-
-@deffn procedure del-assq object alist
-@deffnx procedure del-assv object alist
-@deffnx procedure del-assoc object alist
-@cindex deletion, of alist element
-@findex eq?
-@findex eqv?
-@findex equal?
-These procedures return a newly allocated copy of @var{alist} in which
-all associations with keys equal to @var{object} have been removed.
-Note that while the returned copy is a newly allocated list, the
-association pairs that are the elements of the list are shared with
-@var{alist}, not copied. @code{del-assq} uses @code{eq?} to compare
-@var{object} with the keys, while @code{del-assv} uses @code{eqv?} and
-@code{del-assoc} uses @code{equal?}.
-
-@example
-@group
-(define a
- '((butcher . "231 e22nd St.")
- (baker . "515 w23rd St.")
- (hardware . "988 Lexington Ave.")))
-
-(del-assq 'baker a)
- @result{}
- ((butcher . "231 e22nd St.")
- (hardware . "988 Lexington Ave."))
-@end group
-@end example
-@end deffn
-
-@deffn procedure del-assq! object alist
-@deffnx procedure del-assv! object alist
-@deffnx procedure del-assoc! object alist
-@findex eq?
-@findex eqv?
-@findex equal?
-These procedures remove from @var{alist} all associations with keys
-equal to @var{object}. They return the resulting list.
-@code{del-assq!} uses @code{eq?} to compare @var{object} with the keys,
-while @code{del-assv!} uses @code{eqv?} and @code{del-assoc!} uses
-@code{equal?}. These procedures are like @code{del-assq},
-@code{del-assv}, and @code{del-assoc}, respectively, except that they
-destructively modify @var{alist}.
-@end deffn
-
-@deffn procedure delete-association-procedure deletor predicate selector
-@findex list-deletor
-@findex list-deletor!
-This returns a deletion procedure similar to @code{del-assv} or
-@code{del-assq!}. The @var{predicate} and @var{selector} arguments are
-the same as those for @code{association-procedure}, while the
-@var{deletor} argument should be either the procedure
-@code{list-deletor} (for non-destructive deletions), or the procedure
-@code{list-deletor!} (for destructive deletions).
-
-For example, here is a possible implementation of @code{del-assv}:
-
-@example
-@group
-(define del-assv
- (delete-association-procedure list-deletor eqv? car))
-@end group
-@end example
-@end deffn
-
-@deffn procedure alist-copy alist
-@cindex copying, of alist
-@findex list-copy
-Returns a newly allocated copy of @var{alist}. This is similar to
-@code{list-copy} except that the ``association'' pairs, i.e.@: the
-elements of the list @var{alist}, are also copied. @code{alist-copy}
-could have been implemented like this:
-
-@example
-@group
-(define (alist-copy alist)
- (if (null? alist)
- '()
- (cons (cons (car (car alist)) (cdr (car alist)))
- (alist-copy (cdr alist)))))
-@end group
-@end example
-@end deffn
-
-@node 1D Tables, The Association Table, Association Lists, Associations
-@section 1D Tables
-
-@cindex 1D table (defn)
-@cindex one-dimensional table (defn)
-@cindex table, one-dimensional (defn)
-@cindex weak pair, and 1D table
-@dfn{1D tables} (``one-dimensional'' tables) are similar to association
-lists. In a 1D table, unlike an association list, the keys of the table
-are held @dfn{weakly}: if a key is garbage-collected, its associated
-value in the table is removed. 1D tables compare their keys for
-equality using @code{eq?}.
-
-@cindex property list
-1D tables can often be used as a higher-performance alternative to the
-two-dimensional association table (@pxref{The Association Table}). If
-one of the keys being associated is a compound object such as a vector,
-a 1D table can be stored in one of the vector's slots. Under these
-circumstances, accessing items in a 1D table will be comparable in
-performance to using a property list in a conventional Lisp.
-
-@deffn procedure make-1d-table
-Returns a newly allocated empty 1D table.
-@end deffn
-
-@deffn procedure 1d-table? object
-@cindex type predicate, for 1D table
-@findex list?
-Returns @code{#t} if @var{object} is a 1D table, otherwise returns
-@code{#f}. Any object that satisfies this predicate also satisfies
-@code{list?}.
-@end deffn
-
-@deffn procedure 1d-table/put! 1d-table key datum
-Creates an association between @var{key} and @var{datum} in
-@var{1d-table}. Returns an unspecified value.
-@end deffn
-
-@deffn procedure 1d-table/remove! 1d-table key
-Removes any association for @var{key} in @var{1d-table} and returns an
-unspecified value.
-@end deffn
-
-@deffn procedure 1d-table/get 1d-table key default
-Returns the @var{datum} associated with @var{key} in @var{1d-table}. If
-there is no association for @var{key}, @var{default} is returned.
-@end deffn
-
-@deffn procedure 1d-table/lookup 1d-table key if-found if-not-found
-@var{If-found} must be a procedure of one argument, and
-@var{if-not-found} must be a procedure of no arguments. If
-@var{1d-table} contains an association for @var{key}, @var{if-found} is
-invoked on the @var{datum} of the association. Otherwise,
-@var{if-not-found} is invoked with no arguments. In either case, the
-result of the invoked procedure is returned as the result of
-@code{1d-table/lookup}.
-@end deffn
-
-@deffn procedure 1d-table/alist 1d-table
-Returns a newly allocated association list that contains the same
-information as @var{1d-table}.
-@end deffn
-
-@node The Association Table, Hash Tables, 1D Tables, Associations
-@section The Association Table
-
-@cindex association table (defn)
-@cindex table, association (defn)
-@cindex property list
-@findex eq?
-MIT/GNU Scheme provides a generalization of the property-list mechanism
-found in most other implementations of Lisp: a global two-dimensional
-@dfn{association table}. This table is indexed by two keys, called
-@var{x-key} and @var{y-key} in the following procedure descriptions.
-These keys and the datum associated with them can be arbitrary objects.
-@code{eq?} is used to discriminate keys.
-
-Think of the association table as a matrix: a single datum can be
-accessed using both keys, a column using @var{x-key} only, and a row
-using @var{y-key} only.
-
-@deffn procedure 2d-put! x-key y-key datum
-Makes an entry in the association table that associates @var{datum} with
-@var{x-key} and @var{y-key}. Returns an unspecified result.
-@end deffn
-
-@deffn procedure 2d-remove! x-key y-key
-If the association table has an entry for @var{x-key} and @var{y-key},
-it is removed. Returns an unspecified result.
-@end deffn
-
-@deffn procedure 2d-get x-key y-key
-Returns the @var{datum} associated with @var{x-key} and @var{y-key}.
-Returns @code{#f} if no such association exists.
-@end deffn
-
-@deffn procedure 2d-get-alist-x x-key
-Returns an association list of all entries in the association table that
-are associated with @var{x-key}. The result is a list of
-@code{(@var{y-key} . @var{datum})} pairs. Returns the empty list if no
-entries for @var{x-key} exist.
-
-@example
-@group
-(2d-put! 'foo 'bar 5)
-(2d-put! 'foo 'baz 6)
-(2d-get-alist-x 'foo) @result{} ((baz . 6) (bar . 5))
-@end group
-@end example
-@end deffn
-
-@deffn procedure 2d-get-alist-y y-key
-Returns an association list of all entries in the association table that
-are associated with @var{y-key}. The result is a list of
-@code{(@var{x-key} . @var{datum})} pairs. Returns the empty list if no
-entries for @var{y-key} exist.
-
-@example
-@group
-(2d-put! 'bar 'foo 5)
-(2d-put! 'baz 'foo 6)
-(2d-get-alist-y 'foo) @result{} ((baz . 6) (bar . 5))
-@end group
-@end example
-@end deffn
-
-@node Hash Tables, Object Hashing, The Association Table, Associations
-@section Hash Tables
-
-@cindex hash table
-Hash tables are a fast, powerful mechanism for storing large numbers of
-associations. MIT/GNU Scheme's hash tables feature automatic resizing,
-customizable growth parameters, and customizable hash procedures.
-
-The average times for the insertion, deletion, and lookup operations on
-a hash table are bounded by a constant. The space required by the table
-is proportional to the number of associations in the table; the
-constant of proportionality is described below (@pxref{Resizing of Hash
-Tables}).
-
-(Previously, the hash-table implementation was a run-time-loadable
-option, but as of release 7.7.0 it is loaded by default. It's no longer
-necessary to call @code{load-option} prior to using hash tables.)
-
-@menu
-* Construction of Hash Tables::
-* Basic Hash Table Operations::
-* Resizing of Hash Tables::
-* Address Hashing::
-* Low-Level Hash Table Operations::
-@end menu
-
-@node Construction of Hash Tables, Basic Hash Table Operations, Hash Tables, Hash Tables
-@subsection Construction of Hash Tables
-
-@cindex construction, of hash table
-The next few procedures are hash-table constructors. All hash table
-constructors are procedures that accept one optional argument,
-@var{initial-size}, and return a newly allocated hash table. If
-@var{initial-size} is given, it must be an exact non-negative integer or
-@code{#f}. The meaning of @var{initial-size} is discussed below
-(@pxref{Resizing of Hash Tables}).
-
-@cindex equivalence predicate, of hash table
-@cindex strongly held keys, of hash table
-@cindex weakly held keys, of hash table
-Hash tables are normally characterized by two things: the equivalence
-predicate that is used to compare keys, and whether or not the table
-allows its keys to be reclaimed by the garbage collector. If a table
-prevents its keys from being reclaimed by the garbage collector, it is
-said to hold its keys @dfn{strongly}; otherwise it holds its keys
-@dfn{weakly} (@pxref{Weak Pairs}).
-
-@deffn procedure make-eq-hash-table [initial-size]
-@findex eq?
-Returns a newly allocated hash table that accepts arbitrary objects as
-keys, and compares those keys with @code{eq?}. The keys are held
-weakly. These are the fastest of the standard hash tables.
-@end deffn
-
-@deffn procedure make-eqv-hash-table [initial-size]
-@findex eqv?
-Returns a newly allocated hash table that accepts arbitrary objects as
-keys, and compares those keys with @code{eqv?}. The keys are held
-weakly, except that booleans, characters, and numbers are held strongly.
-These hash tables are a little slower than those made by
-@code{make-eq-hash-table}.
-@end deffn
-
-@deffn procedure make-equal-hash-table [initial-size]
-@findex equal?
-Returns a newly allocated hash table that accepts arbitrary objects as
-keys, and compares those keys with @code{equal?}. The keys are held
-strongly. These hash tables are quite a bit slower than those made by
-@code{make-eq-hash-table}.
-@end deffn
-
-@deffn procedure make-string-hash-table [initial-size]
-@findex string=?
-Returns a newly allocated hash table that accepts character strings as
-keys, and compares them with @code{string=?}. The keys are held
-strongly.
-@end deffn
-
-The next two procedures are used to create new hash-table constructors.
-All of the above hash table constructors, with the exception of
-@code{make-eqv-hash-table}, could have been created by calls to these
-``constructor-constructors''; see the examples below.
-
-@deffn procedure strong-hash-table/constructor key-hash key=? [rehash-after-gc?]
-@deffnx procedure weak-hash-table/constructor key-hash key=? [rehash-after-gc?]
-@cindex hashing, of key in hash table
-@cindex modulus, of hashing procedure
-Each of these procedures accepts two arguments and returns a hash-table
-constructor. The @var{key=?} argument is an equivalence predicate for
-the keys of the hash table. The @var{key-hash} argument is a procedure
-that computes a hash number. Specifically, @var{key-hash} accepts two
-arguments, a key and an exact positive integer (the @dfn{modulus}), and
-returns an exact non-negative integer that is less than the modulus.
-
-The optional argument @var{rehash-after-gc?}, if true, says that the
-values returned by @var{key-hash} might change after a garbage
-collection. If so, the hash-table implementation arranges for the table
-to be rehashed when necessary. (@xref{Address Hashing}, for
-information about hash procedures that have this property.) Otherwise,
-it is assumed that @var{key-hash} always returns the same value for the
-same arguments. The default value of this argument is @code{#f}.
-
-The constructors returned by @code{strong-hash-table/constructor} make
-hash tables that hold their keys strongly. The constructors returned by
-@code{weak-hash-table/constructor} make hash tables that hold their keys
-weakly.
-@end deffn
-
-Some examples showing how some standard hash-table constructors could have
-been defined:
-
-@findex eq-hash-mod
-@findex eq?
-@findex equal-hash-mod
-@findex equal?
-@findex string-hash-mod
-@findex string=?
-@example
-@group
-(define make-eq-hash-table
- (weak-hash-table/constructor eq-hash-mod eq? #t))
-
-(define make-equal-hash-table
- (strong-hash-table/constructor equal-hash-mod equal? #t))
-
-(define make-string-hash-table
- (strong-hash-table/constructor string-hash-mod string=? #f))
-@end group
-@end example
-
-The following procedure is sometimes useful in conjunction with weak
-hash tables. Normally it is not needed, because such hash tables clean
-themselves automatically as they are used.
-
-@deffn procedure hash-table/clean! hash-table
-If @var{hash-table} is a type of hash table that holds its @var{key}s
-weakly, this procedure recovers any space that was being used to record
-associations for objects that have been reclaimed by the garbage
-collector. Otherwise, this procedure does nothing. In either case, it
-returns an unspecified result.
-@end deffn
-
-@node Basic Hash Table Operations, Resizing of Hash Tables, Construction of Hash Tables, Hash Tables
-@subsection Basic Hash Table Operations
-
-The procedures described in this section are the basic operations on
-hash tables. They provide the functionality most often needed by
-programmers. Subsequent sections describe other operations that provide
-additional functionality needed by some applications.
-
-@deffn procedure hash-table? object
-@cindex type predicate, for hash table
-Returns @code{#t} if @var{object} is a hash table, otherwise returns
-@code{#f}.
-@end deffn
-
-@deffn procedure hash-table/put! hash-table key datum
-Associates @var{datum} with @var{key} in @var{hash-table} and returns an
-unspecified result. The average time required by this operation is
-bounded by a constant.
-@end deffn
-
-@deffn procedure hash-table/get hash-table key default
-Returns the datum associated with @var{key} in @var{hash-table}. If
-there is no association for @var{key}, @var{default} is returned. The
-average time required by this operation is bounded by a constant.
-@end deffn
-
-@deffn procedure hash-table/remove! hash-table key
-If @var{hash-table} has an association for @var{key}, removes it.
-Returns an unspecified result. The average time required by this
-operation is bounded by a constant.
-@end deffn
-
-@deffn procedure hash-table/clear! hash-table
-Removes all associations in @var{hash-table} and returns an unspecified
-result. The average and worst-case times required by this operation are
-bounded by a constant.
-@end deffn
-
-@deffn procedure hash-table/count hash-table
-Returns the number of associations in @var{hash-table} as an exact
-non-negative integer. If @var{hash-table} holds its keys weakly, this
-is a conservative upper bound that may count some associations whose
-keys have recently been reclaimed by the garbage collector. The average
-and worst-case times required by this operation are bounded by a
-constant.
-@end deffn
-
-@deffn procedure hash-table->alist hash-table
-Returns the contents of @var{hash-table} as a newly allocated alist.
-Each element of the alist is a pair @code{(@var{key} . @var{datum})}
-where @var{key} is one of the keys of @var{hash-table}, and @var{datum}
-is its associated datum. The average and worst-case times required by
-this operation are linear in the number of associations
-in the table.
-@end deffn
-
-@deffn procedure hash-table/key-list hash-table
-Returns a newly allocated list of the keys in @var{hash-table}. The
-average and worst-case times required by this operation are linear in
-the number of associations in the table.
-@end deffn
-
-@deffn procedure hash-table/datum-list hash-table
-Returns a newly allocated list of the datums in @var{hash-table}. Each
-element of the list corresponds to one of the associations in
-@var{hash-table}; if the table contains multiple associations with the
-same datum, so will this list. The average and worst-case times
-required by this operation are linear in the number of associations in
-the table.
-@end deffn
-
-@deffn procedure hash-table/for-each hash-table procedure
-@var{Procedure} must be a procedure of two arguments. Invokes
-@var{procedure} once for each association in @var{hash-table}, passing
-the association's @var{key} and @var{datum} as arguments, in that order.
-Returns an unspecified result. @var{Procedure} must not modify
-@var{hash-table}, with one exception: it is permitted to call
-@code{hash-table/remove!} to remove the association being processed.
-@end deffn
-
-The following procedure is an alternate form of @code{hash-table/get}
-that is useful in some situations. Usually, @code{hash-table/get} is
-preferable because it is faster.
-
-@deffn procedure hash-table/lookup hash-table key if-found if-not-found
-@var{If-found} must be a procedure of one argument, and
-@var{if-not-found} must be a procedure of no arguments. If
-@var{hash-table} contains an association for @var{key}, @var{if-found}
-is invoked on the datum of the association. Otherwise,
-@var{if-not-found} is invoked with no arguments. In either case, the
-result yielded by the invoked procedure is returned as the result of
-@code{hash-table/lookup} (@code{hash-table/lookup} @emph{reduces} into
-the invoked procedure, i.e.@: calls it tail-recursively). The average
-time required by this operation is bounded by a constant.
-@end deffn
-
-@node Resizing of Hash Tables, Address Hashing, Basic Hash Table Operations, Hash Tables
-@subsection Resizing of Hash Tables
-
-@cindex resizing, of hash table
-@cindex size, of hash table (defn)
-Normally, hash tables automatically resize themselves according to need.
-Because of this, the programmer need not be concerned with management of
-the table's size. However, some limited control over the table's size
-is provided, which will be discussed below. This discussion involves
-two concepts, @dfn{usable size} and @dfn{physical size}, which we will
-now define.
-
-@cindex usable size, of hash table (defn)
-The @dfn{usable size} of a hash table is the number of associations that
-the table can hold at a given time. If the number of associations in
-the table exceeds the usable size, the table will automatically grow,
-increasing the usable size to a new value that is sufficient to hold the
-associations.
-
-@cindex physical size, of hash table (defn)
-The @dfn{physical size} is an abstract measure of a hash table that
-specifies how much space is allocated to hold the associations of the
-table. The physical size is always greater than or equal to the usable
-size. The physical size is not interesting in itself; it is interesting
-only for its effect on the performance of the hash table. While the
-average performance of a hash-table lookup is bounded by a constant, the
-worst-case performance is not. For a table containing a given number of
-associations, increasing the physical size of the table decreases the
-probability that worse-than-average performance will occur.
-
-The physical size of a hash table is statistically related to the number
-of associations. However, it is possible to place bounds on the
-physical size, and from this to estimate the amount of space used by the
-table:
-
-@example
-@group
-(define (hash-table-space-bounds count rehash-size rehash-threshold)
- (let ((tf (/ 1 rehash-threshold)))
- (values (if (exact-integer? rehash-size)
- (- (* count (+ 4 tf))
- (* tf (+ rehash-size rehash-size)))
- (* count (+ 4 (/ tf (* rehash-size rehash-size)))))
- (* count (+ 4 tf)))))
-@end group
-@end example
-
-@noindent
-What this formula shows is that, for a ``normal'' rehash size (that is,
-not an exact integer), the amount of space used by the hash table is
-proportional to the number of associations in the table. The constant
-of proportionality varies statistically, with the low bound being
-
-@example
-(+ 4 (/ (/ 1 rehash-threshold) (* rehash-size rehash-size)))
-@end example
-
-@noindent
-and the high bound being
-
-@example
-(+ 4 (/ 1 rehash-threshold))
-@end example
-
-@noindent
-which, for the default values of these parameters, are @code{4.25} and
-@code{5}, respectively. Reducing the rehash size will tighten these
-bounds, but increases the amount of time spent resizing, so you can see
-that the rehash size gives some control over the time-space tradeoff of
-the table.
-
-The programmer can control the size of a hash table by means of three
-parameters:
-
-@itemize @bullet
-@item
-Each table's @var{initial-size} may be specified when the table is
-created.
-
-@item
-Each table has a @dfn{rehash size} that specifies how the size of the
-table is changed when it is necessary to grow or shrink the table.
-
-@item
-Each table has a @dfn{rehash threshold} that specifies the relationship
-of the table's physical size to its usable size.
-@end itemize
-
-@cindex initial size, of hash table
-If the programmer knows that the table will initially contain a specific
-number of items, @var{initial-size} can be given when the table is
-created. If @var{initial-size} is an exact non-negative integer, it
-specifies the initial usable size of the hash table; the table will not
-change size until the number of items in the table exceeds
-@var{initial-size}, after which automatic resizing is enabled and
-@var{initial-size} no longer has any effect. Otherwise, if
-@var{initial-size} is not given or is @code{#f}, the table is
-initialized to an unspecified size and automatic resizing is immediately
-enabled.
-
-@cindex rehash size, of hash table (defn)
-The @dfn{rehash size} specifies how much to increase the usable size of
-the hash table when it becomes full. It is either an exact positive
-integer, or a real number greater than one. If it is an integer, the
-new size is the sum of the old size and the rehash size. Otherwise, it
-is a real number, and the new size is the product of the old size and
-the rehash size. Increasing the rehash size decreases the average cost
-of an insertion, but increases the average amount of space used by the
-table. The rehash size of a table may be altered dynamically by the
-application in order to optimize the resizing of the table; for example,
-if the table will grow quickly for a known period and afterwards will
-not change size, performance might be improved by using a large rehash
-size during the growth phase and a small one during the static phase.
-The default rehash size of a newly constructed hash table is @code{2.0}.
-
-@strong{Warning}: The use of an exact positive integer for a rehash
-size is almost always undesirable; this option is provided solely for
-compatibility with the Common Lisp hash-table mechanism. The reason for
-this has to do with the time penalty for resizing the hash table. The
-time needed to resize a hash table is proportional to the
-number of associations in the table. This resizing cost is
-@dfn{amortized} across the insertions required to fill the table to the
-point where it needs to grow again. If the table grows by an amount
-proportional to the number of associations, then the cost of
-resizing and the increase in size are both proportional to the
-number of associations, so the @dfn{amortized cost} of an insertion
-operation is still bounded by a constant. However, if the table grows
-by a constant amount, this is not true: the amortized cost of an
-insertion is not bounded by a constant. Thus, using a constant rehash
-size means that the average cost of an insertion increases
-proportionally to the number of associations in the hash table.
-
-@cindex rehash threshold, of hash table (defn)
-The @dfn{rehash threshold} is a real number, between zero exclusive and
-one inclusive, that specifies the ratio between a hash table's usable
-size and its physical size. Decreasing the rehash threshold decreases
-the probability of worse-than-average insertion, deletion, and lookup
-times, but increases the physical size of the table for a given usable
-size. The default rehash threshold of a newly constructed hash table is
-@code{1}.
-
-@deffn procedure hash-table/size hash-table
-Returns the usable size of @var{hash-table} as an exact positive
-integer. This is the number of associations that @var{hash-table} can
-hold before it will grow.
-@end deffn
-
-@deffn procedure hash-table/rehash-size hash-table
-Returns the rehash size of @var{hash-table}.
-@end deffn
-
-@deffn procedure set-hash-table/rehash-size! hash-table x
-@var{X} must be either an exact positive integer, or a real number that
-is greater than one. Sets the rehash size of @var{hash-table} to
-@var{x} and returns an unspecified result. This operation adjusts the
-``shrink threshold'' of the table; the table might shrink if the number
-of associations is less than the new threshold.
-@end deffn
-
-@deffn procedure hash-table/rehash-threshold hash-table
-Returns the rehash threshold of @var{hash-table}.
-@end deffn
-
-@deffn procedure set-hash-table/rehash-threshold! hash-table x
-@var{X} must be a real number between zero exclusive and one inclusive.
-Sets the rehash threshold of @var{hash-table} to @var{x} and returns an
-unspecified result. This operation does not change the usable size of
-the table, but it usually changes the physical size of the table, which
-causes the table to be rehashed.
-@end deffn
-
-@node Address Hashing, Low-Level Hash Table Operations, Resizing of Hash Tables, Hash Tables
-@subsection Address Hashing
-@cindex address hashing
-
-The procedures described in this section may be used to make very
-efficient key-hashing procedures for arbitrary objects. All of these
-procedures are based on @dfn{address hashing}, which uses the address of
-an object as its hash number. The great advantage of address hashing is
-that converting an arbitrary object to a hash number is extremely fast
-and takes the same amount of time for any object.
-
-The disadvantage of address hashing is that the garbage collector
-changes the addresses of most objects. The hash-table implementation
-compensates for this disadvantage by automatically rehashing tables that
-use address hashing when garbage collections occur. Thus, in order to
-use these procedures for key hashing, it is necessary to tell the
-hash-table implementation (by means of the @var{rehash-after-gc?}
-argument to the ``constructor-constructor'' procedure) that the hash
-numbers computed by your key-hashing procedure must be recomputed after
-a garbage collection.
-
-@deffn procedure eq-hash object
-@deffnx procedure eqv-hash object
-@deffnx procedure equal-hash object
-These procedures return a hash number for @var{object}. The result is
-always a non-negative integer, and in the case of @code{eq-hash}, a
-non-negative fixnum. Two objects that are equivalent according to
-@code{eq?}, @code{eqv?}, or @code{equal?}, respectively, will produce the
-same hash number when passed as arguments to these procedures, provided
-that the garbage collector does not run during or between the two calls.
-@end deffn
-
-The following procedures are the key-hashing procedures used by the
-standard address-hash-based hash tables.
-
-@deffn procedure eq-hash-mod object modulus
-This procedure is the key-hashing procedure used by
-@code{make-eq-hash-table}.
-@end deffn
-
-@deffn procedure eqv-hash-mod object modulus
-This procedure is the key-hashing procedure used by
-@code{make-eqv-hash-table}.
-@end deffn
-
-@deffn procedure equal-hash-mod object modulus
-This procedure is the key-hashing procedure used by
-@code{make-equal-hash-table}.
-@end deffn
-
-@node Low-Level Hash Table Operations, , Address Hashing, Hash Tables
-@subsection Low-Level Hash Table Operations
-
-The procedures in this section allow the programmer to control some of
-the internal structure of a hash table. Normally, hash tables maintain
-associations between keys and datums using pairs or weak pairs. These
-procedures allow the programmer to specify the use of some other data
-structure to maintain the association. In this section, the data
-structure that represents an association in a hash table is called an
-@dfn{entry}.
-
-@deffn procedure hash-table/constructor key-hash key=? make-entry entry-valid? entry-key entry-datum set-entry-datum! [rehash-after-gc?]
-Creates and returns a hash-table constructor procedure
-(@pxref{Construction of Hash Tables}). The arguments define the
-characteristics of the hash table as follows:
-
-@table @var
-@item key-hash
-The hashing procedure. A procedure that accepts two arguments, a key and
-an exact positive integer (the @dfn{modulus}), and returns an exact
-non-negative integer that is less than the modulus.
-
-@item key=?
-A equivalence predicate that accepts two keys and is true iff they are
-the same key. If this predicate is true of two keys, then
-@var{key-hash} must return the same value for each of these keys (given
-the same modulus in both cases).
-
-@item make-entry
-A procedure that accepts a key and a datum as arguments and returns a
-newly allocated entry.
-
-@item entry-valid?
-A procedure that accepts an entry and returns @code{#f} iff the entry's
-key has been reclaimed by the garbage collector. Instead of a
-procedure, this may be @code{#t}, which is equivalent to @code{(lambda
-(entry) #t)}.
-@findex weak-pair/car?
-
-@item entry-key
-A procedure that accepts an entry as an argument and returns the entry's
-key.
-
-@item entry-datum
-A procedure that accepts an entry as an argument and returns the entry's
-datum.
-
-@item set-entry-datum!
-A procedure that accepts an entry and an object as arguments, modifies
-the entry's datum to be the object, and returns an unspecified
-result.
-
-@item rehash-after-gc?
-An optional argument that, if true, says the values returned by
-@var{key-hash} might change after a garbage collection. If so, the
-hash-table implementation arranges for the table to be rehashed when
-necessary. (@xref{Address Hashing}, for information about hash
-procedures that have this property.) Otherwise, it is assumed that
-@var{key-hash} always returns the same value for the same arguments.
-The default value of this argument is @code{#f}.
-@end table
-@end deffn
-
-@noindent
-For example, here is how the constructors for ordinary hash tables could
-be defined:
-
-@example
-@group
-(define (strong-hash-table/constructor key-hash key=?
- #!optional rehash-after-gc?)
- (hash-table/constructor key-hash key=?
- cons #t car cdr set-cdr!
- (if (default-object? rehash-after-gc?)
- #f
- rehash-after-gc?)))
-@end group
-
-@group
-(define (weak-hash-table/constructor key-hash key=?
- #!optional rehash-after-gc?)
- (hash-table/constructor key-hash key=? weak-cons weak-pair/car?
- weak-car weak-cdr weak-set-cdr!
- (if (default-object? rehash-after-gc?)
- #f
- rehash-after-gc?)))
-@end group
-@end example
-
-@deffn procedure hash-table/key-hash hash-table
-@deffnx procedure hash-table/key=? hash-table
-@deffnx procedure hash-table/make-entry hash-table
-@deffnx procedure hash-table/entry-valid? hash-table
-@deffnx procedure hash-table/entry-key hash-table
-@deffnx procedure hash-table/entry-datum hash-table
-@deffnx procedure hash-table/set-entry-datum! hash-table
-Each procedure returns the value of the corresponding argument that was
-used to construct @var{hash-table}.
-@end deffn
-
-The following procedures return the contents of a hash table as a
-collection of entries. While the data structure holding the entries is
-newly allocated, the entries themselves are not copied. Since hash
-table operations can modify these entries, the entries should be copied
-if it is desired to keep them while continuing to modify the table.
-
-@deffn procedure hash-table/entries-list hash-table
-Returns a newly allocated list of the entries in @var{hash-table}.
-@end deffn
-
-@deffn procedure hash-table/entries-vector hash-table
-Returns a newly allocated vector of the entries in @var{hash-table}.
-Equivalent to
-
-@example
-(list->vector (hash-table/entries-list @var{hash-table}))
-@end example
-@end deffn
-
-@node Object Hashing, Red-Black Trees, Hash Tables, Associations
-@section Object Hashing
-
-@cindex object hashing
-@cindex hashing, of object
-The MIT/GNU Scheme object-hashing facility provides a mechanism for
-generating a unique hash number for an arbitrary object. This hash
-number, unlike an object's address, is unchanged by garbage collection.
-The object-hashing facility is useful in conjunction with hash tables,
-but it may be used for other things as well. In particular, it is used
-in the generation of the written representation for many objects
-(@pxref{Custom Output}).
-
-All of these procedures accept an optional argument called @var{table};
-this table contains the object-integer associations. If given, this
-argument must be an object-hash table as constructed by
-@code{hash-table/make} (see below). If not given, a default table is
-used.
-
-@deffn procedure hash object [table]
-@findex eq?
-@code{hash} associates an exact non-negative integer with @var{object}
-and returns that integer. If @code{hash} was previously called with
-@var{object} as its argument, the integer returned is the same as was
-returned by the previous call. @code{hash} guarantees that distinct
-objects (in the sense of @code{eq?}) are associated with distinct
-integers.
-@end deffn
-
-@deffn procedure unhash k [table]
-@code{unhash} takes an exact non-negative integer @var{k} and returns
-the object associated with that integer. If there is no object
-associated with @var{k}, or if the object previously associated with
-@var{k} has been reclaimed by the garbage collector, an error of type
-@code{condition-type:bad-range-argument} is signalled. In other words,
-if @code{hash} previously returned @var{k} for some object, and that
-object has not been reclaimed, it is the value of the call to
-@code{unhash}.
-@findex condition-type:bad-range-argument
-@end deffn
-
-An object that is passed to @code{hash} as an argument is not protected
-from being reclaimed by the garbage collector. If all other references
-to that object are eliminated, the object will be reclaimed.
-Subsequently calling @code{unhash} with the hash number of the (now
-reclaimed) object will signal an error.
-
-@example
-@group
-(define x (cons 0 0)) @result{} @r{unspecified}
-(hash x) @result{} 77
-(eqv? (hash x) (hash x)) @result{} #t
-(define x 0) @result{} @r{unspecified}
-(gc-flip) @r{;force a garbage collection}
-(unhash 77) @error{}
-@end group
-@end example
-
-@deffn procedure object-hashed? object [table]
-This predicate is true if @var{object} has an associated hash number.
-Otherwise it is false.
-@end deffn
-
-@deffn procedure valid-hash-number? k [table]
-This predicate is true if @var{k} is the hash number associated with
-some object. Otherwise it is false.
-@end deffn
-
-The following two procedures provide a lower-level interface to the
-object-hashing mechanism.
-
-@deffn procedure object-hash object [table [insert?]]
-@findex eq?
-@code{object-hash} is like @code{hash}, except that it accepts an
-additional optional argument, @var{insert?}. If @var{insert?}@: is
-supplied and is @code{#f}, @code{object-hash} will return an integer for
-@var{object} only if there is already an association in the table;
-otherwise, it will return @code{#f}. If @var{insert?} is not supplied,
-or is not @code{#f}, @code{object-hash} always returns an integer,
-creating an association in the table if necessary.
-
-@code{object-hash} additionally treats @code{#f} differently than does
-@code{hash}. Calling @code{object-hash} with @code{#f} as its argument
-will return an integer that, when passed to @code{unhash}, will signal
-an error rather than returning @code{#f}. Likewise,
-@code{valid-hash-number?} will return @code{#f} for this integer.
-@end deffn
-
-@deffn procedure object-unhash k [table]
-@code{object-unhash} is like @code{unhash}, except that when @var{k} is
-not associated with any object or was previously associated with an
-object that has been reclaimed, @code{object-unhash} returns @code{#f}.
-This means that there is an ambiguity in the value returned by
-@code{object-unhash}: if @code{#f} is returned, there is no way to
-tell if @var{k} is associated with @code{#f} or is not associated with
-any object at all.
-@end deffn
-
-Finally, this procedure makes new object-hash tables:
-
-@deffn procedure hash-table/make
-This procedure creates and returns a new, empty object-hash table that
-is suitable for use as the optional @var{table} argument to the above
-procedures. The returned table contains no associations.
-@end deffn
-
-@node Red-Black Trees, Weight-Balanced Trees, Object Hashing, Associations
-@section Red-Black Trees
-
-@cindex trees, balanced binary
-@cindex balanced binary trees
-@cindex binary trees
-@cindex red-black binary trees
-Balanced binary trees are a useful data structure for maintaining large
-sets of associations whose keys are ordered. While most applications
-involving large association sets should use hash tables, some
-applications can benefit from the use of binary trees. Binary trees
-have two advantages over hash tables:
-
-@itemize @bullet
-@item
-The contents of a binary tree can be converted to an alist, sorted by
-key, in time proportional to the number of associations in the
-tree. A hash table can be converted into an unsorted alist in linear
-time; sorting it requires additional time.
-
-@item
-Two binary trees can be compared for equality in linear time. Hash
-tables, on the other hand, cannot be compared at all; they must be
-converted to alists before comparison can be done, and alist comparison
-is quadratic unless the alists are sorted.
-@end itemize
-
-MIT/GNU Scheme provides an implementation of @dfn{red-black} trees. The
-red-black tree-balancing algorithm provides generally good performance
-because it doesn't try to keep the tree very closely balanced. At any
-given node in the tree, one side of the node can be twice as high as the
-other in the worst case. With typical data the tree will remain fairly
-well balanced anyway.
-
-A red-black tree takes space that is proportional to the number of
-associations in the tree. For the current implementation, the constant
-of proportionality is eight words per association.
-
-Red-black trees hold their keys @dfn{strongly}. In other words, if a
-red-black tree contains an association for a given key, that key cannot
-be reclaimed by the garbage collector.
-
-@cindex run-time-loadable option
-@cindex option, run-time-loadable
-The red-black tree implementation is a run-time-loadable option. To use
-red-black trees, execute
-
-@example
-(load-option 'rb-tree)
-@end example
-@findex load-option
-
-@noindent
-once before calling any of the procedures defined here.
-
-@deffn procedure make-rb-tree key=? key<?
-This procedure creates and returns a newly allocated red-black tree.
-The tree contains no associations. @var{Key=?} and @var{key<?} are
-predicates that compare two keys and determine whether they are equal to
-or less than one another, respectively. For any two keys, at most one
-of these predicates is true.
-@end deffn
-
-@deffn procedure rb-tree? object
-Returns @code{#t} if @var{object} is a red-black tree, otherwise
-returns @code{#f}.
-@end deffn
-
-@deffn procedure rb-tree/insert! rb-tree key datum
-Associates @var{datum} with @var{key} in @var{rb-tree} and returns an
-unspecified value. If @var{rb-tree} already has an association for
-@var{key}, that association is replaced. The average and worst-case
-times required by this operation are proportional to the logarithm of
-the number of assocations in @var{rb-tree}.
-@end deffn
-
-@deffn procedure rb-tree/lookup rb-tree key default
-Returns the datum associated with @var{key} in @var{rb-tree}. If
-@var{rb-tree} doesn't contain an association for @var{key},
-@var{default} is returned. The average and worst-case times required by
-this operation are proportional to the logarithm of the number of
-assocations in @var{rb-tree}.
-@end deffn
-
-@deffn procedure rb-tree/delete! rb-tree key
-If @var{rb-tree} contains an association for @var{key}, removes it.
-Returns an unspecified value. The average and worst-case times required
-by this operation are proportional to the logarithm of the number of
-assocations in @var{rb-tree}.
-@end deffn
-
-@deffn procedure rb-tree->alist rb-tree
-Returns the contents of @var{rb-tree} as a newly allocated alist. Each
-element of the alist is a pair @code{(@var{key} . @var{datum})} where
-@var{key} is one of the keys of @var{rb-tree}, and @var{datum} is its
-associated datum. The alist is sorted by key according to the
-@var{key<?} argument used to construct @var{rb-tree}. The
-time required by this operation is proportional to the
-number of associations in the tree.
-@end deffn
-
-@deffn procedure rb-tree/key-list rb-tree
-Returns a newly allocated list of the keys in @var{rb-tree}. The list
-is sorted by key according to the @var{key<?} argument used to construct
-@var{rb-tree}. The time required by this
-operation is proportional to the number of associations in the tree.
-@end deffn
-
-@deffn procedure rb-tree/datum-list rb-tree
-Returns a newly allocated list of the datums in @var{rb-tree}. Each
-element of the list corresponds to one of the associations in
-@var{rb-tree}, so if the tree contains multiple associations with the
-same datum, so will this list. The list is sorted by the keys of the
-associations, even though they do not appear in the result. The time required by this operation is proportional to the
-number of associations in the tree.
-
-This procedure is equivalent to:
-
-@example
-(lambda (rb-tree) (map cdr (rb-tree->alist rb-tree)))
-@end example
-@end deffn
-
-@deffn procedure rb-tree/equal? rb-tree-1 rb-tree-2 datum=?
-Compares @var{rb-tree-1} and @var{rb-tree-2} for equality, returning
-@code{#t} iff they are equal and @code{#f} otherwise. The trees must
-have been constructed with the same equality and order predicates (same
-in the sense of @code{eq?}). The keys of the trees are compared using
-the @var{key=?} predicate used to build the trees, while the datums of
-the trees are compared using the equivalence predicate @var{datum=?}.
-The worst-case time required by this operation is proportional to the
-number of associations in the tree.
-@end deffn
-
-@deffn procedure rb-tree/empty? rb-tree
-Returns @code{#t} iff @var{rb-tree} contains no associations. Otherwise
-returns @code{#f}.
-@end deffn
-
-@deffn procedure rb-tree/size rb-tree
-Returns the number of associations in @var{rb-tree}, an exact
-non-negative integer. The average and worst-case times required by this
-operation are proportional to the number of associations in the tree.
-@end deffn
-
-@deffn procedure rb-tree/height rb-tree
-Returns the height of @var{rb-tree}, an exact non-negative integer.
-This is the length of the longest path from a leaf of the tree to the
-root. The average and worst-case times required by this operation are
-proportional to the number of associations in the tree.
-
-The returned value satisfies the following:
-
-@example
-@group
-(lambda (rb-tree)
- (let ((size (rb-tree/size rb-tree))
- (lg (lambda (x) (/ (log x) (log 2)))))
- (<= (lg size)
- (rb-tree/height rb-tree)
- (* 2 (lg (+ size 1))))))
-@end group
-@end example
-@end deffn
-
-@deffn procedure rb-tree/copy rb-tree
-Returns a newly allocated copy of @var{rb-tree}. The copy is identical
-to @var{rb-tree} in all respects, except that changes to @var{rb-tree}
-do not affect the copy, and vice versa. The time required by this
-operation is proportional to the number of associations in the tree.
-@end deffn
-
-@deffn procedure alist->rb-tree alist key=? key<?
-Returns a newly allocated red-black tree that contains the same
-associations as @var{alist}. This procedure is equivalent to:
-
-@example
-@group
-(lambda (alist key=? key<?)
- (let ((tree (make-rb-tree key=? key<?)))
- (for-each (lambda (association)
- (rb-tree/insert! tree
- (car association)
- (cdr association)))
- alist)
- tree))
-@end group
-@end example
-@end deffn
-
-The following operations provide access to the smallest and largest
-members in a red/black tree. They are useful for implementing priority
-queues.
-
-@deffn procedure rb-tree/min rb-tree default
-Returns the smallest key in @var{rb-tree}, or @var{default} if the tree
-is empty.
-@end deffn
-
-@deffn procedure rb-tree/min-datum rb-tree default
-Returns the datum associated with the smallest key in @var{rb-tree}, or
-@var{default} if the tree is empty.
-@end deffn
-
-@deffn procedure rb-tree/min-pair rb-tree
-Finds the smallest key in @var{rb-tree} and returns a pair containing
-that key and its associated datum. If the tree is empty, returns
-@code{#f}.
-@end deffn
-
-@deffn procedure rb-tree/max rb-tree default
-Returns the largest key in @var{rb-tree}, or @var{default} if the tree
-is empty.
-@end deffn
-
-@deffn procedure rb-tree/max-datum rb-tree default
-Returns the datum associated with the largest key in @var{rb-tree}, or
-@var{default} if the tree is empty.
-@end deffn
-
-@deffn procedure rb-tree/max-pair rb-tree
-Finds the largest key in @var{rb-tree} and returns a pair containing
-that key and its associated datum. If the tree is empty, returns
-@code{#f}.
-@end deffn
-
-@deffn procedure rb-tree/delete-min! rb-tree default
-@deffnx procedure rb-tree/delete-min-datum! rb-tree default
-@deffnx procedure rb-tree/delete-min-pair! rb-tree
-@deffnx procedure rb-tree/delete-max! rb-tree default
-@deffnx procedure rb-tree/delete-max-datum! rb-tree default
-@deffnx procedure rb-tree/delete-max-pair! rb-tree
-These operations are exactly like the accessors above, in that they
-return information associated with the smallest or largest key, except
-that they simultaneously delete that key.
-@end deffn
-
-@node Weight-Balanced Trees, , Red-Black Trees, Associations
-@section Weight-Balanced Trees
-
-@cindex trees, balanced binary
-@cindex balanced binary trees
-@cindex binary trees
-@cindex weight-balanced binary trees
-Balanced binary trees are a useful data structure for maintaining large
-sets of ordered objects or sets of associations whose keys are ordered.
-MIT/GNU Scheme has a comprehensive implementation of weight-balanced binary
-trees which has several advantages over the other data structures for
-large aggregates:
-
-@itemize @bullet
-@item
-In addition to the usual element-level operations like insertion,
-deletion and lookup, there is a full complement of collection-level
-operations, like set intersection, set union and subset test, all of
-which are implemented with good orders of growth in time and space.
-This makes weight-balanced trees ideal for rapid prototyping of
-functionally derived specifications.
-
-@item
-An element in a tree may be indexed by its position under the ordering
-of the keys, and the ordinal position of an element may be determined,
-both with reasonable efficiency.
-
-@item
-Operations to find and remove minimum element make weight-balanced trees
-simple to use for priority queues.
-
-@item
-The implementation is @emph{functional} rather than @emph{imperative}.
-This means that operations like `inserting' an association in a tree do
-not destroy the old tree, in much the same way that @code{(+ 1 x)}
-modifies neither the constant 1 nor the value bound to @code{x}. The
-trees are referentially transparent thus the programmer need not worry
-about copying the trees. Referential transparency allows space
-efficiency to be achieved by sharing subtrees.
-@end itemize
-
-These features make weight-balanced trees suitable for a wide range of
-applications, especially those that require large numbers of sets or
-discrete maps. Applications that have a few global databases and/or
-concentrate on element-level operations like insertion and lookup are
-probably better off using hash tables or red-black trees.
-
-The @emph{size} of a tree is the number of associations that it
-contains. Weight-balanced binary trees are balanced to keep the sizes
-of the subtrees of each node within a constant factor of each other.
-This ensures logarithmic times for single-path operations (like lookup
-and insertion). A weight-balanced tree takes space that is proportional
-to the number of associations in the tree. For the current
-implementation, the constant of proportionality is six words per
-association.
-
-@cindex binary trees, as sets
-@cindex binary trees, as discrete maps
-@cindex sets, using binary trees
-@cindex discrete maps, using binary trees
-Weight-balanced trees can be used as an implementation for either
-discrete sets or discrete maps (associations). Sets are implemented by
-ignoring the datum that is associated with the key. Under this scheme
-if an association exists in the tree this indicates that the key of the
-association is a member of the set. Typically a value such as
-@code{()}, @code{#t} or @code{#f} is associated with the key.
-
-Many operations can be viewed as computing a result that, depending on
-whether the tree arguments are thought of as sets or maps, is known by
-two different names. An example is @code{wt-tree/member?}, which, when
-regarding the tree argument as a set, computes the set membership
-operation, but, when regarding the tree as a discrete map,
-@code{wt-tree/member?} is the predicate testing if the map is defined at
-an element in its domain. Most names in this package have been chosen
-based on interpreting the trees as sets, hence the name
-@code{wt-tree/member?} rather than @code{wt-tree/defined-at?}.
-
-@cindex run-time-loadable option
-@cindex option, run-time-loadable
-The weight-balanced tree implementation is a run-time-loadable option.
-To use weight-balanced trees, execute
-
-@example
-(load-option 'wt-tree)
-@end example
-@findex load-option
-
-@noindent
-once before calling any of the procedures defined here.
-
-@menu
-* Construction of Weight-Balanced Trees::
-* Basic Operations on Weight-Balanced Trees::
-* Advanced Operations on Weight-Balanced Trees::
-* Indexing Operations on Weight-Balanced Trees::
-@end menu
-
-@node Construction of Weight-Balanced Trees, Basic Operations on Weight-Balanced Trees, Weight-Balanced Trees, Weight-Balanced Trees
-@subsection Construction of Weight-Balanced Trees
-
-Binary trees require there to be a total order on the keys used to
-arrange the elements in the tree. Weight-balanced trees are organized
-by @emph{types}, where the type is an object encapsulating the ordering
-relation. Creating a tree is a two-stage process. First a tree type
-must be created from the predicate that gives the ordering. The tree type
-is then used for making trees, either empty or singleton trees or trees
-from other aggregate structures like association lists. Once created, a
-tree `knows' its type and the type is used to test compatibility between
-trees in operations taking two trees. Usually a small number of tree
-types are created at the beginning of a program and used many times
-throughout the program's execution.
-
-@deffn procedure make-wt-tree-type key<?
-This procedure creates and returns a new tree type based on the ordering
-predicate @var{key<?}.
-@var{Key<?} must be a total ordering, having the property that for all
-key values @code{a}, @code{b} and @code{c}:
-
-@example
-@group
-(key<? a a) @result{} #f
-(and (key<? a b) (key<? b a)) @result{} #f
-(if (and (key<? a b) (key<? b c))
- (key<? a c)
- #t) @result{} #t
-@end group
-@end example
-
-@noindent
-Two key values are assumed to be equal if neither is less than the other
-by @var{key<?}.
-
-Each call to @code{make-wt-tree-type} returns a distinct value, and
-trees are only compatible if their tree types are @code{eq?}. A
-consequence is that trees that are intended to be used in binary-tree
-operations must all be created with a tree type originating from the
-same call to @code{make-wt-tree-type}.
-@end deffn
-
-@defvr variable number-wt-type
-A standard tree type for trees with numeric keys. @code{Number-wt-type}
-could have been defined by
-
-@example
-(define number-wt-type (make-wt-tree-type <))
-@end example
-@end defvr
-
-@defvr variable string-wt-type
-A standard tree type for trees with string keys. @code{String-wt-type}
-could have been defined by
-
-@example
-(define string-wt-type (make-wt-tree-type string<?))
-@end example
-@end defvr
-
-@deffn procedure make-wt-tree wt-tree-type
-This procedure creates and returns a newly allocated weight-balanced
-tree. The tree is empty, i.e. it contains no associations.
-@var{Wt-tree-type} is a weight-balanced tree type obtained by calling
-@code{make-wt-tree-type}; the returned tree has this type.
-@end deffn
-
-@deffn procedure singleton-wt-tree wt-tree-type key datum
-This procedure creates and returns a newly allocated weight-balanced
-tree. The tree contains a single association, that of @var{datum} with
-@var{key}. @var{Wt-tree-type} is a weight-balanced tree type obtained
-by calling @code{make-wt-tree-type}; the returned tree has this type.
-@end deffn
-
-@deffn procedure alist->wt-tree tree-type alist
-Returns a newly allocated weight-balanced tree that contains the same
-associations as @var{alist}. This procedure is equivalent to:
-
-@example
-@group
-(lambda (type alist)
- (let ((tree (make-wt-tree type)))
- (for-each (lambda (association)
- (wt-tree/add! tree
- (car association)
- (cdr association)))
- alist)
- tree))
-@end group
-@end example
-@end deffn
-
-@node Basic Operations on Weight-Balanced Trees, Advanced Operations on Weight-Balanced Trees, Construction of Weight-Balanced Trees, Weight-Balanced Trees
-@subsection Basic Operations on Weight-Balanced Trees
-
-This section describes the basic tree operations on weight-balanced
-trees. These operations are the usual tree operations for insertion,
-deletion and lookup, some predicates and a procedure for determining the
-number of associations in a tree.
-
-@deffn procedure wt-tree? object
-Returns @code{#t} if @var{object} is a weight-balanced tree, otherwise
-returns @code{#f}.
-@end deffn
-
-@deffn procedure wt-tree/empty? wt-tree
-Returns @code{#t} if @var{wt-tree} contains no associations, otherwise
-returns @code{#f}.
-@end deffn
-
-@deffn procedure wt-tree/size wt-tree
-Returns the number of associations in @var{wt-tree}, an exact
-non-negative integer. This operation takes constant time.
-@end deffn
-
-@deffn procedure wt-tree/add wt-tree key datum
-Returns a new tree containing all the associations in @var{wt-tree} and
-the association of @var{datum} with @var{key}. If @var{wt-tree} already
-had an association for @var{key}, the new association overrides the old.
-The average and worst-case times required by this operation are
-proportional to the logarithm of the number of associations in
-@var{wt-tree}.
-@end deffn
-
-@deffn procedure wt-tree/add! wt-tree key datum
-Associates @var{datum} with @var{key} in @var{wt-tree} and returns an
-unspecified value. If @var{wt-tree} already has an association for
-@var{key}, that association is replaced. The average and worst-case
-times required by this operation are proportional to the logarithm of
-the number of associations in @var{wt-tree}.
-@end deffn
-
-@deffn procedure wt-tree/member? key wt-tree
-Returns @code{#t} if @var{wt-tree} contains an association for
-@var{key}, otherwise returns @code{#f}. The average and worst-case
-times required by this operation are proportional to the logarithm of
-the number of associations in @var{wt-tree}.
-@end deffn
-
-@deffn procedure wt-tree/lookup wt-tree key default
-Returns the datum associated with @var{key} in @var{wt-tree}. If
-@var{wt-tree} doesn't contain an association for @var{key},
-@var{default} is returned. The average and worst-case times required by
-this operation are proportional to the logarithm of the number of
-associations in @var{wt-tree}.
-@end deffn
-
-@deffn procedure wt-tree/delete wt-tree key
-Returns a new tree containing all the associations in @var{wt-tree},
-except that if @var{wt-tree} contains an association for @var{key}, it
-is removed from the result. The average and worst-case times required
-by this operation are proportional to the logarithm of the number of
-associations in @var{wt-tree}.
-@end deffn
-
-@deffn procedure wt-tree/delete! wt-tree key
-If @var{wt-tree} contains an association for @var{key} the association
-is removed. Returns an unspecified value. The average and worst-case
-times required by this operation are proportional to the logarithm of
-the number of associations in @var{wt-tree}.
-@end deffn
-
-@node Advanced Operations on Weight-Balanced Trees, Indexing Operations on Weight-Balanced Trees, Basic Operations on Weight-Balanced Trees, Weight-Balanced Trees
-@subsection Advanced Operations on Weight-Balanced Trees
-
-In the following the @emph{size} of a tree is the number of associations
-that the tree contains, and a @emph{smaller} tree contains fewer
-associations.
-
-@deffn procedure wt-tree/split< wt-tree bound
-Returns a new tree containing all and only the associations in
-@var{wt-tree} that have a key that is less than @var{bound} in the
-ordering relation of the tree type of @var{wt-tree}. The average and
-worst-case times required by this operation are proportional to the
-logarithm of the size of @var{wt-tree}.
-@end deffn
-
-@deffn procedure wt-tree/split> wt-tree bound
-Returns a new tree containing all and only the associations in
-@var{wt-tree} that have a key that is greater than @var{bound} in the
-ordering relation of the tree type of @var{wt-tree}. The average and
-worst-case times required by this operation are proportional to the
-logarithm of the size of @var{wt-tree}.
-@end deffn
-
-@deffn procedure wt-tree/union wt-tree-1 wt-tree-2
-Returns a new tree containing all the associations from both trees.
-This operation is asymmetric: when both trees have an association for
-the same key, the returned tree associates the datum from @var{wt-tree-2}
-with the key. Thus if the trees are viewed as discrete maps then
-@code{wt-tree/union} computes the map override of @var{wt-tree-1} by
-@var{wt-tree-2}. If the trees are viewed as sets the result is the set
-union of the arguments.
-The worst-case time required by this operation
-is proportional to the sum of the sizes of both trees.
-If the minimum key of one tree is greater than the maximum key of
-the other tree then the worst-case time required is proportional to
-the logarithm of the size of the larger tree.
-@end deffn
-
-@deffn procedure wt-tree/intersection wt-tree-1 wt-tree-2
-Returns a new tree containing all and only those associations from
-@var{wt-tree-1} that have keys appearing as the key of an association
-in @var{wt-tree-2}. Thus the associated data in the result are those
-from @var{wt-tree-1}. If the trees are being used as sets the result is
-the set intersection of the arguments. As a discrete map operation,
-@code{wt-tree/intersection} computes the domain restriction of
-@var{wt-tree-1} to (the domain of) @var{wt-tree-2}.
-The worst-case time required by this operation is proportional to
-the sum of the sizes of the trees.
-@end deffn
-
-@deffn procedure wt-tree/difference wt-tree-1 wt-tree-2
-Returns a new tree containing all and only those associations from
-@var{wt-tree-1} that have keys that @emph{do not} appear as the key of
-an association in @var{wt-tree-2}. If the trees are viewed as sets the
-result is the asymmetric set difference of the arguments. As a discrete
-map operation, it computes the domain restriction of @var{wt-tree-1} to
-the complement of (the domain of) @var{wt-tree-2}.
-The worst-case time required by this operation is proportional to
-the sum of the sizes of the trees.
-@end deffn
-
-@deffn procedure wt-tree/subset? wt-tree-1 wt-tree-2
-Returns @code{#t} iff the key of each association in @var{wt-tree-1} is
-the key of some association in @var{wt-tree-2}, otherwise returns @code{#f}.
-Viewed as a set operation, @code{wt-tree/subset?} is the improper subset
-predicate.
-A proper subset predicate can be constructed:
-
-@example
-@group
-(define (proper-subset? s1 s2)
- (and (wt-tree/subset? s1 s2)
- (< (wt-tree/size s1) (wt-tree/size s2))))
-@end group
-@end example
-
-As a discrete map operation, @code{wt-tree/subset?} is the subset
-test on the domain(s) of the map(s). In the worst-case the time
-required by this operation is proportional to the size of
-@var{wt-tree-1}.
-@end deffn
-
-@deffn procedure wt-tree/set-equal? wt-tree-1 wt-tree-2
-Returns @code{#t} iff for every association in @var{wt-tree-1} there is
-an association in @var{wt-tree-2} that has the same key, and @emph{vice
-versa}.
-
-Viewing the arguments as sets, @code{wt-tree/set-equal?} is the set
-equality predicate. As a map operation it determines if two maps are
-defined on the same domain.
-
-This procedure is equivalent to
-
-@example
-@group
-(lambda (wt-tree-1 wt-tree-2)
- (and (wt-tree/subset? wt-tree-1 wt-tree-2
- (wt-tree/subset? wt-tree-2 wt-tree-1)))
-@end group
-@end example
-
-In the worst case the time required by this operation is proportional to
-the size of the smaller tree.
-@end deffn
-
-@deffn procedure wt-tree/fold combiner initial wt-tree
-This procedure reduces @var{wt-tree} by combining all the associations,
-using an reverse in-order traversal, so the associations are visited in
-reverse order. @var{Combiner} is a procedure of three arguments: a key,
-a datum and the accumulated result so far. Provided @var{combiner}
-takes time bounded by a constant, @code{wt-tree/fold} takes time
-proportional to the size of @var{wt-tree}.
-
-A sorted association list can be derived simply:
-
-@example
-@group
-(wt-tree/fold (lambda (key datum list)
- (cons (cons key datum) list))
- '()
- @var{wt-tree}))
-@end group
-@end example
-
-The data in the associations can be summed like this:
-
-@example
-@group
-(wt-tree/fold (lambda (key datum sum) (+ sum datum))
- 0
- @var{wt-tree})
-@end group
-@end example
-@end deffn
-
-@deffn procedure wt-tree/for-each action wt-tree
-This procedure traverses @var{wt-tree} in order, applying @var{action} to
-each association.
-The associations are processed in increasing order of their keys.
-@var{Action} is a procedure of two arguments that takes the key and
-datum respectively of the association.
-Provided @var{action} takes time bounded by a constant,
-@code{wt-tree/for-each} takes time proportional to the size of
-@var{wt-tree}.
-The example prints the tree:
-
-@example
-@group
-(wt-tree/for-each (lambda (key value)
- (display (list key value)))
- @var{wt-tree}))
-@end group
-@end example
-@end deffn
-
-@deffn procedure wt-tree/union-merge wt-tree-1 wt-tree-2 merge
-Returns a new tree containing all the associations from both trees. If
-both trees have an association for the same key, the datum associated
-with that key in the result tree is computed by applying the procedure
-@var{merge} to the key, the value from @var{wt-tree-1} and the value
-from @var{wt-tree-2}. @var{Merge} is of the form
-
-@example
-(lambda (@var{key} @var{datum-1} @var{datum-2}) @dots{})
-@end example
-
-If some key occurs only in one tree, that association will appear in the
-result tree without being processed by @var{merge}, so for this
-operation to make sense, either @var{merge} must have both a right and
-left identity that correspond to the association being absent in one of
-the trees, or some guarantee must be made, for example, all the keys in
-one tree are known to occur in the other.
-
-These are all reasonable procedures for @var{merge}
-
-@example
-@group
-(lambda (key val1 val2) (+ val1 val2))
-(lambda (key val1 val2) (append val1 val2))
-(lambda (key val1 val2) (wt-tree/union val1 val2))
-@end group
-@end example
-
-However, a procedure like
-
-@example
-(lambda (key val1 val2) (- val1 val2))
-@end example
-
-would result in a subtraction of the data for all associations with keys
-occuring in both trees but associations with keys occuring in only the
-second tree would be copied, not negated, as is presumably be intent.
-The programmer might ensure that this never happens.
-
-This procedure has the same time behavior as @code{wt-tree/union} but
-with a slightly worse constant factor. Indeed, @code{wt-tree/union}
-might have been defined like this:
-
-@example
-@group
-(define (wt-tree/union tree1 tree2)
- (wt-tree/union-merge tree1 tree2
- (lambda (key val1 val2) val2)))
-@end group
-@end example
-@end deffn
-
-The @var{merge} procedure takes the @var{key} as a parameter in case the
-data are not independent of the key.
-
-
-@node Indexing Operations on Weight-Balanced Trees, , Advanced Operations on Weight-Balanced Trees, Weight-Balanced Trees
-@subsection Indexing Operations on Weight-Balanced Trees
-
-Weight-balanced trees support operations that view the tree as sorted
-sequence of associations. Elements of the sequence can be accessed by
-position, and the position of an element in the sequence can be
-determined, both in logarthmic time.
-
-@deffn procedure wt-tree/index wt-tree index
-@deffnx procedure wt-tree/index-datum wt-tree index
-@deffnx procedure wt-tree/index-pair wt-tree index
-Returns the 0-based @var{index}th association of @var{wt-tree} in the
-sorted sequence under the tree's ordering relation on the keys.
-@code{wt-tree/index} returns the @var{index}th key,
-@code{wt-tree/index-datum} returns the datum associated with the
-@var{index}th key and @code{wt-tree/index-pair} returns a new pair
-@code{(@var{key} . @var{datum})} which is the @code{cons} of the
-@var{index}th key and its datum. The average and worst-case times
-required by this operation are proportional to the logarithm of the
-number of associations in the tree.
-
-These operations signal a condition of type
-@code{condition-type:bad-range-argument} if @var{index}@code{<0} or if
-@var{index} is greater than or equal to the number of associations in
-the tree. If the tree is empty, they signal an anonymous error.
-
-Indexing can be used to find the median and maximum keys in the tree as
-follows:
-
-@example
-@group
-median: (wt-tree/index @var{wt-tree}
- (quotient (wt-tree/size @var{wt-tree})
- 2))
-maximum: (wt-tree/index @var{wt-tree}
- (- (wt-tree/size @var{wt-tree})
- 1))
-@end group
-@end example
-@end deffn
-
-@deffn procedure wt-tree/rank wt-tree key
-Determines the 0-based position of @var{key} in the sorted sequence of
-the keys under the tree's ordering relation, or @code{#f} if the tree
-has no association with for @var{key}. This procedure returns either an
-exact non-negative integer or @code{#f}. The average and worst-case
-times required by this operation are proportional to the logarithm of
-the number of associations in the tree.
-@end deffn
-
-@deffn procedure wt-tree/min wt-tree
-@deffnx procedure wt-tree/min-datum wt-tree
-@deffnx procedure wt-tree/min-pair wt-tree
-Returns the association of @var{wt-tree} that has the least key under the tree's ordering relation.
-@code{wt-tree/min} returns the least key,
-@code{wt-tree/min-datum} returns the datum associated with the
-least key and @code{wt-tree/min-pair} returns a new pair
-@code{(key . datum)} which is the @code{cons} of the minimum key and its datum.
-The average and worst-case times required by this operation are
-proportional to the logarithm of the number of associations in the tree.
-
-These operations signal an error if the tree is empty.
-They could have been written
-
-@example
-@group
-(define (wt-tree/min tree)
- (wt-tree/index tree 0))
-(define (wt-tree/min-datum tree)
- (wt-tree/index-datum tree 0))
-(define (wt-tree/min-pair tree)
- (wt-tree/index-pair tree 0))
-@end group
-@end example
-@end deffn
-
-@deffn procedure wt-tree/delete-min wt-tree
-Returns a new tree containing all of the associations in @var{wt-tree}
-except the association with the least key under the @var{wt-tree}'s
-ordering relation. An error is signalled if the tree is empty. The
-average and worst-case times required by this operation are proportional
-to the logarithm of the number of associations in the tree. This
-operation is equivalent to
-
-@example
-(wt-tree/delete @var{wt-tree} (wt-tree/min @var{wt-tree}))
-@end example
-@end deffn
-
-@deffn procedure wt-tree/delete-min! wt-tree
-Removes the association with the least key under the @var{wt-tree}'s
-ordering relation. An error is signalled if the tree is empty. The
-average and worst-case times required by this operation are proportional
-to the logarithm of the number of associations in the tree. This
-operation is equivalent to
-
-@example
-(wt-tree/delete! @var{wt-tree} (wt-tree/min @var{wt-tree}))
-@end example
-@end deffn
-
-
-@node Procedures, Environments, Associations, Top
-@chapter Procedures
-
-@cindex procedure
-@cindex primitive procedure (defn)
-@cindex built-in procedure
-@findex lambda
-@cindex application hook (defn)
-@cindex hook, application (defn)
-Procedures are created by evaluating @code{lambda} expressions
-(@pxref{Lambda Expressions}); the @code{lambda} may either be explicit
-or may be implicit as in a ``procedure @code{define}''
-(@pxref{Definitions}). Also there are special built-in procedures,
-called @dfn{primitive procedures}, such as @code{car}; these procedures
-are not written in Scheme but in the language used to implement the
-Scheme system. MIT/GNU Scheme also provides @dfn{application hooks}, which
-support the construction of data structures that act like procedures.
-
-@cindex procedure, type
-@cindex procedure, primitive
-@cindex procedure, interpreted
-@cindex procedure, compiled
-@cindex type, of procedure
-@cindex primitive, procedure type
-@cindex interpreted, procedure type
-@cindex compiled, procedure type
-@cindex external representation, for procedure
-In MIT/GNU Scheme, the written representation of a procedure tells you
-the type of the procedure (compiled, interpreted, or primitive):
-
-@example
-@group
-pp
- @result{} #[compiled-procedure 56 ("pp" #x2) #x10 #x307578]
-(lambda (x) x)
- @result{} #[compound-procedure 57]
-(define (foo x) x)
-foo
- @result{} #[compound-procedure 58 foo]
-car
- @result{} #[primitive-procedure car]
-(call-with-current-continuation (lambda (x) x))
- @result{} #[continuation 59]
-@end group
-@end example
-
-@noindent
-@cindex compound procedure
-@cindex procedure, compound
-Note that interpreted procedures are called ``compound'' procedures
-(strictly speaking, compiled procedures are also compound procedures).
-The written representation makes this distinction for historical
-reasons, and may eventually change.
-
-@menu
-* Procedure Operations::
-* Primitive Procedures::
-* Continuations::
-* Application Hooks::
-@end menu
-
-@node Procedure Operations, Primitive Procedures, Procedures, Procedures
-@section Procedure Operations
-
-@deffn procedure apply procedure object object @dots{}
-@cindex application, of procedure
-Calls @var{procedure} with the elements of the following list as
-arguments:
-
-@example
-(cons* @var{object} @var{object} @dots{})
-@end example
-
-@noindent
-The initial @var{object}s may be any objects, but the last @var{object}
-(there must be at least one @var{object}) must be a list.
-
-@example
-@group
-(apply + (list 3 4 5 6)) @result{} 18
-(apply + 3 4 '(5 6)) @result{} 18
-
-(define compose
- (lambda (f g)
- (lambda args
- (f (apply g args)))))
-((compose sqrt *) 12 75) @result{} 30
-@end group
-@end example
-@end deffn
-
-@deffn procedure procedure? object
-@cindex type predicate, for procedure
-Returns @code{#t} if @var{object} is a procedure; otherwise returns
-@code{#f}. If @code{#t} is returned, exactly one of the following
-predicates is satisfied by @var{object}: @code{compiled-procedure?},
-@code{compound-procedure?}, or @code{primitive-procedure?}.
-@end deffn
-
-@deffn procedure compiled-procedure? object
-@cindex type predicate, for compiled procedure
-Returns @code{#t} if @var{object} is a compiled procedure; otherwise
-returns @code{#f}.
-@end deffn
-
-@deffn procedure compound-procedure? object
-@cindex type predicate, for compound procedure
-Returns @code{#t} if @var{object} is a compound (i.e.@: interpreted)
-procedure; otherwise returns @code{#f}.
-@end deffn
-
-@deffn procedure primitive-procedure? object
-@cindex type predicate, for primitive procedure
-Returns @code{#t} if @var{object} is a primitive procedure; otherwise
-returns @code{#f}.
-@end deffn
-
-The following two procedures test the @dfn{arity} of a procedure, that
-is, the number of arguments that the procedure accepts. The results of
-the test may be less restrictive than the effect of calling the
-procedure. In other words, these procedures may indicate that the
-procedure will accept a given number of arguments, but if you call the
-procedure it may signal a
-@code{condition-type:wrong-number-of-arguments} error. This is because
-these procedures examine the apparent arity of a procedure. For
-example, here is a procedure that appears to accept any number of
-arguments, but when called will signal an error if the number of
-arguments is not one:
-@findex condition-type:wrong-number-of-arguments
-
-@example
-(lambda arguments (apply car arguments))
-@end example
-
-@deffn procedure procedure-arity-valid? procedure k
-Returns @code{#t} if @var{procedure} accepts @var{k} arguments;
-otherwise returns @code{#f}.
-@end deffn
-
-@deffn procedure procedure-arity procedure
-Returns a description of the number of arguments that @var{procedure}
-accepts. The result is a newly allocated pair whose car field is the
-minimum number of arguments, and whose cdr field is the maximum
-number of arguments. The minimum is an exact non-negative integer. The
-maximum is either an exact non-negative integer, or @code{#f} meaning
-that the procedure has no maximum number of arguments.
-
-@example
-@group
-(procedure-arity (lambda () 3)) @result{} (0 . 0)
-(procedure-arity (lambda (x) x)) @result{} (1 . 1)
-(procedure-arity car) @result{} (1 . 1)
-(procedure-arity (lambda x x)) @result{} (0 . #f)
-(procedure-arity (lambda (x . y) x)) @result{} (1 . #f)
-(procedure-arity (lambda (x #!optional y) x))
- @result{} (1 . 2)
-@end group
-@end example
-@end deffn
-
-@deffn procedure procedure-environment procedure
-Returns the closing environment of @var{procedure}. Signals an error if
-@var{procedure} is a primitive procedure, or if @var{procedure} is a
-compiled procedure for which the debugging information is unavailable.
-@end deffn
-
-@node Primitive Procedures, Continuations, Procedure Operations, Procedures
-@section Primitive Procedures
-
-@deffn procedure make-primitive-procedure name [arity]
-@var{Name} must be a symbol. @var{Arity} must be an exact non-negative
-integer, @code{-1}, @code{#f}, or @code{#t}; if not supplied it defaults
-to @code{#f}. Returns the primitive procedure called @var{name}. May
-perform further actions depending on @var{arity}:
-
-@table @asis
-@item @code{#f}
-If the primitive procedure is not implemented, signals an error.
-
-@item @code{#t}
-If the primitive procedure is not implemented, returns @code{#f}.
-
-@item integer
-If the primitive procedure is implemented, signals an error if its arity
-is not equal to @var{arity}. If the primitive procedure is not
-implemented, returns an unimplemented primitive procedure object that
-accepts @var{arity} arguments. An @var{arity} of @code{-1} means it
-accepts any number of arguments.
-@end table
-@end deffn
-
-@deffn procedure primitive-procedure-name primitive-procedure
-Returns the name of @var{primitive-procedure}, a symbol.
-
-@example
-(primitive-procedure-name car) @result{} car
-@end example
-@end deffn
-
-@deffn procedure implemented-primitive-procedure? primitive-procedure
-Returns @code{#t} if @var{primitive-procedure} is implemented; otherwise
-returns @code{#f}. Useful because the code that implements a particular
-primitive procedure is not necessarily linked into the executable Scheme
-program.
-@end deffn
-
-@node Continuations, Application Hooks, Primitive Procedures, Procedures
-@section Continuations
-
-@deffn procedure call-with-current-continuation procedure
-@cindex continuation
-@cindex construction, of continuation
-@cindex procedure, escape (defn)
-@cindex escape procedure (defn)
-@var{Procedure} must be a procedure of one argument. Packages up the
-current continuation (see below) as an @dfn{escape procedure} and passes
-it as an argument to @var{procedure}. The escape procedure is a Scheme
-procedure of one argument that, if it is later passed a value, will
-ignore whatever continuation is in effect at that later time and will
-give the value instead to the continuation that was in effect when the
-escape procedure was created. The escape procedure created by
-@code{call-with-current-continuation} has unlimited extent just like any
-other procedure in Scheme. It may be stored in variables or data
-structures and may be called as many times as desired.
-
-The following examples show only the most common uses of this procedure.
-If all real programs were as simple as these examples, there would be no
-need for a procedure with the power of
-@code{call-with-current-continuation}.
-
-@example
-@group
-(call-with-current-continuation
- (lambda (exit)
- (for-each (lambda (x)
- (if (negative? x)
- (exit x)))
- '(54 0 37 -3 245 19))
- #t)) @result{} -3
-@end group
-
-@group
-(define list-length
- (lambda (obj)
- (call-with-current-continuation
- (lambda (return)
- (letrec ((r
- (lambda (obj)
- (cond ((null? obj) 0)
- ((pair? obj) (+ (r (cdr obj)) 1))
- (else (return #f))))))
- (r obj))))))
-(list-length '(1 2 3 4)) @result{} 4
-(list-length '(a b . c)) @result{} #f
-@end group
-@end example
-
-@cindex non-local exit
-@cindex exit, non-local
-A common use of @code{call-with-current-continuation} is for structured,
-non-local exits from loops or procedure bodies, but in fact
-@code{call-with-current-continuation} is quite useful for implementing a
-wide variety of advanced control structures.
-
-Whenever a Scheme expression is evaluated a continuation exists that
-wants the result of the expression. The continuation represents an
-entire (default) future for the computation. If the expression is
-evaluated at top level, for example, the continuation will take the
-result, print it on the screen, prompt for the next input, evaluate it,
-and so on forever. Most of the time the continuation includes actions
-specified by user code, as in a continuation that will take the result,
-multiply it by the value stored in a local variable, add seven, and give
-the answer to the top-level continuation to be printed. Normally these
-ubiquitous continuations are hidden behind the scenes and programmers
-don't think much about them. On the rare occasions that you may need to
-deal explicitly with continuations,
-@code{call-with-current-continuation} lets you do so by creating a
-procedure that acts just like the current continuation.
-@end deffn
-
-@deffn procedure continuation? object
-@cindex type predicate, for continuation
-Returns @code{#t} if @var{object} is a continuation; otherwise returns
-@code{#f}.
-@end deffn
-
-@deffn procedure within-continuation continuation thunk
-@cindex continuation, alternate invocation
-@cindex escape procedure, alternate invocation
-@var{Thunk} must be a procedure of no arguments. Conceptually,@*
-@code{within-continuation} invokes @var{continuation} on the result of
-invoking @var{thunk}, but @var{thunk} is executed in the dynamic context
-of @var{continuation}. In other words, the ``current'' continuation is
-abandoned before @var{thunk} is invoked.
-@end deffn
-
-@deffn procedure dynamic-wind before thunk after
-Calls @var{thunk} without arguments, returning the result(s) of this
-call. @var{Before} and @var{after} are called, also without arguments,
-as required by the following rules (note that in the absence of calls to
-continuations captured using @code{call-with-current-continuation} the
-three arguments are called once each, in order). @var{Before} is called
-whenever execution enters the dynamic extent of the call to @var{thunk}
-and @var{after} is called whenever it exits that dynamic extent. The
-dynamic extent of a procedure call is the period between when the call
-is initiated and when it returns. In Scheme, because of
-@code{call-with-current-continuation}, the dynamic extent of a call may
-not be a single, connected time period. It is defined as follows:
-
-@itemize @bullet
-@item
-The dynamic extent is entered when execution of the body of the called
-procedure begins.
-
-@item
-The dynamic extent is also entered when execution is not within the
-dynamic extent and a continuation is invoked that was captured (using
-@code{call-with-current-continuation}) during the dynamic extent.
-
-@item
-It is exited when the called procedure returns.
-
-@item
-It is also exited when execution is within the dynamic extent and a
-continuation is invoked that was captured while not within the dynamic
-extent.
-@end itemize
-
-If a second call to @code{dynamic-wind} occurs within the dynamic extent
-of the call to @var{thunk} and then a continuation is invoked in such a
-way that the @var{after}s from these two invocations of
-@code{dynamic-wind} are both to be called, then the @var{after}
-associated with the second (inner) call to @code{dynamic-wind} is called
-first.
-
-If a second call to @code{dynamic-wind} occurs within the dynamic extent
-of the call to @var{thunk} and then a continuation is invoked in such a
-way that the @var{before}s from these two invocations of
-@code{dynamic-wind} are both to be called, then the @var{before}
-associated with the first (outer) call to @code{dynamic-wind} is called
-first.
-
-If invoking a continuation requires calling the @var{before} from one
-call to @code{dynamic-wind} and the @var{after} from another, then the
-@var{after} is called first.
-
-The effect of using a captured continuation to enter or exit the dynamic
-extent of a call to @var{before} or @var{after} is undefined.
-
-@example
-@group
-(let ((path '())
- (c #f))
- (let ((add (lambda (s)
- (set! path (cons s path)))))
- (dynamic-wind
- (lambda () (add 'connect))
- (lambda ()
- (add (call-with-current-continuation
- (lambda (c0)
- (set! c c0)
- 'talk1))))
- (lambda () (add 'disconnect)))
- (if (< (length path) 4)
- (c 'talk2)
- (reverse path))))
-
-@result{} (connect talk1 disconnect connect talk2 disconnect)
-@end group
-@end example
-@end deffn
-
-The following two procedures support multiple values.
-
-@deffn procedure call-with-values thunk procedure
-@cindex multiple values, from procedure
-@cindex values, multiple
-@var{Thunk} must be a procedure of no arguments, and @var{procedure}
-must be a procedure. @var{Thunk} is invoked with a continuation that
-expects to receive multiple values; specifically, the continuation
-expects to receive the same number of values that @var{procedure}
-accepts as arguments. @var{Thunk} must return multiple values using the
-@code{values} procedure. Then @var{procedure} is called with the
-multiple values as its arguments. The result yielded by @var{procedure}
-is returned as the result of @code{call-with-values}.
-@end deffn
-
-@deffn procedure values object @dots{}
-Returns multiple values. The continuation in effect when this procedure
-is called must be a multiple-value continuation that was created by
-@code{call-with-values}. Furthermore it must accept as many values as
-there are @var{object}s.
-@end deffn
-
-@node Application Hooks, , Continuations, Procedures
-@section Application Hooks
-
-@cindex application hook (defn)
-@cindex procedure, of application hook
-@cindex extra object, of application hook
-@dfn{Application hooks} are objects that can be applied like procedures.
-Each application hook has two parts: a @dfn{procedure} that specifies
-what to do when the application hook is applied, and an arbitrary
-object, called @dfn{extra}. Often the procedure uses the extra object
-to determine what to do.
-
-@cindex apply hook (defn)
-@cindex entity (defn)
-There are two kinds of application hooks, which differ in what arguments
-are passed to the procedure. When an @dfn{apply hook} is applied, the
-procedure is passed exactly the same arguments that were passed to the
-apply hook. When an @dfn{entity} is applied, the entity itself is
-passed as the first argument, followed by the other arguments that were
-passed to the entity.
-
-Both apply hooks and entities satisfy the predicate @code{procedure?}.
-Each satisfies either @code{compiled-procedure?},
-@code{compound-procedure?}, or @code{primitive-procedure?}, depending on
-its procedure component. An apply hook is considered to accept the same
-number of arguments as its procedure, while an entity is considered to
-accept one less argument than its procedure.
-
-@deffn procedure make-apply-hook procedure object
-Returns a newly allocated apply hook with a procedure component of
-@var{procedure} and an extra component of @var{object}.
-@end deffn
-
-@deffn procedure apply-hook? object
-@cindex type predicate, for apply hook
-Returns @code{#t} if @var{object} is an apply hook; otherwise returns
-@code{#f}.
-@end deffn
-
-@deffn procedure apply-hook-procedure apply-hook
-Returns the procedure component of @var{apply-hook}.
-@end deffn
-
-@deffn procedure set-apply-hook-procedure! apply-hook procedure
-Changes the procedure component of @var{apply-hook} to be
-@var{procedure}. Returns an unspecified value.
-@end deffn
-
-@deffn procedure apply-hook-extra apply-hook
-Returns the extra component of @var{apply-hook}.
-@end deffn
-
-@deffn procedure set-apply-hook-extra! apply-hook object
-Changes the extra component of @var{apply-hook} to be @var{object}.
-Returns an unspecified value.
-@end deffn
-
-@deffn procedure make-entity procedure object
-Returns a newly allocated entity with a procedure component of
-@var{procedure} and an extra component of @var{object}.
-@end deffn
-
-@deffn procedure entity? object
-@cindex type predicate, for entity
-Returns @code{#t} if @var{object} is an entity; otherwise returns
-@code{#f}.
-@end deffn
-
-@deffn procedure entity-procedure entity
-Returns the procedure component of @var{entity}.
-@end deffn
-
-@deffn procedure set-entity-procedure! entity procedure
-Changes the procedure component of @var{entity} to be @var{procedure}.
-Returns an unspecified value.
-@end deffn
-
-@deffn procedure entity-extra entity
-Returns the extra component of @var{entity}.
-@end deffn
-
-@deffn procedure set-entity-extra! entity object
-Changes the extra component of @var{entity} to be @var{object}. Returns
-an unspecified value.
-@end deffn
-
-@node Environments, Input/Output, Procedures, Top
-@chapter Environments
-
-@menu
-* Environment Operations::
-* Environment Variables::
-* REPL Environment::
-* Top-level Environments::
-@end menu
-
-@node Environment Operations, Environment Variables, Environments, Environments
-@section Environment Operations
-
-Environments are first-class objects in MIT/GNU Scheme. An environment
-consists of some bindings and possibly a parent environment, from which
-other bindings are inherited. The operations in this section reveal the
-frame-like structure of environments by permitting you to examine the
-bindings of a particular environment separately from those of its
-parent.
-
-@cindex variable binding
-@cindex binding, variable
-@cindex unassigned binding
-@cindex binding, unassigned
-@findex condition-type:unassigned-variable
-There are several types of bindings that can occur in an environment.
-The most common is the simple variable binding, which associates a value
-(any Scheme object) with an identifier (a symbol). A variable binding
-can also be @dfn{unassigned}, which means that it has no value. An
-unassigned variable is bound, in that is will shadow other bindings of
-the same name in ancestor environments, but a reference to that variable
-will signal an error of type @code{condition-type:unassigned-variable}.
-An unassigned variable can be @dfn{assigned} (using @code{set!} or
-@code{environment-assign!}) to give it a value.
-
-@cindex keyword binding
-@cindex syntactic keyword binding
-@cindex binding, syntactic keyword
-@findex condition-type:macro-binding
-In addition to variable bindings, an environment can also have
-@dfn{keyword bindings}. A keyword binding associates a syntactic
-keyword (usually a macro transformer) with an identifier. Keyword
-bindings are special in that they are considered ``bound'', but ordinary
-variable references don't work on them. So an attempt to reference or
-assign a keyword binding results in an error of type
-@code{condition-type:macro-binding}. However, keyword bindings can be
-redefined using @code{define} or @code{environment-define}.
-
-@deffn procedure environment? object
-@cindex type predicate, for environment
-Returns @code{#t} if @var{object} is an environment; otherwise returns
-@code{#f}.
-@end deffn
-
-@deffn procedure environment-has-parent? environment
-Returns @code{#t} if @var{environment} has a parent environment;
-otherwise returns @code{#f}.
-@end deffn
-
-@deffn procedure environment-parent environment
-Returns the parent environment of @var{environment}. It is an error if
-@var{environment} has no parent.
-@end deffn
-
-@deffn procedure environment-bound-names environment
-Returns a newly allocated list of the names (symbols) that are bound by
-@var{environment}. This does not include the names that are bound by
-the parent environment of @var{environment}. It does include names that
-are unassigned or keywords in @var{environment}.
-@end deffn
-
-@deffn procedure environment-macro-names environment
-Returns a newly allocated list of the names (symbols) that are bound to
-syntactic keywords in @var{environment}.
-@end deffn
-
-@deffn procedure environment-bindings environment
-Returns a newly allocated list of the bindings of @var{environment};
-does not include the bindings of the parent environment. Each element
-of this list takes one of two forms: @code{(@var{symbol})} indicates
-that @var{symbol} is bound but unassigned, while @code{(@var{symbol}
-@var{object})} indicates that @var{symbol} is bound, and its value is
-@var{object}.
-@end deffn
-
-@deffn procedure environment-reference-type environment symbol
-Returns a symbol describing the @dfn{reference type} of @var{symbol} in
-@var{environment} or one of its ancestor environments. The result is
-one of the following:
-
-@table @code
-@item normal
-means @var{symbol} is a variable binding with a normal value.
-
-@item unassigned
-means @var{symbol} is a variable binding with no value.
-
-@item macro
-means @var{symbol} is a keyword binding.
-
-@item unbound
-means @var{symbol} has no associated binding.
-@end table
-@end deffn
-
-@deffn procedure environment-bound? environment symbol
-Returns @code{#t} if @var{symbol} is bound in @var{environment} or one
-of its ancestor environments; otherwise returns @code{#f}. This is
-equivalent to
-
-@example
-(not (eq? 'unbound
- (environment-reference-type @var{environment} @var{symbol})))
-@end example
-@end deffn
-
-@deffn procedure environment-assigned? environment symbol
-Returns @code{#t} if @var{symbol} is bound in @var{environment} or one
-of its ancestor environments, and has a normal value. Returns @code{#f}
-if it is bound but unassigned. Signals an error if it is unbound or is
-bound to a keyword.
-@end deffn
-
-@deffn procedure environment-lookup environment symbol
-@var{Symbol} must be bound to a normal value in @var{environment} or one
-of its ancestor environments. Returns the value to which it is bound.
-Signals an error if unbound, unassigned, or a keyword.
-@end deffn
-
-@deffn procedure environment-lookup-macro environment symbol
-If @var{symbol} is a keyword binding in @var{environment} or one of its
-ancestor environments, returns the value of the binding. Otherwise,
-returns @code{#f}. Does not signal any errors other than argument-type
-errors.
-@end deffn
-
-@deffn procedure environment-assignable? environment symbol
-@var{Symbol} must be bound in @var{environment} or one of its ancestor
-environments. Returns @code{#t} if the binding may be modified by side
-effect.
-@end deffn
-
-@deffn procedure environment-assign! environment symbol object
-@var{Symbol} must be bound in @var{environment} or one of its ancestor
-environments, and must be assignable. Modifies the binding to have
-@var{object} as its value, and returns an unspecified result.
-@end deffn
-
-@deffn procedure environment-definable? environment symbol
-Returns @code{#t} if @var{symbol} is definable in @var{environment}, and
-@code{#f} otherwise. At present, this is false for environments
-generated by application of compiled procedures, and true for all other
-environments.
-@end deffn
-
-@deffn procedure environment-define environment symbol object
-Defines @var{symbol} to be bound to @var{object} in @var{environment},
-and returns an unspecified value. Signals an error if @var{symbol}
-isn't definable in @var{environment}.
-@end deffn
-
-@deffn procedure environment-define-macro environment symbol transformer
-Defines @var{symbol} to be a keyword bound to @var{transformer} in
-@var{environment}, and returns an unspecified value. Signals an error
-if @var{symbol} isn't definable in @var{environment}. The type of
-@var{transformer} is defined by the syntax engine and is not checked by
-this procedure. If the type is incorrect this will subsequently signal
-an error during syntax expansion.
-@end deffn
-
-@deffn procedure eval expression environment
-@cindex s-expression
-@cindex evaluation, of s-expression
-Evaluates @var{expression}, a list-structure representation (sometimes
-called s-expression representation) of a Scheme expression, in
-@var{environment}. You rarely need @code{eval} in ordinary programs; it
-is useful mostly for evaluating expressions that have been created ``on
-the fly'' by a program. @code{eval} is relatively expensive because it
-must convert @var{expression} to an internal form before it is executed.
-
-@example
-@group
-(define foo (list '+ 1 2))
-(eval foo (the-environment)) @result{} 3
-@end group
-@end example
-@end deffn
-
-@node Environment Variables, REPL Environment, Environment Operations, Environments
-@section Environment Variables
-
-@findex define
-The @code{user-initial-environment} is where the top-level
-read-eval-print (@acronym{REP}) loop evaluates expressions and binds
-definitions. It is a child of @code{system-global-environment}, which
-is where all of the Scheme system definitions are bound. All of the
-bindings in @code{system-global-environment} are available when the
-current environment is @code{user-initial-environment}. However, any
-new bindings that you create in the @acronym{REP} loop (with
-@code{define} forms or by loading files containing @code{define} forms)
-occur in @code{user-initial-environment}.
-
-@defvr variable system-global-environment
-The variable @code{system-global-environment} is bound to the
-distinguished environment that's the ancestor of most other environments
-(except for those created by @code{make-root-top-level-environment}).
-It is the parent environment of @code{user-initial-environment}.
-Primitives, system procedures, and most syntactic keywords are bound
-(and sometimes closed) in this environment.
-@end defvr
-
-@defvr variable user-initial-environment
-The variable @code{user-initial-environment} is bound to the default
-environment in which typed expressions are evaluated by the top-level
-@acronym{REP} loop.
-
-Although all bindings in @code{system-global-environment} are visible to
-the @acronym{REP} loop, definitions that are typed at, or loaded by, the
-@acronym{REP} loop occur in the @code{user-initial-environment}. This
-is partly a safety measure: if you enter a definition that happens to
-have the same name as a critical system procedure, your definition will
-be visible only to the procedures you define in the
-@code{user-initial-environment}; the MIT/GNU Scheme system procedures, which
-are defined in @code{system-global-environment}, will continue to see
-the original definition.
-@end defvr
-
-@node REPL Environment, Top-level Environments, Environment Variables, Environments
-@section REPL Environment
-
-@deffn procedure nearest-repl/environment
-@findex user-initial-environment
-Returns the current @acronym{REP} loop environment (i.e.@: the current
-environment of the closest enclosing @acronym{REP} loop). When Scheme
-first starts up, this is the same as @code{user-initial-environment}.
-@end deffn
-
-@deffn procedure ge environment
-Changes the current @acronym{REP} loop environment to @var{environment}.
-@var{Environment} can be either an environment or a procedure object.
-If it's a procedure, the environment in which that procedure was closed
-is the new environment.
-@end deffn
-
-@node Top-level Environments, , REPL Environment, Environments
-@section Top-level Environments
-
-@cindex top-level environment
-@cindex interpreter environment
-@cindex environment, top-level
-@cindex environment, interpreter
-The operations in this section manipulate @dfn{top-level environments},
-as opposed to environments created by the application of procedures.
-For historical reasons, top-level environments are referred to as
-@dfn{interpreter environments}.
-
-@deffn {special form} the-environment
-@cindex current environment
-@cindex environment, current
-Returns the current environment. This form may only be evaluated in a
-top-level environment. An error is signalled if it appears elsewhere.
-@end deffn
-
-@deffn procedure top-level-environment? object
-@deffnx procedure interpreter-environment? object
-@cindex type predicate, for top-level environment
-Returns @code{#t} if @var{object} is an top-level environment; otherwise
-returns @code{#f}.
-
-@code{interpreter-environment?} is an alias for
-@code{top-level-environment?}.
-@end deffn
-
-@deffn procedure extend-top-level-environment environment [names [values]]
-@deffnx procedure make-root-top-level-environment [names [values]]
-Returns a newly allocated top-level environment.
-@code{extend-top-level-environment} creates an environment that has
-parent @var{environment}, while @code{make-root-top-level-environment}
-creates an environment that has no parent.
-
-The optional arguments @var{names} and @var{values} are used to specify
-initial bindings in the new environment. If specified, @var{names} must
-be a list of symbols, and @var{values} must be a list of objects. If
-only @var{names} is specified, each name in @var{names} will be bound in
-the environment, but unassigned. If @var{names} and @var{values} are
-both specified, they must be the same length, and each name in
-@var{names} will be bound to the corresponding value in @var{values}.
-If neither @var{names} nor @var{values} is specified, the environment
-will have no initial bindings.
-@end deffn
-
-@deffn procedure link-variables environment1 symbol1 environment2 symbol2
-Defines @var{symbol1} in @var{environment1} to have the same binding as
-@var{symbol2} in @var{environment2}, and returns an unspecified value.
-Prior to the call, @var{symbol2} must be bound in @var{environment2},
-but the type of binding is irrelevant; it may be a normal binding, an
-unassigned binding, or a keyword binding. Signals an error if
-@var{symbol1} isn't definable in @var{environment1}, or if @var{symbol2}
-is unbound in @var{environment2}.
-
-By ``the same binding'', we mean that the value cell is shared between
-the two environments. If a value is assigned to @var{symbol1} in
-@var{environment1}, a subsequent reference to @var{symbol2} in
-@var{environment2} will see that value, and vice versa.
-@end deffn
-
-@deffn procedure unbind-variable environment symbol
-If @var{symbol} is bound in @var{environment} or one of its ancestor
-environments, removes the binding, so that subsequent accesses to that
-symbol behave as if the binding never existed. Returns @code{#t} if there
-was a binding prior to the call, and @code{#f} if there wasn't.
-@end deffn
-
-@node Input/Output, Operating-System Interface, Environments, Top
-@chapter Input/Output
-
-@cindex input
-@cindex output
-@cindex port
-This chapter describes the procedures that are used for input and
-output (@acronym{I/O}). The chapter first describes @dfn{ports} and
-how they are manipulated, then describes the @acronym{I/O} operations.
-Finally, some low-level procedures are described that permit the
-implementation of custom ports and high-performance @acronym{I/O}.
-
-@menu
-* Ports::
-* File Ports::
-* String Ports::
-* Input Procedures::
-* Output Procedures::
-* Format::
-* Custom Output::
-* Prompting::
-* Port Primitives::
-* Parser Buffers::
-* Parser Language::
-* XML Parser::
-@end menu
-
-@node Ports, File Ports, Input/Output, Input/Output
-@section Ports
-
-@cindex port (defn)
-@findex console-i/o-port
-Scheme uses ports for @acronym{I/O}. A @dfn{port}, which can be
-treated like any other Scheme object, serves as a source or sink for
-data. A port must be open before it can be read from or written to.
-The standard @acronym{I/O} port, @code{console-i/o-port}, is opened
-automatically when you start Scheme. When you use a file for input or
-output, you need to explicitly open and close a port to the file (with
-procedures described in this chapter). Additional procedures let you
-open ports to strings.
-
-@cindex current input port (defn)
-@cindex input port, current (defn)
-@cindex port, current
-@findex read-char
-@findex read
-Many input procedures, such as @code{read-char} and @code{read}, read
-data from the current input port by default, or from a port that you
-specify. The current input port is initially @code{console-i/o-port},
-but Scheme provides procedures that let you change the current input
-port to be a file or string.
-
-@cindex current output port (defn)
-@cindex output port, current (defn)
-@findex write-char
-@findex display
-Similarly, many output procedures, such as @code{write-char} and
-@code{display}, write data to the current output port by default, or to
-a port that you specify. The current output port is initially
-@code{console-i/o-port}, but Scheme provides procedures that let you
-change the current output port to be a file or string.
-
-All ports read or write only @acronym{ISO-8859-1} characters.
-
-Every port is either an input port, an output port, or both. The
-following predicates distinguish all of the possible cases.
-
-@deffn procedure port? object
-@cindex type predicate, for port
-Returns @code{#t} if @var{object} is a port, otherwise returns
-@code{#f}.
-@end deffn
-
-@deffn procedure input-port? object
-Returns @code{#t} if @var{object} is an input port, otherwise returns
-@code{#f}. Any object satisfying this predicate also satisfies
-@code{port?}.
-@end deffn
-
-@deffn procedure output-port? object
-Returns @code{#t} if @var{object} is an output port, otherwise returns
-@code{#f}. Any object satisfying this predicate also satisfies
-@code{port?}.
-@end deffn
-
-@deffn procedure i/o-port? object
-Returns @code{#t} if @var{object} is both an input port and an output
-port, otherwise returns @code{#f}. Any object satisfying this predicate
-also satisfies @code{port?}, @code{input-port?}, and
-@code{output-port?}.
-@end deffn
-
-@deffn procedure guarantee-port object
-@deffnx procedure guarantee-input-port object
-@deffnx procedure guarantee-output-port object
-@deffnx procedure guarantee-i/o-port object
-These procedures check the type of @var{object}, signalling an error
-of type@* @code{condition-type:wrong-type-argument} if it is not a
-port, input port, output port, or @acronym{I/O} port, respectively.
-Otherwise they return @var{object}.
-@findex condition-type:wrong-type-argument
-@end deffn
-
-@cindex standard ports
-The next five procedures return the runtime system's @dfn{standard
-ports}. All of the standard ports are dynamically bound by the
-@acronym{REP} loop; this means that when a new @acronym{REP} loop is
-started, for example by an error, each of these ports is dynamically
-bound to the @acronym{I/O} port of the @acronym{REP} loop. When the
-@acronym{REP} loop exits, the ports revert to their original values.
-
-@deffn procedure current-input-port
-@findex console-input-port
-Returns the current input port. This is the default port used by many
-input procedures. Initially, @code{current-input-port} returns the
-value of @code{console-i/o-port}.
-@end deffn
-
-@deffn procedure current-output-port
-@findex console-output-port
-Returns the current output port. This is the default port used by many
-output procedures. Initially, @code{current-output-port} returns the
-value of @code{console-i/o-port}.
-@end deffn
-
-@deffn procedure notification-output-port
-Returns an output port suitable for generating ``notifications'', that
-is, messages to the user that supply interesting information about the
-execution of a program. For example, the @code{load} procedure writes
-messages to this port informing the user that a file is being loaded.
-Initially, @code{notification-output-port} returns the value of
-@code{console-i/o-port}.
-@end deffn
-
-@deffn procedure trace-output-port
-Returns an output port suitable for generating ``tracing'' information
-about a program's execution. The output generated by the @code{trace}
-procedure is sent to this port. Initially, @code{trace-output-port}
-returns the value of @code{console-i/o-port}.
-@end deffn
-
-@deffn procedure interaction-i/o-port
-Returns an @acronym{I/O} port suitable for querying or prompting the
-user. The standard prompting procedures use this port by default
-(@pxref{Prompting}). Initially, @code{interaction-i/o-port} returns
-the value of @code{console-i/o-port}.
-@end deffn
-
-@deffn procedure with-input-from-port input-port thunk
-@deffnx procedure with-output-to-port output-port thunk
-@deffnx procedure with-notification-output-port output-port thunk
-@deffnx procedure with-trace-output-port output-port thunk
-@deffnx procedure with-interaction-i/o-port i/o-port thunk
-@var{Thunk} must be a procedure of no arguments. Each of these
-procedures binds one of the standard ports to its first argument, calls
-@var{thunk} with no arguments, restores the port to its original value,
-and returns the result that was yielded by @var{thunk}. This temporary
-binding is performed the same way as dynamic binding of a variable,
-including the behavior in the presence of continuations (@pxref{Dynamic
-Binding}).
-
-@code{with-input-from-port} binds the current input port,
-@code{with-output-to-port} binds the current output port,
-@code{with-notification-output-port} binds the ``notification'' output
-port, @code{with-trace-output-port} binds the ``trace'' output port,
-and @code{with-interaction-i/o-port} binds the ``interaction''
-@acronym{I/O} port.
-@end deffn
-
-@deffn procedure set-current-input-port! input-port
-@deffnx procedure set-current-output-port! output-port
-@deffnx procedure set-notification-output-port! output-port
-@deffnx procedure set-trace-output-port! output-port
-@deffnx procedure set-interaction-i/o-port! i/o-port
-Each of these procedures alters the binding of one of the standard ports
-and returns an unspecified value. The binding that is modified
-corresponds to the name of the procedure.
-@end deffn
-
-@defvr variable console-i/o-port
-@cindex port, console
-@cindex console, port
-@cindex input port, console
-@cindex output port, console
-@code{console-i/o-port} is an @acronym{I/O} port that communicates
-with the ``console''. Under unix, the console is the controlling
-terminal of the Scheme process. Under Windows and OS/2, the console
-is the window that is created when Scheme starts up.
-
-This variable is rarely used; instead programs should use one of the
-standard ports defined above. This variable should not be modified.
-@end defvr
-
-@deffn procedure close-port port
-@cindex closing, of port
-Closes @var{port} and returns an unspecified value. If @var{port} is a
-file port, the file is closed.
-@end deffn
-
-@deffn procedure close-input-port port
-Closes @var{port} and returns an unspecified value. @var{Port} must
-be an input port or an @acronym{I/O} port; if it is an @acronym{I/O}
-port, then only the input side of the port is closed.
-@end deffn
-
-@deffn procedure close-output-port port
-Closes @var{port} and returns an unspecified value. @var{Port} must
-be an output port or an @acronym{I/O} port; if it is an @acronym{I/O}
-port, then only the output side of the port is closed.
-@end deffn
-
-@node File Ports, String Ports, Ports, Input/Output
-@section File Ports
-
-@cindex file, input and output ports
-@cindex port, file
-@cindex input port, file
-@cindex output port, file
-@cindex I/O, to files
-Before Scheme can access a file for reading or writing, it is necessary
-to open a port to the file. This section describes procedures used to
-open ports to files. Such ports are closed (like any other port) by
-@code{close-port}. File ports are automatically closed if and when they
-are reclaimed by the garbage collector.
-
-@findex merge-pathnames
-Before opening a file for input or output, by whatever method, the
-@var{filename} argument is converted to canonical form by calling the
-procedure @code{merge-pathnames} with @var{filename} as its sole
-argument. Thus, @var{filename} can be either a string or a pathname,
-and it is merged with the current pathname defaults to produce the
-pathname that is then opened.
-
-@cindex binary file ports
-@cindex newline translation
-Any file can be opened in one of two modes, @dfn{normal} or
-@dfn{binary}. Normal mode is for accessing text files, and binary mode
-is for accessing other files. Unix does not distinguish these modes,
-but Windows and OS/2 do: in normal mode, their file ports perform
-@dfn{newline translation}, mapping between the carriage-return/linefeed
-sequence that terminates text lines in files, and the @code{#\newline}
-that terminates lines in Scheme. In binary mode, such ports do not
-perform newline translation. Unless otherwise mentioned, the procedures
-in this section open files in normal mode.
-
-@deffn procedure open-input-file filename
-@cindex construction, of file input port
-Takes a filename referring to an existing file and returns an input port
-capable of delivering characters from the file. If the file cannot be
-opened, an error of type @code{condition-type:file-operation-error} is
-signalled.
-@findex condition-type:file-operation-error
-@end deffn
-
-@deffn procedure open-output-file filename [append?]
-@cindex construction, of file output port
-Takes a filename referring to an output file to be created and returns
-an output port capable of writing characters to a new file by that name.
-If the file cannot be opened, an error of type
-@code{condition-type:file-operation-error} is signalled.
-@findex condition-type:file-operation-error
-
-@cindex appending, to output file
-The optional argument @var{append?} is an MIT/GNU Scheme extension. If
-@var{append?} is given and not @code{#f}, the file is opened in
-@dfn{append} mode. In this mode, the contents of the file are not
-overwritten; instead any characters written to the file are appended to
-the end of the existing contents. If the file does not exist, append
-mode creates the file and writes to it in the normal way.
-@end deffn
-
-@deffn procedure open-i/o-file filename
-@cindex construction, of file input port
-Takes a filename referring to an existing file and returns an
-@acronym{I/O} port capable of both reading and writing the file. If
-the file cannot be opened, an error of type
-@code{condition-type:file-operation-error} is signalled.
-@findex condition-type:file-operation-error
-
-This procedure is often used to open special files. For example, under
-unix this procedure can be used to open terminal device files, @sc{pty}
-device files, and named pipes.
-@end deffn
-
-@deffn procedure open-binary-input-file filename
-@deffnx procedure open-binary-output-file filename [append?]
-@deffnx procedure open-binary-i/o-file filename
-These procedures open files in binary mode. In all other respects they
-are identical to @code{open-input-file}, @code{open-output-file}, and
-@code{open-i/o-file}, respectively.
-@end deffn
-
-@deffn procedure close-all-open-files
-@cindex closing, of file port
-This procedure closes all file ports that are open at the time that it
-is called, and returns an unspecified value.
-@end deffn
-
-@deffn procedure call-with-input-file filename procedure
-@deffnx procedure call-with-output-file filename procedure
-These procedures call @var{procedure} with one argument: the port
-obtained by opening the named file for input or output, respectively.
-If the file cannot be opened, an error of type
-@code{condition-type:file-operation-error} is signalled. If
-@var{procedure} returns, then the port is closed automatically and the
-value yielded by @var{procedure} is returned. If @var{procedure} does
-not return, then the port will not be closed automatically unless it is
-reclaimed by the garbage collector.@footnote{Because Scheme's escape
-procedures have unlimited extent, it is possible to escape from the
-current continuation but later to escape back in. If implementations
-were permitted to close the port on any escape from the current
-continuation, then it would be impossible to write portable code using
-both @code{call-with-current-continuation} and
-@code{call-with-input-file} or @code{call-with-output-file}.}
-@end deffn
-
-@deffn procedure call-with-binary-input-file filename procedure
-@deffnx procedure call-with-binary-output-file filename procedure
-These procedures open files in binary mode. In all other respects they
-are identical to @code{call-with-input-file} and
-@code{call-with-output-file}, respectively.
-@end deffn
-
-@deffn procedure with-input-from-file filename thunk
-@deffnx procedure with-output-to-file filename thunk
-@cindex current input port, rebinding
-@cindex current output port, rebinding
-@findex current-input-port
-@findex current-output-port
-@var{Thunk} must be a procedure of no arguments.
-The file is opened for input or output, an input or output port
-connected to it is made the default value returned by
-@code{current-input-port} or @code{current-output-port}, and the
-@var{thunk} is called with no arguments. When the @var{thunk} returns,
-the port is closed and the previous default is restored.
-@code{with-input-from-file} and @code{with-output-to-file} return the
-value yielded by @var{thunk}. If an escape procedure is used to escape
-from the continuation of these procedures, their behavior is
-implementation-dependent; in that situation MIT/GNU Scheme leaves the files
-open.
-@end deffn
-
-@deffn procedure with-input-from-binary-file filename thunk
-@deffnx procedure with-output-to-binary-file filename thunk
-These procedures open files in binary mode. In all other respects they
-are identical to @code{with-input-from-file} and
-@code{with-output-to-file}, respectively.
-@end deffn
-
-@node String Ports, Input Procedures, File Ports, Input/Output
-@section String Ports
-
-@cindex string, input and output ports
-@cindex port, string
-@cindex input port, string
-@cindex output port, string
-@cindex I/O, to strings
-This section describes the simplest kinds of ports: input ports that
-read their input from given strings, and output ports that accumulate
-their output and return it as a string. It also describes
-``truncating'' output ports, which can limit the length of the resulting
-string to a given value.
-
-@deffn procedure string->input-port string [start [end]]
-@cindex string, converting to input port
-@cindex construction, of string input port
-Returns a new string port that delivers characters from @var{string}.
-The optional arguments @var{start} and @var{end} may be used to specify
-that the string port delivers characters from a substring of
-@var{string}; if not given, @var{start} defaults to @code{0} and
-@var{end} defaults to @code{(string-length @var{string})}.
-@end deffn
-
-@deffn procedure with-input-from-string string thunk
-@cindex current input port, rebinding
-@var{Thunk} must be a procedure of no arguments.
-@code{with-input-from-string} creates a new input port that reads from
-@var{string}, makes that port the current input port, and calls
-@var{thunk}. When @var{thunk} returns, @code{with-input-from-string}
-restores the previous current input port and returns the result yielded
-by @var{thunk}.
-
-@example
-(with-input-from-string "(a b c) (d e f)" read) @result{} (a b c)
-@end example
-
-Note: this procedure is equivalent to:
-
-@example
-(with-input-from-port (string->input-port @var{string}) @var{thunk})
-@end example
-@end deffn
-
-@deffn procedure with-string-output-port procedure
-@var{Procedure} is called with one argument, an output port. The value
-yielded by @var{procedure} is ignored. When @var{procedure} returns,
-@code{with-string-output-port} returns the port's accumulated output as
-a newly allocated string.
-@end deffn
-
-@deffn procedure with-output-to-string thunk
-@cindex current output port, rebinding
-@cindex construction, of string output port
-@findex current-output-port
-@var{Thunk} must be a procedure of no arguments.
-@code{with-output-to-string} creates a new output port that accumulates
-output, makes that port the default value returned by
-@code{current-output-port}, and calls @var{thunk} with no arguments.
-When @var{thunk} returns, @code{with-output-to-string} restores the
-previous default and returns the accumulated output as a newly allocated
-string.
-
-@example
-@group
-(with-output-to-string
- (lambda ()
- (write 'abc))) @result{} "abc"
-@end group
-@end example
-
-Note: this procedure is equivalent to:
-
-@example
-@group
-(with-string-output-port
- (lambda (port)
- (with-output-to-port port @var{thunk})))
-@end group
-@end example
-@end deffn
-
-@deffn procedure with-output-to-truncated-string k thunk
-Similar to @code{with-output-to-string}, except that the output is
-limited to @var{k} characters. If @var{thunk} attempts to write more
-than @var{k} characters, it will be aborted by invoking an escape
-procedure that returns from @code{with-output-to-truncated-string}.
-
-The value of this procedure is a pair; the car of the pair is @code{#t}
-if @var{thunk} attempted to write more than @var{k} characters, and
-@code{#f} otherwise. The cdr of the pair is a newly allocated string
-containing the accumulated output.
-
-This procedure is helpful for displaying circular lists, as shown in this
-example:
-
-@example
-@group
-(define inf (list 'inf))
-(with-output-to-truncated-string 40
- (lambda ()
- (write inf))) @result{} (#f . "(inf)")
-(set-cdr! inf inf)
-(with-output-to-truncated-string 40
- (lambda ()
- (write inf)))
- @result{} (#t . "(inf inf inf inf inf inf inf inf inf inf")
-@end group
-@end example
-@end deffn
-
-@deffn procedure write-to-string object [k]
-Writes @var{object} to a string output port, and returns the resulting
-newly allocated string. If @var{k} is supplied and not @code{#f}, this
-procedure is equivalent to
-
-@example
-@group
-(with-output-to-truncated-string @var{k}
- (lambda ()
- (write @var{object})))
-@end group
-@end example
-
-otherwise it is equivalent to
-
-@example
-@group
-(with-output-to-string
- (lambda ()
- (write @var{object})))
-@end group
-@end example
-@end deffn
-
-@node Input Procedures, Output Procedures, String Ports, Input/Output
-@section Input Procedures
-@cindex input operations
-
-This section describes the procedures that read input. Input procedures
-can read either from the current input port or from a given port.
-Remember that to read from a file, you must first open a port to the
-file.
-
-@cindex interactive input ports (defn)
-Input ports can be divided into two types, called @dfn{interactive} and
-@dfn{non-interactive}. Interactive input ports are ports that read
-input from a source that is time-dependent; for example, a port that
-reads input from a terminal or from another program. Non-interactive
-input ports read input from a time-independent source, such as an
-ordinary file or a character string.
-
-All optional arguments called @var{input-port}, if not supplied, default
-to the current input port.
-
-@deffn procedure read-char [input-port]
-@cindex character, input from port
-Returns the next character available from @var{input-port}, updating
-@var{input-port} to point to the following character. If no more
-characters are available, an end-of-file object is returned.
-
-In MIT/GNU Scheme, if @var{input-port} is an interactive input port and no
-characters are immediately available, @code{read-char} will hang waiting
-for input, even if the port is in non-blocking mode.
-@end deffn
-
-@deffn procedure peek-char [input-port]
-Returns the next character available from @var{input-port},
-@emph{without} updating @var{input-port} to point to the following
-character. If no more characters are available, an end-of-file object
-is returned.@footnote{The value returned by a call to @code{peek-char}
-is the same as the value that would have been returned by a call to
-@code{read-char} on the same port. The only difference is that the very
-next call to @code{read-char} or @code{peek-char} on that
-@var{input-port} will return the value returned by the preceding call to
-@code{peek-char}. In particular, a call to @code{peek-char} on an
-interactive port will hang waiting for input whenever a call to
-@code{read-char} would have hung.}
-
-In MIT/GNU Scheme, if @var{input-port} is an interactive input port and no
-characters are immediately available, @code{peek-char} will hang waiting
-for input, even if the port is in non-blocking mode.
-@end deffn
-
-@deffn procedure char-ready? [input-port]
-@findex read-char
-Returns @code{#t} if a character is ready on @var{input-port} and
-returns @code{#f} otherwise. If @code{char-ready?} returns @code{#t}
-then the next @code{read-char} operation on @var{input-port} is
-guaranteed not to hang. If @var{input-port} is a file port at end of
-file then @code{char-ready?} returns
-@code{#t}.@footnote{@code{char-ready?} exists to make it possible for a
-program to accept characters from interactive ports without getting
-stuck waiting for input. Any input editors associated with such ports
-must make sure that characters whose existence has been asserted by
-@code{char-ready?} cannot be rubbed out. If @code{char-ready?} were to
-return @code{#f} at end of file, a port at end of file would be
-indistinguishable from an interactive port that has no ready
-characters.}
-@end deffn
-
-@deffn procedure read [input-port]
-@cindex expression, input from port
-@cindex external representation, parsing
-@cindex parsing, of external representation
-Converts external representations of Scheme objects into the objects
-themselves. @code{read} returns the next object parsable from
-@var{input-port}, updating @var{input-port} to point to the first
-character past the end of the written representation of the object. If
-an end of file is encountered in the input before any characters are
-found that can begin an object, @code{read} returns an end-of-file
-object. The @var{input-port} remains open, and further attempts to read
-will also return an end-of-file object. If an end of file is
-encountered after the beginning of an object's written representation,
-but the written representation is incomplete and therefore not parsable,
-an error is signalled.
-@end deffn
-
-@deffn procedure eof-object? object
-@cindex type predicate, for EOF object
-@cindex EOF object, predicate for
-@cindex end of file object (see EOF object)
-@cindex file, end-of-file marker (see EOF object)
-Returns @code{#t} if @var{object} is an end-of-file object; otherwise
-returns @code{#f}.
-@end deffn
-
-@deffn procedure read-char-no-hang [input-port]
-If @var{input-port} can deliver a character without blocking, this
-procedure acts exactly like @code{read-char}, immediately returning that
-character. Otherwise, @code{#f} is returned, unless @var{input-port} is
-a file port at end of file, in which case an end-of-file object is
-returned. In no case will this procedure block waiting for input.
-@end deffn
-
-@deffn procedure read-string char-set [input-port]
-@cindex string, input from port
-Reads characters from @var{input-port} until it finds a terminating
-character that is a member of @var{char-set} (@pxref{Character Sets}) or
-encounters end of file. The port is updated to point to the terminating
-character, or to end of file if no terminating character was found.
-@code{read-string} returns the characters, up to but excluding the
-terminating character, as a newly allocated string.
-
-This procedure ignores the blocking mode of the port, blocking
-unconditionally until it sees either a delimiter or eof of file. If end
-of file is encountered before any characters are read, an end-of-file
-object is returned.
-
-@findex read-char
-On many input ports, this operation is significantly faster than the
-following equivalent code using @code{peek-char} and @code{read-char}:
-
-@example
-@group
-(define (read-string char-set input-port)
- (let ((char (peek-char input-port)))
- (if (eof-object? char)
- char
- (list->string
- (let loop ((char char))
- (if (or (eof-object? char)
- (char-set-member? char-set char))
- '()
- (begin
- (read-char input-port)
- (cons char
- (loop (peek-char input-port))))))))))
-@end group
-@end example
-@end deffn
-
-@deffn procedure read-line [input-port]
-@code{read-line} reads a single line of text from @var{input-port}, and
-returns that line as a newly allocated string. The @code{#\newline}
-terminating the line, if any, is discarded and does not appear in the
-returned string.
-
-This procedure ignores the blocking mode of the port, blocking
-unconditionally until it has read an entire line. If end of file is
-encountered before any characters are read, an end-of-file object is
-returned.
-@end deffn
-
-@deffn procedure read-string! string [input-port]
-@deffnx procedure read-substring! string start end [input-port]
-@code{read-string!} and @code{read-substring!} fill the specified region
-of @var{string} with characters read from @var{input-port} until the
-region is full or else there are no more characters available from the
-port. For @code{read-string!}, the region is all of @var{string}, and
-for @code{read-substring!}, the region is that part of @var{string}
-specified by @var{start} and @var{end}.
-
-The returned value is the number of characters filled into the region.
-However, there are several interesting cases to consider:
-
-@itemize @bullet
-@item
-If @code{read-string!} (@code{read-substring!}) is called when
-@var{input-port} is at ``end-of-file'', then the returned value is
-@code{0}. Note that ``end-of-file'' can mean a file port that is at the
-file's end, a string port that is at the string's end, or any other port
-that will never produce more characters.
-
-@item
-If @var{input-port} is an interactive port (e.g.@: a terminal), and one
-or more characters are immediately available, the region is filled using
-the available characters. The procedure then returns immediately,
-without waiting for further characters, even if the number of available
-characters is less than the size of the region. The returned value is
-the number of characters actually filled in.
-
-@item
-If @var{input-port} is an interactive port and no characters are
-immediately available, the result of the operation depends on the
-blocking mode of the port. If the port is in non-blocking mode,
-@code{read-string!} (@code{read-substring!}) immediately returns the
-value @code{#f}. Otherwise, the operation blocks until a character is
-available. As soon as at least one character is available, the region
-is filled using the available characters. The procedure then returns
-immediately, without waiting for further characters, even if the number
-of available characters is less than the size of the region. The
-returned value is the number of characters actually filled in.
-@end itemize
-
-The importance of @code{read-string!} and @code{read-substring!} are
-that they are both flexible and extremely fast, especially for large
-amounts of data.
-@end deffn
-
-The following variables may be dynamically bound to change the behavior
-of the @code{read} procedure.
-
-@defvr variable *parser-radix*
-This variable defines the radix used by the reader when it parses
-numbers. This is similar to passing a radix argument to
-@code{string->number}. The value of this variable must be one of
-@code{2}, @code{8}, @code{10}, or @code{16}; any other value is ignored,
-and the reader uses radix @code{10}.
-
-Note that much of the number syntax is invalid for radixes other than
-@code{10}. The reader detects cases where such invalid syntax is used
-and signals an error. However, problems can still occur when
-@code{*parser-radix*} is set to @code{16}, because syntax that normally
-denotes symbols can now denote numbers (e.g.@: @code{abc}). Because of
-this, it is usually undesirable to set this variable to anything other
-than the default.
-
-The default value of this variable is @code{10}.
-@end defvr
-
-@defvr variable *parser-canonicalize-symbols?*
-This variable controls how the parser handles case-sensitivity of
-symbols. If it is bound to its default value of @code{#t}, symbols read
-by the parser are converted to lower case before being interned.
-Otherwise, symbols are interned without case conversion.
-
-In general, it is a bad idea to use this feature, as it doesn't really
-make Scheme case-sensitive, and therefore can break features of the
-Scheme runtime that depend on case-insensitive symbols.
-@end defvr
-
-@node Output Procedures, Format, Input Procedures, Input/Output
-@section Output Procedures
-@cindex output procedures
-
-@cindex buffering, of output
-@cindex flushing, of buffered output
-Output ports may or may not support @dfn{buffering} of output, in which
-output characters are collected together in a buffer and then sent to
-the output device all at once. (Most of the output ports implemented by
-the runtime system support buffering.) Sending all of the characters in
-the buffer to the output device is called @dfn{flushing} the buffer. In
-general, output procedures do not flush the buffer of an output port
-unless the buffer is full.
-
-@cindex discretionary flushing, of buffered output
-@findex discretionary-flush-output
-However, the standard output procedures described in this section
-perform what is called @dfn{discretionary} flushing of the buffer.
-Discretionary output flushing works as follows. After a procedure
-performs its output (writing characters to the output buffer), it checks
-to see if the port implements an operation called
-@code{discretionary-flush-output}. If so, then that operation is
-invoked to flush the buffer. At present, only the console port defines
-@code{discretionary-flush-output}; this is used to guarantee that output
-to the console appears immediately after it is written, without
-requiring calls to @code{flush-output}.
-
-All optional arguments called @var{output-port}, if not supplied,
-default to the current output port.
-
-@deffn procedure write-char char [output-port]
-@cindex character, output to port
-Writes @var{char} (the character itself, not a written representation of
-the character) to @var{output-port}, performs discretionary output
-flushing, and returns an unspecified value.
-@end deffn
-
-@deffn procedure write-string string [output-port]
-@cindex string, output to port
-Writes @var{string} to @var{output-port}, performs discretionary output
-flushing, and returns an unspecified value. This is equivalent to
-writing the contents of @var{string}, one character at a time using
-@code{write-char}, except that it is usually much faster.
-@end deffn
-
-@deffn procedure write-substring string start end [output-port]
-@cindex string, output to port
-Writes the substring defined by @var{string}, @var{start}, and @var{end}
-to @var{output-port}, performs discretionary output flushing, and
-returns an unspecified value. This is equivalent to writing the
-contents of the substring, one character at a time using
-@code{write-char}, except that it is usually much faster.
-@end deffn
-
-@deffn procedure write object [output-port]
-@cindex expression, output to port
-Writes a written representation of @var{object} to @var{output-port},
-and returns an unspecified value. If @var{object} has a standard
-external representation, then the written representation generated by
-@code{write} shall be parsable by @code{read} into an equivalent object.
-Thus strings that appear in the written representation are enclosed in
-doublequotes, and within those strings backslash and doublequote are
-escaped by backslashes. @code{write} performs discretionary output
-flushing and returns an unspecified value.
-@end deffn
-
-@deffn procedure display object [output-port]
-@cindex external representation, generating
-@cindex generating, external representation
-Writes a representation of @var{object} to @var{output-port}. Strings
-appear in the written representation as if written by
-@code{write-string} instead of by @code{write}. Character objects
-appear in the representation as if written by @code{write-char} instead
-of by @code{write}. @code{display} performs discretionary output
-flushing and returns an unspecified value.@footnote{@code{write} is
-intended for producing machine-readable output and @code{display} is for
-producing human-readable output.}
-@end deffn
-
-@deffn procedure newline [output-port]
-@cindex newline character, output to port
-Writes an end-of-line to @var{output-port}, performs discretionary
-output flushing, and returns an unspecified value. Equivalent to
-@code{(write-char #\newline @var{output-port})}.
-@end deffn
-
-@deffn procedure fresh-line [output-port]
-Most output ports are able to tell whether or not they are at the
-beginning of a line of output. If @var{output-port} is such a port,
-this procedure writes an end-of-line to the port only if the port is not
-already at the beginning of a line. If @var{output-port} is not such a
-port, this procedure is identical to @code{newline}. In either case,
-@code{fresh-line} performs discretionary output flushing and returns an
-unspecified value.
-@end deffn
-
-@deffn procedure write-line object [output-port]
-Like @code{write}, except that it writes an end-of-line to
-@var{output-port} after writing @var{object}'s representation. This
-procedure performs discretionary output flushing and returns an
-unspecified value.
-@end deffn
-
-@deffn procedure flush-output [output-port]
-If @var{output-port} is buffered, this causes the contents of its buffer
-to be written to the output device. Otherwise it has no effect.
-Returns an unspecified value.
-@end deffn
-
-@deffn procedure beep [output-port]
-@cindex console, ringing the bell
-@cindex ringing the console bell
-@cindex bell, ringing on console
-Performs a ``beep'' operation on @var{output-port}, performs
-discretionary output flushing, and returns an unspecified value. On the
-console port, this usually causes the console bell to beep, but more
-sophisticated interactive ports may take other actions, such as flashing
-the screen. On most output ports, e.g.@: file and string output ports,
-this does nothing.
-@end deffn
-
-@deffn procedure clear [output-port]
-@cindex console, clearing
-@cindex display, clearing
-@cindex screen, clearing
-@cindex terminal screen, clearing
-@cindex clearing the console screen
-``Clears the screen'' of @var{output-port}, performs discretionary
-output flushing, and returns an unspecified value. On a terminal or
-window, this has a well-defined effect. On other output ports, e.g.@:
-file and string output ports, this does nothing.
-@end deffn
-
-@deffn procedure pp object [output-port [as-code?]]
-@cindex pretty printer
-@code{pp} prints @var{object} in a visually appealing and structurally
-revealing manner on @var{output-port}. If object is a procedure,
-@code{pp} attempts to print the source text. If the optional argument
-@var{as-code?} is true, @code{pp} prints lists as Scheme code, providing
-appropriate indentation; by default this argument is false. @code{pp}
-performs discretionary output flushing and returns an unspecified value.
-@end deffn
-
-The following variables may be dynamically bound to change the behavior
-of the @code{write} and @code{display} procedures.
-
-@defvr variable *unparser-radix*
-This variable specifies the default radix used to print numbers. Its
-value must be one of the exact integers @code{2}, @code{8}, @code{10},
-or @code{16}; the default is @code{10}. If @code{*unparser-radix*} is
-not @code{10}, numbers are prefixed to indicate their radix.
-@end defvr
-
-@defvr variable *unparser-list-breadth-limit*
-This variable specifies a limit on the length of the printed
-representation of a list or vector; for example, if the limit is
-@code{4}, only the first four elements of any list are printed, followed
-by ellipses to indicate any additional elements. The value of this
-variable must be an exact non-negative integer, or @code{#f} meaning no
-limit; the default is @code{#f}.
-
-@example
-@group
-(fluid-let ((*unparser-list-breadth-limit* 4))
- (write-to-string '(a b c d)))
- @result{} "(a b c d)"
-(fluid-let ((*unparser-list-breadth-limit* 4))
- (write-to-string '(a b c d e)))
- @result{} "(a b c d ...)"
-@end group
-@end example
-@end defvr
-
-@defvr variable *unparser-list-depth-limit*
-This variable specifies a limit on the nesting of lists and vectors in
-the printed representation. If lists (or vectors) are more deeply
-nested than the limit, the part of the representation that exceeds the
-limit is replaced by ellipses. The value of this variable must be an
-exact non-negative integer, or @code{#f} meaning no limit; the default
-is @code{#f}.
-
-@example
-@group
-(fluid-let ((*unparser-list-depth-limit* 4))
- (write-to-string '((((a))) b c d)))
- @result{} "((((a))) b c d)"
-(fluid-let ((*unparser-list-depth-limit* 4))
- (write-to-string '(((((a)))) b c d)))
- @result{} "((((...))) b c d)"
-@end group
-@end example
-@end defvr
-
-@defvr variable *unparser-string-length-limit*
-This variable specifies a limit on the length of the printed
-representation of strings. If a string's length exceeds this limit, the
-part of the printed representation for the characters exceeding the
-limit is replaced by ellipses. The value of this variable must be an
-exact non-negative integer, or @code{#f} meaning no limit; the default
-is @code{#f}.
-
-@example
-@group
-(fluid-let ((*unparser-string-length-limit* 4))
- (write-to-string "abcd"))
- @result{} "\"abcd\""
-(fluid-let ((*unparser-string-length-limit* 4))
- (write-to-string "abcde"))
- @result{} "\"abcd...\""
-@end group
-@end example
-@end defvr
-
-@defvr variable *unparse-with-maximum-readability?*
-This variable, which takes a boolean value, tells the printer to use a
-special printed representation for objects that normally print in a form
-that cannot be recognized by @code{read}. These objects are printed
-using the representation @code{#@@@var{n}}, where @var{n} is the result
-of calling @code{hash} on the object to be printed. The reader
-recognizes this syntax, calling @code{unhash} on @var{n} to get back the
-original object. Note that this printed representation can only be
-recognized by the Scheme program in which it was generated, because
-these hash numbers are different for each invocation of Scheme.
-@end defvr
-
-@node Format, Custom Output, Output Procedures, Input/Output
-@section Format
-
-@comment **** begin CLTL ****
-
-The procedure @code{format} is very useful for producing nicely
-formatted text, producing good-looking messages, and so on. MIT/GNU
-Scheme's implementation of @code{format} is similar to that of Common
-Lisp, except that Common Lisp defines many more
-directives.@footnote{This description of @code{format} is adapted from
-@cite{Common Lisp, The Language}, second edition, section 22.3.3.}
-
-@cindex run-time-loadable option
-@cindex option, run-time-loadable
-@code{format} is a run-time-loadable option. To use it, execute
-
-@example
-(load-option 'format)
-@end example
-@findex load-option
-
-@noindent
-once before calling it.
-
-@deffn procedure format destination control-string argument @dots{}
-@findex write-string
-@cindex format directive (defn)
-@cindex directive, format (defn)
-Writes the characters of @var{control-string} to @var{destination},
-except that a tilde (@code{~}) introduces a @dfn{format directive}. The
-character after the tilde, possibly preceded by prefix parameters and
-modifiers, specifies what kind of formatting is desired. Most
-directives use one or more @var{argument}s to create their output; the
-typical directive puts the next @var{argument} into the output,
-formatted in some special way. It is an error if no argument remains
-for a directive requiring an argument, but it is not an error if one or
-more arguments remain unprocessed by a directive.
-
-The output is sent to @var{destination}. If @var{destination} is
-@code{#f}, a string is created that contains the output; this string is
-returned as the value of the call to @code{format}. In all other cases
-@code{format} returns an unspecified value. If @var{destination} is
-@code{#t}, the output is sent to the current output port. Otherwise,
-@var{destination} must be an output port, and the output is sent there.
-
-This procedure performs discretionary output flushing (@pxref{Output
-Procedures}).
-
-A @code{format} directive consists of a tilde (@code{~}), optional
-prefix parameters separated by commas, optional colon (@code{:}) and
-at-sign (@code{@@}) modifiers, and a single character indicating what
-kind of directive this is. The alphabetic case of the directive
-character is ignored. The prefix parameters are generally integers,
-notated as optionally signed decimal numbers. If both the colon and
-at-sign modifiers are given, they may appear in either order.
-
-@cindex V as format parameter
-@cindex # as format parameter
-In place of a prefix parameter to a directive, you can put the letter
-@samp{V} (or @samp{v}), which takes an @var{argument} for use as a
-parameter to the directive. Normally this should be an exact integer.
-This feature allows variable-width fields and the like. You can also
-use the character @samp{#} in place of a parameter; it represents the
-number of arguments remaining to be processed.
-
-It is an error to give a format directive more parameters than it is
-described here as accepting. It is also an error to give colon or
-at-sign modifiers to a directive in a combination not specifically
-described here as being meaningful.
-
-@table @code
-@item ~A
-The next @var{argument}, which may be any object, is printed as if by
-@code{display}. @code{~@var{mincol}A} inserts spaces on the right, if
-necessary, to make the width at least @var{mincol} columns. The
-@code{@@} modifier causes the spaces to be inserted on the left rather
-than the right.
-
-@item ~S
-The next @var{argument}, which may be any object, is printed as if by
-@code{write}. @code{~@var{mincol}S} inserts spaces on the right, if
-necessary, to make the width at least @var{mincol} columns. The
-@code{@@} modifier causes the spaces to be inserted on the left rather
-than the right.
-
-@item ~%
-This outputs a @code{#\newline} character. @code{~@var{n}%} outputs
-@var{n} newlines. No @var{argument} is used. Simply putting a newline
-in @var{control-string} would work, but @code{~%} is often used because
-it makes the control string look nicer in the middle of a program.
-
-@item ~~
-This outputs a tilde. @code{~@var{n}~} outputs @var{n} tildes.
-
-@item ~@var{newline}
-Tilde immediately followed by a newline ignores the newline and any
-following non-newline whitespace characters. With an @code{@@}, the
-newline is left in place, but any following whitespace is ignored. This
-directive is typically used when @var{control-string} is too long to fit
-nicely into one line of the program:
-
-@example
-@group
-(define (type-clash-error procedure arg spec actual)
- (format
- #t
- "~%Procedure ~S~%requires its %A argument ~
- to be of type ~S,~%but it was called with ~
- an argument of type ~S.~%"
- procedure arg spec actual))
-@end group
-@end example
-
-@example
-@group
-(type-clash-error 'vector-ref
- "first"
- 'integer
- 'vector)
-
-@r{prints}
-
-Procedure vector-ref
-requires its first argument to be of type integer,
-but it was called with an argument of type vector.
-@end group
-@end example
-
-@noindent
-Note that in this example newlines appear in the output only as
-specified by the @code{~%} directives; the actual newline characters in
-the control string are suppressed because each is preceded by a tilde.
-@end table
-@end deffn
-
-@comment **** end CLTL ****
-
-@node Custom Output, Prompting, Format, Input/Output
-@section Custom Output
-
-MIT/GNU Scheme provides hooks for specifying that certain kinds of objects
-have special written representations. There are no restrictions on the
-written representations, but only a few kinds of objects may have custom
-representation specified for them, specifically: records
-(@pxref{Records}), vectors that have special tags in their zero-th
-elements (@pxref{Vectors}), and pairs that have special tags in their
-car fields (@pxref{Lists}). There is a different procedure for
-specifying the written representation of each of these types.
-
-@deffn procedure set-record-type-unparser-method! record-type unparser-method
-Changes the unparser method of the type represented by @var{record-type}
-to be @var{unparser-method}, and returns an unspecified value.
-Subsequently, when the unparser encounters a record of this type, it
-will invoke @var{unparser-method} to generate the written
-representation.
-@end deffn
-
-@deffn procedure unparser/set-tagged-vector-method! tag unparser-method
-Changes the unparser method of the vector type represented by @var{tag}
-to be @var{unparser-method}, and returns an unspecified value.
-Subsequently, when the unparser encounters a vector with @var{tag} as
-its zero-th element, it will invoke @var{unparser-method} to generate
-the written representation.
-@end deffn
-
-@deffn procedure unparser/set-tagged-pair-method! tag unparser-method
-Changes the unparser method of the pair type represented by @var{tag} to
-be @var{unparser-method}, and returns an unspecified value.
-Subsequently, when the unparser encounters a pair with @var{tag} in its
-car field, it will invoke @var{unparser-method} to generate the written
-representation.
-@end deffn
-
-@cindex unparser method (defn)
-@cindex method, unparser (defn)
-An @dfn{unparser method} is a procedure that is invoked with two
-arguments: an unparser state and an object. An unparser method
-generates a written representation for the object, writing it to the
-output port specified by the unparser state. The value yielded by an
-unparser method is ignored. Note that an unparser state is not an
-output port, rather it is an object that contains an output port as one
-of its components. Application programs generally do not construct or
-examine unparser state objects, but just pass them along.
-
-There are two ways to create an unparser method (which is then
-registered by one of the above procedures). The first, and easiest, is
-to use @code{standard-unparser-method}. The second is to define your
-own method using the procedure @code{with-current-unparser-state}. We
-encourage the use of the first method, as it results in a more uniform
-appearance for objects. Many predefined datatypes, for example
-procedures and environments, already have this appearance.
-
-@deffn procedure standard-unparser-method name procedure
-Returns a standard unparser method. @var{Name} may be any object, and
-is used as the name of the type with which the unparser method is
-associated; @var{name} is usually a symbol. @var{Procedure} must be
-@code{#f} or a procedure of two arguments.
-
-@cindex #[ as external representation
-If @var{procedure} is @code{#f}, the returned method generates an
-external representation of this form:
-
-@example
-#[@var{name} @var{hash}]
-@end example
-
-@noindent
-@findex write
-@findex write-string
-@findex hash
-Here @var{name} is the external representation of the argument
-@var{name}, as generated by @code{write},@footnote{Except that if the
-argument @var{name} is a string, its external representation is
-generated by @code{write-string}.} and @var{hash} is the external
-representation of an exact non-negative integer unique to the object
-being printed (specifically, it is the result of calling @code{hash} on
-the object). Subsequently, the expression
-
-@example
-#@@@var{hash}
-@end example
-
-@noindent
-is notation for the object.
-
-If @var{procedure} is supplied, the returned method generates a slightly
-different external representation:
-
-@example
-#[@var{name} @var{hash} @var{output}]
-@end example
-
-@noindent
-Here @var{name} and @var{hash} are as above, and @var{output} is the
-output generated by @var{procedure}. The representation is constructed
-in three stages:
-
-@enumerate
-@item
-The first part of the format (up to @var{output}) is written to the
-output port specified by the unparser state. This is @code{"#["},
-@var{name}, @code{" "}, and @var{hash}.
-
-@item
-@var{Procedure} is invoked on two arguments: the object and an output
-port.
-
-@item
-The closing bracket is written to the output port.
-@end enumerate
-@end deffn
-
-The following procedure is useful for writing more general kinds of
-unparser methods.
-
-@deffn procedure with-current-unparser-state unparser-state procedure
-This procedure calls @var{procedure} with one argument, the output port
-from @var{unparser-state}. Additionally, it arranges for the remaining
-components of @var{unparser-state} to be given to the printer when they
-are needed. The @var{procedure} generates some output by writing to the
-output port using the usual output operations, and the value yielded by
-@var{procedure} is returned from @code{with-current-unparser-state}.
-
-The port passed to @var{procedure} should only be used within the
-dynamic extent of @var{procedure}.
-@end deffn
-
-@node Prompting, Port Primitives, Custom Output, Input/Output
-@section Prompting
-@cindex prompting
-
-This section describes procedures that prompt the user for input. Why
-should the programmer use these procedures when it is possible to do
-prompting using ordinary input and output procedures? One reason is
-that the prompting procedures are more succinct. However, a second and
-better reason is that the prompting procedures can be separately
-customized for each user interface, providing more natural interaction.
-The interfaces for Edwin and for GNU Emacs have already been customized
-in this fashion; because Edwin and Emacs are very similar editors, their
-customizations provide very similar behavior.
-
-@findex interaction-i/o-port
-Each of these procedure accepts an optional argument called
-@var{port}, which if given must be an @acronym{I/O} port. If not
-given, this port defaults to the value of
-@code{(interaction-i/o-port)}; this is initially the console
-@acronym{I/O} port.
-
-@deffn procedure prompt-for-command-expression prompt [port]
-Prompts the user for an expression that is to be executed as a command.
-This is the procedure called by the @acronym{REP} loop to read the
-user's expressions.
-
-If @var{prompt} is a string, it is used verbatim as the prompt string.
-Otherwise, it must be a pair whose car is @code{standard} and whose cdr
-is a string; in this case the prompt string is formed by prepending to
-the string the current @acronym{REP} loop ``level number'' and a space.
-Also, a space is appended to the string, unless it already ends in a
-space or is an empty string.
-
-The default behavior of this procedure is to print a fresh line, a
-newline, and the prompt string; flush the output buffer; then read an
-object and return it.
-
-Under Edwin and Emacs, before the object is read, the interaction buffer
-is put into a mode that allows expressions to be edited and submitted
-for input using specific editor commands. The first expression that is
-submitted is returned as the value of this procedure.
-@end deffn
-
-@deffn procedure prompt-for-command-char prompt [port]
-@findex char-graphic?
-Prompts the user for a single character that is to be executed as a
-command; the returned character is guaranteed to satisfy
-@code{char-graphic?}. If at all possible, the character is read from
-the user interface using a mode that reads the character as a single
-keystroke; in other words, it should not be necessary for the user to
-follow the character with a carriage return or something similar.
-
-@findex debug
-@findex where
-This is the procedure called by @code{debug} and @code{where} to read
-the user's commands.
-
-If @var{prompt} is a string, it is used verbatim as the prompt string.
-Otherwise, it must be a pair whose car is @code{standard} and whose cdr
-is a string; in this case the prompt string is formed by prepending to
-the string the current @acronym{REP} loop ``level number'' and a space.
-Also, a space is appended to the string, unless it already ends in a
-space or is an empty string.
-
-The default behavior of this procedure is to print a fresh line, a
-newline, and the prompt string; flush the output buffer; read a
-character in raw mode, echo that character, and return it.
-
-Under Edwin and Emacs, instead of reading a character, the interaction
-buffer is put into a mode in which graphic characters submit themselves
-as input. After this mode change, the first such character submitted is
-returned as the value of this procedure.
-@end deffn
-
-@deffn procedure prompt-for-expression prompt [port]
-Prompts the user for an expression.
-
-The prompt string is formed by appending a colon and a space to
-@var{prompt}, unless @var{prompt} already ends in a space or is the null
-string.
-
-The default behavior of this procedure is to print a fresh line, a
-newline, and the prompt string; flush the output buffer; then read an
-object and return it.
-
-Under Edwin and Emacs, the expression is read in the minibuffer.
-@end deffn
-
-@deffn procedure prompt-for-evaluated-expression prompt [environment [port]]
-Prompts the user for an evaluated expression. Calls
-@code{prompt-for-expression} to read an expression, then evaluates the
-expression using @var{environment}; if @var{environment} is not given,
-the @acronym{REP} loop environment is used.
-@end deffn
-
-@deffn procedure prompt-for-confirmation prompt [port]
-Prompts the user for confirmation. The result yielded by this procedure
-is a boolean.
-
-The prompt string is formed by appending the string @code{" (y or n)? "}
-to @var{prompt}, unless @var{prompt} already ends in a space or is the
-null string.
-
-The default behavior of this procedure is to print a fresh line, a
-newline, and the prompt string; flush the output buffer; then read a
-character in raw mode. If the character is @code{#\y}, @code{#\Y}, or
-@code{#\space}, the procedure returns @code{#t}; If the character is
-@code{#\n}, @code{#\N}, or @code{#\rubout}, the procedure returns
-@code{#f}. Otherwise the prompt is repeated.
-
-Under Edwin or Emacs, the confirmation is read in the minibuffer.
-@end deffn
-
-@node Port Primitives, Parser Buffers, Prompting, Input/Output
-@section Port Primitives
-@cindex port primitives
-
-This section describes the low-level operations that can be used to
-build and manipulate @acronym{I/O} ports.
-
-The purpose of these operations is twofold: to allow programmers to
-construct new kinds of @acronym{I/O} ports, and to provide faster
-@acronym{I/O} operations than those supplied by the standard high
-level procedures. The latter is useful because the standard
-@acronym{I/O} operations provide defaulting and error checking, and
-sometimes other features, which are often unnecessary. This interface
-provides the means to bypass such features, thus improving
-performance.
-
-The abstract model of an @acronym{I/O} port, as implemented here, is a
-combination of a set of named operations and a state. The state is an
-arbitrary object, the meaning of which is determined by the
-operations. The operations are defined by a mapping from names to
-procedures.
-
-@cindex port type
-The set of named operations is represented by an object called a
-@dfn{port type}. A port type is constructed from a set of named
-operations, and is subsequently used to construct a port. The port type
-completely specifies the behavior of the port. Port types also support
-a simple form of inheritance, allowing you to create new ports that are
-similar to existing ports.
-
-The port operations are divided into two classes:
-
-@table @asis
-@item Standard operations
-There is a specific set of standard operations for input ports, and a
-different set for output ports. Applications can assume that the
-standard input operations are implemented for all input ports, and
-likewise the standard output operations are implemented for all output
-ports.
-@cindex standard operations, on port
-
-@item Custom operations
-Some ports support additional operations. For example, ports that
-implement output to terminals (or windows) may define an operation named
-@code{y-size} that returns the height of the terminal in characters.
-Because only some ports will implement these operations, programs that
-use custom operations must test each port for their existence, and be
-prepared to deal with ports that do not implement them.
-@cindex custom operations, on port
-@findex y-size
-@end table
-
-@menu
-* Port Types::
-* Constructors and Accessors for Ports::
-* Input Port Operations::
-* Output Port Operations::
-* Blocking Mode::
-* Terminal Mode::
-@end menu
-
-@node Port Types, Constructors and Accessors for Ports, Port Primitives, Port Primitives
-@subsection Port Types
-
-The procedures in this section provide means for constructing port types
-with standard and custom operations, and accessing their operations.
-
-@deffn procedure make-port-type operations port-type
-@cindex construction, of port type
-Creates and returns a new port type.
-@var{Operations} must be a list; each element is a list of two elements,
-the name of the operation (a symbol) and the procedure that implements
-it. @var{Port-type} is either @code{#f} or a port type; if it is a port
-type, any operations implemented by @var{port-type} but not specified in
-@var{operations} will be implemented by the resulting port type.
-
-@var{Operations} need not contain definitions for all of the standard
-operations; the procedure will provide defaults for any standard
-operations that are not defined. At a minimum, the following operations
-must be defined: for input ports, @code{read-char} and @code{peek-char};
-for output ports, either @code{write-char} or @code{write-substring}.
-@acronym{I/O} ports must supply the minimum operations for both input and
-output.
-
-If an operation in @var{operations} is defined to be @code{#f}, then the
-corresponding operation in @var{port-type} is @emph{not} inherited.
-
-If @code{read-char} is defined in @var{operations}, then any standard
-input operations defined in @var{port-type} are ignored. Likewise, if
-@code{write-char} or @code{write-substring} is defined in
-@var{operations}, then any standard output operations defined in
-@var{port-type} are ignored. This feature allows overriding the
-standard operations without having to enumerate them.
-@end deffn
-
-@deffn procedure port-type? object
-@deffnx procedure input-port-type? object
-@deffnx procedure output-port-type? object
-@deffnx procedure i/o-port-type? object
-These predicates return @code{#t} if @var{object} is a port type,
-input-port type, output-port type, or @acronym{I/O}-port type,
-respectively. Otherwise, they return @code{#f}.
-@end deffn
-
-@deffn procedure port-type/operations port-type
-Returns a newly allocated list containing all of the operations
-implemented by @var{port-type}. Each element of the list is a list of
-two elements --- the name and its associated operation.
-@end deffn
-
-@deffn procedure port-type/operation-names port-type
-Returns a newly allocated list whose elements are the names of the
-operations implemented by @var{port-type}.
-@end deffn
-
-@deffn procedure port-type/operation port-type symbol
-Returns the operation named @var{symbol} in @var{port-type}. If
-@var{port-type} has no such operation, returns @code{#f}.
-@end deffn
-
-@node Constructors and Accessors for Ports, Input Port Operations, Port Types, Port Primitives
-@subsection Constructors and Accessors for Ports
-
-The procedures in this section provide means for constructing ports,
-accessing the type of a port, and manipulating the state of a port.
-
-@deffn procedure make-port port-type state
-Returns a new port with type @var{port-type} and the given
-@var{state}. The port will be an input, output, or @acronym{I/O} port
-according to @var{port-type}.
-@end deffn
-
-@deffn procedure port/type port
-Returns the port type of @var{port}.
-@end deffn
-
-@deffn procedure port/state port
-Returns the state component of @var{port}.
-@end deffn
-
-@deffn procedure set-port/state! port object
-Changes the state component of @var{port} to be @var{object}.
-Returns an unspecified value.
-@end deffn
-
-@deffn procedure port/operation port symbol
-Equivalent to
-
-@example
-(port-type/operation (port/type @var{port}) @var{symbol})
-@end example
-@end deffn
-
-@deffn procedure port/operation-names port
-Equivalent to
-
-@example
-(port-type/operation-names (port/type @var{port}))
-@end example
-@end deffn
-
-@deffn procedure make-eof-object input-port
-@cindex EOF object, construction
-@cindex construction, of EOF object
-@findex eof-object?
-Returns an object that satisfies the predicate @code{eof-object?}. This
-is sometimes useful when building input ports.
-@end deffn
-
-@node Input Port Operations, Output Port Operations, Constructors and Accessors for Ports, Port Primitives
-@subsection Input Port Operations
-@cindex input port operations
-
-This section describes the standard operations on input ports.
-Following that, some useful custom operations are described.
-
-@defop operation {input port} read-char input-port
-@cindex character, input from port
-Removes the next character available from @var{input-port} and returns
-it. If @var{input-port} has no more characters and will never have any
-(e.g.@: at the end of an input file), this operation returns an
-end-of-file object. If @var{input-port} has no more characters but will
-eventually have some more (e.g.@: a terminal where nothing has been
-typed recently), and it is in non-blocking mode, @code{#f} is returned;
-otherwise the operation hangs until input is available.
-@end defop
-
-@defop operation {input port} peek-char input-port
-Reads the next character available from @var{input-port} and returns it.
-The character is @emph{not} removed from @var{input-port}, and a
-subsequent attempt to read from the port will get that character again.
-In other respects this operation behaves like @code{read-char}.
-@end defop
-
-@defop operation {input port} discard-char input-port
-Discards the next character available from @var{input-port} and returns
-an unspecified value. In other respects this operation behaves like
-@code{read-char}.
-@end defop
-
-@defop operation {input port} char-ready? input-port k
-@code{char-ready?} returns @code{#t} if at least one character is
-available to be read from @var{input-port}. If no characters are
-available, the operation waits up to @var{k} milliseconds before
-returning @code{#f}, returning immediately if any characters become
-available while it is waiting.
-@end defop
-
-@defop operation {input port} read-string input-port char-set
-@defopx operation {input port} discard-chars input-port char-set
-@cindex string, input from port
-These operations are like @code{read-char} and @code{discard-char},
-except that they read or discard multiple characters at once. This can
-have a marked performance improvement on buffered input ports. All
-characters up to, but excluding, the first character in @var{char-set}
-(or end of file) are read from @var{input-port}. @code{read-string}
-returns these characters as a newly allocated string, while
-@code{discard-chars} discards them and returns an unspecified value.
-These operations hang until sufficient input is available, even if
-@var{input-port} is in non-blocking mode. If end of file is encountered
-before any input characters, @code{read-string} returns an end-of-file
-object.
-@end defop
-
-@defop operation {input port} read-substring input-port string start end
-Reads characters from @var{input-port} into the substring defined by
-@var{string}, @var{start}, and @var{end} until either the substring has
-been filled or there are no more characters available. Returns the
-number of characters written to the substring.
-
-If @var{input-port} is an interactive port, and at least one character
-is immediately available, the available characters are written to the
-substring and this operation returns immediately. If no characters are
-available, and @var{input-port} is in blocking mode, the operation
-blocks until at least one character is available. Otherwise, the
-operation returns @code{#f} immediately.
-
-This is an extremely fast way to read characters from a port.
-@end defop
-
-@deffn procedure input-port/read-char input-port
-@deffnx procedure input-port/peek-char input-port
-@deffnx procedure input-port/discard-char input-port
-@deffnx procedure input-port/char-ready? input-port k
-@deffnx procedure input-port/read-string input-port char-set
-@deffnx procedure input-port/discard-chars input-port char-set
-@deffnx procedure input-port/read-substring input-port string start end
-Each of these procedures invokes the respective operation on
-@var{input-port}. For example, the following are equivalent:
-
-@example
-@group
-(input-port/read-char @var{input-port})
-((input-port/operation @var{input-port} 'read-char) @var{input-port})
-@end group
-@end example
-@end deffn
-
-The following custom operations are implemented for input ports to
-files, and will also work with some other kinds of input ports:
-
-@defop operation {input port} eof? input-port
-Returns @code{#t} if @var{input-port} is known to be at end of file,
-otherwise it returns @code{#f}.
-@end defop
-
-@defop operation {input port} chars-remaining input-port
-Returns an estimate of the number of characters remaining to be read
-from @var{input-port}. This is useful only when @var{input-port} is a
-file port in binary mode; in other cases, it returns @code{#f}.
-@end defop
-
-@defop operation {input port} buffered-input-chars input-port
-Returns the number of unread characters that are stored in
-@var{input-port}'s buffer. This will always be less than or equal to
-the buffer's size.
-@end defop
-
-@defop operation {input port} input-buffer-size input-port
-Returns the maximum number of characters that @var{input-port}'s buffer
-can hold.
-@end defop
-
-@defop operation {input port} set-input-buffer-size input-port size
-Resizes @var{input-port}'s buffer so that it can hold at most @var{size}
-characters. Characters in the buffer are discarded. @var{Size} must be
-an exact non-negative integer.
-@end defop
-
-@node Output Port Operations, Blocking Mode, Input Port Operations, Port Primitives
-@subsection Output Port Operations
-@cindex output port operations
-
-This section describes the standard operations on output ports.
-Following that, some useful custom operations are described.
-
-@defop operation {output port} write-char output-port char
-@cindex character, output to port
-Writes @var{char} to @var{output-port} and returns an unspecified value.
-@end defop
-
-@defop operation {output port} write-substring output-port string start end
-@cindex substring, output to port
-Writes the substring specified by @var{string}, @var{start}, and
-@var{end} to @var{output-port} and returns an unspecified value.
-Equivalent to writing the characters of the substring, one by one, to
-@var{output-port}, but is implemented very efficiently.
-@end defop
-
-@defop operation {output port} fresh-line output-port
-Most output ports are able to tell whether or not they are at the
-beginning of a line of output. If @var{output-port} is such a port,
-end-of-line is written to the port only if the port is not already at
-the beginning of a line. If @var{output-port} is not such a port, an
-end-of-line is unconditionally written to the port. Returns an
-unspecified value.
-@end defop
-
-@defop operation {output port} flush-output output-port
-If @var{output-port} is buffered, this causes its buffer to be written
-out. Otherwise it has no effect. Returns an unspecified value.
-@end defop
-
-@defop operation {output port} discretionary-flush-output output-port
-Normally, this operation does nothing. However, ports that support
-discretionary output flushing implement this operation identically to @code{flush-output}.
-@end defop
-
-@deffn procedure output-port/write-char output-port char
-@deffnx procedure output-port/write-substring output-port string start end
-@deffnx procedure output-port/fresh-line output-port
-@deffnx procedure output-port/flush-output output-port
-@deffnx procedure output-port/discretionary-flush-output output-port
-Each of these procedures invokes the respective operation on
-@var{output-port}. For example, the following are equivalent:
-
-@example
-@group
-(output-port/write-char @var{output-port} @var{char})
-((output-port/operation @var{output-port} 'write-char)
- @var{output-port} @var{char})
-@end group
-@end example
-@end deffn
-
-@deffn procedure output-port/write-string output-port string
-Writes @var{string} to @var{output-port}. Equivalent to
-
-@example
-@group
-(output-port/write-substring @var{output-port}
- @var{string}
- 0
- (string-length @var{string}))
-@end group
-@end example
-@end deffn
-
-The following custom operations are generally useful.
-
-@defop operation {output port} buffered-output-chars output-port
-Returns the number of unwritten characters that are stored in
-@var{output-port}'s buffer. This will always be less than or equal to
-the buffer's size.
-@end defop
-
-@defop operation {output port} output-buffer-size output-port
-Returns the maximum number of characters that @var{output-port}'s buffer
-can hold.
-@end defop
-
-@defop operation {output port} set-output-buffer-size output-port size
-Resizes @var{output-port}'s buffer so that it can hold at most @var{size}
-characters. Characters in the buffer are discarded. @var{Size} must be
-an exact non-negative integer.
-@end defop
-
-@defop operation {output port} x-size output-port
-Returns an exact positive integer that is the width of @var{output-port}
-in characters. If @var{output-port} has no natural width, e.g.@: if it is
-a file port, @code{#f} is returned.
-@end defop
-
-@defop operation {output port} y-size output-port
-Returns an exact positive integer that is the height of
-@var{output-port} in characters. If @var{output-port} has no natural
-height, e.g.@: if it is a file port, @code{#f} is returned.
-@end defop
-
-@deffn procedure output-port/x-size output-port
-This procedure invokes the custom operation whose name is the symbol
-@code{x-size}, if it exists. If the @code{x-size} operation is both
-defined and returns a value other than @code{#f}, that value is returned
-as the result of this procedure. Otherwise, @code{output-port/x-size}
-returns a default value (currently @code{80}).
-
-@code{output-port/x-size} is useful for programs that tailor their
-output to the width of the display (a fairly common practice). If the
-output device is not a display, such programs normally want some
-reasonable default width to work with, and this procedure provides
-exactly that.
-@end deffn
-
-@deffn procedure output-port/y-size output-port
-This procedure invokes the custom operation whose name is the symbol
-@code{y-size}, if it exists. If the @code{y-size} operation is defined,
-the value it returns is returned as the result of this procedure;
-otherwise, @code{#f} is returned.
-@end deffn
-
-@node Blocking Mode, Terminal Mode, Output Port Operations, Port Primitives
-@subsection Blocking Mode
-
-@cindex blocking mode, of port
-An interactive port is always in one of two modes: @dfn{blocking} or
-@dfn{non-blocking}. This mode is independent of the terminal mode:
-each can be changed independent of the other. Furthermore, if it is
-an interactive @acronym{I/O} port, there are separate blocking modes
-for input and for output.
-
-If an input port is in blocking mode, attempting to read from it when no
-input is available will cause Scheme to ``block'', i.e.@: suspend
-itself, until input is available. If an input port is in non-blocking
-mode, attempting to read from it when no input is available will cause
-the reading procedure to return immediately, indicating the lack of
-input in some way (exactly how this situation is indicated is separately
-specified for each procedure or operation).
-
-An output port in blocking mode will block if the output device is not
-ready to accept output. In non-blocking mode it will return immediately
-after performing as much output as the device will allow (again, each
-procedure or operation reports this situation in its own way).
-
-Interactive ports are initially in blocking mode; this can be changed at
-any time with the procedures defined in this section.
-
-These procedures represent blocking mode by the symbol @code{blocking},
-and non-blocking mode by the symbol @code{nonblocking}. An argument
-called @var{mode} must be one of these symbols. A @var{port} argument
-to any of these procedures may be any port, even if that port does not
-support blocking mode; in that case, the port is not modified in any
-way.
-
-@deffn procedure port/input-blocking-mode port
-Returns the input blocking mode of @var{port}.
-@end deffn
-
-@deffn procedure port/set-input-blocking-mode port mode
-Changes the input blocking mode of @var{port} to be @var{mode}. Returns
-an unspecified value.
-@end deffn
-
-@deffn procedure port/with-input-blocking-mode port mode thunk
-@var{Thunk} must be a procedure of no arguments.
-@code{port/with-input-blocking-mode}
-binds the input blocking mode of @var{port} to be @var{mode}, executes
-@var{thunk}, restores the input blocking mode of @var{port} to what it
-was when @code{port/with-input-blocking-mode} was called, and returns
-the value that was yielded by @var{thunk}. This binding is performed
-by @code{dynamic-wind}, which guarantees that the input blocking mode is
-restored if @var{thunk} escapes from its continuation.
-@end deffn
-
-@deffn procedure port/output-blocking-mode port
-Returns the output blocking mode of @var{port}.
-@end deffn
-
-@deffn procedure port/set-output-blocking-mode port mode
-Changes the output blocking mode of @var{port} to be @var{mode}.
-Returns an unspecified value.
-@end deffn
-
-@deffn procedure port/with-output-blocking-mode port mode thunk
-@var{Thunk} must be a procedure of no arguments.
-@code{port/with-output-blocking-mode}
-binds the output blocking mode of @var{port} to be @var{mode}, executes
-@var{thunk}, restores the output blocking mode of @var{port} to what it
-was when @code{port/with-output-blocking-mode} was called, and returns
-the value that was yielded by @var{thunk}. This binding is performed
-by @code{dynamic-wind}, which guarantees that the output blocking mode
-is restored if @var{thunk} escapes from its continuation.
-@end deffn
-
-@node Terminal Mode, , Blocking Mode, Port Primitives
-@subsection Terminal Mode
-
-@cindex terminal mode, of port
-A port that reads from or writes to a terminal has a @dfn{terminal
-mode}; this is either @dfn{cooked} or @dfn{raw}. This mode is
-independent of the blocking mode: each can be changed independent of
-the other. Furthermore, a terminal @acronym{I/O} port has independent
-terminal modes both for input and for output.
-
-@cindex cooked mode, of terminal port
-A terminal port in cooked mode provides some standard processing to make
-the terminal easy to communicate with. For example, under unix, cooked
-mode on input reads from the terminal a line at a time and provides
-rubout processing within the line, while cooked mode on output might
-translate linefeeds to carriage-return/linefeed pairs. In general, the
-precise meaning of cooked mode is operating-system dependent, and
-furthermore might be customizable by means of operating system
-utilities. The basic idea is that cooked mode does whatever is
-necessary to make the terminal handle all of the usual user-interface
-conventions for the operating system, while keeping the program's
-interaction with the port as normal as possible.
-
-@cindex raw mode, of terminal port
-A terminal port in raw mode disables all of that processing. In raw
-mode, characters are directly read from and written to the device
-without any translation or interpretation by the operating system. On
-input, characters are available as soon as they are typed, and are not
-echoed on the terminal by the operating system. In general, programs
-that put ports in raw mode have to know the details of interacting with
-the terminal. In particular, raw mode is used for writing programs such
-as text editors.
-
-Terminal ports are initially in cooked mode; this can be changed at any
-time with the procedures defined in this section.
-
-These procedures represent cooked mode by the symbol @code{cooked}, and
-raw mode by the symbol @code{raw}. Additionally, the value @code{#f}
-represents ``no mode''; it is the terminal mode of a port that is not a
-terminal. An argument called @var{mode} must be one of these three
-values. A @var{port} argument to any of these procedures may be any
-port, even if that port does not support terminal mode; in that case,
-the port is not modified in any way.
-
-@deffn procedure port/input-terminal-mode port
-Returns the input terminal mode of @var{port}.
-@end deffn
-
-@deffn procedure port/set-input-terminal-mode port mode
-Changes the input terminal mode of @var{port} to be @var{mode}.
-Returns an unspecified value.
-@end deffn
-
-@deffn procedure port/with-input-terminal-mode port mode thunk
-@var{Thunk} must be a procedure of no arguments.
-@code{port/with-input-terminal-mode}
-binds the input terminal mode of @var{port} to be @var{mode}, executes
-@var{thunk}, restores the input terminal mode of @var{port} to what it
-was when @code{port/with-input-terminal-mode} was called, and returns
-the value that was yielded by @var{thunk}. This binding is performed
-by @code{dynamic-wind}, which guarantees that the input terminal mode is
-restored if @var{thunk} escapes from its continuation.
-@end deffn
-
-@deffn procedure port/output-terminal-mode port
-Returns the output terminal mode of @var{port}.
-@end deffn
-
-@deffn procedure port/set-output-terminal-mode port mode
-Changes the output terminal mode of @var{port} to be @var{mode}.
-Returns an unspecified value.
-@end deffn
-
-@deffn procedure port/with-output-terminal-mode port mode thunk
-@var{Thunk} must be a procedure of no arguments.
-@code{port/with-output-terminal-mode}
-binds the output terminal mode of @var{port} to be @var{mode}, executes
-@var{thunk}, restores the output terminal mode of @var{port} to what it
-was when @code{port/with-output-terminal-mode} was called, and returns
-the value that was yielded by @var{thunk}. This binding is performed
-by @code{dynamic-wind}, which guarantees that the output terminal mode is
-restored if @var{thunk} escapes from its continuation.
-@end deffn
-
-@node Parser Buffers, Parser Language, Port Primitives, Input/Output
-@section Parser Buffers
-
-@cindex Parser buffer
-The @dfn{parser buffer} mechanism facilitates construction of parsers
-for complex grammars. It does this by providing an input stream with
-unbounded buffering and backtracking. The amount of buffering is
-under program control. The stream can backtrack to any position in
-the buffer.
-
-@cindex Parser-buffer pointer
-The mechanism defines two data types: the @dfn{parser buffer} and the
-@dfn{parser-buffer pointer}. A parser buffer is like an input port
-with buffering and backtracking. A parser-buffer pointer is a pointer
-into the stream of characters provided by a parser buffer.
-
-Note that all of the procedures defined here consider a parser buffer
-to contain a stream of 8-bit characters in the @acronym{ISO-8859-1}
-character set, except for @code{match-utf8-char-in-alphabet} which
-treats it as a stream of Unicode characters encoded as 8-bit bytes in
-the @acronym{UTF-8} encoding.
-
-There are several constructors for parser buffers:
-
-@deffn procedure input-port->parser-buffer port
-Returns a parser buffer that buffers characters read from @var{port}.
-@end deffn
-
-@deffn procedure substring->parser-buffer string start end
-Returns a parser buffer that buffers the characters in the argument
-substring. This is equivalent to creating a string input port and
-calling @code{input-port->parser-buffer}, but it runs faster and uses
-less memory.
-@end deffn
-
-@deffn procedure string->parser-buffer string
-Like @code{substring->parser-buffer} but buffers the entire string.
-@end deffn
-
-@deffn procedure source->parser-buffer source
-Returns a parser buffer that buffers the characters returned by
-calling @var{source}. @var{Source} is a procedure of three arguments:
-a string, a start index, and an end index (in other words, a substring
-specifier). Each time @var{source} is called, it writes some
-characters in the substring, and returns the number of characters
-written. When there are no more characters available, it returns
-zero. It must not return zero in any other circumstance.
-@end deffn
-
-Parser buffers and parser-buffer pointers may be distinguished from
-other objects:
-
-@deffn procedure parser-buffer? object
-Returns @code{#t} if @var{object} is a parser buffer, otherwise
-returns @code{#f}.
-@end deffn
-
-@deffn procedure parser-buffer-pointer? object
-Returns @code{#t} if @var{object} is a parser-buffer pointer,
-otherwise returns @code{#f}.
-@end deffn
-
-Characters can be read from a parser buffer much as they can be read
-from an input port. The parser buffer maintains an internal pointer
-indicating its current position in the input stream. Additionally,
-the buffer remembers all characters that were previously read, and can
-look at characters arbitrarily far ahead in the stream. It is this
-buffering capability that facilitates complex matching and
-backtracking.
-
-@deffn procedure read-parser-buffer-char buffer
-Returns the next character in @var{buffer}, advancing the internal
-pointer past that character. If there are no more characters
-available, returns @code{#f} and leaves the internal pointer
-unchanged.
-@end deffn
-
-@deffn procedure peek-parser-buffer-char buffer
-Returns the next character in @var{buffer}, or @code{#f} if no
-characters are available. Leaves the internal pointer unchanged.
-@end deffn
-
-@deffn procedure parser-buffer-ref buffer index
-Returns a character in @var{buffer}. @var{Index} is a non-negative
-integer specifying the character to be returned. If @var{index} is
-zero, returns the next available character; if it is one, returns the
-character after that, and so on. If @var{index} specifies a position
-after the last character in @var{buffer}, returns @code{#f}. Leaves
-the internal pointer unchanged.
-@end deffn
-
-The internal pointer of a parser buffer can be read or written:
-
-@deffn procedure get-parser-buffer-pointer buffer
-Returns a parser-buffer pointer object corresponding to the internal
-pointer of @var{buffer}.
-@end deffn
-
-@deffn procedure set-parser-buffer-pointer! buffer pointer
-Sets the internal pointer of @var{buffer} to the position specified by
-@var{pointer}. @var{Pointer} must have been returned from a previous
-call of @code{get-parser-buffer-pointer} on @var{buffer}.
-Additionally, if some of @var{buffer}'s characters have been discarded
-by @code{discard-parser-buffer-head!}, @var{pointer} must be outside
-the range that was discarded.
-@end deffn
-
-@deffn procedure get-parser-buffer-tail buffer pointer
-Returns a newly-allocated string consisting of all of the characters
-in @var{buffer} that fall between @var{pointer} and @var{buffer}'s
-internal pointer. @var{Pointer} must have been returned from a
-previous call of @code{get-parser-buffer-pointer} on @var{buffer}.
-Additionally, if some of @var{buffer}'s characters have been discarded
-by @code{discard-parser-buffer-head!}, @var{pointer} must be outside
-the range that was discarded.
-@end deffn
-
-@deffn procedure discard-parser-buffer-head! buffer
-Discards all characters in @var{buffer} that have already been read;
-in other words, all characters prior to the internal pointer. After
-this operation has completed, it is no longer possible to move the
-internal pointer backwards past the current position by calling
-@code{set-parser-buffer-pointer!}.
-@end deffn
-
-The next rather large set of procedures does conditional matching
-against the contents of a parser buffer. All matching is performed
-relative to the buffer's internal pointer, so the first character to
-be matched against is the next character that would be returned by
-@code{peek-parser-buffer-char}. The returned value is always
-@code{#t} for a successful match, and @code{#f} otherwise. For
-procedures whose names do not end in @samp{-no-advance}, a successful
-match also moves the internal pointer of the buffer forward to the end
-of the matched text; otherwise the internal pointer is unchanged.
-
-@deffn procedure match-parser-buffer-char buffer char
-@deffnx procedure match-parser-buffer-char-ci buffer char
-@deffnx procedure match-parser-buffer-not-char buffer char
-@deffnx procedure match-parser-buffer-not-char-ci buffer char
-@deffnx procedure match-parser-buffer-char-no-advance buffer char
-@deffnx procedure match-parser-buffer-char-ci-no-advance buffer char
-@deffnx procedure match-parser-buffer-not-char-no-advance buffer char
-@deffnx procedure match-parser-buffer-not-char-ci-no-advance buffer char
-Each of these procedures compares a single character in @var{buffer}
-to @var{char}. The basic comparison @code{match-parser-buffer-char}
-compares the character to @var{char} using @code{char=?}. The
-procedures whose names contain the @samp{-ci} modifier do
-case-insensitive comparison (i.e.@: they use @code{char-ci=?}). The
-procedures whose names contain the @samp{not-} modifier are successful
-if the character @emph{doesn't} match @var{char}.
-@end deffn
-
-@deffn procedure match-parser-buffer-char-in-set buffer char-set
-@deffnx procedure match-parser-buffer-char-in-set-no-advance buffer char-set
-These procedures compare the next character in @var{buffer} against
-@var{char-set} using @code{char-set-member?}.
-@end deffn
-
-@deffn procedure match-parser-buffer-string buffer string
-@deffnx procedure match-parser-buffer-string-ci buffer string
-@deffnx procedure match-parser-buffer-string-no-advance buffer string
-@deffnx procedure match-parser-buffer-string-ci-no-advance buffer string
-These procedures match @var{string} against @var{buffer}'s contents.
-The @samp{-ci} procedures do case-insensitive matching.
-@end deffn
-
-@deffn procedure match-parser-buffer-substring buffer string start end
-@deffnx procedure match-parser-buffer-substring-ci buffer string start end
-@deffnx procedure match-parser-buffer-substring-no-advance buffer string start end
-@deffnx procedure match-parser-buffer-substring-ci-no-advance buffer string start end
-These procedures match the specified substring against @var{buffer}'s
-contents. The @samp{-ci} procedures do case-insensitive matching.
-@end deffn
-
-@deffn procedure match-utf8-char-in-alphabet buffer alphabet
-This procedure treats @var{buffer}'s contents as @acronym{UTF-8}
-encoded Unicode characters and matches the next such character against
-@var{alphabet}, which must be a Unicode alphabet (@pxref{Unicode}).
-@acronym{UTF-8} represents characters with 1 to 6 bytes, so a
-successful match can move the internal pointer forward by as many as 6
-bytes.
-@end deffn
-
-The remaining procedures provide information that can be used to
-identify locations in a parser buffer's stream.
-
-@deffn procedure parser-buffer-position-string pointer
-Returns a string describing the location of @var{pointer} in terms of
-its character and line indexes. This resulting string is meant to be
-presented to an end user in order to direct their attention to a
-feature in the input stream. In this string, the indexes are
-presented as one-based numbers.
-
-@var{Pointer} may alternatively be a parser buffer, in which case it
-is equivalent to having specified the buffer's internal pointer.
-@end deffn
-
-@deffn procedure parser-buffer-pointer-index pointer
-@deffnx procedure parser-buffer-pointer-line pointer
-Returns the character or line index, respectively, of @var{pointer}.
-Both indexes are zero-based.
-@end deffn
-
-@node Parser Language, XML Parser, Parser Buffers, Input/Output
-@section Parser Language
-
-@cindex Parser language
-Although it is possible to write parsers using the parser-buffer
-abstraction (@pxref{Parser Buffers}), it is tedious. The problem is
-that the abstraction isn't closely matched to the way that people
-think about syntactic structures. In this section, we introduce a
-higher-level mechanism that greatly simplifies the implementation of a
-parser.
-
-The @dfn{parser language} described here allows the programmer to
-write @acronym{BNF}-like specifications that are translated into
-efficient Scheme code at compile time. The language is declarative,
-but it can be freely mixed with Scheme code; this allows the parsing
-of grammars that aren't conveniently described in the language.
-
-@cindex Backtracking, in parser language
-The language also provides backtracking. For example, this expression
-matches any sequence of alphanumeric characters followed by a single
-alphabetic character:
-
-@example
-@group
-(*matcher
- (seq (* (char-set char-set:alphanumeric))
- (char-set char-set:alphabetic)))
-@end group
-@end example
-
-@noindent
-The way that this works is that the matcher matches alphanumeric
-characters in the input stream until it finds a non-alphanumeric
-character. It then tries to match an alphabetic character, which of
-course fails. At this point, if it matched at least one alphanumeric
-character, it @emph{backtracks}: the last matched alphanumeric is
-``unmatched'', and it again attempts to match an alphabetic
-character. The backtracking can be arbitrarily deep; the matcher will
-continue to back up until it finds a way to match the remainder of the
-expression.
-
-So far, this sounds a lot like regular-expression matching
-(@pxref{Regular Expressions}). However, there are some important
-differences.
-
-@itemize @bullet
-@item
-The parser language uses a Scheme-like syntax that is easier to read
-and write than regular-expression notation.
-
-@item
-The language provides macros so that common syntactic constructs can
-be abstracted.
-
-@item
-The language mixes easily with Scheme code, allowing the full power of
-Scheme to be applied to program around limitations in the parser
-language.
-
-@item
-The language provides expressive facilities for converting syntax into
-parsed structure. It also makes it easy to convert parsed strings
-into meaningful objects (e.g.@: numbers).
-
-@item
-The language is compiled into machine language; regular expressions
-are usually interpreted.
-@end itemize
-
-Here is an example that shows off several of the features of the
-parser language. The example is a parser for @acronym{XML} start
-tags:
-
-@anchor{with-pointer example}
-@example
-@group
-(*parser
- (with-pointer p
- (seq "<"
- parse-name
- parse-attribute-list
- (alt (match ">")
- (match "/>")
- (sexp
- (lambda (b)
- (error
- (string-append
- "Unterminated start tag at "
- (parser-buffer-position-string p)))))))))
-@end group
-@end example
-
-@noindent
-This shows that the basic description of a start tag is very similar
-to its @acronym{BNF}. Non-terminal symbols @code{parse-name} and
-@code{parse-attribute-list} do most of the work, and the noise strings
-@code{"<"} and @code{">"} are the syntactic markers delimiting the
-form. There are two alternate endings for start tags, and if the
-parser doesn't find either of the endings, the Scheme code (wrapped in
-@code{sexp}) is run to signal an error. The error procedure
-@code{perror} takes a pointer @code{p}, which it uses to indicate the
-position in the input stream at which the error occurred. In this
-case, that is the beginning of the start tag, i.e.@: the position of
-the leading @code{"<"} marker.
-
-This example still looks pretty complicated, mostly due to the
-error-signalling code. In practice, this is abstracted into a macro,
-after which the expression is quite succinct:
-
-@example
-@group
-(*parser
- (bracket "start tag"
- (seq (noise (string "<")) parse-name)
- (match (alt (string ">") (string "/>")))
- parse-attribute-list))
-@end group
-@end example
-
-@noindent
-The @code{bracket} macro captures the pattern of a bracketed item, and
-hides much of the detail.
-
-The parser language actually consists of two languages: one for
-defining matchers, and one for defining parsers. The languages are
-intentionally very similar, and are meant to be used together. Each
-sub-language is described below in its own section.
-
-@cindex run-time-loadable option
-@cindex option, run-time-loadable
-The parser language is a run-time-loadable option; to use it, execute
-
-@example
-(load-option '*parser)
-@end example
-@findex load-option
-
-@noindent
-once before compiling any code that uses the language.
-
-@menu
-* *Matcher::
-* *Parser::
-* Parser-language Macros::
-@end menu
-
-@node *Matcher, *Parser, Parser Language, Parser Language
-@subsection *Matcher
-
-@cindex Matcher language
-@cindex Matcher procedure
-The @dfn{matcher language} is a declarative language for specifying a
-@dfn{matcher procedure}. A matcher procedure is a procedure that
-accepts a single parser-buffer argument and returns a boolean value
-indicating whether the match it performs was successful. If the match
-succeeds, the internal pointer of the parser buffer is moved forward
-over the matched text. If the match fails, the internal pointer is
-unchanged.
-
-For example, here is a matcher procedure that matches the character
-@samp{a}:
-
-@example
-(lambda (b) (match-parser-buffer-char b #\a))
-@end example
-
-@noindent
-Here is another example that matches two given characters, @var{c1}
-and @var{c2}, in sequence:
-
-@example
-@group
-(lambda (b)
- (let ((p (get-parser-buffer-pointer b)))
- (if (match-parser-buffer-char b @var{c1})
- (if (match-parser-buffer-char b @var{c2})
- #t
- (begin
- (set-parser-buffer-pointer! b p)
- #f))
- #f)))
-@end group
-@end example
-
-@noindent
-This is code is clear, but has lots of details that get in the way of
-understanding what it is doing. Here is the same example in the
-matcher language:
-
-@example
-(*matcher (seq (char @var{c1}) (char @var{c2})))
-@end example
-
-@noindent
-This is much simpler and more intuitive. And it generates virtually
-the same code:
-
-@example
-@group
-(pp (*matcher (seq (char c1) (char c2))))
-@print{} (lambda (#[b1])
-@print{} (let ((#[p1] (get-parser-buffer-pointer #[b1])))
-@print{} (and (match-parser-buffer-char #[b1] c1)
-@print{} (if (match-parser-buffer-char #[b1] c2)
-@print{} #t
-@print{} (begin
-@print{} (set-parser-buffer-pointer! #[b1] #[p1])
-@print{} #f)))))
-@end group
-@end example
-
-Now that we have seen an example of the language, it's time to look at
-the detail. The @code{*matcher} special form is the interface between
-the matcher language and Scheme.
-
-@deffn {special form} *matcher mexp
-The operand @var{mexp} is an expression in the matcher language. The
-@code{*matcher} expression expands into Scheme code that implements a
-matcher procedure.
-@end deffn
-
-Here are the predefined matcher expressions. New matcher expressions
-can be defined using the macro facility (@pxref{Parser-language
-Macros}). We will start with the primitive expressions.
-
-@deffn {matcher expression} char expression
-@deffnx {matcher expression} char-ci expression
-@deffnx {matcher expression} not-char expression
-@deffnx {matcher expression} not-char-ci expression
-These expressions match a given character. In each case, the
-@var{expression} operand is a Scheme expression that must evaluate to
-a character at run time. The @samp{-ci} expressions do
-case-insensitive matching. The @samp{not-} expressions match any
-character other than the given one.
-@end deffn
-
-@deffn {matcher expression} string expression
-@deffnx {matcher expression} string-ci expression
-These expressions match a given string. The @var{expression} operand
-is a Scheme expression that must evaluate to a string at run time.
-The @code{string-ci} expression does case-insensitive matching.
-@end deffn
-
-@deffn {matcher expression} char-set expression
-These expressions match a single character that is a member of a given
-character set. The @var{expression} operand is a Scheme expression
-that must evaluate to a character set at run time.
-@end deffn
-
-@deffn {matcher expression} alphabet expression
-These expressions match a single character that is a member of a given
-Unicode alphabet (@pxref{Unicode}). The @var{expression} operand is a
-Scheme expression that must evaluate to an alphabet at run time.
-@end deffn
-
-@deffn {matcher expression} end-of-input
-The @code{end-of-input} expression is successful only when there are
-no more characters available to be matched.
-@end deffn
-
-@deffn {matcher expression} discard-matched
-The @code{discard-matched} expression always successfully matches the
-null string. However, it isn't meant to be used as a matching
-expression; it is used for its effect. @code{discard-matched} causes
-all of the buffered text prior to this point to be discarded (i.e.@:
-it calls @code{discard-parser-buffer-head!} on the parser buffer).
-
-Note that @code{discard-matched} may not be used in certain places in
-a matcher expression. The reason for this is that it deliberately
-discards information needed for backtracking, so it may not be used in
-a place where subsequent backtracking will need to back over it. As a
-rule of thumb, use @code{discard-matched} only in the last operand of
-a @code{seq} or @code{alt} expression (including any @code{seq} or
-@code{alt} expressions in which it is indirectly contained).
-@end deffn
-
-In addition to the above primitive expressions, there are two
-convenient abbreviations. A character literal (e.g.@: @samp{#\A}) is
-a legal primitive expression, and is equivalent to a @code{char}
-expression with that literal as its operand (e.g.@: @samp{(char
-#\A)}). Likewise, a string literal is equivalent to a @code{string}
-expression (e.g.@: @samp{(string "abc")}).
-
-Next there are several combinator expressions. These closely
-correspond to similar combinators in regular expressions. Parameters
-named @var{mexp} are arbitrary expressions in the matcher language.
-
-@deffn {matcher expression} seq mexp @dots{}
-This matches each @var{mexp} operand in sequence. For example,
-
-@example
-@group
-(seq (char-set char-set:alphabetic)
- (char-set char-set:numeric))
-@end group
-@end example
-
-@noindent
-matches an alphabetic character followed by a numeric character, such
-as @samp{H4}.
-
-Note that if there are no @var{mexp} operands, the @code{seq}
-expression successfully matches the null string.
-@end deffn
-
-@deffn {matcher expression} alt mexp @dots{}
-This attempts to match each @var{mexp} operand in order from left to
-right. The first one that successfully matches becomes the match for
-the entire @code{alt} expression.
-
-The @code{alt} expression participates in backtracking. If one of the
-@var{mexp} operands matches, but the overall match in which this
-expression is embedded fails, the backtracking mechanism will cause
-the @code{alt} expression to try the remaining @var{mexp} operands.
-For example, if the expression
-
-@example
-(seq (alt "ab" "a") "b")
-@end example
-
-@noindent
-is matched against the text @samp{abc}, the @code{alt} expression will
-initially match its first operand. But it will then fail to match the
-second operand of the @code{seq} expression. This will cause the
-@code{alt} to be restarted, at which time it will match @samp{a}, and
-the overall match will succeed.
-
-Note that if there are no @var{mexp} operands, the @code{alt} match
-will always fail.
-@end deffn
-
-@deffn {matcher expression} * mexp
-This matches zero or more occurrences of the @var{mexp} operand.
-(Consequently this match always succeeds.)
-
-The @code{*} expression participates in backtracking; if it matches
-@var{N} occurrences of @var{mexp}, but the overall match fails, it
-will backtrack to @var{N-1} occurrences and continue. If the overall
-match continues to fail, the @code{*} expression will continue to
-backtrack until there are no occurrences left.
-@end deffn
-
-@deffn {matcher expression} + mexp
-This matches one or more occurrences of the @var{mexp} operand. It is
-equivalent to
-
-@example
-(seq @var{mexp} (* @var{mexp}))
-@end example
-@end deffn
-
-@deffn {matcher expression} ? mexp
-This matches zero or one occurrences of the @var{mexp} operand. It is
-equivalent to
-
-@example
-(alt @var{mexp} (seq))
-@end example
-@end deffn
-
-@deffn {matcher expression} sexp expression
-The @code{sexp} expression allows arbitrary Scheme code to be embedded
-inside a matcher. The @var{expression} operand must evaluate to a
-matcher procedure at run time; the procedure is called to match the
-parser buffer. For example,
-
-@example
-@group
-(*matcher
- (seq "a"
- (sexp parse-foo)
- "b"))
-@end group
-@end example
-
-@noindent
-expands to
-
-@example
-@group
-(lambda (#[b1])
- (let ((#[p1] (get-parser-buffer-pointer #[b1])))
- (and (match-parser-buffer-char #[b1] #\a)
- (if (parse-foo #[b1])
- (if (match-parser-buffer-char #[b1] #\b)
- #t
- (begin
- (set-parser-buffer-pointer! #[b1] #[p1])
- #f))
- (begin
- (set-parser-buffer-pointer! #[b1] #[p1])
- #f)))))
-@end group
-@end example
-
-The case in which @var{expression} is a symbol is so common that it
-has an abbreviation: @samp{(sexp @var{symbol})} may be abbreviated as
-just @var{symbol}.
-@end deffn
-
-@deffn {matcher expression} with-pointer identifier mexp
-The @code{with-pointer} expression fetches the parser buffer's
-internal pointer (using @code{get-parser-buffer-pointer}), binds it to
-@var{identifier}, and then matches the pattern specified by
-@var{mexp}. @var{Identifier} must be a symbol.
-
-This is meant to be used on conjunction with @code{sexp}, as a way to
-capture a pointer to a part of the input stream that is outside the
-@code{sexp} expression. An example of the use of @code{with-pointer}
-appears above (@pxref{with-pointer example}).
-@end deffn
-
-@node *Parser, Parser-language Macros, *Matcher, Parser Language
-@subsection *Parser
-
-@cindex Parser language
-@cindex Parser procedure
-The @dfn{parser language} is a declarative language for specifying a
-@dfn{parser procedure}. A parser procedure is a procedure that
-accepts a single parser-buffer argument and parses some of the input
-from the buffer. If the parse is successful, the procedure returns a
-vector of objects that are the result of the parse, and the internal
-pointer of the parser buffer is advanced past the input that was
-parsed. If the parse fails, the procedure returns @code{#f} and the
-internal pointer is unchanged. This interface is much like that of a
-matcher procedure, except that on success the parser procedure returns
-a vector of values rather than @code{#t}.
-
-The @code{*parser} special form is the interface between the parser
-language and Scheme.
-
-@deffn {special form} *parser pexp
-The operand @var{pexp} is an expression in the parser language. The
-@code{*parser} expression expands into Scheme code that implements a
-parser procedure.
-@end deffn
-
-There are several primitive expressions in the parser language. The
-first two provide a bridge to the matcher language (@pxref{*Matcher}):
-
-@deffn {parser expression} match mexp
-The @code{match} expression performs a match on the parser buffer.
-The match to be performed is specified by @var{mexp}, which is an
-expression in the matcher language. If the match is successful, the
-result of the @code{match} expression is a vector of one element: a
-string containing that text.
-@end deffn
-
-@deffn {parser expression} noise mexp
-The @code{noise} expression performs a match on the parser buffer.
-The match to be performed is specified by @var{mexp}, which is an
-expression in the matcher language. If the match is successful, the
-result of the @code{noise} expression is a vector of zero elements.
-(In other words, the text is matched and then thrown away.)
-
-The @var{mexp} operand is often a known character or string, so in the
-case that @var{mexp} is a character or string literal, the
-@code{noise} expression can be abbreviated as the literal. In other
-words, @samp{(noise "foo")} can be abbreviated just @samp{"foo"}.
-@end deffn
-
-@deffn {parser expression} values expression @dots{}
-Sometimes it is useful to be able to insert arbitrary values into the
-parser result. The @code{values} expression supports this. The
-@var{expression} arguments are arbitrary Scheme expressions that are
-evaluated at run time and returned in a vector. The @code{values}
-expression always succeeds and never modifies the internal pointer of
-the parser buffer.
-@end deffn
-
-@deffn {parser expression} discard-matched
-The @code{discard-matched} expression always succeeds, returning a
-vector of zero elements. In all other respects it is identical to the
-@code{discard-matched} expression in the matcher language.
-@end deffn
-
-Next there are several combinator expressions. Parameters named
-@var{pexp} are arbitrary expressions in the parser language. The
-first few combinators are direct equivalents of those in the matcher
-language.
-
-@deffn {parser expression} seq pexp @dots{}
-The @code{seq} expression parses each of the @var{pexp} operands in
-order. If all of the @var{pexp} operands successfully match, the
-result is the concatenation of their values (by @code{vector-append}).
-@end deffn
-
-@deffn {parser expression} alt pexp @dots{}
-The @code{alt} expression attempts to parse each @var{pexp} operand in
-order from left to right. The first one that successfully parses
-produces the result for the entire @code{alt} expression.
-
-Like the @code{alt} expression in the matcher language, this
-expression participates in backtracking.
-@end deffn
-
-@deffn {parser expression} * pexp
-The @code{*} expression parses zero or more occurrences of @var{pexp}.
-The results of the parsed occurrences are concatenated together (by
-@code{vector-append}) to produce the expression's result.
-
-Like the @code{*} expression in the matcher language, this expression
-participates in backtracking.
-@end deffn
-
-@deffn {parser expression} + pexp
-The @code{*} expression parses one or more occurrences of @var{pexp}.
-It is equivalent to
-
-@example
-(seq @var{pexp} (* @var{pexp}))
-@end example
-@end deffn
-
-@deffn {parser expression} ? pexp
-The @code{*} expression parses zero or one occurrences of @var{pexp}.
-It is equivalent to
-
-@example
-(alt @var{pexp} (seq))
-@end example
-@end deffn
-
-The next three expressions do not have equivalents in the matcher
-language. Each accepts a single @var{pexp} argument, which is parsed
-in the usual way. These expressions perform transformations on the
-returned values of a successful match.
-
-@deffn {parser expression} transform expression pexp
-The @code{transform} expression performs an arbitrary transformation
-of the values returned by parsing @var{pexp}. @var{Expression} is a
-Scheme expression that must evaluate to a procedure at run time. If
-@var{pexp} is successfully parsed, the procedure is called with the
-vector of values as its argument, and must return a vector or
-@code{#f}. If it returns a vector, the parse is successful, and those
-are the resulting values. If it returns @code{#f}, the parse fails
-and the internal pointer of the parser buffer is returned to what it
-was before @var{pexp} was parsed.
-
-For example:
-
-@example
-(transform (lambda (v) (if (= 0 (vector-length v)) #f v)) @dots{})
-@end example
-@end deffn
-
-@deffn {parser expression} encapsulate expression pexp
-The @code{encapsulate} expression transforms the values returned by
-parsing @var{pexp} into a single value. @var{Expression} is a Scheme
-expression that must evaluate to a procedure at run time. If
-@var{pexp} is successfully parsed, the procedure is called with the
-vector of values as its argument, and may return any Scheme object.
-The result of the @code{encapsulate} expression is a vector of length
-one containing that object. (And consequently @code{encapsulate}
-doesn't change the success or failure of @var{pexp}, only its value.)
-
-For example:
-
-@example
-(encapsulate vector->list @dots{})
-@end example
-@end deffn
-
-@deffn {parser expression} map expression pexp
-The @code{map} expression performs a per-element transform on the
-values returned by parsing @var{pexp}. @var{Expression} is a Scheme
-expression that must evaluate to a procedure at run time. If
-@var{pexp} is successfully parsed, the procedure is mapped (by
-@code{vector-map}) over the values returned from the parse. The
-mapped values are returned as the result of the @code{map} expression.
-(And consequently @code{map} doesn't change the success or failure of
-@var{pexp}, nor the number of values returned.)
-
-For example:
-
-@example
-(map string->symbol @dots{})
-@end example
-@end deffn
-
-Finally, as in the matcher language, we have @code{sexp} and
-@code{with-pointer} to support embedding Scheme code in the parser.
-
-@deffn {parser expression} sexp expression
-The @code{sexp} expression allows arbitrary Scheme code to be embedded
-inside a parser. The @var{expression} operand must evaluate to a
-parser procedure at run time; the procedure is called to parse the
-parser buffer. This is the parser-language equivalent of the
-@code{sexp} expression in the matcher language.
-
-The case in which @var{expression} is a symbol is so common that it
-has an abbreviation: @samp{(sexp @var{symbol})} may be abbreviated as
-just @var{symbol}.
-@end deffn
-
-@deffn {parser expression} with-pointer identifier pexp
-The @code{with-pointer} expression fetches the parser buffer's
-internal pointer (using @code{get-parser-buffer-pointer}), binds it to
-@var{identifier}, and then parses the pattern specified by @var{pexp}.
-@var{Identifier} must be a symbol. This is the parser-language
-equivalent of the @code{with-pointer} expression in the matcher
-language.
-@end deffn
-
-@node Parser-language Macros, , *Parser, Parser Language
-@subsection Parser-language Macros
-
-The parser and matcher languages provide a macro facility so that
-common patterns can be abstracted. The macro facility allows new
-expression types to be independently defined in the two languages.
-The macros are defined in heirarchically organized tables, so that
-different applications can have private macro bindings.
-
-@deffn {special form} define-*matcher-macro formals expression
-@deffnx {special form} define-*parser-macro formals expression
-These special forms are used to define macros in the matcher and
-parser language, respectively. @var{Formals} is like the
-@var{formals} list of a @code{define} special form, and
-@var{expression} is a Scheme expression.
-
-If @var{formals} is a list (or improper list) of symbols, the first
-symbol in the list is the name of the macro, and the remaining symbols
-are interpreted as the @var{formals} of a lambda expression. A lambda
-expression is formed by combining the latter @var{formals} with the
-@var{expression}, and this lambda expression, when evaluated, becomes
-the @dfn{expander}. The defined macro accepts the same number of
-operands as the expander. A macro instance is expanded by applying
-the expander to the list of operands; the result of the application is
-interpreted as a replacement expression for the macro instance.
-
-If @var{formals} is a symbol, it is the name of the macro. In this
-case, the expander is a procedure of no arguments whose body is
-@var{expression}. When the @var{formals} symbol appears by itself as
-an expression in the language, the expander is called with no
-arguments, and the result is interpreted as a replacement expression
-for the symbol.
-@end deffn
-
-@deffn procedure define-*matcher-expander identifier expander
-@deffnx procedure define-*parser-expander identifier expander
-These procedures provide a procedural interface to the
-macro-definition mechanism. @var{Identifier} must be a symbol, and
-@var{expander} must be an expander procedure, as defined above.
-Instances of the @code{define-*matcher-macro} and
-@code{define-*parser-macro} special forms expand into calls to these
-procedures.
-@end deffn
-
-The remaining procedures define the interface to the parser-macros
-table abstraction. Each parser-macro table has a separate binding
-space for macros in the matcher and parser languages. However, the
-table inherits bindings from one specified table; it's not possible to
-inherit matcher-language bindings from one table and parser-language
-bindings from another.
-
-@deffn procedure make-parser-macros parent-table
-Create and return a new parser-macro table that inherits from
-@var{parent-table}. @var{Parent-table} must be either a parser-macro
-table, or @code{#f}; usually it is specified as the value of
-@code{global-parser-macros}.
-@end deffn
-
-@deffn procedure parser-macros? object
-This is a predicate for parser-macro tables.
-@end deffn
-
-@deffn procedure global-parser-macros
-Return the global parser-macro table. This table is predefined and
-contains all of the bindings documented here.
-@end deffn
-
-There is a ``current'' table at all times, and macro definitions are
-always placed in this table. By default, the current table is the
-global macro table, but the following procedures allow this to be
-changed.
-
-@deffn procedure current-parser-macros
-Return the current parser-macro table.
-@end deffn
-
-@deffn procedure set-current-parser-macros! table
-Change the current parser-macro table to @var{table}, which must
-satisfy @code{parser-macros?}.
-@end deffn
-
-@deffn procedure with-current-parser-macros table thunk
-Bind the current parser-macro table to @var{table}, call @var{thunk}
-with no arguments, then restore the original table binding. The value
-returned by @var{thunk} is the returned as the value of this
-procedure. @var{Table} must satisfy @code{parser-macros?}, and
-@var{thunk} must be a procedure of no arguments.
-@end deffn
-
-@node XML Parser, , Parser Language, Input/Output
-@section XML Parser
-
-@cindex XML parser
-@cindex parser, XML
-MIT/GNU Scheme provides a simple non-validating @acronym{XML} parser.
-This parser is mostly conformant, with the exception that it doesn't
-support @acronym{UTF-16}. The parser also does not support external
-document type declarations (@acronym{DTD}s). The output of the parser
-is a record tree that closely reflects the structure of the
-@acronym{XML} document.
-
-@cindex XML output
-@cindex output, XML
-There is also an output mechanism that writes an @acronym{XML} record
-tree to a port. There is no guarantee that parsing an @acronym{XML}
-document and writing it back out will make a verbatim copy of the
-document. The output will be semantically identical but may have
-small syntactic differences. For example, comments are discarded by
-the parser, and entities are substituted during the parsing process.
-
-The purpose of the @acronym{XML} support is to provide a mechanism for
-reading and writing simple @acronym{XML} documents. In the future
-this support may be further developed to support a standard interface
-such as @acronym{DOM} or @acronym{SAX}.
-
-@cindex run-time-loadable option
-@cindex option, run-time-loadable
-The @acronym{XML} support is a run-time-loadable option; to use it,
-execute
-
-@example
-(load-option 'xml)
-@end example
-@findex load-option
-
-@noindent
-once before compiling any code that uses it.
-
-The @acronym{XML} interface consists of an input procedure, an output
-procedure, and a set of record types.
-
-@deffn procedure parse-xml-document buffer
-This procedure parses an @acronym{XML} input stream and returns a
-newly-allocated @acronym{XML} record tree. The @var{buffer} argument
-must be a parser buffer (@pxref{Parser Buffers}). Most errors in the
-input stream are detected and signalled, with information identifying
-the location of the error where possible. Note that the input stream
-is assumed to be @acronym{UTF-8}.
-@end deffn
-
-@deffn procedure write-xml xml-document port
-This procedure writes an @acronym{XML} record tree to @var{port}. The
-@var{xml-document} argument must be a record of type
-@code{xml-document}, which is the root record of an @acronym{XML}
-record tree. The output is encoded in @acronym{UTF-8}.
-@end deffn
-
-@cindex XML names
-@cindex names, XML
-@acronym{XML} names are represented in memory as symbols. All symbols
-appearing within @acronym{XML} records are @acronym{XML} names.
-Because @acronym{XML} names are case sensitive, there is a procedure
-to intern these symbols:
-
-@deffn procedure xml-intern string
-@cindex XML name
-Returns the @acronym{XML} name called @var{string}. @acronym{XML}
-names are represented as symbols, but unlike ordinary Scheme symbols,
-they are case sensitive. The following is true for any two strings
-@var{string1} and @var{string2}:
-
-@example
-@group
-(let ((name1 (xml-intern @var{string1}))
- (name2 (xml-intern @var{string2})))
- (if (string=? @var{string1} @var{string2})
- (eq? name1 name2)
- (not (eq? name1 name2))))
-@end group
-@end example
-@end deffn
-
-The output from the @acronym{XML} parser and the input to the
-@acronym{XML} output procedure is a complex data structure composed of
-a heirarchy of typed components. Each component is a record whose
-fields correspond to parts of the @acronym{XML} structure that the
-record represents. There are no special operations on these records;
-each is a tuple with named subparts. The root record type is
-@code{xml-document}, which represents a complete @acronym{XML}
-document.
-
-Each record type @var{type} has the following associated bindings:
-
-@table @code
-@item <@var{type}>
-is a variable bound to the record-type descriptor for @var{type}. The
-record-type descriptor may be used as a specializer in @acronym{SOS}
-method definitions, which greatly simplifies code to dispatch on these
-types.
-
-@item @var{type}?
-is a predicate for records of type @var{type}. It accepts one
-argument, which can be any object, and returns @code{#t} if the object
-is a record of this type, or @code{#f} otherwise.
-
-@item make-@var{type}
-is a constructor for records of type @var{type}. It accepts one
-argument for each field of @var{type}, in the same order that they are
-written in the type description, and returns a newly-allocated record
-of that type.
-
-@item @var{type}-@var{field}
-is an accessor procedure for the field @var{field} in records of type
-@var{type}. It accepts one argument, which must be a record of that
-type, and returns the contents of the corresponding field in the
-record.
-
-@item set-@var{type}-@var{field}!
-is a modifier procedure for the field @var{field} in records of type
-@var{type}. It accepts two arguments: the first must be a record of
-that type, and the second is a new value for the corresponding field.
-The record's field is modified to have the new value.
-@end table
-
-@deftp {record type} xml-document declaration misc-1 dtd misc-2 root misc-3
-@vindex <xml-document>
-@findex xml-document?
-@findex make-xml-document
-@findex xml-document-declaration
-@findex xml-document-misc-1
-@findex xml-document-dtd
-@findex xml-document-misc-2
-@findex xml-document-root
-@findex xml-document-misc-3
-@findex set-xml-document-declaration!
-@findex set-xml-document-misc-1!
-@findex set-xml-document-dtd!
-@findex set-xml-document-misc-2!
-@findex set-xml-document-root!
-@findex set-xml-document-misc-3!
-The @code{xml-document} record is the top-level record representing a
-complete @acronym{XML} document. @var{Declaration} is either an
-@code{xml-declaration} object or @code{#f}. @var{Dtd} is either an
-@code{xml-dtd} object or @code{#f}. @var{Root} is an @code{xml-element}
-object. @var{Misc-1}, @var{misc-2}, and @var{misc-3} are lists of
-miscellaneous items; a miscellaneous item is either an
-@code{xml-comment} object, an @code{xml-processing-instructions} object,
-or a string of whitespace.
-@end deftp
-
-@deftp {record type} xml-declaration version encoding standalone
-@vindex <xml-declaration>
-@findex xml-declaration?
-@findex make-xml-declaration
-@findex xml-declaration-version
-@findex xml-declaration-encoding
-@findex xml-declaration-standalone
-@findex set-xml-declaration-version!
-@findex set-xml-declaration-encoding!
-@findex set-xml-declaration-standalone!
-The @code{xml-declaration} record represents the @samp{<?xml @dots{}
-?>} declaration that optionally appears at the beginning of an
-@acronym{XML} document. @var{Version} is a version string, typically
-@code{"1.0"}. @var{Encoding} is either an encoding string or
-@code{#f}. @var{Standalone} is either @code{"yes"}, @code{"no"}, or
-@code{#f}.
-@end deftp
-
-@deftp {record type} xml-element name attributes contents
-@vindex <xml-element>
-@findex xml-element?
-@findex make-xml-element
-@findex xml-element-name
-@findex xml-element-attributes
-@findex xml-element-contents
-@findex set-xml-element-name!
-@findex set-xml-element-attributes!
-@findex set-xml-element-contents!
-The @code{xml-element} record represents general @acronym{XML}
-elements; the bulk of a typical @acronym{XML} document consists of
-these elements. @var{Name} is the element name (a symbol).
-@var{Attributes} is a list of attributes; each attribute is a pair
-whose @sc{car} is the attribute name (a symbol), and whose @sc{cdr} is
-the attribute value (a string). @var{Contents} is a list of the
-contents of the element. Each element of this list is either a
-string, an @code{xml-element} record, an
-@code{xml-processing-instructions} record, or an
-@code{xml-uninterpreted} record.
-@end deftp
-
-@deftp {record type} xml-processing-instructions name text
-@vindex <xml-processing-instructions>
-@findex xml-processing-instructions?
-@findex make-xml-processing-instructions
-@findex xml-processing-instructions-name
-@findex xml-processing-instructions-text
-@findex set-xml-processing-instructions-name!
-@findex set-xml-processing-instructions-text!
-The @code{xml-processing-instructions} record represents processing
-instructions, which have the form @samp{<?@var{name} @dots{} ?>}.
-These instructions are intended to contain non-@acronym{XML} data that
-will be processed by another interpreter; for example they might
-contain @acronym{PHP} programs. The @var{name} field is the processor
-name (a symbol), and the @var{text} field is the body of the
-instructions (a string).
-@end deftp
-
-@deftp {record type} xml-uninterpreted text
-@vindex <xml-uninterpreted>
-@findex xml-uninterpreted?
-@findex make-xml-uninterpreted
-@findex xml-uninterpreted-text
-@findex set-xml-uninterpreted-text!
-Some documents contain entity references that can't be expanded by the
-parser, perhaps because the document requires an external
-@acronym{DTD}. Such references are left uninterpreted in the output
-by wrapping them in @code{xml-uninterpreted} records. In some
-situations, for example when they are embedded in attribute values,
-the surrounding text is also included in the @code{xml-uninterpreted}
-record. The @var{text} field contains the uninterpreted @acronym{XML}
-text (a string).
-@end deftp
-
-@deftp {record type} xml-dtd root external internal
-@vindex <xml-dtd>
-@findex xml-dtd?
-@findex make-xml-dtd
-@findex xml-dtd-root
-@findex xml-dtd-external
-@findex xml-dtd-internal
-@findex set-xml-dtd-root!
-@findex set-xml-dtd-external!
-@findex set-xml-dtd-internal!
-The @code{xml-dtd} record represents a document type declaration. The
-@var{root} field is an @acronym{XML} name for the root element of the
-document. @var{External} is either an @code{xml-external-id} record
-or @code{#f}. @var{Internal} is a list of @acronym{DTD} element
-records (e.g.@: @code{xml-!element}, @code{xml-!attlist}, etc.).
-@end deftp
-
-The remaining record types are valid only within a @acronym{DTD}.
-
-@deftp {record type} xml-!element name content-type
-@vindex <xml-!element>
-@findex xml-!element?
-@findex make-xml-!element
-@findex xml-!element-name
-@findex xml-!element-content-type
-@findex set-xml-!element-name!
-@findex set-xml-!element-content-type!
-The @code{xml-!element} record represents an element-type
-declaration. @var{Name} is the @acronym{XML} name of the type being
-declared (a symbol). @var{Content-type} describes the type and can
-have several different values, as follows:
-
-@itemize @bullet
-@item
-The @acronym{XML} names @samp{EMPTY} and @samp{ANY} correspond to the
-@acronym{XML} keywords of the same name.
-
-@item
-A list @samp{(MIX @var{type} @dots{})} corresponds to the
-@samp{(#PCDATA | @var{type} | @dots{})} syntax.
-@end itemize
-@end deftp
-
-@deftp {record type} xml-!attlist name definitions
-@vindex <xml-!attlist>
-@findex xml-!attlist?
-@findex make-xml-!attlist
-@findex xml-!attlist-name
-@findex xml-!attlist-definitions
-@findex set-xml-!attlist-name!
-@findex set-xml-!attlist-definitions!
-The @code{xml-!attlist} record represents an attribute-list
-declaration. @var{Name} is the @acronym{XML} name of the type for
-which attributes are being declared (a symbol). @var{Definitions} is
-a list of attribute definitions, each of which is a list of three
-elements @code{(@var{name} @var{type} @var{default})}. @var{Name} is
-an @acronym{XML} name for the name of the attribute (a symbol).
-@var{Type} describes the attribute type, and can have one of the
-following values:
-
-@itemize @bullet
-@item
-The @acronym{XML} names @samp{CDATA}, @samp{IDREFS}, @samp{IDREF},
-@samp{ID}, @samp{ENTITY}, @samp{ENTITIES}, @samp{NMTOKENS}, and
-@samp{NMTOKEN} correspond to the @acronym{XML} keywords of the same
-names.
-
-@item
-A list @samp{(NOTATION @var{name1} @var{name2} @dots{})} corresponds
-to the @samp{NOTATION (@var{name1} | @var{name2} @dots{})} syntax.
-
-@item
-A list @samp{(ENUMERATED @var{name1} @var{name2} @dots{})} corresponds
-to the @samp{(@var{name1} | @var{name2} @dots{})} syntax.
-@end itemize
-
-@var{Default} describes the default value for the attribute, and can
-have one of the following values:
-
-@itemize @bullet
-@item
-The @acronym{XML} names @samp{#REQUIRED} and @samp{#IMPLIED}
-correspond to the @acronym{XML} keywords of the same names.
-
-@item
-A list @samp{(#FIXED @var{value})} corresponds to the @samp{#FIXED
-"@var{value}"} syntax. @var{Value} is represented as a string, but
-might also be an @code{xml-uninterpreted} record.
-
-@item
-A list @samp{(DEFAULT @var{value})} corresponds to the
-@samp{"@var{value}"} syntax. @var{Value} is represented as a string,
-but might also be an @code{xml-uninterpreted} record.
-@end itemize
-@end deftp
-
-@deftp {record type} xml-!entity name value
-@vindex <xml-!entity>
-@findex xml-!entity?
-@findex make-xml-!entity
-@findex xml-!entity-name
-@findex xml-!entity-value
-@findex set-xml-!entity-name!
-@findex set-xml-!entity-value!
-The @code{xml-!entity} record represents a general entity
-declaration. @var{Name} is an @acronym{XML} name for the entity.
-@var{Value} is the entity's value, either a string, an
-@code{xml-uninterpreted} record, or an @code{xml-external-id} record.
-@end deftp
-
-@deftp {record type} xml-parameter-!entity name value
-@vindex <xml-parameter-!entity>
-@findex xml-parameter-!entity?
-@findex make-xml-parameter-!entity
-@findex xml-parameter-!entity-name
-@findex xml-parameter-!entity-value
-@findex set-xml-parameter-!entity-name!
-@findex set-xml-parameter-!entity-value!
-The @code{xml-parameter-!entity} record represents a parameter entity
-declaration. @var{Name} is an @acronym{XML} name for the entity.
-@var{Value} is the entity's value, either a string, an
-@code{xml-uninterpreted} record, or an @code{xml-external-id} record.
-@end deftp
-
-@deftp {record type} xml-unparsed-!entity name id notation
-@vindex <xml-unparsed-!entity>
-@findex xml-unparsed-!entity?
-@findex make-xml-unparsed-!entity
-@findex xml-unparsed-!entity-name
-@findex xml-unparsed-!entity-id
-@findex xml-unparsed-!entity-notation
-@findex set-xml-unparsed-!entity-name!
-@findex set-xml-unparsed-!entity-id!
-@findex set-xml-unparsed-!entity-notation!
-The @code{xml-unparsed-!entity} record represents an unparsed entity
-declaration. @code{Name} is an @acronym{XML} name for the entity.
-@var{Id} is an @code{xml-external-id} record. @var{Notation} is an
-@acronym{XML} name for the notation.
-@end deftp
-
-@deftp {record type} xml-!notation name id
-@vindex <xml-!notation>
-@findex xml-!notation?
-@findex make-xml-!notation
-@findex xml-!notation-name
-@findex xml-!notation-id
-@findex set-xml-!notation-name!
-@findex set-xml-!notation-id!
-The @code{xml-!notation} record represents a notation declaration.
-@code{Name} is an @acronym{XML} name for the notation. @var{Id} is an
-@code{xml-external-id} record.
-@end deftp
-
-@deftp {record type} xml-external-id id uri
-@vindex <xml-external-id>
-@findex xml-external-id?
-@findex make-xml-external-id
-@findex xml-external-id-id
-@findex xml-external-id-uri
-@findex set-xml-external-id-id!
-@findex set-xml-external-id-uri!
-The @code{xml-external-id} record is a reference to an external
-@acronym{DTD}. This reference consists of two parts: @var{id} is a
-public @acronym{ID} literal, corresponding to the @samp{PUBLIC}
-keyword, while @var{uri} is a system literal, corresponding to the
-@samp{SYSTEM} keyword. Either or both may be present, depending on
-the context. Each is represented as a string.
-@end deftp
-
-@node Operating-System Interface, Error System, Input/Output, Top
-@chapter Operating-System Interface
-@cindex Operating-System Interface
-
-The Scheme standard provides a simple mechanism for reading and writing
-files: file ports. MIT/GNU Scheme provides additional tools for
-dealing with other aspects of the operating system:
-
-@itemize @bullet
-@item
-@dfn{Pathnames} are a reasonably operating-system independent tool for
-manipulating the component parts of file names. This can be useful for
-implementing defaulting of file name components.
-@cindex pathname
-
-@item
-Control over the @dfn{current working directory}: the place in the file
-system from which relative file names are interpreted.
-@cindex current working directory
-
-@item
-Procedures that rename, copy, delete, and test for the existence of
-files. Also, procedures that return detailed information about a
-particular file, such as its type (directory, link, etc.) or length.
-
-@item
-Procedures for reading the contents of a directory.
-
-@item
-Procedures for obtaining times in various formats, converting between
-the formats, and generating human-readable time strings.
-
-@item
-Procedures to run other programs as subprocesses of Scheme, to read
-their output, and write input to them.
-
-@item
-A means to determine the operating system Scheme is running under.
-@end itemize
-
-@menu
-* Pathnames::
-* Working Directory::
-* File Manipulation::
-* Directory Reader::
-* Date and Time::
-* Machine Time::
-* Subprocesses::
-* TCP Sockets::
-* Miscellaneous OS Facilities::
-@end menu
-
-@node Pathnames, Working Directory, Operating-System Interface, Operating-System Interface
-@section Pathnames
-
-@comment **** begin CLTL ****
-@cindex file name
-MIT/GNU Scheme programs need to use names to designate files. The main
-difficulty in dealing with names of files is that different file systems
-have different naming formats for files. For example, here is a table
-of several file systems (actually, operating systems that provide file
-systems) and what equivalent file names might look like for each one:
-
-@example
-@group
-System File Name
------- ---------
-TOPS-20 <LISPIO>FORMAT.FASL.13
-TOPS-10 FORMAT.FAS[1,4]
-ITS LISPIO;FORMAT FASL
-MULTICS >udd>LispIO>format.fasl
-TENEX <LISPIO>FORMAT.FASL;13
-VAX/VMS [LISPIO]FORMAT.FAS;13
-UNIX /usr/lispio/format.fasl
-DOS C:\USR\LISPIO\FORMAT.FAS
-@end group
-@end example
-
-@cindex filename (defn)
-@cindex pathname (defn)
-It would be impossible for each program that deals with file names to
-know about each different file name format that exists; a new operating
-system to which Scheme was ported might use a format different from any
-of its predecessors. Therefore, MIT/GNU Scheme provides @emph{two} ways to
-represent file names: @dfn{filenames} (also called @dfn{namestrings}),
-which are strings in the implementation-dependent form customary for the
-file system, and @dfn{pathnames}, which are special abstract data
-objects that represent file names in an implementation-independent way.
-Procedures are provided to convert between these two representations,
-and all manipulations of files can be expressed in machine-independent
-terms by using pathnames.
-
-@cindex host, in filename
-In order to allow MIT/GNU Scheme programs to operate in a network
-environment that may have more than one kind of file system, the
-pathname facility allows a file name to specify which file system is to
-be used. In this context, each file system is called a @dfn{host}, in
-keeping with the usual networking terminology.@footnote{This
-introduction is adapted from @cite{Common Lisp, The Language}, second
-edition, section 23.1.}
-@comment **** end CLTL ****
-
-Note that the examples given in this section are specific to unix
-pathnames. Pathnames for other operating systems have different
-external representations.
-
-@menu
-* Filenames and Pathnames::
-* Components of Pathnames::
-* Operations on Pathnames::
-* Miscellaneous Pathnames::
-@end menu
-
-@node Filenames and Pathnames, Components of Pathnames, Pathnames, Pathnames
-@subsection Filenames and Pathnames
-
-Pathname objects are usually created by parsing filenames (character
-strings) into component parts. MIT/GNU Scheme provides operations that
-convert filenames into pathnames and vice versa.
-
-@deffn procedure ->pathname object
-@cindex construction, of pathname
-Returns a pathname that is the equivalent of @var{object}. @var{Object}
-must be a pathname or a string. If @var{object} is a pathname, it is
-returned. If @var{object} is a string, this procedure returns the
-pathname that corresponds to the string; in this case it is equivalent
-to @code{(parse-namestring @var{object} #f #f)}.
-
-@example
-@group
-(->pathname "foo") @result{} #[pathname 65 "foo"]
-(->pathname "/usr/morris") @result{} #[pathname 66 "/usr/morris"]
-@end group
-@end example
-@end deffn
-
-
-@deffn procedure parse-namestring thing [host [defaults]]
-@cindex construction, of pathname
-This turns @var{thing} into a pathname.
-@var{Thing} must be a pathname or a string.
-If @var{thing} is a pathname, it is returned. If @var{thing} is a
-string, this procedure returns the pathname that corresponds to the
-string, parsed according to the syntax of the file system specified by
-@var{host}.
-
-This procedure @emph{does not} do defaulting of pathname components.
-
-The optional arguments are used to determine what syntax should be used
-for parsing the string. In general this is only really useful if your
-implementation of MIT/GNU Scheme supports more than one file system,
-otherwise you would use @code{->pathname}. If given, @var{host} must be
-a host object or @code{#f}, and @var{defaults} must be a pathname.
-@var{Host} specifies the syntax used to parse the string. If @var{host}
-is not given or @code{#f}, the host component from @var{defaults} is
-used instead; if @var{defaults} is not given, the host component from
-@code{*default-pathname-defaults*} is used.
-@end deffn
-
-@deffn procedure ->namestring pathname
-@cindex conversion, pathname to string
-@code{->namestring} returns a newly allocated string that is the
-filename corresponding to @var{pathname}.
-@example
-@group
-(->namestring (->pathname "/usr/morris/minor.van"))
- @result{} "/usr/morris/minor.van"
-@end group
-@end example
-@end deffn
-
-
-@deffn procedure pathname-simplify pathname
-@cindex simplification, of pathname
-Returns a pathname that locates the same file or directory as
-@var{pathname}, but is in some sense simpler. Note that
-@code{pathname-simplify} might not always be able to simplify the
-pathname, e.g.@: on unix with symbolic links the directory
-@file{/usr/morris/../} need not be the same as @file{/usr/}. In cases
-of uncertainty the behavior is conservative, returning the original or a
-partly simplified pathname.
-
-@example
-@group
-(pathname-simplify "/usr/morris/../morris/dance")
- @result{} #[pathname "/usr/morris/dance"]
-@end group
-@end example
-@end deffn
-
-@node Components of Pathnames, Operations on Pathnames, Filenames and Pathnames, Pathnames
-@subsection Components of Pathnames
-@cindex components, of pathname
-@cindex pathname components
-
-@comment **** begin CLTL ****
-A pathname object always has six components, described below. These
-components are the common interface that allows programs to work the
-same way with different file systems; the mapping of the pathname
-components into the concepts peculiar to each file system is taken care
-of by the Scheme implementation.
-
-@table @var
-@item host
-The name of the file system on which the file resides. In the current
-implementation, this component is always a host object that is filled in
-automatically by the runtime system. When specifying the host
-component, use either @code{#f} or the value of the variable
-@code{local-host}.
-@cindex host, pathname component
-
-@item device
-Corresponds to the ``device'' or ``file structure'' concept in many host
-file systems: the name of a (logical or physical) device containing
-files. This component is the drive letter for PC file systems, and is
-unused for unix file systems.
-@cindex device, pathname component
-
-@item directory
-Corresponds to the ``directory'' concept in many host file systems: the
-name of a group of related files (typically those belonging to a single
-user or project). This component is always used for all file systems.
-@cindex directory, pathname component
-
-@item name
-The name of a group of files that can be thought of as conceptually the
-``same'' file. This component is always used for all file systems.
-@cindex name, pathname component
-
-@item type
-Corresponds to the ``filetype'' or ``extension'' concept in many host
-file systems. This says what kind of file this is. Files with the same
-name but different type are usually related in some specific way, such
-as one being a source file, another the compiled form of that source,
-and a third the listing of error messages from the compiler. This
-component is currently used for all file systems, and is formed by
-taking the characters that follow the last dot in the namestring.
-@cindex type, pathname component
-
-@item version
-Corresponds to the ``version number'' concept in many host file systems.
-Typically this is a number that is incremented every time the file is
-modified. This component is currently unused for all file systems.
-@cindex version, pathname component
-@end table
-
-Note that a pathname is not necessarily the name of a specific file.
-Rather, it is a specification (possibly only a partial specification) of
-how to access a file. A pathname need not correspond to any file that
-actually exists, and more than one pathname can refer to the same file.
-For example, the pathname with a version of @code{newest} may refer to
-the same file as a pathname with the same components except a certain
-number as the version. Indeed, a pathname with version @code{newest}
-may refer to different files as time passes, because the meaning of such
-a pathname depends on the state of the file system. In file systems
-with such facilities as ``links'', multiple file names, logical devices,
-and so on, two pathnames that look quite different may turn out to
-address the same file. To access a file given a pathname, one must do a
-file-system operation such as @code{open-input-file}.
-
-Two important operations involving pathnames are @dfn{parsing} and
-@dfn{merging}. Parsing is the conversion of a filename (which might be
-something supplied interactively by the users when asked to supply the
-name of a file) into a pathname object. This operation is
-implementation-dependent, because the format of filenames is
-implementation-dependent. Merging takes a pathname with missing
-components and supplies values for those components from a source of
-default values.
-
-Not all of the components of a pathname need to be specified. If a
-component of a pathname is missing, its value is @code{#f}.
-Before the file system interface can do anything interesting with a
-file, such as opening the file, all the missing components of a pathname
-must be filled in. Pathnames with missing components are used
-internally for various purposes; in particular, parsing a namestring
-that does not specify certain components will result in a pathname with
-missing components.
-
-Any component of a pathname may be the symbol @code{unspecific}, meaning
-that the component simply does not exist, for file systems in which such
-a value makes no sense. For example, unix, Windows, and OS/2 file
-systems usually do not support version numbers, so the version component
-for such a host might be @code{unspecific}.@footnote{This description is
-adapted from @cite{Common Lisp, The Language}, second edition, section
-23.1.1.}
-@comment **** end CLTL ****
-
-In addition to @code{#f} and @code{unspecific}, the components of a
-pathname may take on the following meaningful values:
-
-@table @var
-@item host
-An implementation-defined type which may be tested for using the
-@code{host?} predicate.
-
-@item device
-On systems that support this component (Windows and OS/2), it may be
-specified as a string containing a single alphabetic character, for
-which the alphabetic case is ignored.
-
-@item directory
-A non-empty list, which represents a @dfn{directory path}: a sequence of
-directories, each of which has a name in the previous directory, the
-last of which is the directory specified by the entire path. Each
-element in such a path specifies the name of the directory relative to
-the directory specified by the elements to its left. The first element
-of the list is either the symbol @code{absolute} or the symbol
-@code{relative}. If the first element in the list is the symbol
-@code{absolute}, then the directory component (and subsequently the
-pathname) is @dfn{absolute}; the first component in the sequence is to
-be found at the ``root'' of the file system. If the directory is
-@dfn{relative} then the first component is to be found in some as yet
-unspecified directory; typically this is later specified to be the
-@dfn{current working directory}.
-@cindex root, as pathname component
-@cindex directory path (defn)
-@cindex path, directory (defn)
-
-@cindex up, as pathname component
-@cindex parent, of directory
-Aside from @code{absolute} and @code{relative}, which may only appear as
-the first element of the list, each subsequent element in the list is
-either: a string, which is a literal component; the symbol @code{wild},
-meaningful only when used in conjunction with the directory reader; or
-the symbol @code{up}, meaning the next directory is the ``parent'' of
-the previous one. @code{up} corresponds to the file @file{..} in unix
-and PC file systems.
-
-(The following note does not refer to any file system currently
-supported by MIT/GNU Scheme, but is included for completeness.) In file
-systems that do not have ``hierarchical'' structure, a specified
-directory component will always be a list whose first element is
-@code{absolute}. If the system does not support directories other than
-a single global directory, the list will have no other elements. If the
-system supports ``flat'' directories, i.e.@: a global set of directories
-with no subdirectories, then the list will contain a second element,
-which is either a string or @code{wild}. In other words, a
-non-hierarchical file system is treated as if it were hierarchical, but
-the hierarchical features are unused. This representation is somewhat
-inconvenient for such file systems, but it discourages programmers from
-making code depend on the lack of a file hierarchy.
-
-@item name
-A string, which is a literal component; or the symbol @code{wild},
-meaningful only when used in conjunction with the directory reader.
-
-@item type
-A string, which is a literal component; or the symbol @code{wild},
-meaningful only when used in conjunction with the directory reader.
-
-@item version
-An exact positive integer, which is a literal component; the symbol
-@code{newest}, which means to choose the largest available version
-number for that file; the symbol @code{oldest}, which means to choose
-the smallest version number; or the symbol @code{wild}, meaningful only
-when used in conjunction with the directory reader. In the future some
-other possible values may be added, e.g.@: @code{installed}. Note that
-currently no file systems support version numbers; thus this component
-is not used and should be specified as @code{#f}.
-@cindex newest, as pathname component
-@cindex oldest, as pathname component
-@cindex installed, as pathname component
-@end table
-
-@deffn procedure make-pathname host device directory name type version
-@cindex construction, of pathname
-Returns a pathname object whose components are the respective arguments.
-Each argument must satisfy the restrictions for the corresponding
-component, which were outlined above.
-
-@example
-@group
-(make-pathname #f
- #f
- '(absolute "usr" "morris")
- "foo"
- "scm"
- #f)
- @result{} #[pathname 67 "/usr/morris/foo.scm"]
-@end group
-@end example
-@end deffn
-
-@deffn procedure pathname-host pathname
-@deffnx procedure pathname-device pathname
-@deffnx procedure pathname-directory pathname
-@deffnx procedure pathname-name pathname
-@deffnx procedure pathname-type pathname
-@deffnx procedure pathname-version pathname
-Returns a particular component of @var{pathname}.
-
-@example
-@group
-(define x (->pathname "/usr/morris/foo.scm"))
-(pathname-host x) @result{} #[host 1]
-(pathname-device x) @result{} unspecific
-(pathname-directory x) @result{} (absolute "usr" "morris")
-(pathname-name x) @result{} "foo"
-(pathname-type x) @result{} "scm"
-(pathname-version x) @result{} unspecific
-@end group
-@end example
-@end deffn
-
-@deffn procedure pathname-new-device pathname device
-@deffnx procedure pathname-new-directory pathname directory
-@deffnx procedure pathname-new-name pathname name
-@deffnx procedure pathname-new-type pathname type
-@deffnx procedure pathname-new-version pathname version
-Returns a new copy of @var{pathname} with the respective component
-replaced by the second argument. @var{Pathname} is unchanged.
-Portable programs should not explicitly replace a component with
-@code{unspecific} because this might not be permitted in some
-situations.
-
-@example
-@group
-(define p (->pathname "/usr/blisp/rel15"))
-p
- @result{} #[pathname 71 "/usr/blisp/rel15"]
-(pathname-new-name p "rel100")
- @result{} #[pathname 72 "/usr/blisp/rel100"]
-(pathname-new-directory p '(relative "test" "morris"))
- @result{} #[pathname 73 "test/morris/rel15"]
-p
- @result{} #[pathname 71 "/usr/blisp/rel15"]
-@end group
-@end example
-@end deffn
-
-@deffn procedure pathname-default-device pathname device
-@deffnx procedure pathname-default-directory pathname directory
-@deffnx procedure pathname-default-name pathname name
-@deffnx procedure pathname-default-type pathname type
-@deffnx procedure pathname-default-version pathname version
-These operations are similar to the @code{pathname-new-@var{component}}
-operations, except that they only change the specified @var{component}
-if it has the value @code{#f} in @var{pathname}.
-@end deffn
-
-@node Operations on Pathnames, Miscellaneous Pathnames, Components of Pathnames, Pathnames
-@subsection Operations on Pathnames
-
-@deffn procedure pathname? object
-@cindex type predicate, for pathname
-Returns @code{#t} if @var{object} is a pathname; otherwise returns
-@code{#f}.
-@end deffn
-
-@deffn procedure pathname=? pathname1 pathname2
-@cindex equivalence predicate, for pathnames
-Returns @code{#t} if @var{pathname1} is equivalent to @var{pathname2};
-otherwise returns @code{#f}.
-Pathnames are equivalent if all of their components are equivalent,
-hence two pathnames that are equivalent must identify the same file or
-equivalent partial pathnames.
-However, the converse is not true: non-equivalent pathnames may specify
-the same file (e.g.@: via absolute and relative directory components),
-and pathnames that specify no file at all (e.g.@: name and directory
-components unspecified) may be equivalent.
-@end deffn
-
-@deffn procedure pathname-absolute? pathname
-Returns @code{#t} if @var{pathname} is an absolute rather than relative
-pathname object; otherwise returns @code{#f}. Specifically, this
-procedure returns @code{#t} when the directory component of
-@var{pathname} is a list starting with the symbol @code{absolute}, and
-returns @code{#f} in all other cases. All pathnames are either absolute
-or relative, so if this procedure returns @code{#f}, the argument is a
-relative pathname.
-@end deffn
-
-@deffn procedure directory-pathname? pathname
-Returns @code{#t} if @var{pathname} has only directory components and no
-file components. This is roughly equivalent to
-
-@example
-@group
-(define (directory-pathname? pathname)
- (string-null? (file-namestring pathname)))
-@end group
-@end example
-
-@noindent
-except that it is faster.
-@end deffn
-
-@deffn procedure pathname-wild? pathname
-Returns @code{#t} if @var{pathname} contains any wildcard components;
-otherwise returns @code{#f}.
-@end deffn
-
-@deffn procedure merge-pathnames pathname [defaults [default-version]]
-@cindex merging, of pathnames
-@cindex defaulting, of pathname
-Returns a pathname whose components are obtained by combining those of
-@var{pathname} and @var{defaults}. @var{Defaults} defaults to the value
-of @code{*default-pathname-defaults*} and @var{default-version} defaults
-to @code{newest}.
-
-The pathnames are combined by components: if @var{pathname} has a
-non-missing component, that is the resulting component, otherwise the
-component from @var{defaults} is used.
-The default version can be @code{#f} to preserve the information that
-the component was missing from @var{pathname}.
-The directory component is handled specially: if both pathnames have
-directory components that are lists, and the directory component from
-@var{pathname} is relative (i.e.@: starts with @code{relative}), then the
-resulting directory component is formed by appending @var{pathname}'s
-component to @var{defaults}'s component.
-For example:
-
-@example
-@group
-(define path1 (->pathname "scheme/foo.scm"))
-(define path2 (->pathname "/usr/morris"))
-path1
- @result{} #[pathname 74 "scheme/foo.scm"]
-path2
- @result{} #[pathname 75 "/usr/morris"]
-(merge-pathnames path1 path2)
- @result{} #[pathname 76 "/usr/scheme/foo.scm"]
-(merge-pathnames path2 path1)
- @result{} #[pathname 77 "/usr/morris.scm"]
-@end group
-@end example
-
-The merging rules for the version are more complex and depend on whether
-@var{pathname} specifies a name. If @var{pathname} does not specify a
-name, then the version, if not provided, will come from @var{defaults}.
-However, if @var{pathname} does specify a name then the version is not
-affected by @var{defaults}. The reason is that the version ``belongs
-to'' some other file name and is unlikely to have anything to do with
-the new one. Finally, if this process leaves the version missing, then
-@var{default-version} is used.
-
-The net effect is that if the user supplies just a name, then the host,
-device, directory and type will come from @var{defaults}, but the
-version will come from @var{default-version}. If the user supplies
-nothing, or just a directory, the name, type and version will come over
-from @var{defaults} together.
-@end deffn
-
-@defvr variable *default-pathname-defaults*
-@cindex defaulting, of pathname
-This is the default pathname-defaults pathname; if any pathname
-primitive that needs a set of defaults is not given one, it uses this
-one. @code{set-working-directory-pathname!} sets this variable to a new
-value, computed by merging the new working directory with the variable's
-old value.
-@end defvr
-
-@deffn procedure pathname-default pathname device directory name type version
-This procedure defaults all of the components of @var{pathname}
-simultaneously. It could have been defined by:
-
-@example
-@group
-(define (pathname-default pathname
- device directory name type version)
- (make-pathname (pathname-host pathname)
- (or (pathname-device pathname) device)
- (or (pathname-directory pathname) directory)
- (or (pathname-name pathname) name)
- (or (pathname-type pathname) type)
- (or (pathname-version pathname) version)))
-@end group
-@end example
-@end deffn
-
-@deffn procedure file-namestring pathname
-@deffnx procedure directory-namestring pathname
-@deffnx procedure host-namestring pathname
-@deffnx procedure enough-namestring pathname [defaults]
-@cindex conversion, pathname to string
-These procedures return a string corresponding to a subset of the
-@var{pathname} information. @code{file-namestring} returns a string
-representing just the @var{name}, @var{type} and @var{version}
-components of @var{pathname}; the result of @code{directory-namestring}
-represents just the @var{host}, @var{device}, and @var{directory}
-components; and @code{host-namestring} returns a string for just the
-@var{host} portion.
-
-@code{enough-namestring} takes another argument, @var{defaults}.
-It returns an abbreviated namestring that is just sufficient to identify
-the file named by @var{pathname} when considered relative to the
-@var{defaults} (which defaults to @code{*default-pathname-defaults*}).
-
-@example
-@group
-(file-namestring "/usr/morris/minor.van")
- @result{} "minor.van"
-(directory-namestring "/usr/morris/minor.van")
- @result{} "/usr/morris/"
-(enough-namestring "/usr/morris/men")
- @result{} "men" @r{;perhaps}
-@end group
-@end example
-@end deffn
-
-@deffn procedure file-pathname pathname
-@deffnx procedure directory-pathname pathname
-@deffnx procedure enough-pathname pathname [defaults]
-@cindex selection, components of pathname
-These procedures return a pathname corresponding to a subset of the
-@var{pathname} information.
-@code{file-pathname} returns a pathname with just the
-@var{name}, @var{type} and @var{version} components of @var{pathname}.
-The result of @code{directory-pathname} is a pathname containing the
-@var{host}, @var{device} and @var{directory} components of @var{pathname}.
-
-@code{enough-pathname} takes another argument, @var{defaults}.
-It returns an abbreviated pathname that is just sufficient to identify
-the file named by @var{pathname} when considered relative to the
-@var{defaults} (which defaults to @code{*default-pathname-defaults*}).
-
-These procedures are similar to @code{file-namestring},
-@code{directory-namestring} and @code{enough-namestring}, but they
-return pathnames instead of strings.
-@end deffn
-
-@deffn procedure directory-pathname-as-file pathname
-@cindex file, converting pathname directory to
-Returns a pathname that is equivalent to @var{pathname}, but in which
-the directory component is represented as a file.
-The last directory is removed from the directory component and converted
-into name and type components.
-This is the inverse operation to @code{pathname-as-directory}.
-
-@example
-@group
-(directory-pathname-as-file (->pathname "/usr/blisp/"))
- @result{} #[pathname "/usr/blisp"]
-@end group
-@end example
-@end deffn
-
-@deffn procedure pathname-as-directory pathname
-@cindex directory, converting pathname to
-Returns a pathname that is equivalent to @var{pathname}, but in which
-any file components have been converted to a directory component. If
-@var{pathname} does not have name, type, or version components, it is
-returned without modification. Otherwise, these file components are
-converted into a string, and the string is added to the end of the list
-of directory components. This is the inverse operation to
-@code{directory-pathname-as-file}.
-
-@example
-@group
-(pathname-as-directory (->pathname "/usr/blisp/rel5"))
- @result{} #[pathname "/usr/blisp/rel5/"]
-@end group
-@end example
-@end deffn
-
-
-@node Miscellaneous Pathnames, , Operations on Pathnames, Pathnames
-@subsection Miscellaneous Pathname Procedures
-@cindex directory, reading
-
-This section gives some standard operations on host objects, and some
-procedures that return some useful pathnames.
-
-@defvr variable local-host
-This variable has as its value the host object that describes the local
-host's file system.
-@end defvr
-
-@deffn procedure host? object
-@cindex type predicate, for pathname host
-Returns @code{#t} if @var{object} is a pathname host; otherwise returns
-@code{#f}.
-@end deffn
-
-@deffn procedure host=? host1 host2
-@cindex equivalence predicate, for pathname host
-Returns @code{#t} if @var{host1} and @var{host2} denote the same
-pathname host; otherwise returns @code{#f}.
-@end deffn
-
-@deffn procedure init-file-pathname [host]
-@cindex home directory, as pathname
-Returns a pathname for the user's initialization file on @var{host}.
-The @var{host} argument defaults to the value of @code{local-host}. If
-the initialization file does not exist this procedure returns @code{#f}.
-
-Under unix, the init file is called @file{.scheme.init}; under Windows
-and OS/2, the init file is called @file{scheme.ini}. In either
-case, it is located in the user's home directory, which is computed by
-@code{user-homedir-pathname}.
-@end deffn
-
-@deffn procedure user-homedir-pathname [host]
-@cindex home directory, as pathname
-Returns a pathname for the user's ``home directory'' on @var{host}. The
-@var{host} argument defaults to the value of @code{local-host}. The
-concept of a ``home directory'' is itself somewhat
-implementation-dependent, but it should be the place where the user
-keeps personal files, such as initialization files and mail.
-
-Under unix, the user's home directory is specified by the @code{HOME}
-environment variable. If this variable is undefined, the user name is
-computed using the @code{getlogin} system call, or if that fails, the
-@code{getuid} system call. The resulting user name is passed to the
-@code{getpwnam} system call to obtain the home directory.
-
-Under OS/2, several heuristics are tried to find the user's home
-directory. First, if the environment variable @code{HOME} is defined,
-that is the home directory. If @code{HOME} is undefined, but the
-@code{USERDIR} and @code{USER} environment variables are defined and
-the directory @file{%USERDIR%\%USER%} exists, then it is used. Failing
-that, if the directory @file{%USER%} exists on the OS/2 system
-drive, then it is used. As a last resort, the OS/2 system drive is
-the home directory.
-
-Like OS/2, the Windows implementation uses heuristics based on
-environment variables. The user's home directory is computed by
-examining several environment variables, in the following order:
-
-@itemize @bullet
-@item
-@code{HOMEDRIVE} and @code{HOMEPATH} are both defined and
-@file{%HOMEDRIVE%%HOMEPATH%} is an existing directory. (These variables
-are automatically defined by Windows NT.)
-
-@item
-@code{HOME} is defined and @file{%HOME%} is an existing directory.
-
-@item
-@code{USERDIR} and @code{USERNAME} are defined and
-@file{%USERDIR%\%USERNAME%} is an existing directory.
-
-@item
-@code{USERDIR} and @code{USER} are defined and
-@file{%USERDIR%\%USER%} is an existing directory.
-
-@item
-@code{USERNAME} is defined and @file{%USERNAME%} is an existing
-directory on the Windows system drive.
-
-@item
-@code{USER} is defined and @file{%USER%} is an existing directory on the
-Windows system drive.
-
-@item
-Finally, if all else fails, the Windows system drive is used as the home
-directory.
-@end itemize
-@end deffn
-
-@deffn procedure system-library-pathname pathname
-@cindex library, system pathname
-Locates @var{pathname} in MIT/GNU Scheme's system library directory. An
-error of type @code{condition-type:file-operation-error} is signalled if
-@var{pathname} cannot be located on the library search path.
-@findex condition-type:file-operation-error
-
-@example
-@group
-(system-library-pathname "compiler.com")
- @result{} #[pathname 45 "/usr/local/lib/mit-scheme/compiler.com"]
-@end group
-@end example
-@end deffn
-
-@deffn procedure system-library-directory-pathname pathname
-@cindex library, system pathname
-Locates the pathname of an MIT/GNU Scheme system library directory. An
-error of type @code{condition-type:file-operation-error} is signalled if
-@var{pathname} cannot be located on the library search path.
-
-@example
-@group
-(system-library-directory-pathname "options")
- @result{} #[pathname 44 "/usr/local/lib/mit-scheme/options/"]
-@end group
-@end example
-@end deffn
-
-@node Working Directory, File Manipulation, Pathnames, Operating-System Interface
-@section Working Directory
-
-@cindex absolute pathname (defn)
-@cindex pathname, absolute (defn)
-@cindex relative pathname (defn)
-@cindex pathname, relative (defn)
-@cindex directory, current working (defn)
-@cindex current working directory (defn)
-@cindex working directory (see current working directory)
-When MIT/GNU Scheme is started, the @dfn{current working directory} (or
-simply, @dfn{working directory}) is initialized in an operating-system
-dependent manner; usually, it is the directory in which Scheme was
-invoked. The working directory can be determined from within Scheme by
-calling the @code{pwd} procedure, and changed by calling the @code{cd}
-procedure. Each @acronym{REP} loop has its own working directory, and
-inferior @acronym{REP} loops initialize their working directory from the
-value in effect in their superior at the time they are created.
-
-@deffn procedure working-directory-pathname
-@deffnx procedure pwd
-Returns the current working directory as a pathname that has no name,
-type, or version components, just host, device, and directory
-components. @code{pwd} is an alias for
-@code{working-directory-pathname}; the long name is intended for
-programs and the short name for interactive use.
-@end deffn
-
-@deffn procedure set-working-directory-pathname! filename
-@deffnx procedure cd filename
-@findex ->pathname
-@findex pathname-as-directory
-Makes @var{filename} the current working directory and returns the new
-current working directory as a pathname. @var{Filename} is coerced to a
-pathname using @code{pathname-as-directory}. @code{cd} is an alias for
-@code{set-working-directory-pathname!}; the long name is intended for
-programs and the short name for interactive use.
-
-Additionally, @code{set-working-directory-pathname!} modifies the value
-of@* @code{*default-pathname-defaults*} by merging the new working
-directory into it.
-
-When this procedure is executed in the top-level @acronym{REP} loop, it
-changes the working directory of the running Scheme executable.
-
-@example
-@group
-(set-working-directory-pathname! "/usr/morris/blisp")
- @result{} #[pathname "/usr/morris/blisp/"]
-(set-working-directory-pathname! "~")
- @result{} #[pathname "/usr/morris/"]
-@end group
-@end example
-
-This procedure signals an error if @var{filename} does not refer to an
-existing directory.
-
-If @var{filename} describes a relative rather than absolute pathname,
-this procedure interprets it as relative to the current working
-directory, before changing the working directory.
-
-@example
-@group
-(working-directory-pathname)
- @result{} #[pathname "/usr/morris/"]
-(set-working-directory-pathname! "foo")
- @result{} #[pathname "/usr/morris/foo/"]
-@end group
-@end example
-@end deffn
-
-@deffn procedure with-working-directory-pathname filename thunk
-This procedure temporarily rebinds the current working directory to
-@var{filename}, invokes @var{thunk} (a procedure of no arguments), then
-restores the previous working directory and returns the value yielded by
-@var{thunk}. @var{Filename} is coerced to a pathname using
-@code{pathname-as-directory}. In addition to binding the working
-directory, @code{with-working-directory-pathname} also binds the
-variable @code{*default-pathname-defaults*}, merging the old value of
-that variable with the new working directory pathname. Both bindings
-are performed in exactly the same way as dynamic binding of a variable
-(@pxref{Dynamic Binding}).
-@end deffn
-
-@node File Manipulation, Directory Reader, Working Directory, Operating-System Interface
-@section File Manipulation
-
-This section describes procedures that manipulate files and directories.
-Any of these procedures can signal a number of errors for many reasons.
-The specifics of these errors are much too operating-system dependent to
-document here. However, if such an error is signalled by one of
-these procedures, it will be of type
-@code{condition-type:file-operation-error}.
-@findex condition-type:file-operation-error
-
-@deffn procedure file-exists? filename
-@deffnx procedure file-exists-direct? filename
-@deffnx procedure file-exists-indirect? filename
-@cindex existence, testing of file
-These procedures return @code{#t} if @var{filename} is an existing file
-or directory; otherwise they return @code{#f}. In operating systems
-that support symbolic links, if the file is a symbolic link,
-@code{file-exists-direct?} tests for the existence of the link, while
-@code{file-exists-indirect?} and @code{file-exists?} test for the
-existence of the file pointed to by the link.
-@end deffn
-
-@deffn procedure copy-file source-filename target-filename
-@cindex copying, of file
-Makes a copy of the file named by @var{source-filename}. The copy is
-performed by creating a new file called @var{target-filename}, and
-filling it with the same data as @var{source-filename}.
-@end deffn
-
-@deffn procedure rename-file source-filename target-filename
-@cindex renaming, of file
-@cindex name, of file
-Changes the name of @var{source-filename} to be @var{target-filename}.
-In the unix implementation, this will not rename across file systems.
-@end deffn
-
-@deffn procedure delete-file filename
-@cindex deletion, of file
-Deletes the file named @var{filename}.
-@end deffn
-
-@deffn procedure delete-file-no-errors filename
-Like @code{delete-file}, but returns a boolean value indicating whether
-an error occurred during the deletion. If no errors occurred, @code{#t}
-is returned. If an error of type @code{condition-type:file-error} or
-@code{condition-type:port-error} is signalled, @code{#f} is returned.
-@end deffn
-
-@deffn procedure hard-link-file source-filename target-filename
-@cindex linking (hard), of file
-@cindex hard linking, of file
-Makes a hard link from @var{source-filename} to @var{target-filename}.
-This operation gives the file specified by @var{source-filename} a new
-name, in addition to the old name.
-
-This currently works only on unix systems. It is further restricted to
-work only when @var{source-filename} and @var{target-filename} refer to
-names in the same file system.
-@end deffn
-
-@deffn procedure soft-link-file source-filename target-filename
-@cindex linking (soft), of file
-@cindex soft linking, of file
-@cindex symbolic linking, of file
-Creates a new soft link called @var{target-filename} that points at the
-file @var{source-filename}. (Soft links are also sometimes called
-@dfn{symbolic} links.) Note that @var{source-filename} will be
-interpreted as a string (although you may specify it as a pathname
-object, if you wish). The contents of this string will be stored in the
-file system as the soft link. When a file operation attempts to open
-the link, the contents of the link are interpreted relative to the
-link's location at that time.
-
-This currently works only on unix systems.
-@end deffn
-
-@deffn procedure make-directory filename
-Creates a new directory named @var{filename}. Signals an error if
-@var{filename} already exists, or if the directory cannot be created.
-@end deffn
-
-@deffn procedure delete-directory filename
-Deletes the directory named @var{filename}. Signals an error if
-the directory does not exist, is not a directory, or contains any files
-or subdirectories.
-@end deffn
-
-@deffn procedure ->truename filename
-@cindex truename, of input file
-This procedure attempts to discover and return the ``true name'' of the
-file associated with @var{filename} within the file system. An error of
-type @code{condition-type:file-operation-error} is signalled if the
-appropriate file cannot be located within the file system.
-@findex condition-type:file-operation-error
-@end deffn
-
-@deffn procedure call-with-temporary-file-pathname procedure
-Calls @code{temporary-file-pathname} to create a temporary file, then
-calls @var{procedure} with one argument, the pathname referring to that
-file. When @var{procedure} returns, if the temporary file still exists,
-it is deleted; then, the value yielded by @var{procedure} is returned.
-If @var{procedure} escapes from its continuation, and the file still
-exists, it is deleted.
-@end deffn
-
-@deffn procedure temporary-file-pathname [directory]
-Creates a new empty temporary file and returns a pathname referring to
-it. The temporary file is created with Scheme's default permissions, so
-barring unusual circumstances it can be opened for input and/or output
-without error. The temporary file will remain in existence until
-explicitly deleted. If the file still exists when the Scheme process
-terminates, it will be deleted.
-
-If @var{directory} is specified, the temporary file will be stored
-there. If it is not specified, or if it is @code{#f}, the temporary
-file will be stored in the directory returned by
-@code{temporary-directory-pathname}.
-@end deffn
-
-@deffn procedure temporary-directory-pathname
-Returns the pathname of an existing directory that can be used to store
-temporary files. These directory names are tried, in order, until a
-writeable directory is found:
-
-@itemize @bullet
-@item
-The directories specified by the environment variables @code{TMPDIR},
-@code{TEMP}, or @code{TMP}.
-
-@item
-Under unix, the directories @file{/var/tmp}, @file{/usr/tmp}, or
-@file{/tmp}.
-
-@item
-Under OS/2 or Windows, the following directories on the system drive:
-@file{\temp}, @file{\tmp}, or @file{\}.
-
-@item
-Under OS/2 or Windows, the current directory, as specified by
-@code{*default-pathname-defaults*}.
-@end itemize
-@end deffn
-
-@deffn procedure file-directory? filename
-@cindex directory, predicate for
-Returns @code{#t} if the file named @var{filename} exists and is a
-directory. Otherwise returns @code{#f}. In operating systems that
-support symbolic links, if @var{filename} names a symbolic link, this
-examines the file linked to, not the link itself.
-
-This is equivalent to
-
-@example
-(eq? 'directory (file-type-indirect @var{filename}))
-@end example
-@end deffn
-
-@deffn procedure file-regular? filename
-@cindex file (regular), predicate for
-@cindex regular file, predicate for
-Returns @code{#t} if the file named @var{filename} exists and is a
-regular file (i.e.@: not a directory, symbolic link, device file, etc.).
-Otherwise returns @code{#f}. In operating systems that support symbolic
-links, if @var{filename} names a symbolic link, this examines the file
-linked to, not the link itself.
-
-This is equivalent to
-
-@example
-(eq? 'regular (file-type-indirect @var{filename}))
-@end example
-@end deffn
-
-@deffn procedure file-symbolic-link? filename
-@cindex symbolic link, predicate for
-In operating systems that support symbolic links, if the file named
-@var{filename} exists and is a symbolic link, this procedure returns the
-contents of the symbolic link as a newly allocated string. The returned
-value is the name of the file that the symbolic link points to and must
-be interpreted relative to the directory of @var{filename}. If
-@var{filename} either does not exist or is not a symbolic link, or if
-the operating system does not support symbolic links, this procedure
-returns @code{#f}.
-@end deffn
-
-@deffn procedure file-type-direct filename
-@deffnx procedure file-type-indirect filename
-@cindex file type, procedure for
-If the file named @var{filename} exists, @code{file-type-direct} returns
-a symbol specifying what type of file it is. For example, if
-@var{filename} refers to a directory, the symbol @code{directory} is
-returned. If @var{filename} doesn't refer to an existing file,
-@code{#f} is returned.
-
-If @var{filename} refers to a symbolic link, @code{file-type-direct}
-returns the type of the link itself, while @code{file-type-indirect}
-returns the type of the file linked to.
-
-At this time, the symbols that can be returned are the following. The
-names are intended to be self-explanatory. Most of these names can only
-be returned on particular operating systems, and so the operating-system
-name is prefixed to the name.
-
-@example
-regular
-directory
-unix-symbolic-link
-unix-character-device
-unix-block-device
-unix-named-pipe
-unix-socket
-os2-named-pipe
-win32-named-pipe
-@end example
-@end deffn
-
-@deffn procedure file-readable? filename
-Returns @code{#t} if @var{filename} names a file that can be opened for
-input; i.e.@: a @dfn{readable} file. Otherwise returns @code{#f}.
-@end deffn
-
-@deffn procedure file-writeable? filename
-Returns @code{#t} if @var{filename} names a file that can be opened for
-output; i.e.@: a @dfn{writeable} file. Otherwise returns @code{#f}.
-@end deffn
-
-@deffn procedure file-executable? filename
-Returns @code{#t} if @var{filename} names a file that can be executed.
-Otherwise returns @code{#f}. Under unix, an executable file is
-identified by its mode bits. Under OS/2, an executable file has
-one of the file extensions @file{.exe}, @file{.com}, @file{.cmd}, or
-@file{.bat}. Under Windows, an executable file has one of the file
-extensions @file{.exe}, @file{.com}, or @file{.bat}.
-@end deffn
-
-@deffn procedure file-access filename mode
-@var{Mode} must be an exact integer between @code{0} and @code{7}
-inclusive; it is a bitwise-encoded predicate selector with @code{1}
-meaning ``executable'', @code{2} meaning ``writeable'', and @code{4}
-meaning ``readable''. @code{file-access} returns @code{#t} if
-@var{filename} exists and satisfies the predicates selected by
-@var{mode}. For example, if @var{mode} is @code{5}, then @var{filename}
-must be both readable and executable. If @var{filename} doesn't exist,
-or if it does not satisfy the selected predicates, @code{#f} is
-returned.
-@end deffn
-
-@deffn procedure file-eq? filename1 filename2
-Determines whether @var{filename1} and @var{filename2} refer to the same
-file. Under unix, this is done by comparing the inodes and devices of
-the two files. Under OS/2 and Windows, this is done by comparing
-the filename strings.
-@end deffn
-
-@deffn procedure file-modes filename
-If @var{filename} names an existing file, @code{file-modes} returns an
-exact non-negative integer encoding the file's permissions. The
-encoding of this integer is operating-system dependent. Under unix, it
-is the least-significant 12 bits of the @code{st_mode} element of the
-@code{struct stat} structure. Under OS/2 and Windows, it is the file
-attribute bits, which are described below. If @var{filename} does not
-name an existing file, @code{#f} is returned.
-@end deffn
-
-@deffn procedure set-file-modes! filename modes
-@var{Filename} must name an existing file. @var{Modes} must be an exact
-non-negative integer that could have been returned by a call to
-@code{file-modes}. @code{set-file-modes!} modifies the file's
-permissions to be those encoded by @var{modes}.
-@end deffn
-
-@defvr variable os2-file-mode/read-only
-@defvrx variable os2-file-mode/hidden
-@defvrx variable os2-file-mode/system
-@defvrx variable os2-file-mode/directory
-@defvrx variable os2-file-mode/archived
-The values of these variables are the ``mode bits'' that comprise the
-value returned by @code{file-modes} under OS/2. These bits are small
-integers that are combined by adding to form a complete set of modes.
-The integer zero represents a set of modes in which none of these bits
-are set.
-@end defvr
-
-@defvr variable nt-file-mode/read-only
-@defvrx variable nt-file-mode/hidden
-@defvrx variable nt-file-mode/system
-@defvrx variable nt-file-mode/directory
-@defvrx variable nt-file-mode/archive
-@defvrx variable nt-file-mode/normal
-@defvrx variable nt-file-mode/temporary
-@defvrx variable nt-file-mode/compressed
-The values of these variables are the ``mode bits'' that comprise the
-value returned by @code{file-modes} under Windows. These bits are small
-integers that are combined by adding to form a complete set of modes.
-The integer zero represents a set of modes in which none of these bits
-are set.
-@end defvr
-
-@deffn procedure file-modification-time filename
-@cindex modification time, of file
-Returns the modification time of @var{filename} as an exact non-negative
-integer. The result may be compared to other file times using ordinary
-integer arithmetic. If @var{filename} names a file that does not exist,
-@code{file-modification-time} returns @code{#f}.
-
-@findex file-modification-time-direct
-@findex file-modification-time-indirect
-In operating systems that support symbolic links, if @var{filename}
-names a symbolic link, @code{file-modification-time} returns the
-modification time of the file linked to. An alternate procedure,
-@code{file-modification-time-direct}, returns the modification time of
-the link itself; in all other respects it is identical to
-@code{file-modification-time}. For symmetry,
-@code{file-modification-time-indirect} is a synonym of
-@code{file-modification-time}.
-@end deffn
-
-@deffn procedure file-access-time filename
-@cindex access time, of file
-Returns the access time of @var{filename} as an exact non-negative
-integer. The result may be compared to other file times using ordinary
-integer arithmetic. If @var{filename} names a file that does not exist,
-@code{file-access-time} returns @code{#f}.
-
-@findex file-access-time-direct
-@findex file-access-time-indirect
-In operating systems that support symbolic links, if @var{filename}
-names a symbolic link, @code{file-access-time} returns the access time
-of the file linked to. An alternate procedure,
-@code{file-access-time-direct}, returns the access time of the link
-itself; in all other respects it is identical to
-@code{file-access-time}. For symmetry, @code{file-access-time-indirect}
-is a synonym of @code{file-access-time}.
-@end deffn
-
-@deffn procedure set-file-times! filename access-time modification-time
-@var{Filename} must name an existing file, while @var{access-time} and
-@var{modification-time} must be valid file times that might have been
-returned by @code{file-access-time} and @code{file-modification-time},
-respectively. @code{set-file-times!} alters the access and modification
-times of the file specified by @var{filename} to the values given by
-@var{access-time} and @var{modification-time}, respectively. For
-convenience, either of the time arguments may be specified as @code{#f};
-in this case the corresponding time is not changed.
-@code{set-file-times!} returns an unspecified value.
-@end deffn
-
-@deffn procedure current-file-time
-Returns the current time as an exact non-negative integer, in the same
-format used by the above file-time procedures. This number can be
-compared to other file times using ordinary arithmetic operations.
-@end deffn
-
-@deffn procedure file-touch filename
-@dfn{Touches} the file named @var{filename}. If the file already
-exists, its modification time is set to the current file time and
-@code{#f} is returned. Otherwise, the file is created and @code{#t} is
-returned. This is an atomic test-and-set operation, so it is useful as
-a synchronization mechanism.
-@end deffn
-
-@deffn procedure file-length filename
-Returns the length, in bytes, of the file named @var{filename} as an
-exact non-negative integer.
-@end deffn
-
-@deffn procedure file-attributes filename
-@cindex attribute, of file
-This procedure determines if the file named @var{filename} exists, and
-returns information about it if so; if the file does not exist, it
-returns @code{#f}.
-
-@findex file-attributes-direct
-@findex file-attributes-indirect
-In operating systems that support symbolic links, if @var{filename}
-names a symbolic link, @code{file-attributes} returns the attributes of
-the link itself. An alternate procedure,
-@code{file-attributes-indirect}, returns the attributes of the file
-linked to; in all other respects it is identical to
-@code{file-attributes}. For symmetry, @code{file-attributes-direct} is
-a synonym of @code{file-attributes}.
-@end deffn
-
-The information returned by @code{file-attributes} is decoded by
-accessor procedures. The following accessors are defined in all
-operating systems:
-
-@deffn procedure file-attributes/type attributes
-The file type: @code{#t} if the file is a directory, a character string
-(the name linked to) if a symbolic link, or @code{#f} for all other
-types of file.
-@end deffn
-
-@deffn procedure file-attributes/access-time attributes
-The last access time of the file, an exact non-negative integer.
-@end deffn
-
-@deffn procedure file-attributes/modification-time attributes
-The last modification time of the file, an exact non-negative integer.
-@end deffn
-
-@deffn procedure file-attributes/change-time attributes
-The last change time of the file, an exact non-negative integer.
-@end deffn
-
-@deffn procedure file-attributes/length attributes
-The length of the file in bytes.
-@end deffn
-
-@deffn procedure file-attributes/mode-string attributes
-The mode string of the file, a newly allocated string showing the file's
-mode bits. Under unix, this string is in unix format. Under OS/2 and
-Windows, this string shows the standard ``DOS'' attributes in their
-usual format.
-@end deffn
-
-@deffn procedure file-attributes/n-links attributes
-The number of links to the file, an exact positive integer. Under
-Windows and OS/2, this is always @code{1}.
-@end deffn
-
-The following additional accessors are defined under unix:
-
-@deffn procedure file-attributes/uid attributes
-The user id of the file's owner, an exact non-negative integer.
-@end deffn
-
-@deffn procedure file-attributes/gid attributes
-The group id of the file's group, an exact non-negative integer.
-@end deffn
-
-@deffn procedure file-attributes/inode-number attributes
-The inode number of the file, an exact non-negative integer.
-@end deffn
-
-The following additional accessor is defined under OS/2 and Windows:
-
-@deffn procedure file-attributes/modes attributes
-The attribute bits of the file. This is an exact non-negative integer
-containing the file's attribute bits, exactly as specified by the
-operating system's API.
-@end deffn
-
-The following additional accessor is defined under OS/2:
-
-@deffn procedure file-attributes/allocated-length attributes
-The allocated length of the file, which can be larger than the length of
-the file due to fixed-length allocation units.
-@end deffn
-
-@node Directory Reader, Date and Time, File Manipulation, Operating-System Interface
-@section Directory Reader
-@cindex directory, reading
-
-@deffn procedure directory-read directory [sort?]
-@var{Directory} must be an object that can be converted into a pathname
-by@* @code{->pathname}. The directory specified by @var{directory} is
-read, and the contents of the directory is returned as a newly allocated
-list of absolute pathnames. The result is sorted according to the usual
-sorting conventions for directories, unless @var{sort?} is specified as
-@code{#f}. If @var{directory} has name, type, or version components,
-the returned list contains only those pathnames whose name, type, and
-version components match those of @var{directory}; @code{wild} or
-@code{#f} as one of these components means ``match anything''.
-
-The OS/2 and Windows implementations support ``globbing'', in which the
-characters @code{*} and @code{?} are interpreted to mean ``match
-anything'' and ``match any character'', respectively. This ``globbing''
-is supported only in the file part of @var{directory}.
-@end deffn
-
-@node Date and Time, Machine Time, Directory Reader, Operating-System Interface
-@section Date and Time
-
-MIT/GNU Scheme provides a simple set of procedures for manipulating date
-and time information. There are four time representations, each of
-which serves a different purpose. Each representation may be
-converted to any of the others.
-
-@cindex universal time
-@cindex time, universal
-The primary time representation, @dfn{universal time}, is an exact
-non-negative integer counting the number of seconds that have elapsed
-since midnight January 1, 1900 UTC. (UTC stands for @dfn{Coordinated
-Universal Time}, and is the modern name for Greenwich Mean Time.) This
-format is produced by @code{get-universal-time} and
-@code{decoded-time->universal-time}.
-
-@cindex decoded time
-@cindex time, decoded
-The second representation, @dfn{decoded time}, is a record structure in
-which the time is broken down into components, such as month, minute,
-etc. Decoded time is always relative to a particular time zone, which
-is a component of the structure. This format is produced by
-@code{global-decoded-time} and @code{local-decoded-time}.
-
-@cindex file time
-@cindex time, file
-The third representation, @dfn{file time}, is an exact non-negative
-integer that is larger for increasing time. Unlike universal time,
-this representation is operating-system dependent. This format is
-produced by all of the file-attribute procedures, for example
-@code{file-modification-time} and @code{file-attributes}.
-
-@cindex time, string
-The fourth representation, the @dfn{time string}, is an external
-representation for time. This format is defined by RFC-822,
-@cite{Standard for the format of ARPA Internet text messages}, with the
-modification that years are represented as four-digit numbers rather
-than two-digit numbers. This format is the standard format for Internet
-email and numerous other network protocols.
-
-Within this section, argument variables named @var{universal-time},
-@var{decoded-time}, @var{file-time}, and @var{time-string} are
-respectively required to be of the corresponding format.
-
-@menu
-* Universal Time::
-* Decoded Time::
-* File Time::
-* Time-Format Conversion::
-* External Representation of Time::
-@end menu
-
-@node Universal Time, Decoded Time, Date and Time, Date and Time
-@subsection Universal Time
-
-@deffn procedure get-universal-time
-Return the current time in universal format.
-
-@example
-(get-universal-time) @result{} 3131453078
-@end example
-@end deffn
-
-@defvr variable epoch
-@code{epoch} is the representation of midnight January 1, 1970 UTC in
-universal-time format.
-
-@example
-epoch @result{} 2208988800
-@end example
-@end defvr
-
-@node Decoded Time, File Time, Universal Time, Date and Time
-@subsection Decoded Time
-
-Objects representing standard time components, such as seconds and
-minutes, are required to be exact non-negative integers. Seconds and
-minutes must be inclusively between @code{0} and @code{59}; hours
-between @code{0} and @code{23}; days between @code{1} and @code{31};
-months between @code{1} and @code{12}; years are represented in
-``four-digit'' form, in which 1999 is represented as @code{1999} ---
-@emph{not} @code{99}.
-
-@deffn procedure local-decoded-time
-Return the current time in decoded format. The decoded time is
-represented in the local time zone.
-
-@example
-@group
-(pp (local-decoded-time))
-@print{} #[decoded-time 76]
-@print{} (second 2)
-@print{} (minute 12)
-@print{} (hour 11)
-@print{} (day 27)
-@print{} (month 4)
-@print{} (year 1999)
-@print{} (day-of-week 1)
-@print{} (daylight-savings-time 1)
-@print{} (zone 5)
-@end group
-@end example
-@end deffn
-
-@deffn procedure global-decoded-time
-Return the current time in decoded format. The decoded time is
-represented in UTC.
-
-@example
-@group
-(pp (global-decoded-time))
-@print{} #[decoded-time 77]
-@print{} (second 8)
-@print{} (minute 12)
-@print{} (hour 15)
-@print{} (day 27)
-@print{} (month 4)
-@print{} (year 1999)
-@print{} (day-of-week 1)
-@print{} (daylight-savings-time 0)
-@print{} (zone 0)
-@end group
-@end example
-@end deffn
-
-@deffn procedure make-decoded-time second minute hour day month year [zone]
-Return a new decoded-time object representing the given time. The
-arguments must be valid components according to the above rules, and
-must form a valid date.
-
-If @var{zone} is not supplied or is @code{#f}, the resulting decoded
-time will be represented in the local time zone. Otherwise, @var{zone}
-must be a valid time zone, and the result will be represented in that
-zone.
-
-@strong{Warning}: because this procedure depends on the operating
-system's runtime library, it is not capable of representing all dates.
-In particular, on most unix systems, it is not possible to encode dates
-that occur prior to midnight, January 1, 1970 UTC. Attempting to do
-this will signal an error.
-
-@example
-@group
-(pp (make-decoded-time 0 9 11 26 3 1999))
-@print{} #[decoded-time 19]
-@print{} (second 0)
-@print{} (minute 9)
-@print{} (hour 11)
-@print{} (day 26)
-@print{} (month 3)
-@print{} (year 1999)
-@print{} (day-of-week 4)
-@print{} (daylight-savings-time 0)
-@print{} (zone 5)
-@end group
-
-@group
-(pp (make-decoded-time 0 9 11 26 3 1999 3))
-@print{} #[decoded-time 80]
-@print{} (second 0)
-@print{} (minute 9)
-@print{} (hour 11)
-@print{} (day 26)
-@print{} (month 3)
-@print{} (year 1999)
-@print{} (day-of-week 4)
-@print{} (daylight-savings-time 0)
-@print{} (zone 3)
-@end group
-@end example
-@end deffn
-
-@deffn procedure decoded-time/second decoded-time
-@deffnx procedure decoded-time/minute decoded-time
-@deffnx procedure decoded-time/hour decoded-time
-@deffnx procedure decoded-time/day decoded-time
-@deffnx procedure decoded-time/month decoded-time
-@deffnx procedure decoded-time/year decoded-time
-Return the corresponding component of @var{decoded-time}.
-
-@example
-@group
-(decoded-time/second (local-decoded-time)) @result{} 17
-(decoded-time/year (local-decoded-time)) @result{} 1999
-(decoded-time/day (local-decoded-time)) @result{} 26
-@end group
-@end example
-@end deffn
-
-@deffn procedure decoded-time/day-of-week decoded-time
-Return the day of the week on which @var{decoded-time} falls, encoded
-as an exact integer between @code{0} (Monday) and @code{6} (Sunday),
-inclusive.
-
-@example
-(decoded-time/day-of-week (local-decoded-time)) @result{} 4
-@end example
-@end deffn
-
-@deffn procedure decoded-time/daylight-savings-time? decoded-time
-Return @code{#t} if @var{decoded-time} is represented using daylight
-savings time. Otherwise return @code{#f}.
-
-@example
-(decoded-time/daylight-savings-time? (local-decoded-time))
- @result{} #f
-@end example
-@end deffn
-
-@deffn procedure decoded-time/zone decoded-time
-Return the time zone in which @var{decoded-time} is represented. This
-is an exact rational number between @code{-24} and @code{+24} inclusive,
-that when multiplied by @code{3600} is an integer. The value is the
-number of hours west of UTC.
-
-@example
-(decoded-time/zone (local-decoded-time)) @result{} 5
-@end example
-@end deffn
-
-@deffn procedure time-zone? object
-Returns @code{#t} if @var{object} is an exact number between @code{-24}
-and @code{+24} inclusive, that when multiplied by @code{3600} is an
-integer.
-
-@example
-@group
-(time-zone? -5) @result{} #t
-(time-zone? 11/2) @result{} #t
-(time-zone? 11/7) @result{} #f
-@end group
-@end example
-@end deffn
-
-@deffn procedure month/max-days month
-Returns the maximum number of days possible in @var{month}. @var{Month}
-must be an exact integer between @code{1} and @code{12} inclusive.
-
-@example
-@group
-(month/max-days 2) @result{} 29
-(month/max-days 3) @result{} 31
-(month/max-days 4) @result{} 30
-@end group
-@end example
-@end deffn
-
-@node File Time, Time-Format Conversion, Decoded Time, Date and Time
-@subsection File Time
-
-As stated above, file time is operating-system dependent. As of this
-writing, two formats are used. For unix and Windows systems, file time
-is the number of seconds since midnight January 1, 1970 UTC (the
-standard unix time convention).
-
-OS/2 represents file time as a 32-bit unsigned integer, in which the
-time components are broken down into unsigned bit fields. The
-components are always stated in local time. The fields, from MSB to
-LSB, are:
-
-@itemize @bullet
-@item
-7 bits representing the year, relative to 1900.
-
-@item
-4 bits representing the month, numbered 1 to 12.
-
-@item
-5 bits representing the day of the month, numbered 1 to 31.
-
-@item
-5 bits representing the hour of the day, numbered 0 to 23.
-
-@item
-6 bits representing the minute, numbered 0 to 59.
-
-@item
-5 bits representing the second. This field is unusual in that it counts
-units of two seconds, so it is a number between 0 and 29, representing
-second counts corresponding to 0 through 58.
-@end itemize
-
-The following procedures generate their results in file-time format:
-
-@example
-@group
-file-access-time
-file-access-time-direct
-file-access-time-indirect
-file-modification-time
-file-modification-time-direct
-file-modification-time-indirect
-file-attributes/access-time
-file-attributes/modification-time
-file-attributes/change-time
-@end group
-@end example
-
-@noindent
-Additionally, @code{set-file-times!} accepts its time arguments in
-file-time format.
-
-@node Time-Format Conversion, External Representation of Time, File Time, Date and Time
-@subsection Time-Format Conversion
-
-The procedures described in this section convert times from one format
-to another.
-
-@deffn procedure universal-time->local-decoded-time universal-time
-@deffnx procedure universal-time->global-decoded-time universal-time
-Converts an argument in universal-time format to decoded-time format.
-The result is in the local time zone or UTC, respectively.
-
-@example
-@group
-(pp (universal-time->local-decoded-time (get-universal-time)))
-@print{} #[decoded-time 21]
-@print{} (second 23)
-@print{} (minute 57)
-@print{} (hour 17)
-@print{} (day 29)
-@print{} (month 4)
-@print{} (year 1999)
-@print{} (day-of-week 3)
-@print{} (daylight-savings-time 1)
-@print{} (zone 5)
-@end group
-
-@group
-(pp (universal-time->global-decoded-time
- (get-universal-time)))
-@print{} #[decoded-time 22]
-@print{} (second 27)
-@print{} (minute 57)
-@print{} (hour 21)
-@print{} (day 29)
-@print{} (month 4)
-@print{} (year 1999)
-@print{} (day-of-week 3)
-@print{} (daylight-savings-time 0)
-@print{} (zone 0)
-@end group
-@end example
-@end deffn
-
-@deffn procedure universal-time->file-time universal-time
-Converts an argument in universal-time format to file-time format.
-
-@example
-@group
-(universal-time->file-time (get-universal-time))
- @result{} 925422988
-@end group
-@end example
-@end deffn
-
-@deffn procedure universal-time->local-time-string universal-time
-@deffnx procedure universal-time->global-time-string universal-time
-Converts an argument in universal-time format to a time string. The
-result is in the local time zone or UTC, respectively.
-
-@example
-@group
-(universal-time->local-time-string (get-universal-time))
- @result{} "Thu, 29 Apr 1999 17:55:31 -0400"
-(universal-time->global-time-string (get-universal-time))
- @result{} "Thu, 29 Apr 1999 21:55:51 +0000"
-@end group
-@end example
-@end deffn
-
-@deffn procedure decoded-time->universal-time decoded-time
-Converts an argument in decoded-time format to universal-time format.
-
-@example
-@group
-(decoded-time->universal-time (local-decoded-time))
- @result{} 3134411942
-(decoded-time->universal-time (global-decoded-time))
- @result{} 3134411947
-@end group
-@end example
-@end deffn
-
-@deffn procedure decoded-time->file-time decoded-time
-Converts an argument in decoded-time format to file-time format.
-
-@example
-@group
-(decoded-time->file-time (local-decoded-time))
- @result{} 925423191
-(decoded-time->file-time (global-decoded-time))
- @result{} 925423195
-@end group
-@end example
-@end deffn
-
-@deffn procedure decoded-time->string decoded-time
-Convert an argument in decoded-time format to a time string.
-
-@example
-@group
-(decoded-time->string (local-decoded-time))
- @result{} "Thu, 29 Apr 1999 18:00:43 -0400"
-(decoded-time->string (global-decoded-time))
- @result{} "Thu, 29 Apr 1999 22:00:46 +0000"
-@end group
-@end example
-@end deffn
-
-@deffn procedure file-time->universal-time file-time
-Converts an argument in universal-time format to file-time format.
-
-@example
-@group
-(file-time->universal-time (file-modification-time "/"))
- @result{} 3133891907
-@end group
-@end example
-@end deffn
-
-@deffn procedure file-time->local-decoded-time file-time
-@deffnx procedure file-time->global-decoded-time file-time
-Converts an argument in file-time format to decoded-time format. The
-result is in the local time zone or UTC, respectively.
-
-@example
-@group
-(pp (file-time->local-decoded-time
- (file-modification-time "/")))
-@print{} #[decoded-time 26]
-@print{} (second 47)
-@print{} (minute 31)
-@print{} (hour 17)
-@print{} (day 23)
-@print{} (month 4)
-@print{} (year 1999)
-@print{} (day-of-week 4)
-@print{} (daylight-savings-time 1)
-@print{} (zone 5)
-@end group
-
-@group
-(pp (file-time->global-decoded-time
- (file-modification-time "/")))
-@print{} #[decoded-time 27]
-@print{} (second 47)
-@print{} (minute 31)
-@print{} (hour 21)
-@print{} (day 23)
-@print{} (month 4)
-@print{} (year 1999)
-@print{} (day-of-week 4)
-@print{} (daylight-savings-time 0)
-@print{} (zone 0)
-@end group
-@end example
-@end deffn
-
-@deffn procedure file-time->local-time-string file-time
-@deffnx procedure file-time->global-time-string file-time
-Converts an argument in file-time format to a time string. The result
-is in the local time zone or UTC, respectively.
-
-@example
-@group
-(file-time->local-time-string (file-modification-time "/"))
- @result{} "Fri, 23 Apr 1999 17:31:47 -0400"
-(file-time->global-time-string (file-modification-time "/"))
- @result{} "Fri, 23 Apr 1999 21:31:47 +0000"
-@end group
-@end example
-@end deffn
-
-@deffn procedure string->universal-time time-string
-Converts a time-string argument to universal-time format.
-
-@example
-@group
-(string->universal-time "Fri, 23 Apr 1999 21:31:47 +0000")
- @result{} 3133888307
-(string->universal-time "Fri, 23 Apr 1999 17:31:47 -0400")
- @result{} 3133888307
-@end group
-@end example
-@end deffn
-
-@deffn procedure string->decoded-time time-string
-Converts a time-string argument to decoded-time format.
-
-@example
-@group
-(pp (string->decoded-time "Fri, 23 Apr 1999 17:31:47 -0400"))
-@print{} #[decoded-time 30]
-@print{} (second 47)
-@print{} (minute 31)
-@print{} (hour 17)
-@print{} (day 23)
-@print{} (month 4)
-@print{} (year 1999)
-@print{} (day-of-week 4)
-@print{} (daylight-savings-time 0)
-@print{} (zone 4)
-@end group
-@end example
-@end deffn
-
-@deffn procedure string->file-time time-string
-Converts a time-string argument to file-time format.
-
-@example
-@group
-(string->file-time "Fri, 23 Apr 1999 17:31:47 -0400")
- @result{} 924899507
-@end group
-@end example
-@end deffn
-
-@node External Representation of Time, , Time-Format Conversion, Date and Time
-@subsection External Representation of Time
-
-The normal external representation for time is the time string, as
-described above. The procedures in this section generate alternate
-external representations of time which are more verbose and may be more
-suitable for presentation to human readers.
-
-@deffn procedure decoded-time/date-string decoded-time
-@deffnx procedure decoded-time/time-string decoded-time
-These procedures return strings containing external representations of
-the date and time, respectively, represented by @var{decoded-time}. The
-results are implicitly in local time.
-
-@example
-@group
-(decoded-time/date-string (local-decoded-time))
- @result{} "Tuesday March 30, 1999"
-(decoded-time/time-string (local-decoded-time))
- @result{} "11:22:38 AM"
-@end group
-@end example
-@end deffn
-
-@deffn procedure day-of-week/long-string day-of-week
-@deffnx procedure day-of-week/short-string day-of-week
-Returns a string representing the given @var{day-of-week}. The argument
-must be an exact non-negative integer between @code{0} and @code{6}
-inclusive. @code{day-of-week/long-string} returns a long string that
-fully spells out the name of the day. @code{day-of-week/short-string}
-returns a shortened string that abbreviates the day to three letters.
-
-@example
-@group
-(day-of-week/long-string 0) @result{} "Monday"
-(day-of-week/short-string 0) @result{} "Mon"
-(day-of-week/short-string 3) @result{} "Thu"
-@end group
-@end example
-@end deffn
-
-@deffn procedure month/long-string month
-@deffnx procedure month/short-string month
-Returns a string representing the given @var{month}. The argument must
-be an exact non-negative integer between @code{1} and @code{12}
-inclusive. @code{month/long-string} returns a long string that fully
-spells out the name of the month. @code{month/short-string} returns a
-shortened string that abbreviates the month to three letters.
-
-@example
-@group
-(month/long-string 1) @result{} "January"
-(month/short-string 1) @result{} "Jan"
-(month/short-string 10) @result{} "Oct"
-@end group
-@end example
-@end deffn
-
-@deffn procedure time-zone->string
-Returns a string corresponding to the given time zone. This string is
-the same string that is used to generate RFC-822 time strings.
-
-@example
-@group
-(time-zone->string 5) @result{} "-0500"
-(time-zone->string -4) @result{} "+0400"
-(time-zone->string 11/2) @result{} "-0530"
-@end group
-@end example
-@end deffn
-
-@node Machine Time, Subprocesses, Date and Time, Operating-System Interface
-@section Machine Time
-
-The previous section dealt with procedures that manipulate clock time.
-This section describes procedures that deal with computer time: elapsed
-CPU time, elapsed real time, and so forth. These procedures are useful
-for measuring the amount of time it takes to execute code.
-
-@cindex tick
-Some of the procedures in this section manipulate a time representation
-called @dfn{ticks}. A tick is a unit of time that is unspecified here
-but can be converted to and from seconds by supplied procedures. A
-count in ticks is represented as an exact integer. At present each tick
-is one millisecond, but this may change in the future.
-
-@deffn procedure process-time-clock
-Returns the amount of process time, in ticks, that has elapsed since
-Scheme was started. Process time is measured by the operating system
-and is time during which the Scheme process is computing. It does not
-include time in system calls, but depending on the operating system it
-may include time used by subprocesses.
-
-@example
-(process-time-clock) @result{} 21290
-@end example
-@end deffn
-
-@deffn procedure real-time-clock
-Returns the amount of real time, in ticks, that has elapsed since Scheme
-was started. Real time is the time measured by an ordinary clock.
-
-@example
-(real-time-clock) @result{} 33474836
-@end example
-@end deffn
-
-@deffn procedure internal-time/ticks->seconds ticks
-Returns the number of seconds corresponding to @var{ticks}. The result
-is always a real number.
-
-@example
-@group
-(internal-time/ticks->seconds 21290) @result{} 21.29
-(internal-time/ticks->seconds 33474836) @result{} 33474.836
-@end group
-@end example
-@end deffn
-
-@deffn procedure internal-time/seconds->ticks seconds
-Returns the number of ticks corresponding to @var{seconds}.
-@var{Seconds} must be a real number.
-
-@example
-@group
-(internal-time/seconds->ticks 20.88) @result{} 20880
-(internal-time/seconds->ticks 20.83) @result{} 20830
-@end group
-@end example
-@end deffn
-
-@deffn procedure system-clock
-Returns the amount of process time, in seconds, that has elapsed since
-Scheme was started. Roughly equivalent to:
-
-@example
-(internal-time/ticks->seconds (process-time-clock))
-@end example
-
-@noindent
-Example:
-
-@example
-(system-clock) @result{} 20.88
-@end example
-@end deffn
-
-@deffn procedure runtime
-Returns the amount of process time, in seconds, that has elapsed since
-Scheme was started. However, it does not include time spent in garbage
-collection.
-
-@example
-(runtime) @result{} 20.83
-@end example
-@end deffn
-
-@deffn procedure with-timings thunk receiver
-Calls @var{thunk} with no arguments. After @var{thunk} returns,
-@var{receiver} is called with three arguments describing the time spent
-while computing @var{thunk}: the elapsed run time, the amount of time
-spent in the garbage collector, and the elapsed real time. All three
-times are in ticks.
-
-This procedure is most useful for doing performance measurements, and is
-designed to have relatively low overhead.
-
-@example
-@group
-(with-timings
- (lambda () @r{@dots{} hairy computation @dots{}})
- (lambda (run-time gc-time real-time)
- (write (internal-time/ticks->seconds run-time))
- (write-char #\space)
- (write (internal-time/ticks->seconds gc-time))
- (write-char #\space)
- (write (internal-time/ticks->seconds real-time))
- (newline)))
-@end group
-@end example
-@end deffn
-
-@deffn procedure measure-interval runtime? procedure
-Calls @var{procedure}, passing it the current process time, in seconds,
-as an argument. The result of this call must be another procedure.
-When @var{procedure} returns, the resulting procedure is
-tail-recursively called with the ending time, in seconds, as an
-argument.
-
-If @var{runtime?} is @code{#f}, the elapsed time is deducted from the
-elapsed system time returned by @code{runtime}.
-
-While this procedure can be used for time measurement, its interface is
-somewhat clumsy for that purpose. We recommend that you use
-@code{with-timings} instead, because it is more convenient and has lower
-overhead.
-
-@example
-@group
-(measure-interval #t
- (lambda (start-time)
- (let ((v @r{@dots{} hairy computation @dots{}}))
- (lambda (end-time)
- (write (- end-time start-time))
- (newline)
- v))))
-@end group
-@end example
-@end deffn
-
-@node Subprocesses, TCP Sockets, Machine Time, Operating-System Interface
-@section Subprocesses
-
-@cindex subprocess
-@cindex synchronous subprocess
-MIT/GNU Scheme provides the ability to run and control subprocesses. This
-support is divided into two parts: a low-level set of primitives that
-maps onto the underlying operating system's process-control primitives,
-and a high-level set of procedures for starting a subprocess and running
-it to completion in a single call. Subprocesses that are run in the
-latter fashion are referred to as @dfn{synchronous}, because they are
-started and stopped in synchrony with a Scheme procedure call.
-
-This chapter documents Scheme's high-level synchronous-subprocess
-support. The low-level support is not documented but is available for
-those who are willing to read the source code.
-
-Synchronous-subprocess support is a run-time-loadable option. To use
-it, execute
-
-@example
-(load-option 'synchronous-subprocess)
-@end example
-
-@noindent
-once before calling it.
-
-@menu
-* Subprocess Procedures::
-* Subprocess Conditions::
-* Subprocess Options::
-@end menu
-
-@node Subprocess Procedures, Subprocess Conditions, Subprocesses, Subprocesses
-@subsection Subprocess Procedures
-
-There are two commands for running synchronous subprocesses under
-Scheme. @code{run-shell-command} is very simple to use, provides access
-to all shell features, and is to be preferred in most situations.
-@code{run-synchronous-subprocess} allows direct execution of a program
-and precise control of the command-line arguments passed to the program,
-but does not provide file globbing, I/O redirection, or other shell
-features.
-
-@deffn procedure run-shell-command command option @dots{}
-Runs @var{command}, which must be a string. @var{Command} is passed to
-a command shell for interpretation; how the shell is chosen is detailed
-below.
-
-The @var{option}s are a sequence of keyword/value pairs that specify
-optional behavior. See below for more information about options.
-
-@code{run-shell-command} waits until the subprocess completes its
-execution and returns the exit code from the subprocess. If the
-subprocess is killed or stopped, an error is signalled and the procedure
-does not return.
-@end deffn
-
-@deffn procedure run-synchronous-subprocess program arguments option @dots{}
-Runs @var{program}, passing it the given command-line @var{arguments}.
-@var{Program} must be either the name of a program on the path, or else
-a pathname to a specific program. @var{Arguments} must be a list of
-strings; each string is a single command-line argument to the program.
-
-The @var{option}s are a sequence of keyword/value pairs that specify
-optional behavior. See below for more information about options.
-
-@code{run-synchronous-subprocess} waits until the subprocess completes
-its execution and returns the exit code from the subprocess. If the
-subprocess is killed or stopped, an error is signalled and the procedure
-does not return.
-@end deffn
-
-@node Subprocess Conditions, Subprocess Options, Subprocess Procedures, Subprocesses
-@subsection Subprocess Conditions
-
-If a subprocess spawned by one of the above procedures is killed or
-suspended, then one of the following errors will be signalled.
-
-@deffn {condition type} condition-type:subprocess-signalled subprocess reason
-This condition type is a subtype of
-@code{condition-type:subprocess-abnormal-termination}. It is signalled
-when the subprocess is killed.
-
-@var{Subprocess} is an object that represents the subprocess involved.
-The internals of this object can be accessed but the interface is not
-documented at this time; see the source code for details.
-
-@var{Reason} is interesting only on unix systems, where it is the signal
-that killed the process. On other systems it has a fixed value that
-conveys no useful information.
-@end deffn
-
-@deffn {condition type} condition-type:subprocess-stopped subprocess reason
-This condition type is a subtype of
-@code{condition-type:subprocess-abnormal-termination}. It is signalled
-when the subprocess is stopped or suspended.
-
-@var{Subprocess} is an object that represents the subprocess involved.
-The internals of this object can be accessed but the interface is not
-documented at this time; see the source code for details.
-
-@var{Reason} is interesting only on unix systems, where it is the signal
-that stopped the process. On other systems it has a fixed value that
-conveys no useful information.
-@end deffn
-
-@deffn {condition type} condition-type:subprocess-abnormal-termination subprocess reason
-This condition type is a subtype of @code{condition-type:error}. This
-is an abstract type that is never signalled. It is provided so that
-condition handlers can be bound to it.
-@end deffn
-
-@node Subprocess Options, , Subprocess Conditions, Subprocesses
-@subsection Subprocess Options
-
-The following subprocess options may be passed to
-@code{run-shell-command} or @code{run-synchronous-subprocess}. These
-options are passed as alternating keyword/value pairs, for example:
-
-@example
-@group
-(run-shell-command "ls /"
- 'output my-output-port
- 'output-buffer-size 8192)
-@end group
-@end example
-
-@noindent
-The example shows a shell command being run with two options specified:
-@code{output} and @code{output-buffer-size}.
-
-@deffn {subprocess option} input port
-Specifies the standard input of the subprocess. @var{Port} may be an
-input port, in which case characters are read from @var{port} and fed to
-the subprocess until @var{port} reaches end-of-file. Alternatively,
-@var{port} may be @code{#f}, indicating that the subprocess has no
-standard input.
-
-The default value of this option is @code{#f}.
-
-@example
-@group
-(call-with-input-file "foo.in"
- (lambda (port)
- (run-shell-command "cat > /dev/null" 'input port)))
-@end group
-@end example
-@end deffn
-
-@deffn {subprocess option} input-line-translation line-ending
-Specifies how line-endings should be translated when writing characters
-to the subprocess. Ignored if the @code{input} option is @code{#f}.
-@var{Line-ending} must be either a string specifying the line ending, or
-the symbol @code{default}, meaning to use the operating system's
-standard line ending. In either case, newline characters to be written
-to the @code{input} port are translated to the specified line ending
-before being written.
-
-The default value of this option is @code{default}.
-
-@example
-@group
-(call-with-input-file "foo.in"
- (lambda (port)
- (run-shell-command "cat > /dev/null"
- 'input port
- 'input-line-translation "\r\n")))
-@end group
-@end example
-@end deffn
-
-@deffn {subprocess option} input-buffer-size n
-Specifies the size of the input buffer for the standard input of the
-subprocess. (This is the buffer on the Scheme side, and has nothing to
-do with any buffering done on the subprocess side.) Ignored if the
-@code{input} option is @code{#f}. @var{N} must be an exact positive
-integer specifying the number of characters the buffer can hold.
-
-The default value of this option is @code{512}.
-
-@example
-@group
-(call-with-input-file "foo.in"
- (lambda (port)
- (run-shell-command "cat > /dev/null"
- 'input port
- 'input-buffer-size 4096)))
-@end group
-@end example
-@end deffn
-
-@deffn {subprocess option} output port
-Specifies the standard output and standard error of the subprocess.
-@var{Port} may be an output port, in which case characters are read from
-the subprocess and fed to @var{port} until the subprocess finishes.
-Alternatively, @var{port} may be @code{#f}, indicating that the
-subprocess has no standard output or standard error.
-
-The default value of this option is the value of
-@code{(current-output-port)}.
-
-@example
-@group
-(call-with-output-file "foo.out"
- (lambda (port)
- (run-shell-command "ls -la /etc" 'output port)))
-@end group
-@end example
-@end deffn
-
-@deffn {subprocess option} output-line-translation line-ending
-Specifies how line-endings should be translated when reading characters
-from the standard output of the subprocess. Ignored if the
-@code{output} option is @code{#f}. @var{Line-ending} must be either a
-string specifying the line ending, or the symbol @code{default}, meaning
-to use the operating system's standard line ending. In either case,
-newline characters read from the subprocess port are translated to the
-specified line ending.
-
-The default value of this option is @code{default}.
-
-@example
-@group
-(call-with-output-file "foo.out"
- (lambda (port)
- (run-shell-command "ls -la /etc"
- 'output port
- 'output-line-translation "\r\n")))
-@end group
-@end example
-@end deffn
-
-@deffn {subprocess option} output-buffer-size n
-Specifies the size of the output buffer for the standard output of the
-subprocess. (This is the buffer on the Scheme side, and has nothing to
-do with any buffering done on the subprocess side.) Ignored if the
-@code{output} option is @code{#f}. @var{N} must be an exact positive
-integer specifying the number of characters the buffer can hold.
-
-The default value of this option is @code{512}.
-
-@example
-@group
-(call-with-output-file "foo.out"
- (lambda (port)
- (run-shell-command "ls -la /etc"
- 'output port
- 'output-buffer-size 4096)))
-@end group
-@end example
-@end deffn
-
-@deffn {subprocess option} redisplay-hook thunk
-Specifies that @var{thunk} is to be run periodically when output from
-the subprocess is available. @var{Thunk} must be a procedure of no
-arguments, or @code{#f} indicating that no hook is supplied. This
-option is mostly useful for interactive systems. For example, the Edwin
-text editor uses this to update output buffers when running some
-subprocesses.
-
-The default value of this option is @code{#f}.
-
-@example
-@group
-(run-shell-command "ls -la /etc"
- 'redisplay-hook
- (lambda ()
- (update-buffer-contents buffer)))
-@end group
-@end example
-@end deffn
-
-@deffn {subprocess option} environment environment
-Specifies the environment variables that are to be used for the
-subprocess. @var{Environment} must be either a vector of strings or
-@code{#f} indicating the default environment. If it is a vector of
-strings, each string must be a name/value pair where the name and value
-are separated by an equal sign, for example, @code{"foo=bar"}. To
-define a variable with no value, just omit the value, as in @code{"foo="}.
-
-@vindex scheme-subprocess-environment
-Note that the variable @code{scheme-subprocess-environment} is bound to
-the default subprocess environment.
-
-The default value of this option is @code{#f}.
-
-@example
-@group
-(run-shell-command "ls -la /etc"
- 'environment
- (let* ((v scheme-subprocess-environment)
- (n (vector-length v))
- (v (vector-grow v (+ n 1))))
- (vector-set! v n "TERM=none")
- v))
-@end group
-@end example
-@end deffn
-
-@deffn {subprocess option} working-directory pathname
-Specifies the working directory in which the subprocess will run.
-
-The default value of this option is @code{(working-directory-pathname)}.
-
-@example
-@group
-(run-shell-command "ls -la" 'working-directory "/etc/")
-@end group
-@end example
-@end deffn
-
-@deffn {subprocess option} use-pty? boolean
-This option is meaningful only on unix systems; on other systems it is
-ignored. Specifies whether to communicate with the subprocess using
-@sc{pty} devices; if true, @sc{pty}s will be used, otherwise pipes will
-be used.
-
-The default value of this option is @code{#f}.
-
-@example
-@group
-(run-shell-command "ls -la /etc" 'use-pty? #t)
-@end group
-@end example
-@end deffn
-
-@deffn {subprocess option} shell-file-name pathname
-Specifies the shell program to use for @code{run-shell-command}.
-
-The default value of this option is @code{(os/shell-file-name)}. This
-is the value of the environment variable @code{SHELL}, or if
-@code{SHELL} is not set, the value is operating-system dependent as
-follows:
-
-@itemize @bullet
-@item
-On unix systems, @file{/bin/sh} is used.
-
-@item
-On OS/2 systems, the value of the environment variable @code{COMSPEC} is
-used, or if that is not set, @file{cmd.exe} on the current path.
-
-@item
-On Windows systems, the value of the environment variable @code{COMSPEC}
-is used. If that is not set, @file{cmd.exe} is used for Windows NT, or
-@file{command.com} is used for Windows 9x; in each case the shell is
-found by searching the path.
-@end itemize
-
-@example
-@group
-(run-shell-command "ls -la /etc"
- 'shell-file-name "/usr/local/bin/bash")
-@end group
-@end example
-@end deffn
-
-@node TCP Sockets, Miscellaneous OS Facilities, Subprocesses, Operating-System Interface
-@section TCP Sockets
-
-@cindex socket
-MIT/GNU Scheme provides access to @dfn{sockets}, which are a mechanism for
-inter-process communication. @sc{tcp} stream sockets are supported,
-which communicate between computers over a @sc{tcp/ip} network.
-@sc{tcp} sockets are supported on all operating systems.
-
-@cindex client socket
-@cindex server socket
-@sc{tcp} sockets have two distinct interfaces: one interface to
-implement a @dfn{client} and another to implement a @dfn{server}. The
-basic protocol is that servers set up a listening port and wait for
-connections from clients. Implementation of clients is simpler and will
-be treated first.
-
-@cindex hostname, TCP
-The socket procedures accept two special arguments, called
-@var{host-name} and @var{service}. @var{Host-name} is a string which
-must be the name of an internet host. It is looked up using the
-ordinary lookup rules for your computer. For example, if your host is
-@code{foo.mit.edu} and @var{host-name} is @code{"bar"}, then it
-specifies @code{bar.mit.edu}.
-
-@cindex service, TCP
-@cindex port number, TCP
-@var{Service} specifies the service to which you will connect. A
-networked computer normally provides several different services, such as
-telnet or @acronym{FTP}. Each service is associated with a unique
-@dfn{port number}; for example, the @code{"www"} service is associated
-with port @code{80}. The @var{service} argument specifies the port
-number, either as a string, or directly as an exact non-negative
-integer. Port strings are decoded by the operating system using a
-table; for example, on unix the table is in @file{/etc/services}.
-Usually you will use a port string rather than a number.
-
-@deffn procedure open-tcp-stream-socket host-name service [buffer-size [line-translation]]
-@code{open-tcp-stream-socket} opens a connection to the host specified
-by @var{host-name}. @var{Host-name} is looked up using the ordinary
-lookup rules for your computer. The connection is established to the
-service specified by @var{service}. The returned value is an
-@acronym{I/O} port, to which you can read and write characters using
-ordinary Scheme @acronym{I/O} procedures such as @code{read-char} and
-@code{write-char}.
-
-@var{Buffer-size} specifies the size of the read and write buffers used
-by the port; if this is unspecified or @code{#f}, the buffers will hold
-@code{4096} bytes.
-
-@var{Line-translation} specifies how end-of-line characters will be
-translated when reading or writing to the socket. If this is
-unspecified or @code{#f}, then lines will be terminated by @sc{cr-lf},
-which is the standard for most internet protocols. Otherwise, it must
-be a string, which specifies the line-ending character sequence to use.
-
-When you wish to close the connection, just use @code{close-port}.
-
-As an example, here is how you can open a connection to a web server:
-
-@example
-(open-tcp-stream-socket "web.mit.edu" "www")
-@end example
-@end deffn
-
-@cindex server socket
-Next we will treat setting up a @sc{tcp} server, which is slightly more
-complicated. Creating a server is a two-part process. First, you must
-open a @dfn{server socket}, which causes the operating system to listen
-to the network on a port that you specify. Once the server socket is
-opened, the operating system will allow clients to connect to your
-computer on that port.
-
-In the second step of the process, you @dfn{accept} the connection,
-which completes the connection initiated by the client, and allows you
-to communicate with the client. Accepting a connection does not affect
-the server socket; it continues to listen for additional client
-connections. You can have multiple client connections to the same
-server socket open simultaneously.
-
-@deffn procedure open-tcp-server-socket service [address]
-This procedure opens a server socket that listens for connections to
-@var{service}; the socket will continue to listen until you close it.
-The returned value is a server socket object.
-
-An error is signalled if another process is already listening on the
-service. Additionally, ports whose number is less than @code{1024} are
-privileged on many operating systems, and cannot be used by
-non-privileged processes; if @var{service} specifies such a port and you
-do not have administrative privileges, an error may be signalled.
-
-The optional argument @var{address} specifies the @acronym{IP} address
-on which the socket will listen. If this argument is not supplied or is
-given as @code{#f}, then the socket listens on all @acronym{IP}
-addresses for this machine. (This is equivalent to passing the result
-of calling @code{host-address-any}.)
-@end deffn
-
-@deffn procedure tcp-server-connection-accept server-socket block? peer-address [line-translation]
-Checks to see if a client has connected to @var{server-socket}. If
-so, an @acronym{I/O} port is returned. The returned port can be read
-and written using ordinary Scheme @acronym{I/O} procedures such as
-@code{read-char} and @code{write-char}.
-
-The argument @var{block?} says what to do if no client has connected at
-the time of the call. If @code{#f}, it says to return immediately with
-two values of @code{#f}. Otherwise, the call waits until a client
-connects.
-
-The argument @var{peer-address} is either @code{#f} or an @acronym{IP}
-address as allocated by @code{allocate-host-address}. If it is an
-@acronym{IP} address, the address is modified to be the address of the
-client making the connection.
-
-The optional argument @var{line-translation} specifies how end-of-line
-characters will be translated when reading or writing to the returned
-socket. If this is unspecified or @code{#f}, then lines will be
-terminated by @sc{cr-lf}, which is the standard for most internet
-protocols. Otherwise, it must be a string, which specifies the
-line-ending character sequence to use.
-
-Note that closing the port returned by this procedure does not affect
-@var{server-socket}; it just closes the particular client connection
-that was opened by the call. To close @var{server-socket}, use
-@code{close-tcp-server-socket}.
-@end deffn
-
-@deffn procedure close-tcp-server-socket server-socket
-Closes the server socket @var{server-socket}. The operating system will
-cease listening for network connections to that service. Client
-connections to @var{server-socket} that have already been accepted will
-not be affected.
-@end deffn
-
-@node Miscellaneous OS Facilities, , TCP Sockets, Operating-System Interface
-@section Miscellaneous OS Facilities
-
-This section contains assorted operating-system facilities that don't
-fit into other categories.
-
-@defvr variable microcode-id/operating-system
-@defvrx variable microcode-id/operating-system-name
-@code{microcode-id/operating-system} is bound to a symbol that specifies
-the type of operating system that Scheme is running under. There are
-three possible values: @code{unix}, @code{os/2}, or @code{nt}.
-
-@code{microcode-id/operating-system-name} is a string containing the
-same name as @code{microcode-id/operating-system}; the latter is created
-by interning the former as a symbol.
-@end defvr
-
-@defvr variable microcode-id/operating-system-variant
-This variable is a string that identifies the particular variant of the
-operating system that Scheme is running under. Here are some of the
-possible values:
-
-@example
-@group
-"GNU/Linux"
-"FreeBSD"
-"HP-UX"
-"SunOS"
-"OS/2 2.1"
-"OS/2 4.0"
-"Microsoft Windows NT 4.0 (Build 1381; Service Pack 3)"
-"Microsoft Windows 98 (Build 410)"
-@end group
-@end example
-
-@noindent
-For Windows systems, it is recommended that you match on the prefix of
-this string and ignore the @code{"Build"} suffix. This is because the
-suffix may contain information about service packs or fixes, while the
-prefix will be constant for a particular version of Windows.
-@end defvr
-
-The next few procedures provide access to the @dfn{domain name service}
-(@acronym{DNS}), which maintains associations between internet host
-names such as @code{"www.swiss.ai.mit.edu"} and @acronym{IP} addresses,
-such as @code{18.23.0.16}. In MIT/GNU Scheme, we represent an internet host
-name as a string, and an @acronym{IP} address as a byte vector of length
-4 (byte vectors are just character strings that are accessed using
-@code{vector-8b-ref} rather than @code{string-ref}). The bytes in an
-@acronym{IP} address read in the same order as they do when written out:
-
-@example
-(get-host-by-name "www.swiss") @result{} #("\022\027\000\020")
-@end example
-
-@deffn procedure get-host-by-name host-name
-Looks up the internet host name @var{host-name} using the @acronym{DNS},
-returning a vector of @acronym{IP} addresses for the corresponding host,
-or @code{#f} if there is no such host. Usually the returned vector has
-only one element, but if a host has more than one network interface, the
-vector might have more than one element.
-
-@example
-(get-host-by-name "www.swiss") @result{} #("\022\027\000\020")
-@end example
-@end deffn
-
-@deffn procedure get-host-by-address ip-address
-Does a reverse @acronym{DNS} lookup on @var{ip-address}, returning the
-internet host name corresponding to that address, or @code{#f} if there
-is no such host.
-
-@example
-(get-host-by-address "\022\027\000\020") @result{} "swissnet.ai.mit.edu"
-@end example
-@end deffn
-
-@deffn procedure canonical-host-name host-name
-Finds the ``canonical'' internet host name for @var{host-name}. For
-example:
-
-@example
-@group
-(canonical-host-name "zurich") @result{} "zurich.ai.mit.edu"
-(canonical-host-name "www.swiss") @result{} "swissnet.ai.mit.edu"
-@end group
-@end example
-
-@noindent
-In both examples, the default internet domain @samp{ai.mit.edu} is added
-to @var{host-name}. In the second example, @code{"www.swiss"} is an
-alias for another computer named @code{"swissnet"}.
-@end deffn
-
-@deffn procedure get-host-name
-Returns the string that identifies the computer that MIT/GNU Scheme is
-running on. Usually this is an unqualified internet host name, i.e.@:
-the host name without the domain suffix:
-
-@example
-(get-host-name) @result{} "aarau"
-@end example
-@end deffn
-
-@deffn procedure os/hostname
-Returns the canonical internet host name of the computer that MIT/GNU Scheme
-is running on. So, in contrast to the example for @code{get-host-name}:
-
-@example
-(os/hostname) @result{} "aarau.ai.mit.edu"
-@end example
-@end deffn
-
-@deffn procedure allocate-host-address
-Allocates and returns an @acronym{IP} address object. This is just a
-string of a fixed length (current 4 bytes) into which an @acronym{IP}
-address may be stored. This procedure is used to generate an
-appropriate argument to be passed to
-@code{tcp-server-connection-accept}.
-
-@example
-(allocate-host-address) @result{} "Xe\034\241"
-@end example
-@end deffn
-
-@deffn procedure host-address-any
-Return an @acronym{IP} address object that specifies ``any host''. This
-object is useful only when passed as the @var{address} argument to
-@code{open-tcp-server-socket}.
-
-@example
-(host-address-any) @result{} "\000\000\000\000"
-@end example
-@end deffn
-
-@deffn procedure host-address-loopback
-@cindex loopback interface
-Return an @acronym{IP} address object that specifies the local
-@dfn{loopback} network interface. The loopback interface is a software
-network interface that can be used only for communicating between
-processes on the same computer. This address object is useful only when
-passed as the @var{address} argument to @code{open-tcp-server-socket}.
-
-@example
-(host-address-loopback) @result{} "\177\000\000\001"
-@end example
-@end deffn
-
-@node Error System, Graphics, Operating-System Interface, Top
-@chapter Error System
-
-@findex error
-The MIT/GNU Scheme error system provides a uniform mechanism for the
-signalling of errors and other exceptional conditions. The simplest and
-most generally useful procedures in the error system are:
-
-@table @code
-@item error
-is used to signal simple errors, specifying a message and some irritant
-objects (@pxref{Condition Signalling}). Errors are usually handled by
-stopping the computation and putting the user in an error @sc{repl}.
-
-@item warn
-is used to signal warnings (@pxref{Condition Signalling}). Warnings are
-usually handled by printing a message on the console and continuing the
-computation normally.
-
-@item ignore-errors
-is used to suppress the normal handling of errors within a given dynamic
-extent (@pxref{Condition Handling}). Any error that occurs within the
-extent is trapped, returning immediately to the caller of
-@code{ignore-errors}.
-@end table
-
-More demanding applications require more powerful facilities. To give a
-concrete example, suppose you want floating-point division to return a very
-large number whenever the denominator is zero. This behavior can be
-implemented using the error system.
-
-The Scheme arithmetic system can signal many different kinds of errors,
-including floating-point divide by zero. In our example, we would like to
-handle this particular condition specially, allowing the system to handle
-other arithmetic errors in its usual way.
-
-The error system supports this kind of application by providing
-mechanisms for distinguishing different types of error conditions and
-for specifying where control should be transferred should a given
-condition arise. In this example, there is a specific object that
-represents the ``floating-point divide by zero'' condition type, and it
-is possible to dynamically specify an arbitrary Scheme procedure to be
-executed when a condition of that type is signalled. This procedure
-then finds the stack frame containing the call to the division operator,
-and returns the appropriate value from that frame.
-
-Another useful kind of behavior is the ability to specify uniform
-handling for related classes of conditions. For example, it might be
-desirable, when opening a file for input, to gracefully handle a variety of
-different conditions associated with the file system. One such condition
-might be that the file does not exist, in which case the program will try
-some other action, perhaps opening a different file instead. Another
-related condition is that the file exists, but is read protected, so it
-cannot be opened for input. If these or any other related conditions
-occur, the program would like to skip this operation and move on to
-something else.
-
-At the same time, errors unrelated to the file system should be treated in
-their usual way. For example, calling @code{car} on the argument @code{3}
-should signal an error. Or perhaps the name given for the file is
-syntactically incorrect, a condition that probably wants to be handled
-differently from the case of the file not existing.
-
-@cindex taxonomical link, of condition type (defn)
-@cindex specialization, of condition types (defn)
-@cindex generalization, of condition types (defn)
-To facilitate the handling of classes of conditions, the error system
-taxonomically organizes all condition types. The types are related to one
-another by @dfn{taxonomical links}, which specify that one type is a ``kind
-of'' another type. If two types are linked this way, one is considered to
-be a @dfn{specialization} of the other; or vice-versa, the second is a
-@dfn{generalization} of the first. In our example, all of the errors
-associated with opening an input file would be specializations of the
-condition type ``cannot open input file''.
-
-@vindex condition-type:simple-condition
-@vindex condition-type:warning
-@vindex condition-type:breakpoint
-@vindex condition-type:serious-condition
-The taxonomy of condition types permits any condition type to have no
-more than one immediate generalization. Thus, the condition types form
-a forest (set of trees). While users can create new trees, the standard
-taxonomy (@pxref{Taxonomy}) is rooted at
-@code{condition-type:serious-condition}, @code{condition-type:warning},
-@code{condition-type:simple-condition}, and
-@code{condition-type:breakpoint}; users are encouraged to add new
-subtypes to these condition types rather than create new trees in the
-forest.
-
-To summarize, the error system provides facilities for the following tasks.
-The sections that follow will describe these facilities in more
-detail.
-
-@table @asis
-@item Signalling a condition
-@findex signal-condition
-A condition may be signalled in a number of different ways. Simple
-errors may be signalled, without explicitly defining a condition type,
-using @code{error}. The @code{signal-condition} procedure provides the
-most general signalling mechanism.
-
-@item Handling a condition
-@findex bind-condition-handler
-The programmer can dynamically specify handlers for particular condition
-types or for classes of condition types, by means of the
-@code{bind-condition-handler} procedure. Individual handlers have
-complete control over the handling of a condition, and additionally may
-decide not to handle a particular condition, passing it on to previously
-bound handlers.
-
-@item Restarting from a handler
-@findex with-restart
-The @code{with-restart} procedure provides a means for
-condition-signalling code to communicate to condition-handling code what
-must be done to proceed past the condition. Handlers can examine the
-restarts in effect when a condition was signalled, allowing a structured
-way to continue an interrupted computation.
-
-@item Packaging condition state
-Each condition is represented by an explicit object. Condition objects
-contain information about the nature of the condition, information that
-describes the state of the computation from which the condition arose,
-and information about the ways the computation can be restarted.
-
-@item Classification of conditions
-@cindex condition type
-@cindex type, condition
-@cindex specialization, of condition types
-@cindex generalization, of condition types
-Each condition has a type, represented by a condition type object. Each
-condition type may be a specialization of some other condition types. A
-group of types that share a common generalization can be handled
-uniformly by specifying a handler for the generalization.
-@end table
-
-@menu
-* Condition Signalling::
-* Error Messages::
-* Condition Handling::
-* Restarts::
-* Condition Instances::
-* Condition Types::
-* Taxonomy::
-@end menu
-
-@node Condition Signalling, Error Messages, Error System, Error System
-@section Condition Signalling
-
-@cindex condition signalling (defn)
-@cindex signalling, of condition (defn)
-@findex make-condition
-Once a condition instance has been created using @code{make-condition}
-(or any condition constructor), it can be @dfn{signalled}. The act of
-signalling a condition is separated from the act of creating the
-condition to allow more flexibility in how conditions are handled. For
-example, a condition instance could be returned as the value of a
-procedure, indicating that something unusual has happened, to allow the
-caller to clean up some state. The caller could then signal the
-condition once it is ready.
-
-A more important reason for having a separate condition-signalling
-mechanism is that it allows @emph{resignalling}. When a signalled
-condition has been caught by a particular handler, and the handler decides
-that it doesn't want to process that particular condition, it can signal
-the condition again. This is one way to allow other handlers to get a
-chance to see the condition.
-
-@deffn procedure error reason argument @dots{}
-@cindex REP loop
-@findex signal-condition
-@findex warn
-This is the simplest and most common way to signal a condition that
-requires intervention before a computation can proceed (when
-intervention is not required, @code{warn} is more appropriate).
-@code{error} signals a condition (using @code{signal-condition}), and if
-no handler for that condition alters the flow of control (by invoking a
-restart, for example) it calls the procedure
-@code{standard-error-handler}, which normally prints an error message
-and stops the computation, entering an error @sc{repl}. Under normal
-circumstances @code{error} will not return a value (although an
-interactive debugger can be used to force this to occur).
-
-@findex make-condition
-@vindex condition-type:simple-error
-Precisely what condition is signalled depends on the first argument to
-@code{error}. If @var{reason} is a condition, then that condition is
-signalled and the @var{argument}s are ignored. If @var{reason} is a
-condition type, then a new instance of this type is generated and
-signalled; the @var{argument}s are used to generate the values of the
-fields for this condition type (they are passed as the @var{field-plist}
-argument to @code{make-condition}). In the most common case, however,
-@var{reason} is neither a condition nor a condition type, but rather a
-string or symbol. In this case a condition of type
-@code{condition-type:simple-error} is created with the @var{message}
-field containing the @var{reason} and the @var{irritants} field
-containing the @var{argument}s.
-@end deffn
-
-@deffn procedure warn reason argument @dots{}
-@findex error
-@findex signal-condition
-@vindex condition-type:simple-warning
-When a condition is not severe enough to warrant intervention, it is
-appropriate to signal the condition with @code{warn} rather than
-@code{error}. As with @code{error}, @code{warn} first calls
-@code{signal-condition}; the condition that is signalled is chosen
-exactly as in @code{error} except that a condition of type
-@code{condition-type:simple-warning} is signalled if @var{reason} is
-neither a condition nor a condition type. If the condition is not
-handled, @code{warn} calls the procedure
-@code{standard-warning-handler}, which normally prints a warning message
-and continues the computation by returning from @code{warn}.
-
-@findex muffle-warning
-@code{warn} establishes a restart named @code{muffle-warning} before
-calling @code{signal-condition}. This allows a signal handler to
-prevent the generation of the warning message by calling
-@code{muffle-warning}. The value of a call to @code{warn} is
-unspecified.
-@end deffn
-
-@deffn procedure signal-condition condition
-@cindex generalization, of condition types
-@cindex specialization, of condition types
-@findex break-on-signals
-@findex bind-default-condition-handler
-@findex bind-condition-handler
-This is the fundamental operation for signalling a condition. The
-precise operation of @code{signal-condition} depends on the condition
-type of which @var{condition} is an instance, the condition types set by
-@code{break-on-signals}, and the handlers established by
-@code{bind-condition-handler} and @code{bind-default-condition-handler}.
-
-@cindex REP loop
-If the @var{condition} is an instance of a type that is a specialization
-of any of the types specified by @code{break-on-signals}, then a
-breakpoint @sc{repl} is initiated. Otherwise (or when that @sc{repl}
-returns), the handlers established by @code{bind-condition-handler} are
-checked, most recent first. Each applicable handler is invoked, and the
-search for a handler continues if the handler returns normally. If all
-applicable handlers return, then the applicable handlers established by
-@code{bind-default-condition-handler} are checked, again most recent
-first. Finally, if no handlers apply (or all return in a normal
-manner), @code{signal-condition} returns an unspecified value.
-
-@emph{Note:} unlike many other systems, the MIT/GNU Scheme runtime library
-does @emph{not} establish handlers of any kind. (However, the Edwin
-text editor uses condition handlers extensively.) Thus, calls to
-@code{signal-condition} will return to the caller unless there are user
-supplied condition handlers, as the following example shows:
-
-@example
-@group
-(signal-condition
- (make-condition
- condition-type:error
- (call-with-current-continuation (lambda (x) x))
- '() @r{; no restarts}
- '())) @r{; no fields}
-@result{} @r{unspecified}
-@end group
-@end example
-@end deffn
-
-@node Error Messages, Condition Handling, Condition Signalling, Error System
-@section Error Messages
-
-@cindex error messages, conventions
-@cindex conventions for error messages
-By convention, error messages (and in general, the reports generated by
-@code{write-condition-report}) should consist of one or more complete
-sentences. The usual rules for sentences should be followed: the first
-word of the sentence should be capitalized, and the sentence should be
-terminated by a period. The message should not contain extraneous
-whitespace such as line breaks or indentation.
-
-
-The error system provides a simple formatting language that allows the
-programmer to have some control over the printing of error messages.
-This formatting language will probably be redesigned in a future
-release.
-
-@findex display
-@findex write
-Error messages typically consist of a string describing the error,
-followed by some irritant objects. The string is printed using
-@code{display}, and the irritants are printed using @code{write},
-typically with a space between each irritant. To allow simple
-formatting, we introduce a @dfn{noise} object, printed using
-@code{display}. The irritant list may contain ordinary objects
-interspersed with noise objects. Each noise object is printed using
-@code{display}, with no extra whitespace, while each normal object is
-printed using @code{write}, prefixed by a single space character.
-
-Here is an example:
-
-@example
-@group
-(define (error-within-procedure message irritant procedure)
- (error message
- irritant
- (error-irritant/noise "within procedure")
- procedure
- (error-irritant/noise ".")))
-@end group
-@end example
-
-@noindent
-This would format as follows:
-
-@example
-@group
-(error-within-procedure "Bad widget" 'widget-32 'invert-widget) @error{}
-
-Bad widget widget-32 within procedure invert-widget.
-@end group
-@end example
-
-Here are the operations supporting error messages:
-
-@deffn procedure format-error-message message irritants port
-@var{Message} is typically a string (although this is not required),
-@var{irritants} a list of irritant objects, and @var{port} an output
-port. Formats @var{message} and @var{irritants} to @var{port} in the
-standard way. Note that, during the formatting process, the depth and
-breadth to which lists are printed are each limited to small numbers, to
-guarantee that the output from each irritant is not arbitrarily large.
-@end deffn
-
-@deffn procedure error-irritant/noise value
-Creates and returns a noise object whose value is @var{value}.
-@end deffn
-
-@node Condition Handling, Restarts, Error Messages, Error System
-@section Condition Handling
-
-@cindex handler, condition (defn)
-@cindex condition handler (defn)
-@findex bind-condition-handler
-@findex bind-default-condition-handler
-The occurrence of a condition is signalled using
-@code{signal-condition}. @code{signal-condition} attempts to locate and
-invoke a @dfn{condition handler} that is prepared to deal with the type
-of condition that has occurred. A condition handler is a procedure of
-one parameter, the condition that is being signalled. A procedure is
-installed as a condition handler by calling
-@code{bind-condition-handler} (to establish a handler that is in effect
-only while a particular thunk is executing) or
-@code{bind-default-condition-handler} (to establish a handler that is in
-effect permanently). As implied by the name, handlers created by
-@code{bind-default-condition-handler} are invoked only after all other
-applicable handlers have been invoked.
-
-A @var{handler} may process a signal in any way it deems appropriate,
-but the common patterns are:
-
-@table @asis
-@item Ignore the condition.
-By returning from the handler in the usual manner.
-
-@item Handle the condition.
-By doing some processing and then invoking a restart (or, less
-preferably, a continuation) that was established at some point prior to
-the call to @code{signal-condition}.
-
-@item Resignal a condition.
-By doing some processing and calling @code{signal-condition} with either
-the same condition or a newly created one. In order to support this,
-@code{signal-condition} runs @var{handler} in such a way that a
-subsequent call to @code{signal-condition} sees only the handlers that
-were established prior to this one.
-@end table
-
-@cindex REP loop
-@findex break-on-signals
-As an aid to debugging condition handlers, Scheme maintains a set of
-condition types that will cause an interactive breakpoint to occur prior
-to normal condition signalling. That is, @code{signal-condition}
-creates a new @sc{repl} prior to its normal operation when its argument
-is a condition that is a specialization of any of these types. The
-procedure @code{break-on-signals} establishes this set of condition
-types.
-
-@deffn procedure ignore-errors thunk
-@findex error
-@vindex condition-type:error
-Executes @var{thunk} with a condition handler that intercepts the
-signalling of any specialization of @code{condition-type:error}
-(including those produced by calls to @code{error}) and immediately
-terminates the execution of @var{thunk} and returns from the call to
-@code{ignore-errors} with the signalled condition as its value. If
-@var{thunk} returns normally, its value is returned from
-@code{ignore-errors}.
-
-Notice that @code{ignore-errors} does not ``turn off signalling'' or
-condition handling. Condition handling takes place in the normal manner
-but conditions specialized from @code{condition-type:error} are trapped
-rather than propogated as they would be by default.
-@end deffn
-
-@deffn procedure bind-condition-handler condition-types handler thunk
-@findex signal-condition
-Invokes @var{thunk} after adding @var{handler} as a condition handler
-for the conditions specified by @var{condition-types}.
-@var{Condition-types} must be a list of condition types; signalling a
-condition whose type is a specialization of any of these types will
-cause the @var{handler} to be invoked. See @code{signal-condition} for
-a description of the mechanism used to invoke handlers.
-
-By special extension, if @var{condition-types} is the empty list then
-the @var{handler} is called for all conditions.
-@end deffn
-
-@deffn procedure bind-default-condition-handler condition-types handler
-@findex signal-condition
-Installs @var{handler} as a (permanent) condition handler for the
-conditions specified by @var{condition-types}. @var{Condition-types}
-must be a list of condition types; signalling a condition whose type is
-a specialization of any of these types will cause the @var{handler} to
-be invoked. See @code{signal-condition} for a description of the
-mechanism used to invoke handlers.
-
-By special extension, if @var{condition-types} is the empty list then
-the @var{handler} is called for all conditions.
-@end deffn
-
-@deffn procedure break-on-signals condition-types
-@findex signal-condition
-@cindex REP loop
-Arranges for @code{signal-condition} to create an interactive @sc{repl}
-before it signals a condition that is a specialization of any of the
-types in the list of @var{condition-types}. This can be extremely
-helpful when trying to debug code that uses custom condition handlers.
-In order to create a @sc{repl} when @emph{any} condition type is
-signalled it is best to actually put a breakpoint on entry to
-@code{signal-condition}.
-@end deffn
-
-@deffn procedure standard-error-handler condition
-@findex error
-@findex ignore-error
-@vindex standard-error-hook
-@cindex REP loop
-Called internally by @code{error} after it calls
-@code{signal-condition}. Normally creates creates a new @sc{repl} with
-the prompt @code{"error>"} (but see @code{standard-error-hook}). In
-order to simulate the effect of calling @code{error}, code may call
-@code{signal-condition} directly and then call
-@code{standard-error-handler} if @code{signal-condition} returns.
-@end deffn
-
-@defvr variable standard-error-hook
-@findex standard-error-handler
-@cindex fluid binding
-@cindex dynamic binding
-@cindex REP loop
-This variable controls the behavior of the procedure
-@code{standard-error-handler}, and hence @code{error}. It is intended
-to be bound with @code{fluid-let} and is normally @code{#f}. It may be
-changed to a procedure of one argument and will then be invoked (with
-@code{standard-error-hook} rebound to @code{#f}) by
-@code{standard-error-handler} just prior to starting the error
-@sc{repl}. It is passed one argument, the condition being signalled.
-@end defvr
-
-@deffn procedure standard-warning-handler condition
-@vindex standard-warning-hook
-@findex signal-condition
-@findex notification-output-port
-@findex write-condition-report
-This is the procedure called internally by @code{warn} after it calls
-@code{signal-condition}. The normal behavior of
-@code{standard-warning-handler} is to print a message (but see
-@code{standard-warning-hook}). More precisely, the message is printed
-to the port returned by @code{notification-output-port}. The message is
-formed by first printing the string @code{"Warning: "} to this port, and
-then calling @code{write-condition-report} on @var{condition} and the port.
-
-@findex muffle-warning
-In order to simulate the effect of calling @code{warn}, code may call
-@code{signal-condition} directly and then call
-@code{standard-warning-handler} if @code{signal-condition} returns.
-(This is not sufficient to implement the @code{muffle-warning} protocol,
-however. For that purpose an explicit restart must be provided.)
-@end deffn
-
-@defvr variable standard-warning-hook
-@findex standard-warning-handler
-@cindex fluid binding
-@cindex dynamic binding
-This variable controls the behavior of the procedure
-@code{standard-warning-handler}, and hence @code{warn}. It is intended
-to be bound with @code{fluid-let} and is normally @code{#f}. It may be
-changed to a procedure of one argument and will then be invoked (with
-@code{standard-warning-hook} rebound to @code{#f}) by
-@code{standard-warning-handler} in lieu of writing the warning message.
-It is passed one argument, the condition being signalled.
-@end defvr
-
-@node Restarts, Condition Instances, Condition Handling, Error System
-@section Restarts
-
-@cindex restart effector (defn)
-@cindex effector, restart (defn)
-@cindex restart (defn)
-@findex with-restart
-@findex with-simple-restart
-The Scheme error system provides a mechanism, known as @dfn{restarts},
-that helps coordinate condition-signalling code with condition-handling
-code. A module of code that detects and signals conditions can provide
-procedures (using @code{with-simple-restart} or @code{with-restart}) to
-be invoked by handlers that wish to continue, abort, or restart the
-computation. These procedures, called @dfn{restart effectors}, are
-encapsulated in restart objects.
-
-@findex find-restart
-@findex invoke-restart
-@findex invoke-restart-interactively
-When a condition object is created, it contains a set of restart
-objects, each of which contains a restart effector. Condition handlers
-can inspect the condition they are handling (using @code{find-restart}
-to find restarts by name, or @code{condition/restarts} to see the entire
-set), and they can invoke the associated effectors (using
-@code{invoke-restart} or @code{invoke-restart-interactively}).
-Effectors can take arguments, and these may be computed directly by the
-condition-handling code or by gathering them interactively from the
-user.
-
-@findex abort
-@findex continue
-@findex muffle-warning
-@findex retry
-@findex store-value
-@findex use-value
-@cindex protocol, restart (defn)
-@cindex restart protocol
-The names of restarts can be chosen arbitrarily, but the choice of name
-is significant. These names are used to coordinate between the
-signalling code (which supplies names for restarts) and the handling
-code (which typically chooses a restart effector by the name of its
-restart). Thus, the names specify the @dfn{restart protocol}
-implemented by the signalling code and invoked by the handling code.
-The protocol indicates the number of arguments required by the effector
-code as well as the semantics of the arguments.
-
-Scheme provides a conventional set of names (hence, protocols) for
-common use. By choosing the names of restarts from this set, signalling
-code can indicate that it is able to perform a small set of fairly
-common actions (@code{abort}, @code{continue}, @code{muffle-warning},
-@code{retry}, @code{store-value}, @code{use-value}). In turn, simple
-condition-handling code can look for the kind of action it wishes to
-perform and simply invoke it by name. All of Scheme's conventional
-names are symbols, although in general restart names are not restricted
-to any particular data type. In addition, the object @code{#f} is
-reserved to indicate the ``not for automated use'' protocol: these
-restarts should be activated only under human control.
-
-@findex with-simple-restart
-Restarts themselves are first-class objects. They encapsulate their
-name, a procedure (known as the @var{effector}) to be executed if they
-are invoked, and a thunk (known as the @var{reporter}) that can be
-invoked to display a description of the restart (used, for example, by
-the interactive debugger). Invoking a restart is an indication that a
-handler has chosen to accept control for a condition; as a consequence,
-the @var{effector} of the restart should not return, since this would
-indicate that the handler declined to handle the condition. Thus, the
-@var{effector} should call a continuation captured before the
-condition-signalling process began. The most common pattern of usage by
-signalling code is encapsulated in @code{with-simple-restart}.
-
-Within this chapter, a parameter named @var{restarts} will accept any of
-the following values:
-
-@itemize @bullet
-@item
-A list of restart objects.
-
-@item
-A condition. The procedure @code{condition/restarts} is called on the
-condition, and the resulting list of restarts is used in place of the
-condition.
-
-@item
-The symbol @code{bound-restarts}. The procedure @code{bound-restarts}
-is called (with no arguments), and the resulting list of restarts is
-used in place of the symbol.
-
-@item
-If the @var{restarts} parameter is optional and is not supplied, it is
-equivalent to having specified the symbol @code{bound-restarts}.
-@end itemize
-
-@menu
-* Establishing Restart Code::
-* Invoking Standard Restart Code::
-* Finding and Invoking General Restart Code::
-* The Named Restart Abstraction::
-@end menu
-
-@node Establishing Restart Code, Invoking Standard Restart Code, Restarts, Restarts
-@subsection Establishing Restart Code
-
-@deffn procedure with-simple-restart name reporter thunk
-Invokes @var{thunk} in a dynamic environment created by adding a restart
-named @var{name} to the existing named restarts. @var{Reporter} may be
-used during the execution of @var{thunk} to produce a description of the
-newly created restart; it must either be a procedure of one argument (a
-port) or a string. By convention, the description generated by
-@var{reporter} should be a short complete sentence, with first word
-capitalized and terminated by a period. The sentence should fit on one
-line with a little room to spare (see the examples below); usually this
-means that the sentence should be 70 characters or less in length.
-
-If the restart created by @code{with-simple-restart} is invoked it
-simply aborts the computation in progress by returning an unspecified
-value from the call to @code{with-simple-restart}. Otherwise
-@code{with-simple-restart} returns the value computed by @var{thunk}.
-@end deffn
-
-@example
-@group
-(with-simple-restart 'george "This restart is named george."
- (lambda () 3)) @result{} 3
-
-(with-simple-restart 'george "This restart is named george."
- (lambda ()
- (invoke-restart (find-restart 'george)))) @result{} @code{unspecific}
-
-(with-simple-restart 'george "This restart is named george."
- (lambda () (car 3)))
-;The object 3, passed as the first argument to car,
-; is not the correct type.
-;To continue, call RESTART with an option number:
-; (RESTART 3) => Specify an argument to use in its place.
-; (RESTART 2) => This restart is named george.
-; (RESTART 1) => Return to read-eval-print level 1.
-@end group
-@end example
-
-@deffn procedure with-restart name reporter effector interactor thunk
-@findex invoke-restart
-Invokes @var{thunk} in a dynamic environment created by adding a restart
-named @var{name} to the existing named restarts. @var{Reporter} may be
-used during the execution of @var{thunk} to produce a description of the
-newly created restart; it must either be a procedure of one argument (a
-port) or a string. @var{Effector} is a procedure which will be called
-when the restart is invoked by @code{invoke-restart}. @var{Interactor}
-specifies the arguments that are to be passed to @var{effector} when it
-is invoked interactively; it may be either a procedure of no arguments,
-or @code{#f}. If @var{interactor} is @code{#f}, this restart is not
-meant to be invoked interactively.
-
-The value returned by @code{with-restart} is the value returned by
-@var{thunk}. Should the restart be invoked by a condition handler,
-however, the @var{effector} will not return back to the handler that
-invoked it. Instead, the @var{effector} should call a continuation
-created before the condition-signalling process began, and
-@code{with-restart} will therefore not return in the normal manner.
-@end deffn
-
-@example
-@group
-(define (by-george! thunk)
- @r{; This code handles conditions that arise while executing @var{thunk}}
- @r{; by invoking the GEORGE restart, passing 1 and 2 to the restart's}
- @r{; @var{effector} code.}
- (bind-condition-handler '() ; All conditions
- (lambda (condition)
- (invoke-restart (find-restart 'george) 1 2))
- thunk))
-@end group
-
-@group
-(define (can-george! thunk)
- @r{; This code provides a way of handling errors: the GEORGE restart.}
- @r{; In order to GEORGE you must supply two values.}
- (lambda ()
- (call-with-current-continuation
- (lambda (kappa)
- (with-restart
- 'george @r{; Name}
- "This restart is named george." @r{; Reporter}
- (lambda (a b) @r{; Effector}
- (kappa (list 'george a b)))
- values @r{; Interactor}
- thunk))))) @r{; Thunk}
-@end group
-
-@group
-(by-george! (can-george! (lambda () -3)) @result{} -3
-(by-george! (can-george! (lambda () (car 'x)))) @result{} (george 1 2)
-@end group
-@end example
-
-@node Invoking Standard Restart Code, Finding and Invoking General Restart Code, Establishing Restart Code, Restarts
-@subsection Invoking Standard Restart Code
-
-Scheme supports six standard protocols for restarting from a condition,
-each encapsulated using a named restart (for use by condition-signalling
-code) and a simple procedure (for use by condition-handling code).
-Unless otherwise specified, if one of these procedures is unable to find
-its corresponding restart, it returns immediately with an unspecified
-value.
-
-Each of these procedures accepts an optional argument @var{restarts},
-which is described above in @ref{Restarts}.
-
-@deffn procedure abort [restarts]
-@cindex REP loop
-Abort the computation, using the restart named @code{abort}. The
-corresponding effector takes no arguments and abandons the current line
-of computation. This is the restart provided by Scheme's @sc{repl}.
-
-@vindex condition-type:no-such-restart
-If there is no restart named @code{abort}, this procedure signals an
-error of type @code{condition-type:no-such-restart}.
-@end deffn
-
-@deffn procedure continue [restarts]
-Continue the current computation, using the restart named
-@code{continue}. The corresponding effector takes no arguments and
-continues the computation beyond the point at which the condition was
-signalled.
-@end deffn
-
-@deffn procedure muffle-warning [restarts]
-@findex warn
-Continue the current computation, using the restart named
-@code{muffle-warning}. The corresponding effector takes no arguments
-and continues the computation beyond the point at which any warning
-message resulting from the condition would be presented to the user.
-The procedure @code{warn} establishes a @code{muffle-warning} restart
-for this purpose.
-
-@vindex condition-type:no-such-restart
-If there is no restart named @code{muffle-warning}, this procedure
-signals an error of type @code{condition-type:no-such-restart}.
-@end deffn
-
-@deffn procedure retry [restarts]
-Retry the current computation, using the restart named @code{retry}.
-The corresponding effector takes no arguments and simply retries the
-same computation that triggered the condition. The condition may
-reoccur, of course, if the root cause has not been eliminated. The code
-that signals a ``file does not exist'' error can be expected to supply a
-@code{retry} restart. The restart would be invoked after first creating
-the missing file, since the computation is then likely to succeed if it
-is simply retried.
-@end deffn
-
-@deffn procedure store-value new-value [restarts]
-Retry the current computation, using the restart named
-@code{store-value}, after first storing @var{new-value}. The
-corresponding effector takes one argument, @var{new-value}, and stores
-it away in a restart-dependent location, then retries the same
-computation that triggered the condition. The condition may reoccur, of
-course, if the root cause has not been eliminated. The code that
-signals an ``unassigned variable'' error can be expected to supply a
-@code{store-value} restart; this would store the value in the variable
-and continue the computation.
-@end deffn
-
-@deffn procedure use-value new-value [restarts]
-@findex retry
-@findex store-value
-Retry the current computation, using the restart named @code{use-value},
-but substituting @var{new-value} for a value that previously caused a
-failure. The corresponding effector takes one argument,
-@var{new-value}, and retries the same computation that triggered the
-condition with the new value substituted for the failing value. The
-condition may reoccur, of course, if the new value also induces the
-condition.
-
-The code that signals an ``unassigned variable'' error can be expected
-to supply a @code{use-value} restart; this would simply continue the
-computation with @var{new-value} instead of the value of the variable.
-Contrast this with the @code{retry} and @code{store-value} restarts. If
-the @code{retry} restart is used it will fail because the variable still
-has no value. The @code{store-value} restart could be used, but it
-would alter the value of the variable, so that future references to the
-variable would not be detected.
-@end deffn
-
-@node Finding and Invoking General Restart Code, The Named Restart Abstraction, Invoking Standard Restart Code, Restarts
-@subsection Finding and Invoking General Restart Code
-
-@findex with-restart
-@findex with-simple-restart
-@findex bound-restart
-@findex find-restart
-@findex invoke-restart
-@findex invoke-restart-interactively
-Restarts are a general mechanism for establishing a protocol between
-condition-signalling and condition-handling code. The Scheme error
-system provides ``packaging'' for a number of common protocols. It also
-provides lower-level hooks that are intended for implementing customized
-protocols. The mechanism used by signalling code (@code{with-restart}
-and @code{with-simple-restart}) is used for both purposes.
-
-Four additional operations are provided for the use of
-condition-handling code. Two operations (@code{bound-restarts} and
-@code{find-restart}) allow condition-handling code to locate active
-restarts. The other two operations (@code{invoke-restart} and
-@code{invoke-restart-interactively}) allow restart effectors to be
-invoked once the restart object has been located.
-
-In addition, there is a data abstraction that provides access to the
-information encapsulated in restart objects.
-
-@deffn procedure bound-restarts
-Returns a list of all currently active restart objects, most recently
-installed first. @code{bound-restarts} should be used with caution by
-condition-handling code, since it reveals all restarts that are active
-at the time it is called, rather than at the time the condition was
-signalled. It is useful, however, for collecting the list of restarts
-for inclusion in newly generated condition objects or for inspecting the
-current state of the system.
-@end deffn
-
-@deffn procedure find-restart name [restarts]
-Returns the first restart object named @var{name} in the list of
-@var{restarts} (permissible values for @var{restarts} are described
-above in @ref{Restarts}). When used in a condition handler,
-@code{find-restart} is usually passed the name of a particular restart
-@emph{and} the condition object that has been signalled. In this way
-the handler finds only restarts that were available when the condition
-was created (usually the same as when it was signalled). If
-@var{restarts} is omitted, the currently active restarts would be used,
-and these often include restarts added after the condition ocurred.
-@end deffn
-
-@deffn procedure invoke-restart restart argument @dots{}
-@findex invoke-restart-interactively
-Calls the restart effector encapsulated in @var{restart}, passing the
-specified @var{argument}s to it. @code{invoke-restart} is intended for
-use by condition-handling code that understands the protocol implemented
-by @var{restart}, and can therefore calculate and pass an appropriate
-set of arguments.
-
-If a condition handler needs to interact with a user to gather the
-arguments for an effector (e.g.@: if it does not understand the protocol
-implemented by @var{restart}) @code{invoke-restart-interactively} should
-be used instead of @code{invoke-restart}.
-@end deffn
-
-@deffn procedure invoke-restart-interactively restart
-First calls the interactor encapsulated in @var{restart} to
-interactively gather the arguments needed for @var{restart}'s effector.
-It then calls the effector, passing these arguments to it.
-
-@findex restart/interactor
-@code{invoke-restart-interactively} is intended for calling interactive
-restarts (those for which @code{restart/interactor} is not @code{#f}).
-For convenience, @code{invoke-restart-interactively} will call the
-restart's effector with no arguments if the restart has no interactor;
-this behavior may change in the future.
-@end deffn
-
-@node The Named Restart Abstraction, , Finding and Invoking General Restart Code, Restarts
-@subsection The Named Restart Abstraction
-
-A restart object is very simple, since it encapsulates only a name,
-effector, interactor, and description.
-
-@deffn procedure restart? object
-Returns @code{#f} if and only if @var{object} is not a restart.
-@end deffn
-
-@deffn procedure restart/name restart
-@findex eq?
-Returns the name of @var{restart}. While the Scheme error system uses
-only symbols and the object @code{#f} for its predefined names, programs
-may use arbitrary objects (name equivalence is tested using @code{eq?}).
-@end deffn
-
-@deffn procedure restart/effector restart
-@findex invoke-restart
-@findex invoke-restart-interactively
-Returns the effector encapsulated in @var{restart}. Normally this
-procedure is not used since @code{invoke-restart} and
-@code{invoke-restart-interactively} capture the most common invocation
-patterns.
-@end deffn
-
-@deffn procedure restart/interactor restart
-@findex invoke-restart-interactively
-Returns the interactor encapsulated in @var{restart}. This is either a
-procedure of no arguments or the object @code{#f}. Normally this
-procedure is not used since @code{invoke-restart-interactively} captures
-the most common usage. Thus @code{restart/interactor} is most useful as
-a predicate to determine if @var{restart} is intended to be invoked
-interactively.
-@end deffn
-
-@deffn procedure write-restart-report restart port
-Writes a description of @var{restart} to @var{port}. This works by
-either displaying (if it is a string) or calling (if it is a procedure)
-the @var{reporter} that was supplied when the restart was created.
-@end deffn
-
-@node Condition Instances, Condition Types, Restarts, Error System
-@section Condition Instances
-
-@cindex condition (defn)
-@cindex condition instance (defn)
-@cindex instance, of condition (defn)
-A @dfn{condition}, in addition to the information associated with its
-type, usually contains other information that is not shared with other
-conditions of the same type. For example, the condition type associated
-with ``unbound variable'' errors does not specify the name of the
-variable that was unbound. The additional information is captured in a
-@dfn{condition} object, also called a @dfn{condition instance}.
-
-In addition to information that is specific to a given type of condition
-(such as the variable name for ``unbound variable'' conditions), every
-condition instance also contains a continuation that encapsulates the
-state of the computation in which the condition occurred. This
-continuation is used for analyzing the computation to learn more about
-the context in which the condition occurred. It is @emph{not} intended
-to provide a mechanism for continuing the computation; that mechanism is
-provided by restarts.
-
-@menu
-* Generating Operations on Conditions::
-* Condition State::
-* Simple Condition Instance Operations::
-@end menu
-
-@node Generating Operations on Conditions, Condition State, Condition Instances, Condition Instances
-@subsection Generating Operations on Conditions
-
-@findex condition-constructor
-@findex condition-accessor
-@findex condition-signaller
-@findex condition-predicate
-Scheme provides four procedures that take a condition type as input and
-produce operations on the corresponding condition object. These are
-reminiscent of the operations on record types that produce record
-operators (@pxref{Records}). Given a condition type it is possible to
-generate: a constructor for instances of the type (using
-@code{condition-constructor}); an accessor to extract the contents of a
-field in instances of the type (using @code{condition-accessor}); a
-predicate to test for instances of the type (using
-@code{condition-predicate}); and a procedure to create and signal an
-instance of the type (using @code{condition-signaller}).
-
-Notice that the creation of a condition object is distinct from
-signalling an occurrence of the condition. Condition objects are
-first-class; they may be created and never signalled, or they may be
-signalled more than once. Further notice that there are no procedures
-for modifying conditions; once created, a condition cannot be altered.
-
-@deffn procedure condition-constructor condition-type field-names
-@findex condition/restarts
-@cindex bound-restarts
-@cindex restarts, bound
-Returns a constructor procedure that takes as arguments values for the
-fields specified in @var{field-names} and creates a condition of type
-@var{condition-type}. @var{Field-names} must be a list of symbols that
-is a subset of the @var{field-names} in @var{condition-type}. The
-constructor procedure returned by @code{condition-constructor} has
-signature
-
-@example
-(lambda (@var{continuation} @var{restarts} . @var{field-values}) @dots{})
-@end example
-
-@noindent
-where the @var{field-names} correspond to the @var{field-values}. The
-constructor argument @var{restarts} is described in @ref{Restarts}.
-Conditions created by the constructor procedure have @code{#f} for the
-values of all fields other than those specified by @var{field-names}.
-
-For example, the following procedure @code{make-simple-warning}
-constructs a condition of type @code{condition-type:simple-warning}
-given a continuation (where the condition occurred), a description of
-the restarts to be made available, a warning message, and a list of
-irritants that caused the warning:
-
-@example
-@group
-(define make-simple-warning
- (condition-constructor condition-type:simple-warning
- '(message irritants)))
-@end group
-@end example
-@end deffn
-
-@deffn procedure condition-accessor condition-type field-name
-@cindex specialization, of condition types
-Returns a procedure that takes as input a condition object of type
-@var{condition-type} and extracts the contents of the specified
-@var{field-name}. @code{condition-accessor} signals
-@code{error:bad-range-argument} if the @var{field-name} isn't one of the
-named fields of @var{condition-type}; the returned procedure will signal
-@code{error:wrong-type-argument} if passed an object other than a
-condition of type @var{condition-type} or one of its specializations.
-
-@findex access-condition
-If it is known in advance that a particular field of a condition will be
-accessed repeatedly it is worth constructing an accessor for the field
-using @code{condition-accessor} rather than using the (possibly more
-convenient, but slower) @code{access-condition} procedure.
-@end deffn
-
-@deffn procedure condition-predicate condition-type
-@cindex specialization, of condition types
-Returns a predicate procedure for testing whether an object is a
-condition of type @var{condition-type} or one of its specializations
-(there is no predefined way to test for a condition of a given type but
-@emph{not} a specialization of that type).
-@end deffn
-
-@deffn procedure condition-signaller condition-type field-names default-handler
-Returns a signalling procedure with parameters @var{field-names}. When
-the signalling procedure is called it creates and signals a condition of
-type @var{condition-type}. If the condition isn't handled (i.e.@: if no
-handler is invoked that causes an escape from the current continuation)
-the signalling procedure reduces to a call to @var{default-handler} with
-the condition as its argument.
-
-There are several standard procedures that are conventionally used for
-@var{default-handler}. If @var{condition-type} is a specialization of
-@code{condition-type:error}, @var{default-handler} should be the
-procedure@* @code{standard-error-handler}. If @var{condition-type} is a
-specialization of @code{condition-type:warning}, @var{default-handler}
-should be the procedure @code{standard-warning-handler}. If
-@var{condition-type} is a specialization of
-@code{condition-type:breakpoint}, @var{default-handler} should be the
-procedure @code{standard-breakpoint-handler}.
-@end deffn
-
-@node Condition State, Simple Condition Instance Operations, Generating Operations on Conditions, Condition Instances
-@subsection Condition Abstraction
-
-The condition data type is abstracted through a predicate
-@code{condition?} and a set of accessor procedures.
-
-@deffn procedure condition? object
-Returns @code{#f} if and only if @var{object} is not a condition.
-@end deffn
-
-@deffn procedure condition/type condition
-Returns the condition type of which @var{condition} is an instance.
-@end deffn
-
-@deffn procedure condition/error? condition
-@vindex condition-type:error
-@cindex specialization, of condition types
-Returns @code{#t} if the @var{condition} is an instance of condition
-type @code{condition-type:error} or a specialization of it, @code{#f}
-otherwise.
-@end deffn
-
-@deffn procedure condition/restarts condition
-Returns the list of restarts specified when @var{condition} was created.
-@end deffn
-
-@deffn procedure condition/continuation condition
-Returns the continuation specified when @var{condition} was created.
-This is provided for inspecting the state of the system when the
-condition occurred, @emph{not} for continuing or restarting the
-computation.
-@end deffn
-
-@deffn procedure write-condition-report condition port
-Writes a description of @var{condition} to @var{port}, using the
-reporter function from the condition type associated with
-@var{condition}. See also @code{condition/report-string}.
-@end deffn
-
-@node Simple Condition Instance Operations, , Condition State, Condition Instances
-@subsection Simple Operations on Condition Instances
-
-The simple procedures described in this section are built on top of the
-more detailed abstraction of condition objects described above. While
-these procedures are sometimes easier to use, they are often less
-efficient.
-
-@deffn procedure make-condition condition-type continuation restarts field-plist
-@findex condition/restarts
-@cindex bound-restarts
-@cindex restarts, bound
-Create a new condition object as an instance of @var{condition-type},
-associated with @var{continuation}. The @var{continuation} is provided
-for inspection purposes only, @emph{not} for restarting the computation.
-The @var{restarts} argument is described in @ref{Restarts}. The
-@var{field-plist} is an alternating list of field names and values for
-those fields, where the field names are those that would be returned by
-@code{(condition-type/field-names @var{condition-type})}. It is used to
-provide values for fields in the condition object; fields with no value
-specified are set to @code{#f}. Once a condition object has been
-created there is no way to alter the values of these fields.
-@end deffn
-
-@deffn procedure access-condition condition field-name
-@findex condition-accessor
-Returns the value stored in the field @var{field-name} within
-@var{condition}. @var{Field-name} must be one of the names returned by
-@code{(condition-type/field-names (condition/type @var{condition}))}.
-@code{access-condition} looks up the @var{field-name} at runtime, so it
-is more efficient to use @code{condition-accessor} to create an access
-function if the same field is to be extracted from several instances of
-the same condition type.
-@end deffn
-
-@deffn procedure condition/report-string condition
-@findex write-condition-report
-Returns a string containing a report of the @var{condition}. This is
-generated by calling @code{write-condition-report} on @var{condition}
-and a string output port, and returning the output collected by the port
-as a string.
-@end deffn
-
-@node Condition Types, Taxonomy, Condition Instances, Error System
-@section Condition Types
-
-@cindex condition type
-@cindex type, of condition
-Each condition has a @dfn{condition type} object associated with it.
-These objects are used as a means of focusing on related classes of
-conditions, first by concentrating all of the information about a
-specific class of condition in a single place, and second by specifying
-an inheritance relationship between types. This inheritance
-relationship forms the taxonomic structure of the condition hierarchy
-(@pxref{Taxonomy}).
-
-The following procedures consititute the abstraction for condition
-types.
-
-@deffn procedure make-condition-type name generalization field-names reporter
-@cindex generalization, of condition types
-Creates and returns a (new) condition type that is a specialization of
-@var{generalization} (if it is a condition type) or is the root of a new
-tree of condition types (if @var{generalization} is @code{#f}). For
-debugging purposes, the condition type has a @var{name}, and instances
-of this type contain storage for the fields specified by
-@var{field-names} (a list of symbols) in addition to the fields common
-to all conditions (@var{type}, @var{continuation} and @var{restarts}).
-
-@var{Reporter} is used to produce a description of a particular
-condition of this type. It may be a string describing the condition, a
-procedure of arity two (the first argument will be a condition of this
-type and the second a port) that will @code{write} the message to the
-given port, or @code{#f} to specify that the reporter should be taken
-from the condition type @var{generalization} (or produce an
-``undocumented condition of type @dots{}'' message if @var{generalization}
-is @code{#f}). The conventions used to form descriptions are spelled
-out in @ref{Error Messages}.
-@end deffn
-
-@deffn procedure condition-type/error? condition-type
-@vindex condition-type:error
-@cindex specialization, of condition types
-Returns @code{#t} if the @var{condition-type} is
-@code{condition-type:error} or a specialization of it, @code{#f}
-otherwise.
-@end deffn
-
-@deffn procedure condition-type/field-names condition-type
-@cindex generalization, of condition types
-Returns a list of all of the field names for a condition of type
-@var{condition-type}. This is the set union of the fields specified
-when this @var{condition-type} was created with the
-@code{condition-type/field-names} of the generalization of this
-@var{condition-type}.
-@end deffn
-
-@deffn procedure condition-type/generalizations condition-type
-@cindex generalization, of condition types
-Returns a list of all of the generalizations of @var{condition-type}.
-Notice that every condition type is considered a generalization of
-itself.
-@end deffn
-
-@deffn procedure condition-type? object
-Returns @code{#f} if and only if @var{object} is not a condition type.
-@end deffn
-
-@node Taxonomy, , Condition Types, Error System
-@section Condition-Type Taxonomy
-
-The MIT/GNU Scheme error system provides a rich set of predefined condition
-types. These are organized into a forest through taxonomic links
-providing the relationships for ``specializes'' and ``generalizes''.
-The chart appearing below shows these relationships by indenting all the
-specializations of a given type relative to the type. Note that the
-variables that are bound to these condition types are prefixed by
-@samp{condition-type:}; for example, the type appearing in the following
-table as @samp{simple-error} is stored in the variable
-@code{condition-type:simple-error}. Users are encouraged to add new
-condition types by creating specializations of existing ones.
-
-Following the chart are detailed descriptions of the predefined
-condition types. Some of these types are marked as @dfn{abstract}
-types. Abstract types are not intended to be used directly as the type
-of a condition; they are to be used as generalizations of other types,
-and for binding condition handlers. Types that are not marked as
-abstract are @dfn{concrete}; they are intended to be explicitly used as
-a condition's type.
-
-@page
-@example
-@group
-serious-condition
- error
- simple-error
- illegal-datum
- wrong-type-datum
- wrong-type-argument
- wrong-number-of-arguments
- datum-out-of-range
- bad-range-argument
- inapplicable-object
- file-error
- file-operation-error
- derived-file-error
- port-error
- derived-port-error
- variable-error
- unbound-variable
- unassigned-variable
- arithmetic-error
- divide-by-zero
- floating-point-overflow
- floating-point-underflow
- control-error
- no-such-restart
- not-loading
- primitive-procedure-error
- system-call-error
-warning
- simple-warning
-simple-condition
-breakpoint
-@end group
-@end example
-
-@deffn {condition type} condition-type:serious-condition
-This is an abstract type. All serious conditions that require some form
-of intervention should inherit from this type. In particular, all
-errors inherit from this type.
-@end deffn
-
-@deffn {condition type} condition-type:error
-This is an abstract type. All errors should inherit from this type.
-@end deffn
-
-@deffn {condition type} condition-type:simple-error message irritants
-This is the condition generated by the @code{error} procedure when its
-first argument is not a condition or condition type. The fields
-@var{message} and @var{irritants} are taken directly from the arguments
-to @code{error}; @var{message} contains an object (usually a string) and
-@var{irritants} contains a list of objects. The reporter for this type
-uses @code{format-error-message} to generate its output from
-@var{message} and @var{irritants}.
-@end deffn
-
-@deffn {condition type} condition-type:illegal-datum datum
-This is an abstract type. This type indicates the class of errors in
-which a program discovers an object that lacks specific required
-properties. Most commonly, the object is of the wrong type or is
-outside a specific range. The @var{datum} field contains the offending
-object.
-@end deffn
-
-@deffn {condition type} condition-type:wrong-type-datum datum type
-This type indicates the class of errors in which a program discovers an
-object that is of the wrong type. The @var{type} field contains a
-string describing the type that was expected, and the @var{datum} field
-contains the object that is of the wrong type.
-@end deffn
-
-@example
-@group
-(error:wrong-type-datum 3.4 "integer") @error{}
-;The object 3.4 is not an integer.
-;To continue, call RESTART with an option number:
-; (RESTART 1) => Return to read-eval-print level 1.
-@end group
-@end example
-
-@deffn procedure error:wrong-type-datum datum type
-This procedure signals a condition of type
-@code{condition-type:wrong-type-datum}. The @var{datum} and @var{type}
-fields of the condition are filled in from the corresponding arguments
-to the procedure.
-@end deffn
-
-@deffn {condition type} condition-type:wrong-type-argument datum type operator operand
-This type indicates that a procedure was passed an argument of the wrong
-type. The @var{operator} field contains the procedure (or a symbol
-naming the procedure), the @var{operand} field indicates the argument
-position that was involved (this field contains either a symbol, a
-non-negative integer, or @code{#f}), the @var{type} field contains a
-string describing the type that was expected, and the @var{datum} field
-contains the offending argument.
-@end deffn
-
-@example
-@group
-(+ 'a 3) @error{}
-;The object a, passed as the first argument to integer-add,
-; is not the correct type.
-;To continue, call RESTART with an option number:
-; (RESTART 2) => Specify an argument to use in its place.
-; (RESTART 1) => Return to read-eval-print level 1.
-@end group
-
-@group
-(list-copy 3)
-;The object 3, passed as an argument to list-copy, is not a list.
-;To continue, call RESTART with an option number:
-; (RESTART 1) => Return to read-eval-print level 1.
-@end group
-@end example
-
-@deffn procedure error:wrong-type-argument datum type operator
-This procedure signals a condition of type
-@code{condition-type:wrong-type-argument}. The @var{datum}, @var{type}
-and @var{operator} fields of the condition are filled in from the
-corresponding arguments to the procedure; the @var{operand} field of the
-condition is set to @code{#f}.
-@end deffn
-
-@deffn {condition type} condition-type:wrong-number-of-arguments datum type operands
-This type indicates that a procedure was called with the wrong number of
-arguments. The @var{datum} field contains the procedure being called,
-the @var{type} field contains the number of arguments that the procedure
-accepts, and the @var{operands} field contains a list of the arguments
-that were passed to the procedure.
-@end deffn
-
-@example
-@group
-(car 3 4) @error{}
-;The procedure car has been called with 2 arguments;
-; it requires exactly 1 argument.
-;To continue, call RESTART with an option number:
-; (RESTART 1) => Return to read-eval-print level 1.
-@end group
-@end example
-
-@deffn procedure error:wrong-number-of-arguments datum type operands
-This procedure signals a condition of type
-@code{condition-type:wrong-number-of-arguments}. The @var{datum},
-@var{type} and @var{operands} fields of the condition are filled in from
-the corresponding arguments to the procedure.
-@end deffn
-
-@deffn {condition type} condition-type:datum-out-of-range datum
-This type indicates the class of errors in which a program discovers an
-object that is of the correct type but is otherwise out of range. Most
-often, this type indicates that an index to some data structure is
-outside of the range of indices for that structure. The @var{datum}
-field contains the offending object.
-@end deffn
-
-@example
-@group
-(error:datum-out-of-range 3) @error{}
-;The object 3 is not in the correct range.
-;To continue, call RESTART with an option number:
-; (RESTART 1) => Return to read-eval-print level 1.
-@end group
-@end example
-
-@deffn procedure error:datum-out-of-range datum
-This procedure signals a condition of type
-@code{condition-type:datum-out-of-range}. The @var{datum} field of the
-condition is filled in from the corresponding argument to the procedure.
-@end deffn
-
-@deffn {condition type} condition-type:bad-range-argument datum operator operand
-This type indicates that a procedure was passed an argument that is of
-the correct type but is otherwise out of range. Most often, this type
-indicates that an index to some data structure is outside of the range
-of indices for that structure. The @var{operator} field contains the
-procedure (or a symbol naming the procedure), the @var{operand} field
-indicates the argument position that was involved (this field contains
-either a symbol, a non-negative integer, or @code{#f}), and the
-@var{datum} field is the offending argument.
-@end deffn
-
-@example
-@group
-(string-ref "abc" 3) @error{}
-;The object 3, passed as the second argument to string-ref,
-; is not in the correct range.
-;To continue, call RESTART with an option number:
-; (RESTART 2) => Specify an argument to use in its place.
-; (RESTART 1) => Return to read-eval-print level 1.
-@end group
-@end example
-
-@deffn procedure error:bad-range-argument datum operator
-This procedure signals a condition of type
-@code{condition-type:bad-range-argument}. The @var{datum} and
-@var{operator} fields of the condition are filled in from the
-corresponding arguments to the procedure; the @var{operand} field of the
-condition is set to @code{#f}.
-@end deffn
-
-@deffn {condition type} condition-type:inapplicable-object datum operands
-This type indicates an error in which a program attempted to apply an
-object that is not a procedure. The object being applied is saved in
-the @var{datum} field, and the arguments being passed to the object are
-saved as a list in the @var{operands} field.
-@end deffn
-
-@example
-@group
-(3 4) @error{}
-;The object 3 is not applicable.
-;To continue, call RESTART with an option number:
-; (RESTART 2) => Specify a procedure to use in its place.
-; (RESTART 1) => Return to read-eval-print level 1.
-@end group
-@end example
-
-@deffn {condition type} condition-type:file-error filename
-This is an abstract type. It indicates that an error associated with a
-file has occurred. For example, attempting to delete a nonexistent file
-will signal an error. The @var{filename} field contains a filename or
-pathname associated with the operation that failed.
-@end deffn
-
-@deffn {condition type} condition-type:file-operation-error filename verb noun reason operator operands
-This is the most common condition type for file system errors. The
-@var{filename} field contains the filename or pathname that was being
-operated on. The @var{verb} field contains a string which is the verb
-or verb phrase describing the operation being performed, and the
-@var{noun} field contains a string which is a noun or noun phrase
-describing the object being operated on. The @var{reason} field
-contains a string describing the error that occurred. The
-@var{operator} field contains the procedure performing the operation (or
-a symbol naming that procedure), and the @var{operands} field contains a
-list of the arguments that were passed to that procedure. For example,
-an attempt to delete a nonexistent file would have the following field
-values:
-
-@example
-@group
-filename "/zu/cph/tmp/no-such-file"
-verb "delete"
-noun "file"
-reason "no such file or directory"
-operator file-remove
-operands ("/zu/cph/tmp/no-such-file")
-@end group
-@end example
-
-@noindent
-and would generate a message like this:
-
-@example
-@group
-(delete-file "/zu/cph/tmp/no-such-file") @error{}
-;Unable to delete file "/zu/cph/tmp/no-such-file" because:
-; No such file or directory.
-;To continue, call RESTART with an option number:
-; (RESTART 3) => Try to delete the same file again.
-; (RESTART 2) => Try to delete a different file.
-; (RESTART 1) => Return to read-eval-print level 1.
-@end group
-@end example
-@end deffn
-
-@deffn procedure error:file-operation-error filename verb noun reason operator operands
-This procedure signals a condition of type
-@code{condition-type:file-operation-error}. The fields of the condition
-are filled in from the corresponding arguments to the procedure.
-@end deffn
-
-@deffn {condition type} condition-type:derived-file-error filename condition
-This is another kind of file error, which is generated by obscure
-file-system errors that do not fit into the standard categories. The
-@var{filename} field contains the filename or pathname that was being
-operated on, and the @var{condition} field contains a condition
-describing the error in more detail. Usually the @var{condition} field
-contains a condition of type @code{condition-type:system-call-error}.
-@end deffn
-
-@deffn procedure error:derived-file filename condition
-This procedure signals a condition of type
-@code{condition-type:derived-file-error}. The @var{filename} and
-@var{condition} fields of the condition are filled in from the
-corresponding arguments to the procedure.
-@end deffn
-
-@deffn {condition type} condition-type:port-error port
-This is an abstract type. It indicates that an error associated with a
-I/O port has occurred. For example, writing output to a file port can
-signal an error if the disk containing the file is full; that error
-would be signalled as a port error. The @var{port} field contains the
-associated port.
-@end deffn
-
-@deffn {condition type} condition-type:derived-port-error port condition
-This is a concrete type that is signalled when port errors occur. The
-@var{port} field contains the port associated with the error, and the
-@var{condition} field contains a condition object that describes the
-error in more detail. Usually the @var{condition} field contains a
-condition of type @code{condition-type:system-call-error}.
-@end deffn
-
-@deffn procedure error:derived-port port condition
-This procedure signals a condition of type
-@code{condition-type:derived-port-error}. The @var{port} and
-@var{condition} fields of the condition are filled in from the
-corresponding arguments to the procedure.
-@end deffn
-
-@deffn {condition type} condition-type:variable-error location environment
-This is an abstract type. It indicates that an error associated with a
-variable has occurred. The @var{location} field contains the name of
-the variable, and the @var{environment} field contains the environment
-in which the variable was referenced.
-@end deffn
-
-@deffn {condition type} condition-type:unbound-variable location environment
-This type is generated when a program attempts to access or modify a
-variable that is not bound. The @var{location} field contains the name
-of the variable, and the @var{environment} field contains the
-environment in which the reference occurred.
-@end deffn
-
-@example
-@group
-foo @error{}
-;Unbound variable: foo
-;To continue, call RESTART with an option number:
-; (RESTART 3) => Specify a value to use instead of foo.
-; (RESTART 2) => Define foo to a given value.
-; (RESTART 1) => Return to read-eval-print level 1.
-@end group
-@end example
-
-@deffn {condition type} condition-type:unassigned-variable location environment
-This type is generated when a program attempts to access a variable that
-is not assigned. The @var{location} field contains the name of the
-variable, and the @var{environment} field contains the environment in
-which the reference occurred.
-@end deffn
-
-@example
-@group
-foo @error{}
-;Unassigned variable: foo
-;To continue, call RESTART with an option number:
-; (RESTART 3) => Specify a value to use instead of foo.
-; (RESTART 2) => Set foo to a given value.
-; (RESTART 1) => Return to read-eval-print level 1.
-@end group
-@end example
-
-@deffn {condition type} condition-type:arithmetic-error operator operands
-This is an abstract type. It indicates that a numerical operation was
-unable to complete because of an arithmetic error. (For example,
-division by zero.) The @var{operator} field contains the procedure that
-implements the operation (or a symbol naming the procedure), and the
-@var{operands} field contains a list of the arguments that were passed
-to the procedure.
-@end deffn
-
-@deffn {condition type} condition-type:divide-by-zero operator operands
-This type is generated when a program attempts to divide by zero. The
-@var{operator} field contains the procedure that implements the failing
-operation (or a symbol naming the procedure), and the @var{operands}
-field contains a list of the arguments that were passed to the
-procedure.
-@end deffn
-
-@example
-@group
-(/ 1 0)
-;Division by zero signalled by /.
-;To continue, call RESTART with an option number:
-; (RESTART 1) => Return to read-eval-print level 1.
-@end group
-@end example
-
-@deffn procedure error:divide-by-zero operator operands
-This procedure signals a condition of type
-@code{condition-type:divide-by-zero}. The @var{operator} and
-@var{operands} fields of the condition are filled in from the
-corresponding arguments to the procedure.
-@end deffn
-
-@deffn {condition type} condition-type:floating-point-overflow operator operands
-This type is generated when a program performs an arithmetic operation
-that results in a floating-point overflow. The @var{operator} field
-contains the procedure that implements the operation (or a symbol naming
-the procedure), and the @var{operands} field contains a list of the
-arguments that were passed to the procedure.
-@end deffn
-
-@deffn {condition type} condition-type:floating-point-underflow operator operands
-This type is generated when a program performs an arithmetic operation
-that results in a floating-point underflow. The @var{operator} field
-contains the procedure that implements the operation (or a symbol naming
-the procedure), and the @var{operands} field contains a list of the
-arguments that were passed to the procedure.
-@end deffn
-
-@deffn {condition type} condition-type:primitive-procedure-error operator operands
-This is an abstract type. It indicates that an error was generated by a
-primitive procedure call. Primitive procedures are distinguished from
-ordinary procedures in that they are not written in Scheme but instead
-in the underlying language of the Scheme implementation. The
-@var{operator} field contains the procedure that implements the
-operation (or a symbol naming the procedure), and the @var{operands}
-field contains a list of the arguments that were passed to the
-procedure.
-@end deffn
-
-@deffn {condition type} condition-type:system-call-error operator operands system-call error-type
-This is the most common condition type generated by primitive
-procedures. A condition of this type indicates that the primitive made
-a system call to the operating system, and that the system call
-signalled an error. The system-call error is reflected back to Scheme
-as a condition of this type, except that many common system-call errors
-are automatically translated by the Scheme implementation into more
-useful forms; for example, a system-call error that occurs while trying
-to delete a file will be translated into a condition of type
-@code{condition-type:file-operation-error}. The @var{operator} field
-contains the procedure that implements the operation (or a symbol naming
-the procedure), and the @var{operands} field contains a list of the
-arguments that were passed to the procedure. The @var{system-call} and
-@var{error-type} fields contain symbols that describe the specific
-system call that was being made and the error that occurred,
-respectively; these symbols are completely operating-system dependent.
-@end deffn
-
-@deffn {condition type} condition-type:control-error
-This is an abstract type. It describes a class of errors relating to
-program control flow.
-@end deffn
-
-@deffn {condition type} condition-type:no-such-restart name
-This type indicates that a named restart was not active when it was
-expected to be. Conditions of this type are signalled by several
-procedures that look for particular named restarts, for example
-@code{muffle-warning}. The @var{name} field contains the name that was
-being searched for.
-@end deffn
-
-@example
-@group
-(muffle-warning) @error{}
-;The restart named muffle-warning is not bound.
-;To continue, call RESTART with an option number:
-; (RESTART 1) => Return to read-eval-print level 1.
-@end group
-@end example
-
-@deffn procedure error:no-such-restart name
-This procedure signals a condition of type
-@code{condition-type:no-such-restart}. The @var{name} field of the
-condition is filled in from the corresponding argument to the procedure.
-@end deffn
-
-@deffn {condition type} condition-type:not-loading
-A condition of this type is generated when the procedure
-@code{current-load-pathname} is called from somewhere other than inside
-a file being loaded.
-@end deffn
-
-@example
-@group
-(current-load-pathname) @error{}
-;No file being loaded.
-;To continue, call RESTART with an option number:
-; (RESTART 1) => Return to read-eval-print level 1.
-@end group
-@end example
-
-@deffn {condition type} condition-type:warning
-This is an abstract type. All warnings should inherit from this type.
-Warnings are a class of conditions that are usually handled by informing
-the user of the condition and proceeding the computation normally.
-@end deffn
-
-@deffn {condition type} condition-type:simple-warning message irritants
-This is the condition generated by the @code{warn} procedure. The
-fields @var{message} and @var{irritants} are taken directly from the
-arguments to @code{warn}; @var{message} contains an object (usually a
-string) and @var{irritants} contains a list of objects. The reporter
-for this type uses @code{format-error-message} to generate its output
-from @var{message} and @var{irritants}.
-@end deffn
-
-@deffn {condition type} condition-type:simple-condition message irritants
-This is an unspecialized condition that does not fall into any of the
-standard condition classes. The @var{message} field contains an object
-(usually a string) and @var{irritants} contains a list of objects. The
-reporter for this type uses @code{format-error-message} to generate its
-output from @var{message} and @var{irritants}.
-@end deffn
-
-@deffn {condition type} condition-type:breakpoint environment message prompt
-A condition of this type is generated by the breakpoint mechanism. The
-contents of its fields are beyond the scope of this document.
-@end deffn
-
-@node Graphics, Win32 Package Reference, Error System, Top
-@chapter Graphics
-@cindex graphics
-
-MIT/GNU Scheme has a simple two-dimensional line-graphics interface
-that is suitable for many graphics applications. In particular it is
-often used for plotting data points from experiments. The interface is
-generic in that it can support different types of graphics devices in a
-uniform manner. At the present time only one type of graphics device
-is implemented on each operating system.
-
-Procedures are available for drawing points, lines, and text; defining
-the coordinate system; clipping graphics output; controlling some of the
-drawing characteristics; and controlling the output buffer (for devices
-that perform buffering). Additionally, devices may support custom
-operations, such as control of colors.
-
-There are some constraints on the arguments to the procedures described
-in this chapter. Any argument named @var{graphics-device} must be a
-graphics device object that was returned from a call to
-@code{make-graphics-device}. Any argument that is a coordinate must be
-either an exact integer or an inexact real.
-
-@menu
-* Opening and Closing of Graphics Devices::
-* Coordinates for Graphics::
-* Drawing Graphics::
-* Characteristics of Graphics Output::
-* Buffering of Graphics Output::
-* Clipping of Graphics Output::
-* Custom Graphics Operations::
-* Images::
-* X Graphics:: Graphics on the X Window System
-* Win32 Graphics:: Graphics on Microsoft Windows and Windows NT
-* OS/2 Graphics:: Graphics on IBM OS/2
-@end menu
-
-@node Opening and Closing of Graphics Devices, Coordinates for Graphics, Graphics, Graphics
-@section Opening and Closing of Graphics Devices
-@cindex graphics, opening and closing devices
-
-@deffn procedure graphics-type-available? graphics-device-type
-This predicate returns @code{#t} if the graphics system named by the
-symbol @var{graphics-device-type} is implemented by the Scheme system.
-Otherwise it returns @code{#f}, in which case it is an error to attempt
-to make a graphics device using @var{graphics-device-type}.
-@end deffn
-
-@deffn procedure enumerate-graphics-types
-This procedure returns a list of symbols which are the names of all the
-graphics device types that are supported by the Scheme system. The
-result is useful in deciding what additional arguments to supply to
-@code{make-graphics-device}, as each device type typically has a unique
-way of specifying the initial size, shape and other attributes.
-@end deffn
-
-@deffn procedure make-graphics-device graphics-device-type object @dots{}
-This operation creates and returns a graphics device object.
-@var{Graphics-device-type} is a symbol naming a graphics device type,
-and both the number and the meaning of the remaining arguments is
-determined by that type (see the description of each device type for
-details); @var{graphics-device-type} must satisfy
-@code{graphics-type-available?}. @var{Graphics-device-type} may also be
-@code{#f}, in which case the graphics device type is chosen by the
-system from what is available. This allows completely portable graphics
-programs to be written provided no custom graphics operations are used.
-When @var{graphics-device-type} is @code{#f} no further arguments may be
-given; each graphics device type will use some ``sensible'' defaults.
-If more control is required then the program should use one of the two
-procedures above to dispatch on the available types.
-
-This procedure opens and initializes the device, which remains valid
-until explicitly closed by the procedure @code{graphics-close}.
-Depending on the implementation of the graphics device, if this object
-is reclaimed by the garbage collector, the graphics device may remain
-open or it may be automatically closed. While a graphics device remains
-open the resources associated with it are not released.
-@end deffn
-
-@deffn procedure graphics-close graphics-device
-Closes @var{graphics-device}, releasing its resources. Subsequently it
-is an error to use @var{graphics-device}.
-@end deffn
-
-@node Coordinates for Graphics, Drawing Graphics, Opening and Closing of Graphics Devices, Graphics
-@section Coordinates for Graphics
-@cindex graphics, coordinate systems
-
-@cindex coordinates, graphics
-@cindex device coordinates, graphics (defn)
-@cindex graphics, device coordinates (defn)
-@cindex virtual coordinates, graphics (defn)
-@cindex graphics, virtual coordinates (defn)
-Each graphics device has two different coordinate systems associated
-with it: @dfn{device coordinates} and @dfn{virtual coordinates}. Device
-coordinates are generally defined by low-level characteristics of the
-device itself, and often cannot be changed. Most device coordinate
-systems are defined in terms of pixels, and usually the upper-left-hand
-corner is the origin of the coordinate system, with @var{x} coordinates
-increasing to the right and @var{y} coordinates increasing downwards.
-
-In contrast, virtual coordinates are more flexible in the units
-employed, the position of the origin, and even the direction in which
-the coordinates increase. A virtual coordinate system is defined by
-assigning coordinates to the edges of a device. Because these edge
-coordinates are arbitrary real numbers, any Cartesian coordinate system
-can be defined.
-
-All graphics procedures that use coordinates are defined on virtual
-coordinates. For example, to draw a line at a particular place on a
-device, the virtual coordinates for the endpoints of that line are
-given.
-
-When a graphics device is initialized, its virtual coordinate system is
-reset so that the left edge corresponds to an x-coordinate of @code{-1},
-the right edge to x-coordinate @code{1}, the bottom edge to y-coordinate
-@code{-1}, and the top edge to y-coordinate @code{1}.
-
-@deffn procedure graphics-device-coordinate-limits graphics-device
-Returns (as multiple values) the device coordinate limits for
-@var{graphics-device}. The values, which are exact non-negative
-integers, are: @var{x-left}, @var{y-bottom}, @var{x-right}, and
-@var{y-top}.
-@end deffn
-
-@deffn procedure graphics-coordinate-limits graphics-device
-Returns (as multiple values) the virtual coordinate limits for
-@var{graphics-device}. The values, which are real numbers, are:
-@var{x-left}, @var{y-bottom}, @var{x-right}, and @var{y-top}.
-@end deffn
-
-@deffn procedure graphics-set-coordinate-limits graphics-device x-left y-bottom x-right y-top
-Changes the virtual coordinate limits of @var{graphics-device} to the
-given arguments. @var{X-left}, @var{y-bottom}, @var{x-right}, and
-@var{y-top} must be real numbers. Subsequent calls to
-@code{graphics-coordinate-limits} will return the new limits. This
-operation has no effect on the device's displayed contents.
-
-Note: This operation usually resets the clip rectangle, although it is
-not guaranteed to do so. If a clip rectangle is in effect when this
-procedure is called, it is necessary to redefine the clip rectangle
-afterwards.
-@end deffn
-
-@node Drawing Graphics, Characteristics of Graphics Output, Coordinates for Graphics, Graphics
-@section Drawing Graphics
-@cindex graphics, drawing
-
-The procedures in this section provide the basic drawing capabilities of
-Scheme's graphics system.
-
-@deffn procedure graphics-clear graphics-device
-Clears the display of @var{graphics-device}. Unaffected by the current
-drawing mode.
-@end deffn
-
-@deffn procedure graphics-draw-point graphics-device x y
-Draws a single point on @var{graphics-device} at the virtual coordinates
-given by @var{x} and @var{y}, using the current drawing mode.
-@end deffn
-
-@deffn procedure graphics-erase-point graphics-device x y
-Erases a single point on @var{graphics-device} at the virtual
-coordinates given by @var{x} and @var{y}. This procedure is unaffected
-by the current drawing mode.
-@end deffn
-
-@noindent
-This is equivalent to
-
-@example
-@group
-(lambda (device x y)
- (graphics-bind-drawing-mode device 0
- (lambda ()
- (graphics-draw-point device x y))))
-@end group
-@end example
-
-@deffn procedure graphics-draw-line graphics-device x-start y-start x-end y-end
-@var{X-start}, @var{y-start}, @var{x-end}, and @var{y-end} must be real
-numbers. Draws a line on @var{graphics-device} that connects the points
-(@var{x-start}, @var{y-start}) and (@var{x-end}, @var{y-end}). The line
-is drawn using the current drawing mode and line style.
-@end deffn
-
-@deffn procedure graphics-draw-text graphics-device x y string
-Draws the characters of @var{string} at the point (@var{x}, @var{y}) on
-@var{graphics-device}, using the current drawing mode. The
-characteristics of the characters drawn are device-dependent, but all
-devices are initialized so that the characters are drawn upright, from
-left to right, with the leftmost edge of the leftmost character at
-@var{x}, and the baseline of the characters at @var{y}.
-@end deffn
-
-@cindex graphics, cursor (defn)
-@cindex cursor, graphics (defn)
-The following two procedures provide an alternate mechanism for drawing
-lines, which is more akin to using a plotter. They maintain a
-@dfn{cursor}, which can be positioned to a particular point and then
-dragged to another point, producing a line. Sequences of connected line
-segments can be drawn by dragging the cursor from point to point.
-
-Many graphics operations have an unspecified effect on the cursor. The
-following exceptions are guaranteed to leave the cursor unaffected:
-
-@example
-@group
-graphics-device-coordinate-limits
-graphics-coordinate-limits
-graphics-enable-buffering
-graphics-disable-buffering
-graphics-flush
-graphics-bind-drawing-mode
-graphics-set-drawing-mode
-graphics-bind-line-style
-graphics-set-line-style
-@end group
-@end example
-
-The initial state of the cursor is unspecified.
-
-@deffn procedure graphics-move-cursor graphics-device x y
-Moves the cursor for @var{graphics-device} to the point (@var{x},
-@var{y}). The contents of the device's display are unchanged.
-@end deffn
-
-@deffn procedure graphics-drag-cursor graphics-device x y
-Draws a line from @var{graphics-device}'s cursor to the point (@var{x},
-@var{y}), simultaneously moving the cursor to that point. The line is
-drawn using the current drawing mode and line style.
-@end deffn
-
-@node Characteristics of Graphics Output, Buffering of Graphics Output, Drawing Graphics, Graphics
-@section Characteristics of Graphics Output
-
-@cindex graphics, output characteristics
-Two characteristics of graphics output are so useful that they are
-supported uniformly by all graphics devices: @dfn{drawing mode} and
-@dfn{line style}. A third characteristic, @dfn{color}, is equally
-useful (if not more so), but implementation restrictions prohibit a
-uniform interface.
-
-@cindex drawing mode, graphics (defn)
-@cindex graphics, drawing mode (defn)
-The @dfn{drawing mode}, an exact integer in the range @code{0} to
-@code{15} inclusive, determines how the figure being drawn is combined
-with the background over which it is drawn to generate the final result.
-Initially the drawing mode is set to ``source'', so that the new output
-overwrites whatever appears in that place. Useful alternative drawing
-modes can, for example, erase what was already there, or invert it.
-
-Altogether 16 boolean operations are available for combining the source
-(what is being drawn) and the destination (what is being drawn over).
-The source and destination are combined by the device on a
-pixel-by-pixel basis as follows:
-
-@example
-@group
-Mode Meaning
----- -------
-0 ZERO @r{[erase; use background color]}
-1 source AND destination
-2 source AND (NOT destination)
-3 source
-4 (NOT source) AND destination
-5 destination
-6 source XOR destination
-7 source OR destination
-8 NOT (source OR destination)
-9 NOT (source XOR destination)
-10 NOT destination
-11 source OR (NOT destination)
-12 NOT source
-13 (NOT source) OR destination
-14 (NOT source) OR (NOT destination)
-15 ONE @r{[use foreground color]}
-@end group
-@end example
-
-@cindex line style, graphics (defn)
-@cindex graphics, line style (defn)
-The @dfn{line style}, an exact integer in the range @code{0} to @code{7}
-inclusive, determines which parts of a line are drawn in the foreground
-color, and which in the background color. The default line style,
-``solid'', draws the entire line in the foreground color.
-Alternatively, the ``dash'' style alternates between foreground and
-background colors to generate a dashed line. This capability is useful
-for plotting several things on the same graph.
-
-Here is a table showing the name and approximate pattern of the
-different styles. A @samp{1} in the pattern represents a foreground
-pixel, while a @samp{-} represents a background pixel. Note that the
-precise output for each style will vary from device to device. The only
-style that is guaranteed to be the same for every device is ``solid''.
-
-@example
-@group
-Style Name Pattern
------ ------- -------
-0 solid 1111111111111111
-1 dash 11111111--------
-2 dot 1-1-1-1-1-1-1-1-
-3 dash dot 1111111111111-1-
-4 dash dot dot 11111111111-1-1-
-5 long dash 11111111111-----
-6 center dash 111111111111-11-
-7 center dash dash 111111111-11-11-
-@end group
-@end example
-
-@deffn procedure graphics-bind-drawing-mode graphics-device drawing-mode thunk
-@deffnx procedure graphics-bind-line-style graphics-device line-style thunk
-These procedures bind the drawing mode or line style, respectively, of
-@var{graphics-device}, invoke the procedure @var{thunk} with no
-arguments, then undo the binding when @var{thunk} returns. The value of
-each procedure is the value returned by @var{thunk}. Graphics
-operations performed during @var{thunk}'s dynamic extent will see the
-newly bound mode or style as current.
-@end deffn
-
-@deffn procedure graphics-set-drawing-mode graphics-device drawing-mode
-@deffnx procedure graphics-set-line-style graphics-device line-style
-These procedures change the drawing mode or line style, respectively, of
-@var{graphics-device}. The mode or style will remain in effect until
-subsequent changes or bindings.
-@end deffn
-
-@node Buffering of Graphics Output, Clipping of Graphics Output, Characteristics of Graphics Output, Graphics
-@section Buffering of Graphics Output
-@cindex buffering, of graphics output
-@cindex graphics, buffering of output
-
-To improve performance of graphics output, most graphics devices provide
-some form of buffering. By default, Scheme's graphics procedures flush
-this buffer after every drawing operation. The procedures in this
-section allow the user to control the flushing of the output
-buffer.
-
-@deffn procedure graphics-enable-buffering graphics-device
-Enables buffering for @var{graphics-device}. In other words, after this
-procedure is called, graphics operations are permitted to buffer their
-drawing requests. This usually means that the drawing is delayed until
-the buffer is flushed explicitly by the user, or until it fills up and
-is flushed by the system.
-@end deffn
-
-@deffn procedure graphics-disable-buffering graphics-device
-Disables buffering for @var{graphics-device}. By default, all graphics
-devices are initialized with buffering disabled. After this procedure
-is called, all drawing operations perform their output immediately,
-before returning.
-
-Note: @code{graphics-disable-buffering} flushes the output buffer if
-necessary.
-@end deffn
-
-@deffn procedure graphics-flush graphics-device
-Flushes the graphics output buffer for @var{graphics-device}. This
-operation has no effect for devices that do not support buffering, or if
-buffering is disabled for the device.
-@end deffn
-
-@node Clipping of Graphics Output, Custom Graphics Operations, Buffering of Graphics Output, Graphics
-@section Clipping of Graphics Output
-@cindex graphics, clipping
-@cindex clipping, of graphics
-
-@cindex clip rectangle, graphics (defn)
-Scheme provides a rudimentary mechanism for restricting graphics output
-to a given rectangular subsection of a graphics device. By default,
-graphics output that is drawn anywhere within the device's virtual
-coordinate limits will appear on the device. When a @dfn{clip
-rectangle} is specified, however, output that would have appeared
-outside the clip rectangle is not drawn.
-
-Note that changing the virtual coordinate limits for a device will
-usually reset the clip rectangle for that device, as will any operation
-that affects the size of the device (such as a window resizing
-operation). However, programs should not depend on this.
-
-@deffn procedure graphics-set-clip-rectangle graphics-device x-left y-bottom x-right y-top
-Specifies the clip rectangle for @var{graphics-device} in virtual
-coordinates. @var{X-left}, @var{y-bottom}, @var{x-right}, and
-@var{y-top} must be real numbers. Subsequent graphics output is clipped
-to the intersection of this rectangle and the device's virtual
-coordinate limits.
-@end deffn
-
-@deffn procedure graphics-reset-clip-rectangle graphics-device
-Eliminates the clip rectangle for @var{graphics-device}. Subsequent
-graphics output is clipped to the virtual coordinate limits of the
-device.
-@end deffn
-
-@node Custom Graphics Operations, Images, Clipping of Graphics Output, Graphics
-@section Custom Graphics Operations
-@cindex custom operations, on graphics device
-@cindex graphics, custom operations
-
-In addition to the standard operations, a graphics device may support
-@dfn{custom operations}. For example, most devices have custom
-operations to control color. @code{graphics-operation} is used to
-invoke custom operations.
-
-@deffn procedure graphics-operation graphics-device name object @dots{}
-Invokes the graphics operation on @var{graphics-device} whose name is
-the symbol @var{name}, passing it the remaining arguments. This
-procedure can be used to invoke the standard operations, as well as
-custom operations that are specific to a particular graphics device
-type. The names of the standard graphics operations are formed by
-removing the @code{graphics-} prefix from the corresponding procedure.
-For example, the following are equivalent:
-
-@example
-@group
-(graphics-draw-point device x y)
-(graphics-operation device 'draw-point x y)
-@end group
-@end example
-
-For information on the custom operations for a particular device, see
-the documentation for its type.
-@end deffn
-
-@node Images, X Graphics, Custom Graphics Operations, Graphics
-@section Images
-@cindex graphics, images
-@cindex images, graphics
-@cindex graphics, bitmaps
-@cindex bitmaps, graphics
-
-Some graphics device types support images, which are rectangular pieces
-of picture that may be drawn into a graphics device. Images are often
-called something else in the host graphics system, such as bitmaps or
-pixmaps. The operations supported vary between devices, so look under
-the different device types to see what operations are available. All
-devices that support images support the following operations.
-
-@defop operation graphics-device create-image width height
-Images are created using the @code{create-image} graphics operation,
-specifying the @var{width} and @var{height} of the image in device
-coordinates (pixels).
-
-@example
-(graphics-operation device 'create-image 200 100)
-@end example
-
-@noindent
-The initial contents of an image are unspecified.
-
-@code{create-image} is a graphics operation rather than a procedure
-because the kind of image returned depends on the kind of graphics
-device used and the options specified in its creation. The image may be
-used freely with other graphics devices created with the same
-attributes, but the effects of using an image with a graphics device
-with different attributes (for example, different colors) is undefined.
-Under X, the image is display dependent.
-@end defop
-
-@defop operation graphics-device draw-image x y image
-The image is copied into the graphics device at the specified position.
-@end defop
-
-@defop operation graphics-device draw-subimage x y image im-x im-y w h
-Part of the image is copied into the graphics device at the specified
-(@var{x}, @var{y}) position. The part of the image that is copied is the
-rectangular region at @var{im-x} and @var{im-y} and of width @var{w} and
-height @var{h}. These four numbers are given in device coordinates
-(pixels).
-@end defop
-
-@deffn procedure image? object
-Returns @code{#t} if @var{object} is an image, otherwise returns
-@code{#f}.
-@end deffn
-
-@deffn procedure image/destroy image
-This procedure destroys @var{image}, returning storage to the system.
-Programs should destroy images after they have been used because even
-modest images may use large amounts of memory. Images are reclaimed by
-the garbage collector, but they may be implemented using memory outside
-of Scheme's heap. If an image is reclaimed before being destroyed, the
-implementation might not deallocate that non-heap memory, which can
-cause a subsequent call to @code{create-image} to fail because it is
-unable to allocate enough memory.
-@end deffn
-
-@c @deffn procedure image/descriptor image
-@c The procedure returns the implementation dependent image. Its use is
-@c discouraged as it is non-portable.
-@c @end deffn
-
-@deffn procedure image/height image
-Returns the height of the image in device coordinates.
-@end deffn
-
-@deffn procedure image/width image
-Returns the width of the image in device coordinates.
-@end deffn
-
-@deffn procedure image/fill-from-byte-vector image bytes
-The contents of @var{image} are set in a device-dependent way, using one
-byte per pixel from @var{bytes} (a string). Pixels are filled row by
-row from the top of the image to the bottom, with each row being filled
-from left to right. There must be at least @code{(* (image/height
-@var{image}) (image/width @var{image}))} bytes in @var{bytes}.
-@end deffn
-
-@node X Graphics, Win32 Graphics, Images, Graphics
-@section X Graphics
-@cindex X graphics
-
-@cindex X window system
-MIT/GNU Scheme supports graphics in the X window system (version 11).
-Arbitrary numbers of displays may be opened, and arbitrary numbers of
-graphics windows may be created for each display. A variety of
-operations is available to manipulate various aspects of the windows, to
-control their size, position, colors, and mapping. The X graphics
-device type supports images, which are implemented as Xlib @code{XImage}
-objects. X display, window, and image objects are automatically closed
-if they are reclaimed by the garbage collector.
-
-@menu
-* X Graphics Type::
-* Utilities for X Graphics::
-* Custom Operations on X Graphics Devices::
-@end menu
-
-@node X Graphics Type, Utilities for X Graphics, X Graphics, X Graphics
-@subsection X Graphics Type
-
-
-A graphics device for X windows is created by passing the symbol
-@code{x} as the graphics device type name to
-@code{make-graphics-device}:
-
-@example
-(make-graphics-device 'x #!optional @var{display} @var{geometry} @var{suppress-map?})
-@end example
-
-@noindent
-where @var{display} is either a display object, @code{#f}, or a string;
-@var{geometry} is either @code{#f} or a string; and @var{suppress-map?}
-is a boolean or a vector (see below). A new window is created on the
-appropriate display, and a graphics device representing that window is
-returned.
-
-@findex x-open-display
-@var{Display} specifies which X display the window is to be opened on;
-if it is @code{#f} or a string, it is passed as an argument to
-@code{x-open-display}, and the value returned by that procedure is used
-in place of the original argument. @var{Geometry} is an X geometry
-string, or @code{#f} which means to use the default geometry (which is
-specified as a resource).
-
-@var{Suppress-map?}, if given, may take two forms. First, it may be a
-boolean: if @code{#f} (the default), the window is automatically mapped
-after it is created; otherwise, @code{#t} means to suppress this
-automatic mapping. The second form is a vector of three elements. The
-first element is a boolean with the same meaning as the boolean form of
-@var{suppress-map?}. The second element is a string, which specifies an
-alternative resource name to be used for looking up the window's
-resources. The third element is also a string, which specifies a class
-name for looking up the window's resources. The default value for
-@var{suppress-map?} is @code{#f}.
-
-The default resource and class names are @code{"schemeGraphics"} and
-@code{"SchemeGraphics"} respectively.
-
-@cindex resources, X graphics
-@cindex X resources, graphics
-The window is initialized using the resource and class names specified
-by @var{suppress-map?}, and is sensitive to the following resource
-properties:
-
-@example
-@group
-Property Class Default
--------- ----- -------
-geometry Geometry 512x384+0+0
-font Font fixed
-borderWidth BorderWidth 2
-internalBorder BorderWidth @r{[border width]}
-background Background white
-foreground Foreground black
-borderColor BorderColor @r{[foreground color]}
-cursorColor Foreground @r{[foreground color]}
-pointerColor Foreground @r{[foreground color]}
-@end group
-@end example
-
-The window is created with a @code{backing_store} attribute of
-@code{Always}. The window's name and icon name are initialized to
-@code{"scheme-graphics"}.
-
-
-@node Utilities for X Graphics, Custom Operations on X Graphics Devices, X Graphics Type, X Graphics
-@subsection Utilities for X Graphics
-
-@deffn procedure x-graphics/open-display display-name
-@cindex display, X graphics
-@cindex X display, graphics
-Opens a connection to the display whose name is @var{display-name},
-returning a display object. If unable to open a connection, @code{#f}
-is returned. @var{Display-name} is normally a string, which is an X
-display name in the usual form; however, @code{#f} is also allowed,
-meaning to use the value of the unix environment variable
-@code{DISPLAY}.
-@end deffn
-
-@deffn procedure x-graphics/close-display display
-Closes @var{display}; after calling this procedure, it is an error to
-use @var{display} for any purpose. Any windows that were previously
-opened on @var{display} are destroyed and their resources returned to
-the operating system.
-@end deffn
-
-@deffn procedure x-close-all-displays
-Closes all open connections to X displays. Equivalent to calling
-@code{x-close-display} on all open displays.
-@end deffn
-
-@deffn procedure x-geometry-string x y width height
-@cindex geometry string, X graphics
-@cindex X geometry string, graphics
-This procedure creates and returns a standard X geometry string from the
-given arguments. @var{X} and @var{y} must be either exact integers or
-@code{#f}, while @var{width} and @var{height} must be either exact
-non-negative integers or @code{#f}. Usually either @var{x} and @var{y}
-are both specified or both @code{#f}; similarly for @var{width} and
-@var{height}. If only one of the elements of such a pair is specified,
-it is ignored.
-
-Examples:
-
-@example
-@group
-(x-geometry-string #f #f 100 200) @result{} "100x200"
-(x-geometry-string 2 -3 100 200) @result{} "100x200+2-3"
-(x-geometry-string 2 -3 #f #f) @result{} "+2-3"
-@end group
-@end example
-
-Note that the @var{x} and @var{y} arguments cannot distinguish between
-@code{+0} and @code{-0}, even though these have different meanings in X.
-If either of those arguments is @code{0}, it means @code{+0} in X
-terminology. If you need to distinguish these two cases you must create
-your own geometry string using Scheme's string and number primitives.
-@end deffn
-
-@node Custom Operations on X Graphics Devices, , Utilities for X Graphics, X Graphics
-@subsection Custom Operations on X Graphics Devices
-
-Custom operations are invoked using the procedure
-@code{graphics-operation}. For example,
-
-@example
-(graphics-operation device 'set-foreground-color "blue")
-@end example
-
-@defop operation x-graphics-device set-background-color color-name
-@defopx operation x-graphics-device set-foreground-color color-name
-@defopx operation x-graphics-device set-border-color color-name
-@defopx operation x-graphics-device set-mouse-color color-name
-@findex graphics-clear
-These operations change the colors associated with a window.
-@var{Color-name} must be a string, which is the X server's name for the
-desired color. @code{set-border-color} and @code{set-mouse-color}
-immediately change the border and mouse-cursor colors.
-@code{set-background-color} and @code{set-foreground-color} change the
-colors to be used when drawing, but have no effect on anything drawn
-prior to their invocation. Because changing the background color
-affects the entire window, we recommend calling @code{graphics-clear} on
-the window's device afterwards. Color names include both mnemonic
-names, like @code{"red"}, and intensity names specified in the
-@code{"#@var{rrggbb}"} notation.
-@end defop
-
-@defop operation x-graphics-device draw-arc x y radius-x radius-y angle-start angle-sweep fill?
-@cindex drawing arcs and circles, graphics
-@cindex graphics, drawing arcs and circles
-@cindex circles, drawing
-@findex draw-arc
-
-Operation @code{draw-arc} draws or fills an arc. An arc is a segment of
-a circle, which may have been stretched along the x- or y- axis to form
-an ellipse.
-
-The parameters @var{x}, @var{y}, @var{radius-x} and @var{radius-y}
-describe the circle and @var{angle-start} and @var{angle-sweep} choose
-which part of the circle is drawn. The arc is drawn on the graphics
-device with the center of the circle at the virtual coordinates given by
-@var{x} and @var{y}. @var{radius-x} and @var{radius-y} determine the
-size of the circle in virtual coordinate units.
-
-The parameter @var{angle-start} determines where the arc starts. It is
-measured in degrees in an anti-clockwise direction, starting at 3
-o'clock. @var{angle-sweep} determines how much of the circle is drawn.
-It too is measured anti-clockwise in degrees. A negative value means
-the measurement is in a clockwise direction.
-
-Note that the angles are determined on a unit circle before it is
-stretched into an ellipse, so the actual angles that you will see on the
-computer screen depends on all of: @var{radius-x} and @var{radius-y},
-the window size, and the virtual coordinates.
-
-If @var{fill?} is @code{#f} then just the segment of the circle is
-drawn, otherwise the arc is filled in a pie-slice fashion.
-
-This draws a quarter circle pie slice, standing on its point, with point
-at virtual coordinates (3,5):
-
-@example
-(graphics-opereration g 'draw-arc 3 5 .5 .5 45 90 #t)
-@end example
-
-@end defop
-
-@defop operation x-graphics-device draw-circle x y radius
-@defopx operation x-graphics-device fill-circle x y radius
-@cindex drawing arcs and circles, graphics
-@cindex graphics, drawing arcs and circles
-@cindex circles, drawing
-@findex draw-circle
-@findex fill-circle
-These operations draw a circle (outline) or a filled circle (solid) at
-on the graphics device at the virtual coordinates given by @var{x} and
-@var{y}. These operations could be implemented trivially interms of the
-@code{draw-arc} operation.
-@end defop
-
-@defop operation x-graphics-device set-border-width width
-@defopx operation x-graphics-device set-internal-border-width width
-@findex graphics-clear
-These operations change the external and internal border widths of a
-window. @var{Width} must be an exact non-negative integer, specified in
-pixels. The change takes place immediately. Note that changing the
-internal border width can cause displayed graphics to be garbled; we
-recommend calling @code{graphics-clear} on the window's device after
-doing so.
-@end defop
-
-@defop operation x-graphics-device set-font font-name
-Changes the font used when drawing text in a window. @var{Font-name}
-must be a string that is a font name known to the X server. This
-operation does not affect text drawn prior to its invocation.
-@end defop
-
-@defop operation x-graphics-device set-mouse-shape shape-number
-Changes the shape of the mouse cursor. @var{Shape-number} is an exact
-non-negative integer that is used as an index into the mouse-shape font;
-when multiplied by 2 this number corresponds to an index in the file@*
-@file{/usr/include/X11/cursorfont.h}.
-@end defop
-
-@defop operation x-graphics-device map-window
-@defopx operation x-graphics-device withdraw-window
-These operations control the mapping of windows. They correspond
-directly to Xlib's @code{XMapWindow} and @code{XWithdrawWindow}.
-@end defop
-
-@defop operation x-graphics-device resize-window width height
-Changes the size of a window. @var{Width} and @var{height} must be
-exact non-negative integers. The operation corresponds directly to
-Xlib's @code{XResizeWindow}.
-
-This operation resets the virtual coordinate system and the clip
-rectangle.
-@end defop
-
-@defop operation x-graphics-device move-window x y
-Changes the position of a window on the display. @var{X} and @var{y}
-must be exact integers. The operation corresponds directly to Xlib's
-@code{XMoveWindow}. Note that the coordinates @var{x} and @var{y} do
-not take the external border into account, and therefore will not
-position the window as you might like. The only reliable way to
-position a window is to ask a window manager to do it for you.
-@end defop
-
-@defop operation x-graphics-device get-default resource property
-This operation corresponds directly to Xlib's @code{XGetDefault}.
-@var{Resource} and @var{property} must be strings. The operation
-returns the character string corresponding to the association of
-@var{resource} and @var{property}; if no such association exists,
-@code{#f} is returned.
-@end defop
-
-@defop operation x-graphics-device copy-area source-x-left source-y-top width height destination-x-left destination-y-top
-This operation copies the contents of the rectangle specified by
-@var{source-x-left}, @var{source-y-top}, @var{width}, and @var{height} to
-the rectangle of the same dimensions at @var{destination-x-left} and
-@var{destination-y-top}.
-@end defop
-
-@defop operation x-graphics-device font-structure font-name
-Returns a Scheme equivalent of the X font structure for the font named
-@var{font-name}. If the string @var{font-name} does not name a font
-known to the X server, or names a 16-bit font, @code{#f} is returned.
-@end defop
-
-@deffn procedure x-font-structure/name font-structure
-@deffnx procedure x-font-structure/direction font-structure
-@deffnx procedure x-font-structure/all-chars-exist font-structure
-@deffnx procedure x-font-structure/default-char font-structure
-@deffnx procedure x-font-structure/min-bounds font-structure
-@deffnx procedure x-font-structure/max-bounds font-structure
-@deffnx procedure x-font-structure/start-index font-structure
-@deffnx procedure x-font-structure/character-bounds font-structure
-@deffnx procedure x-font-structure/max-ascent font-structure
-@deffnx procedure x-font-structure/max-descent font-structure
-These procedures extract the components of the font description
-structure returned by the X graphics operation @code{font-structure}. A
-more complete description of these components appears in documentation
-of the @code{XLoadQueryFont} Xlib call. @code{start-index} is the index
-of the first character available in the font. The @code{min-bounds} and
-@code{max-bounds} components are structures of type
-@code{x-character-bounds}, and the @code{character-bounds} component is
-a vector of the same type.
-@end deffn
-
-@deffn procedure x-character-bounds/lbearing character-bounds
-@deffnx procedure x-character-bounds/rbearing character-bounds
-@deffnx procedure x-character-bounds/width character-bounds
-@deffnx procedure x-character-bounds/ascent character-bounds
-@deffnx procedure x-character-bounds/descent character-bounds
-These procedures extract components of objects of type
-@code{x-character-bounds}. A more complete description of them appears
-in documentation of the@* @code{XLoadQueryFont} Xlib call.
-@end deffn
-
-@node Win32 Graphics, OS/2 Graphics, X Graphics, Graphics
-@section Win32 Graphics
-@cindex Win32 graphics
-
-MIT/GNU Scheme supports graphics on Microsoft Windows 95, Windows 98, and
-Windows NT. In addition to the usual operations, there are operations
-to control the size, position and colors of a graphics window. Win32
-devices support images, which are implemented as device independent
-bitmaps (@sc{dib}s).
-
-The Win32 graphics device type is implemented as a top level window.
-@code{graphics-enable-buffering} is implemented and gives a 2x to 4x
-speedup on many graphics operations. As a convenience, when buffering
-is enabled clicking on the graphics window's title bar effects a
-@code{graphics-flush} operation. The user has the benefit of the
-increased performance and the ability to view the progress in drawing at
-the click of a mouse button.
-
-
-@menu
-* Win32 Graphics Type::
-* Custom Operations for Win32 Graphics:: Custom Operations for Win32 Graphics Devices
-@end menu
-
-@node Win32 Graphics Type, Custom Operations for Win32 Graphics, Win32 Graphics, Win32 Graphics
-@subsection Win32 Graphics Type
-
-Win32 graphics devices are created by specifying the symbol @code{win32}
-as the @var{graphics-device-type} argument to
-@code{make-graphics-device}. The Win32 graphics device type is
-implemented as a top-level window and supports color drawing in addition
-to the standard Scheme graphics operations.
-
-Graphics devices are opened as follows:
-
-@example
-(make-graphics-device 'win32 #!optional @var{width} @var{height} @var{palette})
-@end example
-
-@noindent
-where @var{width} and @var{height} specify the size, in pixels, of the
-drawing area in the graphics window (i.e.@: excluding the frame).
-@var{Palette} determines the colors available for drawing in the window.
-
-When a color is specified for drawing, the nearest color available in
-the palette is used. Permitted values for @var{palette} are
-
-@table @asis
-@item @code{'grayscale}
-The window allocates colors from a grayscale palette
-of approximately 236 shades of gray.
-
-@item @code{'grayscale-128}
-The window allocates colors from a grayscale palette of 128 shades of
-gray.
-
-@item @code{'standard}
-The standard palette has good selection of colors and grays.
-
-@item @code{#f} or @code{'system}
-The colors available are those in the system palette. There are usually
-16 to 20 colors in the system palette and these are usually sufficent
-for simple applications like line drawings and x-vs-y graphs of
-mathematical functions. Drawing with the system palette can be more
-efficient.
-
-@end table
-@noindent
-If @var{palette} is not specified then the @code{standard} palette is
-used.
-
-
-
-@node Custom Operations for Win32 Graphics, , Win32 Graphics Type, Win32 Graphics
-@subsection Custom Operations for Win32 Graphics
-
-Custom operations are invoked using the procedure
-@code{graphics-operation}. For example,
-
-@example
-(graphics-operation device 'set-foreground-color "blue")
-@end example
-
-@defop operation win32-graphics-device set-background-color color-name
-@defopx operation win32-graphics-device set-foreground-color color-name
-@findex set-background-color
-@findex set-foreground-color
-@cindex color
-These operations change the colors associated with a window.
-@var{Color-name} must be of one of the valid color specification forms
-listed below. @code{set-background-color} and
-@code{set-foreground-color} change the colors to be used when drawing,
-but have no effect on anything drawn prior to their invocation. Because
-changing the background color affects the entire window, we recommend
-calling @code{graphics-clear} on the window's device afterwards.
-
-The foreground color affects the drawing of text, points, lines,
-ellipses and filled polygons.
-
-Colors are specified in one of three ways:
-
-@table @asis
-@item An integer
-This is the Win32 internal RGB value.
-
-@item By name
-A limited number of names are understood by the system.
-Names are strings, e.g.@: @code{"red"}, @code{"blue"}, @code{"black"}.
-More names can be registered with the @code{define-color} operation.
-
-@item RGB (Red-Green-Blue) triples
-A triple is either a vector or list of three integers in the range
-0--255 inclusive which specify the intensity of the red, green and blue
-components of the color. Thus @code{#(0 0 0)} is black, @code{(0 0
-128)} is dark blue and @code{#(255 255 255)} is white.
-@end table
-
-@noindent
-If the color is not available in the graphics device then the nearest
-available color is used instead.
-@end defop
-
-
-@defop operation win32-graphics-device define-color name spec
-Define the string @var{name} to be the color specified by @var{spec}.
-@var{Spec} may be any acceptable color specification. Note that the
-color names defined this way are available to any Win32 graphics device,
-and the names do @emph{not} have to be defined for each device.
-
-
-Color names defined by this interface may also be used when setting the
-colors of the Scheme console window, or the colors of Edwin editor
-windows.
-@end defop
-
-@defop operation win32-graphics-device find-color name
-Looks up a color previously defined by @code{define-color}. This returns
-the color in its most efficient form for operations
-@code{set-foreground-color} or @code{set-background-color}.
-@end defop
-
-
-@defop operation win32-graphics-device draw-ellipse left top right bottom
-@cindex ellipse, graphics
-@cindex circle, graphics
-@cindex graphics, ellipse
-@cindex graphics, circle
-Draw an ellipse. @var{Left}, @var{top}, @var{right} and @var{bottom}
-indicate the coordinates of the bounding rectangle of the ellipse.
-Circles are merely ellipses with equal width and height. Note that the
-bounding rectangle has horizontal and vertical sides. Ellipses with
-rotated axes cannot be drawn. The rectangle applies to the center of the
-line used to draw the ellipse; if the line width has been set to greater
-than 1 then the ellipse will spill outside the bounding rectange by half
-of the line width.
-@end defop
-
-
-@defop operation win32-graphics-device fill-polygon points
-@findex fill-polygon
-Draws a filled polygon using the current foreground color.
-@var{Points} is a vector of real numbers.
-The numbers are in the order x1 y1 x2 y2 @dots{} xn yn.
-For example,
-
-@example
-(graphics-operation device 'fill-polygon #(0 0 0 1 1 0))
-@end example
-
-@noindent
-draws a solid triangular region between the points (0, 0), (0, 1) and
-(1, 0).
-@end defop
-
-
-@defop operation win32-graphics-device load-bitmap pathname
-@cindex bitmaps
-The graphics device contents and size are initialized from the windows
-bitmap file specified by @var{pathname}. If no file type is supplied
-then a @code{".BMP"} extension is added. If a clip rectangle is in
-effect when this procedure is called, it is necessary to redefine the
-clip rectangle afterwards.
-@end defop
-
-@defop operation win32-graphics-device save-bitmap pathname
-@cindex printing graphics output
-The graphics device contents are saved as a bitmap to the file specified
-by @var{pathname}. If no file type is supplied then a @code{".BMP"}
-extension is added. The saved bitmap may be incorporated into documents
-or printed.
-@end defop
-
-@defop operation win32-graphics-device move-window x y
-The graphics device window is moved to the screen position specified by
-@var{x} and @var{y}.
-@end defop
-
-@defop operation win32-graphics-device resize-window width height
-The graphics device window is resized to the specified @var{width} and
-@var{height} in device coordinates (pixels). If a clip rectangle is in effect
-when this procedure is called, it is necessary to redefine the clip
-rectangle afterwards.
-@end defop
-
-@defop operation win32-graphics-device set-line-width width
-This operation sets the line width for future drawing of lines, points
-and ellipses. It does not affect existing lines and has no effect on
-filled polygons. The line width is specified in device units. The
-default and initial value of this parameter is 1 pixel.
-@end defop
-
-@defop operation win32-graphics-device set-window-name name
-This sets the window title to the string @var{name}. The window is
-given the name @code{"Scheme Graphics"} at creation.
-@end defop
-
-@defop operation win32-graphics-device set-font handle
-Sets the font for drawing text. Currently not well supported. If you
-can get a Win32 font handle it can be used here.
-@end defop
-
-@defop operation win32-graphics-device copy-area source-x-left source-y-top width height destination-x-left destination-y-top
-This operation copies the contents of the rectangle specified by
-@var{source-x-left}, @var{source-y-top}, @var{width}, and @var{height}
-to the rectangle of the same dimensions at @var{destination-x-left} and
-@var{destination-y-top}.
-@end defop
-
-@node OS/2 Graphics, , Win32 Graphics, Graphics
-@section OS/2 Graphics
-@cindex OS/2 graphics
-
-MIT/GNU Scheme supports graphics under the OS/2 Presentation Manager in
-OS/2 version 2.1 and later. The OS/2 graphics device type is
-implemented as a top level window. In addition to the usual operations,
-there are operations to control the size, position, and colors of a
-graphics window. OS/2 graphics devices support images, which are
-implemented as memory presentation spaces.
-
-The custom graphics operations defined in this section are invoked using
-the procedure @code{graphics-operation}. For example,
-
-@example
-(graphics-operation device 'set-foreground-color "blue")
-@end example
-
-@menu
-* OS/2 Graphics Type::
-* Color Operations for OS/2 Graphics::
-* Window Operations for OS/2 Graphics::
-* Event Operations for OS/2 Graphics::
-* Miscellaneous Operations for OS/2 Graphics::
-@end menu
-
-@node OS/2 Graphics Type, Color Operations for OS/2 Graphics, OS/2 Graphics, OS/2 Graphics
-@subsection OS/2 Graphics Type
-
-OS/2 graphics devices are created by specifying the symbol
-@code{os/2} as the @var{graphics-device-type} argument to
-@code{make-graphics-device}. The OS/2 graphics device type is
-implemented as a top-level window and supports color drawing in addition
-to the standard Scheme graphics operations.
-
-Graphics devices are opened as follows:
-
-@example
-(make-graphics-device 'os/2 #!optional @var{width} @var{height})
-@end example
-
-@noindent
-where @var{width} and @var{height} specify the size, in pixels, of the
-drawing area in the graphics window (i.e.@: excluding the frame).
-
-@node Color Operations for OS/2 Graphics, Window Operations for OS/2 Graphics, OS/2 Graphics Type, OS/2 Graphics
-@subsection Color Operations for OS/2 Graphics
-
-These operations control the colors used when drawing on an OS/2
-graphics device.
-
-@defop operation os2-graphics-device color?
-@findex color?
-This operation returns @code{#t} if the display supports color.
-@end defop
-
-@defop operation os2-graphics-device set-background-color color-name
-@defopx operation os2-graphics-device set-foreground-color color-name
-@findex set-background-color
-@findex set-foreground-color
-@cindex color
-These operations change the colors associated with a window.
-@var{Color-name} must be one of the valid color specification forms
-listed below. @code{set-background-color} and
-@code{set-foreground-color} change the colors to be used when drawing,
-but have no effect on anything drawn prior to their invocation. Because
-changing the background color affects the entire window, we recommend
-calling @code{graphics-clear} on the window's device afterwards.
-
-The foreground color affects the drawing of text, points, and lines.
-Colors are specified in one of these ways:
-
-@table @asis
-@item An integer between @code{0} and @code{#xffffff} inclusive
-This is the OS/2 internal RGB value.
-
-@item By name
-A limited number of names are understood by the system. Names are
-strings, e.g.@: @code{"red"}, @code{"blue"}, @code{"black"}. More names
-can be registered with the @code{define-color} operation.
-
-@item RGB (Red-Green-Blue) triples
-A triple is a list of three integers between @code{0} and @code{#xff}
-inclusive which specify the intensity of the red, green and blue
-components of the color. Thus @code{(0 0 0)} is black, @code{(0 0 128)}
-is dark blue and @code{(255 255 255)} is white.
-@end table
-
-@noindent
-If the color is not available in the graphics device then the nearest
-available color is used instead.
-@end defop
-
-@defop operation os2-graphics-device define-color name spec
-Define the string @var{name} to be the color specified by @var{spec}.
-@var{Spec} may be any acceptable color specification. Note that the
-color names defined this way are available to any OS/2 graphics
-device, and the names do @emph{not} have to be defined for each device.
-
-Color names defined by this interface may also be used when setting the
-colors of the Scheme console window, or the colors of Edwin editor
-windows.
-@end defop
-
-@defop operation os2-graphics-device find-color name
-Looks up a color previously defined by @code{define-color}. This
-returns the color in its most efficient form for operations
-@code{set-foreground-color} or @code{set-background-color}.
-@end defop
-
-@node Window Operations for OS/2 Graphics, Event Operations for OS/2 Graphics, Color Operations for OS/2 Graphics, OS/2 Graphics
-@subsection Window Operations for OS/2 Graphics
-
-These operations control the window that contains the OS/2 graphics
-device. They provide facilities to change the window's size and
-position; to raise and lower the window relative to other windows on the
-desktop; to hide or minimize the window, and to restore it from the
-hidden or minimized state; to activate or deactivate the window (that
-is, control the keyboard focus); and to control the text that appears in
-the window's title bar.
-
-@defop operation os2-graphics-device window-position
-This operation returns the position of the graphics-device window on the
-desktop. The position is returned as two values
-(@pxref{Continuations}), which are the x and y coordinates of the
-position. These coordinates are in units of pels (pixels), and measure
-the distance between the lower left hand corner of the desktop and the
-lower left hand corner of the graphics device window's frame.
-@end defop
-
-@defop operation os2-graphics-device set-window-position x y
-The graphics-device window is moved to the screen position specified by
-@var{x} and @var{y}. The coordinates @var{x} and @var{y} are in units
-of pels (pixels), and measure the distance between the lower left hand
-corner of the desktop and the lower left hand corner of the graphics
-device window's frame.
-@end defop
-
-@defop operation os2-graphics-device window-size
-This operation returns the size of the client area of the
-graphics-device window. The client area is the part of the window that
-you draw on; it does not include the window frame, title bar, etc. The
-size is returned as two values (@pxref{Continuations}), which are the
-width and height of the client area in units of pels (pixels).
-@end defop
-
-@defop operation os2-graphics-device set-window-size width height
-This operation sets the size of the client area of the graphics-device
-window to the specified @var{width} and @var{height}, which are in units
-of pels (pixels). The client area is the part of the window that you
-draw on; it does not include the window frame, title bar, etc.
-@end defop
-
-@defop operation os2-graphics-device window-frame-size
-This operation returns the size of the graphics-device window's frame.
-This includes the client area, as well as the border, title bar, etc.
-The size is returned as two values (@pxref{Continuations}), which are
-the width and height of the frame in units of pels (pixels).
-
-The frame size is useful in conjunction with the window position and the
-desktop size to determine relative placement of the window or to
-guarantee that the entire window is visible on the desktop.
-@end defop
-
-@defop operation os2-graphics-device desktop-size
-This operation returns the size of the OS/2 desktop. The size is
-returned as two values (@pxref{Continuations}), which are the width and
-height of the frame in units of pels (pixels).
-@end defop
-
-@defop operation os2-graphics-device raise-window
-This operation raises the graphics-device window so that it is on top of
-any other windows on the desktop.
-@end defop
-
-@defop operation os2-graphics-device lower-window
-This operation lowers the graphics-device window so that it is below all
-other windows on the desktop.
-@end defop
-
-@defop operation os2-graphics-device hide-window
-This operation hides the graphics-device window. The window disappears
-from the desktop, but still appears in the window list.
-@end defop
-
-@defop operation os2-graphics-device minimize-window
-This operation minimizes the graphics-device window. The window
-disappears from the desktop, but still appears in the window list.
-Depending on how you have configured your desktop, the window may appear
-as an icon, either on the desktop or in the minimized window viewer.
-@end defop
-
-@defop operation os2-graphics-device maximize-window
-This operation maximizes the graphics-device window. This causes the
-window to fill the entire desktop.
-@end defop
-
-@defop operation os2-graphics-device restore-window
-This operation restores the graphics-device window to its normal state.
-If the window is hidden or minimized, it is shown again, at its former
-position on the desktop. If the window is maximized, it is returned to
-its normal size.
-@end defop
-
-@defop operation os2-graphics-device activate-window
-This operation makes the graphics-device window be the active window.
-This causes the window to be put in front of all other windows on the
-desktop, highlights its frame, and gives it the keyboard focus.
-@end defop
-
-@defop operation os2-graphics-device deactivate-window
-This operation deactivates the graphics-device window if it was active
-(otherwise it has no effect). This causes some other window to be
-chosen to be active in its place.
-@end defop
-
-@defop operation os2-graphics-device set-window-title title
-This operation changes the text that appears in the graphics device
-window's title bar. The new text is given by @var{title}, which must be
-a string.
-@end defop
-
-@node Event Operations for OS/2 Graphics, Miscellaneous Operations for OS/2 Graphics, Window Operations for OS/2 Graphics, OS/2 Graphics
-@subsection Event Operations for OS/2 Graphics
-
-These operations allow you to read some of the events that are generated
-by the Presentation Manager and put in the message queue of a
-graphics-device window.
-
-@defop operation os2-graphics-device read-button
-This operation waits for the user to push a mouse button inside the
-client area of the graphics-device window. It then returns four values
-(@pxref{Continuations}) which are: the button number; the x and y
-coordinates of the mouse pointer at the time the button was pressed, in
-pels (pixels) relative to the lower left hand corner of the client area;
-and the graphics device that the mouse pointer was over at the time the
-button was pressed.
-
-Note that this operation only works when button events are selected
-(which is the default).
-@end defop
-
-@defop operation os2-graphics-device select-user-events mask
-This operation sets the event-selection mask for the graphics device to
-@var{mask}. The event-selection mask is an exact non-negative integer
-that specifies which types of incoming events are to be saved in the
-user-event queue for later retrieval by the @code{read-user-event}
-operation. The mask is specified by setting the bits corresponding to
-the event types that you are interested in, as follows:
-
-@example
-@group
-Number Mask Description
------- ----- -----------
-0 #x001 Button press/release
-1 #x002 Close (close the window) [WM_CLOSE]
-2 #x004 Focus change [WM_SETFOCUS]
-3 #x008 Key press/release [WM_CHAR]
-4 #x010 Paint [WM_PAINT]
-5 #x020 Size change [WM_SIZE]
-6 #x040 Visibility change [WM_SHOW]
-7 #x080 Command [WM_COMMAND]
-8 #x100 Help [WM_HELP]
-9 #x200 Mouse-move [WM_MOUSEMOVE]
-@end group
-@end example
-
-@noindent
-Note that this operation does not affect any events that are already in
-the user-event queue. Changing the mask only affects what events will
-be added to the queue in the future.
-@end defop
-
-@defop operation os2-graphics-device read-user-event
-This operation returns the next user event available from the user-event
-queue. If there are no events in the queue, the operation waits for an
-event to arrive before returning.
-@end defop
-
-An event is a vector whose first element is the event-type number, whose
-second element is the graphics device that the event refers to, and
-whose remaining elements provide information about the event. Here is a
-table of the possible event types and their vector layout:
-
-@table @code
-@item #(0 @var{device} @var{number} @var{type} @var{x} @var{y} @var{flags})
-A button event. @var{Number} is the button number, for example button
-number @code{0} is usually the left mouse button, @code{1} is usually
-the right button, etc. @var{Type} specifies what occurred: @code{0}
-means the button was pressed, @code{1} means the button was released,
-@code{2} means the button was clicked, and @code{3} means the button was
-double clicked. @var{X} and @var{y} are the position of the mouse
-pointer at the time of the event, in units of pels (pixels) measured
-from the lower left corner of the client area of the associated window.
-Finally, @var{flags} specifies what shift keys were pressed at the time
-of the button event; it is a mask word created by combining zero or more
-of the following flags: @code{#x08} means the shift key was pressed,
-@code{#x10} means the control key was pressed, and @code{#x20} means the
-alt key was pressed.
-
-@item #(1 @var{device})
-A close event. The user has selected the close button from the system
-menu, or typed @key{Alt-f4}.
-
-@item #(2 @var{device} @var{gained?})
-A focus event. If @var{gained?} is @code{#t}, the keyboard focus is
-being gained, and if @var{gained?} is @code{#f}, it is being lost.
-
-@item #(3 @var{device} @var{code} @var{flags} @var{repeat})
-A keyboard event. This is much too complicated to describe here. See
-the OS/2 toolkit documentation for details.
-
-@item #(4 @var{device} @var{xl} @var{xh} @var{yl} @var{yh})
-A paint event. Part of the graphics-device window that was obscured has
-been revealed and the Presentation Manager is informing the window that
-it must repaint that area. Scheme will take care of the painting for
-you, so this event isn't very useful.
-
-@item #(5 @var{device} @var{width} @var{height})
-A size-change event. The size of the graphics-device window has
-changed, and @var{width} and @var{height} specify the new size in pels
-(pixels).
-
-@item #(6 @var{device} @var{shown?})
-A visibility event. Indicates that the graphics-device window has been
-hidden or revealed. If @var{shown?} is @code{#f}, the window is hidden,
-and if it is @code{#t}, the window is shown.
-
-@item #(7 @var{device} @var{source} @var{mouse?})
-@itemx #(8 @var{device} @var{source} @var{mouse?})
-A menu command. @var{Source} specifies which menu item was selected to
-cause this event, and @var{mouse?} is a boolean indicating whether the
-item was selected with the mouse or the keyboard. The event-type number
-@code{7} indicates a command from a @samp{WM_COMMAND} message, while
-@code{8} is a command from a @samp{WM_HELP} message.
-
-@item #(9 @var{device} @var{x} @var{y} @var{hit-test} @var{flags})
-The mouse was moved. @var{X} and @var{y} specify the position of the
-mouse, @var{hit-test} contains the hit-test information, and @var{flags}
-specifies the modifier keys that were pressed at the time.
-@end table
-
-@defop operation os2-graphics-device discard-events
-This operation discards any events that are in the user-event queue.
-This is sometimes useful when you want to prompt the user for some input
-and don't want to consider any previous input.
-@end defop
-
-@node Miscellaneous Operations for OS/2 Graphics, , Event Operations for OS/2 Graphics, OS/2 Graphics
-@subsection Miscellaneous Operations for OS/2 Graphics
-
-These operations allow you to: change the font used for drawing text in
-a graphics-device window; take a snapshot of a graphics-device window
-and return it as an image object; and draw multiple lines efficiently.
-
-@defop operation os2-graphics-device set-font font-name
-This operation sets the font used for drawing text in the
-graphics-device window. @var{Font-name} is a string describing the
-font; this string is in the form "<point-size>.<family-name>", for
-example, @code{"10.Courier"}. You may specify any fixed-pitch font
-family, in any point size that is supported for that font family. This
-includes both image fonts and outline fonts.
-@end defop
-
-@defop operation os2-graphics-device capture-image x-left y-bottom x-right y-top
-This operation creates and returns an image that contains part of the
-client area of the graphics-device window. The portion of the client
-area that is selected is specified by the four coordinate arguments,
-which are given in the current virtual coordinates for the device.
-@xref{Images}, for more information about manipulating images.
-@end defop
-
-@defop operation os2-graphics-device draw-lines xv yv
-This operation draws multiple disjoint lines; it is like multiple calls
-to @code{graphics-draw-line} but much faster. The arguments @var{xv}
-and @var{yv} are vectors of coordinates; these vectors must be the same
-length, and the length must be a multiple of two. The contents of the
-vectors are alternating start/end pairs. For example, the following are
-equivalent:
-
-@example
-@group
-(graphics-draw-line device xs ys xe ye)
-(graphics-operation device 'draw-lines
- (vector xs xe)
- (vector ys ye))
-@end group
-@end example
-@end defop
-
-@node Win32 Package Reference, GNU Free Documentation License, Graphics, Top
-@chapter Win32 Package Reference
-
-@ifinfo
-The Win32 implementation is still in a state of development. It is
-expected that changes will be necessary when MIT/GNU Scheme is ported to
-Windows NT on the DEC Alpha architecture. In particular, the
-current system is not arranged in a way that adequately distinguishes
-between issues that are a consequence of the NT operating system and
-those which are a consequence of the Intel x86 architecture.
-@end ifinfo
-
-@menu
-* Win32 Package Overview::
-* Foreign function interface::
-* Device Independent Bitmap Utilities::
-@end menu
-
-
-@node Win32 Package Overview, Foreign function interface, Win32 Package Reference, Win32 Package Reference
-@section Overview
-
-
-The Win32 implementation is still in a state of development. It is
-expected that changes will be necessary when MIT/GNU Scheme is ported to
-Windows NT on the DEC Alpha architecture. In particular, the
-current system is not arranged in a way that adequately distinguishes
-between issues that are a consequence of the NT operating system and
-those which are a consequence of the Intel x86 architecture.
-@cindex limitations
-
-Thus this documentation is not definitive, it merely outlines how the
-current system works. Parts of the system will change and any project
-implemented using the win32 system must plan for a re-implementation
-stage.
-
-
-The Win32 implementation has several components:
-
-@itemize @bullet
-
-@item
-Special microcode primitives.
-
-@item
-A foreign function interface (FFI) for calling procedures in dynamically
-linked libraries (DLLs).
-
-@item
-An interface for Edwin.
-
-@item
-The Win32 package provides support for using the features of the
-Windows 3.1 and Windows NT 3.1 environments.
-
-@item
-Device Independent Bitmap utilities. These are used by the win32 Scheme
-Graphics implementation. (The Scheme Graphics implementation is
-described in the Reference Manual).
-
-@end itemize
-
-Note that all the names in the Win32 support are part of the
-@code{win32} package. The names are bound in the @code{(win32)}
-environment, and do not appear as bindings in the user or root
-environments.
-An effect of this is that it is far easier to develop Win32 software in
-the @code{(win32)} package environment or a child environment.
-
-@node Foreign function interface, Device Independent Bitmap Utilities, Win32 Package Overview, Win32 Package Reference
-@section Foreign Function Interface
-
-The Win32 foreign function interface (FFI) is a primitive and fairly
-simple system for calling procedures written in C in a
-dynamically linked library (DLL). Both user's procedures from a custom
-DLL and system procedures (e.g.@: MessageBox) are called using the same
-mechanism.
-
-@cindex limitations
-@strong{Warning}: The FFI as it stands has several flaws which make it
-difficult to use reliably. It is expected that both the interface to
-and the mechanisms used by the FFI will be changed in the future. We
-provide it, and this documentation, only to give people an early start
-in accessing some of the features of Win32 from Scheme. Should you use
-it in an experiment we welcome any feedback.
-
-The FFI is designed for calling C procedures that use C data types
-rather than Scheme data objects. Thus it is not possible to write and
-call a C procedure that returns, for example, a Scheme list. The object
-returned will always be an integer (which may represent the address of a
-C data structure).
-
-@cindex warning
-@strong{Warning}: It is extremely dangerous to try to pass Scheme
-callback procedures to C procedures. It is only possible by passing
-integer `handles' rather than the actual procedures, and even so, if a
-garbage collection occurs during the execution of the callback procedure
-objects in Scheme's heap will have moved. Thus in a foreign procedure
-that has a callback and a string, after calling the callback the string
-value may no longer be valid. Playing this game requires a profound
-knowledge of the implementation.
-
-
-The interface to the FFI has two main components: a language for
-declaring the types of values passed to and returned from the foreign
-procedures and a form for declaring foreign procedures.
-
-@menu
-* Windows Types::
-* Windows Foreign Procedures::
-* Win32 API names and procedures::
-@end menu
-
-@node Windows Types, Windows Foreign Procedures, Foreign function interface, Foreign function interface
-@subsection Windows Types
-
-@cindex Windows types
-@cindex foreign type declarations
-@cindex types, Windows
-@cindex defining foreign types
-Foreign types are designed to represent a correspondence between a
-Scheme data type that is used to represent an object within the Scheme
-world and a C data type that represents the data object in the C world.
-Thus we cannot manipulate true C objects in Scheme, nor can we
-manipulate Scheme objects in C.
-
-Each foreign type has four aspects that together ensure that the
-correspondence between the Scheme and C objects is maintained. These
-aspects are all encoded as procedures that either check for validity or
-convert between representations. Thus a foreign type is not a
-declarative type so much as a procedural description of how to pass the
-type. The underlying foreign procedure call mechanism can pass integers
-and vector-like Scheme objects, and returns integer values. All other
-objects must be translated into integers or some other basic type, and
-must be recovered from integers.
-
-The aspects are:
-
-@table @var
-
-@item check
-A predicate that returns @code{#t} if the argument is of an acceptable
-Scheme type, otherwise returns @code{#f}.
-The @var{check} procedure is used for type-checking.
-
-@item convert
-A procedure of one argument which returns a Scheme object of one of the
-basic types.
-It is used to convert an object into a `simpler' object that will
-eventually be converted into a C object.
-The legal simpler objects are integers and strings.
-
-@item return-convert
-A procedure of one argument that, given an integer, returns a Scheme
-object of a type satisfying @var{check}.
-Its purpose is to convert the result returned by the foreign procedure
-into a Scheme value.
-
-@item revert
-Some C procedures modify one or more of their arguments. These
-arguments are passed by reference, i.e.@: as a pointer to their address.
-Since a Scheme object might have a different memory layout and storage
-conventions, it must be passed by copy-in and copy-out rather than by
-reference.
-@var{Revert} is a procedure of two parameters, the original object
-passed and the result of @var{convert} on that object.
-@var{Revert} may then inspect the converted object and copy back the
-changes to the original.
-
-@end table
-
-@deffn {special form} define-windows-type name check convert return revert
-@deffnx {special form} define-similar-windows-type name model [check [convert [return [revert]]]]
-@cindex defining foreign types
-Both forms define a windows type.
-The first form defines a type in terms of its aspects as described
-above.
-The second defines the type as being like another type, except for
-certain aspects, which are redefined.
-@var{Name} is the name of the type.
-@var{Model} is the name of a type.
-@var{Check}, @var{convert}, @var{return} and @var{revert} are
-procedures or the value @code{#f}.
-A @code{#f} means use the default value, which in the second form means
-use the definition provided for @var{model}.
-The defaults are
-
-@table @var
-@item check
-@code{(lambda (x) #t)}, i.e.@: unchecked.
-@item convert
-@code{(lambda (x) x)}, i.e.@: no translation performed.
-@item return
-@code{(lambda (x) x)}, i.e.@: no translation performed.
-@item revert
-@code{(lambda (x y) unspecific)}, i.e.@: no update performed
-@end table
-
-The @code{unchecked} windows type (see below) is defined as:
-
-@example
-(define-windows-type unchecked #f #f #f #f)
-@end example
-
-Windows types are @emph{not} first class values, so they cannot be
-stored in variables or defined using @code{define}:
-
-@example
-@group
-(define my-type unchecked) @error{} Unbound variable
-(define-similar-windows-type my-type unchecked)
- @r{;; the correct way}
-@end group
-@end example
-
-Scheme characters must be converted to integers. This is accomplished
-as follows:
-
-@example
-@group
-(define-windows-type char
- char? @r{; check}
- char->integer @r{; convert}
- integer->char @r{; convert return value}
- #f @r{; cannot be passed by reference}
-)
-@end group
-@end example
-@end deffn
-
-@deffn {windows type} unchecked
-The type which is not checked and undergoes only the basic conversion
-from a Scheme integer to a C integer or from a Scheme string to a C
-pointer to the first byte of the string.
-Returned @code{unchecked} values are returned as integers.
-@end deffn
-
-@deffn {windows type} bool
-Scheme booleans are analogous to C integers @code{0} and @code{1}.
-Windows type @code{bool} have been defined as:
-
-@example
-@group
-(define-windows-type bool
- boolean?
- (lambda (x) (if x 1 0))
- (lambda (x) (if (eq? x 0) #f #t))
- #f)
-@end group
-@end example
-@end deffn
-
-@deffn {windows type} char
-Scheme characters are converted into C objects of type @code{char},
-which are indistinguishable from small integers.
-@end deffn
-
-@deffn {windows type} int
-@deffnx {windows type} uint
-@deffnx {windows type} long
-@deffnx {windows type} ulong
-@deffnx {windows type} short
-@deffnx {windows type} ushort
-@deffnx {windows type} word
-@deffnx {windows type} byte
-Various integer types that are passed without conversion.
-@end deffn
-
-@deffn {windows type} string
-A string that is passed as a C pointer of type @code{char*} to the first
-character in the string.
-@end deffn
-
-@deffn {windows type} char*
-A string or @code{#f}. The string is passed as a pointer to characters.
-The string is correctly null-terminated. @code{#f} is passed as the null
-pointer. This is an example where there is a more complex mapping
-between C objects and Scheme objects. C's @code{char*} type is
-represented as one of two Scheme types depending on its value. This
-allows us us to distinguish between the C string (pointer) that points
-to the empty sequence of characters and the null pointer (which doesnt
-point anywhere).
-@end deffn
-
-@deffn {windows type} handle
-@deffnx {windows type} hbitmap
-@deffnx {windows type} hbrush
-@deffnx {windows type} hcursor
-@deffnx {windows type} hdc
-@deffnx {windows type} hicon
-@deffnx {windows type} hinstance
-@deffnx {windows type} hmenu
-@deffnx {windows type} hpalette
-@deffnx {windows type} hpen
-@deffnx {windows type} hrgn
-@deffnx {windows type} hwnd
-Various kinds of Win32 handle. These names correspond to the same, but
-all uppercase, names in the Windows C language header files. Win32 API
-calls are the source of values of this type and the values are
-meaningless except as arguments to other Win32 API calls. Currently
-these values are represented as integers but we expect that Win32
-handles will in future be represented by allocated Scheme objects
-(e.g.@: records) that will allow predicates (e.g.@: @code{hmenu?}) and
-sensible interlocking with the garbage collector to free the programmer
-of the current tedious allocation and deallocation of handles.
-@end deffn
-
-@deffn {windows type} resource-id
-A Windows resource identifier is either a small integer or a string.
-In C, this distinction is possible because pointers look like
-larger integers, so a machine word representing a small integer can be
-distinguished from a machine word that is a pointer to the text of the
-name of the resource.
-@end deffn
-
-
-@node Windows Foreign Procedures, Win32 API names and procedures, Windows Types, Foreign function interface
-@subsection Windows Foreign Procedures
-
-Foreign procedures are declared as callable entry-points in a module,
-usually a dynamically linked library (DLL).
-
-
-@deffn procedure find-module name
-@cindex loading DLLs
-@cindex DLL, loading
-Returns a module suitable for use in creating procedures with
-@code{windows-procedure}. @var{Name} is a string which is the name of a
-DLL file. Internally, @code{find-module} uses the @code{LoadLibrary}
-Win32 API, so @var{name} should conform to the specifications for this
-call. @var{Name} should be either a full path name of a DLL, or the
-name of a DLL that resides in the same directory as the Scheme binary
-@file{SCHEME.EXE} or in the system directory.
-
-The module returned is a description for the DLL, and the DLL need not
-necessarily be linked at or immediately after this call. DLL modules
-are linked on need and unlinked before Scheme exits and when there
-are no remaining references to entry points after a garbage-collection.
-This behavior ensures that the Scheme system can run when a DLL is
-absent, provided the DLL is not actually used (i.e.@: no attempt is made
-to call a procedure in the DLL).
-@end deffn
-
-
-@defvr variable gdi32.dll
-@cindex DLL, GDI32.DLL
-This variable is bound to the module describing the @file{GDI32.DLL}
-library, which contains the Win32 API graphics calls, e.g.@:
-@code{LineTo}.
-@end defvr
-
-@defvr variable kernel32.dll
-@cindex DLL, KERNEL32.DLL
-This variable is bound to the module describing the @file{KERNEL32.DLL}
-library.
-@end defvr
-
-@defvr variable user32.dll
-@cindex DLL, USER32.DLL
-This variable is bound to the module describing the @file{USER32.DLL}
-library. This module contains many useful Win32 API procedures, like
-@code{MessageBox} and @code{SetWindowText}.
-@end defvr
-
-
-@deffn {special form} windows-procedure (name (parameter type) @dots{}) return-type module entry-name [options]
-@cindex defining foreign procedures
-This form creates a procedure, and could be thought of as
-``foreign-named-lambda''. The form creates a Scheme procedure that
-calls the C procedure identified by the exported entry point
-@var{entry-name} in the module identified by the value of @var{module}.
-Both @var{entry-name} and @var{module} are evaluated at procedure
-creation time, so either may be expression. @var{Entry-name} must
-evaluate to a string and @var{module} must evaluate to a module as
-returned by @code{find-module}.
-These are the only parts of the form that are evaluated at procedure
-creation time.
-
-@var{Name} is the name of the procedure and is for documentation
-purposes only. This form @emph{does not} define a procedure called
-@var{name}. It is more like @code{lambda}. The name might be used for
-debugging and pretty-printing.
-
-A windows procedure has a fixed number of parameters (i.e.@: no `rest'
-parameters or `varargs'), each of which is named and associated with a
-windows type @var{type}. Both the name @var{parameter} and the windows
-type @var{type} must be symbols and are not evaluated. The procedure
-returns a value of the windows type @var{return-type}.
-
-The following example creates a procedure that takes a window handle
-(@code{hwnd}) and a string and returns a boolean (@code{bool}) result.
-The procedure does this by calling the @code{SetWindowText} entry in the
-module that is the value of the variable @code{user32.dll}. The
-variable @code{set-window-title} is defined to have this procedure as
-it's value.
-
-@example
-@group
-(define set-window-title
- (windows-procedure
- (set-window-text (window hwnd) (text string))
- bool user32.dll "SetWindowText"))
-
-(set-window-title my-win "Hi")
- @result{} #t
- @r{;; Changes window's title/text}
-
-set-window-title @result{} #[compiled-procedure @dots{}]
-set-window-text @error{} Unbound variable
-@end group
-@end example
-
-
-When there are no @var{options} the created procedure will (a) check its
-arguments against the types, (b) convert the arguments, (c) call the C
-procedure and (d) convert the returned value. No reversion is
-performed, even if one of the @var{types} has a reversion defined.
-(Reverted types are rare [I have never used one], so paying a cost for
-this unless it is used seems silly).
-
-The following options are allowed:
-
-@table @asis
-@item @code{with-reversions}
-The reversions are included in the type conversions.
-
-@item @code{expand}
-A synonym for @code{with-reversions}.
-
-@item @var{Scheme code}
-The @var{Scheme code} is placed between steps (a) and (b) in the default
-process. The Scheme code can enforce constraints on the arguments,
-including constraints between arguments such as checking that an index
-refers to a valid position in a string.
-@end table
-
-If both options (i.e.@: @code{with-reversions} and Scheme code) are used,
-@code{with-reversions} must appear first. There can be arbitrarily many
-Scheme expression.
-@end deffn
-
-@node Win32 API names and procedures, , Windows Foreign Procedures, Foreign function interface
-@subsection Win32 API names and procedures
-
-This section is a moving target.
-@cindex Win32 API names
-@cindex naming conventions
-
-The @code{#define} values from @file{wingdi.h} and @file{winuser.h} are
-available as bindings in the @code{(win32)} package environment. The
-@code{#define} symbols are all uppercase; these have been translated to
-all lowercase Scheme identifiers, thus @code{WM_LBUTTONUP} is the scheme
-variable @code{wm_lbuttonup}. As Scheme is case insensitive, the
-upper-case version may be used and probably should to make the code look
-more like conventional Windows code. The Scheme bindings have been
-produced automagically. Most of the @code{#define}-symbols contain an
-underscore so there are not many name clashes. There is one very
-notable name clash, however: @code{ERROR} is @code{#define}d to 0, which
-shadows the scheme procedure @code{error} in the root package
-environment. To signal an error, use @code{access} to get @code{error}
-from the system global environment:
-
-@example
-@group
-(declare (usual-integrations))
-@dots{}
-((access error system-global-environment) "Complain" @dots{})
-@end group
-@end example
-
-
-The set of procedures is incomplete because procedures have been added
-on a by-need basis for the implementation of other parts of the system,
-e.g.@: Scheme Graphics. Look in the implementation for further details.
-
-Win32 API procedure names have been uniformly converted into Scheme
-identifiers as follows:
-
-@itemize @bullet
-@item
-A leading uppercase letter is translated into a lowercase letter.
-@item
-Subsequent sequences of uppercase letters are translated into lowercase
-letters preceeded by a hyphen (minus symbol), i.e.@: hyphens are inserted
-at a lowercase to uppercase transition.
-@item
-Predicates beginning with @code{Is} finally have a
-question-mark appended.
-@end itemize
-
-@noindent
-Example: applying these rules to @code{IsWindow} yields
-@code{is-window?}, and @code{GetDC} is translated into @code{get-dc}.
-
-
-@c [It might be worthwhile just keeping the same names. As the
-@c Win32 API procedure names are uniformly `WordWordWordACRONYMWord', case
-@c insensitivity is unlikely to be a problem. The only problem is the
-@c potential for a clash between a procedure name and a type
-@c name.]
-
-
-@node Device Independent Bitmap Utilities, , Foreign function interface, Win32 Package Reference
-@section Device Independent Bitmap Utilities
-
-
-The Device Independent Bitmap (DIB) utilities library @file{DIBUTILS.DLL}
-and the associated procedures in @file{dib.scm} in the Win32 system
-source is an example of how to use the foreign function interface to
-access and manipulate non-Scheme objects.
-@cindex DLL, DIBUTILS.DLL
-
-@deffn {windows type} dib
-In the C world a DIB is a @dfn{handle} to a piece of memory containing
-the bits that represent information about the image and the pixels of
-the image. The handle is a machine-word sized piece of data which may
-be thought of as a 32 bit integer. The handle may be null (i.e.@: zero),
-indicating that there is no block of memory describing the DIB. The
-null value is usually returned by C functions that are supposed to
-create a DIB but failed, for some reason like the memory could not be
-allocated or a file could not be opened.
-
-In the Scheme world a DIB is a structure containing information
-about the bitmap (specifically the integer that represents the handle).
-We also include @code{#f} in the @code{dib} windows type to mirror the
-null handle error value.
-
-@example
-@group
-(define dib-result
- (lambda (handle)
- (if (= handle 0)
- #f
- (make-dib handle))))
-
-(define dib-arg
- (lambda (dib)
- (if dib
- (cell-contents (dib-handle dib))
- 0)))
-
-(define-windows-type dib
- (lambda (thing) (or (dib? thing) (eq? thing #f)))
- dib-arg
- dib-result)
-@end group
-@end example
-@end deffn
-
-
-@menu
-* DIB procedures::
-* Other parts of the DIB Utilities implementation::
-@end menu
-
-@node DIB procedures, Other parts of the DIB Utilities implementation, Device Independent Bitmap Utilities, Device Independent Bitmap Utilities
-@subsection DIB procedures
-
-The following procedures have typed parameters, using the same
-convention as @code{windows-procedure}.
-
-@deffn procedure open-dib (filename string)
-Return type: @var{dib}. Calls the @code{OpenDIB} entry of
-@file{DIBUTILS.DLL}. If the return value is not @code{#f} then the file
-@var{filename} was found, successfully opened, and the contents were
-suitable for loading into memory as a device independent bitmap.
-@end deffn
-
-@deffn procedure write-dib (filename string) (dib dib)
-Return type: @var{bool}. Calls the @code{WriteDIB} entry of
-@file{DIBUTILS.DLL}. Returns @code{#t} if the file @var{filename} could
-be opened and written to. After this operation the file contains the
-bitmap data in a standard format that is understood by @code{open-dib}
-and various system utilities like the bitmap editor. Any problems
-resulting in failure are signalled by a @code{#f} return value.
-@end deffn
-
-@deffn procedure bitmap-from-dib (dib dib) (palette hpalette)
-Return type: @var{hbitmap}.
-Calls the @code{BitmapFromDib} entry of @file{DIBUTILS.DLL}. The returned
-value is a device dependent bitmap. The colours from the DIB are
-matched against colors in @var{palette}.
-@end deffn
-
-@deffn procedure dib-from-bitmap (bitmap hbitmap) (style dword) (bits word) (palette hpalette)
-Return type: @var{dib}.
-Returns a DIB containing the same image as the device dependent bitmap
-@var{bitmap}.
-@var{Style} determines the kind of DIB, e.g.@: compression style.
-Calls the @code{DibFromBitmap} entry of @file{DIBUTILS.DLL}.
-@end deffn
-
-@deffn procedure dib-blt (dest hdc) (x int) (y int) (w int) (h int) (src dib) (src-x int) (src-y int) (raster-op long)
-Return type: @var{bool}. Calls the @code{DibBlt} entry of
-@file{DIBUTILS.DLL}. Similar to the Win32 API @code{BitBlt} call, but
-draws a DIB rather than a piece of another device context. Draws the
-@var{dib} on device context @var{hdc} at position (@var{x},@var{y}). A
-rectangle of width @var{w} and height @var{h} is copied from position
-(@var{src-x},@var{src-y}) of @var{dib}.
-@var{Raster-op} is supposed to allow the source and destination to be
-combined but I don't think I got this right so stick to @code{SRCCOPY}.
-@end deffn
-
-@deffn procedure %delete-dib (dib-handle handle)
-Return type: @var{bool}.
-Calls the @code{DeleteDIB} entry of @file{DIBUTILS.DLL}.
-Note that the parameter is a @var{handle}, and not a @var{dib}.
-This allows us to destroy a DIB and reclaim its memory by knowing only
-the handle value, and not needing the @code{dib} record.
-The importance of this is that if the @code{dib} record is GC-ed then a
-GC hook can reclaim the storage knowing only the handle.
-@end deffn
-
-@deffn procedure delete-dib (dib dib)
-Return type: @var{bool}.
-This procedure calls @code{%delete-dib} to reclaim the storage occupied
-by a DIB.
-After being deleted, the DIB should not be used.
-This procedure allows the programmer to reclaim external heap storage
-rather than risking it running out before the next garbage collection.
-@end deffn
-
-@deffn procedure dib-height (dib dib)
-Return type: @var{int}.
-Calls the @code{DibHeight} expand entry of @file{DIBUTILS.DLL}, which returns
-the height of the bitmap in pixels.
-@end deffn
-
-@deffn procedure dib-width (dib dib)
-Return type: @var{int}.
-Calls the @code{DibWidth} entry of @file{DIBUTILS.DLL}, which returns
-the width of the bitmap in pixels.
-@end deffn
-
-@deffn procedure copy-bitmap (bm hbitmap)
-Return type: @var{hbitmap}.
-Calls the @code{CopyBitmap} of @file{DIBUTILS.DLL}, which creates a new
-bitmap with the same size and contents as the original.
-@end deffn
-
-@deffn procedure create-dib (width int) (height int) (style int) (depth int) (palette hpalette)
-Return type: @var{dib}.
-Calls the @code{CreateDIB} entry of @file{DIBUTILS.DLL}.
-Creates a DIB of @var{width} by @var{height} pixels and @var{depth} bits
-of colour information.
-The @var{style} parameter determines how the bitmap is stored.
-I have only ever used @code{BI_RGB}.
-If @var{depth}<=8 then the @var{palette} determines the DIB's colour table.
-@end deffn
-
-@deffn procedure crop-bitmap (bm hbitmap) (left int) (top int) (right int) (bottom int)
-Return type: @var{hbitmap}.
-Calls the @code{CropBitmap} entry of @file{DIBUTILS.DLL}.
-Returns a new bitmap containing the image from a region of the original.
-@end deffn
-
-@deffn procedure dib-set-pixels-unaligned dib (pixels string)
-Return type: @var{bool}.
-Calls the @code{DIBSetPixelsUnaligned} entry of@* @file{DIBUTILS.DLL}. Stuffs
-bytes from @var{pixels} into the bitmap. There are no alignment
-constraints on @var{pixels} (the usual way of doing this is to use the
-@code{SetDIBits} function which requires that every scan line of the
-bitmap is 32-bit word aligned, even if the scan lines are not a multiple
-of 4 bytes long). doing this
-@end deffn
-
-@node Other parts of the DIB Utilities implementation, , DIB procedures, Device Independent Bitmap Utilities
-@subsection Other parts of the DIB Utilities implementation
-
-
-The @file{DIBUTILS.DLL} library is an ordinary DLL. See the standard
-Microsoft Windows documentation on how to create DLLs. Look at the code
-in the @file{WIN32/DIBUTILS} directory of the Scheme source.
-
-Please note:
-@itemize @bullet
-@item
-@cindex DLL, exports
-For the foreign function interface to find the procedures they must be
-declared as exports in the @file{.DEF} definition file.
-
-@item
-To load the @file{.DLL} file use the @code{find-module} Scheme function.
-Look at @file{WIN32/DIB.SCM} to see how this is done.
-
-@item
-The current system works with C procedures with the @code{__stdcall} and
-@code{__cdecl} calling conventions but @emph{not} the @code{__fastcall}
-calling convention.
-@end itemize
-
+@include overview.texi
+@include special-forms.texi
+@include equivalence.texi
+@include numbers.texi
+@include characters.texi
+@include strings.texi
+@include lists.texi
+@include vectors.texi
+@include bit-strings.texi
+@include misc-datatypes.texi
+@include associations.texi
+@include procedures.texi
+@include environments.texi
+@include io.texi
+@include os-interface.texi
+@include error.texi
+@include graphics.texi
+@include win32-packaging.texi
@node GNU Free Documentation License, Binding Index, Win32 Package Reference, Top
@appendix GNU Free Documentation License
@include gfdl.texinfo
--- /dev/null
+@c This file is part of the MIT/GNU Scheme Reference Manual.
+@c $Id: special-forms.texi,v 1.1 2003/04/15 03:30:15 cph Exp $
+
+@c Copyright 1991,1992,1993,1994,1995 Massachusetts Institute of Technology
+@c Copyright 1996,1997,1999,2000,2001 Massachusetts Institute of Technology
+@c Copyright 2002,2003 Massachusetts Institute of Technology
+@c See file scheme.texinfo for copying conditions.
+
+@node Special Forms, Equivalence Predicates, Overview, Top
+@chapter Special Forms
+
+@cindex special form
+A special form is an expression that follows special evaluation rules.
+This chapter describes the basic Scheme special forms.
+
+@menu
+* Lambda Expressions::
+* Lexical Binding::
+* Dynamic Binding::
+* Definitions::
+* Assignments::
+* Quoting::
+* Conditionals::
+* Sequencing::
+* Iteration::
+* Structure Definitions::
+* Macros::
+* SRFI syntax::
+@end menu
+
+@node Lambda Expressions, Lexical Binding, Special Forms, Special Forms
+@section Lambda Expressions
+
+@deffn {special form} lambda formals expression expression @dots{}
+@cindex lambda expression (defn)
+@cindex procedure, construction
+@cindex procedure, closing environment (defn)
+@cindex procedure, invocation environment (defn)
+@cindex construction, of procedure
+@cindex closing environment, of procedure (defn)
+@cindex invocation environment, of procedure (defn)
+@cindex environment, of procedure
+@cindex environment, procedure closing (defn)
+@cindex environment, procedure invocation (defn)
+A @code{lambda} expression evaluates to a procedure. The environment in
+effect when the @code{lambda} expression is evaluated is remembered as
+part of the procedure; it is called the @dfn{closing environment}. When
+the procedure is later called with some arguments, the closing
+environment is extended by binding the variables in the formal parameter
+list to fresh locations, and the locations are filled with the arguments
+according to rules about to be given. The new environment created by
+this process is referred to as the @dfn{invocation environment}.
+
+@cindex region of variable binding, lambda
+@cindex variable binding, lambda
+Once the invocation environment has been constructed, the
+@var{expression}s in the body of the @code{lambda} expression are
+evaluated sequentially in it. This means that the region of the
+variables bound by the @code{lambda} expression is all of the
+@var{expression}s in the body. The result of evaluating the last
+@var{expression} in the body is returned as the result of the procedure
+call.
+
+@cindex lambda list (defn)
+@cindex parameter list, of lambda (defn)
+@cindex formal parameter list, of lambda (defn)
+@var{Formals}, the formal parameter list, is often referred to as a
+@dfn{lambda list}.
+
+The process of matching up formal parameters with arguments is somewhat
+involved. There are three types of parameters, and the matching treats
+each in sequence:
+
+@need 1000
+@table @asis
+@item Required
+All of the @dfn{required} parameters are matched against the arguments
+first. If there are fewer arguments than required parameters, an error
+of type @code{condition-type:wrong-number-of-arguments} is signalled;
+this error is also signalled if there are more arguments than required
+parameters and there are no further parameters.
+@cindex required parameter (defn)
+@cindex parameter, required (defn)
+@findex condition-type:wrong-number-of-arguments
+
+@item Optional
+Once the required parameters have all been matched, the @dfn{optional}
+parameters are matched against the remaining arguments. If there are
+fewer arguments than optional parameters, the unmatched parameters are
+bound to special objects called @dfn{default objects}. If there are
+more arguments than optional parameters, and there are no further
+parameters, an error of type
+@code{condition-type:wrong-number-of-arguments} is signalled.
+@cindex optional parameter (defn)
+@cindex parameter, optional (defn)
+@cindex default object (defn)
+@findex condition-type:wrong-number-of-arguments
+
+@findex default-object?
+The predicate @code{default-object?}, which is true only of default
+objects, can be used to determine which optional parameters were
+supplied, and which were defaulted.
+
+@item Rest
+Finally, if there is a @dfn{rest} parameter (there can only be one), any
+remaining arguments are made into a list, and the list is bound to the
+rest parameter. (If there are no remaining arguments, the rest
+parameter is bound to the empty list.)
+@cindex rest parameter (defn)
+@cindex parameter, rest (defn)
+
+In Scheme, unlike some other Lisp implementations, the list to which a
+rest parameter is bound is always freshly allocated. It has infinite
+extent and may be modified without affecting the procedure's caller.
+@end table
+
+@findex #!optional
+@findex #!rest
+Specially recognized keywords divide the @var{formals} parameters into
+these three classes. The keywords used here are @samp{#!optional},
+@samp{.}, and @samp{#!rest}. Note that only @samp{.} is defined by
+standard Scheme --- the other keywords are MIT/GNU Scheme extensions.
+@samp{#!rest} has the same meaning as @samp{.} in @var{formals}.
+
+The use of these keywords is best explained by means of examples. The
+following are typical lambda lists, followed by descriptions of which
+parameters are required, optional, and rest. We will use @samp{#!rest}
+in these examples, but anywhere it appears @samp{.} could be used
+instead.
+
+@table @code
+@item (a b c)
+@code{a}, @code{b}, and @code{c} are all required. The procedure must
+be passed exactly three arguments.
+
+@item (a b #!optional c)
+@code{a} and @code{b} are required, @code{c} is optional. The procedure
+may be passed either two or three arguments.
+
+@item (#!optional a b c)
+@code{a}, @code{b}, and @code{c} are all optional. The procedure may be
+passed any number of arguments between zero and three, inclusive.
+
+@item a
+@itemx (#!rest a)
+These two examples are equivalent. @code{a} is a rest parameter. The
+procedure may be passed any number of arguments. Note: this is the only
+case in which @samp{.} cannot be used in place of @samp{#!rest}.
+
+@item (a b #!optional c d #!rest e)
+@code{a} and @code{b} are required, @code{c} and @code{d} are optional,
+and @code{e} is rest. The procedure may be passed two or more
+arguments.
+@end table
+
+Some examples of @code{lambda} expressions:
+
+@example
+@group
+(lambda (x) (+ x x)) @result{} #[compound-procedure 53]
+
+((lambda (x) (+ x x)) 4) @result{} 8
+
+(define reverse-subtract
+ (lambda (x y)
+ (- y x)))
+(reverse-subtract 7 10) @result{} 3
+
+(define foo
+ (let ((x 4))
+ (lambda (y) (+ x y))))
+(foo 6) @result{} 10
+@end group
+@end example
+@end deffn
+
+@deffn {special form} named-lambda formals expression expression @dots{}
+@cindex named lambda (defn)
+The @code{named-lambda} special form is similar to @code{lambda}, except
+that the first ``required parameter'' in @var{formals} is not a
+parameter but the @dfn{name} of the resulting procedure; thus
+@var{formals} must have at least one required parameter. This name has
+no semantic meaning, but is included in the external representation of
+the procedure, making it useful for debugging. In MIT/GNU Scheme,
+@code{lambda} is implemented as @code{named-lambda}, with a special name
+that means ``unnamed''.
+
+@example
+@group
+(named-lambda (f x) (+ x x)) @result{} #[compound-procedure 53 f]
+((named-lambda (f x) (+ x x)) 4) @result{} 8
+@end group
+@end example
+@end deffn
+
+@node Lexical Binding, Dynamic Binding, Lambda Expressions, Special Forms
+@section Lexical Binding
+
+@cindex lexical binding expression
+@cindex binding expression, lexical
+@cindex block structure
+The three binding constructs @code{let}, @code{let*}, and @code{letrec},
+give Scheme block structure. The syntax of the three constructs is
+identical, but they differ in the regions they establish for their
+variable bindings. In a @code{let} expression, the initial values are
+computed before any of the variables become bound. In a @code{let*}
+expression, the evaluations and bindings are sequentially interleaved.
+And in a @code{letrec} expression, all the bindings are in effect while
+the initial values are being computed (thus allowing mutually recursive
+definitions).
+
+@deffn {special form} let ((@var{variable} @var{init}) @dots{}) expression expression @dots{}
+@cindex region of variable binding, let
+@cindex variable binding, let
+The @var{init}s are evaluated in the current environment (in some
+unspecified order), the @var{variable}s are bound to fresh locations
+holding the results, the @var{expression}s are evaluated sequentially in
+the extended environment, and the value of the last @var{expression} is
+returned. Each binding of a @var{variable} has the @var{expression}s as
+its region.
+
+MIT/GNU Scheme allows any of the @var{init}s to be omitted, in which
+case the corresponding @var{variable}s are unassigned.
+
+@cindex lambda, implicit in let
+Note that the following are equivalent:
+
+@example
+@group
+(let ((@var{variable} @var{init}) @dots{}) @var{expression} @var{expression} @dots{})
+((lambda (@var{variable} @dots{}) @var{expression} @var{expression} @dots{}) @var{init} @dots{})
+@end group
+@end example
+
+Some examples:
+
+@example
+@group
+(let ((x 2) (y 3))
+ (* x y)) @result{} 6
+@end group
+
+@group
+(let ((x 2) (y 3))
+ (let ((foo (lambda (z) (+ x y z)))
+ (x 7))
+ (foo 4))) @result{} 9
+@end group
+@end example
+
+@xref{Iteration}, for information on ``named @code{let}''.
+@end deffn
+
+@deffn {special form} let* ((@var{variable} @var{init}) @dots{}) expression expression @dots{}
+@cindex region of variable binding, let*
+@cindex variable binding, let*
+@code{let*} is similar to @code{let}, but the bindings are performed
+sequentially from left to right, and the region of a binding is that
+part of the @code{let*} expression to the right of the binding. Thus
+the second binding is done in an environment in which the first binding
+is visible, and so on.
+
+Note that the following are equivalent:
+
+@example
+@group
+(let* ((@var{variable1} @var{init1})
+ (@var{variable2} @var{init2})
+ @dots{}
+ (@var{variableN} @var{initN}))
+ @var{expression}
+ @var{expression} @dots{})
+@end group
+
+@group
+(let ((@var{variable1} @var{init1}))
+ (let ((@var{variable2} @var{init2}))
+ @dots{}
+ (let ((@var{variableN} @var{initN}))
+ @var{expression}
+ @var{expression} @dots{})
+ @dots{}))
+@end group
+@end example
+
+An example:
+
+@example
+@group
+(let ((x 2) (y 3))
+ (let* ((x 7)
+ (z (+ x y)))
+ (* z x))) @result{} 70
+@end group
+@end example
+@end deffn
+
+@deffn {special form} letrec ((@var{variable} @var{init}) @dots{}) expression expression @dots{}
+@cindex region of variable binding, letrec
+@cindex variable binding, letrec
+The @var{variable}s are bound to fresh locations holding unassigned
+values, the @var{init}s are evaluated in the extended environment (in
+some unspecified order), each @var{variable} is assigned to the result
+of the corresponding @var{init}, the @var{expression}s are evaluated
+sequentially in the extended environment, and the value of the last
+@var{expression} is returned. Each binding of a @var{variable} has the
+entire @code{letrec} expression as its region, making it possible to
+define mutually recursive procedures.
+
+MIT/GNU Scheme allows any of the @var{init}s to be omitted, in which
+case the corresponding @var{variable}s are unassigned.
+
+@example
+@group
+(letrec ((even?
+ (lambda (n)
+ (if (zero? n)
+ #t
+ (odd? (- n 1)))))
+ (odd?
+ (lambda (n)
+ (if (zero? n)
+ #f
+ (even? (- n 1))))))
+ (even? 88)) @result{} #t
+@end group
+@end example
+
+@findex lambda
+@findex delay
+One restriction on @code{letrec} is very important: it shall be possible
+to evaluated each @var{init} without assigning or referring to the value
+of any @var{variable}. If this restriction is violated, then it is an
+error. The restriction is necessary because Scheme passes arguments by
+value rather than by name. In the most common uses of @code{letrec},
+all the @var{init}s are @code{lambda} or @code{delay} expressions and
+the restriction is satisfied automatically.
+@end deffn
+
+@node Dynamic Binding, Definitions, Lexical Binding, Special Forms
+@section Dynamic Binding
+
+@deffn {special form} fluid-let ((@var{variable} @var{init}) @dots{}) expression expression @dots{}
+@cindex binding expression, dynamic (or fluid)
+@cindex fluid binding
+@cindex dynamic binding
+@cindex variable binding, fluid-let
+The @var{init}s are evaluated in the current environment (in some
+unspecified order), the current values of the @var{variable}s are saved,
+the results are assigned to the @var{variable}s, the @var{expression}s
+are evaluated sequentially in the current environment, the
+@var{variable}s are restored to their original values, and the value of
+the last @var{expression} is returned.
+
+@findex let
+The syntax of this special form is similar to that of @code{let}, but
+@code{fluid-let} temporarily rebinds existing variables. Unlike
+@code{let}, @code{fluid-let} creates no new bindings; instead it
+@emph{assigns} the value of each @var{init} to the binding (determined
+by the rules of lexical scoping) of its corresponding @var{variable}.
+
+@cindex unassigned variable, and dynamic bindings
+MIT/GNU Scheme allows any of the @var{init}s to be omitted, in which
+case the corresponding @var{variable}s are temporarily unassigned.
+
+An error of type @code{condition-type:unbound-variable} is signalled if
+any of the @var{variable}s are unbound. However, because
+@code{fluid-let} operates by means of side effects, it is valid for any
+@var{variable} to be unassigned when the form is entered.
+@findex condition-type:unbound-variable
+
+Here is an example showing the difference between @code{fluid-let} and
+@code{let}. First see how @code{let} affects the binding of a variable:
+
+@example
+@group
+(define variable #t)
+(define (access-variable) variable)
+variable @result{} #t
+(let ((variable #f))
+ (access-variable)) @result{} #t
+variable @result{} #t
+@end group
+@end example
+
+@code{access-variable} returns @code{#t} in this case because it
+is defined in an environment with @code{variable} bound to
+@code{#t}. @code{fluid-let}, on the other hand, temporarily reuses an
+existing variable:
+
+@example
+@group
+variable @result{} #t
+(fluid-let ((variable #f)) @r{;reuses old binding}
+ (access-variable)) @result{} #f
+variable @result{} #t
+@end group
+@end example
+
+@cindex extent, of dynamic binding (defn)
+The @dfn{extent} of a dynamic binding is defined to be the time period
+during which the variable contains the new value. Normally this time
+period begins when the body is entered and ends when it is exited; on a
+sequential machine it is normally a contiguous time period. However,
+because Scheme has first-class continuations, it is possible to leave
+the body and then reenter it, as many times as desired. In this
+situation, the extent becomes non-contiguous.
+
+@cindex dynamic binding, and continuations
+@cindex continuation, and dynamic binding
+When the body is exited by invoking a continuation, the new value is
+saved, and the variable is set to the old value. Then, if the body is
+reentered by invoking a continuation, the old value is saved, and the
+variable is set to the new value. In addition, side effects to the
+variable that occur both inside and outside of body are preserved, even
+if continuations are used to jump in and out of body repeatedly.
+@end deffn
+
+Here is a complicated example that shows the interaction between dynamic
+binding and continuations:
+
+@example
+@group
+(define (complicated-dynamic-binding)
+ (let ((variable 1)
+ (inside-continuation))
+ (write-line variable)
+ (call-with-current-continuation
+ (lambda (outside-continuation)
+ (fluid-let ((variable 2))
+ (write-line variable)
+ (set! variable 3)
+ (call-with-current-continuation
+ (lambda (k)
+ (set! inside-continuation k)
+ (outside-continuation #t)))
+ (write-line variable)
+ (set! inside-continuation #f))))
+ (write-line variable)
+ (if inside-continuation
+ (begin
+ (set! variable 4)
+ (inside-continuation #f)))))
+@end group
+@end example
+
+@noindent
+Evaluating @samp{(complicated-dynamic-binding)} writes the following on
+the console:
+
+@example
+@group
+1
+2
+1
+3
+4
+@end group
+@end example
+
+@noindent
+Commentary: the first two values written are the initial binding of
+@code{variable} and its new binding after the @code{fluid-let}'s body is
+entered. Immediately after they are written, @code{variable} is set to
+@samp{3}, and then @code{outside-continuation} is invoked, causing us to
+exit the body. At this point, @samp{1} is written, demonstrating that
+the original value of @code{variable} has been restored, because we have
+left the body. Then we set @code{variable} to @samp{4} and reenter the
+body by invoking @code{inside-continuation}. At this point, @samp{3} is
+written, indicating that the side effect that previously occurred within
+the body has been preserved. Finally, we exit body normally, and write
+@samp{4}, demonstrating that the side effect that occurred outside of
+the body was also preserved.
+
+@node Definitions, Assignments, Dynamic Binding, Special Forms
+@section Definitions
+@cindex definition
+
+@deffn {special form} define variable [expression]
+@deffnx {special form} define @var{formals} expression expression @dots{}
+@cindex variable, adding to environment
+@cindex definition, top-level (defn)
+@cindex definition, internal (defn)
+@cindex top-level definition (defn)
+@cindex internal definition (defn)
+@findex lambda
+@findex let
+@findex let*
+@findex letrec
+@findex fluid-let
+Definitions are valid in some but not all contexts where expressions are
+allowed. Definitions may only occur at the top level of a program and
+at the beginning of a lambda body (that is, the body of a @code{lambda},
+@code{let}, @code{let*}, @code{letrec}, @code{fluid-let}, or ``procedure
+@code{define}'' expression). A definition that occurs at the top level
+of a program is called a @dfn{top-level definition}, and a definition
+that occurs at the beginning of a body is called an @dfn{internal
+definition}.
+
+@cindex lambda, implicit in define
+@cindex procedure define (defn)
+@cindex define, procedure (defn)
+@findex named-lambda
+In the second form of @code{define} (called ``@dfn{procedure
+@code{define}}''), the component @var{formals} is identical to the
+component of the same name in a @code{named-lambda} expression. In
+fact, these two expressions are equivalent:
+
+@example
+@group
+(define (@var{name1} @var{name2} @dots{})
+ @var{expression}
+ @var{expression} @dots{})
+@end group
+
+@group
+(define @var{name1}
+ (named-lambda (@var{name1} @var{name2} @dots{})
+ @var{expression}
+ @var{expression} @dots{}))
+@end group
+@end example
+@end deffn
+
+@menu
+* Top-Level Definitions::
+* Internal Definitions::
+@end menu
+
+@node Top-Level Definitions, Internal Definitions, Definitions, Definitions
+@subsection Top-Level Definitions
+@cindex top-level definition
+@cindex definition, top-level
+
+@cindex variable binding, top-level definition
+A top-level definition,
+
+@example
+(define @var{variable} @var{expression})
+@end example
+
+@noindent
+has essentially the same effect as this assignment expression, if
+@var{variable} is bound:
+
+@example
+(set! @var{variable} @var{expression})
+@end example
+
+@cindex unassigned variable, and definition
+@findex set!
+If @var{variable} is not bound, however, @code{define} binds
+@var{variable} to a new location in the current environment before
+performing the assignment (it is an error to perform a @code{set!} on an
+unbound variable). If you omit @var{expression}, the variable becomes
+unassigned; an attempt to reference such a variable is an error.
+
+@example
+@group
+(define add3
+ (lambda (x) (+ x 3))) @result{} @r{unspecified}
+(add3 3) @result{} 6
+
+(define first car) @result{} @r{unspecified}
+(first '(1 2)) @result{} 1
+
+(define bar) @result{} @r{unspecified}
+bar @error{} Unassigned variable
+@end group
+@end example
+
+@node Internal Definitions, , Top-Level Definitions, Definitions
+@subsection Internal Definitions
+
+@cindex internal definition
+@cindex definition, internal
+@cindex region of variable binding, internal definition
+@cindex variable binding, internal definition
+@findex lambda
+@findex let
+@findex let*
+@findex letrec
+@findex fluid-let
+@findex define
+An @dfn{internal definition} is a definition that occurs at the
+beginning of a @var{body} (that is, the body of a @code{lambda},
+@code{let}, @code{let*}, @code{letrec}, @code{fluid-let}, or ``procedure
+@code{define}'' expression), rather than at the top level of a program.
+The variable defined by an internal definition is local to the
+@var{body}. That is, @var{variable} is bound rather than assigned, and
+the region of the binding is the entire @var{body}. For example,
+
+@example
+@group
+(let ((x 5))
+ (define foo (lambda (y) (bar x y)))
+ (define bar (lambda (a b) (+ (* a b) a)))
+ (foo (+ x 3))) @result{} 45
+@end group
+@end example
+
+@findex letrec
+A @var{body} containing internal definitions can always be converted
+into a completely equivalent @code{letrec} expression. For example, the
+@code{let} expression in the above example is equivalent to
+
+@cindex letrec, implicit in define
+@example
+@group
+(let ((x 5))
+ (letrec ((foo (lambda (y) (bar x y)))
+ (bar (lambda (a b) (+ (* a b) a))))
+ (foo (+ x 3))))
+@end group
+@end example
+
+@need 1000
+@node Assignments, Quoting, Definitions, Special Forms
+@section Assignments
+@cindex assignment
+
+@deffn {special form} set! variable [expression]
+@cindex variable, assigning values to
+@cindex unassigned variable, and assignment
+If @var{expression} is specified, evaluates @var{expression} and stores
+the resulting value in the location to which @var{variable} is bound.
+If @var{expression} is omitted, @var{variable} is altered to be
+unassigned; a subsequent reference to such a @var{variable} is an error.
+In either case, the value of the @code{set!} expression is unspecified.
+
+@var{Variable} must be bound either in some region enclosing the
+@code{set!} expression, or at the top level. However, @var{variable} is
+permitted to be unassigned when the @code{set!} form is entered.
+
+@example
+@group
+(define x 2) @result{} @r{unspecified}
+(+ x 1) @result{} 3
+(set! x 4) @result{} @r{unspecified}
+(+ x 1) @result{} 5
+@end group
+@end example
+
+@cindex access, used with set!
+@findex access
+@var{Variable} may be an @code{access} expression
+(@pxref{Environments}). This allows you to assign variables in an
+arbitrary environment. For example,
+
+@example
+@group
+(define x (let ((y 0)) (the-environment)))
+(define y 'a)
+y @result{} a
+(access y x) @result{} 0
+(set! (access y x) 1) @result{} @r{unspecified}
+y @result{} a
+(access y x) @result{} 1
+@end group
+@end example
+@end deffn
+
+@node Quoting, Conditionals, Assignments, Special Forms
+@section Quoting
+@cindex quoting
+
+This section describes the expressions that are used to modify or
+prevent the evaluation of objects.
+
+@deffn {special form} quote datum
+@cindex external representation, and quote
+@cindex literal, and quote
+@cindex constant, and quote
+@code{(quote @var{datum})} evaluates to @var{datum}. @var{Datum} may be
+any external representation of a Scheme object
+(@pxref{External Representations}).
+Use @code{quote} to include literal constants in
+Scheme code.
+
+@example
+@group
+(quote a) @result{} a
+(quote #(a b c)) @result{} #(a b c)
+(quote (+ 1 2)) @result{} (+ 1 2)
+@end group
+@end example
+
+@cindex ' as external representation
+@cindex apostrophe, as external representation
+@cindex quote, as external representation
+@findex '
+@code{(quote @var{datum})} may be abbreviated as @code{'@var{datum}}.
+The two notations are equivalent in all respects.
+
+@example
+@group
+'a @result{} a
+'#(a b c) @result{} #(a b c)
+'(+ 1 2) @result{} (+ 1 2)
+'(quote a) @result{} (quote a)
+''a @result{} (quote a)
+@end group
+@end example
+
+Numeric constants, string constants, character constants, and boolean
+constants evaluate to themselves, so they don't need to be quoted.
+
+@example
+@group
+'"abc" @result{} "abc"
+"abc" @result{} "abc"
+'145932 @result{} 145932
+145932 @result{} 145932
+'#t @result{} #t
+#t @result{} #t
+'#\a @result{} #\a
+#\a @result{} #\a
+@end group
+@end example
+@end deffn
+
+@deffn {special form} quasiquote template
+@cindex external representation, and quasiquote
+@cindex literal, and quasiquote
+@cindex constant, and quasiquote
+@findex equal?
+``Backquote'' or ``quasiquote'' expressions are useful for constructing
+a list or vector structure when most but not all of the desired
+structure is known in advance. If no commas appear within the
+@var{template}, the result of evaluating @code{`@var{template}} is
+equivalent (in the sense of @code{equal?}) to the result of evaluating
+@code{'@var{template}}. If a comma appears within the @var{template},
+however, the expression following the comma is evaluated (``unquoted'')
+and its result is inserted into the structure instead of the comma and
+the expression. If a comma appears followed immediately by an at-sign
+(@@), then the following expression shall evaluate to a list; the
+opening and closing parentheses of the list are then ``stripped away''
+and the elements of the list are inserted in place of the comma at-sign
+expression sequence.
+
+@example
+@group
+`(list ,(+ 1 2) 4) @result{} (list 3 4)
+
+(let ((name 'a)) `(list ,name ',name)) @result{} (list a 'a)
+
+`(a ,(+ 1 2) ,@@(map abs '(4 -5 6)) b) @result{} (a 3 4 5 6 b)
+
+`((foo ,(- 10 3)) ,@@(cdr '(c)) . ,(car '(cons)))
+ @result{} ((foo 7) . cons)
+
+`#(10 5 ,(sqrt 4) ,@@(map sqrt '(16 9)) 8)
+ @result{} #(10 5 2 4 3 8)
+
+`,(+ 2 3) @result{} 5
+@end group
+@end example
+
+@cindex nesting, of quasiquote expressions
+Quasiquote forms may be nested. Substitutions are made only for
+unquoted components appearing at the same nesting level as the outermost
+backquote. The nesting level increases by one inside each successive
+quasiquotation, and decreases by one inside each unquotation.
+
+@example
+@group
+`(a `(b ,(+ 1 2) ,(foo ,(+ 1 3) d) e) f)
+ @result{} (a `(b ,(+ 1 2) ,(foo 4 d) e) f)
+
+(let ((name1 'x)
+ (name2 'y))
+ `(a `(b ,,name1 ,',name2 d) e))
+ @result{} (a `(b ,x ,'y d) e)
+@end group
+@end example
+
+@cindex backquote, as external representation
+@cindex ` as external representation
+@cindex comma, as external representation
+@cindex , as external representation
+@cindex ,@@ as external representation
+@findex unquote
+@findex unquote-splicing
+@findex `
+@findex ,
+@findex ,@@
+The notations @code{`@var{template}} and (@code{quasiquote
+@var{template}}) are identical in all respects.
+@code{,@var{expression}} is identical to @code{(unquote
+@var{expression})} and @code{,@@@var{expression}} is identical to
+@code{(unquote-splicing @var{expression})}.
+
+@example
+@group
+(quasiquote (list (unquote (+ 1 2)) 4))
+ @result{} (list 3 4)
+
+'(quasiquote (list (unquote (+ 1 2)) 4))
+ @result{} `(list ,(+ 1 2) 4)
+ @emph{i.e.,} (quasiquote (list (unquote (+ 1 2)) 4))
+@end group
+@end example
+
+Unpredictable behavior can result if any of the symbols
+@code{quasiquote}, @code{unquote}, or @code{unquote-splicing} appear in
+a @var{template} in ways otherwise than as described above.
+@end deffn
+
+@node Conditionals, Sequencing, Quoting, Special Forms
+@section Conditionals
+
+@cindex expression, conditional (defn)
+@cindex conditional expression (defn)
+@cindex true, in conditional expression (defn)
+@cindex false, in conditional expression (defn)
+@findex #f
+@findex #t
+The behavior of the @dfn{conditional expressions} is determined by
+whether objects are true or false. The conditional expressions count
+only @code{#f} as false. They count everything else, including
+@code{#t}, pairs, symbols, numbers, strings, vectors, and procedures as
+true (but @pxref{True and False}).
+
+In the descriptions that follow, we say that an object has ``a true
+value'' or ``is true'' when the conditional expressions treat it as
+true, and we say that an object has ``a false value'' or ``is false''
+when the conditional expressions treat it as false.
+
+@deffn {special form} if predicate consequent [alternative]
+@var{Predicate}, @var{consequent}, and @var{alternative} are
+expressions. An @code{if} expression is evaluated as follows: first,
+@var{predicate} is evaluated. If it yields a true value, then
+@var{consequent} is evaluated and its value is returned. Otherwise
+@var{alternative} is evaluated and its value is returned. If
+@var{predicate} yields a false value and no @var{alternative} is
+specified, then the result of the expression is unspecified.
+
+An @code{if} expression evaluates either @var{consequent} or
+@var{alternative}, never both. Programs should not depend on the value
+of an @code{if} expression that has no @var{alternative}.
+
+@example
+@group
+(if (> 3 2) 'yes 'no) @result{} yes
+(if (> 2 3) 'yes 'no) @result{} no
+(if (> 3 2)
+ (- 3 2)
+ (+ 3 2)) @result{} 1
+@end group
+@end example
+@end deffn
+
+@deffn {special form} cond clause clause @dots{}
+@cindex cond clause
+@cindex clause, of cond expression
+Each @var{clause} has this form:
+
+@example
+(@var{predicate} @var{expression} @dots{})
+@end example
+
+@noindent
+@cindex else clause, of cond expression (defn)
+@findex else
+where @var{predicate} is any expression. The last @var{clause} may be
+an @dfn{@code{else} clause}, which has the form:
+
+@example
+(else @var{expression} @var{expression} @dots{})
+@end example
+
+A @code{cond} expression does the following:
+
+@enumerate
+@item
+Evaluates the @var{predicate} expressions of successive @var{clause}s in
+order, until one of the @var{predicate}s evaluates to a true
+value.
+
+@item
+When a @var{predicate} evaluates to a true value, @code{cond} evaluates
+the @var{expression}s in the associated @var{clause} in left to right
+order, and returns the result of evaluating the last @var{expression} in
+the @var{clause} as the result of the entire @code{cond} expression.
+
+If the selected @var{clause} contains only the @var{predicate} and no
+@var{expression}s, @code{cond} returns the value of the @var{predicate}
+as the result.
+
+@item
+If all @var{predicate}s evaluate to false values, and there is no
+@code{else} clause, the result of the conditional expression is
+unspecified; if there is an @code{else} clause, @code{cond} evaluates
+its @var{expression}s (left to right) and returns the value of the last
+one.
+@end enumerate
+
+@example
+@group
+(cond ((> 3 2) 'greater)
+ ((< 3 2) 'less)) @result{} greater
+
+(cond ((> 3 3) 'greater)
+ ((< 3 3) 'less)
+ (else 'equal)) @result{} equal
+@end group
+@end example
+
+Normally, programs should not depend on the value of a @code{cond}
+expression that has no @code{else} clause. However, some Scheme
+programmers prefer to write @code{cond} expressions in which at least
+one of the @var{predicate}s is always true. In this style, the final
+@var{clause} is equivalent to an @code{else} clause.
+
+@cindex => in cond clause
+@findex =>
+Scheme supports an alternative @var{clause} syntax:
+
+@example
+(@var{predicate} => @var{recipient})
+@end example
+
+@noindent
+where @var{recipient} is an expression. If @var{predicate} evaluates to
+a true value, then @var{recipient} is evaluated. Its value must be a
+procedure of one argument; this procedure is then invoked on the value
+of the @var{predicate}.
+
+@example
+@group
+(cond ((assv 'b '((a 1) (b 2))) => cadr)
+ (else #f)) @result{} 2
+@end group
+@end example
+@end deffn
+
+@deffn {special form} case key clause clause @dots{}
+@cindex case clause
+@cindex clause, of case expression
+@var{Key} may be any expression. Each @var{clause} has this
+form:
+
+@example
+((@var{object} @dots{}) @var{expression} @var{expression} @dots{})
+@end example
+
+@cindex else clause, of case expression (defn)
+@findex else
+No @var{object} is evaluated, and all the @var{object}s must be
+distinct. The last @var{clause} may be an @dfn{@code{else} clause},
+which has the form:
+
+@example
+(else @var{expression} @var{expression} @dots{})
+@end example
+
+A @code{case} expression does the following:
+
+@enumerate
+@item
+Evaluates @var{key} and compares the result with each
+@var{object}.
+
+@item
+If the result of evaluating @var{key} is equivalent (in the sense of
+@code{eqv?}; @pxref{Equivalence Predicates}) to an @var{object},
+@code{case} evaluates the @var{expression}s in the corresponding
+@var{clause} from left to right and returns the result of evaluating the
+last @var{expression} in the @var{clause} as the result of the
+@code{case} expression.
+@findex eqv?
+
+@item
+If the result of evaluating @var{key} is different from every
+@var{object}, and if there's an @code{else} clause, @code{case}
+evaluates its @var{expression}s and returns the result of the last one
+as the result of the @code{case} expression. If there's no @code{else}
+clause, @code{case} returns an unspecified result. Programs should not
+depend on the value of a @code{case} expression that has no @code{else}
+clause.
+@end enumerate
+
+For example,
+
+@example
+@group
+(case (* 2 3)
+ ((2 3 5 7) 'prime)
+ ((1 4 6 8 9) 'composite)) @result{} composite
+
+(case (car '(c d))
+ ((a) 'a)
+ ((b) 'b)) @result{} @r{unspecified}
+
+(case (car '(c d))
+ ((a e i o u) 'vowel)
+ ((w y) 'semivowel)
+ (else 'consonant)) @result{} consonant
+@end group
+@end example
+@end deffn
+
+@deffn {special form} and expression @dots{}
+The @var{expression}s are evaluated from left to right, and the value of
+the first @var{expression} that evaluates to a false value is returned.
+Any remaining @var{expression}s are not evaluated. If all the
+@var{expression}s evaluate to true values, the value of the last
+@var{expression} is returned. If there are no @var{expression}s then
+@code{#t} is returned.
+
+@example
+@group
+(and (= 2 2) (> 2 1)) @result{} #t
+(and (= 2 2) (< 2 1)) @result{} #f
+(and 1 2 'c '(f g)) @result{} (f g)
+(and) @result{} #t
+@end group
+@end example
+@end deffn
+
+@deffn {special form} or expression @dots{}
+The @var{expression}s are evaluated from left to right, and the value of
+the first @var{expression} that evaluates to a true value is returned.
+Any remaining @var{expression}s are not evaluated. If all
+@var{expression}s evaluate to false values, the value of the last
+@var{expression} is returned. If there are no @var{expression}s then
+@code{#f} is returned.
+
+@example
+@group
+(or (= 2 2) (> 2 1)) @result{} #t
+(or (= 2 2) (< 2 1)) @result{} #t
+(or #f #f #f) @result{} #f
+(or (memq 'b '(a b c)) (/ 3 0)) @result{} (b c)
+@end group
+@end example
+@end deffn
+
+@node Sequencing, Iteration, Conditionals, Special Forms
+@section Sequencing
+@cindex sequencing expressions
+
+The @code{begin} special form is used to evaluate expressions in a
+particular order.
+
+@deffn {special form} begin expression expression @dots{}
+The @var{expression}s are evaluated sequentially from left to right, and
+the value of the last @var{expression} is returned. This expression
+type is used to sequence side effects such as input and output.
+
+@example
+@group
+(define x 0)
+(begin (set! x 5)
+ (+ x 1)) @result{} 6
+
+(begin (display "4 plus 1 equals ")
+ (display (+ 4 1)))
+ @print{} 4 plus 1 equals 5
+ @result{} @r{unspecified}
+@end group
+@end example
+
+@cindex implicit begin
+Often the use of @code{begin} is unnecessary, because many special forms
+already support sequences of expressions (that is, they have an implicit
+@code{begin}). Some of these special forms are:
+
+@example
+@group
+case
+cond
+define @r{;``procedure @code{define}'' only}
+do
+fluid-let
+lambda
+let
+let*
+letrec
+named-lambda
+@end group
+@end example
+@findex case
+@findex cond
+@findex define
+@findex do
+@findex fluid-let
+@findex lambda
+@findex let
+@findex let*
+@findex letrec
+@findex named-lambda
+
+@findex sequence
+The obsolete special form @code{sequence} is identical to @code{begin}.
+It should not be used in new code.
+@end deffn
+
+@node Iteration, Structure Definitions, Sequencing, Special Forms
+@section Iteration
+
+@cindex expression, iteration (defn)
+@cindex iteration expression (defn)
+@cindex looping (see iteration expressions)
+@cindex tail recursion, vs. iteration expression
+The @dfn{iteration expressions} are: ``named @code{let}'' and @code{do}.
+They are also binding expressions, but are more commonly referred to as
+iteration expressions. Because Scheme is properly tail-recursive, you
+don't need to use these special forms to express iteration; you can
+simply use appropriately written ``recursive'' procedure calls.
+
+@deffn {special form} let name ((@var{variable} @var{init}) @dots{}) expression expression @dots{}
+@cindex named let (defn)
+MIT/GNU Scheme permits a variant on the syntax of @code{let} called
+``named @code{let}'' which provides a more general looping construct
+than @code{do}, and may also be used to express recursions.
+
+Named @code{let} has the same syntax and semantics as ordinary
+@code{let} except that @var{name} is bound within the @var{expression}s
+to a procedure whose formal arguments are the @var{variable}s and whose
+body is the @var{expression}s. Thus the execution of the
+@var{expression}s may be repeated by invoking the procedure named by
+@var{name}.
+
+@cindex unassigned variable, and named let
+MIT/GNU Scheme allows any of the @var{init}s to be omitted, in which
+case the corresponding @var{variable}s are unassigned.
+
+Note: the following expressions are equivalent:
+
+@example
+@group
+(let @var{name} ((@var{variable} @var{init}) @dots{})
+ @var{expression}
+ @var{expression} @dots{})
+
+((letrec ((@var{name}
+ (named-lambda (@var{name} @var{variable} @dots{})
+ @var{expression}
+ @var{expression} @dots{})))
+ @var{name})
+ @var{init} @dots{})
+@end group
+@end example
+
+Here is an example:
+
+@example
+@group
+(let loop
+ ((numbers '(3 -2 1 6 -5))
+ (nonneg '())
+ (neg '()))
+ (cond ((null? numbers)
+ (list nonneg neg))
+ ((>= (car numbers) 0)
+ (loop (cdr numbers)
+ (cons (car numbers) nonneg)
+ neg))
+ (else
+ (loop (cdr numbers)
+ nonneg
+ (cons (car numbers) neg)))))
+
+ @result{} ((6 1 3) (-5 -2))
+@end group
+@end example
+@end deffn
+
+@deffn {special form} do ((@var{variable} @var{init} @var{step}) @dots{}) (@var{test} @var{expression} @dots{}) command @dots{}
+@code{do} is an iteration construct. It specifies a set of variables to
+be bound, how they are to be initialized at the start, and how they are
+to be updated on each iteration. When a termination condition is met,
+the loop exits with a specified result value.
+
+@code{do} expressions are evaluated as follows: The @var{init}
+expressions are evaluated (in some unspecified order), the
+@var{variable}s are bound to fresh locations, the results of the
+@var{init} expressions are stored in the bindings of the
+@var{variable}s, and then the iteration phase begins.
+
+Each iteration begins by evaluating @var{test}; if the result is false,
+then the @var{command} expressions are evaluated in order for effect,
+the @var{step} expressions are evaluated in some unspecified order, the
+@var{variable}s are bound to fresh locations, the results of the
+@var{step}s are stored in the bindings of the @var{variable}s, and the
+next iteration begins.
+
+If @var{test} evaluates to a true value, then the @var{expression}s are
+evaluated from left to right and the value of the last @var{expression}
+is returned as the value of the @code{do} expression. If no
+@var{expression}s are present, then the value of the @code{do}
+expression is unspecified in standard Scheme; in MIT/GNU Scheme, the
+value of @var{test} is returned.
+
+@cindex region of variable binding, do
+@cindex variable binding, do
+The region of the binding of a @var{variable} consists of the entire
+@code{do} expression except for the @var{init}s. It is an error for a
+@var{variable} to appear more than once in the list of @code{do}
+variables.
+
+A @var{step} may be omitted, in which case the effect is the same as if
+@code{(@var{variable} @var{init} @var{variable})} had been written
+instead of @code{(@var{variable} @var{init})}.
+
+@example
+@group
+(do ((vec (make-vector 5))
+ (i 0 (+ i 1)))
+ ((= i 5) vec)
+ (vector-set! vec i i)) @result{} #(0 1 2 3 4)
+@end group
+
+@group
+(let ((x '(1 3 5 7 9)))
+ (do ((x x (cdr x))
+ (sum 0 (+ sum (car x))))
+ ((null? x) sum))) @result{} 25
+@end group
+@end example
+@end deffn
+
+@node Structure Definitions, Macros, Iteration, Special Forms
+@section Structure Definitions
+
+This section provides examples and describes the options and syntax of
+@code{define-structure}, an MIT/GNU Scheme macro that is very similar to
+@code{defstruct} in Common Lisp. The differences between them are
+summarized at the end of this section. For more information, see
+Steele's Common Lisp book.
+
+@deffn {special form} define-structure (name structure-option @dots{}) slot-description @dots{}
+Each @var{slot-description} takes one of the following forms:
+
+@example
+@group
+@var{slot-name}
+(@var{slot-name} @var{default-init} [@var{slot-option} @var{value}]*)
+@end group
+@end example
+
+@cindex keyword constructor
+@cindex BOA constructor
+The fields @var{name} and @var{slot-name} must both be symbols. The
+field @var{default-init} is an expression for the initial value of the
+slot. It is evaluated each time a new instance is constructed. If it
+is not specified, the initial content of the slot is undefined. Default
+values are only useful with a @sc{boa} constructor with argument list or
+a keyword constructor (see below).
+
+Evaluation of a @code{define-structure} expression defines a structure
+descriptor and a set of procedures to manipulate instances of the
+structure. These instances are represented as records by default
+(@pxref{Records}) but may alternately be lists or vectors. The
+accessors and modifiers are marked with compiler declarations so that
+calls to them are automatically transformed into appropriate references.
+Often, no options are required, so a simple call to
+@code{define-structure} looks like:
+
+@example
+(define-structure foo a b c)
+@end example
+
+This defines a type descriptor @code{foo}, a constructor
+@code{make-foo}, a predicate @code{foo?}, accessors @code{foo-a},
+@code{foo-b}, and @code{foo-c}, and modifiers @code{set-foo-a!},
+@code{set-foo-b!}, and @code{set-foo-c!}.
+
+In general, if no options are specified, @code{define-structure} defines
+the following (using the simple call above as an example):
+
+@table @asis
+@item type descriptor
+The name of the type descriptor is the same as the name of the
+structure, e.g.@: @samp{foo}. The type descriptor satisfies the
+predicate @code{record-type?}.
+
+@item constructor
+The name of the constructor is @code{"make-"} followed by the name of
+the structure, e.g.@: @samp{make-foo}. The number of arguments accepted
+by the constructor is the same as the number of slots; the arguments are
+the initial values for the slots, and the order of the arguments matches
+the order of the slot definitions.
+
+@item predicate
+The name of the predicate is the name of the structure followed by
+@code{"?"}, e.g.@: @samp{foo?}. The predicate is a procedure of one
+argument, which returns @code{#t} if its argument is a record of the
+type defined by this structure definition, and @code{#f} otherwise.
+
+@item accessors
+For each slot, an accessor is defined. The name of the accessor is
+formed by appending the name of the structure, a hyphen, and the name of
+the slot, e.g.@: @samp{foo-a}. The accessor is a procedure of one
+argument, which must be a record of the type defined by this structure
+definition. The accessor extracts the contents of the corresponding
+slot in that record and returns it.
+
+@item modifiers
+For each slot, a modifier is defined. The name of the modifier is
+formed by appending @code{"set-"}, the name of the accessor, and
+@code{"!"}, e.g.@: @samp{set-foo-a!}. The modifier is a procedure of
+two arguments, the first of which must be a record of the type defined
+by this structure definition, and the second of which may be any object.
+The modifier modifies the contents of the corresponding slot in that
+record to be that object, and returns an unspecified value.
+@end table
+
+When options are not supplied, @code{(@var{name})} may be abbreviated to
+@var{name}. This convention holds equally for @var{structure-options}
+and @var{slot-options}. Hence, these are equivalent:
+
+@example
+@group
+(define-structure foo a b c)
+(define-structure (foo) (a) b (c))
+@end group
+@end example
+
+@noindent
+as are
+
+@example
+@group
+(define-structure (foo keyword-constructor) a b c)
+(define-structure (foo (keyword-constructor)) a b c)
+@end group
+@end example
+
+When specified as option values, @code{false} and @code{nil} are
+equivalent to @code{#f}, and @code{true} and @code{t} are equivalent to
+@code{#t}.
+@end deffn
+
+Possible @var{slot-options} are:
+
+@deffn {slot option} read-only value
+When given a @var{value} other than @code{#f}, this specifies that no
+modifier should be created for the slot.
+@end deffn
+
+@deffn {slot option} type type-descriptor
+This is accepted but not presently used.
+@end deffn
+
+Possible @var{structure-options} are:
+
+@deffn {structure option} predicate [name]
+This option controls the definition of a predicate procedure for the
+structure. If @var{name} is not given, the predicate is defined with
+the default name (see above). If @var{name} is @code{#f}, the predicate
+is not defined at all. Otherwise, @var{name} must be a symbol, and
+the predicate is defined with that symbol as its name.
+@end deffn
+
+@deffn {structure option} copier [name]
+This option controls the definition of a procedure to copy instances of
+the structure. This is a procedure of one argument, a structure
+instance, that makes a newly allocated copy of the structure and returns
+it. If @var{name} is not given, the copier is defined, and the name
+of the copier is @code{"copy-"} followed by the structure name (e.g.@:
+@samp{copy-foo}). If @var{name} is @code{#f}, the copier is not
+defined. Otherwise, @var{name} must be a symbol, and the copier is
+defined with that symbol as its name.
+@end deffn
+
+@deffn {structure option} print-procedure expression
+Evaluating @var{expression} must yield a procedure of two arguments,
+which is used to print instances of the structure. The procedure is an
+@dfn{unparser method} (@pxref{Custom Output}). If the structure
+instances are records, this option has the same effect as calling
+@code{set-record-type-unparser-method!}.
+@findex set-record-type-unparser-method!
+@end deffn
+
+@deffn {structure option} constructor [name [argument-list]]
+@cindex BOA constructor (defn)
+This option controls the definition of constructor procedures. These
+constructor procedures are called ``@sc{boa} constructors'', for ``By
+Order of Arguments'', because the arguments to the constructor specify
+the initial contents the structure's slots by the order in which they
+are given. This is as opposed to ``keyword constructors'', which
+specify the initial contents using keywords, and in which the order of
+arguments is irrelevant.
+
+If @var{name} is not given, a constructor is defined with the default
+name and arguments (see above). If @var{name} is @code{#f}, no
+constructor is defined; @var{argument-list} may not be specified in this
+case. Otherwise, @var{name} must be a symbol, and a constructor is
+defined with that symbol as its name. If @var{name} is a symbol,
+@var{argument-list} is optionally allowed; if it is omitted, the
+constructor accepts one argument for each slot in the structure
+definition, in the same order in which the slots appear in the
+definition. Otherwise, @var{argument-list} must be a lambda list
+(@pxref{Lambda Expressions}), and each of the parameters of the lambda
+list must be the name of a slot in the structure. The arguments
+accepted by the constructor are defined by this lambda list. Any slot
+that is not specified by the lambda list is initialized to the
+@var{default-init} as specified above; likewise for any slot specified
+as an optional parameter when the corresponding argument is not
+supplied.
+
+If the @code{constructor} option is specified, the default constructor
+is not defined. Additionally, the @code{constructor} option may be
+specified multiple times to define multiple constructors with
+different names and argument lists.
+
+@example
+@group
+(define-structure (foo
+ (constructor make-foo (#!optional a b)))
+ (a 6 read-only #t)
+ (b 9))
+@end group
+@end example
+@end deffn
+
+@deffn {structure option} keyword-constructor [name]
+@cindex keyword constructor (defn)
+This option controls the definition of keyword constructor procedures.
+A @dfn{keyword constructor} is a procedure that accepts arguments that
+are alternating slot names and values. If @var{name} is omitted, a
+keyword constructor is defined, and the name of the constructor is
+@code{"make-"} followed by the name of the structure (e.g.@:
+@samp{make-foo}). Otherwise, @var{name} must be a symbol, and a keyword
+constructor is defined with this symbol as its name.
+
+If the @code{keyword-constructor} option is specified, the default
+constructor is not defined. Additionally, the
+@code{keyword-constructor} option may be specified multiple times to
+define multiple keyword constructors; this is usually not done since
+such constructors would all be equivalent.
+
+@example
+@group
+(define-structure (foo (keyword-constructor make-bar)) a b)
+(foo-a (make-bar 'b 20 'a 19)) @result{} 19
+@end group
+@end example
+@end deffn
+
+@deffn {structure option} type-descriptor name
+This option cannot be used with the @code{type} or @code{named} options.
+
+By default, structures are implemented as records. The name of the
+structure is defined to hold the type descriptor of the record defined
+by the structure. The @code{type-descriptor} option specifies a
+different name to hold the type descriptor.
+
+@example
+@group
+(define-structure foo a b)
+foo @result{} #[record-type 18]
+
+(define-structure (bar (type-descriptor <bar>)) a b)
+bar @error{} Unbound variable: bar
+<bar> @result{} #[record-type 19]
+@end group
+@end example
+@end deffn
+
+@deffn {structure option} conc-name [name]
+By default, the prefix for naming accessors and modifiers is the name of
+the structure followed by a hyphen. The @code{conc-name} option can be
+used to specify an alternative. If @var{name} is not given, the prefix
+is the name of the structure followed by a hyphen (the default). If
+@var{name} is @code{#f}, the slot names are used directly, without
+prefix. Otherwise, @var{name} must a symbol, and that symbol is used as
+the prefix.
+
+@example
+@code{(define-structure (foo (conc-name moby/)) a b)}
+@end example
+
+@noindent
+defines accessors @code{moby/a} and @code{moby/b}, and modifiers
+@code{set-moby/a!} and @code{set-moby/b!}.
+
+@example
+@code{(define-structure (foo (conc-name #f)) a b)}
+@end example
+
+@noindent
+defines accessors @code{a} and @code{b}, and modifiers @code{set-a!} and
+@code{set-b!}.
+@end deffn
+
+@deffn {structure option} type representation-type
+This option cannot be used with the @code{type-descriptor} option.
+
+By default, structures are implemented as records. The @code{type}
+option overrides this default, allowing the programmer to specify that
+the structure be implemented using another data type. The option value
+@var{representation-type} specifies the alternate data type; it is
+allowed to be one of the symbols @code{vector} or @code{list}, and the
+data type used is the one corresponding to the symbol.
+
+If this option is given, and the @code{named} option is not specified,
+the representation will not be tagged, and neither a predicate nor a
+type descriptor will be defined; also, the @code{print-procedure}
+option may not be given.
+
+@example
+@group
+(define-structure (foo (type list)) a b)
+(make-foo 1 2) @result{} (1 2)
+@end group
+@end example
+@end deffn
+
+@deffn {structure option} named [expression]
+This is valid only in conjunction with the @code{type} option and
+specifies that the structure instances be tagged to make them
+identifiable as instances of this structure type. This option cannot be
+used with the @code{type-descriptor} option.
+
+In the usual case, where @var{expression} is not given, the @code{named}
+option causes a type descriptor and predicate to be defined for the
+structure (recall that the @code{type} option without @code{named}
+suppresses their definition), and also defines a default unparser method
+for the structure instances (which can be overridden by the
+@code{print-procedure} option). If the default unparser method is not
+wanted then the @code{print-procedure} option should be specified as
+@code{#F}. This causes the structure to be printed in its native
+representation, as a list or vector, which includes the type descriptor.
+The type descriptor is a unique object, @emph{not} a record type, that
+describes the structure instances and is additionally stored in the
+structure instances to identify them: if the representation type is
+@code{vector}, the type descriptor is stored in the zero-th slot of the
+vector, and if the representation type is @code{list}, it is stored as
+the first element of the list.
+
+
+@example
+@group
+(define-structure (foo (type vector) named) a b c)
+(vector-ref (make-foo 1 2 3) 0) @result{} #[structure-type 52]
+@end group
+@end example
+
+If @var{expression} is specified, it is an expression that is evaluated
+to yield a tag object. The @var{expression} is evaluated once when the
+structure definition is evaluated (to specify the unparser method), and
+again whenever a predicate or constructor is called. Because of this,
+@var{expression} is normally a variable reference or a constant. The
+value yielded by @var{expression} may be any object at all. That object
+is stored in the structure instances in the same place that the type
+descriptor is normally stored, as described above. If @var{expression}
+is specified, no type descriptor is defined, only a predicate.
+
+@example
+@group
+(define-structure (foo (type vector) (named 'foo)) a b c)
+(vector-ref (make-foo 1 2 3) 0) @result{} foo
+@end group
+@end example
+@end deffn
+
+@deffn {structure option} safe-accessors [boolean]
+This option allows the programmer to have some control over the safety
+of the slot accessors (and modifiers) generated by
+@code{define-structure}. If @code{safe-accessors} is not specified, or
+if @var{boolean} is @code{#f}, then the accessors are optimized for
+speed at the expense of safety; when compiled, the accessors will turn
+into very fast inline sequences, usually one to three machine
+instructions in length. However, if @code{safe-accessors} is specified
+and @var{boolean} is either omitted or @code{#t}, then the accessors are
+optimized for safety, will check the type and structure of their
+argument, and will be close-coded.
+
+@example
+@group
+(define-structure (foo safe-accessors) a b c)
+@end group
+@end example
+@end deffn
+
+@deffn {structure option} initial-offset offset
+This is valid only in conjunction with the @code{type} option.
+@var{Offset} must be an exact non-negative integer and specifies the
+number of slots to leave open at the beginning of the structure instance
+before the specified slots are allocated. Specifying an @var{offset} of
+zero is equivalent to omitting the @code{initial-offset} option.
+
+If the @code{named} option is specified, the structure tag appears in
+the first slot, followed by the ``offset'' slots, and then the regular
+slots. Otherwise, the ``offset'' slots come first, followed by the
+regular slots.
+
+@example
+@group
+(define-structure (foo (type vector) (initial-offset 3))
+ a b c)
+(make-foo 1 2 3) @result{} #(() () () 1 2 3)
+@end group
+@end example
+@end deffn
+
+The essential differences between MIT/GNU Scheme's @code{define-structure}
+and Common Lisp's @code{defstruct} are:
+
+@itemize @bullet
+@item
+The default constructor procedure takes positional arguments, in the
+same order as specified in the definition of the structure. A keyword
+constructor may be specified by giving the option
+@code{keyword-constructor}.
+
+@item
+@sc{boa} constructors are described using Scheme lambda lists. Since there
+is nothing corresponding to @code{&aux} in Scheme lambda lists, this
+functionality is not implemented.
+
+@item
+By default, no @code{copier} procedure is defined.
+
+@item
+The side-effect procedure corresponding to the accessor @code{foo} is
+given the name @code{set-foo!}.
+
+@item
+Keywords are ordinary symbols -- use @code{foo} instead of @code{:foo}.
+
+@item
+The option values @code{false}, @code{nil}, @code{true}, and @code{t}
+are treated as if the appropriate boolean constant had been specified
+instead.
+
+@item
+The @code{print-function} option is named @code{print-procedure}. Its
+argument is a procedure of two arguments (the unparser state and the
+structure instance) rather than three as in Common Lisp.
+
+@item
+By default, named structures are tagged with a unique object of some
+kind. In Common Lisp, the structures are tagged with symbols. This
+depends on the Common Lisp package system to help generate unique tags;
+MIT/GNU Scheme has no such way to generate unique symbols.
+
+@item
+The @code{named} option may optionally take an argument, which is
+normally the name of a variable (any expression may be used, but it is
+evaluated whenever the tag name is needed). If used, structure
+instances will be tagged with that variable's value. The variable must
+be defined when @code{define-structure} is evaluated.
+
+@item
+The @code{type} option is restricted to the values @code{vector} and
+@code{list}.
+
+@item
+The @code{include} option is not implemented.
+@end itemize
+
+@node Macros, SRFI syntax, Structure Definitions, Special Forms
+@section Macros
+
+(This section is largely taken from the @cite{Revised^4 Report on the
+Algorithmic Language Scheme}. The section on Syntactic Closures is
+derived from a document written by Chris Hanson. The section on
+Explicit Renaming is derived from a document written by William
+Clinger.)
+
+@cindex macro
+Scheme programs can define and use new derived expression types, called
+@dfn{macros}. Program-defined expression types have the syntax
+
+@example
+(@var{keyword} @var{datum} @dots{})
+@end example
+
+@noindent
+@cindex syntactic keyword
+@cindex keyword
+@cindex macro keyword
+where @var{keyword} is an identifier that uniquely determines the
+expression type. This identifier is called the @dfn{syntactic keyword},
+or simply @dfn{keyword}, of the macro. The number of the @var{datum}s,
+and their syntax, depends on the expression type.
+
+@cindex macro use
+@cindex macro transformer
+Each instance of a macro is called a @dfn{use} of the macro. The set of
+rules that specifies how a use of a macro is transcribed into a more
+primitive expression is called the @dfn{transformer} of the macro.
+
+@cindex anonymous syntactic keyword
+MIT/GNU Scheme also supports @dfn{anonymous syntactic keywords}. This means
+that it's not necessary to bind a macro transformer to a syntactic
+keyword before it is used. Instead, any macro-transformer expression
+can appear as the first element of a form, and the form will be expanded
+by the transformer.
+
+The macro definition facility consists of these parts:
+
+@itemize @bullet
+@item
+A set of expressions used to establish that certain identifiers are
+macro keywords, associate them with macro transformers, and control the
+scope within which a macro is defined.
+
+@item
+A standard high-level pattern language for specifying macro
+transformers, introduced by the @code{syntax-rules} special form.
+
+@item
+Two non-standard low-level languages for specifying macro transformers,
+@dfn{syntactic closures} and @dfn{explicit renaming}.
+@end itemize
+
+@cindex hygienic
+@cindex referentially transparent
+The syntactic keyword of a macro may shadow variable bindings, and local
+variable bindings may shadow keyword bindings. All macros defined using
+the pattern language are ``hygienic'' and ``referentially transparent''
+and thus preserve Scheme's lexical scoping:
+
+@itemize @bullet
+@item
+If a macro transformer inserts a binding for an identifier (variable or
+keyword), the identifier will in effect be renamed throughout its scope
+to avoid conflicts with other identifiers.
+
+@item
+If a macro transformer inserts a free reference to an identifier, the
+reference refers to the binding that was visible where the transformer
+was specified, regardless of any local bindings that may surround the
+use of the macro.
+@end itemize
+
+@menu
+* Syntactic Binding Constructs::
+* Pattern Language::
+* Syntactic Closures::
+* Explicit Renaming::
+@end menu
+
+@node Syntactic Binding Constructs, Pattern Language, Macros, Macros
+@subsection Binding Constructs for Syntactic Keywords
+
+@code{let-syntax}, @code{letrec-syntax}, @code{let*-syntax} and
+@code{define-syntax} are analogous to @code{let}, @code{letrec},
+@code{let*} and @code{define}, but they bind syntactic keywords to macro
+transformers instead of binding variables to locations that contain
+values.
+
+@deffn {special form} let-syntax bindings expression expression @dots{}
+@var{Bindings} should have the form
+
+@example
+((@var{keyword} @var{transformer-spec}) @dots{})
+@end example
+
+@noindent
+Each @var{keyword} is an identifier, each @var{transformer-spec} is a
+a macro-transformer expression, and the body is a sequence of
+one or more expressions. It is an error for a @var{keyword} to appear
+more than once in the list of keywords being bound.
+
+The @var{expression}s are expanded in the syntactic environment obtained
+by extending the syntactic environment of the @code{let-syntax}
+expression with macros whose keywords are the @var{keyword}s, bound to
+the specified transformers. Each binding of a @var{keyword} has the
+@var{expression}s as its region.
+
+@example
+@group
+(let-syntax ((when (syntax-rules ()
+ ((when test stmt1 stmt2 ...)
+ (if test
+ (begin stmt1
+ stmt2 ...))))))
+ (let ((if #t))
+ (when if (set! if 'now))
+ if)) @result{} now
+
+(let ((x 'outer))
+ (let-syntax ((m (syntax-rules () ((m) x))))
+ (let ((x 'inner))
+ (m)))) @result{} outer
+@end group
+@end example
+@end deffn
+
+@deffn {special form} letrec-syntax bindings expression expression @dots{}
+The syntax of @code{letrec-syntax} is the same as for @code{let-syntax}.
+
+The @var{expression}s are expanded in the syntactic environment obtained
+by extending the syntactic environment of the @code{letrec-syntax}
+expression with macros whose keywords are the @var{keyword}s, bound to
+the specified transformers. Each binding of a @var{keyword} has the
+@var{bindings} as well as the @var{expression}s within its region, so
+the transformers can transcribe expressions into uses of the macros
+introduced by the @code{letrec-syntax} expression.
+
+@example
+@group
+(letrec-syntax
+ ((my-or (syntax-rules ()
+ ((my-or) #f)
+ ((my-or e) e)
+ ((my-or e1 e2 ...)
+ (let ((temp e1))
+ (if temp
+ temp
+ (my-or e2 ...)))))))
+ (let ((x #f)
+ (y 7)
+ (temp 8)
+ (let odd?)
+ (if even?))
+ (my-or x
+ (let temp)
+ (if y)
+ y))) @result{} 7
+@end group
+@end example
+@end deffn
+
+@deffn {special form} let*-syntax bindings expression expression @dots{}
+The syntax of @code{let*-syntax} is the same as for @code{let-syntax}.
+
+The @var{expression}s are expanded in the syntactic environment obtained
+by extending the syntactic environment of the @code{letrec-syntax}
+expression with macros whose keywords are the @var{keyword}s, bound to
+the specified transformers. Each binding of a @var{keyword} has the
+subsequent @var{bindings} as well as the @var{expression}s within its
+region. Thus
+
+@example
+@group
+(let*-syntax
+ ((a (syntax-rules @dots{}))
+ (b (syntax-rules @dots{})))
+ @dots{})
+@end group
+@end example
+
+@noindent
+is equivalent to
+
+@example
+@group
+(let-syntax ((a (syntax-rules @dots{})))
+ (let-syntax ((b (syntax-rules @dots{})))
+ @dots{}))
+@end group
+@end example
+@end deffn
+
+@deffn {special form} define-syntax keyword transformer-spec
+@var{Keyword} is an identifier, and @var{transformer-spec} is a macro
+transformer expression. The syntactic environment is extended by
+binding the @var{keyword} to the specified transformer.
+
+The region of the binding introduced by @code{define-syntax} is the
+entire block in which it appears. However, the @var{keyword} may only
+be used after it has been defined.
+
+MIT/GNU Scheme permits @code{define-syntax} to appear both at top level and
+within @code{lambda} bodies. The Revised^4 Report permits only
+top-level uses of @code{define-syntax}.
+
+When compiling a program, a top-level instance of @code{define-syntax}
+both defines the syntactic keyword and generates code that will redefine
+the keyword when the program is loaded. This means that the same syntax
+can be used for defining macros that will be used during compilation
+and for defining macros to be used at run time.
+
+Although macros may expand into definitions and syntax definitions in
+any context that permits them, it is an error for a definition or syntax
+definition to shadow a syntactic keyword whose meaning is needed to
+determine whether some form in the group of forms that contains the
+shadowing definition is in fact a definition, or, for internal definitions,
+is needed to determine the boundary between the group and the expressions
+that follow the group. For example, the following are errors:
+
+@example
+(define define 3)
+
+(begin (define begin list))
+
+(let-syntax
+ ((foo (syntax-rules ()
+ ((foo (proc args ...) body ...)
+ (define proc
+ (lambda (args ...)
+ body ...))))))
+ (let ((x 3))
+ (foo (plus x y) (+ x y))
+ (define foo x)
+ (plus foo x)))
+@end example
+@end deffn
+
+@node Pattern Language, Syntactic Closures, Syntactic Binding Constructs, Macros
+@subsection Pattern Language
+
+MIT/GNU Scheme supports a high-level pattern language for specifying macro
+transformers. This pattern language is defined by the Revised^4 Report
+and is portable to other conforming Scheme implementations. To use the
+pattern language, specify a @var{transformer-spec} as a
+@code{syntax-rules} form:
+
+@deffn {special form} syntax-rules literals syntax-rule @dots{}
+@var{Literals} is a list of identifiers and each @var{syntax-rule}
+should be of the form
+
+@example
+(@var{pattern} @var{template})
+@end example
+
+The @var{pattern} in a @var{syntax-rule} is a list @var{pattern} that
+begins with the keyword for the macro.
+
+A @var{pattern} is either an identifier, a constant, or one of the
+following
+
+@example
+(@var{pattern} @dots{})
+(@var{pattern} @var{pattern} @dots{} . @var{pattern})
+(@var{pattern} @dots{} @var{pattern} @var{ellipsis})
+@end example
+
+@noindent
+and a template is either an identifier, a constant, or one of the
+following
+
+@example
+(@var{element} @dots{})
+(@var{element} @var{element} @dots{} . @var{template})
+@end example
+
+@vindex ...
+where an @var{element} is a @var{template} optionally followed by an
+@var{ellipsis} and an @var{ellipsis} is the identifier @samp{...} (which
+cannot be used as an identifier in either a template or a pattern).
+
+An instance of @code{syntax-rules} produces a new macro transformer by
+specifying a sequence of hygienic rewrite rules. A use of a macro whose
+keyword is associated with a transformer specified by
+@code{syntax-rules} is matched against the patterns contained in the
+@var{syntax-rule}s, beginning with the leftmost @var{syntax-rule}. When
+a match is found, the macro use is transcribed hygienically according to
+the template.
+
+An identifier that appears in the pattern of a @var{syntax-rule} is a
+@dfn{pattern-variable}, unless it is the keyword that begins the
+pattern, is listed in @var{literals}, or is the identifier @samp{...}.
+Pattern variables match arbitrary input elements and are used to refer
+to elements of the input in the template. It is an error for the same
+pattern variable to appear more than once in a @var{pattern}.
+
+The keyword at the beginning of the pattern in a @var{syntax-rule} is
+not involved in the matching and is not considered a pattern variable or
+literal identifier.
+
+Identifiers that appear in @var{literals} are interpreted as literal
+identifiers to be matched against corresponding subforms of the input.
+A subform in the input matches a literal identifier if and only if it is
+an identifier and either both its occurrence in the macro expression and
+its occurrence in the macro definition have the same lexical binding, or
+the two identifiers are equal and both have no lexical binding.
+
+A subpattern followed by @samp{...} can match zero or more elements of
+the input. It is an error for @samp{...} to appear in @var{literals}.
+Within a pattern the identifier @samp{...} must follow the last element
+of a nonempty sequence of subpatterns.
+
+More formally, an input form @var{F} matches a pattern @var{P} if and
+only if:
+
+@itemize @bullet
+@item
+@var{P} is a non-literal identifier; or
+
+@item
+@var{P} is a literal identifier and @var{F} is an identifier with the
+same binding; or
+
+@item
+@var{P} is a list @code{(@var{P_1} @dots{} @var{P_n})} and @var{F} is a
+list of @var{n} forms that match @var{P_1} through @var{P_n},
+respectively; or
+
+@item
+@var{P} is an improper list @code{(@var{P_1} @var{P_2} @dots{} @var{P_n}
+. @var{P_n+1})} and @var{F} is a list or improper list of @var{n} or
+more forms that match @var{P_1} through @var{P_n}, respectively, and
+whose @var{n}th ``cdr'' matches @var{P_n+1}; or
+
+@item
+@var{P} is of the form @code{(@var{P_1} @dots{} @var{P_n} @var{P_n+1}
+@var{ellipsis})} where @var{ellipsis} is the identifier @samp{...} and
+@var{F} is a proper list of at least @var{n} forms, the first @var{n} of
+which match @var{P_1} through @var{P_n}, respectively, and each
+remaining element of @var{F} matches @var{P_n+1}; or
+
+@item
+@var{P} is a datum and @var{F} is equal to @var{P} in the sense of the
+@code{equal?} procedure.
+@end itemize
+
+It is an error to use a macro keyword, within the scope of its
+binding, in an expression that does not match any of the patterns.
+
+When a macro use is transcribed according to the template of the
+matching @var{syntax rule}, pattern variables that occur in the template
+are replaced by the subforms they match in the input. Pattern variables
+that occur in subpatterns followed by one or more instances of the
+identifier @samp{...} are allowed only in subtemplates that are followed
+by as many instances of @samp{...}. They are replaced in the output by
+all of the subforms they match in the input, distributed as indicated.
+It is an error if the output cannot be built up as specified.
+
+Identifiers that appear in the template but are not pattern variables or
+the identifier @samp{...} are inserted into the output as literal
+identifiers. If a literal identifier is inserted as a free identifier
+then it refers to the binding of that identifier within whose scope the
+instance of @code{syntax-rules} appears. If a literal identifier is
+inserted as a bound identifier then it is in effect renamed to prevent
+inadvertent captures of free identifiers.
+
+@example
+@group
+(let ((=> #f))
+ (cond (#t => 'ok))) @result{} ok
+@end group
+@end example
+
+The macro transformer for @code{cond} recognizes @code{=>}
+as a local variable, and hence an expression, and not as the
+top-level identifier @code{=>}, which the macro transformer treats
+as a syntactic keyword. Thus the example expands into
+
+@example
+@group
+(let ((=> #f))
+ (if #t (begin => 'ok)))
+@end group
+@end example
+
+instead of
+
+@example
+@group
+(let ((=> #f))
+ (let ((temp #t))
+ (if temp
+ ('ok temp))))
+@end group
+@end example
+
+which would result in an invalid procedure call.
+@end deffn
+
+@node Syntactic Closures, Explicit Renaming, Pattern Language, Macros
+@subsection Syntactic Closures
+
+@cindex syntactic closures
+MIT/GNU Scheme's syntax-transformation engine is an implementation of
+@dfn{syntactic closures}, a mechanism invented by Alan Bawden and
+Jonathan Rees. The main feature of the syntactic-closures mechanism is
+its simplicity and its close relationship to the environment models
+commonly used with Scheme. Using the mechanism to write macro
+transformers is somewhat cumbersome and can be confusing for the newly
+initiated, but it is easily mastered.
+
+@menu
+* Syntax Terminology::
+* SC Transformer Definition::
+* SC Identifiers::
+@end menu
+
+@node Syntax Terminology, SC Transformer Definition, Syntactic Closures, Syntactic Closures
+@subsubsection Syntax Terminology
+
+This section defines the concepts and data types used by the syntactic
+closures facility.
+
+@itemize @bullet
+@item
+@cindex form
+@dfn{Forms} are the syntactic entities out of which programs are
+recursively constructed. A form is any expression, any definition, any
+syntactic keyword, or any syntactic closure. The variable name that
+appears in a @code{set!} special form is also a form. Examples of
+forms:
+
+@example
+@group
+17
+#t
+car
+(+ x 4)
+(lambda (x) x)
+(define pi 3.14159)
+if
+define
+@end group
+@end example
+
+@item
+@cindex alias
+@cindex identifier
+@cindex synthetic identifier
+An @dfn{alias} is an alternate name for a given symbol. It can appear
+anywhere in a form that the symbol could be used, and when quoted it is
+replaced by the symbol; however, it does not satisfy the predicate
+@code{symbol?}. Macro transformers rarely distinguish symbols from
+aliases, referring to both as @dfn{identifiers}. Another name for an
+alias is @dfn{synthetic identifier}; this document uses both names.
+
+@item
+@cindex syntactic environment
+A @dfn{syntactic environment} maps identifiers to their meanings. More
+precisely, it determines whether an identifier is a syntactic keyword
+or a variable. If it is a keyword, the meaning is an interpretation
+for the form in which that keyword appears. If it is a variable, the
+meaning identifies which binding of that variable is referenced. In
+short, syntactic environments contain all of the contextual information
+necessary for interpreting the meaning of a particular form.
+
+@item
+@cindex syntactic closure
+A @dfn{syntactic closure} consists of a form, a syntactic environment,
+and a list of identifiers. All identifiers in the form take their
+meaning from the syntactic environment, except those in the given list.
+The identifiers in the list are to have their meanings determined
+later.
+
+A syntactic closure may be used in any context in which its form could
+have been used. Since a syntactic closure is also a form, it may not
+be used in contexts where a form would be illegal. For example, a form
+may not appear as a clause in the @code{cond} special form.
+
+A syntactic closure appearing in a quoted structure is replaced by its
+form.
+@end itemize
+
+@node SC Transformer Definition, SC Identifiers, Syntax Terminology, Syntactic Closures
+@subsubsection Transformer Definition
+
+This section describes the special forms for defining syntactic-closures
+macro transformers, and the associated procedures for manipulating
+syntactic closures and syntactic environments.
+
+@deffn {special form} sc-macro-transformer expression
+The @var{expression} is expanded in the syntactic environment of the
+@code{sc-macro-transformer} expression, and the expanded expression is
+evaluated in the transformer environment to yield a macro transformer as
+described below. This macro transformer is bound to a macro keyword by
+the special form in which the @code{transformer} expression appears (for
+example, @code{let-syntax}).
+
+@cindex macro transformer
+@cindex input form
+@cindex usage environment
+@cindex output form
+@cindex transformer environment
+In the syntactic closures facility, a @dfn{macro transformer} is a
+procedure that takes two arguments, a form and a syntactic environment,
+and returns a new form. The first argument, the @dfn{input form}, is
+the form in which the macro keyword occurred. The second argument, the
+@dfn{usage environment}, is the syntactic environment in which the input
+form occurred. The result of the transformer, the @dfn{output form}, is
+automatically closed in the @dfn{transformer environment}, which is the
+syntactic environment in which the @code{transformer} expression
+occurred.
+
+For example, here is a definition of a @code{push} macro using
+@code{syntax-rules}:
+
+@example
+@group
+(define-syntax push
+ (syntax-rules ()
+ ((push item list)
+ (set! list (cons item list)))))
+@end group
+@end example
+
+@noindent
+Here is an equivalent definition using @code{sc-macro-transformer}:
+
+@example
+@group
+(define-syntax push
+ (sc-macro-transformer
+ (lambda (exp env)
+ (let ((item (make-syntactic-closure env '() (cadr exp)))
+ (list (make-syntactic-closure env '() (caddr exp))))
+ `(set! ,list (cons ,item ,list))))))
+@end group
+@end example
+
+@noindent
+In this example, the identifiers @code{set!} and @code{cons} are closed
+in the transformer environment, and thus will not be affected by the
+meanings of those identifiers in the usage environment @code{env}.
+
+Some macros may be non-hygienic by design. For example, the following
+defines a @code{loop} macro that implicitly binds @code{exit} to an
+escape procedure. The binding of @code{exit} is intended to capture
+free references to @code{exit} in the body of the loop, so @code{exit}
+must be left free when the body is closed:
+
+@example
+@group
+(define-syntax loop
+ (sc-macro-transformer
+ (lambda (exp env)
+ (let ((body (cdr exp)))
+ `(call-with-current-continuation
+ (lambda (exit)
+ (let f ()
+ ,@@(map (lambda (exp)
+ (make-syntactic-closure env '(exit)
+ exp))
+ body)
+ (f))))))))
+@end group
+@end example
+@end deffn
+
+@deffn {special form} rsc-macro-transformer expression
+This form is an alternative way to define a syntactic-closures macro
+transformer. Its syntax and usage are identical to
+@code{sc-macro-transformer}, except that the roles of the usage
+environment and transformer environment are reversed. (Hence
+@acronym{RSC} stands for @dfn{Reversed Syntactic Closures}.) In other
+words, the procedure specified by @var{expression} still accepts two
+arguments, but its second argument will be the transformer environment
+rather than the usage environment, and the returned expression is closed
+in the usage environment rather than the transformer environment.
+
+The advantage of this arrangement is that it allows a simpler definition
+style in some situations. For example, here is the @code{push} macro
+from above, rewritten in this style:
+
+@example
+@group
+(define-syntax push
+ (rsc-macro-transformer
+ (lambda (exp env)
+ `(,(make-syntactic-closure env '() 'SET!)
+ ,(caddr exp)
+ (,(make-syntactic-closure env '() 'CONS)
+ ,(cadr exp)
+ ,(caddr exp))))))
+@end group
+@end example
+
+@noindent
+In this style only the introduced keywords are closed, while everything
+else remains open.
+
+Note that @code{rsc-macro-transformer} and @code{sc-macro-transformer}
+are easily interchangeable. Here is how to emulate
+@code{rsc-macro-transformer} using @code{sc-macro-transformer}. (This
+technique can be used to effect the opposite emulation as well.)
+
+@example
+@group
+(define-syntax push
+ (sc-macro-transformer
+ (lambda (exp usage-env)
+ (capture-syntactic-environment
+ (lambda (env)
+ (make-syntactic-closure usage-env '()
+ `(,(make-syntactic-closure env '() 'SET!)
+ ,(caddr exp)
+ (,(make-syntactic-closure env '() 'CONS)
+ ,(cadr exp)
+ ,(caddr exp)))))))))
+@end group
+@end example
+@end deffn
+
+To assign meanings to the identifiers in a form, use
+@code{make-syntactic-closure} to close the form in a syntactic
+environment.
+
+@deffn procedure make-syntactic-closure environment free-names form
+@var{Environment} must be a syntactic environment, @var{free-names}
+must be a list of identifiers, and @var{form} must be a form.
+@code{make-syntactic-closure} constructs and returns a syntactic
+closure of @var{form} in @var{environment}, which can be used anywhere
+that @var{form} could have been used. All the identifiers used in
+@var{form}, except those explicitly excepted by @var{free-names},
+obtain their meanings from @var{environment}.
+
+Here is an example where @var{free-names} is something other than the
+empty list. It is instructive to compare the use of @var{free-names}
+in this example with its use in the @code{loop} example above: the
+examples are similar except for the source of the identifier being left
+free.
+
+@example
+@group
+(define-syntax let1
+ (sc-macro-transformer
+ (lambda (exp env)
+ (let ((id (cadr exp))
+ (init (caddr exp))
+ (exp (cadddr exp)))
+ `((lambda (,id)
+ ,(make-syntactic-closure env (list id) exp))
+ ,(make-syntactic-closure env '() init))))))
+@end group
+@end example
+
+@noindent
+@code{let1} is a simplified version of @code{let} that only binds a
+single identifier, and whose body consists of a single expression.
+When the body expression is syntactically closed in its original
+syntactic environment, the identifier that is to be bound by
+@code{let1} must be left free, so that it can be properly captured by
+the @code{lambda} in the output form.
+@end deffn
+
+In most situations, the @var{free-names} argument to
+@code{make-syntactic-closure} is the empty list. In those cases, the
+more succinct @code{close-syntax} can be used:
+
+@deffn procedure close-syntax form environment
+@var{Environment} must be a syntactic environment and @var{form} must be
+a form. Returns a new syntactic closure of @var{form} in
+@var{environment}, with no free names. Entirely equivalent to
+
+@example
+(make-syntactic-closure @var{environment} '() @var{form})
+@end example
+@end deffn
+
+To obtain a syntactic environment other than the usage environment,
+use @code{capture-syntactic-environment}.
+
+@deffn procedure capture-syntactic-environment procedure
+@code{capture-syntactic-environment} returns a form that will, when
+transformed, call @var{procedure} on the current syntactic environment.
+@var{Procedure} should compute and return a new form to be transformed,
+in that same syntactic environment, in place of the form.
+
+An example will make this clear. Suppose we wanted to define a simple
+@code{loop-until} keyword equivalent to
+
+@example
+@group
+(define-syntax loop-until
+ (syntax-rules ()
+ ((loop-until id init test return step)
+ (letrec ((loop
+ (lambda (id)
+ (if test return (loop step)))))
+ (loop init)))))
+@end group
+@end example
+
+@noindent
+The following attempt at defining @code{loop-until} has a subtle
+bug:
+
+@example
+@group
+(define-syntax loop-until
+ (sc-macro-transformer
+ (lambda (exp env)
+ (let ((id (cadr exp))
+ (init (caddr exp))
+ (test (cadddr exp))
+ (return (cadddr (cdr exp)))
+ (step (cadddr (cddr exp)))
+ (close
+ (lambda (exp free)
+ (make-syntactic-closure env free exp))))
+ `(letrec ((loop
+ (lambda (,id)
+ (if ,(close test (list id))
+ ,(close return (list id))
+ (loop ,(close step (list id)))))))
+ (loop ,(close init '())))))))
+@end group
+@end example
+
+@noindent
+This definition appears to take all of the proper precautions to
+prevent unintended captures. It carefully closes the subexpressions in
+their original syntactic environment and it leaves the @code{id}
+identifier free in the @code{test}, @code{return}, and @code{step}
+expressions, so that it will be captured by the binding introduced by
+the @code{lambda} expression. Unfortunately it uses the identifiers
+@code{if} and @code{loop} @emph{within} that @code{lambda} expression,
+so if the user of @code{loop-until} just happens to use, say, @code{if}
+for the identifier, it will be inadvertently captured.
+
+The syntactic environment that @code{if} and @code{loop} want to be
+exposed to is the one just outside the @code{lambda} expression: before
+the user's identifier is added to the syntactic environment, but after
+the identifier @code{loop} has been added.
+@code{capture-syntactic-environment} captures exactly that environment
+as follows:
+
+@example
+@group
+(define-syntax loop-until
+ (sc-macro-transformer
+ (lambda (exp env)
+ (let ((id (cadr exp))
+ (init (caddr exp))
+ (test (cadddr exp))
+ (return (cadddr (cdr exp)))
+ (step (cadddr (cddr exp)))
+ (close
+ (lambda (exp free)
+ (make-syntactic-closure env free exp))))
+ `(letrec ((loop
+ ,(capture-syntactic-environment
+ (lambda (env)
+ `(lambda (,id)
+ (,(make-syntactic-closure env '() `if)
+ ,(close test (list id))
+ ,(close return (list id))
+ (,(make-syntactic-closure env '() `loop)
+ ,(close step (list id)))))))))
+ (loop ,(close init '())))))))
+@end group
+@end example
+
+@noindent
+In this case, having captured the desired syntactic environment, it is
+convenient to construct syntactic closures of the identifiers @code{if}
+and the @code{loop} and use them in the body of the
+@code{lambda}.
+
+A common use of @code{capture-syntactic-environment} is to get the
+transformer environment of a macro transformer:
+
+@example
+@group
+(sc-macro-transformer
+ (lambda (exp env)
+ (capture-syntactic-environment
+ (lambda (transformer-env)
+ @dots{}))))
+@end group
+@end example
+@end deffn
+
+@node SC Identifiers, , SC Transformer Definition, Syntactic Closures
+@subsubsection Identifiers
+
+This section describes the procedures that create and manipulate
+identifiers. The identifier data type extends the syntactic closures
+facility to be compatible with the high-level @code{syntax-rules}
+facility.
+
+@cindex alias
+As discussed earlier, an identifier is either a symbol or an
+@dfn{alias}. An alias is implemented as a syntactic closure whose
+@var{form} is an identifier:
+
+@example
+@group
+(make-syntactic-closure env '() 'a) @result{} @r{an alias}
+@end group
+@end example
+
+@noindent
+Aliases are implemented as syntactic closures because they behave just
+like syntactic closures most of the time. The difference is that an
+alias may be bound to a new value (for example by @code{lambda} or
+@code{let-syntax}); other syntactic closures may not be used this way.
+If an alias is bound, then within the scope of that binding it is looked
+up in the syntactic environment just like any other identifier.
+
+Aliases are used in the implementation of the high-level facility
+@code{syntax-rules}. A macro transformer created by @code{syntax-rules}
+uses a template to generate its output form, substituting subforms of
+the input form into the template. In a syntactic closures
+implementation, all of the symbols in the template are replaced by
+aliases closed in the transformer environment, while the output form
+itself is closed in the usage environment. This guarantees that the
+macro transformation is hygienic, without requiring the transformer to
+know the syntactic roles of the substituted input subforms.
+
+@deffn procedure identifier? object
+Returns @code{#t} if @var{object} is an identifier, otherwise returns
+@code{#f}. Examples:
+
+@example
+@group
+(identifier? 'a) @result{} #t
+(identifier? (make-syntactic-closure env '() 'a))
+ @result{} #t
+
+(identifier? "a") @result{} #f
+(identifier? #\a) @result{} #f
+(identifier? 97) @result{} #f
+(identifier? #f) @result{} #f
+(identifier? '(a)) @result{} #f
+(identifier? '#(a)) @result{} #f
+@end group
+@end example
+@end deffn
+
+The predicate @code{eq?} is used to determine if two identifers are
+``the same''. Thus @code{eq?} can be used to compare identifiers
+exactly as it would be used to compare symbols. Often, though, it is
+useful to know whether two identifiers ``mean the same thing''. For
+example, the @code{cond} macro uses the symbol @code{else} to identify
+the final clause in the conditional. A macro transformer for
+@code{cond} cannot just look for the symbol @code{else}, because the
+@code{cond} form might be the output of another macro transformer that
+replaced the symbol @code{else} with an alias. Instead the transformer
+must look for an identifier that ``means the same thing'' in the usage
+environment as the symbol @code{else} means in the transformer
+environment.
+
+@deffn procedure identifier=? environment1 identifier1 environment2 identifier2
+@var{Environment1} and @var{environment2} must be syntactic
+environments, and @var{identifier1} and @var{identifier2} must be
+identifiers. @code{identifier=?} returns @code{#t} if the meaning of
+@var{identifier1} in @var{environment1} is the same as that of
+@var{identifier2} in @var{environment2}, otherwise it returns @code{#f}.
+Examples:
+
+@example
+@group
+(let-syntax
+ ((foo
+ (sc-macro-transformer
+ (lambda (form env)
+ (capture-syntactic-environment
+ (lambda (transformer-env)
+ (identifier=? transformer-env 'x env 'x)))))))
+ (list (foo)
+ (let ((x 3))
+ (foo))))
+ @result{} (#t #f)
+@end group
+
+@group
+(let-syntax ((bar foo))
+ (let-syntax
+ ((foo
+ (sc-macro-transformer
+ (lambda (form env)
+ (capture-syntactic-environment
+ (lambda (transformer-env)
+ (identifier=? transformer-env 'foo
+ env (cadr form))))))))
+ (list (foo foo)
+ (foo bar))))
+ @result{} (#f #t)
+@end group
+@end example
+@end deffn
+
+Sometimes it is useful to be able to introduce a new identifier that is
+guaranteed to be different from any existing identifier, similarly to
+the way that @code{generate-uninterned-symbol} is used.
+
+@deffn procedure make-synthetic-identifier identifier
+Creates and returns and new synthetic identifier (alias) that is
+guaranteed to be different from all existing identifiers.
+@var{Identifier} is any existing identifier, which is used in deriving
+the name of the new identifier.
+
+This is implemented by syntactically closing @var{identifier} in a
+special empty environment.
+@end deffn
+
+@node Explicit Renaming, , Syntactic Closures, Macros
+@subsection Explicit Renaming
+
+@cindex explicit renaming
+@dfn{Explicit renaming} is an alternative facility for defining macro
+transformers. In the MIT/GNU Scheme implementation, explicit-renaming
+transformers are implemented as an abstraction layer on top of syntactic
+closures. An explicit-renaming macro transformer is defined by an
+instance of the @code{er-macro-transformer} keyword:
+
+@deffn {special form} er-macro-transformer expression
+The @var{expression} is expanded in the syntactic environment of the
+@code{er-macro-transformer} expression, and the expanded expression is
+evaluated in the transformer environment to yield a macro transformer as
+described below. This macro transformer is bound to a macro keyword by
+the special form in which the @code{transformer} expression appears (for
+example, @code{let-syntax}).
+
+@cindex macro transformer
+@cindex input form, to macro
+In the explicit-renaming facility, a @dfn{macro transformer} is a
+procedure that takes three arguments, a form, a renaming procedure, and
+a comparison predicate, and returns a new form. The first argument, the
+@dfn{input form}, is the form in which the macro keyword occurred.
+
+@cindex renaming procedure
+The second argument to a transformation procedure is a @dfn{renaming
+procedure} that takes the representation of an identifier as its
+argument and returns the representation of a fresh identifier that
+occurs nowhere else in the program. For example, the transformation
+procedure for a simplified version of the @code{let} macro might be
+written as
+
+@example
+@group
+(lambda (exp rename compare)
+ (let ((vars (map car (cadr exp)))
+ (inits (map cadr (cadr exp)))
+ (body (cddr exp)))
+ `((lambda ,vars ,@@body)
+ ,@@inits)))
+@end group
+@end example
+
+@noindent
+This would not be hygienic, however. A hygienic @code{let} macro must
+rename the identifier @code{lambda} to protect it from being captured by
+a local binding. The renaming effectively creates an fresh alias for
+@code{lambda}, one that cannot be captured by any subsequent binding:
+
+@example
+@group
+(lambda (exp rename compare)
+ (let ((vars (map car (cadr exp)))
+ (inits (map cadr (cadr exp)))
+ (body (cddr exp)))
+ `((,(rename 'lambda) ,vars ,@@body)
+ ,@@inits)))
+@end group
+@end example
+
+The expression returned by the transformation procedure will be expanded
+in the syntactic environment obtained from the syntactic environment of
+the macro application by binding any fresh identifiers generated by the
+renaming procedure to the denotations of the original identifiers in the
+syntactic environment in which the macro was defined. This means that a
+renamed identifier will denote the same thing as the original identifier
+unless the transformation procedure that renamed the identifier placed
+an occurrence of it in a binding position.
+
+The renaming procedure acts as a mathematical function in the sense that
+the identifiers obtained from any two calls with the same argument will
+be the same in the sense of @code{eqv?}. It is an error if the renaming
+procedure is called after the transformation procedure has returned.
+
+@cindex comparison predicate
+The third argument to a transformation procedure is a @dfn{comparison
+predicate} that takes the representations of two identifiers as its
+arguments and returns true if and only if they denote the same thing in
+the syntactic environment that will be used to expand the transformed
+macro application. For example, the transformation procedure for a
+simplified version of the @code{cond} macro can be written as
+
+@example
+@group
+(lambda (exp rename compare)
+ (let ((clauses (cdr exp)))
+ (if (null? clauses)
+ `(,(rename 'quote) unspecified)
+ (let* ((first (car clauses))
+ (rest (cdr clauses))
+ (test (car first)))
+ (cond ((and (identifier? test)
+ (compare test (rename 'else)))
+ `(,(rename 'begin) ,@@(cdr first)))
+ (else `(,(rename 'if)
+ ,test
+ (,(rename 'begin) ,@@(cdr first))
+ (cond ,@@rest))))))))))
+@end group
+@end example
+
+@noindent
+In this example the identifier @code{else} is renamed before being passed
+to the comparison predicate, so the comparison will be true if and
+only if the test expression is an identifier that denotes the same
+thing in the syntactic environment of the expression being transformed
+as @code{else} denotes in the syntactic environment in which the @code{cond}
+macro was defined. If @code{else} were not renamed before being passed to
+the comparison predicate, then it would match a local variable that
+happened to be named @code{else}, and the macro would not be hygienic.
+
+Some macros are non-hygienic by design. For example, the following
+defines a @code{loop} macro that implicitly binds @code{exit} to an
+escape procedure. The binding of @code{exit} is intended to capture
+free references to @code{exit} in the body of the loop, so @code{exit}
+is not renamed.
+
+@example
+@group
+(define-syntax loop
+ (er-macro-transformer
+ (lambda (x r c)
+ (let ((body (cdr x)))
+ `(,(r 'call-with-current-continuation)
+ (,(r 'lambda) (exit)
+ (,(r 'let) ,(r 'f) () ,@@body (,(r 'f)))))))))
+@end group
+@end example
+
+Suppose a @code{while} macro is implemented using @code{loop}, with the
+intent that @code{exit} may be used to escape from the @code{while}
+loop. The @code{while} macro cannot be written as
+
+@example
+@group
+(define-syntax while
+ (syntax-rules ()
+ ((while test body ...)
+ (loop (if (not test) (exit #f))
+ body ...))))
+@end group
+@end example
+
+@noindent
+because the reference to @code{exit} that is inserted by the
+@code{while} macro is intended to be captured by the binding of
+@code{exit} that will be inserted by the @code{loop} macro. In other
+words, this @code{while} macro is not hygienic. Like @code{loop}, it
+must be written using the @code{er-macro-transformer} syntax:
+
+@example
+@group
+(define-syntax while
+ (er-macro-transformer
+ (lambda (x r c)
+ (let ((test (cadr x))
+ (body (cddr x)))
+ `(,(r 'loop)
+ (,(r 'if) (,(r 'not) ,test) (exit #f))
+ ,@@body)))))
+@end group
+@end example
+@end deffn
+
+@node SRFI syntax, , Macros, Special Forms
+@section SRFI syntax
+
+@cindex SRFI syntax
+Several special forms have been introduced to support some of the
+@uref{http://srfi.schemers.org/,Scheme Requests for Implementation}
+(@acronym{SRFI}). Note that MIT/GNU Scheme has for some time supported
+@uref{http://srfi.schemers.org/srfi-23/srfi-23.html,@acronym{SRFI} 23}
+(error-reporting mechanism) and
+@uref{http://srfi.schemers.org/srfi-30/srfi-30.html,@acronym{SRFI} 30}
+(nested multi-line comments), since these @acronym{SRFI}s reflect
+existing practice rather than introducing new functionality.
+
+@menu
+* cond-expand (SRFI 0)::
+* receive (SRFI 8)::
+* define-record-type (SRFI 9)::
+@end menu
+
+@node cond-expand (SRFI 0), receive (SRFI 8), SRFI syntax, SRFI syntax
+@subsection cond-expand (SRFI 0)
+
+@cindex SRFI 0
+@uref{http://srfi.schemers.org/srfi-0/srfi-0.html,@acronym{SRFI} 0}
+is a mechanism for portably determining the availability of
+@uref{http://srfi.schemers.org/,@acronym{SRFI}} @dfn{features}.
+The @code{cond-expand} special form conditionally expands according to
+the features available.
+
+@deffn {special form} cond-expand clause clause dots{}
+Each @var{clause} has the form
+
+@example
+(@var{feature-requirement} @var{expression} @dots{})
+@end example
+
+where @var{feature-requirement} can have one of the following forms:
+
+@example
+@group
+@var{feature-identifier}
+(and @var{feature-requirement} @dots{})
+(or @var{feature-requirement} @dots{})
+(not @var{feature-requirement})
+else
+@end group
+@end example
+
+(Note that at most one @code{else} clause may be present, and it must
+always be the last clause.)
+
+The @code{cond-expand} special form tests for the existence of features
+at macro-expansion time. It either expands into the body of one of its
+@var{clause}s or signals an error during syntactic processing.
+@code{cond-expand} expands into the body of the first @var{clause} whose
+@var{feature-requirement} is currently satisfied (an @code{else}
+@var{clause}, if present, is selected if none of the previous
+@var{clauses} is selected).
+
+A @var{feature-requirement} has an obvious interpretation as a logical
+formula, where the @var{feature-identifier} variables have meaning true
+if the feature corresponding to the @var{feature-identifier}, as
+specified in the @acronym{SRFI} registry, is in effect at the location
+of the @code{cond-expand} form, and false otherwise. A
+@var{feature-requirement} is satisfied if its formula is true under this
+interpretation.
+
+@example
+@group
+(cond-expand
+ ((and srfi-1 srfi-10)
+ (write 1))
+ ((or srfi-1 srfi-10)
+ (write 2))
+ (else))
+
+(cond-expand
+ (command-line
+ (define (program-name) (car (argv)))))
+@end group
+@end example
+
+The second example assumes that @code{command-line} is an alias for some
+feature which gives access to command line arguments. Note that an
+error will be signaled at macro-expansion time if this feature is not
+present.
+
+Note that MIT/GNU Scheme allows @code{cond-expand} in any context where a
+special form is allowed. This is an extension of the semantics defined
+by @acronym{SRFI 0}, which only allows @code{cond-expand} at top level.
+@end deffn
+
+@node receive (SRFI 8), define-record-type (SRFI 9), cond-expand (SRFI 0), SRFI syntax
+@subsection receive (SRFI 8)
+
+@cindex SRFI 8
+@uref{http://srfi.schemers.org/srfi-8/srfi-8.html,@acronym{SRFI} 8}
+defines a convenient syntax to bind an identifier to each of the values
+of a multiple-valued expression and then evaluate an expression in the
+scope of the bindings. As an instance of this pattern, consider the
+following excerpt from a @samp{quicksort} procedure:
+
+@example
+@group
+(call-with-values
+ (lambda ()
+ (partition (precedes pivot) others))
+ (lambda (fore aft)
+ (append (qsort fore) (cons pivot (qsort aft)))))
+@end group
+@end example
+
+Here @samp{partition} is a multiple-valued procedure that takes two
+arguments, a predicate and a list, and returns two lists, one comprising
+the list elements that satisfy the predicate, the other those that do
+not. The purpose of the expression shown is to partition the list
+@samp{others}, sort each of the sublists, and recombine the results into
+a sorted list.
+
+For our purposes, the important step is the binding of the identifiers
+@samp{fore} and @samp{aft} to the values returned by @samp{partition}.
+Expressing the construction and use of these bindings with the
+call-by-values primitive is cumbersome: One must explicitly embed the
+expression that provides the values for the bindings in a parameterless
+procedure, and one must explicitly embed the expression to be evaluated
+in the scope of those bindings in another procedure, writing as its
+parameters the identifiers that are to be bound to the values received.
+
+These embeddings are boilerplate, exposing the underlying binding
+mechanism but not revealing anything relevant to the particular program
+in which it occurs. So the use of a syntactic abstraction that exposes
+only the interesting parts -- the identifiers to be bound, the
+multiple-valued expression that supplies the values, and the body of the
+receiving procedure -- makes the code more concise and more readable:
+
+@example
+@group
+(receive (fore aft) (partition (precedes pivot) others)
+ (append (qsort fore) (cons pivot (qsort aft))))
+@end group
+@end example
+
+The advantages are similar to those of a @samp{let} expression over a
+procedure call with a @samp{lambda} expression as its operator. In both
+cases, cleanly separating a ``header'' in which the bindings are
+established from a ``body'' in which they are used makes it easier to
+follow the code.
+
+@deffn {special form} receive formals expression body
+@var{Formals} and @var{body} are defined as for @samp{lambda}
+(@pxref{Lambda Expressions}). Specifically, @var{formals} can have the
+following forms (the use of @samp{#!optional} and @samp{#!rest} is also
+allowed in @var{formals} but is omitted for brevity):
+
+@table @samp
+@item (@var{ident1} @dots{} @var{identN})
+The environment in which the @samp{receive} expression is evaluated is
+extended by binding @var{ident1}, @dots{}, @var{identN} to fresh
+locations. The @var{expression} is evaluated, and its values are stored
+into those locations. (It is an error if @var{expression} does not have
+exactly @var{N} values.)
+
+@item @var{ident}
+The environment in which the @samp{receive} expression is evaluated is
+extended by binding @var{ident} to a fresh location. The
+@var{expression} is evaluated, its values are converted into a newly
+allocated list, and the list is stored in the location bound to
+@var{ident}.
+
+@item (@var{ident1} @dots{} @var{identN} . @var{identN+1})
+The environment in which the @samp{receive} expression is evaluated is
+extended by binding @var{ident1}, @dots{}, @var{identN+1} to fresh
+locations. The @var{expression} is evaluated. Its first @var{N} values
+are stored into the locations bound to @var{ident1} @dots{} @var{identN}.
+Any remaining values are converted into a newly allocated list, which is
+stored into the location bound to @var{identN+1}. (It is an error if
+@var{expression} does not have at least @var{N} values.)
+@end table
+
+In any case, the expressions in @var{body} are evaluated sequentially in
+the extended environment. The results of the last expression in the
+body are the values of the @samp{receive} expression.
+@end deffn
+
+@node define-record-type (SRFI 9), , receive (SRFI 8), SRFI syntax
+@subsection define-record-type (SRFI 9)
+
+@cindex SRFI 9
+The @samp{define-record-type} syntax described in
+@uref{http://srfi.schemers.org/srfi-9/srfi-9.html,@acronym{SRFI} 9} is a
+slight simplification of one written for Scheme 48 by Jonathan Rees.
+Unlike many record-defining special forms, it does not create any new
+identifiers. Instead, the names of the record type, predicate,
+constructor, and so on are all listed explicitly in the source. This
+has the following advantages:
+
+@itemize @bullet
+@item
+It can be defined using a simple macro in Scheme implementations that
+provide a procedural interface for creating record types.
+
+@item
+It does not restrict users to a particular naming convention.
+
+@item
+Tools like @command{grep} and the GNU Emacs tag facility will see the
+defining occurance of each identifier.
+@end itemize
+
+@deffn {special form} define-record-type type-name (constructor-name field-tag @dots{}) predicate-name field-spec @dots{}
+@var{Type-name}, @var{contructor-name}, @var{field-tag}, and
+@var{predicate-name} are identifiers. @var{Field-spec} has one of these
+two forms:
+
+@example
+@group
+(@var{field-tag} @var{accessor-name})
+(@var{field-tag} @var{accessor-name} @var{modifier-name})
+@end group
+@end example
+
+@noindent
+where @var{field-tag}, @var{accessor-name}, and @var{modifier-name} are
+each identifiers.
+
+@code{define-record-type} is generative: each use creates a new record
+type that is distinct from all existing types, including other record
+types and Scheme's predefined types. Record-type definitions may only
+occur at top-level (there are two possible semantics for ``internal''
+record-type definitions, generative and nongenerative, and no consensus
+as to which is better).
+
+An instance of @code{define-record-type} is equivalent to the following
+definitions:
+
+@itemize @bullet
+@item
+@var{Type-name} is bound to a representation of the record type itself.
+Operations on record types, such as defining print methods, reflection,
+etc.@: are left to other SRFIs.
+
+@item
+@var{constructor-name} is bound to a procedure that takes as many
+arguments as there are @var{field-tag}s in the (@var{constructor-name}
+@dots{}) subform and returns a new @var{type-name} record. Fields whose
+tags are listed with @var{constructor-name} have the corresponding
+argument as their initial value. The initial values of all other fields
+are unspecified.
+
+@item
+@var{predicate-name} is a predicate that returns @code{#t} when given a
+value returned by @var{constructor-name} and @code{#f} for everything
+else.
+
+@item
+Each @var{accessor-name} is a procedure that takes a record of type
+@var{type-name} and returns the current value of the corresponding
+field. It is an error to pass an accessor a value which is not a record
+of the appropriate type.
+
+@item
+Each @var{modifier-name} is a procedure that takes a record of type
+@var{type-name} and a value which becomes the new value of the
+corresponding field; an unspecified value is returned. It is an error
+to pass a modifier a first argument which is not a record of the
+appropriate type.
+@end itemize
+
+Assigning the value of any of these identifiers has no effect on the
+behavior of any of their original values.
+@end deffn
+
+The following
+
+@example
+@group
+(define-record-type :pare
+ (kons x y)
+ pare?
+ (x kar set-kar!)
+ (y kdr))
+@end group
+@end example
+
+@noindent
+defines @samp{kons} to be a constructor, @samp{kar} and @samp{kdr} to be
+accessors, @samp{set-kar!} to be a modifier, and @samp{pare?} to be a
+predicate for objects of type @samp{:pare}.
+
+@example
+@group
+(pare? (kons 1 2)) @result{} #t
+(pare? (cons 1 2)) @result{} #f
+(kar (kons 1 2)) @result{} 1
+(kdr (kons 1 2)) @result{} 2
+(let ((k (kons 1 2)))
+ (set-kar! k 3)
+ (kar k)) @result{} 3
+@end group
+@end example
--- /dev/null
+@c This file is part of the MIT/GNU Scheme Reference Manual.
+@c $Id: strings.texi,v 1.1 2003/04/15 03:30:18 cph Exp $
+
+@c Copyright 1991,1992,1993,1994,1995 Massachusetts Institute of Technology
+@c Copyright 1996,1997,1999,2000,2001 Massachusetts Institute of Technology
+@c Copyright 2002,2003 Massachusetts Institute of Technology
+@c See file scheme.texinfo for copying conditions.
+
+@node Strings, Lists, Characters, Top
+@chapter Strings
+
+@cindex string, character (defn)
+@findex char-ascii?
+A @dfn{string} is a mutable sequence of characters. In the current
+implementation of MIT/GNU Scheme, the elements of a string must all
+satisfy the predicate @code{char-ascii?}; if someone ports MIT/GNU
+Scheme to a non-@acronym{ASCII} operating system this requirement will
+change.
+
+@cindex external representation, for string
+@cindex " as external representation
+@cindex double quote, as external representation
+@cindex \ as escape character in string
+@cindex backslash, as escape character in string
+@cindex escape character, for string
+@findex "
+@findex \
+A string is written as a sequence of characters enclosed within double
+quotes @code{" "}. To include a double quote inside a string, precede
+the double quote with a backslash @code{\} (escape it), as in
+
+@example
+"The word \"recursion\" has many meanings."
+@end example
+
+@noindent
+The printed representation of this string is
+
+@example
+The word "recursion" has many meanings.
+@end example
+
+@noindent
+To include a backslash inside a string, precede it with another
+backslash; for example,
+
+@example
+"Use #\\Control-q to quit."
+@end example
+
+@noindent
+The printed representation of this string is
+
+@example
+Use #\Control-q to quit.
+@end example
+
+@findex \t
+@findex \n
+@findex \f
+@findex #\tab
+@findex #\newline
+@findex #\page
+The effect of a backslash that doesn't precede a double quote or
+backslash is unspecified in standard Scheme, but MIT/GNU Scheme specifies
+the effect for three other characters: @code{\t}, @code{\n}, and
+@code{\f}. These escape sequences are respectively translated into the
+following characters: @code{#\tab}, @code{#\newline}, and @code{#\page}.
+Finally, a backslash followed by exactly three octal digits is
+translated into the character whose @acronym{ISO-8859-1} code is those
+digits.
+
+If a string literal is continued from one line to another, the string
+will contain the newline character (@code{#\newline}) at the line break.
+Standard Scheme does not specify what appears in a string literal at a
+line break.
+
+@cindex length, of string (defn)
+@cindex index, of string (defn)
+@cindex valid index, of string (defn)
+@cindex string length (defn)
+@cindex string index (defn)
+The @dfn{length} of a string is the number of characters that it
+contains. This number is an exact non-negative integer that is
+established when the string is created
+(but @pxref{Variable-Length Strings}).
+Each character in a string has an @dfn{index}, which is a
+number that indicates the character's position in the string. The index
+of the first (leftmost) character in a string is 0, and the index of the
+last character is one less than the length of the string. The
+@dfn{valid indexes} of a string are the exact non-negative integers less
+than the length of the string.
+
+@cindex substring (defn)
+@cindex start, of substring (defn)
+@cindex end, of substring (defn)
+A number of the string procedures operate on substrings. A
+@dfn{substring} is a segment of a @var{string}, which is specified by
+two integers @var{start} and @var{end} satisfying these relationships:
+
+@example
+0 <= @var{start} <= @var{end} <= (string-length @var{string})
+@end example
+
+@noindent
+@var{Start} is the index of the first character in the substring, and
+@var{end} is one greater than the index of the last character in the
+substring. Thus if @var{start} and @var{end} are equal, they refer to
+an empty substring, and if @var{start} is zero and @var{end} is the
+length of @var{string}, they refer to all of @var{string}.
+
+@cindex case sensitivity, of string operations
+@cindex -ci, in string procedure name
+Some of the procedures that operate on strings ignore the difference
+between uppercase and lowercase. The versions that ignore case include
+@samp{-ci} (for ``case insensitive'') in their names.
+
+@menu
+* Construction of Strings::
+* Selecting String Components::
+* Comparison of Strings::
+* Alphabetic Case in Strings::
+* Cutting and Pasting Strings::
+* Searching Strings::
+* Matching Strings::
+* Regular Expressions::
+* Modification of Strings::
+* Variable-Length Strings::
+* Byte Vectors::
+@end menu
+
+@node Construction of Strings, Selecting String Components, Strings, Strings
+@section Construction of Strings
+@cindex construction, of string
+
+@deffn {procedure} make-string k [char]
+Returns a newly allocated string of length @var{k}. If you specify
+@var{char}, all elements of the string are initialized to @var{char},
+otherwise the contents of the string are unspecified. @var{Char} must
+satisfy the predicate @code{char-ascii?}.
+
+@example
+(make-string 10 #\x) @result{} "xxxxxxxxxx"
+@end example
+@end deffn
+
+@deffn procedure string char @dots{}
+Returns a newly allocated string consisting of the specified characters.
+The arguments must all satisfy @code{char-ascii?}.
+
+@example
+@group
+(string #\a) @result{} "a"
+(string #\a #\b #\c) @result{} "abc"
+(string #\a #\space #\b #\space #\c) @result{} "a b c"
+(string) @result{} ""
+@end group
+@end example
+@end deffn
+
+@deffn procedure list->string char-list
+@cindex list, converting to string
+@findex string->list
+@var{Char-list} must be a list of @acronym{ISO-8859-1} characters.
+@code{list->string} returns a newly allocated string formed from the
+elements of @var{char-list}. This is equivalent to @code{(apply string
+@var{char-list})}. The inverse of this operation is
+@code{string->list}.
+
+@example
+@group
+(list->string '(#\a #\b)) @result{} "ab"
+(string->list "Hello") @result{} (#\H #\e #\l #\l #\o)
+@end group
+@end example
+@end deffn
+
+@deffn {procedure} string-copy string
+@cindex copying, of string
+Returns a newly allocated copy of @var{string}.
+
+Note regarding variable-length strings: the maximum length of the result
+depends only on the length of @var{string}, not its maximum length. If
+you wish to copy a string and preserve its maximum length, do the
+following:
+
+@example
+@group
+(define (string-copy-preserving-max-length string)
+ (let ((length))
+ (dynamic-wind
+ (lambda ()
+ (set! length (string-length string))
+ (set-string-length! string
+ (string-maximum-length string)))
+ (lambda ()
+ (string-copy string))
+ (lambda ()
+ (set-string-length! string length)))))
+@end group
+@end example
+@end deffn
+
+@node Selecting String Components, Comparison of Strings, Construction of Strings, Strings
+@section Selecting String Components
+@cindex selection, of string component
+@cindex component selection, of string
+
+@deffn procedure string? object
+@cindex type predicate, for string
+Returns @code{#t} if @var{object} is a string; otherwise returns
+@code{#f}.
+
+@example
+@group
+(string? "Hi") @result{} #t
+(string? 'Hi) @result{} #f
+@end group
+@end example
+@end deffn
+
+@deffn procedure string-length string
+Returns the length of @var{string} as an exact non-negative integer.
+
+@example
+@group
+(string-length "") @result{} 0
+(string-length "The length") @result{} 10
+@end group
+@end example
+@end deffn
+
+@deffn procedure string-null? string
+@cindex empty string, predicate for
+@cindex null string, predicate for
+Returns @code{#t} if @var{string} has zero length; otherwise returns
+@code{#f}.
+
+@example
+@group
+(string-null? "") @result{} #t
+(string-null? "Hi") @result{} #f
+@end group
+@end example
+@end deffn
+
+@deffn procedure string-ref string k
+Returns character @var{k} of @var{string}. @var{K} must be a valid index
+of @var{string}.
+
+@example
+@group
+(string-ref "Hello" 1) @result{} #\e
+(string-ref "Hello" 5) @error{} 5 not in correct range
+@end group
+@end example
+@end deffn
+
+@deffn {procedure} string-set! string k char
+Stores @var{char} in element @var{k} of @var{string} and returns an
+unspecified value. @var{K} must be a valid index of @var{string}, and
+@var{char} must satisfy the predicate @code{char-ascii?}.
+
+@example
+@group
+(define str "Dog") @result{} @r{unspecified}
+(string-set! str 0 #\L) @result{} @r{unspecified}
+str @result{} "Log"
+(string-set! str 3 #\t) @error{} 3 not in correct range
+@end group
+@end example
+@end deffn
+
+@need 1000
+@node Comparison of Strings, Alphabetic Case in Strings, Selecting String Components, Strings
+@section Comparison of Strings
+@cindex ordering, of strings
+@cindex comparison, of strings
+
+@deffn procedure string=? string1 string2
+@deffnx procedure substring=? string1 start end string2 start end
+@deffnx {procedure} string-ci=? string1 string2
+@deffnx procedure substring-ci=? string1 start end string2 start end
+@cindex equivalence predicate, for strings
+Returns @code{#t} if the two strings (substrings) are the same length
+and contain the same characters in the same (relative) positions;
+otherwise returns @code{#f}. @code{string-ci=?} and
+@code{substring-ci=?} don't distinguish uppercase and lowercase letters,
+but @code{string=?} and @code{substring=?} do.
+
+@example
+@group
+(string=? "PIE" "PIE") @result{} #t
+(string=? "PIE" "pie") @result{} #f
+(string-ci=? "PIE" "pie") @result{} #t
+(substring=? "Alamo" 1 3 "cola" 2 4) @result{} #t @r{; compares "la"}
+@end group
+@end example
+@end deffn
+
+@deffn procedure string<? string1 string2
+@deffnx procedure substring<? string1 start1 end1 string2 start2 end2
+@deffnx procedure string>? string1 string2
+@deffnx procedure string<=? string1 string2
+@deffnx procedure string>=? string1 string2
+@deffnx {procedure} string-ci<? string1 string2
+@deffnx procedure substring-ci<? string1 start1 end1 string2 start2 end2
+@deffnx {procedure} string-ci>? string1 string2
+@deffnx {procedure} string-ci<=? string1 string2
+@deffnx {procedure} string-ci>=? string1 string2
+These procedures compare strings (substrings) according to the order of
+the characters they contain (also @pxref{Comparison of Characters}).
+The arguments are compared using a lexicographic (or dictionary) order.
+If two strings differ in length but are the same up to the length of the
+shorter string, the shorter string is considered to be less than the
+longer string.
+
+@example
+@group
+(string<? "cat" "dog") @result{} #t
+(string<? "cat" "DOG") @result{} #f
+(string-ci<? "cat" "DOG") @result{} #t
+(string>? "catkin" "cat") @result{} #t @r{; shorter is lesser}
+@end group
+@end example
+@end deffn
+
+@deffn procedure string-compare string1 string2 if-eq if-lt if-gt
+@deffnx procedure string-compare-ci string1 string2 if-eq if-lt if-gt
+@var{If-eq}, @var{if-lt}, and @var{if-gt} are procedures of no arguments
+(thunks). The two strings are compared; if they are equal, @var{if-eq}
+is applied, if @var{string1} is less than @var{string2}, @var{if-lt} is
+applied, else if @var{string1} is greater than @var{string2},
+@var{if-gt} is applied. The value of the procedure is the value of the
+thunk that is applied.
+
+@code{string-compare} distinguishes uppercase and lowercase letters;@*
+@code{string-compare-ci} does not.
+
+@example
+@group
+(define (cheer) (display "Hooray!"))
+(define (boo) (display "Boo-hiss!"))
+(string-compare "a" "b" cheer (lambda() 'ignore) boo)
+ @print{} Hooray!
+ @result{} @r{unspecified}
+@end group
+@end example
+@end deffn
+
+@deffn procedure string-hash string
+@deffnx procedure string-hash-mod string k
+@cindex hashing, of string
+@findex string=?
+@findex =
+@code{string-hash} returns an exact non-negative integer that can be used
+for storing the specified @var{string} in a hash table. Equal strings
+(in the sense of @code{string=?}) return equal (@code{=}) hash codes,
+and non-equal but similar strings are usually mapped to distinct hash
+codes.
+
+@code{string-hash-mod} is like @code{string-hash}, except that it limits
+the result to a particular range based on the exact non-negative integer
+@var{k}. The following are equivalent:
+
+@example
+@group
+(string-hash-mod @var{string} @var{k})
+(modulo (string-hash @var{string}) @var{k})
+@end group
+@end example
+@end deffn
+
+@node Alphabetic Case in Strings, Cutting and Pasting Strings, Comparison of Strings, Strings
+@section Alphabetic Case in Strings
+@cindex alphabetic case, of string
+@cindex case, of string
+@cindex capitalization, of string
+@cindex uppercase, in string
+@cindex lowercase, in string
+
+@deffn procedure string-capitalized? string
+@deffnx procedure substring-capitalized? string start end
+These procedures return @code{#t} if the first word in the string
+(substring) is capitalized, and any subsequent words are either lower
+case or capitalized. Otherwise, they return @code{#f}. A word is
+defined as a non-null contiguous sequence of alphabetic characters,
+delimited by non-alphabetic characters or the limits of the string
+(substring). A word is capitalized if its first letter is upper case
+and all its remaining letters are lower case.
+
+@example
+@group
+(map string-capitalized? '("" "A" "art" "Art" "ART"))
+ @result{} (#f #t #f #t #f)
+@end group
+@end example
+@end deffn
+
+@deffn procedure string-upper-case? string
+@deffnx procedure substring-upper-case? string start end
+@deffnx procedure string-lower-case? string
+@deffnx procedure substring-lower-case? string start end
+These procedures return @code{#t} if all the letters in the string
+(substring) are of the correct case, otherwise they return @code{#f}.
+The string (substring) must contain at least one letter or the
+procedures return @code{#f}.
+
+@example
+@group
+(map string-upper-case? '("" "A" "art" "Art" "ART"))
+ @result{} (#f #t #f #f #t)
+@end group
+@end example
+@end deffn
+
+@deffn procedure string-capitalize string
+@deffnx procedure string-capitalize! string
+@deffnx procedure substring-capitalize! string start end
+@code{string-capitalize} returns a newly allocated copy of @var{string}
+in which the first alphabetic character is uppercase and the remaining
+alphabetic characters are lowercase. For example, @code{"abcDEF"}
+becomes @code{"Abcdef"}. @code{string-capitalize!} is the destructive
+version of @code{string-capitalize}: it alters @var{string} and returns
+an unspecified value. @code{substring-capitalize!} destructively
+capitalizes the specified part of @var{string}.
+@end deffn
+
+@deffn procedure string-downcase string
+@deffnx procedure string-downcase! string
+@deffnx procedure substring-downcase! string start end
+@code{string-downcase} returns a newly allocated copy of @var{string} in
+which all uppercase letters are changed to lowercase.
+@code{string-downcase!} is the destructive version of
+@code{string-downcase}: it alters @var{string} and returns an
+unspecified value. @code{substring-downcase!} destructively changes the
+case of the specified part of @var{string}.
+
+@example
+@group
+(define str "ABCDEFG") @result{} @r{unspecified}
+(substring-downcase! str 3 5) @result{} @r{unspecified}
+str @result{} "ABCdeFG"
+@end group
+@end example
+@end deffn
+
+@deffn procedure string-upcase string
+@deffnx procedure string-upcase! string
+@deffnx procedure substring-upcase! string start end
+@code{string-upcase} returns a newly allocated copy of @var{string} in
+which all lowercase letters are changed to uppercase.
+@code{string-upcase!} is the destructive version of
+@code{string-upcase}: it alters @var{string} and returns an unspecified
+value. @code{substring-upcase!} destructively changes the case of the
+specified part of @var{string}.
+@end deffn
+
+@node Cutting and Pasting Strings, Searching Strings, Alphabetic Case in Strings, Strings
+@section Cutting and Pasting Strings
+@cindex cutting, of string
+@cindex pasting, of strings
+
+@deffn {procedure} string-append string @dots{}
+@cindex appending, of strings
+Returns a newly allocated string made from the concatenation of the given
+strings. With no arguments, @code{string-append} returns the empty
+string (@code{""}).
+
+@example
+@group
+(string-append) @result{} ""
+(string-append "*" "ace" "*") @result{} "*ace*"
+(string-append "" "" "") @result{} ""
+(eq? str (string-append str)) @result{} #f @r{; newly allocated}
+@end group
+@end example
+@end deffn
+
+@deffn procedure substring string start end
+Returns a newly allocated string formed from the characters of
+@var{string} beginning with index @var{start} (inclusive) and ending
+with @var{end} (exclusive).
+
+@example
+@group
+(substring "" 0 0) @result{} ""
+(substring "arduous" 2 5) @result{} "duo"
+(substring "arduous" 2 8) @error{} 8 not in correct range
+
+(define (string-copy s)
+ (substring s 0 (string-length s)))
+@end group
+@end example
+@end deffn
+
+@deffn procedure string-head string end
+Returns a newly allocated copy of the initial substring of @var{string},
+up to but excluding @var{end}. It could have been defined by:
+
+@example
+@group
+(define (string-head string end)
+ (substring string 0 end))
+@end group
+@end example
+@end deffn
+
+@deffn procedure string-tail string start
+Returns a newly allocated copy of the final substring of @var{string},
+starting at index @var{start} and going to the end of @var{string}. It
+could have been defined by:
+
+@example
+@group
+(define (string-tail string start)
+ (substring string start (string-length string)))
+
+(string-tail "uncommon" 2) @result{} "common"
+@end group
+@end example
+@end deffn
+
+@deffn procedure string-pad-left string k [char]
+@deffnx procedure string-pad-right string k [char]
+@cindex padding, of string
+@findex #\space
+These procedures return a newly allocated string created by padding
+@var{string} out to length @var{k}, using @var{char}. If @var{char} is
+not given, it defaults to @code{#\space}. If @var{k} is less than the
+length of @var{string}, the resulting string is a truncated form of
+@var{string}. @code{string-pad-left} adds padding characters or
+truncates from the beginning of the string (lowest indices), while
+@code{string-pad-right} does so at the end of the string (highest
+indices).
+
+@example
+@group
+(string-pad-left "hello" 4) @result{} "ello"
+(string-pad-left "hello" 8) @result{} " hello"
+(string-pad-left "hello" 8 #\*) @result{} "***hello"
+(string-pad-right "hello" 4) @result{} "hell"
+(string-pad-right "hello" 8) @result{} "hello "
+@end group
+@end example
+@end deffn
+
+@deffn procedure string-trim string [char-set]
+@deffnx procedure string-trim-left string [char-set]
+@deffnx procedure string-trim-right string [char-set]
+@cindex trimming, of string
+@findex char-set:whitespace
+Returns a newly allocated string created by removing all characters that
+are not in @var{char-set} from: (@code{string-trim}) both ends of
+@var{string}; (@code{string-trim-left}) the beginning of @var{string};
+or (@code{string-trim-right}) the end of @var{string}. @var{Char-set}
+defaults to @code{char-set:not-whitespace}.
+
+@example
+@group
+(string-trim " in the end ") @result{} "in the end"
+(string-trim " ") @result{} ""
+(string-trim "100th" char-set:numeric) @result{} "100"
+(string-trim-left "-.-+-=-" (char-set #\+))
+ @result{} "+-=-"
+(string-trim "but (+ x y) is" (char-set #\( #\)))
+ @result{} "(+ x y)"
+@end group
+@end example
+@end deffn
+
+@node Searching Strings, Matching Strings, Cutting and Pasting Strings, Strings
+@section Searching Strings
+@cindex searching, of string
+@cindex character, searching string for
+@cindex substring, searching string for
+
+The first few procedures in this section perform @dfn{string search}, in
+which a given string (the @dfn{text}) is searched to see if it contains
+another given string (the @dfn{pattern}) as a proper substring. At
+present these procedures are implemented using a hybrid strategy. For
+short patterns of less than 4 characters, the naive string-search
+algorithm is used. For longer patterns, the Boyer-Moore string-search
+algorithm is used.
+
+@deffn procedure string-search-forward pattern string
+@deffnx procedure substring-search-forward pattern string start end
+@var{Pattern} must be a string. Searches @var{string} for the leftmost
+occurrence of the substring @var{pattern}. If successful, the index of
+the first character of the matched substring is returned; otherwise,
+@code{#f} is returned.
+
+@code{substring-search-forward} limits its search to the specified
+substring of @var{string}; @code{string-search-forward} searches all of
+@var{string}.
+
+@example
+@group
+(string-search-forward "rat" "pirate")
+ @result{} 2
+(string-search-forward "rat" "pirate rating")
+ @result{} 2
+(substring-search-forward "rat" "pirate rating" 4 13)
+ @result{} 7
+(substring-search-forward "rat" "pirate rating" 9 13)
+ @result{} #f
+@end group
+@end example
+@end deffn
+
+@deffn procedure string-search-backward pattern string
+@deffnx procedure substring-search-backward pattern string start end
+@var{Pattern} must be a string. Searches @var{string} for the rightmost
+occurrence of the substring @var{pattern}. If successful, the index to
+the right of the last character of the matched substring is returned;
+otherwise, @code{#f} is returned.
+
+@code{substring-search-backward} limits its search to the specified
+substring of @var{string}; @code{string-search-backward} searches all of
+@var{string}.
+
+@example
+@group
+(string-search-backward "rat" "pirate")
+ @result{} 5
+(string-search-backward "rat" "pirate rating")
+ @result{} 10
+(substring-search-backward "rat" "pirate rating" 1 8)
+ @result{} 5
+(substring-search-backward "rat" "pirate rating" 9 13)
+ @result{} #f
+@end group
+@end example
+@end deffn
+
+@deffn procedure string-search-all pattern string
+@deffnx procedure substring-search-all pattern string start end
+@var{Pattern} must be a string. Searches @var{string} to find all
+occurrences of the substring @var{pattern}. Returns a list of the
+occurrences; each element of the list is an index pointing to the first
+character of an occurrence.
+
+@code{substring-search-all} limits its search to the specified substring
+of @var{string}; @code{string-search-all} searches all of @var{string}.
+
+@example
+@group
+(string-search-all "rat" "pirate")
+ @result{} (2)
+(string-search-all "rat" "pirate rating")
+ @result{} (2 7)
+(substring-search-all "rat" "pirate rating" 4 13)
+ @result{} (7)
+(substring-search-all "rat" "pirate rating" 9 13)
+ @result{} ()
+@end group
+@end example
+@end deffn
+
+@deffn procedure substring? pattern string
+@var{Pattern} must be a string. Searches @var{string} to see if it
+contains the substring @var{pattern}. Returns @code{#t} if
+@var{pattern} is a substring of @var{string}, otherwise returns
+@code{#f}.
+
+@example
+@group
+(substring? "rat" "pirate") @result{} #t
+(substring? "rat" "outrage") @result{} #f
+(substring? "" any-string) @result{} #t
+(if (substring? "moon" text)
+ (process-lunar text)
+ 'no-moon)
+@end group
+@end example
+@end deffn
+
+@deffn procedure string-find-next-char string char
+@deffnx procedure substring-find-next-char string start end char
+@deffnx procedure string-find-next-char-ci string char
+@deffnx procedure substring-find-next-char-ci string start end char
+Returns the index of the first occurrence of @var{char} in the string
+(substring); returns @code{#f} if @var{char} does not appear in the
+string. For the substring procedures, the index returned is relative to
+the entire string, not just the substring. The @code{-ci} procedures
+don't distinguish uppercase and lowercase letters.
+
+@example
+@group
+(string-find-next-char "Adam" #\A) @result{} 0
+(substring-find-next-char "Adam" 1 4 #\A) @result{} #f
+(substring-find-next-char-ci "Adam" 1 4 #\A) @result{} 2
+@end group
+@end example
+@end deffn
+
+@deffn procedure string-find-next-char-in-set string char-set
+@deffnx procedure substring-find-next-char-in-set string start end char-set
+Returns the index of the first character in the string (or substring)
+that is also in @var{char-set}, or returns @code{#f} if none of the
+characters in @var{char-set} occur in @var{string}.
+For the substring procedure, only the substring is searched, but the
+index returned is relative to the entire string, not just the substring.
+
+@example
+@group
+(string-find-next-char-in-set my-string char-set:alphabetic)
+ @result{} @r{start position of the first word in} my-string
+@r{; Can be used as a predicate:}
+(if (string-find-next-char-in-set my-string
+ (char-set #\( #\) ))
+ 'contains-parentheses
+ 'no-parentheses)
+@end group
+@end example
+@end deffn
+
+@deffn procedure string-find-previous-char string char
+@deffnx procedure substring-find-previous-char string start end char
+@deffnx procedure string-find-previous-char-ci string char
+@deffnx procedure substring-find-previous-char-ci string start end char
+Returns the index of the last occurrence of @var{char} in the string
+(substring); returns @code{#f} if @var{char} doesn't appear in the
+string. For the substring procedures, the index returned is relative to
+the entire string, not just the substring. The @code{-ci} procedures
+don't distinguish uppercase and lowercase letters.
+@end deffn
+
+@deffn procedure string-find-previous-char-in-set string char-set
+@deffnx procedure substring-find-previous-char-in-set string start end char-set
+Returns the index of the last character in the string (substring) that
+is also in @var{char-set}. For the substring procedure, the index
+returned is relative to the entire string, not just the substring.
+@end deffn
+
+@node Matching Strings, Regular Expressions, Searching Strings, Strings
+@section Matching Strings
+@cindex matching, of strings
+
+@deffn procedure string-match-forward string1 string2
+@deffnx procedure substring-match-forward string1 start end string2 start end
+@deffnx procedure string-match-forward-ci string1 string2
+@deffnx procedure substring-match-forward-ci string1 start end string2 start end
+Compares the two strings (substrings), starting from the beginning, and
+returns the number of characters that are the same. If the two strings
+(substrings) start differently, returns 0. The @code{-ci} procedures
+don't distinguish uppercase and lowercase letters.
+
+@example
+@group
+(string-match-forward "mirror" "micro") @result{} 2 @r{; matches "mi"}
+(string-match-forward "a" "b") @result{} 0 @r{; no match}
+@end group
+@end example
+@end deffn
+
+@deffn procedure string-match-backward string1 string2
+@deffnx procedure substring-match-backward string1 start end string2 start end
+@deffnx procedure string-match-backward-ci string1 string2
+@deffnx procedure substring-match-backward-ci string1 start end string2 start end
+Compares the two strings (substrings), starting from the end and
+matching toward the front, returning the number of characters that are
+the same. If the two strings (substrings) end differently, returns 0.
+The @code{-ci} procedures don't distinguish uppercase and lowercase
+letters.
+
+@example
+@group
+(string-match-backward-ci "BULBOUS" "fractious")
+ @result{} 3 @r{; matches "ous"}
+@end group
+@end example
+@end deffn
+
+@deffn procedure string-prefix? string1 string2
+@deffnx procedure substring-prefix? string1 start1 end1 string2 start2 end2
+@deffnx procedure string-prefix-ci? string1 string2
+@deffnx procedure substring-prefix-ci? string1 start1 end1 string2 start2 end2
+@cindex prefix, of string
+These procedures return @code{#t} if the first string (substring) forms
+the prefix of the second; otherwise returns @code{#f}. The @code{-ci}
+procedures don't distinguish uppercase and lowercase letters.
+
+@example
+@group
+(string-prefix? "abc" "abcdef") @result{} #t
+(string-prefix? "" any-string) @result{} #t
+@end group
+@end example
+@end deffn
+
+@deffn procedure string-suffix? string1 string2
+@deffnx procedure substring-suffix? string1 start1 end1 string2 start2 end2
+@deffnx procedure string-suffix-ci? string1 string2
+@deffnx procedure substring-suffix-ci? string1 start1 end1 string2 start2 end2
+@cindex suffix, of string
+These procedures return @code{#t} if the first string (substring) forms
+the suffix of the second; otherwise returns @code{#f}. The @code{-ci}
+procedures don't distinguish uppercase and lowercase letters.
+
+@example
+@group
+(string-suffix? "ous" "bulbous") @result{} #t
+(string-suffix? "" any-string) @result{} #t
+@end group
+@end example
+@end deffn
+
+@node Regular Expressions, Modification of Strings, Matching Strings, Strings
+@section Regular Expressions
+
+MIT/GNU Scheme provides support for using regular expressions to search and
+match strings. This manual does not define regular expressions; instead
+see @ref{Regexps, , Syntax of Regular Expressions, emacs, The Emacs
+Editor}.
+
+In addition to providing standard regular-expression support, MIT/GNU
+Scheme also provides the @acronym{REXP} abstraction. This is an
+alternative way to write regular expressions that is easier to read
+and understand than the standard notation. Regular expressions
+written in this notation can be translated into the standard
+notation.
+
+The regular-expression support is a run-time-loadable option. To use
+it, execute
+
+@example
+(load-option 'regular-expression)
+@end example
+
+@noindent
+once before calling any of the procedures defined here.
+
+@menu
+* Regular-expression procedures::
+* REXP abstraction::
+@end menu
+
+@node Regular-expression procedures, REXP abstraction, Regular Expressions, Regular Expressions
+@subsection Regular-expression procedures
+@cindex searching, for regular expression
+@cindex regular expression, searching string for
+
+Procedures that perform regular-expression match and search accept
+standardized arguments. @var{Regexp} is the regular expression; it is a
+string. @var{String} is the string being matched or searched.
+Procedures that operate on substrings also accept @var{start} and
+@var{end} index arguments with the usual meaning. The optional argument
+@var{case-fold?} says whether the match/search is case-sensitive; if
+@var{case-fold?} is @code{#f}, it is case-sensitive, otherwise it is
+case-insensitive. The optional argument @var{syntax-table} is a
+character syntax table that defines the character syntax, such as which
+characters are legal word constituents. This feature is primarily for
+Edwin, so character syntax tables will not be documented here.
+Supplying @code{#f} for (or omitting) @var{syntax-table} will select the
+default character syntax, equivalent to Edwin's @code{fundamental}
+mode.
+
+@deffn procedure re-string-match regexp string [case-fold? [syntax-table]]
+@deffnx procedure re-substring-match regexp string start end [case-fold? [syntax-table]]
+These procedures match @var{regexp} against the respective string or
+substring, returning @code{#f} for no match, or a set of match registers
+(see below) if the match succeeds. Here is an example showing how to
+extract the matched substring:
+
+@example
+@group
+(let ((r (re-substring-match @var{regexp} @var{string} @var{start} @var{end})))
+ (and r
+ (substring @var{string} @var{start} (re-match-end-index 0 r))))
+@end group
+@end example
+@end deffn
+
+@deffn procedure re-string-search-forward regexp string [case-fold? [syntax-table]]
+@deffnx procedure re-substring-search-forward regexp string start end [case-fold? [syntax-table]]
+Searches @var{string} for the leftmost substring matching @var{regexp}.
+Returns a set of match registers (see below) if the search is
+successful, or @code{#f} if it is unsuccessful.
+
+@code{re-substring-search-forward} limits its search to the specified
+substring of @var{string}; @code{re-string-search-forward} searches all
+of @var{string}.
+@end deffn
+
+@deffn procedure re-string-search-backward regexp string [case-fold? [syntax-table]]
+@deffnx procedure re-substring-search-backward regexp string start end [case-fold? [syntax-table]]
+Searches @var{string} for the rightmost substring matching @var{regexp}.
+Returns a set of match registers (see below) if the search is
+successful, or @code{#f} if it is unsuccessful.
+
+@code{re-substring-search-backward} limits its search to the specified
+substring of @var{string}; @code{re-string-search-backward} searches all
+of @var{string}.
+@end deffn
+
+When a successful match or search occurs, the above procedures return a
+set of @dfn{match registers}. The match registers are a set of index
+registers that record indexes into the matched string. Each index
+register corresponds to an instance of the regular-expression grouping
+operator @samp{\(}, and records the start index (inclusive) and end
+index (exclusive) of the matched group. These registers are numbered
+from @code{1} to @code{9}, corresponding left-to-right to the grouping
+operators in the expression. Additionally, register @code{0}
+corresponds to the entire substring matching the regular expression.
+
+@deffn procedure re-match-start-index n registers
+@deffnx procedure re-match-end-index n registers
+@var{N} must be an exact integer between @code{0} and @code{9}
+inclusive. @var{Registers} must be a match-registers object as returned
+by one of the regular-expression match or search procedures above.
+@code{re-match-start-index} returns the start index of the corresponding
+regular-expression register, and @code{re-match-end-index} returns the
+corresponding end index.
+@end deffn
+
+@deffn procedure re-match-extract string registers n
+@var{Registers} must be a match-registers object as returned by one of
+the regular-expression match or search procedures above. @var{String}
+must be the string that was passed as an argument to the procedure that
+returned @var{registers}. @var{N} must be an exact integer between
+@code{0} and @code{9} inclusive. If the matched regular expression
+contained @var{m} grouping operators, then the value of this procedure
+is undefined for @var{n} strictly greater than @var{m}.
+
+This procedure extracts the substring corresponding to the match
+register specified by @var{registers} and @var{n}. This is equivalent
+to the following expression:
+
+@example
+@group
+(substring @var{string}
+ (re-match-start-index @var{n} @var{registers})
+ (re-match-end-index @var{n} @var{registers}))
+@end group
+@end example
+@end deffn
+
+@deffn procedure regexp-group alternative @dots{}
+Each @var{alternative} must be a regular expression. The returned value
+is a new regular expression that consists of the @var{alternative}s
+combined by a grouping operator. For example:
+
+@example
+@group
+(regexp-group "foo" "bar" "baz")
+ @result{} "\\(foo\\|bar\\|baz\\)"
+@end group
+@end example
+@end deffn
+
+@node REXP abstraction, , Regular-expression procedures, Regular Expressions
+@subsection REXP abstraction
+
+@cindex REXP abstraction
+In addition to providing standard regular-expression support, MIT/GNU
+Scheme also provides the @acronym{REXP} abstraction. This is an
+alternative way to write regular expressions that is easier to read
+and understand than the standard notation. Regular expressions
+written in this notation can be translated into the standard notation.
+
+The @acronym{REXP} abstraction is a set of combinators that are
+composed into a complete regular expression. Each combinator directly
+corresponds to a particular piece of regular-expression notation. For
+example, the expression @code{(rexp-any-char)} corresponds to the
+@code{.} character in standard regular-expression notation, while
+@code{(rexp* @var{rexp})} corresponds to the @code{*} character.
+
+The primary advantages of @acronym{REXP} are that it makes the nesting
+structure of regular expressions explicit, and that it simplifies the
+description of complex regular expressions by allowing them to be
+built up using straightforward combinators.
+
+@deffn procedure rexp? object
+Returns @code{#t} if @var{object} is a @acronym{REXP} expression, or
+@code{#f} otherwise. A @acronym{REXP} is one of: a string, which
+represents the pattern matching that string; a character set, which
+represents the pattern matching a character in that set; or an object
+returned by calling one of the procedures defined here.
+@end deffn
+
+@deffn procedure rexp->regexp rexp
+Converts @var{rexp} to standard regular-expression notation, returning
+a newly-allocated string.
+@end deffn
+
+@deffn procedure rexp-compile rexp
+Converts @var{rexp} to standard regular-expression notation, then
+compiles it and returns the compiled result. Equivalent to
+
+@example
+(re-compile-pattern (rexp->regexp @var{rexp}) #f)
+@end example
+@end deffn
+
+@deffn procedure rexp-any-char
+Returns a @acronym{REXP} that matches any single character except a
+newline. This is equivalent to the @code{.} construct.
+@end deffn
+
+@deffn procedure rexp-line-start
+Returns a @acronym{REXP} that matches the start of a line. This is
+equivalent to the @code{^} construct.
+@end deffn
+
+@deffn procedure rexp-line-end
+Returns a @acronym{REXP} that matches the end of a line. This is
+equivalent to the @code{$} construct.
+@end deffn
+
+@deffn procedure rexp-string-start
+Returns a @acronym{REXP} that matches the start of the text being
+matched. This is equivalent to the @code{\`} construct.
+@end deffn
+
+@deffn procedure rexp-string-end
+Returns a @acronym{REXP} that matches the end of the text being
+matched. This is equivalent to the @code{\'} construct.
+@end deffn
+
+@deffn procedure rexp-word-edge
+Returns a @acronym{REXP} that matches the start or end of a word.
+This is equivalent to the @code{\b} construct.
+@end deffn
+
+@deffn procedure rexp-not-word-edge
+Returns a @acronym{REXP} that matches anywhere that is not the start
+or end of a word. This is equivalent to the @code{\B} construct.
+@end deffn
+
+@deffn procedure rexp-word-start
+Returns a @acronym{REXP} that matches the start of a word.
+This is equivalent to the @code{\<} construct.
+@end deffn
+
+@deffn procedure rexp-word-end
+Returns a @acronym{REXP} that matches the end of a word.
+This is equivalent to the @code{\>} construct.
+@end deffn
+
+@deffn procedure rexp-word-char
+Returns a @acronym{REXP} that matches any word-constituent character.
+This is equivalent to the @code{\w} construct.
+@end deffn
+
+@deffn procedure rexp-not-word-char
+Returns a @acronym{REXP} that matches any character that isn't a word
+constituent. This is equivalent to the @code{\W} construct.
+@end deffn
+
+The next two procedures accept a @var{syntax-type} argument specifying
+the syntax class to be matched against. This argument is a symbol
+selected from the following list. Each symbol is followed by the
+equivalent character used in standard regular-expression notation.
+@code{whitespace} (space character),
+@code{punctuation} (@code{.}),
+@code{word} (@code{w}),
+@code{symbol} (@code{_}),
+@code{open} (@code{(}),
+@code{close} (@code{)}),
+@code{quote} (@code{'}),
+@code{string-delimiter} (@code{"}),
+@code{math-delimiter} (@code{$}),
+@code{escape} (@code{\}),
+@code{char-quote} (@code{/}),
+@code{comment-start} (@code{<}),
+@code{comment-end} (@code{>}).
+
+@deffn procedure rexp-syntax-char syntax-type
+Returns a @acronym{REXP} that matches any character of type
+@var{syntax-type}. This is equivalent to the @code{\s} construct.
+@end deffn
+
+@deffn procedure rexp-not-syntax-char syntax-type
+Returns a @acronym{REXP} that matches any character not of type
+@var{syntax-type}. This is equivalent to the @code{\S} construct.
+@end deffn
+
+@deffn procedure rexp-sequence rexp @dots{}
+Returns a @acronym{REXP} that matches each @var{rexp} argument in
+sequence. If no @var{rexp} argument is supplied, the result matches
+the null string. This is equivalent to concatenating the regular
+expressions corresponding to each @var{rexp} argument.
+@end deffn
+
+@deffn procedure rexp-alternatives rexp @dots{}
+Returns a @acronym{REXP} that matches any of the @var{rexp}
+arguments. This is equivalent to concatenating the regular
+expressions corresponding to each @var{rexp} argument, separating them
+by the @code{\|} construct.
+@end deffn
+
+@deffn procedure rexp-group rexp @dots{}
+@code{rexp-group} is like @code{rexp-sequence}, except that the result
+is marked as a match group. This is equivalent to the @code{\(}
+@dots{} @code{\)} construct.
+@end deffn
+
+The next three procedures in principal accept a single @acronym{REXP}
+argument. For convenience, they accept multiple arguments, which are
+converted into a single argument by @code{rexp-group}. Note, however,
+that if only one @acronym{REXP} argument is supplied, and it's very
+simple, no grouping occurs.
+
+@deffn procedure rexp* rexp @dots{}
+Returns a @acronym{REXP} that matches zero or more instances of the
+pattern matched by the @var{rexp} arguments. This is equivalent to
+the @code{*} construct.
+@end deffn
+
+@deffn procedure rexp+ rexp @dots{}
+Returns a @acronym{REXP} that matches one or more instances of the
+pattern matched by the @var{rexp} arguments. This is equivalent to
+the @code{+} construct.
+@end deffn
+
+@deffn procedure rexp-optional rexp @dots{}
+Returns a @acronym{REXP} that matches zero or one instances of the
+pattern matched by the @var{rexp} arguments. This is equivalent to
+the @code{?} construct.
+@end deffn
+
+@deffn procedure rexp-case-fold rexp
+Returns a @acronym{REXP} that matches the same pattern as @var{rexp},
+but is insensitive to character case. This has no equivalent in
+standard regular-expression notation.
+@end deffn
+
+@node Modification of Strings, Variable-Length Strings, Regular Expressions, Strings
+@section Modification of Strings
+@cindex modification, of string
+@cindex replacement, of string component
+@cindex filling, of string
+@cindex moving, of string elements
+
+@deffn procedure string-replace string char1 char2
+@deffnx procedure substring-replace string start end char1 char2
+@deffnx procedure string-replace! string char1 char2
+@deffnx procedure substring-replace! string start end char1 char2
+These procedures replace all occurrences of @var{char1} with @var{char2}
+in the original string (substring). @code{string-replace} and
+@code{substring-replace} return a newly allocated string containing the
+result. @code{string-replace!} and @code{substring-replace!}
+destructively modify @var{string} and return an unspecified value.
+
+@example
+@group
+(define str "a few words") @result{} @r{unspecified}
+(string-replace str #\space #\-) @result{} "a-few-words"
+(substring-replace str 2 9 #\space #\-) @result{} "a few-words"
+str @result{} "a few words"
+(string-replace! str #\space #\-) @result{} @r{unspecified}
+str @result{} "a-few-words"
+@end group
+@end example
+@end deffn
+
+@deffn {procedure} string-fill! string char
+Stores @var{char} in every element of @var{string} and returns an
+unspecified value.
+@end deffn
+
+@deffn procedure substring-fill! string start end char
+Stores @var{char} in elements @var{start} (inclusive) to @var{end}
+(exclusive) of @var{string} and returns an unspecified value.
+
+@example
+@group
+(define s (make-string 10 #\space)) @result{} @r{unspecified}
+(substring-fill! s 2 8 #\*) @result{} @r{unspecified}
+s @result{} " ****** "
+@end group
+@end example
+@end deffn
+
+@deffn procedure substring-move-left! string1 start1 end1 string2 start2
+@deffnx procedure substring-move-right! string1 start1 end1 string2 start2
+@findex eqv?
+Copies the characters from @var{start1} to @var{end1} of @var{string1}
+into @var{string2} at the @var{start2}-th position. The characters are
+copied as follows (note that this is only important when @var{string1}
+and @var{string2} are @code{eqv?}):
+
+@table @code
+@item substring-move-left!
+The copy starts at the left end and moves toward the right (from smaller
+indices to larger). Thus if @var{string1} and @var{string2} are the
+same, this procedure moves the characters toward the left inside the
+string.
+
+@item substring-move-right!
+The copy starts at the right end and moves toward the left (from larger
+indices to smaller). Thus if @var{string1} and @var{string2} are the
+same, this procedure moves the characters toward the right inside the
+string.
+@end table
+
+The following example shows how these procedures can be used to build up
+a string (it would have been easier to use @code{string-append}):
+@example
+@group
+(define answer (make-string 9 #\*)) @result{} @r{unspecified}
+answer @result{} "*********"
+(substring-move-left! "start" 0 5 answer 0) @result{} @r{unspecified}
+answer @result{} "start****"
+(substring-move-left! "-end" 0 4 answer 5) @result{} @r{unspecified}
+answer @result{} "start-end"
+@end group
+@end example
+@end deffn
+
+@deffn procedure reverse-string string
+@deffnx procedure reverse-substring string start end
+@deffnx procedure reverse-string! string
+@deffnx procedure reverse-substring! string start end
+Reverses the order of the characters in the given string or substring.
+@code{reverse-string} and @code{reverse-substring} return newly
+allocated strings; @code{reverse-string!} and @code{reverse-substring!}
+modify their argument strings and return an unspecified value.
+
+@example
+@group
+(reverse-string "foo bar baz") @result{} "zab rab oof"
+(reverse-substring "foo bar baz" 4 7) @result{} "rab"
+(let ((foo "foo bar baz"))
+ (reverse-string! foo)
+ foo) @result{} "zab rab oof"
+(let ((foo "foo bar baz"))
+ (reverse-substring! foo 4 7)
+ foo) @result{} "foo rab baz"
+@end group
+@end example
+@end deffn
+
+@node Variable-Length Strings, Byte Vectors, Modification of Strings, Strings
+@section Variable-Length Strings
+
+@cindex length, of string
+@cindex maximum length, of string (defn)
+MIT/GNU Scheme allows the length of a string to be dynamically adjusted in a
+limited way. When a new string is allocated, by whatever method, it has
+a specific length. At the time of allocation, it is also given a
+@dfn{maximum length}, which is guaranteed to be at least as large as the
+string's length. (Sometimes the maximum length will be slightly larger
+than the length, but it is a bad idea to count on this. Programs should
+assume that the maximum length is the same as the length at the time of
+the string's allocation.) After the string is allocated, the operation
+@code{set-string-length!} can be used to alter the string's length to
+any value between 0 and the string's maximum length, inclusive.
+
+@deffn procedure string-maximum-length string
+Returns the maximum length of @var{string}. The following is
+guaranteed:
+
+@example
+@group
+(<= (string-length string)
+ (string-maximum-length string)) @result{} #t
+@end group
+@end example
+@findex string-length
+
+The maximum length of a string never changes.
+@end deffn
+
+@deffn procedure set-string-length! string k
+Alters the length of @var{string} to be @var{k}, and returns an
+unspecified value. @var{K} must be less than or equal to the maximum
+length of @var{string}. @code{set-string-length!} does not change the
+maximum length of @var{string}.
+@end deffn
+
+@node Byte Vectors, , Variable-Length Strings, Strings
+@section Byte Vectors
+@cindex byte vector
+@cindex vector, byte
+
+@findex string-ref
+MIT/GNU Scheme implements strings as packed vectors of 8-bit
+@acronym{ISO-8859-1} bytes. Most of the string operations, such as
+@code{string-ref}, coerce these 8-bit codes into character objects.
+However, some lower-level operations are made available for use.
+
+@deffn procedure vector-8b-ref string k
+Returns character @var{k} of @var{string} as an @acronym{ISO-8859-1}
+code. @var{K} must be a valid index of @var{string}.
+
+@example
+@group
+(vector-8b-ref "abcde" 2) @result{} 99 @r{;c}
+@end group
+@end example
+@end deffn
+
+@deffn procedure vector-8b-set! string k code
+Stores @var{code} in element @var{k} of @var{string} and returns an
+unspecified value. @var{K} must be a valid index of @var{string}, and
+@var{code} must be a valid @acronym{ISO-8859-1} code.
+@end deffn
+
+@deffn procedure vector-8b-fill! string start end code
+Stores @var{code} in elements @var{start} (inclusive) to @var{end}
+(exclusive) of @var{string} and returns an unspecified value.
+@var{Code} must be a valid @acronym{ISO-8859-1} code.
+@end deffn
+
+@deffn procedure vector-8b-find-next-char string start end code
+@deffnx procedure vector-8b-find-next-char-ci string start end code
+Returns the index of the first occurrence of @var{code} in the given
+substring; returns @code{#f} if @var{code} does not appear. The index
+returned is relative to the entire string, not just the substring.
+@var{Code} must be a valid @acronym{ISO-8859-1} code.
+
+@code{vector-8b-find-next-char-ci} doesn't distinguish uppercase and
+lowercase letters.
+@end deffn
+
+@deffn procedure vector-8b-find-previous-char string start end code
+@deffnx procedure vector-8b-find-previous-char-ci string start end code
+Returns the index of the last occurrence of @var{code} in the given
+substring; returns @code{#f} if @var{code} does not appear. The index
+returned is relative to the entire string, not just the substring.
+@var{Code} must be a valid @acronym{ISO-8859-1} code.
+
+@code{vector-8b-find-previous-char-ci} doesn't distinguish uppercase and
+lowercase letters.
+@end deffn
--- /dev/null
+@c This file is part of the MIT/GNU Scheme Reference Manual.
+@c $Id: vectors.texi,v 1.1 2003/04/15 03:30:22 cph Exp $
+
+@c Copyright 1991,1992,1993,1994,1995 Massachusetts Institute of Technology
+@c Copyright 1996,1997,1999,2000,2001 Massachusetts Institute of Technology
+@c Copyright 2002,2003 Massachusetts Institute of Technology
+@c See file scheme.texinfo for copying conditions.
+
+@node Vectors, Bit Strings, Lists, Top
+@chapter Vectors
+
+@cindex vector (defn)
+@dfn{Vectors} are heterogenous structures whose elements are indexed by
+exact non-negative integers. A vector typically occupies less space
+than a list of the same length, and the average time required to access
+a randomly chosen element is typically less for the vector than for the
+list.
+
+@cindex length, of vector (defn)
+@cindex index, of vector (defn)
+@cindex valid index, of vector (defn)
+@cindex vector length (defn)
+@cindex vector index (defn)
+The @dfn{length} of a vector is the number of elements that it contains.
+This number is an exact non-negative integer that is fixed when the
+vector is created. The @dfn{valid indexes} of a vector are the exact
+non-negative integers less than the length of the vector. The first
+element in a vector is indexed by zero, and the last element is indexed
+by one less than the length of the vector.
+
+@cindex external representation, for vector
+@cindex #( as external representation
+@cindex parenthesis, as external representation
+@findex #(
+Vectors are written using the notation @code{#(@var{object} @dots{})}.
+For example, a vector of length 3 containing the number zero in element
+0, the list @code{(2 2 2 2)} in element 1, and the string @code{"Anna"}
+in element 2 can be written as
+
+@example
+#(0 (2 2 2 2) "Anna")
+@end example
+
+@noindent
+Note that this is the external representation of a vector, not an
+expression evaluating to a vector. Like list constants, vector
+constants must be quoted:
+
+@example
+'#(0 (2 2 2 2) "Anna") @result{} #(0 (2 2 2 2) "Anna")
+@end example
+
+@cindex subvector (defn)
+@cindex start, of subvector (defn)
+@cindex end, of subvector (defn)
+@cindex index, of subvector (defn)
+@cindex valid index, of subvector (defn)
+A number of the vector procedures operate on subvectors. A
+@dfn{subvector} is a segment of a vector that is specified by two exact
+non-negative integers, @var{start} and @var{end}. @var{Start} is the
+index of the first element that is included in the subvector, and
+@var{end} is one greater than the index of the last element that is
+included in the subvector. Thus if @var{start} and @var{end} are the
+same, they refer to a null subvector, and if @var{start} is zero and
+@var{end} is the length of the vector, they refer to the entire vector.
+The @dfn{valid indexes} of a subvector are the exact integers between
+@var{start} inclusive and @var{end} exclusive.
+
+@menu
+* Construction of Vectors::
+* Selecting Vector Components::
+* Cutting Vectors::
+* Modifying Vectors::
+@end menu
+
+@node Construction of Vectors, Selecting Vector Components, Vectors, Vectors
+@section Construction of Vectors
+@cindex construction, of vector
+
+@deffn {procedure} make-vector k [object]
+Returns a newly allocated vector of @var{k} elements. If @var{object}
+is specified, @code{make-vector} initializes each element of the vector
+to @var{object}. Otherwise the initial elements of the result are
+unspecified.
+@end deffn
+
+@deffn procedure vector object @dots{}
+@findex list
+Returns a newly allocated vector whose elements are the given arguments.
+@code{vector} is analogous to @code{list}.
+
+@example
+(vector 'a 'b 'c) @result{} #(a b c)
+@end example
+@end deffn
+
+@deffn procedure vector-copy vector
+@cindex copying, of vector
+Returns a newly allocated vector that is a copy of @var{vector}.
+@end deffn
+
+@deffn procedure list->vector list
+@cindex list, converting to vector
+@findex vector->list
+Returns a newly allocated vector initialized to the elements of
+@var{list}. The inverse of @code{list->vector} is @code{vector->list}.
+
+@example
+(list->vector '(dididit dah)) @result{} #(dididit dah)
+@end example
+@end deffn
+
+@deffn procedure make-initialized-vector k initialization
+Similar to @code{make-vector}, except that the elements of the result
+are determined by calling the procedure @var{initialization} on the
+indices. For example:
+
+@example
+@group
+(make-initialized-vector 5 (lambda (x) (* x x)))
+ @result{} #(0 1 4 9 16)
+@end group
+@end example
+@end deffn
+
+@deffn procedure vector-grow vector k
+@cindex growing, of vector
+@var{K} must be greater than or equal to the length of @var{vector}.
+Returns a newly allocated vector of length @var{k}. The first
+@code{(vector-length @var{vector})} elements of the result are
+initialized from the corresponding elements of @var{vector}. The
+remaining elements of the result are unspecified.
+@end deffn
+
+@deffn procedure vector-map procedure vector
+@cindex mapping, of vector
+@var{Procedure} must be a procedure of one argument. @code{vector-map}
+applies @var{procedure} element-wise to the elements of @var{vector} and
+returns a newly allocated vector of the results, in order from left to
+right. The dynamic order in which @var{procedure} is applied to the
+elements of @var{vector} is unspecified.
+
+@example
+@group
+(vector-map cadr '#((a b) (d e) (g h))) @result{} #(b e h)
+(vector-map (lambda (n) (expt n n)) '#(1 2 3 4))
+ @result{} #(1 4 27 256)
+(vector-map + '#(5 7 9)) @result{} #(5 7 9)
+@end group
+@end example
+@end deffn
+
+@node Selecting Vector Components, Cutting Vectors, Construction of Vectors, Vectors
+@section Selecting Vector Components
+@cindex selection, of vector component
+@cindex component selection, of vector
+
+@deffn procedure vector? object
+@cindex type predicate, for vector
+Returns @code{#t} if @var{object} is a vector; otherwise returns
+@code{#f}.
+@end deffn
+
+@deffn procedure vector-length vector
+Returns the number of elements in @var{vector}.
+@end deffn
+
+@deffn procedure vector-ref vector k
+Returns the contents of element @var{k} of @var{vector}. @var{K} must
+be a valid index of @var{vector}.
+
+@example
+(vector-ref '#(1 1 2 3 5 8 13 21) 5) @result{} 8
+@end example
+@end deffn
+
+@deffn procedure vector-set! vector k object
+Stores @var{object} in element @var{k} of @var{vector} and returns an
+unspecified value. @var{K} must be a valid index of
+@var{vector}.
+
+@example
+@group
+(let ((vec (vector 0 '(2 2 2 2) "Anna")))
+ (vector-set! vec 1 '("Sue" "Sue"))
+ vec)
+ @result{} #(0 ("Sue" "Sue") "Anna")
+@end group
+@end example
+@end deffn
+
+@deffn procedure vector-first vector
+@deffnx procedure vector-second vector
+@deffnx procedure vector-third vector
+@deffnx procedure vector-fourth vector
+@deffnx procedure vector-fifth vector
+@deffnx procedure vector-sixth vector
+@deffnx procedure vector-seventh vector
+@deffnx procedure vector-eighth vector
+These procedures access the first several elements of @var{vector} in
+the obvious way. It is an error if the implicit index of one of these
+procedurs is not a valid index of @var{vector}.
+@end deffn
+
+@deffn procedure vector-binary-search vector key<? unwrap-key key
+@cindex searching, of vector
+Searches @var{vector} for an element with a key matching @var{key},
+returning the element if one is found or @code{#f} if none. The
+search operation takes time proportional to the logarithm of the length
+of @var{vector}. @var{Unwrap-key} must be a procedure that maps each
+element of @var{vector} to a key. @var{Key<?} must be a procedure that
+implements a total ordering on the keys of the elements.
+
+@example
+@group
+(define (translate number)
+ (vector-binary-search '#((1 . i)
+ (2 . ii)
+ (3 . iii)
+ (6 . vi))
+ < car number))
+(translate 2) @result{} (2 . ii)
+(translate 4) @result{} #F
+@end group
+@end example
+@end deffn
+
+@node Cutting Vectors, Modifying Vectors, Selecting Vector Components, Vectors
+@section Cutting Vectors
+@cindex cutting, of vector
+
+@deffn procedure subvector vector start end
+Returns a newly allocated vector that contains the elements of
+@var{vector} between index @var{start} (inclusive) and @var{end}
+(exclusive).
+@end deffn
+
+@deffn procedure vector-head vector end
+Equivalent to
+
+@example
+(subvector @var{vector} 0 @var{end})
+@end example
+@end deffn
+
+@deffn procedure vector-tail vector start
+Equivalent to
+
+@example
+(subvector @var{vector} @var{start} (vector-length @var{vector}))
+@end example
+@end deffn
+
+@node Modifying Vectors, , Cutting Vectors, Vectors
+@section Modifying Vectors
+@cindex modification, of vector
+@cindex filling, of vector
+@cindex moving, of vector elements
+
+@deffn {procedure} vector-fill! vector object
+@deffnx procedure subvector-fill! vector start end object
+Stores @var{object} in every element of the vector (subvector) and
+returns an unspecified value.
+@end deffn
+
+@deffn procedure subvector-move-left! vector1 start1 end1 vector2 start2
+@deffnx procedure subvector-move-right! vector1 start1 end1 vector2 start2
+Destructively copies the elements of @var{vector1}, starting with index
+@var{start1} (inclusive) and ending with @var{end1} (exclusive), into
+@var{vector2} starting at index @var{start2} (inclusive).
+@var{Vector1}, @var{start1}, and @var{end1} must specify a valid
+subvector, and @var{start2} must be a valid index for @var{vector2}.
+The length of the source subvector must not exceed the length of
+@var{vector2} minus the index @var{start2}.
+
+The elements are copied as follows (note that this is only important when
+@var{vector1} and @var{vector2} are @code{eqv?}):
+
+@table @code
+@item subvector-move-left!
+The copy starts at the left end and moves toward the right (from smaller
+indices to larger). Thus if @var{vector1} and @var{vector2} are the
+same, this procedure moves the elements toward the left inside the
+vector.
+
+@item subvector-move-right!
+The copy starts at the right end and moves toward the left (from larger
+indices to smaller). Thus if @var{vector1} and @var{vector2} are the
+same, this procedure moves the elements toward the right inside the
+vector.
+@end table
+@end deffn
+
+@deffn procedure sort! vector procedure
+@deffnx procedure merge-sort! vector procedure
+@deffnx procedure quick-sort! vector procedure
+@var{Procedure} must be a procedure of two arguments that defines a
+@dfn{total ordering} on the elements of @var{vector}. The elements of
+@var{vector} are rearranged so that they are sorted in the order defined
+by @var{procedure}. The elements are rearranged in place, that is,
+@var{vector} is destructively modified so that its elements are in the
+new order.
+
+@code{sort!} returns @var{vector} as its value.
+
+Two sorting algorithms are implemented: @code{merge-sort!} and
+@code{quick-sort!}. The procedure @code{sort!} is an alias for
+@code{merge-sort!}.
+
+See also the definition of @code{sort}.
+@end deffn
--- /dev/null
+@c This file is part of the MIT/GNU Scheme Reference Manual.
+@c $Id: win32-packaging.texi,v 1.1 2003/04/15 03:30:25 cph Exp $
+
+@c Copyright 1991,1992,1993,1994,1995 Massachusetts Institute of Technology
+@c Copyright 1996,1997,1999,2000,2001 Massachusetts Institute of Technology
+@c Copyright 2002,2003 Massachusetts Institute of Technology
+@c See file scheme.texinfo for copying conditions.
+
+@node Win32 Package Reference, GNU Free Documentation License, Graphics, Top
+@chapter Win32 Package Reference
+
+@ifinfo
+The Win32 implementation is still in a state of development. It is
+expected that changes will be necessary when MIT/GNU Scheme is ported to
+Windows NT on the DEC Alpha architecture. In particular, the
+current system is not arranged in a way that adequately distinguishes
+between issues that are a consequence of the NT operating system and
+those which are a consequence of the Intel x86 architecture.
+@end ifinfo
+
+@menu
+* Win32 Package Overview::
+* Foreign function interface::
+* Device Independent Bitmap Utilities::
+@end menu
+
+
+@node Win32 Package Overview, Foreign function interface, Win32 Package Reference, Win32 Package Reference
+@section Overview
+
+
+The Win32 implementation is still in a state of development. It is
+expected that changes will be necessary when MIT/GNU Scheme is ported to
+Windows NT on the DEC Alpha architecture. In particular, the
+current system is not arranged in a way that adequately distinguishes
+between issues that are a consequence of the NT operating system and
+those which are a consequence of the Intel x86 architecture.
+@cindex limitations
+
+Thus this documentation is not definitive, it merely outlines how the
+current system works. Parts of the system will change and any project
+implemented using the win32 system must plan for a re-implementation
+stage.
+
+
+The Win32 implementation has several components:
+
+@itemize @bullet
+
+@item
+Special microcode primitives.
+
+@item
+A foreign function interface (FFI) for calling procedures in dynamically
+linked libraries (DLLs).
+
+@item
+An interface for Edwin.
+
+@item
+The Win32 package provides support for using the features of the
+Windows 3.1 and Windows NT 3.1 environments.
+
+@item
+Device Independent Bitmap utilities. These are used by the win32 Scheme
+Graphics implementation. (The Scheme Graphics implementation is
+described in the Reference Manual).
+
+@end itemize
+
+Note that all the names in the Win32 support are part of the
+@code{win32} package. The names are bound in the @code{(win32)}
+environment, and do not appear as bindings in the user or root
+environments.
+An effect of this is that it is far easier to develop Win32 software in
+the @code{(win32)} package environment or a child environment.
+
+@node Foreign function interface, Device Independent Bitmap Utilities, Win32 Package Overview, Win32 Package Reference
+@section Foreign Function Interface
+
+The Win32 foreign function interface (FFI) is a primitive and fairly
+simple system for calling procedures written in C in a
+dynamically linked library (DLL). Both user's procedures from a custom
+DLL and system procedures (e.g.@: MessageBox) are called using the same
+mechanism.
+
+@cindex limitations
+@strong{Warning}: The FFI as it stands has several flaws which make it
+difficult to use reliably. It is expected that both the interface to
+and the mechanisms used by the FFI will be changed in the future. We
+provide it, and this documentation, only to give people an early start
+in accessing some of the features of Win32 from Scheme. Should you use
+it in an experiment we welcome any feedback.
+
+The FFI is designed for calling C procedures that use C data types
+rather than Scheme data objects. Thus it is not possible to write and
+call a C procedure that returns, for example, a Scheme list. The object
+returned will always be an integer (which may represent the address of a
+C data structure).
+
+@cindex warning
+@strong{Warning}: It is extremely dangerous to try to pass Scheme
+callback procedures to C procedures. It is only possible by passing
+integer `handles' rather than the actual procedures, and even so, if a
+garbage collection occurs during the execution of the callback procedure
+objects in Scheme's heap will have moved. Thus in a foreign procedure
+that has a callback and a string, after calling the callback the string
+value may no longer be valid. Playing this game requires a profound
+knowledge of the implementation.
+
+
+The interface to the FFI has two main components: a language for
+declaring the types of values passed to and returned from the foreign
+procedures and a form for declaring foreign procedures.
+
+@menu
+* Windows Types::
+* Windows Foreign Procedures::
+* Win32 API names and procedures::
+@end menu
+
+@node Windows Types, Windows Foreign Procedures, Foreign function interface, Foreign function interface
+@subsection Windows Types
+
+@cindex Windows types
+@cindex foreign type declarations
+@cindex types, Windows
+@cindex defining foreign types
+Foreign types are designed to represent a correspondence between a
+Scheme data type that is used to represent an object within the Scheme
+world and a C data type that represents the data object in the C world.
+Thus we cannot manipulate true C objects in Scheme, nor can we
+manipulate Scheme objects in C.
+
+Each foreign type has four aspects that together ensure that the
+correspondence between the Scheme and C objects is maintained. These
+aspects are all encoded as procedures that either check for validity or
+convert between representations. Thus a foreign type is not a
+declarative type so much as a procedural description of how to pass the
+type. The underlying foreign procedure call mechanism can pass integers
+and vector-like Scheme objects, and returns integer values. All other
+objects must be translated into integers or some other basic type, and
+must be recovered from integers.
+
+The aspects are:
+
+@table @var
+
+@item check
+A predicate that returns @code{#t} if the argument is of an acceptable
+Scheme type, otherwise returns @code{#f}.
+The @var{check} procedure is used for type-checking.
+
+@item convert
+A procedure of one argument which returns a Scheme object of one of the
+basic types.
+It is used to convert an object into a `simpler' object that will
+eventually be converted into a C object.
+The legal simpler objects are integers and strings.
+
+@item return-convert
+A procedure of one argument that, given an integer, returns a Scheme
+object of a type satisfying @var{check}.
+Its purpose is to convert the result returned by the foreign procedure
+into a Scheme value.
+
+@item revert
+Some C procedures modify one or more of their arguments. These
+arguments are passed by reference, i.e.@: as a pointer to their address.
+Since a Scheme object might have a different memory layout and storage
+conventions, it must be passed by copy-in and copy-out rather than by
+reference.
+@var{Revert} is a procedure of two parameters, the original object
+passed and the result of @var{convert} on that object.
+@var{Revert} may then inspect the converted object and copy back the
+changes to the original.
+
+@end table
+
+@deffn {special form} define-windows-type name check convert return revert
+@deffnx {special form} define-similar-windows-type name model [check [convert [return [revert]]]]
+@cindex defining foreign types
+Both forms define a windows type.
+The first form defines a type in terms of its aspects as described
+above.
+The second defines the type as being like another type, except for
+certain aspects, which are redefined.
+@var{Name} is the name of the type.
+@var{Model} is the name of a type.
+@var{Check}, @var{convert}, @var{return} and @var{revert} are
+procedures or the value @code{#f}.
+A @code{#f} means use the default value, which in the second form means
+use the definition provided for @var{model}.
+The defaults are
+
+@table @var
+@item check
+@code{(lambda (x) #t)}, i.e.@: unchecked.
+@item convert
+@code{(lambda (x) x)}, i.e.@: no translation performed.
+@item return
+@code{(lambda (x) x)}, i.e.@: no translation performed.
+@item revert
+@code{(lambda (x y) unspecific)}, i.e.@: no update performed
+@end table
+
+The @code{unchecked} windows type (see below) is defined as:
+
+@example
+(define-windows-type unchecked #f #f #f #f)
+@end example
+
+Windows types are @emph{not} first class values, so they cannot be
+stored in variables or defined using @code{define}:
+
+@example
+@group
+(define my-type unchecked) @error{} Unbound variable
+(define-similar-windows-type my-type unchecked)
+ @r{;; the correct way}
+@end group
+@end example
+
+Scheme characters must be converted to integers. This is accomplished
+as follows:
+
+@example
+@group
+(define-windows-type char
+ char? @r{; check}
+ char->integer @r{; convert}
+ integer->char @r{; convert return value}
+ #f @r{; cannot be passed by reference}
+)
+@end group
+@end example
+@end deffn
+
+@deffn {windows type} unchecked
+The type which is not checked and undergoes only the basic conversion
+from a Scheme integer to a C integer or from a Scheme string to a C
+pointer to the first byte of the string.
+Returned @code{unchecked} values are returned as integers.
+@end deffn
+
+@deffn {windows type} bool
+Scheme booleans are analogous to C integers @code{0} and @code{1}.
+Windows type @code{bool} have been defined as:
+
+@example
+@group
+(define-windows-type bool
+ boolean?
+ (lambda (x) (if x 1 0))
+ (lambda (x) (if (eq? x 0) #f #t))
+ #f)
+@end group
+@end example
+@end deffn
+
+@deffn {windows type} char
+Scheme characters are converted into C objects of type @code{char},
+which are indistinguishable from small integers.
+@end deffn
+
+@deffn {windows type} int
+@deffnx {windows type} uint
+@deffnx {windows type} long
+@deffnx {windows type} ulong
+@deffnx {windows type} short
+@deffnx {windows type} ushort
+@deffnx {windows type} word
+@deffnx {windows type} byte
+Various integer types that are passed without conversion.
+@end deffn
+
+@deffn {windows type} string
+A string that is passed as a C pointer of type @code{char*} to the first
+character in the string.
+@end deffn
+
+@deffn {windows type} char*
+A string or @code{#f}. The string is passed as a pointer to characters.
+The string is correctly null-terminated. @code{#f} is passed as the null
+pointer. This is an example where there is a more complex mapping
+between C objects and Scheme objects. C's @code{char*} type is
+represented as one of two Scheme types depending on its value. This
+allows us us to distinguish between the C string (pointer) that points
+to the empty sequence of characters and the null pointer (which doesnt
+point anywhere).
+@end deffn
+
+@deffn {windows type} handle
+@deffnx {windows type} hbitmap
+@deffnx {windows type} hbrush
+@deffnx {windows type} hcursor
+@deffnx {windows type} hdc
+@deffnx {windows type} hicon
+@deffnx {windows type} hinstance
+@deffnx {windows type} hmenu
+@deffnx {windows type} hpalette
+@deffnx {windows type} hpen
+@deffnx {windows type} hrgn
+@deffnx {windows type} hwnd
+Various kinds of Win32 handle. These names correspond to the same, but
+all uppercase, names in the Windows C language header files. Win32 API
+calls are the source of values of this type and the values are
+meaningless except as arguments to other Win32 API calls. Currently
+these values are represented as integers but we expect that Win32
+handles will in future be represented by allocated Scheme objects
+(e.g.@: records) that will allow predicates (e.g.@: @code{hmenu?}) and
+sensible interlocking with the garbage collector to free the programmer
+of the current tedious allocation and deallocation of handles.
+@end deffn
+
+@deffn {windows type} resource-id
+A Windows resource identifier is either a small integer or a string.
+In C, this distinction is possible because pointers look like
+larger integers, so a machine word representing a small integer can be
+distinguished from a machine word that is a pointer to the text of the
+name of the resource.
+@end deffn
+
+
+@node Windows Foreign Procedures, Win32 API names and procedures, Windows Types, Foreign function interface
+@subsection Windows Foreign Procedures
+
+Foreign procedures are declared as callable entry-points in a module,
+usually a dynamically linked library (DLL).
+
+
+@deffn procedure find-module name
+@cindex loading DLLs
+@cindex DLL, loading
+Returns a module suitable for use in creating procedures with
+@code{windows-procedure}. @var{Name} is a string which is the name of a
+DLL file. Internally, @code{find-module} uses the @code{LoadLibrary}
+Win32 API, so @var{name} should conform to the specifications for this
+call. @var{Name} should be either a full path name of a DLL, or the
+name of a DLL that resides in the same directory as the Scheme binary
+@file{SCHEME.EXE} or in the system directory.
+
+The module returned is a description for the DLL, and the DLL need not
+necessarily be linked at or immediately after this call. DLL modules
+are linked on need and unlinked before Scheme exits and when there
+are no remaining references to entry points after a garbage-collection.
+This behavior ensures that the Scheme system can run when a DLL is
+absent, provided the DLL is not actually used (i.e.@: no attempt is made
+to call a procedure in the DLL).
+@end deffn
+
+
+@defvr variable gdi32.dll
+@cindex DLL, GDI32.DLL
+This variable is bound to the module describing the @file{GDI32.DLL}
+library, which contains the Win32 API graphics calls, e.g.@:
+@code{LineTo}.
+@end defvr
+
+@defvr variable kernel32.dll
+@cindex DLL, KERNEL32.DLL
+This variable is bound to the module describing the @file{KERNEL32.DLL}
+library.
+@end defvr
+
+@defvr variable user32.dll
+@cindex DLL, USER32.DLL
+This variable is bound to the module describing the @file{USER32.DLL}
+library. This module contains many useful Win32 API procedures, like
+@code{MessageBox} and @code{SetWindowText}.
+@end defvr
+
+
+@deffn {special form} windows-procedure (name (parameter type) @dots{}) return-type module entry-name [options]
+@cindex defining foreign procedures
+This form creates a procedure, and could be thought of as
+``foreign-named-lambda''. The form creates a Scheme procedure that
+calls the C procedure identified by the exported entry point
+@var{entry-name} in the module identified by the value of @var{module}.
+Both @var{entry-name} and @var{module} are evaluated at procedure
+creation time, so either may be expression. @var{Entry-name} must
+evaluate to a string and @var{module} must evaluate to a module as
+returned by @code{find-module}.
+These are the only parts of the form that are evaluated at procedure
+creation time.
+
+@var{Name} is the name of the procedure and is for documentation
+purposes only. This form @emph{does not} define a procedure called
+@var{name}. It is more like @code{lambda}. The name might be used for
+debugging and pretty-printing.
+
+A windows procedure has a fixed number of parameters (i.e.@: no `rest'
+parameters or `varargs'), each of which is named and associated with a
+windows type @var{type}. Both the name @var{parameter} and the windows
+type @var{type} must be symbols and are not evaluated. The procedure
+returns a value of the windows type @var{return-type}.
+
+The following example creates a procedure that takes a window handle
+(@code{hwnd}) and a string and returns a boolean (@code{bool}) result.
+The procedure does this by calling the @code{SetWindowText} entry in the
+module that is the value of the variable @code{user32.dll}. The
+variable @code{set-window-title} is defined to have this procedure as
+it's value.
+
+@example
+@group
+(define set-window-title
+ (windows-procedure
+ (set-window-text (window hwnd) (text string))
+ bool user32.dll "SetWindowText"))
+
+(set-window-title my-win "Hi")
+ @result{} #t
+ @r{;; Changes window's title/text}
+
+set-window-title @result{} #[compiled-procedure @dots{}]
+set-window-text @error{} Unbound variable
+@end group
+@end example
+
+
+When there are no @var{options} the created procedure will (a) check its
+arguments against the types, (b) convert the arguments, (c) call the C
+procedure and (d) convert the returned value. No reversion is
+performed, even if one of the @var{types} has a reversion defined.
+(Reverted types are rare [I have never used one], so paying a cost for
+this unless it is used seems silly).
+
+The following options are allowed:
+
+@table @asis
+@item @code{with-reversions}
+The reversions are included in the type conversions.
+
+@item @code{expand}
+A synonym for @code{with-reversions}.
+
+@item @var{Scheme code}
+The @var{Scheme code} is placed between steps (a) and (b) in the default
+process. The Scheme code can enforce constraints on the arguments,
+including constraints between arguments such as checking that an index
+refers to a valid position in a string.
+@end table
+
+If both options (i.e.@: @code{with-reversions} and Scheme code) are used,
+@code{with-reversions} must appear first. There can be arbitrarily many
+Scheme expression.
+@end deffn
+
+@node Win32 API names and procedures, , Windows Foreign Procedures, Foreign function interface
+@subsection Win32 API names and procedures
+
+This section is a moving target.
+@cindex Win32 API names
+@cindex naming conventions
+
+The @code{#define} values from @file{wingdi.h} and @file{winuser.h} are
+available as bindings in the @code{(win32)} package environment. The
+@code{#define} symbols are all uppercase; these have been translated to
+all lowercase Scheme identifiers, thus @code{WM_LBUTTONUP} is the scheme
+variable @code{wm_lbuttonup}. As Scheme is case insensitive, the
+upper-case version may be used and probably should to make the code look
+more like conventional Windows code. The Scheme bindings have been
+produced automagically. Most of the @code{#define}-symbols contain an
+underscore so there are not many name clashes. There is one very
+notable name clash, however: @code{ERROR} is @code{#define}d to 0, which
+shadows the scheme procedure @code{error} in the root package
+environment. To signal an error, use @code{access} to get @code{error}
+from the system global environment:
+
+@example
+@group
+(declare (usual-integrations))
+@dots{}
+((access error system-global-environment) "Complain" @dots{})
+@end group
+@end example
+
+
+The set of procedures is incomplete because procedures have been added
+on a by-need basis for the implementation of other parts of the system,
+e.g.@: Scheme Graphics. Look in the implementation for further details.
+
+Win32 API procedure names have been uniformly converted into Scheme
+identifiers as follows:
+
+@itemize @bullet
+@item
+A leading uppercase letter is translated into a lowercase letter.
+@item
+Subsequent sequences of uppercase letters are translated into lowercase
+letters preceeded by a hyphen (minus symbol), i.e.@: hyphens are inserted
+at a lowercase to uppercase transition.
+@item
+Predicates beginning with @code{Is} finally have a
+question-mark appended.
+@end itemize
+
+@noindent
+Example: applying these rules to @code{IsWindow} yields
+@code{is-window?}, and @code{GetDC} is translated into @code{get-dc}.
+
+
+@c [It might be worthwhile just keeping the same names. As the
+@c Win32 API procedure names are uniformly `WordWordWordACRONYMWord', case
+@c insensitivity is unlikely to be a problem. The only problem is the
+@c potential for a clash between a procedure name and a type
+@c name.]
+
+
+@node Device Independent Bitmap Utilities, , Foreign function interface, Win32 Package Reference
+@section Device Independent Bitmap Utilities
+
+
+The Device Independent Bitmap (DIB) utilities library @file{DIBUTILS.DLL}
+and the associated procedures in @file{dib.scm} in the Win32 system
+source is an example of how to use the foreign function interface to
+access and manipulate non-Scheme objects.
+@cindex DLL, DIBUTILS.DLL
+
+@deffn {windows type} dib
+In the C world a DIB is a @dfn{handle} to a piece of memory containing
+the bits that represent information about the image and the pixels of
+the image. The handle is a machine-word sized piece of data which may
+be thought of as a 32 bit integer. The handle may be null (i.e.@: zero),
+indicating that there is no block of memory describing the DIB. The
+null value is usually returned by C functions that are supposed to
+create a DIB but failed, for some reason like the memory could not be
+allocated or a file could not be opened.
+
+In the Scheme world a DIB is a structure containing information
+about the bitmap (specifically the integer that represents the handle).
+We also include @code{#f} in the @code{dib} windows type to mirror the
+null handle error value.
+
+@example
+@group
+(define dib-result
+ (lambda (handle)
+ (if (= handle 0)
+ #f
+ (make-dib handle))))
+
+(define dib-arg
+ (lambda (dib)
+ (if dib
+ (cell-contents (dib-handle dib))
+ 0)))
+
+(define-windows-type dib
+ (lambda (thing) (or (dib? thing) (eq? thing #f)))
+ dib-arg
+ dib-result)
+@end group
+@end example
+@end deffn
+
+
+@menu
+* DIB procedures::
+* Other parts of the DIB Utilities implementation::
+@end menu
+
+@node DIB procedures, Other parts of the DIB Utilities implementation, Device Independent Bitmap Utilities, Device Independent Bitmap Utilities
+@subsection DIB procedures
+
+The following procedures have typed parameters, using the same
+convention as @code{windows-procedure}.
+
+@deffn procedure open-dib (filename string)
+Return type: @var{dib}. Calls the @code{OpenDIB} entry of
+@file{DIBUTILS.DLL}. If the return value is not @code{#f} then the file
+@var{filename} was found, successfully opened, and the contents were
+suitable for loading into memory as a device independent bitmap.
+@end deffn
+
+@deffn procedure write-dib (filename string) (dib dib)
+Return type: @var{bool}. Calls the @code{WriteDIB} entry of
+@file{DIBUTILS.DLL}. Returns @code{#t} if the file @var{filename} could
+be opened and written to. After this operation the file contains the
+bitmap data in a standard format that is understood by @code{open-dib}
+and various system utilities like the bitmap editor. Any problems
+resulting in failure are signalled by a @code{#f} return value.
+@end deffn
+
+@deffn procedure bitmap-from-dib (dib dib) (palette hpalette)
+Return type: @var{hbitmap}.
+Calls the @code{BitmapFromDib} entry of @file{DIBUTILS.DLL}. The returned
+value is a device dependent bitmap. The colours from the DIB are
+matched against colors in @var{palette}.
+@end deffn
+
+@deffn procedure dib-from-bitmap (bitmap hbitmap) (style dword) (bits word) (palette hpalette)
+Return type: @var{dib}.
+Returns a DIB containing the same image as the device dependent bitmap
+@var{bitmap}.
+@var{Style} determines the kind of DIB, e.g.@: compression style.
+Calls the @code{DibFromBitmap} entry of @file{DIBUTILS.DLL}.
+@end deffn
+
+@deffn procedure dib-blt (dest hdc) (x int) (y int) (w int) (h int) (src dib) (src-x int) (src-y int) (raster-op long)
+Return type: @var{bool}. Calls the @code{DibBlt} entry of
+@file{DIBUTILS.DLL}. Similar to the Win32 API @code{BitBlt} call, but
+draws a DIB rather than a piece of another device context. Draws the
+@var{dib} on device context @var{hdc} at position (@var{x},@var{y}). A
+rectangle of width @var{w} and height @var{h} is copied from position
+(@var{src-x},@var{src-y}) of @var{dib}.
+@var{Raster-op} is supposed to allow the source and destination to be
+combined but I don't think I got this right so stick to @code{SRCCOPY}.
+@end deffn
+
+@deffn procedure %delete-dib (dib-handle handle)
+Return type: @var{bool}.
+Calls the @code{DeleteDIB} entry of @file{DIBUTILS.DLL}.
+Note that the parameter is a @var{handle}, and not a @var{dib}.
+This allows us to destroy a DIB and reclaim its memory by knowing only
+the handle value, and not needing the @code{dib} record.
+The importance of this is that if the @code{dib} record is GC-ed then a
+GC hook can reclaim the storage knowing only the handle.
+@end deffn
+
+@deffn procedure delete-dib (dib dib)
+Return type: @var{bool}.
+This procedure calls @code{%delete-dib} to reclaim the storage occupied
+by a DIB.
+After being deleted, the DIB should not be used.
+This procedure allows the programmer to reclaim external heap storage
+rather than risking it running out before the next garbage collection.
+@end deffn
+
+@deffn procedure dib-height (dib dib)
+Return type: @var{int}.
+Calls the @code{DibHeight} expand entry of @file{DIBUTILS.DLL}, which returns
+the height of the bitmap in pixels.
+@end deffn
+
+@deffn procedure dib-width (dib dib)
+Return type: @var{int}.
+Calls the @code{DibWidth} entry of @file{DIBUTILS.DLL}, which returns
+the width of the bitmap in pixels.
+@end deffn
+
+@deffn procedure copy-bitmap (bm hbitmap)
+Return type: @var{hbitmap}.
+Calls the @code{CopyBitmap} of @file{DIBUTILS.DLL}, which creates a new
+bitmap with the same size and contents as the original.
+@end deffn
+
+@deffn procedure create-dib (width int) (height int) (style int) (depth int) (palette hpalette)
+Return type: @var{dib}.
+Calls the @code{CreateDIB} entry of @file{DIBUTILS.DLL}.
+Creates a DIB of @var{width} by @var{height} pixels and @var{depth} bits
+of colour information.
+The @var{style} parameter determines how the bitmap is stored.
+I have only ever used @code{BI_RGB}.
+If @var{depth}<=8 then the @var{palette} determines the DIB's colour table.
+@end deffn
+
+@deffn procedure crop-bitmap (bm hbitmap) (left int) (top int) (right int) (bottom int)
+Return type: @var{hbitmap}.
+Calls the @code{CropBitmap} entry of @file{DIBUTILS.DLL}.
+Returns a new bitmap containing the image from a region of the original.
+@end deffn
+
+@deffn procedure dib-set-pixels-unaligned dib (pixels string)
+Return type: @var{bool}.
+Calls the @code{DIBSetPixelsUnaligned} entry of@* @file{DIBUTILS.DLL}. Stuffs
+bytes from @var{pixels} into the bitmap. There are no alignment
+constraints on @var{pixels} (the usual way of doing this is to use the
+@code{SetDIBits} function which requires that every scan line of the
+bitmap is 32-bit word aligned, even if the scan lines are not a multiple
+of 4 bytes long). doing this
+@end deffn
+
+@node Other parts of the DIB Utilities implementation, , DIB procedures, Device Independent Bitmap Utilities
+@subsection Other parts of the DIB Utilities implementation
+
+
+The @file{DIBUTILS.DLL} library is an ordinary DLL. See the standard
+Microsoft Windows documentation on how to create DLLs. Look at the code
+in the @file{WIN32/DIBUTILS} directory of the Scheme source.
+
+Please note:
+@itemize @bullet
+@item
+@cindex DLL, exports
+For the foreign function interface to find the procedures they must be
+declared as exports in the @file{.DEF} definition file.
+
+@item
+To load the @file{.DLL} file use the @code{find-module} Scheme function.
+Look at @file{WIN32/DIB.SCM} to see how this is done.
+
+@item
+The current system works with C procedures with the @code{__stdcall} and
+@code{__cdecl} calling conventions but @emph{not} the @code{__fastcall}
+calling convention.
+@end itemize