This action might not be possible to undo. Are you sure you want to continue?

Welcome to Scribd! Start your free trial and access books, documents and more.Find out more

6

Report on the Algorithmic Language

Scheme

MICHAEL SPERBER

R. KENT DYBVIG, MATTHEW FLATT, ANTON VAN STRAATEN

(Editors)

RICHARD KELSEY, WILLIAM CLINGER, JONATHAN REES

(Editors, Revised

5

Report on the Algorithmic Language Scheme)

ROBERT BRUCE FINDLER, JACOB MATTHEWS

(Authors, formal semantics)

26 September 2007

SUMMARY

The report gives a deﬁning description of the programming language Scheme. Scheme is a statically scoped and properly

tail-recursive dialect of the Lisp programming language invented by Guy Lewis Steele Jr. and Gerald Jay Sussman. It was

designed to have an exceptionally clear and simple semantics and few diﬀerent ways to form expressions. A wide variety

of programming paradigms, including functional, imperative, and message passing styles, ﬁnd convenient expression in

Scheme.

This report is accompanied by a report describing standard libraries [24]; references to this document are identiﬁed by

designations such as “library section” or “library chapter”. It is also accompanied by a report containing non-normative

appendices [22]. A fourth report gives some historical background and rationales for many aspects of the language and

its libraries [23].

The individuals listed above are not the sole authors of the text of the report. Over the years, the following individuals

were involved in discussions contributing to the design of the Scheme language, and were listed as authors of prior reports:

Hal Abelson, Norman Adams, David Bartley, Gary Brooks, William Clinger, R. Kent Dybvig, Daniel Friedman, Robert

Halstead, Chris Hanson, Christopher Haynes, Eugene Kohlbecker, Don Oxley, Kent Pitman, Jonathan Rees, Guillermo

Rozas, Guy L. Steele Jr., Gerald Jay Sussman, and Mitchell Wand.

In order to highlight recent contributions, they are not listed as authors of this version of the report. However, their

contribution and service is gratefully acknowledged.

We intend this report to belong to the entire Scheme community, and so we grant permission to copy it in whole or in

part without fee. In particular, we encourage implementors of Scheme to use this report as a starting point for manuals

and other documentation, modifying it as necessary.

2 Revised

6

Scheme

CONTENTS

Introduction . . . . . . . . . . . . . . . . . . . . . . 3

Description of the language

1 Overview of Scheme . . . . . . . . . . . . . . . . . 5

1.1 Basic types . . . . . . . . . . . . . . . . . . 5

1.2 Expressions . . . . . . . . . . . . . . . . . . 6

1.3 Variables and binding . . . . . . . . . . . . 6

1.4 Deﬁnitions . . . . . . . . . . . . . . . . . . . 6

1.5 Forms . . . . . . . . . . . . . . . . . . . . . 7

1.6 Procedures . . . . . . . . . . . . . . . . . . 7

1.7 Procedure calls and syntactic keywords . . . 7

1.8 Assignment . . . . . . . . . . . . . . . . . . 7

1.9 Derived forms and macros . . . . . . . . . . 8

1.10 Syntactic data and datum values . . . . . . 8

1.11 Continuations . . . . . . . . . . . . . . . . . 8

1.12 Libraries . . . . . . . . . . . . . . . . . . . . 9

1.13 Top-level programs . . . . . . . . . . . . . . 9

2 Requirement levels . . . . . . . . . . . . . . . . . 9

3 Numbers . . . . . . . . . . . . . . . . . . . . . . . 10

3.1 Numerical tower . . . . . . . . . . . . . . . 10

3.2 Exactness . . . . . . . . . . . . . . . . . . . 10

3.3 Fixnums and ﬂonums . . . . . . . . . . . . . 10

3.4 Implementation requirements . . . . . . . . 10

3.5 Inﬁnities and NaNs . . . . . . . . . . . . . . 11

3.6 Distinguished -0.0 . . . . . . . . . . . . . . 11

4 Lexical syntax and datum syntax . . . . . . . . . 11

4.1 Notation . . . . . . . . . . . . . . . . . . . . 12

4.2 Lexical syntax . . . . . . . . . . . . . . . . . 12

4.3 Datum syntax . . . . . . . . . . . . . . . . . 16

5 Semantic concepts . . . . . . . . . . . . . . . . . . 17

5.1 Programs and libraries . . . . . . . . . . . . 17

5.2 Variables, keywords, and regions . . . . . . 17

5.3 Exceptional situations . . . . . . . . . . . . 18

5.4 Argument checking . . . . . . . . . . . . . . 18

5.5 Syntax violations . . . . . . . . . . . . . . . 19

5.6 Safety . . . . . . . . . . . . . . . . . . . . . 19

5.7 Boolean values . . . . . . . . . . . . . . . . 19

5.8 Multiple return values . . . . . . . . . . . . 19

5.9 Unspeciﬁed behavior . . . . . . . . . . . . . 20

5.10 Storage model . . . . . . . . . . . . . . . . . 20

5.11 Proper tail recursion . . . . . . . . . . . . . 20

5.12 Dynamic extent and the dynamic environment 20

6 Entry format . . . . . . . . . . . . . . . . . . . . . 20

6.1 Syntax entries . . . . . . . . . . . . . . . . . 21

6.2 Procedure entries . . . . . . . . . . . . . . . 21

6.3 Implementation responsibilities . . . . . . . 22

6.4 Other kinds of entries . . . . . . . . . . . . 22

6.5 Equivalent entries . . . . . . . . . . . . . . . 22

6.6 Evaluation examples . . . . . . . . . . . . . 22

6.7 Naming conventions . . . . . . . . . . . . . 23

7 Libraries . . . . . . . . . . . . . . . . . . . . . . . 23

7.1 Library form . . . . . . . . . . . . . . . . . 23

7.2 Import and export levels . . . . . . . . . . . 25

7.3 Examples . . . . . . . . . . . . . . . . . . . 26

8 Top-level programs . . . . . . . . . . . . . . . . . 27

8.1 Top-level program syntax . . . . . . . . . . 27

8.2 Top-level program semantics . . . . . . . . . 28

9 Primitive syntax . . . . . . . . . . . . . . . . . . . 28

9.1 Primitive expression types . . . . . . . . . . 28

9.2 Macros . . . . . . . . . . . . . . . . . . . . . 29

10 Expansion process . . . . . . . . . . . . . . . . . . 29

11 Base library . . . . . . . . . . . . . . . . . . . . . 31

11.1 Base types . . . . . . . . . . . . . . . . . . . 31

11.2 Deﬁnitions . . . . . . . . . . . . . . . . . . . 31

11.3 Bodies . . . . . . . . . . . . . . . . . . . . . 32

11.4 Expressions . . . . . . . . . . . . . . . . . . 32

11.5 Equivalence predicates . . . . . . . . . . . . 37

11.6 Procedure predicate . . . . . . . . . . . . . 39

11.7 Arithmetic . . . . . . . . . . . . . . . . . . . 39

11.8 Booleans . . . . . . . . . . . . . . . . . . . . 47

11.9 Pairs and lists . . . . . . . . . . . . . . . . . 47

11.10Symbols . . . . . . . . . . . . . . . . . . . . 49

11.11Characters . . . . . . . . . . . . . . . . . . . 50

11.12Strings . . . . . . . . . . . . . . . . . . . . . 50

11.13Vectors . . . . . . . . . . . . . . . . . . . . 51

11.14Errors and violations . . . . . . . . . . . . . 52

11.15Control features . . . . . . . . . . . . . . . . 53

11.16Iteration . . . . . . . . . . . . . . . . . . . . 55

11.17Quasiquotation . . . . . . . . . . . . . . . . 55

11.18Binding constructs for syntactic keywords . 56

11.19Macro transformers . . . . . . . . . . . . . . 57

11.20Tail calls and tail contexts . . . . . . . . . . 59

Appendices

A Formal semantics . . . . . . . . . . . . . . . . . . 61

A.1 Background . . . . . . . . . . . . . . . . . . 61

A.2 Grammar . . . . . . . . . . . . . . . . . . . 62

A.3 Quote . . . . . . . . . . . . . . . . . . . . . 65

A.4 Multiple values . . . . . . . . . . . . . . . . 65

A.5 Exceptions . . . . . . . . . . . . . . . . . . 67

A.6 Arithmetic and basic forms . . . . . . . . . 69

A.7 Lists . . . . . . . . . . . . . . . . . . . . . . 69

A.8 Eqv . . . . . . . . . . . . . . . . . . . . . . 69

A.9 Procedures and application . . . . . . . . . 70

A.10 Call/cc and dynamic wind . . . . . . . . . . 72

A.11 Letrec . . . . . . . . . . . . . . . . . . . . . 73

A.12 Underspeciﬁcation . . . . . . . . . . . . . . 74

B Sample deﬁnitions for derived forms . . . . . . . . 75

C Additional material . . . . . . . . . . . . . . . . . 77

D Example . . . . . . . . . . . . . . . . . . . . . . . 77

E Language changes . . . . . . . . . . . . . . . . . . 79

References . . . . . . . . . . . . . . . . . . . . . . . . 80

Alphabetic index of deﬁnitions of concepts, key-

words, and procedures . . . . . . . . . . . . . . . 82

Introduction 3

INTRODUCTION

Programming languages should be designed not by piling

feature on top of feature, but by removing the weaknesses

and restrictions that make additional features appear nec-

essary. Scheme demonstrates that a very small number of

rules for forming expressions, with no restrictions on how

they are composed, suﬃce to form a practical and eﬃcient

programming language that is ﬂexible enough to support

most of the major programming paradigms in use today.

Scheme was one of the ﬁrst programming languages to in-

corporate ﬁrst-class procedures as in the lambda calculus,

thereby proving the usefulness of static scope rules and

block structure in a dynamically typed language. Scheme

was the ﬁrst major dialect of Lisp to distinguish proce-

dures from lambda expressions and symbols, to use a sin-

gle lexical environment for all variables, and to evaluate

the operator position of a procedure call in the same way

as an operand position. By relying entirely on procedure

calls to express iteration, Scheme emphasized the fact that

tail-recursive procedure calls are essentially gotos that pass

arguments. Scheme was the ﬁrst widely used programming

language to embrace ﬁrst-class escape procedures, from

which all previously known sequential control structures

can be synthesized. A subsequent version of Scheme in-

troduced the concept of exact and inexact number objects,

an extension of Common Lisp’s generic arithmetic. More

recently, Scheme became the ﬁrst programming language

to support hygienic macros, which permit the syntax of a

block-structured language to be extended in a consistent

and reliable manner.

Guiding principles

To help guide the standardization eﬀort, the editors have

adopted a set of principles, presented below. Like the

Scheme language deﬁned in Revised

5

Report on the Algo-

rithmic Language Scheme [14], the language described in

this report is intended to:

• allow programmers to read each other’s code, and al-

low development of portable programs that can be ex-

ecuted in any conforming implementation of Scheme;

• derive its power from simplicity, a small number of

generally useful core syntactic forms and procedures,

and no unnecessary restrictions on how they are com-

posed;

• allow programs to deﬁne new procedures and new hy-

gienic syntactic forms;

• support the representation of program source code as

data;

• make procedure calls powerful enough to express any

form of sequential control, and allow programs to per-

form non-local control operations without the use of

global program transformations;

• allow interesting, purely functional programs to run

indeﬁnitely without terminating or running out of

memory on ﬁnite-memory machines;

• allow educators to use the language to teach program-

ming eﬀectively, at various levels and with a variety of

pedagogical approaches; and

• allow researchers to use the language to explore the de-

sign, implementation, and semantics of programming

languages.

In addition, this report is intended to:

• allow programmers to create and distribute substan-

tial programs and libraries, e.g., implementations of

Scheme Requests for Implementation, that run with-

out modiﬁcation in a variety of Scheme implementa-

tions;

• support procedural, syntactic, and data abstraction

more fully by allowing programs to deﬁne hygiene-

bending and hygiene-breaking syntactic abstractions

and new unique datatypes along with procedures and

hygienic macros in any scope;

• allow programmers to rely on a level of automatic run-

time type and bounds checking suﬃcient to ensure

type safety; and

• allow implementations to generate eﬃcient code, with-

out requiring programmers to use implementation-

speciﬁc operators or declarations.

While it was possible to write portable programs in Scheme

as described in Revised

5

Report on the Algorithmic Lan-

guage Scheme, and indeed portable Scheme programs were

written prior to this report, many Scheme programs were

not, primarily because of the lack of substantial stan-

dardized libraries and the proliferation of implementation-

speciﬁc language additions.

In general, Scheme should include building blocks that al-

low a wide variety of libraries to be written, include com-

monly used user-level features to enhance portability and

readability of library and application code, and exclude fea-

tures that are less commonly used and easily implemented

in separate libraries.

The language described in this report is intended to also be

backward compatible with programs written in Scheme as

4 Revised

6

Scheme

described in Revised

5

Report on the Algorithmic Language

Scheme to the extent possible without compromising the

above principles and future viability of the language. With

respect to future viability, the editors have operated under

the assumption that many more Scheme programs will be

written in the future than exist in the present, so the fu-

ture programs are those with which we should be most

concerned.

Acknowledgements

Many people contributed signiﬁcant help to this revision

of the report. Speciﬁcally, we thank Aziz Ghuloum and

Andr´e van Tonder for contributing reference implemen-

tations of the library system. We thank Alan Bawden,

John Cowan, Sebastian Egner, Aubrey Jaﬀer, Shiro Kawai,

Bradley Lucier, and Andr´e van Tonder for contributing in-

sights on language design. Marc Feeley, Martin Gasbichler,

Aubrey Jaﬀer, Lars T Hansen, Richard Kelsey, Olin Shiv-

ers, and Andr´e van Tonder wrote SRFIs that served as

direct input to the report. Marcus Crestani, David Frese,

Aziz Ghuloum, Arthur A. Gleckler, Eric Knauel, Jonathan

Rees, and Andr´e van Tonder thoroughly proofread early

versions of the report.

We would also like to thank the following people for their

help in creating this report: Lauri Alanko, Eli Barzilay,

Alan Bawden, Brian C. Barnes, Per Bothner, Trent Buck,

Thomas Bushnell, Taylor Campbell, Ludovic Court`es, Pas-

cal Costanza, John Cowan, Ray Dillinger, Jed Davis, J.A.

“Biep” Durieux, Carl Eastlund, Sebastian Egner, Tom

Emerson, Marc Feeley, Matthias Felleisen, Andy Free-

man, Ken Friedenbach, Martin Gasbichler, Arthur A.

Gleckler, Aziz Ghuloum, Dave Gurnell, Lars T Hansen,

Ben Harris, Sven Hartrumpf, Dave Herman, Nils M.

Holm, Stanislav Ievlev, James Jackson, Aubrey Jaﬀer,

Shiro Kawai, Alexander Kjeldaas, Eric Knauel, Michael

Lenaghan, Felix Klock, Donovan Kolbly, Marcin Kowal-

czyk, Thomas Lord, Bradley Lucier, Paulo J. Matos, Dan

Muresan, Ryan Newton, Jason Orendorﬀ, Erich Rast,

Jeﬀ Read, Jonathan Rees, Jorgen Sch¨afer, Paul Schlie,

Manuel Serrano, Olin Shivers, Jonathan Shapiro, Jens Axel

Søgaard, Jay Sulzberger, Pinku Surana, Mikael Tillenius,

Sam Tobin-Hochstadt, David Van Horn, Andr´e van Ton-

der, Reinder Verlinde, Alan Watson, Andrew Wilcox, Jon

Wilson, Lynn Winebarger, Keith Wright, and Chongkai

Zhu.

We would like to thank the following people for their help

in creating the previous revisions of this report: Alan

Bawden, Michael Blair, George Carrette, Andy Cromarty,

Pavel Curtis, Jeﬀ Dalton, Olivier Danvy, Ken Dickey,

Bruce Duba, Marc Feeley, Andy Freeman, Richard Gabriel,

Yekta G¨ ursel, Ken Haase, Robert Hieb, Paul Hudak,

Morry Katz, Chris Lindblad, Mark Meyer, Jim Miller, Jim

Philbin, John Ramsdell, Mike Shaﬀ, Jonathan Shapiro,

Julie Sussman, Perry Wagle, Daniel Weise, Henry Wu, and

Ozan Yigit.

We thank Carol Fessenden, Daniel Friedman, and Christo-

pher Haynes for permission to use text from the Scheme

311 version 4 reference manual. We thank Texas In-

struments, Inc. for permission to use text from the TI

Scheme Language Reference Manual [26]. We gladly ac-

knowledge the inﬂuence of manuals for MIT Scheme [20],

T [21], Scheme 84 [12], Common Lisp [25], Chez Scheme [8],

PLT Scheme [11], and Algol 60 [1].

We also thank Betty Dexter for the extreme eﬀort she put

into setting this report in T

E

X, and Donald Knuth for de-

signing the program that caused her troubles.

The Artiﬁcial Intelligence Laboratory of the Massachusetts

Institute of Technology, the Computer Science Department

of Indiana University, the Computer and Information Sci-

ences Department of the University of Oregon, and the

NEC Research Institute supported the preparation of this

report. Support for the MIT work was provided in part by

the Advanced Research Projects Agency of the Department

of Defense under Oﬃce of Naval Research contract N00014-

80-C-0505. Support for the Indiana University work was

provided by NSF grants NCS 83-04567 and NCS 83-03325.

1. Overview of Scheme 5

DESCRIPTION OF THE LANGUAGE

1. Overview of Scheme

This chapter gives an overview of Scheme’s semantics. The

purpose of this overview is to explain enough about the ba-

sic concepts of the language to facilitate understanding of

the subsequent chapters of the report, which are organized

as a reference manual. Consequently, this overview is not

a complete introduction to the language, nor is it precise

in all respects or normative in any way.

Following Algol, Scheme is a statically scoped program-

ming language. Each use of a variable is associated with a

lexically apparent binding of that variable.

Scheme has latent as opposed to manifest types [28]. Types

are associated with objects (also called values) rather than

with variables. (Some authors refer to languages with la-

tent types as untyped, weakly typed or dynamically typed

languages.) Other languages with latent types are Python,

Ruby, Smalltalk, and other dialects of Lisp. Languages

with manifest types (sometimes referred to as strongly

typed or statically typed languages) include Algol 60, C,

C#, Java, Haskell, and ML.

All objects created in the course of a Scheme computation,

including procedures and continuations, have unlimited ex-

tent. No Scheme object is ever destroyed. The reason that

implementations of Scheme do not (usually!) run out of

storage is that they are permitted to reclaim the storage

occupied by an object if they can prove that the object

cannot possibly matter to any future computation. Other

languages in which most objects have unlimited extent in-

clude C#, Java, Haskell, most Lisp dialects, ML, Python,

Ruby, and Smalltalk.

Implementations of Scheme must be properly tail-

recursive. This allows the execution of an iterative com-

putation in constant space, even if the iterative compu-

tation is described by a syntactically recursive procedure.

Thus with a properly tail-recursive implementation, iter-

ation can be expressed using the ordinary procedure-call

mechanics, so that special iteration constructs are useful

only as syntactic sugar.

Scheme was one of the ﬁrst languages to support proce-

dures as objects in their own right. Procedures can be

created dynamically, stored in data structures, returned

as results of procedures, and so on. Other languages with

these properties include Common Lisp, Haskell, ML, Ruby,

and Smalltalk.

One distinguishing feature of Scheme is that continuations,

which in most other languages only operate behind the

scenes, also have “ﬁrst-class” status. First-class continu-

ations are useful for implementing a wide variety of ad-

vanced control constructs, including non-local exits, back-

tracking, and coroutines.

In Scheme, the argument expressions of a procedure call

are evaluated before the procedure gains control, whether

the procedure needs the result of the evaluation or not.

C, C#, Common Lisp, Python, Ruby, and Smalltalk are

other languages that always evaluate argument expressions

before invoking a procedure. This is distinct from the lazy-

evaluation semantics of Haskell, or the call-by-name se-

mantics of Algol 60, where an argument expression is not

evaluated unless its value is needed by the procedure.

Scheme’s model of arithmetic provides a rich set of numer-

ical types and operations on them. Furthermore, it distin-

guishes exact and inexact number objects: Essentially, an

exact number object corresponds to a number exactly, and

an inexact number object is the result of a computation

that involved rounding or other errors.

1.1. Basic types

Scheme programs manipulate objects, which are also re-

ferred to as values. Scheme objects are organized into sets

of values called types. This section gives an overview of the

fundamentally important types of the Scheme language.

More types are described in later chapters.

Note: As Scheme is latently typed, the use of the term type

in this report diﬀers from the use of the term in the context of

other languages, particularly those with manifest typing.

Booleans A boolean is a truth value, and can be either

true or false. In Scheme, the object for “false” is written #f.

The object for “true” is written #t. In most places where a

truth value is expected, however, any object diﬀerent from

#f counts as true.

Numbers Scheme supports a rich variety of numerical

data types, including objects representing integers of arbi-

trary precision, rational numbers, complex numbers, and

inexact numbers of various kinds. Chapter 3 gives an

overview of the structure of Scheme’s numerical tower.

Characters Scheme characters mostly correspond to

textual characters. More precisely, they are isomorphic

to the scalar values of the Unicode standard.

Strings Strings are ﬁnite sequences of characters with

ﬁxed length and thus represent arbitrary Unicode texts.

6 Revised

6

Scheme

Symbols A symbol is an object representing a string,

the symbol’s name. Unlike strings, two symbols whose

names are spelled the same way are never distinguishable.

Symbols are useful for many applications; for instance, they

may be used the way enumerated values are used in other

languages.

Pairs and lists A pair is a data structure with two com-

ponents. The most common use of pairs is to represent

(singly linked) lists, where the ﬁrst component (the “car”)

represents the ﬁrst element of the list, and the second com-

ponent (the “cdr”) the rest of the list. Scheme also has a

distinguished empty list, which is the last cdr in a chain of

pairs that form a list.

Vectors Vectors, like lists, are linear data structures rep-

resenting ﬁnite sequences of arbitrary objects. Whereas

the elements of a list are accessed sequentially through the

chain of pairs representing it, the elements of a vector are

addressed by integer indices. Thus, vectors are more ap-

propriate than lists for random access to elements.

Procedures Procedures are values in Scheme.

1.2. Expressions

The most important elements of Scheme code are expres-

sions. Expressions can be evaluated, producing a value.

(Actually, any number of values—see section 5.8.) The

most fundamental expressions are literal expressions:

#t =⇒ #t

23 =⇒ 23

This notation means that the expression #t evaluates to

#t, that is, the value for “true”, and that the expression

23 evaluates to a number object representing the number

23.

Compound expressions are formed by placing parenthe-

ses around their subexpressions. The ﬁrst subexpression

identiﬁes an operation; the remaining subexpressions are

operands to the operation:

(+ 23 42) =⇒ 65

(+ 14 (* 23 42)) =⇒ 980

In the ﬁrst of these examples, + is the name of the built-

in operation for addition, and 23 and 42 are the operands.

The expression (+ 23 42) reads as “the sum of 23 and 42”.

Compound expressions can be nested—the second example

reads as “the sum of 14 and the product of 23 and 42”.

As these examples indicate, compound expressions in

Scheme are always written using the same preﬁx notation.

As a consequence, the parentheses are needed to indicate

structure. Consequently, “superﬂuous” parentheses, which

are often permissible in mathematical notation and also in

many programming languages, are not allowed in Scheme.

As in many other languages, whitespace (including line

endings) is not signiﬁcant when it separates subexpressions

of an expression, and can be used to indicate structure.

1.3. Variables and binding

Scheme allows identiﬁers to stand for locations contain-

ing values. These identiﬁers are called variables. In many

cases, speciﬁcally when the location’s value is never mod-

iﬁed after its creation, it is useful to think of the variable

as standing for the value directly.

(let ((x 23)

(y 42))

(+ x y)) =⇒ 65

In this case, the expression starting with let is a bind-

ing construct. The parenthesized structure following the

let lists variables alongside expressions: the variable x

alongside 23, and the variable y alongside 42. The let

expression binds x to 23, and y to 42. These bindings are

available in the body of the let expression, (+ x y), and

only there.

1.4. Deﬁnitions

The variables bound by a let expression are local, because

their bindings are visible only in the let’s body. Scheme

also allows creating top-level bindings for identiﬁers as fol-

lows:

(define x 23)

(define y 42)

(+ x y) =⇒ 65

(These are actually “top-level” in the body of a top-level

program or library; see section 1.12 below.)

The ﬁrst two parenthesized structures are deﬁnitions; they

create top-level bindings, binding x to 23 and y to 42. Deﬁ-

nitions are not expressions, and cannot appear in all places

where an expression can occur. Moreover, a deﬁnition has

no value.

Bindings follow the lexical structure of the program: When

several bindings with the same name exist, a variable refers

to the binding that is closest to it, starting with its occur-

rence in the program and going from inside to outside, and

referring to a top-level binding if no local binding can be

found along the way:

(define x 23)

(define y 42)

(let ((y 43))

1. Overview of Scheme 7

(+ x y)) =⇒ 66

(let ((y 43))

(let ((y 44))

(+ x y))) =⇒ 67

1.5. Forms

While deﬁnitions are not expressions, compound ex-

pressions and deﬁnitions exhibit similar syntactic struc-

ture:

(define x 23)

(* x 2)

While the ﬁrst line contains a deﬁnition, and the second

an expression, this distinction depends on the bindings for

define and *. At the purely syntactical level, both are

forms, and form is the general name for a syntactic part

of a Scheme program. In particular, 23 is a subform of the

form (define x 23).

1.6. Procedures

Deﬁnitions can also be used to deﬁne procedures:

(define (f x)

(+ x 42))

(f 23) =⇒ 65

A procedure is, slightly simpliﬁed, an abstraction of an

expression over objects. In the example, the ﬁrst deﬁni-

tion deﬁnes a procedure called f. (Note the parentheses

around f x, which indicate that this is a procedure deﬁni-

tion.) The expression (f 23) is a procedure call, meaning,

roughly, “evaluate (+ x 42) (the body of the procedure)

with x bound to 23”.

As procedures are objects, they can be passed to other

procedures:

(define (f x)

(+ x 42))

(define (g p x)

(p x))

(g f 23) =⇒ 65

In this example, the body of g is evaluated with p bound to

f and x bound to 23, which is equivalent to (f 23), which

evaluates to 65.

In fact, many predeﬁned operations of Scheme are pro-

vided not by syntax, but by variables whose values are

procedures. The + operation, for example, which receives

special syntactic treatment in many other languages, is just

a regular identiﬁer in Scheme, bound to a procedure that

adds number objects. The same holds for * and many oth-

ers:

(define (h op x y)

(op x y))

(h + 23 42) =⇒ 65

(h * 23 42) =⇒ 966

Procedure deﬁnitions are not the only way to create pro-

cedures. A lambda expression creates a new procedure as

an object, with no need to specify a name:

((lambda (x) (+ x 42)) 23) =⇒ 65

The entire expression in this example is a procedure call;

(lambda (x) (+ x 42)), evaluates to a procedure that

takes a single number object and adds 42 to it.

1.7. Procedure calls and syntactic key-

words

Whereas (+ 23 42), (f 23), and ((lambda (x) (+ x

42)) 23) are all examples of procedure calls, lambda and

let expressions are not. This is because let, even though

it is an identiﬁer, is not a variable, but is instead a syn-

tactic keyword. A form that has a syntactic keyword as its

ﬁrst subexpression obeys special rules determined by the

keyword. The define identiﬁer in a deﬁnition is also a syn-

tactic keyword. Hence, deﬁnitions are also not procedure

calls.

The rules for the lambda keyword specify that the ﬁrst

subform is a list of parameters, and the remaining subforms

are the body of the procedure. In let expressions, the

ﬁrst subform is a list of binding speciﬁcations, and the

remaining subforms constitute a body of expressions.

Procedure calls can generally be distinguished from these

special forms by looking for a syntactic keyword in the ﬁrst

position of an form: if the ﬁrst position does not contain

a syntactic keyword, the expression is a procedure call.

(So-called identiﬁer macros allow creating other kinds of

special forms, but are comparatively rare.) The set of syn-

tactic keywords of Scheme is fairly small, which usually

makes this task fairly simple. It is possible, however, to

create new bindings for syntactic keywords; see section 1.9

below.

1.8. Assignment

Scheme variables bound by deﬁnitions or let or lambda

expressions are not actually bound directly to the ob-

jects speciﬁed in the respective bindings, but to loca-

tions containing these objects. The contents of these lo-

cations can subsequently be modiﬁed destructively via as-

signment:

(let ((x 23))

(set! x 42)

x) =⇒ 42

8 Revised

6

Scheme

In this case, the body of the let expression consists of two

expressions which are evaluated sequentially, with the value

of the ﬁnal expression becoming the value of the entire let

expression. The expression (set! x 42) is an assignment,

saying “replace the object in the location referenced by x

with 42”. Thus, the previous value of x, 23, is replaced by

42.

1.9. Derived forms and macros

Many of the special forms speciﬁed in this report can be

translated into more basic special forms. For example, a

let expression can be translated into a procedure call and

a lambda expression. The following two expressions are

equivalent:

(let ((x 23)

(y 42))

(+ x y)) =⇒ 65

((lambda (x y) (+ x y)) 23 42)

=⇒ 65

Special forms like let expressions are called derived forms

because their semantics can be derived from that of other

kinds of forms by a syntactic transformation. Some proce-

dure deﬁnitions are also derived forms. The following two

deﬁnitions are equivalent:

(define (f x)

(+ x 42))

(define f

(lambda (x)

(+ x 42)))

In Scheme, it is possible for a program to create its own

derived forms by binding syntactic keywords to macros:

(define-syntax def

(syntax-rules ()

((def f (p ...) body)

(define (f p ...)

body))))

(def f (x)

(+ x 42))

The define-syntax construct speciﬁes that a parenthe-

sized structure matching the pattern (def f (p ...)

body), where f, p, and body are pattern variables, is trans-

lated to (define (f p ...) body). Thus, the def form

appearing in the example gets translated to:

(define (f x)

(+ x 42))

The ability to create new syntactic keywords makes Scheme

extremely ﬂexible and expressive, allowing many of the

features built into other languages to be derived forms in

Scheme.

1.10. Syntactic data and datum values

A subset of the Scheme objects is called datum values.

These include booleans, number objects, characters, sym-

bols, and strings as well as lists and vectors whose ele-

ments are data. Each datum value may be represented in

textual form as a syntactic datum, which can be written

out and read back in without loss of information. A da-

tum value may be represented by several diﬀerent syntactic

data. Moreover, each datum value can be trivially trans-

lated to a literal expression in a program by prepending a

’ to a corresponding syntactic datum:

’23 =⇒ 23

’#t =⇒ #t

’foo =⇒ foo

’(1 2 3) =⇒ (1 2 3)

’#(1 2 3) =⇒ #(1 2 3)

The ’ shown in the previous examples is not needed for rep-

resentations of number objects or booleans. The syntactic

datum foo represents a symbol with name “foo”, and ’foo

is a literal expression with that symbol as its value. (1 2

3) is a syntactic datum that represents a list with elements

1, 2, and 3, and ’(1 2 3) is a literal expression with this

list as its value. Likewise, #(1 2 3) is a syntactic datum

that represents a vector with elements 1, 2 and 3, and ’#(1

2 3) is the corresponding literal.

The syntactic data are a superset of the Scheme forms.

Thus, data can be used to represent Scheme forms as data

objects. In particular, symbols can be used to represent

identiﬁers.

’(+ 23 42) =⇒ (+ 23 42)

’(define (f x) (+ x 42))

=⇒ (define (f x) (+ x 42))

This facilitates writing programs that operate on Scheme

source code, in particular interpreters and program trans-

formers.

1.11. Continuations

Whenever a Scheme expression is evaluated there is a con-

tinuation wanting the result of the expression. The con-

tinuation represents an entire (default) future for the com-

putation. For example, informally the continuation of 3 in

the expression

(+ 1 3)

adds 1 to it. Normally these ubiquitous continuations

are hidden behind the scenes and programmers do not

think much about them. On rare occasions, however, a

programmer may need to deal with continuations explic-

itly. The call-with-current-continuation procedure

(see section 11.15) allows Scheme programmers to do that

2. Requirement levels 9

by creating a procedure that reinstates the current continu-

ation. The call-with-current-continuation procedure

accepts a procedure, calls it immediately with an argu-

ment that is an escape procedure. This escape procedure

can then be called with an argument that becomes the

result of the call to call-with-current-continuation.

That is, the escape procedure abandons its own con-

tinuation, and reinstates the continuation of the call to

call-with-current-continuation.

In the following example, an escape procedure representing

the continuation that adds 1 to its argument is bound to

escape, and then called with 3 as an argument. The con-

tinuation of the call to escape is abandoned, and instead

the 3 is passed to the continuation that adds 1:

(+ 1 (call-with-current-continuation

(lambda (escape)

(+ 2 (escape 3)))))

=⇒ 4

An escape procedure has unlimited extent: It can be

called after the continuation it captured has been in-

voked, and it can be called multiple times. This

makes call-with-current-continuation signiﬁcantly

more powerful than typical non-local control constructs

such as exceptions in other languages.

1.12. Libraries

Scheme code can be organized in components called li-

braries. Each library contains deﬁnitions and expressions.

It can import deﬁnitions from other libraries and export

deﬁnitions to other libraries.

The following library called (hello) exports a deﬁnition

called hello-world, and imports the base library (see

chapter 11) and the simple I/O library (see library sec-

tion 8.3). The hello-world export is a procedure that

displays Hello World on a separate line:

(library (hello)

(export hello-world)

(import (rnrs base)

(rnrs io simple))

(define (hello-world)

(display "Hello World")

(newline)))

1.13. Top-level programs

A Scheme program is invoked via a top-level program. Like

a library, a top-level program contains imports, deﬁnitions

and expressions, and speciﬁes an entry point for execution.

Thus a top-level program deﬁnes, via the transitive closure

of the libraries it imports, a Scheme program.

The following top-level program obtains the ﬁrst ar-

gument from the command line via the command-line

procedure from the (rnrs programs (6)) library (see

library chapter 10). It then opens the ﬁle using

open-file-input-port (see library section 8.2, yielding

a port, i.e. a connection to the ﬁle as a data source, and

calls the get-bytes-all procedure to obtain the contents

of the ﬁle as binary data. It then uses put-bytes to output

the contents of the ﬁle to standard output:

#!r6rs

(import (rnrs base)

(rnrs io ports)

(rnrs programs))

(put-bytes (standard-output-port)

(call-with-port

(open-file-input-port

(cadr (command-line)))

get-bytes-all))

2. Requirement levels

The key words “must”, “must not”, “should”, “should

not”, “recommended”, “may”, and “optional” in this re-

port are to be interpreted as described in RFC 2119 [3].

Speciﬁcally:

must This word means that a statement is an absolute

requirement of the speciﬁcation.

must not This phrase means that a statement is an ab-

solute prohibition of the speciﬁcation.

should This word, or the adjective “recommended”,

means that valid reasons may exist in particular cir-

cumstances to ignore a statement, but that the impli-

cations must be understood and weighed before choos-

ing a diﬀerent course.

should not This phrase, or the phrase “not recom-

mended”, means that valid reasons may exist in par-

ticular circumstances when the behavior of a state-

ment is acceptable, but that the implications should

be understood and weighed before choosing the course

described by the statement.

may This word, or the adjective “optional”, means that

an item is truly optional.

In particular, this report occasionally uses “should” to des-

ignate circumstances that are outside the speciﬁcation of

this report, but cannot be practically detected by an im-

plementation; see section 5.4. In such circumstances, a

particular implementation may allow the programmer to

ignore the recommendation of the report and even exhibit

reasonable behavior. However, as the report does not spec-

ify the behavior, these programs may be unportable, that

is, their execution might produce diﬀerent results on dif-

ferent implementations.

10 Revised

6

Scheme

Moreover, this report occasionally uses the phrase “not re-

quired” to note the absence of an absolute requirement.

3. Numbers

This chapter describes Scheme’s model for numbers. It is

important to distinguish between the mathematical num-

bers, the Scheme objects that attempt to model them, the

machine representations used to implement the numbers,

and notations used to write numbers. In this report, the

term number refers to a mathematical number, and the

term number object refers to a Scheme object representing

a number. This report uses the types complex, real, ra-

tional, and integer to refer to both mathematical numbers

and number objects. The ﬁxnum and ﬂonum types refer

to special subsets of the number objects, as determined by

common machine representations, as explained below.

3.1. Numerical tower

Numbers may be arranged into a tower of subsets in which

each level is a subset of the level above it:

number

complex

real

rational

integer

For example, 5 is an integer. Therefore 5 is also a rational,

a real, and a complex. The same is true of the number

objects that model 5.

Number objects are organized as a corresponding tower

of subtypes deﬁned by the predicates number?, complex?,

real?, rational?, and integer?; see section 11.7.4. Inte-

ger number objects are also called integer objects.

There is no simple relationship between the subset that

contains a number and its representation inside a com-

puter. For example, the integer 5 may have several rep-

resentations. Scheme’s numerical operations treat number

objects as abstract data, as independent of their represen-

tation as possible. Although an implementation of Scheme

may use many diﬀerent representations for numbers, this

should not be apparent to a casual programmer writing

simple programs.

3.2. Exactness

It is useful to distinguish between number objects that are

known to correspond to a number exactly, and those num-

ber objects whose computation involved rounding or other

errors. For example, index operations into data structures

may need to know the index exactly, as may some opera-

tions on polynomial coeﬃcients in a symbolic algebra sys-

tem. On the other hand, the results of measurements are

inherently inexact, and irrational numbers may be approx-

imated by rational and therefore inexact approximations.

In order to catch uses of numbers known only inexactly

where exact numbers are required, Scheme explicitly dis-

tinguishes exact from inexact number objects. This dis-

tinction is orthogonal to the dimension of type.

A number object is exact if it is the value of an exact nu-

merical literal or was derived from exact number objects

using only exact operations. Exact number objects corre-

spond to mathematical numbers in the obvious way.

Conversely, a number object is inexact if it is the value of

an inexact numerical literal, or was derived from inexact

number objects, or was derived using inexact operations.

Thus inexactness is contagious.

Exact arithmetic is reliable in the following sense: If ex-

act number objects are passed to any of the arithmetic

procedures described in section 11.7.1, and an exact num-

ber object is returned, then the result is mathematically

correct. This is generally not true of computations involv-

ing inexact number objects because approximate methods

such as ﬂoating-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.

3.3. Fixnums and ﬂonums

A ﬁxnum is an exact integer object that lies within a cer-

tain implementation-dependent subrange of the exact in-

teger objects. (Library section 11.2 describes a library for

computing with ﬁxnums.) Likewise, every implementation

must designate a subset of its inexact real number objects

as ﬂonums, and to convert certain external representations

into ﬂonums. (Library section 11.3 describes a library for

computing with ﬂonums.) Note that this does not imply

that an implementation must use ﬂoating-point represen-

tations.

3.4. Implementation requirements

Implementations of Scheme must support number objects

for the entire tower of subtypes given in section 3.1. More-

over, implementations must support exact integer objects

and exact rational number objects of practically unlimited

size and precision, and to implement certain procedures

(listed in 11.7.1) so they always return exact results when

given exact arguments. (“Practically unlimited” means

that the size and precision of these numbers should only

be limited by the size of the available memory.)

4. Lexical syntax and datum syntax 11

Implementations may support only a limited range of inex-

act number objects of any type, subject to the requirements

of this section. For example, an implementation may limit

the range of the inexact real number objects (and therefore

the range of inexact integer and rational number objects)

to the dynamic range of the ﬂonum format. Furthermore

the gaps between the inexact integer objects and rationals

are likely to be very large in such an implementation as the

limits of this range are approached.

An implementation may use ﬂoating point and other ap-

proximate representation strategies for inexact numbers.

This report recommends, but does not require, that the

IEEE ﬂoating-point standards be followed by implementa-

tions that use ﬂoating-point representations, and that im-

plementations using other representations should match or

exceed the precision achievable using these ﬂoating-point

standards [13].

In particular, implementations that use ﬂoating-point rep-

resentations must follow these rules: A ﬂoating-point result

must be represented with at least as much precision as is

used to express any of the inexact arguments to that oper-

ation. Potentially inexact operations such as sqrt, when

applied to exact arguments, should produce exact answers

whenever possible (for example the square root of an exact

4 ought to be an exact 2). However, this is not required.

If, on the other hand, an exact number object is operated

upon so as to produce an inexact result (as by sqrt), and

if the result is represented in ﬂoating point, then the most

precise ﬂoating-point format available must be used; but if

the result is represented in some other way then the repre-

sentation must have at least as much precision as the most

precise ﬂoating-point format available.

It is the programmer’s responsibility to avoid using inexact

number objects with magnitude or signiﬁcand too large to

be represented in the implementation.

3.5. Inﬁnities and NaNs

Some Scheme implementations, speciﬁcally those that fol-

low the IEEE ﬂoating-point standards, distinguish special

number objects called positive inﬁnity, negative inﬁnity,

and NaN.

Positive inﬁnity is regarded as an inexact real (but not

rational) number object that represents an indeterminate

number greater than the numbers represented by all ra-

tional number objects. Negative inﬁnity is regarded as an

inexact real (but not rational) number object that rep-

resents an indeterminate number less than the numbers

represented by all rational numbers.

A NaN is regarded as an inexact real (but not rational)

number object so indeterminate that it might represent

any real number, including positive or negative inﬁnity,

and might even be greater than positive inﬁnity or less

than negative inﬁnity.

3.6. Distinguished -0.0

Some Scheme implementations, speciﬁcally those that fol-

low the IEEE ﬂoating-point standards, distinguish between

number objects for 0.0 and −0.0, i.e., positive and nega-

tive inexact zero. This report will sometimes specify the

behavior of certain arithmetic operations on these number

objects. These speciﬁcations are marked with “if −0.0 is

distinguished” or “implementations that distinguish −0.0”.

4. Lexical syntax and datum syntax

The syntax of Scheme code is organized in three levels:

1. the lexical syntax that describes how a program text

is split into a sequence of lexemes,

2. the datum syntax, formulated in terms of the lexical

syntax, that structures the lexeme sequence as a se-

quence of syntactic data, where a syntactic datum is

a recursively structured entity,

3. the program syntax formulated in terms of the read

syntax, imposing further structure and assigning

meaning to syntactic data.

Syntactic data (also called external representations) double

as a notation for objects, and Scheme’s (rnrs io ports

(6)) library (library section 8.2) provides the get-datum

and put-datum procedures for reading and writing syntac-

tic data, converting between their textual representation

and the corresponding objects. Each syntactic datum rep-

resents a corresponding datum value. A syntactic datum

can be used in a program to obtain the corresponding da-

tum value using quote (see section 11.4.1).

Scheme source code consists of syntactic data and (non-

signiﬁcant) comments. Syntactic data in Scheme source

code are called forms. (A form nested inside another form

is called a subform.) Consequently, Scheme’s syntax has

the property that any sequence of characters that is a form

is also a syntactic datum representing 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 be a representation of objects or the text of a program.

It is also a source of power, since it facilitates writing pro-

grams such as interpreters or compilers that treat programs

as objects (or vice versa).

A datum value may have several diﬀerent external repre-

sentations. For example, both “#e28.000” and “#x1c” are

syntactic data representing the exact integer object 28, and

the syntactic data “(8 13)”, “( 08 13 )”, “(8 . (13 .

12 Revised

6

Scheme

()))” all represent a list containing the exact integer ob-

jects 8 and 13. Syntactic data that represent equal objects

(in the sense of equal?; see section 11.5) are always equiv-

alent as forms of a program.

Because of the close correspondence between syntactic data

and datum values, this report sometimes uses the term

datum for either a syntactic datum or a datum value when

the exact meaning is apparent from the context.

An implementation must not extend the lexical or datum

syntax in any way, with one exception: it need not treat the

syntax #!'identiﬁer`, for any 'identiﬁer` (see section 4.2.4)

that is not r6rs, as a syntax violation, and it may use

speciﬁc #!-preﬁxed identiﬁers as ﬂags indicating that sub-

sequent input contains extensions to the standard lexical or

datum syntax. The syntax #!r6rs may be used to signify

that the input afterward is written with the lexical syn-

tax and datum syntax described by this report. #!r6rs is

otherwise treated as a comment; see section 4.2.3.

4.1. Notation

The formal syntax for Scheme is written in an extended

BNF. Non-terminals are written using angle brackets. Case

is insigniﬁcant for non-terminal names.

All spaces in the grammar are for legibility. 'Empty`

stands for the empty string.

The following extensions to BNF are used to make the de-

scription more concise: 'thing`* means zero or more occur-

rences of 'thing`, and 'thing`

+

means at least one 'thing`.

Some non-terminal names refer to the Unicode scalar val-

ues of the same name: 'character tabulation` (U+0009),

'linefeed` (U+000A), 'carriage return` (U+000D),

'line tabulation` (U+000B), 'form feed` (U+000C),

'carriage return` (U+000D), 'space` (U+0020),

'next line` (U+0085), 'line separator` (U+2028), and

'paragraph separator` (U+2029).

4.2. Lexical syntax

The lexical syntax determines how a character sequence is

split into a sequence of lexemes, omitting non-signiﬁcant

portions such as comments and whitespace. The character

sequence is assumed to be text according to the Unicode

standard [27]. Some of the lexemes, such as identiﬁers,

representations of number objects, strings etc., of the lex-

ical syntax are syntactic data in the datum syntax, and

thus represent objects. Besides the formal account of the

syntax, this section also describes what datum values are

represented by these syntactic data.

The lexical syntax, in the description of comments, con-

tains a forward reference to 'datum`, which is described

as part of the datum syntax. Being comments, however,

these 'datum`s do not play a signiﬁcant role in the syntax.

Case is signiﬁcant except in representations of booleans,

number objects, and in hexadecimal numbers specifying

Unicode scalar values. For example, #x1A and #X1a are

equivalent. The identiﬁer Foo is, however, distinct from

the identiﬁer FOO.

4.2.1. Formal account

'Interlexeme space` may occur on either side of any lexeme,

but not within a lexeme.

'Identiﬁer`s, ., 'number`s, 'character`s, and 'boolean`s,

must be terminated by a 'delimiter` or by the end of the

input.

The following two characters are reserved for future exten-

sions to the language: { }

'lexeme` −→ 'identiﬁer` [ 'boolean` [ 'number`

[ 'character` [ 'string`

[ ( [ ) [ [ [ ] [ #( [ #vu8( | ’ [ ` [ , [ ,@ [ .

[ #’ [ #` [ #, [ #,@

'delimiter` −→ ( [ ) [ [ [ ] [ " [ ; [ #

[ 'whitespace`

'whitespace` −→ 'character tabulation`

[ 'linefeed` [ 'line tabulation` [ 'form feed`

[ 'carriage return` [ 'next line`

[ 'any character whose category is Zs, Zl, or Zp`

'line ending` −→ 'linefeed` [ 'carriage return`

[ 'carriage return` 'linefeed` [ 'next line`

[ 'carriage return` 'next line` [ 'line separator`

'comment` −→ ; 'all subsequent characters up to a

'line ending` or 'paragraph separator``

[ 'nested comment`

[ #; 'interlexeme space` 'datum`

[ #!r6rs

'nested comment` −→ #| 'comment text`

'comment cont`* |#

'comment text` −→ 'character sequence not containing

#| or |#`

'comment cont` −→ 'nested comment` 'comment text`

'atmosphere` −→ 'whitespace` [ 'comment`

'interlexeme space` −→ 'atmosphere`*

'identiﬁer` −→ 'initial` 'subsequent`*

[ 'peculiar identiﬁer`

'initial` −→ 'constituent` [ 'special initial`

[ 'inline hex escape`

'letter` −→ a [ b [ c [ ... [ z

[ A [ B [ C [ ... [ Z

'constituent` −→ 'letter`

[ 'any character whose Unicode scalar value is greater than

127, and whose category is Lu, Ll, Lt, Lm, Lo, Mn,

Nl, No, Pd, Pc, Po, Sc, Sm, Sk, So, or Co`

4. Lexical syntax and datum syntax 13

'special initial` −→ ! [ $ [ % [ & [ * [ / [ : [ < [ =

[ > [ ? [ ^ [ _ [ ~

'subsequent` −→ 'initial` [ 'digit`

[ 'any character whose category is Nd, Mc, or Me`

[ 'special subsequent`

'digit` −→ 0 [ 1 [ 2 [ 3 [ 4 [ 5 [ 6 [ 7 [ 8 [ 9

'hex digit` −→ 'digit`

[ a [ A [ b [ B [ c [ C [ d [ D [ e [ E [ f [ F

'special subsequent` −→ + [ - [ . [ @

'inline hex escape` −→ \x'hex scalar value`;

'hex scalar value` −→ 'hex digit`

+

'peculiar identiﬁer` −→ + [ - [ ... [ -> 'subsequent`*

'boolean` −→ #t [ #T [ #f [ #F

'character` −→ #\'any character`

[ #\'character name`

[ #\x'hex scalar value`

'character name` −→ nul [ alarm [ backspace [ tab

[ linefeed [ newline [ vtab [ page [ return

[ esc [ space [ delete

'string` −→ " 'string element`* "

'string element` −→ 'any character other than " or \`

[ \a [ \b [ \t [ \n [ \v [ \f [ \r

[ \" [ \\

[ \'intraline whitespace`'line ending`

'intraline whitespace`

[ 'inline hex escape`

'intraline whitespace` −→ 'character tabulation`

[ 'any character whose category is Zs`

A 'hex scalar value` represents a Unicode scalar

value between 0 and #x10FFFF, excluding the range

[#xD800, #xDFFF].

The rules for 'num R`, 'complex R`, 'real R`, 'ureal R`,

'uinteger R`, and 'preﬁx R` below should be replicated for

R = 2, 8, 10, and 16. There are no rules for 'decimal 2`,

'decimal 8`, and 'decimal 16`, which means that num-

ber representations containing decimal points or exponents

must be in decimal radix.

'number` −→ 'num 2` [ 'num 8`

[ 'num 10` [ 'num 16`

'num R` −→ 'preﬁx R` 'complex R`

'complex R` −→ 'real R` [ 'real R` @ 'real R`

[ 'real R` + 'ureal R` i [ 'real R` - 'ureal R` i

[ 'real R` + 'naninf` i [ 'real R` - 'naninf` i

[ 'real R` + i [ 'real R` - i

[ + 'ureal R` i [ - 'ureal R` i

[ + 'naninf` i [ - 'naninf` i

[ + i [ - i

'real R` −→ 'sign` 'ureal R`

[ + 'naninf` [ - 'naninf`

'naninf` −→ nan.0 [ inf.0

'ureal R` −→ 'uinteger R`

[ 'uinteger R` / 'uinteger R`

[ 'decimal R` 'mantissa width`

'decimal 10` −→ 'uinteger 10` 'suﬃx`

[ . 'digit 10`

+

'suﬃx`

[ 'digit 10`

+

. 'digit 10`* 'suﬃx`

[ 'digit 10`

+

. 'suﬃx`

'uinteger R` −→ 'digit R`

+

'preﬁx R` −→ 'radix R` 'exactness`

[ 'exactness` 'radix R`

'suﬃx` −→ 'empty`

[ 'exponent marker` 'sign` 'digit 10`

+

'exponent marker` −→ e [ E [ s [ S [ f [ F

[ d [ D [ l [ L

'mantissa width` −→ 'empty`

[ | 'digit 10`

+

'sign` −→ 'empty` [ + [ -

'exactness` −→ 'empty`

[ #i [ #I [ #e [ #E

'radix 2` −→ #b [ #B

'radix 8` −→ #o [ #O

'radix 10` −→ 'empty` [ #d [ #D

'radix 16` −→ #x [ #X

'digit 2` −→ 0 [ 1

'digit 8` −→ 0 [ 1 [ 2 [ 3 [ 4 [ 5 [ 6 [ 7

'digit 10` −→ 'digit`

'digit 16` −→ 'hex digit`

4.2.2. Line endings

Line endings are signiﬁcant in Scheme in single-line com-

ments (see section 4.2.3) and within string literals. In

Scheme source code, any of the line endings in 'line ending`

marks the end of a line. Moreover, the two-character line

endings 'carriage return` 'linefeed` and 'carriage return`

'next line` each count as a single line ending.

In a string literal, a 'line ending` not preceded by a \

stands for a linefeed character, which is the standard line-

ending character of Scheme.

4.2.3. Whitespace and comments

Whitespace characters are spaces, linefeeds, carriage re-

turns, character tabulations, form feeds, line tabulations,

and any other character whose category is Zs, Zl, or Zp.

Whitespace is used for improved readability and as nec-

essary to separate lexemes from each other. Whitespace

may occur between any two lexemes, but not within a lex-

eme. Whitespace may also occur inside a string, where it

is signiﬁcant.

The lexical syntax includes several comment forms. In all

cases, comments are invisible to Scheme, except that they

act as delimiters, so, for example, a comment cannot ap-

pear in the middle of an identiﬁer or representation of a

number object.

14 Revised

6

Scheme

A semicolon (;) indicates the start of a line comment. The

comment continues to the end of the line on which the

semicolon appears.

Another way to indicate a comment is to preﬁx a

'datum` (cf. section 4.3.1) with #;, possibly with

'interlexeme space` before the 'datum`. The comment

consists of the comment preﬁx #; and the 'datum` to-

gether. This notation is useful for “commenting out” sec-

tions of code.

Block comments may be indicated with properly nested #|

and |# pairs.

#|

The FACT procedure computes the factorial

of a non-negative integer.

|#

(define fact

(lambda (n)

;; base case

(if (= n 0)

#;(= n 1)

1 ; identity of *

(* n (fact (- n 1))))))

The lexeme #!r6rs, which signiﬁes that the program text

that follows is written with the lexical and datum syntax

described in this report, is also otherwise treated as a com-

ment.

4.2.4. Identiﬁers

Most identiﬁers allowed by other programming languages

are also acceptable to Scheme. In general, a sequence of

letters, digits, and “extended alphabetic characters” is an

identiﬁer when it begins with a character that cannot be-

gin a representation of a number object. In addition, +,

-, and ... are identiﬁers, as is a sequence of letters, dig-

its, and extended alphabetic characters that begins with

the two-character sequence ->. Here are some examples of

identiﬁers:

lambda q soup

list->vector + V17a

<= a34kTMNs ->-

the-word-recursion-has-many-meanings

Extended alphabetic characters may be used within iden-

tiﬁers as if they were letters. The following are extended

alphabetic characters:

! $ % & * + - . / : < = > ? @ ^ _ ~

Moreover, all characters whose Unicode scalar values are

greater than 127 and whose Unicode category is Lu, Ll,

Lt, Lm, Lo, Mn, Mc, Me, Nd, Nl, No, Pd, Pc, Po, Sc,

Sm, Sk, So, or Co can be used within identiﬁers. In addi-

tion, any character can be used within an identiﬁer when

speciﬁed via an 'inline hex escape`. For example, the iden-

tiﬁer H\x65;llo is the same as the identiﬁer Hello, and

the identiﬁer \x3BB; is the same as the identiﬁer λ.

Any identiﬁer may be used as a variable or as a syntactic

keyword (see sections 5.2 and 9.2) in a Scheme program.

Any identiﬁer may also be used as a syntactic datum, in

which case it represents a symbol (see section 11.10).

4.2.5. Booleans

The standard boolean objects for true and false have ex-

ternal representations #t and #f.

4.2.6. Characters

Characters are represented using the nota-

tion #\'character` or #\'character name` or

#\x'hex scalar value`.

For example:

#\a lower case letter a

#\A upper case letter A

#\( left parenthesis

#\ space character

#\nul U+0000

#\alarm U+0007

#\backspace U+0008

#\tab U+0009

#\linefeed U+000A

#\newline U+000A

#\vtab U+000B

#\page U+000C

#\return U+000D

#\esc U+001B

#\space U+0020

preferred way to write a space

#\delete U+007F

#\xFF U+00FF

#\x03BB U+03BB

#\x00006587 U+6587

#\λ U+03BB

#\x0001z &lexical exception

#\λx &lexical exception

#\alarmx &lexical exception

#\alarm x U+0007

followed by x

#\Alarm &lexical exception

#\alert &lexical exception

#\xA U+000A

#\xFF U+00FF

#\xff U+00FF

#\x ff U+0078

followed by another datum, ff

4. Lexical syntax and datum syntax 15

#\x(ff) U+0078

followed by another datum,

a parenthesized ff

#\(x) &lexical exception

#\(x &lexical exception

#\((x) U+0028

followed by another datum,

parenthesized x

#\x00110000 &lexical exception

out of range

#\x000000001 U+0001

#\xD800 &lexical exception

in excluded range

(The notation &lexical exception means that the line in

question is a lexical syntax violation.)

Case is signiﬁcant in #\'character`, and in #\'character

name`, but not in #\x'hex scalar value`. A 'character`

must be followed by a 'delimiter` or by the end of the in-

put. This rule resolves various ambiguous cases involving

named characters, requiring, for example, the sequence of

characters “#\space” to be interpreted as the space char-

acter rather than as the character “#\s” followed by the

identiﬁer “pace”.

Note: The #\newline notation is retained for backward com-

patibility. Its use is deprecated; #\linefeed should be used

instead.

4.2.7. Strings

String are represented by sequences of characters enclosed

within doublequotes ("). Within a string literal, various es-

cape sequences represent characters other than themselves.

Escape sequences always start with a backslash (\):

• \a : alarm, U+0007

• \b : backspace, U+0008

• \t : character tabulation, U+0009

• \n : linefeed, U+000A

• \v : line tabulation, U+000B

• \f : formfeed, U+000C

• \r : return, U+000D

• \" : doublequote, U+0022

• \\ : backslash, U+005C

• \'intraline whitespace`'line ending`

'intraline whitespace` : nothing

• \x'hex scalar value`; : speciﬁed character (note the

terminating semi-colon).

These escape sequences are case-sensitive, except that the

alphabetic digits of a 'hex scalar value` can be uppercase

or lowercase.

Any other character in a string after a backslash is a syntax

violation. Except for a line ending, any character outside

of an escape sequence and not a doublequote stands for

itself in the string literal. For example the single-character

string literal "λ" (doublequote, a lower case lambda, dou-

blequote) represents the same string as "\x03bb;". A line

ending that does not follow a backslash stands for a linefeed

character.

Examples:

"abc" U+0061, U+0062, U+0063

"\x41;bc" "Abc" ; U+0041, U+0062, U+0063

"\x41; bc" "A bc"

U+0041, U+0020, U+0062, U+0063

"\x41bc;" U+41BC

"\x41" &lexical exception

"\x;" &lexical exception

"\x41bx;" &lexical exception

"\x00000041;" "A" ; U+0041

"\x0010FFFF;" U+10FFFF

"\x00110000;" &lexical exception

out of range

"\x000000001;" U+0001

"\xD800;" &lexical exception

in excluded range

"A

bc" U+0041, U+000A, U+0062, U+0063

if no space occurs after the A

4.2.8. Numbers

The syntax of external representations for number objects

is described formally by the 'number` rule in the formal

grammar. Case is not signiﬁcant in external representa-

tions of number objects.

A representation of a number object may be written in bi-

nary, octal, decimal, or hexadecimal by the use of a radix

preﬁx. The radix preﬁxes are #b (binary), #o (octal), #d

(decimal), and #x (hexadecimal). With no radix preﬁx,

a representation of a number object is assumed to be ex-

pressed in decimal.

A representation of a number object may be speciﬁed to

be either exact or inexact by a preﬁx. The preﬁxes are

#e for exact, and #i for inexact. An exactness preﬁx may

appear before or after any radix preﬁx that is used. If the

representation of a number object has no exactness preﬁx,

the constant is inexact if it contains a decimal point, an

exponent, or a nonempty mantissa width; otherwise it is

exact.

In systems with inexact number objects of varying preci-

sions, it may be useful to specify the precision of a constant.

16 Revised

6

Scheme

For this purpose, representations of number objects may be

written with an exponent marker that indicates the desired

precision of the inexact representation. The letters s, f, d,

and l specify the use of short, single, double, and long

precision, respectively. (When fewer than four internal in-

exact representations exist, the four size speciﬁcations are

mapped onto those available. For example, an implementa-

tion with two internal representations may map short and

single together and long and double together.) In addition,

the exponent marker e speciﬁes the default precision for

the implementation. The default precision has at least as

much precision as double, but implementations may wish

to allow this default to be set by the user.

3.1415926535898F0

Round to single, perhaps 3.141593

0.6L0

Extend to long, perhaps .600000000000000

A representation of a number object with nonempty man-

tissa width, x|p, represents the best binary ﬂoating-point

approximation of x using a p-bit signiﬁcand. For example,

1.1|53 is a representation of the best approximation of

1.1 in IEEE double precision. If x is an external represen-

tation of an inexact real number object that contains no

vertical bar, then its numerical value should be computed

as though it had a mantissa width of 53 or more.

Implementations that use binary ﬂoating-point representa-

tions of real number objects should represent x|p using a

p-bit signiﬁcand if practical, or by a greater precision if a

p-bit signiﬁcand is not practical, or by the largest available

precision if p or more bits of signiﬁcand are not practical

within the implementation.

Note: The precision of a signiﬁcand should not be confused

with the number of bits used to represent the signiﬁcand. In the

IEEE ﬂoating-point standards, for example, the signiﬁcand’s

most signiﬁcant bit is implicit in single and double precision

but is explicit in extended precision. Whether that bit is im-

plicit or explicit does not aﬀect the mathematical precision. In

implementations that use binary ﬂoating point, the default pre-

cision can be calculated by calling the following procedure:

(define (precision)

(do ((n 0 (+ n 1))

(x 1.0 (/ x 2.0)))

((= 1.0 (+ 1.0 x)) n)))

Note: When the underlying ﬂoating-point representation is

IEEE double precision, the |p suﬃx should not always be omit-

ted: Denormalized ﬂoating-point numbers have diminished pre-

cision, and therefore their external representations should carry

a |p suﬃx with the actual width of the signiﬁcand.

The literals +inf.0 and -inf.0 represent positive and neg-

ative inﬁnity, respectively. The +nan.0 literal represents

the NaN that is the result of (/ 0.0 0.0), and may rep-

resent other NaNs as well.

If x is an external representation of an inexact real number

object and contains no vertical bar and no exponent marker

other than e, the inexact real number object it represents

is a ﬂonum (see library section 11.3). Some or all of the

other external representations of inexact real number ob-

jects may also represent ﬂonums, but that is not required

by this report.

4.3. Datum syntax

The datum syntax describes the syntax of syntactic data in

terms of a sequence of 'lexeme`s, as deﬁned in the lexical

syntax.

Syntactic data include the lexeme data described in the

previous section as well as the following constructs for

forming compound data:

• pairs and lists, enclosed by ( ) or [ ] (see sec-

tion 4.3.2)

• vectors (see section 4.3.3)

• bytevectors (see section 4.3.4)

4.3.1. Formal account

The following grammar describes the syntax of syntactic

data in terms of various kinds of lexemes deﬁned in the

grammar in section 4.2:

'datum` −→ 'lexeme datum`

[ 'compound datum`

'lexeme datum` −→ 'boolean` [ 'number`

[ 'character` [ 'string` [ 'symbol`

'symbol` −→ 'identiﬁer`

'compound datum` −→ 'list` [ 'vector` [ 'bytevector`

'list` −→ ('datum`*) [ ['datum`*]

[ ('datum`

+

. 'datum`) [ ['datum`

+

. 'datum`]

[ 'abbreviation`

'abbreviation` −→ 'abbrev preﬁx` 'datum`

'abbrev preﬁx` −→ ’ [ ` [ , [ ,@

[ #’ | #` | #, | #,@

'vector` −→ #('datum`*)

'bytevector` −→ #vu8('u8`*)

'u8` −→ 'any 'number` representing an exact

integer in ¦0, . . . , 255¦`

4.3.2. Pairs and lists

List and pair data, representing pairs and lists of values (see

section 11.9) are represented using parentheses or brackets.

Matching pairs of brackets that occur in the rules of 'list`

are equivalent to matching pairs of parentheses.

5. Semantic concepts 17

The most general notation for Scheme pairs as syntac-

tic data is the “dotted” notation ('datum

1

` . 'datum

2

`)

where 'datum

1

` is the representation of the value of the

car ﬁeld and 'datum

2

` is the representation of the value of

the cdr ﬁeld. For example (4 . 5) is a pair whose car is

4 and whose cdr is 5.

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 represented by () .

For example,

(a b c d e)

and

(a . (b . (c . (d . (e . ())))))

are equivalent notations for a list of symbols.

The general rule is that, if a dot is followed by an open

parenthesis, the dot, open parenthesis, and matching clos-

ing parenthesis can be omitted in the external representa-

tion.

The sequence of characters “(4 . 5)” is the external rep-

resentation of a pair, not an expression that evaluates to a

pair. Similarly, the sequence of characters “(+ 2 6)” is not

an external representation of the integer 8, even though it

is an expression (in the language of the (rnrs base (6))

library) evaluating to the integer 8; rather, it is a syntac-

tic datum representing a three-element list, the elements

of which are the symbol + and the integers 2 and 6.

4.3.3. Vectors

Vector data, representing vectors of objects (see sec-

tion 11.13), are represented using the notation #('datum`

. . . ). For example, a vector of length 3 containing the

number object for zero in element 0, the list (2 2 2 2)

in element 1, and the string "Anna" in element 2 can be

represented as follows:

#(0 (2 2 2 2) "Anna")

This is the external representation of a vector, not an ex-

pression that evaluates to a vector.

4.3.4. Bytevectors

Bytevector data, representing bytevectors (see library

chapter 2), are represented using the notation #vu8('u8`

. . . ), where the 'u8`s represent the octets of the bytevec-

tor. For example, a bytevector of length 3 containing the

octets 2, 24, and 123 can be represented as follows:

#vu8(2 24 123)

This is the external representation of a bytevector, and also

an expression that evaluates to a bytevector.

4.3.5. Abbreviations

’'datum`

`'datum`

,'datum`

,@'datum`

#’'datum`

#`'datum`

#,'datum`

#,@'datum`

Each of these is an abbreviation:

’'datum` for (quote 'datum`),

`'datum` for (quasiquote 'datum`),

,'datum` for (unquote 'datum`),

,@'datum` for (unquote-splicing 'datum`),

#’'datum` for (syntax 'datum`),

#`'datum` for (quasisyntax 'datum`),

#,'datum` for (unsyntax 'datum`), and

#,@'datum` for (unsyntax-splicing 'datum`).

5. Semantic concepts

5.1. Programs and libraries

A Scheme program consists of a top-level program together

with a set of libraries, each of which deﬁnes a part of the

program connected to the others through explicitly spec-

iﬁed exports and imports. A library consists of a set of

export and import speciﬁcations and a body, which con-

sists of deﬁnitions, and expressions. A top-level program is

similar to a library, but has no export speciﬁcations. Chap-

ters 7 and 8 describe the syntax and semantics of libraries

and top-level programs, respectively. Chapter 11 describes

a base library that deﬁnes many of the constructs tradi-

tionally associated with Scheme. A separate report [24] de-

scribes the various standard libraries provided by a Scheme

system.

The division between the base library and the other stan-

dard libraries is based on use, not on construction. In par-

ticular, some facilities that are typically implemented as

“primitives” by a compiler or the run-time system rather

than in terms of other standard procedures or syntactic

forms are not part of the base library, but are deﬁned in

separate libraries. Examples include the ﬁxnums and ﬂon-

ums libraries, the exceptions and conditions libraries, and

the libraries for records.

5.2. Variables, keywords, and regions

Within the body of a library or top-level program, an iden-

tiﬁer may name a kind of syntax, or it may name a location

where a value can be stored. An identiﬁer that names a

18 Revised

6

Scheme

kind of syntax is called a keyword, or syntactic keyword,

and is said to be bound to that kind of syntax (or, in the

case of a syntactic abstraction, a transformer that trans-

lates the syntax into more primitive forms; see section 9.2).

An identiﬁer that names a location is called a variable and

is said to be bound to that location. At each point within

a top-level program or a library, a speciﬁc, ﬁxed set of

identiﬁers is bound. The set of these identiﬁers, the set of

visible bindings, is known as the environment in eﬀect at

that point.

Certain forms are used to create syntactic abstractions and

to bind keywords to transformers for those new syntactic

abstractions, while other forms create new locations and

bind variables to those locations. Collectively, these forms

are called binding constructs. Some binding constructs take

the form of deﬁnitions, while others are expressions. With

the exception of exported library bindings, a binding cre-

ated by a deﬁnition is visible only within the body in which

the deﬁnition appears, e.g., the body of a library, top-level

program, or lambda expression. Exported library bindings

are also visible within the bodies of the libraries and top-

level programs that import them (see chapter 7).

Expressions that bind variables include the lambda, let,

let*, letrec, letrec*, let-values, and let*-values

forms from the base library (see sections 11.4.2, 11.4.6).

Of these, lambda is the most fundamental. Variable def-

initions appearing within the body of such an expression,

or within the bodies of a library or top-level program, are

treated as a set of letrec* bindings. In addition, for li-

brary bodies, the variables exported from the library can be

referenced by importing libraries and top-level programs.

Expressions that bind keywords include the let-syntax

and letrec-syntax forms (see section 11.18). A define

form (see section 11.2.1) is a deﬁnition that creates a vari-

able binding (see section 11.2), and a define-syntax form

is a deﬁnition that creates a keyword binding (see sec-

tion 11.2.2).

Scheme is a statically scoped language with block struc-

ture. To each place in a top-level program or library body

where an identiﬁer is bound there corresponds a region of

code within which the binding is visible. The region is

determined by the particular binding construct that estab-

lishes the binding; if the binding is established by a lambda

expression, for example, then its region is the entire lambda

expression. Every mention of an identiﬁer refers to the

binding of the identiﬁer that establishes the innermost of

the regions containing the use. If a use of an identiﬁer ap-

pears in a place where none of the surrounding expressions

contains a binding for the identiﬁer, the use may refer to a

binding established by a deﬁnition or import at the top of

the enclosing library or top-level program (see chapter 7).

If there is no binding for the identiﬁer, it is said to be

unbound.

5.3. Exceptional situations

A variety of exceptional situations are distinguished in this

report, among them violations of syntax, violations of a

procedure’s speciﬁcation, violations of implementation re-

strictions, and exceptional situations in the environment.

When an exceptional situation is detected by the imple-

mentation, an exception is raised, which means that a

special procedure called the current exception handler is

called. A program can also raise an exception, and over-

ride the current exception handler; see library section 7.1.

When an exception is raised, an object is provided that de-

scribes the nature of the exceptional situation. The report

uses the condition system described in library section 7.2

to describe exceptional situations, classifying them by con-

dition types.

Some exceptional situations allow continuing the program

if the exception handler takes appropriate action. The cor-

responding exceptions are called continuable. For most of

the exceptional situations described in this report, portable

programs cannot rely upon the exception being continuable

at the place where the situation was detected. For those

exceptions, the exception handler that is invoked by the

exception should not return. In some cases, however, con-

tinuing is permissible, and the handler may return. See

library section 7.1.

Implementations must raise an exception when they are

unable to continue correct execution of a correct pro-

gram due to some implementation restriction. For ex-

ample, an implementation that does not support in-

ﬁnities must raise an exception with condition type

&implementation-restriction when it evaluates an ex-

pression whose result would be an inﬁnity.

Some possible implementation restrictions such as the

lack of representations for NaNs and inﬁnities (see sec-

tion 11.7.2) are anticipated by this report, and implemen-

tations typically must raise an exception of the appropriate

condition type if they encounter such a situation.

This report uses the phrase “an exception is raised” syn-

onymously with “an exception must be raised”. This re-

port uses the phrase “an exception with condition type t”

to indicate that the object provided with the exception is

a condition object of the speciﬁed type. The phrase “a

continuable exception is raised” indicates an exceptional

situation that permits the exception handler to return.

5.4. Argument checking

Many procedures speciﬁed in this report or as part of a

standard library restrict the arguments they accept. Typi-

cally, a procedure accepts only speciﬁc numbers and types

of arguments. Many syntactic forms similarly restrict the

5. Semantic concepts 19

values to which one or more of their subforms can evalu-

ate. These restrictions imply responsibilities for both the

programmer and the implementation. Speciﬁcally, the pro-

grammer is responsible for ensuring that the values indeed

adhere to the restrictions described in the speciﬁcation.

The implementation must check that the restrictions in

the speciﬁcation are indeed met, to the extent that it is

reasonable, possible, and necessary to allow the speciﬁed

operation to complete successfully. The implementation’s

responsibilities are speciﬁed in more detail in chapter 6 and

throughout the report.

Note that it is not always possible for an implementation

to completely check the restrictions set forth in a speci-

ﬁcation. For example, if an operation is speciﬁed to ac-

cept a procedure with speciﬁc properties, checking of these

properties is undecidable in general. Similarly, some oper-

ations accept both lists and procedures that are called by

these operations. Since lists can be mutated by the pro-

cedures through the (rnrs mutable-pairs (6)) library

(see library chapter 17), an argument that is a list when

the operation starts may become a non-list during the exe-

cution of the operation. Also, the procedure might escape

to a diﬀerent continuation, preventing the operation from

performing more checks. Requiring the operation to check

that the argument is a list after each call to such a proce-

dure would be impractical. Furthermore, some operations

that accept lists only need to traverse these lists partially

to perform their function; requiring the implementation to

traverse the remainder of the list to verify that all spec-

iﬁed restrictions have been met might violate reasonable

performance assumptions. For these reasons, the program-

mer’s obligations may exceed the checking obligations of

the implementation.

When an implementation detects a violation of a restriction

for an argument, it must raise an exception with condition

type &assertion in a way consistent with the safety of

execution as described in section 5.6.

5.5. Syntax violations

The subforms of a special form usually need to obey cer-

tain syntactic restrictions. As forms may be subject to

macro expansion, which may not terminate, the question

of whether they obey the speciﬁed restrictions is undecid-

able in general.

When macro expansion terminates, however, implementa-

tions must detect violations of the syntax. A syntax viola-

tion is an error with respect to the syntax of library bodies,

top-level bodies, or the “syntax” entries in the speciﬁca-

tion of the base library or the standard libraries. More-

over, attempting to assign to an immutable variable (i.e.,

the variables exported by a library; see section 7.1) is also

considered a syntax violation.

If a top-level or library form in a program is not syntac-

tically correct, then the implementation must raise an ex-

ception with condition type &syntax, and execution of that

top-level program or library must not be allowed to begin.

5.6. Safety

The standard libraries whose exports are described by this

document are said to be safe libraries. Libraries and top-

level programs that import only from safe libraries are also

said to be safe.

As deﬁned by this document, the Scheme programming

language is safe in the following sense: The execution of

a safe top-level program cannot go so badly wrong as to

crash or to continue to execute while behaving in ways

that are inconsistent with the semantics described in this

document, unless an exception is raised.

Violations of an implementation restriction must raise

an exception with condition type &implementation-

restriction, as must all violations and errors that would

otherwise threaten system integrity in ways that might re-

sult in execution that is inconsistent with the semantics

described in this document.

The above safety properties are guaranteed only for top-

level programs and libraries that are said to be safe. In

particular, implementations may provide access to unsafe

libraries in ways that cannot guarantee safety.

5.7. Boolean values

Although there is a separate boolean type, any Scheme

value can be used as a boolean value for the purpose of

a conditional test. In a conditional test, all values count

as true in such a test except for #f. This report uses the

word “true” to refer to any Scheme value except #f, and

the word “false” to refer to #f.

5.8. Multiple return values

A Scheme expression can evaluate to an arbitrary ﬁnite

number of values. These values are passed to the expres-

sion’s continuation.

Not all continuations accept any number of values. For

example, a continuation that accepts the argument to a

procedure call is guaranteed to accept exactly one value.

The eﬀect of passing some other number of values to such a

continuation is unspeciﬁed. The call-with-values proce-

dure described in section 11.15 makes it possible to create

continuations that accept speciﬁed numbers of return val-

ues. If the number of return values passed to a continuation

created by a call to call-with-values is not accepted by

20 Revised

6

Scheme

its consumer that was passed in that call, then an excep-

tion is raised. A more complete description of the number

of values accepted by diﬀerent continuations and the conse-

quences of passing an unexpected number of values is given

in the description of the values procedure in section 11.15.

A number of forms in the base library have sequences of ex-

pressions as subforms that are evaluated sequentially, with

the return values of all but the last expression being dis-

carded. The continuations discarding these values accept

any number of values.

5.9. Unspeciﬁed behavior

If an expression is said to “return unspeciﬁed values”, then

the expression must evaluate without raising an exception,

but the values returned depend on the implementation;

this report explicitly does not say how many or what val-

ues should be returned. Programmers should not rely on

a speciﬁc number of return values or the speciﬁc values

themselves.

5.10. Storage model

Variables and objects such as pairs, vectors, bytevectors,

strings, hashtables, and records implicitly refer to locations

or sequences of locations. A string, for example, contains 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 string-set! procedure, but the string contains the

same locations as before.

An object fetched from a location, by a variable reference or

by a procedure such as car, vector-ref, or string-ref, is

equivalent in the sense of eqv? (section 11.5) 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 report 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 refer to them.

It is desirable for constants (i.e. the values of literal expres-

sions) to reside in read-only memory. To express this, it is

convenient to imagine that every object that refers to loca-

tions is associated with a ﬂag telling whether that object

is mutable or immutable. Literal constants, the strings re-

turned by symbol->string, records with no mutable ﬁelds,

and other values explicitly designated as immutable are

immutable objects, while all objects created by the other

procedures listed in this report are mutable. An attempt

to store a new value into a location referred to by an im-

mutable object should raise an exception with condition

type &assertion.

5.11. Proper tail recursion

Implementations of Scheme must be properly tail-recursive.

Procedure calls that occur in certain syntactic contexts

called tail contexts are tail calls. A Scheme implementa-

tion is properly tail-recursive if it supports an unbounded

number of active tail calls. A call is active if the called

procedure may still return. Note that this includes regu-

lar returns as well as returns through continuations cap-

tured earlier by call-with-current-continuation that

are later invoked. In the absence of captured continuations,

calls could return at most once and the active calls would

be those that had not yet returned. A formal deﬁnition of

proper tail recursion can be found in Clinger’s paper [5].

The rules for identifying tail calls in constructs from the

(rnrs base (6)) library are described in section 11.20.

5.12. Dynamic extent and the dynamic en-

vironment

For a procedure call, the time between when it is initiated

and when it returns is called its dynamic extent. In Scheme,

call-with-current-continuation (section 11.15) allows

reentering a dynamic extent after its procedure call has

returned. Thus, the dynamic extent of a call may not be a

single, connected time period.

Some operations described in the report acquire informa-

tion in addition to their explicit arguments from the dy-

namic environment. For example, call-with-current-

continuation accesses an implicit context established by

dynamic-wind (section 11.15), and the raise procedure

(library section 7.1) accesses the current exception handler.

The operations that modify the dynamic environment do so

dynamically, for the dynamic extent of a call to a procedure

like dynamic-wind or with-exception-handler. When

such a call returns, the previous dynamic environment is

restored. The dynamic environment can be thought of as

part of the dynamic extent of a call. Consequently, it is

captured by call-with-current-continuation, and re-

stored by invoking the escape procedure it creates.

6. Entry format

The chapters that describe bindings in the base library

and the standard libraries are organized into entries. Each

entry describes one language feature or a group of related

features, where a feature is either a syntactic construct or

a built-in procedure. An entry begins with one or more

header lines of the form

6. Entry format 21

template category

The category deﬁnes the kind of binding described by the

entry, typically either “syntax” or “procedure”. An entry

may specify various restrictions on subforms or arguments.

For background on this, see section 5.4.

6.1. Syntax entries

If category is “syntax”, the entry describes a special syn-

tactic construct, and the template gives the syntax of the

forms of the construct. The template is written in a nota-

tion similar to a right-hand side of the BNF rules in chap-

ter 4, and describes the set of forms equivalent to the forms

matching the template as syntactic data. Some “syntax”

entries carry a suﬃx (expand), specifying that the syn-

tactic keyword of the construct is exported with level 1.

Otherwise, the syntactic keyword is exported with level 0;

see section 7.2.

Components of the form described by a template are desig-

nated by syntactic variables, which are written using angle

brackets, for example, 'expression`, 'variable`. Case is in-

signiﬁcant in syntactic variables. Syntactic variables stand

for other forms, or sequences of them. A syntactic variable

may refer to a non-terminal in the grammar for syntactic

data (see section 4.3.1), in which case only forms match-

ing that non-terminal are permissible in that position. For

example, 'identiﬁer` stands for a form which must be an

identiﬁer. Also, 'expression` stands for any form which is

a syntactically valid expression. Other non-terminals that

are used in templates are deﬁned as part of the speciﬁca-

tion.

The notation

'thing

1

` . . .

indicates zero or more occurrences of a 'thing`, and

'thing

1

` 'thing

2

` . . .

indicates one or more occurrences of a 'thing`.

It is the programmer’s responsibility to ensure that each

component of a form has the shape speciﬁed by a template.

Descriptions of syntax may express other restrictions on

the components of a form. Typically, such a restriction is

formulated as a phrase of the form “'x` must be a . . . ”.

Again, these specify the programmer’s responsibility. It is

the implementation’s responsibility to check that these re-

strictions are satisﬁed, as long as the macro transformers

involved in expanding the form terminate. If the imple-

mentation detects that a component does not meet the

restriction, an exception with condition type &syntax is

raised.

6.2. Procedure entries

If category is “procedure”, then the entry describes a pro-

cedure, and the header line gives a template for a call to the

procedure. Parameter names in the template are italicized.

Thus the header line

(vector-ref vector k) procedure

indicates that the built-in procedure vector-ref takes two

arguments, a vector vector and an exact non-negative in-

teger object k (see below). The header lines

(make-vector k) procedure

(make-vector k ﬁll ) procedure

indicate that the make-vector procedure takes either

one or two arguments. The parameter names are case-

insensitive: Vector is the same as vector.

As with syntax templates, an ellipsis . . . at the end of a

header line, as in

(= z

1

z

2

z

3

. . . ) procedure

indicates that the procedure takes arbitrarily many argu-

ments of the same type as speciﬁed for the last parameter

name. In this case, = accepts two or more arguments that

must all be complex number objects.

A procedure that detects an argument that it is not speci-

ﬁed to handle must raise an exception with condition type

&assertion. Also, the argument speciﬁcations are ex-

haustive: if the number of arguments provided in a pro-

cedure call does not match any number of arguments ac-

cepted by the procedure, an exception with condition type

&assertion must be raised.

For succinctness, the report follows the convention that if

a parameter name is also the name of a type, then the cor-

responding argument must be of the named type. For ex-

ample, the header line for vector-ref given above dictates

that the ﬁrst argument to vector-ref must be a vector.

The following naming conventions imply type restrictions:

obj any object

z complex number object

x real number object

y real number object

q rational number object

n integer object

k exact non-negative integer object

bool boolean (#f or #t)

octet exact integer object in ¦0, . . . , 255¦

byte exact integer object in ¦−128, . . . , 127¦

char character (see section 11.11)

pair pair (see section 11.9)

vector vector (see section 11.13)

string string (see section 11.12)

condition condition (see library section 7.2)

bytevector bytevector (see library chapter 2)

proc procedure (see section 1.6)

22 Revised

6

Scheme

Other type restrictions are expressed through parameter-

naming conventions that are described in speciﬁc chapters.

For example, library chapter 11 uses a number of special

parameter variables for the various subsets of the numbers.

With the listed type restrictions, it is the programmer’s

responsibility to ensure that the corresponding argument

is of the speciﬁed type. It is the implementation’s respon-

sibility to check for that type.

A parameter called list means that it is the programmer’s

responsibility to pass an argument that is a list (see sec-

tion 11.9). It is the implementation’s responsibility to

check that the argument is appropriately structured for

the operation to perform its function, to the extent that

this is possible and reasonable. The implementation must

at least check that the argument is either an empty list or

a pair.

Descriptions of procedures may express other restrictions

on the arguments of a procedure. Typically, such a restric-

tion is formulated as a phrase of the form “x must be a

. . . ” (or otherwise using the word “must”).

6.3. Implementation responsibilities

In addition to the restrictions implied by naming conven-

tions, an entry may list additional explicit restrictions.

These explicit restrictions usually describe both the pro-

grammer’s responsibilities, who must ensure that the sub-

forms of a form are appropriate, or that an appropriate

argument is passed, and the implementation’s responsibil-

ities, which must check that subform adheres to the speci-

ﬁed restrictions (if macro expansion terminates), or if the

argument is appropriate. A description may explicitly list

the implementation’s responsibilities for some arguments

or subforms in a paragraph labeled “Implementation re-

sponsibilities”. In this case, the responsibilities speciﬁed

for these subforms or arguments in the rest of the descrip-

tion are only for the programmer. A paragraph describing

implementation responsibility does not aﬀect the imple-

mentation’s responsibilities for checking subforms or argu-

ments not mentioned in the paragraph.

6.4. Other kinds of entries

If category is something other than “syntax” and “proce-

dure”, then the entry describes a non-procedural value, and

the category describes the type of that value. The header

line

&who condition type

indicates that &who is a condition type. The header

line

unquote auxiliary syntax

indicates that unquote is a syntax binding that may

occur only as part of speciﬁc surrounding expressions.

Any use as an independent syntactic construct or iden-

tiﬁer is a syntax violation. As with “syntax” entries,

some “auxiliary syntax” entries carry a suﬃx (expand),

specifying that the syntactic keyword of the construct is

exported with level 1.

6.5. Equivalent entries

The description of an entry occasionally states that it is

the same as another entry. This means that both entries

are equivalent. Speciﬁcally, it means that if both entries

have the same name and are thus exported from diﬀerent

libraries, the entries from both libraries can be imported

under the same name without conﬂict.

6.6. Evaluation examples

The symbol “=⇒” used in program examples can be read

“evaluates to”. For example,

(* 5 8) =⇒ 40

means that the expression (* 5 8) evaluates to the ob-

ject 40. Or, more precisely: the expression given by the

sequence of characters “(* 5 8)” evaluates, in an environ-

ment that imports the relevant library, to an object that

may be represented externally by the sequence of char-

acters “40”. See section 4.3 for a discussion of external

representations of objects.

The “=⇒” symbol is also used when the evaluation of an

expression causes a violation. For example,

(integer->char #xD800) =⇒ &assertion exception

means that the evaluation of the expression

(integer->char #xD800) must raise an exception

with condition type &assertion.

Moreover, the “=⇒” symbol is also used to explicitly say

that the value of an expression in unspeciﬁed. For exam-

ple:

(eqv? "" "") =⇒ unspeciﬁed

Mostly, examples merely illustrate the behavior speciﬁed

in the entry. In some cases, however, they disambiguate

otherwise ambiguous speciﬁcations and are thus norma-

tive. Note that, in some cases, speciﬁcally in the case of

inexact number objects, the return value is only speciﬁed

conditionally or approximately. For example:

(atan -inf.0)

=⇒ -1.5707963267948965 ; approximately

7. Libraries 23

6.7. Naming conventions

By convention, the names of procedures that store values

into previously allocated locations (see section 5.10) usu-

ally end in “!”.

By convention, “->” appears within the names of proce-

dures that take an object of one type and return an anal-

ogous object of another type. For example, list->vector

takes a list and returns a vector whose elements are the

same as those of the list.

By convention, the names of predicates—procedures that

always return a boolean value—end in “?” when the name

contains any letters; otherwise, the predicate’s name does

not end with a question mark.

By convention, the components of compound names are

separated by “-” In particular, preﬁxes that are actual

words or can be pronounced as though they were actual

words are followed by a hyphen, except when the ﬁrst char-

acter following the hyphen would be something other than

a letter, in which case the hyphen is omitted. Short, un-

pronounceable preﬁxes (“fx” and “fl”) are not followed

by a hyphen.

By convention, the names of condition types start with “&”.

7. Libraries

Libraries are parts of a program that can be distributed

independently. The library system supports macro deﬁni-

tions within libraries, macro exports, and distinguishes the

phases in which deﬁnitions and imports are needed. This

chapter deﬁnes the notation for libraries and a semantics

for library expansion and execution.

7.1. Library form

A library deﬁnition must have the following form:

(library 'library name)

(export 'export spec) ...)

(import 'import spec) ...)

'library body))

A library declaration contains the following elements:

• The 'library name` speciﬁes the name of the library

(possibly with version).

• The export subform speciﬁes a list of exports, which

name a subset of the bindings deﬁned within or im-

ported into the library.

• The import subform speciﬁes the imported bindings

as a list of import dependencies, where each depen-

dency speciﬁes:

– the imported library’s name, and, optionally,

constraints on its version,

– the relevant levels, e.g., expand or run time (see

section 7.2, and

– the subset of the library’s exports to make avail-

able within the importing library, and the local

names to use within the importing library for

each of the library’s exports.

• The 'library body` is the library body, consisting of a

sequence of deﬁnitions followed by a sequence of ex-

pressions. The deﬁnitions may be both for local (un-

exported) and exported bindings, and the expressions

are initialization expressions to be evaluated for their

eﬀects.

An identiﬁer can be imported with the same local name

from two or more libraries or for two levels from the same

library only if the binding exported by each library is

the same (i.e., the binding is deﬁned in one library, and

it arrives through the imports only by exporting and re-

exporting). Otherwise, no identiﬁer can be imported mul-

tiple times, deﬁned multiple times, or both deﬁned and

imported. No identiﬁers are visible within a library except

for those explicitly imported into the library or deﬁned

within the library.

A 'library name` uniquely identiﬁes a library within an im-

plementation, and is globally visible in the import clauses

(see below) of all other libraries within an implementation.

A 'library name` has the following form:

('identiﬁer1) 'identiﬁer2) ... 'version))

where 'version` is empty or has the following form:

('sub-version) ...)

Each 'sub-version` must represent an exact nonnegative

integer object. An empty 'version` is equivalent to ().

An 'export spec` names a set of imported and locally de-

ﬁned bindings to be exported, possibly with diﬀerent exter-

nal names. An 'export spec` must have one of the following

forms:

'identiﬁer)

(rename ('identiﬁer1) 'identiﬁer2)) ...)

In an 'export spec`, an 'identiﬁer` names a single binding

deﬁned within or imported into the library, where the ex-

ternal name for the export is the same as the name of

the binding within the library. A rename spec exports

the binding named by 'identiﬁer

1

` in each ('identiﬁer

1

`

'identiﬁer

2

`) pairing, using 'identiﬁer

2

` as the external

name.

Each 'import spec` speciﬁes a set of bindings to be im-

ported into the library, the levels at which they are to

be available, and the local names by which they are to

be known. An 'import spec` must be one of the follow-

ing:

24 Revised

6

Scheme

'import set)

(for 'import set) 'import level) ...)

An 'import level` is one of the following:

run

expand

(meta 'level))

where 'level` represents an exact integer object.

As an 'import level`, run is an abbreviation for (meta 0),

and expand is an abbreviation for (meta 1). Levels and

phases are discussed in section 7.2.

An 'import set` names a set of bindings from another li-

brary and possibly speciﬁes local names for the imported

bindings. It must be one of the following:

'library reference)

(library 'library reference))

(only 'import set) 'identiﬁer) ...)

(except 'import set) 'identiﬁer) ...)

(prefix 'import set) 'identiﬁer))

(rename 'import set) ('identiﬁer1) 'identiﬁer2)) ...)

A 'library reference` identiﬁes a library by its name and

optionally by its version. It has one of the following forms:

('identiﬁer1) 'identiﬁer2) ...)

('identiﬁer1) 'identiﬁer2) ... 'version reference))

A 'library reference` whose ﬁrst 'identiﬁer` is for,

library, only, except, prefix, or rename is permitted

only within a library 'import set`. The 'import set`

(library 'library reference`) is otherwise equivalent to

'library reference`.

A 'library reference` with no 'version reference` (ﬁrst

form above) is equivalent to a 'library reference` with a

'version reference` of ().

A 'version reference` speciﬁes a set of 'version`s that it

matches. The 'library reference` identiﬁes all libraries

of the same name and whose version is matched by the

'version reference`. A 'version reference` has the following

form:

('sub-version reference1) ... 'sub-version referencen))

(and 'version reference) ...)

(or 'version reference) ...)

(not 'version reference))

A 'version reference` of the ﬁrst form matches a 'version`

with at least n elements, whose 'sub-version reference`s

match the corresponding 'sub-version`s. An

and 'version reference` matches a version if all

'version references` following the and match it. Cor-

respondingly, an or 'version reference` matches a version

if one of 'version references` following the or matches it,

and a not 'version reference` matches a version if the

'version reference` following it does not match it.

A 'sub-version reference` has one of the following forms:

'sub-version)

(>= 'sub-version))

(<= 'sub-version))

(and 'sub-version reference) ...)

(or 'sub-version reference) ...)

(not 'sub-version reference))

A 'sub-version reference` of the ﬁrst form matches

a 'sub-version` if it is equal to it. A >=

'sub-version reference` of the ﬁrst form matches a sub-

version if it is greater or equal to the 'sub-version` following

it; analogously for <=. An and 'sub-version reference`

matches a sub-version if all of the subsequent

'sub-version reference`s match it. Correspondingly,

an or 'sub-version reference` matches a sub-version if one

of the subsequent 'sub-version reference`s matches it, and

a not 'sub-version reference` matches a sub-version if the

subsequent 'sub-version reference` does not match it.

Examples:

version reference version match?

() (1) yes

(1) (1) yes

(1) (2) no

(2 3) (2) no

(2 3) (2 3) yes

(2 3) (2 3 5) yes

(or (1 (>= 1)) (2)) (2) yes

(or (1 (>= 1)) (2)) (1 1) yes

(or (1 (>= 1)) (2)) (1 0) no

((or 1 2 3)) (1) yes

((or 1 2 3)) (2) yes

((or 1 2 3)) (3) yes

((or 1 2 3)) (4) no

When more than one library is identiﬁed by a library

reference, the choice of libraries is determined in some

implementation-dependent manner.

To avoid problems such as incompatible types and repli-

cated state, implementations should prohibit the two li-

braries whose library names consist of the same sequence

of identiﬁers but whose versions do not match to co-exist

in the same program.

By default, all of an imported library’s exported bind-

ings are made visible within an importing library using

the names given to the bindings by the imported library.

The precise set of bindings to be imported and the names

of those bindings can be adjusted with the only, except,

prefix, and rename forms as described below.

• An only form produces a subset of the bindings

from another 'import set`, including only the listed

'identiﬁer`s. The included 'identiﬁer`s must be in the

original 'import set`.

7. Libraries 25

• An except form produces a subset of the bindings

from another 'import set`, including all but the listed

'identiﬁer`s. All of the excluded 'identiﬁer`s must be

in the original 'import set`.

• A prefix form adds the 'identiﬁer` preﬁx to each

name from another 'import set`.

• A rename form, (rename ('identiﬁer

1

` 'identiﬁer

2

`)

...), removes the bindings for 'identiﬁer

1

` ... to

form an intermediate 'import set`, then adds the bind-

ings back for the corresponding 'identiﬁer

2

` ... to

form the ﬁnal 'import set`. Each 'identiﬁer

1

` must

be in the original 'import set`, each 'identiﬁer

2

` must

not be in the intermediate 'import set`, and the

'identiﬁer

2

`s must be distinct.

It is a syntax violation if a constraint given above is not

met.

The 'library body` of a library form consists of forms that

are classiﬁed as deﬁnitions or expressions. Which forms

belong to which class depends on the imported libraries

and the result of expansion—see chapter 10. Generally,

forms that are not deﬁnitions (see section 11.2 for deﬁni-

tions available through the base library) are expressions.

A 'library body` is like a 'body` (see section 11.3) except

that a 'library body`s need not include any expressions. It

must have the following form:

'deﬁnition) ... 'expression) ...

When begin, let-syntax, or letrec-syntax forms occur

in a top-level body prior to the ﬁrst expression, they are

spliced into the body; see section 11.4.7. Some or all of the

body, including portions wrapped in begin, let-syntax,

or letrec-syntax forms, may be speciﬁed by a syntactic

abstraction (see section 9.2).

The transformer expressions and bindings are evaluated

and created from left to right, as described in chapter 10.

The expressions of variable deﬁnitions are evaluated from

left to right, as if in an implicit letrec*, and the body

expressions are also evaluated from left to right after the

expressions of the variable deﬁnitions. A fresh location is

created for each exported variable and initialized to the

value of its local counterpart. The eﬀect of returning twice

to the continuation of the last body expression is unspeci-

ﬁed.

Note: The names library, export, import, for, run, expand,

meta, import, export, only, except, prefix, rename, and, or,

not, >=, and <= appearing in the library syntax are part of

the syntax and are not reserved, i.e., the same names can be

used for other purposes within the library or even exported

from or imported into a library with diﬀerent meanings, without

aﬀecting their use in the library form.

Bindings deﬁned with a library are not visible in code out-

side of the library, unless the bindings are explicitly ex-

ported from the library. An exported macro may, however,

implicitly export an otherwise unexported identiﬁer deﬁned

within or imported into the library. That is, it may insert a

reference to that identiﬁer into the output code it produces.

All explicitly exported variables are immutable in both the

exporting and importing libraries. It is thus a syntax vi-

olation if an explicitly exported variable appears on the

left-hand side of a set! expression, either in the exporting

or importing libraries.

All implicitly exported variables are also immutable in both

the exporting and importing libraries. It is thus a syn-

tax violation if a variable appears on the left-hand side of

a set! expression in any code produced by an exported

macro outside of the library in which the variable is de-

ﬁned. It is also a syntax violation if a reference to an

assigned variable appears in any code produced by an ex-

ported macro outside of the library in which the variable

is deﬁned, where an assigned variable is one that appears

on the left-hand side of a set! expression in the exporting

library.

All other variables deﬁned within a library are mutable.

7.2. Import and export levels

Expanding a library may require run-time information

from another library. For example, if a macro transformer

calls a procedure from library A, then the library A must

be instantiated before expanding any use of the macro in

library B. Library A may not be needed when library B is

eventually run as part of a program, or it may be needed

for run time of library B, too. The library mechanism dis-

tinguishes these times by phases, which are explained in

this section.

Every library can be characterized by expand-time infor-

mation (minimally, its imported libraries, a list of the ex-

ported keywords, a list of the exported variables, and code

to evaluate the transformer expressions) and run-time in-

formation (minimally, code to evaluate the variable def-

inition right-hand-side expressions, and code to evaluate

the body expressions). The expand-time information must

be available to expand references to any exported binding,

and the run-time information must be available to evaluate

references to any exported variable binding.

A phase is a time at which the expressions within a li-

brary are evaluated. Within a library body, top-level ex-

pressions and the right-hand sides of define forms are

evaluated at run time, i.e., phase 0, and the right-hand

sides of define-syntax forms are evaluated at expand

time, i.e., phase 1. When define-syntax, let-syntax,

or letrec-syntax forms appear within code evaluated at

phase n, the right-hand sides are evaluated at phase n+1.

26 Revised

6

Scheme

These phases are relative to the phase in which the li-

brary itself is used. An instance of a library corresponds

to an evaluation of its variable deﬁnitions and expressions

in a particular phase relative to another library—a process

called instantiation. For example, if a top-level expression

in a library B refers to a variable export from another li-

brary A, then it refers to the export from an instance of

A at phase 0 (relative to the phase of B). But if a phase

1 expression within B refers to the same binding from A,

then it refers to the export from an instance of A at phase

1 (relative to the phase of B).

A visit of a library corresponds to the evaluation of its

syntax deﬁnitions in a particular phase relative to another

library—a process called visiting. For example, if a top-

level expression in a library B refers to a macro export

from another library A, then it refers to the export from

a visit of A at phase 0 (relative to the phase of B), which

corresponds to the evaluation of the macro’s transformer

expression at phase 1.

A level is a lexical property of an identiﬁer that determines

in which phases it can be referenced. The level for each

identiﬁer bound by a deﬁnition within a library is 0; that is,

the identiﬁer can be referenced only at phase 0 within the

library. The level for each imported binding is determined

by the enclosing for form of the import in the importing

library, in addition to the levels of the identiﬁer in the

exporting library. Import and export levels are combined

by pairwise addition of all level combinations. For example,

references to an imported identiﬁer exported for levels p

a

and p

b

and imported for levels q

a

, q

b

, and q

c

are valid at

levels p

a

+q

a

, p

a

+q

b

, p

a

+q

c

, p

b

+q

a

, p

b

+q

b

, and p

b

+q

c

. An

'import set` without an enclosing for is equivalent to (for

'import set` run), which is the same as (for 'import set`

(meta 0)).

The export level of an exported binding is 0 for all bindings

that are deﬁned within the exporting library. The export

levels of a reexported binding, i.e., an export imported from

another library, are the same as the eﬀective import levels

of that binding within the reexporting library.

For the libraries deﬁned in the library report, the ex-

port level is 0 for nearly all bindings. The exceptions are

syntax-rules, identifier-syntax, ..., and from the

(rnrs base (6)) library, which are exported with level 1,

set! from the (rnrs base (6)) library, which is exported

with levels 0 and 1, and all bindings from the composite

(rnrs (6)) library (see library chapter 15), which are ex-

ported with levels 0 and 1.

Macro expansion within a library can introduce a reference

to an identiﬁer that is not explicitly imported into the li-

brary. In that case, the phase of the reference must match

the identiﬁer’s level as shifted by the diﬀerence between

the phase of the source library (i.e., the library that sup-

plied the identiﬁer’s lexical context) and the library that

encloses the reference. For example, suppose that expand-

ing a library invokes a macro transformer, and the evalua-

tion of the macro transformer refers to an identiﬁer that is

exported from another library (so the phase-1 instance of

the library is used); suppose further that the value of the

binding is a syntax object representing an identiﬁer with

only a level-n binding; then, the identiﬁer must be used

only at phase n + 1 in the library being expanded. This

combination of levels and phases is why negative levels on

identiﬁers can be useful, even though libraries exist only at

non-negative phases.

If any of a library’s deﬁnitions are referenced at phase 0

in the expanded form of a program, then an instance of

the referenced library is created for phase 0 before the pro-

gram’s deﬁnitions and expressions are evaluated. This rule

applies transitively: if the expanded form of one library ref-

erences at phase 0 an identiﬁer from another library, then

before the referencing library is instantiated at phase n, the

referenced library must be instantiated at phase n. When

an identiﬁer is referenced at any phase n greater than 0, in

contrast, then the deﬁning library is instantiated at phase

n at some unspeciﬁed time before the reference is evalu-

ated. Similarly, when a macro keyword is referenced at

phase n during the expansion of a library, then the deﬁn-

ing library is visited at phase n at some unspeciﬁed time

before the reference is evaluated.

An implementation may distinguish instances/visits of a

library for diﬀerent phases or to use an instance/visit at

any phase as an instance/visit at any other phase. An im-

plementation may further expand each library form with

distinct visits of libraries in any phase and/or instances of

libraries in phases above 0. An implementation may create

instances/visits of more libraries at more phases than re-

quired to satisfy references. When an identiﬁer appears as

an expression in a phase that is inconsistent with the identi-

ﬁer’s level, then an implementation may raise an exception

either at expand time or run time, or it may allow the refer-

ence. Thus, a library whose meaning depends on whether

the instances of a library are distinguished or shared across

phases or library expansions may be unportable.

7.3. Examples

Examples for various 'import spec`s and 'export spec`s:

(library (stack)

(export make push! pop! empty!)

(import (rnrs))

(define (make) (list ’()))

(define (push! s v) (set-car! s (cons v (car s))))

(define (pop! s) (let ([v (caar s)])

(set-car! s (cdar s))

v))

(define (empty! s) (set-car! s ’())))

8. Top-level programs 27

(library (balloons)

(export make push pop)

(import (rnrs))

(define (make w h) (cons w h))

(define (push b amt)

(cons (- (car b) amt) (+ (cdr b) amt)))

(define (pop b) (display "Boom! ")

(display (* (car b) (cdr b)))

(newline)))

(library (party)

;; Total exports:

;; make, push, push!, make-party, pop!

(export (rename (balloon:make make)

(balloon:push push))

push!

make-party

(rename (party-pop! pop!)))

(import (rnrs)

(only (stack) make push! pop!) ; not empty!

(prefix (balloons) balloon:))

;; Creates a party as a stack of balloons,

;; starting with two balloons

(define (make-party)

(let ([s (make)]) ; from stack

(push! s (balloon:make 10 10))

(push! s (balloon:make 12 9))

s))

(define (party-pop! p)

(balloon:pop (pop! p))))

(library (main)

(export)

(import (rnrs) (party))

(define p (make-party))

(pop! p) ; displays "Boom! 108"

(push! p (push (make 5 5) 1))

(pop! p)) ; displays "Boom! 24"

Examples for macros and phases:

(library (my-helpers id-stuff)

(export find-dup)

(import (rnrs))

(define (find-dup l)

(and (pair? l)

(let loop ((rest (cdr l)))

(cond

[(null? rest) (find-dup (cdr l))]

[(bound-identifier=? (car l) (car rest))

(car rest)]

[else (loop (cdr rest))])))))

(library (my-helpers values-stuff)

(export mvlet)

(import (rnrs) (for (my-helpers id-stuff) expand))

(define-syntax mvlet

(lambda (stx)

(syntax-case stx ()

[( [(id ...) expr] body0 body ...)

(not (find-dup (syntax (id ...))))

(syntax

(call-with-values

(lambda () expr)

(lambda (id ...) body0 body ...)))]))))

(library (let-div)

(export let-div)

(import (rnrs)

(my-helpers values-stuff)

(rnrs r5rs))

(define (quotient+remainder n d)

(let ([q (quotient n d)])

(values q (- n (* q d)))))

(define-syntax let-div

(syntax-rules ()

[( n d (q r) body0 body ...)

(mvlet [(q r) (quotient+remainder n d)]

body0 body ...)])))

8. Top-level programs

A top-level program speciﬁes an entry point for deﬁning and

running a Scheme program. A top-level program speciﬁes

a set of libraries to import and code to run. Through the

imported libraries, whether directly or through the tran-

sitive closure of importing, a top-level program deﬁnes a

complete Scheme program.

8.1. Top-level program syntax

A top-level program is a delimited piece of text, typically

a ﬁle, that has the following form:

'import form) 'top-level body)

An 'import form` has the following form:

(import 'import spec) . . . )

A 'top-level body` has the following form:

'top-level body form) . . .

A 'top-level body form` is either a 'deﬁnition` or an

'expression`.

The 'import form` is identical to the import clause in li-

braries (see section 7.1), and speciﬁes a set of libraries

to import. A 'top-level body` is like a 'library body`

(see section 7.1), except that deﬁnitions and expressions

may occur in any order. Thus, the syntax speciﬁed by

'top-level body form` refers to the result of macro expan-

sion.

28 Revised

6

Scheme

When uses of begin, let-syntax, or letrec-syntax from

the (rnrs base (6)) library occur in a top-level body

prior to the ﬁrst expression, they are spliced into the body;

see section 11.4.7. Some or all of the body, including por-

tions wrapped in begin, let-syntax, or letrec-syntax

forms, may be speciﬁed by a syntactic abstraction (see sec-

tion 9.2).

8.2. Top-level program semantics

A top-level program is executed by treating the program

similarly to a library, and evaluating its deﬁnitions and

expressions. The semantics of a top-level body may be

roughly explained by a simple translation into a library

body: Each 'expression` that appears before a deﬁnition in

the top-level body is converted into a dummy deﬁnition

(define 'variable) (begin 'expression) 'unspeciﬁed)))

where 'variable` is a fresh identiﬁer and 'unspeciﬁed` is a

side-eﬀect-free expression returning an unspeciﬁed value.

(It is generally impossible to determine which forms are

deﬁnitions and expressions without concurrently expand-

ing the body, so the actual translation is somewhat more

complicated; see chapter 10.)

On platforms that support it, a top-level program may ac-

cess its command line by calling the command-line proce-

dure (see library section 10).

9. Primitive syntax

After the import form within a library form or a top-

level program, the forms that constitute the body of the

library or the top-level program depend on the libraries

that are imported. In particular, imported syntactic key-

words determine the available syntactic abstractions and

whether each form is a deﬁnition or expression. A few

form types are always available independent of imported

libraries, however, including constant literals, variable ref-

erences, procedure calls, and macro uses.

9.1. Primitive expression types

The entries in this section all describe expressions, which

may occur in the place of 'expression` syntactic variables.

See also section 11.4.

Constant literals

'number` syntax

'boolean` syntax

'character` syntax

'string` syntax

'bytevector` syntax

An expression consisting of a representation of a number

object, a boolean, a character, a string, or a bytevector,

evaluates “to itself”.

145932 =⇒ 145932

#t =⇒ #t

"abc" =⇒ "abc"

#vu8(2 24 123) =⇒ #vu8(2 24 123)

As noted in section 5.10, the value of a literal expression is

immutable.

Variable references

'variable` syntax

An expression consisting of a variable (section 5.2) is a

variable reference if it is not a macro use (see below). The

value of the variable reference is the value stored in the

location to which the variable is bound. It is a syntax

violation to reference an unbound variable.

The following example examples assumes the base library

has been imported:

(define x 28)

x =⇒ 28

Procedure calls

('operator` 'operand

1

` . . . ) syntax

A procedure call consists of expressions for the procedure

to be called and the arguments to be passed to it, with

enclosing parentheses. A form in an expression context is

a procedure call if 'operator` is not an identiﬁer bound as

a syntactic keyword (see section 9.2 below).

When a procedure call is evaluated, the operator and

operand expressions are evaluated (in an unspeciﬁed or-

der) and the resulting procedure is passed the resulting

arguments.

The following examples assume the (rnrs base (6)) li-

brary has been imported:

(+ 3 4) =⇒ 7

((if #f + *) 3 4) =⇒ 12

If the value of 'operator` is not a procedure, an excep-

tion with condition type &assertion is raised. Also, if

'operator` does not accept as many arguments as there are

'operand`s, an exception with condition type &assertion

is raised.

Note: In contrast to other dialects of Lisp, the order of evalua-

tion is unspeciﬁed, and the operator expression and the operand

expressions are always evaluated with the same evaluation rules.

10. Expansion process 29

Although the order of evaluation is otherwise unspeciﬁed, the

eﬀect of any concurrent evaluation of the operator and operand

expressions is constrained to be consistent with some sequential

order of evaluation. The order of evaluation may be chosen

diﬀerently for each procedure call.

Note: In many dialects of Lisp, the form () is a legitimate

expression. In Scheme, expressions written as list/pair forms

must have at least one subexpression, so () is not a syntactically

valid expression.

9.2. Macros

Libraries and top-level programs can deﬁne and use new

kinds of derived expressions and deﬁnitions called syntactic

abstractions or macros. A syntactic abstraction is created

by binding a keyword to a macro transformer or, simply,

transformer. The transformer determines how a use of

the macro (called a macro use) is transcribed into a more

primitive form.

Most macro uses have the form:

('keyword) 'datum) . . . )

where 'keyword` is an identiﬁer that uniquely determines

the kind of form. This identiﬁer is called the syntactic

keyword, or simply keyword, of the macro. The number of

'datum`s and the syntax of each depends on the syntactic

abstraction.

Macro uses can also take the form of improper lists, single-

ton identiﬁers, or set! forms, where the second subform

of the set! is the keyword (see section 11.19) library sec-

tion 12.3):

('keyword) 'datum) . . . . 'datum))

'keyword)

(set! 'keyword) 'datum))

The define-syntax, let-syntax and letrec-syntax

forms, described in sections 11.2.2 and 11.18, create bind-

ings for keywords, associate them with macro transformers,

and control the scope within which they are visible.

The syntax-rules and identifier-syntax forms, de-

scribed in section 11.19, create transformers via a pattern

language. Moreover, the syntax-case form, described in

library chapter 12, allows creating transformers via arbi-

trary Scheme code.

Keywords occupy the same name space as variables. That

is, within the same scope, an identiﬁer can be bound as

a variable or keyword, or neither, but not both, and local

bindings of either kind may shadow other bindings of either

kind.

Macros deﬁned using syntax-rules and identifier-

syntax are “hygienic” and “referentially transparent” and

thus preserve Scheme’s lexical scoping [16, 15, 2, 6, 9]:

• If a macro transformer inserts a binding for an identi-

ﬁer (variable or keyword) not appearing in the macro

use, the identiﬁer is in eﬀect renamed throughout its

scope to avoid conﬂicts with other identiﬁers.

• If a macro transformer inserts a free reference to an

identiﬁer, the reference refers to the binding that was

visible where the transformer was speciﬁed, regardless

of any local bindings that may surround the use of the

macro.

Macros deﬁned using the syntax-case facility are also hy-

gienic unless datum->syntax (see library section 12.6) is

used.

10. Expansion process

Macro uses (see section 9.2) are expanded into core forms

at the start of evaluation (before compilation or inter-

pretation) by a syntax expander. The set of core forms

is implementation-dependent, as is the representation of

these forms in the expander’s output. If the expander en-

counters a syntactic abstraction, it invokes the associated

transformer to expand the syntactic abstraction, then re-

peats the expansion process for the form returned by the

transformer. If the expander encounters a core form, it re-

cursively processes its subforms that are in expression or

deﬁnition context, if any, and reconstructs the form from

the expanded subforms. Information about identiﬁer bind-

ings is maintained during expansion to enforce lexical scop-

ing for variables and keywords.

To handle deﬁnitions, the expander processes the initial

forms in a 'body` (see section 11.3) or 'library body` (see

section 7.1) from left to right. How the expander processes

each form encountered depends upon the kind of form.

macro use The expander invokes the associated trans-

former to transform the macro use, then recursively

performs whichever of these actions are appropriate

for the resulting form.

define-syntax form The expander expands and evalu-

ates the right-hand-side expression and binds the key-

word to the resulting transformer.

define form The expander records the fact that the de-

ﬁned identiﬁer is a variable but defers expansion of the

right-hand-side expression until after all of the deﬁni-

tions have been processed.

begin form The expander splices the subforms into the

list of body forms it is processing. (See section 11.4.7.)

let-syntax or letrec-syntax form The expander

splices the inner body forms into the list of (outer)

body forms it is processing, arranging for the key-

words bound by the let-syntax and letrec-syntax

to be visible only in the inner body forms.

30 Revised

6

Scheme

expression, i.e., nondeﬁnition The expander com-

pletes the expansion of the deferred right-hand-side

expressions and the current and remaining expressions

in the body, and then creates the equivalent of a

letrec* form from the deﬁned variables, expanded

right-hand-side expressions, and expanded body

expressions.

For the right-hand side of the deﬁnition of a variable, ex-

pansion is deferred until after all of the deﬁnitions have

been seen. Consequently, each keyword and variable refer-

ence within the right-hand side resolves to the local bind-

ing, if any.

A deﬁnition in the sequence of forms must not deﬁne any

identiﬁer whose binding is used to determine the meaning

of the undeferred portions of the deﬁnition or any deﬁnition

that precedes it in the sequence of forms. For example, the

bodies of the following expressions violate this restriction.

(let ()

(define define 17)

(list define))

(let-syntax ([def0 (syntax-rules ()

[( x) (define x 0)])])

(let ([z 3])

(def0 z)

(define def0 list)

(list z)))

(let ()

(define-syntax foo

(lambda (e)

(+ 1 2)))

(define + 2)

(foo))

The following do not violate the restriction.

(let ([x 5])

(define lambda list)

(lambda x x)) =⇒ (5 5)

(let-syntax ([def0 (syntax-rules ()

[( x) (define x 0)])])

(let ([z 3])

(define def0 list)

(def0 z)

(list z))) =⇒ (3)

(let ()

(define-syntax foo

(lambda (e)

(let ([+ -]) (+ 1 2))))

(define + 2)

(foo)) =⇒ -1

The implementation should treat a violation of the restric-

tion as a syntax violation.

Note that this algorithm does not directly reprocess any

form. It requires a single left-to-right pass over the deﬁni-

tions followed by a single pass (in any order) over the body

expressions and deferred right-hand sides.

Example:

(lambda (x)

(define-syntax defun

(syntax-rules ()

[( x a e) (define x (lambda a e))]))

(defun even? (n) (or (= n 0) (odd? (- n 1))))

(define-syntax odd?

(syntax-rules () [( n) (not (even? n))]))

(odd? (if (odd? x) (* x x) x)))

In the example, the deﬁnition of defun is encountered ﬁrst,

and the keyword defun is associated with the transformer

resulting from the expansion and evaluation of the corre-

sponding right-hand side. A use of defun is encountered

next and expands into a define form. Expansion of the

right-hand side of this deﬁne form is deferred. The deﬁni-

tion of odd? is next and results in the association of the

keyword odd? with the transformer resulting from expand-

ing and evaluating the corresponding right-hand side. A

use of odd? appears next and is expanded; the resulting

call to not is recognized as an expression because not is

bound as a variable. At this point, the expander completes

the expansion of the current expression (the call to not)

and the deferred right-hand side of the even? deﬁnition;

the uses of odd? appearing in these expressions are ex-

panded using the transformer associated with the keyword

odd?. The ﬁnal output is the equivalent of

(lambda (x)

(letrec* ([even?

(lambda (n)

(or (= n 0)

(not (even? (- n 1)))))])

(not (even? (if (not (even? x)) (* x x) x)))))

although the structure of the output is implementation-

dependent.

Because deﬁnitions and expressions can be interleaved in

a 'top-level body` (see chapter 8), the expander’s process-

ing of a 'top-level body` is somewhat more complicated. It

behaves as described above for a 'body` or 'library body`

with the following exceptions: When the expander ﬁnds a

nondeﬁnition, it defers its expansion and continues scan-

ning for deﬁnitions. Once it reaches the end of the set of

forms, it processes the deferred right-hand-side and body

expressions, then generates the equivalent of a letrec*

form from the deﬁned variables, expanded right-hand-side

expressions, and expanded body expressions. For each

body expression 'expression` that appears before a vari-

able deﬁnition in the body, a dummy binding is created

at the corresponding place within the set of letrec* bind-

ings, with a fresh temporary variable on the left-hand side

11. Base library 31

and the equivalent of (begin 'expression` 'unspeciﬁed`),

where 'unspeciﬁed` is a side-eﬀect-free expression return-

ing an unspeciﬁed value, on the right-hand side, so that

left-to-right evaluation order is preserved. The begin

wrapper allows 'expression` to evaluate to an arbitrary

number of values.

11. Base library

This chapter describes Scheme’s (rnrs base (6)) library,

which exports many of the procedure and syntax bindings

that are traditionally associated with Scheme.

Section 11.20 deﬁnes the rules that identify tail calls and

tail contexts in constructs from the (rnrs base (6)) li-

brary.

11.1. Base types

No object satisﬁes more than one of the following predi-

cates:

boolean? pair?

symbol? number?

char? string?

vector? procedure?

null?

These predicates deﬁne the base types boolean, pair, sym-

bol, number, char (or character), string, vector, and pro-

cedure. Moreover, the empty list is a special object of its

own type.

Note that, although there is a separate boolean type, any

Scheme value can be used as a boolean value for the pur-

pose of a conditional test; see section 5.7.

11.2. Deﬁnitions

Deﬁnitions may appear within a 'top-level body` (sec-

tion 8.1), at the top of a 'library body` (section 7.1), or

at the top of a 'body` (section 11.3).

A 'deﬁnition` may be a variable deﬁnition (section 11.2.1)

or keyword deﬁnition (section 11.2.1). Macro uses that ex-

pand into deﬁnitions or groups of deﬁnitions (packaged in

a begin, let-syntax, or letrec-syntax form; see sec-

tion 11.4.7) may also appear wherever other deﬁnitions

may appear.

11.2.1. Variable deﬁnitions

The define form described in this section is a 'deﬁnition`

used to create variable bindings and may appear anywhere

other deﬁnitions may appear.

(define 'variable` 'expression`) syntax

(define 'variable`) syntax

(define ('variable` 'formals`) 'body`) syntax

(define ('variable` . 'formal`) 'body`) syntax

The ﬁrst from of define binds 'variable` to a new location

before assigning the value of 'expression` to it.

(define add3

(lambda (x) (+ x 3)))

(add3 3) =⇒ 6

(define first car)

(first ’(1 2)) =⇒ 1

The continuation of 'expression` should not be invoked

more than once.

Implementation responsibilities: Implementations should

detect that the continuation of 'expression` is invoked more

than once. If the implementation detects this, it must raise

an exception with condition type &assertion.

The second form of define is equivalent to

(define 'variable) 'unspeciﬁed))

where 'unspeciﬁed` is a side-eﬀect-free expression return-

ing an unspeciﬁed value.

In the third form of define, 'formals` must be either a

sequence of zero or more variables, or a sequence of one

or more variables followed by a dot . and another variable

(as in a lambda expression, see section 11.4.2). This form

is equivalent to

(define 'variable)

(lambda ('formals)) 'body))).

In the fourth form of define, 'formal` must be a single

variable. This form is equivalent to

(define 'variable)

(lambda 'formal) 'body))).

11.2.2. Syntax deﬁnitions

The define-syntax form described in this section is a

'deﬁnition` used to create keyword bindings and may ap-

pear anywhere other deﬁnitions may appear.

(define-syntax 'keyword` 'expression`) syntax

Binds 'keyword` to the value of 'expression`, which

must evaluate, at macro-expansion time, to a trans-

former. Macro transformers can be created using the

syntax-rules and identifier-syntax forms described in

section 11.19. See library section 12.3 for a more complete

description of transformers.

Keyword bindings established by define-syntax are vis-

ible throughout the body in which they appear, except

where shadowed by other bindings, and nowhere else, just

like variable bindings established by define. All bind-

ings established by a set of deﬁnitions, whether keyword

32 Revised

6

Scheme

or variable deﬁnitions, are visible within the deﬁnitions

themselves.

Implementation responsibilities: The implementation

should detect if the value of 'expression` cannot possibly

be a transformer.

Example:

(let ()

(define even?

(lambda (x)

(or (= x 0) (odd? (- x 1)))))

(define-syntax odd?

(syntax-rules ()

((odd? x) (not (even? x)))))

(even? 10)) =⇒ #t

An implication of the left-to-right processing order (sec-

tion 10) is that one deﬁnition can aﬀect whether a subse-

quent form is also a deﬁnition.

Example:

(let ()

(define-syntax bind-to-zero

(syntax-rules ()

((bind-to-zero id) (define id 0))))

(bind-to-zero x)

x) =⇒ 0

The behavior is unaﬀected by any binding for

bind-to-zero that might appear outside of the let

expression.

11.3. Bodies

The 'body` of a lambda, let, let*, let-values,

let*-values, letrec, or letrec* expression, or that of

a deﬁnition with a body consists of zero or more deﬁni-

tions followed by one or more expressions.

'deﬁnition` ... 'expression

1

` 'expression

2

` ...

Each identiﬁer deﬁned by a deﬁnition is local to the 'body`.

That is, the identiﬁer is bound, and the region of the bind-

ing is the entire 'body` (see section 5.2).

Example:

(let ((x 5))

(define foo (lambda (y) (bar x y)))

(define bar (lambda (a b) (+ (* a b) a)))

(foo (+ x 3))) =⇒ 45

When begin, let-syntax, or letrec-syntax forms occur

in a body prior to the ﬁrst expression, they are spliced

into the body; see section 11.4.7. Some or all of the

body, including portions wrapped in begin, let-syntax,

or letrec-syntax forms, may be speciﬁed by a macro use

(see section 9.2).

An expanded 'body` (see chapter 10) containing variable

deﬁnitions can always be converted into an equivalent

letrec* expression. For example, the let expression in

the above example is equivalent to

(let ((x 5))

(letrec* ((foo (lambda (y) (bar x y)))

(bar (lambda (a b) (+ (* a b) a))))

(foo (+ x 3))))

11.4. Expressions

The entries in this section describe the expressions of the

(rnrs base (6)) library, which may occur in the position

of the 'expression` syntactic variable in addition to the

primitive expression types as described in section 9.1.

11.4.1. Quotation

(quote 'datum`) syntax

Syntax: 'Datum` should be a syntactic datum.

Semantics: (quote 'datum`) evaluates to the datum value

represented by 'datum` (see section 4.3). This notation is

used to include constants.

(quote a) =⇒ a

(quote #(a b c)) =⇒ #(a b c)

(quote (+ 1 2)) =⇒ (+ 1 2)

As noted in section 4.3.5, (quote 'datum`) may be abbre-

viated as ’'datum`:

’"abc" =⇒ "abc"

’145932 =⇒ 145932

’a =⇒ a

’#(a b c) =⇒ #(a b c)

’() =⇒ ()

’(+ 1 2) =⇒ (+ 1 2)

’(quote a) =⇒ (quote a)

’’a =⇒ (quote a)

As noted in section 5.10, constants are immutable.

Note: Diﬀerent constants that are the value of a quote expres-

sion may share the same locations.

11.4.2. Procedures

(lambda 'formals` 'body`) syntax

Syntax: 'Formals` must be a formal parameter list as de-

scribed below, and 'body` must be as described in sec-

tion 11.3.

Semantics: A lambda expression evaluates to a procedure.

The environment in eﬀect when the lambda expression is

evaluated is remembered as part of the procedure. When

the procedure is later called with some arguments, the en-

vironment in which the lambda expression was evaluated

11. Base library 33

is extended by binding the variables in the parameter list

to fresh locations, and the resulting argument values are

stored in those locations. Then, the expressions in the

body of the lambda expression (which may contain deﬁni-

tions and thus represent a letrec* form, see section 11.3)

are evaluated sequentially in the extended environment.

The results of the last expression in the body are returned

as the results of the procedure call.

(lambda (x) (+ x x)) =⇒ a procedure

((lambda (x) (+ x x)) 4) =⇒ 8

((lambda (x)

(define (p y)

(+ y 1))

(+ (p x) x))

5) =⇒ 11

(define reverse-subtract

(lambda (x y) (- y x)))

(reverse-subtract 7 10) =⇒ 3

(define add4

(let ((x 4))

(lambda (y) (+ x y))))

(add4 6) =⇒ 10

'Formals` must have one of the following forms:

• ('variable

1

` . . . ): The procedure takes a ﬁxed num-

ber of arguments; when the procedure is called, the ar-

guments are stored in the bindings of the correspond-

ing variables.

• 'variable`: The procedure takes any number of argu-

ments; when the procedure is called, the sequence of

arguments is converted into a newly allocated list, and

the list is stored in the binding of the 'variable`.

• ('variable

1

` . . . 'variable

n

` . 'variable

n+1

`): If a

period . precedes the last variable, then the procedure

takes n or more arguments, where n is the number of

parameters before the period (there must be at least

one). The value stored in the binding of the last vari-

able is a newly allocated list of the arguments left over

after all the other arguments have been matched up

against the other parameters.

((lambda x x) 3 4 5 6) =⇒ (3 4 5 6)

((lambda (x y . z) z)

3 4 5 6) =⇒ (5 6)

Any 'variable` must not appear more than once in

'formals`.

11.4.3. Conditionals

(if 'test` 'consequent` 'alternate`) syntax

(if 'test` 'consequent`) syntax

Syntax: 'Test`, 'consequent`, and 'alternate` must be ex-

pressions.

Semantics: An if expression is evaluated as follows: ﬁrst,

'test` is evaluated. If it yields a true value (see section 5.7),

then 'consequent` is evaluated and its values are returned.

Otherwise 'alternate` is evaluated and its values are re-

turned. If 'test` yields #f and no 'alternate` is speciﬁed,

then the result of the expression is unspeciﬁed.

(if (> 3 2) ’yes ’no) =⇒ yes

(if (> 2 3) ’yes ’no) =⇒ no

(if (> 3 2)

(- 3 2)

(+ 3 2)) =⇒ 1

(if #f #f) =⇒ unspeciﬁed

The 'consequent` and 'alternate` expressions are in tail

context if the if expression itself is; see section 11.20.

11.4.4. Assignments

(set! 'variable` 'expression`) syntax

'Expression` is evaluated, and the resulting value is stored

in the location to which 'variable` is bound. 'Variable`

must be bound either in some region enclosing the set!

expression or at the top level. The result of the set! ex-

pression is unspeciﬁed.

(let ((x 2))

(+ x 1)

(set! x 4)

(+ x 1)) =⇒ 5

It is a syntax violation if 'variable` refers to an immutable

binding.

Note: The identiﬁer set! is exported with level 1 as well. See

section 11.19.

11.4.5. Derived conditionals

(cond 'cond clause

1

` 'cond clause

2

` . . . ) syntax

=> auxiliary syntax

else auxiliary syntax

Syntax: Each 'cond clause` must be of the form

('test) 'expression1) . . . )

where 'test` is an expression. Alternatively, a

'cond clause` may be of the form

('test) => 'expression))

The last 'cond clause` may be an “else clause”, which has

the form

34 Revised

6

Scheme

(else 'expression1) 'expression2) . . . ).

Semantics: A cond expression is evaluated by evaluating

the 'test` expressions of successive 'cond clause`s in order

until one of them evaluates to a true value (see section 5.7).

When a 'test` evaluates to a true value, then the remaining

'expression`s in its 'cond clause` are evaluated in order,

and the results of the last 'expression` in the 'cond clause`

are returned as the results of the entire cond expression.

If the selected 'cond clause` contains only the 'test` and

no 'expression`s, then the value of the 'test` is returned

as the result. If the selected 'cond clause` uses the =>

alternate form, then the 'expression` is evaluated. Its value

must be a procedure. This procedure should accept one

argument; it is called on the value of the 'test` and the

values returned by this procedure are returned by the cond

expression. If all 'test`s evaluate to #f, and there is no else

clause, then the conditional expression returns unspeciﬁed

values; if there is an else clause, then its 'expression`s are

evaluated, and the values of the last one are returned.

(cond ((> 3 2) ’greater)

((< 3 2) ’less)) =⇒ greater

(cond ((> 3 3) ’greater)

((< 3 3) ’less)

(else ’equal)) =⇒ equal

(cond (’(1 2 3) => cadr)

(else #f)) =⇒ 2

For a 'cond clause` of one of the following forms

('test) 'expression1) . . . )

(else 'expression1) 'expression2) . . . )

the last 'expression` is in tail context if the cond form itself

is. For a 'cond clause` of the form

('test) => 'expression))

the (implied) call to the procedure that results from the

evaluation of 'expression` is in a tail context if the cond

form itself is. See section 11.20.

A sample deﬁnition of cond in terms of simpler forms is in

appendix B.

(case 'key` 'case clause

1

` 'case clause

2

` . . . ) syntax

Syntax: 'Key` must be an expression. Each 'case clause`

must have one of the following forms:

(('datum1) . . . ) 'expression1) 'expression2) . . . )

(else 'expression1) 'expression2) . . . )

The second form, which speciﬁes an “else clause”, may

only appear as the last 'case clause`. Each 'datum` is an

external representation of some object. The data repre-

sented by the 'datum`s need not be distinct.

Semantics: A case expression is evaluated as follows.

'Key` is evaluated and its result is compared using eqv?

(see section 11.5) against the data represented by the

'datum`s of each 'case clause` in turn, proceeding in or-

der from left to right through the set of clauses. If the

result of evaluating 'key` is equivalent to a datum of a

'case clause`, the corresponding 'expression`s are evalu-

ated from left to right and the results of the last expres-

sion in the 'case clause` are returned as the results of the

case expression. Otherwise, the comparison process con-

tinues. If the result of evaluating 'key` is diﬀerent from

every datum in each set, then if there is an else clause its

expressions are evaluated and the results of the last are the

results of the case expression; otherwise the case expres-

sion returns unspeciﬁed values.

(case (* 2 3)

((2 3 5 7) ’prime)

((1 4 6 8 9) ’composite)) =⇒ composite

(case (car ’(c d))

((a) ’a)

((b) ’b)) =⇒ unspeciﬁed

(case (car ’(c d))

((a e i o u) ’vowel)

((w y) ’semivowel)

(else ’consonant)) =⇒ consonant

The last 'expression` of a 'case clause` is in tail context if

the case expression itself is; see section 11.20.

(and 'test

1

` . . . ) syntax

Syntax: The 'test`s must be expressions.

Semantics: If there are no 'test`s, #t is returned. Other-

wise, the 'test` expressions are evaluated from left to right

until a 'test` returns #f or the last 'test` is reached. In the

former case, the and expression returns #f without evalu-

ating the remaining expressions. In the latter case, the last

expression is evaluated and its values are returned.

(and (= 2 2) (> 2 1)) =⇒ #t

(and (= 2 2) (< 2 1)) =⇒ #f

(and 1 2 ’c ’(f g)) =⇒ (f g)

(and) =⇒ #t

The and keyword could be deﬁned in terms of if using

syntax-rules (see section 11.19) as follows:

(define-syntax and

(syntax-rules ()

((and) #t)

((and test) test)

((and test1 test2 ...)

(if test1 (and test2 ...) #f))))

The last 'test` expression is in tail context if the and ex-

pression itself is; see section 11.20.

(or 'test

1

` . . . ) syntax

Syntax: The 'test`s must be expressions.

11. Base library 35

Semantics: If there are no 'test`s, #f is returned. Other-

wise, the 'test` expressions are evaluated from left to right

until a 'test` returns a true value val (see section 5.7) or the

last 'test` is reached. In the former case, the or expression

returns val without evaluating the remaining expressions.

In the latter case, the last expression is evaluated and its

values are returned.

(or (= 2 2) (> 2 1)) =⇒ #t

(or (= 2 2) (< 2 1)) =⇒ #t

(or #f #f #f) =⇒ #f

(or ’(b c) (/ 3 0)) =⇒ (b c)

The or keyword could be deﬁned in terms of if using

syntax-rules (see section 11.19) as follows:

(define-syntax or

(syntax-rules ()

((or) #f)

((or test) test)

((or test1 test2 ...)

(let ((x test1))

(if x x (or test2 ...))))))

The last 'test` expression is in tail context if the or expres-

sion itself is; see section 11.20.

11.4.6. Binding constructs

The binding constructs described in this section create lo-

cal bindings for variables that are visible only in a delimited

region. The syntax of the constructs let, let*, letrec,

and letrec* is identical, but they diﬀer in the regions (see

section 5.2) they establish for their variable bindings and

in the order in which the values for the bindings are com-

puted. In a let expression, the initial values are computed

before any of the variables become bound; in a let* expres-

sion, the bindings and evaluations are performed sequen-

tially. In a letrec or letrec* expression, all the bindings

are in eﬀect while their initial values are being computed,

thus allowing mutually recursive deﬁnitions. In a letrec

expression, the initial values are computed before being as-

signed to the variables; in a letrec*, the evaluations and

assignments are performed sequentially.

In addition, the binding constructs let-values and

let*-values generalize let and let* to allow multiple

variables to be bound to the results of expressions that

evaluate to multiple values. They are analogous to let and

let* in the way they establish regions: in a let-values

expression, the initial values are computed before any of

the variables become bound; in a let*-values expression,

the bindings are performed sequentially.

Sample deﬁnitions of all the binding forms of this section

in terms of simpler forms are in appendix B.

(let 'bindings` 'body`) syntax

Syntax: 'Bindings` must have the form

(('variable1) 'init1)) . . . ),

where each 'init` is an expression, and 'body` is as de-

scribed in section 11.3. Any variable must not appear more

than once in the 'variable`s.

Semantics: The 'init`s are evaluated in the current envi-

ronment (in some unspeciﬁed order), the 'variable`s are

bound to fresh locations holding the results, the 'body` is

evaluated in the extended environment, and the values of

the last expression of 'body` are returned. Each binding

of a 'variable` has 'body` as its region.

(let ((x 2) (y 3))

(* x y)) =⇒ 6

(let ((x 2) (y 3))

(let ((x 7)

(z (+ x y)))

(* z x))) =⇒ 35

See also named let, section 11.16.

(let* 'bindings` 'body`) syntax

Syntax: 'Bindings` must have the form

(('variable1) 'init1)) . . . ),

where each 'init` is an expression, and 'body` is as de-

scribed in section 11.3.

Semantics: The let* form is similar to let, but the 'init`s

are evaluated and bindings created sequentially from left to

right, with the region of each binding including the bind-

ings to its right as well as 'body`. Thus the second 'init`

is evaluated in an environment in which the ﬁrst binding

is visible and initialized, and so on.

(let ((x 2) (y 3))

(let* ((x 7)

(z (+ x y)))

(* z x))) =⇒ 70

Note: While the variables bound by a let expression must be

distinct, the variables bound by a let* expression need not be

distinct.

(letrec 'bindings` 'body`) syntax

Syntax: 'Bindings` must have the form

(('variable1) 'init1)) . . . ),

where each 'init` is an expression, and 'body` is as de-

scribed in section 11.3. Any variable must not appear more

than once in the 'variable`s.

Semantics: The 'variable`s are bound to fresh locations,

the 'init`s are evaluated in the resulting environment (in

some unspeciﬁed order), each 'variable` is assigned to the

result of the corresponding 'init`, the 'body` is evaluated in

the resulting environment, and the values of the last expres-

sion in 'body` are returned. Each binding of a 'variable`

has the entire letrec expression as its region, making it

possible to deﬁne mutually recursive procedures.

36 Revised

6

Scheme

(letrec ((even?

(lambda (n)

(if (zero? n)

#t

(odd? (- n 1)))))

(odd?

(lambda (n)

(if (zero? n)

#f

(even? (- n 1))))))

(even? 88))

=⇒ #t

It should be possible to evaluate each 'init` without as-

signing or referring to the value of any 'variable`. In the

most common uses of letrec, all the 'init`s are lambda

expressions and the restriction is satisﬁed automatically.

Another restriction is that the continuation of each 'init`

should not be invoked more than once.

Implementation responsibilities: Implementations must de-

tect references to a 'variable` during the evaluation of the

'init` expressions (using one particular evaluation order

and order of evaluating the 'init` expressions). If an im-

plementation detects such a violation of the restriction, it

must raise an exception with condition type &assertion.

Implementations may or may not detect that the continu-

ation of each 'init` is invoked more than once. However, if

the implementation detects this, it must raise an exception

with condition type &assertion.

(letrec* 'bindings` 'body`) syntax

Syntax: 'Bindings` must have the form

(('variable1) 'init1)) . . . ),

where each 'init` is an expression, and 'body` is as de-

scribed in section 11.3. Any variable must not appear more

than once in the 'variable`s.

Semantics: The 'variable`s are bound to fresh locations,

each 'variable` is assigned in left-to-right order to the re-

sult of evaluating the corresponding 'init`, the 'body` is

evaluated in the resulting environment, and the values of

the last expression in 'body` are returned. Despite the left-

to-right evaluation and assignment order, each binding of a

'variable` has the entire letrec* expression as its region,

making it possible to deﬁne mutually recursive procedures.

(letrec* ((p

(lambda (x)

(+ 1 (q (- x 1)))))

(q

(lambda (y)

(if (zero? y)

0

(+ 1 (p (- y 1))))))

(x (p 5))

(y x))

y)

=⇒ 5

It must be possible to evaluate each 'init` without assigning

or referring to the value of the corresponding 'variable`

or the 'variable` of any of the bindings that follow it in

'bindings`. Another restriction is that the continuation of

each 'init` should not be invoked more than once.

Implementation responsibilities: Implementations must,

during the evaluation of an 'init` expression, detect ref-

erences to the value of the corresponding 'variable` or the

'variable` of any of the bindings that follow it in 'bindings`.

If an implementation detects such a violation of the re-

striction, it must raise an exception with condition type

&assertion. Implementations may or may not detect that

the continuation of each 'init` is invoked more than once.

However, if the implementation detects this, it must raise

an exception with condition type &assertion.

(let-values 'mv-bindings` 'body`) syntax

Syntax: 'Mv-bindings` must have the form

(('formals1) 'init1)) . . . ),

where each 'init` is an expression, and 'body` is as de-

scribed in section 11.3. Any variable must not appear more

than once in the set of 'formals`.

Semantics: The 'init`s are evaluated in the current en-

vironment (in some unspeciﬁed order), and the variables

occurring in the 'formals` are bound to fresh locations

containing the values returned by the 'init`s, where the

'formals` are matched to the return values in the same

way that the 'formals` in a lambda expression are matched

to the arguments in a procedure call. Then, the 'body` is

evaluated in the extended environment, and the values of

the last expression of 'body` are returned. Each binding

of a variable has 'body` as its region. If the 'formals` do

not match, an exception with condition type &assertion

is raised.

(let-values (((a b) (values 1 2))

((c d) (values 3 4)))

(list a b c d)) =⇒ (1 2 3 4)

(let-values (((a b . c) (values 1 2 3 4)))

(list a b c)) =⇒ (1 2 (3 4))

(let ((a ’a) (b ’b) (x ’x) (y ’y))

(let-values (((a b) (values x y))

((x y) (values a b)))

(list a b x y))) =⇒ (x y a b)

(let*-values 'mv-bindings` 'body`) syntax

Syntax: 'Mv-bindings` must have the form

(('formals1) 'init1)) . . . ),

11. Base library 37

where each 'init` is an expression, and 'body` is as de-

scribed in section 11.3. In each 'formals`, any variable

must not appear more than once.

Semantics: The let*-values form is similar to

let-values, but the 'init`s are evaluated and bindings

created sequentially from left to right, with the region of

the bindings of each 'formals` including the bindings to its

right as well as 'body`. Thus the second 'init` is evalu-

ated in an environment in which the bindings of the ﬁrst

'formals` is visible and initialized, and so on.

(let ((a ’a) (b ’b) (x ’x) (y ’y))

(let*-values (((a b) (values x y))

((x y) (values a b)))

(list a b x y))) =⇒ (x y x y)

Note: While all of the variables bound by a let-values expres-

sion must be distinct, the variables bound by diﬀerent 'formals)

of a let*-values expression need not be distinct.

11.4.7. Sequencing

(begin 'form` . . . ) syntax

(begin 'expression` 'expression` . . . ) syntax

The 'begin` keyword has two diﬀerent roles, depending on

its context:

• It may appear as a form in a 'body` (see section 11.3),

'library body` (see section 7.1), or 'top-level body`

(see chapter 8), or directly nested in a begin form that

appears in a body. In this case, the begin form must

have the shape speciﬁed in the ﬁrst header line. This

use of begin acts as a splicing form—the forms inside

the 'body` are spliced into the surrounding body, as

if the begin wrapper were not actually present.

A begin form in a 'body` or 'library body` must be

non-empty if it appears after the ﬁrst 'expression`

within the body.

• It may appear as an ordinary expression and must

have the shape speciﬁed in the second header line.

In this case, the 'expression`s are evaluated sequen-

tially from left to right, and the values of the last

'expression` are returned. This expression type is used

to sequence side eﬀects such as assignments or input

and output.

(define x 0)

(begin (set! x 5)

(+ x 1)) =⇒ 6

(begin (display "4 plus 1 equals ")

(display (+ 4 1))) =⇒ unspeciﬁed

and prints 4 plus 1 equals 5

11.5. Equivalence predicates

A predicate is a procedure that always returns a boolean

value (#t or #f). An equivalence predicate is the compu-

tational analogue of a mathematical equivalence relation

(it is symmetric, reﬂexive, and transitive). Of the equiva-

lence predicates described in this section, eq? is the ﬁnest

or most discriminating, and equal? is the coarsest. The

eqv? predicate is slightly less discriminating than eq?.

(eqv? obj

1

obj

2

) procedure

The eqv? procedure deﬁnes a useful equivalence relation

on objects. Brieﬂy, it returns #t if obj

1

and obj

2

should

normally be regarded as the same object and #f otherwise.

This relation is left slightly open to interpretation, but the

following partial speciﬁcation of eqv? must hold for all im-

plementations.

The eqv? procedure returns #t if one of the following holds:

• Obj

1

and obj

2

are both booleans and are the same

according to the boolean=? procedure (section 11.8).

• Obj

1

and obj

2

are both symbols and are the same ac-

cording to the symbol=? procedure (section 11.10).

• Obj

1

and obj

2

are both exact number objects and are

numerically equal (see =, section 11.7).

• Obj

1

and obj

2

are both inexact number objects, are

numerically equal (see =, section 11.7), and yield the

same results (in the sense of eqv?) when passed as ar-

guments to any other procedure that can be deﬁned as

a ﬁnite composition of Scheme’s standard arithmetic

procedures.

• Obj

1

and obj

2

are both characters and are the same

character according to the char=? procedure (sec-

tion 11.11).

• Both obj

1

and obj

2

are the empty list.

• Obj

1

and obj

2

are objects such as pairs, vectors,

bytevectors (library chapter 2), strings, hashtables,

records (library chapter 6), ports (library section 8.2),

or hashtables (library chapter 13) that refer to the

same locations in the store (section 5.10).

• Obj

1

and obj

2

are record-type descriptors that are

speciﬁed to be eqv? in library section 6.3.

The eqv? procedure returns #f if one of the following holds:

• Obj

1

and obj

2

are of diﬀerent types (section 11.1).

• Obj

1

and obj

2

are booleans for which the boolean=?

procedure returns #f.

38 Revised

6

Scheme

• Obj

1

and obj

2

are symbols for which the symbol=?

procedure returns #f.

• One of obj

1

and obj

2

is an exact number object but

the other is an inexact number object.

• Obj

1

and obj

2

are rational number objects for which

the = procedure returns #f.

• Obj

1

and obj

2

yield diﬀerent results (in the sense of

eqv?) when passed as arguments to any other proce-

dure that can be deﬁned as a ﬁnite composition of

Scheme’s standard arithmetic procedures.

• Obj

1

and obj

2

are characters for which the char=? pro-

cedure returns #f.

• One of obj

1

and obj

2

is the empty list, but the other

is not.

• Obj

1

and obj

2

are objects such as pairs, vectors,

bytevectors (library chapter 2), strings, records (li-

brary chapter 6), ports (library section 8.2), or hashta-

bles (library chapter 13) that refer to distinct loca-

tions.

• Obj

1

and obj

2

are pairs, vectors, strings, or records,

or hashtables, where the applying the same accessor

(i.e. car, cdr, vector-ref, string-ref, or record ac-

cessors) to both yields results for which eqv? returns

#f.

• Obj

1

and obj

2

are procedures that would behave dif-

ferently (return diﬀerent values or have diﬀerent side

eﬀects) for some arguments.

Note: The eqv? procedure returning #t when obj1 and obj2

are number objects does not imply that = would also return #t

when called with obj1 and obj2 as arguments.

(eqv? ’a ’a) =⇒ #t

(eqv? ’a ’b) =⇒ #f

(eqv? 2 2) =⇒ #t

(eqv? ’() ’()) =⇒ #t

(eqv? 100000000 100000000) =⇒ #t

(eqv? (cons 1 2) (cons 1 2))=⇒ #f

(eqv? (lambda () 1)

(lambda () 2)) =⇒ #f

(eqv? #f ’nil) =⇒ #f

The following examples illustrate cases in which the above

rules do not fully specify the behavior of eqv?. All that

can be said about such cases is that the value returned by

eqv? must be a boolean.

(let ((p (lambda (x) x)))

(eqv? p p)) =⇒ unspeciﬁed

(eqv? "" "") =⇒ unspeciﬁed

(eqv? ’#() ’#()) =⇒ unspeciﬁed

(eqv? (lambda (x) x)

(lambda (x) x)) =⇒ unspeciﬁed

(eqv? (lambda (x) x)

(lambda (y) y)) =⇒ unspeciﬁed

(eqv? +nan.0 +nan.0) =⇒ unspeciﬁed

The next set of examples shows the use of eqv? with proce-

dures that have local state. Calls to gen-counter must re-

turn a distinct procedure every time, since each procedure

has its own internal counter. Calls to gen-loser return

procedures that behave equivalently when called. How-

ever, eqv? may not detect this equivalence.

(define gen-counter

(lambda ()

(let ((n 0))

(lambda () (set! n (+ n 1)) n))))

(let ((g (gen-counter)))

(eqv? g g)) =⇒ unspeciﬁed

(eqv? (gen-counter) (gen-counter))

=⇒ #f

(define gen-loser

(lambda ()

(let ((n 0))

(lambda () (set! n (+ n 1)) 27))))

(let ((g (gen-loser)))

(eqv? g g)) =⇒ unspeciﬁed

(eqv? (gen-loser) (gen-loser))

=⇒ unspeciﬁed

(letrec ((f (lambda () (if (eqv? f g) ’both ’f)))

(g (lambda () (if (eqv? f g) ’both ’g))))

(eqv? f g)) =⇒ unspeciﬁed

(letrec ((f (lambda () (if (eqv? f g) ’f ’both)))

(g (lambda () (if (eqv? f g) ’g ’both))))

(eqv? f g)) =⇒ #f

Implementations may share structure between constants

where appropriate. Furthermore, a constant may be copied

at any time by the implementation so as to exist simul-

taneously in diﬀerent sets of locations, as noted in sec-

tion 11.4.1. Thus the value of eqv? on constants is some-

times implementation-dependent.

(eqv? ’(a) ’(a)) =⇒ unspeciﬁed

(eqv? "a" "a") =⇒ unspeciﬁed

(eqv? ’(b) (cdr ’(a b))) =⇒ unspeciﬁed

(let ((x ’(a)))

(eqv? x x)) =⇒ #t

(eq? obj

1

obj

2

) procedure

The eq? predicate is similar to eqv? except that in some

cases it is capable of discerning distinctions ﬁner than those

detectable by eqv?.

The eq? and eqv? predicates are guaranteed to have the

same behavior on symbols, booleans, the empty list, pairs,

procedures, non-empty strings, bytevectors, and vectors,

and records. The behavior of eq? on number objects and

11. Base library 39

characters is implementation-dependent, but it always re-

turns either #t or #f, and returns #t only when eqv? would

also return #t. The eq? predicate may also behave diﬀer-

ently from eqv? on empty vectors, empty bytevectors, and

empty strings.

(eq? ’a ’a) =⇒ #t

(eq? ’(a) ’(a)) =⇒ unspeciﬁed

(eq? (list ’a) (list ’a)) =⇒ #f

(eq? "a" "a") =⇒ unspeciﬁed

(eq? "" "") =⇒ unspeciﬁed

(eq? ’() ’()) =⇒ #t

(eq? 2 2) =⇒ unspeciﬁed

(eq? #\A #\A) =⇒ unspeciﬁed

(eq? car car) =⇒ #t

(let ((n (+ 2 3)))

(eq? n n)) =⇒ unspeciﬁed

(let ((x ’(a)))

(eq? x x)) =⇒ #t

(let ((x ’#()))

(eq? x x)) =⇒ unspeciﬁed

(let ((p (lambda (x) x)))

(eq? p p)) =⇒ unspeciﬁed

(equal? obj

1

obj

2

) procedure

The equal? predicate returns #t if and only if the (possibly

inﬁnite) unfoldings of its arguments into regular trees are

equal as ordered trees.

The equal? predicate treats pairs and vectors as nodes

with outgoing edges, uses string=? to compare strings,

uses bytevector=? to compare bytevectors (see library

chapter 2), and uses eqv? to compare other nodes.

(equal? ’a ’a) =⇒ #t

(equal? ’(a) ’(a)) =⇒ #t

(equal? ’(a (b) c)

’(a (b) c)) =⇒ #t

(equal? "abc" "abc") =⇒ #t

(equal? 2 2) =⇒ #t

(equal? (make-vector 5 ’a)

(make-vector 5 ’a)) =⇒ #t

(equal? ’#vu8(1 2 3 4 5)

(u8-list->bytevector

’(1 2 3 4 5)) =⇒ #t

(equal? (lambda (x) x)

(lambda (y) y)) =⇒ unspeciﬁed

(let* ((x (list ’a))

(y (list ’a))

(z (list x y)))

(list (equal? z (list y x))

(equal? z (list x x))))

=⇒ (#t #t)

Note: The equal? procedure must always terminate, even if

its arguments contain cycles.

11.6. Procedure predicate

(procedure? obj ) procedure

Returns #t if obj is a procedure, otherwise returns #f.

(procedure? car) =⇒ #t

(procedure? ’car) =⇒ #f

(procedure? (lambda (x) (* x x)))

=⇒ #t

(procedure? ’(lambda (x) (* x x)))

=⇒ #f

11.7. Arithmetic

The procedures described here implement arithmetic that

is generic over the numerical tower described in chapter 3.

The generic procedures described in this section accept

both exact and inexact number objects as arguments, per-

forming coercions and selecting the appropriate operations

as determined by the numeric subtypes of their arguments.

Library chapter 11 describes libraries that deﬁne other nu-

merical procedures.

11.7.1. Propagation of exactness and inexactness

The procedures listed below must return the mathemati-

cally correct exact result provided all their arguments are

exact:

+ - *

max min abs

numerator denominator gcd

lcm floor ceiling

truncate round rationalize

real-part imag-part make-rectangular

The procedures listed below must return the correct ex-

act result provided all their arguments are exact, and no

divisors are zero:

/

div mod div-and-mod

div0 mod0 div0-and-mod0

Moreover, the procedure expt must return the correct ex-

act result provided its ﬁrst argument is an exact real num-

ber object and its second argument is an exact integer ob-

ject.

The general rule is that the generic operations return the

correct exact result when all of their arguments are exact

and the result is mathematically well-deﬁned, but return an

inexact result when any argument is inexact. Exceptions to

this rule include sqrt, exp, log, sin, cos, tan, asin, acos,

atan, expt, make-polar, magnitude, and angle, which

may (but are not required to) return inexact results even

40 Revised

6

Scheme

when given exact arguments, as indicated in the speciﬁca-

tion of these procedures.

One general exception to the rule above is that an im-

plementation may return an exact result despite inexact

arguments if that exact result would be the correct result

for all possible substitutions of exact arguments for the in-

exact ones. An example is (* 1.0 0) which may return

either 0 (exact) or 0.0 (inexact).

11.7.2. Representability of inﬁnities and NaNs

The speciﬁcation of the numerical operations is written as

though inﬁnities and NaNs are representable, and speci-

ﬁes many operations with respect to these number objects

in ways that are consistent with the IEEE-754 standard

for binary ﬂoating-point arithmetic. An implementation

of Scheme may or may not represent inﬁnities and NaNs;

however, an implementation must raise a continuable ex-

ception with condition type &no-infinities or &no-nans

(respectively; see library section 11.3) whenever it is un-

able to represent an inﬁnity or NaN as speciﬁed. In this

case, the continuation of the exception handler is the con-

tinuation that otherwise would have received the inﬁnity

or NaN value. This requirement also applies to conversions

between number objects and external representations, in-

cluding the reading of program source code.

11.7.3. Semantics of common operations

Some operations are the semantic basis for several arith-

metic procedures. The behavior of these operations is de-

scribed in this section for later reference.

Integer division

Scheme’s operations for performing integer division rely on

mathematical operations div, mod, div

0

, and mod

0

, that

are deﬁned as follows:

div, mod, div

0

, and mod

0

each accept two real numbers x

1

and x

2

as operands, where x

2

must be nonzero.

div returns an integer, and mod returns a real. Their re-

sults are speciﬁed by

x

1

div x

2

= n

d

x

1

mod x

2

= x

m

where

x

1

= n

d

x

2

+x

m

0 ≤ x

m

< [x

2

[

Examples:

123 div 10 = 12

123 mod 10 = 3

123 div −10 = −12

123 mod −10 = 3

−123 div 10 = −13

−123 mod 10 = 7

−123 div −10 = 13

−123 mod −10 = 7

div

0

and mod

0

are like div and mod, except the result of

mod

0

lies within a half-open interval centered on zero. The

results are speciﬁed by

x

1

div

0

x

2

= n

d

x

1

mod

0

x

2

= x

m

where:

x

1

= n

d

x

2

+x

m

−[

x2

2

[ ≤ x

m

< [

x2

2

[

Examples:

123 div

0

10 = 12

123 mod

0

10 = 3

123 div

0

−10 = −12

123 mod

0

−10 = 3

−123 div

0

10 = −12

−123 mod

0

10 = −3

−123 div

0

−10 = 12

−123 mod

0

−10 = −3

Transcendental functions

In general, the transcendental functions log, sin

−1

(arc-

sine), cos

−1

(arccosine), and tan

−1

are multiply deﬁned.

The value of log z is deﬁned to be the one whose imagi-

nary part lies in the range from −π (inclusive if −0.0 is

distinguished, exclusive otherwise) to π (inclusive). log 0

is undeﬁned.

The value of log z for non-real z is deﬁned in terms of log

on real numbers as

log z = log [z[ + (angle z)i

where angle z is the angle of z = a e

ib

speciﬁed as:

angle z = b + 2πn

with −π ≤ angle z ≤ π and angle z = b + 2πn for some

integer n.

With the one-argument version of log deﬁned this way, the

values of the two-argument-version of log, sin

−1

z, cos

−1

z,

11. Base library 41

tan

−1

z, and the two-argument version of tan

−1

are accord-

ing to the following formulæ:

log z b =

log z

log b

sin

−1

z = −i log(iz +

1 −z

2

)

cos

−1

z = π/2 −sin

−1

z

tan

−1

z = (log(1 +iz) −log(1 −iz))/(2i)

tan

−1

x y = angle(x +yi)

The range of tan

−1

x y is as in the following table. The

asterisk (*) indicates that the entry applies to implemen-

tations that distinguish minus zero.

y condition x condition range of result r

y = 0.0 x > 0.0 0.0

∗ y = +0.0 x > 0.0 +0.0

∗ y = −0.0 x > 0.0 −0.0

y > 0.0 x > 0.0 0.0 < r <

π

2

y > 0.0 x = 0.0

π

2

y > 0.0 x < 0.0

π

2

< r < π

y = 0.0 x < 0 π

∗ y = +0.0 x < 0.0 π

∗ y = −0.0 x < 0.0 −π

y < 0.0 x < 0.0 −π < r < −

π

2

y < 0.0 x = 0.0 −

π

2

y < 0.0 x > 0.0 −

π

2

< r < 0.0

y = 0.0 x = 0.0 undeﬁned

∗ y = +0.0 x = +0.0 +0.0

∗ y = −0.0 x = +0.0 −0.0

∗ y = +0.0 x = −0.0 π

∗ y = −0.0 x = −0.0 −π

∗ y = +0.0 x = 0

π

2

∗ y = −0.0 x = 0 −

π

2

11.7.4. Numerical operations

Numerical type predicates

(number? obj ) procedure

(complex? obj ) procedure

(real? obj ) procedure

(rational? obj ) procedure

(integer? obj ) procedure

These numerical type predicates can be applied to any kind

of argument. They return #t if the object is a number ob-

ject of the named type, and #f otherwise. In general, if a

type predicate is true of a number object then all higher

type predicates are also true of that number object. Con-

sequently, if a type predicate is false of a number object,

then all lower type predicates are also false of that number

object.

If z is a complex number object, then (real? z ) is

true if and only if (zero? (imag-part z )) and (exact?

(imag-part z )) are both true.

If x is a real number object, then (rational? x) is true

if and only if there exist exact integer objects k

1

and k

2

such that (= x (/ k

1

k

2

)) and (= (numerator x) k

1

)

and (= (denominator x) k

2

) are all true. Thus inﬁnities

and NaNs are not rational number objects.

If q is a rational number objects, then (integer? q) is

true if and only if (= (denominator q) 1) is true. If q is

not a rational number object, then (integer? q) is #f.

(complex? 3+4i) =⇒ #t

(complex? 3) =⇒ #t

(real? 3) =⇒ #t

(real? -2.5+0.0i) =⇒ #f

(real? -2.5+0i) =⇒ #t

(real? -2.5) =⇒ #t

(real? #e1e10) =⇒ #t

(rational? 6/10) =⇒ #t

(rational? 6/3) =⇒ #t

(rational? 2) =⇒ #t

(integer? 3+0i) =⇒ #t

(integer? 3.0) =⇒ #t

(integer? 8/4) =⇒ #t

(number? +nan.0) =⇒ #t

(complex? +nan.0) =⇒ #t

(real? +nan.0) =⇒ #t

(rational? +nan.0) =⇒ #f

(complex? +inf.0) =⇒ #t

(real? -inf.0) =⇒ #t

(rational? -inf.0) =⇒ #f

(integer? -inf.0) =⇒ #f

Note: Except for number?, the behavior of these type predi-

cates on inexact number objects is unreliable, because any in-

accuracy may aﬀect the result.

(real-valued? obj ) procedure

(rational-valued? obj ) procedure

(integer-valued? obj ) procedure

These numerical type predicates can be applied to any kind

of argument. The real-valued? procedure returns #t if

the object is a number object and is equal in the sense of

= to some real number object, or if the object is a NaN,

or a complex number object whose real part is a NaN and

whose imaginary part is zero in the sense of zero?. The

rational-valued? and integer-valued? procedures re-

turn #t if the object is a number object and is equal in the

sense of = to some object of the named type, and otherwise

they return #f.

(real-valued? +nan.0) =⇒ #t

(real-valued? +nan.0+0i) =⇒ #t

(real-valued? -inf.0) =⇒ #t

(real-valued? 3) =⇒ #t

42 Revised

6

Scheme

(real-valued? -2.5+0.0i) =⇒ #t

(real-valued? -2.5+0i) =⇒ #t

(real-valued? -2.5) =⇒ #t

(real-valued? #e1e10) =⇒ #t

(rational-valued? +nan.0) =⇒ #f

(rational-valued? -inf.0) =⇒ #f

(rational-valued? 6/10) =⇒ #t

(rational-valued? 6/10+0.0i)=⇒ #t

(rational-valued? 6/10+0i) =⇒ #t

(rational-valued? 6/3) =⇒ #t

(integer-valued? 3+0i) =⇒ #t

(integer-valued? 3+0.0i) =⇒ #t

(integer-valued? 3.0) =⇒ #t

(integer-valued? 3.0+0.0i) =⇒ #t

(integer-valued? 8/4) =⇒ #t

Note: These procedures test whether a given number object

can be coerced to the speciﬁed type without loss of numerical

accuracy. Speciﬁcally, the behavior of these predicates diﬀers

from the behavior of real?, rational?, and integer? on com-

plex number objects whose imaginary part is inexact zero.

Note: The behavior of these type predicates on inexact number

objects is unreliable, because any inaccuracy may aﬀect the

result.

(exact? z ) procedure

(inexact? z ) procedure

These numerical predicates provide tests for the exactness

of a quantity. For any number object, precisely one of these

predicates is true.

(exact? 5) =⇒ #t

(inexact? +inf.0) =⇒ #t

Generic conversions

(inexact z ) procedure

(exact z ) procedure

The inexact procedure returns an inexact representation

of z . If inexact number objects of the appropriate type have

bounded precision, then the value returned is an inexact

number object that is nearest to the argument. If an exact

argument has no reasonably close inexact equivalent, an ex-

ception with condition type &implementation-violation

may be raised.

Note: For a real number object whose magnitude is ﬁnite but

so large that it has no reasonable ﬁnite approximation as an

inexact number, a reasonably close inexact equivalent may be

+inf.0 or -inf.0. Similarly, the inexact representation of a

complex number object whose components are ﬁnite may have

inﬁnite components.

The exact procedure returns an exact representation of

z . The value returned is the exact number object that is

numerically closest to the argument; in most cases, the

result of this procedure should be numerically equal to

its argument. If an inexact argument has no reasonably

close exact equivalent, an exception with condition type

&implementation-violation may be raised.

These procedures implement the natural one-to-one cor-

respondence between exact and inexact integer objects

throughout an implementation-dependent range.

The inexact and exact procedures are idempotent.

Arithmetic operations

(= z

1

z

2

z

3

. . . ) procedure

(< x

1

x

2

x

3

. . . ) procedure

(> x

1

x

2

x

3

. . . ) procedure

(<= x

1

x

2

x

3

. . . ) procedure

(>= x

1

x

2

x

3

. . . ) procedure

These procedures return #t if their arguments are (respec-

tively): equal, monotonically increasing, monotonically de-

creasing, monotonically nondecreasing, or monotonically

nonincreasing, and #f otherwise.

(= +inf.0 +inf.0) =⇒ #t

(= -inf.0 +inf.0) =⇒ #f

(= -inf.0 -inf.0) =⇒ #t

For any real number object x that is neither inﬁnite nor

NaN:

(< -inf.0 x +inf.0)) =⇒ #t

(> +inf.0 x -inf.0)) =⇒ #t

For any number object z :

(= +nan.0 z) =⇒ #f

For any real number object x:

(< +nan.0 x) =⇒ #f

(> +nan.0 x) =⇒ #f

These predicates must be transitive.

Note: The traditional implementations of these predicates in

Lisp-like languages are not transitive.

Note: While it is possible to compare inexact number objects

using these predicates, the results may be unreliable because a

small inaccuracy may aﬀect the result; this is especially true of

= and zero? (below).

When in doubt, consult a numerical analyst.

(zero? z ) procedure

(positive? x) procedure

(negative? x) procedure

(odd? n) procedure

11. Base library 43

(even? n) procedure

(finite? x) procedure

(infinite? x) procedure

(nan? x) procedure

These numerical predicates test a number object for a par-

ticular property, returning #t or #f. The zero? procedure

tests if the number object is = to zero, positive? tests

whether it is greater than zero, negative? tests whether

it is less than zero, odd? tests whether it is odd, even?

tests whether it is even, finite? tests whether it is not an

inﬁnity and not a NaN, infinite? tests whether it is an

inﬁnity, nan? tests whether it is a NaN.

(zero? +0.0) =⇒ #t

(zero? -0.0) =⇒ #t

(zero? +nan.0) =⇒ #f

(positive? +inf.0) =⇒ #t

(negative? -inf.0) =⇒ #t

(positive? +nan.0) =⇒ #f

(negative? +nan.0) =⇒ #f

(finite? +inf.0) =⇒ #f

(finite? 5) =⇒ #t

(finite? 5.0) =⇒ #t

(infinite? 5.0) =⇒ #f

(infinite? +inf.0) =⇒ #t

Note: As with the predicates above, the results may be unre-

liable because a small inaccuracy may aﬀect the result.

(max x

1

x

2

. . . ) procedure

(min x

1

x

2

. . . ) procedure

These procedures return the maximum or minimum of their

arguments.

(max 3 4) =⇒ 4

(max 3.9 4) =⇒ 4.0

For any real number object x:

(max +inf.0 x) =⇒ +inf.0

(min -inf.0 x) =⇒ -inf.0

Note: If any argument is inexact, then the result is also inexact

(unless the procedure can prove that the inaccuracy is not large

enough to aﬀect the result, which is possible only in unusual

implementations). If min or max is used to compare number

objects of mixed exactness, and the numerical value of the result

cannot be represented as an inexact number object without loss

of accuracy, then the procedure may raise an exception with

condition type &implementation-restriction.

(+ z

1

. . . ) procedure

(* z

1

. . . ) procedure

These procedures return the sum or product of their argu-

ments.

(+ 3 4) =⇒ 7

(+ 3) =⇒ 3

(+) =⇒ 0

(+ +inf.0 +inf.0) =⇒ +inf.0

(+ +inf.0 -inf.0) =⇒ +nan.0

(* 4) =⇒ 4

(*) =⇒ 1

(* 5 +inf.0) =⇒ +inf.0

(* -5 +inf.0) =⇒ -inf.0

(* +inf.0 +inf.0) =⇒ +inf.0

(* +inf.0 -inf.0) =⇒ -inf.0

(* 0 +inf.0) =⇒ 0 or +nan.0

(* 0 +nan.0) =⇒ 0 or +nan.0

(* 1.0 0) =⇒ 0 or 0.0

For any real number object x that is neither inﬁnite nor

NaN:

(+ +inf.0 x) =⇒ +inf.0

(+ -inf.0 x) =⇒ -inf.0

For any real number object x:

(+ +nan.0 x) =⇒ +nan.0

For any real number object x that is not an exact 0:

(* +nan.0 x) =⇒ +nan.0

If any of these procedures are applied to mixed

non-rational real and non-real complex arguments,

they either raise an exception with condition type

&implementation-restriction or return an unspeciﬁed

number object.

Implementations that distinguish −0.0 should adopt be-

havior consistent with the following examples:

(+ 0.0 -0.0) =⇒ 0.0

(+ -0.0 0.0) =⇒ 0.0

(+ 0.0 0.0) =⇒ 0.0

(+ -0.0 -0.0) =⇒ -0.0

(- z ) procedure

(- z

1

z

2

. . . ) procedure

With two or more arguments, this procedures returns the

diﬀerence of its arguments, associating to the left. With

one argument, however, it returns the additive inverse of

its argument.

(- 3 4) =⇒ -1

(- 3 4 5) =⇒ -6

(- 3) =⇒ -3

(- +inf.0 +inf.0) =⇒ +nan.0

If this procedure is applied to mixed non-rational real and

non-real complex arguments, it either raises an exception

with condition type &implementation-restriction or re-

turns an unspeciﬁed number object.

Implementations that distinguish −0.0 should adopt be-

havior consistent with the following examples:

44 Revised

6

Scheme

(- 0.0) =⇒ -0.0

(- -0.0) =⇒ 0.0

(- 0.0 -0.0) =⇒ 0.0

(- -0.0 0.0) =⇒ -0.0

(- 0.0 0.0) =⇒ 0.0

(- -0.0 -0.0) =⇒ 0.0

(/ z ) procedure

(/ z

1

z

2

. . . ) procedure

If all of the arguments are exact, then the divisors must

all be nonzero. With two or more arguments, this pro-

cedure returns the quotient of its arguments, associating

to the left. With one argument, however, it returns the

multiplicative inverse of its argument.

(/ 3 4 5) =⇒ 3/20

(/ 3) =⇒ 1/3

(/ 0.0) =⇒ +inf.0

(/ 1.0 0) =⇒ +inf.0

(/ -1 0.0) =⇒ -inf.0

(/ +inf.0) =⇒ 0.0

(/ 0 0) =⇒ &assertion exception

(/ 3 0) =⇒ &assertion exception

(/ 0 3.5) =⇒ 0.0

(/ 0 0.0) =⇒ +nan.0

(/ 0.0 0) =⇒ +nan.0

(/ 0.0 0.0) =⇒ +nan.0

If this procedure is applied to mixed non-rational real and

non-real complex arguments, it either raises an exception

with condition type &implementation-restriction or re-

turns an unspeciﬁed number object.

(abs x) procedure

Returns the absolute value of its argument.

(abs -7) =⇒ 7

(abs -inf.0) =⇒ +inf.0

(div-and-mod x

1

x

2

) procedure

(div x

1

x

2

) procedure

(mod x

1

x

2

) procedure

(div0-and-mod0 x

1

x

2

) procedure

(div0 x

1

x

2

) procedure

(mod0 x

1

x

2

) procedure

These procedures implement number-theoretic integer divi-

sion and return the results of the corresponding mathemat-

ical operations speciﬁed in section 11.7.3. In each case, x

1

must be neither inﬁnite nor a NaN, and x

2

must be nonzero;

otherwise, an exception with condition type &assertion is

raised.

(div x1 x2) =⇒ x1 div x2

(mod x1 x2) =⇒ x1 mod x2

(div-and-mod x1 x2) =⇒ x1 div x2, x1 mod x2

; two return values

(div0 x1 x2) =⇒ x1 div0 x2

(mod0 x1 x2) =⇒ x1 mod0 x2

(div0-and-mod0 x1 x2)

=⇒ x1 div0 x2, x1 mod0 x2

; two return values

(gcd n

1

. . . ) procedure

(lcm n

1

. . . ) procedure

These procedures return the greatest common divisor or

least common multiple of their arguments. The result is

always non-negative.

(gcd 32 -36) =⇒ 4

(gcd) =⇒ 0

(lcm 32 -36) =⇒ 288

(lcm 32.0 -36) =⇒ 288.0

(lcm) =⇒ 1

(numerator q) procedure

(denominator q) procedure

These procedures return the numerator or denominator of

their argument; the result is computed as if the argument

was represented as a fraction in lowest terms. The denom-

inator is always positive. The denominator of 0 is deﬁned

to be 1.

(numerator (/ 6 4)) =⇒ 3

(denominator (/ 6 4)) =⇒ 2

(denominator

(inexact (/ 6 4))) =⇒ 2.0

(floor x) procedure

(ceiling x) procedure

(truncate x) procedure

(round x) procedure

These procedures return inexact integer objects for inexact

arguments that are not inﬁnities or NaNs, and exact integer

objects for exact rational arguments. For such arguments,

floor returns the largest integer object not larger than x.

The ceiling procedure returns the smallest integer object

not smaller than x. The truncate procedure returns the

integer object closest to x whose absolute value is not larger

than the absolute value of x. The round procedure returns

the closest integer object to x, rounding to even when x

represents a number halfway between two integers.

Note: If the argument to one of these procedures is inexact,

then the result is also inexact. If an exact value is needed, the

result should be passed to the exact procedure.

Although inﬁnities and NaNs are not integer objects, these

procedures return an inﬁnity when given an inﬁnity as an

argument, and a NaN when given a NaN.

11. Base library 45

(floor -4.3) =⇒ -5.0

(ceiling -4.3) =⇒ -4.0

(truncate -4.3) =⇒ -4.0

(round -4.3) =⇒ -4.0

(floor 3.5) =⇒ 3.0

(ceiling 3.5) =⇒ 4.0

(truncate 3.5) =⇒ 3.0

(round 3.5) =⇒ 4.0

(round 7/2) =⇒ 4

(round 7) =⇒ 7

(floor +inf.0) =⇒ +inf.0

(ceiling -inf.0) =⇒ -inf.0

(round +nan.0) =⇒ +nan.0

(rationalize x

1

x

2

) procedure

The rationalize procedure returns the a number object

representing the simplest rational number diﬀering from x

1

by no more than x

2

. A rational number r

1

is simpler than

another rational number r

2

if r

1

= p

1

/q

1

and r

2

= p

2

/q

2

(in lowest terms) and [p

1

[ ≤ [p

2

[ and [q

1

[ ≤ [q

2

[. Thus

3/5 is simpler than 4/7. Although not all rationals are

comparable in this ordering (consider 2/7 and 3/5) any

interval contains a rational number that is simpler than

every other rational number in that interval (the simpler

2/5 lies between 2/7 and 3/5). Note that 0 = 0/1 is the

simplest rational of all.

(rationalize (exact .3) 1/10)

=⇒ 1/3

(rationalize .3 1/10)

=⇒ #i1/3 ; approximately

(rationalize +inf.0 3) =⇒ +inf.0

(rationalize +inf.0 +inf.0) =⇒ +nan.0

(rationalize 3 +inf.0) =⇒ 0.0

The ﬁrst two examples hold only in implementations whose

inexact real number objects have suﬃcient precision.

(exp z ) procedure

(log z ) procedure

(log z

1

z

2

) procedure

(sin z ) procedure

(cos z ) procedure

(tan z ) procedure

(asin z ) procedure

(acos z ) procedure

(atan z ) procedure

(atan x

1

x

2

) procedure

These procedures compute the usual transcendental func-

tions. The exp procedure computes the base-e exponential

of z . The log procedure with a single argument computes

the natural logarithm of z (not the base-ten logarithm);

(log z

1

z

2

) computes the base-z

2

logarithm of z

1

. The

asin, acos, and atan procedures compute arcsine, arc-

cosine, and arctangent, respectively. The two-argument

variant of atan computes (angle (make-rectangular x

2

x

1

)).

See section 11.7.3 for the underlying mathematical opera-

tions. These procedures may return inexact results even

when given exact arguments.

(exp +inf.0) =⇒ +inf.0

(exp -inf.0) =⇒ 0.0

(log +inf.0) =⇒ +inf.0

(log 0.0) =⇒ -inf.0

(log 0) =⇒ &assertion exception

(log -inf.0)

=⇒ +inf.0+3.141592653589793i

; approximately

(atan -inf.0)

=⇒ -1.5707963267948965 ; approximately

(atan +inf.0)

=⇒ 1.5707963267948965 ; approximately

(log -1.0+0.0i)

=⇒ 0.0+3.141592653589793i ; approximately

(log -1.0-0.0i)

=⇒ 0.0-3.141592653589793i ; approximately

; if -0.0 is distinguished

(sqrt z ) procedure

Returns the principal square root of z . For rational z ,

the result has either positive real part, or zero real part

and non-negative imaginary part. With log deﬁned as in

section 11.7.3, the value of (sqrt z ) could be expressed as

e

log z

2

.

The sqrt procedure may return an inexact result even

when given an exact argument.

(sqrt -5)

=⇒ 0.0+2.23606797749979i ; approximately

(sqrt +inf.0) =⇒ +inf.0

(sqrt -inf.0) =⇒ +inf.0i

(exact-integer-sqrt k) procedure

The exact-integer-sqrt procedure returns two non-

negative exact integer objects s and r where k = s

2

+ r

and k < (s + 1)

2

.

(exact-integer-sqrt 4) =⇒ 2 0

; two return values

(exact-integer-sqrt 5) =⇒ 2 1

; two return values

(expt z

1

z

2

) procedure

Returns z

1

raised to the power z

2

. For nonzero z

1

, this

is e

z2 log z1

. 0.0

z

is 1.0 if z = 0.0, and 0.0 if (real-part

z ) is positive. For other cases in which the ﬁrst argument

46 Revised

6

Scheme

is zero, either an exception is raised with condition type

&implementation-restriction, or an unspeciﬁed num-

ber object is returned.

For an exact real number object z

1

and an exact integer

object z

2

, (expt z

1

z

2

) must return an exact result. For

all other values of z

1

and z

2

, (expt z

1

z

2

) may return an

inexact result, even when both z

1

and z

2

are exact.

(expt 5 3) =⇒ 125

(expt 5 -3) =⇒ 1/125

(expt 5 0) =⇒ 1

(expt 0 5) =⇒ 0

(expt 0 5+.0000312i) =⇒ 0

(expt 0 -5) =⇒ unspeciﬁed

(expt 0 -5+.0000312i) =⇒ unspeciﬁed

(expt 0 0) =⇒ 1

(expt 0.0 0.0) =⇒ 1.0

(make-rectangular x

1

x

2

) procedure

(make-polar x

3

x

4

) procedure

(real-part z ) procedure

(imag-part z ) procedure

(magnitude z ) procedure

(angle z ) procedure

Suppose a

1

, a

2

, a

3

, and a

4

are real numbers, and c is a

complex number such that the following holds:

c = a

1

+a

2

i = a

3

e

ia4

Then, if x

1

, x

2

, x

3

, and x

4

are number objects representing

a

1

, a

2

, a

3

, and a

4

, respectively, (make-rectangular x

1

x

2

) returns c, and (make-polar x

3

x

4

) returns c.

(make-rectangular 1.1 2.2)

=⇒ 1.1+2.2i ; approximately

(make-polar 1.1 2.2)

=⇒ 1.1@2.2 ; approximately

Conversely, if −π ≤ a

4

≤ π, and if z is a number object rep-

resenting c, then (real-part z ) returns a

1

(imag-part

z ) returns a

2

, (magnitude z ) returns a

3

, and (angle z )

returns a

4

.

(real-part 1.1+2.2i) =⇒ 1.1 ; approximately

(imag-part 1.1+2.2i) =⇒ 2.2i ; approximately

(magnitude 1.1@2.2) =⇒ 1.1 ; approximately

(angle 1.1@2.2) =⇒ 2.2 ; approximately

(angle -1.0)

=⇒ 3.141592653589793 ; approximately

(angle -1.0+0.0i)

=⇒ 3.141592653589793 ; approximately

(angle -1.0-0.0i)

=⇒ -3.141592653589793 ; approximately

; if -0.0 is distinguished

(angle +inf.0) =⇒ 0.0

(angle -inf.0)

=⇒ 3.141592653589793 ; approximately

Moreover, suppose x

1

, x

2

are such that either x

1

or x

2

is an

inﬁnity, then

(make-rectangular x1 x2) =⇒ z

(magnitude z) =⇒ +inf.0

The make-polar, magnitude, and angle procedures may

return inexact results even when given exact arguments.

(angle -1)

=⇒ 3.141592653589793 ; approximately

Numerical Input and Output

(number->string z ) procedure

(number->string z radix) procedure

(number->string z radix precision) procedure

Radix must be an exact integer object, either 2, 8, 10,

or 16. If omitted, radix defaults to 10. If a precision

is speciﬁed, then z must be an inexact complex number

object, precision must be an exact positive integer object,

and radix must be 10. The number->string procedure

takes a number object and a radix and returns as a string

an external representation of the given number object in

the given radix such that

(let ((number z) (radix radix))

(eqv? (string->number

(number->string number radix)

radix)

number))

is true. If no possible result makes this expression

true, an exception with condition type &implementation-

restriction is raised.

Note: The error case can occur only when z is not a com-

plex number object or is a complex number object with a non-

rational real or imaginary part.

If a precision is speciﬁed, then the representations of the

inexact real components of the result, unless they are inﬁ-

nite or NaN, specify an explicit 'mantissa width` p, and p

is the least p ≥ precision for which the above expression is

true.

If z is inexact, the radix is 10, and the above expression

and condition can be satisﬁed 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, trailing zeroes, and mantissa width) needed

to make the above expression and condition true [4, 7];

otherwise the format of the result is unspeciﬁed.

The result returned by number->string never contains an

explicit radix preﬁx.

11. Base library 47

(string->number string) procedure

(string->number string radix) procedure

Returns a number object with maximally precise represen-

tation expressed by the given string. Radix must be an

exact integer object, either 2, 8, 10, or 16. If supplied,

radix is a default radix that may be overridden by an ex-

plicit radix preﬁx in string (e.g., "#o177"). If radix is not

supplied, then the default radix is 10. If string is not a

syntactically valid notation for a number object or a nota-

tion for a rational number object with a zero denominator,

then string->number returns #f.

(string->number "100") =⇒ 100

(string->number "100" 16) =⇒ 256

(string->number "1e2") =⇒ 100.0

(string->number "0/0") =⇒ #f

(string->number "+inf.0") =⇒ +inf.0

(string->number "-inf.0") =⇒ -inf.0

(string->number "+nan.0") =⇒ +nan.0

Note: The string->number procedure always returns a number

object or #f; it never raises an exception.

11.8. Booleans

The standard boolean objects for true and false have ex-

ternal representations #t and #f. However, of all objects,

only #f counts as false in conditional expressions. See sec-

tion 5.7.

Note: Programmers accustomed to other dialects of Lisp

should be aware that Scheme distinguishes both #f and the

empty list from each other and from the symbol nil.

(not obj ) procedure

Returns #t if obj is #f, and returns #f otherwise.

(not #t) =⇒ #f

(not 3) =⇒ #f

(not (list 3)) =⇒ #f

(not #f) =⇒ #t

(not ’()) =⇒ #f

(not (list)) =⇒ #f

(not ’nil) =⇒ #f

(boolean? obj ) procedure

Returns #t if obj is either #t or #f and returns #f other-

wise.

(boolean? #f) =⇒ #t

(boolean? 0) =⇒ #f

(boolean? ’()) =⇒ #f

(boolean=? bool

1

bool

2

bool

3

. . . ) procedure

Returns #t if the booleans are the same.

11.9. Pairs and lists

A pair is a compound structure with two ﬁelds called the

car and cdr ﬁelds (for historical reasons). Pairs are created

by the procedure cons. The car and cdr ﬁelds are accessed

by the procedures car and cdr.

Pairs are used primarily to represent lists. A list can be

deﬁned recursively as either the empty list or a pair whose

cdr is a list. More precisely, the set of lists is deﬁned as

the smallest set X such that

• The empty list is in X.

• If list is in X, then any pair whose cdr ﬁeld contains

list is also in X.

The objects in the car ﬁelds of successive pairs of a list are

the elements of the list. For example, a two-element list

is a pair whose car is the ﬁrst element and whose cdr is a

pair whose car is the second element and whose cdr is the

empty list. The length of a list is the number of elements,

which is the same as the number of pairs.

The empty list is a special object of its own type. It is not

a pair. It has no elements and its length is zero.

Note: The above deﬁnitions imply that all lists have ﬁnite

length and are terminated by the empty list.

A chain of pairs not ending in the empty list is called an

improper list. Note that an improper list is not a list.

The list and dotted notations can be combined to represent

improper lists:

(a b c . d)

is equivalent to

(a . (b . (c . d)))

Whether a given pair is a list depends upon what is stored

in the cdr ﬁeld.

(pair? obj ) procedure

Returns #t if obj is a pair, and otherwise returns #f.

(pair? ’(a . b)) =⇒ #t

(pair? ’(a b c)) =⇒ #t

(pair? ’()) =⇒ #f

(pair? ’#(a b)) =⇒ #f

(cons obj

1

obj

2

) procedure

Returns a newly allocated pair whose car is obj

1

and whose

cdr is obj

2

. The pair is guaranteed to be diﬀerent (in the

sense of eqv?) from every existing object.

48 Revised

6

Scheme

(cons ’a ’()) =⇒ (a)

(cons ’(a) ’(b c d)) =⇒ ((a) b c d)

(cons "a" ’(b c)) =⇒ ("a" b c)

(cons ’a 3) =⇒ (a . 3)

(cons ’(a b) ’c) =⇒ ((a b) . c)

(car pair) procedure

Returns the contents of the car ﬁeld of pair.

(car ’(a b c)) =⇒ a

(car ’((a) b c d)) =⇒ (a)

(car ’(1 . 2)) =⇒ 1

(car ’()) =⇒ &assertion exception

(cdr pair) procedure

Returns the contents of the cdr ﬁeld of pair.

(cdr ’((a) b c d)) =⇒ (b c d)

(cdr ’(1 . 2)) =⇒ 2

(cdr ’()) =⇒ &assertion exception

(caar pair) procedure

(cadr pair) procedure

.

.

.

.

.

.

(cdddar pair) procedure

(cddddr pair) procedure

These procedures are compositions of car and cdr, where

for example caddr could be deﬁned by

(define caddr (lambda (x) (car (cdr (cdr x))))).

Arbitrary compositions, up to four deep, are provided.

There are twenty-eight of these procedures in all.

(null? obj ) procedure

Returns #t if obj is the empty list, #fotherwise.

(list? obj ) procedure

Returns #t if obj is a list, #f otherwise. By deﬁnition,

all lists are chains of pairs that have ﬁnite length and are

terminated by the empty list.

(list? ’(a b c)) =⇒ #t

(list? ’()) =⇒ #t

(list? ’(a . b)) =⇒ #f

(list obj . . . ) procedure

Returns a newly allocated list of its arguments.

(list ’a (+ 3 4) ’c) =⇒ (a 7 c)

(list) =⇒ ()

(length list) procedure

Returns the length of list.

(length ’(a b c)) =⇒ 3

(length ’(a (b) (c d e))) =⇒ 3

(length ’()) =⇒ 0

(append list . . . obj ) procedure

Returns a possibly improper list consisting of the elements

of the ﬁrst list followed by the elements of the other lists,

with obj as the cdr of the ﬁnal pair. An improper list

results if obj is not a list.

(append ’(x) ’(y)) =⇒ (x y)

(append ’(a) ’(b c d)) =⇒ (a b c d)

(append ’(a (b)) ’((c))) =⇒ (a (b) (c))

(append ’(a b) ’(c . d)) =⇒ (a b c . d)

(append ’() ’a) =⇒ a

If append constructs a nonempty chain of pairs, it is always

newly allocated. If no pairs are allocated, obj is returned.

(reverse list) procedure

Returns a newly allocated list consisting of the elements of

list in reverse order.

(reverse ’(a b c)) =⇒ (c b a)

(reverse ’(a (b c) d (e (f))))

=⇒ ((e (f)) d (b c) a)

(list-tail list k) procedure

List should be a list of size at least k. The list-tail

procedure returns the subchain of pairs of list obtained by

omitting the ﬁrst k elements.

(list-tail ’(a b c d) 2) =⇒ (c d)

Implementation responsibilities: The implementation must

check that list is a chain of pairs whose length is at least

k. It should not check that it is a chain of pairs beyond

this length.

(list-ref list k) procedure

List must be a list whose length is at least k + 1. The

list-tail procedure returns the kth element of list.

(list-ref ’(a b c d) 2) =⇒ c

Implementation responsibilities: The implementation must

check that list is a chain of pairs whose length is at least

k + 1. It should not check that it is a list of pairs beyond

this length.

11. Base library 49

(map proc list

1

list

2

. . . ) procedure

The lists should all have the same length. Proc should

accept as many arguments as there are lists and return a

single value. Proc should not mutate any of the lists.

The map procedure applies proc element-wise to the ele-

ments of the lists and returns a list of the results, in order.

Proc is always called in the same dynamic environment as

map itself. The order in which proc is applied to the ele-

ments of the lists is unspeciﬁed. If multiple returns occur

from map, the values returned by earlier returns are not

mutated.

(map cadr ’((a b) (d e) (g h)))

=⇒ (b e h)

(map (lambda (n) (expt n n))

’(1 2 3 4 5))

=⇒ (1 4 27 256 3125)

(map + ’(1 2 3) ’(4 5 6)) =⇒ (5 7 9)

(let ((count 0))

(map (lambda (ignored)

(set! count (+ count 1))

count)

’(a b))) =⇒ (1 2) or (2 1)

Implementation responsibilities: The implementation

should check that the lists all have the same length. The

implementation must check the restrictions on proc to the

extent performed by applying it as described. An imple-

mentation may check whether proc is an appropriate argu-

ment before applying it.

(for-each proc list

1

list

2

. . . ) procedure

The lists should all have the same length. Proc should

accept as many arguments as there are lists. Proc should

not mutate any of the lists.

The for-each procedure applies proc element-wise to the

elements of the lists for its side eﬀects, in order from the

ﬁrst elements to the last. Proc is always called in the same

dynamic environment as for-each itself. The return val-

ues of for-each are unspeciﬁed.

(let ((v (make-vector 5)))

(for-each (lambda (i)

(vector-set! v i (* i i)))

’(0 1 2 3 4))

v) =⇒ #(0 1 4 9 16)

(for-each (lambda (x) x) ’(1 2 3 4))

=⇒ unspeciﬁed

(for-each even? ’()) =⇒ unspeciﬁed

Implementation responsibilities: The implementation

should check that the lists all have the same length. The

implementation must check the restrictions on proc to the

extent performed by applying it as described. An imple-

mentation may check whether proc is an appropriate argu-

ment before applying it.

Note: Implementations of for-each may or may not tail-call

proc on the last elements.

11.10. Symbols

Symbols are objects whose usefulness rests on the fact that

two symbols are identical (in the sense of eq?, eqv? and

equal?) if and only if their names are spelled the same

way. A symbol literal is formed using quote.

(symbol? obj ) procedure

Returns #t if obj is a symbol, otherwise returns #f.

(symbol? ’foo) =⇒ #t

(symbol? (car ’(a b))) =⇒ #t

(symbol? "bar") =⇒ #f

(symbol? ’nil) =⇒ #t

(symbol? ’()) =⇒ #f

(symbol? #f) =⇒ #f

(symbol->string symbol ) procedure

Returns the name of symbol as an immutable string.

(symbol->string ’flying-fish)

=⇒ "flying-fish"

(symbol->string ’Martin) =⇒ "Martin"

(symbol->string

(string->symbol "Malvina"))

=⇒ "Malvina"

(symbol=? symbol

1

symbol

2

symbol

3

. . . ) procedure

Returns #t if the symbols are the same, i.e., if their names

are spelled the same.

(string->symbol string) procedure

Returns the symbol whose name is string.

(eq? ’mISSISSIppi ’mississippi)

=⇒ #f

(string->symbol "mISSISSIppi")

=⇒ the symbol with name "mISSISSIppi"

(eq? ’bitBlt (string->symbol "bitBlt"))

=⇒ #t

(eq? ’JollyWog

(string->symbol

(symbol->string ’JollyWog)))

=⇒ #t

(string=? "K. Harper, M.D."

(symbol->string

(string->symbol "K. Harper, M.D.")))

=⇒ #t

50 Revised

6

Scheme

11.11. Characters

Characters are objects that represent Unicode scalar val-

ues [27].

Note: Unicode deﬁnes a standard mapping between sequences

of Unicode scalar values (integers in the range 0 to #x10FFFF,

excluding the range #xD800 to #xDFFF) in the latest version

of the standard and human-readable “characters”. More pre-

cisely, Unicode distinguishes between glyphs, which are printed

for humans to read, and characters, which are abstract enti-

ties that map to glyphs (sometimes in a way that’s sensitive

to surrounding characters). Furthermore, diﬀerent sequences of

scalar values sometimes correspond to the same character. The

relationships among scalar, characters, and glyphs are subtle

and complex.

Despite this complexity, most things that a literate human

would call a “character” can be represented by a single Unicode

scalar value (although several sequences of Unicode scalar val-

ues may represent that same character). For example, Roman

letters, Cyrillic letters, Hebrew consonants, and most Chinese

characters fall into this category.

Unicode scalar values exclude the range #xD800 to #xDFFF,

which are part of the range of Unicode code points. However,

the Unicode code points in this range, the so-called surrogates,

are an artifact of the UTF-16 encoding, and can only appear in

speciﬁc Unicode encodings, and even then only in pairs that en-

code scalar values. Consequently, all characters represent code

points, but the surrogate code points do not have representa-

tions as characters.

(char? obj ) procedure

Returns #t if obj is a character, otherwise returns #f.

(char->integer char) procedure

(integer->char sv) procedure

Sv must be a Unicode scalar value, i.e., a non-negative ex-

act integer object in [0, #xD7FF] ∪[#xE000, #x10FFFF].

Given a character, char->integer returns its Unicode

scalar value as an exact integer object. For a Unicode scalar

value sv, integer->char returns its associated character.

(integer->char 32) =⇒ #\space

(char->integer (integer->char 5000))

=⇒ 5000

(integer->char #\xD800) =⇒ &assertion exception

(char=? char

1

char

2

char

3

. . . ) procedure

(char<? char

1

char

2

char

3

. . . ) procedure

(char>? char

1

char

2

char

3

. . . ) procedure

(char<=? char

1

char

2

char

3

. . . ) procedure

(char>=? char

1

char

2

char

3

. . . ) procedure

These procedures impose a total ordering on the set of

characters according to their Unicode scalar values.

(char<? #\z #\ß) =⇒ #t

(char<? #\z #\Z) =⇒ #f

11.12. Strings

Strings are sequences of characters.

The length of a string is the number of characters that it

contains. This number is ﬁxed when the string is created.

The valid indices of a string are the integers less than the

length of the string. The ﬁrst character of a string has

index 0, the second has index 1, and so on.

(string? obj ) procedure

Returns #t if obj is a string, otherwise returns #f.

(make-string k) procedure

(make-string k char) procedure

Returns a newly allocated string of length k. If char is

given, then all elements of the string are initialized to char,

otherwise the contents of the string are unspeciﬁed.

(string char . . . ) procedure

Returns a newly allocated string composed of the argu-

ments.

(string-length string) procedure

Returns the number of characters in the given string as an

exact integer object.

(string-ref string k) procedure

K must be a valid index of string. The string-ref proce-

dure returns character k of string using zero-origin index-

ing.

Note: Implementors should make string-ref run in constant

time.

(string=? string

1

string

2

string

3

. . . ) procedure

Returns #t if the strings are the same length and contain

the same characters in the same positions. Otherwise, the

string=? procedure returns #f.

(string=? "Straße" "Strasse")

=⇒ #f

(string<? string

1

string

2

string

3

. . . ) procedure

(string>? string

1

string

2

string

3

. . . ) procedure

(string<=? string

1

string

2

string

3

. . . ) procedure

(string>=? string

1

string

2

string

3

. . . ) procedure

These procedures are the lexicographic extensions to

strings of the corresponding orderings on characters. For

example, string<? is the lexicographic ordering on strings

induced by the ordering char<? on characters. If two

strings diﬀer in length but are the same up to the length

of the shorter string, the shorter string is considered to be

lexicographically less than the longer string.

11. Base library 51

(string<? "z" "ß") =⇒ #t

(string<? "z" "zz") =⇒ #t

(string<? "z" "Z") =⇒ #f

(substring string start end) procedure

String must be a string, and start and end must be exact

integer objects satisfying

0 ≤ start ≤ end ≤ (string-length string).

The substring procedure returns a newly allocated string

formed from the characters of string beginning with index

start (inclusive) and ending with index end (exclusive).

(string-append string . . . ) procedure

Returns a newly allocated string whose characters form the

concatenation of the given strings.

(string->list string) procedure

(list->string list) procedure

List must be a list of characters. The string->list pro-

cedure returns a newly allocated list of the characters that

make up the given string. The list->string procedure re-

turns a newly allocated string formed from the characters

in list. The string->list and list->string procedures

are inverses so far as equal? is concerned.

(string-for-each proc string

1

string

2

. . . ) procedure

The strings must all have the same length. Proc should

accept as many arguments as there are strings. The

string-for-each procedure applies proc element-wise to

the characters of the strings for its side eﬀects, in order

from the ﬁrst characters to the last. Proc is always called in

the same dynamic environment as string-for-each itself.

The return values of string-for-each are unspeciﬁed.

Analogous to for-each.

Implementation responsibilities: The implementation must

check the restrictions on proc to the extent performed by

applying it as described. An implementation may check

whether proc is an appropriate argument before applying

it.

(string-copy string) procedure

Returns a newly allocated copy of the given string.

11.13. Vectors

Vectors are heterogeneous structures whose elements are

indexed by integers. A vector typically occupies less space

than a list of the same length, and the average time needed

to access a randomly chosen element is typically less for the

vector than for the list.

The length of a vector is the number of elements that it

contains. This number is a non-negative integer that is

ﬁxed when the vector is created. The valid indices of a

vector are the exact non-negative integer objects less than

the length of the vector. The ﬁrst element in a vector is

indexed by zero, and the last element is indexed by one

less than the length of the vector.

Like list constants, vector constants must be quoted:

’#(0 (2 2 2 2) "Anna")

=⇒ #(0 (2 2 2 2) "Anna")

(vector? obj ) procedure

Returns #t if obj is a vector. Otherwise the procedure

returns #f.

(make-vector k) procedure

(make-vector k ﬁll ) procedure

Returns a newly allocated vector of k elements. If a second

argument is given, then each element is initialized to ﬁll .

Otherwise the initial contents of each element is unspeci-

ﬁed.

(vector obj . . . ) procedure

Returns a newly allocated vector whose elements contain

the given arguments. Analogous to list.

(vector ’a ’b ’c) =⇒ #(a b c)

(vector-length vector) procedure

Returns the number of elements in vector as an exact in-

teger object.

(vector-ref vector k) procedure

K must be a valid index of vector. The vector-ref pro-

cedure returns the contents of element k of vector.

(vector-ref ’#(1 1 2 3 5 8 13 21) 5)

=⇒ 8

(vector-set! vector k obj ) procedure

K must be a valid index of vector. The vector-set! pro-

cedure stores obj in element k of vector, and returns un-

speciﬁed values.

Passing an immutable vector to vector-set! should cause

an exception with condition type &assertion to be raised.

52 Revised

6

Scheme

(let ((vec (vector 0 ’(2 2 2 2) "Anna")))

(vector-set! vec 1 ’("Sue" "Sue"))

vec)

=⇒ #(0 ("Sue" "Sue") "Anna")

(vector-set! ’#(0 1 2) 1 "doe")

=⇒ unspeciﬁed

; constant vector

; should raise &assertion exception

(vector->list vector) procedure

(list->vector list) procedure

The vector->list procedure returns a newly allocated list

of the objects contained in the elements of vector. The

list->vector procedure returns a newly created vector

initialized to the elements of the list list.

(vector->list ’#(dah dah didah))

=⇒ (dah dah didah)

(list->vector ’(dididit dah))

=⇒ #(dididit dah)

(vector-fill! vector ﬁll ) procedure

Stores ﬁll in every element of vector and returns unspeci-

ﬁed values.

(vector-map proc vector

1

vector

2

. . . ) procedure

The vectors must all have the same length. Proc should

accept as many arguments as there are vectors and return

a single value.

The vector-map procedure applies proc element-wise to

the elements of the vectors and returns a vector of the

results, in order. Proc is always called in the same dynamic

environment as vector-map itself. The order in which proc

is applied to the elements of the vectors is unspeciﬁed. If

multiple returns occur from vector-map, the return values

returned by earlier returns are not mutated.

Analogous to map.

Implementation responsibilities: The implementation must

check the restrictions on proc to the extent performed by

applying it as described. An implementation may check

whether proc is an appropriate argument before applying

it.

(vector-for-each proc vector

1

vector

2

. . . ) procedure

The vectors must all have the same length. Proc should

accept as many arguments as there are vectors. The

vector-for-each procedure applies proc element-wise to

the elements of the vectors for its side eﬀects, in order

from the ﬁrst elements to the last. Proc is always called in

the same dynamic environment as vector-for-each itself.

The return values of vector-for-each are unspeciﬁed.

Analogous to for-each.

Implementation responsibilities: The implementation must

check the restrictions on proc to the extent performed by

applying it as described. An implementation may check

whether proc is an appropriate argument before applying

it.

11.14. Errors and violations

(error who message irritant

1

. . . ) procedure

(assertion-violation who message irritant

1

. . . )

procedure

Who must be a string or a symbol or #f. Message must

be a string. The irritants are arbitrary objects.

These procedures raise an exception. The error proce-

dure should be called when an error has occurred, typically

caused by something that has gone wrong in the interaction

of the program with the external world or the user. The

assertion-violation procedure should be called when an

invalid call to a procedure was made, either passing an in-

valid number of arguments, or passing an argument that it

is not speciﬁed to handle.

The who argument should describe the procedure or oper-

ation that detected the exception. The message argument

should describe the exceptional situation. The irritants

should be the arguments to the operation that detected

the operation.

The condition object provided with the exception (see li-

brary chapter 7) has the following condition types:

• If who is not #f, the condition has condition type &who,

with who as the value of its ﬁeld. In that case, who

should be the name of the procedure or entity that

detected the exception. If it is #f, the condition does

not have condition type &who.

• The condition has condition type &message, with

message as the value of its ﬁeld.

• The condition has condition type &irritants, and its

ﬁeld has as its value a list of the irritants.

Moreover, the condition created by error has condition

type &error, and the condition created by assertion-

violation has condition type &assertion.

(define (fac n)

(if (not (integer-valued? n))

(assertion-violation

’fac "non-integral argument" n))

(if (negative? n)

(assertion-violation

’fac "negative argument" n))

11. Base library 53

(letrec

((loop (lambda (n r)

(if (zero? n)

r

(loop (- n 1) (* r n))))))

(loop n 1)))

(fac 5) =⇒ 120

(fac 4.5) =⇒ &assertion exception

(fac -3) =⇒ &assertion exception

(assert 'expression`) syntax

An assert form is evaluated by evaluating 'expression`.

If 'expression` returns a true value, that value is returned

from the assert expression. If 'expression` returns #f, an

exception with condition types &assertion and &message

is raised. The message provided in the condition object is

implementation-dependent.

Note: Implementations should exploit the fact that assert is

syntax to provide as much information as possible about the

location of the assertion failure.

11.15. Control features

This chapter describes various primitive procedures which

control the ﬂow of program execution in special ways.

(apply proc arg

1

. . . rest-args) procedure

Rest-args must be a list. Proc should accept n arguments,

where n is number of args plus the length of rest-args.

The apply procedure calls proc with the elements of the

list (append (list arg

1

. . . ) rest-args) as the actual ar-

guments.

If a call to apply occurs in a tail context, the call to proc

is also in a tail context.

(apply + (list 3 4)) =⇒ 7

(define compose

(lambda (f g)

(lambda args

(f (apply g args)))))

((compose sqrt *) 12 75) =⇒ 30

(call-with-current-continuation proc) procedure

(call/cc proc) procedure

Proc should accept one argument. The procedure

call-with-current-continuation (which is the same as

the procedure call/cc) packages the current continuation

as an “escape procedure” and passes it as an argument to

proc. The escape procedure is a Scheme procedure that,

if it is later called, will abandon whatever continuation is

in eﬀect at that later time and will instead reinstate the

continuation that was in eﬀect when the escape procedure

was created. Calling the escape procedure may cause the

invocation of before and after procedures installed using

dynamic-wind.

The escape procedure accepts the same number of argu-

ments as the continuation of the original call to call-

with-current-continuation.

The escape procedure that is passed to proc 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.

If a call to call-with-current-continuation occurs in a

tail context, the call to proc is also in a tail context.

The following examples show only some ways in which

call-with-current-continuation is used. If all real uses

were as simple as these examples, there would be no need

for a procedure with the power of call-with-current-

continuation.

(call-with-current-continuation

(lambda (exit)

(for-each (lambda (x)

(if (negative? x)

(exit x)))

’(54 0 37 -3 245 19))

#t)) =⇒ -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)) =⇒ 4

(list-length ’(a b . c)) =⇒ #f

(call-with-current-continuation procedure?)

=⇒ #t

Note: Calling an escape procedure reenters the dynamic ex-

tent of the call to call-with-current-continuation, and thus

restores its dynamic environment; see section 5.12.

(values obj . . .) procedure

Delivers all of its arguments to its continuation. The

values procedure might be deﬁned as follows:

(define (values . things)

(call-with-current-continuation

(lambda (cont) (apply cont things))))

54 Revised

6

Scheme

The continuations of all non-ﬁnal expressions within a se-

quence of expressions, such as in lambda, begin, let, let*,

letrec, letrec*, let-values, let*-values, case, and

cond forms, usually take an arbitrary number of values.

Except for these and the continuations created by call-

with-values, let-values, and let*-values, continua-

tions implicitly accepting a single value, such as the con-

tinuations of 'operator` and 'operand`s of procedure calls

or the 'test` expressions in conditionals, take exactly one

value. The eﬀect of passing an inappropriate number of

values to such a continuation is undeﬁned.

(call-with-values producer consumer) procedure

Producer must be a procedure and should accept zero ar-

guments. Consumer must be a procedure and should ac-

cept as many values as producer returns. The call-with-

values procedure calls producer with no arguments and

a continuation that, when passed some values, calls the

consumer procedure with those values as arguments. The

continuation for the call to consumer is the continuation

of the call to call-with-values.

(call-with-values (lambda () (values 4 5))

(lambda (a b) b))

=⇒ 5

(call-with-values * -) =⇒ -1

If a call to call-with-values occurs in a tail context, the

call to consumer is also in a tail context.

Implementation responsibilities: After producer returns,

the implementation must check that consumer accepts as

many values as consumer has returned.

(dynamic-wind before thunk after) procedure

Before, thunk, and after must be procedures, and each

should accept zero arguments. These procedures may re-

turn any number of values. The dynamic-wind proce-

dure calls thunk without arguments, returning the results

of this call. Moreover, dynamic-wind calls before with-

out arguments whenever the dynamic extent of the call to

thunk is entered, and after without arguments whenever

the dynamic extent of the call to thunk is exited. Thus,

in the absence of calls to escape procedures created by

call-with-current-continuation, dynamic-wind calls

before, thunk, and after, in that order.

While the calls to before and after are not considered to

be within the dynamic extent of the call to thunk, calls

to the before and after procedures of any other calls to

dynamic-wind that occur within the dynamic extent of the

call to thunk are considered to be within the dynamic ex-

tent of the call to thunk.

More precisely, an escape procedure transfers control out

of the dynamic extent of a set of zero or more active

dynamic-wind calls x . . . and transfer control into the dy-

namic extent of a set of zero or more active dynamic-wind

calls y . . .. It leaves the dynamic extent of the most re-

cent x and calls without arguments the corresponding after

procedure. If the after procedure returns, the escape pro-

cedure proceeds to the next most recent x, and so on. Once

each x has been handled in this manner, the escape pro-

cedure calls without arguments the before procedure cor-

responding to the least recent y. If the before procedure

returns, the escape procedure reenters the dynamic extent

of the least recent y and proceeds with the next least recent

y, and so on. Once each y has been handled in this man-

ner, control is transferred to the continuation packaged in

the escape procedure.

Implementation responsibilities: The implementation must

check the restrictions on thunk and after only if they are

actually called.

(let ((path ’())

(c #f))

(let ((add (lambda (s)

(set! path (cons s path)))))

(dynamic-wind

(lambda () (add ’connect))

(lambda ()

(add (call-with-current-continuation

(lambda (c0)

(set! c c0)

’talk1))))

(lambda () (add ’disconnect)))

(if (< (length path) 4)

(c ’talk2)

(reverse path))))

=⇒ (connect talk1 disconnect

connect talk2 disconnect)

(let ((n 0))

(call-with-current-continuation

(lambda (k)

(dynamic-wind

(lambda ()

(set! n (+ n 1))

(k))

(lambda ()

(set! n (+ n 2)))

(lambda ()

(set! n (+ n 4))))))

n) =⇒ 1

(let ((n 0))

(call-with-current-continuation

(lambda (k)

(dynamic-wind

values

(lambda ()

(dynamic-wind

values

(lambda ()

11. Base library 55

(set! n (+ n 1))

(k))

(lambda ()

(set! n (+ n 2))

(k))))

(lambda ()

(set! n (+ n 4))))))

n) =⇒ 7

Note: Entering a dynamic extent restores its dynamic environ-

ment; see section 5.12.

11.16. Iteration

(let 'variable` 'bindings` 'body`) syntax

“Named let” is a variant on the syntax of let that pro-

vides a general looping construct and may also be used

to express recursion. It has the same syntax and seman-

tics as ordinary let except that 'variable` is bound within

'body` to a procedure whose parameters are the bound

variables and whose body is 'body`. Thus the execution of

'body` may be repeated by invoking the procedure named

by 'variable`.

(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))

((< (car numbers) 0)

(loop (cdr numbers)

nonneg

(cons (car numbers) neg)))))

=⇒ ((6 1 3) (-5 -2))

11.17. Quasiquotation

(quasiquote 'qq template`) syntax

unquote auxiliary syntax

unquote-splicing auxiliary syntax

“Backquote” or “quasiquote” expressions are useful for

constructing a list or vector structure when some but not

all of the desired structure is known in advance.

Syntax: 'Qq template` should be as speciﬁed by the gram-

mar at the end of this entry.

Semantics: If no unquote or unquote-splicing forms

appear within the 'qq template`, the result of evaluating

(quasiquote 'qq template`) is equivalent to the result of

evaluating (quote 'qq template`).

If an (unquote 'expression` . . . ) form appears inside a

'qq template`, however, the 'expression`s are evaluated

(“unquoted”) and their results are inserted into the struc-

ture instead of the unquote form.

If an (unquote-splicing 'expression` . . . ) form appears

inside a 'qq template`, then the 'expression`s must evalu-

ate to lists; the opening and closing parentheses of the lists

are then “stripped away” and the elements of the lists are

inserted in place of the unquote-splicing form.

Any unquote-splicing or multi-operand unquote form

must appear only within a list or vector 'qq template`.

As noted in section 4.3.5, (quasiquote 'qq template`)

may be abbreviated `'qq template`, (unquote

'expression`) may be abbreviated ,'expression`, and

(unquote-splicing 'expression`) may be abbreviated

,@'expression`.

`(list ,(+ 1 2) 4) =⇒ (list 3 4)

(let ((name ’a)) `(list ,name ’,name))

=⇒ (list a (quote a))

`(a ,(+ 1 2) ,@(map abs ’(4 -5 6)) b)

=⇒ (a 3 4 5 6 b)

`(( foo ,(- 10 3)) ,@(cdr ’(c)) . ,(car ’(cons)))

=⇒ ((foo 7) . cons)

`#(10 5 ,(sqrt 4) ,@(map sqrt ’(16 9)) 8)

=⇒ #(10 5 2 4 3 8)

(let ((name ’foo))

`((unquote name name name)))

=⇒ (foo foo foo)

(let ((name ’(foo)))

`((unquote-splicing name name name)))

=⇒ (foo foo foo)

(let ((q ’((append x y) (sqrt 9))))

``(foo ,,@q))

=⇒ `(foo

(unquote (append x y) (sqrt 9)))

(let ((x ’(2 3))

(y ’(4 5)))

`(foo (unquote (append x y) (sqrt 9))))

=⇒ (foo (2 3 4 5) 3)

Quasiquote forms may be nested. Substitutions are made

only for unquoted components appearing at the same nest-

ing level as the outermost quasiquote. The nesting level

increases by one inside each successive quasiquotation, and

decreases by one inside each unquotation.

`(a `(b ,(+ 1 2) ,(foo ,(+ 1 3) d) e) f)

=⇒ (a `(b ,(+ 1 2) ,(foo 4 d) e) f)

(let ((name1 ’x)

(name2 ’y))

`(a `(b ,,name1 ,’,name2 d) e))

=⇒ (a `(b ,x ,’y d) e)

A quasiquote expression may return either fresh, mutable

objects or literal structure for any structure that is con-

structed at run time during the evaluation of the expres-

sion. Portions that do not need to be rebuilt are always

literal. Thus,

56 Revised

6

Scheme

(let ((a 3)) `((1 2) ,a ,4 ,’five 6))

may be equivalent to either of the following expres-

sions:

’((1 2) 3 4 five 6)

(let ((a 3))

(cons ’(1 2)

(cons a (cons 4 (cons ’five ’(6))))))

However, it is not equivalent to this expression:

(let ((a 3)) (list (list 1 2) a 4 ’five 6))

It is a syntax violation if any of the identiﬁers quasiquote,

unquote, or unquote-splicing appear in positions within

a 'qq template` otherwise than as described above.

The following grammar for quasiquote expressions is not

context-free. It is presented as a recipe for generating an

inﬁnite number of production rules. Imagine a copy of the

following rules for D = 1, 2, 3, . . .. D keeps track of the

nesting depth.

'qq template` −→ 'qq template 1`

'qq template 0` −→ 'expression`

'quasiquotation D` −→ (quasiquote 'qq template D`)

'qq template D` −→ 'lexeme datum`

[ 'list qq template D`

[ 'vector qq template D`

[ 'unquotation D`

'list qq template D` −→ ('qq template or splice D`*)

[ ('qq template or splice D`

+

. 'qq template D`)

[ 'quasiquotation D + 1`

'vector qq template D` −→ #('qq template or splice D`*)

'unquotation D` −→ (unquote 'qq template D −1`)

'qq template or splice D` −→ 'qq template D`

[ 'splicing unquotation D`

'splicing unquotation D` −→

(unquote-splicing 'qq template D −1`*)

[ (unquote 'qq template D −1`*)

In 'quasiquotation`s, a 'list qq template D` can some-

times be confused with either an 'unquotation D` or

a 'splicing unquotation D`. The interpretation as an

'unquotation` or 'splicing unquotation D` takes prece-

dence.

11.18. Binding constructs for syntactic key-

words

The let-syntax and letrec-syntax forms bind keywords.

Like a begin form, a let-syntax or letrec-syntax form

may appear in a deﬁnition context, in which case it is

treated as a deﬁnition, and the forms in the body must

also be deﬁnitions. A let-syntax or letrec-syntax form

may also appear in an expression context, in which case

the forms within their bodies must be expressions.

(let-syntax 'bindings` 'form` . . . ) syntax

Syntax: 'Bindings` must have the form

(('keyword) 'expression)) . . . )

Each 'keyword` is an identiﬁer, and each 'expression` is

an expression that evaluates, at macro-expansion time,

to a transformer. Transformers may be created by

syntax-rules or identifier-syntax (see section 11.19)

or by one of the other mechanisms described in library

chapter 12. It is a syntax violation for 'keyword` to ap-

pear more than once in the list of keywords being bound.

Semantics: The 'form`s are expanded in the syntactic envi-

ronment obtained by extending the syntactic environment

of the let-syntax form with macros whose keywords are

the 'keyword`s, bound to the speciﬁed transformers. Each

binding of a 'keyword` has the 'form`s as its region.

The 'form`s of a let-syntax form are treated, whether

in deﬁnition or expression context, as if wrapped in an

implicit begin; see section 11.4.7. Thus deﬁnitions in the

result of expanding the 'form`s have the same region as

any deﬁnition appearing in place of the let-syntax form

would have.

Implementation responsibilities: The implementation

should detect if the value of 'expression` cannot possibly

be a transformer.

(let-syntax ((when (syntax-rules ()

((when test stmt1 stmt2 ...)

(if test

(begin stmt1

stmt2 ...))))))

(let ((if #t))

(when if (set! if ’now))

if)) =⇒ now

(let ((x ’outer))

(let-syntax ((m (syntax-rules () ((m) x))))

(let ((x ’inner))

(m)))) =⇒ outer

(let ()

(let-syntax

((def (syntax-rules ()

((def stuff ...) (define stuff ...)))))

(def foo 42))

foo) =⇒ 42

(let ()

(let-syntax ())

5) =⇒ 5

(letrec-syntax 'bindings` 'form` . . . ) syntax

Syntax: Same as for let-syntax.

Semantics: The 'form`s are expanded in the syntactic envi-

ronment obtained by extending the syntactic environment

of the letrec-syntax form with macros whose keywords

11. Base library 57

are the 'keyword`s, bound to the speciﬁed transformers.

Each binding of a 'keyword` has the 'bindings` as well

as the 'form`s within its region, so the transformers can

transcribe forms into uses of the macros introduced by the

letrec-syntax form.

The 'form`s of a letrec-syntax form are treated, whether

in deﬁnition or expression context, as if wrapped in an

implicit begin; see section 11.4.7. Thus deﬁnitions in the

result of expanding the 'form`s have the same region as any

deﬁnition appearing in place of the letrec-syntax form

would have.

Implementation responsibilities: The implementation

should detect if the value of 'expression` cannot possibly

be a transformer.

(letrec-syntax

((my-or (syntax-rules ()

((my-or) #f)

((my-or e) e)

((my-or e1 e2 ...)

(let ((temp e1))

(if temp

temp

(my-or e2 ...)))))))

(let ((x #f)

(y 7)

(temp 8)

(let odd?)

(if even?))

(my-or x

(let temp)

(if y)

y))) =⇒ 7

The following example highlights how let-syntax and

letrec-syntax diﬀer.

(let ((f (lambda (x) (+ x 1))))

(let-syntax ((f (syntax-rules ()

((f x) x)))

(g (syntax-rules ()

((g x) (f x)))))

(list (f 1) (g 1))))

=⇒ (1 2)

(let ((f (lambda (x) (+ x 1))))

(letrec-syntax ((f (syntax-rules ()

((f x) x)))

(g (syntax-rules ()

((g x) (f x)))))

(list (f 1) (g 1))))

=⇒ (1 1)

The two expressions are identical except that

the let-syntax form in the ﬁrst expression is a

letrec-syntax form in the second. In the ﬁrst ex-

pression, the f occurring in g refers to the let-bound

variable f, whereas in the second it refers to the keyword f

whose binding is established by the letrec-syntax form.

11.19. Macro transformers

(syntax-rules ('literal` . . . ) 'syntax rule` . . . )

syntax (expand)

auxiliary syntax (expand)

... auxiliary syntax (expand)

Syntax: Each 'literal` must be an identiﬁer. Each

'syntax rule` must have the following form:

('srpattern) 'template))

An 'srpattern` is a restricted form of 'pattern`, namely,

a nonempty 'pattern` in one of four parenthesized forms

below whose ﬁrst subform is an identiﬁer or an underscore

. A 'pattern` is an identiﬁer, constant, or one of the fol-

lowing.

('pattern) ...)

('pattern) 'pattern) ... . 'pattern))

('pattern) ... 'pattern) 'ellipsis) 'pattern) ...)

('pattern) ... 'pattern) 'ellipsis) 'pattern) ... . 'pattern))

#('pattern) ...)

#('pattern) ... 'pattern) 'ellipsis) 'pattern) ...)

An 'ellipsis` is the identiﬁer “...” (three periods).

A 'template` is a pattern variable, an identiﬁer that is not

a pattern variable, a pattern datum, or one of the following.

('subtemplate) ...)

('subtemplate) ... . 'template))

#('subtemplate) ...)

A 'subtemplate` is a 'template` followed by zero or more

ellipses.

Semantics: An instance of syntax-rules evaluates, at

macro-expansion time, to a new macro transformer by

specifying a sequence of hygienic rewrite rules. A use of

a macro whose keyword is associated with a transformer

speciﬁed by syntax-rules is matched against the patterns

contained in the 'syntax rule`s, beginning with the left-

most 'syntax rule`. When a match is found, the macro use

is transcribed hygienically according to the template. It is

a syntax violation when no match is found.

An identiﬁer appearing within a 'pattern` may be an un-

derscore ( ), a literal identiﬁer listed in the list of literals

('literal` . . . ), or an ellipsis ( ... ). All other identiﬁers

appearing within a 'pattern` are pattern variables. It is

a syntax violation if an ellipsis or underscore appears in

('literal` . . . ).

While the ﬁrst subform of 'srpattern` may be an identiﬁer,

the identiﬁer is not involved in the matching and is not

considered a pattern variable or literal identiﬁer.

Pattern variables match arbitrary input subforms and are

used to refer to elements of the input. It is a syntax viola-

tion if the same pattern variable appears more than once

in a 'pattern`.

58 Revised

6

Scheme

Underscores also match arbitrary input subforms but are

not pattern variables and so cannot be used to refer to those

elements. Multiple underscores may appear in a 'pattern`.

A literal identiﬁer matches an input subform if and only

if the input subform is an identiﬁer and either both its

occurrence in the input expression and its occurrence in

the list of literals have the same lexical binding, or the two

identiﬁers have the same name and both have no lexical

binding.

A subpattern followed by an ellipsis can match zero or more

elements of the input.

More formally, an input form F matches a pattern P if and

only if one of the following holds:

• P is an underscore ( ).

• P is a pattern variable.

• P is a literal identiﬁer and F is an identiﬁer such that

both P and F would refer to the same binding if both

were to appear in the output of the macro outside of

any bindings inserted into the output of the macro.

(If neither of two like-named identiﬁers refers to any

binding, i.e., both are undeﬁned, they are considered

to refer to the same binding.)

• P is of the form (P

1

. . . P

n

) and F is a list of n

elements that match P

1

through P

n

.

• P is of the form (P

1

. . . P

n

. P

x

) and F is a list

or improper list of n or more elements whose ﬁrst

n elements match P

1

through P

n

and whose nth cdr

matches P

x

.

• P is of the form (P

1

. . . P

k

P

e

'ellipsis` P

m+1

. . .

P

n

), where 'ellipsis` is the identiﬁer ... and F is a list

of n elements whose ﬁrst k elements match P

1

through

P

k

, whose next m − k elements each match P

e

, and

whose remaining n−m elements match P

m+1

through

P

n

.

• P is of the form (P

1

. . . P

k

P

e

'ellipsis` P

m+1

. . .

P

n

. P

x

), where 'ellipsis` is the identiﬁer ... and

F is a list or improper list of n elements whose ﬁrst

k elements match P

1

through P

k

, whose next m − k

elements each match P

e

, whose next n − m elements

match P

m+1

through P

n

, and whose nth and ﬁnal cdr

matches P

x

.

• P is of the form #(P

1

. . . P

n

) and F is a vector of n

elements that match P

1

through P

n

.

• P is of the form #(P

1

. . . P

k

P

e

'ellipsis` P

m+1

. . .

P

n

), where 'ellipsis` is the identiﬁer ... and F is a

vector of n or more elements whose ﬁrst k elements

match P

1

through P

k

, whose next m−k elements each

match P

e

, and whose remaining n−m elements match

P

m+1

through P

n

.

• P is a pattern datum (any nonlist, nonvector, non-

symbol datum) and F is equal to P in the sense of the

equal? procedure.

When a macro use is transcribed according to the template

of the matching 'syntax rule`, pattern variables that occur

in the template are replaced by the subforms they match

in the input.

Pattern data and identiﬁers that are not pattern variables

or ellipses are copied into the output. A subtemplate fol-

lowed by an ellipsis expands into zero or more occurrences

of the subtemplate. Pattern variables that occur in sub-

patterns followed by one or more ellipses may occur only

in subtemplates that are followed by (at least) as many el-

lipses. These pattern variables are replaced in the output

by the input subforms to which they are bound, distributed

as speciﬁed. If a pattern variable is followed by more el-

lipses in the subtemplate than in the associated subpattern,

the input form is replicated as necessary. The subtemplate

must contain at least one pattern variable from a subpat-

tern followed by an ellipsis, and for at least one such pat-

tern variable, the subtemplate must be followed by exactly

as many ellipses as the subpattern in which the pattern

variable appears. (Otherwise, the expander would not be

able to determine how many times the subform should be

repeated in the output.) It is a syntax violation if the

constraints of this paragraph are not met.

A template of the form ('ellipsis` 'template`) is identi-

cal to 'template`, except that ellipses within the template

have no special meaning. That is, any ellipses contained

within 'template` are treated as ordinary identiﬁers. In

particular, the template (... ...) produces a single el-

lipsis, .... This allows syntactic abstractions to expand

into forms containing ellipses.

(define-syntax be-like-begin

(syntax-rules ()

((be-like-begin name)

(define-syntax name

(syntax-rules ()

((name expr (... ...))

(begin expr (... ...))))))))

(be-like-begin sequence)

(sequence 1 2 3 4) =⇒ 4

As an example for hygienic use of auxiliary identiﬁer, if let

and cond are deﬁned as in section 11.4.6 and appendix B

then they are hygienic (as required) and the following is

not an error.

(let ((=> #f))

(cond (#t => ’ok))) =⇒ ok

The macro transformer for cond recognizes => as a local

variable, and hence an expression, and not as the identi-

ﬁer =>, which the macro transformer treats as a syntactic

keyword. Thus the example expands into

11. Base library 59

(let ((=> #f))

(if #t (begin => ’ok)))

instead of

(let ((=> #f))

(let ((temp #t))

(if temp (’ok temp))))

which would result in an assertion violation.

(identifier-syntax 'template`) syntax (expand)

(identifier-syntax syntax (expand)

('id

1

` 'template

1

`)

((set! 'id

2

` 'pattern`)

'template

2

`))

set! auxiliary syntax (expand)

Syntax: The 'id`s must be identiﬁers. The 'template`s

must be as for syntax-rules.

Semantics: When a keyword is bound to a transformer

produced by the ﬁrst form of identifier-syntax, refer-

ences to the keyword within the scope of the binding are

replaced by 'template`.

(define p (cons 4 5))

(define-syntax p.car (identifier-syntax (car p)))

p.car =⇒ 4

(set! p.car 15) =⇒ &syntax exception

The second, more general, form of identifier-syntax

permits the transformer to determine what happens when

set! is used. In this case, uses of the identiﬁer by itself are

replaced by 'template

1

`, and uses of set! with the identi-

ﬁer are replaced by 'template

2

`.

(define p (cons 4 5))

(define-syntax p.car

(identifier-syntax

( (car p))

((set! e) (set-car! p e))))

(set! p.car 15)

p.car =⇒ 15

p =⇒ (15 5)

11.20. Tail calls and tail contexts

A tail call is a procedure call that occurs in a tail con-

text. Tail contexts are deﬁned inductively. Note that a tail

context is always determined with respect to a particular

lambda expression.

• The last expression within the body of a lambda ex-

pression, shown as 'tail expression` below, occurs in a

tail context.

(lambda 'formals)

'deﬁnition)*

'expression)* 'tail expression))

• If one of the following expressions is in a tail context,

then the subexpressions shown as 'tail expression` are

in a tail context. These were derived from speciﬁ-

cations of the syntax of the forms described in this

chapter by replacing some occurrences of 'expression`

with 'tail expression`. Only those rules that contain

tail contexts are shown here.

(if 'expression) 'tail expression) 'tail expression))

(if 'expression) 'tail expression))

(cond 'cond clause)

+

)

(cond 'cond clause)* (else 'tail sequence)))

(case 'expression)

'case clause)

+

)

(case 'expression)

'case clause)*

(else 'tail sequence)))

(and 'expression)* 'tail expression))

(or 'expression)* 'tail expression))

(let 'bindings) 'tail body))

(let 'variable) 'bindings) 'tail body))

(let* 'bindings) 'tail body))

(letrec* 'bindings) 'tail body))

(letrec 'bindings) 'tail body))

(let-values 'mv-bindings) 'tail body))

(let*-values 'mv-bindings) 'tail body))

(let-syntax 'bindings) 'tail body))

(letrec-syntax 'bindings) 'tail body))

(begin 'tail sequence))

A 'cond clause` is

('test) 'tail sequence)),

a 'case clause` is

(('datum)*) 'tail sequence)),

a 'tail body` is

'deﬁnition)* 'tail sequence),

and a 'tail sequence` is

'expression)* 'tail expression).

• If a cond expression is in a tail context, and has a

clause of the form ('expression

1

` => 'expression

2

`)

then the (implied) call to the procedure that results

from the evaluation of 'expression

2

` is in a tail context.

'Expression

2

` itself is not in a tail context.

60 Revised

6

Scheme

Certain built-in procedures must also perform tail calls.

The ﬁrst argument passed to apply and to call-with-

current-continuation, and the second argument passed

to call-with-values, must be called via a tail call.

In the following example the only tail call is the call to f.

None of the calls to g or h are tail calls. The reference to

x is in a tail context, but it is not a call and thus is not a

tail call.

(lambda ()

(if (g)

(let ((x (h)))

x)

(and (g) (f))))

Note: Implementations may recognize that some non-tail calls,

such as the call to h above, can be evaluated as though they

were tail calls. In the example above, the let expression could

be compiled as a tail call to h. (The possibility of h return-

ing an unexpected number of values can be ignored, because

in that case the eﬀect of the let is explicitly unspeciﬁed and

implementation-dependent.)

Appendix A. Formal semantics 61

APPENDICES

Appendix A. Formal semantics

This appendix presents a non-normative, formal, opera-

tional semantics for Scheme, that is based on an earlier

semantics [18]. It does not cover the entire language. The

notable missing features are the macro system, I/O, and

the numerical tower. The precise list of features included

is given in section A.2.

The core of the speciﬁcation is a single-step term rewriting

relation that indicates how an (abstract) machine behaves.

In general, the report is not a complete speciﬁcation, giving

implementations freedom to behave diﬀerently, typically to

allow optimizations. This underspeciﬁcation shows up in

two ways in the semantics.

The ﬁrst is reduction rules that reduce to special

“unknown: string” states (where the string provides a

description of the unknown state). The intention is that

rules that reduce to such states can be replaced with arbi-

trary reduction rules. The precise speciﬁcation of how to

replace those rules is given in section A.12.

The other is that the single-step relation relates one pro-

gram to multiple diﬀerent programs, each corresponding

to a legal transition that an abstract machine might take.

Accordingly we use the transitive closure of the single step

relation →

∗

to deﬁne the semantics, o, as a function from

programs ({) to sets of observable results ({):

o : { −→ 2

R

o({) = ¦O(/) [ { →

∗

/¦

where the function O turns an answer (/) from the seman-

tics into an observable result. Roughly, O is the identity

function on simple base values, and returns a special tag

for more complex values, like procedure and pairs.

So, an implementation conforms to the semantics if, for

every program {, the implementation produces one of the

results in o({) or, if the implementation loops forever,

then there is an inﬁnite reduction sequence starting at {,

assuming that the reduction relation → has been adjusted

to replace the unknown: states.

The precise deﬁnitions of {, /, {, and O are also given in

section A.2.

To help understand the semantics and how it behaves, we

have implemented it in PLT Redex. The implementation is

available at the report’s website: http://www.r6rs.org/.

All of the reduction rules and the metafunctions shown in

the ﬁgures in this semantics were generated automatically

from the source code.

A.1. Background

We assume the reader has a basic familiarity with context-

sensitive reduction semantics. Readers unfamiliar with this

system may wish to consult Felleisen and Flatt’s mono-

graph [10] or Wright and Felleisen [29] for a thorough in-

troduction, including the relevant technical background, or

an introduction to PLT Redex [19] for a somewhat lighter

one.

As a rough guide, we deﬁne the operational semantics of

a language via a relation on program terms, where the

relation corresponds to a single step of an abstract ma-

chine. The relation is deﬁned using evaluation contexts,

namely terms with a distinguished place in them, called

holes, where the next step of evaluation occurs. We say

that a term e decomposes into an evaluation context E

and another term e

**if e is the same as E but with the
**

hole replaced by e

. We write E[e

**] to indicate the term
**

obtained by replacing the hole in E with e

.

For example, assuming that we have deﬁned a grammar

containing non-terminals for evaluation contexts (E), ex-

pressions (e), variables (x), and values (v), we would write:

E

1

[((lambda (x

1

) e

1

) v

1

)] →

E

1

[¦x

1

→ v

1

¦e

1

] (#x

1

= #v

1

)

to deﬁne the β

v

rewriting rule (as a part of the → sin-

gle step relation). We use the names of the non-terminals

(possibly with subscripts) in a rewriting rule to restrict the

application of the rule, so it applies only when some term

produced by that grammar appears in the corresponding

position in the term. If the same non-terminal with an

identical subscript appears multiple times, the rule only ap-

plies when the corresponding terms are structurally identi-

cal (nonterminals without subscripts are not constrained to

match each other). Thus, the occurrence of E

1

on both the

left-hand and right-hand side of the rule above means that

the context of the application expression does not change

when using this rule. The ellipses are a form of Kleene star,

meaning that zero or more occurrences of terms matching

the pattern proceeding the ellipsis may appear in place of

the the ellipsis and the pattern preceding it. We use the

notation ¦x

1

→ v

1

¦e

1

for capture-avoiding substitu-

tion; in this case it means that each x

1

is replaced with the

corresponding v

1

in e

1

. Finally, we write side-conditions in

parentheses beside a rule; the side-condition in the above

rule indicates that the number of x

1

s must be the same

as the number of v

1

s. Sometimes we use equality in the

side-conditions; when we do it merely means simple term

equality, i.e., the two terms must have the same syntactic

shape.

Making the evaluation context E explicit in the rule allows

us to deﬁne relations that manipulate their context. As

a simple example, we can add another rule that signals a

violation when a procedure is applied to the wrong number

of arguments by discarding the evaluation context on the

62 Revised

6

Scheme

1 ::= (store (sf ) es) [ uncaught exception: v [ unknown: description

/ ::= (store (sf ) (values v )) [ uncaught exception: v [ unknown: description

1 ::= (values 1v ) [ exception [ unknown

1v ::= pair [ null [

sym [ sqv [ condition [ procedure

sf ::= (x v) [ (x bh) [ (pp (cons v v))

es ::=

seq [

sqv [

() [ (begin es es )

[ (begin0 es es ) [ (es es ) [ (if es es es) [ (set! x es) [ x [ nonproc

[ pproc [ (lambda f es es ) [ (letrec ((x es) ) es es )

[ (letrec* ((x es) ) es es ) [ (dw x es es es) [ (throw x es)

[ unspecified [ (handlers es es) [ (l! x es) [ (reinit x)

f ::= (x ) [ (x x dot x) [ x

s ::= seq [ () [ sqv [ sym

seq ::= (s s ) [ (s s dot sqv) [ (s s dot sym)

sqv ::= n [ #t [ #f

p ::= (store (sf ) e)

e ::= (begin e e ) [ (begin0 e e ) [ (e e ) [ (if e e e) [ (set! x e)

[ (handlers e e) [ x [ nonproc [ proc [ (dw x e e e) [ unspecified

[ (letrec ((x e) ) e e ) [ (letrec* ((x e) ) e e )

[ (l! x es) [ (reinit x)

v ::= nonproc [ proc

nonproc ::= pp [ null [

sym [ sqv [ (make-cond string)

proc ::= (lambda f e e ) [ pproc [ (throw x e)

pproc ::= aproc [ proc1 [ proc2 [ list [ dynamic-wind [ apply [ values

proc1 ::= null? [ pair? [ car [ cdr [ call/cc [ procedure? [ condition? [ raise*

proc2 ::= cons [ consi [ set-car! [ set-cdr! [ eqv? [ call-with-values [ with-exception-handler

aproc ::= + [ - [ / [ *

raise* ::= raise-continuable [ raise

pp ::= ip [ mp

ip ::= [immutable pair pointers]

mp ::= [mutable pair pointers]

sym ::= [variables except dot]

x ::= [variables except dot and keywords]

n ::= [numbers]

Figure A.2a: Grammar for programs and observables

right-hand side of a rule:

E[((lambda (x

1

) e) v

1

)] →

violation: wrong argument count (#x

1

= #v

1

)

Later we take advantage of the explicit evaluation context

in more sophisticated ways.

A.2. Grammar

Figure A.2a shows the grammar for the subset of the report

this semantics models. Non-terminals are written in italics

or in a calligraphic font ({ /, {, and {

v

) and literals are

written in a monospaced font.

The { non-terminal represents possible program states.

The ﬁrst alternative is a program with a store and an ex-

pression. The second alternative is an uncaught exception,

and the third is used to indicate a place where the model

does not completely specify the behavior of the primitives

it models (see section A.12 for details of those situations).

The / non-terminal represents a ﬁnal result of a program.

It is just like { except that expression has been reduced to

some sequence of values.

The { and {

v

non-terminals specify the observable re-

sults of a program. Each { is either a sequence of values

that correspond to the values produced by the program

that terminates normally, or a tag indicating an uncaught

exception was raised, or unknown if the program encoun-

Appendix A. Formal semantics 63

P ::= (store (sf ) E

)

E ::= F[(handlers proc E

)] [ F[(dw x e E

e)] [ F

E

::= [ ] [ E

E

◦

::= [ ]◦ [ E

F ::= [ ] [ (v F

◦

v ) [ (if F

◦

e e) [ (set! x F

◦

) [ (begin F

e e )

[ (begin0 F

e e ) [ (begin0 (values v ) F

e )

[ (begin0 unspecified F

e ) [ (call-with-values (lambda () F

e ) v)

[ (l! x F

◦

)

F

::= [ ] [ F

F

◦

::= [ ]◦ [ F

U ::= (v [ ] v ) [ (if [ ] e e) [ (set! x [ ]) [ (call-with-values (lambda () [ ]) v)

PG ::= (store (sf ) G)

G ::= F[(dw x e G e)] [ F

H ::= F[(handlers proc H)] [ F

S ::= [ ] [ (begin e e S es ) [ (begin S es ) [ (begin0 e e S es )

[ (begin0 S es ) [ (e S es ) [ (if S es es) [ (if e S es) [ (if e e S)

[ (set! x S) [ (handlers s S es es) [ (handlers s S) [ (throw x e)

[ (lambda f S es ) [ (lambda f e e S es )

[ (letrec ((x e) (x S) (x es) ) es es )

[ (letrec ((x e) ) S es ) [ (letrec ((x e) ) e e S es )

[ (letrec* ((x e) (x S) (x es) ) es es )

[ (letrec* ((x e) ) S es ) [ (letrec* ((x e) ) e e S es )

Figure A.2b: Grammar for evaluation contexts

ters a situation the semantics does not cover. The {

v

non-terminal speciﬁes what the observable results are for

a particular value: a pair, the empty list, a symbol, a self-

quoting value (#t, #f, and numbers), a condition, or a

procedure.

The sf non-terminal generates individual elements of the

store. The store holds all of the mutable state of a program.

It is explained in more detail along with the rules that

manipulate it.

Expressions (es) include quoted data, begin expressions,

begin0 expressions

1

, application expressions, if expres-

sions, set! expressions, variables, non-procedure values

(nonproc), primitive procedures (pproc), lambda expres-

sions, letrec and letrec* expressions.

The last few expression forms are only generated for in-

1

begin0 is not part of the standard, but we include it to make

the rules for dynamic-wind and letrec easier to read. Although we

model it directly, it can be deﬁned in terms of other forms we model

here that do come from the standard:

(begin0 e1 e2 · · · ) =

(call-with-values

(lambda () e

1

)

(lambda x

e

2

· · ·

(apply values x)))

termediate states (dw for dynamic-wind, throw for con-

tinuations, unspecified for the result of the assignment

operators, handlers for exception handlers, and l! and

reinit for letrec), and should not appear in an initial

program. Their use is described in the relevant sections of

this appendix.

The f non-terminal describes the formals for lambda ex-

pressions. (The dot is used instead of a period for pro-

cedures that accept an arbitrary number of arguments, in

order to avoid meta-circular confusion in our PLT Redex

model.)

The s non-terminal covers all datums, which can be ei-

ther non-empty sequences (seq), the empty sequence, self-

quoting values (sqv), or symbols. Non-empty sequences are

either just a sequence of datums, or they are terminated

with a dot followed by either a symbol or a self-quoting

value. Finally the self-quoting values are numbers and the

booleans #t and #f.

The p non-terminal represents programs that have no

quoted data. Most of the reduction rules rewrite p to p,

rather than { to {, since quoted data is ﬁrst rewritten into

calls to the list construction functions before ordinary eval-

uation proceeds. In parallel to es, e represents expressions

that have no quoted expressions.

64 Revised

6

Scheme

(store (sf

1

) S1[

sqv

1

])→ [6sqv]

(store (sf

1

) S1[sqv

1

])

(store (sf

1

) S1[

()])→ [6eseq]

(store (sf

1

) S1[null])

(store (sf

1

) S1[

seq

1

])→ [6qcons]

(store (sf

1

) ((lambda (qp) S1[qp]) Qiseq

1

)) (qp fresh)

(store (sf

1

) S1[

seq

1

])→ [6qconsi]

(store (sf

1

) ((lambda (qp) S1[qp]) Qmseq

1

)) (qp fresh)

Qi : seq → e

Qi() = null

Qi(s1 s2 ) = (cons Qis1 Qi(s2 ))

Qi(s1 dot sqv

1

) = (cons Qis1 sqv

1

)

Qi(s1 s2 s3 dot sqv

1

) = (cons Qis1 Qi(s2 s3 dot sqv

1

))

Qi(s1 dot sym

1

) = (cons Qis1

sym

1

)

Qi(s1 s2 s3 dot sym

1

) = (cons Qis1 Qi(s2 s3 dot sym

1

))

Qisym

1

=

sym1

Qisqv

1

= sqv

1

Qm : seq → e

Qm() = null

Qm(s1 s2 ) = (consi Qms1 Qm(s2 ))

Qm(s1 dot sqv

1

) = (consi Qms1 sqv

1

)

Qm(s1 s2 s3 dot sqv

1

) = (consi Qms1 Qm(s2 s3 dot sqv

1

))

Qm(s1 dot sym

1

) = (consi Qms1

sym

1

)

Qm(s1 s2 s3 dot sym

1

) = (consi Qms1 Qm(s2 s3 dot sym

1

))

Qmsym

1

=

sym1

Qmsqv

1

= sqv

1

Figure A.3: Quote

The values (v) are divided into four categories:

• Non-procedures (nonproc) include pair pointers (pp),

the empty list (null), symbols, self-quoting values

(sqv), and conditions. Conditions represent the re-

port’s condition values, but here just contain a mes-

sage and are otherwise inert.

• User procedures ((lambda f e e )) include multi-

arity lambda expressions and lambda expressions with

dotted parameter lists,

• Primitive procedures (pproc) include

– arithmetic procedures (aproc): +, -, /, and *,

– procedures of one argument (proc1): null?,

pair?, car, cdr, call/cc, procedure?,

condition?, unspecified?, raise, and

raise-continuable,

– procedures of two arguments (proc2):

cons, set-car!, set-cdr!, eqv?, and

call-with-values,

– as well as list, dynamic-wind, apply, values,

and with-exception-handler.

• Finally, continuations are represented as throw expres-

sions whose body consists of the context where the

continuation was grabbed.

The next three set of non-terminals in ﬁgure A.2a represent

pairs (pp), which are divided into immutable pairs (ip) and

mutable pairs (mp). The ﬁnal set of non-terminals in ﬁg-

ure A.2a, sym, x, and n represent symbols, variables, and

numbers respectively. The non-terminals ip, mp, and sym

are all assumed to all be disjoint. Additionally, the vari-

ables x are assumed not to include any keywords or prim-

itive operations, so any program variables whose names

coincide with them must be renamed before the semantics

can give the meaning of that program.

The set of non-terminals for evaluation contexts is shown

in ﬁgure A.2b. The P non-terminal controls where eval-

uation happens in a program that does not contain any

quoted data. The E and F evaluation contexts are for ex-

pressions. They are factored in that manner so that the

Appendix A. Formal semantics 65

P1[v1]→ [6promote]

P1[(values v1)]

P1[(values v1)]◦→ [6demote]

P1[v1]

P1[(call-with-values (lambda () (values v2 )) v1)]→ [6cwvd]

P1[(v1 v2 )]

P1[(call-with-values v1 v2)]→ [6cwvw]

P1[(call-with-values (lambda () (v1)) v2)] (v1 ,= (lambda () e))

Figure A.4: Multiple values and call-with-values

PG, G, and H evaluation contexts can re-use F and have

ﬁne-grained control over the context to support exceptions

and dynamic-wind. The starred and circled variants, E

,

E

◦

, F

, and F

◦

dictate where a single value is promoted

to multiple values and where multiple values are demoted

to a single value. The U context is used to manage the re-

port’s underspeciﬁcation of the results of set!, set-car!,

and set-cdr! (see section A.12 for details). Finally, the S

context is where quoted expressions can be simpliﬁed. The

precise use of the evaluation contexts is explained along

with the relevant rules.

To convert the answers (/) of the semantics into observable

results, we use these two functions:

O : / → {

O(store (sf ) (values v

1

)) =

(values O

v

v

1

)

Ouncaught exception: v =

exception

Ounknown: description =

unknown

O

v

: v → {

v

O

v

pp

1

= pair

O

v

null = null

O

v

sym

1

=

sym

1

O

v

sqv

1

= sqv

1

O

v

(make-cond string) = condition

O

v

proc = procedure

They eliminate the store, and replace complex values with

simple tags that indicate only the kind of value that was

produced or, if no values were produced, indicates that ei-

ther an uncaught exception was raised, or that the program

reached a state that is not speciﬁed by the semantics.

A.3. Quote

The ﬁrst reduction rules that apply to any program is the

rules in ﬁgure A.3 that eliminate quoted expressions. The

ﬁrst two rules erase the quote for quoted expressions that

do not introduce any pairs. The last two rules lift quoted

datums to the top of the expression so they are evaluated

only once, and turn the datums into calls to either cons or

consi, via the metafunctions Q

i

and Q

m

.

Note that the left-hand side of the [6qcons] and [6qconsi]

rules are identical, meaning that if one rule applies to a

term, so does the other rule. Accordingly, a quoted expres-

sion may be lifted out into a sequence of cons expressions,

which create mutable pairs, or into a sequence of consi

expressions, which create immutable pairs (see section A.7

for the rules on how that happens).

These rules apply before any other because of the contexts

in which they, and all of the other rules, apply. In particu-

lar, these rule applies in the S context. Figure A.2b shows

that the S context allows this reduction to apply in any

subexpression of an e, as long as all of the subexpressions

to the left have no quoted expressions in them, although

expressions to the right may have quoted expressions. Ac-

cordingly, this rule applies once for each quoted expression

in the program, moving out to the beginning of the pro-

gram. The rest of the rules apply in contexts that do not

contain any quoted expressions, ensuring that these rules

convert all quoted data into lists before those rules apply.

Although the identiﬁer qp does not have a subscript, the

semantics of PLT Redex’s “fresh” declaration takes special

care to ensures that the qp on the right-hand side of the

rule is indeed the same as the one in the side-condition.

A.4. Multiple values

The basic strategy for multiple values is to add a rule that

demotes (values v) to v and another rule that promotes

v to (values v). If we allowed these rules to apply in an

66 Revised

6

Scheme

PG[(raise* v1)]→ [6xunee]

uncaught exception: v1

P[(handlers G[(raise* v1)])]→ [6xuneh]

uncaught exception: v1

PG1[(with-exception-handler proc

1

proc

2

)]→ [6xwh1]

PG1[(handlers proc

1

(proc

2

))]

P1[(handlers proc

1

G1[(with-exception-handler proc

2

proc

3

)])]→ [6xwhn]

P1[(handlers proc

1

G1[(handlers proc

1

proc

2

(proc

3

))])]

P1[(handlers proc

1

G1[(with-exception-handler v1 v2)])]→ [6xwhne]

P1[(handlers proc

1

G1[(raise (make-cond “with-exception-handler expects procs”))])] (v1 ,∈ proc or v2 ,∈ proc)

P1[(handlers proc

1

proc

2

G1[(raise-continuable v1)])]→ [6xrc]

P1[(handlers proc

1

proc

2

G1[(handlers proc

1

(proc

2

v1))])]

P1[(handlers proc

1

proc

2

G1[(raise v1)])]→ [6xr]

P1[(handlers proc

1

proc

2

G1[(handlers proc

1

(begin (proc

2

v1) (raise (make-cond “handler returned”))))])]

P1[(condition? (make-cond string))]→ [6ct]

P1[#t]

P1[(condition? v1)]→ [6cf]

P1[#f] (v1 ,= (make-cond string))

P1[(handlers proc

1

(values v1 ))]→ [6xdone]

P1[(values v1 )]

PG1[(with-exception-handler v1 v2)]→ [6weherr]

PG1[(raise (make-cond “with-exception-handler expects procs”))] (v1 ,∈ proc or v2 ,∈ proc)

Figure A.5: Exceptions

arbitrary evaluation context, however, we would get in-

ﬁnite reduction sequences of endless alternation between

promotion and demotion. So, the semantics allows de-

motion only in a context expecting a single value and al-

lows promotion only in a context expecting multiple val-

ues. We obtain this behavior with a small extension to

the Felleisen-Hieb framework (also present in the opera-

tional model for R

5

RS [17]). We extend the notation so

that holes have names (written with a subscript), and the

context-matching syntax may also demand a hole of a par-

ticular name (also written with a subscript, for instance

E[e]

**). The extension allows us to give diﬀerent names to
**

the holes in which multiple values are expected and those in

which single values are expected, and structure the gram-

mar of contexts accordingly.

To exploit this extension, we use three kinds of holes in the

evaluation context grammar in ﬁgure A.2b. The ordinary

hole [ ] appears where the usual kinds of evaluation can

occur. The hole [ ]

**appears in contexts that allow multiple
**

values and [ ]

◦

appears in contexts that expect a single

value. Accordingly, the rule [6promote] only applies in [ ]

**contexts, and [6demote] only applies in [ ]
**

◦

contexts.

To see how the evaluation contexts are organized to ensure

that promotion and demotion occur in the right places,

consider the F, F

and F

◦

evaluation contexts. The F

and F

◦

evaluation contexts are just the same as F, except

that they allow promotion to multiple values and demotion

to a single value, respectively. So, the F evaluation con-

text, rather than being deﬁned in terms of itself, exploits

F

and F

◦

to dictate where promotion and demotion can

occur. For example, F can be (if F

◦

e e) meaning that

demotion from (values v) to v can occur in the test of

an if expression. Similarly, F can be (begin F

e e )

meaning that v can be promoted to (values v) in the ﬁrst

subexpression of a begin.

In general, the promotion and demotion rules simplify the

deﬁnitions of the other rules. For instance, the rule for if

does not need to consider multiple values in its ﬁrst subex-

pression. Similarly, the rule for begin does not need to

consider the case of a single value as its ﬁrst subexpres-

sion.

The other two rules in ﬁgure A.4 handle call-with-

values. The evaluation contexts for call-with-values

(in the F non-terminal) allow evaluation in the body of a

Appendix A. Formal semantics 67

P1[(+)] → P1[0] [6+0]

P1[(+ n1 n2 )] → P1[

Σ¦n1, n2 ¦

] [6+]

P1[(- n1)] → P1[

−n1

] [6u-]

P1[(- n1 n2 n3 )] → P1[

n1 −Σ¦n2, n3 ¦

] [6-]

P1[(-)] → P1[(raise (make-cond “arity mismatch”))] [6-arity]

P1[(*)] → P1[1] [6*1]

P1[(* n1 n2 )] → P1[

Π¦n1, n2 ¦

] [6*]

P1[(/ n1)] → P1[(/ 1 n1)] [6u/]

P1[(/ n1 n2 n3 )] → P1[

n1/Π¦n2, n3 ¦

] [6/]

(0 ,∈ ¦n2, n3, . . .¦)

P1[(/ n n 0 n )] → P1[(raise (make-cond “divison by zero”))] [6/0]

P1[(/)] → P1[(raise (make-cond “arity mismatch”))] [6/arity]

P1[(aproc v1 )] → P1[(raise (make-cond “arith-op applied to non-number”))] [6ae]

(∃v ∈ v1 s.t. v is not a number)

P1[(if v1 e1 e2)] → P1[e1] [6if3t]

(v1 ,= #f)

P1[(if #f e1 e2)] → P1[e2] [6if3f]

P1[(begin (values v ) e1 e2 )] → P1[(begin e1 e2 )] [6beginc]

P1[(begin e1)] → P1[e1] [6begind]

P1[(begin0 (values v1 ) (values v2 ) e2 )] → P1[(begin0 (values v1 ) e2 )] [6begin0n]

P1[(begin0 e1)] → P1[e1] [6begin01]

Figure A.6: Arithmetic and basic forms

procedure that has been passed as the ﬁrst argument to

call-with-values, as long as the second argument has

been reduced to a value. Once evaluation inside that pro-

cedure completes, it will produce multiple values (since it

is an F

**position), and the entire call-with-values ex-
**

pression reduces to an application of its second argument

to those values, via the rule [6cwvd]. Finally, in the case

that the ﬁrst argument to call-with-values is a value,

but is not of the form (lambda () e), the rule [6cwvw]

wraps it in a thunk to trigger evaluation.

A.5. Exceptions

The workhorses for the exception system are

(handlers proc e)

expressions and the G and PG evaluation contexts (shown

in ﬁgure A.2b). The handlers expression records the ac-

tive exception handlers (proc ) in some expression (e).

The intention is that only the nearest enclosing handlers

expression is relevant to raised exceptions, and the G and

PG evaluation contexts help achieve that goal. They are

just like their counterparts E and P, except that handlers

expressions cannot occur on the path to the hole, and the

exception system rules take advantage of that context to

ﬁnd the closest enclosing handler.

To see how the contexts work together with handler ex-

pressions, consider the left-hand side of the [6xunee] rule in

ﬁgure A.5. It matches expressions that have a call to raise

or raise-continuable (the non-terminal raise* matches

both exception-raising procedures) in a PG evaluation con-

text. Since the PG context does not contain any handlers

expressions, this exception cannot be caught, so this ex-

pression reduces to a ﬁnal state indicating the uncaught

exception. The rule [6xuneh] also signals an uncaught ex-

ception, but it covers the case where a handlers expres-

sion has exhausted all of the handlers available to it. The

rule applies to expressions that have a handlers expres-

sion (with no exception handlers) in an arbitrary evalua-

68 Revised

6

Scheme

P1[(list v1 v2 )]→ [6listc]

P1[(cons v1 (list v2 ))]

P1[(list)]→ [6listn]

P1[null]

(store (sf

1

) E1[(cons v1 v2)])→ [6cons]

(store (sf

1

(mp (cons v1 v2))) E1[mp]) (mp fresh)

(store (sf

1

) E1[(consi v1 v2)])→ [6consi]

(store (sf

1

(ip (cons v1 v2))) E1[ip]) (ip fresh)

(store (sf

1

(pp

i

(cons v1 v2)) sf

2

) E1[(car pp

i

)])→ [6car]

(store (sf

1

(pp

i

(cons v1 v2)) sf

2

) E1[v1])

(store (sf

1

(pp

i

(cons v1 v2)) sf

2

) E1[(cdr pp

i

)])→ [6cdr]

(store (sf

1

(pp

i

(cons v1 v2)) sf

2

) E1[v2])

(store (sf

1

(mp

1

(cons v1 v2)) sf

2

) E1[(set-car! mp

1

v3)])→ [6setcar]

(store (sf

1

(mp

1

(cons v3 v2)) sf

2

) E1[unspecified])

(store (sf

1

(mp

1

(cons v1 v2)) sf

2

) E1[(set-cdr! mp

1

v3)])→ [6setcdr]

(store (sf

1

(mp

1

(cons v1 v3)) sf

2

) E1[unspecified])

P1[(null? null)]→ [6null?t]

P1[#t]

P1[(null? v1)]→ [6null?f]

P1[#f] (v1 ,= null)

P1[(pair? pp)]→ [6pair?t]

P1[#t]

P1[(pair? v1)]→ [6pair?f]

P1[#f] (v1 ,∈ pp)

P1[(car vi)]→ [6care]

P1[(raise (make-cond “can’t take car of non-pair”))] (vi ,∈ pp)

P1[(cdr vi)]→ [6cdre]

P1[(raise (make-cond “can’t take cdr of non-pair”))] (vi ,∈ pp)

P1[(set-car! v1 v2)]→ [6scare]

P1[(raise (make-cond “can’t set-car! on a non-pair or an immutable pair”))] (v1 ,∈ mp)

P1[(set-cdr! v1 v2)]→ [6scdre]

P1[(raise (make-cond “can’t set-cdr! on a non-pair or an immutable pair”))] (v1 ,∈ mp)

Figure A.7: Lists

tion context where a call to one of the exception-raising

functions is nested in the handlers expression. The use of

the G evaluation context ensures that there are no other

handler expressions between this one and the raise.

The next two rules cover call to the procedure

with-exception-handler. The [6xwh1] rule applies when

there are no handler expressions. It constructs a new one

and applies v

2

as a thunk in the handler body. If there

already is a handler expression, the [6xwhn] applies. It col-

lects the current handlers and adds the new one into a new

handlers expression and, as with the previous rule, invokes

the second argument to with-exception-handlers.

The next two rules cover exceptions that are raised in

the context of a handlers expression. If a continu-

able exception is raised, [6xrc] applies. It takes the

most recently installed handler from the nearest enclos-

ing handlers expression and applies it to the argument to

raise-continuable, but in a context where the exception

handlers do not include that latest handler. The [6xr] rule

behaves similarly, except it raises a new exception if the

handler returns. The new exception is created with the

make-cond special form.

The make-cond special form is a stand-in for the report’s

conditions. It does not evaluate its argument (note its ab-

Appendix A. Formal semantics 69

P1[(eqv? v1 v1)]→ [6eqt]

P1[#t] (v1 ,∈ proc, v1 ,= (make-cond string))

P1[(eqv? v1 v2)]→ [6eqf]

P1[#f] (v1 ,= v2, v1 ,∈ proc or v2 ,∈ proc, v1 ,= (make-cond string) or v2 ,= (make-cond string))

P1[(eqv? (make-cond string) (make-cond string))]→ [6eqct]

P1[#t]

P1[(eqv? (make-cond string) (make-cond string))]→ [6eqcf]

P1[#f]

Figure A.8: Eqv

sence from the E grammar in ﬁgure A.2b). That argument

is just a literal string describing the context in which the

exception was raised. The only operation on conditions is

condition?, whose semantics are given by the two rules

[6ct] and [6cf].

Finally, the rule [6xdone] drops a handlers expression

when its body is fully evaluated, and the rule [6weherr]

raises an exception when with-exception-handler is sup-

plied with incorrect arguments.

A.6. Arithmetic and basic forms

This model does not include the report’s arithmetic, but

does include an idealized form in order to make experi-

mentation with other features and writing test suites for

the model simpler. Figure A.6 shows the reduction rules

for the primitive procedures that implement addition, sub-

traction, multiplication, and division. They defer to their

mathematical analogues. In addition, when the subtrac-

tion or divison operator are applied to no arguments, or

when division receives a zero as a divisor, or when any of

the arithmetic operations receive a non-number, an excep-

tion is raised.

The bottom half of ﬁgure A.6 shows the rules for if, begin,

and begin0. The relevant evaluation contexts are given by

the F non-terminal.

The evaluation contexts for if only allow evaluation in its

test expression. Once that is a value, the rules reduce an

if expression to its consequent if the test is not #f, and to

its alternative if it is #f.

The begin evaluation contexts allow evaluation in the ﬁrst

subexpression of a begin, but only if there are two or more

subexpressions. In that case, once the ﬁrst expression has

been fully simpliﬁed, the reduction rules drop its value.

If there is only a single subexpression, the begin itself is

dropped.

Like the begin evaluation contexts, the begin0 evaluation

contexts allow evaluation of the ﬁrst subexpression of a

begin0 expression when there are two or more subexpres-

sions. The begin0 evaluation contexts also allow evalua-

tion in the second subexpression of a begin0 expression,

as long as the ﬁrst subexpression has been fully simpliﬁed.

The [6begin0n] rule for begin0 then drops a fully simpliﬁed

second subexpression. Eventually, there is only a single ex-

pression in the begin0, at which point the [begin01] rule

ﬁres, and removes the begin0 expression.

A.7. Lists

The rules in ﬁgure A.7 handle lists. The ﬁrst two rules

handle list by reducing it to a succession of calls to cons,

followed by null.

The next two rules, [6cons] and [6consi], allocate new cons

cells. They both move (cons v

1

v

2

) into the store, bound

to a fresh pair pointer (see also section A.3 for a description

of “fresh”). The [6cons] uses a mp variable, to indicate

the pair is mutable, and the [6consi] uses a ip variable to

indicate the pair is immutable.

The rules [6car] and [6cdr] extract the components of a pair

from the store when presented with a pair pointer (the pp

can be either mp or ip, as shown in ﬁgure A.2a).

The rules [6setcar] and [6setcdr] handle assignment of mu-

table pairs. They replace the contents of the appropriate

location in the store with the new value, and reduce to

unspecified. See section A.12 for an explanation of how

unspecified reduces.

The next four rules handle the null? predicate and the

pair? predicate, and the ﬁnal four rules raise exceptions

when car, cdr, set-car! or set-cdr! receive non pairs.

A.8. Eqv

The rules for eqv? are shown in ﬁgure A.8. The ﬁrst two

rules cover most of the behavior of eqv?. The ﬁrst says that

when the two arguments to eqv? are syntactically identical,

70 Revised

6

Scheme

P1[(e1 ei e

i+1

)]→ [6mark]

P1[((lambda (x) (e1 x e

i+1

)) ei)] (x fresh, ei ,∈ v, ∃e ∈ e1 e

i+1

s.t. e ,∈ v)

(store (sf

1

) E1[((lambda (x1 x2 ) e1 e2 ) v1 v2 )])→ [6appN!]

(store (sf

1

(bp v1)) E1[(¦x1 → bp¦(lambda (x2 ) e1 e2 ) v2 )])

(bp fresh, #x2 = #v2, V x1, (lambda (x2 ) e1 e2 ))

P1[((lambda (x1 x2 ) e1 e2 ) v1 v2 )]→ [6appN]

P1[(¦x1 → v1¦(lambda (x2 ) e1 e2 ) v2 )] (#x2 = #v2, V x1, (lambda (x2 ) e1 e2 ))

P1[((lambda () e1 e2 ))]→ [6app0]

P1[(begin e1 e2 )]

P1[((lambda (x1 x2 dot xr) e1 e2 ) v1 v2 v3 )]→ [6µapp]

P1[((lambda (x1 x2 xr) e1 e2 ) v1 v2 (list v3 ))] (#x2 = #v2)

P1[((lambda x1 e1 e2 ) v1 )]→ [6µapp1]

P1[((lambda (x1) e1 e2 ) (list v1 ))]

(store (sf

1

(x1 v1) sf

2

) E1[x1])→ [6var]

(store (sf

1

(x1 v1) sf

2

) E1[v1])

(store (sf

1

(x1 v1) sf

2

) E1[(set! x1 v2)])→ [6set]

(store (sf

1

(x1 v2) sf

2

) E1[unspecified])

P1[(procedure? proc)]→ [6proct]

P1[#t]

P1[(procedure? nonproc)]→ [6procf]

P1[#f]

P1[((lambda (x1 ) e e ) v1 )]→ [6arity]

P1[(raise (make-cond “arity mismatch”))] (#x1 ,= #v1)

P1[((lambda (x1 x2 dot x) e e ) v1 )]→ [6µarity]

P1[(raise (make-cond “arity mismatch”))] (#v1 < #x2 + 1)

P1[(nonproc v )]→ [6appe]

P1[(raise (make-cond “can’t call non-procedure”))]

P1[(proc1 v1 )]→ [61arity]

P1[(raise (make-cond “arity mismatch”))] (#v1 ,= 1)

P1[(proc2 v1 )]→ [62arity]

P1[(raise (make-cond “arity mismatch”))] (#v1 ,= 2)

Figure A.9a: Procedures & application

then eqv? produces #t and the second says that when the

arguments are not syntactically identical, then eqv? pro-

duces #f. The structure of v has been carefully designed

so that simple term equality corresponds closely to eqv?’s

behavior. For example, pairs are represented as pointers

into the store and eqv? only compares those pointers.

The side-conditions on those ﬁrst two rules ensure that

they do not apply when simple term equality does not

match the behavior of eqv?. There are two situations

where it does not match: comparing two conditions and

comparing two procedures. For the ﬁrst, the report does

not specify eqv?’s behavior, except to say that it must re-

turn a boolean, so the remaining two rules ([6eqct], and

[6eqcf]) allow such comparisons to return #t or #f. Com-

paring two procedures is covered in section A.12.

A.9. Procedures and application

In evaluating a procedure call, the report leaves unspeci-

ﬁed the order in which arguments are evaluated. So, our

reduction system allows multiple, diﬀerent reductions to

occur, one for each possible order of evaluation.

To capture unspeciﬁed evaluation order but allow only

evaluation that is consistent with some sequential order-

ing of the evaluation of an application’s subexpressions,

Appendix A. Formal semantics 71

V ∈ 2

x×e

V x1, (set! x2 e1) if x1 = x2

V x1, (set! x2 e1) if V x1, e1 and x1 ,= x2

V x1, (begin e1 e2 e3 ) if V x1, e1 or V x1, (begin e2 e3 )

V x1, (begin e1) if V x1, e1

V x1, (e1 e2 ) if V x1, (begin e1 e2 )

V x1, (if e1 e2 e3) if V x1, e1 or V x1, e2 or V x1, e3

V x1, (begin0 e1 e2 ) if V x1, (begin e1 e2 )

V x1, (lambda (x2 ) e1 e2 ) if V x1, (begin e1 e2 ) and x1 ,∈ ¦x2 ¦

V x1, (lambda (x2 dot x3) e1 e2 ) if V x1, (begin e1 e2 ) and x1 ,∈ ¦x2 x3¦

V x1, (lambda x2 e1 e2 ) if V x1, (begin e1 e2 ) and x1 ,= x2

V x1, (letrec ((x2 e1) ) e2 e3 ) if V x1, (begin e1 e2 e3 ) and x1 ,∈ ¦x2 ¦

V x1, (letrec* ((x2 e1) ) e2 e3 ) if V x1, (begin e1 e2 e3 ) and x1 ,∈ ¦x2 ¦

V x1, (l! x2 e1) if V x1, (set! x2 e1)

V x1, (reinit x2 e1) if V x1, (set! x2 e1)

V x1, (dw x2 e1 e2 e3) if V x1, e1 or V x1, e2 or V x1, e3

Figure A.9b: Variable-assignment relation

we use non-deterministic choice to ﬁrst pick a subexpres-

sion to reduce only when we have not already committed

to reducing some other subexpression. To achieve that ef-

fect, we limit the evaluation of application expressions to

only those that have a single expression that is not fully

reduced, as shown in the non-terminal F, in ﬁgure A.2b.

To evaluate application expressions that have more than

two arguments to evaluate, the rule [6mark] picks one of

the subexpressions of an application that is not fully sim-

pliﬁed and lifts it out in its own application, allowing it to

be evaluated. Once one of the lifted expressions is evalu-

ated, the [6appN] substitutes its value back into the original

application.

The [6appN] rule also handles other applications whose ar-

guments are ﬁnished by substituting the ﬁrst argument

for the ﬁrst formal parameter in the expression. Its side-

condition uses the relation in ﬁgure A.9b to ensure that

there are no set! expressions with the parameter x

1

as a

target. If there is such an assignment, the [6appN!] rule ap-

plies (see also section A.3 for a description of “fresh”). In-

stead of directly substituting the actual parameter for the

formal parameter, it creates a new location in the store,

initially bound the actual parameter, and substitutes a

variable standing for that location in place of the formal

parameter. The store, then, handles any eventual assign-

ment to the parameter. Once all of the parameters have

been substituted away, the rule [6app0] applies and evalu-

ation of the body of the procedure begins.

At ﬁrst glance, the rule [6appN] appears superﬂuous, since

it seems like the rules could just reduce ﬁrst by [6appN!]

and then look up the variable when it is evaluated. There

are two reasons why we keep the [6appN], however. The

ﬁrst is purely conventional: reducing applications via sub-

stitution is taught to us at an early age and is commonly

used in rewriting systems in the literature. The second

reason is more technical: the [6mark] rule requires that

[6appN] be applied once e

i

has been reduced to a value.

[6appN!] would lift the value into the store and put a vari-

able reference into the application, leading to another use

of [6mark], and another use of [6appN!], which continues

forever.

The rule [6µapp] handles a well-formed application of a

function with a dotted parameter lists. It such an applica-

tion into an application of an ordinary procedure by con-

structing a list of the extra arguments. Similarly, the rule

[6µapp1] handles an application of a procedure that has a

single variable as its parameter list.

The rule [6var] handles variable lookup in the store and

[6set] handles variable assignment.

The next two rules [6proct] and [6procf] handle applications

of procedure?, and the remaining rules cover applications

of non-procedures and arity violations.

The rules in ﬁgure A.9c cover apply. The ﬁrst rule, [6ap-

plyf], covers the case where the last argument to apply is

the empty list, and simply reduces by erasing the empty

list and the apply. The second rule, [6applyc] covers a well-

formed application of apply where apply’s ﬁnal argument

is a pair. It reduces by extracting the components of the

pair from the store and putting them into the application

of apply. Repeated application of this rule thus extracts

all of the list elements passed to apply out of the store.

The remaining ﬁve rules cover the various violations that

can occur when using apply. The ﬁrst one covers the case

where apply is supplied with a cyclic list. The next four

cover applying a non-procedure, passing a non-list as the

last argument, and supplying too few arguments to apply.

72 Revised

6

Scheme

P1[(apply proc

1

v1 null)]→ [6applyf]

P1[(proc

1

v1 )]

(store (sf

1

(pp

1

(cons v2 v3)) sf

2

) E1[(apply proc

1

v1 pp

1

)])→ [6applyc]

(store (sf

1

(pp

1

(cons v2 v3)) sf

2

) E1[(apply proc

1

v1 v2 v3)])

(Cpp

1

, v3, (sf

1

(pp

1

(cons v2 v3)) sf

2

))

(store (sf

1

(pp

1

(cons v2 v3)) sf

2

) E1[(apply proc

1

v1 pp

1

)])→ [6applyce]

(store (sf

1

(pp

1

(cons v2 v3)) sf

2

) E1[(raise (make-cond “apply called on circular list”))])

(Cpp

1

, v3, (sf

1

(pp

1

(cons v2 v3)) sf

2

))

P1[(apply nonproc v )]→ [6applynf]

P1[(raise (make-cond “can’t apply non-procedure”))]

P1[(apply proc v1 v2)]→ [6applye]

P1[(raise (make-cond “apply’s last argument non-list”))] (v2 ,∈ list-v)

P1[(apply)]→ [6apparity0]

P1[(raise (make-cond “arity mismatch”))]

P1[(apply v)]→ [6apparity1]

P1[(raise (make-cond “arity mismatch”))]

C ∈ 2

pp×val ×(sf ···)

Cpp

1

, pp

2

, (sf

1

(pp

2

(cons v1 v2)) sf

2

) if pp

1

= v2

Cpp

1

, pp

2

, (sf

1

(pp

2

(cons v1 v2)) sf

2

) if Cpp

1

, v2, (sf

1

(pp

2

(cons v1 v2)) sf

2

) and pp

1

,= v2

Figure A.9c: Apply

A.10. Call/cc and dynamic wind

The speciﬁcation of dynamic-wind uses (dw x e e e) ex-

pressions to record which dynamic-wind thunks are active

at each point in the computation. Its ﬁrst argument is

an identiﬁer that is globally unique and serves to iden-

tify invocations of dynamic-wind, in order to avoid exiting

and re-entering the same dynamic context during a con-

tinuation switch. The second, third, and fourth arguments

are calls to some before, thunk, and after procedures from

a call to dynamic-wind. Evaluation only occurs in the

middle expression; the dw expression only serves to record

which before and after procedures need to be run during a

continuation switch. Accordingly, the reduction rule for an

application of dynamic-wind reduces to a call to the before

procedure, a dw expression and a call to the after proce-

dure, as shown in rule [6wind] in ﬁgure A.10. The next two

rules cover abuses of the dynamic-wind procedure: call-

ing it with non-procedures, and calling it with the wrong

number of arguments. The [6dwdone] rule erases a dw ex-

pression when its second argument has ﬁnished evaluating.

The next two rules cover call/cc. The rule [6call/cc]

creates a new continuation. It takes the context of the

call/cc expression and packages it up into a throw ex-

pression that represents the continuation. The throw ex-

pression uses the fresh variable x to record where the ap-

plication of call/cc occurred in the context for use in the

[6throw] rule when the continuation is applied. That rule

takes the arguments of the continuation, wraps them with

a call to values, and puts them back into the place where

the original call to call/cc occurred, replacing the current

context with the context returned by the T metafunction.

The T (for “trim”) metafunction accepts two D contexts

and builds a context that matches its second argument,

the destination context, except that additional calls to the

before and after procedures from dw expressions in the con-

text have been added.

The ﬁrst clause of the T metafunction exploits the H con-

text, a context that contains everything except dw expres-

sions. It ensures that shared parts of the dynamic-wind

context are ignored, recurring deeper into the two expres-

sion contexts as long as the ﬁrst dw expression in each have

matching identiﬁers (x

1

). The ﬁnal rule is a catchall; it

only applies when all the others fail and thus applies ei-

ther when there are no dws in the context, or when the dw

expressions do not match. It calls the two other metafunc-

tions deﬁned in ﬁgure A.10 and puts their results together

into a begin expression.

The R metafunction extracts all of the before procedures

from its argument and the S metafunction extracts all of

the after procedures from its argument. They each con-

struct new contexts and exploit H to work through their

arguments, one dw at a time. In each case, the metafunc-

tions are careful to keep the right dw context around each of

Appendix A. Formal semantics 73

P1[(dynamic-wind proc

1

proc

2

proc

3

)]→ [6wind]

P1[(begin (proc

1

) (begin0 (dw x (proc

1

) (proc

2

) (proc

3

)) (proc

3

)))] (x fresh)

P1[(dynamic-wind v1 v2 v3)]→ [6winde]

P1[(raise (make-cond “dynamic-wind expects procs”))] (v1 ,∈ proc or v2 ,∈ proc or v3 ,∈ proc)

P1[(dynamic-wind v1 )]→ [6dwarity]

P1[(raise (make-cond “arity mismatch”))] (#v1 ,= 3)

P1[(dw x e (values v1 ) e)]→ [6dwdone]

P1[(values v1 )]

(store (sf

1

) E1[(call/cc v1)])→ [6call/cc]

(store (sf

1

) E1[(v1 (throw x E1[x]))]) (x fresh)

(store (sf

1

) E1[((throw x1 E2[x1]) v1 )])→ [6throw]

(store (sf

1

) T E1, E2[(values v1 )])

T : E E → E

T H1[(dw x1 e1 E1 e2)], H2[(dw x1 e3 E2 e4)] = H2[(dw x1 e3 T E1, E2 e4)]

T E1, E2 = (begin SE1[1] RE2) (otherwise)

R : E → E

RH1[(dw x1 e1 E1 e2)] = H1[(begin e1 (dw x1 e1 RE1 e2))]

RH1 = H1 (otherwise)

S : E → E

SE1[(dw x1 e1 H2 e2)] = SE1[(begin0 (dw x1 e1 [ ] e2) e2)]

SH1 = [ ] (otherwise)

Figure A.10: Call/cc and dynamic wind

the procedures in case a continuation jump occurs during

one of their evaluations. Since R, receives the destination

context, it keeps the intermediate parts of the context in

its result. In contrast S discards all of the context except

the dws, since that was the context where the call to the

continuation occurred.

A.11. Letrec

Figre A.11 shows the rules that handle letrec and

letrec* and the supplementary expressions that they pro-

duce, l! and reinit. As a ﬁrst approximation, both

letrec and letrec* reduce by allocating locations in the

store to hold the values of the init expressions, initializing

those locations to bh (for “black hole”), evaluating the init

expressions, and then using l! to update the locations in

the store with the value of the init expressions. They also

use reinit to detect when an init expression in a letrec is

reentered via a continuation.

Before considering how letrec and letrec* use l! and

reinit, ﬁrst consider how l! and reinit behave. The

ﬁrst two rules in ﬁgure A.11 cover l!. It behaves very

much like set!, but it initializes both ordinary variables,

and variables that are current bound to the black hole (bh).

The next two rules cover ordinary set! when applied to

a variable that is currently bound to a black hole. This

situation can arise when the program assigns to a variable

before letrec initializes it, eg (letrec ((x (set! x 5)))

x). The report speciﬁes that either an implementation

should perform the assignment, as reﬂected in the [6setdt]

rule or it raise an exception, as reﬂected in the [6setdte]

rule.

The [6dt] rule covers the case where a variable is referred

to before the value of a init expression is ﬁlled in, which

must always raise an exception.

A reinit expression is used to detect a program that cap-

tures a continuation in an initialization expression and re-

turns to it, as shown in the three rules [6init], [6reinit], and

[6reinite]. The reinit form accepts an identiﬁer that is

bound in the store to a boolean as its argument. Those

are identiﬁers are initially #f. When reinit is evaluated,

it checks the value of the variable and, if it is still #f, it

changes it to #t. If it is already #t, then reinit either just

does nothing, or it raises an exception, in keeping with the

two legal behaviors of letrec and letrec*.

74 Revised

6

Scheme

(store (sf

1

(x1 bh) sf

2

) E1[(l! x1 v2)])→ [6initdt]

(store (sf

1

(x1 v2) sf

2

) E1[unspecified])

(store (sf

1

(x1 v1) sf

2

) E1[(l! x1 v2)])→ [6initv]

(store (sf

1

(x1 v2) sf

2

) E1[unspecified])

(store (sf

1

(x1 bh) sf

2

) E1[(set! x1 v1)])→ [6setdt]

(store (sf

1

(x1 v1) sf

2

) E1[unspecified])

(store (sf

1

(x1 bh) sf

2

) E1[(set! x1 v1)])→ [6setdte]

(store (sf

1

(x1 bh) sf

2

) E1[(raise (make-cond “letrec variable touched”))])

(store (sf

1

(x1 bh) sf

2

) E1[x1])→ [6dt]

(store (sf

1

(x1 bh) sf

2

) E1[(raise (make-cond “letrec variable touched”))])

(store (sf

1

(x1 #f) sf

2

) E1[(reinit x1)])→ [6init]

(store (sf

1

(x1 #t) sf

2

) E1[

ignore])

(store (sf

1

(x1 #t) sf

2

) E1[(reinit x1)])→ [6reinit]

(store (sf

1

(x1 #t) sf

2

) E1[

ignore])

(store (sf

1

(x1 #t) sf

2

) E1[(reinit x1)])→ [6reinite]

(store (sf

1

(x1 #t) sf

2

) E1[(raise (make-cond “reinvoked continuation of letrec init”))])

(store (sf

1

) E1[(letrec ((x1 e1) ) e2 e3 )])→ [6letrec]

(store (sf

1

(lx bh) (ri #f) )

E1[((lambda (x1 ) (l! lx x1) ¦x1 → lx ¦e2 ¦x1 → lx ¦e3 )

(begin0 ¦x1 → lx ¦e1 (reinit ri )) )])

(lx fresh, ri fresh)

(store (sf

1

) E1[(letrec* ((x1 e1) ) e2 e3 )])→ [6letrec*]

(store (sf

1

(lx bh) (ri #f) ) E1[¦x1 → lx ¦(begin (begin (l! lx e1) (reinit ri )) e2 e3 )])

(lx fresh, ri fresh)

Figure A.11: Letrec and letrec*

The last two rules in ﬁgure A.11 put together l! and

reinit. The [6letrec] rule reduces a letrec expression

to an application expression, in order to capture the un-

speciﬁed order of evaluation of the init expressions. Each

init expression is wrapped in a begin0 that records the

value of the init and then uses reinit to detect continu-

ations that return to the init expression. Once all of the

init expressions have been evaluated, the procedure on the

right-hand side of the rule is invoked, causing the value of

the init expression to be ﬁlled in the store, and evaluation

continues with the body of the original letrec expression.

The [6letrec*] rule behaves similarly, but uses a begin ex-

pression rather than an application, since the init expres-

sions are evaluated from left to right. Moreover, each init

expression is ﬁlled into the store as it is evaluated, so that

subsequent init expressions can refer to its value.

A.12. Underspeciﬁcation

The rules in ﬁgure A.12 cover aspects of the semantics that

are explicitly unspeciﬁed. Implementations can replace the

rules [6ueqv], [6uval] and with diﬀerent rules that cover the

left-hand sides and, as long as they follow the informal

speciﬁcation, any replacement is valid. Those three situ-

ations correspond to the case when eqv? applied to two

procedures and when multiple values are used in a single-

value context.

The remaining rules in ﬁgure A.12 cover the results from

the assignment operations, set!, set-car!, and set-cdr!.

An implementation does not adjust those rules, but instead

renders them useless by adjusting the rules that insert

unspecified: [6setcar], [6setcdr], [6set], and [6setd]. Those

rules can be adjusted by replacing unspecified with any

number of values in those rules.

So, the remaining rules just specify the minimal behav-

ior that we know that a value or values must have and

otherwise reduce to an unknown: state. The rule [6ude-

mand] drops unspecified in the U context. See ﬁgure A.2b

for the precise deﬁnition of U, but intuitively it is a con-

text that is only a single expression layer deep that con-

tains expressions whose value depends on the value of their

subexpressions, like the ﬁrst subexpression of a if. Follow-

ing that are rules that discard unspecified in expressions

Appendix B. Sample deﬁnitions for derived forms 75

P[(eqv? proc proc)] → unknown: equivalence of procedures [6ueqv]

P[(values v1 )]◦ → unknown: context expected one value, received #v1 [6uval]

(#v1 ,= 1)

P[U[unspecified]] → unknown: unspeciﬁed result [6udemand]

(store (sf ) unspecified) → unknown: unspeciﬁed result [6udemandtl]

P1[(begin unspecified e1 e2 )] → P1[(begin e1 e2 )] [6ubegin]

P1[(handlers v unspecified)] → P1[unspecified] [6uhandlers]

P1[(dw x e unspecified e)] → P1[unspecified] [6udw]

P1[(begin0 (values v1 ) unspecified e1 )] → P1[(begin0 (values v1 ) e1 )] [6ubegin0]

P1[(begin0 unspecified (values v2 ) e2 )] → P1[(begin0 unspecified e2 )] [6ubegin0u]

P1[(begin0 unspecified unspecified e2 )] → P1[(begin0 unspecified e2 )] [6ubegin0uu]

Figure A.12: Explicitly unspeciﬁed behavior

that discard the results of some of their subexpressions.

The [6ubegin] shows how begin discards its ﬁrst expres-

sion when there are more expressions to evaluate. The next

two rules, [6uhandlers] and [6udw] propagate unspecified

to their context, since they also return any number of val-

ues to their context. Finally, the two begin0 rules preserve

unspecified until the rule [6begin01] can return it to its

context.

Appendix B. Sample deﬁnitions for de-

rived forms

This appendix contains sample deﬁnitions for some of the

keywords described in this report in terms of simpler forms:

cond

The cond keyword (section 11.4.5) could be deﬁned in

terms of if, let and begin using syntax-rules as fol-

lows:

(define-syntax cond

(syntax-rules (else =>)

((cond (else result1 result2 ...))

(begin result1 result2 ...))

((cond (test => result))

(let ((temp test))

(if temp (result temp))))

((cond (test => result) clause1 clause2 ...)

(let ((temp test))

(if temp

(result temp)

(cond clause1 clause2 ...))))

((cond (test)) test)

((cond (test) clause1 clause2 ...)

(let ((temp test))

(if temp

temp

(cond clause1 clause2 ...))))

((cond (test result1 result2 ...))

(if test (begin result1 result2 ...)))

((cond (test result1 result2 ...)

clause1 clause2 ...)

(if test

(begin result1 result2 ...)

(cond clause1 clause2 ...)))))

case

The case keyword (section 11.4.5) could be deﬁned in

terms of let, cond, and memv (see library chapter 3) using

syntax-rules as follows:

(define-syntax case

(syntax-rules (else)

((case expr0

((key ...) res1 res2 ...)

...

(else else-res1 else-res2 ...))

(let ((tmp expr0))

(cond

((memv tmp ’(key ...)) res1 res2 ...)

...

(else else-res1 else-res2 ...))))

((case expr0

((keya ...) res1a res2a ...)

((keyb ...) res1b res2b ...)

...)

(let ((tmp expr0))

(cond

((memv tmp ’(keya ...)) res1a res2a ...)

((memv tmp ’(keyb ...)) res1b res2b ...)

...)))))

76 Revised

6

Scheme

let*

The let* keyword (section 11.4.6) could be deﬁned in

terms of let using syntax-rules as follows:

(define-syntax let*

(syntax-rules ()

((let* () body1 body2 ...)

(let () body1 body2 ...))

((let* ((name1 expr1) (name2 expr2) ...)

body1 body2 ...)

(let ((name1 expr1))

(let* ((name2 expr2) ...)

body1 body2 ...)))))

letrec

The letrec keyword (section 11.4.6) could be deﬁned ap-

proximately in terms of let and set! using syntax-rules,

using a helper to generate the temporary variables needed

to hold the values before the assignments are made, as fol-

lows:

(define-syntax letrec

(syntax-rules ()

((letrec () body1 body2 ...)

(let () body1 body2 ...))

((letrec ((var init) ...) body1 body2 ...)

(letrec-helper

(var ...)

()

((var init) ...)

body1 body2 ...))))

(define-syntax letrec-helper

(syntax-rules ()

((letrec-helper

()

(temp ...)

((var init) ...)

body1 body2 ...)

(let ((var <undefined>) ...)

(let ((temp init) ...)

(set! var temp)

...)

(let () body1 body2 ...)))

((letrec-helper

(x y ...)

(temp ...)

((var init) ...)

body1 body2 ...)

(letrec-helper

(y ...)

(newtemp temp ...)

((var init) ...)

body1 body2 ...))))

The syntax <undefined> represents an expression that re-

turns something that, when stored in a location, causes an

exception with condition type &assertion to be raised if

an attempt to read from or write to the location occurs be-

fore the assignments generated by the letrec transforma-

tion take place. (No such expression is deﬁned in Scheme.)

A simpler deﬁnition using syntax-case and generate-

temporaries is given in library chapter 12.

letrec*

The letrec* keyword could be deﬁned approximately in

terms of let and set! using syntax-rules as follows:

(define-syntax letrec*

(syntax-rules ()

((letrec* ((var1 init1) ...) body1 body2 ...)

(let ((var1 <undefined>) ...)

(set! var1 init1)

...

(let () body1 body2 ...)))))

The syntax <undefined> is as in the deﬁnition of letrec

above.

let-values

The following deﬁnition of let-values (section 11.4.6) us-

ing syntax-rules employs a pair of helpers to create tem-

porary names for the formals.

(define-syntax let-values

(syntax-rules ()

((let-values (binding ...) body1 body2 ...)

(let-values-helper1

()

(binding ...)

body1 body2 ...))))

(define-syntax let-values-helper1

;; map over the bindings

(syntax-rules ()

((let-values

((id temp) ...)

()

body1 body2 ...)

(let ((id temp) ...) body1 body2 ...))

((let-values

assocs

((formals1 expr1) (formals2 expr2) ...)

body1 body2 ...)

(let-values-helper2

formals1

()

expr1

assocs

((formals2 expr2) ...)

body1 body2 ...))))

(define-syntax let-values-helper2

;; create temporaries for the formals

(syntax-rules ()

Appendix C. Additional material 77

((let-values-helper2

()

temp-formals

expr1

assocs

bindings

body1 body2 ...)

(call-with-values

(lambda () expr1)

(lambda temp-formals

(let-values-helper1

assocs

bindings

body1 body2 ...))))

((let-values-helper2

(first . rest)

(temp ...)

expr1

(assoc ...)

bindings

body1 body2 ...)

(let-values-helper2

rest

(temp ... newtemp)

expr1

(assoc ... (first newtemp))

bindings

body1 body2 ...))

((let-values-helper2

rest-formal

(temp ...)

expr1

(assoc ...)

bindings

body1 body2 ...)

(call-with-values

(lambda () expr1)

(lambda (temp ... . newtemp)

(let-values-helper1

(assoc ... (rest-formal newtemp))

bindings

body1 body2 ...))))))

let*-values

The following macro deﬁnes let*-values in terms of let

and let-values using syntax-rules:

(define-syntax let*-values

(syntax-rules ()

((let*-values () body1 body2 ...)

(let () body1 body2 ...))

((let*-values (binding1 binding2 ...)

body1 body2 ...)

(let-values (binding1)

(let*-values (binding2 ...)

body1 body2 ...)))))

let

The let keyword could be deﬁned in terms of lambda and

letrec using syntax-rules as follows:

(define-syntax let

(syntax-rules ()

((let ((name val) ...) body1 body2 ...)

((lambda (name ...) body1 body2 ...)

val ...))

((let tag ((name val) ...) body1 body2 ...)

((letrec ((tag (lambda (name ...)

body1 body2 ...)))

tag)

val ...))))

Appendix C. Additional material

This report itself, as well as more material related to this

report such as reference implementations of some parts of

Scheme and archives of mailing lists discussing this report

is at

http://www.r6rs.org/

The Schemers web site at

http://www.schemers.org/

as well as the Readscheme site at

http://library.readscheme.org/

contain extensive Scheme bibliographies, as well as papers,

programs, implementations, and other material related to

Scheme.

Appendix D. Example

This section describes an example consisting of

the (runge-kutta) library, which provides an

integrate-system procedure that integrates the system

y

k

= f

k

(y

1

, y

2

, . . . , y

n

), k = 1, . . . , n

of diﬀerential equations with the method of Runge-Kutta.

As the (runge-kutta) library makes use of the (rnrs

base (6)) library, its skeleton is as follows:

#!r6rs

(library (runge-kutta)

(export integrate-system

head tail)

(import (rnrs base))

'library body))

The procedure deﬁnitions described below go in the place

of 'library body`.

78 Revised

6

Scheme

The parameter system-derivative is a function that

takes a system state (a vector of values for the state vari-

ables y

1

, . . . , y

n

) and produces a system derivative (the val-

ues y

1

, . . . , y

n

). The parameter initial-state provides

an initial system state, and h is an initial guess for the

length of the integration step.

The value returned by integrate-system is an inﬁnite

stream of system states.

(define integrate-system

(lambda (system-derivative initial-state h)

(let ((next (runge-kutta-4 system-derivative h)))

(letrec ((states

(cons initial-state

(lambda ()

(map-streams next states)))))

states))))

The runge-kutta-4 procedure takes a function, f, that

produces a system derivative from a system state. The

runge-kutta-4 procedure produces a function that takes

a system state and produces a new system state.

(define runge-kutta-4

(lambda (f h)

(let ((*h (scale-vector h))

(*2 (scale-vector 2))

(*1/2 (scale-vector (/ 1 2)))

(*1/6 (scale-vector (/ 1 6))))

(lambda (y)

;; y is a system state

(let* ((k0 (*h (f y)))

(k1 (*h (f (add-vectors y (*1/2 k0)))))

(k2 (*h (f (add-vectors y (*1/2 k1)))))

(k3 (*h (f (add-vectors y k2)))))

(add-vectors y

(*1/6 (add-vectors k0

(*2 k1)

(*2 k2)

k3))))))))

(define elementwise

(lambda (f)

(lambda vectors

(generate-vector

(vector-length (car vectors))

(lambda (i)

(apply f

(map (lambda (v) (vector-ref v i))

vectors)))))))

(define generate-vector

(lambda (size proc)

(let ((ans (make-vector size)))

(letrec ((loop

(lambda (i)

(cond ((= i size) ans)

(else

(vector-set! ans i (proc i))

(loop (+ i 1)))))))

(loop 0)))))

(define add-vectors (elementwise +))

(define scale-vector

(lambda (s)

(elementwise (lambda (x) (* x s)))))

The map-streams procedure is analogous to map: it applies

its ﬁrst argument (a procedure) to all the elements of its

second argument (a stream).

(define map-streams

(lambda (f s)

(cons (f (head s))

(lambda () (map-streams f (tail s))))))

Inﬁnite streams are implemented as pairs whose car holds

the ﬁrst element of the stream and whose cdr holds a pro-

cedure that delivers the rest of the stream.

(define head car)

(define tail

(lambda (stream) ((cdr stream))))

The following program illustrates the use of integrate-

system in integrating the system

C

dv

C

dt

= −i

L

−

v

C

R

L

di

L

dt

= v

C

which models a damped oscillator.

#!r6rs

(import (rnrs base)

(rnrs io simple)

(runge-kutta))

(define damped-oscillator

(lambda (R L C)

(lambda (state)

(let ((Vc (vector-ref state 0))

(Il (vector-ref state 1)))

(vector (- 0 (+ (/ Vc (* R C)) (/ Il C)))

(/ Vc L))))))

(define the-states

(integrate-system

(damped-oscillator 10000 1000 .001)

’#(1 0)

.01))

(letrec ((loop (lambda (s)

(newline)

(write (head s))

(loop (tail s)))))

(loop the-states))

This prints output like the following:

Appendix E. Language changes 79

#(1 0)

#(0.99895054 9.994835e-6)

#(0.99780226 1.9978681e-5)

#(0.9965554 2.9950552e-5)

#(0.9952102 3.990946e-5)

#(0.99376684 4.985443e-5)

#(0.99222565 5.9784474e-5)

#(0.9905868 6.969862e-5)

#(0.9888506 7.9595884e-5)

#(0.9870173 8.94753e-5)

Appendix E. Language changes

This chapter describes most of the changes that have been

made to Scheme since the “Revised

5

Report” [14] was pub-

lished:

• Scheme source code now uses the Unicode character

set. Speciﬁcally, the character set that can be used

for identiﬁers has been greatly expanded.

• Identiﬁers can now start with the characters ->.

• Identiﬁers and symbol literals are now case-sensitive.

• Identiﬁers and representations of characters, booleans,

number objects, and . must be explicitly delimited.

• # is now a delimiter.

• Bytevector literal syntax has been added.

• Matched square brackets can be used synonymously

with parentheses.

• The read-syntax abbreviations #’ (for syntax), #`

(for quasisyntax), #, (for unsyntax), and #,@

(for unsyntax-splicing have been added; see sec-

tion 4.3.5.)

• # can no longer be used in place of digits in number

representations.

• The external representation of number objects can

now include a mantissa width.

• Literals for NaNs and inﬁnities were added.

• String and character literals can now use a variety of

escape sequences.

• Block and datum comments have been added.

• The #!r6rs comment for marking report-compliant

lexical syntax has been added.

• Characters are now speciﬁed to correspond to Unicode

scalar values.

• Many of the procedures and syntactic forms of the lan-

guage are now part of the (rnrs base (6)) library.

Some procedures and syntactic forms have been moved

to other libraries; see ﬁgure A.1.

• The base language has the following new proce-

dures and syntactic forms: letrec*, let-values,

let*-values, real-valued?, rational-valued?,

integer-valued?, exact, inexact, finite?,

infinite?, nan?, div, mod, div-and-mod, div0, mod0,

div0-and-mod0, exact-integer-sqrt, boolean=?,

symbol=?, string-for-each, vector-map, vector-

for-each, error, assertion-violation, assert,

call/cc, identifier-syntax.

• The following procedures have been removed: char-

ready?, transcript-on, transcript-off, load.

• The case-insensitive string comparisons (string-

ci=?, string-ci<?, string-ci>?, string-ci<=?,

string-ci>=?) operate on the case-folded versions of

the strings rather than as the simple lexicographic or-

dering induced by the corresponding character com-

parison procedures.

• Libraries have been added to the language.

• A number of standard libraries are described in a sep-

arate report [24].

• Many situations that “were an error” now have deﬁned

or constrained behavior. In particular, many are now

speciﬁed in terms of the exception system.

• The full numerical tower is now required.

• The semantics for the transcendental functions has

been speciﬁed more fully.

• The semantics of expt for zero bases has been reﬁned.

• In syntax-rules forms, a may be used in place of

the keyword.

• The let-syntax and letrec-syntax no longer intro-

duce a new environment for their bodies.

• For implementations that support NaNs or inﬁnities,

many arithmetic operations have been speciﬁed on

these values consistently with IEEE 754.

• For implementations that support a distinct -0.0, the

semantics of many arithmetic operations with regard

to -0.0 has been speciﬁed consistently with IEEE 754.

• Scheme’s real number objects now have an exact zero

as their imaginary part.

• The speciﬁcation of quasiquote has been extended.

Nested quasiquotations work correctly now, and

unquote and unquote-splicing have been extended

to several operands.

80 Revised

6

Scheme

identiﬁer moved to

assoc (rnrs lists (6))

assv (rnrs lists (6))

assq (rnrs lists (6))

call-with-input-file (rnrs io simple (6))

call-with-output-file (rnrs io simple (6))

char-upcase (rnrs unicode (6))

char-downcase (rnrs unicode (6))

char-ci=? (rnrs unicode (6))

char-ci<? (rnrs unicode (6))

char-ci>? (rnrs unicode (6))

char-ci<=? (rnrs unicode (6))

char-ci>=? (rnrs unicode (6))

char-alphabetic? (rnrs unicode (6))

char-numeric? (rnrs unicode (6))

char-whitespace? (rnrs unicode (6))

char-upper-case? (rnrs unicode (6))

char-lower-case? (rnrs unicode (6))

close-input-port (rnrs io simple (6))

close-output-port (rnrs io simple (6))

current-input-port (rnrs io simple (6))

current-output-port (rnrs io simple (6))

display (rnrs io simple (6))

do (rnrs control (6))

eof-object? (rnrs io simple (6))

eval (rnrs eval (6))

delay (rnrs r5rs (6))

exact->inexact (rnrs r5rs (6))

force (rnrs r5rs (6))

identiﬁer moved to

inexact->exact (rnrs r5rs (6))

member (rnrs lists (6))

memv (rnrs lists (6))

memq (rnrs lists (6))

modulo (rnrs r5rs (6))

newline (rnrs io simple (6))

null-environment (rnrs r5rs (6))

open-input-file (rnrs io simple (6))

open-output-file (rnrs io simple (6))

peek-char (rnrs io simple (6))

quotient (rnrs r5rs (6))

read (rnrs io simple (6))

read-char (rnrs io simple (6))

remainder (rnrs r5rs (6))

scheme-report-environment (rnrs r5rs (6))

set-car! (rnrs mutable-pairs (6))

set-cdr! (rnrs mutable-pairs (6))

string-ci=? (rnrs unicode (6))

string-ci<? (rnrs unicode (6))

string-ci>? (rnrs unicode (6))

string-ci<=? (rnrs unicode (6))

string-ci>=? (rnrs unicode (6))

string-set! (rnrs mutable-strings (6))

string-fill! (rnrs mutable-strings (6))

with-input-from-file (rnrs io simple (6))

with-output-to-file (rnrs io simple (6))

write (rnrs io simple (6))

write-char (rnrs io simple (6))

Figure A.1: Identiﬁers moved to libraries

• Procedures now may or may not refer to locations.

Consequently, eqv? is now unspeciﬁed in a few cases

where it was speciﬁed before.

• The mutability of the values of quasiquote structures

has been speciﬁed to some degree.

• The dynamic environment of the before and after pro-

cedures of dynamic-wind is now speciﬁed.

• Various expressions that have only side eﬀects are now

allowed to return an arbitrary number of values.

• The order and semantics for macro expansion has been

more fully speciﬁed.

• Internal deﬁnitions are now deﬁned in terms of

letrec*.

• The old notion of program structure and Scheme’s top-

level environment has been replaced by top-level pro-

grams and libraries.

• The denotational semantics has been replaced by an

operational semantics based on an earlier semantics

for the language of the “Revised

5

Report” [14, 18].

REFERENCES

[1] J. W. Backus, F.L. Bauer, J.Green, C. Katz, J. Mc-

Carthy P. Naur, A. J. Perlis, H. Rutishauser,

K. Samuelson, B. Vauquois J. H. Wegstein, A. van

Wijngaarden, and M. Woodger. Revised report on

the algorithmic language Algol 60. Communications

of the ACM, 6(1):1–17, 1963.

[2] Alan Bawden and Jonathan Rees. Syntactic closures.

In ACM Conference on Lisp and Functional Program-

ming, pages 86–95, Snowbird, Utah, 1988. ACM Press.

[3] Scott Bradner. Key words for use in RFCs to indi-

cate requirement levels. http://www.ietf.org/rfc/

rfc2119.txt, March 1997. RFC 2119.

[4] Robert G. Burger and R. Kent Dybvig. Print-

ing ﬂoating-point numbers quickly and accurately.

In Proc. of the ACM SIGPLAN ’96 Conference on

Programming Language Design and Implementation,

pages 108–116, Philadelphia, PA, USA, May 1996.

ACM Press.

[5] William Clinger. Proper tail recursion and space

eﬃciency. In Keith Cooper, editor, Proceedings of

References 81

the 1998 Conference on Programming Language De-

sign and Implementation, pages 174–185, Montreal,

Canada, June 1998. ACM Press. Volume 33(5) of SIG-

PLAN Notices.

[6] William Clinger and Jonathan Rees. Macros that

work. In Proc. 1991 ACM SIGPLAN Symposium on

Principles of Programming Languages, pages 155–162,

Orlando, Florida, January 1991. ACM Press.

[7] William D. Clinger. How to read ﬂoating point num-

bers accurately. In Proc. Conference on Programming

Language Design and Implementation ’90, pages 92–

101, White Plains, New York, USA, June 1990. ACM.

[8] R. Kent Dybvig. Chez Scheme Version 7 User’s

Guide. Cadence Research Systems, 2005. http:

//www.scheme.com/csug7/.

[9] R. Kent Dybvig, Robert Hieb, and Carl Bruggeman.

Syntactic abstraction in Scheme. Lisp and Symbolic

Computation, 1(1):53–75, 1988.

[10] Matthias Felleisen and Matthew Flatt. Programming

languages and lambda calculi. http://www.cs.utah.

edu/plt/publications/pllc.pdf, 2003.

[11] Matthew Flatt. PLT MzScheme: Language Man-

ual. Rice University, University of Utah, July

2006. http://download.plt-scheme.org/doc/352/

html/mzscheme/.

[12] Daniel P. Friedman, Christopher Haynes, Eugene

Kohlbecker, and Mitchell Wand. Scheme 84 interim

reference manual. Indiana University, January 1985.

Indiana University Computer Science Technical Re-

port 153.

[13] IEEE standard 754-1985. IEEE standard for binary

ﬂoating-point arithmetic, 1985. Reprinted in SIG-

PLAN Notices, 22(2):9-25, 1987.

[14] Richard Kelsey, William Clinger, and Jonathan Rees.

Revised

5

report on the algorithmic language Scheme.

Higher-Order and Symbolic Computation, 11(1):7–

105, 1998.

[15] Eugene E. Kohlbecker, Daniel P. Friedman, Matthias

Felleisen, and Bruce Duba. Hygienic macro expansion.

In Proceedings of the 1986 ACM Conference on Lisp

and Functional Programming, pages 151–161, 1986.

[16] Eugene E. Kohlbecker Jr. Syntactic Extensions in

the Programming Language Lisp. PhD thesis, Indiana

University, August 1986.

[17] Jacob Matthews and Robert Bruce Findler. An op-

erational semantics for R5RS Scheme. In J. Michael

Ashley and Michael Sperber, editors, Proceedings of

the Sixth Workshop on Scheme and Functional Pro-

gramming, pages 41–54, Tallin, Estonia, September

2005. Indiana University Technical Report TR619.

[18] Jacob Matthews and Robert Bruce Findler. An oper-

ational semantics for Scheme. Journal of Functional

Programming, 2007. From http://www.cambridge.

org/journals/JFP/.

[19] Jacob Matthews, Robert Bruce Findler, Matthew

Flatt, and Matthias Felleisen. A visual environment

for developing context-sensitive term rewriting sys-

tems. In Proc. 15th Conference on Rewriting Tech-

niques and Applications, Aachen, June 2004. Springer-

Verlag.

[20] MIT Department of Electrical Engineering and Com-

puter Science. Scheme manual, seventh edition,

September 1984.

[21] Jonathan A. Rees, Norman I. Adams IV, and James R.

Meehan. The T manual. Yale University Computer

Science Department, fourth edition, January 1984.

[22] Michael Sperber, R. Kent Dybvig, Matthew Flatt, and

Anton van Straaten. Revised

6

report on the algorith-

mic language Scheme (Non-Normative appendices).

http://www.r6rs.org/, 2007.

[23] Michael Sperber, R. Kent Dybvig, Matthew Flatt, and

Anton van Straaten. Revised

6

report on the algorith-

mic language Scheme (Rationale). http://www.r6rs.

org/, 2007.

[24] Michael Sperber, R. Kent Dybvig, Matthew Flatt, An-

ton van Straaten, Richard Kelsey, William Clinger,

and Jonathan Rees. Revised

6

report on the algorith-

mic language Scheme (Libraries). http://www.r6rs.

org/, 2007.

[25] Guy Lewis Steele Jr. Common Lisp: The Language.

Digital Press, Burlington, MA, second edition, 1990.

[26] Texas Instruments, Inc. TI Scheme Language Ref-

erence Manual, November 1985. Preliminary version

1.0.

[27] The Unicode Consortium. The Unicode standard, ver-

sion 5.0.0. deﬁned by: The Unicode Standard, Version

5.0 (Boston, MA, Addison-Wesley, 2007. ISBN 0-321-

48091-0), 2007.

[28] William M. Waite and Gerhard Goos. Compiler Con-

struction. Springer-Verlag, 1984.

[29] Andrew Wright and Matthias Felleisen. A syntactic

approach to type soundness. Information and Com-

putation, 115(1):38–94, 1994. First appeared as Tech-

nical Report TR160, Rice University, 1991.

82 Revised

6

Scheme

ALPHABETIC INDEX OF DEFINITIONS OF CONCEPTS, KEYWORDS, AND

PROCEDURES

The index includes entries from the library document; the

entries are marked with “(library)”.

! 23

#,@ 17

#\ 14

#| 14

& 23

’ 17

#’ 17

* 43

* (formal semantics) 67

+ 14, 43

+ (formal semantics) 67

, 17

#, 17

,@ 17

- 14, 23, 43

- (formal semantics) 67

-0.0 11

-> 14, 23

... 14, 51, 52 (library), 57

/ 44

/ (formal semantics) 67

; 14

#; 14

< 42

<= 42

= 42

=> 24 (library), 33, 34

> 42

>= 42

? 23

51 (library), 57

#‘ 17

‘ 17

|# 14

abs 44

accessor 15 (library)

acos 45

and 34

angle 46

antimark 50 (library)

append 48

apply 53

apply (formal semantics) 72

argument checking 18

asin 45

assert 53

&assertion 28 (library)

assertion-violation 52

assertion-violation? 28 (library)

assignment 7

assoc 12 (library)

assp 12 (library)

assq 13 (library)

assv 13 (library)

atan 45

#b 13, 15

backquote 55

base record type 15 (library)

begin 37

begin (formal semantics) 67, 75

begin0 (formal semantics) 67, 75

big-endian 5 (library)

binary port 31, 32 (library)

binary-port? 34 (library)

binding 6, 18

binding construct 18

bit ﬁelds 43 (library)

bitwise-and 48 (library)

bitwise-arithmetic-shift 49 (library)

bitwise-arithmetic-shift-left 49 (library)

bitwise-arithmetic-shift-right 49 (library)

bitwise-bit-count 48 (library)

bitwise-bit-field 49 (library)

bitwise-bit-set? 49 (library)

bitwise-copy-bit 49 (library)

bitwise-copy-bit-field 49 (library)

bitwise-first-bit-set 49 (library)

bitwise-if 48 (library)

bitwise-ior 48 (library)

bitwise-length 48 (library)

bitwise-not 48 (library)

bitwise-reverse-bit-field 50 (library)

bitwise-rotate-bit-field 49 (library)

bitwise-xor 48 (library)

body 32

boolean 5

boolean=? 47

boolean? 31, 47

bound 18

bound-identifier=? 54 (library)

buffer-mode 32 (library)

buffer-mode? 32 (library)

byte 5 (library)

bytevector 5 (library)

bytevector->sint-list 7 (library)

bytevector->string 33 (library)

bytevector->u8-list 6 (library)

bytevector->uint-list 7 (library)

bytevector-copy 6 (library)

Index 83

bytevector-copy! 6 (library)

bytevector-fill! 6 (library)

bytevector-ieee-double-native-ref 9 (library)

bytevector-ieee-double-native-set! 9 (library)

bytevector-ieee-double-ref 9 (library)

bytevector-ieee-single-native-ref 9 (library)

bytevector-ieee-single-native-set! 9 (library)

bytevector-ieee-single-ref 9 (library)

bytevector-length 5 (library)

bytevector-s16-native-ref 7 (library)

bytevector-s16-native-set! 7 (library)

bytevector-s16-ref 7 (library)

bytevector-s16-set! 7 (library)

bytevector-s32-native-ref 8 (library)

bytevector-s32-native-set! 8 (library)

bytevector-s32-ref 8 (library)

bytevector-s32-set! 8 (library)

bytevector-s64-native-ref 8 (library)

bytevector-s64-native-set! 8 (library)

bytevector-s64-ref 8 (library)

bytevector-s64-set! 8 (library)

bytevector-s8-ref 6 (library)

bytevector-s8-set! 6 (library)

bytevector-sint-ref 6 (library)

bytevector-sint-set! 6 (library)

bytevector-u16-native-ref 7 (library)

bytevector-u16-native-set! 7 (library)

bytevector-u16-ref 7 (library)

bytevector-u16-set! 7 (library)

bytevector-u32-native-ref 8 (library)

bytevector-u32-native-set! 8 (library)

bytevector-u32-ref 8 (library)

bytevector-u32-set! 8 (library)

bytevector-u64-native-ref 8 (library)

bytevector-u64-native-set! 8 (library)

bytevector-u64-ref 8 (library)

bytevector-u64-set! 8 (library)

bytevector-u8-ref 6 (library)

bytevector-u8-set! 6 (library)

bytevector-uint-ref 6 (library)

bytevector-uint-set! 6 (library)

bytevector=? 6 (library)

bytevector? 5 (library)

caar 48

cadr 48

call 28

call by need 64 (library)

call-with-bytevector-output-port 39 (library)

call-with-current-continuation 53

call-with-input-file 41 (library)

call-with-output-file 41 (library)

call-with-port 34 (library)

call-with-string-output-port 39 (library)

call-with-values 54

call-with-values (formal semantics) 65

call/cc 53

call/cc (formal semantics) 73

car 48

car (formal semantics) 68

case 34, 75

case-lambda 15 (library)

cdddar 48

cddddr 48

cdr 48

cdr (formal semantics) 68

ceiling 44

char->integer 50

char-alphabetic? 3 (library)

char-ci<=? 3 (library)

char-ci<? 3 (library)

char-ci=? 3 (library)

char-ci>=? 3 (library)

char-ci>? 3 (library)

char-downcase 3 (library)

char-foldcase 3 (library)

char-general-category 4 (library)

char-lower-case? 3 (library)

char-numeric? 3 (library)

char-title-case? 3 (library)

char-titlecase 3 (library)

char-upcase 3 (library)

char-upper-case? 3 (library)

char-whitespace? 3 (library)

char<=? 50

char<? 50

char=? 50

char>=? 50

char>? 50

char? 31, 50

character 5

Characters 50

close-input-port 42 (library)

close-output-port 42 (library)

close-port 34 (library)

code point 50

codec 32 (library)

command-line 43 (library)

comment 12, 14

complex? 41

compound condition 25 (library)

cond 33, 58, 75

condition 25 (library)

&condition 26 (library)

condition 26 (library)

condition-accessor 26 (library)

condition-irritants 28 (library)

condition-message 27 (library)

condition-predicate 26 (library)

condition-who 28 (library)

84 Revised

6

Scheme

condition? 26 (library)

condition? (formal semantics) 66

cons 47

cons (formal semantics) 68

cons* 13 (library)

consi (formal semantics) 68

constant 20

constructor descriptor 21 (library)

continuable exception 18, 25 (library)

continuation 8

core form 29

cos 45

current exception handler 24 (library)

current-error-port 39 (library), 41 (library)

current-input-port 35 (library), 41 (library)

current-output-port 39 (library), 41 (library)

#d 15

datum 11, 12

datum value 8, 11

datum->syntax 55 (library)

define 31

define-condition-type 27 (library)

define-enumeration 61 (library)

define-record-type 16 (library)

define-syntax 31

deﬁnition 6, 18, 25, 31

delay 64 (library)

delete-file 42 (library)

denominator 44

derived form 8

display 42 (library)

div 44

div-and-mod 44

div0 44

div0-and-mod0 44

do 14 (library)

dot (formal semantics) 70

dw (formal semantics) 73, 75

dynamic environment 20

dynamic extent 20

dynamic-wind 53, 54

dynamic-wind (formal semantics) 73

#e 13, 15

else 24 (library), 33, 34

empty list 17, 31, 47, 48

end-of-ﬁle object 33 (library)

end-of-line style 32 (library)

endianness 5 (library)

endianness 5 (library)

enum-set->list 61 (library)

enum-set-complement 61 (library)

enum-set-constructor 60 (library)

enum-set-difference 61 (library)

enum-set-indexer 60 (library)

enum-set-intersection 61 (library)

enum-set-member? 61 (library)

enum-set-projection 61 (library)

enum-set-subset? 61 (library)

enum-set-union 61 (library)

enum-set-universe 60 (library)

enum-set=? 61 (library)

enumeration 60 (library)

enumeration sets 60 (library)

enumeration type 60 (library)

environment 62 (library)

environment 62 (library)

eof-object 33 (library), 41 (library)

eof-object? 33 (library), 41 (library)

eol-style 32 (library)

eq? 38

equal-hash 60 (library)

equal? 39

equivalence function 58 (library)

equivalence predicate 37

eqv? 20, 37

eqv? (formal semantics) 69, 75

&error 28 (library)

error 52

error-handling-mode 33 (library)

error? 28 (library)

escape procedure 9, 53

escape sequence 15

eval 62 (library)

even? 43

exact 10, 37

exact 42

exact->inexact 63 (library)

exact-integer-sqrt 45

exact? 42

exactness 10

exceptional situation 18, 25 (library)

exceptions 24 (library)

exists 10 (library)

exit 43 (library)

exp 45

export 23

expression 6, 25

expt 45

external representation 11

#f 14, 47

false 19

ﬁeld 15 (library)

fields 16 (library)

ﬁle options 31 (library)

file-exists? 42 (library)

file-options 31 (library)

filter 11 (library)

find 10 (library)

Index 85

finite? 43

ﬁxnum 10

fixnum->flonum 48 (library)

fl 23

fl* 46 (library)

fl+ 46 (library)

fl- 46 (library)

fl/ 46 (library)

fl<=? 46 (library)

fl<? 46 (library)

fl=? 46 (library)

fl>=? 46 (library)

fl>? 46 (library)

flabs 47 (library)

flacos 47 (library)

flasin 47 (library)

flatan 47 (library)

flceiling 47 (library)

flcos 47 (library)

fldenominator 47 (library)

fldiv 47 (library)

fldiv-and-mod 47 (library)

fldiv0 47 (library)

fldiv0-and-mod0 47 (library)

fleven? 46 (library)

flexp 47 (library)

flexpt 48 (library)

flfinite? 46 (library)

flfloor 47 (library)

flinfinite? 46 (library)

flinteger? 46 (library)

fllog 47 (library)

flmax 46 (library)

flmin 46 (library)

flmod 47 (library)

flmod0 47 (library)

flnan? 46 (library)

flnegative? 46 (library)

flnumerator 47 (library)

flodd? 46 (library)

ﬂonum 10

flonum? 46 (library)

floor 44

flpositive? 46 (library)

flround 47 (library)

flsin 47 (library)

flsqrt 48 (library)

fltan 47 (library)

fltruncate 47 (library)

flush-output-port 38 (library)

flzero? 46 (library)

fold-left 11 (library)

fold-right 11 (library)

for-all 10 (library)

for-each 49

force 64 (library)

form 7, 11

free-identifier=? 54 (library)

fx 23

fx* 43 (library)

fx*/carry 44 (library)

fx+ 43 (library)

fx+/carry 44 (library)

fx- 44 (library)

fx-/carry 44 (library)

fx<=? 43 (library)

fx<? 43 (library)

fx=? 43 (library)

fx>=? 43 (library)

fx>? 43 (library)

fxand 44 (library)

fxarithmetic-shift 45 (library)

fxarithmetic-shift-left 45 (library)

fxarithmetic-shift-right 45 (library)

fxbit-count 44 (library)

fxbit-field 45 (library)

fxbit-set? 45 (library)

fxcopy-bit 45 (library)

fxcopy-bit-field 45 (library)

fxdiv 44 (library)

fxdiv-and-mod 44 (library)

fxdiv0 44 (library)

fxdiv0-and-mod0 44 (library)

fxeven? 43 (library)

fxfirst-bit-set 45 (library)

fxif 44 (library)

fxior 44 (library)

fxlength 44 (library)

fxmax 43 (library)

fxmin 43 (library)

fxmod 44 (library)

fxmod0 44 (library)

fxnegative? 43 (library)

fxnot 44 (library)

fxodd? 43 (library)

fxpositive? 43 (library)

fxreverse-bit-field 46 (library)

fxrotate-bit-field 45 (library)

fxxor 44 (library)

fxzero? 43 (library)

gcd 44

generate-temporaries 56 (library)

get-bytevector-all 37 (library)

get-bytevector-n 37 (library)

get-bytevector-n! 37 (library)

get-bytevector-some 37 (library)

get-char 37 (library)

get-datum 38 (library)

get-line 38 (library)

86 Revised

6

Scheme

get-string-all 38 (library)

get-string-n 37 (library)

get-string-n! 37 (library)

get-u8 36 (library)

guard 24 (library)

hash function 58 (library)

hashtable 58 (library)

hashtable-clear! 59 (library)

hashtable-contains? 59 (library)

hashtable-copy 59 (library)

hashtable-delete! 59 (library)

hashtable-entries 59 (library)

hashtable-equivalence-function 59 (library)

hashtable-hash-function 60 (library)

hashtable-keys 59 (library)

hashtable-mutable? 60 (library)

hashtable-ref 59 (library)

hashtable-set! 59 (library)

hashtable-size 59 (library)

hashtable-update! 59 (library)

hashtable? 59 (library)

hole 61

hygienic 29

#i 13, 15

&i/o 29 (library)

&i/o-decoding 32 (library)

i/o-decoding-error? 32 (library)

&i/o-encoding 32 (library)

i/o-encoding-error-char 32 (library)

i/o-encoding-error? 32 (library)

i/o-error-filename 30 (library)

i/o-error-port 30 (library)

i/o-error-position 30 (library)

i/o-error? 29 (library)

&i/o-file-already-exists 30 (library)

i/o-file-already-exists-error? 30 (library)

&i/o-file-does-not-exist 30 (library)

i/o-file-does-not-exist-error? 30 (library)

&i/o-file-is-read-only 30 (library)

i/o-file-is-read-only-error? 30 (library)

&i/o-file-protection 30 (library)

i/o-file-protection-error? 30 (library)

&i/o-filename 30 (library)

i/o-filename-error? 30 (library)

&i/o-invalid-position 30 (library)

i/o-invalid-position-error? 30 (library)

&i/o-port 30 (library)

i/o-port-error? 30 (library)

&i/o-read 29 (library)

i/o-read-error? 29 (library)

&i/o-write 30 (library)

i/o-write-error? 30 (library)

identiﬁer 6, 12, 14, 17

identiﬁer macro 53 (library)

identifier-syntax 59

identifier? 54 (library)

if 33

if (formal semantics) 67

imag-part 46

immutable 20

immutable 16 (library)

immutable record type 16 (library)

implementation restriction 10, 18

&implementation-restriction 29 (library)

implementation-restriction-violation? 29 (library)

implicit identiﬁer 55 (library)

import 23

import level 26

improper list 47

inexact 10, 37

inexact 42

inexact->exact 63 (library)

inexact? 42

infinite? 43

inﬁnity 11

input port 31 (library)

input-port? 35 (library)

instance 26

instantiation 26

integer object 10

integer->char 50

integer-valued? 41

integer? 41

&irritants 28 (library)

irritants-condition? 28 (library)

keyword 18, 29

lambda 32

lambda (formal semantics) 65, 70

latin-1-codec 32 (library)

lazy evaluation 64 (library)

lcm 44

length 48

let 32, 35, 55, 58, 77

let* 32, 35, 76

let*-values 32, 36

let-syntax 56

let-values 32, 36

letrec 32, 35, 76

letrec (formal semantics) 74

letrec* 32, 36, 76

letrec* (formal semantics) 74

letrec-syntax 56

level 26

lexeme 12

&lexical 29 (library)

lexical-violation? 29 (library)

library 9, 17, 23

library 23

Index 87

list 6

list 48

list (formal semantics) 68

list->string 51

list->vector 52

list-ref 48

list-sort 13 (library)

list-tail 48

list? 48

literal 28

little-endian 5 (library)

location 20

log 45

lookahead-char 37 (library)

lookahead-u8 37 (library)

macro 8, 29

macro keyword 29

macro transformer 29, 51 (library), 56

macro use 29

magnitude 46

make-assertion-violation 28 (library)

make-bytevector 5 (library)

make-custom-binary-input-port 35 (library)

make-custom-binary-input/output-port 41 (library)

make-custom-binary-output-port 39 (library)

make-custom-textual-input-port 36 (library)

make-custom-textual-input/output-port 41 (library)

make-custom-textual-output-port 40 (library)

make-enumeration 60 (library)

make-eq-hashtable 58 (library)

make-eqv-hashtable 58 (library)

make-error 28 (library)

make-hashtable 58 (library)

make-i/o-decoding-error 32 (library)

make-i/o-encoding-error 32 (library)

make-i/o-error 29 (library)

make-i/o-file-already-exists-error 30 (library)

make-i/o-file-does-not-exist-error 30 (library)

make-i/o-file-is-read-only-error 30 (library)

make-i/o-file-protection-error 30 (library)

make-i/o-filename-error 30 (library)

make-i/o-invalid-position-error 30 (library)

make-i/o-port-error 30 (library)

make-i/o-read-error 29 (library)

make-i/o-write-error 30 (library)

make-implementation-restriction-violation 29 (li-

brary)

make-irritants-condition 28 (library)

make-lexical-violation 29 (library)

make-message-condition 27 (library)

make-no-infinities-violation 48 (library)

make-no-nans-violation 48 (library)

make-non-continuable-violation 28 (library)

make-polar 46

make-record-constructor-descriptor 21 (library)

make-record-type-descriptor 20 (library)

make-rectangular 46

make-serious-condition 28 (library)

make-string 50

make-syntax-violation 29 (library)

make-transcoder 33 (library)

make-undefined-violation 29 (library)

make-variable-transformer 51 (library)

make-vector 51

make-violation 28 (library)

make-warning 27 (library)

make-who-condition 28 (library)

map 49

mark 50 (library)

max 43

may 9

member 12 (library)

memp 12 (library)

memq 12 (library)

memv 12 (library)

&message 27 (library)

message-condition? 27 (library)

min 43

mod 44

mod0 44

modulo 63 (library)

must 9

must be 21

must not 9

mutable 20

mutable 16 (library)

mutable record type 16 (library)

mutator 15 (library)

NaN 11

nan? 43

native-endianness 5 (library)

native-eol-style 32 (library)

native-transcoder 33 (library)

negative inﬁnity 11

negative? 42

newline 42 (library)

nil 47

&no-infinities 48 (library)

no-infinities-violation? 48 (library)

&no-nans 48 (library)

no-nans-violation? 48 (library)

&non-continuable 28 (library)

non-continuable-violation? 28 (library)

nongenerative 16 (library)

nongenerative 16 (library)

not 47

null (formal semantics) 68, 72

null-environment 64 (library)

88 Revised

6

Scheme

null? 31, 48

null? (formal semantics) 68

number 5, 10, 43 (library)

number->string 46

number? 31, 41

numerator 44

numerical types 10

#o 13, 15

object 5

octet 5 (library)

odd? 42

opaque 16 (library)

open-bytevector-input-port 35 (library)

open-bytevector-output-port 39 (library)

open-file-input-port 35 (library)

open-file-input/output-port 41 (library)

open-file-output-port 38 (library)

open-input-file 42 (library)

open-output-file 42 (library)

open-string-input-port 35 (library)

open-string-output-port 39 (library)

or 34, 35

output ports 31 (library)

output-port-buffer-mode 38 (library)

output-port? 38 (library)

pair 6, 47

pair? 31, 47

pair? (formal semantics) 68

parent 16 (library)

parent-rtd 16 (library)

partition 11 (library)

pattern variable 52 (library), 57

peek-char 42 (library)

phase 25

port 31 (library)

port-eof? 35 (library)

port-has-port-position? 34 (library)

port-has-set-port-position!? 34 (library)

port-position 34 (library)

port-transcoder 34 (library)

port? 34 (library)

position 34 (library)

positive inﬁnity 11

positive? 42

predicate 37

preﬁx notation 6

procedure 6, 7

procedure call 7, 28

procedure? 31, 39

procedure? (formal semantics) 70

promise 64 (library)

proper tail recursion 20

protocol 21 (library)

protocol 16 (library)

put-bytevector 40 (library)

put-char 40 (library)

put-datum 40 (library)

put-string 40 (library)

put-u8 40 (library)

quasiquote 55, 56

quasisyntax 57 (library)

quote 32

quotient 63 (library)

raise 18

raise 25 (library)

raise (formal semantics) 66

raise-continuable 25 (library)

raise-continuable (formal semantics) 66

rational-valued? 41

rational? 41

rationalize 45

read 42 (library)

read-char 42 (library)

real->flonum 46 (library)

real-part 46

real-valued? 41

real? 41

record 15 (library)

record constructor 15 (library), 21 (library)

record-accessor 22 (library)

record-constructor 22 (library)

record-constructor descriptor 21 (library)

record-constructor-descriptor 19 (library)

record-field-mutable? 24 (library)

record-mutator 22 (library)

record-predicate 22 (library)

record-rtd 23 (library)

record-type descriptor 15 (library), 20 (library)

record-type-descriptor 19 (library)

record-type-descriptor? 21 (library)

record-type-field-names 24 (library)

record-type-generative? 24 (library)

record-type-name 23 (library)

record-type-opaque? 24 (library)

record-type-parent 23 (library)

record-type-sealed? 24 (library)

record-type-uid 23 (library)

record? 23 (library)

referentially transparent 29

region 14 (library), 18, 33, 35–37

remainder 63 (library)

remove 12 (library)

remp 12 (library)

remq 12 (library)

remv 12 (library)

responsibility 19

reverse 48

(rnrs (6)) 62 (library)

Index 89

(rnrs arithmetic bitwise (6)) 48 (library)

(rnrs arithmetic fixnums (6)) 43 (library)

(rnrs arithmetic flonums (6)) 46 (library)

(rnrs base (6)) 31

(rnrs bytevectors (6)) 5 (library)

(rnrs conditions (6)) 25 (library)

(rnrs control (6)) 14 (library)

(rnrs enums (6)) 60 (library)

(rnrs exceptions (6)) 24 (library)

(rnrs files (6)) 42 (library)

(rnrs hashtables (6)) 58 (library)

(rnrs io ports (6)) 31 (library)

(rnrs io simple (6)) 41 (library)

(rnrs lists (6)) 10 (library)

(rnrs mutable-pairs (6)) 62 (library)

(rnrs mutable-strings (6)) 63 (library)

(rnrs programs (6)) 43 (library)

(rnrs r5rs (6)) 63 (library)

(rnrs records inspection (6)) 23 (library)

(rnrs records procedural (6)) 20 (library)

(rnrs records syntactic (6)) 16 (library)

(rnrs sorting (6)) 13 (library)

(rnrs syntax-case (6)) 50 (library)

(rnrs unicode (6)) 3 (library)

round 44

rtd 20 (library)

safe libraries 19

scalar value 50

scheme-report-environment 64 (library)

sealed 16 (library)

sealed 16 (library)

&serious 28 (library)

serious-condition? 28 (library)

set! 33

set! (formal semantics) 70, 74

set-car! 62 (library)

set-car! (formal semantics) 68

set-cdr! 63 (library)

set-cdr! (formal semantics) 68

set-port-position! 34 (library)

should 9

should not 9

simple condition 25 (library)

simple-conditions 26 (library)

simplest rational 45

sin 45

sint-list->bytevector 7 (library)

special form 7

splicing 37

sqrt 45

standard library 17

standard-error-port 39 (library)

standard-input-port 35 (library)

standard-output-port 39 (library)

string 5

string 50

string->bytevector 33 (library)

string->list 51

string->number 47

string->symbol 49

string->utf16 9 (library)

string->utf32 9 (library)

string->utf8 9 (library)

string-append 51

string-ci-hash 60 (library)

string-ci<=? 4 (library)

string-ci<? 4 (library)

string-ci=? 4 (library)

string-ci>=? 4 (library)

string-ci>? 4 (library)

string-copy 51

string-downcase 4 (library)

string-fill! 63 (library)

string-foldcase 4 (library)

string-for-each 51

string-hash 60 (library)

string-length 50

string-normalize-nfc 4 (library)

string-normalize-nfd 4 (library)

string-normalize-nfkc 4 (library)

string-normalize-nfkd 4 (library)

string-ref 50

string-set! 63 (library)

string-titlecase 4 (library)

string-upcase 4 (library)

string<=? 50

string<? 50

string=? 50

string>=? 50

string>? 50

string? 31, 50

subform 7, 11

substitution 50 (library)

substring 51

surrogate 50

symbol 6, 14

symbol->string 20, 49

symbol-hash 60 (library)

symbol=? 49

symbol? 31, 49

syntactic abstraction 29

syntactic datum 8, 11, 16

syntactic keyword 7, 14, 18, 29

&syntax 29 (library)

syntax 53 (library)

syntax object 51 (library)

syntax violation 19

syntax->datum 55 (library)

syntax-case 51 (library)

90 Revised

6

Scheme

syntax-rules 57

syntax-violation 58 (library)

syntax-violation-form 29 (library)

syntax-violation-subform 29 (library)

syntax-violation? 29 (library)

#t 14, 47

tail call 20, 59

tail context 20

tan 45

textual port 32 (library)

textual ports 31 (library)

textual-port? 34 (library)

throw (formal semantics) 73

top-level program 9, 17, 27

transcoded-port 34 (library)

transcoder 32 (library)

transcoder-codec 33 (library)

transcoder-eol-style 33 (library)

transcoder-error-handling-mode 33 (library)

transformation procedure 51 (library)

transformer 29, 51 (library), 56

true 19, 33, 34

truncate 44

type 31

u8-list->bytevector 6 (library)

uint-list->bytevector 7 (library)

unbound 18, 28

&undefined 29 (library)

undefined-violation? 29 (library)

Unicode 50

Unicode scalar value 50

universe 60 (library)

unless 14 (library)

unquote 55, 56

unquote-splicing 55, 56

unspeciﬁed behavior 20

unspeciﬁed values 20

unsyntax 57 (library)

unsyntax-splicing 57 (library)

utf-16-codec 32 (library)

utf-8-codec 32 (library)

utf16->string 10 (library)

utf32->string 10 (library)

utf8->string 9 (library)

valid indices 50, 51

values 53

values (formal semantics) 65–67, 73, 75

variable 6, 14, 18, 28

variable transformer 51 (library)

vector 6

vector 51

vector->list 52

vector-fill! 52

vector-for-each 52

vector-length 51

vector-map 52

vector-ref 51

vector-set! 51

vector-sort 13 (library)

vector-sort! 13 (library)

vector? 31, 51

&violation 28 (library)

violation? 28 (library)

visit 26

visiting 26

&warning 27 (library)

warning? 27 (library)

when 14 (library)

Whitespace 13

&who 28 (library)

who-condition? 28 (library)

with-exception-handler 24 (library)

with-exception-handler (formal semantics) 66

with-input-from-file 41 (library)

with-output-to-file 41 (library)

with-syntax 56 (library)

wrap 50 (library)

wrapped syntax object 50 (library)

write 42 (library)

write-char 42 (library)

#x 13, 15

zero? 42

2

Revised6 Scheme

CONTENTS

Introduction . . . . . . . . . . . . . . . . . . . . . . Description of the language 1 Overview of Scheme . . . . . . . . . . . . . . . . . 1.1 Basic types . . . . . . . . . . . . . . . . . . 1.2 Expressions . . . . . . . . . . . . . . . . . . 1.3 Variables and binding . . . . . . . . . . . . 1.4 Deﬁnitions . . . . . . . . . . . . . . . . . . . 1.5 Forms . . . . . . . . . . . . . . . . . . . . . 1.6 Procedures . . . . . . . . . . . . . . . . . . 1.7 Procedure calls and syntactic keywords . . . 1.8 Assignment . . . . . . . . . . . . . . . . . . 1.9 Derived forms and macros . . . . . . . . . . 1.10 Syntactic data and datum values . . . . . . 1.11 Continuations . . . . . . . . . . . . . . . . . 1.12 Libraries . . . . . . . . . . . . . . . . . . . . 1.13 Top-level programs . . . . . . . . . . . . . . 2 Requirement levels . . . . . . . . . . . . . . . . . 3 Numbers . . . . . . . . . . . . . . . . . . . . . . . 3.1 Numerical tower . . . . . . . . . . . . . . . 3.2 Exactness . . . . . . . . . . . . . . . . . . . 3.3 Fixnums and ﬂonums . . . . . . . . . . . . . 3.4 Implementation requirements . . . . . . . . 3.5 Inﬁnities and NaNs . . . . . . . . . . . . . . 3.6 Distinguished -0.0 . . . . . . . . . . . . . . 4 Lexical syntax and datum syntax . . . . . . . . . 4.1 Notation . . . . . . . . . . . . . . . . . . . . 4.2 Lexical syntax . . . . . . . . . . . . . . . . . 4.3 Datum syntax . . . . . . . . . . . . . . . . . 5 Semantic concepts . . . . . . . . . . . . . . . . . . 5.1 Programs and libraries . . . . . . . . . . . . 5.2 Variables, keywords, and regions . . . . . . 5.3 Exceptional situations . . . . . . . . . . . . 5.4 Argument checking . . . . . . . . . . . . . . 5.5 Syntax violations . . . . . . . . . . . . . . . 5.6 Safety . . . . . . . . . . . . . . . . . . . . . 5.7 Boolean values . . . . . . . . . . . . . . . . 5.8 Multiple return values . . . . . . . . . . . . 5.9 Unspeciﬁed behavior . . . . . . . . . . . . . 5.10 Storage model . . . . . . . . . . . . . . . . . 5.11 Proper tail recursion . . . . . . . . . . . . . 5.12 Dynamic extent and the dynamic environment 6 Entry format . . . . . . . . . . . . . . . . . . . . . 6.1 Syntax entries . . . . . . . . . . . . . . . . . 6.2 Procedure entries . . . . . . . . . . . . . . . 6.3 Implementation responsibilities . . . . . . . 6.4 Other kinds of entries . . . . . . . . . . . . 6.5 Equivalent entries . . . . . . . . . . . . . . . 6.6 Evaluation examples . . . . . . . . . . . . . 6.7 Naming conventions . . . . . . . . . . . . . 7 Libraries . . . . . . . . . . . . . . . . . . . . . . . 3 5 5 6 6 6 7 7 7 7 8 8 8 9 9 9 10 10 10 10 10 11 11 11 12 12 16 17 17 17 18 18 19 19 19 19 20 20 20 20 20 21 21 22 22 22 22 23 23

7.1 Library form . . . . . . . . . . 7.2 Import and export levels . . . . 7.3 Examples . . . . . . . . . . . . 8 Top-level programs . . . . . . . . . . 8.1 Top-level program syntax . . . 8.2 Top-level program semantics . . 9 Primitive syntax . . . . . . . . . . . . 9.1 Primitive expression types . . . 9.2 Macros . . . . . . . . . . . . . . 10 Expansion process . . . . . . . . . . . 11 Base library . . . . . . . . . . . . . . 11.1 Base types . . . . . . . . . . . . 11.2 Deﬁnitions . . . . . . . . . . . . 11.3 Bodies . . . . . . . . . . . . . . 11.4 Expressions . . . . . . . . . . . 11.5 Equivalence predicates . . . . . 11.6 Procedure predicate . . . . . . 11.7 Arithmetic . . . . . . . . . . . . 11.8 Booleans . . . . . . . . . . . . . 11.9 Pairs and lists . . . . . . . . . . 11.10Symbols . . . . . . . . . . . . . 11.11Characters . . . . . . . . . . . . 11.12Strings . . . . . . . . . . . . . . 11.13Vectors . . . . . . . . . . . . . 11.14Errors and violations . . . . . . 11.15Control features . . . . . . . . . 11.16Iteration . . . . . . . . . . . . . 11.17Quasiquotation . . . . . . . . . 11.18Binding constructs for syntactic 11.19Macro transformers . . . . . . . 11.20Tail calls and tail contexts . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . keywords . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

23 25 26 27 27 28 28 28 29 29 31 31 31 32 32 37 39 39 47 47 49 50 50 51 52 53 55 55 56 57 59 61 61 62 65 65 67 69 69 69 70 72 73 74 75 77 77 79 80 82

Appendices A Formal semantics . . . . . . . . . . . . . . . . . . A.1 Background . . . . . . . . . . . . . . . . . . A.2 Grammar . . . . . . . . . . . . . . . . . . . A.3 Quote . . . . . . . . . . . . . . . . . . . . . A.4 Multiple values . . . . . . . . . . . . . . . . A.5 Exceptions . . . . . . . . . . . . . . . . . . A.6 Arithmetic and basic forms . . . . . . . . . A.7 Lists . . . . . . . . . . . . . . . . . . . . . . A.8 Eqv . . . . . . . . . . . . . . . . . . . . . . A.9 Procedures and application . . . . . . . . . A.10 Call/cc and dynamic wind . . . . . . . . . . A.11 Letrec . . . . . . . . . . . . . . . . . . . . . A.12 Underspeciﬁcation . . . . . . . . . . . . . . B Sample deﬁnitions for derived forms . . . . . . . . C Additional material . . . . . . . . . . . . . . . . . D Example . . . . . . . . . . . . . . . . . . . . . . . E Language changes . . . . . . . . . . . . . . . . . . References . . . . . . . . . . . . . . . . . . . . . . . . Alphabetic index of deﬁnitions of concepts, keywords, and procedures . . . . . . . . . . . . . . .

Introduction 3

INTRODUCTION

Programming languages should be designed not by piling feature on top of feature, but by removing the weaknesses and restrictions that make additional features appear necessary. Scheme demonstrates that a very small number of rules for forming expressions, with no restrictions on how they are composed, suﬃce to form a practical and eﬃcient programming language that is ﬂexible enough to support most of the major programming paradigms in use today. Scheme was one of the ﬁrst programming languages to incorporate ﬁrst-class procedures as in the lambda calculus, thereby proving the usefulness of static scope rules and block structure in a dynamically typed language. Scheme was the ﬁrst major dialect of Lisp to distinguish procedures from lambda expressions and symbols, to use a single lexical environment for all variables, and to evaluate the operator position of a procedure call in the same way as an operand position. By relying entirely on procedure calls to express iteration, Scheme emphasized the fact that tail-recursive procedure calls are essentially gotos that pass arguments. Scheme was the ﬁrst widely used programming language to embrace ﬁrst-class escape procedures, from which all previously known sequential control structures can be synthesized. A subsequent version of Scheme introduced the concept of exact and inexact number objects, an extension of Common Lisp’s generic arithmetic. More recently, Scheme became the ﬁrst programming language to support hygienic macros, which permit the syntax of a block-structured language to be extended in a consistent and reliable manner. • make procedure calls powerful enough to express any form of sequential control, and allow programs to perform non-local control operations without the use of global program transformations; • allow interesting, purely functional programs to run indeﬁnitely without terminating or running out of memory on ﬁnite-memory machines; • allow educators to use the language to teach programming eﬀectively, at various levels and with a variety of pedagogical approaches; and • allow researchers to use the language to explore the design, implementation, and semantics of programming languages. In addition, this report is intended to: • allow programmers to create and distribute substantial programs and libraries, e.g., implementations of Scheme Requests for Implementation, that run without modiﬁcation in a variety of Scheme implementations; • support procedural, syntactic, and data abstraction more fully by allowing programs to deﬁne hygienebending and hygiene-breaking syntactic abstractions and new unique datatypes along with procedures and hygienic macros in any scope; • allow programmers to rely on a level of automatic runtime type and bounds checking suﬃcient to ensure type safety; and • allow implementations to generate eﬃcient code, without requiring programmers to use implementationspeciﬁc operators or declarations. While it was possible to write portable programs in Scheme as described in Revised5 Report on the Algorithmic Language Scheme, and indeed portable Scheme programs were written prior to this report, many Scheme programs were not, primarily because of the lack of substantial standardized libraries and the proliferation of implementationspeciﬁc language additions. In general, Scheme should include building blocks that allow a wide variety of libraries to be written, include commonly used user-level features to enhance portability and readability of library and application code, and exclude features that are less commonly used and easily implemented in separate libraries. The language described in this report is intended to also be backward compatible with programs written in Scheme as

Guiding principles To help guide the standardization eﬀort, the editors have adopted a set of principles, presented below. Like the Scheme language deﬁned in Revised5 Report on the Algorithmic Language Scheme [14], the language described in this report is intended to: • allow programmers to read each other’s code, and allow development of portable programs that can be executed in any conforming implementation of Scheme; • derive its power from simplicity, a small number of generally useful core syntactic forms and procedures, and no unnecessary restrictions on how they are composed; • allow programs to deﬁne new procedures and new hygienic syntactic forms; • support the representation of program source code as data;

We gladly acknowledge the inﬂuence of manuals for MIT Scheme [20]. Daniel Weise. Lynn Winebarger. Olin Shivers. Trent Buck. and Chongkai Zhu. Dave Gurnell. Andy Freeman. Olin Shivers. Martin Gasbichler. Alan Watson. Andy Cromarty. Martin Gasbichler. Aubrey Jaﬀer. Erich Rast. Mikael Tillenius. Aziz Ghuloum. Matthias Felleisen. and Andr´ van Tonder thoroughly proofread early e versions of the report. Taylor Campbell. Scheme 84 [12]. Jens Axel Søgaard. Support for the MIT work was provided in part by the Advanced Research Projects Agency of the Department of Defense under Oﬃce of Naval Research contract N0001480-C-0505. We would also like to thank the following people for their help in creating this report: Lauri Alanko. a Manuel Serrano. Mark Meyer. Eric Knauel. Marcus Crestani. Ken Dickey. Ben Harris. Jon Wilson. Perry Wagle. Keith Wright. We thank Alan Bawden. Paulo J. Marcin Kowalczyk. Ken Friedenbach. Pavel Curtis. the editors have operated under the assumption that many more Scheme programs will be written in the future than exist in the present. Tom Emerson. Andrew Wilcox. Bradley Lucier. Paul Schlie. and Christopher Haynes for permission to use text from the Scheme 311 version 4 reference manual. Lars T Hansen. With respect to future viability. Ken Haase. Bruce Duba. PLT Scheme [11]. Alan Bawden. Jim Philbin. Marc Feeley. Shiro Kawai. Henry Wu. Barnes. Eli Barzilay. Inc. Aziz Ghuloum. Jonathan Shapiro. Jeﬀ Read. . Support for the Indiana University work was provided by NSF grants NCS 83-04567 and NCS 83-03325. We also thank Betty Dexter for the extreme eﬀort she put into setting this report in TEX. Pinku Surana. Bradley Lucier. and Ozan Yigit. Sven Hartrumpf. Speciﬁcally. Sebastian Egner. Chris Lindblad. and Andr´ van Tonder wrote SRFIs that served as e direct input to the report. Ludovic Court`s. Richard Kelsey. “Biep” Durieux. Marc Feeley. Acknowledgements Many people contributed signiﬁcant help to this revision of the report. Daniel Friedman. Gleckler. Jim Miller. Chez Scheme [8]. Andr´ van Tone der. Jorgen Sch¨fer. Paul Hudak. John Cowan. Marc Feeley. Jeﬀ Dalton. Dan Muresan. We thank Texas Instruments. Michael Lenaghan. Mike Shaﬀ. Yekta G¨rsel.4 Revised6 Scheme Julie Sussman. Sam Tobin-Hochstadt. Donovan Kolbly. Shiro Kawai. David Van Horn. John Cowan. Matos. Jonathan Rees. John Ramsdell. The Artiﬁcial Intelligence Laboratory of the Massachusetts Institute of Technology. and Andr´ van Tonder for contributing ine sights on language design. Sebastian Egner. Alexander Kjeldaas. Holm. Thomas Bushnell. J. Thomas Lord. and the NEC Research Institute supported the preparation of this report. Robert Hieb. We thank Carol Fessenden. Olivier Danvy. Jason Orendorﬀ.A. Lars T Hansen. Eric Knauel. we thank Aziz Ghuloum and Andr´ van Tonder for contributing reference implemene tations of the library system. the Computer and Information Sciences Department of the University of Oregon. James Jackson. T [21]. Carl Eastlund. We would like to thank the following people for their help in creating the previous revisions of this report: Alan Bawden. Dave Herman. Michael Blair. Reinder Verlinde. Nils M. Per Bothner. for permission to use text from the TI Scheme Language Reference Manual [26]. Felix Klock. Arthur A. Pase cal Costanza. Jed Davis. and Donald Knuth for designing the program that caused her troubles. Arthur A. Jonathan Rees. Jay Sulzberger. David Frese. Aubrey Jaﬀer. Common Lisp [25]. Jonathan Shapiro. the Computer Science Department of Indiana University. Brian C. Gleckler. Andy Freeman. so the future programs are those with which we should be most concerned. Ray Dillinger. described in Revised5 Report on the Algorithmic Language Scheme to the extent possible without compromising the above principles and future viability of the language. Stanislav Ievlev. Ryan Newton. Richard Gabriel. Aubrey Jaﬀer. George Carrette. and Algol 60 [1]. u Morry Katz.

Characters Scheme characters mostly correspond to textual characters. an exact number object corresponds to a number exactly. This chapter gives an overview of Scheme’s semantics. and coroutines. the argument expressions of a procedure call are evaluated before the procedure gains control. Basic types Scheme programs manipulate objects. and Smalltalk. including procedures and continuations. Each use of a variable is associated with a lexically apparent binding of that variable. the use of the term type in this report diﬀers from the use of the term in the context of other languages. and ML. Procedures can be created dynamically. The purpose of this overview is to explain enough about the basic concepts of the language to facilitate understanding of the subsequent chapters of the report. Ruby. weakly typed or dynamically typed languages. (Some authors refer to languages with latent types as untyped. Python. Implementations of Scheme must be properly tailrecursive. In most places where a truth value is expected. Overview of Scheme In Scheme. First-class continuations are useful for implementing a wide variety of advanced control constructs. All objects created in the course of a Scheme computation. stored in data structures. Haskell. so that special iteration constructs are useful only as syntactic sugar. Consequently. Languages with manifest types (sometimes referred to as strongly typed or statically typed languages) include Algol 60. Numbers Scheme supports a rich variety of numerical data types. Smalltalk. This section gives an overview of the fundamentally important types of the Scheme language. returned as results of procedures. which are also referred to as values. C. Other languages with these properties include Common Lisp. Strings Strings are ﬁnite sequences of characters with ﬁxed length and thus represent arbitrary Unicode texts. also have “ﬁrst-class” status. and Smalltalk are other languages that always evaluate argument expressions before invoking a procedure. Overview of Scheme 5 DESCRIPTION OF THE LANGUAGE 1. C#. More precisely. and Smalltalk. Scheme is a statically scoped programming language. they are isomorphic to the scalar values of the Unicode standard. Scheme’s model of arithmetic provides a rich set of numerical types and operations on them. whether the procedure needs the result of the evaluation or not. have unlimited extent. Furthermore. This allows the execution of an iterative computation in constant space. where an argument expression is not evaluated unless its value is needed by the procedure. any object diﬀerent from #f counts as true. and so on. and inexact numbers of various kinds. Java. complex numbers. Booleans A boolean is a truth value. including non-local exits. . Java. backtracking. Chapter 3 gives an overview of the structure of Scheme’s numerical tower. iteration can be expressed using the ordinary procedure-call mechanics. and other dialects of Lisp. particularly those with manifest typing. Haskell. the object for “false” is written #f. 1. which in most other languages only operate behind the scenes. Haskell.) Other languages with latent types are Python. including objects representing integers of arbitrary precision. Python. One distinguishing feature of Scheme is that continuations. even if the iterative computation is described by a syntactically recursive procedure. ML. it distinguishes exact and inexact number objects: Essentially. Scheme has latent as opposed to manifest types [28]. Note: As Scheme is latently typed. Scheme objects are organized into sets of values called types. and an inexact number object is the result of a computation that involved rounding or other errors. nor is it precise in all respects or normative in any way. which are organized as a reference manual. C#. most Lisp dialects. More types are described in later chapters. Following Algol. No Scheme object is ever destroyed. Ruby. Ruby. this overview is not a complete introduction to the language. ML. The reason that implementations of Scheme do not (usually!) run out of storage is that they are permitted to reclaim the storage occupied by an object if they can prove that the object cannot possibly matter to any future computation.1.1. This is distinct from the lazyevaluation semantics of Haskell. however. Scheme was one of the ﬁrst languages to support procedures as objects in their own right. or the call-by-name semantics of Algol 60. Other languages in which most objects have unlimited extent include C#. and can be either true or false. The object for “true” is written #t. Thus with a properly tail-recursive implementation. rational numbers. Common Lisp. C. Types are associated with objects (also called values) rather than with variables. In Scheme. Ruby.

they create top-level bindings. like lists. Compound expressions can be nested—the second example reads as “the sum of 14 and the product of 23 and 42”. and 23 and 42 are the operands. producing a value.) The ﬁrst two parenthesized structures are deﬁnitions. and referring to a top-level binding if no local binding can be found along the way: (define x 23) (define y 42) (let ((y 43)) In the ﬁrst of these examples.8. Scheme also allows creating top-level bindings for identiﬁers as follows: (define x 23) (define y 42) (+ x y) This notation means that the expression #t evaluates to #t. Deﬁnitions are not expressions.3. 1. Moreover. In many cases. + is the name of the builtin operation for addition. (Actually. where the ﬁrst component (the “car”) represents the ﬁrst element of the list. binding x to 23 and y to 42. a deﬁnition has no value. As in many other languages. Scheme also has a distinguished empty list. Consequently. Expressions 1. whitespace (including line endings) is not signiﬁcant when it separates subexpressions of an expression. they may be used the way enumerated values are used in other languages. the symbol’s name. are linear data structures representing ﬁnite sequences of arbitrary objects.6 Revised6 Scheme structure. The parenthesized structure following the let lists variables alongside expressions: the variable x alongside 23. starting with its occurrence in the program and going from inside to outside. it is useful to think of the variable as standing for the value directly. for instance. and cannot appear in all places where an expression can occur. Whereas the elements of a list are accessed sequentially through the chain of pairs representing it. the elements of a vector are addressed by integer indices. 1. which is the last cdr in a chain of pairs that form a list. Variables and binding Scheme allows identiﬁers to stand for locations containing values. the remaining subexpressions are operands to the operation: (+ 23 42) (+ 14 (* 23 42)) =⇒ 65 =⇒ 980 =⇒ 65 (These are actually “top-level” in the body of a top-level program or library. see section 1. Deﬁnitions The most important elements of Scheme code are expressions. Unlike strings. that is. compound expressions in Scheme are always written using the same preﬁx notation. These bindings are available in the body of the let expression. and the variable y alongside 42. the value for “true”. Vectors Vectors. As a consequence. two symbols whose names are spelled the same way are never distinguishable. the parentheses are needed to indicate . Compound expressions are formed by placing parentheses around their subexpressions. the expression starting with let is a binding construct.4. Expressions can be evaluated. vectors are more appropriate than lists for random access to elements. Procedures Procedures are values in Scheme.) The most fundamental expressions are literal expressions: #t 23 =⇒ #t =⇒ 23 The variables bound by a let expression are local. Bindings follow the lexical structure of the program: When several bindings with the same name exist. (+ x y).2. (let ((x 23) (y 42)) (+ x y)) =⇒ 65 In this case. and y to 42. speciﬁcally when the location’s value is never modiﬁed after its creation. The expression (+ 23 42) reads as “the sum of 23 and 42”. and only there. are not allowed in Scheme. any number of values—see section 5. which are often permissible in mathematical notation and also in many programming languages. a variable refers to the binding that is closest to it.12 below. and the second component (the “cdr”) the rest of the list. These identiﬁers are called variables. and can be used to indicate structure. and that the expression 23 evaluates to a number object representing the number 23. Pairs and lists A pair is a data structure with two components. Thus. Symbols A symbol is an object representing a string. because their bindings are visible only in the let’s body. The most common use of pairs is to represent (singly linked) lists. The let expression binds x to 23. As these examples indicate. The ﬁrst subexpression identiﬁes an operation. Symbols are useful for many applications. “superﬂuous” parentheses.

see section 1. the ﬁrst deﬁnition deﬁnes a procedure called f. and form is the general name for a syntactic part of a Scheme program. however.6. an abstraction of an expression over objects. even though it is an identiﬁer.7. they can be passed to other procedures: (define (f x) (+ x 42)) (define (g p x) (p x)) (g f 23) =⇒ 65 In this example. The + operation. roughly. (lambda (x) (+ x 42)). but to locations containing these objects. for example.) The set of syntactic keywords of Scheme is fairly small. While the ﬁrst line contains a deﬁnition. with no need to specify a name: ((lambda (x) (+ x 42)) 23) =⇒ 65 The entire expression in this example is a procedure call. Hence. the ﬁrst subform is a list of binding speciﬁcations. In let expressions. Assignment Scheme variables bound by deﬁnitions or let or lambda expressions are not actually bound directly to the objects speciﬁed in the respective bindings. meaning. the body of g is evaluated with p bound to f and x bound to 23. is just a regular identiﬁer in Scheme. 1. which receives special syntactic treatment in many other languages. Procedures Deﬁnitions can also be used to deﬁne procedures: (define (f x) (+ x 42)) (f 23) =⇒ 65 A procedure is. “evaluate (+ x 42) (the body of the procedure) with x bound to 23”. to create new bindings for syntactic keywords. bound to a procedure that adds number objects. The define identiﬁer in a deﬁnition is also a syntactic keyword. In particular. 1.1. is not a variable. In the example. (Note the parentheses around f x. The contents of these locations can subsequently be modiﬁed destructively via assignment: (let ((x 23)) (set! x 42) x) =⇒ 42 . As procedures are objects. A lambda expression creates a new procedure as an object. slightly simpliﬁed. which usually makes this task fairly simple. and the remaining subforms are the body of the procedure.5.) The expression (f 23) is a procedure call. It is possible.9 below. The same holds for * and many others: 1. A form that has a syntactic keyword as its ﬁrst subexpression obeys special rules determined by the keyword. both are forms. the expression is a procedure call. many predeﬁned operations of Scheme are provided not by syntax. which indicate that this is a procedure deﬁnition. which is equivalent to (f 23).8. evaluates to a procedure that takes a single number object and adds 42 to it. compound expressions and deﬁnitions exhibit similar syntactic structure: (define x 23) (* x 2) Procedure deﬁnitions are not the only way to create procedures. and the second an expression. (So-called identiﬁer macros allow creating other kinds of special forms. which evaluates to 65. this distinction depends on the bindings for define and *. At the purely syntactical level. Overview of Scheme (+ x y)) (let ((y 43)) (let ((y 44)) (+ x y))) =⇒ 66 (define (h op x y) (op x y)) (h + 23 42) (h * 23 42) =⇒ 65 =⇒ 966 7 =⇒ 67 1. but are comparatively rare. and ((lambda (x) (+ x 42)) 23) are all examples of procedure calls. deﬁnitions are also not procedure calls. Procedure calls and syntactic keywords Whereas (+ 23 42). Forms While deﬁnitions are not expressions. lambda and let expressions are not. but is instead a syntactic keyword . This is because let. The rules for the lambda keyword specify that the ﬁrst subform is a list of parameters. Procedure calls can generally be distinguished from these special forms by looking for a syntactic keyword in the ﬁrst position of an form: if the ﬁrst position does not contain a syntactic keyword. 23 is a subform of the form (define x 23). In fact. and the remaining subforms constitute a body of expressions. (f 23). but by variables whose values are procedures.

Continuations Whenever a Scheme expression is evaluated there is a continuation wanting the result of the expression. the body of the let expression consists of two expressions which are evaluated sequentially. The syntactic datum foo represents a symbol with name “foo”.8 Revised6 Scheme In this case.11.) body)))) (def f (x) (+ x 42)) This facilitates writing programs that operate on Scheme source code.9. symbols. data can be used to represent Scheme forms as data objects..) body) (define (f p . informally the continuation of 3 in the expression (+ 1 3) The define-syntax construct speciﬁes that a parenthesized structure matching the pattern (def f (p . allowing many of the features built into other languages to be derived forms in Scheme. Some procedure deﬁnitions are also derived forms. it is possible for a program to create its own derived forms by binding syntactic keywords to macros: (define-syntax def (syntax-rules () ((def f (p . and ’#(1 2 3) is the corresponding literal. Each datum value may be represented in textual form as a syntactic datum. Thus. p. 2 and 3. Syntactic data and datum values A subset of the Scheme objects is called datum values.) body). with the value of the ﬁnal expression becoming the value of the entire let expression. and 3..10. (1 2 3) is a syntactic datum that represents a list with elements 1. adds 1 to it.. The following two deﬁnitions are equivalent: (define (f x) (+ x 42)) (define f (lambda (x) (+ x 42))) The ’ shown in the previous examples is not needed for representations of number objects or booleans. 2. which can be written out and read back in without loss of information. The call-with-current-continuation procedure (see section 11. Normally these ubiquitous continuations are hidden behind the scenes and programmers do not think much about them. Derived forms and macros Many of the special forms speciﬁed in this report can be translated into more basic special forms. and ’(1 2 3) is a literal expression with this list as its value.15) allows Scheme programmers to do that . characters. The syntactic data are a superset of the Scheme forms. is translated to (define (f p . A datum value may be represented by several diﬀerent syntactic data. the def form appearing in the example gets translated to: (define (f x) (+ x 42)) The ability to create new syntactic keywords makes Scheme extremely ﬂexible and expressive. however.. Thus. The expression (set! x 42) is an assignment. Likewise. For example.. and body are pattern variables. 1. and strings as well as lists and vectors whose elements are data.. the previous value of x. and ’foo is a literal expression with that symbol as its value. symbols can be used to represent identiﬁers. 1. For example. The continuation represents an entire (default) future for the computation. a programmer may need to deal with continuations explicitly.) body). where f. On rare occasions. in particular interpreters and program transformers. These include booleans. number objects. Thus. Moreover. 23. ’(+ 23 42) =⇒ (+ 23 42) ’(define (f x) (+ x 42)) =⇒ (define (f x) (+ x 42)) In Scheme.. saying “replace the object in the location referenced by x with 42”.. is replaced by 42. In particular. The following two expressions are equivalent: (let ((x 23) (y 42)) (+ x y)) =⇒ 65 ((lambda (x y) (+ x y)) 23 42) =⇒ 65 Special forms like let expressions are called derived forms because their semantics can be derived from that of other kinds of forms by a syntactic transformation. each datum value can be trivially translated to a literal expression in a program by prepending a ’ to a corresponding syntactic datum: ’23 ’#t ’foo ’(1 2 3) ’#(1 2 3) =⇒ =⇒ =⇒ =⇒ =⇒ 23 #t foo (1 2 3) #(1 2 3) 1. #(1 2 3) is a syntactic datum that represents a vector with elements 1. a let expression can be translated into a procedure call and a lambda expression.

a Scheme program. and “optional” in this report are to be interpreted as described in RFC 2119 [3]. It then opens the ﬁle using open-file-input-port (see library section 8. and instead the 3 is passed to the continuation that adds 1: (+ 1 (call-with-current-continuation (lambda (escape) (+ 2 (escape 3))))) =⇒ 4 procedure from the (rnrs programs (6)) library (see library chapter 10). Top-level programs A Scheme program is invoked via a top-level program. The following top-level program obtains the ﬁrst argument from the command line via the command-line . a particular implementation may allow the programmer to ignore the recommendation of the report and even exhibit reasonable behavior. The hello-world export is a procedure that displays Hello World on a separate line: (library (hello) (export hello-world) (import (rnrs base) (rnrs io simple)) (define (hello-world) (display "Hello World") (newline))) 1. or the adjective “optional”. calls it immediately with an argument that is an escape procedure. means that valid reasons may exist in particular circumstances to ignore a statement. the escape procedure abandons its own continuation. The continuation of the call to escape is abandoned.e. but cannot be practically detected by an implementation. means that an item is truly optional. a top-level program contains imports. The key words “must”. In such circumstances. and calls the get-bytes-all procedure to obtain the contents of the ﬁle as binary data. 1. should not This phrase. Requirement levels An escape procedure has unlimited extent: It can be called after the continuation it captured has been invoked. but that the implications should be understood and weighed before choosing the course described by the statement. means that valid reasons may exist in particular circumstances when the behavior of a statement is acceptable. Each library contains deﬁnitions and expressions. It can import deﬁnitions from other libraries and export deﬁnitions to other libraries. and then called with 3 as an argument. but that the implications must be understood and weighed before choosing a diﬀerent course. a connection to the ﬁle as a data source. The following library called (hello) exports a deﬁnition called hello-world. this report occasionally uses “should” to designate circumstances that are outside the speciﬁcation of this report.3). see section 5.2. “should not”. their execution might produce diﬀerent results on different implementations. In the following example. these programs may be unportable. i. In particular. Libraries Scheme code can be organized in components called libraries. However. Requirement levels 9 by creating a procedure that reinstates the current continuation.2. Like a library. may This word. “must not”.12. that is. and speciﬁes an entry point for execution. This escape procedure can then be called with an argument that becomes the result of the call to call-with-current-continuation. deﬁnitions and expressions. and it can be called multiple times. via the transitive closure of the libraries it imports. or the phrase “not recommended”.4. or the adjective “recommended”. and reinstates the continuation of the call to call-with-current-continuation. Thus a top-level program deﬁnes. yielding a port. as the report does not specify the behavior. “recommended”. should This word. must not This phrase means that a statement is an absolute prohibition of the speciﬁcation. “may”. an escape procedure representing the continuation that adds 1 to its argument is bound to escape. That is.13. “should”. This makes call-with-current-continuation signiﬁcantly more powerful than typical non-local control constructs such as exceptions in other languages. It then uses put-bytes to output the contents of the ﬁle to standard output: #!r6rs (import (rnrs base) (rnrs io ports) (rnrs programs)) (put-bytes (standard-output-port) (call-with-port (open-file-input-port (cadr (command-line))) get-bytes-all)) 2. and imports the base library (see chapter 11) and the simple I/O library (see library section 8. The call-with-current-continuation procedure accepts a procedure. Speciﬁcally: must This word means that a statement is an absolute requirement of the speciﬁcation.

and the term number object refers to a Scheme object representing a number. Exact arithmetic is reliable in the following sense: If exact number objects are passed to any of the arithmetic procedures described in section 11. Moreover. The ﬁxnum and ﬂonum types refer to special subsets of the number objects. This is generally not true of computations involving inexact number objects because approximate methods such as ﬂoating-point arithmetic may be used. as determined by common machine representations. real?.) Likewise. Thus inexactness is contagious.4. and a complex. complex?. every implementation must designate a subset of its inexact real number objects as ﬂonums.10 Revised6 Scheme may need to know the index exactly. and notations used to write numbers. real. Exact number objects correspond to mathematical numbers in the obvious way. and integer?. It is important to distinguish between the mathematical numbers. a real. In this report. and to convert certain external representations into ﬂonums. On the other hand.2 describes a library for computing with ﬁxnums.7. and those number objects whose computation involved rounding or other errors. Numerical tower Numbers may be arranged into a tower of subsets in which each level is a subset of the level above it: number complex real rational integer For example.4. rational?. 3.7. Fixnums and ﬂonums A ﬁxnum is an exact integer object that lies within a certain implementation-dependent subrange of the exact integer objects.7. a number object is inexact if it is the value of an inexact numerical literal.2. The same is true of the number objects that model 5.) 3. There is no simple relationship between the subset that contains a number and its representation inside a computer. or was derived using inexact operations. A number object is exact if it is the value of an exact numerical literal or was derived from exact number objects using only exact operations. the machine representations used to implement the numbers. 5 is an integer. the results of measurements are inherently inexact. Therefore 5 is also a rational. this report occasionally uses the phrase “not required” to note the absence of an absolute requirement.1. (Library section 11. as explained below. For example. the term number refers to a mathematical number. For example. Conversely. (“Practically unlimited” means that the size and precision of these numbers should only be limited by the size of the available memory.1. as independent of their representation as possible.3. Integer number objects are also called integer objects. Number objects are organized as a corresponding tower of subtypes deﬁned by the predicates number?. Scheme explicitly distinguishes exact from inexact number objects. Exactness It is useful to distinguish between number objects that are known to correspond to a number exactly. but it is the duty of each implementation to make the result as close as practical to the mathematically ideal result.1) so they always return exact results when given exact arguments. This distinction is orthogonal to the dimension of type. 3. the Scheme objects that attempt to model them. 3. Numbers This chapter describes Scheme’s model for numbers. Scheme’s numerical operations treat number objects as abstract data. or was derived from inexact number objects. and an exact number object is returned. then the result is mathematically correct. 3. and irrational numbers may be approximated by rational and therefore inexact approximations. Implementation requirements Implementations of Scheme must support number objects for the entire tower of subtypes given in section 3.1. the integer 5 may have several representations. (Library section 11.) Note that this does not imply that an implementation must use ﬂoating-point representations. This report uses the types complex. see section 11.3 describes a library for computing with ﬂonums. this should not be apparent to a casual programmer writing simple programs. Moreover. In order to catch uses of numbers known only inexactly where exact numbers are required. index operations into data structures . and to implement certain procedures (listed in 11. and integer to refer to both mathematical numbers and number objects. Although an implementation of Scheme may use many diﬀerent representations for numbers. rational. implementations must support exact integer objects and exact rational number objects of practically unlimited size and precision. as may some operations on polynomial coeﬃcients in a symbolic algebra system.

3. then the most precise ﬂoating-point format available must be used. It is also a source of power. where a syntactic datum is a recursively structured entity.4. 2. These speciﬁcations are marked with “if −0. that the IEEE ﬂoating-point standards be followed by implementations that use ﬂoating-point representations. positive and negative inexact zero. Lexical syntax and datum syntax The syntax of Scheme code is organized in three levels: 1. the program syntax formulated in terms of the read syntax. Positive inﬁnity is regarded as an inexact real (but not rational) number object that represents an indeterminate number greater than the numbers represented by all rational number objects. speciﬁcally those that follow the IEEE ﬂoating-point standards. Scheme’s syntax has the property that any sequence of characters that is a form is also a syntactic datum representing some object. and NaN. speciﬁcally those that follow the IEEE ﬂoating-point standards. This report will sometimes specify the behavior of certain arithmetic operations on these number objects.0 Some Scheme implementations. and that implementations using other representations should match or exceed the precision achievable using these ﬂoating-point standards [13]. when applied to exact arguments. “(8 .0”.6. . and Scheme’s (rnrs io ports (6)) library (library section 8.0 is distinguished” or “implementations that distinguish −0. 3. If.4. An implementation may use ﬂoating point and other approximate representation strategies for inexact numbers. Lexical syntax and datum syntax 11 Implementations may support only a limited range of inexact number objects of any type.2) provides the get-datum and put-datum procedures for reading and writing syntactic data. Negative inﬁnity is regarded as an inexact real (but not rational) number object that represents an indeterminate number less than the numbers represented by all rational numbers. Syntactic data (also called external representations) double as a notation for objects. and might even be greater than positive inﬁnity or less than negative inﬁnity. implementations that use ﬂoating-point representations must follow these rules: A ﬂoating-point result must be represented with at least as much precision as is used to express any of the inexact arguments to that operation. However. but if the result is represented in some other way then the representation must have at least as much precision as the most precise ﬂoating-point format available. converting between their textual representation and the corresponding objects. distinguish between number objects for 0. since it facilitates writing programs such as interpreters or compilers that treat programs as objects (or vice versa).5. but does not require. (13 . 4.0 and −0. imposing further structure and assigning meaning to syntactic data. A NaN is regarded as an inexact real (but not rational) number object so indeterminate that it might represent any real number. Syntactic data in Scheme source code are called forms. an implementation may limit the range of the inexact real number objects (and therefore the range of inexact integer and rational number objects) to the dynamic range of the ﬂonum format. In particular. since it may not be obvious out of context whether a given sequence of characters is intended to be a representation of objects or the text of a program. “( 08 13 )”. should produce exact answers whenever possible (for example the square root of an exact 4 ought to be an exact 2). negative inﬁnity. the lexical syntax that describes how a program text is split into a sequence of lexemes. the datum syntax. (A form nested inside another form is called a subform.. For example. this is not required. A datum value may have several diﬀerent external representations. Potentially inexact operations such as sqrt. A syntactic datum can be used in a program to obtain the corresponding datum value using quote (see section 11.000” and “#x1c” are syntactic data representing the exact integer object 28. including positive or negative inﬁnity. an exact number object is operated upon so as to produce an inexact result (as by sqrt). i.1). Distinguished -0. subject to the requirements of this section. formulated in terms of the lexical syntax. Furthermore the gaps between the inexact integer objects and rationals are likely to be very large in such an implementation as the limits of this range are approached. This report recommends. Scheme source code consists of syntactic data and (nonsigniﬁcant) comments. This can lead to confusion. both “#e28.e. and the syntactic data “(8 13)”. on the other hand.0. and if the result is represented in ﬂoating point.) Consequently. that structures the lexeme sequence as a sequence of syntactic data. 3. Each syntactic datum represents a corresponding datum value. Inﬁnities and NaNs Some Scheme implementations. For example. It is the programmer’s responsibility to avoid using inexact number objects with magnitude or signiﬁcand too large to be represented in the implementation. distinguish special number objects called positive inﬁnity.

The identiﬁer Foo is. distinct from the identiﬁer FOO. Nl. space (U+0020). such as identiﬁers. The following two characters are reserved for future extensions to the language: { } lexeme −→ identiﬁer | boolean | number | character | string | ( | ) | [ | ] | #( | #vu8( | ’ | ` | . Some of the lexemes. and boolean s. All spaces in the grammar are for legibility. or Zp line ending −→ linefeed | carriage return | carriage return linefeed | next line | carriage return next line | line separator comment −→ . line tabulation (U+000B). however.@ delimiter −→ ( | ) | [ | ] | " | .. or Co ()))” all represent a list containing the exact integer objects 8 and 13.2. | #’ | #` | #. however. . Syntactic data that represent equal objects (in the sense of equal?. as a syntax violation. No. omitting non-signiﬁcant portions such as comments and whitespace. and whose category is Lu. and in hexadecimal numbers specifying Unicode scalar values. of the lexical syntax are syntactic data in the datum syntax. with one exception: it need not treat the syntax #! identiﬁer . Ll. but not within a lexeme.4) that is not r6rs. Being comments. character s.1. | Z constituent −→ letter | any character whose Unicode scalar value is greater than 127.5) are always equivalent as forms of a program. and paragraph separator (U+2029). carriage return (U+000D). The syntax #!r6rs may be used to signify that the input afterward is written with the lexical syntax and datum syntax described by this report. Lo. The character sequence is assumed to be text according to the Unicode standard [27]. line separator (U+2028).. number objects. | z | A | B | C | . which is described . Po. #!r6rs is otherwise treated as a comment. Mn. and thus represent objects. Non-terminals are written using angle brackets. this report sometimes uses the term datum for either a syntactic datum or a datum value when the exact meaning is apparent from the context. all subsequent characters up to a line ending or paragraph separator | nested comment | #. number s. 4. Identiﬁer s. strings etc. | # | whitespace whitespace −→ character tabulation | linefeed | line tabulation | form feed | carriage return | next line | any character whose category is Zs. Besides the formal account of the syntax. interlexeme space datum | #!r6rs nested comment −→ #| comment text comment cont * |# comment text −→ character sequence not containing #| or |# comment cont −→ nested comment comment text atmosphere −→ whitespace | comment interlexeme space −→ atmosphere * identiﬁer −→ initial subsequent * | peculiar identiﬁer initial −→ constituent | special initial | inline hex escape letter −→ a | b | c | . these datum s do not play a signiﬁcant role in the syntax. next line (U+0085). and thing + means at least one thing . The lexical syntax.2. Because of the close correspondence between syntactic data and datum values. Sc. contains a forward reference to datum .2. Pc. Some non-terminal names refer to the Unicode scalar values of the same name: character tabulation (U+0009). Sk. Lm. in the description of comments. form feed (U+000C).12 Revised6 Scheme as part of the datum syntax. stands for the empty string. and it may use speciﬁc #!-preﬁxed identiﬁers as ﬂags indicating that subsequent input contains extensions to the standard lexical or datum syntax.. carriage return (U+000D). must be terminated by a delimiter or by the end of the input. Case is insigniﬁcant for non-terminal names. So. Lexical syntax The lexical syntax determines how a character sequence is split into a sequence of lexemes. for any identiﬁer (see section 4. Lt. 4.. | #. #x1A and #X1a are equivalent. Empty The following extensions to BNF are used to make the description more concise: thing * means zero or more occurrences of thing . Zl. | . Pd. For example. Sm. Notation The formal syntax for Scheme is written in an extended BNF.@ | ... see section 4. this section also describes what datum values are represented by these syntactic data. An implementation must not extend the lexical or datum syntax in any way. linefeed (U+000A). Case is signiﬁcant except in representations of booleans.1.2. see section 11. Formal account Interlexeme space may occur on either side of any lexeme. 4. representations of number objects.3.

decimal 8 .. line tabulations. for example. Moreover.ureal R i | real R + naninf i | real R .3) and within string literals. Zl.ureal R i | + naninf i | . or Me | special subsequent digit −→ 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 hex digit −→ digit | a | A | b | B | c | C | d | D | e | E | f | F special subsequent −→ + | . Whitespace may occur between any two lexemes. and decimal 16 . but not within a lexeme. ureal R .i | + ureal R i | . Whitespace and comments Whitespace characters are spaces. 4.2.| . Line endings Line endings are signiﬁcant in Scheme in single-line comments (see section 4. 8.2. carriage returns.naninf i | + i | . or Zp. linefeeds. except that they act as delimiters. any of the line endings in line ending marks the end of a line.4. hex scalar value −→ hex digit + peculiar identiﬁer −→ + | . suﬃx uinteger R −→ digit R + preﬁx R −→ radix R exactness | exactness radix R suﬃx −→ empty | exponent marker sign digit 10 + exponent marker −→ e | E | s | S | f | F | d | D | l | L mantissa width −→ empty | | digit 10 + sign −→ empty | + | exactness −→ empty | #i | #I | #e | #E radix 2 −→ #b | #B radix 8 −→ #o | #O radix 10 −→ empty | #d | #D radix 16 −→ #x | #X digit 2 −→ 0 | 1 digit 8 −→ 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 digit 10 −→ digit digit 16 −→ hex digit 4. | @ inline hex escape −→ \x hex scalar value .2. character tabulations. so. which means that number representations containing decimal points or exponents must be in decimal radix. | -> subsequent * boolean −→ #t | #T | #f | #F character −→ #\ any character | #\ character name | #\x hex scalar value character name −→ nul | alarm | backspace | tab | linefeed | newline | vtab | page | return | esc | space | delete string −→ " string element * " string element −→ any character other than " or \ | \a | \b | \t | \n | \v | \f | \r | \" | \\ | \ intraline whitespace line ending intraline whitespace | inline hex escape intraline whitespace −→ character tabulation | any character whose category is Zs A hex scalar value represents a Unicode scalar value between 0 and #x10FFFF. uinteger R .naninf i | real R + i | real R . 10. where it is signiﬁcant. a comment cannot appear in the middle of an identiﬁer or representation of a number object.2. . In a string literal. real R . The lexical syntax includes several comment forms.| . The rules for num R . a line ending not preceded by a \ stands for a linefeed character. There are no rules for decimal 2 .naninf naninf −→ nan. comments are invisible to Scheme. number −→ num 2 | num 8 | num 10 | num 16 num R −→ preﬁx R complex R complex R −→ real R | real R @ real R | real R + ureal R i | real R . Whitespace is used for improved readability and as necessary to separate lexemes from each other. #xDFFF].0 | inf. Whitespace may also occur inside a string.. In all cases. and preﬁx R below should be replicated for R = 2. which is the standard lineending character of Scheme.3. digit 10 * suﬃx | digit 10 + . and 16. complex R . the two-character line endings carriage return linefeed and carriage return next line each count as a single line ending. form feeds.i real R −→ sign ureal R | + naninf | . Mc.0 ureal R −→ uinteger R | uinteger R / uinteger R | decimal R mantissa width decimal 10 −→ uinteger 10 suﬃx | . excluding the range [#xD800. digit 10 + suﬃx | digit 10 + . In Scheme source code. Lexical syntax and datum syntax 13 special initial −→ ! | $ | % | & | * | / | : | < | = | > | ? | ^ | _ | ~ subsequent −→ initial | digit | any character whose category is Nd. and any other character whose category is Zs.

Pd. |# (define fact (lambda (n) . / : < = > ? @ ^ _ ~ Moreover. base case (if (= n 0) #. Sm. 4. In general. are identiﬁers. Here are some examples of identiﬁers: lambda q soup list->vector + V17a <= a34kTMNs ->the-word-recursion-has-many-meanings Extended alphabetic characters may be used within identiﬁers as if they were letters. possibly with interlexeme space before the datum .) indicates the start of a line comment. Lt. Ll. Identiﬁers Most identiﬁers allowed by other programming languages are also acceptable to Scheme.1) with #. all characters whose Unicode scalar values are greater than 127 and whose Unicode category is Lu. Characters Characters are represented using the notation #\ character or #\ character name or #\x hex scalar value . and . For example: #\a #\A #\( #\ #\nul #\alarm #\backspace #\tab #\linefeed #\newline #\vtab #\page #\return #\esc #\space #\delete #\xFF #\x03BB #\x00006587 #\λ #\x0001z #\λx #\alarmx #\alarm x #\Alarm #\alert #\xA #\xFF #\xff #\x ff lower case letter a upper case letter A left parenthesis space character U+0000 U+0007 U+0008 U+0009 U+000A U+000A U+000B U+000C U+000D U+001B U+0020 preferred way to write a space U+007F U+00FF U+03BB U+6587 U+03BB &lexical exception &lexical exception &lexical exception U+0007 followed by x &lexical exception &lexical exception U+000A U+00FF U+00FF U+0078 followed by another datum. Nd.n 1)))))) The lexeme #!r6rs. Po. and the identiﬁer \x3BB.2.4. Pc. The comment continues to the end of the line on which the semicolon appears. -. The comment consists of the comment preﬁx #. #| The FACT procedure computes the factorial of a non-negative integer. In addition. ff A semicolon (.3. identity of * (* n (fact (. Sk. Any identiﬁer may be used as a variable or as a syntactic keyword (see sections 5.. Booleans The standard boolean objects for true and false have external representations #t and #f. is also otherwise treated as a comment. digits. For example. Any identiﬁer may also be used as a syntactic datum. or Co can be used within identiﬁers. section 4. +. Lo. in which case it represents a symbol (see section 11. and extended alphabetic characters that begins with the two-character sequence ->.. 4. digits.(= n 1) 1 . No.2.. which signiﬁes that the program text that follows is written with the lexical and datum syntax described in this report.llo is the same as the identiﬁer Hello. Block comments may be indicated with properly nested #| and |# pairs. 4. any character can be used within an identiﬁer when .14 Revised6 Scheme speciﬁed via an inline hex escape . the identiﬁer H\x65. Me. The following are extended alphabetic characters: ! $ % & * + . Mc. and “extended alphabetic characters” is an identiﬁer when it begins with a character that cannot begin a representation of a number object.. is the same as the identiﬁer λ. Sc. and the datum together.10). So.2. In addition. Lm. Another way to indicate a comment is to preﬁx a datum (cf.. Nl.5.6. This notation is useful for “commenting out” sections of code.2 and 9. as is a sequence of letters. Mn. a sequence of letters.2) in a Scheme program.

U+0062. U+000D • \" : doublequote. Within a string literal. U+0062. except that the alphabetic digits of a hex scalar value can be uppercase or lowercase. the constant is inexact if it contains a decimal point. or a nonempty mantissa width. it may be useful to specify the precision of a constant. parenthesized x #\x00110000 &lexical exception out of range #\x000000001 U+0001 #\xD800 &lexical exception in excluded range These escape sequences are case-sensitive. U+0020. U+0062.bc" "\x41. Numbers The syntax of external representations for number objects is described formally by the number rule in the formal grammar. In systems with inexact number objects of varying precisions." U+41BC "\x41" &lexical exception "\x. U+000C • \r : return. This rule resolves various ambiguous cases involving named characters. requiring. and in #\ character name . or hexadecimal by the use of a radix preﬁx. bc" 4. Escape sequences always start with a backslash (\): • \a : alarm. Note: The #\newline notation is retained for backward compatibility." &lexical exception in excluded range "A bc" U+0041. A representation of a number object may be speciﬁed to be either exact or inexact by a preﬁx. For example the single-character string literal "λ" (doublequote. U+0063 "\x41bc." "A" . #d (decimal). a representation of a number object is assumed to be expressed in decimal. U+0041. decimal. U+0007 • \b : backspace. U+0022 • \\ : backslash. Its use is deprecated. A character must be followed by a delimiter or by the end of the input. A representation of a number object may be written in binary. U+0063 "A bc" U+0041." &lexical exception "\x41bx. U+0008 • \t : character tabulation.7. U+0041 "\x0010FFFF. A line ending that does not follow a backslash stands for a linefeed character.8." &lexical exception out of range "\x000000001. . Strings String are represented by sequences of characters enclosed within doublequotes ("). but not in #\x hex scalar value . An exactness preﬁx may appear before or after any radix preﬁx that is used. Case is not signiﬁcant in external representations of number objects. The radix preﬁxes are #b (binary). doublequote) represents the same string as "\x03bb. 4. U+000A." &lexical exception "\x00000041." U+0001 "\xD800.4. U+000B • \f : formfeed. U+005C • \ intraline whitespace line ending intraline whitespace : nothing • \x hex scalar value . #o (octal). Examples: U+0061. (The notation &lexical exception means that the line in question is a lexical syntax violation. If the representation of a number object has no exactness preﬁx. an exponent. : speciﬁed character (note the terminating semi-colon).".2. for example.) Case is signiﬁcant in #\ character . Except for a line ending. U+000A • \v : line tabulation. a lower case lambda. U+0062. With no radix preﬁx. Lexical syntax and datum syntax 15 #\x(ff) U+0078 followed by another datum. The preﬁxes are #e for exact. otherwise it is exact. U+0063 "Abc" . various escape sequences represent characters other than themselves. any character outside of an escape sequence and not a doublequote stands for itself in the string literal. Any other character in a string after a backslash is a syntax violation. U+0009 • \n : linefeed. a parenthesized ff #\(x) &lexical exception #\(x &lexical exception #\((x) U+0028 followed by another datum.2. and #i for inexact. the sequence of characters “#\space” to be interpreted as the space character rather than as the character “#\s” followed by the identiﬁer “pace”. octal. #\linefeed should be used instead. U+0063 if no space occurs after the A "abc" "\x41. and #x (hexadecimal)." U+10FFFF "\x00110000.

. Pairs and lists List and pair data. the default precision can be calculated by calling the following procedure: (define (precision) (do ((n 0 (+ n 1)) (x 1.0 and -inf. (When fewer than four internal inexact representations exist.2. For this purpose. enclosed by ( ) or [ ] (see section 4. single. The letters s.0 0.2) • vectors (see section 4. and long precision.0))) ((= 1. or by a greater precision if a p-bit signiﬁcand is not practical. Formal account The following grammar describes the syntax of syntactic data in terms of various kinds of lexemes deﬁned in the grammar in section 4. 3. Whether that bit is implicit or explicit does not aﬀect the mathematical precision.0 x)) n))) Note: When the underlying ﬂoating-point representation is IEEE double precision.3) • bytevectors (see section 4.141593 0. and may represent other NaNs as well. The +nan. In the IEEE ﬂoating-point standards. but that is not required by this report. If x is an external representation of an inexact real number object that contains no vertical bar. respectively.2: datum −→ lexeme datum | compound datum lexeme datum −→ boolean | number | character | string | symbol symbol −→ identiﬁer compound datum −→ list | vector | bytevector list −→ ( datum *) | [ datum *] | ( datum + . and therefore their external representations should carry a |p suﬃx with the actual width of the signiﬁcand. for example. the inexact real number object it represents is a ﬂonum (see library section 11.3. datum ] | abbreviation abbreviation −→ abbrev preﬁx datum abbrev preﬁx −→ ’ | ` | .9) are represented using parentheses or brackets.0 represent positive and negative inﬁnity.3.6L0 Extend to long. x |p. A representation of a number object with nonempty mantissa width. the exponent marker e speciﬁes the default precision for the implementation. and l specify the use of short.0). | #. the signiﬁcand’s most signiﬁcant bit is implicit in single and double precision but is explicit in extended precision. representing pairs and lists of values (see section 11. represents the best binary ﬂoating-point approximation of x using a p-bit signiﬁcand. . d.) In addition. For example.4) 4. . datum ) | [ datum + . but implementations may wish to allow this default to be set by the user. The default precision has at least as much precision as double. respectively.1|53 is a representation of the best approximation of 1. .@ vector −→ #( datum *) bytevector −→ #vu8( u8 *) u8 −→ any number representing an exact integer in {0. Implementations that use binary ﬂoating-point representations of real number objects should represent x |p using a p-bit signiﬁcand if practical.0 (/ x 2. the |p suﬃx should not always be omitted: Denormalized ﬂoating-point numbers have diminished precision. The literals +inf. .@ | #’ | #` | #.0 literal represents the NaN that is the result of (/ 0.1415926535898F0 Round to single. 1. an implementation with two internal representations may map short and single together and long and double together.3. representations of number objects may be written with an exponent marker that indicates the desired precision of the inexact representation.1 in IEEE double precision. the four size speciﬁcations are mapped onto those available. or by the largest available precision if p or more bits of signiﬁcand are not practical within the implementation.3. double. f. perhaps 3. In implementations that use binary ﬂoating point. Matching pairs of brackets that occur in the rules of list are equivalent to matching pairs of parentheses.3. Syntactic data include the lexeme data described in the previous section as well as the following constructs for forming compound data: • pairs and lists.3. Datum syntax The datum syntax describes the syntax of syntactic data in terms of a sequence of lexeme s.0 (+ 1. | . 255} 4.1.600000000000000 4. then its numerical value should be computed as though it had a mantissa width of 53 or more. perhaps .16 Revised6 Scheme If x is an external representation of an inexact real number object and contains no vertical bar and no exponent marker other than e. Some or all of the other external representations of inexact real number objects may also represent ﬂonums. as deﬁned in the lexical syntax.3). For example. Note: The precision of a signiﬁcand should not be confused with the number of bits used to represent the signiﬁcand.

#` datum for (quasisyntax datum ). some facilities that are typically implemented as “primitives” by a compiler or the run-time system rather than in terms of other standard procedures or syntactic forms are not part of the base library. a vector of length 3 containing the number object for zero in element 0. rather. .2. Examples include the ﬁxnums and ﬂonums libraries. A library consists of a set of export and import speciﬁcations and a body. are represented using the notation #( datum . Variables. #’ datum for (syntax datum ). respectively. but has no export speciﬁcations. the exceptions and conditions libraries. and #. and also an expression that evaluates to a bytevector. the list (2 2 2 2) in element 1. each of which deﬁnes a part of the program connected to the others through explicitly speciﬁed exports and imports. ()))))) are equivalent notations for a list of symbols.3. #. A separate report [24] describes the various standard libraries provided by a Scheme system. In particular. 4.@ datum Each of these is an abbreviation: ’ datum for (quote datum ). . datum for (unquote datum ). datum . and matching closing parenthesis can be omitted in the external representation. A more streamlined notation can be used for lists: the elements of the list are simply enclosed in parentheses and separated by spaces. Similarly. 24. datum2 ) where datum1 is the representation of the value of the car ﬁeld and datum2 is the representation of the value of the cdr ﬁeld. the elements of which are the symbol + and the integers 2 and 6. if a dot is followed by an open parenthesis. the sequence of characters “(+ 2 6)” is not an external representation of the integer 8. (a b c d e) 17 4. not an expression that evaluates to a pair. A top-level program is similar to a library. The division between the base library and the other standard libraries is based on use.1. For example. Programs and libraries A Scheme program consists of a top-level program together with a set of libraries. datum for (unsyntax datum ). For example (4 .13). . The empty list is represented by () . and regions Within the body of a library or top-level program. For example. Semantic concepts 5. an identiﬁer may name a kind of syntax. 5)” is the external representation of a pair. (c . An identiﬁer that names a This is the external representation of a bytevector. 4. This is the external representation of a vector. . and (a . and 123 can be represented as follows: #vu8(2 24 123) 5. a bytevector of length 3 containing the octets 2. Chapter 11 describes a base library that deﬁnes many of the constructs traditionally associated with Scheme. ). Chapters 7 and 8 describe the syntax and semantics of libraries and top-level programs. and the string "Anna" in element 2 can be represented as follows: #(0 (2 2 2 2) "Anna") 5. not an expression that evaluates to a vector. The general rule is that.@ datum for (unsyntax-splicing datum ). (d . and expressions. (b . which consists of deﬁnitions.5.@ datum for (unquote-splicing datum ). Abbreviations ’ datum ` datum . The sequence of characters “(4 . or it may name a location where a value can be stored. Vectors Vector data. Bytevectors Bytevector data. Semantic concepts The most general notation for Scheme pairs as syntactic data is the “dotted” notation ( datum1 . where the u8 s represent the octets of the bytevector. . the dot.4. 5) is a pair whose car is 4 and whose cdr is 5.5. even though it is an expression (in the language of the (rnrs base (6)) library) evaluating to the integer 8. it is a syntactic datum representing a three-element list. datum #. but are deﬁned in separate libraries. . For example. ). . representing bytevectors (see library chapter 2). (e . not on construction. representing vectors of objects (see section 11. open parenthesis.3.@ datum #’ datum #` datum #.3. ` datum for (quasiquote datum ).3. keywords. are represented using the notation #vu8( u8 . and the libraries for records.

letrec. Collectively.1) is a deﬁnition that creates a variable binding (see section 11.1. Some exceptional situations allow continuing the program if the exception handler takes appropriate action. When an exception is raised. Expressions that bind variables include the lambda. a transformer that translates the syntax into more primitive forms. A program can also raise an exception. let. In some cases. Certain forms are used to create syntactic abstractions and to bind keywords to transformers for those new syntactic abstractions. The region is determined by the particular binding construct that establishes the binding. Exported library bindings are also visible within the bodies of the libraries and toplevel programs that import them (see chapter 7). If a use of an identiﬁer appears in a place where none of the surrounding expressions contains a binding for the identiﬁer. see library section 7.2. then its region is the entire lambda expression. and is said to be bound to that kind of syntax (or. a speciﬁc. Of these. while other forms create new locations and bind variables to those locations. An identiﬁer that names a location is called a variable and is said to be bound to that location. among them violations of syntax.4. Variable definitions appearing within the body of such an expression.3. and a define-syntax form is a deﬁnition that creates a keyword binding (see section 11.2. The set of these identiﬁers. Every mention of an identiﬁer refers to the binding of the identiﬁer that establishes the innermost of the regions containing the use. if the binding is established by a lambda expression. a procedure accepts only speciﬁc numbers and types of arguments.2 to describe exceptional situations. for library bodies. portable programs cannot rely upon the exception being continuable at the place where the situation was detected. are treated as a set of letrec* bindings. an object is provided that describes the nature of the exceptional situation. an implementation that does not support inﬁnities must raise an exception with condition type &implementation-restriction when it evaluates an expression whose result would be an inﬁnity. see section 9.2) are anticipated by this report. At each point within a top-level program or a library. Implementations must raise an exception when they are unable to continue correct execution of a correct program due to some implementation restriction. which means that a special procedure called the current exception handler is called. 11.2). ﬁxed set of identiﬁers is bound. 5. e. top-level program. This report uses the phrase “an exception with condition type t” to indicate that the object provided with the exception is a condition object of the speciﬁed type. violations of a procedure’s speciﬁcation. letrec*. For most of the exceptional situations described in this report. classifying them by condition types. and exceptional situations in the environment. a binding created by a deﬁnition is visible only within the body in which the deﬁnition appears. Expressions that bind keywords include the let-syntax and letrec-syntax forms (see section 11.18 Revised6 Scheme kind of syntax is called a keyword.g. and let*-values forms from the base library (see sections 11. With the exception of exported library bindings. The corresponding exceptions are called continuable. or lambda expression. the use may refer to a binding established by a deﬁnition or import at the top of the enclosing library or top-level program (see chapter 7). and implementations typically must raise an exception of the appropriate condition type if they encounter such a situation.7. If there is no binding for the identiﬁer.6). Some possible implementation restrictions such as the lack of representations for NaNs and inﬁnities (see section 11. an exception is raised . This report uses the phrase “an exception is raised” synonymously with “an exception must be raised”. Exceptional situations A variety of exceptional situations are distinguished in this report. The report uses the condition system described in library section 7. or syntactic keyword.4. Argument checking Many procedures speciﬁed in this report or as part of a standard library restrict the arguments they accept. lambda is the most fundamental. is known as the environment in eﬀect at that point.2). To each place in a top-level program or library body where an identiﬁer is bound there corresponds a region of code within which the binding is visible. Scheme is a statically scoped language with block structure. these forms are called binding constructs. while others are expressions.2). 5. The phrase “a continuable exception is raised” indicates an exceptional situation that permits the exception handler to return. See library section 7. however.18). violations of implementation restrictions. for example. and override the current exception handler.2. A define form (see section 11. the body of a library. the variables exported from the library can be referenced by importing libraries and top-level programs.. Typically.1. Some binding constructs take the form of deﬁnitions. let*. in the case of a syntactic abstraction. the set of visible bindings. In addition. and the handler may return. it is said to be unbound. For those exceptions.4. continuing is permissible. Many syntactic forms similarly restrict the . let-values. When an exceptional situation is detected by the implementation. the exception handler that is invoked by the exception should not return. For example. or within the bodies of a library or top-level program.

Violations of an implementation restriction must raise an exception with condition type &implementationrestriction. The implementation must check that the restrictions in the speciﬁcation are indeed met. 5. as must all violations and errors that would otherwise threaten system integrity in ways that might result in execution that is inconsistent with the semantics described in this document. and execution of that top-level program or library must not be allowed to begin. and necessary to allow the speciﬁed operation to complete successfully. For example. Semantic concepts values to which one or more of their subforms can evaluate. then the implementation must raise an exception with condition type &syntax. Libraries and toplevel programs that import only from safe libraries are also said to be safe. The implementation’s responsibilities are speciﬁed in more detail in chapter 6 and throughout the report. Safety The standard libraries whose exports are described by this document are said to be safe libraries. some operations accept both lists and procedures that are called by these operations. if an operation is speciﬁed to accept a procedure with speciﬁc properties. In particular.1) is also considered a syntax violation. checking of these properties is undecidable in general. implementations must detect violations of the syntax. For example. As forms may be subject to macro expansion. some operations that accept lists only need to traverse these lists partially to perform their function. This report uses the word “true” to refer to any Scheme value except #f. any Scheme value can be used as a boolean value for the purpose of a conditional test.. unless an exception is raised. attempting to assign to an immutable variable (i. 19 If a top-level or library form in a program is not syntactically correct. A syntax violation is an error with respect to the syntax of library bodies. 5. These values are passed to the expression’s continuation.6. which may not terminate. the variables exported by a library. see section 7. Speciﬁcally. Multiple return values The subforms of a special form usually need to obey certain syntactic restrictions. For these reasons. Syntax violations 5. When macro expansion terminates. Similarly.15 makes it possible to create continuations that accept speciﬁed numbers of return values. Moreover. The call-with-values procedure described in section 11. it must raise an exception with condition type &assertion in a way consistent with the safety of execution as described in section 5. Since lists can be mutated by the procedures through the (rnrs mutable-pairs (6)) library (see library chapter 17). the Scheme programming language is safe in the following sense: The execution of a safe top-level program cannot go so badly wrong as to crash or to continue to execute while behaving in ways that are inconsistent with the semantics described in this document. all values count as true in such a test except for #f. implementations may provide access to unsafe libraries in ways that cannot guarantee safety. Also. however. Boolean values Although there is a separate boolean type. or the “syntax” entries in the speciﬁcation of the base library or the standard libraries. top-level bodies.e. a continuation that accepts the argument to a procedure call is guaranteed to accept exactly one value. A Scheme expression can evaluate to an arbitrary ﬁnite number of values. Not all continuations accept any number of values.8. to the extent that it is reasonable. Furthermore. The above safety properties are guaranteed only for toplevel programs and libraries that are said to be safe. In a conditional test.5.6. If the number of return values passed to a continuation created by a call to call-with-values is not accepted by . requiring the implementation to traverse the remainder of the list to verify that all speciﬁed restrictions have been met might violate reasonable performance assumptions.7. and the word “false” to refer to #f. preventing the operation from performing more checks.5. When an implementation detects a violation of a restriction for an argument. the programmer’s obligations may exceed the checking obligations of the implementation. Requiring the operation to check that the argument is a list after each call to such a procedure would be impractical. the question of whether they obey the speciﬁed restrictions is undecidable in general. As deﬁned by this document. The eﬀect of passing some other number of values to such a continuation is unspeciﬁed. 5. These restrictions imply responsibilities for both the programmer and the implementation. the procedure might escape to a diﬀerent continuation. an argument that is a list when the operation starts may become a non-list during the execution of the operation. the programmer is responsible for ensuring that the values indeed adhere to the restrictions described in the speciﬁcation. possible. Note that it is not always possible for an implementation to completely check the restrictions set forth in a speciﬁcation.

15.15) allows reentering a dynamic extent after its procedure call has returned.11. contains as many locations as there are characters in the string. Programmers should not rely on a speciﬁc number of return values or the speciﬁc values themselves. Whenever this report speaks of storage being allocated for a variable or object. Thus.15). hashtables. Proper tail recursion Implementations of Scheme must be properly tail-recursive. Entry format The chapters that describe bindings in the base library and the standard libraries are organized into entries. where a feature is either a syntactic construct or a built-in procedure. and the chosen locations are marked to indicate that they are now in use before the variable or object is made to refer to them. Storage model Variables and objects such as pairs. An object fetched from a location. while all objects created by the other procedures listed in this report are mutable. and restored by invoking the escape procedure it creates. 6. the dynamic extent of a call may not be a single. Each entry describes one language feature or a group of related features.12. and other values explicitly designated as immutable are immutable objects. then an exception is raised. 5.10. When such a call returns. for the dynamic extent of a call to a procedure like dynamic-wind or with-exception-handler. (These locations need not correspond to a full machine word. Note that this includes regular returns as well as returns through continuations captured earlier by call-with-current-continuation that are later invoked. it is convenient to imagine that every object that refers to locations is associated with a ﬂag telling whether that object is mutable or immutable. A formal deﬁnition of proper tail recursion can be found in Clinger’s paper [5]. Every location is marked to show whether it is in use. In the absence of captured continuations. this report explicitly does not say how many or what values should be returned. Dynamic extent and the dynamic environment For a procedure call. is equivalent in the sense of eqv? (section 11. but the values returned depend on the implementation. Procedure calls that occur in certain syntactic contexts called tail contexts are tail calls. the time between when it is initiated and when it returns is called its dynamic extent. vectors. and the raise procedure (library section 7. the values of literal expressions) to reside in read-only memory. calls could return at most once and the active calls would be those that had not yet returned. then the expression must evaluate without raising an exception. An attempt 5. what is meant is that an appropriate number of locations are chosen from the set of locations that are not in use.20. No variable or object ever refers to a location that is not in use. A string. The rules for identifying tail calls in constructs from the (rnrs base (6)) library are described in section 11. 5. 5. For example. An entry begins with one or more header lines of the form .e. Some operations described in the report acquire information in addition to their explicit arguments from the dynamic environment. its consumer that was passed in that call. A number of forms in the base library have sequences of expressions as subforms that are evaluated sequentially. connected time period. Consequently. or string-ref. for example. strings.1) accesses the current exception handler. call-with-current-continuation (section 11. it is captured by call-with-current-continuation.) A new value may be stored into one of these locations using the string-set! procedure. To express this. A call is active if the called procedure may still return. In Scheme. It is desirable for constants (i. The continuations discarding these values accept any number of values.5) to the object last stored in the location before the fetch. A more complete description of the number of values accepted by diﬀerent continuations and the consequences of passing an unexpected number of values is given in the description of the values procedure in section 11. The dynamic environment can be thought of as part of the dynamic extent of a call. with the return values of all but the last expression being discarded. and records implicitly refer to locations or sequences of locations. but the string contains the same locations as before. the previous dynamic environment is restored. The operations that modify the dynamic environment do so dynamically. the strings returned by symbol->string. A Scheme implementation is properly tail-recursive if it supports an unbounded number of active tail calls. vector-ref. by a variable reference or by a procedure such as car. bytevectors. call-with-currentcontinuation accesses an implicit context established by dynamic-wind (section 11. Unspeciﬁed behavior If an expression is said to “return unspeciﬁed values”.20 Revised6 Scheme to store a new value into a location referred to by an immutable object should raise an exception with condition type &assertion. Literal constants. records with no mutable ﬁelds.9.

. see section 7. Syntactic variables stand for other forms. The header lines (make-vector k ) (make-vector k ﬁll ) procedure procedure The category deﬁnes the kind of binding described by the entry. ”. Also. indicate that the make-vector procedure takes either one or two arguments. . Thus the header line (vector-ref vector k ) procedure indicates that the built-in procedure vector-ref takes two arguments. . for example. the report follows the convention that if a parameter name is also the name of a type. specifying that the syntactic keyword of the construct is exported with level 1. For succinctness. an ellipsis .6) indicates one or more occurrences of a thing . Typically. these specify the programmer’s responsibility. If the implementation detects that a component does not meet the restriction. 127} character (see section 11. at the end of a header line. typically either “syntax” or “procedure”. 6. an exception with condition type &syntax is raised. A procedure that detects an argument that it is not speciﬁed to handle must raise an exception with condition type &assertion. indicates zero or more occurrences of a thing . then the corresponding argument must be of the named type. expression stands for any form which is a syntactically valid expression. . the argument speciﬁcations are exhaustive: if the number of arguments provided in a procedure call does not match any number of arguments accepted by the procedure. and the template gives the syntax of the forms of the construct. It is the implementation’s responsibility to check that these restrictions are satisﬁed.6.9) vector (see section 11. Also. . The notation thing1 . An entry may specify various restrictions on subforms or arguments. For example. . ) procedure indicates that the procedure takes arbitrarily many arguments of the same type as speciﬁed for the last parameter name. . Procedure entries If category is “procedure”. . . Other non-terminals that are used in templates are deﬁned as part of the speciﬁcation. For example.1. as long as the macro transformers involved in expanding the form terminate.2) bytevector (see library chapter 2) procedure (see section 1. . . and the header line gives a template for a call to the procedure. It is the programmer’s responsibility to ensure that each component of a form has the shape speciﬁed by a template.13) string (see section 11. In this case. Case is insigniﬁcant in syntactic variables. a vector vector and an exact non-negative integer object k (see below). . Parameter names in the template are italicized . 255} exact integer object in {−128. variable . Syntax entries If category is “syntax”. the header line for vector-ref given above dictates that the ﬁrst argument to vector-ref must be a vector. identiﬁer stands for a form which must be an identiﬁer. As with syntax templates. in which case only forms matching that non-terminal are permissible in that position. . . The parameter names are caseinsensitive: Vector is the same as vector .3. Again. an exception with condition type &assertion must be raised.11) pair (see section 11. expression . the syntactic keyword is exported with level 0. which are written using angle brackets. or sequences of them. Otherwise.4. and thing1 thing2 . = accepts two or more arguments that must all be complex number objects. The following naming conventions imply type restrictions: obj z x y q n k bool octet byte char pair vector string condition bytevector proc any object complex number object real number object real number object rational number object integer object exact non-negative integer object boolean (#f or #t) exact integer object in {0. Components of the form described by a template are designated by syntactic variables. .2. For background on this.2. Some “syntax” entries carry a suﬃx (expand). . The template is written in a notation similar to a right-hand side of the BNF rules in chapter 4. such a restriction is formulated as a phrase of the form “ x must be a . .12) condition (see library section 7.1). . A syntactic variable may refer to a non-terminal in the grammar for syntactic data (see section 4. . see section 5. Descriptions of syntax may express other restrictions on the components of a form. then the entry describes a procedure. Entry format 21 template category 6. the entry describes a special syntactic construct. as in (= z1 z2 z3 . and describes the set of forms equivalent to the forms matching the template as syntactic data.

3 for a discussion of external representations of objects. In this case. in some cases. Implementation responsibilities In addition to the restrictions implied by naming conventions. 6.4. however.5. the entries from both libraries can be imported under the same name without conﬂict. For example.22 Revised6 Scheme unquote auxiliary syntax Other type restrictions are expressed through parameternaming conventions that are described in speciﬁc chapters. the return value is only speciﬁed conditionally or approximately. For example. to an object that may be represented externally by the sequence of characters “40”. it means that if both entries have the same name and are thus exported from diﬀerent libraries. A parameter called list means that it is the programmer’s responsibility to pass an argument that is a list (see section 11.5707963267948965 . in an environment that imports the relevant library. line condition type The header Moreover. For example: (eqv? "" "") =⇒ unspeciﬁed Mostly. or that an appropriate argument is passed. Evaluation examples The symbol “=⇒” used in program examples can be read “evaluates to”. For example: (atan -inf. 6. to the extent that this is possible and reasonable. As with “syntax” entries. Other kinds of entries If category is something other than “syntax” and “procedure”. who must ensure that the subforms of a form are appropriate. or if the argument is appropriate. This means that both entries are equivalent. which must check that subform adheres to the speciﬁed restrictions (if macro expansion terminates). In some cases. ” (or otherwise using the word “must”). means that the expression (* 5 8) evaluates to the object 40. . the responsibilities speciﬁed for these subforms or arguments in the rest of the description are only for the programmer.0) =⇒ -1. With the listed type restrictions. The header line &who indicates that &who is a condition type. indicates that unquote is a syntax binding that may occur only as part of speciﬁc surrounding expressions. Descriptions of procedures may express other restrictions on the arguments of a procedure. Typically. more precisely: the expression given by the sequence of characters “(* 5 8)” evaluates. such a restriction is formulated as a phrase of the form “x must be a . A description may explicitly list the implementation’s responsibilities for some arguments or subforms in a paragraph labeled “Implementation responsibilities”. approximately . Any use as an independent syntactic construct or identiﬁer is a syntax violation. These explicit restrictions usually describe both the programmer’s responsibilities.3. For example. (integer->char #xD800) =⇒ &assertion exception means that the evaluation (integer->char #xD800) must with condition type &assertion. and the category describes the type of that value. they disambiguate otherwise ambiguous speciﬁcations and are thus normative. See section 4. The “=⇒” symbol is also used when the evaluation of an expression causes a violation. speciﬁcally in the case of inexact number objects.6. some “auxiliary syntax” entries carry a suﬃx (expand).9). it is the programmer’s responsibility to ensure that the corresponding argument is of the speciﬁed type. It is the implementation’s responsibility to check that the argument is appropriately structured for the operation to perform its function. Note that. library chapter 11 uses a number of special parameter variables for the various subsets of the numbers. Equivalent entries The description of an entry occasionally states that it is the same as another entry. (* 5 8) =⇒ 40 6. the “=⇒” symbol is also used to explicitly say that the value of an expression in unspeciﬁed. It is the implementation’s responsibility to check for that type. Or. . then the entry describes a non-procedural value. The implementation must at least check that the argument is either an empty list or a pair. specifying that the syntactic keyword of the construct is exported with level 1. of the expression raise an exception 6. an entry may list additional explicit restrictions. and the implementation’s responsibilities. A paragraph describing implementation responsibility does not aﬀect the implementation’s responsibilities for checking subforms or arguments not mentioned in the paragraph. Speciﬁcally. examples merely illustrate the behavior speciﬁed in the entry.

no identiﬁer can be imported multiple times.e. By convention.. an identiﬁer names a single binding deﬁned within or imported into the library. Libraries Libraries are parts of a program that can be distributed independently.. An import spec must be one of the following: . and distinguishes the phases in which deﬁnitions and imports are needed. An export spec names a set of imported and locally deﬁned bindings to be exported.) (import import spec . the names of predicates—procedures that always return a boolean value—end in “?” when the name contains any letters. • The export subform speciﬁes a list of exports. • The import subform speciﬁes the imported bindings as a list of import dependencies. By convention. preﬁxes that are actual words or can be pronounced as though they were actual words are followed by a hyphen.) 7... Each import spec speciﬁes a set of bindings to be imported into the library. and. macro exports. Libraries 23 6. except when the ﬁrst character following the hyphen would be something other than a letter. the binding is deﬁned in one library. By convention. where version is empty or has the following form: ( sub-version ... No identiﬁers are visible within a library except for those explicitly imported into the library or deﬁned within the library. Naming conventions By convention. The library system supports macro deﬁnitions within libraries. e. The deﬁnitions may be both for local (unexported) and exported bindings. the predicate’s name does not end with a question mark. in which case the hyphen is omitted. list->vector takes a list and returns a vector whose elements are the same as those of the list. and the expressions are initialization expressions to be evaluated for their eﬀects. An empty version is equivalent to (). constraints on its version. and the local names to use within the importing library for each of the library’s exports. the names of procedures that store values into previously allocated locations (see section 5.g. This chapter deﬁnes the notation for libraries and a semantics for library expansion and execution.2. By convention. Otherwise. expand or run time (see section 7. unpronounceable preﬁxes (“fx” and “fl”) are not followed by a hyphen. optionally. otherwise. A rename spec exports the binding named by identiﬁer1 in each ( identiﬁer1 identiﬁer2 ) pairing. An identiﬁer can be imported with the same local name from two or more libraries or for two levels from the same library only if the binding exported by each library is the same (i.. possibly with diﬀerent external names. the components of compound names are separated by “-” In particular... the names of condition types start with “&”.1. An export spec must have one of the following forms: identiﬁer (rename ( identiﬁer1 identiﬁer2 ) . and – the subset of the library’s exports to make available within the importing library. A library name uniquely identiﬁes a library within an implementation. which name a subset of the bindings deﬁned within or imported into the library. or both deﬁned and imported. version ) 7. “->” appears within the names of procedures that take an object of one type and return an analogous object of another type. using identiﬁer2 as the external name. Library form A library deﬁnition must have the following form: (library library name (export export spec . and is globally visible in the import clauses (see below) of all other libraries within an implementation.7. Short. deﬁned multiple times.) A library declaration contains the following elements: • The library name speciﬁes the name of the library (possibly with version). where each dependency speciﬁes: In an export spec ..10) usually end in “!”. the levels at which they are to be available. • The library body is the library body. consisting of a sequence of deﬁnitions followed by a sequence of expressions. – the imported library’s name. and it arrives through the imports only by exporting and reexporting).. For example. where the external name for the export is the same as the name of the binding within the library. – the relevant levels.) library body ) Each sub-version must represent an exact nonnegative integer object.7. and the local names by which they are to be known. A library name has the following form: ( identiﬁer1 identiﬁer2 ..

.) (prefix import set identiﬁer ) (rename import set ( identiﬁer1 identiﬁer2 ) . As an import level . To avoid problems such as incompatible types and replicated state. A library reference with no version reference (ﬁrst form above) is equivalent to a library reference with a version reference of ().. and rename forms as described below.) (not sub-version reference ) import level ... all of an imported library’s exported bindings are made visible within an importing library using the names given to the bindings by the imported library. sub-version referencen ) (and version reference . The included identiﬁer s must be in the original import set .. It has one of the following forms: ( identiﬁer1 ( identiﬁer1 identiﬁer2 .) identiﬁer2 .. an or sub-version reference matches a sub-version if one of the subsequent sub-version reference s matches it... whose sub-version reference s match the corresponding sub-version s. Levels and phases are discussed in section 7. Correspondingly. prefix. An import set names a set of bindings from another library and possibly speciﬁes local names for the imported bindings. prefix. Examples: version reference () (1) (1) (2 3) (2 3) (2 3) (or (1 (>= 1)) (2)) (or (1 (>= 1)) (2)) (or (1 (>= 1)) (2)) ((or 1 2 3)) ((or 1 2 3)) ((or 1 2 3)) ((or 1 2 3)) version (1) (1) (2) (2) (2 3) (2 3 5) (2) (1 1) (1 0) (1) (2) (3) (4) match? yes yes no no yes yes yes yes no yes yes yes no A library reference identiﬁes a library by its name and optionally by its version..24 Revised6 Scheme import set (for import set sub-version (>= sub-version ) (<= sub-version ) (and sub-version reference ... The precise set of bindings to be imported and the names of those bindings can be adjusted with the only.) A sub-version reference of the ﬁrst form matches a sub-version if it is equal to it. library. A sub-version reference has one of the following forms: .) (not version reference ) When more than one library is identiﬁed by a library reference. implementations should prohibit the two libraries whose library names consist of the same sequence of identiﬁers but whose versions do not match to co-exist in the same program. An and sub-version reference matches a sub-version if all of the subsequent sub-version reference s match it.. and a not version reference matches a version if the version reference following it does not match it. except.. an or version reference matches a version if one of version references following the or matches it. Correspondingly. The import set (library library reference ) is otherwise equivalent to library reference . • An only form produces a subset of the bindings from another import set . A version reference speciﬁes a set of version s that it matches. version reference ) A library reference whose ﬁrst identiﬁer is for. including only the listed identiﬁer s. The library reference identiﬁes all libraries of the same name and whose version is matched by the version reference .. analogously for <=..) (or sub-version reference . By default.) (except import set identiﬁer . An and version reference matches a version if all version references following the and match it..2... and a not sub-version reference matches a sub-version if the subsequent sub-version reference does not match it. or rename is permitted only within a library import set . A version reference has the following form: ( sub-version reference1 .) (or version reference . It must be one of the following: library reference (library library reference ) (only import set identiﬁer . the choice of libraries is determined in some implementation-dependent manner.) An import level is one of the following: run expand (meta level ) where level represents an exact integer object. except. and expand is an abbreviation for (meta 1). A version reference of the ﬁrst form matches a version with at least n elements... only. A >= sub-version reference of the ﬁrst form matches a subversion if it is greater or equal to the sub-version following it... run is an abbreviation for (meta 0).

i. When begin. and code to evaluate the transformer expressions) and run-time information (minimally. then the library A must be instantiated before expanding any use of the macro in library B. Libraries • An except form produces a subset of the bindings from another import set .. which are explained in this section. export.7. Which forms belong to which class depends on the imported libraries and the result of expansion—see chapter 10. and.. unless the bindings are explicitly exported from the library. phase 1. including all but the listed identiﬁer s.2). • A rename form. or letrec-syntax forms appear within code evaluated at phase n. without aﬀecting their use in the library form. expand. i. All other variables deﬁned within a library are mutable. All of the excluded identiﬁer s must be in the original import set . they are spliced into the body. to form an intermediate import set .. however. to form the ﬁnal import set . and the right-hand sides of define-syntax forms are evaluated at expand time.. The library mechanism distinguishes these times by phases. It is also a syntax violation if a reference to an assigned variable appears in any code produced by an exported macro outside of the library in which the variable is deﬁned.2. The eﬀect of returning twice to the continuation of the last body expression is unspeciﬁed. or letrec-syntax forms.e. if a macro transformer calls a procedure from library A. only. then adds the bindings back for the corresponding identiﬁer2 . rename. not. let-syntax. removes the bindings for identiﬁer1 . expression . except. import. export. A fresh location is created for each exported variable and initialized to the value of its local counterpart. It must have the following form: deﬁnition . Each identiﬁer1 must be in the original import set . let-syntax.. and <= appearing in the library syntax are part of the syntax and are not reserved. see section 11. prefix.. Generally. >=. each identiﬁer2 must not be in the intermediate import set .. A library body is like a body (see section 11. its imported libraries.3) except that a library body s need not include any expressions. (rename ( identiﬁer1 identiﬁer2 ) . and the body expressions are also evaluated from left to right after the expressions of the variable deﬁnitions. An exported macro may. The transformer expressions and bindings are evaluated and created from left to right. import. 25 Bindings deﬁned with a library are not visible in code outside of the library. and the identiﬁer2 s must be distinct... Some or all of the body. or it may be needed for run time of library B. top-level expressions and the right-hand sides of define forms are evaluated at run time. When define-syntax. meta.4. It is a syntax violation if a constraint given above is not met.7. and code to evaluate the body expressions). The library body of a library form consists of forms that are classiﬁed as deﬁnitions or expressions. implicitly export an otherwise unexported identiﬁer deﬁned within or imported into the library. including portions wrapped in begin. Library A may not be needed when library B is eventually run as part of a program. it may insert a reference to that identiﬁer into the output code it produces. Import and export levels Expanding a library may require run-time information from another library.2 for deﬁnitions available through the base library) are expressions. and the run-time information must be available to evaluate references to any exported variable binding. Within a library body. too. forms that are not deﬁnitions (see section 11. for. Note: The names library.. It is thus a syntax violation if an explicitly exported variable appears on the left-hand side of a set! expression..). let-syntax. phase 0. the same names can be used for other purposes within the library or even exported from or imported into a library with diﬀerent meanings. code to evaluate the variable definition right-hand-side expressions. All implicitly exported variables are also immutable in both the exporting and importing libraries. where an assigned variable is one that appears on the left-hand side of a set! expression in the exporting library. as if in an implicit letrec*. A phase is a time at which the expressions within a library are evaluated. Every library can be characterized by expand-time information (minimally. • A prefix form adds the identiﬁer preﬁx to each name from another import set . .. as described in chapter 10. run. The expand-time information must be available to expand references to any exported binding. the right-hand sides are evaluated at phase n + 1.e. may be speciﬁed by a syntactic abstraction (see section 9. That is. i. or letrec-syntax forms occur in a top-level body prior to the ﬁrst expression. a list of the exported keywords. or.. a list of the exported variables. The expressions of variable deﬁnitions are evaluated from left to right. All explicitly exported variables are immutable in both the exporting and importing libraries. 7. For example. either in the exporting or importing libraries.e. It is thus a syntax violation if a variable appears on the left-hand side of a set! expression in any code produced by an exported macro outside of the library in which the variable is deﬁned.

The export levels of a reexported binding. then it refers to the export from an instance of A at phase 0 (relative to the phase of B). pa +qc . This rule applies transitively: if the expanded form of one library references at phase 0 an identiﬁer from another library. This combination of levels and phases is why negative levels on identiﬁers can be useful. then an instance of the referenced library is created for phase 0 before the program’s deﬁnitions and expressions are evaluated. which are exported with levels 0 and 1. references to an imported identiﬁer exported for levels pa and pb and imported for levels qa .. These phases are relative to the phase in which the library itself is used. an export imported from another library. a library whose meaning depends on whether the instances of a library are distinguished or shared across phases or library expansions may be unportable. Thus. Examples Examples for various import spec s and export spec s: (library (stack) (export make push! pop! empty!) (import (rnrs)) (define (make) (list ’())) (define (push! s v) (set-car! s (cons v (car s)))) (define (pop! s) (let ([v (caar s)]) (set-car! s (cdar s)) v)) (define (empty! s) (set-car! s ’()))) . An implementation may distinguish instances/visits of a library for diﬀerent phases or to use an instance/visit at any phase as an instance/visit at any other phase. are the same as the eﬀective import levels of that binding within the reexporting library. the identiﬁer must be used only at phase n + 1 in the library being expanded.e. When an identiﬁer appears as an expression in a phase that is inconsistent with the identiﬁer’s level. In that case. Macro expansion within a library can introduce a reference to an identiﬁer that is not explicitly imported into the library. and qc are valid at levels pa +qa . The level for each imported binding is determined by the enclosing for form of the import in the importing library. which corresponds to the evaluation of the macro’s transformer expression at phase 1. For example. the phase of the reference must match the identiﬁer’s level as shifted by the diﬀerence between the phase of the source library (i. then an implementation may raise an exception either at expand time or run time. then. when a macro keyword is referenced at phase n during the expansion of a library.. The level for each identiﬁer bound by a deﬁnition within a library is 0. i. and all bindings from the composite (rnrs (6)) library (see library chapter 15). . set! from the (rnrs base (6)) library. and the evaluation of the macro transformer refers to an identiﬁer that is exported from another library (so the phase-1 instance of the library is used). When an identiﬁer is referenced at any phase n greater than 0. and from the (rnrs base (6)) library. or it may allow the reference. and pb +qc . But if a phase 1 expression within B refers to the same binding from A. A visit of a library corresponds to the evaluation of its syntax deﬁnitions in a particular phase relative to another library—a process called visiting. An implementation may further expand each library form with distinct visits of libraries in any phase and/or instances of libraries in phases above 0. suppose further that the value of the binding is a syntax object representing an identiﬁer with only a level-n binding. if a toplevel expression in a library B refers to a macro export from another library A. even though libraries exist only at non-negative phases. which are exported with level 1. The exceptions are syntax-rules.. in contrast. For the libraries deﬁned in the library report. An implementation may create instances/visits of more libraries at more phases than required to satisfy references. if a top-level expression in a library B refers to a variable export from another library A. then before the referencing library is instantiated at phase n.26 Revised6 Scheme encloses the reference. then it refers to the export from an instance of A at phase 1 (relative to the phase of B).. identifier-syntax. The export level of an exported binding is 0 for all bindings that are deﬁned within the exporting library. in addition to the levels of the identiﬁer in the exporting library. qb . If any of a library’s deﬁnitions are referenced at phase 0 in the expanded form of a program. An import set without an enclosing for is equivalent to (for import set run). which is exported with levels 0 and 1.e. then the deﬁning library is instantiated at phase n at some unspeciﬁed time before the reference is evaluated. pb +qa . Similarly. An instance of a library corresponds to an evaluation of its variable deﬁnitions and expressions in a particular phase relative to another library—a process called instantiation. Import and export levels are combined by pairwise addition of all level combinations.3. suppose that expanding a library invokes a macro transformer. the identiﬁer can be referenced only at phase 0 within the library. pa +qb . the export level is 0 for nearly all bindings. that is. A level is a lexical property of an identiﬁer that determines in which phases it can be referenced. the referenced library must be instantiated at phase n. then it refers to the export from a visit of A at phase 0 (relative to the phase of B). pb +qb . For example. the library that supplied the identiﬁer’s lexical context) and the library that 7. which is the same as (for import set (meta 0)). For example. then the deﬁning library is visited at phase n at some unspeciﬁed time before the reference is evaluated.. For example.

(car (pop b) h) (cons w h)) amt) b) amt) (+ (cdr b) amt))) (display "Boom! ") (display (* (car b) (cdr b))) (newline))) (define-syntax mvlet (lambda (stx) (syntax-case stx () [( [(id ..... push. A top-level body form expression . . displays "Boom! 108" (push! p (push (make 5 5) 1)) (pop! p)) ...) expr] body0 body . is either a deﬁnition or an The import form is identical to the import clause in libraries (see section 7. Total exports: (export let-div) . make-party. the syntax speciﬁed by top-level body form refers to the result of macro expansion. Thus... and speciﬁes a set of libraries to import. A top-level body is like a library body (see section 7. .1. a top-level program deﬁnes a complete Scheme program.8.. pop! (import (rnrs) (export (rename (balloon:make make) (my-helpers values-stuff) (balloon:push push)) (rnrs r5rs)) push! make-party (define (quotient+remainder n d) (rename (party-pop! pop!))) (let ([q (quotient n d)]) (import (rnrs) (values q (. ) A top-level body has the following form: top-level body form .. that has the following form: import form top-level body Examples for macros and phases: (library (my-helpers id-stuff) (export find-dup) (import (rnrs)) (define (find-dup l) (and (pair? l) (let loop ((rest (cdr l))) (cond [(null? rest) (find-dup (cdr l))] [(bound-identifier=? (car l) (car rest)) (car rest)] [else (loop (cdr rest))]))))) (library (my-helpers values-stuff) (export mvlet) An import form has the following form: (import import spec . . . Top-level programs (push! s (balloon:make 12 9)) A top-level program speciﬁes an entry point for deﬁning and s)) running a Scheme program. from stack (push! s (balloon:make 10 10)) 8.. typically a ﬁle.)]))) (define (make-party) (let ([s (make)]) . make.n (* q d))))) (only (stack) make push! pop!) . .. displays "Boom! 24" imported libraries. starting with two balloons body0 body .)))])))) (library (party) (library (let-div) . push!..) body0 body . whether directly or through the transitive closure of importing. Through the (balloon:pop (pop! p)))) (library (main) (export) (import (rnrs) (party)) (define p (make-party)) (pop! p) .) (not (find-dup (syntax (id . except that deﬁnitions and expressions may occur in any order... A top-level program speciﬁes (define (party-pop! p) a set of libraries to import and code to run.. 8.)))) (syntax (call-with-values (lambda () expr) (lambda (id .1)... not empty! (define-syntax let-div (prefix (balloons) balloon:)) (syntax-rules () [( n d (q r) body0 body . Top-level program syntax A top-level program is a delimited piece of text.) . (mvlet [(q r) (quotient+remainder n d)] .1). Top-level programs 27 (import (rnrs) (for (my-helpers id-stuff) expand)) (library (balloons) (export make push pop) (import (rnrs)) (define (define (cons (define (make w (push b (. Creates a party as a stack of balloons.

let-syntax.4.) On platforms that support it. a character.2. . an exception with condition type &assertion is raised. procedure calls. Note: In contrast to other dialects of Lisp. imported syntactic keywords determine the available syntactic abstractions and whether each form is a deﬁnition or expression. A few form types are always available independent of imported libraries. a top-level program may access its command line by calling the command-line procedure (see library section 10). and macro uses. and the operator expression and the operand expressions are always evaluated with the same evaluation rules. Top-level program semantics A top-level program is executed by treating the program similarly to a library. Constant literals number boolean character syntax syntax syntax If the value of operator is not a procedure. a boolean. Primitive expression types The entries in this section all describe expressions. Some or all of the body. It is a syntax violation to reference an unbound variable.28 Revised6 Scheme string bytevector syntax syntax When uses of begin. if operator does not accept as many arguments as there are operand s. see chapter 10.2). or letrec-syntax from the (rnrs base (6)) library occur in a top-level body prior to the ﬁrst expression. may be speciﬁed by a syntactic abstraction (see section 9. or a bytevector. variable references. (It is generally impossible to determine which forms are deﬁnitions and expressions without concurrently expanding the body.4. ) syntax A procedure call consists of expressions for the procedure to be called and the arguments to be passed to it. When a procedure call is evaluated.1. Variable references variable syntax where variable is a fresh identiﬁer and unspeciﬁed is a side-eﬀect-free expression returning an unspeciﬁed value. see section 11. An expression consisting of a representation of a number object. with enclosing parentheses. and evaluating its deﬁnitions and expressions. an exception with condition type &assertion is raised. including portions wrapped in begin.10. . so the actual translation is somewhat more complicated. A form in an expression context is a procedure call if operator is not an identiﬁer bound as a syntactic keyword (see section 9. including constant literals. the forms that constitute the body of the library or the top-level program depend on the libraries that are imported. . a string.7. Also.2) is a variable reference if it is not a macro use (see below). the operator and operand expressions are evaluated (in an unspeciﬁed order) and the resulting procedure is passed the resulting arguments. In particular. they are spliced into the body. which may occur in the place of expression syntactic variables. or letrec-syntax forms. let-syntax. Primitive syntax ( operator operand1 . 9. The following example examples assumes the base library has been imported: (define x 28) x =⇒ 28 Procedure calls 9. 145932 #t "abc" #vu8(2 24 123) =⇒ 145932 =⇒ #t =⇒ "abc" =⇒ #vu8(2 24 123) 8. the value of a literal expression is immutable. evaluates “to itself”. See also section 11. The value of the variable reference is the value stored in the location to which the variable is bound. An expression consisting of a variable (section 5. The following examples assume the (rnrs base (6)) library has been imported: (+ 3 4) ((if #f + *) 3 4) =⇒ =⇒ 7 12 After the import form within a library form or a toplevel program. The semantics of a top-level body may be roughly explained by a simple translation into a library body: Each expression that appears before a deﬁnition in the top-level body is converted into a dummy deﬁnition (define variable (begin expression unspeciﬁed )) As noted in section 5.2 below). however. the order of evaluation is unspeciﬁed.

Moreover. If the expander encounters a syntactic abstraction. described in section 11. regardless of any local bindings that may surround the use of the macro. That is.3) or library body (see section 7. In Scheme. The number of datum s and the syntax of each depends on the syntactic abstraction. Macros deﬁned using syntax-rules and identifiersyntax are “hygienic” and “referentially transparent” and thus preserve Scheme’s lexical scoping [16. 6. the expander processes the initial forms in a body (see section 11. Macro uses can also take the form of improper lists. • If a macro transformer inserts a free reference to an identiﬁer. singleton identiﬁers. datum ) keyword (set! keyword datum ) Macro uses (see section 9. Macros Libraries and top-level programs can deﬁne and use new kinds of derived expressions and deﬁnitions called syntactic abstractions or macros. but not both. the syntax-case form. Most macro uses have the form: ( keyword datum . . Expansion process where keyword is an identiﬁer that uniquely determines the kind of form. begin form The expander splices the subforms into the list of body forms it is processing.18. an identiﬁer can be bound as a variable or keyword. arranging for the keywords bound by the let-syntax and letrec-syntax to be visible only in the inner body forms. allows creating transformers via arbitrary Scheme code.7. as is the representation of these forms in the expander’s output.19. Information about identiﬁer bindings is maintained during expansion to enforce lexical scoping for variables and keywords. transformer. let-syntax and letrec-syntax forms. 15. ) 10. 2. then repeats the expansion process for the form returned by the transformer.2 and 11. The syntax-rules and identifier-syntax forms. so () is not a syntactically valid expression. . define-syntax form The expander expands and evaluates the right-hand-side expression and binds the keyword to the resulting transformer. Keywords occupy the same name space as variables. associate them with macro transformers. it invokes the associated transformer to expand the syntactic abstraction. The transformer determines how a use of the macro (called a macro use) is transcribed into a more primitive form. This identiﬁer is called the syntactic keyword. if any. then recursively performs whichever of these actions are appropriate for the resulting form. of the macro. or neither. or set! forms. expressions written as list/pair forms must have at least one subexpression. the reference refers to the binding that was visible where the transformer was speciﬁed. . and control the scope within which they are visible. create bindings for keywords. or simply keyword.2. 29 • If a macro transformer inserts a binding for an identiﬁer (variable or keyword) not appearing in the macro use. 9]: . where the second subform of the set! is the keyword (see section 11.10. The set of core forms is implementation-dependent. and local bindings of either kind may shadow other bindings of either kind. Note: In many dialects of Lisp.6) is used. and reconstructs the form from the expanded subforms. To handle deﬁnitions. described in sections 11. (See section 11. macro use The expander invokes the associated transformer to transform the macro use.3): ( keyword datum .1) from left to right.2. described in library chapter 12. The define-syntax. Macros deﬁned using the syntax-case facility are also hygienic unless datum->syntax (see library section 12. .19) library section 12. 9. the identiﬁer is in eﬀect renamed throughout its scope to avoid conﬂicts with other identiﬁers. If the expander encounters a core form.4. Expansion process Although the order of evaluation is otherwise unspeciﬁed. .) let-syntax or letrec-syntax form The expander splices the inner body forms into the list of (outer) body forms it is processing. A syntactic abstraction is created by binding a keyword to a macro transformer or. define form The expander records the fact that the deﬁned identiﬁer is a variable but defers expansion of the right-hand-side expression until after all of the deﬁnitions have been processed. create transformers via a pattern language. the form () is a legitimate expression. it recursively processes its subforms that are in expression or deﬁnition context. within the same scope. How the expander processes each form encountered depends upon the kind of form. the eﬀect of any concurrent evaluation of the operator and operand expressions is constrained to be consistent with some sequential order of evaluation.2) are expanded into core forms at the start of evaluation (before compilation or interpretation) by a syntax expander. The order of evaluation may be chosen diﬀerently for each procedure call. simply.

then generates the equivalent of a letrec* form from the deﬁned variables. For the right-hand side of the deﬁnition of a variable.. the resulting call to not is recognized as an expression because not is bound as a variable. Consequently. At this point. It requires a single left-to-right pass over the deﬁnitions followed by a single pass (in any order) over the body expressions and deferred right-hand sides. The deﬁnition of odd? is next and results in the association of the keyword odd? with the transformer resulting from expanding and evaluating the corresponding right-hand side. the deﬁnition of defun is encountered ﬁrst.n 1)))) (define-syntax odd? (syntax-rules () [( n) (not (even? n))])) (odd? (if (odd? x) (* x x) x))) expression.30 Revised6 Scheme Note that this algorithm does not directly reprocess any form. For each body expression expression that appears before a variable deﬁnition in the body. it processes the deferred right-hand-side and body expressions. Example: (lambda (x) (define-syntax defun (syntax-rules () [( x a e) (define x (lambda a e))])) (defun even? (n) (or (= n 0) (odd? (. and expanded body expressions.e. Expansion of the right-hand side of this deﬁne form is deferred. each keyword and variable reference within the right-hand side resolves to the local binding. a dummy binding is created at the corresponding place within the set of letrec* bindings. the expander completes the expansion of the current expression (the call to not) and the deferred right-hand side of the even? deﬁnition. i.n 1)))))]) (not (even? (if (not (even? x)) (* x x) x))))) The following do not violate the restriction. with a fresh temporary variable on the left-hand side (let-syntax ([def0 (syntax-rules () [( x) (define x 0)])]) (let ([z 3]) (define def0 list) (def0 z) (list z))) =⇒ (3) (let () (define-syntax foo (lambda (e) (let ([+ -]) (+ 1 2)))) (define + 2) (foo)) =⇒ -1 The implementation should treat a violation of the restriction as a syntax violation. A use of odd? appears next and is expanded. A deﬁnition in the sequence of forms must not deﬁne any identiﬁer whose binding is used to determine the meaning of the undeferred portions of the deﬁnition or any deﬁnition that precedes it in the sequence of forms. expansion is deferred until after all of the deﬁnitions have been seen. the expander’s processing of a top-level body is somewhat more complicated. the uses of odd? appearing in these expressions are expanded using the transformer associated with the keyword odd?. nondeﬁnition The expander completes the expansion of the deferred right-hand-side expressions and the current and remaining expressions in the body. and the keyword defun is associated with the transformer resulting from the expansion and evaluation of the corresponding right-hand side. and expanded body expressions. (let ([x 5]) (define lambda list) (lambda x x)) =⇒ (5 5) although the structure of the output is implementationdependent. if any. Because deﬁnitions and expressions can be interleaved in a top-level body (see chapter 8). (let () (define define 17) (list define)) (let-syntax ([def0 (syntax-rules () [( x) (define x 0)])]) (let ([z 3]) (def0 z) (define def0 list) (list z))) (let () (define-syntax foo (lambda (e) (+ 1 2))) (define + 2) (foo)) In the example. . it defers its expansion and continues scanning for deﬁnitions. and then creates the equivalent of a letrec* form from the deﬁned variables. expanded right-hand-side expressions. It behaves as described above for a body or library body with the following exceptions: When the expander ﬁnds a nondeﬁnition. For example. Once it reaches the end of the set of forms. expanded right-hand-side expressions. The ﬁnal output is the equivalent of (lambda (x) (letrec* ([even? (lambda (n) (or (= n 0) (not (even? (. A use of defun is encountered next and expands into a define form. the bodies of the following expressions violate this restriction.

see section 11. See library section 12. and procedure. so that left-to-right evaluation order is preserved. (define-syntax keyword expression ) syntax Binds keyword to the value of expression . formal must be a single variable. The second form of define is equivalent to (define variable unspeciﬁed ) 11.2. The begin wrapper allows expression to evaluate to an arbitrary number of values. number.19.2. although there is a separate boolean type. any Scheme value can be used as a boolean value for the purpose of a conditional test. on the right-hand side. 11.2. the empty list is a special object of its own type. Syntax deﬁnitions 11. and nowhere else.2. Deﬁnitions Deﬁnitions may appear within a top-level body (section 8. to a transformer. at macro-expansion time. Base library =⇒ =⇒ 6 1 This chapter describes Scheme’s (rnrs base (6)) library.7) may also appear wherever other deﬁnitions may appear. formals must be either a sequence of zero or more variables. or letrec-syntax form.1). symbol.1.3). it must raise an exception with condition type &assertion.2. In the third form of define. All bindings established by a set of deﬁnitions. 11. see section 5. or at the top of a body (section 11. pair. Section 11. formal ) body ) syntax syntax syntax syntax The ﬁrst from of define binds variable to a new location before assigning the value of expression to it.1.2.20 deﬁnes the rules that identify tail calls and tail contexts in constructs from the (rnrs base (6)) library.1). see section 11. and another variable (as in a lambda expression.7.3 for a more complete description of transformers. Keyword bindings established by define-syntax are visible throughout the body in which they appear. Base library 31 and the equivalent of (begin expression unspeciﬁed ). whether keyword . Variable deﬁnitions The define form described in this section is a deﬁnition used to create variable bindings and may appear anywhere other deﬁnitions may appear. string. (define (define (define (define variable expression ) variable ) ( variable formals ) body ) ( variable . let-syntax. A deﬁnition may be a variable deﬁnition (section 11. If the implementation detects this. Base types No object satisﬁes more than one of the following predicates: boolean? symbol? char? vector? null? pair? number? string? procedure? where unspeciﬁed is a side-eﬀect-free expression returning an unspeciﬁed value. Moreover. Implementation responsibilities: Implementations should detect that the continuation of expression is invoked more than once. (define add3 (lambda (x) (+ x 3))) (add3 3) (define first car) (first ’(1 2)) 11. where unspeciﬁed is a side-eﬀect-free expression returning an unspeciﬁed value. This form is equivalent to (define variable (lambda ( formals ) body )). at the top of a library body (section 7.4. char (or character).1). which must evaluate. Macro transformers can be created using the syntax-rules and identifier-syntax forms described in section 11. except where shadowed by other bindings. or a sequence of one or more variables followed by a dot . This form is equivalent to (define variable (lambda formal body )).4.2). just like variable bindings established by define. The continuation of expression should not be invoked more than once. The define-syntax form described in this section is a deﬁnition used to create keyword bindings and may appear anywhere other deﬁnitions may appear. which exports many of the procedure and syntax bindings that are traditionally associated with Scheme. Note that. In the fourth form of define. Macro uses that expand into deﬁnitions or groups of deﬁnitions (packaged in a begin. vector. These predicates deﬁne the base types boolean.1) or keyword deﬁnition (section 11.11.

let-syntax.x 1))))) (define-syntax odd? (syntax-rules () ((odd? x) (not (even? x))))) (even? 10)) =⇒ #t 11. let-syntax. or letrec* expression.3.. (quote datum ) may be abbreviated as ’ datum : ’"abc" ’145932 ’a ’#(a b c) ’() ’(+ 1 2) ’(quote a) ’’a =⇒ =⇒ =⇒ =⇒ =⇒ =⇒ =⇒ =⇒ "abc" 145932 a #(a b c) () (+ 1 2) (quote a) (quote a) 11. Bodies The body of a lambda. they are spliced into the body. expression1 expression2 .4. Quotation (quote datum ) Syntax: Datum should be a syntactic datum. the let expression in the above example is equivalent to (let ((x 5)) (letrec* ((foo (lambda (y) (bar x y))) (bar (lambda (a b) (+ (* a b) a)))) (foo (+ x 3)))) or variable deﬁnitions. Semantics: (quote datum ) evaluates to the datum value represented by datum (see section 4.3). Each identiﬁer deﬁned by a deﬁnition is local to the body .4. let-values.3.4. For example. An expanded body (see chapter 10) containing variable deﬁnitions can always be converted into an equivalent Syntax: Formals must be a formal parameter list as described below. That is. Example: (let ((x 5)) (define foo (lambda (y) (bar x y))) (define bar (lambda (a b) (+ (* a b) a))) (foo (+ x 3))) =⇒ 45 As noted in section 5.4.32 Revised6 Scheme letrec* expression. 11. constants are immutable. As noted in section 4. Example: (let () (define even? (lambda (x) (or (= x 0) (odd? (. Procedures (lambda formals body ) syntax When begin. The environment in eﬀect when the lambda expression is evaluated is remembered as part of the procedure. or letrec-syntax forms. let*.. may be speciﬁed by a macro use (see section 9. Expressions The entries in this section describe the expressions of the (rnrs base (6)) library. Example: (let () (define-syntax bind-to-zero (syntax-rules () ((bind-to-zero id) (define id 0)))) (bind-to-zero x) x) =⇒ 0 syntax The behavior is unaﬀected by any binding for bind-to-zero that might appear outside of the let expression.. the environment in which the lambda expression was evaluated . are visible within the deﬁnitions themselves. the identiﬁer is bound. This notation is used to include constants. and body must be as described in section 11.1. letrec. deﬁnition . which may occur in the position of the expression syntactic variable in addition to the primitive expression types as described in section 9. Note: Diﬀerent constants that are the value of a quote expression may share the same locations. 11.1. let. and the region of the binding is the entire body (see section 5.10.2.2).5.. Some or all of the body. see section 11. let*-values.2). Implementation responsibilities: The implementation should detect if the value of expression cannot possibly be a transformer. When the procedure is later called with some arguments. (quote a) (quote #(a b c)) (quote (+ 1 2)) =⇒ =⇒ =⇒ a #(a b c) (+ 1 2) An implication of the left-to-right processing order (section 10) is that one deﬁnition can aﬀect whether a subsequent form is also a deﬁnition. or letrec-syntax forms occur in a body prior to the ﬁrst expression. or that of a deﬁnition with a body consists of zero or more deﬁnitions followed by one or more expressions. Semantics: A lambda expression evaluates to a procedure.7. including portions wrapped in begin.3.

11. Base library 33 is extended by binding the variables in the parameter list to fresh locations, and the resulting argument values are stored in those locations. Then, the expressions in the body of the lambda expression (which may contain deﬁnitions and thus represent a letrec* form, see section 11.3) are evaluated sequentially in the extended environment. The results of the last expression in the body are returned as the results of the procedure call.

(lambda (x) (+ x x)) ((lambda (x) (+ x x)) 4) ((lambda (x) (define (p y) (+ y 1)) (+ (p x) x)) 5) (define reverse-subtract (lambda (x y) (- y x))) (reverse-subtract 7 10) (define add4 (let ((x 4)) (lambda (y) (+ x y)))) (add4 6) =⇒ =⇒ a procedure 8

11.4.3. Conditionals (if test (if test consequent alternate ) consequent ) syntax syntax

Syntax: Test , consequent , and alternate must be expressions. Semantics: An if expression is evaluated as follows: ﬁrst, test is evaluated. If it yields a true value (see section 5.7), then consequent is evaluated and its values are returned. Otherwise alternate is evaluated and its values are returned. If test yields #f and no alternate is speciﬁed, then the result of the expression is unspeciﬁed.

(if (> 3 2) ’yes ’no) (if (> 2 3) ’yes ’no) (if (> 3 2) (- 3 2) (+ 3 2)) (if #f #f) =⇒ =⇒ yes no

=⇒ 11

=⇒ 1 =⇒ unspeciﬁed

=⇒

3

The consequent and alternate expressions are in tail context if the if expression itself is; see section 11.20. 11.4.4. Assignments

=⇒

10

(set! variable Formals must have one of the following forms:

expression )

syntax

• ( variable1 . . . ): The procedure takes a ﬁxed number of arguments; when the procedure is called, the arguments are stored in the bindings of the corresponding variables. • variable : The procedure takes any number of arguments; when the procedure is called, the sequence of arguments is converted into a newly allocated list, and the list is stored in the binding of the variable . • ( variable1 . . . variablen . variablen+1 ): If a period . precedes the last variable, then the procedure takes n or more arguments, where n is the number of parameters before the period (there must be at least one). The value stored in the binding of the last variable is a newly allocated list of the arguments left over after all the other arguments have been matched up against the other parameters.

((lambda x x) 3 4 5 6) ((lambda (x y . z) z) 3 4 5 6) =⇒ =⇒ (3 4 5 6) (5 6)

Expression is evaluated, and the resulting value is stored in the location to which variable is bound. Variable must be bound either in some region enclosing the set! expression or at the top level. The result of the set! expression is unspeciﬁed.

(let ((x 2)) (+ x 1) (set! x 4) (+ x 1))

=⇒

5

**It is a syntax violation if variable refers to an immutable binding.
**

Note: The identiﬁer set! is exported with level 1 as well. See section 11.19.

**11.4.5. Derived conditionals (cond cond clause1 => else
**

( test

cond clause2 . . . ) syntax auxiliary syntax auxiliary syntax

**Syntax: Each cond clause must be of the form
**

expression1 . . . )

**where test is an expression. cond clause may be of the form
**

( test => expression )

Alternatively,

a

Any variable formals .

must not appear more than once in

The last cond clause may be an “else clause”, which has the form

34

Revised6 Scheme

(else expression1 expression2 . . . ).

Semantics: A cond expression is evaluated by evaluating the test expressions of successive cond clause s in order until one of them evaluates to a true value (see section 5.7). When a test evaluates to a true value, then the remaining expression s in its cond clause are evaluated in order, and the results of the last expression in the cond clause are returned as the results of the entire cond expression. If the selected cond clause contains only the test and no expression s, then the value of the test is returned as the result. If the selected cond clause uses the => alternate form, then the expression is evaluated. Its value must be a procedure. This procedure should accept one argument; it is called on the value of the test and the values returned by this procedure are returned by the cond expression. If all test s evaluate to #f, and there is no else clause, then the conditional expression returns unspeciﬁed values; if there is an else clause, then its expression s are evaluated, and the values of the last one are returned.

(cond ((> 3 2) ’greater) ((< 3 2) ’less)) (cond ((> 3 3) ’greater) ((< 3 3) ’less) (else ’equal)) (cond (’(1 2 3) => cadr) (else #f)) =⇒ greater

datum s of each case clause in turn, proceeding in order from left to right through the set of clauses. If the result of evaluating key is equivalent to a datum of a case clause , the corresponding expression s are evaluated from left to right and the results of the last expression in the case clause are returned as the results of the case expression. Otherwise, the comparison process continues. If the result of evaluating key is diﬀerent from every datum in each set, then if there is an else clause its expressions are evaluated and the results of the last are the results of the case expression; otherwise the case expression returns unspeciﬁed values.

(case (* 2 3) ((2 3 5 7) ’prime) ((1 4 6 8 9) ’composite)) =⇒ (case (car ’(c d)) ((a) ’a) ((b) ’b)) =⇒ (case (car ’(c d)) ((a e i o u) ’vowel) ((w y) ’semivowel) (else ’consonant)) =⇒

composite

unspeciﬁed

consonant

=⇒ =⇒

equal 2

The last expression of a case clause is in tail context if the case expression itself is; see section 11.20. (and test1 . . . ) Syntax: The test s must be expressions. Semantics: If there are no test s, #t is returned. Otherwise, the test expressions are evaluated from left to right until a test returns #f or the last test is reached. In the former case, the and expression returns #f without evaluating the remaining expressions. In the latter case, the last expression is evaluated and its values are returned.

(and (= 2 2) (> 2 1)) (and (= 2 2) (< 2 1)) (and 1 2 ’c ’(f g)) (and) =⇒ =⇒ =⇒ =⇒ #t #f (f g) #t

syntax

**For a cond clause of one of the following forms
**

( test expression1 . . . ) (else expression1 expression2 . . . )

the last expression is in tail context if the cond form itself is. For a cond clause of the form

( test => expression )

the (implied) call to the procedure that results from the evaluation of expression is in a tail context if the cond form itself is. See section 11.20. A sample deﬁnition of cond in terms of simpler forms is in appendix B. (case key case clause1 case clause2 . . . ) syntax

**The and keyword could be deﬁned in terms of if using syntax-rules (see section 11.19) as follows:
**

(define-syntax and (syntax-rules () ((and) #t) ((and test) test) ((and test1 test2 ...) (if test1 (and test2 ...) #f))))

**Syntax: Key must be an expression. Each case clause must have one of the following forms:
**

(( datum1 . . . ) expression1 expression2 . . . ) (else expression1 expression2 . . . )

The second form, which speciﬁes an “else clause”, may only appear as the last case clause . Each datum is an external representation of some object. The data represented by the datum s need not be distinct. Semantics: A case expression is evaluated as follows. Key is evaluated and its result is compared using eqv? (see section 11.5) against the data represented by the

The last test expression is in tail context if the and expression itself is; see section 11.20. (or test1 . . . ) Syntax: The test s must be expressions. syntax

11. Base library 35 Semantics: If there are no test s, #f is returned. Otherwise, the test expressions are evaluated from left to right until a test returns a true value val (see section 5.7) or the last test is reached. In the former case, the or expression returns val without evaluating the remaining expressions. In the latter case, the last expression is evaluated and its values are returned.

(or (or (or (or (= 2 2) (> 2 1)) (= 2 2) (< 2 1)) #f #f #f) ’(b c) (/ 3 0)) =⇒ =⇒ =⇒ =⇒ #t #t #f (b c) (( variable1 init1 ) . . . ),

where each init is an expression, and body is as described in section 11.3. Any variable must not appear more than once in the variable s. Semantics: The init s are evaluated in the current environment (in some unspeciﬁed order), the variable s are bound to fresh locations holding the results, the body is evaluated in the extended environment, and the values of the last expression of body are returned. Each binding of a variable has body as its region.

(let ((x 2) (y 3)) (* x y)) (let ((x 2) (y 3)) (let ((x 7) (z (+ x y))) (* z x))) =⇒ 6

**The or keyword could be deﬁned in terms of if using syntax-rules (see section 11.19) as follows:
**

(define-syntax or (syntax-rules () ((or) #f) ((or test) test) ((or test1 test2 ...) (let ((x test1)) (if x x (or test2 ...))))))

=⇒

35

See also named let, section 11.16. (let* bindings body ) Syntax: Bindings must have the form

(( variable1 init1 ) . . . ),

syntax

The last test expression is in tail context if the or expression itself is; see section 11.20. 11.4.6. Binding constructs The binding constructs described in this section create local bindings for variables that are visible only in a delimited region. The syntax of the constructs let, let*, letrec, and letrec* is identical, but they diﬀer in the regions (see section 5.2) they establish for their variable bindings and in the order in which the values for the bindings are computed. In a let expression, the initial values are computed before any of the variables become bound; in a let* expression, the bindings and evaluations are performed sequentially. In a letrec or letrec* expression, all the bindings are in eﬀect while their initial values are being computed, thus allowing mutually recursive deﬁnitions. In a letrec expression, the initial values are computed before being assigned to the variables; in a letrec*, the evaluations and assignments are performed sequentially. In addition, the binding constructs let-values and let*-values generalize let and let* to allow multiple variables to be bound to the results of expressions that evaluate to multiple values. They are analogous to let and let* in the way they establish regions: in a let-values expression, the initial values are computed before any of the variables become bound; in a let*-values expression, the bindings are performed sequentially. Sample deﬁnitions of all the binding forms of this section in terms of simpler forms are in appendix B. (let bindings body ) syntax

where each init is an expression, and body is as described in section 11.3. Semantics: The let* form is similar to let, but the init s are evaluated and bindings created sequentially from left to right, with the region of each binding including the bindings to its right as well as body . Thus the second init is evaluated in an environment in which the ﬁrst binding is visible and initialized, and so on.

(let ((x 2) (y 3)) (let* ((x 7) (z (+ x y))) (* z x)))

=⇒

70

Note: While the variables bound by a let expression must be distinct, the variables bound by a let* expression need not be distinct.

**(letrec bindings body ) Syntax: Bindings must have the form
**

(( variable1 init1 ) . . . ),

syntax

where each init is an expression, and body is as described in section 11.3. Any variable must not appear more than once in the variable s. Semantics: The variable s are bound to fresh locations, the init s are evaluated in the resulting environment (in some unspeciﬁed order), each variable is assigned to the result of the corresponding init , the body is evaluated in the resulting environment, and the values of the last expression in body are returned. Each binding of a variable has the entire letrec expression as its region, making it possible to deﬁne mutually recursive procedures.

Syntax: Bindings must have the form

36

Revised6 Scheme

(letrec ((even? (lambda (n) (if (zero? n) #t (odd? (- n 1))))) (odd? (lambda (n) (if (zero? n) #f (even? (- n 1)))))) (even? 88)) =⇒ #t

It must be possible to evaluate each init without assigning or referring to the value of the corresponding variable or the variable of any of the bindings that follow it in bindings . Another restriction is that the continuation of each init should not be invoked more than once. Implementation responsibilities: Implementations must, during the evaluation of an init expression, detect references to the value of the corresponding variable or the variable of any of the bindings that follow it in bindings . If an implementation detects such a violation of the restriction, it must raise an exception with condition type &assertion. Implementations may or may not detect that the continuation of each init is invoked more than once. However, if the implementation detects this, it must raise an exception with condition type &assertion.

It should be possible to evaluate each init without assigning or referring to the value of any variable . In the most common uses of letrec, all the init s are lambda expressions and the restriction is satisﬁed automatically. Another restriction is that the continuation of each init should not be invoked more than once. Implementation responsibilities: Implementations must detect references to a variable during the evaluation of the init expressions (using one particular evaluation order and order of evaluating the init expressions). If an implementation detects such a violation of the restriction, it must raise an exception with condition type &assertion. Implementations may or may not detect that the continuation of each init is invoked more than once. However, if the implementation detects this, it must raise an exception with condition type &assertion. (letrec* bindings body ) Syntax: Bindings must have the form

(( variable1 init1 ) . . . ),

(let-values mv-bindings

body )

syntax

**Syntax: Mv-bindings must have the form
**

(( formals1 init1 ) . . . ),

where each init is an expression, and body is as described in section 11.3. Any variable must not appear more than once in the set of formals . Semantics: The init s are evaluated in the current environment (in some unspeciﬁed order), and the variables occurring in the formals are bound to fresh locations containing the values returned by the init s, where the formals are matched to the return values in the same way that the formals in a lambda expression are matched to the arguments in a procedure call. Then, the body is evaluated in the extended environment, and the values of the last expression of body are returned. Each binding of a variable has body as its region. If the formals do not match, an exception with condition type &assertion is raised.

(let-values (((a b) (values 1 2)) ((c d) (values 3 4))) (list a b c d)) =⇒ (1 2 3 4) (let-values (((a b . c) (values 1 2 3 4))) (list a b c)) =⇒ (1 2 (3 4)) (let ((a ’a) (b ’b) (x ’x) (y ’y)) (let-values (((a b) (values x y)) ((x y) (values a b))) (list a b x y))) =⇒ (x y a b)

syntax

where each init is an expression, and body is as described in section 11.3. Any variable must not appear more than once in the variable s. Semantics: The variable s are bound to fresh locations, each variable is assigned in left-to-right order to the result of evaluating the corresponding init , the body is evaluated in the resulting environment, and the values of the last expression in body are returned. Despite the leftto-right evaluation and assignment order, each binding of a variable has the entire letrec* expression as its region, making it possible to deﬁne mutually recursive procedures.

(letrec* ((p (lambda (x) (+ 1 (q (- x 1))))) (q (lambda (y) (if (zero? y) 0 (+ 1 (p (- y 1)))))) (x (p 5)) (y x)) y) =⇒ 5

(let*-values mv-bindings

body )

syntax

**Syntax: Mv-bindings must have the form
**

(( formals1 init1 ) . . . ),

11. Base library 37 where each init is an expression, and body is as described in section 11.3. In each formals , any variable must not appear more than once. Semantics: The let*-values form is similar to let-values, but the init s are evaluated and bindings created sequentially from left to right, with the region of the bindings of each formals including the bindings to its right as well as body . Thus the second init is evaluated in an environment in which the bindings of the ﬁrst formals is visible and initialized, and so on.

(let ((a ’a) (b ’b) (x ’x) (y ’y)) (let*-values (((a b) (values x y)) ((x y) (values a b))) (list a b x y))) =⇒ (x y x y) Note: While all of the variables bound by a let-values expression must be distinct, the variables bound by diﬀerent formals of a let*-values expression need not be distinct.

**11.5. Equivalence predicates
**

A predicate is a procedure that always returns a boolean value (#t or #f). An equivalence predicate is the computational analogue of a mathematical equivalence relation (it is symmetric, reﬂexive, and transitive). Of the equivalence predicates described in this section, eq? is the ﬁnest or most discriminating, and equal? is the coarsest. The eqv? predicate is slightly less discriminating than eq?. (eqv? obj1 obj2 ) procedure

The eqv? procedure deﬁnes a useful equivalence relation on objects. Brieﬂy, it returns #t if obj1 and obj2 should normally be regarded as the same object and #f otherwise. This relation is left slightly open to interpretation, but the following partial speciﬁcation of eqv? must hold for all implementations. The eqv? procedure returns #t if one of the following holds:

11.4.7. Sequencing (begin form . . . ) (begin expression expression . . . ) syntax syntax

• Obj1 and obj2 are both booleans and are the same according to the boolean=? procedure (section 11.8). • Obj1 and obj2 are both symbols and are the same according to the symbol=? procedure (section 11.10). • Obj1 and obj2 are both exact number objects and are numerically equal (see =, section 11.7). • Obj1 and obj2 are both inexact number objects, are numerically equal (see =, section 11.7), and yield the same results (in the sense of eqv?) when passed as arguments to any other procedure that can be deﬁned as a ﬁnite composition of Scheme’s standard arithmetic procedures. • Obj1 and obj2 are both characters and are the same character according to the char=? procedure (section 11.11). • Both obj1 and obj2 are the empty list.

The begin keyword has two diﬀerent roles, depending on its context: • It may appear as a form in a body (see section 11.3), library body (see section 7.1), or top-level body (see chapter 8), or directly nested in a begin form that appears in a body. In this case, the begin form must have the shape speciﬁed in the ﬁrst header line. This use of begin acts as a splicing form—the forms inside the body are spliced into the surrounding body, as if the begin wrapper were not actually present. A begin form in a body or library body must be non-empty if it appears after the ﬁrst expression within the body. • It may appear as an ordinary expression and must have the shape speciﬁed in the second header line. In this case, the expression s are evaluated sequentially from left to right, and the values of the last expression are returned. This expression type is used to sequence side eﬀects such as assignments or input and output.

(define x 0) (begin (set! x 5) (+ x 1))

• Obj1 and obj2 are objects such as pairs, vectors, bytevectors (library chapter 2), strings, hashtables, records (library chapter 6), ports (library section 8.2), or hashtables (library chapter 13) that refer to the same locations in the store (section 5.10). • Obj1 and obj2 are record-type descriptors that are speciﬁed to be eqv? in library section 6.3. The eqv? procedure returns #f if one of the following holds:

=⇒

6

(begin (display "4 plus 1 equals ") (display (+ 4 1))) =⇒ unspeciﬁed and prints 4 plus 1 equals 5

• Obj1 and obj2 are of diﬀerent types (section 11.1). • Obj1 and obj2 are booleans for which the boolean=? procedure returns #f.

car.1. but the other is not.e.38 Revised6 Scheme • Obj1 and obj2 are symbols for which the symbol=? procedure returns #f. strings. Calls to gen-counter must return a distinct procedure every time. Calls to gen-loser return procedures that behave equivalently when called. All that can be said about such cases is that the value returned by eqv? must be a boolean. • Obj1 and obj2 yield diﬀerent results (in the sense of eqv?) when passed as arguments to any other procedure that can be deﬁned as a ﬁnite composition of Scheme’s standard arithmetic procedures. (lambda (x) x)) (eqv? (lambda (x) x) (lambda (y) y)) (eqv? +nan. or hashtables (library chapter 13) that refer to distinct locations. and records. Thus the value of eqv? on constants is sometimes implementation-dependent.4. • Obj1 and obj2 are objects such as pairs. non-empty strings. and vectors. cdr. (define gen-counter (lambda () (let ((n 0)) (lambda () (set! n (+ n 1)) n)))) (let ((g (gen-counter))) (eqv? g g)) =⇒ unspeciﬁed (eqv? (gen-counter) (gen-counter)) =⇒ #f (define gen-loser (lambda () (let ((n 0)) (lambda () (set! n (+ n 1)) 27)))) (let ((g (gen-loser))) (eqv? g g)) =⇒ unspeciﬁed (eqv? (gen-loser) (gen-loser)) =⇒ unspeciﬁed (letrec ((f (lambda () (if (eqv? f g) ’both ’f))) (g (lambda () (if (eqv? f g) ’both ’g)))) (eqv? f g)) =⇒ unspeciﬁed (letrec ((f (lambda () (if (eqv? f g) ’f ’both))) (g (lambda () (if (eqv? f g) ’g ’both)))) (eqv? f g)) =⇒ #f Note: The eqv? procedure returning #t when obj1 and obj2 are number objects does not imply that = would also return #t when called with obj1 and obj2 as arguments. • One of obj1 and obj2 is an exact number object but the other is an inexact number object. ports (library section 8. a constant may be copied at any time by the implementation so as to exist simultaneously in diﬀerent sets of locations. • Obj1 and obj2 are pairs. However. • Obj1 and obj2 are rational number objects for which the = procedure returns #f. strings. since each procedure has its own internal counter. or records. The behavior of eq? on number objects and . Furthermore. • Obj1 and obj2 are characters for which the char=? procedure returns #f. (eqv? ’(a) ’(a)) (eqv? "a" "a") (eqv? ’(b) (cdr ’(a b))) (let ((x ’(a))) (eqv? x x)) =⇒ =⇒ =⇒ =⇒ unspeciﬁed unspeciﬁed unspeciﬁed #t The following examples illustrate cases in which the above rules do not fully specify the behavior of eqv?. ’a ’a) =⇒ ’a ’b) =⇒ 2 2) =⇒ ’() ’()) =⇒ 100000000 100000000) =⇒ (cons 1 2) (cons 1 2))=⇒ (lambda () 1) (lambda () 2)) =⇒ (eqv? #f ’nil) =⇒ (eqv? (eqv? (eqv? (eqv? (eqv? (eqv? (eqv? #t #f #t #t #t #f #f #f Implementations may share structure between constants where appropriate. procedures. bytevectors. vector-ref. as noted in section 11. eqv? may not detect this equivalence.0 +nan. pairs. or hashtables. • One of obj1 and obj2 is the empty list. (let ((p (lambda (x) x))) (eqv? p p)) (eqv? "" "") (eqv? ’#() ’#()) (eqv? (lambda (x) x) =⇒ =⇒ =⇒ unspeciﬁed unspeciﬁed unspeciﬁed (eq? obj1 obj2 ) procedure The eq? predicate is similar to eqv? except that in some cases it is capable of discerning distinctions ﬁner than those detectable by eqv?.2). The eq? and eqv? predicates are guaranteed to have the same behavior on symbols.0) =⇒ unspeciﬁed =⇒ unspeciﬁed =⇒ unspeciﬁed The next set of examples shows the use of eqv? with procedures that have local state. bytevectors (library chapter 2). • Obj1 and obj2 are procedures that would behave differently (return diﬀerent values or have diﬀerent side eﬀects) for some arguments. or record accessors) to both yields results for which eqv? returns #f. booleans. vectors. records (library chapter 6). the empty list. where the applying the same accessor (i. string-ref. vectors.

cos. and returns #t only when eqv? would also return #t. but return an inexact result when any argument is inexact. The general rule is that the generic operations return the correct exact result when all of their arguments are exact and the result is mathematically well-deﬁned. exp.11. magnitude. #t #t #t #t #t #t The procedures listed below must return the correct exact result provided all their arguments are exact. sin. empty bytevectors. and uses eqv? to compare other nodes. asin. atan. 11.7. performing coercions and selecting the appropriate operations as determined by the numeric subtypes of their arguments. uses bytevector=? to compare bytevectors (see library chapter 2). Base library 39 characters is implementation-dependent. tan. and no divisors are zero: / div div0 mod mod0 div-and-mod div0-and-mod0 #t unspeciﬁed Moreover. uses string=? to compare strings. Procedure predicate (procedure? obj ) procedure Returns #t if obj is a procedure. and angle. Propagation of exactness and inexactness The procedures listed below must return the mathematically correct exact result provided all their arguments are exact: + max numerator lcm truncate real-part min denominator floor round imag-part * abs gcd ceiling rationalize make-rectangular (equal? obj1 obj2 ) procedure The equal? predicate returns #t if and only if the (possibly inﬁnite) unfoldings of its arguments into regular trees are equal as ordered trees. expt.6. which may (but are not required to) return inexact results even . The equal? predicate treats pairs and vectors as nodes with outgoing edges. (eq? ’a ’a) (eq? ’(a) ’(a)) (eq? (list ’a) (list ’a)) (eq? "a" "a") (eq? "" "") (eq? ’() ’()) (eq? 2 2) (eq? #\A #\A) (eq? car car) (let ((n (+ 2 3))) (eq? n n)) (let ((x ’(a))) (eq? x x)) (let ((x ’#())) (eq? x x)) (let ((p (lambda (x) x))) (eq? p p)) =⇒ =⇒ =⇒ =⇒ =⇒ =⇒ =⇒ =⇒ =⇒ =⇒ =⇒ =⇒ =⇒ #t unspeciﬁed #f unspeciﬁed unspeciﬁed #t unspeciﬁed unspeciﬁed #t unspeciﬁed #t unspeciﬁed unspeciﬁed 11. Exceptions to this rule include sqrt. but it always returns either #t or #f. make-polar.1.7. (equal? ’a ’a) =⇒ (equal? ’(a) ’(a)) =⇒ (equal? ’(a (b) c) ’(a (b) c)) =⇒ (equal? "abc" "abc") =⇒ (equal? 2 2) =⇒ (equal? (make-vector 5 ’a) (make-vector 5 ’a)) =⇒ (equal? ’#vu8(1 2 3 4 5) (u8-list->bytevector ’(1 2 3 4 5)) =⇒ (equal? (lambda (x) x) (lambda (y) y)) =⇒ (let* ((x (list ’a)) (y (list ’a)) (z (list x y))) (list (equal? z (list y x)) (equal? z (list x x)))) =⇒ (#t #t) Note: The equal? procedure must always terminate. log. and empty strings. even if its arguments contain cycles. otherwise returns #f. (procedure? car) =⇒ #t (procedure? ’car) =⇒ #f (procedure? (lambda (x) (* x x))) =⇒ #t (procedure? ’(lambda (x) (* x x))) =⇒ #f 11. acos. The generic procedures described in this section accept both exact and inexact number objects as arguments. The eq? predicate may also behave diﬀerently from eqv? on empty vectors. Arithmetic The procedures described here implement arithmetic that is generic over the numerical tower described in chapter 3. Library chapter 11 describes libraries that deﬁne other numerical procedures. the procedure expt must return the correct exact result provided its ﬁrst argument is an exact real number object and its second argument is an exact integer object.

0 0) which may return either 0 (exact) or 0. cos−1 (arccosine). see library section 11. One general exception to the rule above is that an implementation may return an exact result despite inexact arguments if that exact result would be the correct result for all possible substitutions of exact arguments for the inexact ones. log 0 is undeﬁned. and speciﬁes many operations with respect to these number objects in ways that are consistent with the IEEE-754 standard for binary ﬂoating-point arithmetic.7. mod.0 is distinguished. and tan−1 are multiply deﬁned. 11. div0 . Their results are speciﬁed by x1 div x2 x1 mod x2 where = nd = xm 123 mod −10 = 3 −123 div 10 = −13 −123 mod 10 = 7 −123 div −10 = 13 −123 mod −10 = 7 div0 and mod0 are like div and mod. This requirement also applies to conversions between number objects and external representations. and mod returns a real. 123 div 10 123 mod 10 = 12 = 3 With the one-argument version of log deﬁned this way. cos−1 z.2.40 Revised6 Scheme 123 div −10 = −12 when given exact arguments. exclusive otherwise) to π (inclusive). mod. In this case.0 (inexact). x1 = nd · x2 + xm 0 ≤ xm < |x2 | Examples: . div0 . An example is (* 1.3) whenever it is unable to represent an inﬁnity or NaN as speciﬁed. Integer division Scheme’s operations for performing integer division rely on mathematical operations div. an implementation must raise a continuable exception with condition type &no-infinities or &no-nans (respectively. the values of the two-argument-version of log.7. div returns an integer. and mod0 each accept two real numbers x1 and x2 as operands. The value of log z for non-real z is deﬁned in terms of log on real numbers as log z = log |z| + (angle z)i where angle z is the angle of z = a · eib speciﬁed as: angle z = b + 2πn with −π ≤ angle z ≤ π and angle z = b + 2πn for some integer n. as indicated in the speciﬁcation of these procedures. where x2 must be nonzero. The behavior of these operations is described in this section for later reference. and mod0 . the transcendental functions log. the continuation of the exception handler is the continuation that otherwise would have received the inﬁnity or NaN value. 11. sin−1 (arcsine). An implementation of Scheme may or may not represent inﬁnities and NaNs. sin−1 z. Semantics of common operations Some operations are the semantic basis for several arithmetic procedures. The value of log z is deﬁned to be the one whose imaginary part lies in the range from −π (inclusive if −0. except the result of mod0 lies within a half-open interval centered on zero. including the reading of program source code. that are deﬁned as follows: div. Representability of inﬁnities and NaNs The speciﬁcation of the numerical operations is written as though inﬁnities and NaNs are representable. The results are speciﬁed by x1 div0 x2 x1 mod0 x2 where: x1 = nd · x2 + xm −| x2 | ≤ xm < | x2 | 2 2 Examples: 123 div0 10 123 mod0 10 123 div0 −10 123 mod0 −10 −123 div0 10 −123 mod0 10 −123 div0 −10 −123 mod0 −10 = 12 = nd = xm = 3 = −12 = 3 = −12 = −3 = 12 = −3 Transcendental functions In general. however.3.

0) (complex? +nan.0 2 undeﬁned +0.0 = +0.0) (integer? -inf. Numerical operations Numerical type predicates (real-valued? obj ) (rational-valued? obj ) (integer-valued? obj ) procedure procedure procedure procedure procedure procedure procedure procedure (number? obj ) (complex? obj ) (real? obj ) (rational? obj ) (integer? obj ) These numerical type predicates can be applied to any kind of argument. or a complex number object whose real part is a NaN and whose imaginary part is zero in the sense of zero?. and the two-argument version of tan−1 are according to the following formulæ: log z b sin−1 z cos z tan−1 z tan−1 x y −1 = log z log b 1 − z2) −1 If z is a complex number object.0 −0. or if the object is a NaN. If x is a real number object.0 = −0.0 = −0. The real-valued? procedure returns #t if the object is a number object and is equal in the sense of = to some real number object.0 x > 0.11. and otherwise they return #f.0 = +0.0 < r < π 2 <r<π π π −π −π < r < − π 2 −π 2 − π < r < 0.0 x < 0.0 = −0.0 π −π −π 2 π 2 π 2 π 2 ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ Note: Except for number?.0 = 0.5+0. y y y y y y y y y y y y y y y y y y y y condition = 0.0 x > 0.0 −0.0 x=0 x=0 range of result r 0.0 = −0.5+0i) (real? -2.0 x = 0.0 +0.0 x > 0.4. They return #t if the object is a number object of the named type.0 = −0.0 x > 0.0 x condition x > 0. Thus inﬁnities and NaNs are not rational number objects.0 x = 0.0 x = 0.0) (rational? +nan. and #f otherwise.0 < 0.0 x<0 x < 0. then (integer? q) is true if and only if (= (denominator q) 1) is true.0 = +0.0 = +0. if a type predicate is false of a number object. These numerical type predicates can be applied to any kind of argument.0) =⇒ =⇒ =⇒ =⇒ =⇒ =⇒ =⇒ =⇒ =⇒ =⇒ =⇒ =⇒ =⇒ =⇒ =⇒ =⇒ =⇒ =⇒ =⇒ =⇒ =⇒ #t #t #t #f #t #t #t #t #t #t #t #t #t #t #t #t #f #t #t #f #f = −i log(iz + = π/2 − sin z = (log(1 + iz) − log(1 − iz))/(2i) = angle(x + yi) The range of tan−1 x y is as in the following table. (complex? 3+4i) (complex? 3) (real? 3) (real? -2.0 x = +0.0) (rational? -inf. then (real? z ) is true if and only if (zero? (imag-part z )) and (exact? (imag-part z )) are both true.0 x < 0.0 > 0.0) (complex? +inf. Base library 41 tan−1 z.0+0i) -inf.0 x = −0. The asterisk (*) indicates that the entry applies to implementations that distinguish minus zero.0) 3) =⇒ =⇒ =⇒ =⇒ #t #t #t #t .0 < 0. Consequently.0 > 0. the behavior of these type predicates on inexact number objects is unreliable.7. In general.0) (real? +nan.0 x < 0.0i) (real? -2. because any inaccuracy may aﬀect the result. (real-valued? (real-valued? (real-valued? (real-valued? +nan. if a type predicate is true of a number object then all higher type predicates are also true of that number object.0 0. If q is not a rational number object. then (rational? x ) is true if and only if there exist exact integer objects k1 and k2 such that (= x (/ k1 k2 )) and (= (numerator x ) k1 ) and (= (denominator x ) k2 ) are all true. The rational-valued? and integer-valued? procedures return #t if the object is a number object and is equal in the sense of = to some object of the named type. then (integer? q) is #f.0 = +0.0) (integer? 8/4) (number? +nan.0 = 0.0 x = −0. If q is a rational number objects.0) +nan. then all lower type predicates are also false of that number object.0 < 0. 11.5) (real? #e1e10) (rational? 6/10) (rational? 6/3) (rational? 2) (integer? 3+0i) (integer? 3.0 > 0.0) (real? -inf.0 x = +0.

0i) 3. monotonically nondecreasing. If an exact argument has no reasonably close inexact equivalent.5) #e1e10) =⇒ =⇒ =⇒ =⇒ #t #t #t #t #f #f #t #t #t #t #t #t #t #t #t (rational-valued? (rational-valued? (rational-valued? (rational-valued? (rational-valued? (rational-valued? (integer-valued? (integer-valued? (integer-valued? (integer-valued? (integer-valued? +nan. the behavior of these predicates diﬀers from the behavior of real?. . consult a numerical analyst. the result of this procedure should be numerically equal to its argument.0. or monotonically nonincreasing. . (= z1 z2 z3 .0 or -inf.0 x +inf.0 x ) =⇒ =⇒ #f #f These predicates must be transitive. . .0) (= -inf.0)) =⇒ =⇒ #t #t For any number object z : Generic conversions (= +nan.0) =⇒ 6/10) =⇒ 6/10+0. If an inexact argument has no reasonably close exact equivalent. For any number object. ) procedure procedure procedure procedure procedure These procedures return #t if their arguments are (respectively): equal. a reasonably close inexact equivalent may be +inf. The inexact procedure returns an inexact representation of z . an exception with condition type &implementation-violation may be raised. If inexact number objects of the appropriate type have bounded precision. because any inaccuracy may aﬀect the result.0 x -inf. ) (<= x1 x2 x3 . an exception with condition type &implementation-violation may be raised. and #f otherwise. Similarly. in most cases. precisely one of these predicates is true. and integer? on complex number objects whose imaginary part is inexact zero.0 x ) (> +nan.5+0. (= +inf.0 z ) =⇒ #f For any real number object x : (inexact z ) (exact z ) procedure procedure (< +nan. . then the value returned is an inexact number object that is nearest to the argument. . (exact? 5) (inexact? +inf.0) =⇒ =⇒ #t #t For any real number object x that is neither inﬁnite nor NaN: (< -inf.0 -inf.0) (= -inf.0i) 8/4) =⇒ =⇒ =⇒ =⇒ =⇒ The exact procedure returns an exact representation of z .0 +inf. monotonically decreasing. The value returned is the exact number object that is numerically closest to the argument.0+0. monotonically increasing. . .0 +inf.42 Revised6 Scheme (real-valued? (real-valued? (real-valued? (real-valued? -2. Speciﬁcally. Note: The traditional implementations of these predicates in Lisp-like languages are not transitive. the results may be unreliable because a small inaccuracy may aﬀect the result.0) =⇒ =⇒ =⇒ #t #f #t (exact? z ) (inexact? z ) procedure procedure These numerical predicates provide tests for the exactness of a quantity.0)) (> +inf. ) (< x1 x2 x3 . . Note: The behavior of these type predicates on inexact number objects is unreliable.0i)=⇒ 6/10+0i) =⇒ 6/3) =⇒ 3+0i) 3+0. rational?. Note: While it is possible to compare inexact number objects using these predicates. ) (> x1 x2 x3 . ) (>= x1 x2 x3 . These procedures implement the natural one-to-one correspondence between exact and inexact integer objects throughout an implementation-dependent range. Note: For a real number object whose magnitude is ﬁnite but so large that it has no reasonable ﬁnite approximation as an inexact number. (zero? z ) (positive? x ) (negative? x ) (odd? n) procedure procedure procedure procedure .0) =⇒ -inf.0i) -2. the inexact representation of a complex number object whose components are ﬁnite may have inﬁnite components.5+0i) -2. . When in doubt. The inexact and exact procedures are idempotent. Arithmetic operations Note: These procedures test whether a given number object can be coerced to the speciﬁed type without loss of numerical accuracy. this is especially true of = and zero? (below).0) 3.

0) (zero? +nan. it returns the additive inverse of its argument.0 x ) =⇒ +nan. then the procedure may raise an exception with condition type &implementation-restriction. .0) =⇒ =⇒ =⇒ =⇒ -1 -6 -3 +nan.0) -0. finite? tests whether it is not an inﬁnity and not a NaN.0 -0. negative? tests whether it is less than zero. and the numerical value of the result cannot be represented as an inexact number object without loss of accuracy.0 should adopt behavior consistent with the following examples: (+ (+ (+ (+ 0. The zero? procedure tests if the number object is = to zero. With two or more arguments.0 Note: As with the predicates above.0 (+ z1 .0) =⇒ =⇒ =⇒ =⇒ =⇒ =⇒ =⇒ =⇒ =⇒ =⇒ =⇒ =⇒ #t #t #f #t #t #f #f #f #t #t #f #t For any real number object x that is neither inﬁnite nor NaN: (+ +inf.0 0.0 0. Implementations that distinguish −0.0 4 1 +inf. positive? tests whether it is greater than zero. .0 -0. . even? tests whether it is even. odd? tests whether it is odd. this procedures returns the diﬀerence of its arguments.0) (* -5 +inf.0 x ) =⇒ +nan. ) (min x1 x2 .0 should adopt behavior consistent with the following examples: These procedures return the sum or product of their arguments. they either raise an exception with condition type &implementation-restriction or return an unspeciﬁed number object.0) (finite? +inf.0 0) =⇒ =⇒ =⇒ =⇒ =⇒ =⇒ =⇒ =⇒ =⇒ =⇒ =⇒ =⇒ =⇒ =⇒ 7 3 0 +inf.0) (* +inf.0 -0.0 +inf.0) (* 1.9 4) =⇒ =⇒ 4 4.0 +inf. ((((3 4) 3 4 5) 3) +inf.0 For any real number object x that is not an exact 0: (* +nan.0 For any real number object x : (max +inf. .0 -inf. nan? tests whether it is a NaN. then the result is also inexact (unless the procedure can prove that the inaccuracy is not large enough to aﬀect the result.0) (* 4) (*) (* 5 +inf. . which is possible only in unusual implementations).11. Implementations that distinguish −0.z1 z2 . If min or max is used to compare number objects of mixed exactness. .0) 0.0 -inf. .0 For any real number object x : (+ +nan.0) (* 0 +inf.0 These numerical predicates test a number object for a particular property.0 0 or 0. .0 0 or +nan.0) (infinite? +inf. ) procedure procedure Note: If any argument is inexact. .0 These procedures return the maximum or minimum of their arguments. (max 3 4) (max 3.0 x ) =⇒ =⇒ +inf. however.0 -inf. infinite? tests whether it is an inﬁnity.0) (* 0 +nan. ) procedure procedure If any of these procedures are applied to mixed non-rational real and non-real complex arguments.0) (zero? -0. associating to the left.0 x ) (+ -inf.0 x ) =⇒ =⇒ +inf. (max x1 x2 .0 -inf.0 +inf.0) -0.0 x ) (min -inf.0 +nan.0 0.0) (+ +inf.0) (positive? +inf.0) (infinite? 5.0 +inf.0 (.0) (negative? +nan.0 -inf. Base library 43 (even? n) (finite? x ) (infinite? x ) (nan? x ) procedure procedure procedure procedure (+ 3 4) (+ 3) (+) (+ +inf. ) procedure procedure If this procedure is applied to mixed non-rational real and non-real complex arguments. . the results may be unreliable because a small inaccuracy may aﬀect the result.0) (negative? -inf.0 0. .0) (finite? 5) (finite? 5.0) (positive? +nan.0) =⇒ =⇒ =⇒ =⇒ 0. (zero? +0. With one argument. it either raises an exception with condition type &implementation-restriction or returns an unspeciﬁed number object.z ) (.0 -inf.0 0 or +nan.0) (* +inf. ) (* z1 . returning #t or #f.

it either raises an exception with condition type &implementation-restriction or returns an unspeciﬁed number object.0 =⇒ +nan. (abs x ) Returns the absolute value of its argument.3.0) =⇒ =⇒ =⇒ =⇒ =⇒ =⇒ -0.0) =⇒ =⇒ 7 +inf. . The truncate procedure returns the integer object closest to x whose absolute value is not larger than the absolute value of x .0 0.0 1 (numerator q) (denominator q) procedure procedure If this procedure is applied to mixed non-rational real and non-real complex arguments.0 0) 0. x1 must be neither inﬁnite nor a NaN. . rounding to even when x represents a number halfway between two integers. In each case. . (abs -7) (abs -inf. and x2 must be nonzero. then the divisors must all be nonzero.0 -0.0 0.0 -0.0 =⇒ 0.5) 0 0. and exact integer objects for exact rational arguments. it returns the multiplicative inverse of its argument.0 0.44 Revised6 Scheme ((((((0.0) -0. these =⇒ x1 mod x2 =⇒ x1 div x2 . then the result is also inexact.0 (div0 x1 x2 ) =⇒ x1 div0 x2 (mod0 x1 x2 ) =⇒ x1 mod0 x2 (div0-and-mod0 x1 x2 ) =⇒ x1 div0 x2 .0 0.0 These procedures return the greatest common divisor or least common multiple of their arguments. ) procedure procedure (gcd n1 .0) 0. . this procedure returns the quotient of its arguments.0) 0.0 0. For such arguments. two return values . Note: If the argument to one of these procedures is inexact.0 -36) (lcm) =⇒ =⇒ =⇒ =⇒ =⇒ 4 0 288 288. . and a NaN when given a NaN. With two or more arguments.0) 0.0) -0. floor returns the largest integer object not larger than x .0 -0. two return values (/ z ) (/ z1 z2 . x1 mod x2 procedures return an inﬁnity when given an inﬁnity as an argument. x1 mod0 x2 .0 =⇒ +nan. however. . the result is computed as if the argument was represented as a fraction in lowest terms.0 0.0) +inf.0) -0.0 These procedures return the numerator or denominator of their argument.0 =⇒ -inf.0 =⇒ +nan. an exception with condition type &assertion is raised.0) =⇒ 3/20 =⇒ 1/3 =⇒ +inf. ) (lcm n1 . (/ (/ (/ (/ (/ (/ (/ (/ (/ (/ (/ (/ 3 4 5) 3) 0. If an exact value is needed. (gcd 32 -36) (gcd) (lcm 32 -36) (lcm 32. .7. (div x1 x2 ) (mod x1 x2 ) (div-and-mod x1 x2 ) These procedures return inexact integer objects for inexact arguments that are not inﬁnities or NaNs.0 0) -1 0.0 0. The denominator is always positive. The denominator of 0 is deﬁned to be 1. The round procedure returns the closest integer object to x . With one argument.0) 1.0 procedure (floor x ) (ceiling x ) (truncate x ) (round x ) procedure procedure procedure procedure procedure procedure procedure procedure procedure procedure (div-and-mod x1 x2 ) (div x1 x2 ) (mod x1 x2 ) (div0-and-mod0 x1 x2 ) (div0 x1 x2 ) (mod0 x1 x2 ) These procedures implement number-theoretic integer division and return the results of the corresponding mathematical operations speciﬁed in section 11.0) 0 0) 3 0) 0 3. (numerator (/ 6 4)) (denominator (/ 6 4)) (denominator (inexact (/ 6 4))) =⇒ =⇒ =⇒ 3 2 2.0 =⇒ &assertion exception =⇒ &assertion exception =⇒ 0.0 =⇒ +inf. The result is always non-negative. =⇒ x1 div x2 Although inﬁnities and NaNs are not integer objects. ) procedure procedure If all of the arguments are exact. The ceiling procedure returns the smallest integer object not smaller than x . otherwise. associating to the left. the result should be passed to the exact procedure.

0) =⇒ (rationalize 3 +inf.5) (ceiling 3.7.3) (floor 3.0i) =⇒ 0.141592653589793i .0 if z = 0. approximately (log -1.0 4 7 +inf. acos.0) =⇒ -1. See section 11. (sqrt -5) =⇒ (sqrt +inf.141592653589793i .0z is 1.0 0.0) (round +nan.5) (round 3. For rational z .0 is distinguished (rationalize x1 x2 ) procedure The rationalize procedure returns the a number object representing the simplest rational number diﬀering from x1 by no more than x2 .0.7. 0 two return values 1 two return values These procedures compute the usual transcendental functions. =⇒ 2 . (log z1 z2 ) computes the base-z2 logarithm of z1 .0) =⇒ +inf.141592653589793i .0 +nan. The (expt z1 z2 ) procedure Returns z1 raised to the power z2 .0 3.0 -inf. if -0.0i The ﬁrst two examples hold only in implementations whose inexact real number objects have suﬃcient precision.0+3.5707963267948965 . the value of (sqrt z ) could be expressed as log z e 2 .11.0-0. and arctangent.0 -inf. (exact-integer-sqrt 4) (exact-integer-sqrt 5) =⇒ 2 . The log procedure with a single argument computes the natural logarithm of z (not the base-ten logarithm).0 asin.0 +inf. approximately (atan +inf.0i) =⇒ 0.0+3. Note that 0 = 0/1 is the simplest rational of all.3) 1/10) =⇒ 1/3 (rationalize . The exp procedure computes the base-e exponential of z .0 0) =⇒ &assertion exception -inf. or zero real part and non-negative imaginary part. 0.0+0. (rationalize (exact . For nonzero z1 .0 0. A rational number r1 is simpler than another rational number r2 if r1 = p1 /q1 and r2 = p2 /q2 (in lowest terms) and |p1 | ≤ |p2 | and |q1 | ≤ |q2 |.3 for the underlying mathematical operations. (exp (exp (log (log (log (log +inf.5) (truncate 3.0 (sqrt z ) procedure Returns the principal square root of z . Base library 45 (floor -4. approximately =⇒ +inf.23606797749979i . approximately (rationalize +inf. arccosine. The two-argument variant of atan computes (angle (make-rectangular x2 x1 )).0) =⇒ 0. this is ez2 log z1 . approximately . and atan procedures compute arcsine.3) (truncate -4.0) =⇒ +inf.0 if (real-part z ) is positive.3.0) =⇒ =⇒ =⇒ =⇒ =⇒ =⇒ =⇒ =⇒ =⇒ =⇒ =⇒ =⇒ =⇒ -5. The sqrt procedure may return an inexact result even when given an exact argument.0 4.5) (round 7/2) (round 7) (floor +inf.0 -4.0) =⇒ +inf.3) (ceiling -4.0) 0. Thus 3/5 is simpler than 4/7. respectively. and 0.5707963267948965 . For other cases in which the ﬁrst argument .0 +inf.0 4.0) (sqrt -inf.0 -4. With log deﬁned as in section 11.0+2.0 =⇒ +inf.0 -4.0 3) =⇒ (rationalize +inf. the result has either positive real part.0 +nan.0-3.0) (ceiling -inf.0) =⇒ +inf. approximately (log -1.3 1/10) =⇒ #i1/3 . (exp z ) (log z ) (log z1 z2 ) (sin z ) (cos z ) (tan z ) (asin z ) (acos z ) (atan z ) (atan x1 x2 ) procedure procedure procedure procedure procedure procedure procedure procedure procedure procedure (exact-integer-sqrt k ) procedure The exact-integer-sqrt procedure returns two nonnegative exact integer objects s and r where k = s2 + r and k < (s + 1)2 .0 3.0) =⇒ -inf. These procedures may return inexact results even when given exact arguments. Although not all rationals are comparable in this ordering (consider 2/7 and 3/5) any interval contains a rational number that is simpler than every other rational number in that interval (the simpler 2/5 lies between 2/7 and 3/5).0) =⇒ 1.3) (round -4. approximately (atan -inf.

0+0. either an exception is raised with condition type &implementation-restriction. radix defaults to 10. 8.0 is zero. a3 . approximately (angle -1. if -0. specify an explicit mantissa width p. precision must be an exact positive integer object. and radix must be 10.1@2. and p is the least p ≥ precision for which the above expression is true.1 .1+2. a2 . 10.0 The make-polar. approximately Numerical Input and Output (make-rectangular x1 x2 ) (make-polar x3 x4 ) (real-part z ) (imag-part z ) (magnitude z ) (angle z ) procedure procedure procedure procedure procedure procedure (number->string z ) (number->string z radix ) (number->string z radix precision) procedure procedure procedure Suppose a1 .1@2. or an unspeciﬁed number object is returned.0) =⇒ =⇒ =⇒ =⇒ =⇒ =⇒ =⇒ =⇒ =⇒ 125 1/125 1 0 0 unspeciﬁed unspeciﬁed 1 1. if −π ≤ a4 ≤ π. (magnitude z ) returns a3 . Conversely.0) =⇒ 3.2i) (imag-part 1. trailing zeroes.0i) =⇒ -3. (angle -1. then the representations of the inexact real components of the result. an exception with condition type &implementationrestriction is raised. and if z is a number object representing c. If a precision is speciﬁed. and (make-polar x3 x4 ) returns c. The result returned by number->string never contains an explicit radix preﬁx. approximately (angle -1. (real-part 1. approximately .2) =⇒ 1. 7]. respectively. otherwise the format of the result is unspeciﬁed.2) (angle 1.0-0.1 .2 .141592653589793 . then z must be an inexact complex number object.141592653589793 .2) =⇒ =⇒ =⇒ =⇒ 1. suppose x1 .2) =⇒ 1. (make-rectangular x1 x2 ) returns c. then (real-part z ) returns a1 (imag-part z ) returns a2 . and angle procedures may return inexact results even when given exact arguments. approximately . (angle -1) =⇒ 3. and the above expression and condition can be satisﬁed by a result that contains a decimal point. and a4 .0000312i) 0 -5) 0 -5+. magnitude. Note: The error case can occur only when z is not a complex number object or is a complex number object with a nonrational real or imaginary part. approximately If a precision is speciﬁed. (expt z1 z2 ) must return an exact result. (expt z1 z2 ) may return an inexact result. For an exact real number object z1 and an exact integer object z2 . even when both z1 and z2 are exact.0) =⇒ 3.1+2. If z is inexact.0) =⇒ 0. and c is a complex number such that the following holds: c = a1 + a2 i = a3 eia4 Then. and x4 are number objects representing a1 .141592653589793 . x2 are such that either x1 or x2 is an inﬁnity.2i .1 2. x3 . approximately 1. and mantissa width) needed to make the above expression and condition true [4. the radix is 10.0 (angle -inf.0000312i) 0 0) 0. if x1 .0 is distinguished (angle +inf.2i) (magnitude 1. then the result contains a decimal point and is expressed using the minimum number of digits (exclusive of exponent. and (angle z ) returns a4 .46 Revised6 Scheme Moreover. a3 . unless they are inﬁnite or NaN.0 0. For all other values of z1 and z2 . x2 .2 .1@2.141592653589793 .0i) =⇒ 3.1+2. If no possible result makes this expression true. approximately 2. (make-rectangular 1. approximately 2. or 16. and a4 are real numbers. The number->string procedure takes a number object and a radix and returns as a string an external representation of the given number object in the given radix such that (let ((number z ) (radix radix )) (eqv? (string->number (number->string number radix) radix) number)) is true.141592653589793 . a2 . approximately (make-polar 1. either 2. If omitted. then (make-rectangular x1 x2 ) (magnitude z ) =⇒ z =⇒ +inf. approximately Radix must be an exact integer object. (expt (expt (expt (expt (expt (expt (expt (expt (expt 5 3) 5 -3) 5 0) 0 5) 0 5+.1 2.2i .

(boolean? #f) (boolean? 0) (boolean? ’()) =⇒ =⇒ =⇒ #t #f #f (cons obj1 obj2 ) (boolean=? bool1 bool2 bool3 . . See section 5. which is the same as the number of pairs. only #f counts as false in conditional expressions.7. Note that an improper list is not a list. More precisely. The car and cdr ﬁelds are accessed by the procedures car and cdr. either 2. (c . and otherwise returns #f.8. For example. (boolean? obj ) Returns #t if obj is either #t or #f and returns #f otherwise. or 16. Pairs are created by the procedure cons.0 -inf. procedure procedure Returns a newly allocated pair whose car is obj1 and whose cdr is obj2 . The objects in the car ﬁelds of successive pairs of a list are the elements of the list. The list and dotted notations can be combined to represent improper lists: (a b c .0") "-inf. (not (not (not (not (not (not (not #t) 3) (list 3)) #f) ’()) (list)) ’nil) =⇒ =⇒ =⇒ =⇒ =⇒ =⇒ =⇒ #f #f #f #t #f #f #f is equivalent to (a . a two-element list is a pair whose car is the ﬁrst element and whose cdr is a pair whose car is the second element and whose cdr is the empty list. Booleans The standard boolean objects for true and false have external representations #t and #f. d))) Whether a given pair is a list depends upon what is stored in the cdr ﬁeld.0 +nan.0 Note: The string->number procedure always returns a number object or #f. A chain of pairs not ending in the empty list is called an improper list. Pairs are used primarily to represent lists. . • If list is in X .11. Radix must be an exact integer object. If radix is not supplied. then any pair whose cdr ﬁeld contains list is also in X . . 11. and returns #f otherwise. d) (not obj ) procedure Returns #t if obj is #f.0") "+nan. The pair is guaranteed to be diﬀerent (in the sense of eqv?) from every existing object. The length of a list is the number of elements.0 #f +inf. b)) ’(a b c)) ’()) ’#(a b)) =⇒ =⇒ =⇒ =⇒ #t #t #f #f procedure Returns #t if obj is a pair. However. Base library 47 (string->number string) (string->number string radix ) procedure procedure 11. A list can be deﬁned recursively as either the empty list or a pair whose cdr is a list. "#o177"). then the default radix is 10. (string->number (string->number (string->number (string->number (string->number (string->number (string->number "100") "100" 16) "1e2") "0/0") "+inf. If string is not a syntactically valid notation for a number object or a notation for a rational number object with a zero denominator. radix is a default radix that may be overridden by an explicit radix preﬁx in string (e. Note: Programmers accustomed to other dialects of Lisp should be aware that Scheme distinguishes both #f and the empty list from each other and from the symbol nil. If supplied.9. Note: The above deﬁnitions imply that all lists have ﬁnite length and are terminated by the empty list.0") =⇒ =⇒ =⇒ =⇒ =⇒ =⇒ =⇒ 100 256 100.g. (b . 10. then string->number returns #f. Pairs and lists A pair is a compound structure with two ﬁelds called the car and cdr ﬁelds (for historical reasons). It has no elements and its length is zero. of all objects. (pair? obj ) procedure (pair? (pair? (pair? (pair? ’(a . The empty list is a special object of its own type. It is not a pair. ) Returns #t if the booleans are the same. Returns a number object with maximally precise representation expressed by the given string.. the set of lists is deﬁned as the smallest set X such that • The empty list is in X . 8. it never raises an exception.

b)) =⇒ =⇒ =⇒ #t #t #f Implementation responsibilities: The implementation must check that list is a chain of pairs whose length is at least k . . . it is always newly allocated. . #fotherwise. 2)) (cdr ’()) procedure =⇒ (b c d) =⇒ 2 =⇒ &assertion exception If append constructs a nonempty chain of pairs. It should not check that it is a chain of pairs beyond this length. An improper list results if obj is not a list. (car (car (car (car ’(a b c)) ’((a) b c d)) ’(1 . (caar pair ) (cadr pair ) . are provided. (list-ref list k ) procedure List must be a list whose length is at least k + 1. . procedure procedure (reverse list) procedure Returns a newly allocated list consisting of the elements of list in reverse order. where for example caddr could be deﬁned by (define caddr (lambda (x) (car (cdr (cdr x))))). (cdddar pair ) (cddddr pair ) procedure procedure . (reverse ’(a b c)) =⇒ (c b a) (reverse ’(a (b c) d (e (f)))) =⇒ ((e (f)) d (b c) a) These procedures are compositions of car and cdr. . . (list-tail ’(a b c d) 2) =⇒ (c d) Returns #t if obj is a list. (list ’a (+ 3 4) ’c) (list) =⇒ =⇒ (a 7 c) () procedure Implementation responsibilities: The implementation must check that list is a chain of pairs whose length is at least k + 1. Arbitrary compositions. (list-ref ’(a b c d) 2) =⇒ c (list obj . all lists are chains of pairs that have ﬁnite length and are terminated by the empty list. obj ) procedure =⇒ a =⇒ (a) =⇒ 1 =⇒ &assertion exception Returns a possibly improper list consisting of the elements of the ﬁrst list followed by the elements of the other lists. (length ’(a b c)) (length ’(a (b) (c d e))) (length ’()) =⇒ =⇒ =⇒ 3 3 0 procedure (car pair ) Returns the contents of the car ﬁeld of pair . . ) Returns a newly allocated list of its arguments. It should not check that it is a list of pairs beyond this length. c) (length list) Returns the length of list. (cdr ’((a) b c d)) (cdr ’(1 . There are twenty-eight of these procedures in all. (append (append (append (append (append ’(x) ’(y)) ’(a) ’(b c d)) ’(a (b)) ’((c))) ’(a b) ’(c . (list? ’(a b c)) (list? ’()) (list? ’(a .48 Revised6 Scheme (cons (cons (cons (cons (cons ’a ’()) ’(a) ’(b c d)) "a" ’(b c)) ’a 3) ’(a b) ’c) =⇒ =⇒ =⇒ =⇒ =⇒ (a) ((a) b c d) ("a" b c) (a . 3) ((a b) . The list-tail procedure returns the k th element of list. d)) ’() ’a) =⇒ =⇒ =⇒ =⇒ =⇒ (x (a (a (a a y) b c d) (b) (c)) b c . The list-tail procedure returns the subchain of pairs of list obtained by omitting the ﬁrst k elements. If no pairs are allocated. (list? obj ) procedure procedure (list-tail list k ) procedure List should be a list of size at least k . #f otherwise. up to four deep. By deﬁnition. . obj is returned. d) (cdr pair ) Returns the contents of the cdr ﬁeld of pair . . (null? obj ) Returns #t if obj is the empty list. 2)) ’()) procedure (append list . with obj as the cdr of the ﬁnal pair.

The return values of for-each are unspeciﬁed. i. An implementation may check whether proc is an appropriate argument before applying it. Proc should accept as many arguments as there are lists and return a single value. if their names are spelled the same.. (symbol? obj ) =⇒ =⇒ =⇒ =⇒ =⇒ =⇒ procedure Returns #t if obj is a symbol. . ) procedure implementation must check the restrictions on proc to the extent performed by applying it as described. the values returned by earlier returns are not mutated.D. (map cadr ’((a b) (d e) (g h))) =⇒ (b e h) (map (lambda (n) (expt n n)) ’(1 2 3 4 5)) =⇒ (1 4 27 256 3125) (map + ’(1 2 3) ’(4 5 6)) =⇒ (5 7 9) 11. in order from the ﬁrst elements to the last. in order. M. Proc should not mutate any of the lists. Harper. M. .e. (for-each proc list1 list2 . (symbol->string ’flying-fish) =⇒ (symbol->string ’Martin) =⇒ (symbol->string (string->symbol "Malvina")) =⇒ "flying-fish" "Martin" "Malvina" The lists should all have the same length. An implementation may check whether proc is an appropriate argument before applying it. otherwise returns #f.11. .10. The . The implementation must check the restrictions on proc to the extent performed by applying it as described. Proc should not mutate any of the lists. Harper. Base library 49 (map proc list1 list2 . Proc should accept as many arguments as there are lists. Note: Implementations of for-each may or may not tail-call proc on the last elements. The lists should all have the same length. . (eq? ’mISSISSIppi ’mississippi) =⇒ #f (string->symbol "mISSISSIppi") =⇒ the symbol with name "mISSISSIppi" (eq? ’bitBlt (string->symbol "bitBlt")) =⇒ #t (eq? ’JollyWog (string->symbol (symbol->string ’JollyWog))) =⇒ #t (string=? "K. ) procedure (symbol->string symbol ) procedure Returns the name of symbol as an immutable string. If multiple returns occur from map.D. (string->symbol string) Returns the symbol whose name is string. (symbol? (symbol? (symbol? (symbol? (symbol? (symbol? ’foo) (car ’(a b))) "bar") ’nil) ’()) #f) #t #t #f #t #f #f (let ((count 0)) (map (lambda (ignored) (set! count (+ count 1)) count) ’(a b))) =⇒ (1 2) or (2 1) Implementation responsibilities: The implementation should check that the lists all have the same length. . A symbol literal is formed using quote. The map procedure applies proc element-wise to the elements of the lists and returns a list of the results. ) procedure Returns #t if the symbols are the same. (let ((v (make-vector 5))) (for-each (lambda (i) (vector-set! v i (* i i))) ’(0 1 2 3 4)) v) =⇒ #(0 1 4 9 16) (for-each (lambda (x) x) ’(1 2 3 4)) =⇒ unspeciﬁed (for-each even? ’()) =⇒ unspeciﬁed (symbol=? symbol1 symbol2 symbol3 . Proc is always called in the same dynamic environment as for-each itself. The order in which proc is applied to the elements of the lists is unspeciﬁed. Symbols Symbols are objects whose usefulness rests on the fact that two symbols are identical (in the sense of eq?. ." (symbol->string (string->symbol "K. Proc is always called in the same dynamic environment as map itself. The for-each procedure applies proc element-wise to the elements of the lists for its side eﬀects."))) =⇒ #t procedure Implementation responsibilities: The implementation should check that the lists all have the same length. eqv? and equal?) if and only if their names are spelled the same way.

Roman letters. . (char<? #\z #\ß) (char<? #\z #\Z) =⇒ #t =⇒ #f These procedures are the lexicographic extensions to strings of the corresponding orderings on characters. . and can only appear in speciﬁc Unicode encodings. The valid indices of a string are the integers less than the length of the string. Otherwise. ) (string>? string1 string2 string3 . ) procedure Returns #t if the strings are the same length and contain the same characters in the same positions. and most Chinese characters fall into this category. . . the Unicode code points in this range. For a Unicode scalar value sv . are an artifact of the UTF-16 encoding. .11. .e. (string-length string) procedure Returns the number of characters in the given string as an exact integer object. Characters Characters are objects that represent Unicode scalar values [27]. ) procedure procedure procedure procedure procedure (string<? string1 string2 string3 . which are part of the range of Unicode code points. ) (char>? char1 char2 char3 . diﬀerent sequences of scalar values sometimes correspond to the same character. If two strings diﬀer in length but are the same up to the length of the shorter string. . otherwise returns #f. . char->integer returns its Unicode scalar value as an exact integer object. This number is ﬁxed when the string is created. (string-ref string k ) procedure (char? obj ) procedure Returns #t if obj is a character. . a non-negative exact integer object in [0. string<? is the lexicographic ordering on strings induced by the ordering char<? on characters. the shorter string is considered to be lexicographically less than the longer string. but the surrogate code points do not have representations as characters. . . which are abstract entities that map to glyphs (sometimes in a way that’s sensitive to surrounding characters). However. . Furthermore. . Sv must be a Unicode scalar value. ) procedure Returns a newly allocated string composed of the arguments. ) (string<=? string1 string2 string3 . (string? obj ) procedure Returns #t if obj is a string.12. (make-string k ) (make-string k char ) procedure procedure Returns a newly allocated string of length k . For example. Strings Strings are sequences of characters. More precisely. Note: Unicode deﬁnes a standard mapping between sequences of Unicode scalar values (integers in the range 0 to #x10FFFF.. . Consequently. . The length of a string is the number of characters that it contains. otherwise returns #f. Cyrillic letters. the string=? procedure returns #f. . then all elements of the string are initialized to char . . Unicode scalar values exclude the range #xD800 to #xDFFF. . Unicode distinguishes between glyphs. . 11. . i. and so on. The relationships among scalar. characters. and characters. For example. The ﬁrst character of a string has index 0. (integer->char 32) =⇒ #\space (char->integer (integer->char 5000)) =⇒ 5000 (integer->char #\xD800) =⇒ &assertion exception (string=? string1 string2 string3 . most things that a literate human would call a “character” can be represented by a single Unicode scalar value (although several sequences of Unicode scalar values may represent that same character). the so-called surrogates. integer->char returns its associated character. and glyphs are subtle and complex. If char is given. The string-ref procedure returns character k of string using zero-origin indexing. ) (char>=? char1 char2 char3 . (string=? "Straße" "Strasse") =⇒ #f (char=? char1 char2 char3 . and even then only in pairs that encode scalar values. the second has index 1. ) procedure procedure procedure procedure These procedures impose a total ordering on the set of characters according to their Unicode scalar values. which are printed for humans to read. Given a character. Hebrew consonants. ) (char<=? char1 char2 char3 . excluding the range #xD800 to #xDFFF) in the latest version of the standard and human-readable “characters”. #xD7FF] ∪ [#xE000. .50 Revised6 Scheme 11. all characters represent code points. otherwise the contents of the string are unspeciﬁed. ) (string>=? string1 string2 string3 . . Despite this complexity. (char->integer char ) (integer->char sv) procedure procedure K must be a valid index of string. #x10FFFF]. ) (char<? char1 char2 char3 . Note: Implementors should make string-ref run in constant time. (string char . .

Returns a newly allocated vector of k elements. then each element is initialized to ﬁll . Analogous to list. (vector? obj ) procedure Returns #t if obj is a vector. An implementation may check whether proc is an appropriate argument before applying it. A vector typically occupies less space than a list of the same length. This number is a non-negative integer that is ﬁxed when the vector is created. The vector-ref procedure returns the contents of element k of vector . The string-for-each procedure applies proc element-wise to the characters of the strings for its side eﬀects. in order from the ﬁrst characters to the last. .13. ) procedure Returns a newly allocated string whose characters form the concatenation of the given strings. and the last element is indexed by one less than the length of the vector. The length of a vector is the number of elements that it contains. The ﬁrst element in a vector is indexed by zero.11. and the average time needed to access a randomly chosen element is typically less for the vector than for the list. . and start and end must be exact integer objects satisfying 0 ≤ start ≤ end ≤ (string-length string). Proc should accept as many arguments as there are strings. The return values of string-for-each are unspeciﬁed. The valid indices of a vector are the exact non-negative integer objects less than the length of the vector. (vector-ref ’#(1 1 2 3 5 8 13 21) 5) =⇒ 8 (vector-set! vector k obj ) procedure (string-copy string) procedure K must be a valid index of vector . and returns unspeciﬁed values. . If a second argument is given. (vector-length vector ) procedure Returns the number of elements in vector as an exact integer object. ) procedure (string-for-each proc string1 string2 . (make-vector k ) (make-vector k ﬁll ) procedure procedure (string->list string) (list->string list) procedure procedure List must be a list of characters. Vectors Vectors are heterogeneous structures whose elements are indexed by integers. . ) procedure Returns a newly allocated vector whose elements contain the given arguments. vector constants must be quoted: ’#(0 (2 2 2 2) "Anna") =⇒ #(0 (2 2 2 2) "Anna") (substring string start end ) procedure String must be a string. . The string->list and list->string procedures are inverses so far as equal? is concerned. The vector-set! procedure stores obj in element k of vector . (vector ’a ’b ’c) =⇒ #(a b c) The strings must all have the same length. The string->list procedure returns a newly allocated list of the characters that make up the given string. The list->string procedure returns a newly allocated string formed from the characters in list. . (vector-ref vector k ) procedure K must be a valid index of vector . . Base library 51 (string<? "z" "ß") (string<? "z" "zz") (string<? "z" "Z") =⇒ #t =⇒ #t =⇒ #f 11. Passing an immutable vector to vector-set! should cause an exception with condition type &assertion to be raised. Like list constants. Proc is always called in the same dynamic environment as string-for-each itself. (vector obj . Otherwise the procedure returns #f. Implementation responsibilities: The implementation must check the restrictions on proc to the extent performed by applying it as described. (string-append string . Otherwise the initial contents of each element is unspeciﬁed. The substring procedure returns a newly allocated string formed from the characters of string beginning with index start (inclusive) and ending with index end (exclusive). Returns a newly allocated copy of the given string. Analogous to for-each.

in order. The condition object provided with the exception (see library chapter 7) has the following condition types: • If who is not #f. Moreover. Implementation responsibilities: The implementation must check the restrictions on proc to the extent performed by applying it as described. Proc should accept as many arguments as there are vectors. with message as the value of its ﬁeld. . If multiple returns occur from vector-map. ) procedure (assertion-violation who message irritant1 . The irritants are arbitrary objects. . constant vector . The error procedure should be called when an error has occurred.52 Revised6 Scheme (let ((vec (vector 0 ’(2 2 2 2) "Anna"))) (vector-set! vec 1 ’("Sue" "Sue")) vec) =⇒ #(0 ("Sue" "Sue") "Anna") (vector-set! ’#(0 1 2) 1 "doe") =⇒ unspeciﬁed . .14. The vector-for-each procedure applies proc element-wise to the elements of the vector s for its side eﬀects. the return values returned by earlier returns are not mutated. should raise &assertion exception Analogous to for-each. . . with who as the value of its ﬁeld. (vector->list ’#(dah dah didah)) =⇒ (dah dah didah) (list->vector ’(dididit dah)) =⇒ #(dididit dah) (vector-fill! vector ﬁll ) procedure Stores ﬁll in every element of vector and returns unspeciﬁed values. (vector-map proc vector1 vector2 . The return values of vector-for-each are unspeciﬁed. 11. either passing an invalid number of arguments. In that case. The assertion-violation procedure should be called when an invalid call to a procedure was made. The order in which proc is applied to the elements of the vector s is unspeciﬁed. Errors and violations (vector->list vector ) (list->vector list) procedure procedure (error who message irritant1 . Proc should accept as many arguments as there are vectors and return a single value. These procedures raise an exception. the condition does not have condition type &who. and its ﬁeld has as its value a list of the irritants. . Proc is always called in the same dynamic environment as vector-for-each itself. (define (fac n) (if (not (integer-valued? n)) (assertion-violation ’fac "non-integral argument" n)) (if (negative? n) (assertion-violation ’fac "negative argument" n)) The vector->list procedure returns a newly allocated list of the objects contained in the elements of vector . Analogous to map. and the condition created by assertionviolation has condition type &assertion. (vector-for-each proc vector1 vector2 . The message argument should describe the exceptional situation. or passing an argument that it is not speciﬁed to handle. ) procedure Who must be a string or a symbol or #f. Proc is always called in the same dynamic environment as vector-map itself. ) procedure The vector s must all have the same length. the condition created by error has condition type &error. Implementation responsibilities: The implementation must check the restrictions on proc to the extent performed by applying it as described. The list->vector procedure returns a newly created vector initialized to the elements of the list list. • The condition has condition type &message. • The condition has condition type &irritants. in order from the ﬁrst elements to the last. The vector-map procedure applies proc element-wise to the elements of the vector s and returns a vector of the results. typically caused by something that has gone wrong in the interaction of the program with the external world or the user. An implementation may check whether proc is an appropriate argument before applying it. who should be the name of the procedure or entity that detected the exception. The irritants should be the arguments to the operation that detected the operation. ) procedure The vector s must all have the same length. Message must be a string. An implementation may check whether proc is an appropriate argument before applying it. If it is #f. . . The who argument should describe the procedure or operation that detected the exception. the condition has condition type &who. .

Note: Implementations should exploit the fact that assert is syntax to provide as much information as possible about the location of the assertion failure. . The procedure call-with-current-continuation (which is the same as the procedure call/cc) packages the current continuation as an “escape procedure” and passes it as an argument to proc. there would be no need for a procedure with the power of call-with-currentcontinuation. ) rest-args) as the actual arguments. that value is returned from the assert expression. Control features This chapter describes various primitive procedures which control the ﬂow of program execution in special ways. If expression returns #f. The escape procedure accepts the same number of arguments as the continuation of the original call to callwith-current-continuation. The values procedure might be deﬁned as follows: (define (values . see section 5. and thus restores its dynamic environment. It may be stored in variables or data structures and may be called as many times as desired. (apply proc arg1 . (call-with-current-continuation (lambda (exit) (for-each (lambda (x) (if (negative? x) (exit x))) ’(54 0 37 -3 245 19)) #t)) =⇒ -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)) =⇒ 4 (assert expression ) syntax An assert form is evaluated by evaluating expression . rest-args) procedure Rest-args must be a list. c)) =⇒ #f (call-with-current-continuation procedure?) =⇒ #t Note: Calling an escape procedure reenters the dynamic extent of the call to call-with-current-continuation.) procedure Delivers all of its arguments to its continuation. (call-with-current-continuation proc) (call/cc proc) procedure procedure Proc should accept one argument. an exception with condition types &assertion and &message is raised. The message provided in the condition object is implementation-dependent. The apply procedure calls proc with the elements of the list (append (list arg1 . . The escape procedure is a Scheme procedure that. where n is number of args plus the length of rest-args.11. . If a call to call-with-current-continuation occurs in a tail context. . The escape procedure that is passed to proc has unlimited extent just like any other procedure in Scheme. .15. If all real uses were as simple as these examples. (values obj . things) (call-with-current-continuation (lambda (cont) (apply cont things)))) . Base library 53 (letrec ((loop (lambda (n r) (if (zero? n) r (loop (. the call to proc is also in a tail context. .n 1) (* r n)))))) (loop n 1))) (fac 5) (fac 4.5) (fac -3) =⇒ 120 =⇒ &assertion exception =⇒ &assertion exception if it is later called. will abandon whatever continuation is in eﬀect at that later time and will instead reinstate the continuation that was in eﬀect when the escape procedure was created. Calling the escape procedure may cause the invocation of before and after procedures installed using dynamic-wind. If expression returns a true value. (apply + (list 3 4)) (define compose (lambda (f g) (lambda args (f (apply g args))))) ((compose sqrt *) 12 75) =⇒ 30 =⇒ 7 (list-length ’(a b . If a call to apply occurs in a tail context. the call to proc is also in a tail context.12. The following examples show only some ways in which call-with-current-continuation is used. 11. Proc should accept n arguments.

the escape procedure reenters the dynamic extent of the least recent y and proceeds with the next least recent y. Once each x has been handled in this manner. The call-withvalues procedure calls producer with no arguments and a continuation that. case. (dynamic-wind before thunk after ) procedure Before. and after without arguments whenever the dynamic extent of the call to thunk is exited. usually take an arbitrary number of values. Except for these and the continuations created by callwith-values. and let*-values. Moreover. More precisely. take exactly one value. in that order. let*. such as in lambda. and so on. Thus. (call-with-values (lambda () (values 4 5)) (lambda (a b) b)) =⇒ 5 (call-with-values * -) =⇒ -1 If a call to call-with-values occurs in a tail context. thunk . These procedures may return any number of values. the implementation must check that consumer accepts as many values as consumer has returned. and after must be procedures. and so on. letrec*. . . calls the consumer procedure with those values as arguments. While the calls to before and after are not considered to be within the dynamic extent of the call to thunk . let*-values. let. returning the results of this call. Implementation responsibilities: The implementation must check the restrictions on thunk and after only if they are actually called. . . when passed some values. It leaves the dynamic extent of the most recent x and calls without arguments the corresponding after procedure. and transfer control into the dynamic extent of a set of zero or more active dynamic-wind calls y . (call-with-values producer consumer ) procedure Producer must be a procedure and should accept zero arguments. calls to the before and after procedures of any other calls to dynamic-wind that occur within the dynamic extent of the call to thunk are considered to be within the dynamic extent of the call to thunk .. the escape procedure calls without arguments the before procedure corresponding to the least recent y. letrec. dynamic-wind calls before without arguments whenever the dynamic extent of the call to thunk is entered. begin. Consumer must be a procedure and should accept as many values as producer returns. thunk . control is transferred to the continuation packaged in the escape procedure. and after . continuations implicitly accepting a single value. let-values. The continuation for the call to consumer is the continuation of the call to call-with-values. and each should accept zero arguments. dynamic-wind calls before. Implementation responsibilities: After producer returns. in the absence of calls to escape procedures created by call-with-current-continuation. an escape procedure transfers control out of the dynamic extent of a set of zero or more active . the call to consumer is also in a tail context. and cond forms. such as the continuations of operator and operand s of procedure calls or the test expressions in conditionals. (let ((path ’()) (c #f)) (let ((add (lambda (s) (set! path (cons s path))))) (dynamic-wind (lambda () (add ’connect)) (lambda () (add (call-with-current-continuation (lambda (c0) (set! c c0) ’talk1)))) (lambda () (add ’disconnect))) (if (< (length path) 4) (c ’talk2) (reverse path)))) =⇒ (connect talk1 disconnect connect talk2 disconnect) (let ((n 0)) (call-with-current-continuation (lambda (k) (dynamic-wind (lambda () (set! n (+ n 1)) (k)) (lambda () (set! n (+ n 2))) (lambda () (set! n (+ n 4)))))) n) =⇒ 1 (let ((n 0)) (call-with-current-continuation (lambda (k) (dynamic-wind values (lambda () (dynamic-wind values (lambda () The continuations of all non-ﬁnal expressions within a sequence of expressions. the escape procedure proceeds to the next most recent x. Once each y has been handled in this manner. The dynamic-wind procedure calls thunk without arguments. let-values. If the after procedure returns. The eﬀect of passing an inappropriate number of values to such a continuation is undeﬁned. If the before procedure returns.54 Revised6 Scheme dynamic-wind calls x .

As noted in section 4. Thus. `(a `(b . It has the same syntax and semantics as ordinary let except that variable is bound within body to a procedure whose parameters are the bound variables and whose body is body ..’.17. `(list . ) form appears inside a qq template .11. then the expression s must evaluate to lists. expression . the expression s are evaluated (“unquoted”) and their results are inserted into the structure instead of the unquote form. Thus the execution of body may be repeated by invoking the procedure named by variable .@q)) =⇒ `(foo (unquote (append x y) (sqrt 9))) (let ((x ’(2 3)) (y ’(4 5))) `(foo (unquote (append x y) (sqrt 9)))) =⇒ (foo (2 3 4 5) 3) n) Note: Entering a dynamic extent restores its dynamic environment.10 3)) .@ expression .(car ’(cons))) =⇒ ((foo 7) .5. (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)) ((< (car numbers) 0) (loop (cdr numbers) nonneg (cons (car numbers) neg))))) =⇒ ((6 1 3) (-5 -2)) 11. Base library 55 (set! n (+ n 1)) (k)) (lambda () (set! n (+ n 2)) (k)))) (lambda () (set! n (+ n 4)))))) =⇒ 7 If an (unquote expression . Substitutions are made only for unquoted components appearing at the same nesting level as the outermost quasiquote. Semantics: If no unquote or unquote-splicing forms appear within the qq template . see section 5.(.(+ 1 2) . . Syntax: Qq template should be as speciﬁed by the grammar at the end of this entry.12. A quasiquote expression may return either fresh. Iteration (let variable bindings body ) syntax “Named let” is a variant on the syntax of let that provides a general looping construct and may also be used to express recursion. .name)) =⇒ (list a (quote a)) `(a . the opening and closing parentheses of the lists are then “stripped away” and the elements of the lists are inserted in place of the unquote-splicing form. Any unquote-splicing or multi-operand unquote form must appear only within a list or vector qq template .name2 d) e)) =⇒ (a `(b .(+ 1 2) .(+ 1 2) . (quasiquote qq template ) may be abbreviated ` qq template . however.name ’.@(map sqrt ’(16 9)) 8) =⇒ #(10 5 2 4 3 8) (let ((name ’foo)) `((unquote name name name))) =⇒ (foo foo foo) (let ((name ’(foo))) `((unquote-splicing name name name))) =⇒ (foo foo foo) (let ((q ’((append x y) (sqrt 9)))) ``(foo . . Quasiquotation (quasiquote qq template ) unquote unquote-splicing syntax auxiliary syntax auxiliary syntax Quasiquote forms may be nested. (unquote expression ) may be abbreviated . ) form appears inside a qq template . and decreases by one inside each unquotation. The nesting level increases by one inside each successive quasiquotation. If an (unquote-splicing expression .16.(+ 1 2) 4) =⇒ (list 3 4) (let ((name ’a)) `(list .x . the result of evaluating (quasiquote qq template ) is equivalent to the result of evaluating (quote qq template ). 11.(+ 1 3) d) e) f) =⇒ (a `(b .@(cdr ’(c)) . .(sqrt 4) .@(map abs ’(4 -5 6)) b) =⇒ (a 3 4 5 6 b) `(( foo .’y d) e) “Backquote” or “quasiquote” expressions are useful for constructing a list or vector structure when some but not all of the desired structure is known in advance.. Portions that do not need to be rebuilt are always literal. .(foo . .(foo 4 d) e) f) (let ((name1 ’x) (name2 ’y)) `(a `(b . mutable objects or literal structure for any structure that is constructed at run time during the evaluation of the expression.name1 . and (unquote-splicing expression ) may be abbreviated . cons) `#(10 5 .3.

.))))) (def foo 42)) foo) =⇒ 42 (let () (let-syntax ()) 5) 11. The following grammar for quasiquote expressions is not context-free.7. =⇒ 5 (letrec-syntax bindings form . ) syntax Syntax: Same as for let-syntax. see section 11. . It is a syntax violation for keyword to appear more than once in the list of keywords being bound. bound to the speciﬁed transformers.. at macro-expansion time.19) or by one of the other mechanisms described in library chapter 12. Transformers may be created by syntax-rules or identifier-syntax (see section 11. A let-syntax or letrec-syntax form may also appear in an expression context. or unquote-splicing appear in positions within a qq template otherwise than as described above. 3. whether in deﬁnition or expression context. .a . Imagine a copy of the following rules for D = 1..) (define stuff . unquote. and each expression is an expression that evaluates. ) syntax may be equivalent to either of the following expressions: ’((1 2) 3 4 five 6) (let ((a 3)) (cons ’(1 2) (cons a (cons 4 (cons ’five ’(6)))))) Syntax: Bindings must have the form expression ) . someD or as an prece- (m)))) =⇒ outer (let () (let-syntax ((def (syntax-rules () ((def stuff . Thus deﬁnitions in the result of expanding the form s have the same region as any deﬁnition appearing in place of the let-syntax form would have.’five 6)) (let-syntax bindings (( keyword form . ) However. Semantics: The form s are expanded in the syntactic environment obtained by extending the syntactic environment of the let-syntax form with macros whose keywords are the keyword s. it is not equivalent to this expression: (let ((a 3)) (list (list 1 2) a 4 ’five 6)) Each keyword is an identiﬁer. 2. ..56 Revised6 Scheme (let ((a 3)) `((1 2) . . . in which case the forms within their bodies must be expressions. Binding constructs for syntactic keywords The let-syntax and letrec-syntax forms bind keywords.4 .. qq template −→ qq template 1 qq template 0 −→ expression quasiquotation D −→ (quasiquote qq template D ) Implementation responsibilities: The implementation qq template D −→ lexeme datum should detect if the value of expression cannot possibly | list qq template D be a transformer.18. | vector qq template D | unquotation D (let-syntax ((when (syntax-rules () list qq template D −→ ( qq template or splice D *) ((when test stmt1 stmt2 . . The interpretation unquotation or splicing unquotation D takes dence. qq template D ) (if test (begin stmt1 | quasiquotation D + 1 stmt2 . It is presented as a recipe for generating an inﬁnite number of production rules..4.)))))) vector qq template D −→ #( qq template or splice D *) (let ((if #t)) unquotation D −→ (unquote qq template D − 1 ) (when if (set! if ’now)) qq template or splice D −→ qq template D if)) =⇒ now | splicing unquotation D splicing unquotation D −→ (let ((x ’outer)) (unquote-splicing qq template D − 1 *) (let-syntax ((m (syntax-rules () ((m) x)))) | (unquote qq template D − 1 *) (let ((x ’inner)) In quasiquotation s.) | ( qq template or splice D + . to a transformer . . . as if wrapped in an implicit begin. It is a syntax violation if any of the identiﬁers quasiquote. Semantics: The form s are expanded in the syntactic environment obtained by extending the syntactic environment of the letrec-syntax form with macros whose keywords . a list qq template D can times be confused with either an unquotation a splicing unquotation D .. Each binding of a keyword has the form s as its region. and the forms in the body must also be deﬁnitions. Like a begin form. The form s of a let-syntax form are treated. in which case it is treated as a deﬁnition. D keeps track of the nesting depth. .. a let-syntax or letrec-syntax form may appear in a deﬁnition context..

.))))))) (let ((x #f) (y 7) (temp 8) (let odd?) (if even?)) (my-or x (let temp) (if y) y))) =⇒ 7 11. template ) #( subtemplate .) ( subtemplate . ) syntax (expand) auxiliary syntax (expand) .. to a new macro transformer by specifying a sequence of hygienic rewrite rules. bound to the speciﬁed transformers.4. whether in deﬁnition or expression context. ( pattern ( pattern ( pattern ( pattern #( pattern #( pattern . An identiﬁer appearing within a pattern may be an underscore ( ).. A pattern is an identiﬁer. It is a syntax violation when no match is found. (letrec-syntax ((my-or (syntax-rules () ((my-or) #f) ((my-or e) e) ((my-or e1 e2 .. as if wrapped in an implicit begin. While the ﬁrst subform of srpattern may be an identiﬁer. the f occurring in g refers to the let-bound variable f. A use of a macro whose keyword is associated with a transformer speciﬁed by syntax-rules is matched against the patterns contained in the syntax rule s.. In the ﬁrst expression. syntax rule must have the following form: ( srpattern template ) Each An srpattern is a restricted form of pattern .... . pattern ) .. whereas in the second it refers to the keyword f whose binding is established by the letrec-syntax form..) (let ((temp e1)) (if temp temp (my-or e2 .. so the transformers can transcribe forms into uses of the macros introduced by the letrec-syntax form.. When a match is found. It is a syntax violation if the same pattern variable appears more than once in a pattern .. ( subtemplate .) A subtemplate is a template followed by zero or more ellipses... A template is a pattern variable. auxiliary syntax (expand) Syntax: Each literal must be an identiﬁer... a literal identiﬁer listed in the list of literals ( literal . (let ((f (lambda (x) (+ x 1)))) (let-syntax ((f (syntax-rules () ((f x) x))) (g (syntax-rules () ((g x) (f x))))) (list (f 1) (g 1)))) =⇒ (1 2) (let ((f (lambda (x) (+ x 1)))) (letrec-syntax ((f (syntax-rules () ((f x) x))) (g (syntax-rules () ((g x) (f x))))) (list (f 1) (g 1)))) =⇒ (1 1) The two expressions are identical except that the let-syntax form in the ﬁrst expression is a letrec-syntax form in the second. Base library 57 are the keyword s. the identiﬁer is not involved in the matching and is not considered a pattern variable or literal identiﬁer. constant..) An ellipsis is the identiﬁer “.) pattern . namely. Pattern variables match arbitrary input subforms and are used to refer to elements of the input. ... All other identiﬁers appearing within a pattern are pattern variables. The form s of a letrec-syntax form are treated... . The following example highlights how let-syntax and letrec-syntax diﬀer. Implementation responsibilities: The implementation should detect if the value of expression cannot possibly be a transformer. Macro transformers (syntax-rules ( literal . . Each binding of a keyword has the bindings as well as the form s within its region. see section 11. Thus deﬁnitions in the result of expanding the form s have the same region as any deﬁnition appearing in place of the letrec-syntax form would have. or an ellipsis ( . pattern ) . pattern ellipsis pattern ... It is a syntax violation if an ellipsis or underscore appears in ( literal .11... an identiﬁer that is not a pattern variable. . .” (three periods). ).) ... the macro use is transcribed hygienically according to the template. pattern ellipsis pattern .) . ) syntax rule . . . . beginning with the leftmost syntax rule . )... or one of the following.. pattern ellipsis pattern .. Semantics: An instance of syntax-rules evaluates..19. a nonempty pattern in one of four parenthesized forms below whose ﬁrst subform is an identiﬁer or an underscore .. at macro-expansion time. ). or one of the following. .7. a pattern datum.. .

and whose remaining n − m elements match Pm+1 through Pn . . This allows syntactic abstractions to expand into forms containing ellipses. • P is of the form (P1 . whose next m − k elements each match Pe . Pk Pe ellipsis Pm+1 .. (Otherwise.. . where ellipsis is the identiﬁer . . . . The subtemplate must contain at least one pattern variable from a subpattern followed by an ellipsis.. • P is a literal identiﬁer and F is an identiﬁer such that both P and F would refer to the same binding if both were to appear in the output of the macro outside of any bindings inserted into the output of the macro. and whose nth and ﬁnal cdr matches Px .. whose next m−k elements each match Pe . A template of the form ( ellipsis template ) is identical to template . =⇒ 4 As an example for hygienic use of auxiliary identiﬁer. which the macro transformer treats as a syntactic keyword.58 Revised6 Scheme • P is a pattern datum (any nonlist. In particular. Px ) and F is a list or improper list of n or more elements whose ﬁrst n elements match P1 through Pn and whose nth cdr matches Px . • P is of the form (P1 .. Pattern data and identiﬁers that are not pattern variables or ellipses are copied into the output. whose next m − k elements each match Pe . . and F is a vector of n or more elements whose ﬁrst k elements match P1 through Pk . distributed as speciﬁed. • P is of the form #(P1 .. More formally.. These pattern variables are replaced in the output by the input subforms to which they are bound. Pn . Pn ). . A subtemplate followed by an ellipsis expands into zero or more occurrences of the subtemplate. • P is of the form (P1 . . whose next n − m elements match Pm+1 through Pn . pattern variables that occur in the template are replaced by the subforms they match in the input. (let ((=> #f)) (cond (#t => ’ok))) =⇒ ok The macro transformer for cond recognizes => as a local variable.. . and not as the identiﬁer =>. (If neither of two like-named identiﬁers refers to any binding. any ellipses contained within template are treated as ordinary identiﬁers.. nonsymbol datum) and F is equal to P in the sense of the equal? procedure... Pn ) and F is a vector of n elements that match P1 through Pn . if let and cond are deﬁned as in section 11. • P is a pattern variable. an input form F matches a pattern P if and only if one of the following holds: • P is an underscore ( ). . .. and hence an expression. .) It is a syntax violation if the constraints of this paragraph are not met..4. . . and whose remaining n−m elements match Pm+1 through Pn . the subtemplate must be followed by exactly as many ellipses as the subpattern in which the pattern variable appears.. Pattern variables that occur in subpatterns followed by one or more ellipses may occur only in subtemplates that are followed by (at least) as many ellipses. . where ellipsis is the identiﬁer .e. A subpattern followed by an ellipsis can match zero or more elements of the input. Pn ) and F is a list of n elements that match P1 through Pn . . . nonvector. except that ellipses within the template have no special meaning. Px ).. • P is of the form #(P1 . . Multiple underscores may appear in a pattern . Pn ). A literal identiﬁer matches an input subform if and only if the input subform is an identiﬁer and either both its occurrence in the input expression and its occurrence in the list of literals have the same lexical binding. both are undeﬁned.. . .) • P is of the form (P1 .... Thus the example expands into . Pk Pe ellipsis Pm+1 . That is. When a macro use is transcribed according to the template of the matching syntax rule .6 and appendix B then they are hygienic (as required) and the following is not an error. . where ellipsis is the identiﬁer . or the two identiﬁers have the same name and both have no lexical binding. and F is a list of n elements whose ﬁrst k elements match P1 through Pk .. (define-syntax be-like-begin (syntax-rules () ((be-like-begin name) (define-syntax name (syntax-rules () ((name expr (. Pk Pe ellipsis Pm+1 .) produces a single ellipsis. and F is a list or improper list of n elements whose ﬁrst k elements match P1 through Pk . i. . the expander would not be able to determine how many times the subform should be repeated in the output. If a pattern variable is followed by more ellipses in the subtemplate than in the associated subpattern.)) (begin expr (. and for at least one such pattern variable. the input form is replicated as necessary. the template (..)))))))) (be-like-begin sequence) (sequence 1 2 3 4) Underscores also match arbitrary input subforms but are not pattern variables and so cannot be used to refer to those elements.. Pn . they are considered to refer to the same binding.

car =⇒ 15 p =⇒ (15 5) A cond clause is ( test tail sequence ). deﬁnition * tail sequence . (define p (cons 4 5)) (define-syntax p. Tail contexts are deﬁned inductively. (if expression (if expression tail expression tail expression ) tail expression ) (cond cond clause + ) (cond cond clause * (else tail sequence )) (case expression case clause + ) (case expression case clause * (else tail sequence )) (and expression * tail expression ) (or expression * tail expression ) (let bindings tail body ) (let variable bindings tail body ) (let* bindings tail body ) (letrec* bindings tail body ) (letrec bindings tail body ) (let-values mv-bindings tail body ) (let*-values mv-bindings tail body ) (let-syntax bindings tail body ) (letrec-syntax bindings tail body ) (begin tail sequence ) The second. The template s must be as for syntax-rules. and a tail sequence is expression * tail expression . In this case. more general. and has a clause of the form ( expression1 => expression2 ) then the (implied) call to the procedure that results from the evaluation of expression2 is in a tail context. (define p (cons 4 5)) (define-syntax p. Semantics: When a keyword is bound to a transformer produced by the ﬁrst form of identifier-syntax. Tail calls and tail contexts A tail call is a procedure call that occurs in a tail context. .car 15) p. Only those rules that contain tail contexts are shown here. uses of the identiﬁer by itself are replaced by template1 . (identifier-syntax template ) syntax (expand) (identifier-syntax syntax (expand) ( id1 template1 ) ((set! id2 pattern ) template2 )) set! auxiliary syntax (expand) Syntax: The id s must be identiﬁers. a case clause is (( datum *) tail sequence ). Expression2 itself is not in a tail context. • The last expression within the body of a lambda expression. and uses of set! with the identiﬁer are replaced by template2 . a tail body is 11. • If a cond expression is in a tail context. Note that a tail context is always determined with respect to a particular lambda expression. references to the keyword within the scope of the binding are replaced by template .car (identifier-syntax (car p))) p. then the subexpressions shown as tail expression are in a tail context.car 15) =⇒ &syntax exception • If one of the following expressions is in a tail context. shown as tail expression below. Base library 59 (let ((=> #f)) (if #t (begin => ’ok))) (lambda formals deﬁnition * expression * tail expression ) instead of (let ((=> #f)) (let ((temp #t)) (if temp (’ok temp)))) which would result in an assertion violation. These were derived from speciﬁcations of the syntax of the forms described in this chapter by replacing some occurrences of expression with tail expression .20.car =⇒ 4 (set! p. form of identifier-syntax permits the transformer to determine what happens when set! is used.car (identifier-syntax ( (car p)) ((set! e) (set-car! p e)))) (set! p.11. occurs in a tail context.

because in that case the eﬀect of the let is explicitly unspeciﬁed and implementation-dependent.) .60 Revised6 Scheme Certain built-in procedures must also perform tail calls. can be evaluated as though they were tail calls. None of the calls to g or h are tail calls. The reference to x is in a tail context. In the following example the only tail call is the call to f. must be called via a tail call. In the example above. (The possibility of h returning an unexpected number of values can be ignored. (lambda () (if (g) (let ((x (h))) x) (and (g) (f)))) Note: Implementations may recognize that some non-tail calls. the let expression could be compiled as a tail call to h. but it is not a call and thus is not a tail call. such as the call to h above. The ﬁrst argument passed to apply and to call-withcurrent-continuation. and the second argument passed to call-with-values.

the side-condition in the above rule indicates that the number of x1 s must be the same as the number of v1 s. the rule only applies when the corresponding terms are structurally identical (nonterminals without subscripts are not constrained to match each other). when we do it merely means simple term equality. Roughly. We say that a term e decomposes into an evaluation context E and another term e if e is the same as E but with the hole replaced by e . system may wish to consult Felleisen and Flatt’s monograph [10] or Wright and Felleisen [29] for a thorough introduction. The precise deﬁnitions of P. All of the reduction rules and the metafunctions shown in the ﬁgures in this semantics were generated automatically from the source code.e.12. expressions (e). so it applies only when some term produced by that grammar appears in the corresponding position in the term. To help understand the semantics and how it behaves. namely terms with a distinguished place in them. For example. The precise speciﬁcation of how to replace those rules is given in section A. i.1. Formal semantics This appendix presents a non-normative. R. or an introduction to PLT Redex [19] for a somewhat lighter one. assuming that the reduction relation → has been adjusted to replace the unknown: states. The core of the speciﬁcation is a single-step term rewriting relation that indicates how an (abstract) machine behaves. As a simple example. we deﬁne the operational semantics of a language via a relation on program terms. The precise list of features included is given in section A. Readers unfamiliar with this . giving implementations freedom to behave diﬀerently. called holes.2. Thus. an implementation conforms to the semantics if. As a rough guide. We use the names of the non-terminals (possibly with subscripts) in a rewriting rule to restrict the application of the rule.org/.. for every program P. and O are also given in section A. The ﬁrst is reduction rules that reduce to special “unknown: string” states (where the string provides a description of the unknown state). We write E[e ] to indicate the term obtained by replacing the hole in E with e . then there is an inﬁnite reduction sequence starting at P. where the relation corresponds to a single step of an abstract machine. Formal semantics 61 APPENDICES Appendix A.2. typically to allow optimizations. we write side-conditions in parentheses beside a rule. and values (v). the occurrence of E1 on both the left-hand and right-hand side of the rule above means that the context of the application expression does not change when using this rule. If the same non-terminal with an identical subscript appears multiple times. Background We assume the reader has a basic familiarity with contextsensitive reduction semantics. variables (x). the report is not a complete speciﬁcation. like procedure and pairs. and the numerical tower. I/O. and returns a special tag for more complex values. assuming that we have deﬁned a grammar containing non-terminals for evaluation contexts (E). Accordingly we use the transitive closure of the single step relation →∗ to deﬁne the semantics. as a function from programs (P) to sets of observable results (R): S : P −→ 2R S(P) = {O(A) | P →∗ A} where the function O turns an answer (A) from the semantics into an observable result. The intention is that rules that reduce to such states can be replaced with arbitrary reduction rules. meaning that zero or more occurrences of terms matching the pattern proceeding the ellipsis may appear in place of the the ellipsis and the pattern preceding it. The notable missing features are the macro system. in this case it means that each x1 is replaced with the corresponding v1 in e1 . we can add another rule that signals a violation when a procedure is applied to the wrong number of arguments by discarding the evaluation context on the A. It does not cover the entire language. each corresponding to a legal transition that an abstract machine might take. if the implementation loops forever. we would write: E1 [((lambda (x1 · · · ) e1 ) v1 · · · )] → E1 [{x1 · · · → v1 · · ·}e1 ] (#x1 = #v1 ) to deﬁne the βv rewriting rule (as a part of the → single step relation). the two terms must have the same syntactic shape. The implementation is available at the report’s website: http://www.r6rs. operational semantics for Scheme. The ellipses are a form of Kleene star. Sometimes we use equality in the side-conditions. The relation is deﬁned using evaluation contexts. that is based on an earlier semantics [18]. This underspeciﬁcation shows up in two ways in the semantics. O is the identity function on simple base values. In general. S. formal. The other is that the single-step relation relates one program to multiple diﬀerent programs. the implementation produces one of the results in S(P) or. Finally. we have implemented it in PLT Redex. We use the notation {x1 · · · → v1 · · ·}e1 for capture-avoiding substitution. So.Appendix A. including the relevant technical background. A. where the next step of evaluation occurs. Making the evaluation context E explicit in the rule allows us to deﬁne relations that manipulate their context.

or a tag indicating an uncaught exception was raised. and Rv ) and literals are written in a monospaced font. and the third is used to indicate a place where the model does not completely specify the behavior of the primitives it models (see section A.62 Revised6 Scheme P A R Rv sf es f s seq sqv p e ::= ::= ::= ::= ::= ::= | | | | ::= ::= ::= ::= ::= ::= | | | ::= ::= ::= ::= ::= ::= ::= ::= (store (sf · · · ) es) | uncaught exception: v | unknown: description (store (sf · · · ) (values v · · · )) | uncaught exception: v | unknown: description (values Rv · · · ) | exception | unknown pair | null | sym | sqv | condition | procedure (x v ) | (x bh) | (pp (cons v v )) seq | sqv | () | (begin es es · · · ) (begin0 es es · · · ) | (es es · · · ) | (if es es es) | (set! x es) | x | nonproc pproc | (lambda f es es · · · ) | (letrec ((x es) · · · ) es es · · · ) (letrec* ((x es) · · · ) es es · · · ) | (dw x es es es) | (throw x es) unspecified | (handlers es · · · es) | (l! x es) | (reinit x ) (x · · · ) | (x x · · · dot x ) | x seq | () | sqv | sym (s s · · · ) | (s s · · · dot sqv ) | (s s · · · dot sym) n | #t | #f (store (sf · · · ) e) (begin e e · · · ) | (begin0 e e · · · ) | (e e · · · ) | (if e e e) | (set! x e) (handlers e · · · e) | x | nonproc | proc | (dw x e e e) | unspecified (letrec ((x e) · · · ) e e · · · ) | (letrec* ((x e) · · · ) e e · · · ) (l! x es) | (reinit x ) nonproc | proc pp | null | sym | sqv | (make-cond string) (lambda f e e · · · ) | pproc | (throw x e) aproc | proc1 | proc2 | list | dynamic-wind | apply | values null? | pair? | car | cdr | call/cc | procedure? | condition? | raise* cons | consi | set-car! | set-cdr! | eqv? | call-with-values | with-exception-handler + | . The R and Rv non-terminals specify the observable results of a program.2.2a: Grammar for programs and observables right-hand side of a rule: E[((lambda (x1 · · · ) e) v1 · · · )] → violation: wrong argument count (#x1 = #v1 ) Later we take advantage of the explicit evaluation context in more sophisticated ways.12 for details of those situations). A.| / | * raise-continuable | raise v nonproc proc pproc proc1 proc2 aproc raise* pp ip mp sym x n ::= ip | mp ::= [immutable pair pointers] ::= [mutable pair pointers] ::= [variables except dot] ::= [variables except dot and keywords] ::= [numbers] Figure A. Non-terminals are written in italics or in a calligraphic font (P A. The ﬁrst alternative is a program with a store and an expression. Grammar Figure A. The second alternative is an uncaught exception. The P non-terminal represents possible program states.2a shows the grammar for the subset of the report this semantics models. It is just like P except that expression has been reduced to some sequence of values. Each R is either a sequence of values that correspond to the values produced by the program that terminates normally. The A non-terminal represents a ﬁnal result of a program. or unknown if the program encoun- . R.

in order to avoid meta-circular confusion in our PLT Redex model. if expressions. a selfquoting value (#t.Appendix A. or a procedure. It is explained in more detail along with the rules that manipulate it. rather than P to P. The last few expression forms are only generated for in1 begin0 is not part of the standard. the empty list. (The dot is used instead of a period for procedures that accept an arbitrary number of arguments. non-procedure values (nonproc). Finally the self-quoting values are numbers and the booleans #t and #f. #f. it can be deﬁned in terms of other forms we model here that do come from the standard: termediate states (dw for dynamic-wind. Although we model it directly. or symbols. The sf non-terminal generates individual elements of the store. The p non-terminal represents programs that have no quoted data. letrec and letrec* expressions. handlers for exception handlers. variables. begin expressions. (begin0 e1 e2 · · · ) = (call-with-values (lambda () e1 ) (lambda x e2 · · · (apply values x))) . application expressions. which can be either non-empty sequences (seq). lambda expressions. or they are terminated with a dot followed by either a symbol or a self-quoting value. The Rv non-terminal speciﬁes what the observable results are for a particular value: a pair. e represents expressions that have no quoted expressions. Expressions (es) include quoted data. and l! and reinit for letrec). selfquoting values (sqv ). and should not appear in an initial program. a symbol. The f non-terminal describes the formals for lambda expressions. Formal semantics 63 P E E E◦ F ::= (store (sf · · · ) E ) ::= F [(handlers proc · · · E )] | F [(dw x e E e)] | F ::= [ ] | E ::= [ ]◦ | E ::= | | | ::= ::= ::= [ ] | (v · · · F ◦ v · · · ) (begin0 F e e · · · ) | (begin0 unspecified F (l! x F ◦ ) [] | F [ ]◦ | F (v · · · [ ] v · · · ) | (if | (if F ◦ e e) | (set! x F ◦ ) | (begin F e e · · · ) (begin0 (values v · · · ) F e · · · ) e · · · ) | (call-with-values (lambda () F e · · · ) v ) F F◦ U PG G H S [ ] e e) | (set! x [ ]) | (call-with-values (lambda () [ ]) v ) ::= (store (sf · · · ) G) ::= F [(dw x e G e)] | F ::= F [(handlers proc · · · H )] | F ::= | | | | | | | [ ] | (begin e e · · · S es · · · ) | (begin S es · · · ) | (begin0 e e · · · S es · · · ) (begin0 S es · · · ) | (e · · · S es · · · ) | (if S es es) | (if e S es) | (if e e S ) (set! x S ) | (handlers s · · · S es · · · es) | (handlers s · · · S ) | (throw x e) (lambda f S es · · · ) | (lambda f e e · · · S es · · · ) (letrec ((x e) · · · (x S ) (x es) · · · ) es es · · · ) (letrec ((x e) · · · ) S es · · · ) | (letrec ((x e) · · · ) e e · · · S es · · · ) (letrec* ((x e) · · · (x S ) (x es) · · · ) es es · · · ) (letrec* ((x e) · · · ) S es · · · ) | (letrec* ((x e) · · · ) e e · · · S es · · · ) Figure A. Their use is described in the relevant sections of this appendix. but we include it to make the rules for dynamic-wind and letrec easier to read. primitive procedures (pproc).2b: Grammar for evaluation contexts ters a situation the semantics does not cover. the empty sequence. set! expressions. Non-empty sequences are either just a sequence of datums. unspecified for the result of the assignment operators. and numbers). In parallel to es. begin0 expressions1 . a condition.) The s non-terminal covers all datums. Most of the reduction rules rewrite p to p. The store holds all of the mutable state of a program. since quoted data is ﬁrst rewritten into calls to the list construction functions before ordinary evaluation proceeds. throw for continuations.

The set of non-terminals for evaluation contexts is shown in ﬁgure A. and numbers respectively. the variables x are assumed not to include any keywords or primitive operations.2b. The E and F evaluation contexts are for expressions. procedure?. – as well as list. and with-exception-handler. dynamic-wind. and call-with-values. and sym are all assumed to all be disjoint. mp. and conditions. – procedures of two arguments (proc2 ): cons. raise. which are divided into immutable pairs (ip) and mutable pairs (mp). condition?. x . cdr. self-quoting values (sqv ). but here just contain a message and are otherwise inert.3: Quote The values (v) are divided into four categories: • Non-procedures (nonproc) include pair pointers (pp). and *. continuations are represented as throw expressions whose body consists of the context where the continuation was grabbed. -. /. the empty list (null). and n represent symbols. – procedures of one argument (proc1 ): null?. Conditions represent the report’s condition values. eqv?. set-car!. car. pair?. values. variables.2a represent pairs (pp). Additionally. The ﬁnal set of non-terminals in ﬁgure A. The P non-terminal controls where evaluation happens in a program that does not contain any quoted data. • Finally. apply. sym.2a. set-cdr!. The non-terminals ip. call/cc. symbols.64 Revised6 Scheme (store (sf 1 · · · ) S 1 [ sqv 1 ])→ (store (sf 1 · · · ) S 1 [sqv 1 ]) (store (sf 1 · · · ) S 1 [ ()])→ (store (sf 1 · · · ) S 1 [null]) (store (sf 1 · · · ) S 1 [ seq 1 ])→ (store (sf 1 · · · ) ((lambda (qp) S 1 [qp]) Qi seq 1 )) (store (sf 1 · · · ) S 1 [ seq 1 ])→ (store (sf 1 · · · ) ((lambda (qp) S 1 [qp]) Qm seq 1 )) [6sqv] [6eseq] [6qcons] (qp fresh) [6qconsi] (qp fresh) Qi Qi Qi Qi Qi Qi Qi Qi Qi : seq → e () (s 1 s 2 · · · ) (s 1 dot sqv 1 ) (s 1 s 2 s 3 · · · dot sqv 1 ) (s 1 dot sym 1 ) (s 1 s 2 s 3 · · · dot sym 1 ) sym 1 sqv 1 : seq → e () (s 1 s 2 · · · ) (s 1 dot sqv 1 ) (s 1 s 2 s 3 · · · dot sqv 1 ) (s 1 dot sym 1 ) (s 1 s 2 s 3 · · · dot sym 1 ) sym 1 sqv 1 = = = = = = = = null (cons (cons (cons (cons (cons sym1 sqv 1 Qi Qi Qi Qi Qi s1 s1 s1 s1 s1 Qi (s 2 · · · ) ) sqv 1 ) Qi (s 2 s 3 · · · dot sqv 1 ) ) sym 1 ) Qi (s 2 s 3 · · · dot sym 1 ) ) Qm Qm Qm Qm Qm Qm Qm Qm Qm = = = = = = = = null (consi (consi (consi (consi (consi sym1 sqv 1 Qm Qm Qm Qm Qm s1 s1 s1 s1 s1 Qm (s 2 · · · ) ) sqv 1 ) Qm (s 2 s 3 · · · dot sqv 1 ) ) sym 1 ) Qm (s 2 s 3 · · · dot sym 1 ) ) Figure A. They are factored in that manner so that the . unspecified?. • User procedures ((lambda f e e · · ·)) include multiarity lambda expressions and lambda expressions with dotted parameter lists. so any program variables whose names coincide with them must be renamed before the semantics can give the meaning of that program. The next three set of non-terminals in ﬁgure A. and raise-continuable. • Primitive procedures (pproc) include – arithmetic procedures (aproc): +.

if no values were produced. we use these two functions: O:A→R O (store (sf · · · ) (values v1 · · · )) = (values Ov v1 · · · ) O uncaught exception: v = exception O unknown: description = unknown A.4: Multiple values and call-with-values PG. Formal semantics 65 P 1 [v1 ] → P 1 [(values v1 )] P 1 [(values v1 )]◦ → P 1 [v1 ] P 1 [(call-with-values (lambda () (values v2 · · · )) v1 )]→ P 1 [(v1 v2 · · · )] P 1 [(call-with-values v1 v2 )]→ P 1 [(call-with-values (lambda () (v1 )) v2 )] [6promote] [6demote] [6cwvd] [6cwvw] (v1 = (lambda () e)) Figure A. a quoted expression may be lifted out into a sequence of cons expressions. These rules apply before any other because of the contexts in which they. or that the program reached a state that is not speciﬁed by the semantics. meaning that if one rule applies to a term. this rule applies once for each quoted expression in the program. The U context is used to manage the report’s underspeciﬁcation of the results of set!. ensuring that these rules convert all quoted data into lists before those rules apply. Accordingly. which create mutable pairs. Ov Ov Ov Ov Ov Ov Ov : v → Rv pp 1 null sym1 sqv 1 (make-cond string) proc = = = = = = pair null sym1 sqv 1 condition procedure They eliminate the store. and set-cdr! (see section A. and replace complex values with simple tags that indicate only the kind of value that was produced or. The rest of the rules apply in contexts that do not contain any quoted expressions.3. and H evaluation contexts can re-use F and have ﬁne-grained control over the context to support exceptions and dynamic-wind. Multiple values The basic strategy for multiple values is to add a rule that demotes (values v) to v and another rule that promotes v to (values v).Appendix A. and turn the datums into calls to either cons or consi. or into a sequence of consi expressions. and all of the other rules. and F ◦ dictate where a single value is promoted to multiple values and where multiple values are demoted to a single value. indicates that either an uncaught exception was raised. F . Although the identiﬁer qp does not have a subscript. Finally. In particular. The ﬁrst two rules erase the quote for quoted expressions that do not introduce any pairs. apply. via the metafunctions Qi and Qm . The precise use of the evaluation contexts is explained along with the relevant rules. set-car!. Figure A.3 that eliminate quoted expressions. A. To convert the answers (A) of the semantics into observable results.12 for details). Quote The ﬁrst reduction rules that apply to any program is the rules in ﬁgure A. the S context is where quoted expressions can be simpliﬁed. so does the other rule. E .7 for the rules on how that happens). Accordingly. which create immutable pairs (see section A. as long as all of the subexpressions to the left have no quoted expressions in them. The last two rules lift quoted datums to the top of the expression so they are evaluated only once. these rule applies in the S context. E ◦ . moving out to the beginning of the program.4. the semantics of PLT Redex’s “fresh” declaration takes special care to ensures that the qp on the right-hand side of the rule is indeed the same as the one in the side-condition. G.2b shows that the S context allows this reduction to apply in any subexpression of an e. If we allowed these rules to apply in an . although expressions to the right may have quoted expressions. Note that the left-hand side of the [6qcons] and [6qconsi] rules are identical. The starred and circled variants.

the semantics allows demotion only in a context expecting a single value and allows promotion only in a context expecting multiple values. F can be (if F ◦ e e) meaning that demotion from (values v) to v can occur in the test of an if expression. the rule [6promote] only applies in [ ] contexts. So.5: Exceptions arbitrary evaluation context. the promotion and demotion rules simplify the deﬁnitions of the other rules. the rule for if does not need to consider multiple values in its ﬁrst subexpression. Accordingly. we would get inﬁnite reduction sequences of endless alternation between promotion and demotion. however. The evaluation contexts for call-with-values (in the F non-terminal) allow evaluation in the body of a . the rule for begin does not need to consider the case of a single value as its ﬁrst subexpression. except that they allow promotion to multiple values and demotion to a single value. and [6demote] only applies in [ ]◦ contexts. and the context-matching syntax may also demand a hole of a particular name (also written with a subscript. For instance. In general. for instance E[e] ). The F and F ◦ evaluation contexts are just the same as F . So. The other two rules in ﬁgure A.4 handle call-withvalues. and structure the grammar of contexts accordingly. To exploit this extension. To see how the evaluation contexts are organized to ensure that promotion and demotion occur in the right places. F can be (begin F e e · · · ) meaning that v can be promoted to (values v) in the ﬁrst subexpression of a begin. Similarly. respectively.66 Revised6 Scheme PG[(raise* v1 )]→ uncaught exception: v1 P [(handlers G[(raise* v1 )])]→ uncaught exception: v1 PG 1 [(with-exception-handler proc 1 proc 2 )]→ PG 1 [(handlers proc 1 (proc 2 ))] P 1 [(handlers proc 1 · · · G 1 [(with-exception-handler proc 2 proc 3 )])]→ P 1 [(handlers proc 1 · · · G 1 [(handlers proc 1 · · · proc 2 (proc 3 ))])] P 1 [(handlers proc 1 · · · G 1 [(with-exception-handler v1 v2 )])]→ P 1 [(handlers proc 1 · · · G 1 [(raise (make-cond “with-exception-handler expects procs”))])] P 1 [(handlers proc 1 · · · proc 2 G 1 [(raise-continuable v1 )])]→ P 1 [(handlers proc 1 · · · proc 2 G 1 [(handlers proc 1 · · · (proc 2 v1 ))])] P 1 [(handlers proc 1 · · · proc 2 G 1 [(raise v1 )])]→ P 1 [(handlers proc 1 · · · proc 2 G 1 [(handlers proc 1 · · · (begin (proc 2 v1 ) (raise (make-cond “handler returned”))))])] P 1 [(condition? (make-cond string))]→ P 1 [#t] P 1 [(condition? v1 )]→ P 1 [#f] (v1 = (make-cond string)) P 1 [(handlers proc 1 · · · (values v1 · · · ))]→ P 1 [(values v1 · · · )] PG 1 [(with-exception-handler v1 v2 )]→ PG 1 [(raise (make-cond “with-exception-handler expects procs”))] (v1 ∈ proc or v2 ∈ proc) [6xunee] [6xuneh] [6xwh1] [6xwhn] [6xwhne] (v1 ∈ proc or v2 ∈ proc) [6xrc] [6xr] [6ct] [6cf] [6xdone] [6weherr] Figure A.2b. We obtain this behavior with a small extension to the Felleisen-Hieb framework (also present in the operational model for R5 RS [17]). The extension allows us to give diﬀerent names to the holes in which multiple values are expected and those in which single values are expected. The ordinary hole [ ] appears where the usual kinds of evaluation can occur. For example. The hole [ ] appears in contexts that allow multiple values and [ ]◦ appears in contexts that expect a single value. exploits F and F ◦ to dictate where promotion and demotion can occur. Similarly. we use three kinds of holes in the evaluation context grammar in ﬁgure A. We extend the notation so that holes have names (written with a subscript). the F evaluation context. consider the F . rather than being deﬁned in terms of itself. F and F ◦ evaluation contexts.

5. n 2 · · ·} ] → P 1 [(/ 1 n 1 )] → P 1 [ n1 /Π{n 2 . . . as long as the second argument has been reduced to a value. The rule [6xuneh] also signals an uncaught exception. this exception cannot be caught. via the rule [6cwvd].n 1 )] P 1 [(. Exceptions The workhorses for the exception system are (handlers proc · · · e) expressions and the G and PG evaluation contexts (shown in ﬁgure A.t. consider the left-hand side of the [6xunee] rule in ﬁgure A. n 2 · · ·} ] → P 1[ − n 1 ] → P 1 [ n1 − Σ{n 2 . The intention is that only the nearest enclosing handlers expression is relevant to raised exceptions. . and the exception system rules take advantage of that context to ﬁnd the closest enclosing handler. To see how the contexts work together with handler expressions. but it covers the case where a handlers expression has exhausted all of the handlers available to it. and the entire call-with-values expression reduces to an application of its second argument to those values. The handlers expression records the active exception handlers (proc · · ·) in some expression (e). it will produce multiple values (since it is an F position). They are just like their counterparts E and P . except that handlers expressions cannot occur on the path to the hole.6: Arithmetic and basic forms procedure that has been passed as the ﬁrst argument to call-with-values.5.n 1 n 2 n 3 · · · )] P 1 [(-)] P 1 [(*)] P 1 [(* n 1 n 2 · · · )] P 1 [(/ n 1 )] P 1 [(/ n 1 n 2 n 3 · · · )] → P 1 [0] → P 1 [ Σ{n 1 . The rule applies to expressions that have a handlers expression (with no exception handlers) in an arbitrary evalua- A.Appendix A.}) [6+0] [6+] [6u-] [6-] [6-arity] [6*1] [6*] [6u/] [6/] [6/0] [6/arity] [6ae] P 1 [(/ n n · · · 0 n · · · )] → P 1 [(raise (make-cond “divison by zero”))] P 1 [(/)] P 1 [(aproc v1 · · · )] → P 1 [(raise (make-cond “arity mismatch”))] → P 1 [(raise (make-cond “arith-op applied to non-number”))] (∃v ∈ v1 · · · s. so this expression reduces to a ﬁnal state indicating the uncaught exception. v is not a number) → P 1 [e 1 ] (v1 = #f) → P 1 [e 2 ] → P 1 [(begin e 1 e 2 · · · )] → P 1 [e 1 ] P 1 [(if v1 e 1 e 2 )] P 1 [(if #f e 1 e 2 )] P 1 [(begin (values v · · · ) e 1 e 2 · · · )] P 1 [(begin e 1 )] [6if3t] [6if3f] [6beginc] [6begind] [6begin0n] [6begin01] P 1 [(begin0 (values v1 · · · ) (values v2 · · · ) e 2 · · · )] → P 1 [(begin0 (values v1 · · · ) e 2 · · · )] P 1 [(begin0 e 1 )] → P 1 [e 1 ] Figure A. Since the PG context does not contain any handlers expressions. n 3 . n 3 · · ·} ] → P 1 [(raise (make-cond “arity mismatch”))] → P 1 [1] → P 1 [ Π{n 1 . n 3 · · ·} ] (0 ∈ {n 2 . Formal semantics 67 P 1 [(+)] P 1 [(+ n 1 n 2 · · · )] P 1 [(. in the case that the ﬁrst argument to call-with-values is a value. but is not of the form (lambda () e). the rule [6cwvw] wraps it in a thunk to trigger evaluation. .2b). Finally. Once evaluation inside that procedure completes. and the G and PG evaluation contexts help achieve that goal. It matches expressions that have a call to raise or raise-continuable (the non-terminal raise* matches both exception-raising procedures) in a PG evaluation context.

invokes the second argument to with-exception-handlers. The use of the G evaluation context ensures that there are no other handler expressions between this one and the raise.68 Revised6 Scheme P 1 [(list v1 v2 · · · )]→ P 1 [(cons v1 (list v2 · · · ))] P 1 [(list)]→ P 1 [null] (store (sf 1 · · · ) E 1 [(cons v1 v2 )])→ (store (sf 1 · · · (mp (cons v1 v2 ))) E 1 [mp]) (store (sf 1 · · · ) E 1 [(consi v1 v2 )])→ (store (sf 1 · · · (ip (cons v1 v2 ))) E 1 [ip]) (mp fresh) [6listc] [6listn] [6cons] [6consi] (ip fresh) [6car] [6cdr] [6setcar] [6setcdr] [6null?t] [6null?f] [6pair?t] [6pair?f] [6care] (v i ∈ pp) [6cdre] (v i ∈ pp) [6scare] (v1 ∈ mp) [6scdre] (v1 ∈ mp) (store (sf 1 · · · (pp i (cons v1 v2 )) sf 2 · · · ) E 1 [(car pp i )])→ (store (sf 1 · · · (pp i (cons v1 v2 )) sf 2 · · · ) E 1 [v1 ]) (store (sf 1 · · · (pp i (cons v1 v2 )) sf 2 · · · ) E 1 [(cdr pp i )])→ (store (sf 1 · · · (pp i (cons v1 v2 )) sf 2 · · · ) E 1 [v2 ]) (store (sf 1 · · · (mp 1 (cons v1 v2 )) sf 2 · · · ) E 1 [(set-car! mp 1 v 3 )])→ (store (sf 1 · · · (mp 1 (cons v 3 v2 )) sf 2 · · · ) E 1 [unspecified]) (store (sf 1 · · · (mp 1 (cons v1 v2 )) sf 2 · · · ) E 1 [(set-cdr! mp 1 v 3 )])→ (store (sf 1 · · · (mp 1 (cons v1 v 3 )) sf 2 · · · ) E 1 [unspecified]) P 1 [(null? null)]→ P 1 [#t] P 1 [(null? v1 )]→ P 1 [#f] (v1 = null) P 1 [(pair? pp)]→ P 1 [#t] P 1 [(pair? v1 )]→ P 1 [#f] (v1 ∈ pp) P 1 [(car v i )]→ P 1 [(raise (make-cond “can’t take car of non-pair”))] P 1 [(cdr v i )]→ P 1 [(raise (make-cond “can’t take cdr of non-pair”))] P 1 [(set-car! v1 v2 )]→ P 1 [(raise (make-cond “can’t set-car! on a non-pair or an immutable pair”))] P 1 [(set-cdr! v1 v2 )]→ P 1 [(raise (make-cond “can’t set-cdr! on a non-pair or an immutable pair”))] Figure A. If there already is a handler expression. except it raises a new exception if the handler returns.7: Lists tion context where a call to one of the exception-raising functions is nested in the handlers expression. It collects the current handlers and adds the new one into a new handlers expression and. The next two rules cover exceptions that are raised in the context of a handlers expression. The new exception is created with the make-cond special form. If a continuable exception is raised. but in a context where the exception handlers do not include that latest handler. The next two rules cover call to the procedure with-exception-handler. It does not evaluate its argument (note its ab- . The make-cond special form is a stand-in for the report’s conditions. It constructs a new one and applies v 2 as a thunk in the handler body. The [6xwh1] rule applies when there are no handler expressions. [6xrc] applies. as with the previous rule. It takes the most recently installed handler from the nearest enclosing handlers expression and applies it to the argument to raise-continuable. the [6xwhn] applies. The [6xr] rule behaves similarly.

Formal semantics 69 P 1 [(eqv? v1 v1 )]→ P 1 [#t] (v1 ∈ proc. and the rule [6weherr] raises an exception when with-exception-handler is supplied with incorrect arguments. the rule [6xdone] drops a handlers expression when its body is fully evaluated.2a). The begin evaluation contexts allow evaluation in the ﬁrst subexpression of a begin. at which point the [begin01] rule ﬁres. The next two rules. Once that is a value.2b). whose semantics are given by the two rules [6ct] and [6cf]. an exception is raised. the rules reduce an if expression to its consequent if the test is not #f. The [6cons] uses a mp variable. subtraction. Arithmetic and basic forms This model does not include the report’s arithmetic. . v1 = (make-cond string)) [6eqt] P 1 [(eqv? v1 v2 )]→ [6eqf] P 1 [#f] (v1 = v2 . and begin0. The ﬁrst says that when the two arguments to eqv? are syntactically identical. That argument is just a literal string describing the context in which the exception was raised. to indicate the pair is mutable. or when division receives a zero as a divisor. The next four rules handle the null? predicate and the pair? predicate.Appendix A. The evaluation contexts for if only allow evaluation in its test expression. and the [6consi] uses a ip variable to indicate the pair is immutable. and to its alternative if it is #f.3 for a description of “fresh”). as shown in ﬁgure A. In that case. and division. there is only a single expression in the begin0. The rules [6car] and [6cdr] extract the components of a pair from the store when presented with a pair pointer (the pp can be either mp or ip.8. bound to a fresh pair pointer (see also section A. the begin itself is dropped. Like the begin evaluation contexts. A. The ﬁrst two rules handle list by reducing it to a succession of calls to cons. The ﬁrst two rules cover most of the behavior of eqv?. the begin0 evaluation contexts allow evaluation of the ﬁrst subexpression of a The rules in ﬁgure A. once the ﬁrst expression has been fully simpliﬁed. Eqv The rules for eqv? are shown in ﬁgure A. multiplication. begin. but does include an idealized form in order to make experimentation with other features and writing test suites for the model simpler. The [6begin0n] rule for begin0 then drops a fully simpliﬁed second subexpression. They defer to their mathematical analogues. when the subtraction or divison operator are applied to no arguments. set-car! or set-cdr! receive non pairs. cdr. but only if there are two or more subexpressions. [6cons] and [6consi].8: Eqv sence from the E grammar in ﬁgure A. See section A. Finally. A. allocate new cons cells. Figure A. Lists A.6. begin0 expression when there are two or more subexpressions.6 shows the rules for if. Eventually. followed by null. In addition. or when any of the arithmetic operations receive a non-number.6 shows the reduction rules for the primitive procedures that implement addition. If there is only a single subexpression. The relevant evaluation contexts are given by the F non-terminal. and removes the begin0 expression. The begin0 evaluation contexts also allow evaluation in the second subexpression of a begin0 expression. They replace the contents of the appropriate location in the store with the new value. v1 ∈ proc or v2 ∈ proc. The only operation on conditions is condition?.7. and reduce to unspecified.12 for an explanation of how unspecified reduces. the reduction rules drop its value.8. The rules [6setcar] and [6setcdr] handle assignment of mutable pairs. as long as the ﬁrst subexpression has been fully simpliﬁed. The bottom half of ﬁgure A. They both move (cons v1 v2 ) into the store. v1 = (make-cond string) or v2 = (make-cond string)) P 1 [(eqv? (make-cond string) (make-cond string))]→ P 1 [#t] P 1 [(eqv? (make-cond string) (make-cond string))]→ P 1 [#f] [6eqct] [6eqcf] Figure A. and the ﬁnal four rules raise exceptions when car.7 handle lists.

and [6eqcf]) allow such comparisons to return #t or #f. A.12.9a: Procedures & application then eqv? produces #t and the second says that when the arguments are not syntactically identical. the report leaves unspeciﬁed the order in which arguments are evaluated. e i ∈ v . So. one for each possible order of evaluation. #x2 = #v2 . To capture unspeciﬁed evaluation order but allow only evaluation that is consistent with some sequential ordering of the evaluation of an application’s subexpressions. .9. There are two situations where it does not match: comparing two conditions and comparing two procedures. The side-conditions on those ﬁrst two rules ensure that they do not apply when simple term equality does not match the behavior of eqv?. then eqv? produces #f. Comparing two procedures is covered in section A. except to say that it must return a boolean. (lambda (x2 · · · ) e 1 e 2 · · · ) ) [6app0] [6µapp] [6µapp1] [6var] [6set] [6proct] [6procf] [6arity] [6µarity] [6appe] [61arity] P 1 [((lambda (x1 x2 · · · dot x ) e e · · · ) v1 · · · )]→ P 1 [(raise (make-cond “arity mismatch”))] (#v1 < #x2 + 1) P 1 [(nonproc v · · · )]→ P 1 [(raise (make-cond “can’t call non-procedure”))] P 1 [(proc1 v1 · · · )]→ P 1 [(raise (make-cond “arity mismatch”))] P 1 [(proc2 v1 · · · )]→ P 1 [(raise (make-cond “arity mismatch”))] (#v1 = 1) [62arity] (#v1 = 2) Figure A. the report does not specify eqv?’s behavior. V x1 . For example. diﬀerent reductions to occur.70 Revised6 Scheme P 1 [(e 1 · · · e i e i+1 · · · )]→ P 1 [((lambda (x ) (e 1 · · · x e i+1 · · · )) e i )] [6mark] (x fresh. ∃e ∈ e 1 · · · e i+1 · · · s. e ∈ v ) [6appN!] (store (sf 1 · · · ) E 1 [((lambda (x1 x2 · · · ) e 1 e 2 · · · ) v1 v2 · · · )])→ (store (sf 1 · · · (bp v1 )) E 1 [({x1 → bp}(lambda (x2 · · · ) e 1 e 2 · · · ) v2 · · · )]) (bp fresh. pairs are represented as pointers into the store and eqv? only compares those pointers.t. (lambda (x2 · · · ) e 1 e 2 · · · ) ) P 1 [((lambda (x1 x2 · · · ) e 1 e 2 · · · ) v1 v2 · · · )]→ P 1 [({x1 → v1 }(lambda (x2 · · · ) e 1 e 2 · · · ) v2 · · · )] P 1 [((lambda () e 1 e 2 · · · ))]→ P 1 [(begin e 1 e 2 · · · )] P 1 [((lambda (x1 x2 · · · dot x r ) e 1 e 2 · · · ) v1 v2 · · · v 3 · · · )]→ P 1 [((lambda (x1 x2 · · · x r ) e 1 e 2 · · · ) v1 v2 · · · (list v 3 · · · ))] P 1 [((lambda x1 e 1 e 2 · · · ) v1 · · · )]→ P 1 [((lambda (x1 ) e 1 e 2 · · · ) (list v1 · · · ))] (store (sf 1 · · · (x1 v1 ) sf 2 · · · ) E 1 [x1 ])→ (store (sf 1 · · · (x1 v1 ) sf 2 · · · ) E 1 [v1 ]) (store (sf 1 · · · (x1 v1 ) sf 2 · · · ) E 1 [(set! x1 v2 )])→ (store (sf 1 · · · (x1 v2 ) sf 2 · · · ) E 1 [unspecified]) P 1 [(procedure? proc)]→ P 1 [#t] P 1 [(procedure? nonproc)]→ P 1 [#f] P 1 [((lambda (x1 · · · ) e e · · · ) v1 · · · )]→ P 1 [(raise (make-cond “arity mismatch”))] (#x1 = #v1 ) (#x2 = #v2 ) [6appN] (#x2 = #v2 . The structure of v has been carefully designed so that simple term equality corresponds closely to eqv?’s behavior. ¬V x1 . Procedures and application In evaluating a procedure call. so the remaining two rules ([6eqct]. For the ﬁrst. our reduction system allows multiple.

It such an application into an application of an ordinary procedure by constructing a list of the extra arguments. (begin e 1 e 2 · · · ) and x1 = x2 x1 .9b to ensure that there are no set! expressions with the parameter x1 as a target. e 2 or V x1 . covers the case where the last argument to apply is the empty list. e 1 x1 . it creates a new location in the store. At ﬁrst glance.Appendix A. The rule [6µapp] handles a well-formed application of a function with a dotted parameter lists. Once all of the parameters have been substituted away. (set! x2 e 1 ) x1 . and substitutes a variable standing for that location in place of the formal parameter. [6applyc] covers a wellformed application of apply where apply’s ﬁnal argument is a pair. (if e 1 e 2 e 3 ) x1 . The second reason is more technical: the [6mark] rule requires that [6appN] be applied once e i has been reduced to a value. e 3 x1 . the rule [6mark] picks one of the subexpressions of an application that is not fully simpliﬁed and lifts it out in its own application. To achieve that effect. To evaluate application expressions that have more than two arguments to evaluate. (begin e 1 e 2 · · · ) x1 . The next four cover applying a non-procedure. then. (begin e 1 e 2 · · · ) x1 . e 1 or V x1 . (letrec ((x2 e 1 ) · · · ) e 2 e 3 · · · ) x1 . The ﬁrst one covers the case where apply is supplied with a cyclic list. Its sidecondition uses the relation in ﬁgure A. [6appN!] would lift the value into the store and put a variable reference into the application. (lambda (x2 · · · dot x 3 ) e 1 e 2 · · · ) x1 . (begin e 2 e 3 · · · ) x1 . (begin e 1 e 2 · · · ) and x1 ∈ {x2 · · ·} x1 . e 1 or V x1 . (letrec* ((x2 e 1 ) · · · ) e 2 e 3 · · · ) x1 .9c cover apply.9b: Variable-assignment relation we use non-deterministic choice to ﬁrst pick a subexpression to reduce only when we have not already committed to reducing some other subexpression. (begin e 1 e 2 · · · ) and x1 ∈ {x2 · · · x 3 } x1 . . e 1 or V x1 . (begin e 1 ) x1 . The store. the rule [6appN] appears superﬂuous. The rules in ﬁgure A. The ﬁrst is purely conventional: reducing applications via substitution is taught to us at an early age and is commonly used in rewriting systems in the literature. The rule [6var] handles variable lookup in the store and [6set] handles variable assignment. the [6appN] substitutes its value back into the original application. which continues forever. The remaining ﬁve rules cover the various violations that can occur when using apply. e 1 and x1 = x2 x1 . (begin0 e 1 e 2 · · · ) x1 . Once one of the lifted expressions is evaluated. leading to another use of [6mark]. allowing it to be evaluated. we limit the evaluation of application expressions to only those that have a single expression that is not fully reduced. the [6appN!] rule applies (see also section A. (set! x2 e 1 ) x1 . (set! x2 e 1 ) x1 .2b. (e 1 e 2 · · · ) x1 . [6applyf]. Instead of directly substituting the actual parameter for the formal parameter. (lambda x2 e 1 e 2 · · · ) x1 .3 for a description of “fresh”). the rule [6µapp1] handles an application of a procedure that has a single variable as its parameter list. (dw x2 e 1 e 2 e 3 ) if if if if if if if if if if if if if if if x1 V V V V V V V V V V V V V V = x2 x1 . e 2 or V x1 . Formal semantics 71 V V V V V V V V V V V V V V V V ∈ 2x ×e x1 . passing a non-list as the last argument. in ﬁgure A. The second rule. and simply reduces by erasing the empty list and the apply. If there is such an assignment. and supplying too few arguments to apply. (l! x2 e 1 ) x1 . Similarly. The next two rules [6proct] and [6procf] handle applications of procedure?. and another use of [6appN!]. The [6appN] rule also handles other applications whose arguments are ﬁnished by substituting the ﬁrst argument for the ﬁrst formal parameter in the expression. (reinit x2 e 1 ) x1 . e 3 Figure A. Repeated application of this rule thus extracts all of the list elements passed to apply out of the store. (begin e 1 e 2 e 3 · · · ) x1 . The ﬁrst rule. There are two reasons why we keep the [6appN]. (set! x2 e 1 ) x1 . It reduces by extracting the components of the pair from the store and putting them into the application of apply. (begin e 1 · · · e 2 e 3 · · · ) and x1 ∈ {x2 · · ·} x1 . (lambda (x2 · · · ) e 1 e 2 · · · ) x1 . initially bound the actual parameter. handles any eventual assignment to the parameter. however. since it seems like the rules could just reduce ﬁrst by [6appN!] and then look up the variable when it is evaluated. (begin e 1 · · · e 2 e 3 · · · ) and x1 ∈ {x2 · · ·} x1 . and the remaining rules cover applications of non-procedures and arity violations. the rule [6app0] applies and evaluation of the body of the procedure begins. as shown in the non-terminal F .

wraps them with a call to values. and after procedures from a call to dynamic-wind.10. third. a context that contains everything except dw expressions. Call/cc and dynamic wind The speciﬁcation of dynamic-wind uses (dw x e e e) expressions to record which dynamic-wind thunk s are active at each point in the computation. the destination context. as shown in rule [6wind] in ﬁgure A. They each construct new contexts and exploit H to work through their arguments. pp 2 . thunk .10. Evaluation only occurs in the middle expression.72 Revised6 Scheme P 1 [(apply proc 1 v1 · · · null)]→ P 1 [(proc 1 v1 · · · )] (store (sf 1 · · · (pp 1 (cons v2 v 3 )) sf 2 · · · ) E 1 [(apply proc 1 v1 · · · pp 1 )])→ (store (sf 1 · · · (pp 1 (cons v2 v 3 )) sf 2 · · · ) E 1 [(apply proc 1 v1 · · · v2 v 3 )]) (¬C pp 1 . and fourth arguments are calls to some before.10 and puts their results together into a begin expression. one dw at a time. In each case. It ensures that shared parts of the dynamic-wind context are ignored. and puts them back into the place where the original call to call/cc occurred. The [6dwdone] rule erases a dw expression when its second argument has ﬁnished evaluating. v 3 . replacing the current context with the context returned by the T metafunction. The R metafunction extracts all of the before procedures from its argument and the S metafunction extracts all of the after procedures from its argument. The ﬁrst clause of the T metafunction exploits the H context. the reduction rule for an application of dynamic-wind reduces to a call to the before procedure. the metafunctions are careful to keep the right dw context around each of . (sf 1 · · · (pp 2 (cons v1 v2 )) sf 2 · · · ) C pp 1 . That rule takes the arguments of the continuation. The throw expression uses the fresh variable x to record where the application of call/cc occurred in the context for use in the [6throw] rule when the continuation is applied. it only applies when all the others fail and thus applies either when there are no dws in the context. The second. It takes the context of the call/cc expression and packages it up into a throw expression that represents the continuation. The T (for “trim”) metafunction accepts two D contexts and builds a context that matches its second argument. (sf 1 · · · (pp 2 (cons v1 v2 )) sf 2 · · · ) and pp 1 = v2 Figure A. Its ﬁrst argument is an identiﬁer that is globally unique and serves to identify invocations of dynamic-wind. (sf 1 · · · (pp 2 (cons v1 v2 )) sf 2 · · · ) (v2 ∈ list-v ) [6apparity0] [6apparity1] [6applynf] [6applye] if pp 1 = v2 if C pp 1 . (sf 1 · · · (pp 1 (cons v2 v 3 )) sf 2 · · · ) ) P 1 [(apply nonproc v · · · )]→ P 1 [(raise (make-cond “can’t apply non-procedure”))] P 1 [(apply proc v1 · · · v2 )]→ P 1 [(raise (make-cond “apply’s last argument non-list”))] P 1 [(apply)]→ P 1 [(raise (make-cond “arity mismatch”))] P 1 [(apply v )]→ P 1 [(raise (make-cond “arity mismatch”))] C ∈ 2pp ×val ×(sf ···) C pp 1 . The next two rules cover call/cc. or when the dw expressions do not match. (sf 1 · · · (pp 1 (cons v2 v 3 )) sf 2 · · · ) ) [6applyf] [6applyc] (store (sf 1 · · · (pp 1 (cons v2 v 3 )) sf 2 · · · ) E 1 [(apply proc 1 v1 · · · pp 1 )])→ [6applyce] (store (sf 1 · · · (pp 1 (cons v2 v 3 )) sf 2 · · · ) E 1 [(raise (make-cond “apply called on circular list”))]) (C pp 1 . The ﬁnal rule is a catchall. pp 2 . The rule [6call/cc] creates a new continuation. v 3 . Accordingly. the dw expression only serves to record which before and after procedures need to be run during a continuation switch. v2 . It calls the two other metafunctions deﬁned in ﬁgure A. The next two rules cover abuses of the dynamic-wind procedure: calling it with non-procedures.9c: Apply A. recurring deeper into the two expression contexts as long as the ﬁrst dw expression in each have matching identiﬁers (x1 ). a dw expression and a call to the after procedure. and calling it with the wrong number of arguments. except that additional calls to the before and after procedures from dw expressions in the context have been added. in order to avoid exiting and re-entering the same dynamic context during a continuation switch.

E 2 [(values v1 · · · )]) T :E ×E →E T H 1 [(dw x1 e 1 E 1 e 2 )]. then reinit either just does nothing. A reinit expression is used to detect a program that captures a continuation in an initialization expression and returns to it.Appendix A.11. it changes it to #t. receives the destination context. as shown in the three rules [6init]. Formal semantics 73 P 1 [(dynamic-wind proc 1 proc 2 proc 3 )]→ P 1 [(begin (proc 1 ) (begin0 (dw x (proc 1 ) (proc 2 ) (proc 3 )) (proc 3 )))] P 1 [(dynamic-wind v1 v2 v 3 )]→ P 1 [(raise (make-cond “dynamic-wind expects procs”))] P 1 [(dynamic-wind v1 · · · )]→ P 1 [(raise (make-cond “arity mismatch”))] P 1 [(dw x e (values v1 · · · ) e)]→ P 1 [(values v1 · · · )] (store (sf 1 · · · ) E 1 [(call/cc v1 )])→ (store (sf 1 · · · ) E 1 [(v1 (throw x E 1 [x ]))]) (x fresh) (#v1 = 3) [6wind] (x fresh) [6winde] (v1 ∈ proc or v2 ∈ proc or v 3 ∈ proc) [6dwarity] [6dwdone] [6call/cc] [6throw] (store (sf 1 · · · ) E 1 [((throw x1 E 2 [x1 ]) v1 · · · )])→ (store (sf 1 · · · ) T E 1 . evaluating the init expressions.10: Call/cc and dynamic wind the procedures in case a continuation jump occurs during one of their evaluations. in keeping with the two legal behaviors of letrec and letrec*. and [6reinite]. The report speciﬁes that either an implementation should perform the assignment.11 shows the rules that handle letrec and letrec* and the supplementary expressions that they produce. since that was the context where the call to the continuation occurred. much like set!. As a ﬁrst approximation. If it is already #t. as reﬂected in the [6setdte] rule. H 2 [(dw x1 e 3 E 2 e 4 )] T E 1. The next two rules cover ordinary set! when applied to a variable that is currently bound to a black hole. or it raises an exception. eg (letrec ((x (set! x 5))) x). The ﬁrst two rules in ﬁgure A. The reinit form accepts an identiﬁer that is bound in the store to a boolean as its argument. The [6dt] rule covers the case where a variable is referred to before the value of a init expression is ﬁlled in. ﬁrst consider how l! and reinit behave. as reﬂected in the [6setdt] rule or it raise an exception. but it initializes both ordinary variables. and then using l! to update the locations in the store with the value of the init expressions. When reinit is evaluated. it checks the value of the variable and. Before considering how letrec and letrec* use l! and reinit. They also use reinit to detect when an init expression in a letrec is reentered via a continuation.11 cover l!. and variables that are current bound to the black hole (bh). initializing those locations to bh (for “black hole”). both letrec and letrec* reduce by allocating locations in the store to hold the values of the init expressions. l! and reinit. if it is still #f. This situation can arise when the program assigns to a variable before letrec initializes it. which must always raise an exception. it keeps the intermediate parts of the context in its result. E 2 R:E →E R H 1 [(dw x1 e 1 E 1 e 2 )] R H1 S :E →E S E 1 [(dw x1 e 1 H 2 e 2 )] S H1 = = H 2 [(dw x1 e 3 T E 1 . A. In contrast S discards all of the context except the dws. [6reinit]. Letrec Figre A. Those are identiﬁers are initially #f. Since R. It behaves very . E 2 e 4 )] (begin S E 1 [1] R E 2 ) (otherwise) H 1 [(begin e 1 (dw x1 e 1 R E 1 e 2 ))] H1 (otherwise) S E 1 [(begin0 (dw x1 e 1 [ ] e 2 ) e 2 )] [] (otherwise) = = = = Figure A.

as long as they follow the informal speciﬁcation. Each init expression is wrapped in a begin0 that records the value of the init and then uses reinit to detect continuations that return to the init expression. See ﬁgure A.12 cover the results from the assignment operations. the procedure on the right-hand side of the rule is invoked. each init expression is ﬁlled into the store as it is evaluated. the remaining rules just specify the minimal behavior that we know that a value or values must have and otherwise reduce to an unknown: state. Once all of the init expressions have been evaluated. ri · · · fresh) Figure A. and evaluation continues with the body of the original letrec expression.12 cover aspects of the semantics that are explicitly unspeciﬁed. but intuitively it is a context that is only a single expression layer deep that contains expressions whose value depends on the value of their subexpressions.2b for the precise deﬁnition of U. The rule [6udemand] drops unspecified in the U context. [6uval] and with diﬀerent rules that cover the left-hand sides and.11: Letrec and letrec* The last two rules in ﬁgure A. [6setcdr]. but instead renders them useless by adjusting the rules that insert unspecified: [6setcar]. Following that are rules that discard unspecified in expressions A. like the ﬁrst subexpression of a if. set!. An implementation does not adjust those rules. ri · · · fresh) [6initdt] [6initv] [6setdt] [6setdte] [6dt] [6init] [6reinit] [6reinite] [6letrec] (store (sf 1 · · · ) E 1 [(letrec* ((x1 e 1 ) · · · ) e 2 e 3 · · · )])→ [6letrec*] (store (sf 1 · · · (lx bh) · · · (ri #f) · · · ) E 1 [{x1 → lx · · ·}(begin (begin (l! lx e 1 ) (reinit ri)) · · · e 2 e 3 · · · )]) (lx · · · fresh. The [6letrec] rule reduces a letrec expression to an application expression. causing the value of the init expression to be ﬁlled in the store. rules [6ueqv]. So. [6set]. but uses a begin expression rather than an application. Implementations can replace the .74 Revised6 Scheme (store (sf 1 · · · (x1 bh) sf 2 · · · ) E 1 [(l! x1 v2 )])→ (store (sf 1 · · · (x1 v2 ) sf 2 · · · ) E 1 [unspecified]) (store (sf 1 · · · (x1 v1 ) sf 2 · · · ) E 1 [(l! x1 v2 )])→ (store (sf 1 · · · (x1 v2 ) sf 2 · · · ) E 1 [unspecified]) (store (sf 1 · · · (x1 bh) sf 2 · · · ) E 1 [(set! x1 v1 )])→ (store (sf 1 · · · (x1 v1 ) sf 2 · · · ) E 1 [unspecified]) (store (sf 1 · · · (x1 bh) sf 2 · · · ) E 1 [(set! x1 v1 )])→ (store (sf 1 · · · (x1 bh) sf 2 · · · ) E 1 [(raise (make-cond “letrec variable touched”))]) (store (sf 1 · · · (x1 bh) sf 2 · · · ) E 1 [x1 ])→ (store (sf 1 · · · (x1 bh) sf 2 · · · ) E 1 [(raise (make-cond “letrec variable touched”))]) (store (sf 1 · · · (x1 #f) sf 2 · · · ) E 1 [(reinit x1 )])→ (store (sf 1 · · · (x1 #t) sf 2 · · · ) E 1 [ ignore]) (store (sf 1 · · · (x1 #t) sf 2 · · · ) E 1 [(reinit x1 )])→ (store (sf 1 · · · (x1 #t) sf 2 · · · ) E 1 [ ignore]) (store (sf 1 · · · (x1 #t) sf 2 · · · ) E 1 [(reinit x1 )])→ (store (sf 1 · · · (x1 #t) sf 2 · · · ) E 1 [(raise (make-cond “reinvoked continuation of letrec init”))]) (store (sf 1 · · · ) E 1 [(letrec ((x1 e 1 ) · · · ) e 2 e 3 · · · )])→ (store (sf 1 · · · (lx bh) · · · (ri #f) · · · ) E 1 [((lambda (x1 · · · ) (l! lx x1 ) · · · {x1 → lx · · ·}e 2 {x1 → lx · · ·}e 3 · · · ) (begin0 {x1 → lx · · ·}e 1 (reinit ri)) · · · )]) (lx · · · fresh. any replacement is valid. Underspeciﬁcation The rules in ﬁgure A. and [6setd]. set-car!. and set-cdr!. since the init expressions are evaluated from left to right. so that subsequent init expressions can refer to its value.12. Moreover. Those rules can be adjusted by replacing unspecified with any number of values in those rules.11 put together l! and reinit. The remaining rules in ﬁgure A. in order to capture the unspeciﬁed order of evaluation of the init expressions. Those three situations correspond to the case when eqv? applied to two procedures and when multiple values are used in a singlevalue context. The [6letrec*] rule behaves similarly.

) res1b res2b .)) ((cond (test => result)) (let ((temp test)) (if temp (result temp)))) ((cond (test => result) clause1 clause2 .)) (if test (begin result1 result2 ......... since they also return any number of values to their context. [6uhandlers] and [6udw] propagate unspecified to their context...) res1a res2a . The next two rules.... cond......Appendix B.) ..) ((memv tmp ’(keyb .5) could be deﬁned in terms of if..)) res1a res2a .) .) res1 res2 ..)) res1 res2 . Finally...)))) ((cond (test result1 result2 ... Sample deﬁnitions for derived forms 75 P [(eqv? proc proc)] P [(values v1 · · · )]◦ P [U [unspecified]] (store (sf · · · ) unspecified) P 1 [(begin unspecified e 1 e 2 · · · )] P 1 [(handlers v · · · unspecified)] P 1 [(dw x e unspecified e)] → unknown: equivalence of procedures → unknown: context expected one value. (else else-res1 else-res2 ........ The [6ubegin] shows how begin discards its ﬁrst expression when there are more expressions to evaluate..) (let ((tmp expr0)) (cond ((memv tmp ’(keya ..)) res1b res2b ...5) could be deﬁned in terms of let.4.))))) This appendix contains sample deﬁnitions for some of the keywords described in this report in terms of simpler forms: cond The cond keyword (section 11... the two begin0 rules preserve unspecified until the rule [6begin01] can return it to its context......) (cond clause1 clause2 ..) ..) (if test (begin result1 result2 .)) (begin result1 result2 ..)))) ((cond (test)) test) ((cond (test) clause1 clause2 . received #v1 (#v1 = 1) → unknown: unspeciﬁed result → unknown: unspeciﬁed result → P 1 [(begin e 1 e 2 · · · )] → P 1 [unspecified] → P 1 [unspecified] [6ueqv] [6uval] [6udemand] [6udemandtl] [6ubegin] [6uhandlers] [6udw] [6ubegin0] [6ubegin0u] [6ubegin0uu] P 1 [(begin0 (values v1 · · · ) unspecified e 1 · · · )] → P 1 [(begin0 (values v1 · · · ) e 1 · · · )] P 1 [(begin0 unspecified (values v2 · · · ) e 2 · · · )] → P 1 [(begin0 unspecified e 2 · · · )] P 1 [(begin0 unspecified unspecified e 2 · · · )] → P 1 [(begin0 unspecified e 2 · · · )] Figure A.) (let ((temp test)) ..) (let ((temp test)) (if temp (result temp) (cond clause1 clause2 ...) ((keyb ....12: Explicitly unspeciﬁed behavior that discard the results of some of their subexpressions.. (else else-res1 else-res2 .))) ((cond (test result1 result2 .)))) ((case expr0 ((keya .) .. rived forms Sample deﬁnitions for decase The case keyword (section 11..))))) Appendix B..4.... (if temp temp (cond clause1 clause2 . let and begin using syntax-rules as follows: (define-syntax cond (syntax-rules (else =>) ((cond (else result1 result2 .)) (let ((tmp expr0)) (cond ((memv tmp ’(key .. and memv (see library chapter 3) using syntax-rules as follows: (define-syntax case (syntax-rules (else) ((case expr0 ((key .) clause1 clause2 .

...)) ((let-values assocs ((formals1 expr1) (formals2 expr2) .) () body1 body2 ...) (let ((id temp) ...))))) letrec The letrec keyword (section 11......)))) The syntax <undefined> is as in the deﬁnition of letrec above.) (let-values-helper2 formals1 () expr1 assocs ((formals2 expr2) .) body1 body2 ... letrec* The letrec* keyword could be deﬁned approximately in terms of let and set! using syntax-rules as follows: (define-syntax letrec* (syntax-rules () ((letrec* ((var1 init1) ..) (letrec-helper (y .....) (let () body1 body2 .6) could be deﬁned approximately in terms of let and set! using syntax-rules.) body1 body2 . (let () body1 body2 .) (let () body1 body2 ... as follows: (define-syntax letrec (syntax-rules () ((letrec () body1 body2 .)))) (define-syntax let-values-helper2 ..) body1 body2 .) body1 body2 ..) (let ((temp init) ..) A simpler deﬁnition using syntax-case and generatetemporaries is given in library chapter 12. map over the bindings (syntax-rules () ((let-values ((id temp) ... causes an exception with condition type &assertion to be raised if .6) using syntax-rules employs a pair of helpers to create temporary names for the formals........) body1 body2 ..))))) let* The let* keyword (section 11....) body1 body2 .) (let () body1 body2 ........) (let-values-helper1 () (binding .) (set! var1 init1) .)) ((let* ((name1 expr1) (name2 expr2) .. let-values The following deﬁnition of let-values (section 11.....76 Revised6 Scheme an attempt to read from or write to the location occurs before the assignments generated by the letrec transformation take place..) (let ((name1 expr1)) (let* ((name2 expr2) ... create temporaries for the formals (syntax-rules () The syntax <undefined> represents an expression that returns something that...4...4..) body1 body2 ..... using a helper to generate the temporary variables needed to hold the values before the assignments are made.))) ((letrec-helper (x y . (No such expression is deﬁned in Scheme.) ((var init) .) body1 body2 . (define-syntax let-values (syntax-rules () ((let-values (binding .) ((var init) ...) ((var init) .) (let ((var <undefined>) .) body1 body2 .....)))) (define-syntax letrec-helper (syntax-rules () ((letrec-helper () (temp ...) body1 body2 ...)) ((letrec ((var init) .) (letrec-helper (var ....) () ((var init) ....)))) (define-syntax let-values-helper1 ..) body1 body2 .) body1 body2 . when stored in a location.) body1 body2 ....) (let ((var1 <undefined>) .4...6) could be deﬁned in terms of let using syntax-rules as follows: (define-syntax let* (syntax-rules () ((let* () body1 body2 ......) (temp ..) (newtemp temp ..) (set! var temp) ...

..r6rs.) (call-with-values (lambda () expr1) (lambda (temp . (first newtemp)) bindings body1 body2 .)))))) let The let keyword could be deﬁned in terms of lambda and letrec using syntax-rules as follows: (define-syntax let (syntax-rules () ((let ((name val) .....))) tag) val . . n let*-values of diﬀerential equations with the method of Runge-Kutta. which provides an integrate-system procedure that integrates the system yk = fk (y1 . programs... implementations... . .. y2 .) val .) ((lambda (name ...) body1 body2 ..)))) Appendix C. (rest-formal newtemp)) bindings body1 body2 .. newtemp) (let-values-helper1 (assoc .....) bindings body1 body2 . ..) (call-with-values (lambda () expr1) (lambda temp-formals (let-values-helper1 assocs bindings body1 body2 .schemers.. Additional material This report itself... ....) expr1 (assoc .) (let () body1 body2 .. rest) (temp .) bindings body1 body2 . ..) body1 body2 .org/ The Schemers web site at http://www.))))) As the (runge-kutta) library makes use of the (rnrs base (6)) library. k = 1. yn )....) body1 body2 .. and other material related to Scheme.org/ contain extensive Scheme bibliographies...readscheme...org/ as well as the Readscheme site at http://library.) body1 body2 .) body1 body2 . ....... as well as papers. Example This section describes an example consisting of the (runge-kutta) library..) (let-values (binding1) (let*-values (binding2 . ...)) ((let tag ((name val) .Appendix C. . Additional material 77 ((let-values-helper2 () temp-formals expr1 assocs bindings body1 body2 .)))) ((let-values-helper2 (first ...)) ((let*-values (binding1 binding2 ..) body1 body2 .. as well as more material related to this report such as reference implementations of some parts of Scheme and archives of mailing lists discussing this report is at http://www..)) ((let-values-helper2 rest-formal (temp . The following macro deﬁnes let*-values in terms of let and let-values using syntax-rules: (define-syntax let*-values (syntax-rules () ((let*-values () body1 body2 .) ((letrec ((tag (lambda (name .) (let-values-helper2 rest (temp .... . Appendix D...) expr1 (assoc ...... newtemp) expr1 (assoc . its skeleton is as follows: #!r6rs (library (runge-kutta) (export integrate-system head tail) (import (rnrs base)) library body ) The procedure deﬁnitions described below go in the place of library body .

01)) (letrec ((loop (lambda (s) (newline) (write (head s)) (loop (tail s))))) (loop the-states)) v i)) (define generate-vector (lambda (size proc) (let ((ans (make-vector size))) (letrec ((loop (lambda (i) (cond ((= i size) ans) (else (vector-set! ans i (proc i)) (loop (+ i 1))))))) This prints output like the following: . . . (define runge-kutta-4 (lambda (f h) (let ((*h (scale-vector h)) (*2 (scale-vector 2)) (*1/2 (scale-vector (/ 1 2))) (*1/6 (scale-vector (/ 1 6)))) (lambda (y) .. The runge-kutta-4 procedure produces a function that takes a system state and produces a new system state. .001) ’#(1 0) . . . #!r6rs (import (rnrs base) (rnrs io simple) (runge-kutta)) (define damped-oscillator (lambda (R L C) (lambda (state) (let ((Vc (vector-ref state 0)) (Il (vector-ref state 1))) (vector (. The parameter initial-state provides an initial system state. y is a system state (let* ((k0 (*h (f y))) (k1 (*h (f (add-vectors y (*1/2 k0))))) (k2 (*h (f (add-vectors y (*1/2 k1))))) (k3 (*h (f (add-vectors y k2))))) (add-vectors y (*1/6 (add-vectors k0 (*2 k1) (*2 k2) k3)))))))) (define elementwise (lambda (f) (lambda vectors (generate-vector (vector-length (car vectors)) (lambda (i) (apply f (map (lambda (v) (vector-ref vectors))))))) Inﬁnite streams are implemented as pairs whose car holds the ﬁrst element of the stream and whose cdr holds a procedure that delivers the rest of the stream.0 (+ (/ Vc (* R C)) (/ Il C))) (/ Vc L)))))) (define the-states (integrate-system (damped-oscillator 10000 1000 . f. that produces a system derivative from a system state. The value returned by integrate-system is an inﬁnite stream of system states. .78 Revised6 Scheme (loop 0))))) (define add-vectors (elementwise +)) (define scale-vector (lambda (s) (elementwise (lambda (x) (* x s))))) The parameter system-derivative is a function that takes a system state (a vector of values for the state variables y1 . yn ) and produces a system derivative (the values y1 . (define map-streams (lambda (f s) (cons (f (head s)) (lambda () (map-streams f (tail s)))))) The runge-kutta-4 procedure takes a function. (define head car) (define tail (lambda (stream) ((cdr stream)))) The following program illustrates the use of integratesystem in integrating the system C dvC vC = −iL − dt R L diL = vC dt which models a damped oscillator. and h is an initial guess for the length of the integration step. . (define integrate-system (lambda (system-derivative initial-state h) (let ((next (runge-kutta-4 system-derivative h))) (letrec ((states (cons initial-state (lambda () (map-streams next states))))) states)))) The map-streams procedure is analogous to map: it applies its ﬁrst argument (a procedure) to all the elements of its second argument (a stream). . yn ).

see ﬁgure A. exact. • The semantics of expt for zero bases has been reﬁned.99376684 4. • Characters are now speciﬁed to correspond to Unicode scalar values. and #. #` quasisyntax). • Identiﬁers can now start with the characters ->. assert. Nested quasiquotations work correctly now.9595884e-5) #(0. Speciﬁcally. rational-valued?. string-ci>?.99780226 1. error. many are now speciﬁed in terms of the exception system.99895054 9. must be explicitly delimited. string-ci<?. mod. • Bytevector literal syntax has been added. vector-map.@ unsyntax-splicing have been added. let*-values. let-values. load. div0. string-ci<=?. • String and character literals can now use a variety of escape sequences. • The semantics for the transcendental functions has been speciﬁed more fully.9978681e-5) #(0. integer-valued?. Language changes 79 #(1 0) #(0. • A number of standard libraries are described in a separate report [24].9905868 6. identifier-syntax. number objects. • The base language has the following new procedures and syntactic forms: letrec*. • Identiﬁers and symbol literals are now case-sensitive. • The following procedures have been removed: charready?. div. inexact. • Scheme’s real number objects now have an exact zero as their imaginary part. transcript-off. • For implementations that support NaNs or inﬁnities.94753e-5) • Many of the procedures and syntactic forms of the language are now part of the (rnrs base (6)) library.5. string-ci>=?) operate on the case-folded versions of the strings rather than as the simple lexicographic ordering induced by the corresponding character comparison procedures. #. booleans.9784474e-5) #(0.9952102 3. • In syntax-rules forms. symbol=?. may be used in place of Appendix E. • The external representation of number objects can now include a mantissa width. • The full numerical tower is now required. the character set that can be used for identiﬁers has been greatly expanded. • # is now a delimiter.0 has been speciﬁed consistently with IEEE 754. • Block and datum comments have been added. real-valued?.985443e-5) #(0. nan?. • The #!r6rs comment for marking report-compliant lexical syntax has been added. Some procedures and syntactic forms have been moved to other libraries.Appendix E. div-and-mod. vectorfor-each.) • # can no longer be used in place of digits in number representations. call/cc. and . finite?. • The let-syntax and letrec-syntax no longer introduce a new environment for their bodies. • Identiﬁers and representations of characters. and unquote and unquote-splicing have been extended to several operands. • The (for (for tion read-syntax abbreviations #’ (for syntax). mod0.969862e-5) #(0. In particular. exact-integer-sqrt. see sec4.3. .990946e-5) #(0.9950552e-5) #(0.99222565 5. many arithmetic operations have been speciﬁed on these values consistently with IEEE 754. • Literals for NaNs and inﬁnities were added. • Matched square brackets can be used synonymously with parentheses. div0-and-mod0. assertion-violation.9888506 7. • The case-insensitive string comparisons (stringci=?. • Many situations that “were an error” now have deﬁned or constrained behavior. a the keyword.0. string-for-each. • The speciﬁcation of quasiquote has been extended. boolean=?. infinite?. the semantics of many arithmetic operations with regard to -0. transcript-on. (for unsyntax).994835e-6) #(0. Language changes This chapter describes most of the changes that have been made to Scheme since the “Revised5 Report” [14] was published: • Scheme source code now uses the Unicode character set. • For implementations that support a distinct -0.9870173 8. • Libraries have been added to the language.1.9965554 2.

May 1996. In Proc. • The old notion of program structure and Scheme’s toplevel environment has been replaced by top-level programs and libraries. Utah.1: Identiﬁers moved to libraries • Procedures now may or may not refer to locations. http://www.ietf. 18]. and M. • Various expressions that have only side eﬀects are now allowed to return an arbitrary number of values. Naur. PA. Snowbird. F. Perlis.80 Revised6 Scheme identiﬁer assoc assv assq call-with-input-file call-with-output-file char-upcase char-downcase char-ci=? char-ci<? char-ci>? char-ci<=? char-ci>=? char-alphabetic? char-numeric? char-whitespace? char-upper-case? char-lower-case? close-input-port close-output-port current-input-port current-output-port display do eof-object? eval delay exact->inexact force moved to (rnrs lists (6)) (rnrs lists (6)) (rnrs lists (6)) (rnrs io simple (6)) (rnrs io simple (6)) (rnrs unicode (6)) (rnrs unicode (6)) (rnrs unicode (6)) (rnrs unicode (6)) (rnrs unicode (6)) (rnrs unicode (6)) (rnrs unicode (6)) (rnrs unicode (6)) (rnrs unicode (6)) (rnrs unicode (6)) (rnrs unicode (6)) (rnrs unicode (6)) (rnrs io simple (6)) (rnrs io simple (6)) (rnrs io simple (6)) (rnrs io simple (6)) (rnrs io simple (6)) (rnrs control (6)) (rnrs io simple (6)) (rnrs eval (6)) (rnrs r5rs (6)) (rnrs r5rs (6)) (rnrs r5rs (6)) identiﬁer inexact->exact member memv memq modulo newline null-environment open-input-file open-output-file peek-char quotient read read-char remainder scheme-report-environment set-car! set-cdr! string-ci=? string-ci<? string-ci>? string-ci<=? string-ci>=? string-set! string-fill! with-input-from-file with-output-to-file write write-char moved to (rnrs r5rs (6)) (rnrs lists (6)) (rnrs lists (6)) (rnrs lists (6)) (rnrs r5rs (6)) (rnrs io simple (6)) (rnrs r5rs (6)) (rnrs io simple (6)) (rnrs io simple (6)) (rnrs io simple (6)) (rnrs r5rs (6)) (rnrs io simple (6)) (rnrs io simple (6)) (rnrs r5rs (6)) (rnrs r5rs (6)) (rnrs mutable-pairs (6)) (rnrs mutable-pairs (6)) (rnrs unicode (6)) (rnrs unicode (6)) (rnrs unicode (6)) (rnrs unicode (6)) (rnrs unicode (6)) (rnrs mutable-strings (6)) (rnrs mutable-strings (6)) (rnrs io simple (6)) (rnrs io simple (6)) (rnrs io simple (6)) (rnrs io simple (6)) Figure A. J. [4] Robert G. • The order and semantics for macro expansion has been more fully speciﬁed. Samuelson. of the ACM SIGPLAN ’96 Conference on Programming Language Design and Implementation.L. • The dynamic environment of the before and after procedures of dynamic-wind is now speciﬁed. Katz. A. ACM Press. 1988. H. RFC 2119. Bauer. Proper tail recursion and space eﬃciency. C. Wegstein. [2] Alan Bawden and Jonathan Rees.txt. Vauquois J.org/rfc/ rfc2119. 6(1):1–17. • The denotational semantics has been replaced by an operational semantics based on an earlier semantics for the language of the “Revised5 Report” [14. pages 86–95. Kent Dybvig. Printing ﬂoating-point numbers quickly and accurately. 1963. van Wijngaarden. Communications of the ACM. McCarthy P. Consequently. A. In ACM Conference on Lisp and Functional Programming. • The mutability of the values of quasiquote structures has been speciﬁed to some degree. [5] William Clinger. B. J. In Keith Cooper. K. REFERENCES [1] J. Burger and R. Philadelphia. Syntactic closures. Woodger. Revised report on the algorithmic language Algol 60. Rutishauser. Proceedings of . March 1997. [3] Scott Bradner. eqv? is now unspeciﬁed in a few cases where it was speciﬁed before. pages 108–116. • Internal deﬁnitions are now deﬁned in terms of letrec*. ACM Press. H. J. Key words for use in RFCs to indicate requirement levels.Green. Backus. W. editor. USA.

Indiana University Computer Science Technical Report 153. 1986. R.0 (Boston. org/. and James R. 1987.0. and Bruce Duba. [21] Jonathan A. An operational semantics for R5RS Scheme. 2007. pages 41–54. 15th Conference on Rewriting Techniques and Applications. Information and Computation. Canada. editors. http://www. pages 174–185. seventh edition. pages 155–162. 11(1):7– 105. 2003. Friedman. Addison-Wesley. Anton van Straaten. August 1986. Christopher Haynes. Estonia. http://www. [25] Guy Lewis Steele Jr. Scheme 84 interim reference manual. [23] Michael Sperber. Robert Hieb. and Matthias Felleisen. Springer-Verlag. [24] Michael Sperber. July 2006. In Proc. Orlando. and Anton van Straaten. 1991 ACM SIGPLAN Symposium on Principles of Programming Languages. June 2004. White Plains. [29] Andrew Wright and Matthias Felleisen. Waite and Gerhard Goos. The T manual. From http://www. TI Scheme Language Reference Manual. Adams IV. Matthew Flatt. 2007. Macros that work. Aachen. How to read ﬂoating point numbers accurately. Inc. Meehan. Robert Bruce Findler. 2005. 1998. Rees. November 1985. 2007. ACM. Daniel P.org/doc/352/ html/mzscheme/. Rice University. USA. PLT MzScheme: Language Manual. http://download. Clinger. Revised6 report on the algorithmic language Scheme (Rationale). Indiana University Technical Report TR619. [11] Matthew Flatt. June 1998. [6] William Clinger and Jonathan Rees. [10] Matthias Felleisen and Matthew Flatt.r6rs. Kohlbecker. Michael Ashley and Michael Sperber. January 1984. Yale University Computer Science Department.r6rs. org/journals/JFP/. Digital Press. Indiana University. and Anton van Straaten. In Proc. Syntactic abstraction in Scheme. 1984. Kent Dybvig. and Carl Bruggeman. September 2005. ISBN 0-32148091-0). and Mitchell Wand. 1(1):53–75. [26] Texas Instruments. Revised6 report on the algorithmic language Scheme (Non-Normative appendices). 2007.References the 1998 Conference on Programming Language Design and Implementation. Version 5. Florida. [8] R. Chez Scheme Version 7 User’s Guide. and Jonathan Rees. Preliminary version 1. [18] Jacob Matthews and Robert Bruce Findler. Reprinted in SIGPLAN Notices. Common Lisp: The Language. Rice University. [20] MIT Department of Electrical Engineering and Computer Science. second edition. Richard Kelsey. [7] William D. [28] William M. Burlington. Compiler Construction. January 1985. pages 151–161. IEEE standard for binary ﬂoating-point arithmetic. Hygienic macro expansion. In Proceedings of the 1986 ACM Conference on Lisp and Functional Programming.org/. Matthew Flatt. version 5. University of Utah. Matthew Flatt. [27] The Unicode Consortium. [13] IEEE standard 754-1985. Programming languages and lambda calculi. . ACM Press.cs. Matthew Flatt. 2007. [16] Eugene E. Eugene Kohlbecker. September 1984. First appeared as Technical Report TR160. June 1990. [17] Jacob Matthews and Robert Bruce Findler. William Clinger. MA. Kent Dybvig. http://www. [14] Richard Kelsey. and Jonathan Rees. MA. Kent Dybvig. [9] R. Proceedings of 81 the Sixth Workshop on Scheme and Functional Programming. Kohlbecker Jr. William Clinger. pages 92– 101. ACM Press.utah. 2007. Conference on Programming Language Design and Implementation ’90. 1994. Kent Dybvig. Revised5 report on the algorithmic language Scheme. SpringerVerlag.0. [12] Daniel P. [19] Jacob Matthews. Tallin. Montreal. Scheme manual. Lisp and Symbolic Computation.r6rs.pdf. Syntactic Extensions in the Programming Language Lisp. Cadence Research Systems. Matthias Felleisen. [15] Eugene E. deﬁned by: The Unicode Standard. PhD thesis. In Proc. Revised6 report on the algorithmic language Scheme (Libraries).cambridge. 1991. fourth edition.com/csug7/. An operational semantics for Scheme. http: //www. http://www.scheme. 22(2):9-25. In J. 1990. [22] Michael Sperber. Norman I. 115(1):38–94. A syntactic approach to type soundness. New York. R. org/.0. January 1991.plt-scheme. The Unicode standard. Higher-Order and Symbolic Computation. A visual environment for developing context-sensitive term rewriting systems. Journal of Functional Programming. edu/plt/publications/pllc. Indiana University. R. 1988. Volume 33(5) of SIGPLAN Notices. Kent Dybvig. 1985. Friedman.

82 Revised6 Scheme ALPHABETIC INDEX OF DEFINITIONS OF CONCEPTS.. 75 big-endian 5 (library) binary port 31. 14. 75 begin0 (formal semantics) 67. the entries are marked with “(library)”.@ 17 . 43 + (formal semantics) 67 . 57 / 44 / (formal semantics) 67 .. 47 bound 18 bound-identifier=? 54 (library) buffer-mode 32 (library) buffer-mode? 32 (library) byte 5 (library) bytevector 5 (library) bytevector->sint-list 7 (library) bytevector->string 33 (library) bytevector->u8-list 6 (library) bytevector->uint-list 7 (library) bytevector-copy 6 (library) . 18 binding construct 18 bit ﬁelds 43 (library) bitwise-and 48 (library) bitwise-arithmetic-shift 49 (library) bitwise-arithmetic-shift-left 49 (library) bitwise-arithmetic-shift-right 49 (library) bitwise-bit-count 48 (library) bitwise-bit-field 49 (library) bitwise-bit-set? 49 (library) bitwise-copy-bit 49 (library) bitwise-copy-bit-field 49 (library) bitwise-first-bit-set 49 (library) bitwise-if 48 (library) bitwise-ior 48 (library) bitwise-length 48 (library) bitwise-not 48 (library) bitwise-reverse-bit-field 50 (library) bitwise-rotate-bit-field 49 (library) bitwise-xor 48 (library) body 32 boolean 5 boolean=? 47 boolean? 31.14.@ 17 #\ 14 #| 14 & 23 ’ 17 #’ 17 * 43 * (formal semantics) 67 + 14. 43 . KEYWORDS. 51.0 11 -> 14. 17 #. 23. 15 backquote 55 base record type 15 (library) begin 37 begin (formal semantics) 67.(formal semantics) 67 -0. 14 #. 17 . 32 (library) binary-port? 34 (library) binding 6. 33. 52 (library). 23 . 14 < 42 <= 42 = 42 => 24 (library). ! 23 #. 34 > 42 >= 42 ? 23 51 (library). 57 #‘ 17 ‘ 17 |# 14 abs 44 accessor 15 (library) acos 45 and 34 angle 46 antimark 50 (library) append 48 apply 53 apply (formal semantics) 72 argument checking 18 asin 45 assert 53 &assertion 28 (library) assertion-violation 52 assertion-violation? 28 (library) assignment 7 assoc 12 (library) assp 12 (library) assq 13 (library) assv 13 (library) atan 45 #b 13. AND PROCEDURES The index includes entries from the library document.

50 character 5 Characters 50 close-input-port 42 (library) close-output-port 42 (library) close-port 34 (library) code point 50 codec 32 (library) command-line 43 (library) comment 12. 75 condition 25 (library) &condition 26 (library) condition 26 (library) condition-accessor 26 (library) condition-irritants 28 (library) condition-message 27 (library) condition-predicate 26 (library) condition-who 28 (library) . 58.Index 83 bytevector-copy! 6 (library) bytevector-fill! 6 (library) bytevector-ieee-double-native-ref 9 (library) bytevector-ieee-double-native-set! 9 (library) bytevector-ieee-double-ref 9 (library) bytevector-ieee-single-native-ref 9 (library) bytevector-ieee-single-native-set! 9 (library) bytevector-ieee-single-ref 9 (library) bytevector-length 5 (library) bytevector-s16-native-ref 7 (library) bytevector-s16-native-set! 7 (library) bytevector-s16-ref 7 (library) bytevector-s16-set! 7 (library) bytevector-s32-native-ref 8 (library) bytevector-s32-native-set! 8 (library) bytevector-s32-ref 8 (library) bytevector-s32-set! 8 (library) bytevector-s64-native-ref 8 (library) bytevector-s64-native-set! 8 (library) bytevector-s64-ref 8 (library) bytevector-s64-set! 8 (library) bytevector-s8-ref 6 (library) bytevector-s8-set! 6 (library) bytevector-sint-ref 6 (library) bytevector-sint-set! 6 (library) bytevector-u16-native-ref 7 (library) bytevector-u16-native-set! 7 (library) bytevector-u16-ref 7 (library) bytevector-u16-set! 7 (library) bytevector-u32-native-ref 8 (library) bytevector-u32-native-set! 8 (library) bytevector-u32-ref 8 (library) bytevector-u32-set! 8 (library) bytevector-u64-native-ref 8 (library) bytevector-u64-native-set! 8 (library) bytevector-u64-ref 8 (library) bytevector-u64-set! 8 (library) bytevector-u8-ref 6 (library) bytevector-u8-set! 6 (library) bytevector-uint-ref 6 (library) bytevector-uint-set! 6 (library) bytevector=? 6 (library) bytevector? 5 (library) caar 48 cadr 48 call 28 call by need 64 (library) call-with-bytevector-output-port 39 (library) call-with-current-continuation 53 call-with-input-file 41 (library) call-with-output-file 41 (library) call-with-port 34 (library) call-with-string-output-port 39 (library) call-with-values 54 call-with-values (formal semantics) 65 call/cc 53 call/cc (formal semantics) 73 car 48 car (formal semantics) 68 case 34. 75 case-lambda 15 (library) cdddar 48 cddddr 48 cdr 48 cdr (formal semantics) 68 ceiling 44 char->integer 50 char-alphabetic? 3 (library) char-ci<=? 3 (library) char-ci<? 3 (library) char-ci=? 3 (library) char-ci>=? 3 (library) char-ci>? 3 (library) char-downcase 3 (library) char-foldcase 3 (library) char-general-category 4 (library) char-lower-case? 3 (library) char-numeric? 3 (library) char-title-case? 3 (library) char-titlecase 3 (library) char-upcase 3 (library) char-upper-case? 3 (library) char-whitespace? 3 (library) char<=? 50 char<? 50 char=? 50 char>=? 50 char>? 50 char? 31. 14 complex? 41 compound condition 25 (library) cond 33.

15 else 24 (library). 31 delay 64 (library) delete-file 42 (library) denominator 44 derived form 8 display 42 (library) div 44 div-and-mod 44 div0 44 div0-and-mod0 44 do 14 (library) dot (formal semantics) 70 dw (formal semantics) 73.84 Revised6 Scheme enum-set-intersection 61 (library) enum-set-member? 61 (library) enum-set-projection 61 (library) enum-set-subset? 61 (library) enum-set-union 61 (library) enum-set-universe 60 (library) enum-set=? 61 (library) enumeration 60 (library) enumeration sets 60 (library) enumeration type 60 (library) environment 62 (library) environment 62 (library) eof-object 33 (library). 25 expt 45 external representation 11 #f 14. 53 escape sequence 15 eval 62 (library) even? 43 exact 10. 25 (library) continuation 8 core form 29 cos 45 current exception handler 24 (library) current-error-port 39 (library). 47 false 19 ﬁeld 15 (library) fields 16 (library) ﬁle options 31 (library) file-exists? 42 (library) file-options 31 (library) filter 11 (library) find 10 (library) condition? 26 (library) condition? (formal semantics) 66 cons 47 cons (formal semantics) 68 cons* 13 (library) consi (formal semantics) 68 constant 20 constructor descriptor 21 (library) continuable exception 18. 75 dynamic environment 20 dynamic extent 20 dynamic-wind 53. 54 dynamic-wind (formal semantics) 73 #e 13. 37 exact 42 exact->inexact 63 (library) exact-integer-sqrt 45 exact? 42 exactness 10 exceptional situation 18. 25. 25 (library) exceptions 24 (library) exists 10 (library) exit 43 (library) exp 45 export 23 expression 6. 48 end-of-ﬁle object 33 (library) end-of-line style 32 (library) endianness 5 (library) endianness 5 (library) enum-set->list 61 (library) enum-set-complement 61 (library) enum-set-constructor 60 (library) enum-set-difference 61 (library) enum-set-indexer 60 (library) . 34 empty list 17. 11 datum->syntax 55 (library) define 31 define-condition-type 27 (library) define-enumeration 61 (library) define-record-type 16 (library) define-syntax 31 deﬁnition 6. 33. 41 (library) eof-object? 33 (library). 12 datum value 8. 18. 41 (library) current-input-port 35 (library). 37 eqv? (formal semantics) 69. 75 &error 28 (library) error 52 error-handling-mode 33 (library) error? 28 (library) escape procedure 9. 41 (library) eol-style 32 (library) eq? 38 equal-hash 60 (library) equal? 39 equivalence function 58 (library) equivalence predicate 37 eqv? 20. 47. 41 (library) current-output-port 39 (library). 31. 41 (library) #d 15 datum 11.

44 (library) fx-/carry 44 (library) fx<=? 43 (library) fx<? 43 (library) fx=? 43 (library) fx>=? 43 (library) fx>? 43 (library) fxand 44 (library) fxarithmetic-shift 45 (library) fxarithmetic-shift-left 45 (library) fxarithmetic-shift-right 45 (library) fxbit-count 44 (library) fxbit-field 45 (library) fxbit-set? 45 (library) fxcopy-bit 45 (library) fxcopy-bit-field 45 (library) fxdiv 44 (library) fxdiv-and-mod 44 (library) fxdiv0 44 (library) fxdiv0-and-mod0 44 (library) fxeven? 43 (library) fxfirst-bit-set 45 (library) fxif 44 (library) fxior 44 (library) fxlength 44 (library) fxmax 43 (library) fxmin 43 (library) fxmod 44 (library) fxmod0 44 (library) fxnegative? 43 (library) fxnot 44 (library) fxodd? 43 (library) fxpositive? 43 (library) fxreverse-bit-field 46 (library) fxrotate-bit-field 45 (library) fxxor 44 (library) fxzero? 43 (library) gcd 44 generate-temporaries 56 (library) get-bytevector-all 37 (library) get-bytevector-n 37 (library) get-bytevector-n! 37 (library) get-bytevector-some 37 (library) get-char 37 (library) get-datum 38 (library) get-line 38 (library) .46 (library) fl/ 46 (library) fl<=? 46 (library) fl<? 46 (library) fl=? 46 (library) fl>=? 46 (library) fl>? 46 (library) flabs 47 (library) flacos 47 (library) flasin 47 (library) flatan 47 (library) flceiling 47 (library) flcos 47 (library) fldenominator 47 (library) fldiv 47 (library) fldiv-and-mod 47 (library) fldiv0 47 (library) fldiv0-and-mod0 47 (library) fleven? 46 (library) flexp 47 (library) flexpt 48 (library) flfinite? 46 (library) flfloor 47 (library) flinfinite? 46 (library) flinteger? 46 (library) fllog 47 (library) flmax 46 (library) flmin 46 (library) flmod 47 (library) flmod0 47 (library) flnan? 46 (library) flnegative? 46 (library) flnumerator 47 (library) flodd? 46 (library) ﬂonum 10 flonum? 46 (library) floor 44 flpositive? 46 (library) flround 47 (library) flsin 47 (library) flsqrt 48 (library) fltan 47 (library) fltruncate 47 (library) flush-output-port 38 (library) flzero? 46 (library) fold-left 11 (library) fold-right 11 (library) for-all 10 (library) for-each 49 force 64 (library) form 7.Index 85 finite? 43 ﬁxnum 10 fixnum->flonum 48 (library) fl 23 fl* 46 (library) fl+ 46 (library) fl. 11 free-identifier=? 54 (library) fx 23 fx* 43 (library) fx*/carry 44 (library) fx+ 43 (library) fx+/carry 44 (library) fx.

12. 36. 36 let-syntax 56 let-values 32. 29 lambda 32 lambda (formal semantics) 65. 18 &implementation-restriction 29 (library) implementation-restriction-violation? 29 (library) implicit identiﬁer 55 (library) import 23 import level 26 improper list 47 inexact 10. 37 inexact 42 inexact->exact 63 (library) inexact? 42 infinite? 43 inﬁnity 11 input port 31 (library) input-port? 35 (library) instance 26 instantiation 26 integer object 10 integer->char 50 integer-valued? 41 integer? 41 &irritants 28 (library) irritants-condition? 28 (library) keyword 18. 23 library 23 get-string-all 38 (library) get-string-n 37 (library) get-string-n! 37 (library) get-u8 36 (library) guard 24 (library) hash function 58 (library) hashtable 58 (library) hashtable-clear! 59 (library) hashtable-contains? 59 (library) hashtable-copy 59 (library) hashtable-delete! 59 (library) hashtable-entries 59 (library) hashtable-equivalence-function 59 (library) hashtable-hash-function 60 (library) hashtable-keys 59 (library) hashtable-mutable? 60 (library) hashtable-ref 59 (library) hashtable-set! 59 (library) hashtable-size 59 (library) hashtable-update! 59 (library) hashtable? 59 (library) hole 61 hygienic 29 #i 13. 35. 70 latin-1-codec 32 (library) lazy evaluation 64 (library) lcm 44 length 48 let 32.86 Revised6 Scheme identifier-syntax 59 identifier? 54 (library) if 33 if (formal semantics) 67 imag-part 46 immutable 20 immutable 16 (library) immutable record type 16 (library) implementation restriction 10. 55. 17. 76 letrec* (formal semantics) 74 letrec-syntax 56 level 26 lexeme 12 &lexical 29 (library) lexical-violation? 29 (library) library 9. 15 &i/o 29 (library) &i/o-decoding 32 (library) i/o-decoding-error? 32 (library) &i/o-encoding 32 (library) i/o-encoding-error-char 32 (library) i/o-encoding-error? 32 (library) i/o-error-filename 30 (library) i/o-error-port 30 (library) i/o-error-position 30 (library) i/o-error? 29 (library) &i/o-file-already-exists 30 (library) i/o-file-already-exists-error? 30 (library) &i/o-file-does-not-exist 30 (library) i/o-file-does-not-exist-error? 30 (library) &i/o-file-is-read-only 30 (library) i/o-file-is-read-only-error? 30 (library) &i/o-file-protection 30 (library) i/o-file-protection-error? 30 (library) &i/o-filename 30 (library) i/o-filename-error? 30 (library) &i/o-invalid-position 30 (library) i/o-invalid-position-error? 30 (library) &i/o-port 30 (library) i/o-port-error? 30 (library) &i/o-read 29 (library) i/o-read-error? 29 (library) &i/o-write 30 (library) i/o-write-error? 30 (library) identiﬁer 6. 35. 77 let* 32. 35. 76 let*-values 32. 58. 17 identiﬁer macro 53 (library) . 36 letrec 32. 14. 76 letrec (formal semantics) 74 letrec* 32.

29 macro keyword 29 macro transformer 29. 72 null-environment 64 (library) . 51 (library).Index 87 list 6 list 48 list (formal semantics) 68 list->string 51 list->vector 52 list-ref 48 list-sort 13 (library) list-tail 48 list? 48 literal 28 little-endian 5 (library) location 20 log 45 lookahead-char 37 (library) lookahead-u8 37 (library) macro 8. 56 macro use 29 magnitude 46 make-assertion-violation 28 (library) make-bytevector 5 (library) make-custom-binary-input-port 35 (library) make-custom-binary-input/output-port 41 (library) make-custom-binary-output-port 39 (library) make-custom-textual-input-port 36 (library) make-custom-textual-input/output-port 41 (library) make-custom-textual-output-port 40 (library) make-enumeration 60 (library) make-eq-hashtable 58 (library) make-eqv-hashtable 58 (library) make-error 28 (library) make-hashtable 58 (library) make-i/o-decoding-error 32 (library) make-i/o-encoding-error 32 (library) make-i/o-error 29 (library) make-i/o-file-already-exists-error 30 (library) make-i/o-file-does-not-exist-error 30 (library) make-i/o-file-is-read-only-error 30 (library) make-i/o-file-protection-error 30 (library) make-i/o-filename-error 30 (library) make-i/o-invalid-position-error 30 (library) make-i/o-port-error 30 (library) make-i/o-read-error 29 (library) make-i/o-write-error 30 (library) make-implementation-restriction-violation 29 (library) make-irritants-condition 28 (library) make-lexical-violation 29 (library) make-message-condition 27 (library) make-no-infinities-violation 48 (library) make-no-nans-violation 48 (library) make-non-continuable-violation 28 (library) make-polar 46 make-record-constructor-descriptor 21 (library) make-record-type-descriptor 20 (library) make-rectangular 46 make-serious-condition 28 (library) make-string 50 make-syntax-violation 29 (library) make-transcoder 33 (library) make-undefined-violation 29 (library) make-variable-transformer 51 (library) make-vector 51 make-violation 28 (library) make-warning 27 (library) make-who-condition 28 (library) map 49 mark 50 (library) max 43 may 9 member 12 (library) memp 12 (library) memq 12 (library) memv 12 (library) &message 27 (library) message-condition? 27 (library) min 43 mod 44 mod0 44 modulo 63 (library) must 9 must be 21 must not 9 mutable 20 mutable 16 (library) mutable record type 16 (library) mutator 15 (library) NaN 11 nan? 43 native-endianness 5 (library) native-eol-style 32 (library) native-transcoder 33 (library) negative inﬁnity 11 negative? 42 newline 42 (library) nil 47 &no-infinities 48 (library) no-infinities-violation? 48 (library) &no-nans 48 (library) no-nans-violation? 48 (library) &non-continuable 28 (library) non-continuable-violation? 28 (library) nongenerative 16 (library) nongenerative 16 (library) not 47 null (formal semantics) 68.

39 procedure? (formal semantics) 70 promise 64 (library) proper tail recursion 20 protocol 21 (library) protocol 16 (library) . 20 (library) record-type-descriptor 19 (library) record-type-descriptor? 21 (library) record-type-field-names 24 (library) record-type-generative? 24 (library) record-type-name 23 (library) record-type-opaque? 24 (library) record-type-parent 23 (library) record-type-sealed? 24 (library) record-type-uid 23 (library) record? 23 (library) referentially transparent 29 region 14 (library). 48 null? (formal semantics) 68 number 5. 35 output ports 31 (library) output-port-buffer-mode 38 (library) output-port? 38 (library) pair 6. 47 pair? (formal semantics) 68 parent 16 (library) parent-rtd 16 (library) partition 11 (library) pattern variable 52 (library). 35–37 remainder 63 (library) remove 12 (library) remp 12 (library) remq 12 (library) remv 12 (library) responsibility 19 reverse 48 (rnrs (6)) 62 (library) null? 31. 41 numerator 44 numerical types 10 #o 13. 56 quasisyntax 57 (library) quote 32 quotient 63 (library) raise 18 raise 25 (library) raise (formal semantics) 66 raise-continuable 25 (library) raise-continuable (formal semantics) 66 rational-valued? 41 rational? 41 rationalize 45 read 42 (library) read-char 42 (library) real->flonum 46 (library) real-part 46 real-valued? 41 real? 41 record 15 (library) record constructor 15 (library). 7 procedure call 7. 15 object 5 octet 5 (library) odd? 42 opaque 16 (library) open-bytevector-input-port 35 (library) open-bytevector-output-port 39 (library) open-file-input-port 35 (library) open-file-input/output-port 41 (library) open-file-output-port 38 (library) open-input-file 42 (library) open-output-file 42 (library) open-string-input-port 35 (library) open-string-output-port 39 (library) or 34. 57 peek-char 42 (library) phase 25 port 31 (library) port-eof? 35 (library) port-has-port-position? 34 (library) port-has-set-port-position!? 34 (library) port-position 34 (library) port-transcoder 34 (library) port? 34 (library) position 34 (library) positive inﬁnity 11 positive? 42 predicate 37 preﬁx notation 6 procedure 6.88 Revised6 Scheme put-bytevector 40 (library) put-char 40 (library) put-datum 40 (library) put-string 40 (library) put-u8 40 (library) quasiquote 55. 10. 47 pair? 31. 33. 28 procedure? 31. 21 (library) record-accessor 22 (library) record-constructor 22 (library) record-constructor descriptor 21 (library) record-constructor-descriptor 19 (library) record-field-mutable? 24 (library) record-mutator 22 (library) record-predicate 22 (library) record-rtd 23 (library) record-type descriptor 15 (library). 43 (library) number->string 46 number? 31. 18.

18. 14. 74 set-car! 62 (library) set-car! (formal semantics) 68 set-cdr! 63 (library) set-cdr! (formal semantics) 68 set-port-position! 34 (library) should 9 should not 9 simple condition 25 (library) simple-conditions 26 (library) simplest rational 45 sin 45 sint-list->bytevector 7 (library) special form 7 splicing 37 sqrt 45 standard library 17 standard-error-port 39 (library) standard-input-port 35 (library) standard-output-port 39 (library) string 5 string 50 string->bytevector 33 (library) string->list 51 string->number 47 string->symbol 49 string->utf16 9 (library) string->utf32 9 (library) string->utf8 9 (library) string-append 51 string-ci-hash 60 (library) string-ci<=? 4 (library) string-ci<? 4 (library) string-ci=? 4 (library) string-ci>=? 4 (library) string-ci>? 4 (library) string-copy 51 string-downcase 4 (library) string-fill! 63 (library) string-foldcase 4 (library) string-for-each 51 string-hash 60 (library) string-length 50 string-normalize-nfc 4 (library) string-normalize-nfd 4 (library) string-normalize-nfkc 4 (library) string-normalize-nfkd 4 (library) string-ref 50 string-set! 63 (library) string-titlecase 4 (library) string-upcase 4 (library) string<=? 50 string<? 50 string=? 50 string>=? 50 string>? 50 string? 31. 14 symbol->string 20. 29 &syntax 29 (library) syntax 53 (library) syntax object 51 (library) syntax violation 19 syntax->datum 55 (library) syntax-case 51 (library) . 49 syntactic abstraction 29 syntactic datum 8. 16 syntactic keyword 7. 11 substitution 50 (library) substring 51 surrogate 50 symbol 6. 11.Index 89 (rnrs arithmetic bitwise (6)) 48 (library) (rnrs arithmetic fixnums (6)) 43 (library) (rnrs arithmetic flonums (6)) 46 (library) (rnrs base (6)) 31 (rnrs bytevectors (6)) 5 (library) (rnrs conditions (6)) 25 (library) (rnrs control (6)) 14 (library) (rnrs enums (6)) 60 (library) (rnrs exceptions (6)) 24 (library) (rnrs files (6)) 42 (library) (rnrs hashtables (6)) 58 (library) (rnrs io ports (6)) 31 (library) (rnrs io simple (6)) 41 (library) (rnrs lists (6)) 10 (library) (rnrs mutable-pairs (6)) 62 (library) (rnrs mutable-strings (6)) 63 (library) (rnrs programs (6)) 43 (library) (rnrs r5rs (6)) 63 (library) (rnrs records inspection (6)) 23 (library) (rnrs records procedural (6)) 20 (library) (rnrs records syntactic (6)) 16 (library) (rnrs sorting (6)) 13 (library) (rnrs syntax-case (6)) 50 (library) (rnrs unicode (6)) 3 (library) round 44 rtd 20 (library) safe libraries 19 scalar value 50 scheme-report-environment 64 (library) sealed 16 (library) sealed 16 (library) &serious 28 (library) serious-condition? 28 (library) set! 33 set! (formal semantics) 70. 50 subform 7. 49 symbol-hash 60 (library) symbol=? 49 symbol? 31.

27 transcoded-port 34 (library) transcoder 32 (library) transcoder-codec 33 (library) transcoder-eol-style 33 (library) transcoder-error-handling-mode 33 (library) transformation procedure 51 (library) transformer 29. 47 tail call 20. 59 tail context 20 tan 45 textual port 32 (library) textual ports 31 (library) textual-port? 34 (library) throw (formal semantics) 73 top-level program 9. 56 unspeciﬁed behavior 20 unspeciﬁed values 20 unsyntax 57 (library) unsyntax-splicing 57 (library) utf-16-codec 32 (library) utf-8-codec 32 (library) utf16->string 10 (library) utf32->string 10 (library) utf8->string 9 (library) valid indices 50. 56 true 19. 18. 51 (library). 28 &undefined 29 (library) undefined-violation? 29 (library) Unicode 50 Unicode scalar value 50 universe 60 (library) unless 14 (library) unquote 55. 17. 15 zero? 42 syntax-rules 57 syntax-violation 58 (library) syntax-violation-form 29 (library) syntax-violation-subform 29 (library) syntax-violation? 29 (library) #t 14. 51 values 53 values (formal semantics) 65–67. 56 unquote-splicing 55. 33. 28 variable transformer 51 (library) vector 6 vector 51 vector->list 52 vector-fill! 52 . 73. 75 variable 6. 34 truncate 44 type 31 u8-list->bytevector 6 (library) uint-list->bytevector 7 (library) unbound 18.90 Revised6 Scheme vector-for-each 52 vector-length 51 vector-map 52 vector-ref 51 vector-set! 51 vector-sort 13 (library) vector-sort! 13 (library) vector? 31. 51 &violation 28 (library) violation? 28 (library) visit 26 visiting 26 &warning 27 (library) warning? 27 (library) when 14 (library) Whitespace 13 &who 28 (library) who-condition? 28 (library) with-exception-handler 24 (library) with-exception-handler (formal semantics) 66 with-input-from-file 41 (library) with-output-to-file 41 (library) with-syntax 56 (library) wrap 50 (library) wrapped syntax object 50 (library) write 42 (library) write-char 42 (library) #x 13. 14.

- 1 Bach 2015 - Tema 1 [Presentacion]
- 1 Bach 2015 - Tema 1 [Cuestiones]
- 1 Bach 2015 - Examen T0-1 B
- 1 Bach 2015 - Examen T0-1 A
- 1 Bach 2015 - Tema 1 [Apuntes]
- 3ESO 2015 - Tema 1 [Cuestiones]
- 1 Bach 2015 - Tema 0
- 1 Bach 2015 - Tema 0
- Manual Dom4
- SSH Para La Gestion de Redes
- Introducción a La Auditoría Wireless
- UT 10 - Respuestas
- ComunicaciónPLC_PC_a.pdf
- ComunicacionPLC_PC.pdf
- AWL_lista
- Introducción_a_la_neumática.pdf
- 02 Principales_aplicaciones_de_las_valvulas.pdf
- sessio7_solucions
- sessio7_enunciats
- problemes_extra3i4
- Sessions 6 8
- e Cuac i Ones Funcional Es 2
- e Cuac i Ones Funcional Es 1
- sessio7_enunciats
- Andreescu - Functional Equations.pdf

- C++, Pascal Variables Are Declared Outside the Code-body of the Function
- JCL_FAQ
- Chapter 6. Varying Variables
- L8 Working With Macros and Libraries
- ppt_cod.ppt
- 16066 Storage Classs
- The GNU C Library - Signal ..
- unit_V
- BOF
- pro e
- C Programming Summary
- Week 8 C5 Functions
- c que
- Handout 5.docx
- Extra Material Matlab
- Scrap
- CCS5 Tutorial
- Compiler Optimizations
- Open Source License VMware Workstation 11.1.2 and VMware Player 7.1.2 GA
- Config Open Cv
- The Pascal Library
- AS400 System Adm Book
- Excel Macro in 1 day- beginner's guide
- Td Win32asm 210.Asm
- 5 Functions PPT
- Dist+Lab+File
- Cap 8 Multimodule Programming
- Computer science class 12 key notes and revision
- What are the various types of C Vuser correlation functions
- Vasusir Class Notes

Are you sure?

This action might not be possible to undo. Are you sure you want to continue?

We've moved you to where you read on your other device.

Get the full title to continue

Get the full title to continue reading from where you left off, or restart the preview.

scribd