\input texinfo @c -*-texinfo-*-
@iftex
@finalout
@end iftex
@comment $Id: scheme.texinfo,v 1.116 2002/03/13 05:47:01 cph Exp $
@comment %**start of header (This is for running Texinfo on a region.)
@setfilename scheme.info
@settitle MIT Scheme Reference
@comment %**end of header (This is for running Texinfo on a region.)
@setchapternewpage odd
@syncodeindex vr fn
@syncodeindex pg fn
@syncodeindex tp fn

@comment Parts of this document are essentially plagiarized from "Common
@comment Lisp: The Language".  Those parts are marked by the following
@comment comment lines:
@comment
@comment **** begin CLTL ****
@comment **** end CLTL ****

@dircategory Programming Languages
@direntry
* MIT Scheme Ref: (mit-scheme-ref).	MIT Scheme Reference Manual
@end direntry

@tex
% Don't let TeX put extra vspace around math displays ($$ ... $$),
% because these always appear inside @tex ... @end tex commands
% that put space there to begin with.
\abovedisplayskip=0pt plus 3pt
\abovedisplayshortskip=0pt plus 3pt
\belowdisplayskip=0pt plus 3pt
\belowdisplayshortskip=0pt plus 3pt
@end tex

@ifinfo
This file documents the MIT Scheme system.

Copyright @copyright{} 1988-2002 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.1 or
any later version published by the Free Software Foundation; with no
Invariant Sections, with no Front-Cover Texts, and with no Back-Cover
Texts.  A copy of the license is included in the section entitled "GNU
Free Documentation License".
@end ifinfo

@titlepage
@title{MIT Scheme Reference Manual}
@subtitle Edition 1.96
@subtitle for Scheme Release 7.7.0
@subtitle 13 March 2002
@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

Permission is granted to copy, distribute and/or modify this document
under the terms of the GNU Free Documentation License, Version 1.1 or
any later version published by the Free Software Foundation; with no
Invariant Sections, with no Front-Cover Texts, and with no Back-Cover
Texts.  A copy of the license is included in the section entitled "GNU
Free Documentation License".
@end titlepage

@node Top, Acknowledgements, (dir), (dir)

@ifinfo
Scheme is the UnCommon Lisp.  This Info file is the programmer reference
document for the MIT implementation of Scheme.  It describes the
facilities available for developing programs in MIT Scheme, and the
``public'' parts of the implementation.
@end ifinfo

@menu
* Acknowledgements::            
* Overview::                    
* Special Forms::               
* Equivalence Predicates::      
* Numbers::                     
* Characters::                  
* Strings::                     
* Lists::                       
* Vectors::                     
* Bit Strings::                 
* Miscellaneous Datatypes::     
* Associations::                
* Procedures::                  
* Environments::                
* Input/Output::                
* Operating-System Interface::  
* Error System::                
* Graphics::                    
* Win32 Package Reference::     
* GNU Free Documentation License::  
* Binding Index::               
* Concept Index::               

@detailmenu
 --- The Detailed Node Listing ---

Overview

* Notational Conventions::      
* Scheme Concepts::             
* Lexical Conventions::         
* Expressions::                 

Notational Conventions

* Errors::                      
* Examples::                    
* Entry Format::                

Scheme Concepts

* Variable Bindings::           
* Environment Concepts::        
* Initial and Current Environments::  
* Static Scoping::              
* True and False::              
* External Representations::    
* Disjointness of Types::       
* Storage Model::               

Lexical Conventions

* Whitespace::                  
* Delimiters::                  
* Identifiers::                 
* Uppercase and Lowercase::     
* Naming Conventions::          
* Comments::                    
* Additional Notations::        

Expressions

* Literal Expressions::         
* Variable References::         
* Special Form Syntax::         
* Procedure Call Syntax::       

Special Forms

* Lambda Expressions::          
* Lexical Binding::             
* Dynamic Binding::             
* Definitions::                 
* Assignments::                 
* Quoting::                     
* Conditionals::                
* Sequencing::                  
* Iteration::                   
* Structure Definitions::       
* Macros::                      

Definitions

* Top-Level Definitions::       
* Internal Definitions::        

Macros

* Syntactic Binding Constructs::  
* Pattern Language::            
* Syntactic Closures::          
* Explicit Renaming::           

Syntactic Closures

* Syntax Terminology::          
* SC Transformer Definition::   
* SC Identifiers::              

Numbers

* Numerical types::             
* Exactness::                   
* Implementation restrictions::  
* Syntax of numerical constants::  
* Numerical operations::        
* Numerical input and output::  
* Fixnum and Flonum Operations::  
* Random Numbers::              

Fixnum and Flonum Operations

* Fixnum Operations::           
* Flonum Operations::           

Characters

* External Representation of Characters::  
* Comparison of Characters::    
* Miscellaneous Character Operations::  
* Internal Representation of Characters::  
* ISO-8859-1 Characters::       
* Character Sets::              
* Unicode::                     

Strings

* 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::                

Regular Expressions

* Regular-expression procedures::  
* REXP abstraction::            

Lists

* Pairs::                       
* Construction of Lists::       
* Selecting List Components::   
* Cutting and Pasting Lists::   
* Filtering Lists::             
* Searching Lists::             
* Mapping of Lists::            
* Reduction of Lists::          
* Miscellaneous List Operations::  

Vectors

* Construction of Vectors::     
* Selecting Vector Components::  
* Cutting Vectors::             
* Modifying Vectors::           

Bit Strings

* 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::  

Miscellaneous Datatypes

* Booleans::                    
* Symbols::                     
* Cells::                       
* Records::                     
* Promises::                    
* Streams::                     
* Weak Pairs::                  

Associations

* Association Lists::           
* 1D Tables::                   
* The Association Table::       
* Hash Tables::                 
* Object Hashing::              
* Red-Black Trees::             
* Weight-Balanced Trees::       

Hash Tables

* Construction of Hash Tables::  
* Basic Hash Table Operations::  
* Resizing of Hash Tables::     
* Address Hashing::             
* Low-Level Hash Table Operations::  

Weight-Balanced Trees

* Construction of Weight-Balanced Trees::  
* Basic Operations on Weight-Balanced Trees::  
* Advanced Operations on Weight-Balanced Trees::  
* Indexing Operations on Weight-Balanced Trees::  

Procedures

* Procedure Operations::        
* Primitive Procedures::        
* Continuations::               
* Application Hooks::           

Environments

* Environment Operations::      
* Environment Variables::       
* REPL Environment::            
* Top-level Environments::    

Input/Output

* Ports::                       
* File Ports::                  
* String Ports::                
* Input Procedures::            
* Output Procedures::           
* Format::                      
* Custom Output::               
* Prompting::                   
* Port Primitives::             
* Parser Buffers::              
* Parser Language::             
* XML Parser::                  

Port Primitives

* Port Types::                  
* Constructors and Accessors for Ports::  
* Input Port Operations::       
* Output Port Operations::      
* Blocking Mode::               
* Terminal Mode::               

Parser Language

* *Matcher::                    
* *Parser::                     
* Parser-language Macros::      

Operating-System Interface

* Pathnames::                   
* Working Directory::           
* File Manipulation::           
* Directory Reader::            
* Date and Time::               
* Machine Time::                
* Subprocesses::                
* TCP Sockets::                 
* Miscellaneous OS Facilities::  

Pathnames

* Filenames and Pathnames::     
* Components of Pathnames::     
* Operations on Pathnames::     
* Miscellaneous Pathnames::     

Date and Time

* Universal Time::              
* Decoded Time::                
* File Time::                   
* Time-Format Conversion::      
* External Representation of Time::  

Subprocesses

* Subprocess Procedures::       
* Subprocess Conditions::       
* Subprocess Options::          

Error System

* Condition Signalling::        
* Error Messages::              
* Condition Handling::          
* Restarts::                    
* Condition Instances::         
* Condition Types::             
* Taxonomy::                    

Restarts

* Establishing Restart Code::   
* Invoking Standard Restart Code::  
* Finding and Invoking General Restart Code::  
* The Named Restart Abstraction::  

Condition Instances

* Generating Operations on Conditions::  
* Condition State::             
* Simple Condition Instance Operations::  

Graphics

* 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

X Graphics

* X Graphics Type::             
* Utilities for X Graphics::    
* Custom Operations on X Graphics Devices::  

