commit a4b6859b932ef42a30865acec9a538fa0d069abe
parent 84214dbef6a2c8c2cebdfe27bc6af66f5f78738f
Author: Yuval Langer <yuvallangerontheroad@gmail.com>
Date: Sat, 27 Jan 2024 17:45:04 +0200
Add more chapters, sections, and subsections.
Diffstat:
1 file changed, 2115 insertions(+), 1 deletion(-)
diff --git a/doc/r7rs-small/r7rs-small.texinfo b/doc/r7rs-small/r7rs-small.texinfo
@@ -78,132 +78,2246 @@ The report concludes with a list of references and an alphabetic index.
@node Introduction
@chapter Introduction
+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, suffice to form a practical
+and efficient programming language that is flexible enough to support most of the major
+programming paradigms in use today.
+
+Scheme was one of the first programming languages to incorporate first-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 first 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, thus allowing a programming style that is both
+coherent and efficient. Scheme was the first widely used programming language to
+embrace first-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 numbers, an extension of Common Lisp’s generic
+arithmetic. More recently, Scheme became the first programming language to support
+hygienic macros, which permit the syntax of a block-structured language to be extended
+in a consistent and reliable manner.
+
+Background
+
+The first description of Scheme was written in 1975 [35]. A revised report [31] appeared in
+1978, which described the evolution of the language as its MIT implementation was
+upgraded to support an innovative compiler [32]. Three distinct projects began in 1981
+and 1982 to use variants of Scheme for courses at MIT, Yale, and Indiana University [27,
+24, 14]. An introductory computer science textbook using Scheme was published in 1984
+[1].
+
+As Scheme became more widespread, local dialects began to diverge until students and
+researchers occasionally found it difficult to understand code written at other sites.
+Fifteen representatives of the major implementations of Scheme therefore met in
+October 1984 to work toward a better and more widely accepted standard for Scheme.
+Their report, the RRRS [8], was published at MIT and Indiana University in the summer of
+1985. Further revision took place in the spring of 1986, resulting in the R3RS [29]. Work in
+the spring of 1988 resulted in R4RS [10], which became the basis for the IEEE Standard for
+the Scheme Programming Language in 1991 [18]. In 1998, several additions to the IEEE
+standard, including high-level hygienic macros, multiple return values, and eval, were
+finalized as the R5RS [20].
+
+In the fall of 2006, work began on a more ambitious standard, including many new
+improvements and stricter requirements made in the interest of improved portability. The
+resulting standard, the R6RS, was completed in August 2007 [33], and was organized as a
+core language and set of mandatory standard libraries. Several new implementations of
+Scheme conforming to it were created. However, most existing R5RS implementations
+(even excluding those which are essentially unmaintained) did not adopt R6RS, or adopted
+only selected parts of it.
+
+In consequence, the Scheme Steering Committee decided in August 2009 to divide the
+standard into two separate but compatible languages — a “small” language, suitable for
+educators, researchers, and users of embedded languages, focused on R5RS
+compatibility, and a “large” language focused on the practical needs of mainstream
+software development, intended to become a replacement for R6RS. The present report
+describes the “small” language of that effort: therefore it cannot be considered in
+isolation as the successor to R6RS.
+
+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
+implementers of Scheme to use this report as a starting point for manuals and other
+documentation, modifying it as necessary.
+
+Acknowledgments
+
+We would like to thank the members of the Steering Committee, William Clinger, Marc
+Feeley, Chris Hanson, Jonathan Rees, and Olin Shivers, for their support and guidance.
+
+This report is very much a community effort, and we’d like to thank everyone who
+provided comments and feedback, including the following people: David Adler, Eli
+Barzilay, Taylan Ulrich Bayırlı/Kammer, Marco Benelli, Pierpaolo Bernardi, Peter Bex, Per
+Bothner, John Boyle, Taylor Campbell, Raffael Cavallaro, Ray Dillinger, Biep Durieux,
+Sztefan Edwards, Helmut Eller, Justin Ethier, Jay Reynolds Freeman, Tony Garnock-Jones,
+Alan Manuel Gloria, Steve Hafner, Sven Hartrumpf, Brian Harvey, Moritz Heidkamp,
+Jean-Michel Hufflen, Aubrey Jaffer, Takashi Kato, Shiro Kawai, Richard Kelsey, Oleg
+Kiselyov, Pjotr Kourzanov, Jonathan Kraut, Daniel Krueger, Christian Stigen Larsen, Noah
+Lavine, Stephen Leach, Larry D. Lee, Kun Liang, Thomas Lord, Vincent Stewart Manis, Perry
+Metzger, Michael Montague, Mikael More, Vitaly Magerya, Vincent Manis, Vassil Nikolov,
+Joseph Wayne Norton, Yuki Okumura, Daichi Oohashi, Jeronimo Pellegrini, Jussi
+Piitulainen, Alex Queiroz, Jim Rees, Grant Rettke, Andrew Robbins, Devon Schudy, Bakul
+Shah, Robert Smith, Arthur Smyles, Michael Sperber, John David Stone, Jay Sulzberger,
+Malcolm Tredinnick, Sam Tobin-Hochstadt, Andre van Tonder, Daniel Villeneuve, Denis
+Washington, Alan Watson, Mark H. Weaver, Göran Weinholt, David A. Wheeler, Andy
+Wingo, James Wise, Jörg F. Wittenberger, Kevin A. Wortman, Sascha Ziemann.
+
+In addition we would like to thank all the past editors, and the people who helped them in
+turn: Hal Abelson, Norman Adams, David Bartley, Alan Bawden, Michael Blair, Gary
+Brooks, George Carrette, Andy Cromarty, Pavel Curtis, Jeff Dalton, Olivier Danvy, Ken
+Dickey, Bruce Duba, Robert Findler, Andy Freeman, Richard Gabriel, Yekta Gürsel, Ken
+Haase, Robert Halstead, Robert Hieb, Paul Hudak, Morry Katz, Eugene Kohlbecker, Chris
+Lindblad, Jacob Matthews, Mark Meyer, Jim Miller, Don Oxley, Jim Philbin, Kent Pitman,
+John Ramsdell, Guillermo Rozas, Mike Shaff, Jonathan Shapiro, Guy Steele, Julie Sussman,
+Perry Wagle, Mitchel Wand, Daniel Weise, Henry Wu, and Ozan Yigit. We thank Carol
+Fessenden, Daniel Friedman, and Christopher Haynes for permission to use text from the
+Scheme 311 version 4 reference manual. We thank Texas Instruments, Inc. for permission
+to use text from the TI Scheme Language Reference Manual [37]. We gladly acknowledge the
+influence of manuals for MIT Scheme [24], T [28], Scheme 84 [15], Common Lisp [34], and
+Algol 60 [25], as well as the following SRFIs: 0, 1, 4, 6, 9, 11, 13, 16, 30, 34, 39, 43, 46, 62, and
+87, all of which are available at http://srfi.schemers.org.
+
+
@node Overview of Scheme
@chapter Overview of Scheme
@node Semantics
@section Semantics
+This section gives an overview of Scheme’s semantics. A detailed informal semantics is the
+subject of chapters 3 through 6. For reference purposes, section 7.2 provides a formal
+semantics of Scheme.
+
+Scheme is a statically scoped programming language. Each use of a variable is associated
+with a lexically apparent binding of that variable.
+
+Scheme is a dynamically typed language. Types are associated with values (also called
+objects) rather than with variables. Statically typed languages, by contrast, associate types
+with variables and expressions as well as with values.
+
+All objects created in the course of a Scheme computation, including procedures and
+continuations, have unlimited extent. 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. Implementations of Scheme are
+required to be properly tail-recursive. This allows the execution of an iterative
+computation in constant space, even if the iterative computation is described by a
+syntactically recursive procedure. Thus with a properly tail-recursive implementation,
+iteration can be expressed using the ordinary procedure-call mechanics, so that special
+iteration constructs are useful only as syntactic sugar. See section 3.5.
+
+Scheme procedures are objects in their own right. Procedures can be created
+dynamically, stored in data structures, returned as results of procedures, and so on. One
+distinguishing feature of Scheme is that continuations, which in most other languages
+only operate behind the scenes, also have “first-class” status. Continuations are useful for
+implementing a wide variety of advanced control constructs, including non-local exits,
+backtracking, and coroutines. See section 6.10.
+
+Arguments to Scheme procedures are always passed by value, which means that the
+actual argument expressions are evaluated before the procedure gains control,
+regardless of whether the procedure needs the result of the evaluation. Scheme’s model
+of arithmetic is designed to remain as independent as possible of the particular ways in
+which numbers are represented within a computer. In Scheme, every integer is a rational
+number, every rational is a real, and every real is a complex number. Thus the distinction
+between integer and real arithmetic, so important to many programming languages,
+does not appear in Scheme. In its place is a distinction between exact arithmetic, which
+corresponds to the mathematical ideal, and inexact arithmetic on approximations. Exact
+arithmetic is not limited to integers.
+
@node Syntax
@section Syntax
+Scheme, like most dialects of Lisp, employs a fully parenthesized prefix notation for
+programs and other data; the grammar of Scheme generates a sublanguage of the
+language used for data. An important consequence of this simple, uniform representation
+is that Scheme programs and data can easily be treated uniformly by other Scheme
+programs. For example, the eval procedure evaluates a Scheme program expressed as
+data.
+
+The read procedure performs syntactic as well as lexical decomposition of the data it
+reads. The read procedure parses its input as data (section 7.1.2), not as program.
+
+The formal syntax of Scheme is described in section 7.1.
+
@node Notation and terminology
@section Notation and terminology
@node Base and optional features
@subsection Base and optional features
+Every identifier defined in this report appears in one or more of several libraries.
+Identifiers defined in the base library are not marked specially in the body of the report.
+This library includes the core syntax of Scheme and generally useful procedures that
+manipulate data. For example, the variable abs is bound to a procedure of one argument
+that computes the absolute value of a number, and the variable + is bound to a procedure
+that computes sums. The full list all the standard libraries and the identifiers they export
+is given in Appendix A.
+
+All implementations of Scheme:
+
+* Must provide the base library and all the identifiers exported from it.
+
+* May provide or omit the other libraries given in this report, but each library must either
+ be provided in its entirety, exporting no additional identifiers, or else omitted
+ altogether.
+
+* May provide other libraries not described in this report.
+
+* May also extend the function of any identifier in this report, provided the extensions
+ are not in conflict with the language reported here.
+
+* Must support portable code by providing a mode of operation in which the lexical
+ syntax does not conflict with the lexical syntax described in this report.
+
@node Error situations and unspecified behavior
@subsection Error situations and unspecified behavior
+When speaking of an error situation, this report uses the phrase “an error is signaled” to
+indicate that implementations must detect and report the error. An error is signaled by
+raising a non-continuable exception, as if by the procedure raise as described in section
+6.11. The object raised is implementation-dependent and need not be distinct from
+objects previously used for the same purpose. In addition to errors signaled in situations
+described in this report, programmers can signal their own errors and handle signaled
+errors.
+
+The phrase “an error that satisfies predicate is signaled” means that an error is signaled as
+above. Furthermore, if the object that is signaled is passed to the specified predicate (such
+as file-error? or read-error?), the predicate returns #t.
+
+If such wording does not appear in the discussion of an error, then implementations are
+not required to detect or report the error, though they are encouraged to do so. Such a
+situation is sometimes, but not always, referred to with the phrase “an error.” In such a
+situation, an implementation may or may not signal an error; if it does signal an error, the
+object that is signaled may or may not satisfy the predicates error-object?, file-error?, or
+read-error?. Alternatively, implementations may provide non-portable extensions.
+
+For example, it is an error for a procedure to be passed an argument of a type that the
+procedure is not explicitly specified to handle, even though such domain errors are seldom
+mentioned in this report. Implementations may signal an error, extend a procedure’s
+domain of definition to include such arguments, or fail catastrophically.
+
+This report uses the phrase “may report a violation of an implementation restriction” to
+indicate circumstances under which an implementation is permitted to report that it is
+unable to continue execution of a correct program because of some restriction imposed
+by the implementation. Implementation restrictions are discouraged, but
+implementations are encouraged to report violations of implementation restrictions.
+
+For example, an implementation may report a violation of an implementation restriction if
+it does not have enough storage to run a program, or if an arithmetic operation would
+produce an exact number that is too large for the implementation to represent.
+
+If the value of an expression is said to be “unspecified,” then the expression must evaluate
+to some object without signaling an error, but the value depends on the implementation;
+this report explicitly does not say what value is returned.
+
+Finally, the words and phrases “must,” “must not,” “shall,” “shall not,” “should,” “should
+not,” “may,” “required,” “recommended,” and “optional,” although not capitalized in this
+report, are to be interpreted as described in RFC 2119 [3]. They are used only with
+reference to implementer or implementation behavior, not with reference to
+programmer or program behavior.
+
@node Entry format
@subsection Entry format
+
+Chapters 4 and 6 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
+procedure. An entry begins with one or more header lines of the form
+
+category:
+
+template
+
+
+for identifiers in the base library, or
+
+name library
+
+category:
+
+template
+
+
+where
+
+name is the short name of a library as defined in Appendix A.
+
+If
+
+category is “syntax,” the entry describes an expression type, and the template gives the
+syntax of the expression type. Components of expressions are designated by syntactic
+variables, which are written using angle brackets, for example <expression> and
+<variable>. Syntactic variables are intended to denote segments of program text; for
+example, <expression> stands for any string of characters which is a syntactically valid
+expression. The notation
+
+<thing1> …
+
+indicates zero or more occurrences of a <thing>, and
+
+<thing1> <thing2> …
+
+indicates one or more occurrences of a <thing>.
+
+If
+
+category is “auxiliary syntax,” then the entry describes a syntax binding that occurs only as
+part of specific surrounding expressions. Any use as an independent syntactic construct
+or variable is an error.
+
+If
+
+category is “procedure,” then the entry describes a procedure, and the header line gives a
+template for a call to the procedure. Argument names in the template are
+
+italicized. Thus the header line
+
+procedure: (vector-ref
+
+vector
+
+k)
+
+
+indicates that the procedure bound to the vector-ref variable takes two arguments, a
+vector
+
+vector and an exact non-negative integer
+
+k (see below). The header lines
+
+procedure: (make-vector
+
+k)
+
+
+procedure: (make-vector
+
+k
+
+fill)
+
+
+indicate that the make-vector procedure must be defined to take either one or two
+arguments.
+
+It is an error for a procedure to be presented with an argument that it is not specified to
+handle. For succinctness, we follow the convention that if an argument name is also the
+name of a type listed in section 3.2, then it is an error if that argument is not of the named
+type. For example, the header line for vector-ref given above dictates that the first
+argument to vector-ref is a vector. The following naming conventions also imply type
+restrictions:
+
+ alist association list
+ (list of pairs)
+ boolean boolean value
+ (#t or #f)
+ byte exact integer 0
+ ≤byte < 256
+ bytevector bytevector
+ char character
+ end exact
+ non-negative
+ integer
+ k, exact
+ non-negative
+ k1, … integer
+
+ kj, …
+ letter alphabetic
+ character
+ list, list (see section
+ 6.4)
+ list1, …
+
+ listj, …
+ n, integer
+
+ n1, …
+
+ nj, …
+ obj any object
+ pair pair
+ port port
+ proc procedure
+ q, rational
+ number
+ q1, …
+
+ qj, …
+ start exact
+ non-negative
+ integer
+ string string
+ symbol symbol
+ thunk zero-argument
+ procedure
+ vector vector
+ x, real number
+
+ x1, …
+
+ xj, …
+ y, real number
+
+ y1, …
+
+ yj, …
+ z, complex
+ number
+ z1, …
+
+ zj, …
+
+The names
+
+start and
+
+end are used as indexes into strings, vectors, and bytevectors. Their use implies the
+following:
+
+* It is an error if
+
+ start is greater than
+
+ end.
+
+* It is an error if
+
+ end is greater than the length of the string, vector, or bytevector.
+
+* If
+
+ start is omitted, it is assumed to be zero.
+
+* If
+
+ end is omitted, it assumed to be the length of the string, vector, or bytevector.
+
+* The index
+
+ start is always inclusive and the index
+
+ end is always exclusive. As an example, consider a string. If
+
+ start and
+
+ end are the same, an empty substring is referred to, and if
+
+ start is zero and
+
+ end is the length of
+
+ string, then the entire string is referred to.
+
@node Evaluation examples
@subsection Evaluation examples
+The symbol “⟹” used in program examples is read “evaluates to.” For example,
+
+(* 5 8) ⟹ 40 means that the expression (* 5 8) evaluates to the object 40. Or, more
+precisely: the expression given by the sequence of characters “(* 5 8)” evaluates, in an
+environment containing the base library, to an object that can be represented externally
+by the sequence of characters “ 40.” See section 3.3 for a discussion of external
+representations of objects.
+
@node Naming conventions
@subsection Naming conventions
+By convention, ? is the final character of the names of procedures that always return a
+boolean value. Such procedures are called predicates. Predicates are generally understood
+to be side-effect free, except that they may raise an exception when passed the wrong
+type of argument.
+
+Similarly, ! is the final character of the names of procedures that store values into
+previously allocated locations (see section 3.4). Such procedures are called mutation
+procedures. The value returned by a mutation procedure is unspecified.
+
+By convention, “->” appears within the names of procedures that take an object of one
+type and return an analogous 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.
+
+A command is a procedure that does not return useful values to its continuation.
+
+A thunk is a procedure that does not accept arguments.
+
@node Lexical conventions
@chapter Lexical conventions
+This section gives an informal account of some of the lexical conventions used in writing
+Scheme programs. For a formal syntax of Scheme, see section 7.1.
+
@node Identifiers
@section Identifiers
+An identifieris any sequence of letters, digits, and “extended identifier characters”
+provided that it does not have a prefix which is a valid number. However, the . token (a
+single period) used in the list syntax is not an identifier.
+
+All implementations of Scheme must support the following extended identifier
+characters:
+
+! $ % & * + - . / : < = > ? @ ^ _ ~ Alternatively, an identifier can be represented by a sequence
+of zero or more characters enclosed within vertical lines (|), analogous to string literals.
+Any character, including whitespace characters, but excluding the backslash and vertical
+line characters, can appear verbatim in such an identifier. In addition, characters can be
+specified using either an <inline hex escape> or the same escapes available in strings.
+
+For example, the identifier |H\x65;llo| is the same identifier as Hello, and in an
+implementation that supports the appropriate Unicode character the identifier |\x3BB;|
+is the same as the identifier λ. What is more, |\t\t| and |\x9;\x9;| are the same. Note
+that || is a valid identifier that is different from any other identifier.
+
+Here are some examples of identifiers:
+
+... +
++soup+ <=?
+->string a34kTMNs
+lambda list->vector
+q V17a
+|two words| |two\x20;words|
+the-word-recursion-has-many-meanings See section 7.1.1 for the formal syntax of
+identifiers.
+
+Identifiers have two uses within Scheme programs:
+
+* Any identifier can be used as a variableor as a syntactic keyword(see sections 3.1 and
+ 4.3).
+
+* When an identifier appears as a literal or within a literal (see section 4.1.2), it is being
+ used to denote a symbol (see section 6.5).
+
+In contrast with earlier revisions of the report [20], the syntax distinguishes between
+upper and lower case in identifiers and in characters specified using their names.
+However, it does not distinguish between upper and lower case in numbers, nor in <inline
+hex escapes> used in the syntax of identifiers, characters, or strings. None of the
+identifiers defined in this report contain upper-case characters, even when they appear to
+do so as a result of the English-language convention of capitalizing the first word of a
+sentence.
+
+The following directives give explicit control over case folding.
+
+#!fold-case
+#!no-fold-case
+
+These directives can appear anywhere comments are permitted (see section 2.2) but
+must be followed by a delimiter. They are treated as comments, except that they affect
+the reading of subsequent data from the same port. The #!fold-case directive causes
+subsequent identifiers and character names to be case-folded as if by string-foldcase (see
+section 6.7). It has no effect on character literals. The #!no-fold-case directive causes a
+return to the default, non-folding behavior.
+
@node Whitespace and comments
@section Whitespace and comments
+Whitespace characters include the space, tab, and newline characters. (Implementations
+may provide additional whitespace characters such as page break.) Whitespace is used
+for improved readability and as necessary to separate tokens from each other, a token
+being an indivisible lexical unit such as an identifier or number, but is otherwise
+insignificant. Whitespace can occur between any two tokens, but not within a token.
+Whitespace occurring inside a string or inside a symbol delimited by vertical lines is
+significant.
+
+The lexical syntax includes several comment forms. Comments are treated exactly like
+whitespace.
+
+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
+prefix a <datum> (cf. section 7.1.2) with #;and optional <whitespace>. The comment
+consists of the comment prefix #;, the space, and the <datum> together. This notation is
+useful for “commenting out” sections of code.
+
+Block comments are indicated with properly nested #|and |# pairs.
+
+#|
+ The FACT procedure computes the factorial
+ of a non-negative integer.
+|#
+(define fact
+ (lambda (n)
+ (if (= n 0)
+ #;(= n 1)
+ 1 ;Base case: return 1
+ (* n (fact (- n 1))))))
+
@node Other notations
@section Other notations
+For a description of the notations used for numbers, see section 6.2.
+
+. + -
+ These are used in numbers, and can also occur anywhere in an identifier. A delimited
+ plus or minus sign by itself is also an identifier. A delimited period (not occurring
+ within a number or identifier) is used in the notation for pairs (section 6.4), and to
+ indicate a rest-parameter in a formal parameter list (section 4.1.4). Note that a
+ sequence of two or more periods is an identifier.
+
+( )
+ Parentheses are used for grouping and to notate lists (section 6.4).
+
+'
+ The apostrophe (single quote) character is used to indicate literal data (section
+ 4.1.2).
+
+`
+ The grave accent (backquote) character is used to indicate partly constant data
+ (section 4.2.8).
+
+, ,@
+ The character comma and the sequence comma at-sign are used in conjunction with
+ quasiquotation (section 4.2.8).
+
+"
+ The quotation mark character is used to delimit strings (section 6.7).
+
+\
+ Backslash is used in the syntax for character constants (section 6.6) and as an escape
+ character within string constants (section 6.7) and identifiers (section 7.1.1).
+
+[ ] { } |
+ Left and right square and curly brackets (braces) are reserved for possible future
+ extensions to the language.
+
+#
+ The number sign is used for a variety of purposes depending on the character that
+ immediately follows it:
+
+#t #f
+ These are the boolean constants (section 6.3), along with the alternatives #true and
+ #false.
+
+#\
+ This introduces a character constant (section 6.6).
+
+#(
+ This introduces a vector constant (section 6.8). Vector constants are terminated by ) .
+
+#u8(
+ This introduces a bytevector constant (section 6.9). Bytevector constants are
+ terminated by ) .
+
+#e #i #b #o #d #x
+ These are used in the notation for numbers (section 6.2.5).
+
+#<n>= #<n>#
+ These are used for labeling and referencing other literal data (section 2.4).
+
@node Datum labels
@section Datum labels
+lexical syntax: #<n>=<datum>
+lexical syntax: #<n>#
+
+The lexical syntax #<n>=<datum> reads the same as <datum>, but also results in <datum>
+being labelled by <n>. It is an error if <n> is not a sequence of digits.
+
+The lexical syntax #<n># serves as a reference to some object labelled by #<n>=; the
+result is the same object as the #<n>= (see section 6.1). Together, these syntaxes permit
+the notation of structures with shared or circular substructure.
+
+(let ((x (list 'a 'b 'c)))
+ (set-cdr! (cddr x) x)
+ x) ⟹ #0=(a b c . #0#)
+The scope of a datum label is the portion of the outermost datum in which it appears that
+is to the right of the label. Consequently, a reference #<n># can occur only after a label
+#<n>=; it is an error to attempt a forward reference. In addition, it is an error if the
+reference appears as the labelled object itself (as in #<n>= #<n>#), because the object
+labelled by #<n>= is not well defined in this case.
+
+It is an error for a <program> or <library> to include circular references except in literals.
+In particular, it is an error for quasiquote (section 4.2.8) to contain them.
+
+#1=(begin (display #\x) #1#)
+ ⟹ error
+
@node Basic concepts
@chapter Basic concepts
@node Variables, syntactic keywords, and regions
@section Variables, syntactic keywords, and regions
+An identifiercan name either a type of syntax or a location where a value can be stored. An
+identifier that names a type of syntax is called a syntactic keywordand is said to be bound to
+a transformer for that syntax. An identifier that names a location is called a variableand is
+said to be bound to that location. The set of all visible bindingsin effect at some point in a
+program is known as the environment in effect at that point. The value stored in the
+location to which a variable is bound is called the variable’s value. By abuse of
+terminology, the variable is sometimes said to name the value or to be bound to the
+value. This is not quite accurate, but confusion rarely results from this practice.
+
+Certain expression types are used to create new kinds of syntax and to bind syntactic
+keywords to those new syntaxes, while other expression types create new locations and
+bind variables to those locations. These expression types are called binding constructs.
+Those that bind syntactic keywords are listed in section 4.3. The most fundamental of the
+variable binding constructs is the lambda expression, because all other variable binding
+constructs (except top-level bindings) can be explained in terms of lambda expressions.
+The other variable binding constructs are let, let*, letrec, letrec*, let-values, let*-values,
+and do expressions (see sections 4.1.4, 4.2.2, and 4.2.4).
+
+Scheme is a language with block structure. To each place where an identifier is bound in a
+program there corresponds a region of the program text within which the binding is
+visible. The region is determined by the particular binding construct that establishes 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 identifier refers to the binding of the
+identifier that established the innermost of the regions containing the use. If there is no
+binding of the identifier whose region contains the use, then the use refers to the binding
+for the variable in the global environment, if any (chapters 4 and 6); if there is no binding
+for the identifier, it is said to be unbound.
+
@node Disjointness of types
@section Disjointness of types
+No object satisfies more than one of the following predicates:
+
+boolean? bytevector?
+char? eof-object?
+null? number?
+pair? port?
+procedure? string?
+symbol? vector?
+and all predicates created by define-record-type.
+
+These predicates define the types boolean, bytevector, character, the empty list object,
+eof-object, number, pair, port, procedure, string, symbol, vector, and all record types.
+
+Although there is a separate boolean type, any Scheme value can be used as a boolean
+value for the purpose of a conditional test. As explained in section 6.3, 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.
+
@node External representations
@section External representations
+An important concept in Scheme (and Lisp) is that of the external representation of an
+object as a sequence of characters. For example, an external representation of the
+integer 28 is the sequence of characters “28”, and an external representation of a list
+consisting of the integers 8 and 13 is the sequence of characters “(8 13)”.
+
+The external representation of an object is not necessarily unique. The integer 28 also has
+representations “#e28.000” and “#x1c”, and the list in the previous paragraph also has the
+representations “( 08 13 )” and “(8 . (13 . ()))” (see section 6.4).
+
+Many objects have standard external representations, but some, such as procedures, do
+not have standard representations (although particular implementations may define
+representations for them).
+
+An external representation can be written in a program to obtain the corresponding
+object (see quote, section 4.1.2).
+
+External representations can also be used for input and output. The procedure read
+(section 6.13.2) parses external representations, and the procedure write (section 6.13.3)
+generates them. Together, they provide an elegant and powerful input/output facility.
+
+Note that the sequence of characters “(+ 2 6)” is not an external representation of the
+integer 8, even though it is an expression evaluating to the integer 8; rather, it is an
+external representation of a three-element list, the elements of which are the symbol +
+and the integers 2 and 6. Scheme’s syntax has the property that any sequence of
+characters that is an expression is also the external representation of some object. This
+can lead to confusion, since it is not always obvious out of context whether a given
+sequence of characters is intended to denote data or program, but it is also a source of
+power, since it facilitates writing programs such as interpreters and compilers that treat
+programs as data (or vice versa).
+
+The syntax of external representations of various kinds of objects accompanies the
+description of the primitives for manipulating the objects in the appropriate sections of
+chapter 6.
+
@node Storage model
@section Storage model
+Variables and objects such as pairs, strings, vectors, and bytevectors implicitly denote
+locationsor sequences of locations. A string, for example, denotes as many locations as
+there are characters in the string. A new value can be stored into one of these locations
+using the string-set! procedure, but the string continues to denote 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 6.1) 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 newly allocated for a variable or object,
+what is meant is that an appropriate number of locations are chosen from the set of
+locations that are not in use, and the chosen locations are marked to indicate that they
+are now in use before the variable or object is made to denote them. Notwithstanding
+this, it is understood that the empty list cannot be newly allocated, because it is a unique
+object. It is also understood that empty strings, empty vectors, and empty bytevectors,
+which contain no locations, may or may not be newly allocated.
+
+Every object that denotes locations is either mutableor immutable. Literal constants, the
+strings returned by symbol->string, and possibly the environment returned by
+scheme-report-environment are immutable objects. All objects created by the other
+procedures listed in this report are mutable. It is an error to attempt to store a new value
+into a location that is denoted by an immutable object.
+
+These locations are to be understood as conceptual, not physical. Hence, they do not
+necessarily correspond to memory addresses, and even if they do, the memory address
+might not be constant.
+
+ Rationale: In many systems it is desirable for constants(i.e. the values of literal
+ expressions) to reside in read-only memory. Making it an error to alter constants
+ permits this implementation strategy, while not requiring other systems to
+ distinguish between mutable and immutable objects.
+
@node Proper tail recursion
@section Proper tail recursion
+Implementations of Scheme are required to be properly tail-recursive. Procedure calls that
+occur in certain syntactic contexts defined below are tail calls. A Scheme implementation is
+properly tail-recursive if it supports an unbounded number of active tail calls. A call is
+active if the called procedure might still return. Note that this includes calls that might be
+returned from either by the current continuation or by continuations captured 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 definition of proper tail recursion can be found in [6].
+
+ Rationale: Intuitively, no space is needed for an active tail call because the
+ continuation that is used in the tail call has the same semantics as the continuation
+ passed to the procedure containing the call. Although an improper implementation
+ might use a new continuation in the call, a return to this new continuation would be
+ followed immediately by a return to the continuation passed to the procedure. A
+ properly tail-recursive implementation returns to that continuation directly.
+
+ Proper tail recursion was one of the central ideas in Steele and Sussman’s original
+ version of Scheme. Their first Scheme interpreter implemented both functions and
+ actors. Control flow was expressed using actors, which differed from functions in
+ that they passed their results on to another actor instead of returning to a caller. In
+ the terminology of this section, each actor finished with a tail call to another actor.
+
+ Steele and Sussman later observed that in their interpreter the code for dealing with
+ actors was identical to that for functions and thus there was no need to include both
+ in the language.
+
+A tail callis a procedure call that occurs in a tail context. Tail contexts are defined
+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 expression, shown as <tail expression>
+ below, occurs in a tail context. The same is true of all the bodies of case-lambda
+ expressions.
+
+ (lambda <formals>
+ <definition>* <expression>* <tail expression>)
+ (case-lambda (<formals> <tail body>)*)
+
+* 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 rules in the grammar
+ given in chapter 7 by replacing some occurrences of <body> with <tail body>, some
+ occurrences of <expression> with <tail expression>, and some occurrences of
+ <sequence> with <tail sequence>. 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>)
+ (when <test> <tail sequence>)
+ (unless <test> <tail sequence>)
+ (let (<binding spec>*) <tail body>)
+ (let <variable> (<binding spec>*) <tail body>)
+ (let* (<binding spec>*) <tail body>)
+ (letrec (<binding spec>*) <tail body>)
+ (letrec* (<binding spec>*) <tail body>)
+ (let-values (<mv binding spec>*) <tail body>)
+ (let*-values (<mv binding spec>*) <tail body>)
+ (let-syntax (<syntax spec>*) <tail body>)
+ (letrec-syntax (<syntax spec>*) <tail body>)
+ (begin <tail sequence>)
+ (do (<iteration spec>*)
+ (<test> <tail sequence>)
+ <expression>*)
+ where
+ <cond clause> ⟶(<test> <tail sequence>)
+ <case clause> ⟶((<datum>*) <tail sequence>)
+ <tail body> ⟶<definition>* <tail sequence>
+ <tail sequence> ⟶<expression>* <tail expression>
+
+* If a cond or case expression is in a tail context, 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. <expression2> itself is not in a
+ tail context.
+
+Certain procedures defined in this report are also required to perform tail calls. The first
+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. Similarly, eval must
+evaluate its first argument as if it were in tail position within the eval procedure.
+
+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 returning an
+ unexpected number of values can be ignored, because in that case the effect of the
+ let is explicitly unspecified and implementation-dependent.)
+
@node Expressions
@chapter Expressions
+Expression types are categorized as primitive or derived. Primitive expression types include
+variables and procedure calls. Derived expression types are not semantically primitive,
+but can instead be defined as macros. Suitable syntax definitions of some of the derived
+expressions are given in section 7.3.
+
+The procedures force, promise?, make-promise, and make-parameter are also described
+in this chapter because they are intimately associated with the delay, delay-force, and
+parameterize expression types.
+
@node Primitive expression types
@section Primitive expression types
@node Variable references
@subsection Variable references
+syntax: <variable>
+
+An expression consisting of a variable(section 3.1) is a variable reference. The value of the
+variable reference is the value stored in the location to which the variable is bound. It is an
+error to reference an unboundvariable.
+
+(define x 28)
+x ⟹ 28
+
@node Literal expressions
@subsection Literal expressions
+syntax: (quote <datum>)
+syntax: '<datum>
+syntax: <constant>
+
+(quote <datum>) evaluates to <datum>.<Datum> can be any external representation of a
+Scheme object (see section 3.3). This notation is used to include literal constants in
+Scheme code.
+
+(quote a) ⟹ a
+(quote #(a b c)) ⟹ #(a b c)
+(quote (+ 1 2)) ⟹ (+ 1 2) (quote <datum>) can be abbreviated as '<datum>. The two
+notations are equivalent in all respects.
+
+'a ⟹ a
+'#(a b c) ⟹ #(a b c)
+'() ⟹ ()
+'(+ 1 2) ⟹ (+ 1 2)
+'(quote a) ⟹ (quote a)
+''a ⟹ (quote a) Numerical constants, string constants, character constants,
+vector constants, bytevector constants, and boolean constants evaluate to themselves;
+they need not be quoted.
+
+'145932 ⟹ 145932
+145932 ⟹ 145932
+'"abc" ⟹ "abc"
+"abc" ⟹ "abc"
+'#\a ⟹ #\a
+#\a ⟹ #\a
+'#(a 10) ⟹ #(a 10)
+#(a 10) ⟹ #(a 10)
+'#u8(64 65) ⟹ #u8(64 65)
+#u8(64 65) ⟹ #u8(64 65)
+'#t ⟹ #t
+#t ⟹ #t As noted in section 3.4, it is an error to attempt to alter a constant (i.e. the value
+of a literal expression) using a mutation procedure like set-car! or string-set!.
+
@node Procedure calls
@subsection Procedure calls
+syntax: (<operator> <operand1> …)
+
+A procedure call is written by enclosing in parentheses an expression for the procedure to
+be called followed by expressions for the arguments to be passed to it. The operator and
+operand expressions are evaluated (in an unspecified order) and the resulting procedure
+is passed the resulting arguments.
+
+(+ 3 4) ⟹ 7
+((if #f + *) 3 4) ⟹ 12 The procedures in this document are available as the values of
+variables exported by the standard libraries. For example, the addition and multiplication
+procedures in the above examples are the values of the variables + and * in the base
+library. New procedures are created by evaluating lambda expressions (see section 4.1.4).
+
+Procedure calls can return any number of values (see values in section 6.10). Most of the
+procedures defined in this report return one value or, for procedures such as apply, pass
+on the values returned by a call to one of their arguments. Exceptions are noted in the
+individual descriptions.
+
+ Note: In contrast to other dialects of Lisp, the order of evaluation is unspecified, and
+ the operator expression and the operand expressions are always evaluated with the
+ same evaluation rules.
+
+ Note: Although the order of evaluation is otherwise unspecified, the effect 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 differently for each procedure call.
+
+ Note: In many dialects of Lisp, the empty list, (), is a legitimate expression evaluating
+ to itself. In Scheme, it is an error.
+
@node Procedures
@subsection Procedures
+syntax: (lambda <formals> <body>)
+
+Syntax: <Formals> is a formal arguments list as described below, and <body> is a sequence
+of zero or more definitions followed by one or more expressions.
+
+Semantics: A lambda expression evaluates to a procedure. The environment in effect when
+the lambda expression was evaluated is remembered as part of the procedure. When the
+procedure is later called with some actual arguments, the environment in which the
+lambda expression was evaluated will be extended by binding the variables in the formal
+argument list to fresh locations, and the corresponding actual argument values will be
+stored in those locations. (A fresh location is one that is distinct from every previously
+existing location.) Next, the expressions in the body of the lambda expression (which, if it
+contains definitions, represents a letrec* form — see section 4.2.2) will be evaluated
+sequentially in the extended environment. The results of the last expression in the body
+will be returned as the results of the procedure call.
+
+(lambda (x) (+ x x)) ⟹ a procedure
+((lambda (x) (+ x x)) 4) ⟹ 8
+
+(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> have one of the following forms:
+
+* (<variable1> …): The procedure takes a fixed number of arguments; when the
+ procedure is called, the arguments will be stored in fresh locations that are bound to
+ the corresponding variables.
+
+* <variable>: The procedure takes any number of arguments; when the procedure is
+ called, the sequence of actual arguments is converted into a newly allocated list, and
+ the list is stored in a fresh location that is bound to <variable>.
+
+* (<variable1> … <variablen> . <variablen+1>): If a space-delimited period precedes the last
+ variable, then the procedure takes n or more arguments, where n is the number of
+ formal arguments before the period (it is an error if there is not at least one). The value
+ stored in the binding of the last variable will be a newly allocated list of the actual
+ arguments left over after all the other actual arguments have been matched up against
+ the other formal arguments.
+
+It is an error for a <variable> to appear more than once in <formals>.
+
+((lambda x x) 3 4 5 6) ⟹ (3 4 5 6)
+((lambda (x y . z) z)
+ 3 4 5 6) ⟹ (5 6)
+
+Each procedure created as the result of evaluating a lambda expression is (conceptually)
+tagged with a storage location, in order to make eqv? and eq? work on procedures (see
+section 6.1).
+
@node Conditionals
@subsection Conditionals
+syntax: (if <test> <consequent> <alternate>)
+syntax: (if <test> <consequent>)
+
+Syntax: <Test>, <consequent>, and <alternate> are expressions.
+
+Semantics: An if expression is evaluated as follows: first, <test> is evaluated. If it yields a
+true value(see section 6.3), then <consequent> is evaluated and its values are returned.
+Otherwise <alternate> is evaluated and its values are returned. If <test> yields a false
+value and no <alternate> is specified, then the result of the expression is unspecified.
+
+(if (> 3 2) 'yes 'no) ⟹ yes
+(if (> 2 3) 'yes 'no) ⟹ no
+(if (> 3 2)
+ (- 3 2)
+ (+ 3 2)) ⟹ 1
+
@node Assignments
@subsection Assignments
+syntax: (set! <variable> <expression>)
+
+Semantics: <Expression> is evaluated, and the resulting value is stored in the location to
+which <variable> is bound. It is an error if <variable> is not bound either in some
+regionenclosing the set! expression or else globally. The result of the set! expression is
+unspecified.
+
+(define x 2)
+(+ x 1) ⟹ 3
+(set! x 4) ⟹ unspecified
+(+ x 1) ⟹ 5
+
@node Inclusion
@subsection Inclusion
+syntax: (include <string1> <string2> …)
+syntax: (include-ci <string1> <string2> …)
+Semantics: Both include and include-ci take one or more filenames expressed as string
+literals, apply an implementation-specific algorithm to find corresponding files, read the
+contents of the files in the specified order as if by repeated applications of read, and
+effectively replace the include or include-ci expression with a begin expression containing
+what was read from the files. The difference between the two is that include-ci reads each
+file as if it began with the #!fold-case directive, while include does not.
-
+ Note: Implementations are encouraged to search for files in the directory which
+ contains the including file, and to provide a way for users to specify other directories
+ to search.
@node Derived expression types
@section Derived expression types
+
+The constructs in this section are hygienic, as discussed in section 4.3. For reference
+purposes, section 7.3 gives syntax definitions that will convert most of the constructs
+described in this section into the primitive constructs described in the previous section.
+
@node Conditionals
@subsection Conditionals
+
+syntax: (cond <clause1> <clause2> …)
+auxiliary syntax: else
+auxiliary syntax: =>
+
+Syntax: <Clauses> take one of two forms, either
+
+(<test> <expression1> …)where <test> is any expression, or (<test> => <expression>)The
+last <clause> can be an “else clause,” which has the form (else <expression1>
+<expression2> …).
+
+Semantics: A cond expression is evaluated by evaluating the <test> expressions of
+successive <clause>s in order until one of them evaluates to a true value(see section 6.3).
+When a <test> evaluates to a true value, the remaining <expression>s in its <clause> are
+evaluated in order, and the results of the last <expression> in the <clause> are returned
+as the results of the entire cond expression.
+
+If the selected <clause> contains only the <test> and no <expression>s, then the value of
+the <test> is returned as the result. If the selected <clause> uses the => alternate form,
+then the <expression> is evaluated. It is an error if its value is not a procedure that
+accepts one argument. This procedure is then 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 result of the conditional
+expression is unspecified; if there is an else clause, then its <expression>s are evaluated in
+order, 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 ((assv 'b '((a 1) (b 2))) => cadr)
+ (else #f)) ⟹ 2
+
+syntax: (case <key> <clause1> <clause2> …)
+
+Syntax: <Key> can be any expression. Each <clause> has the form
+
+((<datum1> …) <expression1> <expression2> …),where each <datum> is an external
+representation of some object. It is an error if any of the <datum>s are the same
+anywhere in the expression. Alternatively, a <clause> can be of the form ((<datum1> …) =>
+<expression>)The last <clause> can be an “else clause,” which has one of the forms (else
+<expression1> <expression2> …)
+or (else => <expression>).
+
+Semantics: A case expression is evaluated as follows. <Key> is evaluated and its result is
+compared against each <datum>. If the result of evaluating <key> is the same (in the
+sense of eqv?; see section 6.1) to a <datum>, then the expressions in the corresponding
+<clause> are evaluated in order and the results of the last expression in the <clause> are
+returned as the results of the case expression.
+
+If the result of evaluating <key> is different from every <datum>, 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 result of the case expression is unspecified.
+
+If the selected <clause> or else clause uses the => alternate form, then the <expression> is
+evaluated. It is an error if its value is not a procedure accepting one argument. This
+procedure is then called on the value of the <key> and the values returned by this
+procedure are returned by the case expression.
+
+(case (* 2 3)
+ ((2 3 5 7) 'prime)
+ ((1 4 6 8 9) 'composite)) ⟹ composite
+(case (car '(c d))
+ ((a) 'a)
+ ((b) 'b)) ⟹ unspecified
+(case (car '(c d))
+ ((a e i o u) 'vowel)
+ ((w y) 'semivowel)
+ (else => (lambda (x) x))) ⟹ c
+
+syntax: (and <test1> …)
+
+Semantics: The <test> expressions are evaluated from left to right, and if any expression
+evaluates to #f (see section 6.3), then #f is returned. Any remaining expressions are not
+evaluated. If all the expressions evaluate to true values, the values of the last expression
+are returned. If there are no expressions, then #t is returned.
+
+(and (= 2 2) (> 2 1)) ⟹ #t
+(and (= 2 2) (< 2 1)) ⟹ #f
+(and 1 2 'c '(f g)) ⟹ (f g)
+(and) ⟹ #t
+
+syntax: (or <test1> …)
+
+Semantics: The <test> expressions are evaluated from left to right, and the value of the
+first expression that evaluates to a true value (see section 6.3) is returned. Any remaining
+expressions are not evaluated. If all expressions evaluate to #f or if there are no
+expressions, then #f is returned.
+
+(or (= 2 2) (> 2 1)) ⟹ #t
+(or (= 2 2) (< 2 1)) ⟹ #t
+(or #f #f #f) ⟹ #f
+(or (memq 'b '(a b c))
+ (/ 3 0)) ⟹ (b c)
+
+syntax: (when <test> <expression1> <expression2> …)
+
+Syntax: The <test> is an expression.
+
+Semantics: The test is evaluated, and if it evaluates to a true value, the expressions are
+evaluated in order. The result of the when expression is unspecified.
+
+(when (= 1 1.0)
+ (display "1")
+ (display "2")) ⟹ unspecified
+ and prints 12
+
+syntax: (unless <test> <expression1> <expression2> …)
+
+Syntax: The <test> is an expression.
+
+Semantics: The test is evaluated, and if it evaluates to #f, the expressions are evaluated in
+order. The result of the unless expression is unspecified.
+
+(unless (= 1 1.0)
+ (display "1")
+ (display "2")) ⟹ unspecified
+ and prints nothing
+
+syntax: (cond-expand <ce-clause1> <ce-clause2> …)
+
+Syntax: The cond-expand expression type provides a way to statically expand different
+expressions depending on the implementation. A <ce-clause> takes the following form:
+
+(<feature requirement> <expression> …)
+
+The last clause can be an “else clause,” which has the form
+
+(else <expression> …)
+
+A <feature requirement> takes one of the following forms:
+
+* <feature identifier>
+
+* (library <library name>)
+
+* (and <feature requirement> …)
+
+* (or <feature requirement> …)
+
+* (not <feature requirement>)
+
+Semantics: Each implementation maintains a list of feature identifiers which are present,
+as well as a list of libraries which can be imported. The value of a <feature requirement> is
+determined by replacing each <feature identifier> and (library <library name>) on the
+implementation’s lists with #t, and all other feature identifiers and library names with #f,
+then evaluating the resulting expression as a Scheme boolean expression under the
+normal interpretation of and, or, and not.
+
+A cond-expand is then expanded by evaluating the <feature requirement>s of successive
+<ce-clause>s in order until one of them returns #t. When a true clause is found, the
+corresponding <expression>s are expanded to a begin, and the remaining clauses are
+ignored. If none of the <feature requirement>s evaluate to #t, then if there is an else
+clause, its <expression>s are included. Otherwise, the behavior of the cond-expand is
+unspecified. Unlike cond, cond-expand does not depend on the value of any variables.
+
+The exact features provided are implementation-defined, but for portability a core set of
+features is given in appendix B.
+
@node Binding constructs
@subsection Binding constructs
+
+The binding constructs let, let*, letrec, letrec*, let-values, and let*-values give Scheme a
+block structure, like Algol 60. The syntax of the first four constructs is identical, but they
+differ in the regionsthey establish for their variable bindings. 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; while in letrec and
+letrec* expressions, all the bindings are in effect while their initial values are being
+computed, thus allowing mutually recursive definitions. The let-values and let*-values
+constructs are analogous to let and let* respectively, but are designed to handle
+multiple-valued expressions, binding different identifiers to the returned values.
+
+syntax: (let <bindings> <body>)
+
+Syntax: <Bindings> has the form
+
+((<variable1> <init1>) …),where each <init> is an expression, and <body> is a sequence of
+zero or more definitions followed by a sequence of one or more expressions as described
+in section 4.1.4. It is an error for a <variable> to appear more than once in the list of
+variables being bound.
+
+Semantics: The <init>s are evaluated in the current environment (in some unspecified
+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 4.2.4.
+
+syntax: (let* <bindings> <body>)
+
+Syntax: <Bindings> has the form
+
+((<variable1> <init1>) …),and <body> is a sequence of zero or more definitions followed by
+one or more expressions as described in section 4.1.4.
+
+Semantics: The let* binding construct is similar to let, but the bindings are performed
+sequentially from left to right, and the regionof a binding indicated by (<variable> <init>)
+is that part of the let* expression to the right of the binding. Thus the second binding is
+done in an environment in which the first binding is visible, and so on. The <variable>s
+need not be distinct.
+
+(let ((x 2) (y 3))
+ (let* ((x 7)
+ (z (+ x y)))
+ (* z x))) ⟹ 70
+
+syntax: (letrec <bindings> <body>)
+
+Syntax: <Bindings> has the form
+
+((<variable1> <init1>) …),and <body> is a sequence of zero or more definitions followed by
+one or more expressions as described in section 4.1.4. It is an error for a <variable> to
+appear more than once in the list of variables being bound.
+
+Semantics: The <variable>s are bound to fresh locations holding unspecified values, the
+<init>s are evaluated in the resulting environment (in some unspecified 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 define mutually recursive procedures.
+
+(letrec ((even?
+ (lambda (n)
+ (if (zero? n)
+ #t
+ (odd? (- n 1)))))
+ (odd?
+ (lambda (n)
+ (if (zero? n)
+ #f
+ (even? (- n 1))))))
+ (even? 88))
+⟹ #t One restriction on letrec is very important: if it is not possible to evaluate each <init>
+without assigning or referring to the value of any <variable>, it is an error. The restriction
+is necessary because letrec is defined in terms of a procedure call where a lambda
+expression binds the <variable>s to the values of the <init>s. In the most common uses of
+letrec, all the <init>s are lambda expressions and the restriction is satisfied automatically.
+
+syntax: (letrec* <bindings> <body>)
+
+Syntax: <Bindings> has the form
+
+((<variable1> <init1>) …),and <body>is a sequence of zero or more definitions followed by
+one or more expressions as described in section 4.1.4. It is an error for a <variable> to
+appear more than once in the list of variables being bound.
+
+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> (interleaving
+evaluations and assignments), 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 define mutually recursive procedures.
+
+If it is not 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>, it is an error. Another restriction is that it is an error to invoke the
+continuation of an <init> more than once.
+
+;; Returns the arithmetic, geometric, and
+;; harmonic means of a nested list of numbers
+(define (means ton)
+ (letrec*
+ ((mean
+ (lambda (f g)
+ (f (/ (sum g ton) n))))
+ (sum
+ (lambda (g ton)
+ (if (null? ton)
+ (+)
+ (if (number? ton)
+ (g ton)
+ (+ (sum g (car ton))
+ (sum g (cdr ton)))))))
+ (n (sum (lambda (x) 1) ton)))
+ (values (mean values values)
+ (mean exp log)
+ (mean / /))))
+Evaluating (means '(3 (1 4))) returns three values: 8/3, 2.28942848510666 (approximately),
+and 36/19.
+
+syntax: (let-values <mv binding spec> <body>)
+
+Syntax: <Mv binding spec> has the form
+
+((<formals1> <init1>) …), where each <init> is an expression, and <body> is zero or more
+definitions followed by a sequence of one or more expressions as described in section
+4.1.4. It is an error for a variable to appear more than once in the set of <formals>.
+
+Semantics: The <init>s are evaluated in the current environment (in some unspecified
+order) as if by invoking call-with-values, and the variables occurring in the <formals> are
+bound to fresh locations holding 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.
+
+It is an error if the <formals> do not match the number of values returned by the
+corresponding <init>.
+
+(let-values (((root rem) (exact-integer-sqrt 32)))
+ (* root rem)) ⟹ 35
+
+syntax: (let*-values <mv binding spec> <body>)
+
+Syntax: <Mv binding spec> has the form
+
+((<formals> <init>) …),and <body> is a sequence of zero or more definitions followed by
+one or more expressions as described in section 4.1.4. In each <formals>, it is an error if
+any variable appears more than once.
+
+Semantics: The let*-values construct 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 <init>s to its right as well as <body>. Thus the second <init>
+is evaluated in an environment in which the first set of bindings 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)
+
@node Sequencing
@subsection Sequencing
+
+Both of Scheme’s sequencing constructs are named begin, but the two have slightly
+different forms and uses:
+
+syntax: (begin <expression or definition> …)
+
+This form of begin can appear as part of a <body>, or at the outermost level of a
+<program>, or at the REPL, or directly nested in a begin that is itself of this form. It causes
+the contained expressions and definitions to be evaluated exactly as if the enclosing begin
+construct were not present.
+
+ Rationale: This form is commonly used in the output of macros (see section 4.3) which
+ need to generate multiple definitions and splice them into the context in which they
+ are expanded.
+
+syntax: (begin <expression1> <expression2> …)
+
+This form of begin can be used as an ordinary expression. 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 effects such as assignments or
+input and output.
+
+(define x 0)
+
+(and (= x 0)
+ (begin (set! x 5)
+ (+ x 1))) ⟹ 6
+
+(begin (display "4 plus 1 equals ")
+ (display (+ 4 1))) ⟹ unspecified
+ and prints 4 plus 1 equals 5
+
+Note that there is a third form of begin used as a library declaration: see section 5.6.1.
+
@node Iteration
@subsection Iteration
+
+syntax: (do ((<variable1> <init1> <step1>)
+…)
+(<test> <expression> …)
+<command> …)
+
+Syntax: All of <init>, <step>, <test>, and <command> are expressions.
+
+Semantics: A do expression is an iteration construct. It specifies a set of variables to be
+bound, how they are to be initialized at the start, and how they are to be updated on each
+iteration. When a termination condition is met, the loop exits after evaluating the
+<expression>s.
+
+A do expression is evaluated as follows: The <init> expressions are evaluated (in some
+unspecified order), the <variable>s are bound to fresh locations, the results of the <init>
+expressions are stored in the bindings of the <variable>s, and then the iteration phase
+begins.
+
+Each iteration begins by evaluating <test>; if the result is false (see section 6.3), then the
+<command> expressions are evaluated in order for effect, the <step> expressions are
+evaluated in some unspecified order, the <variable>s are bound to fresh locations, the
+results of the <step>s are stored in the bindings of the <variable>s, and the next iteration
+begins.
+
+If <test> evaluates to a true value, then the <expression>s are evaluated from left to right
+and the values of the last <expression> are returned. If no <expression>s are present,
+then the value of the do expression is unspecified.
+
+The regionof the binding of a <variable> consists of the entire do expression except for
+the <init>s. It is an error for a <variable> to appear more than once in the list of do
+variables.
+
+A <step> can be omitted, in which case the effect is the same as if (<variable> <init>
+<variable>) had been written instead of (<variable> <init>).
+
+(do ((vec (make-vector 5))
+ (i 0 (+ i 1)))
+ ((= i 5) vec)
+ (vector-set! vec i i)) ⟹ #(0 1 2 3 4)
+
+(let ((x '(1 3 5 7 9)))
+ (do ((x x (cdr x))
+ (sum 0 (+ sum (car x))))
+ ((null? x) sum))) ⟹ 25
+
+syntax: (let <variable> <bindings> <body>)
+
+Semantics: “Named let” is a variant on the syntax of let which provides a more general
+looping construct than do and can also be used to express recursion. It has the same
+syntax and semantics as ordinary let except that <variable> is bound within <body> to a
+procedure whose formal arguments are the bound variables and whose body is <body>.
+Thus the execution of <body> can 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))
+
@node Delayed evaluation
@subsection Delayed evaluation
+
+lazy library syntax: (delay <expression>)
+
+Semantics: The delay construct is used together with the procedure force to implement
+lazy evaluation or call by need. (delay <expression>) returns an object called a promise which
+at some point in the future can be asked (by the force procedure) to evaluate
+<expression>, and deliver the resulting value. The effect of <expression> returning
+multiple values is unspecified.
+
+lazy library syntax: (delay-force <expression>)
+
+Semantics: The expression (delay-force
+
+expression) is conceptually similar to (delay (force
+
+expression)), with the difference that forcing the result of delay-force will in effect result in
+a tail call to (force
+
+expression), while forcing the result of (delay (force
+
+expression)) might not. Thus iterative lazy algorithms that might result in a long series of
+chains of delay and force can be rewritten using delay-force to prevent consuming
+unbounded space during evaluation.
+
+lazy library procedure: (force promise)
+
+The force procedure forces the value of a
+
+promise created by delay, delay-force, or make-promise.If no value has been computed for
+the promise, then a value is computed and returned. The value of the promise must be
+cached (or “memoized”) so that if it is forced a second time, the previously computed
+value is returned. Consequently, a delayed expression is evaluated using the parameter
+values and exception handler of the call to force which first requested its value. If
+
+promise is not a promise, it may be returned unchanged.
+
+(force (delay (+ 1 2))) ⟹ 3
+(let ((p (delay (+ 1 2))))
+ (list (force p) (force p)))
+ ⟹ (3 3)
+
+(define integers
+ (letrec ((next
+ (lambda (n)
+ (delay (cons n (next (+ n 1)))))))
+ (next 0)))
+(define head
+ (lambda (stream) (car (force stream))))
+(define tail
+ (lambda (stream) (cdr (force stream))))
+
+(head (tail (tail integers)))
+ ⟹ 2 The following example is a mechanical transformation of a lazy
+stream-filtering algorithm into Scheme. Each call to a constructor is wrapped in delay, and
+each argument passed to a deconstructor is wrapped in force. The use of (delay-force ...)
+instead of (delay (force ...)) around the body of the procedure ensures that an
+ever-growing sequence of pending promises does not exhaust available storage, because
+force will in effect force such sequences iteratively.
+
+(define (stream-filter p? s)
+ (delay-force
+ (if (null? (force s))
+ (delay '())
+ (let ((h (car (force s)))
+ (t (cdr (force s))))
+ (if (p? h)
+ (delay (cons h (stream-filter p? t)))
+ (stream-filter p? t))))))
+
+(head (tail (tail (stream-filter odd? integers))))
+ ⟹ 5 The following examples are not intended to illustrate good
+programming style, as delay, force, and delay-force are mainly intended for programs
+written in the functional style. However, they do illustrate the property that only one value
+is computed for a promise, no matter how many times it is forced.
+
+(define count 0)
+(define p
+ (delay (begin (set! count (+ count 1))
+ (if (> count x)
+ count
+ (force p)))))
+(define x 5)
+p ⟹ a promise
+(force p) ⟹ 6
+p ⟹ a promise, still
+(begin (set! x 10)
+ (force p)) ⟹ 6 Various extensions to this semantics of delay, force and delay-force
+are supported in some implementations:
+
+* Calling force on an object that is not a promise may simply return the object.
+
+* It may be the case that there is no means by which a promise can be operationally
+ distinguished from its forced value. That is, expressions like the following may evaluate
+ to either #t or to #f, depending on the implementation:
+
+ (eqv? (delay 1) 1) ⟹ unspecified
+ (pair? (delay (cons 1 2))) ⟹ unspecified
+* Implementations may implement “implicit forcing,” where the value of a promise is
+ forced by procedures that operate only on arguments of a certain type, like cdr and *.
+ However, procedures that operate uniformly on their arguments, like list, must not
+ force them.
+
+ (+ (delay (* 3 7)) 13) ⟹ unspecified
+ (car
+ (list (delay (* 3 7)) 13)) ⟹ a promise
+
+lazy library procedure: (promise?
+
+obj)
+
+
+The promise? procedure returns #t if its argument is a promise, and #f otherwise. Note
+that promises are not necessarily disjoint from other Scheme types such as procedures.
+
+lazy library procedure: (make-promise
+
+obj)
+
+
+The make-promise procedure returns a promise which, when forced, will return
+
+obj. It is similar to delay, but does not delay its argument: it is a procedure rather than
+syntax. If
+
+obj is already a promise, it is returned.
+
@node Dynamic bindings
@subsection Dynamic bindings
+
+The dynamic extent of a procedure call is the time between when it is initiated and when it
+returns. In Scheme, call-with-current-continuation (section 6.10) allows reentering a
+dynamic extent after its procedure call has returned. Thus, the dynamic extent of a call
+might not be a single, continuous time period.
+
+This sections introduces parameter objects, which can be bound to new values for the
+duration of a dynamic extent. The set of all parameter bindings at a given time is called
+the dynamic environment.
+
+procedure: (make-parameter init)
+procedure: (make-parameter init converter)
+
+Returns a newly allocated parameter object, which is a procedure that accepts zero
+arguments and returns the value associated with the parameter object. Initially, this value
+is the value of (
+
+converter
+
+init), or of
+
+init if the conversion procedure
+
+converter is not specified. The associated value can be temporarily changed using
+parameterize, which is described below.
+
+The effect of passing arguments to a parameter object is implementation-dependent.
+
+syntax: (parameterize ((<param1> <value1>) …)
+ <body>)
+
+Syntax: Both <param1> and <value1> are expressions.
+
+It is an error if the value of any <param> expression is not a parameter object.
+
+Semantics: A parameterize expression is used to change the values returned by specified
+parameter objects during the evaluation of the body.
+
+The <param> and <value> expressions are evaluated in an unspecified order. The <body>
+is evaluated in a dynamic environment in which calls to the parameters return the results
+of passing the corresponding values to the conversion procedure specified when the
+parameters were created. Then the previous values of the parameters are restored
+without passing them to the conversion procedure. The results of the last expression in
+the <body> are returned as the results of the entire parameterize expression.
+
+ Note: If the conversion procedure is not idempotent, the results of (parameterize ((x
+ (x))) ...), which appears to bind the parameter
+
+ x to its current value, might not be what the user expects.
+
+If an implementation supports multiple threads of execution, then parameterize must not
+change the associated values of any parameters in any thread other than the current
+thread and threads created inside <body>.
+
+Parameter objects can be used to specify configurable settings for a computation
+without the need to pass the value to every procedure in the call chain explicitly.
+
+(define radix
+ (make-parameter
+ 10
+ (lambda (x)
+ (if (and (exact-integer? x) (<= 2 x 16))
+ x
+ (error "invalid radix")))))
+
+(define (f n) (number->string n (radix)))
+
+(f 12) ⟹ "12"
+(parameterize ((radix 2))
+ (f 12)) ⟹ "1100"
+(f 12) ⟹ "12"
+
+(radix 16) ⟹ unspecified
+
+(parameterize ((radix 0))
+ (f 12)) ⟹ error
+
@node Exception handling
@subsection Exception handling
+
+syntax: (guard (<variable>
+ <cond clause1> <cond clause2> …)
+ <body>)
+
+Syntax: Each <cond clause> is as in the specification of cond.
+
+Semantics: The <body> is evaluated with an exception handler that binds the raised object
+(see raise in section 6.11) to <variable> and, within the scope of that binding, evaluates the
+clauses as if they were the clauses of a cond expression. That implicit cond expression is
+evaluated with the continuation and dynamic environment of the guard expression. If
+every <cond clause>’s <test> evaluates to #f and there is no else clause, then
+raise-continuable is invoked on the raised object within the dynamic environment of the
+original call to raise or raise-continuable, except that the current exception handler is that
+of the guard expression.
+
+See section 6.11 for a more complete discussion of exceptions.
+
+(guard (condition
+ ((assq 'a condition) => cdr)
+ ((assq 'b condition)))
+ (raise (list (cons 'a 42))))
+⟹ 42
+
+(guard (condition
+ ((assq 'a condition) => cdr)
+ ((assq 'b condition)))
+ (raise (list (cons 'b 23))))
+⟹ (b . 23)
+
@node Quasiquotation
@subsection Quasiquotation
+
+syntax: (quasiquote <qq template>)
+syntax: `<qq template>
+auxiliary syntax: unquote
+auxiliary syntax: ,
+auxiliary syntax: unquote-splicing
+auxiliary syntax: ,﹫
+
+“Quasiquote”expressions are useful for constructing a list or vector structure when some
+but not all of the desired structure is known in advance. If no commasappear within the
+<qq template>, the result of evaluating `<qq template> is equivalent to the result of
+evaluating '<qq template>. If a commaappears within the <qq template>, however, the
+expression following the comma is evaluated (“unquoted”) and its result is inserted into
+the structure instead of the comma and the expression. If a comma appears followed
+without intervening whitespace by a commercial at-sign (﹫),then it is an error if the
+following expression does not evaluate to a list; the opening and closing parentheses of
+the list are then “stripped away” and the elements of the list are inserted in place of the
+comma at-sign expression sequence. A comma at-sign normally appears only within a list
+or vector <qq template>.
+
+ Note: In order to unquote an identifier beginning with @, it is necessary to use either
+ an explicit unquote or to put whitespace after the comma, to avoid colliding with the
+ comma at-sign sequence.
+
+`(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 ((foo '(foo bar)) (@baz 'baz))
+ `(list ,@foo , @baz))
+⟹ (list foo bar baz) Quasiquote expressions can be nested. Substitutions are made only
+for unquoted components appearing at the same nesting 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 newly allocated, mutable
+objects or literal structure for any structure that is constructed at run time during the
+evaluation of the expression. Portions that do not need to be rebuilt are always literal.
+Thus,
+
+(let ((a 3)) `((1 2) ,a ,4 ,'five 6)) may be treated as 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)))))) However, it is not equivalent to this expression:
+
+(let ((a 3)) (list (list 1 2) a 4 'five 6)) The two notations `<qq template> and (quasiquote <qq
+template>) are identical in all respects. ,<expression> is identical to (unquote
+<expression>), and ,@<expression> is identical to (unquote-splicing <expression>). The
+write procedure may output either format.
+
+(quasiquote (list (unquote (+ 1 2)) 4))
+⟹ (list 3 4)
+'(quasiquote (list (unquote (+ 1 2)) 4))
+⟹ `(list ,(+ 1 2) 4)
+ i.e., (quasiquote (list (unquote (+ 1 2)) 4))
+
+It is an error if any of the identifiers quasiquote, unquote, or unquote-splicing appear in
+positions within a <qq template> otherwise than as described above.
+
@node Case-lambda
@subsection Case-lambda
+
+case-lambda library syntax: (case-lambda <clause> …)
+
+Syntax: Each <clause> is of the form (<formals> <body>), where <formals> and <body>
+have the same syntax as in a lambda expression.
+
+Semantics: A case-lambda expression evaluates to a procedure that accepts a variable
+number of arguments and is lexically scoped in the same manner as a procedure resulting
+from a lambda expression. When the procedure is called, the first <clause> for which the
+arguments agree with <formals> is selected, where agreement is specified as for the
+<formals> of a lambda expression. The variables of <formals> are bound to fresh
+locations, the values of the arguments are stored in those locations, the <body> is
+evaluated in the extended environment, and the results of <body> are returned as the
+results of the procedure call.
+
+It is an error for the arguments not to agree with the <formals> of any <clause>.
+
+(define range
+ (case-lambda
+ ((e) (range 0 e))
+ ((b e) (do ((r '() (cons e r))
+ (e (- e 1) (- e 1)))
+ ((< e b) r)))))
+
+(range 3) ⟹ (0 1 2)
+(range 3 5) ⟹ (3 4)
+
@node Macros
@section Macros
+
+Scheme programs can define and use new derived expression types, called
+macros.Program-defined expression types have the syntax
+
+(<keyword> <datum> ...)where <keyword> is an identifier that uniquely determines the
+expression type. This identifier is called the syntactic keyword, or simply keyword, of the
+macro. The number of the <datum>s, and their syntax, depends on the expression type.
+
+Each instance of a macro is called a useof the macro. The set of rules that specifies how a
+use of a macro is transcribed into a more primitive expression is called the transformerof
+the macro.
+
+The macro definition facility consists of two parts:
+
+* A set of expressions used to establish that certain identifiers are macro keywords,
+ associate them with macro transformers, and control the scope within which a macro
+ is defined, and
+
+* a pattern language for specifying macro transformers.
+
+The syntactic keyword of a macro can shadow variable bindings, and local variable
+bindings can shadow syntactic bindings. Two mechanisms are provided to prevent
+unintended conflicts:
+
+* If a macro transformer inserts a binding for an identifier (variable or keyword), the
+ identifier will in effect be renamed throughout its scope to avoid conflicts with other
+ identifiers. Note that a global variable definition may or may not introduce a binding;
+ see section 5.3.
+
+* If a macro transformer inserts a free reference to an identifier, the reference refers to
+ the binding that was visible where the transformer was specified, regardless of any
+ local bindings that surround the use of the macro.
+
+In consequence, all macros defined using the pattern language are “hygienic” and
+“referentially transparent” and thus preserve Scheme’s lexical scoping. [21, 22, 2, 9, 12]
+
+Implementations may provide macro facilities of other types.
+
@node Binding constructs for syntactic keywords
@subsection Binding constructs for syntactic keywords
+
+The let-syntax and letrec-syntax binding constructs are analogous to let and letrec, but
+they bind syntactic keywords to macro transformers instead of binding variables to
+locations that contain values. Syntactic keywords can also be bound globally or locally
+with define-syntax; see section 5.4.
+
+syntax: (let-syntax <bindings> <body>)
+
+Syntax: <Bindings> has the form
+
+((<keyword> <transformer spec>) …)Each <keyword> is an identifier, each <transformer
+spec> is an instance of syntax-rules, and <body> is a sequence of zero or more
+definitions followed by one or more expressions. It is an error for a <keyword> to
+appear more than once in the list of keywords being bound.
+
+Semantics: The <body> is expanded in the syntactic environment obtained by extending
+the syntactic environment of the let-syntax expression with macros whose keywords are
+the <keyword>s, bound to the specified transformers. Each binding of a <keyword> has
+<body> as its region.
+
+(let-syntax ((given-that (syntax-rules ()
+ ((given-that test stmt1 stmt2 ...)
+ (if test
+ (begin stmt1
+ stmt2 ...))))))
+ (let ((if #t))
+ (given-that if (set! if 'now))
+ if)) ⟹ now
+
+(let ((x 'outer))
+ (let-syntax ((m (syntax-rules () ((m) x))))
+ (let ((x 'inner))
+ (m)))) ⟹ outer
+
+syntax: (letrec-syntax <bindings> <body>)
+
+Syntax: Same as for let-syntax.
+
+Semantics: The <body> is expanded in the syntactic environment obtained by extending
+the syntactic environment of the letrec-syntax expression with macros whose keywords
+are the <keyword>s, bound to the specified transformers. Each binding of a <keyword>
+has the <transformer spec>s as well as the <body> within its region, so the transformers
+can transcribe expressions into uses of the macros introduced by the letrec-syntax
+expression.
+
+(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
+
@node Pattern language
@subsection Pattern language
+
+A <transformer spec> has one of the following forms:
+
+syntax: (syntax-rules (<pattern literal> …)
+ <syntax rule> …)
+syntax: (syntax-rules <ellipsis> (<pattern literal> …)
+ <syntax rule> …)
+auxiliary syntax: _
+auxiliary syntax: …
+
+Syntax: It is an error if any of the <pattern literal>s, or the <ellipsis> in the second form, is
+not an identifier. It is also an error if <syntax rule> is not of the form
+
+(<pattern> <template>)The <pattern> in a <syntax rule> is a list <pattern> whose first
+element is an identifier.
+
+A <pattern> is either an identifier, a constant, or one of the following
+
+(<pattern> …)
+(<pattern> <pattern> … . <pattern>)
+(<pattern> … <pattern> <ellipsis> <pattern> …)
+(<pattern> … <pattern> <ellipsis> <pattern> …
+ . <pattern>)
+#(<pattern> …)
+#(<pattern> … <pattern> <ellipsis> <pattern> …)and a <template> is either an identifier, a
+constant, or one of the following (<element> …)
+(<element> <element> … . <template>)
+(<ellipsis> <template>)
+#(<element> …)where an <element> is a <template> optionally followed by an <ellipsis>.
+An <ellipsis> is the identifier specified in the second form of syntax-rules, or the default
+identifier ... (three consecutive periods) otherwise.
+
+Semantics: An instance of syntax-rules produces a new macro transformer by specifying a
+sequence of hygienic rewrite rules. A use of a macro whose keyword is associated with a
+transformer specified by syntax-rules is matched against the patterns contained in the
+<syntax rule>s, beginning with the leftmost <syntax rule>. When a match is found, the
+macro use is transcribed hygienically according to the template.
+
+An identifier appearing within a <pattern> can be an underscore (_), a literal identifier
+listed in the list of <pattern literal>s, or the <ellipsis>. All other identifiers appearing
+within a <pattern> are pattern variables.
+
+The keyword at the beginning of the pattern in a <syntax rule> is not involved in the
+matching and is considered neither a pattern variable nor a literal identifier.
+
+Pattern variables match arbitrary input elements and are used to refer to elements of
+the input in the template. It is an error for the same pattern variable to appear more
+than once in a <pattern>.
+
+Underscores also match arbitrary input elements but are not pattern variables and so
+cannot be used to refer to those elements. If an underscore appears in the <pattern
+literal>s list, then that takes precedence and underscores in the <pattern> match as
+literals. Multiple underscores can appear in a <pattern>.
+
+Identifiers that appear in (<pattern literal> …) are interpreted as literal identifiers to be
+matched against corresponding elements of the input. An element in the input matches
+a literal identifier if and only if it is an identifier and either both its occurrence in the
+macro expression and its occurrence in the macro definition have the same lexical
+binding, or the two identifiers are the same and both have no lexical binding.
+
+A subpattern followed by <ellipsis> can match zero or more elements of the input,
+unless <ellipsis> appears in the <pattern literal>s, in which case it is matched as a literal.
+
+More formally, an input expression E matches a pattern P if and only if:
+
+* P is an underscore (_).
+
+* P is a non-literal identifier; or
+
+* P is a literal identifier and E is an identifier with the same binding; or
+
+* P is a list (P1 … Pn) and E is a list of n elements that match P1 through Pn, respectively;
+ or
+
+* P is an improper list (P1P2 … Pn . Pn+1) and E is a list or improper list of n or more
+ elements that match P1 through Pn, respectively, and whose nth tail matches Pn+1; or
+
+* P is of the form (P1 … PkPe <ellipsis> Pm+1 … Pn) where E is a proper list of n elements,
+ the first k of which match P1 through Pk, respectively, whose next m−k elements each
+ match Pe, whose remaining n−m elements match Pm+1 through Pn; or
+
+* P is of the form (P1 … PkPe <ellipsis> Pm+1 … Pn . Px) where E is a list or improper list of n
+ elements, the first k of which match P1 through Pk, whose next m−k elements each
+ match Pe, whose remaining n−m elements match Pm+1 through Pn, and whose nth and
+ final cdr matches Px; or
+
+* P is a vector of the form #(P1 … Pn) and E is a vector of n elements that match P1
+ through Pn; or
+
+* P is of the form #(P1 … PkPe <ellipsis> Pm+1 …Pn) where E is a vector of n elements the
+ first k of which match P1 through Pk, whose next m−k elements each match Pe, and
+ whose remaining n−m elements match Pm+1 through Pn; or
+
+* P is a constant and E is equal to P in the sense of the equal? procedure.
+
+It is an error to use a macro keyword, within the scope of its binding, in an expression
+that does not match any of the patterns.
+
+When a macro use is transcribed according to the template of the matching <syntax
+rule>, pattern variables that occur in the template are replaced by the elements they
+match in the input. Pattern variables that occur in subpatterns followed by one or more
+instances of the identifier <ellipsis> are allowed only in subtemplates that are followed
+by as many instances of <ellipsis>. They are replaced in the output by all of the elements
+they match in the input, distributed as indicated. It is an error if the output cannot be
+built up as specified.
+
+Identifiers that appear in the template but are not pattern variables or the identifier
+<ellipsis> are inserted into the output as literal identifiers. If a literal identifier is inserted
+as a free identifier then it refers to the binding of that identifier within whose scope the
+instance of syntax-rules appears. If a literal identifier is inserted as a bound identifier
+then it is in effect renamed to prevent inadvertent captures of free identifiers.
+
+A template of the form (<ellipsis> <template>) is identical to <template>, except that
+ellipses within the template have no special meaning. That is, any ellipses contained
+within <template> are treated as ordinary identifiers. In particular, the template
+(<ellipsis> <ellipsis>) produces a single <ellipsis>. This allows syntactic abstractions to
+expand into code 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, if let and cond are defined as in section 7.3 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 base identifier =>, which the macro
+transformer treats as a syntactic keyword. Thus the example expands into
+
+(let ((=> #f))
+ (if #t (begin => 'ok))) instead of
+
+(let ((=> #f))
+ (let ((temp #t))
+ (if temp ('ok temp)))) which would result in an invalid procedure call.
+
@node Signaling errors in macro transformers
@subsection Signaling errors in macro transformers
+syntax: (syntax-error <message> <args> …)
+
+syntax-error behaves similarly to error (6.11) except that implementations with an
+expansion pass separate from evaluation should signal an error as soon as syntax-error
+is expanded. This can be used as a syntax-rules <template> for a <pattern> that is an
+invalid use of the macro, which can provide more descriptive error messages.
+<message> is a string literal, and <args> arbitrary expressions providing additional
+information. Applications cannot count on being able to catch syntax errors with
+exception handlers or guards.
+
+(define-syntax simple-let
+ (syntax-rules ()
+ ((_ (head ... ((x . y) val) . tail)
+ body1 body2 ...)
+ (syntax-error
+ "expected an identifier but got"
+ (x . y)))
+ ((_ ((name val) ...) body1 body2 ...)
+ ((lambda (name ...) body1 body2 ...)
+ val ...))))
+
@node Program structure
@chapter Program structure
+
@node Programs
@section Programs
+
+A Scheme program consists of one or more import declarations followed by a sequence
+of expressions and definitions. Import declarations specify the libraries on which a
+program or library depends; a subset of the identifiers exported by the libraries are made
+available to the program. Expressions are described in chapter 4. Definitions are either
+variable definitions, syntax definitions, or record-type definitions, all of which are
+explained in this chapter. They are valid in some, but not all, contexts where expressions
+are allowed, specifically at the outermost level of a <program> and at the beginning of a
+<body>.
+
+At the outermost level of a program, (begin <expression or definition1> …) is equivalent to
+the sequence of expressions and definitions in the begin. Similarly, in a <body>, (begin
+<definition1> …) is equivalent to the sequence <definition1> …. Macros can expand into
+such begin forms. For the formal definition, see 4.2.3.
+
+Import declarations and definitions cause bindings to be created in the global
+environment or modify the value of existing global bindings. The initial environment of a
+program is empty, so at least one import declaration is needed to introduce initial
+bindings.
+
+Expressions occurring at the outermost level of a program do not create any bindings.
+They are executed in order when the program is invoked or loaded, and typically perform
+some kind of initialization.
+
+Programs and libraries are typically stored in files, although in some implementations
+they can be entered interactively into a running Scheme system. Other paradigms are
+possible. Implementations which store libraries in files should document the mapping
+from the name of a library to its location in the file system.
+
@node Import declarations
@section Import declarations
+
+An import declaration takes the following form:
+
+(import <import-set> …)
+An import declaration provides a way to import identifiers exported by a library. Each
+<import set> names a set of bindings from a library and possibly specifies local names for
+the imported bindings. It takes one of the following forms:
+
+* <library name>
+
+* (only <import set> <identifier> …)
+
+* (except <import set> <identifier> …)
+
+* (prefix <import set> <identifier>)
+
+* (rename <import set>
+ (<identifier1> <identifier2>) …)
+
+In the first form, all of the identifiers in the named library’s export clauses are imported
+with the same names (or the exported names if exported with rename). The additional
+<import set> forms modify this set as follows:
+
+* only produces a subset of the given <import set> including only the listed identifiers
+ (after any renaming). It is an error if any of the listed identifiers are not found in the
+ original set.
+
+* except produces a subset of the given <import set>, excluding the listed identifiers
+ (after any renaming). It is an error if any of the listed identifiers are not found in the
+ original set.
+
+* rename modifies the given <import set>, replacing each instance of <identifier1> with
+ <identifier2>. It is an error if any of the listed <identifier1>s are not found in the original
+ set.
+
+* prefix automatically renames all identifiers in the given <import set>, prefixing each
+ with the specified <identifier>.
+
+In a program or library declaration, it is an error to import the same identifier more than
+once with different bindings, or to redefine or mutate an imported binding with a
+definition or with set!, or to refer to an identifier before it is imported. However, a REPL
+should permit these actions.
+
@node Variable definitions
@section Variable definitions
@node Top level definitions