Chapter 1. Introduction

Chez Scheme is an implementation of ANSI/IEEE Standard Scheme [19] with support for all required and optional features of the Revised4 and Revised5 Reports on Scheme [6,20] along with numerous language and programming environment extensions.

This book describes these extensions in detail. It contains as well a description of the formal syntax of the extended language and a concise summary of standard and Chez Scheme forms and procedures, which gives the syntax of each form and the number and types of arguments accepted by each procedure. Details on standard Scheme features can be found in The Scheme Programming Language, Second Edition [9] or the Revised5 Report on Scheme. The Scheme Programming Language, Second Edition also contains an introduction to the Scheme language.

The remainder of this chapter covers Chez Scheme syntax (Section 1.1), notational conventions (Section 1.2), parameters (Section 1.3), the interaction environment (Section 1.4), and where to look for more information on Chez Scheme (Section 1.5).

Chapter 2 describes debugging and object inspection facilities. Chapter 3 documents facilities for interacting with separate processes or code written in other languages. Chapter 4 describes binding forms. Chapter 5 documents control structures. Chapter 6 documents operations on nonnumeric objects, while Chapter 7 documents various numeric operations, including efficient type-specific operations. Chapter 8 describes input/output operations and generic ports, which allow the definition of ports with arbitrary input/output semantics. Chapter 9 describes syntactic extension and modules. Chapter 10 describes system operations, such as operations for interacting with the operating system and customizing Chez Scheme's user interface. Chapter 11 describes how to invoke and control the storage management system and documents guardians and weak pairs. Chapter 12 describes various compatibility features.

The back of this book contains a bibliography, the description of formal syntax, the summary of forms, and an index. The page numbers appearing in the summary of forms and the italicized page numbers appearing in the index indicate the locations in the text where forms and procedures are formally defined.

Acknowledgements: Mike Ashley, Carl Bruggeman, Bob Burger, Bob Hieb, and Oscar Waddell contributed significantly to the development of Chez Scheme and to this book. Many of the features documented in this book were suggested by current Chez Scheme users. Additional suggestions for improvements to Chez Scheme and to this book are welcome.

About the illustrations: The illustrations appearing on the cover and at the front of each chapter were created by artist Jean-Pierre Hébert with the help of a Chez Scheme program. This series is an extension of Hébert's "One Hundred Views of a Single Theme," which was inspired by Max Bill's "Fifteen Variations on a Single Theme," a set of 16 lithographs produced during 1935-1938, and Hokusai's "One Hundred Views of Mount Fuji," produced from 1834-1847. The illustrations were developed for their aesthetic possibilities and to fulfill the expectations foreseen at the time of Constructivism, the Bauhaus, and De Stilj in the first part of the 20th century. They exploit mathematics, a universal language, particularly empowered by geometry programming, as a true medium for creativity, expressiveness, and art. More of Hébert's "Hundred Views" can be found in a series of prints published by Cone Edition Press (Topsham, VT) starting in 1998.

The cover illustration exposes the polygonal nature of the Theme. In the Theme, each polygon is missing a side, while in the cover, the polygons are outlined and filled using two gradations of colors (yellow to cyan) and grays (black to white).The illustrations appearing at the front of each chapter are in two tracks: a curvilinear track, in which each segment of the Theme is replaced by half-circle patterns alternatively flipped within and without the polygonal line, and a rectilinear track, which reflects the Theme more directly.


Section 1.1. Chez Scheme Syntax

Chez Scheme extends Scheme's syntax both at the object (datum) level and at the level of syntactic forms. At the object level, Chez Scheme supports representations for symbols that contain nonstandard characters, IEEE floating-point infinities and NANs, nondecimal numbers expressed in floating-point and scientific notation, vectors with explicit lengths, shared and cyclic structures, records, boxes, and more.

Object-level extensions are summarized below and detailed in the formal syntax appendix in the back of this book. Form-level extensions are described throughout the book and summarized in the Summary of Forms, which also appears in the back of this book.

The standard syntax for identifiers (symbols, variables, keywords, and module names) requires that they be formed from the following set of characters:

Standard identifiers normally cannot start with any character that may start a number, i.e., a digit, plus sign ( + ), minus sign ( - ), or decimal point ( . ). Exceptions are +-, and ..., which are valid identifiers. For example, hi, Hello, n, x, x3, and ?$&*!!! are all identifiers. Identifiers must be delimited by whitespace, parentheses, a string (double) quote ( " ), or the comment character ( ; ).

Chez Scheme extends the syntax of identifiers in several ways. First, the sequence of characters making up an identifier's name may start with digits, periods, plus signs, and minus signs as long as the sequence cannot be parsed as a number. For example, 0abc, +++, and .. are all valid identifiers in Chez Scheme. Second, identifiers may contain embedded # characters, e.g., abc#def. Third, the single-character sequences { and } are identifiers. Finally, identifiers containing arbitrary characters may be printed by escaping them them with \ or with |. \ is used to escape a single character, the one that follows, as in the syntax of strings, whereas | is used to escape the group of characters that follow it up through the matching |. For example, \||\| is an identifier with a two-character name consisting of the character | followed by the the character \, and |hit me!| is an identifier whose name contains a space. Upper-case letters are usually converted to lower-case letters in an identifier's name, but escaping them prevents this conversion from taking place. For example, while ABC and Abc are both equivalent to abc, |ABC|, |Abc|, and abc are all distinct identifiers.

In addition, uninterned symbols are printed with the prefix #:, e.g., #:abc.

Chez Scheme allows matched sets of square brackets, [ and ], to be used in place of parentheses. This feature is often used when typing programs to set off certain portions of the syntax. For example,

(let ([x e1] [y e2])
  (cond
    [(eq? x y) 'yes]
    [else 'no]))

is equivalent to

(let ((x e1) (y e2))
  (cond
    ((eq? x y) 'yes)
    (else 'no)))

Arbitrary radixes from two through 36 may be specified with the prefix #nr, where n is the radix. Case is not significant, so #nR may be used as well. Digit values from 10 through 35 are specified as either lower- or upper-case alphabetic characters, just as for hexadecimal numbers. For example, #36rZZ is 35 × 36 + 35, or 1295.

Chez Scheme also permits nondecimal numbers to be printed in floating-point or scientific notation. For example, #o1.4 is equivalent to 1.5, and #b1e10 is equivalent to 4.0. Digits take precedence over exponent specifiers, so that #x1e20 is simply the four-digit hexadecimal number equivalent to 7712.

IEEE floating-point (inexact) infinities and NANs are represented by the syntaxes +inf.0 for positive infinity, -inf.0 for negative infinity, and +nan.0 for NANs. -nan.0 may be used to refer to NANs as well, although the system prints all NANs as +nan.0. Case is not significant, so that, for example, +Inf.0 and +INF.0 are both equivalent to +inf.0.

In addition to #\space and #\newline, Chez Scheme recognizes #\backspace, #\linefeed (same as \#newline), #\nul, #\page, #\return, #\rubout, and #\tab, Of these, all but \#rubout and #\nul are considered whitespace characters. Characters may also be printed with an octal syntax consisting of the prefix #\ followed by a three octal-digit sequence. For example, #\000 is equivalent to #\nul.

Vectors may be printed with an explicit length prefix, and when the explicit length prefix is specified, duplicate trailing elements may be omitted. For example, #(a b c) may be printed as #3(a b c), and a vector of length 100 containing all zeros may be printed as #100(0). The printer generally prints the prefix and suppresses duplicate trailing elements unless the parameter print-vector-length is set to false.

Boxes are single-celled objects, like pairs without cdr cells. They are printed with a #& prefix, e.g., #&17 is a box containing the integer 17.

Records are printed with the syntax #[type-name field ...], where type-name is the string name of the record type and field ... are the printed representations for the contents of the fields of the record.

Shared and cyclic structure may be printed using the graph mark and reference prefixes #n= and #n#. #n= is used to mark an item in the input, and #n# is used to refer to the item marked n. For example, '(#1=(a) . #1#) is a pair whose car and cdr contain the same list, and #0=(a . #0#) is a cyclic list, i.e., its cdr is itself.

A syntax form (see page 164) may be abbreviated in the same manner as a quote form, using the prefix #' in place of '. That is, #'datum is equivalent to (syntax datum). A \#primitive form (see page 199) may be abbreviated similarly with the #% prefix, e.g., #%car or #2%car.

Chez Scheme employs a single end-of-file object, which is printed #!eof. If the end-of-file object appears outside of any datum within a file being loaded, load will treat it as if it were a true end of file and stop loading at that point. Inserting #!eof into the middle of a file can thus be handy when tracking down a load-time error.

Broken pointers in weak pairs (see page 218) are represented by the broken weak pointer object, which is printed #!bwp.

For backwards compatibility with early revised reports on Scheme, #t may be printed as #!true, #f as #!false, and () as #!null.

Fast-loading format objects (see Section 8.8), including object code produced by the compiler, are printed with the prefix #@.

Comments may begin as usual with a semicolon and continue to the end of a line.

;;; the following procedure computes the sum of the
;;; squares of its arguments
(define sum-of-squares
  (lambda args
    (apply + (map (lambda (x) (* x x)) args))))

Chez Scheme allows two additional ways to insert comments. First, comments may blocked with properly nested #| and |# pairs.

#| the following procedure computes the sum of the #| here's a
   nested comment just for fun |# squares of its arguments |#
(define sum-of-squares
  (lambda args
    (apply + (map (lambda (x) (* x x)) args))))

Second, comments may begin with the prefix #;, in which case they end with the end of the next datum. This is useful for quickly commenting out sections of code while developing a program.

(define test1
  (lambda (#;arg) ; no argument for now
    #; ; the following definition doesn't work
    (define nan? (lambda (x) (= x nan?)))
    ; this definition does
    (define nan? (lambda (x) (not (= x x))))
    (list (nan? 0.0) (nan? (/ 0.0 0.0)))))
(test1)  (#f #t)


Section 1.2. Notational Conventions

This book follows essentially the same notational conventions as The Scheme Programming Language, Second Edition. These conventions are repeated below, with notes specific to Chez Scheme.

When the value produced by a procedure or syntactic form is said to be unspecified, the value may be any Scheme object. Chez Scheme usually returns a unique void object (see void) whenever the result is unspecified; avoid counting on this behavior, however, especially if your program may be ported to another Scheme implementation. Printing of the void object is suppressed by Chez Scheme's waiter (read-evaluate-print loop).

This book uses the phrase "an error will be signaled" to identify errors that the implementation always detects and signals. The phrase "it is an error" identifies a situation that violates some requirement of the language but that the implementation may not necessarily detect. Except at the highest optimization level, Chez Scheme detects and signals errors in both categories via the error handling facilities described in 10.1 whenever feasible.

Although most Scheme expressions may evaluate to multiple values, this book usually refers to the result of an expression as a single value. Multiple values are produced by the Scheme procedure values and may be received using the Scheme procedure call-with-values. Both procedures are documented in Section 5.8 of The Scheme Programming Language, Second Edition.

Scheme objects are displayed in a typewriter typeface just as they are to be typed at the keyboard. This includes syntactic keywords, variables, constant objects, Scheme expressions, and example programs. An italic typeface is used to set off syntax variables in the descriptions of syntactic forms and arguments in the descriptions of procedures. Italics are also used to set off technical terms the first time they appear. In general, names written in typewriter font are never capitalized (even at the beginning of a sentence). The same is true for syntax variables written in italics.

In the description of a syntactic form or procedure, a pattern shows the syntactic form or the application of the procedure. The syntax keyword or procedure name is given in typewriter font, as are parentheses. The remaining pieces of the syntax or arguments are shown in italics, using names that imply the types of the expressions or arguments expected by the syntactic form or procedure. Ellipses are used to specify zero or more occurrences of a subexpression or argument.


Section 1.3. Parameters

All Chez Scheme system customization is done via parameters. A parameter is a procedure that encapsulates a hidden state variable. When invoked without arguments, a parameter returns the value of the encapsulated variable. When invoked with one argument, the parameter changes the value of the variable to the value of its argument. A parameter may signal an error if its argument is not appropriate.

New parameters may be created and used by programs running in Chez Scheme. Parameters are used rather than global variables for program customization for two reasons: First, unintentional redefinition of a customization variable can cause unexpected problems, whereas unintentional redefinition of a parameter simply makes the parameter inaccessible. For example, a program that defines *print-level* for its own purposes in early releases of Chez Scheme would have unexpected effects on the printing of Scheme objects, whereas a program that defines print-level for its own purposes simply loses the ability to alter the printers behavior. Of course, a program that invokes print-level by accident can still affect the system in unintended ways, but such an occurrence is less likely, and can only happen in an incorrect program.

Second, invalid values for parameters can be detected and rejected immediately when the "assignment" is made, rather than at the point where the first use occurs, when it is too late to recover and reinstate the old value. For example, an assignment of *print-level* to -1 would not have been caught until the first call to write or pretty-print, whereas an attempted assignment of -1 to the parameter print-level, i.e., (print-level -1), is signaled as an error immediately, before the change is actually made.

See Section 10.7 for more information on creating and manipulating parameters. Built-in system parameters are described in different sections throughout this book and are listed along with other syntactic forms and procedures in the Summary of Forms in the back of this book.


Section 1.4. Interacting with Chez Scheme

Chez Scheme is normally used interactively. The system prompts the user with a right angle bracket ">" at the beginning of each input line. Any Scheme expression may be entered. The system evaluates the expression and prints the result. After printing the result, the system prompts again for more input.

Typically, a Scheme programmer creates a source file of Scheme forms using a text editor and loads the file into Chez Scheme to test them. The conventional filename extension for Chez Scheme source files is ".ss". A source file may be loaded during an interactive session by typing (load "filename"). Files to be loaded may also be named on the command line when the system is started. Any form that may be typed interactively may be placed in a file to be loaded.

Chez Scheme compiles source forms as it sees them to machine code before evaluating them. In order to speed loading of a large file, the file may be compiled with the output placed in an object file. (compile-file "filename") compiles the forms in the file "filename.ss" and places the resulting object code in the file "filename.so". Loading a pre-compiled file is no different from loading the source file, except that loading is faster since compilation is already done.

You can exit the system by typing the end-of-file character or by using the procedure exit. Typing the end-of-file character is equivalent to (exit), (exit (void)), or (exit 0), each of which is considered a normal exit. Any other argument to exit is considered an abormal exit and returns an error status to the invoking shell.

Interaction of the system with the user is performed by a Scheme program called a waiter, running in a program state called a café. The waiter is a read-evaluate-print loop, or REPL: it prompts for input, reads the input, evaluates the input, prints the result, and loops back for more.

Running programs may be interrupted by typing the interrupt character (typically Control-C). In response, the system enters a debug handler, which prompts for input with a "debug>" prompt. Several commands may be issued to the debug handler, including

"e"
or end-of-file to exit from the handler and continue,
"r"
to stop execution and reset to the current café,
"a"
to abort Chez Scheme,
"n"
to enter a new café (see below),
"i"
to inspect the current continuation, and
"s"
to display statistics about the interrupted program.
While typing an input expression to the waiter, the interrupt character simply resets to the current café.

When an error occurs, the system prints an error message and resets. Typing (debug) after an error occurs places you into the debug handler, where you can inspect the current continuation (control stack) to help determine the cause of the problem.

It is possible to open up a chain of Chez Scheme cafés by invoking the new-cafe procedure with no arguments. Entering a new cafe is also one of the options when an interrupt occurs (see below). Each café has its own reset and exit handlers. Exiting from one café in the chain returns you to the next one back, and so on, until the entire chain closes and you leave the system altogether. Sometimes it is useful to interrupt a long computation by typing the interrupt character, enter a new café to execute something (perhaps to check a status variable set by the computation), and exit the café back to the old computation.

You can tell what level you are at by the number of angle brackets in the prompt, one for level one, two for level two, and so on. Three angle brackets in the prompt means you would have to exit from three cafés to leave Chez Scheme. If you wish to abort from Chez Scheme and you are several cafés deep, the procedure abort leaves the system directly.

It is possible to use Chez Scheme as a batch process by performing all processing in a loaded file or by redirecting its input to a file or pipe. A file compile may be run in batch mode via a shell command such as the following:

echo '(compile-file "filename")' | scheme

When running in batch mode, especially from within "make" files, it is often desirable to force the error handler to exit immediately to the shell with a nonzero exit status. The description of error-handler on page 186 demonstrates how to do so.


Section 1.5. More Information

A wide range of articles and technical reports document features of Chez Scheme and its implementation:

Electronic versions of many of these publications are available via links on the Chez Scheme web page, http://www.scheme.com.


Chez Scheme User's Guide
© 1998 R. Kent Dybvig
Cadence Research Systems
http://www.scheme.com
Illustrations © 1998 Jean-Pierre Hébert
about this book