Win32 Graphics

* Win32 Graphics Type::         
* Custom Operations for Win32 Graphics::  Custom Operations for Win32 Graphics Devices

OS/2 Graphics

* 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::  

Win32 Package Reference

* Win32 Package Overview::      
* Foreign function interface::  
* Device Independent Bitmap Utilities::  

Foreign Function Interface

* Windows Types::               
* Windows Foreign Procedures::  
* Win32 API names and procedures::  

Device Independent Bitmap Utilities

* DIB procedures::              
* Other parts of the DIB Utilities implementation::  

@end detailmenu
@end menu

@node Acknowledgements, Overview, Top, Top
@unnumbered Acknowledgements

While "a cast of thousands" may be an overstatement, it is certainly the
case that this document represents the work of many people.  First and
foremost, thanks go to the authors of the @cite{Revised^4 Report on the
Algorithmic Language Scheme}, from which much of this document is
derived.  Thanks also to BBN Advanced Computers Inc.@: for the use of
parts of their @cite{Butterfly Scheme Reference}, and to Margaret
O'Connell for translating it from BBN's text-formatting language to
ours.

Special thanks to Richard Stallman, Bob Chassell, and Brian Fox, all of
the Free Software Foundation, for creating and maintaining the Texinfo
formatting language in which this document is written.

This report describes research done at the Artificial Intelligence
Laboratory and the Laboratory for Computer Science, both of the
Massachusetts Institute of Technology.  Support for this research is
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 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 Scheme User's Manual}.

This chapter summarizes the semantics of Scheme, briefly describes the
MIT 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 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 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 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 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 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 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 Scheme allows all of the identifiers that standard
Scheme does, plus many more.

MIT 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 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 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 Scheme extension.
@findex #!optional
@findex #!rest
@findex lambda

@item #*
This character sequence introduces a bit string (@pxref{Bit Strings}).
This notation is an MIT 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 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 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 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 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::                      
@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 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 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 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 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 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 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 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 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 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-rtd)) a b)
bar             @error{} Unbound variable: bar
bar-rtd         @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 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 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,  , 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 Scheme also supports @dfn{anonymous syntactic keywords}.  This means
that it's not necessary to binding 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 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 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 @code{...} can match zero or more elements of
the input.  It is an error for @code{...} to appear in @var{literals}.
Within a pattern the identifier @code{...} 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 @code{...} 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 @code{...} are allowed only in subtemplates that are followed
by as many instances of @code{...}.  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 @code{...} 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 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 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 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
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
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 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 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 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 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 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 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 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
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 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 Scheme character consists of a @dfn{code} part and a @dfn{bucky
bits} part.  The MIT 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 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 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 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 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 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 Scheme provides rudimentary support for Unicode characters.  In an
ideal world, Unicode would be the base character set for MIT 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 Scheme, the elements of a string must all
satisfy the predicate @code{char-ascii?}; if someone ports MIT
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 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 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
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
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{\(}
... @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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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}) ...)
@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 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 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 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 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 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 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 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 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
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 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, and
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 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}-rtd
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-rtd
@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-processing-instructions} object or a string of
whitespace.
@end deftp

@deftp {record type} xml-declaration version encoding standalone
@vindex xml-declaration-rtd
@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-rtd
@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-rtd
@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-rtd
@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-rtd
@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-rtd
@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-rtd
@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-rtd
@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-rtd
@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-rtd
@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-rtd
@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-rtd
@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 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 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 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 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 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 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 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 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 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 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 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{...hairy computation...})
 (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{...hairy computation...}))
                      (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 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 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
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.

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 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 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 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 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...
@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...
@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 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...
@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}) ...)
@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 ...'' 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 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 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 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 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 ... 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 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 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 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) ...) 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  ...]
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))
...
((access error system-global-environment) "Complain" ...)
@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

@node GNU Free Documentation License, Binding Index, Win32 Package Reference, Top
@unnumbered GNU Free Documentation License
@include gfdl.texinfo

@node Binding Index, Concept Index, GNU Free Documentation License, Top
@unnumbered Binding Index
@printindex fn

@node Concept Index,  , Binding Index, Top
@unnumbered Concept Index
@printindex cp

@summarycontents
@contents

@bye
