From: Arthur Gleckler Date: Fri, 20 Dec 1991 15:43:26 +0000 (+0000) Subject: Initial revision X-Git-Tag: 20090517-FFI~10026 X-Git-Url: https://birchwood-abbey.net/git?a=commitdiff_plain;h=bbc428a92d7381e1d62ab220b31fa0ae8c348d50;p=mit-scheme.git Initial revision --- diff --git a/v7/doc/ref-manual/scheme.texinfo b/v7/doc/ref-manual/scheme.texinfo new file mode 100644 index 000000000..1809b5f2f --- /dev/null +++ b/v7/doc/ref-manual/scheme.texinfo @@ -0,0 +1,12384 @@ +\input texinfo @c -*-texinfo-*- +@iftex +@finalout +@end iftex +@comment %**start of header (This is for running Texinfo on a region.) +@setfilename scheme +@settitle MIT Scheme Reference +@comment %**end of header (This is for running Texinfo on a region.) +@setchapternewpage odd +@synindex vr 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 **** + +@comment This TeX macro is used in the description of the entry formats. +@comment It is similar to the @deffn macro, but doesn't screw around +@comment with the left margin or make an entry in the index. +@tex + +\gdef\defnameexample #1#2{% +\advance \hsize by -\leftskip % +\advance \hsize by -\rightskip % +\noindent % +\setbox0=\hbox{\hskip \deflastargmargin{\rm #2}\hskip \deftypemargin}% +\dimen0=\hsize \advance \dimen0 by -\wd0 % compute size for first line +\dimen1=\hsize \advance \dimen1 by -\defargsindent %size for continuations +\parshape 2 0in \dimen0 \defargsindent \dimen1 % +% Now output arg 2 ("Function" or some such) +% ending at \deftypemargin from the right margin, +% but stuck inside a box of width 0 so it does not interfere with linebreaking +\rlap{\rightline{{\rm #2}\hskip \deftypemargin}}% +\tolerance=10000 \hbadness=10000 % Make all lines underfull and no complaints +\hskip \deftypemargin % Indent function name slightly +{\df #1}\enskip % Generate function name +} + +\gdef\deffnheaderexample #1#2#3{% +\begingroup\defnameexample {#2}{#1}\defunargs{#3}\endgroup} + +\gdef\defmethparsebodyexample #1#2#3#4 {\begingroup\inENV % +\medbreak % +% Define the end token that this defining construct specifies +% so that it will exit this group. +\def#1{\endgraf\endgroup\medbreak}% +\def#2##1 {\begingroup\obeylines\activeparens\spacesplit{#3{##1}}}% +\parindent=0in % +\begingroup\obeylines\activeparens\spacesplit{#3{#4}}} + +\gdef\deffnexample{\defmethparsebodyexample\Edeffnexample\deffnexamplex\deffnheaderexample} + +% 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, 1989, 1990, 1991 Massachusetts Institute of Technology + +This material was developed by the Scheme project at the Massachusetts +Institute of Technology, Department of Electrical Engineering and Computer +Science. Permission to copy this document, to redistribute it, and to use +it for any purpose is granted, subject to the following restrictions and +understandings. + +@enumerate +@item +Any copy made of this document must include this copyright notice in +full. + +@item +Users of this document agree to make their best efforts (a) to return to +the MIT Scheme project any improvements or extensions that they make, so +that these may be included in future releases; and (b) to inform MIT of +noteworthy uses of this document. + +@item +All materials developed as a consequence of the use of this document shall +duly acknowledge such use, in accordance with the usual standards of +acknowledging credit in academic research. + +@item +MIT has made no warrantee or representation that the contents of this +document will be error-free, and MIT is under no obligation to provide any +services, by way of maintenance, update, or otherwise. + +@item +In conjunction with products arising from the use of this material, there +shall be no use of the name of the Massachusetts Institute of Technology +nor of any adaptation thereof in any advertising, promotional, or sales +literature without prior written consent from MIT in each case. +@end enumerate +@end ifinfo + +@titlepage +@title{MIT Scheme Reference Manual} +@subtitle Edition 1.1 +@subtitle for Scheme Release 7.1.3 +@subtitle November 1991 +@author by Chris Hanson +@author the MIT Scheme Team +@author and a cast of thousands + +@page + +@vskip 0pt plus 1filll +Copyright @copyright{} 1988, 1989, 1990, 1991 Massachusetts Institute of Technology + +This material was developed by the Scheme project at the Massachusetts +Institute of Technology, Department of Electrical Engineering and Computer +Science. Permission to copy this document, to redistribute it, and to use +it for any purpose is granted, subject to the following restrictions and +understandings. + +@enumerate +@item +Any copy made of this document must include this copyright notice in +full. + +@item +Users of this document agree to make their best efforts (a) to return to +the MIT Scheme project any improvements or extensions that they +make, so that these may be included in future releases; and (b) to +inform MIT of noteworthy uses of this document. + +@item +All materials developed as a consequence of the use of this document shall +duly acknowledge such use, in accordance with the usual standards of +acknowledging credit in academic research. + +@item +MIT has made no warrantee or representation that the contents of +this document will be error-free, and MIT is under no obligation to +provide any services, by way of maintenance, update, or otherwise. + +@item +In conjunction with products arising from the use of this material, +there shall be no use of the name of the Massachusetts Institute of +Technology nor of any adaptation thereof in any advertising, +promotional, or sales literature without prior written consent from +MIT in each case. +@end enumerate +@end titlepage + +@node Top, Overview, (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 +* Overview:: Overview +* Special Forms:: Special Forms +* Equivalence Predicates:: Equivalence Predicates +* Numbers:: Numbers +* Characters:: Characters +* Strings:: Strings +* Lists:: Lists +* Vectors:: Vectors +* Bit Strings:: Bit Strings +* Miscellaneous Datatypes:: Miscellaneous Datatypes +* Associations:: Associations +* Procedures:: Procedures +* Environments:: Environments +* Input/Output:: Input/Output +* File-System Interface:: File-System Interface +* Error System:: Error System +* Graphics:: Graphics +* Procedure Index:: Index of Procedures, Special Forms, and Variables +* Concept Index:: Index of Concepts + + --- The Detailed Node Listing --- + +Overview + +* Notational Conventions:: Notational Conventions +* Scheme Concepts:: Scheme Concepts +* Lexical Conventions:: Lexical Conventions +* Expressions:: Expressions + +Notational Conventions + +* Errors:: Errors +* Examples:: Examples +* Entry Format:: Entry Format + +Scheme Concepts + +* Variable Bindings:: Variable Bindings +* Environment Concepts:: Environment Concepts +* Initial and Current Environments:: Initial and Current Environments +* Static Scoping:: Static Scoping +* True and False:: True and False +* External Representations:: External Representations +* Disjointness of Types:: Disjointness of Types +* Storage Model:: Storage Model + +Lexical Conventions + +* Whitespace:: Whitespace +* Delimiters:: Delimiters +* Identifiers:: Identifiers +* Uppercase and Lowercase:: Uppercase and Lowercase +* Naming Conventions:: Naming Conventions +* Comments:: Comments +* Additional Notations:: Additional Notations + +Expressions + +* Literal Expressions:: Literal Expressions +* Variable References:: Variable References +* Special Form Syntax:: Special Form Syntax +* Procedure Call Syntax:: Procedure Call Syntax + +Special Forms + +* Lambda Expressions:: Lambda Expressions +* Lexical Binding:: Lexical Binding +* Fluid Binding:: Fluid Binding +* Definitions:: Definitions +* Assignments:: Assignments +* Quoting:: Quoting +* Conditionals:: Conditionals +* Sequencing:: Sequencing +* Iteration:: Iteration + +Definitions + +* Top-Level Definitions:: Top-Level Definitions +* Internal Definitions:: Internal Definitions + +Numbers + +* Numerical types:: Numerical types +* Exactness:: Exactness +* Implementation restrictions:: Implementation restrictions +* Syntax of numerical constants:: Syntax of numerical constants +* Numerical operations:: Numerical operations +* Numerical input and output:: Numerical input and output +* Fixnum and Flonum Operations:: Fixnum and Flonum Operations + +Fixnum and Flonum Operations + +* Fixnum Operations:: Fixnum Operations +* Flonum Operations:: Flonum Operations + +Characters + +* External Representation of Characters:: External Representation of Characters +* Comparison of Characters:: Comparison of Characters +* Miscellaneous Character Operations:: Miscellaneous Character Operations +* Internal Representation of Characters:: Internal Representation of Characters +* ASCII Characters:: ASCII Characters +* Character Sets:: Character Sets + +Strings + +* Construction of Strings:: Construction of Strings +* Selecting String Components:: Selecting String Components +* Comparison of Strings:: Comparison of Strings +* Alphabetic Case in Strings:: Alphabetic Case in Strings +* Cutting and Pasting Strings:: Cutting and Pasting Strings +* Searching Strings:: Searching Strings +* Matching Strings:: Matching Strings +* Modification of Strings:: Modification of Strings +* Variable-Length Strings:: Variable-Length Strings +* Byte Vectors:: Byte Vectors + +Lists + +* Pairs:: Pairs +* Construction of Lists:: Construction of Lists +* Selecting List Components:: Selecting List Components +* Cutting and Pasting Lists:: Cutting and Pasting Lists +* Filtering Lists:: Filtering Lists +* Searching Lists:: Searching Lists +* Mapping of Lists:: Mapping of Lists +* Reduction of Lists:: Reduction of Lists +* Miscellaneous List Operations:: Miscellaneous List Operations + +Vectors + +* Construction of Vectors:: Construction of Vectors +* Selecting Vector Components:: Selecting Vector Components +* Cutting Vectors:: Cutting Vectors +* Modifying Vectors:: Modifying Vectors + +Bit Strings + +* Construction of Bit Strings:: Construction of Bit Strings +* Selecting Bit String Components:: Selecting Bit String Components +* Cutting and Pasting Bit Strings:: Cutting and Pasting Bit Strings +* Bitwise Operations on Bit Strings:: Bitwise Operations on Bit Strings +* Modification of Bit Strings:: Modification of Bit Strings +* Integer Conversions of Bit Strings:: Integer Conversions of Bit Strings + +Miscellaneous Datatypes + +* Booleans:: Booleans +* Symbols:: Symbols +* Cells:: Cells +* Records:: Records +* Promises:: Promises +* Streams:: Streams +* Weak Pairs:: Weak Pairs + +Associations + +* Association Lists:: Association Lists +* 1D Tables:: 1D Tables +* The Association Table:: The Association Table +* Hash Tables:: Hash Tables +* Hashing:: Hashing + +Procedures + +* Procedure Operations:: Procedure Operations +* Primitive Procedures:: Primitive Procedures +* Continuations:: Continuations +* Application Hooks:: Application Hooks + +Environments + +* Environment Operations:: Environment Operations +* Environment Variables:: Environment Variables +* REPL Environment:: REPL Environment +* Interpreter Environments:: Interpreter Environments + +Input/Output + +* Ports:: Ports +* File Ports:: File Ports +* String Ports:: String Ports +* Input Procedures:: Input Procedures +* Output Procedures:: Output Procedures +* Format:: Format +* Custom Output:: Custom Output +* Port Primitives:: Port Primitives + +Port Primitives + +* Input Port Primitives:: Input Port Primitives +* Output Port Primitives:: Output Port Primitives + +File-System Interface + +* Pathnames:: Pathnames +* Working Directory:: Working Directory +* File Manipulation:: File Manipulation +* Directory Reader:: Directory Reader + +Pathnames + +* Filenames and Pathnames:: Filenames and Pathnames +* Components of Pathnames:: Components of Pathnames +* Operations on Pathnames:: Operations on Pathnames + +Error System + +* Simple Errors:: Simple Errors +* Error Handler:: Error Handler +* Error Messages:: Error Messages +* Condition Types:: Condition Types +* Condition Instances:: Condition Instances +* Condition Signalling:: Condition Signalling +* Condition Handling:: Condition Handling +* Predefined Errors:: Predefined Errors + +Graphics + +* Opening and Closing of Graphics Devices:: Opening and Closing of Graphics Devices +* Coordinates for Graphics:: Coordinates for Graphics +* Drawing Graphics:: Drawing Graphics +* Characteristics of Graphics Output:: Characteristics of Graphics Output +* Buffering of Graphics Output:: Buffering of Graphics Output +* Clipping of Graphics Output:: Clipping of Graphics Output +* Custom Graphics Operations:: Custom Graphics Operations +* X Graphics:: X Graphics +* Starbase Graphics:: Starbase Graphics + +X Graphics + +* X Graphics Type:: X Graphics Type +* Utilities for X Graphics:: Utilities for X Graphics +* Custom Operations on X Graphics Devices:: Custom Operations on X Graphics Devices +@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 of the Massachusetts Institute of Technology. Support for +the laboratory's artificial intelligence research is provided in part by +the Advanced Research Projects Agency of the Department of Defense under +Office of Naval Research contracts N00014-85-K-0124 and +N00014-86-K-0180. + +@node Overview, Special Forms, Acknowledgements, Top +@chapter Overview + +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:: Notational Conventions +* Scheme Concepts:: Scheme Concepts +* Lexical Conventions:: Lexical Conventions +* Expressions:: 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:: Errors +* Examples:: Examples +* Entry Format:: 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 signal-error +When this manual uses the phrase ``an error will be signalled,'' it +means that Scheme will call @code{signal-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, the 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 +(begin (write 'foo) 'bar) + @print{} foo + @result{} bar +@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: + +@iftex +@deffnexample @var{category} @var{template} +@end deffnexample +@end iftex +@ifinfo +@display +* @var{category}: @var{template} +@end display +@end ifinfo + +@noindent +where @var{category} specifies the kind of item (``variable'', ``special +form'', or ``procedure''), and how the item conforms to standard Scheme, as +follows: + +@table @asis +@item @var{category} +@var{Category}, with no extra marking, indicates that the item is described +in the @cite{Revised^4 Report on the Algorithmic Language Scheme}. + +@item @var{category}+ +A plus sign after @var{category} indicates that the item is an MIT +Scheme extension. +@cindex + in entries +@cindex plus sign, in entries +@end table + +@noindent +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, + +@iftex +@deffnexample procedure cdr pair +@end deffnexample +@end iftex +@ifinfo +@display +* procedure: cdr PAIR +@end display +@end ifinfo + +@noindent +indicates that the standard Scheme procedure @code{cdr} takes one argument, +which must be a pair. + +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: + +@table @var +@item object +any object +@item thunk +a procedure of no arguments +@item x +@itemx y +a real number +@item q +@itemx n +an integer +@item k +an exact non-negative integer +@end table +@end table + +Some examples: + +@iftex +@deffnexample procedure list object @dots{} +@end deffnexample +@end iftex +@ifinfo +@display +* procedure: list OBJECT @dots{} +@end display +@end ifinfo + +@noindent +indicates that the standard Scheme procedure @code{list} takes zero or +more arguments, each of which may be any Scheme object. + +@iftex +@deffnexample procedure write-char char [output-port] +@end deffnexample +@end iftex +@ifinfo +@display +* procedure: write-char CHAR [OUTPUT-PORT] +@end display +@end ifinfo + +@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:: Variable Bindings +* Environment Concepts:: Environment Concepts +* Initial and Current Environments:: Initial and Current Environments +* Static Scoping:: Static Scoping +* True and False:: True and False +* External Representations:: External Representations +* Disjointness of Types:: Disjointness of Types +* Storage Model:: 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 signals +an ``Unassigned Variable'' error. Unassigned variables are useful only +in combination with side effects (@pxref{Assignments}). + +@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 an +``Unbound Variable'' error. + +@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 @sc{rep} +loop has a current environment. (@sc{rep} stands for +``read-eval-print''; the @sc{rep} loop is the Scheme program that reads +your input, evaluates it, and prints the result.) The environment of +the top-level @sc{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 @sc{rep} loop is created, its +environment is determined by the program that creates it. @sc{rep} +loops that are created by the error handler use the environment in which +the error occurred, if possible, or failing that they use the previous +@sc{rep} loop's environment. + +@example +@group +1 ]=> z @error{} Unbound variable + +2 Error-> (define z 3) + +2 Error-> z @result{} 3 + +2 Error-> interrupt typed + +1 ]=> z @result{} 3 +@end group +@end example + +@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 @sc{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 soon 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 defined +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 +@pxref{True and False}, for an exception): + +@example +@group +bit-string? null? string? +boolean? number? symbol? +cell? pair? vector? +char? procedure? weak-pair? +environment? promise? +@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. + +@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:: Whitespace +* Delimiters:: Delimiters +* Identifiers:: Identifiers +* Uppercase and Lowercase:: Uppercase and Lowercase +* Naming Conventions:: Naming Conventions +* Comments:: Comments +* Additional Notations:: 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 +Certain identifiers are reserved for use as syntactic keywords; they +should not be used as variables (for a list of the initial syntactic +keywords, @pxref{Special Form Syntax}). +@cindex syntactic keyword, identifier as + +@item +Any identifier that is not a syntactic keyword can be used as a +variable. +@cindex variable, 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 +lambda q +list->vector soup ++ V17a +<=? a34kTMNs +the-word-recursion-has-many-meanings +@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 #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. +@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:: Literal Expressions +* Variable References:: Variable References +* Special Form Syntax:: Special Form Syntax +* Procedure Call 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 +"abc" @result{} "abc" +145932 @result{} 145932 +#t @result{} #t +#\a @result{} #\a +@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 +(define x 28) +x @result{} 28 +@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. The following list contains all of the +syntactic keywords that are defined when MIT Scheme is initialized: + +@example +@group +access define-syntax macro +and delay make-environment +begin do named-lambda +bkpt error or +case fluid-let quasiquote +cond if quote +cons-stream in-package scode-quote +declare lambda sequence +default-object? let set! +define let* the-environment +define-integrable let-syntax unassigned? +define-macro letrec using-syntax +define-structure local-declare +@end group +@end example + +@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 +@findex apply +If the @var{operator} is a syntactic keyword, then the expression is not +treated as a procedure call: it is a special form. Thus you should not +use syntactic keywords as procedure names. If you were to bind one of +these keywords to a procedure, you would have to use @code{apply} to +call the procedure. MIT Scheme signals an error when such a +binding is attempted. + +@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:: Lambda Expressions +* Lexical Binding:: Lexical Binding +* Fluid Binding:: Fluid Binding +* Definitions:: Definitions +* Assignments:: Assignments +* Quoting:: Quoting +* Conditionals:: Conditionals +* Sequencing:: Sequencing +* Iteration:: Iteration +@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, a ``Wrong +Number of Arguments'' error 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) + +@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, a ``Wrong Number of Arguments'' error is signalled. +@cindex optional parameter (defn) +@cindex parameter, optional (defn) +@cindex default object (defn) + +@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. + +@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 +(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 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, Fluid 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 +(let ((@var{variable} @var{init}) @dots{}) @var{expression} @var{expression} @dots{}) +((lambda (@var{variable} @dots{}) @var{expression} @var{expression} @dots{}) @var{init} @dots{}) +@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 Fluid Binding, Definitions, Lexical Binding, Special Forms +@section Fluid Binding + +@deffn {special form+} fluid-let ((@var{variable} @var{init}) @dots{}) expression expression @dots{} +@cindex binding expression, fluid (or dynamic) +@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 values 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 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. + +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. + +Here is a complicated example that shows the interaction between dynamic +binding and continuations: + +@example +@group +(define (complicated-fluid-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-fluid-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. +@end deffn + +@node Definitions, Assignments, Fluid 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:: Top-Level Definitions +* Internal 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 is +unassigned; an attempt to reference such a variable signals an +``Unassigned Variable'' error. + +@example +(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 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; subsequent references to such @var{variable} are +``Unassigned Variable'' errors. 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{} 'a +''a @result{} '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 +`(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 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 +(if (> 3 2) 'yes 'no) @result{} yes +(if (> 2 3) 'yes 'no) @result{} no +(if (> 3 2) + (- 3 2) + (+ 3 2)) @result{} 1 +@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 +(cond ((assv 'b '((a 1) (b 2))) => cadr) + (else #f)) @result{} 2 +@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 +(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 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 + +@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, , 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 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 +(string=? (symbol->string @var{obj1}) + (symbol->string @var{obj2})) + @result{} #t +@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 +(string=? (symbol->string @var{obj1}) + (symbol->string @var{obj2})) + @result{} #f +@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 +(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 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 + +@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, 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 +(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 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 + +@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:: Numerical types +* Exactness:: Exactness +* Implementation restrictions:: Implementation restrictions +* Syntax of numerical constants:: Syntax of numerical constants +* Numerical operations:: Numerical operations +* Numerical input and output:: Numerical input and output +* Fixnum and Flonum Operations:: Fixnum and Flonum Operations +@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 in this case.} +@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_4inexact (/ 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 +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 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 x1 x2 +@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 in this case. + +@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; MIT Scheme signals an error in this case. + +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 + +@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 +@end deffn + +@node Fixnum and Flonum Operations, , 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:: Fixnum Operations +* Flonum 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 0)) + (let ((m (+ n 1))) + (if (fix:fixnum? m) + (loop m) + n))) +@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 #432 -10) @result{} 1 +(fix:lsh -1 3) @result{} -8 +(fix:lsh -128 -4) @result{} -8 +@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: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 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 @sc{ascii} +character set. This may change when someone ports MIT Scheme to a +non-@sc{ascii} operating system.} + +@menu +* External Representation of Characters:: External Representation of Characters +* Comparison of Characters:: Comparison of Characters +* Miscellaneous Character Operations:: Miscellaneous Character Operations +* Internal Representation of Characters:: Internal Representation of Characters +* ASCII Characters:: ASCII Characters +* Character Sets:: Character Sets +@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 +#\a @r{; lowercase letter} +#\A @r{; uppercase letter} +#\( @r{; left parenthesis} +#\space @r{; the space character} +#\newline @r{; the newline character} +@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 @sc{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 +@sc{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 either @code{#\linefeed} or +@code{#\return}, depending on the operating system that Scheme is +running under. All of the standard @sc{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 +(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 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, signals an error. + +@example +(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 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-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{(chardigit 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, ASCII 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 @sc{ascii} can; it includes characters with Super, +Hyper, and Top bucky bits, as well as Control and Meta. Every +@sc{ascii} character corresponds to some MIT Scheme character, but not +vice versa.@footnote{Note that the Control bucky bit is different from +the @sc{ascii} control key. This means that @code{#\SOH} (@sc{ascii} +ctrl-A) is different from @code{#\C-A}. In fact, the Control bucky bit +is completely orthogonal to the @sc{ascii} control key, making possible +such characters as @code{#\C-SOH}.} + +MIT Scheme uses a 7-bit @sc{ascii} character code with 5 bucky +bits. The least significant bucky bit, Meta, is stored adjacent to the +MSB of the character code, allowing the least significant 8 bits of a +character object to be interpreted as ordinary @sc{ascii} with a meta +bit. This is compatible with standard practice for 8-bit characters +when meta bits are employed. + +@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 +(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 example +@end deffn + +@deffn {procedure+} char-code char +Returns the character code of @var{char}, an exact integer. For +example, + +@example +(char-code #\a) @result{} 97 +(char-code #\c-a) @result{} 97 +@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 +@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 ASCII Characters, Character Sets, Internal Representation of Characters, Characters +@section ASCII Characters + +MIT Scheme internally uses @sc{ascii} codes for @sc{i/o}, and stores +character objects in a fashion that makes it convenient to convert +between @sc{ascii} codes and characters. Also, character strings are +implemented as byte vectors whose elements are @sc{ascii} codes; these +codes are converted to character objects when accessed. For these +reasons it is sometimes desirable to be able to convert between +@sc{ascii} codes and characters. + +@cindex ASCII character (defn) +@cindex character, ASCII (defn) +Not all characters can be represented as @sc{ascii} codes. A character +that has an equivalent @sc{ascii} representation is called an @dfn{ASCII +character}. + +@deffn {procedure+} char-ascii? char +Returns the @sc{ascii} code for @var{char} if @var{char} has an +@sc{ascii} representation; otherwise returns @code{#f}. + +@findex char-bits +In the current implementation, the characters that satisfy this +predicate are those in which the Control, Super, Hyper, and Top bucky +bits are turned off. All characters for which the @code{char-bits} +procedure returns @code{0} or @code{1} (i.e.@: no bucky bits, or just +Meta) count as legal @sc{ascii} characters. +@end deffn + +@deffn {procedure+} char->ascii char +Returns the @sc{ascii} code for @var{char}. An error is signalled if +@var{char} doesn't have an @sc{ascii} representation. +@end deffn + +@deffn {procedure+} ascii->char code +@var{Code} must be the exact integer representation of an @sc{ascii} +code. This procedure returns the character corresponding to @var{code}. +@end deffn + +@node Character Sets, , ASCII 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 @sc{ascii} 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}.@footnote{Because character sets are implemented as strings, +@code{string?} returns @code{#t} for character set objects. However, +string operations aren't meaningful with character sets.} +@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 the @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 @sc{ascii} +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 @sc{ascii} characters. This is equivalent to @code{(apply char-set +@var{chars})}. +@end deffn + +@deffn {procedure+} ascii-range->char-set lower upper +@var{Lower} and @var{upper} must be exact non-negative integers +representing @sc{ascii} 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 @sc{ascii} codes are +between @var{lower} (inclusive) and @var{upper} (exclusive). +@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 @sc{ascii} 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-set1 char-set2 +Returns a character set consisting of the characters that are in both +@var{char-set1} and @var{char-set2}. +@end deffn + +@deffn {procedure+} char-set-union char-set1 char-set2 +Returns a character set consisting of the characters that are in one or +both of @var{char-set1} and @var{char-set2}. +@end deffn + +@deffn {procedure+} char-set-invert char-set +Returns a character set consisting of the @sc{ascii} characters that are +not in @var{char-set}. +@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-@sc{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 @sc{ascii} 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. + +@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:: Construction of Strings +* Selecting String Components:: Selecting String Components +* Comparison of Strings:: Comparison of Strings +* Alphabetic Case in Strings:: Alphabetic Case in Strings +* Cutting and Pasting Strings:: Cutting and Pasting Strings +* Searching Strings:: Searching Strings +* Matching Strings:: Matching Strings +* Modification of Strings:: Modification of Strings +* Variable-Length Strings:: Variable-Length Strings +* Byte Vectors:: 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?}. +@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 +(string #\a) @result{} "a" +(string #\a #\b #\c) @result{} "abc" +(string #\a #\space #\b #\space #\c) @result{} "a b c" +(string) @result{} "" +@end example + +@findex char->string +For compatibility with old code, @code{char->string} is a synonym for +this procedure. +@end deffn + +@deffn procedure list->string char-list +@cindex list, converting to string +@findex string->list +@var{Char-list} must be a list of @sc{ascii} 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}. +@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 +(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 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}. +@end deffn + +@deffn procedure string-length string +Returns the length of @var{string} as an exact non-negative integer. +@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}. +@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}. +@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?}. +@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. +@end deffn + +@deffn procedure string? string1 string2 +@deffnx procedure string<=? string1 string2 +@deffnx procedure string>=? string1 string2 +@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. +@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. +@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 @code{#t} if the first character in the string +(substring) is an uppercase letter and none of the remaining characters +are uppercase letters. If the first character is not an uppercase +letter or if any of the remaining characters are uppercase letters, they +return @code{#f}. If the string (substring) contains less than two +letters, they return @code{#f}. +@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}. +@end deffn + +@deffn {procedure+} string-capitalize string +@deffnx {procedure+} string-capitalize! string +@code{string-capitalize} returns a newly allocated copy of @var{string} +in which the first character is uppercase and the remaining letters 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. +@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}. +@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{""}). +@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). +@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 +(define (string-head string end) + (substring string 0 end)) +@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 +(define (string-tail string start) + (substring string start (string-length string))) +@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}, these procedures are equivalent to +@code{string-head}. @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). +@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:whitespace}. +@end deffn + +@node Searching Strings, Matching Strings, Cutting and Pasting Strings, Strings +@section Searching Strings +@cindex searching, of string +@cindex character, searching string for + +@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. +@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 (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 + +@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, Modification of Strings, 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. +@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. +@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 +(string-prefix? "abc" "abcdef") @result{} #t +@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 +(string-suffix? "def" "abcdef") @result{} #t +@end example +@end deffn + +@node Modification of Strings, Variable-Length Strings, Matching Strings, 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. +@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. +@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 +@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. This feature works as follows. 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 @emph{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 @sc{ascii} +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 @sc{ascii} code. +@var{K} must be a valid index of @var{string}. +@end deffn + +@deffn {procedure+} vector-8b-set! string k ascii +Stores @var{ascii} in element @var{k} of @var{string} and returns an +unspecified value. @var{K} must be a valid index of @var{string}, and +@var{ascii} must be a valid @sc{ascii} code. +@end deffn + +@deffn {procedure+} vector-8b-fill! string start end +Stores @var{ascii} in elements @var{start} (inclusive) to @var{end} +(exclusive) of @var{string} and returns an unspecified value. +@var{Ascii} must be a valid @sc{ascii} code. +@end deffn + +@deffn {procedure+} vector-8b-find-next-char string start end ascii +@deffnx {procedure+} vector-8b-find-next-char-ci string start end ascii +Returns the index of the first occurrence of @var{ascii} in the given +substring; returns @code{#f} if @var{ascii} does not appear. The index +returned is relative to the entire string, not just the substring. +@var{Ascii} must be a valid @sc{ascii} 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 ascii +@deffnx {procedure+} vector-8b-find-previous-char-ci string start end ascii +Returns the index of the last occurrence of @var{ascii} in the given +substring; returns @code{#f} if @var{ascii} does not appear. The index +returned is relative to the entire string, not just the substring. +@var{Ascii} must be a valid @sc{ascii} 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 record +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:: Pairs +* Construction of Lists:: Construction of Lists +* Selecting List Components:: Selecting List Components +* Cutting and Pasting Lists:: Cutting and Pasting Lists +* Filtering Lists:: Filtering Lists +* Searching Lists:: Searching Lists +* Mapping of Lists:: Mapping of Lists +* Reduction of Lists:: Reduction of Lists +* Miscellaneous List Operations:: 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 +(general-car-cdr @var{object} #b1011) +(cdr (car (car @var{object}))) +@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 +(string->list "abcd") @result{} (#\a #\b #\c #\d) +(substring->list "abcdef" 1 3) @result{} (#\b #\c) +@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}. + +@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 +(list-ref '(a b c d) 2) @result{} c +(list-ref '(a b c d) + (inexact->exact (round 1.8))) + @result{} c +@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}, signalling 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 + +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 + +@node Filtering Lists, Searching Lists, Cutting and Pasting Lists, Lists +@section Filtering Lists +@cindex filtering, of list +@cindex deletion, of list element + +@deffn {procedure+} list-transform-positive list predicate +@deffnx {procedure+} list-transform-negative 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. +@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+} list-search-positive list predicate +@deffnx {procedure+} list-search-negative list predicate +Returns the first element in @var{list} for which @var{predicate} is +(respectively) true or false; returns @code{#f} if it doesn't find such +an element. (This means that if @var{predicate} is true (false) 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. +@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 +(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 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 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+} 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}, that +value 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+} 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 + +@deffn {procedure+} sort list procedure +@cindex total ordering (defn) +@var{Procedure} must be a procedure of two arguments that defines a +@dfn{total ordering} on the elements of @var{list}. In other words, if +@var{x} and @var{y} are two distinct elements of @var{list}, 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 + +@code{sort} returns a newly allocated list whose elements are the +elements of @var{list}, except that the elements are rearranged so that +they are sorted in the order defined by @var{procedure}. So, for +example, if the elements of @var{list} are numbers, and @var{procedure} +is @code{<}, then the resulting list is sorted in monotonically +nondecreasing order. Likewise, if @var{procedure} is @code{>}, the +resulting list is sorted in monotonically nonincreasing order. To be +precise, if @var{x} and @var{y} are any two adjacent elements in the +resulting list, 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 +@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) +A number of the vector procedures operate on subvectors. A +@dfn{subvector} is a segment of a vector, which 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. + +@menu +* Construction of Vectors:: Construction of Vectors +* Selecting Vector Components:: Selecting Vector Components +* Cutting Vectors:: Cutting Vectors +* Modifying 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 + +@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 @var{vector}'s length is too small. +@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 be 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 + +@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. + +@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:: Construction of Bit Strings +* Selecting Bit String Components:: Selecting Bit String Components +* Cutting and Pasting Bit Strings:: Cutting and Pasting Bit Strings +* Bitwise Operations on Bit Strings:: Bitwise Operations on Bit Strings +* Modification of Bit Strings:: Modification of Bit Strings +* Integer Conversions 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 + +@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 if @var{integer} is too large to be represented +in @var{length} bits. +@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 if @var{integer} is too large to be +represented in @var{length} bits. +@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:: Booleans +* Symbols:: Symbols +* Cells:: Cells +* Records:: Records +* Promises:: Promises +* Streams:: Streams +* Weak Pairs:: 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 some standard declarations, 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 +(boolean? #f) @result{} #t +(boolean? 0) @result{} #f +@end example +@end deffn + +@deffn procedure not object +@deffnx {procedure+} false? object +@cindex false, predicate for +@cindex inverse, of boolean object +These procedures returns @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 +(not #t) @result{} #f +(not 3) @result{} #f +(not (list 3)) @result{} #f +(not #f) @result{} #t +@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 eqv? +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{eqv?} 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{eqv?}). + +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 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 eqv? +Returns a newly allocated uninterned symbol that is guaranteed not to be +@code{eqv?} to any other object in the Scheme system. The symbol's name +consists of a string (initially @code{"G"}) followed by an integer that +is incremented on every call (the integer is initially 0). The optional +@var{object} can be an integer or a symbol. If @var{object} is a +symbol, the string prefix of all subsequently generated symbol names +will be that symbol's name. If @var{object} is an integer, the integer +suffix of all subsequently generated symbol names will start counting +from that value. + +@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 this3] +(generate-uninterned-symbol 100) + @result{} #[uninterned-symbol 35 this100] +(generate-uninterned-symbol) + @result{} #[uninterned-symbol 36 this101] +@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 +(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 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. +@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 fluid binding of a variable, including the behavior when +continuations are used (@pxref{Fluid 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. This +abstraction will very likely be a part of the next edition of the Scheme +standard. The procedures defined in this section that are expected to +be in the standard are not marked with @samp{+}. + +@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-updater 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 updater 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.@footnote{In the current implementation of MIT Scheme, any +object that satisfies this predicate also satisfies @code{vector?}. +However, we plan to change the implementation to make records distinct +from all other data types.} 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}.@footnote{However, in MIT Scheme, +the record-type descriptor representing a given record type is unique.} +@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) + +(define a-stream + (letrec ((next + (lambda (n) + (cons n (delay (next (+ n 1))))))) + (next 0))) + +(define head car) + +(define tail + (lambda (stream) + (force (cdr stream)))) + +(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) + +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 +@findex the-empty-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.@footnote{The variable @code{the-empty-stream}, +which is bound to the end-of-stream marker, is provided for +compatibility with old code; use @code{(stream)} in new code.} +@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 +@findex car +@findex head +Returns the first element in @var{stream}. @code{stream-car} is +equivalent to @code{car}.@footnote{@code{head}, a synonym for +@code{stream-car}, is provided for compatibility with old code; use +@code{stream-car} in new code.} +@end deffn + +@deffn {procedure+} stream-cdr stream +@findex force +@findex cdr +@findex tail +Returns the first tail of @var{stream}. Equivalent to @code{(force +(cdr @var{stream}))}.@footnote{@code{tail}, a synonym for +@code{stream-cdr}, is provided for compatibility with old code; use +@code{stream-cdr} in new code.} +@end deffn + +@deffn {procedure+} stream-null? stream +@cindex empty stream, predicate for +@findex null? +@findex empty-stream? +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.@footnote{@code{empty-stream?}, a synonym for +@code{stream-null?}, is provided for compatibility with old code; use +@code{stream-null?} in new code.} +@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-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 stream procedure +@cindex mapping, of stream +Returns a newly allocated stream, each element being the result of +invoking @var{procedure} with the corresponding element of @var{stream} +as its argument. @var{Procedure} must be a procedure of one argument. +@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 +@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 is lookup required for both keys. + +@item +@dfn{Hash tables} are a powerful mechanism with nearly constant-time +access to large amounts of data. However, the overhead for hash tables +is somewhat high, both in time and space, making them unsuitable for +small tables. And hash tables are not as flexible as association lists. +@end itemize + +@menu +* Association Lists:: Association Lists +* 1D Tables:: 1D Tables +* The Association Table:: The Association Table +* Hash Tables:: Hash Tables +* Hashing:: Hashing +@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. +@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. + +@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 and @code{#t} is returned. Otherwise @code{#f} is +returned. +@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, 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 growth, +customizable growth parameters, and customizable hash functions. + +@cindex run-time-loadable option +@cindex option, run-time-loadable +The hash-table implementation is a run-time-loadable option. To use +hash tables, execute + +@example +(load-option 'hash-table) +@end example +@findex load-option + +@noindent +once before calling any of the procedures defined here. + +@deffn {procedure+} make-object-hash-table [k] +@findex eq? +Returns a newly allocated hash table that accepts arbitrary objects as +keys, and uses @code{eq?} to compare the keys. The keys are weakly +held, i.e.@: the hash table does not protect them from being reclaimed +by the garbage collector. @var{K} specifies the initial usable size of +the hash table, and defaults to 10 if not specified. The entries of the +hash table are weak pairs whose car field is the @var{key} and whose cdr +field is the @var{datum}. +@end deffn + +@deffn {procedure+} make-string-hash-table [k] +@findex string=? +Returns a newly allocated hash table that accepts strings as keys, and +compares them with @code{string=?}. The keys are strongly held, i.e.@: +while in the hash table they will not be reclaimed by the garbage +collector. @var{K} specifies the initial usable size of the hash table, +and defaults to 10 if not specified. The entries of the hash table are +ordinary pairs whose car field is the @var{key} and whose cdr field is +the @var{datum}. +@end deffn + +@deffn {procedure+} make-symbol-hash-table [k] +@findex eq? +Returns a newly allocated hash table that accepts symbols as keys, and +compares them with @code{eq?}. The keys are strongly held, i.e.@: while +in the hash table they will not be reclaimed by the garbage collector. +@var{K} specifies the initial usable size of the hash table, and +defaults to 10 if not specified. The entries of the hash table are +ordinary pairs whose car field is the @var{key} and whose cdr field is +the @var{datum}. +@end deffn + +@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. +@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. +@end deffn + +@deffn {procedure+} hash-table/clear! hash-table +Removes all associations in @var{hash-table} and returns an unspecified +result. +@end deffn + +@deffn {procedure+} hash-table/get hash-table key default +Returns the @var{datum} associated with @var{key} in @var{hash-table}. +If there is no association for @var{key}, @var{default} is returned. +@end deffn + +@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 @var{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}. +@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 entry being processed. +@end deffn + +@deffn {procedure+} hash-table/entries-list hash-table +Returns a newly allocated list of the entries in @var{hash-table}. The +elements of the list are usually either pairs or weak pairs, depending +on the type of 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 + +@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 + +@deffn {procedure+} hash-table/constructor key-hash key=? make-entry entry-valid? entry-key entry-value set-entry-value! +Returns a constructor procedure for a hash table. The returned +procedure accepts one optional argument @var{k}, which specifies the +initial usable size of the table, and returns a newly allocated hash +table; @code{k} defaults to @code{10} if not supplied. The arguments to +@code{hash-table/constructor} define the characteristics of the hash +table as follows: + +@table @var +@item key-hash +The hashing function. A procedure that accepts two arguments, a +@var{key} and an exact positive integer (the hash modulus), and returns +an exact non-negative integer that is less than the second argument. +Examples: @code{string-hash-mod}, @code{symbol-hash-mod}. +@findex string-hash-mod +@findex symbol-hash-mod + +@item key=? +A equivalence predicate that accepts two @var{key} arguments and is true +if they are the same key. Examples: @code{eq?}, @code{string=?}. +@findex eq? +@findex string=? + +@item make-entry +A procedure that accepts a @var{key} and a @var{datum} as arguments and +returns an entry. Typically @code{cons} or @code{weak-cons}. +@findex cons +@findex weak-cons + +@item entry-valid? +A procedure that accepts an entry and returns @code{#f} only if the +entry's @var{key} has been reclaimed by the garbage collector. For +example, if entries are weak pairs, this should be +@code{weak-pair/car?}. 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 +@var{key}. Typically @code{car} or @code{weak-car}. +@findex car +@findex weak-car + +@item entry-value +A procedure that accepts an entry as an argument and returns the entry's +@var{datum}. Typically @code{cdr} or @code{weak-cdr}. +@findex cdr +@findex weak-cdr + +@item set-entry-value! +A procedure that accepts an entry and an object as arguments, modifies +the entry's @var{datum} to be the object, and returns an unspecified +result. Typically @code{set-cdr!} or @code{weak-set-cdr!}. +@findex set-cdr! +@findex weak-set-cdr! +@end table +@end deffn + +@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-value hash-table +@deffnx {procedure+} hash-table/set-entry-value! hash-table +Each of these procedures corresponds to the respective argument of +@code{hash-table/constructor}. When called, these procedures return the +value of the argument that was used to construct @var{hash-table}. +@end deffn + +Two parameters control the growth of a hash table, the @dfn{rehash +threshold} and the @dfn{rehash size}. + +@cindex rehash threshold, of hash table (defn) +@cindex usable size, of hash table (defn) +@cindex physical size, of hash table (defn) +@cindex size, of hash table (defn) +The @dfn{rehash threshold} is a real number, between zero exclusive and +one inclusive, that specifies how full the hash table can get before it +must grow. In other words it is the ratio between a hash table's +@dfn{usable size} and its @dfn{physical size}. If the number of entries +in the table exceeds this fraction of the table's physical size, the +table is grown to a larger size. The default rehash threshold of a +newly constructed hash table is @code{1}, but this can be changed with +@code{set-hash-table/rehash-threshold!}. + +@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. +@end deffn + +@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. The default rehash size of a newly constructed hash +table is @code{2.0}, but this can be changed with +@code{set-hash-table/rehash-size!}. + +@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. +@end deffn + +@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 entries that @var{hash-table} can hold +before it must grow. +@end deffn + +@deffn {procedure+} hash-table/count hash-table +Returns the number of entries in @var{hash-table} as an exact +non-negative integer. This is always less than or equal to the usable +size of @var{hash-table}. +@end deffn + +@node Hashing, , Hash Tables, Associations +@section 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 some objects +(@pxref{Custom Output}). + +@deffn {procedure+} object-hash object +@deffnx {procedure+} object-unhash k +@findex eq? +@code{object-hash} associates an exact non-negative integer with +@var{object} and returns that integer. If @code{object-hash} was +previously called with @var{object} as its argument, the integer +returned is the same as was returned by the previous call. +@code{object-hash} guarantees that distinct objects (in the sense of +@code{eq?}) are associated with distinct integers. + +@code{object-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}, @code{#f} is returned. In other words, if +@code{object-hash} previously returned @var{k} for some object, that +object is the value of the call to @code{object-unhash}. + +An object that is passed to @code{object-hash} as an argument is not +protected from being garbage-collected. If all other references to that +object are eliminated, the object will be garbage-collected. +Subsequently calling @code{object-unhash} with the hash number of the +(garbage-collected) object will return @code{#f}. + +@example +@group +(define x (cons 0 0)) @result{} @r{unspecified} +(object-hash x) @result{} 77 +(eqv? (object-hash x) (object-hash x)) @result{} #t +(define x 0) @result{} @r{unspecified} +(gc-flip) @r{;force a garbage collection} +(object-unhash 77) @result{} #f +@end group +@end example + +@findex hash +@findex unhash +Note: @code{hash} is a synonym for @code{object-hash} and @code{unhash} +is a synonym for @code{object-unhash}. These synonyms are obsolete and +should not be used. +@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:: Procedure Operations +* Primitive Procedures:: Primitive Procedures +* Continuations:: Continuations +* Application Hooks:: 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 + +@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 + +(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{Continuation} must be a continuation produced by +@code{call-with-current-continuation}. +@var{Thunk} must be a procedure of no arguments. +Conceptually, @code{within-continuation} invokes @code{continuation} on +the result of invoking @code{thunk}, but @code{thunk} is executed in the +dynamic context of @code{continuation}. In other words, the ``current'' +continuation is abandoned before @code{thunk} is invoked. +@end deffn + +@deffn {procedure+} dynamic-wind before-thunk action-thunk after-thunk +@cindex unwind protect +@findex unwind-protect +This facility is a generalization of Common Lisp @code{unwind-protect}, +designed to take into account the fact that continuations produced by +@code{call-with-current-continuation} may be reentered. The arguments +@var{before-thunk}, @var{action-thunk}, and @var{after-thunk} must all +be procedures of no arguments (thunks). + +@code{dynamic-wind} behaves as follows. First @var{before-thunk} is +called. Then @var{action-thunk} is called. Finally, @var{after-thunk} +is called. The value returned by @var{action-thunk} is returned as the +result of @code{dynamic-wind}. @var{After-thunk} is also called if +@var{action-thunk} escapes from its continuation. If @var{action-thunk} +captures its continuation as an escape procedure, escapes from it, then +escapes back to it, @var{after-thunk} is invoked when escaping away, and +@var{before-thunk} is invoked when escaping back. + +@cindex locks, and dynamic-wind +@code{dynamic-wind} is useful, for example, for ensuring the proper +maintenance of locks: locking would occur in the @var{before-thunk}, +protected code would appear in the @var{action-thunk}, and unlocking +would occur in the @var{after-thunk}. +@end deffn + +The following two procedures support multiple values. A future revision +of the Scheme standard will support a facility similar to, but almost +certainly different from, this one. + +@deffn {procedure+} 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{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{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 Operations +* Environment Variables:: Environment Variables +* REPL Environment:: REPL Environment +* Interpreter Environments:: Interpreter 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. + +@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}. +@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{name})} +indicates that @var{name} is bound but unassigned, while +@code{(@var{name} @var{object})} indicates that @var{name} is bound, and +its value is @var{object}. +@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}. +@end deffn + +@deffn {procedure+} environment-lookup environment symbol +@var{Symbol} must be bound in @var{environment} or one of its ancestor +environments. Returns the value to which it is bound. Signals an error +if @var{symbol} is unassigned. +@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+} 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 (@sc{rep}) loop evaluates expressions and stores +definitions. It is a child of the @code{system-global-environment}, +which is where all of the Scheme system definitions are stored. 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 @sc{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 +environment that's the parent of the @code{user-initial-environment}. +Primitives and system procedures 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 +@sc{rep} loop. + +Although all bindings in @code{system-global-environment} are visible to +the @sc{rep} loop, definitions that are typed at, or loaded by, the +@sc{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 ("closed") in the @code{system-global-environment}, +will continue to see the original definition. +@end defvr + +@node REPL Environment, Interpreter Environments, Environment Variables, Environments +@section REPL Environment + +@deffn {procedure+} nearest-repl/environment +@findex user-initial-environment +Returns the current @sc{rep} loop environment (i.e.@: the current +environment of the closest enclosing @sc{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 @sc{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 Interpreter Environments, , REPL Environment, Environments +@section Interpreter Environments + +The operations in this section return environments that are constructed +by the interpreter. These operations should not be used lightly, as +they will significantly degrade the performance of compiled code. In +particular, they force the current environment to represented in a form +suitable for use by the interpreter. This prevents the compiler from +performing many useful optimizations on such environments, and forces +the use of the interpreter for variable references in them. However, +because all top-level environments (such as +@code{user-initial-environment}) are already interpreter environments, +it does no harm to use such operations on them. + +@deffn {special form+} make-environment expression @dots{} +@cindex construction, of environment +Produces a new environment that is a child of the environment in which +it is executed, evaluates the @var{expression}s sequentially in the new +environment, and returns the new environment. Note that + +@example +(make-environment @var{expression} @dots{}) +@end example + +@noindent +is equivalent to: + +@example +(let () + @var{expression} @dots{} + (the-environment)) +@end example +@end deffn + +@deffn {special form+} the-environment +Returns the current environment. +@end deffn + +@deffn {procedure+} interpreter-environment? object +@cindex type predicate, for interpreter environment +Returns @code{#t} if @var{object} is an interpreter environment; +otherwise returns @code{#f}. +@end deffn + +@node Input/Output, File-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 +(@sc{i/o}). The chapter first describes @dfn{ports} and how they are +manipulated, then describes the @sc{i/o} operations. Finally, some +low-level procedures are described that permit the implementation of +custom ports and high-performance @sc{i/o}. + +@menu +* Ports:: Ports +* File Ports:: File Ports +* String Ports:: String Ports +* Input Procedures:: Input Procedures +* Output Procedures:: Output Procedures +* Format:: Format +* Custom Output:: Custom Output +* Port Primitives:: Port Primitives +@end menu + +@node Ports, File Ports, Input/Output, Input/Output +@section Ports + +@cindex port (defn) +Scheme uses ports for @sc{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 +@sc{i/o} ports, the keyboard and the terminal screen, are 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 the keyboard, 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 the +terminal screen, but Scheme provides procedures that let you change the +current output port to be a file or string. + +Most ports read or write only @sc{ascii} characters. However, it is +possible to create ports that will read and write arbitrary characters. +The limitation to @sc{ascii} characters is imposed entirely by the port, +not by the @sc{i/o} operations. + +@deffn procedure input-port? object +@deffnx procedure output-port? object +@cindex type predicate, for input port +@cindex type predicate, for output port +Returns @code{#t} if @var{object} is an input port or output port +respectively, otherwise returns @code{#f}. Any object satisfying one of +these predicates also satisfies @code{vector?}. +@end deffn + +@deffn {procedure+} guarantee-input-port object +@deffnx {procedure+} guarantee-output-port object +These procedures check the type of @var{object}, signalling an error if it +is not an input port or output port, respectively. Otherwise they return +@var{object}. +@end deffn + +@deffn procedure current-input-port +@findex console-input-port +Returns the current input port. Initially, @code{current-input-port} +returns the value of @code{console-input-port}. +@end deffn + +@deffn procedure current-output-port +@findex console-output-port +Returns the current output port. Initially, @code{current-output-port} +returns the value of @code{console-output-port}. +@end deffn + +@deffn {procedure+} with-input-from-port input-port thunk +@var{Thunk} must be a procedure of no arguments. +@code{with-input-from-port} binds the current input port to +@var{input-port}, calls @var{thunk} with no arguments, restores the +current input port to its original value, and returns the result that +was returned by @var{thunk}. This temporary binding is performed the +same way as fluid binding of a variable, including the behavior in the +presence of continuations (@pxref{Fluid Binding}). +@end deffn + +@deffn {procedure+} with-output-to-port output-port thunk +@var{Thunk} must be a procedure of no arguments. +@code{with-output-to-port} binds the current output port to +@var{output-port}, calls @var{thunk} with no arguments, restores the +current output port to its original value, and returns the result that +was returned by @var{thunk}. This temporary binding is performed the +same way as fluid binding of a variable, including the behavior in the +presence of continuations (@pxref{Fluid Binding}). +@end deffn + +@defvr {variable+} console-input-port +@cindex port, console +@cindex input port, console +@cindex console, input port +@code{console-input-port} is an input port that reads from the terminal +keyboard (in unix, standard input). +@end defvr + +@defvr {variable+} console-output-port +@cindex output port, console +@cindex console, output port +@code{console-output-port} is an output port that writes to the terminal +screen (in unix, standard output). +@end defvr + +@deffn procedure close-input-port input-port +@cindex closing, of port +Closes @var{input-port} and returns an unspecified value. If +@var{input-port} is a file port, the file is closed. +@end deffn + +@deffn procedure close-output-port output-port +Closes @var{output-port} and returns an unspecified value. If +@var{output-port} is a file port, the file 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 +@findex close-input-port +@findex close-output-port +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-input-port} or @code{close-output-port}, depending on their +type. + +@findex canonicalize-input-filename +@findex canonicalize-output-filename +Before opening an input file, by whatever method, the @var{filename} +argument is converted to canonical form by the procedure +@code{canonicalize-input-filename}. Similarly, the @var{filename} +argument used to open an output file is converted using +@code{canonicalize-output-filename}. See those procedures' definitions +for details on the canonicalization process. For naive purposes, the +following guidelines can be used: @var{filename} is a character string +that is the name of the file; relative filenames (on unix, those not +beginning with @samp{/}) are interpreted relative to the directory in +which MIT Scheme was started. + +Implementation notes: + +@itemize @bullet +@item +On unix systems, opening an output file that already exists causes the +existing file to be removed and a new one opened in its place. However, +if the user does not have permission to write in the file's directory, +the file is truncated to zero length and overwritten. + +@item +File input ports always deliver @sc{ascii} characters, and file +output ports only accept @sc{ascii} characters. This will change if +someone ports MIT Scheme to a non-@sc{ascii} operating system. +@end itemize + +Here are the specific operations for file ports: + +@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 is signalled. + +@findex close-input-port +Use the procedure @code{close-input-port} to close the port opened by +this procedure. If an input port returned by this procedure is +reclaimed by the garbage collector, it is automatically closed. +@end deffn + +@deffn procedure open-output-file filename +@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 is signalled. If a file with the +given name already exists, if possible it will be deleted and a new file +opened in its place, or failing that the existing file will be truncated +and overwritten. + +@findex close-output-port +Use the procedure @code{close-output-port} to close the port opened by +this procedure. If an output port returned by this procedure is +reclaimed by the garbage collector, it is automatically closed. +@end deffn + +@deffn {procedure+} close-all-open-files +@cindex closing, of file port +This procedure closes all file ports (input and output) that are open at +the time that it is called. +@end deffn + +@deffn procedure call-with-input-file filename procedure +@deffnx procedure call-with-output-file filename procedure +@var{Procedure} must be a procedure of one argument. For +@code{call-with-input-file} the file specified by @var{filename} must +already exist; for @code{call-with-output-file}, if the file exists, if +possible it will be deleted and a new file opened in its place, or +failing that the existing file will be truncated and overwritten. + +These procedures call @var{procedure} with one argument: the port +obtained by opening the named file for input or output. If the file +cannot be opened, an 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 with-input-from-file filename thunk +@deffnx procedure with-output-to-file filename thunk +@cindex current input port, rebinding +@cindex current output port, rebinding +@var{Thunk} must be a procedure of no arguments. For +@code{with-input-from-file} the file specified by @var{filename} must +already exist; for @code{with-output-to-file}, if the file exists, if +possible it will be deleted and a new file opened in its place, or +failing that the existing file will be truncated and overwritten. + +@findex current-input-port +@findex current-output-port +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 closes the port. +@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, that can limit the length of the resulting +string to a given value. + +String input ports always deliver @sc{ascii} characters, and string +output ports only accept @sc{ascii} characters. This will change if +someone ports MIT Scheme to a non-@sc{ascii} operating system. + +@deffn {procedure+} with-input-from-string string thunk +@cindex current input port, rebinding +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 returned 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+} string->input-port string +@cindex string, converting to input port +@cindex construction, of string input port +Returns a new string port that delivers characters from @var{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. 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 +(with-output-to-string + (lambda () + (write 'abc))) @result{} "abc" +@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] +@findex with-output-to-truncated-string +Writes @var{object} to a string output port, and returns the resulting +newly allocated string. If @var{k} is supplied and not @code{#f}, the +output is truncated after @var{k} characters. Unlike +@code{with-output-to-truncated-string}, if @var{k} is specified, this +procedure always returns a string. There is no sure way to find out +whether or not the returned string was truncated. +@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 particular port. +Remember that to read from a file, you must first open a port to the +file.@footnote{Previous implementations of MIT Scheme treated +interactive ports specially: when certain of these procedures were +called, the input editor was temporarily enabled or disabled or the port +was temporarily switched between blocking and non-blocking modes. In +the current implementation, these procedures have no effect on the input +editor or the blocking mode.} + +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. +@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. +@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. However, if end of +file was encountered before any characters were read, @code{read-string} +returns an end-of-file object. + +@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 + +@node Output Procedures, Format, Input Procedures, Input/Output +@section Output Procedures +@cindex output procedures + +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}, 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 +that appear in the written representation are not enclosed in +doublequotes, and no characters are escaped within those strings. +Character objects appear in the representation as if written by +@code{write-char} instead of by @code{write}. @code{display} 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 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} returns an unspecified value. +@end deffn + +@deffn procedure newline [output-port] +@cindex newline character, output to port +Writes an end of line to @var{output-port} and returns an unspecified +value. Equivalent to @code{(write-char #\newline @var{output-port})}. +@end deffn + +@deffn {procedure+} write-line object [output-port] +Like @code{write}, except that it writes an end of line to +@var{output-port} before writing @var{object}'s representation. 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} and returns an unspecified +value. This is equivalent to writing the contents of string, one +character at a time using @code{write-char}, except that it is usually +much faster. + +@code{(write-string @var{string})} is the same as @code{(display +@var{string})} except that it is faster. Use @code{write-string} when you +know the argument is a string, and @code{display} when you don't. +@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} and returns an +unspecified value. On the console output port, this usually causes the +terminal 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} 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 is +equivalent to @code{(write-char #\page @var{output-port})}. +@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} +returns an unspecified value. +@end deffn + +@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. + +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 make 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 + +@code{(type-clash-error 'vector-ref "first" 'integer 'vector)} prints: + +@example +@group +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, Port Primitives, 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: first, an unparser state, and second, 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{unparser/standard-method}. The second is to define your +own method using the procedures @code{unparse-char}, +@code{unparse-string}, and @code{unparse-object}. 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+} unparser/standard-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}, if +supplied, must be @code{#f} or a procedure of two arguments. + +@cindex #[ as external representation +If @var{procedure} is not supplied, or is @code{#f}, the returned method +generates an external representation of this form: + +@example +#[@var{name} @var{hash}] +@end example + +@noindent +@findex display +@findex object-hash +Here @var{name} is the external representation of the argument +@var{name}, as generated by @code{display}, 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{object-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 includes the space +between @var{hash} and @var{output}. + +@item +@var{Procedure} is invoked on two arguments: the unparser state and the +object. + +@item +The closing bracket is written to the output port. +@end enumerate +@end deffn + +The following three procedures are useful when writing unparser methods. + +@deffn {procedure+} unparse-char unparser-state char +@findex write-char +Writes @var{char} to the output-port component of @var{unparser-state}, +and returns an unspecified value. Similar to @code{write-char}. +@end deffn + +@deffn {procedure+} unparse-string unparser-state string +@findex write-string +Writes @var{string} to the output-port component of +@var{unparser-state}, and returns an unspecified value. Similar to +@code{write-string}. +@end deffn + +@deffn {procedure+} unparse-object unparser-state object +@findex display +@findex write +Writes @var{object} to the output-port component of +@var{unparser-state}, and returns an unspecified value. @var{Object} is +generated either as if by @code{display} or as if by @code{write}, +depending on other components of @var{unparser-state}. +@end deffn + +@node Port Primitives, , Custom Output, Input/Output +@section Port Primitives +@cindex port primitives + +This section describes the low-level operations that can be used to +build and manipulate @sc{i/o} ports. + +The purpose of these operations is twofold: to allow programmers to +construct new kinds of @sc{i/o} ports, and to provide faster @sc{i/o} +operations than those supplied by the standard high level procedures. +The latter is useful because the standard @sc{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. + +@findex eq? +The abstract model of an @sc{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. +Typically the names are symbols, but any object that can be +discriminated by @code{eq?} may be used. + +The 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 +appropriate set of operations is implemented for every port. +@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 +* Input Port Primitives:: Input Port Primitives +* Output Port Primitives:: Output Port Primitives +@end menu + +@node Input Port Primitives, Output Port Primitives, Port Primitives, Port Primitives +@subsection Input Port Primitives +@cindex input port primitives + +@deffn {procedure+} make-input-port operations object +@cindex construction, of input port +Operations must be a list; each element is a list of two elements, the +name of the operation and the procedure that implements it. A new input +port is returned with the given operations and a state component of +@var{object}. @var{Operations} need not contain definitions for all of +the standard operations. @code{make-input-port} will provide defaults +for any standard operations that are not defined. At a minimum, the +operations @code{read-char}, @code{peek-char}, and @code{char-ready?} +must be defined. +@end deffn + +@deffn {procedure+} input-port/copy input-port object +@cindex copying, of input port +Returns a new copy of @var{input-port}, identical to the original except +that its state component is @var{object}. @var{Input-port} is not +modified. + +@code{input-port/copy} is normally used to speed up creation of input +ports. This is done by creating a template using +@code{make-input-port}; a dummy state component is supplied for the +template. Then @code{input-port/copy} is used to make a copy of the +template, supplying the copy with the correct state. This is useful +because @code{make-input-port} is somewhat slow, as it must parse the +@var{operations} list, provide defaulting for missing operations, etc. +@end deffn + +@deffn {procedure+} input-port/state input-port +Returns the state component of @var{input-port}. +@end deffn + +@deffn {procedure+} set-input-port/state! input-port object +Changes the state component of @var{input-port} to be @var{object}. +Returns an unspecified value. +@end deffn + +@deffn {procedure+} input-port/operation input-port name +Returns the procedure that implements the operation called @var{name}, +or @code{#f} if @var{input-port} has no such operation. +@end deffn + +@deffn {procedure+} input-port/custom-operation input-port name +Returns the procedure that implements the custom operation called +@var{name}. If @var{name} names a standard operation, or if +@var{input-port} has no such custom operation, @code{#f} is returned. +This is faster than @code{input-port/operation} if @var{name} is known +to be the name of a custom operation. +@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 + +The following are the standard operations on input ports. + +@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 + +@deffn {procedure+} input-port/operation/read-char input-port +@deffnx {procedure+} input-port/operation/peek-char input-port +@deffnx {procedure+} input-port/operation/discard-char input-port +@deffnx {procedure+} input-port/operation/char-ready? input-port +@deffnx {procedure+} input-port/operation/read-string input-port +@deffnx {procedure+} input-port/operation/discard-chars input-port +Each of these procedures returns the procedure that implements the +respective operation for @var{input-port}. Each is equivalent to, but +faster than, @code{input-port/operation} on the respective operation +name: + +@example +@group +(input-port/operation/read-char @var{input-port}) +(input-port/operation @var{input-port} 'read-char) +@end group +@end example +@end deffn + +@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 +Each of these procedures invokes the respective operation on +@var{input-port}. For example, the following are equivalent: + +@example +@group +(input-port/read-string @var{input-port} @var{char-set}) +((input-port/operation/read-string @var{input-port}) @var{input-port} @var{char-set}) +@end group +@end example +@end deffn + +@node Output Port Primitives, , Input Port Primitives, Port Primitives +@subsection Output Port Primitives +@cindex output port primitives + +@deffn {procedure+} make-output-port operations object +@cindex construction, of output port +Operations must be a list; each element is a list of two elements, the +name of the operation and the procedure that implements it. A new +output port is returned with the given operations and a state component +of @var{object}. @var{Operations} need not contain definitions for all +of the standard operations. @code{make-output-port} will provide +defaults for any standard operations that are not defined. At a +minimum, the operation @code{write-char} must be defined. +@end deffn + +@deffn {procedure+} output-port/copy output-port object +@cindex copying, of output port +Returns a new copy of @var{output-port}, identical to the original except +that its state component is @var{object}. @var{Output-port} is not +modified. + +@code{output-port/copy} is normally used to speed up creation of output +ports. This is done by creating a template using +@code{make-output-port}; a dummy state component is supplied for the +template. Then @code{output-port/copy} is used to make a copy of the +template, supplying the copy with the correct state. This is useful +because @code{make-output-port} is somewhat slow, as it must parse the +@var{operations} list, provide defaulting for missing operations, etc. +@end deffn + +@deffn {procedure+} output-port/state output-port +Returns the state component of @var{output-port}. +@end deffn + +@deffn {procedure+} set-output-port/state! output-port object +Changes the state component of @var{output-port} to be @var{object}. +Returns an unspecified value. +@end deffn + +@deffn {procedure+} output-port/operation output-port name +Returns the procedure that implements the operation called @var{name}, +or @code{#f} if @var{output-port} has no such operation. +@end deffn + +@deffn {procedure+} output-port/custom-operation output-port name +Returns the procedure that implements the custom operation called +@var{name}. If @var{name} names a standard operation, or if +@var{output-port} has no such custom operation, @code{#f} is returned. +This is faster than @code{output-port/operation} if @var{name} is known +to be the name of a custom operation. +@end deffn + +The following are the standard operations on output ports. + +@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-string output-port string +@cindex string, output to port +Writes @var{string} to @var{output-port} and returns an unspecified +value. Equivalent to writing the characters of @var{string}, one by +one, to @var{output-port}, but is often implemented more efficiently. +@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 + +@deffn {procedure+} output-port/operation/write-char output-port +@deffnx {procedure+} output-port/operation/write-string output-port +@deffnx {procedure+} output-port/operation/flush-output output-port +Each of these procedures returns the procedure that implements the +respective operation for @var{output-port}. Each is equivalent to, but +faster than, @code{output-port/operation} on the respective operation +name: + +@example +@group +(output-port/operation/write-char @var{output-port}) +(output-port/operation @var{output-port} 'write-char) +@end group +@end example +@end deffn + +@deffn {procedure+} output-port/write-char output-port char +@deffnx {procedure+} output-port/write-string output-port string +@deffnx {procedure+} output-port/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/write-char @var{output-port}) @var{output-port} @var{char}) +@end group +@end example +@end deffn + +The custom operation @code{x-size} is so useful that we provide a +procedure to call it: + +@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 79). + +@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 + +@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 + +@node File-System Interface, Error System, Input/Output, Top +@chapter File-System Interface +@cindex file-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 file 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 +A facility for reading the contents of a directory. +@end itemize + +@menu +* Pathnames:: Pathnames +* Working Directory:: Working Directory +* File Manipulation:: File Manipulation +* Directory Reader:: Directory Reader +@end menu + +@node Pathnames, Working Directory, File-System Interface, File-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 FORMAT.FASL.13 +TOPS-10 FORMAT.FAS[1,4] +ITS LISPIO;FORMAT FASL +MULTICS >udd>LispIO>format.fasl +TENEX FORMAT.FASL;13 +VAX/VMS [LISPIO]FORMAT.FAS;13 +UNIX /usr/lispio/format.fasl +@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}, 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:: Filenames and Pathnames +* Components of Pathnames:: Components of Pathnames +* Operations on Pathnames:: Operations on 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. In addition, +@code{->pathname} will convert other objects, such as symbols, into +pathnames. + +@deffn {procedure+} ->pathname object +@cindex construction, of pathname +Returns a pathname that is the equivalent of @var{object}. +@var{Object} must be a pathname, a string, or a symbol. If @var{object} +is a pathname, it is returned. If @var{object} is a string, this +procedure acts like @code{string->pathname}. If @var{object} is a +symbol, it is converted to a string, passed to @code{string->pathname}, +and the result returned. + +@example +@group +(->pathname "foo") @result{} #[pathname 65 "foo"] +(->pathname '/usr/morris) @result{} #[pathname 66 "/usr/morris"] +@end group +@end example +@end deffn + +@deffn {procedure+} string->pathname string +@cindex string, converting to pathname +Returns the pathname that corresponds to the filename @var{string}. +This operation is the inverse of @code{pathname->string}. +@end deffn + +@deffn {procedure+} pathname->string pathname +@findex string->pathname +Returns a newly allocated string that is the filename corresponding to +@var{pathname}. This operation is the inverse of +@code{string->pathname}. + +@example +@group +(pathname->string (string->pathname "/usr/morris/foo")) + @result{} "/usr/morris/foo" +@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 of MIT Scheme, this component is not used and should +always be @code{#f}. +@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. In the current implementation of MIT Scheme, this component +is not used and should always be @code{#f}. +@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). +@cindex directory, pathname component + +@item name +The name of a group of files that can be thought of as conceptually the +``same'' file. +@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. +@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. In the current implementation of MIT Scheme, this +component is not used and should always be @code{#f}. +@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}.@footnote{This +description is adapted from @cite{Common Lisp, The Language}, second +edition, section 23.1.1.} +@comment **** end CLTL **** + +Each component in a pathname is typically one of the following (with +some exceptions that will be described below): + +@table @asis +@item a string +This is a @dfn{literal component}. It is considered to be fully +specified. +@cindex literal component, of pathname +@cindex pathname component, literal +@cindex component, of pathname, literal + +@item @code{#f} +This is a @dfn{missing component}. It is considered to be unspecified. +@cindex #f, as pathname component +@cindex missing component, of pathname +@cindex pathname component, missing +@cindex component, of pathname, missing + +@item @code{wild} +This is a @dfn{wildcard component}. It is useful only when the pathname +is being used with the directory reader, where it means that the +pathname component matches anything. +@cindex wild, as pathname component +@cindex wildcard component, of pathname +@cindex pathname component, wildcard +@cindex component, of pathname, wildcard + +@item @code{unspecific} +This is an @dfn{unspecifiable component}. It is treated the same as a +missing component except that it is not considered to be missing for +purposes of merging or defaulting components. +@cindex unspecifiable component, of pathname +@cindex unspecific, as pathname component +@cindex component, of pathname, unspecific +@end table + +The directory and version pathname components are exceptions to these +rules in that they may never be strings, although the values @code{#f}, +@code{wild}, and @code{unspecific} are allowed with their usual +meanings. Here are the other values allowed for these components: + +@itemize @bullet +@item +A directory, if it is not one of the above values, must be 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. If the first +element in the list is the symbol @code{root}, 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. Otherwise, the directory is @dfn{relative}, meaning that 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 self, as pathname component +@cindex up, as pathname component +@cindex parent, of directory +Aside from the special case of @code{root}, which may only appear as the +first element of the list (if it appears at all), each element in the +list is either a string or the symbol @code{wild} (each with the same +meaning as described above), or one of these symbols: @code{self}, which +means the next directory in the sequence is the same as the previous +one, or @code{up}, which means the next directory is the ``parent'' of +the previous one. @code{self} and @code{up} correspond to the files +@file{.} and @file{..} in unix file systems. + +In file systems that do not have ``heirarchical'' structure, a specified +directory component will always be a list whose first element is +@code{root}. 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, +whiich is either a string or @code{wild}. In other words, a +non-heirarchical file system is treated as if it were heirarchical, but +the heirarchical 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 heirarchy. Fortunately few +such file systems are in common use today. + +@item +A version component may take the following values: 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; or +the symbol @code{oldest}, which means to choose the smallest version +number. In the future some other possible values may be added, e.g.@: +@code{installed}. Note that in the current implementation this +component is not used and should be @code{#f}. +@cindex newest, as pathname component +@cindex oldest, as pathname component +@cindex installed, as pathname component +@end itemize + +@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 '(root "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{} #f +(pathname-device x) @result{} #f +(pathname-directory x) @result{} (root "usr" "morris") +(pathname-name x) @result{} "foo" +(pathname-type x) @result{} "scm" +(pathname-version x) @result{} #f +@end group +@end example +@end deffn + +@deffn {procedure+} pathname-components pathname receiver +Calls @var{receiver} with the six components of @var{pathname}, and +returns the result yielded by @var{receiver}. + +@example +@group +(pathname-components (->pathname "/usr/morris/foo.scm") list) + @result{} (#f #f (root "usr" "morris") "foo" "scm" #f) +@end group +@end example +@end deffn + +@deffn {procedure+} pathname-new-host pathname host +@deffnx {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. + +@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 '("test" "morris")) + @result{} #[pathname 73 "test/morris/rel15"] +p + @result{} #[pathname 71 "/usr/blisp/rel15"] +@end group +@end example +@end deffn + +@deffn {procedure+} pathname-name-path pathname +Extracts the name, type, and version components of @var{pathname} and +returns a pathname with just these components. For example, + +@example +@group +(pathname-name-path (->pathname "/usr/blisp/rel5")) + @result{} #[pathname 69 "rel5"] +@end group +@end example +@end deffn + +@deffn {procedure+} pathname-directory-path pathname +Extracts the host, device, and directory components of @var{pathname} +and returns a pathname with just these components. + +@example +@group +(pathname-directory-path (->pathname "/usr/blisp/rel5")) + @result{} #[pathname 70 "/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 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. Otherwise, these file components are converted into a string, +and the string is added to the end of the list of directory components. +Note the difference between this procedure and +@code{pathname-directory-path}. + +@example +@group +(pathname-as-directory (->pathname "/usr/blisp/rel5")) + @result{} #[pathname "/usr/blisp/rel5/"] +@end group +@end example +@end deffn + +@deffn {procedure+} pathname-name-string pathname +Extracts the name, type, and version components of @var{pathname} and +returns a newly allocated filename (string) with just these components. +For example, + +@example +@group +(pathname-name-string (->pathname "/usr/blisp/rel5")) + @result{} "rel5" +@end group +@end example + +@code{pathname-name-string} could have been defined as follows: + +@example +@group +(define (pathname-name-string pathname) + (pathname->string (pathname-name-path pathname))) +@end group +@end example +@end deffn + +@deffn {procedure+} pathname-directory-string pathname +Extracts the host, device, and directory components of @var{pathname} +and returns a newly allocated filename (string) with just these +components. + +@example +@group +(pathname-directory-string (->pathname "/usr/blisp/rel5")) + @result{} "/usr/blisp/" +@end group +@end example + +@code{pathname-directory-string} could have been defined as follows: + +@example +@group +(define (pathname-directory-string pathname) + (pathname->string (pathname-directory-path pathname))) +@end group +@end example +@end deffn + +@node Operations on 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+} merge-pathnames pathname1 pathname2 +@cindex merging, of pathnames +@cindex defaulting, of pathname +Returns a pathname whose components are obtained by combining those of +@var{pathname1} and @var{pathname2}. The pathnames are combined by +components: if @var{pathname1} has a non-missing component, that is the +resulting component, otherwise the component from @var{pathname2} is +used. The directory component is handled specially: if both pathnames +have directory components that are lists, and the directory component +from @var{pathname1} is relative (i.e.@: does not start with @code{root}), +the the resulting directory component is formed by appending +@var{pathname1}'s component to @var{pathname2}'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 +@end deffn + +@deffn {procedure+} pathname-default-host pathname host +@deffnx {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 + +@deffn {procedure+} pathname-default pathname host 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 + host device directory + name type version) + (make-pathname (or (pathname-host pathname) host) + (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 + +@node Working Directory, File Manipulation, Pathnames, File-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) +A pathname may be absolute or relative. An @dfn{absolute pathname} is a +complete path from the top level of the file system to the destination +resource (under unix, a filename corresponding to an absolute pathname +begins with the slash character, @samp{/}). A @dfn{relative pathname} +is a partial path that's interpreted relative to the 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. + +@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->absolute-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 +using @code{->pathname}, @code{pathname->absolute-pathname}, and +@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. + +@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 +actual directory in the file system. + +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 canonicalized in exactly as does +@code{set-working-directory-pathname!}. The binding is performed in +exactly the same way as fluid binding of a variable (@pxref{Fluid +Binding}). +@end deffn + +@deffn {procedure+} pathname->absolute-pathname pathname +Converts @var{pathname} into an absolute pathname. If @var{pathname} is +relative, it is converted to absolute form starting at the current +working directory. If @var{pathname} is already an absolute pathname, +it is returned. +@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}. All pathnames are either +absolute or relative, so if this procedure returns @code{#f}, the +argument is a relative pathname. +@end deffn + +@node File Manipulation, Directory Reader, Working Directory, File-System Interface +@section File Manipulation + +@deffn {procedure+} file-exists? filename +@cindex existence, testing of file +Returns @code{#t} if @var{filename} is an existing file or directory; +otherwise returns @code{#f}. If the file is a symbolic link, this +procedure tests the existence of the file linked to, not the link +itself. +@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}. If +@var{target-filename} exists prior to this procedure's invocation, it is +deleted before the new output file is created. +@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+} canonicalize-input-filename filename +@cindex canonicalization, of filename +If @var{filename} refers to an existing file or directory, returns as a +string the absolute pathname of the file (or directory). If +@var{filename} doesn't refer to an existing file or directory, an error +is signalled. +@end deffn + +@deffn {procedure+} canonicalize-output-filename filename +Returns as a string the absolute pathname of @var{filename}, whether or +not the file or directory that @var{filename} refers to exists. + +@example +@group +(pwd) + @result{} #[pathname "/usr/morris/"] +(canonicalize-output-filename "foo") + @result{} "/usr/morris/foo" +@end group +@end example +@end deffn + +@deffn {procedure+} pathname->input-truename pathname +@cindex truename, of input file +Converts @var{pathname} into the corresponding absolute pathname. If +pathname doesn't exist, returns @code{#f}. +@end deffn + +@deffn {procedure+} pathname->output-truename pathname +@cindex truename, of output file +Converts @var{pathname} into the corresponding absolute pathname. +@end deffn + +@deffn {procedure+} file-modification-time filename +@cindex modification time, of file +Returns the modification time of @var{filename} as an exact integer. +The result may be compared to other modification times using ordinary +integer arithmetic. If @var{filename} names a file that does not exist, +returns @code{#f}. If @var{filename} names a symbolic link, this +returns the modification time of the file linked to, not the link +itself. +@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}. If @var{filename} names a +symbolic link, this examines the file linked to, not the link itself. +@end deffn + +@deffn {procedure+} file-symbolic-link? filename +@cindex symbolic link, predicate for +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, this procedure returns @code{#f}. +@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}. The information returned is a vector of 10 items: + +@enumerate +@item +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. + +@item +The number of links to the file. + +@item +The user id of the file's owner, an exact non-negative integer. + +@item +The group id of the file's group, an exact non-negative integer. + +@item +The last access time of the file, an exact non-negative integer. + +@item +The last modification time of the file, an exact non-negative integer. + +@item +The last change time of the file, an exact non-negative integer. + +@item +The size of the file in bytes. + +@item +The mode string of the file. This is a newly allocated string showing +the file's mode bits. + +@item +The inode number of the file, an exact non-negative integer. +@end enumerate +@end deffn + +@node Directory Reader, , File Manipulation, File-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''. +@end deffn + +@node Error System, Graphics, File-System Interface, Top +@chapter Error System + +@findex error +The Scheme error system provides a uniform mechanism for the signalling of +errors and other exceptional conditions. For most purposes, the only part +of the error system that is needed is the special form @code{error}, which +is used to signal simple errors, specifying a message and some irritant +objects (@pxref{Simple Errors}). In addition, an option to @code{error} +permits users to do simple formatting of their error messages (@pxref{Error +Messages}). + +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 the specification of 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 kind of behavior that is useful 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''. + +The taxonomy of condition types imposes a partial order on the types, +because each type is allowed to have multiple generalizations. This is +allowed because some condition types can be generalized in several +different ways. An example of this is ``floating-point divide by zero'', +which can be generalized to either a ``floating-point overflow'' or a +``divide by zero''. The latter generalization, ``divide by zero'', cannot +be a specialization of the former, because it can also be signalled by +arithmetic on numbers other than floating-point. + +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 conditions +Conditions 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 conditions +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 Classification of conditions +Each condition has a type, which is represented by a +@code{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. + +@item Packaging condition state +Each condition is represented by an explicit object. Condition objects +contain information about the nature of the condition as well as +information that describes the state of the computation from which the +condition arose. +@end table + +@menu +* Simple Errors:: Simple Errors +* Error Handler:: Error Handler +* Error Messages:: Error Messages +* Condition Types:: Condition Types +* Condition Instances:: Condition Instances +* Condition Signalling:: Condition Signalling +* Condition Handling:: Condition Handling +* Predefined Errors:: Predefined Errors +@end menu + +@node Simple Errors, Error Handler, Error System, Error System +@section Simple Errors + +@cindex irritants, of error (defn) +The simplest error-signalling mechanism is the special form +@code{error}. It allows the programmer to signal errors by specifying +an error message and providing a list of some objects (@dfn{irritants}) +that are relevant to the error. + +@deffn {special form+} error message irritant @dots{} +Signals an error. This special form expands into the following code: + +@example +(error-procedure @var{message} (list @var{irritant} @dots{}) (the-environment)) +@end example + +@noindent +@findex the-environment +The use of @code{the-environment} would normally force the environment +in which it appears to be an interpreter environment. However, the +compiler treats @code{error} expressions specially so that errors signalled +from compiled code do not supply the environment argument to +@code{error-procedure}. +@end deffn + +@deffn {procedure+} error-procedure message irritants environment +Signals an error. @var{Message} is normally a short string that +summarizes the error, and @var{irritants} is a list of objects that +contain interesting information about the error. @var{Environment} is +the environment in which the error occurred. + +Normally, the message and irritants are used to build a condition whose +type is @code{error-type:vanilla}, @var{environment} is attached to that +condition, and then the condition is signalled. However, if +@var{message} is a @code{condition-type} object, then that object is +used (instead of @code{error-type:vanilla}) to build the condition. + +The argument @var{environment} is used by the standard error handler. +Currently there is no mechanism to retrieve this information. +@end deffn + +@defvr {condition type+} error-type:vanilla +This is the error type used by @code{error-procedure} when it signals +anonymous errors. Do not use this type for signalling new errors, as some +of the system code expects to find the message in a special place for +errors of this type. This object is made public solely so that condition +handlers can be bound to it. +@end defvr + +@deffn {procedure+} warn message irritant @dots{} +This procedure takes arguments just like @code{error}, formats and prints a +message in the usual way, but does not signal an exception. The output +goes to the output-port of the nearest @code{cmdl} object. In the future +this may be made customizable in some ways, such as allowing conditional +error signalling based on a flag. +@end deffn + +@node Error Handler, Error Messages, Simple Errors, Error System +@section Error Handler + +@cindex standard error handler +@cindex error handler, standard +In the absence of more specific handling, errors invoke the +@dfn{standard error handler}. This handler normally prints an error +message and enters a new @sc{rep} loop. + +@deffn {procedure+} standard-error-handler condition +This procedure is used to handle error conditions that are not otherwise +taken care of. It can be useful when building custom error +handlers. +@end deffn + +While the standard error handler is executing, the following procedures +provide useful information. + +@deffn {procedure+} error-condition +This procedure returns the condition that was passed to the standard +error handler as its argument. If the standard error handler is not +executing, this procedure returns @code{#f}. +@end deffn + +@deffn {procedure+} error-message +@deffnx {procedure+} error-irritants +@deffnx {procedure+} error-continuation +These procedures extract standard components from @code{(error-condition)}. +@code{error-continuation} returns @code{#f} if @code{error-condition} +does. +@end deffn + +@node Error Messages, Condition Types, Error Handler, Error System +@section Error Messages + +The error system provides a simple formatting language that allows the +programmer to have some control over the printing of error messages. The +basic idea is as follows. + +@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, which is 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 #\newline) + (error-irritant/noise "within procedure") + procedure)) +@end group +@end example + +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 + +Note the use of a separate noise object for the newline. In general, for +characters such as newline or formfeed (i.e.@: non-graphic characters), this +is desirable since it makes it easier for the formatter to notice +formatting characters with special meanings and handle them specially +should it be necessary. + +Here are the operations supporting error messages: + +@deffn {procedure+} format-error-message message irritants port +@var{Message} must be a string, @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 + +@deffn {procedure+} error-irritant/noise? object +Returns @code{#t} if @var{object} was created by +@code{error-irritant/noise}; otherwise returns @code{#f}. +@end deffn + +@deffn {procedure+} error-irritant/noise-value noise +Returns the value of the noise object @var{noise}. This is the object that +was passed to @code{error-irritant/noise} as an argument when @var{noise} +was created. +@end deffn + +@deffn {procedure+} error-irritants/sans-noise +@findex error-irritants +This returns the value of @code{error-irritants} with the noise objects +removed. It could have been written: + +@example +@group +(define (error-irritants/sans-noise) + (list-transform-negative (error-irritants) + error-irritant/noise?)) +@end group +@end example +@end deffn + +@node Condition Types, Condition Instances, Error Messages, 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 +inheritance relationships between types. + +Condition types are defined by the following operations. Any argument +called @var{condition-type} is assumed to be a condition type +object. + +@deffn {procedure+} make-condition-type generalizations reporter +This procedure creates and returns a new condition type. +@var{Generalizations} must be a list of condition types; the resulting +condition type will be a specialization of each of these types. +@var{Reporter} is a procedure of two arguments, a condition instance and +an output port, which will write a concise description of the condition +on the output port. As a special option, @var{reporter} may be a +string, in which case a standard error message will be printed using +that string. +@end deffn + +@deffn {procedure+} condition-type? object +@cindex type predicate, for condition type +Returns @code{#t} if @var{object} is a condition type; otherwise returns +@code{#f}. +@end deffn + +@deffn {procedure+} guarantee-condition-type object +Signals an error if @var{object} is not a condition type. Returns +@var{object} as its value otherwise. +@end deffn + +@deffn {procedure+} condition-type/generalizations condition-type +Returns the generalizations of @var{condition-type}. This is the reflexive +and transitive closure of the @var{generalizations} argument to +@code{make-condition-type}, i.e.@: all of the members of +@var{generalizations} plus all of their generalizations as well. This list +always contains @var{condition-type}. +@end deffn + +@deffn {procedure+} condition-type/reporter condition-type +Returns the report procedure for @var{condition-type}. +@end deffn + +@deffn {procedure+} condition-type/properties condition-type +Each condition type contains a 1D table for associating arbitrary +properties with the condition type. This operation returns the table +associated with @var{condition-type}. +@end deffn + +@deffn {procedure+} condition-type/error? condition-type +@cindex error type (defn) +@cindex type, of error (defn) +This predicate is true only of condition types that are considered to be +errors. Condition types satisfying this predicate are treated specially +under certain cirumstances, and are sometimes referred to as @dfn{error +types}. + +The following two expressions are equivalent (as predicates): + +@example +@group +(condition-type/error? x) +(memq condition-type:error (condition-type/generalizations x)) +@end group +@end example +@end deffn + +@defvr {condition type+} condition-type:error +The value of this variable a condition type with no generalizations that +is used to mark condition types as being errors. +@end defvr + +@deffn {procedure+} make-error-type generalizations reporter +@findex make-condition-type +This operation is like @code{make-condition-type}, except that if none of +@var{generalizations} satisfies @code{condition-type/error?}, it adds +@code{condition-type:error} to the set of generalizations. +@end deffn + +@deffn {procedure+} error-type? object +@cindex type predicate, for error type +Returns @code{#t} if @var{object} is a condition type that satisfies +@code{condition-type/error?}; otherwise returns @code{#f}. +@end deffn + +@node Condition Instances, Condition Signalling, Condition Types, 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 +@dfn{condition} objects, also called @dfn{condition instances}. + +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 when condition handlers want to restart the +computation in some way, or sometimes for analyzing the computation to +learn more about the context in which the condition occurred. + +The following operations define the condition datatype. Any argument +called @var{condition} is assumed to be a condition object. + +@deffn {procedure+} make-condition condition-type irritants continuation +Makes a new condition instance, with a type of @var{condition-type}. +@var{Irritants} is a list of arbitrary objects, and @var{continuation} +must be a continuation, normally the continuation of the computation +which caused the condition. +@end deffn + +@deffn {procedure+} condition? object +@cindex type predicate, for condition instance +Returns true iff @var{object} is a condition instance. +@end deffn + +@deffn {procedure+} error? object +@cindex type predicate, for error instance +@findex condition-type/error? +Returns @code{#t} if @var{object} is a condition instance that satisfies +@code{condition/error?}; otherwise returns @code{#f}. +@end deffn + +@deffn {procedure+} guarantee-condition object +Signals an error if @var{object} is not a condition instance. Returns +@var{object} otherwise. +@end deffn + +@deffn {procedure+} condition/type condition +Returns the condition type associated with @var{condition}. +@end deffn + +@deffn {procedure+} condition/irritants condition +Returns the irritants associated with @var{condition}. +@end deffn + +@deffn {procedure+} condition/continuation condition +Returns the continuation associated with @var{condition}. +@end deffn + +@deffn {procedure+} condition/write-report condition [output-port] +Writes a concise description of @var{condition} to @var{output-port}, +which defaults to the current output port. +@end deffn + +@deffn {procedure+} condition/report-string condition +Returns a newly allocated string that is a concise description of +@var{condition}. +@end deffn + +@deffn {procedure+} condition/properties condition +Each condition instance contains a 1D table for associating arbitrary +properties with the condition. This procedure returns the table +associated with @var{condition}. +@end deffn + +@deffn {procedure+} condition/internal? condition +This predicate is true of certain conditions that normally should not be +handled by user code. Condition handlers that handle ``all'' conditions +should ignore conditions satisfying this predicate, unless the handler's +writer has a good understanding of internal conditions. +@end deffn + +@deffn {procedure+} condition/generalizations condition +@deffnx {procedure+} condition/error? condition +@deffnx {procedure+} condition/reporter condition +These operations access the corresponding components in the type of +@var{condition}. For example, the following expressions are +equivalent: + +@example +(condition/generalizations condition) +(condition-type/generalizations (condition/type condition)) +@end example + +@cindex error condition (defn) +@cindex condition, error (defn) +Note that condition instances satisfying the predicate +@code{condition/error?} are sometimes referred to as @dfn{error +conditions}, or even @dfn{errors}. +@end deffn + +@node Condition Signalling, Condition Handling, Condition Instances, 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}, 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. + +There is a single procedure responsible for signalling conditions. All +other signalling mechanisms go through this procedure: + +@deffn {procedure+} signal-condition condition [default-handler] +Signals @var{condition}. @var{Default-handler}, if given, must be a +procedure of one argument. The signalling procedure attempts to find a +handler for the condition, using the following rules: + +@itemize @bullet +@item +The set of condition handlers is searched, until it finds one that will +handle any of the condition types specified by the generalizations of +@var{condition}. Each handler specifies, at the time it is bound, a set of +condition types it will handle; if the intersection of that set and +@var{condition}'s generalizations is not empty, the handler is +selected. +@cindex condition handler +@cindex handler, of condition + +If a handler is found, it is invoked on @var{condition}. If it returns +@code{#f}, that means the handler has declined to handle the condition +and the search continues. Otherwise the handler's value is returned as +the value of @code{signal-condition}. + +@item +If no condition handler is found, and the argument @var{default-handler} is +supplied, it is invoked on @var{condition}; its value is returned as the +value of @code{signal-condition}. + +@item +Otherwise, @code{#f} is returned, indicating that no handler could be +found. +@end itemize +@end deffn + +@deffn {procedure+} signal-error condition +@findex standard-error-handler +Signals @var{condition}, which must be a condition instance. If this +condition is not otherwise handled, the standard error handler is +invoked. Equivalent to @code{(signal-condition @var{condition} +standard-error-handler)}. +@end deffn + +@node Condition Handling, Predefined Errors, Condition Signalling, Error System +@section Condition Handling + +@cindex condition handling (defn) +@cindex handling, of condition (defn) +@dfn{Condition handling} refers to the act of defining the behavior of a +signalled condition. This is controlled by the binding of +@dfn{condition handlers}. + +@cindex condition handler (defn) +@cindex handler, of condition (defn) +@findex signal-condition +A @dfn{condition handler} is a procedure of one argument. When a handler +is invoked by @code{signal-condition}, a condition is supplied to +the handler as its argument. The handler may return a value: if the value +is @code{#f}, this indicates that the handler has decided not to handle +this particular condition. In that case, @code{signal-condition} continues +its search for another handler. Otherwise the value returned by the +handler is returned as the value of @code{signal-condition}. + +@cindex resignalling, of condition (defn) +Often, though, the handler will not return a value. Usually a condition +handler will exit by invoking some continuation. Sometimes it will +signal a different condition instead, or signal the same condition +again. This latter action, @dfn{resignalling} the same condition, is +equivalent to returning @code{#f} from the handler. This is because +when the handler is invoked, the set of condition-handler bindings is +unwound to the point at which the handler was bound. In other words, +when a condition handler is bound, the set of condition handlers that is +in effect at the time of binding is the set that will be in effect when +the handler is invoked. + +@cindex binding, of condition handler (defn) +@cindex condition handler, binding (defn) +A condition handler is @dfn{bound} by specifying that it will handle a +condition whose generalizations intersect a given set of condition types. +Condition handlers are bound using a mechanism very similar to fluid +binding of variables. A condition handler binding has a dynamic extent +rather than a lexical scope, that is, it is effective for a specified time +segment rather than for a specified code segment. + +The order in which the bindings are searched (by @code{signal-condition}) +is the opposite from the order in which they are bound. Thus, more +recently bound handlers appear earlier in the search order. + +@deffn {procedure+} bind-condition-handler condition-types handler thunk +@findex condition/internal? +Executes @var{thunk}, handling any condition whose generalizations +intersect @var{condition-types} by passing it to @var{handler}. +@var{Condition-types} must be a list of condition-type objects. If +@var{condition-types} is the empty list, it means @var{handler} should +handle @emph{all} conditions, regardless of their type; such handlers +should ignore conditions satisfying the predicate +@code{condition/internal?}. +@end deffn + +@node Predefined Errors, , Condition Handling, Error System +@section Predefined Errors + +@defvr {condition type+} error-type:wrong-type-argument +Signalled when the argument to a procedure is determined to have an +incorrect type. For example, this error is signalled by @code{car} if +its argument is not a pair. This is a specialization of +@code{error-type:illegal-argument}. +@end defvr + +@deffn {procedure+} error:illegal-datum object [procedure-name] +Signals @code{error-type:wrong-type-argument}. @var{Object} is the +argument in question, and @code{procedure-name}, if supplied, is the +name of the procedure that determined the argument's incorrectness. +@end deffn + +@defvr {condition type+} error-type:bad-range-argument +Signalled when the argument to a procedure is determined to have the +correct type but is not in the acceptable range. For example, this +error is signalled by @code{vector-ref} if its second argument is an +exact negative integer. This is a specialization of +@code{error-type:illegal-argument}. +@end defvr + +@deffn {procedure+} error:datum-out-of-range object [procedure-name] +Signals @code{error-type:bad-range-argument}. @var{Object} is the +argument in question, and @code{procedure-name}, if supplied, is the +name of the procedure that determined the argument's incorrectness. +@end deffn + +@defvr {condition type+} error-type:illegal-argument +This type is not signalled -- one of its specializations is signalled +when the argument to a procedure is determined to be incorrect in some +fashion. +@end defvr + +@defvr {condition type+} error-type:open-file +Signalled if an error occurs while trying to open a file for input or +output. +@end defvr + +@defvr {condition type+} error-type:file +This type is not signalled -- one of its specializations is signalled +when any @sc{i/o} error occurs. The name of this type is a misnomer; it +can be signalled by any @sc{i/o} operation, whether or not it involves +files. +@end defvr + +@node Graphics, Procedure Index, 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 two types of graphics device +are implemented. + +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. + +@menu +* Opening and Closing of Graphics Devices:: Opening and Closing of Graphics Devices +* Coordinates for Graphics:: Coordinates for Graphics +* Drawing Graphics:: Drawing Graphics +* Characteristics of Graphics Output:: Characteristics of Graphics Output +* Buffering of Graphics Output:: Buffering of Graphics Output +* Clipping of Graphics Output:: Clipping of Graphics Output +* Custom Graphics Operations:: Custom Graphics Operations +* X Graphics:: X Graphics +* Starbase Graphics:: Starbase Graphics +@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 @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}. This is useful because a given graphics +device type may exist as an object in the Scheme runtime environment +even though the primitive procedures required to support that type do +not. This predicate determines when full support is available. +@end deffn + +@deffn {procedure+} make-graphics-device graphics-device-type object @dots{} +This operation creates a graphics device object. The first argument is +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). This procedure opens and initializes the +device, which remains valid until explicitly closed by the procedure +@code{graphics-close}. In the current implementation of MIT +Scheme, if this object is garbage-collected, the graphics device remains +open, and any resources it is using are not released. In the future the +garbage collector may be changed to automatically close such devices. +@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 x coordinates +increasing to the right and 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. Thus, 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}. It is 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}. It is unaffected by the +current drawing mode. + +This is equivalent to + +@example +(lambda (device x y) + (graphics-bind-drawing-mode device 0 + (lambda () + (graphics-draw-point device x y)))) +@end example +@end deffn + +@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 0 to 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 0 to 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}. It 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, X Graphics, 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 +(graphics-draw-point device x y) +(graphics-operation device 'draw-point x y) +@end example + +For information on the custom operations for a particular device, see +the documentation for its type. +@end deffn + +@node X Graphics, Starbase Graphics, Custom Graphics Operations, Graphics +@section X Graphics +@cindex X graphics + +@cindex X window system +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. + +@menu +* X Graphics Type:: X Graphics Type +* Utilities for X Graphics:: Utilities for X Graphics +* Custom Operations on X Graphics Devices:: Custom Operations on X Graphics Devices +@end menu + +@node X Graphics Type, Utilities for X Graphics, X Graphics, X Graphics +@subsection X Graphics Type + +@defvr {variable+} x-graphics-device-type +This is the graphics device type for X windows. X windows are opened as +follows: + +@example +(make-graphics-device x-graphics-device-type + @var{display} + @var{geometry} + #!optional @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. 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 and not +@code{#f}, prevents the window from being mapped after it is +created. + +@cindex resources, X graphics +@cindex X resources, graphics +The window is initialized using the resource name +@code{"scheme-graphics"}, and is sensitive to the following resource +properties: + +@example +@group +Property Class Default +-------- ----- ------- +geometry Geometry @r{[none]} +font Font 9x15 +borderWidth BorderWidth 2 +internalBorder BorderWidth @r{[border width]} +background Background white +foreground Foreground black +borderColor BorderColor @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"}. +@end defvr + +@node Utilities for X Graphics, Custom Operations on X Graphics Devices, X Graphics Type, X Graphics +@subsection Utilities for X Graphics + +@deffn {procedure+} x-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 the +usual X display name; however, @code{#f} is also allowed, meaning to use +the value of the unix environment variable @code{DISPLAY}. +@end deffn + +@deffn {procedure+} x-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 +(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 example + +Note that the @var{x} and @var{y} arguments cannot distinguish between +@code{+0} and @code{-0}, even though those 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. +@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. 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 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, the function returns +false. +@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 unmap-window +These operations control the mapping of windows. They correspond +directly to the Xlib procedures @code{XMapWindow} and +@code{XUnmapWindow}. +@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 the +Xlib procedure @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 the Xlib +procedure @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 the Xlib procedure +@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 starbase-filename +On Hewlett-Packard computers that support Starbase graphics, this +operation returns a character string that can be used to open the +device's window as a Starbase graphics device using the ``sox11'' +driver. Note that the default distribution of Scheme for HP computers +does not include support for Starbase --- you must rebuild the microcode +to get this support. +@end defop + +@node Starbase Graphics, , X Graphics, Graphics +@section Starbase Graphics +@cindex starbase graphics + +On Hewlett-Packard computers under the HP-UX operating system, Scheme +supports graphics through the Starbase graphics library. Note that the +default distribution of Scheme for HP computers does not include support +for Starbase --- you must rebuild the microcode to get this support. + +@defvr {variable+} starbase-graphics-device-type +This is the device type for Starbase graphics devices. A Starbase +device is opened as follows: + +@example +(make-graphics-device starbase-graphics-device-type + @var{device-name} + @var{driver-name}) +@end example + +where @var{device-name} and @var{driver-name} are strings that are used +as the device and driver arguments to the Starbase @code{gopen} call. +The device is opened with kind @code{OUTDEV} and mode @code{0}. The +device is initialized to have a mapping mode of @code{DISTORT}, and a +line color index of @code{1}. +@end defvr + +@defop {operation+} starbase-graphics-device write-image-file filename invert? +This operation writes an image of the Starbase device's display in the +file specified by @var{filename}. The image is formatted to print on an +HP Laserjet printer. Normally pixels with a color index of 0 are not +drawn by the printer, and all other pixels are; this results in the +background being white and the foreground being black in the printed +image. If @var{invert?} is not @code{#f}, this is reversed: the +background is printed as black and the foreground is not printed. +@end defop + +@defop {operation+} starbase-graphics-device color-map-size +Returns, as an exact non-negative integer, the number of entries in the +color map for the device. +@end defop + +@defop {operation+} starbase-graphics-device define-color color-index red green blue +Defines the color associated with the color-map index @var{color-index}. +@var{Color-index} must be an exact non-negative integer strictly less +than the number of entries in the color map. @var{Red}, @var{green}, +and @var{blue} must be real numbers in the range 0 to 1 inclusive, which +define the color to be put in the map. +@end defop + +@defop {operation+} starbase-graphics-device set-line-color color-index +Changes the foreground color used in graphics operations for this +device. @var{Color-index} must be an exact non-negative integer +strictly less than the number of entries in the color map. Graphics +drawn after this operation is invoked will appear in this new color. +@end defop + +The text drawn by a Starbase device is controlled by the following +characteristics: + +@table @asis +@item Aspect +The @dfn{aspect} of a character is its height-to-width ratio, a real +number. By default, this has the value @code{1}. +@cindex aspect, of graphics character (defn) + +@item Height +The @dfn{height} of a character in virtual device coordinates, a real +number. This is measured along the ``up vector'', which is defined by +the slant of the character. By default, the height is @code{.1}. +@cindex height, of graphics character (defn) + +@item Rotation +The @dfn{rotation} of a character defines the direction in which the +characters are drawn. It is specified as a real number in degrees, but +only 4 values have any meaning: @code{0}, @code{90}, @code{180}, and +@code{270}. @code{0} draws left-to-right with upright characters; +@code{90} draws top-to-bottom with characters on their right side; +@code{180} draws right-to-left with upside-down characters; @code{270} +draws bottom-to-top with characters on their left side. The default +rotation is @code{0}. +@cindex rotation, of graphics character (defn) + +@item Slant +The @dfn{slant} of a character defines the ``up vector''; it is a real +number which is the tangent of the angle between the character's +``vertical'' (defined by the rotation), and the ``up vector'', measured +clockwise. The default slant is @code{0}. +@cindex slant, of graphics character (defn) +@end table + +@defop {operation+} starbase-graphics-device text-aspect +@defopx {operation+} starbase-graphics-device text-height +@defopx {operation+} starbase-graphics-device text-rotation +@defopx {operation+} starbase-graphics-device text-slant +These operations return the current values of the text +characteristics. +@end defop + +@defop {operation+} starbase-graphics-device set-text-aspect aspect +@defopx {operation+} starbase-graphics-device set-text-height height +@defopx {operation+} starbase-graphics-device set-text-rotation rotation +@defopx {operation+} starbase-graphics-device set-text-slant slant +These operations alter the current values of the text characteristics. +They have no effect on text drawn prior to their invocation. +@end defop + +@node Procedure Index, Concept Index, Graphics, Top +@unnumbered Index of Procedures, Special Forms, and Variables +@printindex fn + +@node Concept Index, , Procedure Index, Top +@unnumbered Index of Concepts +@printindex cp + +@summarycontents +@contents + +@c Local Variables: +@c eval: (auto-save-mode -1) +@c End: + +@bye diff --git a/v7/doc/user-manual/user.texinfo b/v7/doc/user-manual/user.texinfo new file mode 100644 index 000000000..865885223 --- /dev/null +++ b/v7/doc/user-manual/user.texinfo @@ -0,0 +1,2028 @@ +\input texinfo @c -*-Texinfo-*- +@tex +\special{twoside} +@end tex +@c %**start of header +@setfilename user.info +@settitle MIT Scheme User's Manual +@c %**end of header +@setchapternewpage odd +@synindex vr fn + +@ifinfo +This file documents the use of MIT Scheme. + +Copyright @copyright{} 1991 Massachusetts Institute of Technology + +This material was developed by the Scheme project at the Massachusetts +Institute of Technology, Department of Electrical Engineering and Computer +Science. Permission to copy this document, to redistribute it, and to use +it for any purpose is granted, subject to the following restrictions and +understandings. + +@enumerate +@item +Any copy made of this document must include this copyright notice in +full. + +@item +Users of this document agree to make their best efforts (a) to return to +the MIT Scheme project any improvements or extensions that they make, so +that these may be included in future releases; and (b) to inform MIT of +noteworthy uses of this document. + +@item +All materials developed as a consequence of the use of this document shall +duly acknowledge such use, in accordance with the usual standards of +acknowledging credit in academic research. + +@item +MIT has made no warrantee or representation that the contents of this +document will be error-free, and MIT is under no obligation to provide any +services, by way of maintenance, update, or otherwise. + +@item +In conjunction with products arising from the use of this material, there +shall be no use of the name of the Massachusetts Institute of Technology +nor of any adaptation thereof in any advertising, promotional, or sales +literature without prior written consent from MIT in each case. +@end enumerate +@end ifinfo + +@titlepage +@title{MIT Scheme User's Manual} +@subtitle Edition 0.9 +@subtitle for Scheme Release 7.1 +@subtitle DRAFT: @today{} +@author by Chris Hanson + +@page + +@vskip 0pt plus 1filll +Copyright @copyright{} 1991 Massachusetts Institute of Technology + +This material was developed by the Scheme project at the Massachusetts +Institute of Technology, Department of Electrical Engineering and Computer +Science. Permission to copy this document, to redistribute it, and to use +it for any purpose is granted, subject to the following restrictions and +understandings. + +@enumerate +@item +Any copy made of this document must include this copyright notice in +full. + +@item +Users of this document agree to make their best efforts (a) to return to +the MIT Scheme project any improvements or extensions that they make, so +that these may be included in future releases; and (b) to inform MIT of +noteworthy uses of this document. + +@item +All materials developed as a consequence of the use of this document shall +duly acknowledge such use, in accordance with the usual standards of +acknowledging credit in academic research. + +@item +MIT has made no warrantee or representation that the contents of this +document will be error-free, and MIT is under no obligation to provide any +services, by way of maintenance, update, or otherwise. + +@item +In conjunction with products arising from the use of this material, there +shall be no use of the name of the Massachusetts Institute of Technology +nor of any adaptation thereof in any advertising, promotional, or sales +literature without prior written consent from MIT in each case. +@end enumerate +@end titlepage + +@node Top, Running Scheme, (dir), (dir) + +@menu +* Running Scheme:: Running Scheme +* REPL:: The Read-Eval-Print Loop +* Debugging:: Debugging +* Loading Files:: Loading Files +* World Images:: World Images +* Compiling Files:: Compiling Files +* GNU Emacs Interface:: GNU Emacs Interface +* Edwin:: Edwin +* Variable Index:: Variable, Declaration, and Option Index +* Key Index:: Key Index +* Concept Index:: Concept Index + + --- The Detailed Node Listing --- + +Running Scheme + +* Basics of Starting Scheme:: Basics of Starting Scheme +* Command-Line Options:: Command-Line Options +* Environment Variables:: Environment Variables +* Leaving Scheme:: Leaving Scheme + +The Read-Eval-Print Loop + +* The Prompt and Level Number:: The Prompt and Level Number +* Interrupting:: Interrupting +* Proceeding:: Proceeding +* The Current REPL Environment:: The Current REPL Environment + +Debugging + +* Subproblems and Reductions:: Subproblems and Reductions +* Debugger:: The Debugger + +Compiling Files + +* Compilation Procedures:: Compilation Procedures +* Declarations:: Declarations + +Declarations + +* Standard Names:: Standard Names +* In-line Coding:: In-line Coding +* Operator Reduction:: Operator Reduction +@end menu + +@node Running Scheme, REPL, Top, Top +@chapter Running Scheme + +This chapter describes how to run MIT Scheme on a unix system. It also +describes the command-line options and environment variables that affect +how Scheme runs. + +@menu +* Basics of Starting Scheme:: Basics of Starting Scheme +* Command-Line Options:: Command-Line Options +* Environment Variables:: Environment Variables +* Leaving Scheme:: Leaving Scheme +@end menu + +@node Basics of Starting Scheme, Command-Line Options, Running Scheme, Running Scheme +@section Basics of Starting Scheme + +Usually, MIT Scheme is invoked by typing + +@example +scheme +@end example + +@noindent +at your operating system's command interpreter. Scheme will load +itself, clear the screen, and print something like this: + +@example +Scheme saved on Monday December 10, 1990 at 9:55:37 PM + Release 7.1.0 (beta) + Microcode 11.59 + Runtime 14.104 +@end example + +@noindent +This information, which can be printed again by evaluating + +@findex identify-world +@lisp +(identify-world) +@end lisp + +@cindex release number +@cindex microcode, version +@cindex runtime system, version +@cindex version numbers +@noindent +tells you the following version information. ``Release'' is the release +number for the entire Scheme system. This number is changed each time a +new version of Scheme is released. An ``(alpha)'' or ``(beta)'' +following the release number indicates that this is a alpha- or +beta-test release. ``Microcode'' is the version number for the part of +the system that is written in C. ``Runtime'' is the version number for +the part of the system that is written in Scheme. + +@cindex subsystem versions +@cindex SF, version +@cindex compiler, version +@cindex Edwin, version +@cindex student package, version +@cindex compatibility package, version +Following this there may be additional version numbers for specific +subsystems. @samp{SF} refers to the scode optimization program +@code{sf}, @samp{Liar} is the native-code compiler, @samp{Edwin} is the +Emacs-like text editor, and @samp{Student} is the S&ICP compatibility +package. + +@cindex compiler, starting +If the compiler is supported for your machine, you can invoke it by +giving Scheme the @samp{-compiler} option: + +@example +scheme -compiler +@end example + +@noindent +This option causes Scheme to use a larger constant space and heap, and +to load the world image containing the compiler. + +@cindex init file +Scheme supports @dfn{init files}: if the file @file{~/.scheme.init} +exists, it is loaded immediately after the identification banner, and +before the input prompt is printed. The @code{-no-init-file} command +line option causes Scheme to ignore the @file{~/.scheme.init} file (see +@xref{Command-Line Options}). + +@node Command-Line Options, Environment Variables, Basics of Starting Scheme, Running Scheme +@section Command-Line Options + +Scheme accepts the following command-line options. The options may +appear in any order, but they must all appear before any other +arguments on the command line. (At present, any arguments other than +these options will generate a warning message when Scheme starts. In +the future, there will be an advertised mechanism by which the extra +arguments can be handled by user code.) + +@table @code + +@item -band @var{filename} +@findex -band +@findex MITSCHEME_BAND +@cindex world image +@cindex band +Specifies the initial world image file (@dfn{band}) to be loaded. +Searches for @var{filename} in the working directory and the library +directories, using the full pathname of the first readable file of that +name. If @var{filename} is an absolute pathname (on unix, this means it +starts with @samp{/}), then no search occurs --- @var{filename} is +tested for readability and then used directly. If this option isn't +given, the filename is the value of the environment variable +@code{MITSCHEME_BAND}, or if that isn't defined, @file{runtime.com}; in +these cases the library directories are searched, but not the working +directory. + +@item -compiler +@findex -compiler +@findex MITSCHEME_COMPILER_BAND +This option specifies defaults appropriate for loading the compiler. It +specifies the use of large sizes, exactly like @code{-large}. If the +@code{-band} option is also specified, that is the only effect of this +option. Otherwise, the default band's filename is the value of the +environment variable @code{MITSCHEME_COMPILER_BAND}, if defined, or +@file{compiler.com}; the library directories are searched to locate this +file. Note that the @code{-compiler} option is available only on +machines with compiled-code support. + +@item -edwin +@findex -edwin +@findex MITSCHEME_EDWIN_BAND +This option specifies defaults appropriate for loading the editor. It +specifies the use of large sizes, exactly like @code{-large}. If the +@code{-band} option is also specified, that is the only effect of this +option. Otherwise, the default band's filename is the value of the +environment variable @code{MITSCHEME_EDWIN_BAND}, if defined, or +@file{edwin.com}; the library directories are searched to locate this +file. Note that the @code{-edwin} option is available only on machines +with compiled-code support. + +@item -no-init-file +@findex -no-init-file +This option causes Scheme to ignore the @file{~/.scheme.init} file, +normally loaded automatically when Scheme starts (if it exists). + +@item -eval +@findex -eval +This option causes Scheme to evaluate the expressions following it on +the command line, up to (but not including) the next option that starts +with a hyphen. The expressions are evaluated in the +@code{user-initial-environment}. + +@item -load +@findex -load +This option causes Scheme to load the files (or lists of files) +following it on the command line, up to (but not including) the next +option that starts with a hyphen. The files are loaded in the +@code{user-initial-environment} using the default syntax table. + +@item -large +@findex -large +Specifies that large heap, constant, and stack sizes should be used. +These are specified by the environment variables + +@group +@findex MITSCHEME_LARGE_HEAP +@findex MITSCHEME_LARGE_CONSTANT +@findex MITSCHEME_LARGE_STACK +@example +MITSCHEME_LARGE_HEAP +MITSCHEME_LARGE_CONSTANT +MITSCHEME_LARGE_STACK +@end example +@end group + +@noindent +If this option isn't given, the small sizes are used, specified by the +environment variables + +@group +@findex MITSCHEME_SMALL_HEAP +@findex MITSCHEME_SMALL_CONSTANT +@findex MITSCHEME_SMALL_STACK +@example +MITSCHEME_SMALL_HEAP +MITSCHEME_SMALL_CONSTANT +MITSCHEME_SMALL_STACK +@end example +@end group + +@noindent +There are reasonable built-in defaults for all of these environment +variables, should any of them be undefined. Note that any or all of the +defaults can be individually overridden by the @code{-heap}, +@code{-constant}, and @code{-stack} options. + +@findex print-gc-statistics +Note: the Scheme procedure @code{(print-gc-statistics)} shows how much +heap and constant space is available and in use. + +@item -heap @var{blocks} +@findex -heap +Specifies the size of the heap in 1024-word blocks. Overrides any +default. Normally two such heaps are allocated; @code{bchscheme} +allocates only one, and uses a disk file for the other. + +@item -constant @var{blocks} +@findex -constant +Specifies the size of constant space in 1024-word blocks. Overrides any +default. Constant space holds the compiled code for the runtime system +and other subsystems. + +@item -stack @var{blocks} +@findex -stack +Specifies the size of the stack in 1024-word blocks. Overrides any +default. This is Scheme's stack, NOT the unix stack used by C programs. + +@item -option-summary +@findex -option-summary +Causes Scheme to write an option summary to standard error. This shows +the values of all of the settable option variables. + +@item -emacs +@findex -emacs +Specifies that Scheme is running as a subprocess of GNU Emacs. This +option is automatically supplied by GNU Emacs, and should not be given +under other circumstances. + +@item -interactive +@findex -interactive +If this option isn't specified, and Scheme's standard @sc{i/o} is not a +terminal, Scheme will detach itself from its controlling terminal. This +will prevent it from getting signals sent to the process group of that +terminal. If this option is specified, Scheme will not detach itself +from the controlling terminal. + +This detaching behavior is useful for running Scheme as a background +job. For example, using the C shell in unix, the following will run +Scheme as a background job, redirecting its input and output to files, +and preventing it from being killed by keyboard interrupts or by logging +out: + +@example +scheme < /usr/cph/foo.in >& /usr/cph/foo.out & +@end example + +@item -nocore +@findex -nocore +Specifies that Scheme should not generate a core dump under any +circumstances. If this option is not given, and Scheme terminates +abnormally, you will be prompted to decide whether a core dump should be +generated. + +@item -library @var{path} +@findex -library +@findex MITSCHEME_LIBRARY_PATH +Sets the library search path to @var{path}. This is a colon-separated +list of directories that is searched to find various library files, such +as bands. If this option is not given, the value of the environment +variable @code{MITSCHEME_LIBRARY_PATH} is used; if that isn't defined, +@file{/usr/local/lib/mit-scheme} is used. + +@item -utabmd @var{filename} +@item -utab @var{filename} +@findex -utabmd +@findex -utab +@findex MITSCHEME_UTABMD_FILE +Specifies that @var{filename} contains the microcode tables (the +microcode tables are information that informs the runtime system about +the microcode's structure). @var{Filename} is searched for in the +working directory and the library directories. If this option isn't +given, the filename is the value of the environment variable +@code{MITSCHEME_UTABMD_FILE}, or if that isn't defined, +@file{utabmd.bin}; in these cases the library directories are searched, +but not the working directory. + +@code{-utab} is an alternate name for the @code{-utabmd} option. At +most one of these options may be given. + +@item -fasl @var{filename} +@findex -fasl +Specifies that a @dfn{cold load} should be performed, using +@var{filename} as the initial file to be loaded. If this option isn't +given, a normal load is performed instead. This option may not be used +together with the @code{-band} option. This option is useful only for +maintainance and development of the MIT Scheme runtime system. + +@item -gc-directory @var{directory} +@findex -gc-directory +@findex MITSCHEME_GC_DIRECTORY +Specifies that @var{directory} should be used to create files for +garbage collection. This option is recognized only by @code{bchscheme}. +If the option is not given, the value of environment variable +@code{MITSCHEME_GC_DIRECTORY} is used instead, and if that is not +defined, @file{/tmp} is used. + +@item -gc-drone @var{program} +@findex -gc-drone +@findex MITSCHEME_GC_DRONE +Specifies that @var{program} should be used as the drone program for +overlapped I/O during garbage collection. This option is recognized +only by @code{bchscheme}. If the option is not given, the value of +environment variable @code{MITSCHEME_GC_DRONE} is used instead, and if +that is not defined, @file{gcdrone} is used. + +@item -gc-end-position @var{number} +@findex -gc-end-position +@findex MITSCHEME_GC_END_POSITION +This option is recognized only by @code{bchscheme}. It specifies the +last byte position in @code{-gc-file} at which this invocation of scheme +can write. If the option is not given, the value of environment +variable @code{MITSCHEME_GC_END_POSITION} is used instead, and if that +is not defined, it is computed from the start position (as provided with +-gc-start-position) and the heap size. The area of the file used (and +locked if possible) is the region between @code{-gc-start-position} and +@code{-gc-end-position}. + +@item -gc-file @var{filename} +@item -gcfile +@findex -gc-file +@findex -gcfile +@findex MITSCHEME_GC_FILE +Specifies that @var{filename} should be used for garbage collection. +This option is recognized only by @code{bchscheme}. If the option is +not given, the value of environment variable @code{MITSCHEME_GC_FILE} is +used, and if this is not defined, a unique filename is generated in the +directory specified with @code{-gc-directory}. + +@code{-gcfile} is an alias for @code{-gc-file}. At most one of these +options should be specified. + +@item -gc-keep +@findex -gc-keep +Specifies that the gc file used for garbage collection should not be +deleted when scheme terminates. This option is recognized only by +@code{bchscheme}. The gc file is deleted only if the file was created +by this invocation of scheme, and this option is not set. + +@item -gc-read-overlap @var{N} +@findex -gc-read-overlap +@findex MITSCHEME_GC_READ_OVERLAP +Specifies that scheme should delegate at most @var{N} simultaneous disk +read operations during garbage collection. This option is recognized +only by @code{bchscheme}. If the option is not given, the value of +environment variable @code{MITSCHEME_GC_READ_OVERLAP} is used instead, +and if that is not defined, 0 is used, disabling overlapped reads. + +@item -gc-start-position @var{number} +@findex -gc-start-position +@findex MITSCHEME_GC_START_POSITION +This option is recognized only by @code{bchscheme}. It specifies the +first byte position in @code{-gc-file} at which this invocation of +scheme can write. If the option is not given, the value of environment +variable @code{MITSCHEME_GC_START_POSITION} is used instead, and if that +is not defined, 0 is used, meaning the beginning of the file. The area +of the file used (and locked if possible) is the region between +@code{-gc-start-position} and @code{-gc-end-position}. + +@item -gc-window-size @var{blocks} +@findex -gc-window-size +@findex MITSCHEME_GC_WINDOW_SIZE +Specifies the size of the windows into new space during garbage +collection. This option is recognized only by @code{bchscheme}. +If this option is not given, the value of environment variable +@code{MITSCHEME_GC_WINDOW_SIZE} is used instead, and if that is not +defined, the value 16 is used. + +@item -gc-write-overlap @var{N} +@findex -gc-write-overlap +@findex MITSCHEME_GC_WRITE_OVERLAP +Specifies that scheme should delegate at most @var{N} simultaneous disk +write operations during garbage collection. This option is recognized +only by @code{bchscheme}. If the option is not given, the value of +environment variable @code{MITSCHEME_GC_WRITE_OVERLAP} is used instead, +and if that is not defined, 0 is used, disabling overlapped writes. +@end table + +@node Environment Variables, Leaving Scheme, Command-Line Options, Running Scheme +@section Environment Variables + +This is a summary of the environment variables that are specific to MIT +Scheme. + +@table @asis + +@item @code{MITSCHEME_BAND} (default: @file{runtime.com}) +@findex MITSCHEME_BAND +The initial band to be loaded. Overridden by @code{-band}, +@code{-compiler}, or @code{-edwin}. + +@item @code{MITSCHEME_COMPILER_BAND} (default: @file{compiler.com}) +@findex MITSCHEME_COMPILER_BAND +The initial band to be loaded if the @code{-compiler} option is given. +Overridden by @code{-band}. + +@item @code{MITSCHEME_EDWIN_BAND} (default: @file{edwin.com}) +@findex MITSCHEME_EDWIN_BAND +The initial band to be loaded if the @code{-edwin} option is given. +Overridden by @code{-band}. + +@item @code{MITSCHEME_LARGE_CONSTANT} (default: @samp{1000}) +@findex MITSCHEME_LARGE_CONSTANT +The size of constant space, in 1024-word blocks, if the @code{-large}, +@code{-compiler}, or @code{-edwin} options are given. Overridden by +@code{-constant}. Note: default is somewhat larger on RISC machines. + +@item @code{MITSCHEME_LARGE_HEAP} (default: @samp{1000}) +@findex MITSCHEME_LARGE_HEAP +The size of the heap, in 1024-word blocks, if the @code{-large}, +@code{-compiler}, or @code{-edwin} options are given. Overridden by +@code{-heap}. + +@item @code{MITSCHEME_LARGE_STACK} (default: @samp{100}) +@findex MITSCHEME_LARGE_STACK +The size of the stack, in 1024-word blocks, if the @code{-large}, +@code{-compiler}, or @code{-edwin} options are given. Overridden by +@code{-stack}. + +@item @code{MITSCHEME_LIBRARY_PATH} (default: @file{/usr/local/lib/mit-scheme}) +@findex MITSCHEME_LIBRARY_PATH +A colon-separated list of directories. These directories are searched, +left to right, to find bands and various other files. + +@item @code{MITSCHEME_SMALL_CONSTANT} (default: @samp{400}) +@findex MITSCHEME_SMALL_CONSTANT +The size of constant space, in 1024-word blocks, if the size options are +not given. Overridden by @code{-constant}, @code{-large}, +@code{-compiler}, or @code{-edwin}. Note: default is somewhat larger on +RISC machines. + +@item @code{MITSCHEME_SMALL_HEAP} (default: @samp{250}) +@findex MITSCHEME_SMALL_HEAP +The size of the heap, in 1024-word blocks, if the size options are not +given. Overridden by @code{-heap}, @code{-large}, @code{-compiler}, or +@code{-edwin}. + +@item @code{MITSCHEME_SMALL_STACK} (default: @samp{100}) +@findex MITSCHEME_SMALL_STACK +The size of the stack, in 1024-word blocks, if the size options are not +given. Overridden by @code{-stack}, @code{-large}, @code{-compiler}, or +@code{-edwin}. + +@item @code{MITSCHEME_UTABMD_FILE} (default: @file{utabmd.bin}) +@findex MITSCHEME_UTABMD_FILE +The file containing the microcode tables. Overridden by @code{-utabmd} +and @code{-utab}. + +@item @code{MITSCHEME_GC_DIRECTORY} (default: @file{/tmp}) +@findex MITSCHEME_GC_DIRECTORY +The directory where to write gc files. Overriden by @code{-gc-directory}. + +@item @code{MITSCHEME_GC_DRONE} (default: @file{gcdrone}) +@findex MITSCHEME_GC_DRONE +The program to use as the I/O drone during garbage collection. +Overriden by @code{-gc-drone}. + +@item @code{MITSCHEME_GC_END_POSITION} (default: start-position + heap-size) +@findex MITSCHEME_GC_END_POSITION +The last position in the gc file to use. Overriden by +@code{-gc-end-position}. + +@item @code{MITSCHEME_GC_FILE} (default: @file{GCXXXXXX}) +@findex MITSCHEME_GC_FILE +The name of the file to use for garbage collection. If it ends in 6 Xs, +the Xs are replaced by a letter and process id of the scheme process, +thus generating a unique name. Overriden by @code{-gc-file}. + +@item @code{MITSCHEME_GC_READ_OVERLAP} (default: 0) +@findex MITSCHEME_GC_READ_OVERLAP +The maximum number of simultaneous read operations. Overriden by +@code{-gc-read-overlap}. + +@item @code{MITSCHEME_GC_START_POSITION} (default: 0) +@findex MITSCHEME_GC_START_POSITION +The first position in the gc file to use. Overriden by +@code{-gc-start-position}. + +@item @code{MITSCHEME_GC_WINDOW_SIZE} (default: 16) +@findex MITSCHEME_GC_WINDOW_SIZE +The size in blocks of windows into new space (in the gc file). +Overriden by @code{-gc-window-size}. + +@item @code{MITSCHEME_GC_WRITE_OVERLAP} (default: 0) +@findex MITSCHEME_GC_WRITE_OVERLAP +The maximum number of simultaneous write operations. Overriden by +@code{-gc-write-overlap}. +@end table + +@node Leaving Scheme, , Environment Variables, Running Scheme +@section Leaving Scheme + +There are two ways you can leave Scheme. The first is to evaluate + +@findex exit +@lisp +(exit) +@end lisp + +@noindent +which will halt the Scheme system, after first requesting confirmation. +Any information that was in the environment is lost, so this should not +be done lightly. + +The second way to leave Scheme is to suspend it; when this is done you +may later restart where you left off. Unfortunately this is not +possible in all operating systems --- currently it is known to work on +BSD Unix, Ultrix, SunOS, HP-UX (version 6.5 or later). It does NOT work +on AT&T Unix. (Specifically, for unix or POSIX systems, suspension is +available if the system supports job control.) + +Scheme is suspended by evaluating + +@findex quit +@lisp +(quit) +@end lisp + +@noindent +If your system supports suspension, this will cause Scheme to stop, and +you will be returned to the operating system's command interpreter. +Scheme remains stopped, and can be continued using the job-control +commands of your command interpreter. If your system doesn't support +suspension, this procedure does nothing. + +@node REPL, Debugging, Running Scheme, Top +@chapter The Read-Eval-Print Loop + +@cindex REPL +When you first start up Scheme, you will be typing at a program called +the @dfn{Read-Eval-Print Loop} (abbreviated @dfn{REPL}). It displays a +prompt at the left hand side of the screen whenever it is waiting for +input. You then type an expression (terminating it with @key{RET}). +Scheme evaluates the expression, prints the result, and gives you +another prompt. + +@menu +* The Prompt and Level Number:: The Prompt and Level Number +* Interrupting:: Interrupting +* Proceeding:: Proceeding +* The Current REPL Environment:: The Current REPL Environment +@end menu + +@node The Prompt and Level Number, Interrupting, REPL, REPL +@section The Prompt and Level Number + +@cindex prompt, REPL +The @sc{repl} @dfn{prompt} normally has the form + +@example +1 ]=> +@end example + +@cindex level number, REPL +@noindent +The @samp{1} in the prompt is a @dfn{level number}, which is always a +positive integer. This number is incremented under certain +circumstances, the most common being an error. For example, here is +what you will see if you type @kbd{f o o @key{RET}} after starting +Scheme: + +@example +1 ]=> foo + +Unbound variable foo + +2 Error-> +@end example + +@noindent +In this case, the level number has been incremented to @samp{2}, which +indicates that a new @sc{repl} has been started (also the prompt string +has been changed to remind you that the @sc{repl} was started because of +an error). The @samp{2} means that this new @sc{repl} is ``over'' the +old one. The original @sc{repl} still exists, and is waiting for you to +return to it. Furthermore, if an error occurs while you are in this +@sc{repl}, yet another @sc{repl} will be started, and the level number +will be increased to @samp{3}. This can continue ad infinitum, but +normally it is rare to use more than a few levels. + +The normal way to get out of an error @sc{repl} and back to the top +level @sc{repl} is to use the @kbd{C-g} interrupt. This is a +single-keystroke command executed by holding down the @key{CTRL} key and +pressing the @key{G} key. @kbd{C-g} always terminates whatever is +running and returns you to the top level @sc{repl} immediately. + +Note: The appearance of the @samp{Error->} prompt does not mean that +Scheme is in some weird inconsistent state that you should avoid. It is +merely a reminder that your program was in error: an illegal operation +was attempted, but it was detected and avoided. Often the best way to +find out what is in error is to do some poking around in the error +@sc{repl}. If you abort out of it, the context of the error will be +destroyed, and you may not be able to find out what happened. + +@node Interrupting, Proceeding, The Prompt and Level Number, REPL +@section Interrupting + +@kindex C-g +@kindex C-c +Scheme has two interrupt keys under unix (other systems may have more +than two): @kbd{C-g} and @kbd{C-c}. The @kbd{C-g} key stops any Scheme +evaluation that is running and returns you to the top level @sc{repl}. +@kbd{C-c} prompts you for another character and performs some action +based on that character. It is not necessary to type @key{RET} after +@kbd{C-g} or @kbd{C-c}, nor is it needed after the character that +@kbd{C-c} will ask you for. + +Here are the more common options for @kbd{C-c}. + +@table @kbd + +@item C-c i +@kindex C-c i +Ignore the interrupt. Type this if you made a mistake and didn't +really mean to type @kbd{C-c}. + +@item C-c ? +@kindex C-c ? +Print help information. This will describe any other options not +documented here. + +@item C-c q +@kindex C-c q +@findex exit +Similar to typing @code{(exit)} at the @sc{repl}, except that it works +even if Scheme is running an evaluation, and does not request +confirmation. + +@item C-c z +@kindex C-c z +@findex quit +Similar to typing @code{(quit)} at the @sc{repl}, except that it works +even if Scheme is running an evaluation. + +@item C-c C-c +@kindex C-c C-c +Identical to typing @kbd{C-g}. If no evaluation is running, this is +equivalent to evaluating + +@findex cmdl-interrupt/abort-top-level +@lisp +(cmdl-interrupt/abort-top-level) +@end lisp + +@noindent +@kindex C-c C-g +@kindex C-c g +The options @kbd{C-c C-g} and @kbd{C-c g}, supplied for compatibility +with older implementations, are equivalent to @kbd{C-c C-c}. + +@item C-c C-x +@kindex C-c C-x +Abort whatever Scheme evaluation is currently running and return to the +``current'' @sc{repl}. If no evaluation is running, this is equivalent +to evaluating + +@findex cmdl-interrupt/abort-nearest +@lisp +(cmdl-interrupt/abort-nearest) +@end lisp + +@kindex C-c x +The option @kbd{C-c x}, supplied for compatibility with older +implementations, is equivalent to @kbd{C-c C-x}. + +@item C-c C-u +@kindex C-c C-u +Abort whatever Scheme evaluation is running and go up one level. If you +are already at level number 1, it just aborts the evaluation, leaving +you at level 1. If no evaluation is running, this is equivalent to +evaluating + +@findex cmdl-interrupt/abort-previous +@lisp +(cmdl-interrupt/abort-previous) +@end lisp + +@kindex C-c u +The option @kbd{C-c u}, supplied for compatibility with older +implementations, is equivalent to @kbd{C-c C-u}. + +@item C-c C-b +@kindex C-c C-b +@cindex breakpoint +Suspend whatever Scheme evaluation is running and start a +@dfn{breakpoint} @sc{repl}. The evaluation can be resumed by evaluating + +@findex proceed +@lisp +(proceed) +@end lisp + +@noindent +in that @sc{repl} at any time. + +@kindex C-c b +The option @kbd{C-c b}, supplied for compatibility with older +implementations, is equivalent to @kbd{C-c C-b}. +@end table + +@node Proceeding, The Current REPL Environment, Interrupting, REPL +@section Proceeding + +Another way of exiting a @sc{repl} is to use the @code{proceed} +procedure: + +@deffn {procedure+} proceed [value] +@cindex error REPL, proceeding from +There are two ways to use this procedure from an error @sc{repl} (usage +from other kinds of @sc{repl} is not necessarily the same). If +@var{value} is not given, @code{proceed} retries the expression that +caused the error. Unless you have done something to fix the error +condition, this will just cause the error to happen all over again. If, +for example, you are in an error @sc{repl} caused by evaluating an +unbound variable, the proper way to use @code{proceed} is to first +define a value for the variable, then to evaluate @code{(proceed)}. +Your program should continue from that point normally. + +One caveat: when you get an unbound variable error, the environment for +the error @sc{repl} is the environment in which you looked up the +variable, which is not necessarily the environment in which the variable +should be defined. It is best to use the @code{ge} procedure to +guarantee that your definition goes into the right place. + +If @var{value} is given, @code{proceed} returns it in place of the +expression that caused the error. Thus, if you cannot easily fix a +particular bug, but you know a correct value for the erring expression, +you can continue the computation this way. +@end deffn + +@node The Current REPL Environment, , Proceeding, REPL +@section The Current REPL Environment + +@cindex current REPL environment +@findex user-initial-environment +@findex system-global-environment +Every @sc{repl} has a @dfn{current environment}, which is the place +where expressions are evaluated and definitions are stored. When Scheme +is started, this environment is the value of the variable +@code{user-initial-environment}. There are a number of other +environments in the system, for example +@code{system-global-environment}, where the runtime system's bindings +are stored. + +You can get the current @sc{repl} environment by evaluating + +@findex nearest-repl/environment +@lisp +(nearest-repl/environment) +@end lisp + +There are several other ways to obtain environments. For example, if +you have a procedure object, you can get a pointer to the environment in +which it was closed by evaluating + +@findex procedure-environment +@lisp +(procedure-environment @var{procedure}) +@end lisp + +Your programs create new environments whenever a procedure is called. +When an error occurs, the error @sc{repl} that is created is usually +initialized so that its current environment is the one in which the +error occurred. When it is not possible to supply the error's +environment, the following message is printed: + +@lisp +There is no environment available; +using the current REPL environment +@end lisp + +@noindent +This message tells you that the error @sc{repl} is using the same +environment as the @sc{repl} whose level number is one less than the +error @sc{repl}'s. + +Here is the procedure that changes the @sc{repl}'s environment: + +@deffn {procedure+} ge environment +Changes the current @sc{repl} environment to be @var{environment} +(@code{ge} stands for ``Goto Environment''). @var{Environment} is +allowed to be a procedure as well as an environment object. If it is a +procedure, then the closing environment of that procedure is used in its +place. +@end deffn + +@deffn {procedure+} gst syntax-table +In addition to the current environment, each @sc{repl} maintains a +current @dfn{syntax table}. The current syntax table tells the +@sc{repl} which keywords are used to identify special forms (e.g. +@code{if}, @code{lambda}). If you write macros, often you will want to +make your own syntax table, in which case it is useful to be able to +make that syntax table be the current one. @code{Gst} allows you to do +that. +@end deffn + +@node Debugging, Loading Files, REPL, Top +@chapter Debugging + +This chapter is adapted from @cite{Don't Panic: A 6.001 User's Guide to +the Chipmunk System}, by Arthur A. Gleckler. + +@cindex bugs +@cindex debugging +Even computer software that has been planned carefully and written well +may not always work correctly. Mysterious creatures called @dfn{bugs} +may creep in and wreak havoc, leaving the programmer to clean up the +mess. Some have theorized that a program fails only because its author +made a mistake, but experienced computer programmers know that bugs are +always to blame. This is why the task of fixing broken computer +software is called @dfn{debugging}. + +It is impossible to prove the correctness of any non-trivial program; +hence the Cynic's First Law of Debugging: + +@quotation +Programs don't become more reliable as they are debugged; the bugs just +get harder to find. +@end quotation + +@cindex breakpoints +Scheme is equipped with a variety of special software for finding and +removing bugs. The debugging tools include facilities for tracing a +program's use of specified procedures, for examining Scheme +environments, and for setting @dfn{breakpoints}, places where the +program will pause for inspection. + +@cindex error +Many bugs are detected when programs try to do something which is +impossible, like adding a number to a symbol, or using a variable which +does not exist; this type of mistake is called an @dfn{error}. +Whenever an error occurs, Scheme prints an error message and starts a +new @sc{repl}. For example, using a nonexistent variable @code{foo} will +cause Scheme to respond + +@example +1 ]=> foo + +Unbound variable foo +;Package: (user) + +2 Error-> +@end example + +Sometimes, a bug will never cause an error, but will still cause the +program to operate incorrectly. For instance, + +@lisp +(prime? 7) @result{} #f +@end lisp + +In this situation, Scheme does not know that the program is misbehaving. +The programmer must notice the problem and, if necessary, start the +debugging tools manually. + +There are several approaches to finding bugs in a Scheme program: + +@itemize @bullet +@item +Inspect the original Scheme program. + +@item +Use the debugging tools to follow your program's progress. + +@item +Edit the program to insert checks and breakpoints. +@end itemize + +@noindent +Only experience can teach how to debug programs, so be sure to +experiment with all these approaches while doing your own debugging. +Planning ahead is the best way to ward off bugs, but when bugs do +appear, be prepared to attack them with all the tools available. + +@menu +* Subproblems and Reductions:: Subproblems and Reductions +* Debugger:: The Debugger +@end menu + +@node Subproblems and Reductions, Debugger, Debugging, Debugging +@section Subproblems and Reductions + +@cindex subproblem +@cindex reduction +@cindex subexpression +Understanding the concepts of @dfn{reduction} and @dfn{subproblem} is +essential to good use of the debugging tools. The Scheme interpreter +evaluates an expression by @dfn{reducing} it to a simpler expression. +In general, Scheme's evaluation rules designate that evaluation proceeds +from one expression to the next by either starting to work on a +@dfn{subexpression} of the given expression, or by reducing the entire +expression to a new (simpler, or reduced) form. Thus, a history of the +successive forms processed during the evaluation of an expression will +show a sequence of subproblems, where each subproblem may consist of a +sequence of reductions. + +For example, both @code{(+ 5 6)} and @code{(+ 7 9)} are subproblems of +the following combination: + +@lisp +(* (+ 5 6) (+ 7 9)) +@end lisp + +If @code{(prime? n)} is true, then @code{(cons 'prime n)} is a reduction +for the following expression: + +@lisp +(if (prime? n) + (cons 'prime n) + (cons 'not-prime n)) +@end lisp + +This is because the entire subproblem of the @code{if} combination can +be reduced to the problem @code{(cons 'prime n)}, once we know that +@code{(prime? n)} is true; the @code{(cons 'not-prime n)} can be +ignored, because it will never be needed. On the other hand, if +@code{(prime? n)} were false, then @code{(cons 'not-prime n)} would be +the reduction for the @code{if} combination. + +The @emph{subproblem level} is a number representing how far back in the +history of the current computation a particular evaluation is. Consider +@code{factorial}: + +@lisp +(define (factorial n) + (if (< n 2) + 1 + (* n (factorial (- n 1))))) +@end lisp + +@noindent +If we stop @code{factorial} in the middle of evaluating @code{(- n 1)}, +the @code{(- n 1)} is at subproblem level 0. Following the history of +the computation ``upwards,'' @code{(factorial (- n 1))} is at subproblem +level 1, and @code{(* n (factorial (- n 1)))} is at subproblem level 2. +These expressions all have @emph{reduction number} 0. Continuing +upwards, the @code{if} combination has reduction number 1. + +Moving backwards in the history of a computation, subproblem levels and +reduction numbers increase, starting from zero at the expression +currently being evaluated. Reduction numbers increase until the next +subproblem, where they start over at zero. The best way to get a feel +for subproblem levels and reduction numbers is to experiment with the +debugging tools, especially @code{debug}. + +@node Debugger, , Subproblems and Reductions, Debugging +@section The Debugger + +@cindex debugger +@cindex continuation Browser +@cindex browser, Continuation +@findex debug +The @dfn{debugger}, called @code{debug}, is the tool you should use when +Scheme signals an error and you want to find out what caused the error. +When Scheme signals an error, it records all the information necessary +to continue running the Scheme program that caused the error; the +debugger provides you with the means to inspect this information. For +this reason, the debugger is sometimes called a @dfn{continuation +browser}. + +Here is the transcript of a typical Scheme session, showing a user +evaluating the expression @code{(fib 10)}, Scheme responding with an +unbound variable error for the variable @code{fob}, and the user +starting the debugger: + +@example +1 ]=> (fib 10) + +Unbound variable fob + +2 Error-> (debug) + +There are 8 subproblems on the stack. + +Subproblem level: 0 (this is the lowest subproblem level) +Expression (from stack): + fob +Environment created by the procedure: fib + applied to: (10) +The execution history for this subproblem contains 1 reduction. +You are now in the debugger. Type q to quit, ? for commands. + +3 Debug--> +@end example + +@noindent +@cindex execution history +This tells us that the error occurred while trying to evaluate the +expression @code{fob} while running @code{(fib 10)}. It also tells us +this is subproblem level 0, the first of 8 subproblems that are +available for us to examine. The expression shown is marked ``(from +stack)'', which tells us that this expression was reconstructed from the +interpreter's internal data structures. Another source of information +is the @dfn{execution history}, which keeps a record of expressions +evaluated by the interpreter. The debugger informs us that the +execution history has recorded some information for this subproblem, +specifically a description of one reduction. + +@node Loading Files, World Images, Debugging, Top +@chapter Loading Files + +To load files of Scheme code, use the procedure @code{load}: + +@deffn {procedure} load filename [environment [syntax-table]] +@var{Filename} may be a string naming a file, or a list of strings +naming many files. @var{Environment}, if given, is the environment to +evaluate the file in; if not given the current @sc{repl} environment is +used. Likewise @var{syntax-table} is the syntax table to use. + +@findex pathname-type +@code{Load} determines whether the file to be loaded is binary or source +code, and performs the appropriate action. By convention, files of +source code have a pathname type of @code{"scm"}, and files of binary +SCode have pathname type @code{"bin"}. Native-code binaries have +pathname type @code{"com"}. (See the description of +@code{pathname-type} in the reference manual.) +@end deffn + +@defvr {variable+} load-noisily? +If @code{load-noisily?} is set to @code{#t}, @code{load} will print the +value of each expression in the file as it is evaluated. Otherwise, +nothing is printed except for the value of the last expression in the +file. (Note: the noisy loading feature is implemented for source-code +files only.) +@end defvr + +@defvr {variable+} load/default-types +This variable is a list of strings that are the pathname types to look +for, in that order, if @code{load} is given a pathname that has no type. +The initial value of this variable is + +@lisp +("com" "bin" "scm") +@end lisp +@end defvr + +@cindex working directory +@findex pwd +@findex cd +All pathnames are interpreted relative to a working directory, which is +initialized when Scheme is started. The working directory can be +obtained from the procedure @code{pwd} or modified by the procedure +@code{cd}; see the reference manual for details. + +@node World Images, Compiling Files, Loading Files, Top +@chapter World Images + +@cindex world image +@cindex band +A @dfn{world image} is a file that contains a complete Scheme system, +perhaps additionally including user application code. Scheme provides +two methods for saving and restoring world images. The first method +writes a file containing all of the Scheme code in the world, which is +called a @dfn{band}. The file @file{runtime.com} that is loaded by the +microcode is just such a band. To make your own band, use the procedure +@code{disk-save}: + +@deffn {procedure+} disk-save filename [identify] +Causes a band to be written to the file specified by @var{filename}. +The optional argument @var{identify} controls what happens when that +band is restored, as follows: + +@table @asis +@item not specified +Start up in the top-level @sc{repl}, identifying the world in the normal +way. + +@item a string +Do the same thing except print that string instead of @samp{Scheme} when +restarting. + +@item the constant @code{#t} +Restart exactly where you were when the call to @code{disk-save} was +performed. This is especially useful for saving your state when an +error has occurred and you are not in the top-level @sc{repl}. + +@item the constant @code{#f} +Just like @code{#t}, except that the runtime system will not perform +normal restart initializations; in particular, it will not load your +init file. +@end table +@end deffn + +@findex disk-restore +To restore a saved band, give the @code{-band} option when starting +Scheme. Alternatively, evaluate @code{(disk-restore @var{filename})} +from a running Scheme, which will destroy the current world, replacing +it with the saved world. The argument to @code{disk-restore} may be +omitted, in which case it defaults to the filename from which the +current world was last restored. + +Note: when restoring a saved band, the Scheme executable must be +configured with a large enough constant space and heap to hold the +band's contents. If you attempt to restore a band using the +@code{-band} option, and the band is too large, Scheme will write an +error message that tells you the appropriate command-line options needed +to load that band. If you attempt restore a too-large band using +@code{disk-restore}, Scheme will signal an error, but will not provide +the configuration information. In general, the configuration that was +used to save a band is sufficiently large to restore it. + +@findex dump-world +Another method for saving the world is the @code{dump-world} procedure, +which accepts the same arguments as @code{disk-save} and works in much +the same way. However, rather than dumping a band, @code{dump-world} +saves an executable image, which is started just like any other program. +This has the advantage of being considerably faster to start on some +systems, but the image file is typically much larger than the +corresponding band. However, @code{dump-world} is only supported for a +few operating systems, and is not built in to the distributed executable +files --- if you wish to use @code{dump-world}, you must build your own +executable file from the source code. + +@node Compiling Files, GNU Emacs Interface, World Images, Top +@chapter Compiling Files + +Note: the procedures described in this section are only available in the +@file{compiler.com} world image. Furthermore, @code{cf} is only +available on machines that support native-code compilation. + +@menu +* Compilation Procedures:: Compilation Procedures +* Declarations:: Declarations +@end menu + +@node Compilation Procedures, Declarations, Compiling Files, Compiling Files +@section Compilation Procedures + +@deffn {procedure+} cf filename [destination] +This is the program that transforms a source-code file into native-code +binary form. If @var{destination} is not given, as in + +@lisp +(cf "foo") +@end lisp + +@noindent +@code{cf} compiles the file @file{foo.scm}, producing the file +@file{foo.com} (incidentally it will also produce @file{foo.bin}, +@file{foo.binf}, and possibly @file{foo.ext}). If you later evaluate + +@lisp +(load "foo") +@end lisp + +@noindent +@file{foo.com} will be loaded rather than @file{foo.scm}. + +If @var{destination} is given, it says where the output files should go. +If this argument is a directory, they go in that directory, e.g.: + +@lisp +(cf "foo" "../bar/") +@end lisp + +@noindent +will take @file{foo.scm} and generate the file @file{../bar/foo.com}. +If @var{destination} is not a directory, it is the root name of the +output: + +@lisp +(cf "foo" "bar") +@end lisp + +@noindent +takes @file{foo.scm} and generates @file{bar.com}. + +About the @file{.binf} files: these files contain the debugging +information that Scheme uses when you call @code{debug} to examine +compiled code. When you load a @file{.com} file, Scheme remembers where +it was loaded from, and when the debugger looks at the compiled code +from that file, it attempts to find the @file{.binf} file in the same +directory from which the @file{.com} file was loaded. Thus it is a good +idea to leave these files together. + +Another useful thing contained in the @file{.binf} file is the symbol +table produced by the assembler. If you have both the @file{foo.com} +and @file{foo.binf} files, you can generate an assembly listing in +@file{foo.lap} by evaluating: + +@findex compiler:write-lap-file +@lisp +(compiler:write-lap-file "foo") +@end lisp +@end deffn + +Unfortunately, the @file{.binf} files are somewhat large in the current +implementation. If you wish to save space, these files may be deleted; +if Scheme tries to find one and cannot, it will still permit debugging, +but will be unable to produce much information about your program. + +@deffn {procedure+} sf filename [destination] +@code{sf} is the program that transforms a source-code file into binary +SCode form; it is used on machines that do not support native-code +compilation. It performs numerous optimizations that can make your +programs run considerably faster than unoptimized interpreted code. +Also, the binary files that it generates load very quickly compared to +source-code files. + +The simplest way to use @code{sf} is just to say: + +@lisp +(sf @var{filename}) +@end lisp + +@noindent +This will cause your file to be transformed, and the resulting binary +file to be written out with the same name, but with @code{pathname-type} +@code{"bin"}. If you do not specify a @code{pathname-type} on the input +file, @code{"scm"} is assumed. + +Like @code{load}, the first argument to @code{sf} may be a list of +filenames rather than a single filename. + +@code{sf} takes an optional second argument, which is the filename of +the output file. If this argument is a directory, then the output file +has its normal name but is put in that directory instead. +@end deffn + +@node Declarations, , Compilation Procedures, Compiling Files +@section Declarations +@cindex declarations + +Several declarations can be added to your programs to help @code{cf} and +@code{sf} make them more efficient. + +@menu +* Standard Names:: Standard Names +* In-line Coding:: In-line Coding +* Operator Reduction:: Operator Reduction +@end menu + +@node Standard Names, In-line Coding, Declarations, Declarations +@subsection Standard Names + +Normally, all files have a line + +@findex usual-integrations +@lisp +(declare (usual-integrations)) +@end lisp + +@noindent +near their beginning, which tells the compiler that free variables whose +names are defined in @code{system-global-environment} will not be +shadowed by other definitions when the program is loaded. If you +redefine some global name in your code, for example @code{car}, +@code{cdr}, and @code{cons}, you should indicate it in the declaration: + +@lisp +(declare (usual-integrations car cdr cons)) +@end lisp + +You can obtain an alphabetically-sorted list of the names that the +@code{usual-integrations} declaration affects by evaluating the +following expression: + +@lisp +(eval '(sort (append usual-integrations/constant-names + usual-integrations/expansion-names) + (lambda (x y) + (string<=? (symbol->string x) + (symbol->string y)))) + (->environment '(scode-optimizer))) +@end lisp + +@node In-line Coding, Operator Reduction, Standard Names, Declarations +@subsection In-line Coding + +Another useful facility is the ability to in-line code procedure +definitions. In fact, the compiler will perform full beta conversion, +with automatic renaming, if you request it. Here are the relevant +declarations: + +@deffn {declaration+} integrate name @dots{} +The variables @var{name}s should be defined in the same file as this +declaration. Any reference to one of the named variables that appears +in the same block as the declaration, or one of its descendant blocks, +will be replaced by the corresponding definition's value expression. +@end deffn + +@deffn {declaration+} integrate-operator name @dots{} +Similar to the @code{integrate} declaration, except that it only +substitutes for references that appear in the operator position of a +combination. All other references are ignored. +@end deffn + +@deffn {declaration+} integrate-external filename +Causes the compiler to use the top-level integrations provided by +@var{filename}. @var{filename} should not specify a file type, and the +source-code file that it names must have been previously processed by +the compiler. + +If @var{filename} is a relative filename (the normal case), it is +interpreted as being relative to the file in which the declaration +appears. Thus if the declaration appears in file @file{/usr/cph/foo.scm}, +then the compiler looks for a file called @file{/usr/cph/@var{filename}.ext}. + +Note: When the compiler finds top-level integrations, it collects them +and outputs them into an auxiliary file with extension @file{.ext}. +This @file{.ext} file is what the @code{integrate-external} declaration +refers to. +@end deffn + +@findex define-integrable +@findex define +Note that the most common use of this facility, in-line coding of +procedure definitions, requires a somewhat complicated use of these +declarations. Because this is so common, there is a special form, +@code{define-integrable}, which is like @code{define} but performs the +appropriate declarations. For example: + +@lisp +(define-integrable (foo-bar foo bar) + (vector-ref (vector-ref foo bar) 3)) +@end lisp + +Here is how you do the same thing without this special form: there +should be an @code{integrate-operator} declaration for the procedure's +name, and (internal to the procedure's definition) an @code{integrate} +declaration for each of the procedure's parameters, like this: + +@lisp +(declare (integrate-operator foo-bar)) + +(define foo-bar + (lambda (foo bar) + (declare (integrate foo bar)) + (vector-ref (vector-ref foo bar) 3))) +@end lisp + +The reason for this complication is as follows: the +@code{integrate-operator} declaration finds all the references to +@code{foo-bar} and replaces them with the lambda expression from the +definition. Then, the @code{integrate} declarations take effect because +the combination in which the reference to @code{foo-bar} occurred +supplies code which is substituted throughout the body of the procedure +definition. For example: + +@lisp +(foo-bar (car baz) (cdr baz)) +@end lisp + +@noindent +First use the @code{integrate-operator} declaration: + +@group +@lisp +((lambda (foo bar) + (declare (integrate foo bar)) + (vector-ref (vector-ref foo bar) 3)) + (car baz) + (cdr baz)) +@end lisp +@end group + +@noindent +Next use the internal @code{integrate} declaration: + +@group +@lisp +((lambda (foo bar) + (vector-ref (vector-ref (car baz) (cdr baz)) 3)) + (car baz) + (cdr baz)) +@end lisp +@end group + +@noindent +Next notice that the variables @code{foo} and @code{bar} are not used, +and eliminate them: + +@group +@lisp +((lambda () + (vector-ref (vector-ref (car baz) (cdr baz)) 3))) +@end lisp +@end group + +@noindent +Finally, remove the @code{((lambda () @dots{}))} to produce + +@lisp +(vector-ref (vector-ref (car baz) (cdr baz)) 3) +@end lisp + +@node Operator Reduction, , In-line Coding, Declarations +@subsection Operator Reduction + +@findex reduce-operator +The @code{reduce-operator} declaration is provided to inform the +compiler that certain names are n-ary versions of binary operators. +Here are some examples: + +@noindent +Declaration: + +@group +@lisp +(declare (reduce-operator (cons* cons))) +@end lisp +@end group + +@noindent +Replacements: + +@group +@lisp +(cons* @var{x} @var{y} @var{z} @var{w}) @expansion{} (cons @var{x} (cons @var{y} (cons @var{z} @var{w}))), +(cons* @var{x} @var{y}) @expansion{} (cons @var{x} @var{y}) +(cons* @var{x}) @expansion{} @var{x} +(cons*) @error{} too few arguments +@end lisp +@end group + +@noindent +Declaration: + +@group +@lisp +(declare (reduce-operator (list cons (null-value '() any)))) +@end lisp +@end group + +@noindent +Replacements: + +@group +@lisp +(list @var{x} @var{y} @var{z} @var{w}) @expansion{} (cons @var{x} (cons @var{y} (cons @var{z} (cons @var{w} '())))) +(list @var{x} @var{y}) @expansion{} (cons @var{x} (cons @var{y} '())) +(list @var{x}) @expansion{} (cons @var{x} '()) +(list) @expansion{} '() +@end lisp +@end group + +@noindent +Declaration: + +@group +@lisp +(declare (reduce-operator (- %- (null-value 0 single) (group left)))) +@end lisp +@end group + +@noindent +Replacements: + +@group +@lisp +(- @var{x} @var{y} @var{z} @var{w}) @expansion{} (%- (%- (%- @var{x} @var{y}) @var{z}) @var{w}) +(- @var{x} @var{y}) @expansion{} (%- @var{x} @var{y}) +(- @var{x}) @expansion{} (%- 0 @var{x}) +(-) @expansion{} 0 +@end lisp +@end group + +@noindent +Declaration: + +@group +@lisp +(declare (reduce-operator (+ %+ (null-value 0 none) (group right)))) +@end lisp +@end group + +@noindent +Replacements: + +@group +@lisp +(+ @var{x} @var{y} @var{z} @var{w}) @expansion{} (%+ @var{x} (%+ @var{y} (%+ @var{z} @var{w}))) +(+ @var{x} @var{y}) @expansion{} (%+ @var{x} @var{y}) +(+ @var{x}) @expansion{} @var{x} +(+) @expansion{} 0 +@end lisp +@end group + +Note: This declaration does not cause an appropriate definition of +@code{+} (in the last example) to appear in your code. It merely +informs the compiler that certain optimizations can be performed on +calls to @code{+} by replacing them with calls to @code{%+}. You should +provide a definition of @code{+} as well, although it is not required. + +The general format of the declaration is (brackets denote optional +elements): + +@group +@lisp +(reduce-operator + (@var{name} + @var{binop} + @r{[}(group @var{ordering})@r{]} + @r{[}(null-value @var{value} @var{null-option})@r{]} + @r{[}(singleton @var{unop})@r{]} + @r{[}(wrapper @var{wrap})@r{]} + )) +@end lisp +@end group + +@noindent +where + +@itemize @bullet + +@item +@var{name} is a symbol. + +@item +@var{binop}, @var{value}, @var{unop}, and @var{wrap} are simple +expressions in one of these forms: + +@table @code + +@item '@var{constant} +A constant. + +@item @var{variable} +A variable. + +@item (primitive @var{primitive-name} @r{[}@var{arity}@r{]}) +The primitive procedure named @var{primitive-name}. The optional +element @var{arity} specifies the number of arguments that the primitive +accepts. +@end table + +@item +@var{null-option} is either @code{always}, @code{any}, @code{one}, +@code{single}, @code{none}, or @code{empty}. + +@item +@var{ordering} is either @code{left}, @code{right}, or +@code{associative}. +@end itemize + +The meaning of these fields is: + +@itemize @bullet + +@item +@var{name} is the name of the n-ary operation to be reduced. + +@item +@var{binop} is the binary operation into which the n-ary operation is to +be reduced. + +@item +The @code{group} option specifies whether @var{name} associates to the +right or left. + +@item +The @code{null-value} option specifies a value to use in the following +cases: + +@table @code + +@item none +@itemx empty +When no arguments are supplied to @var{name}, @var{value} is returned. + +@item one +@itemx single +When a single argument is provided to @var{name}, @var{value} becomes +the second argument to @var{binop}. + +@item any +@itemx always +@var{binop} is used on the ``last'' argument, and @var{value} provides +the remaining argument to @var{binop}. +@end table + +In the above options, when @var{value} is supplied to @var{binop}, it is +supplied on the left if grouping to the left, otherwise it is supplied +on the right. + +@item +The @code{singleton} option specifies a function, @var{unop}, to be +invoked on the single argument left. This option supersedes the +@code{null-value} option, which can only take the value @code{none}. + +@item +The @code{wrapper} option specifies a function, @var{wrap}, to be +invoked on the result of the outermost call to @var{binop} after the +expansion. +@end itemize + +@node GNU Emacs Interface, Edwin, Compiling Files, Top +@chapter GNU Emacs Interface + +There is an interface library, called @code{xscheme}, distributed with +MIT Scheme and GNU Emacs, which facilitates running Scheme as a +subprocess of Emacs. If you wish to use this interface, please install +the version of @file{xscheme.el} that comes with MIT Scheme, as it is +guaranteed to be correct for your version of Scheme. + +@findex run-scheme +@findex -emacs +To invoke Scheme from Emacs, use @kbd{M-x run-scheme}, which is defined +when either of the libraries @file{scheme} or @file{xscheme} is loaded. +You may give @code{run-scheme} a prefix argument, in which case it will +allow you to edit the command line that is used to invoke Scheme. +@emph{Do not} remove the @code{-emacs} option! + +@findex scheme-interaction-mode +Scheme will be started up as a subprocess in a buffer called +@code{*scheme*}. This buffer will be in @code{scheme-interaction-mode} +and all output from the Scheme process will go there. The mode line for +the @code{*scheme*} buffer will have this form: + +@example +-----Scheme: 1 [Evaluator] (Scheme Interaction: input)------ +@end example + +@noindent +@cindex level number, REPL +The first field, showing @samp{1} in this example, is the level number. + +@noindent +The second field, showing @samp{[Evaluator]} in this example, describes +the type of @sc{repl} that is running. Other values include: + +@example +[Debugger] +[Where] +@end example + +@noindent +The @dfn{mode} after @samp{Scheme Interaction} is one of: + +@table @samp +@item input +Scheme is waiting for input. + +@item run +Scheme is running an evaluation. + +@item gc +Scheme is garbage collecting. +@end table + +@findex scheme-mode +When @code{xscheme} is loaded, @code{scheme-mode} is extended to include +commands for evaluating expressions (do @kbd{C-h m} in any +@code{scheme-mode} buffer for the most up-to-date information): + +@table @kbd + +@item @key{ESC} o +@kindex @key{ESC} o +@findex xscheme-send-buffer +Evaluates the current buffer (@code{xscheme-send-buffer}). + +@item @key{ESC} z +@kindex @key{ESC} z +@findex xscheme-send-definition +Evaluates the current definition (@code{xscheme-send-definition}). This +is also bound to @kbd{@key{ESC} C-x}. + +@item @key{ESC} C-z +@kindex @key{ESC} C-z +@findex xscheme-send-region +Evaluates the current region (@code{xscheme-send-region}). + +@item C-x C-e +@kindex C-x C-e +@findex xscheme-send-previous-expression +Evaluates the expression to the left of point +(@code{xscheme-send-previous-expression}). This is also bound to +@kbd{@key{ESC} @key{RET}}. + +@item C-c C-s +@kindex C-c C-s +@findex xscheme-select-process-buffer +Selects the @code{*scheme*} buffer and places you at its end +(@code{xscheme-select-process-buffer}). + +@item C-c C-y +@kindex C-c C-y +@findex xscheme-yank-previous-send +Yanks the most recently evaluated expression, placing it at point +(@code{xscheme-yank-previous-send}). This works only in the +@code{*scheme*} buffer. +@end table + +The following commands provide interrupt capability: + +@table @kbd + +@item C-c C-c +@kindex C-c C-c +@findex xscheme-send-control-g-interrupt +Like typing @kbd{C-g} when running Scheme without Emacs +(@code{xscheme-send-control-g-interrupt}). + +@item C-c C-x +@kindex C-c C-x +@findex xscheme-send-control-x-interrupt +Like typing @kbd{C-c C-x} when running Scheme without Emacs +(@code{xscheme-send-control-x-interrupt}). + +@item C-c C-u +@kindex C-c C-u +@findex xscheme-send-control-u-interrupt +Like typing @kbd{C-c C-u} when running Scheme without Emacs +(@code{xscheme-send-control-u-interrupt}). + +@item C-c C-b +@kindex C-c C-b +@findex xscheme-send-breakpoint-interrupt +Like typing @kbd{C-c C-b} when running Scheme without Emacs +(@code{xscheme-send-breakpoint-interrupt}). + +@item C-c C-p +@kindex C-c C-p +@findex xscheme-send-proceed +Like evaluating @code{(proceed)} (@code{xscheme-send-proceed}). +@end table + +@node Edwin, Variable Index, GNU Emacs Interface, Top +@chapter Edwin + +This chapter describes how to start Edwin, the MIT Scheme text editor. +Edwin is very similar to GNU Emacs --- you should refer to the GNU Emacs +manual for information about Edwin's commands and key bindings --- +except that Edwin's extension language is MIT Scheme, while GNU Emacs +extensions are written in Emacs Lisp. This manual does not discuss +customization of Edwin. + +To use Edwin, start Scheme with a world image containing Edwin (for +example by giving the @code{-edwin} command-line option), then call the +procedure @code{edit}: + +@deffn {procedure+} edit +Enter the Edwin text editor. If entering for the first time, the editor +is initialized (by calling @code{create-editor} with no arguments). +Otherwise, the previously-initialized editor is reentered. + +@findex edwin +The procedure @code{edwin} is an alias for @code{edit}. +@end deffn + +@defvr {variable+} inhibit-editor-init-file? +When Edwin is first initialized, it loads your init file (called +@file{~/.edwin}) if you have one. If the Scheme variable +@code{inhibit-editor-init-file?} is true, however, your init file will +not be loaded even if it exists. By default, this variable is false. +@end defvr + +@deffn {procedure+} create-editor arg @dots{} +Initializes Edwin, or reinitializes it if already initialized. +@code{Create-editor} is normally invoked automatically by @code{edit}. + +If no @var{arg}s are given, the value of @code{create-editor-args} is +used instead. In other words, the following are equivalent: + +@lisp +(create-editor) +(apply create-editor create-editor-args) +@end lisp + +@noindent +On the other hand, if @var{arg}s are given, they are used to update +@code{create-editor-args}, making the following equivalent: + +@lisp +(apply create-editor @var{args}) +(begin (set! create-editor-args @var{args}) (create-editor)) +@end lisp +@end deffn + +@defvr {variable+} create-editor-args +This variable controls the initialization of Edwin. The following +values are defined: + +@table @code + +@item (console) +This says to run Edwin on Scheme's console, or in unix terminology, the +standard input and output. If the console is not a terminal device, or +is not powerful enough to run Edwin, an error will be signalled at +initialization time. + +@item (x) +@findex DISPLAY +This says to create an X window and run Edwin on it. This requires the +@code{DISPLAY} environment variable to have been set to the appropriate +value before Scheme was started. + +@item (x @var{geometry}) +This is like @code{(x)} except that @var{geometry} specifies the +window's geometry in the usual way. @var{Geometry} must be a character +string whose contents is an X geometry specification. + +@item (#f) +This is the default. It says to try running Edwin on Scheme's console, +and failing that, to create an X window and run Edwin on that. This +signals an error if neither the console nor the X display is usable. +@end table +@end defvr + +Once Edwin has been entered, it can be exited in the following ways: + +@table @kbd + +@item C-x z +@kindex C-x z +@findex suspend-edwin +Stop Edwin and return to Scheme (@code{suspend-edwin}). The call to the +procedure @code{edit} that entered Edwin returns normally. A subsequent +call to @code{edit} will resume Edwin where it was stopped. + +@item C-x c +@kindex C-x c +@findex save-buffers-kill-edwin +Offer to save any modified buffers, then kill Edwin, returning to Scheme +(@code{save-buffers-kill-edwin}). This is like the @code{suspend-edwin} +command, except that a subsequent call to @code{edit} will reinitialize +the editor. + +@item C-x C-z +@kindex C-x C-z +@findex suspend-scheme +Stop Edwin and suspend Scheme, returning control to the operating +system's command interpreter (@code{suspend-scheme}). When Scheme is +resumed (using the command interpreter's job-control commands), Edwin is +automatically restarted where it was stopped. This command is identical +to the @kbd{C-x C-z} command of GNU Emacs. + +@item C-x C-c +@kindex C-x C-c +@findex save-buffers-kill-scheme +Offer to save any modified buffers, then kill both Edwin and Scheme +(@code{save-buffers-kill-scheme}). Control is returned to the operating +system's command interpreter, and the Scheme process is terminated. +This command is identical to the @kbd{C-x C-c} command of GNU Emacs. +@end table + +The following Scheme procedures are useful for recovering from bugs in +Edwin's implementation. All of them are designed for use when Edwin is +@emph{not} running --- they should not be used when Edwin is running. +These procedures are designed to help Edwin's implementors deal with +bugs during the implementation of the editor; they are not intended for +casual use, but as a means of recovering from bugs that would otherwise +require reloading the editor's world image from the disk. + +@deffn {procedure+} save-editor-files +Examines Edwin, offering to save any unsaved buffers. This is useful if +some bug caused Edwin to die while there were unsaved buffers, and you +want to save the information without restarting the editor. +@end deffn + +@deffn {procedure+} reset-editor +Resets Edwin, causing it to be reinitialized the next time that +@code{edit} is called. If you encounter a fatal bug in Edwin, a good +way to recover is to first call @code{save-editor-files}, and then to +call @code{reset-editor}. That should completely reset the editor to +its initial state. +@end deffn + +@deffn {procedure+} reset-editor-windows +Resets Edwin's display structures, without affecting any of the buffers +or their contents. This is useful if a bug in the display code causes +Edwin's internal display data structures to get into an inconsistent +state that prevents Edwin from running. +@end deffn + +@node Variable Index, Key Index, Edwin, Top +@unnumbered Variable, Declaration, and Option Index +@printindex fn + +@node Key Index, Concept Index, Variable Index, Top +@unnumbered Key Index +@printindex ky + +@node Concept Index, , Key Index, Top +@unnumbered Concept Index +@printindex cp + +@contents +@bye + +@c Local Variables: +@c selective-display: t +@c truncate-lines: t +@c End: