commit 22c3d49b6fda769830ee182cd5cb6f7bddfad6a8
parent a4b6859b932ef42a30865acec9a538fa0d069abe
Author: Yuval Langer <yuvallangerontheroad@gmail.com>
Date: Sat, 27 Jan 2024 17:54:44 +0200
Add more chapters, sections, and subsections.
Diffstat:
1 file changed, 4959 insertions(+), 32 deletions(-)
diff --git a/doc/r7rs-small/r7rs-small.texinfo b/doc/r7rs-small/r7rs-small.texinfo
@@ -2320,75 +2320,5002 @@ should permit these actions.
@node Variable definitions
@section Variable definitions
+
+A variable definition binds one or more identifiers and specifies an initial value for each of
+them. The simplest kind of variable definition takes one of the following forms:
+
+* (define <variable> <expression>)
+
+* (define (<variable> <formals>) <body>)
+
+ <Formals> are either a sequence of zero or more variables, or a sequence of one or
+ more variables followed by a space-delimited period and another variable (as in a
+ lambda expression). This form is equivalent to
+
+ (define <variable>
+ (lambda (<formals>) <body>)).
+* (define (<variable> . <formal>) <body>)
+
+ <Formal> is a single variable. This form is equivalent to
+
+ (define <variable>
+ (lambda <formal> <body>)).
+
@node Top level definitions
@subsection Top level definitions
+
+At the outermost level of a program, a definition
+
+(define <variable> <expression>)has essentially the same effect as the assignment
+expression (set! <variable> <expression>)if <variable> is bound to a non-syntax value.
+However, if <variable> is not bound, or is a syntactic keyword, then the definition will bind
+<variable> to a new location before performing the assignment, whereas it would be an
+error to perform a set! on an unboundvariable.
+
+(define add3
+ (lambda (x) (+ x 3)))
+(add3 3) ⟹ 6
+(define first car)
+(first '(1 2)) ⟹ 1
+
@node Internal definitions
@subsection Internal definitions
+
+Definitions can occur at the beginning of a <body> (that is, the body of a lambda, let, let*,
+letrec, letrec*, let-values, let*-values, let-syntax, letrec-syntax, parameterize, guard, or
+case-lambda). Note that such a body might not be apparent until after expansion of other
+syntax. Such definitions are known as internal definitionsas opposed to the global
+definitions described above. The variables defined by internal definitions are local to the
+<body>. That is, <variable> is bound rather than assigned, and the region of the binding is
+the entire <body>. For example,
+
+(let ((x 5))
+ (define foo (lambda (y) (bar x y)))
+ (define bar (lambda (a b) (+ (* a b) a)))
+ (foo (+ x 3))) ⟹ 45 An expanded <body> containing internal definitions can always
+be converted into a completely equivalent letrec* expression. For example, the let
+expression in the above example is equivalent to
+
+(let ((x 5))
+ (letrec* ((foo (lambda (y) (bar x y)))
+ (bar (lambda (a b) (+ (* a b) a))))
+ (foo (+ x 3)))) Just as for the equivalent letrec* expression, it is an error if it is not
+possible to evaluate each <expression> of every internal definition in a <body> without
+assigning or referring to the value of the corresponding <variable> or the <variable> of
+any of the definitions that follow it in <body>.
+
+It is an error to define the same identifier more than once in the same <body>.
+
+Wherever an internal definition can occur, (begin <definition1> …) is equivalent to the
+sequence of definitions that form the body of the begin.
+
@node Multiple-value definitions
@subsection Multiple-value definitions
+
+Another kind of definition is provided by define-values, which creates multiple definitions
+from a single expression returning multiple values. It is allowed wherever define is
+allowed.
+
+syntax: (define-values <formals> <expression>)
+
+It is an error if a variable appears more than once in the set of <formals>.
+
+Semantics: <Expression> is evaluated, and the <formals> are bound to the return values in
+the same way that the <formals> in a lambda expression are matched to the arguments in
+a procedure call.
+
+(define-values (x y) (exact-integer-sqrt 17))
+(list x y) ⟹ (4 1)
+
+(let ()
+ (define-values (x y) (values 1 2))
+ (+ x y)) ⟹ 3
+
@node Syntax definitions
@section Syntax definitions
+
+Syntax definitions have this form:
+
+(define-syntax <keyword> <transformer spec>)
+
+<Keyword> is an identifier, and the <transformer spec> is an instance of syntax-rules. Like
+variable definitions, syntax definitions can appear at the outermost level or nested within
+a body.
+
+If the define-syntax occurs at the outermost level, then the global syntactic environment
+is extended by binding the <keyword> to the specified transformer, but previous
+expansions of any global binding for <keyword> remain unchanged. Otherwise, it is an
+internal syntax definition, and is local to the <body> in which it is defined. Any use of a
+syntax keyword before its corresponding definition is an error. In particular, a use that
+precedes an inner definition will not apply an outer definition.
+
+(let ((x 1) (y 2))
+ (define-syntax swap!
+ (syntax-rules ()
+ ((swap! a b)
+ (let ((tmp a))
+ (set! a b)
+ (set! b tmp)))))
+ (swap! x y)
+ (list x y)) ⟹ (2 1)
+
+Macros can expand into definitions in any context that permits them. However, it is an
+error for a definition to define an identifier whose binding has to be known in order to
+determine the meaning of the definition itself, or of any preceding definition that belongs
+to the same group of internal definitions. Similarly, it is an error for an internal definition
+to define an identifier whose binding has to be known in order to determine the
+boundary between the internal definitions and the expressions of the body it belongs to.
+For example, the following are errors:
+
+(define define 3)
+
+(begin (define begin list))
+
+(let-syntax
+ ((foo (syntax-rules ()
+ ((foo (proc args ...) body ...)
+ (define proc
+ (lambda (args ...)
+ body ...))))))
+ (let ((x 3))
+ (foo (plus x y) (+ x y))
+ (define foo x)
+ (plus foo x)))
+
@node Record-type definitions
@section Record-type definitions
+
+Record-type definitions are used to introduce new data types, called record types. Like other
+definitions, they can appear either at the outermost level or in a body. The values of a
+record type are called records and are aggregations of zero or more fields, each of which
+holds a single location. A predicate, a constructor, and field accessors and mutators are
+defined for each record type.
+
+syntax: (define-record-type <name>
+ <constructor> <pred> <field> …)
+
+Syntax: <name> and <pred> are identifiers. The <constructor> is of the form
+
+(<constructor name> <field name> …)and each <field> is either of the form (<field name>
+<accessor name>)or of the form (<field name> <accessor name> <modifier name>) It is an
+error for the same identifier to occur more than once as a field name. It is also an error
+for the same identifier to occur more than once as an accessor or mutator name.
+
+The define-record-type construct is generative: each use creates a new record type that is
+distinct from all existing types, including Scheme’s predefined types and other record
+types — even record types of the same name or structure.
+
+An instance of define-record-type is equivalent to the following definitions:
+
+* <name> is bound to a representation of the record type itself. This may be a run-time
+ object or a purely syntactic representation. The representation is not utilized in this
+ report, but it serves as a means to identify the record type for use by further language
+ extensions.
+
+* <constructor name> is bound to a procedure that takes as many arguments as there
+ are <field name>s in the (<constructor name> …) subexpression and returns a new
+ record of type <name>. Fields whose names are listed with <constructor name> have
+ the corresponding argument as their initial value. The initial values of all other fields are
+ unspecified. It is an error for a field name to appear in <constructor> but not as a <field
+ name>.
+
+* <pred> is bound to a predicate that returns #t when given a value returned by the
+ procedure bound to <constructor name> and #f for everything else.
+
+* Each <accessor name> is bound to a procedure that takes a record of type <name> and
+ returns the current value of the corresponding field. It is an error to pass an accessor a
+ value which is not a record of the appropriate type.
+
+* Each <modifier name> is bound to a procedure that takes a record of type <name> and
+ a value which becomes the new value of the corresponding field; an unspecified value
+ is returned. It is an error to pass a modifier a first argument which is not a record of
+ the appropriate type.
+
+For instance, the following record-type definition
+
+(define-record-type <pare>
+ (kons x y)
+ pare?
+ (x kar set-kar!)
+ (y kdr))
+defines kons to be a constructor, kar and kdr to be accessors, set-kar! to be a modifier,
+and pare? to be a predicate for instances of <pare>.
+
+(pare? (kons 1 2)) ⟹ #t
+ (pare? (cons 1 2)) ⟹ #f
+ (kar (kons 1 2)) ⟹ 1
+ (kdr (kons 1 2)) ⟹ 2
+ (let ((k (kons 1 2)))
+ (set-kar! k 3)
+ (kar k)) ⟹ 3
+
@node Libraries
@section Libraries
+
+Libraries provide a way to organize Scheme programs into reusable parts with explicitly
+defined interfaces to the rest of the program. This section defines the notation and
+semantics for libraries.
+
@node Library Syntax
@subsection Library Syntax
+
+A library definition takes the following form:
+
+(define-library <library name>
+ <library declaration> …)
+<library name> is a list whose members are identifiers and exact non-negative integers. It
+is used to identify the library uniquely when importing from other programs or libraries.
+Libraries whose first identifier is scheme are reserved for use by this report and future
+versions of this report. Libraries whose first identifier is srfi are reserved for libraries
+implementing Scheme Requests for Implementation. It is inadvisable, but not an error,
+for identifiers in library names to contain any of the characters | \ ? * < " : > + [ ] / or
+control characters after escapes are expanded.
+
+A <library declaration> is any of:
+
+* (export <export spec> …)
+
+* (import <import set> …)
+
+* (begin <command or definition> …)
+
+* (include <filename1> <filename2> …)
+
+* (include-ci <filename1> <filename2> …)
+
+* (include-library-declarations <filename1> <filename2> …)
+
+* (cond-expand <ce-clause1> <ce-clause2> …)
+
+An export declaration specifies a list of identifiers which can be made visible to other
+libraries or programs. An <export spec> takes one of the following forms:
+
+* <identifier>
+
+* (rename <identifier1> <identifier2>)
+
+In an <export spec>, an <identifier> names a single binding defined within or imported
+into the library, where the external name for the export is the same as the name of the
+binding within the library. A rename spec exports the binding defined within or imported
+into the library and named by <identifier1> in each (<identifier1> <identifier2>) pairing,
+using <identifier2> as the external name.
+
+An import declaration provides a way to import the identifiers exported by another
+library. It has the same syntax and semantics as an import declaration used in a program
+or at the REPL (see section 5.2).
+
+The begin, include, and include-ci declarations are used to specify the body of the library.
+They have the same syntax and semantics as the corresponding expression types. This
+form of begin is analogous to, but not the same as, the two types of begin defined in
+section 4.2.3.
+
+The include-library-declarations declaration is similar to include except that the contents
+of the file are spliced directly into the current library definition. This can be used, for
+example, to share the same export declaration among multiple libraries as a simple form
+of library interface.
+
+The cond-expand declaration has the same syntax and semantics as the cond-expand
+expression type, except that it expands to spliced-in library declarations rather than
+expressions enclosed in begin.
+
+One possible implementation of libraries is as follows: After all cond-expand library
+declarations are expanded, a new environment is constructed for the library consisting of
+all imported bindings. The expressions from all begin, include and include-ci library
+declarations are expanded in that environment in the order in which they occur in the
+library. Alternatively, cond-expand and import declarations may be processed in left to
+right order interspersed with the processing of other declarations, with the environment
+growing as imported bindings are added to it by each import declaration.
+
+When a library is loaded, its expressions are executed in textual order. If a library’s
+definitions are referenced in the expanded form of a program or library body, then that
+library must be loaded before the expanded program or library body is evaluated. This
+rule applies transitively. If a library is imported by more than one program or library, it
+may possibly be loaded additional times.
+
+Similarly, during the expansion of a library (foo), if any syntax keywords imported from
+another library (bar) are needed to expand the library, then the library (bar) must be
+expanded and its syntax definitions evaluated before the expansion of (foo).
+
+Regardless of the number of times that a library is loaded, each program or library that
+imports bindings from a library must do so from a single loading of that library,
+regardless of the number of import declarations in which it appears. That is, (import (only
+(foo) a)) followed by (import (only (foo) b)) has the same effect as (import (only (foo) a b)).
+
@node Library example
@subsection Library example
+
+The following example shows how a program can be divided into libraries plus a relatively
+small main program [16]. If the main program is entered into a REPL, it is not necessary to
+import the base library.
+
+(define-library (example grid)
+ (export make rows cols ref each
+ (rename put! set!))
+ (import (scheme base))
+ (begin
+ ;; Create an NxM grid.
+ (define (make n m)
+ (let ((grid (make-vector n)))
+ (do ((i 0 (+ i 1)))
+ ((= i n) grid)
+ (let ((v (make-vector m #false)))
+ (vector-set! grid i v)))))
+ (define (rows grid)
+ (vector-length grid))
+ (define (cols grid)
+ (vector-length (vector-ref grid 0)))
+ ;; Return #false if out of range.
+ (define (ref grid n m)
+ (and (< -1 n (rows grid))
+ (< -1 m (cols grid))
+ (vector-ref (vector-ref grid n) m)))
+ (define (put! grid n m v)
+ (vector-set! (vector-ref grid n) m v))
+ (define (each grid proc)
+ (do ((j 0 (+ j 1)))
+ ((= j (rows grid)))
+ (do ((k 0 (+ k 1)))
+ ((= k (cols grid)))
+ (proc j k (ref grid j k)))))))
+
+(define-library (example life)
+ (export life)
+ (import (except (scheme base) set!)
+ (scheme write)
+ (example grid))
+ (begin
+ (define (life-count grid i j)
+ (define (count i j)
+ (if (ref grid i j) 1 0))
+ (+ (count (- i 1) (- j 1))
+ (count (- i 1) j)
+ (count (- i 1) (+ j 1))
+ (count i (- j 1))
+ (count i (+ j 1))
+ (count (+ i 1) (- j 1))
+ (count (+ i 1) j)
+ (count (+ i 1) (+ j 1))))
+ (define (life-alive? grid i j)
+ (case (life-count grid i j)
+ ((3) #true)
+ ((2) (ref grid i j))
+ (else #false)))
+ (define (life-print grid)
+ (display "\x1B;[1H\x1B;[J") ; clear vt100
+ (each grid
+ (lambda (i j v)
+ (display (if v "*" " "))
+ (when (= j (- (cols grid) 1))
+ (newline)))))
+ (define (life grid iterations)
+ (do ((i 0 (+ i 1))
+ (grid0 grid grid1)
+ (grid1 (make (rows grid) (cols grid))
+ grid0))
+ ((= i iterations))
+ (each grid0
+ (lambda (j k v)
+ (let ((a (life-alive? grid0 j k)))
+ (set! grid1 j k a))))
+ (life-print grid1)))))
+
+;; Main program.
+(import (scheme base)
+ (only (example life) life)
+ (rename (prefix (example grid) grid-)
+ (grid-make make-grid)))
+
+;; Initialize a grid with a glider.
+(define grid (make-grid 24 24))
+(grid-set! grid 1 1 #true)
+(grid-set! grid 2 2 #true)
+(grid-set! grid 3 0 #true)
+(grid-set! grid 3 1 #true)
+(grid-set! grid 3 2 #true)
+
+;; Run for 80 iterations.
+(life grid 80)
+
@node The REPL
@section The REPL
+Implementations may provide an interactive session called a REPL (Read-Eval-Print Loop),
+where import declarations, expressions and definitions can be entered and evaluated one
+at a time. For convenience and ease of use, the global Scheme environment in a REPL
+must not be empty, but must start out with at least the bindings provided by the base
+library. 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 of (scheme base) bindings can be found in
+Appendix A.
+
+Implementations may provide an initial REPL environment which behaves as if all possible
+variables are bound to locations, most of which contain unspecified values. Top level REPL
+definitions in such an implementation are truly equivalent to assignments, unless the
+identifier is defined as a syntax keyword.
+
+An implementation may provide a mode of operation in which the REPL reads its input
+from a file. Such a file is not, in general, the same as a program, because it can contain
+import declarations in places other than the beginning.
+
@node Standard procedures
@chapter Standard procedures
+
+This chapter describes Scheme’s built-in procedures. The procedures force, promise?, and
+make-promise are intimately associated with the expression types delay and delay-force,
+and are described with them in section 4.2.5. In the same way, the procedure
+make-parameter is intimately associated with the expression type parameterize, and is
+described with it in section 4.2.6.
+
+A program can use a global variable definition to bind any variable. It may subsequently
+alter any such binding by an assignment (see section 4.1.6). These operations do not
+modify the behavior of any procedure defined in this report or imported from a library
+(see section 5.6). Altering any global binding that has not been introduced by a definition
+has an unspecified effect on the behavior of the procedures defined in this chapter.
+
+When a procedure is said to return a newly allocated object, it means that the locations in
+the object are fresh.
+
@node Equivalence predicates
@section Equivalence predicates
+
+A predicate is a procedure that always returns a boolean value (#t or #f). An equivalence
+predicate is the computational analogue of a mathematical equivalence relation; it is
+symmetric, reflexive, and transitive. Of the equivalence predicates described in this
+section, eq? is the finest or most discriminating, equal? is the coarsest, and eqv? is
+slightly less discriminating than eq?.
+
+procedure: (eqv?
+
+obj1
+
+obj2)
+
+
+The eqv? procedure defines a useful equivalence relation on objects. Briefly, it returns #t
+if
+
+obj1 and
+
+obj2 are normally regarded as the same object. This relation is left slightly open to
+interpretation, but the following partial specification of eqv? holds for all implementations
+of Scheme.
+
+The eqv? procedure returns #t if:
+
+* obj1 and
+
+ obj2 are both #t or both #f.
+
+* obj1 and
+
+ obj2 are both symbols and are the same symbol according to the symbol=? procedure
+ (section 6.5).
+
+* obj1 and
+
+ obj2 are both exact numbers and are numerically equal (in the sense of =).
+
+* obj1 and
+
+ obj2 are both inexact numbers such that they are numerically equal (in the sense of =)
+ and they yield the same results (in the sense of eqv?) when passed as arguments to any
+ other procedure that can be defined as a finite composition of Scheme’s standard
+ arithmetic procedures, provided it does not result in a NaN value.
+
+* obj1 and
+
+ obj2 are both characters and are the same character according to the char=? procedure
+ (section 6.6).
+
+* obj1 and
+
+ obj2 are both the empty list.
+
+* obj1 and
+
+ obj2 are pairs, vectors, bytevectors, records, or strings that denote the same location in
+ the store (section 3.4).
+
+* obj1 and
+
+ obj2 are procedures whose location tags are equal (section 4.1.4).
+
+The eqv? procedure returns #f if:
+
+* obj1 and
+
+ obj2 are of different types (section 3.2).
+
+* one of
+
+ obj1 and
+
+ obj2 is #t but the other is #f.
+
+* obj1 and
+
+ obj2 are symbols but are not the same symbol according to the symbol=? procedure
+ (section 6.5).
+
+* one of
+
+ obj1 and
+
+ obj2 is an exact number but the other is an inexact number.
+
+* obj1 and
+
+ obj2 are both exact numbers and are numerically unequal (in the sense of =).
+
+* obj1 and
+
+ obj2 are both inexact numbers such that either they are numerically unequal (in the
+ sense of =), or they do not yield the same results (in the sense of eqv?) when passed as
+ arguments to any other procedure that can be defined as a finite composition of
+ Scheme’s standard arithmetic procedures, provided it does not result in a NaN value. As
+ an exception, the behavior of eqv? is unspecified when both
+
+ obj1 and
+
+ obj2 are NaN.
+
+* obj1 and
+
+ obj2 are characters for which the char=? procedure returns #f.
+
+* one of
+
+ obj1 and
+
+ obj2 is the empty list but the other is not.
+
+* obj1 and
+
+ obj2 are pairs, vectors, bytevectors, records, or strings that denote distinct locations.
+
+* obj1 and
+
+ obj2 are procedures that would behave differently (return different values or have
+ different side effects) for some arguments.
+
+(eqv? 'a 'a) ⟹ #t
+(eqv? 'a 'b) ⟹ #f
+(eqv? 2 2) ⟹ #t
+(eqv? 2 2.0) ⟹ #f
+(eqv? '() '()) ⟹ #t
+(eqv? 100000000 100000000) ⟹ #t
+(eqv? 0.0 +nan.0) ⟹ #f
+(eqv? (cons 1 2) (cons 1 2)) ⟹ #f
+(eqv? (lambda () 1)
+ (lambda () 2)) ⟹ #f
+(let ((p (lambda (x) x)))
+ (eqv? p p)) ⟹ #t
+(eqv? #f 'nil) ⟹ #f The following examples illustrate cases in which the above rules
+do not fully specify the behavior of eqv?. All that can be said about such cases is that the
+value returned by eqv? must be a boolean.
+
+(eqv? "" "") ⟹ unspecified
+(eqv? '#() '#()) ⟹ unspecified
+(eqv? (lambda (x) x)
+ (lambda (x) x)) ⟹ unspecified
+(eqv? (lambda (x) x)
+ (lambda (y) y)) ⟹ unspecified
+(eqv? 1.0e0 1.0f0) ⟹ unspecified
+(eqv? +nan.0 +nan.0) ⟹ unspecified Note that (eqv? 0.0 -0.0) will return #f if negative zero
+is distinguished, and #t if negative zero is not distinguished.
+
+The next set of examples shows the use of eqv? with procedures that have local state. The
+gen-counter procedure must return a distinct procedure every time, since each
+procedure has its own internal counter. The gen-loser procedure, however, returns
+operationally equivalent procedures each time, since the local state does not affect the
+value or side effects of the procedures. However, eqv? may or may not detect this
+equivalence.
+
+(define gen-counter
+ (lambda ()
+ (let ((n 0))
+ (lambda () (set! n (+ n 1)) n))))
+(let ((g (gen-counter)))
+ (eqv? g g)) ⟹ #t
+(eqv? (gen-counter) (gen-counter))
+ ⟹ #f
+(define gen-loser
+ (lambda ()
+ (let ((n 0))
+ (lambda () (set! n (+ n 1)) 27))))
+(let ((g (gen-loser)))
+ (eqv? g g)) ⟹ #t
+(eqv? (gen-loser) (gen-loser))
+ ⟹ unspecified
+
+(letrec ((f (lambda () (if (eqv? f g) 'both 'f)))
+ (g (lambda () (if (eqv? f g) 'both 'g))))
+ (eqv? f g))
+ ⟹ unspecified
+
+(letrec ((f (lambda () (if (eqv? f g) 'f 'both)))
+ (g (lambda () (if (eqv? f g) 'g 'both))))
+ (eqv? f g))
+ ⟹ #f Since it is an error to modify constant objects (those returned by literal
+expressions), implementations may share structure between constants where
+appropriate. Thus the value of eqv? on constants is sometimes
+implementation-dependent.
+
+(eqv? '(a) '(a)) ⟹ unspecified
+(eqv? "a" "a") ⟹ unspecified
+(eqv? '(b) (cdr '(a b))) ⟹ unspecified
+(let ((x '(a)))
+ (eqv? x x)) ⟹ #t The above definition of eqv? allows implementations latitude in
+their treatment of procedures and literals: implementations may either detect or fail to
+detect that two procedures or two literals are equivalent to each other, and can decide
+whether or not to merge representations of equivalent objects by using the same pointer
+or bit pattern to represent both.
+
+ Note: If inexact numbers are represented as IEEE binary floating-point numbers, then
+ an implementation of eqv? that simply compares equal-sized inexact numbers for
+ bitwise equality is correct by the above definition.
+
+procedure: (eq?
+
+obj1
+
+obj2)
+
+
+The eq? procedure is similar to eqv? except that in some cases it is capable of discerning
+distinctions finer than those detectable by eqv?. It must always return #f when eqv? also
+would, but may return #f in some cases where eqv? would return #t.
+
+On symbols, booleans, the empty list, pairs, and records, and also on non-empty strings,
+vectors, and bytevectors, eq? and eqv? are guaranteed to have the same behavior. On
+procedures, eq? must return true if the arguments’ location tags are equal. On numbers
+and characters, eq?’s behavior is implementation-dependent, but it will always return
+either true or false. On empty strings, empty vectors, and empty bytevectors, eq? may also
+behave differently from eqv?.
+
+(eq? 'a 'a) ⟹ #t
+(eq? '(a) '(a)) ⟹ unspecified
+(eq? (list 'a) (list 'a)) ⟹ #f
+(eq? "a" "a") ⟹ unspecified
+(eq? "" "") ⟹ unspecified
+(eq? '() '()) ⟹ #t
+(eq? 2 2) ⟹ unspecified
+(eq? #\A #\A) ⟹ unspecified
+(eq? car car) ⟹ #t
+(let ((n (+ 2 3)))
+ (eq? n n)) ⟹ unspecified
+(let ((x '(a)))
+ (eq? x x)) ⟹ #t
+(let ((x '#()))
+ (eq? x x)) ⟹ #t
+(let ((p (lambda (x) x)))
+ (eq? p p)) ⟹ #t
+
+ Rationale: It will usually be possible to implement eq? much more efficiently than
+ eqv?, for example, as a simple pointer comparison instead of as some more
+ complicated operation. One reason is that it is not always possible to compute eqv?
+ of two numbers in constant time, whereas eq? implemented as pointer comparison
+ will always finish in constant time.
+
+procedure: (equal?
+
+obj1
+
+obj2)
+
+
+The equal? procedure, when applied to pairs, vectors, strings and bytevectors, recursively
+compares them, returning #t when the unfoldings of its arguments into (possibly infinite)
+trees are equal (in the sense of equal?) as ordered trees, and #f otherwise. It returns the
+same as eqv? when applied to booleans, symbols, numbers, characters, ports,
+procedures, and the empty list. If two objects are eqv?, they must be equal? as well. In all
+other cases, equal? may return either #t or #f. Even if its arguments are circular data
+structures, equal? must always terminate.
+
+(equal? 'a 'a) ⟹ #t
+(equal? '(a) '(a)) ⟹ #t
+(equal? '(a (b) c)
+ '(a (b) c)) ⟹ #t
+(equal? "abc" "abc") ⟹ #t
+(equal? 2 2) ⟹ #t
+(equal? (make-vector 5 'a)
+ (make-vector 5 'a)) ⟹ #t
+(equal? '#1=(a b . #1#)
+ '#2=(a b a b . #2#)) ⟹ #t
+(equal? (lambda (x) x)
+ (lambda (y) y)) ⟹ unspecified
+
+ Note: A rule of thumb is that objects are generally equal? if they print the same.
+
@node Numbers
@section Numbers
+
+It is important to distinguish between mathematical numbers, the Scheme numbers that
+attempt to model them, the machine representations used to implement the Scheme
+numbers, and notations used to write numbers. This report uses the types number,
+complex, real, rational, and integer to refer to both mathematical numbers and Scheme
+numbers.
+
@node Numerical types
@subsection Numerical types
+
+Mathematically, numbers are arranged into a tower of subtypes in which each level is a
+subset of the level above it:
+
+ number
+ complex number
+ real number
+ rational number
+ integer
+
+For example, 3 is an integer. Therefore 3 is also a rational, a real, and a complex number.
+The same is true of the Scheme numbers that model 3. For Scheme numbers, these types
+are defined by the predicates number?, complex?, real?, rational?, and integer?.
+
+There is no simple relationship between a number’s type and its representation inside a
+computer. Although most implementations of Scheme will offer at least two different
+representations of 3, these different representations denote the same integer.
+
+Scheme’s numerical operations treat numbers as abstract data, as independent of their
+representation as possible. Although an implementation of Scheme may use multiple
+internal representations of numbers, this ought not to be apparent to a casual
+programmer writing simple programs.
+
@node Exactness
@subsection Exactness
+
+It is useful to distinguish between numbers that are represented exactly and those that
+might not be. For example, indexes into data structures must be known exactly, as must
+some polynomial coefficients in a symbolic algebra system. On the other hand, the results
+of measurements are inherently inexact, and irrational numbers may be approximated by
+rational and therefore inexact approximations. In order to catch uses of inexact numbers
+where exact numbers are required, Scheme explicitly distinguishes exact from inexact
+numbers. This distinction is orthogonal to the dimension of type.
+
+A Scheme number is exact if it was written as an exact constant or was derived from exact
+numbers using only exact operations. A number is inexact if it was written as an inexact
+constant, if it was derived using inexact ingredients, or if it was derived using inexact
+operations. Thus inexactness is a contagious property of a number. In particular, an exact
+complex number has an exact real part and an exact imaginary part; all other complex
+numbers are inexact complex numbers.
+
+If two implementations produce exact results for a computation that did not involve
+inexact intermediate results, the two ultimate results will be mathematically equal. This is
+generally not true of computations involving inexact numbers since approximate
+methods such as floating-point arithmetic may be used, but it is the duty of each
+implementation to make the result as close as practical to the mathematically ideal result.
+
+Rational operations such as + should always produce exact results when given exact
+arguments. If the operation is unable to produce an exact result, then it may either report
+the violation of an implementation restriction or it may silently coerce its result to an
+inexact value. However, (/ 3 4) must not return the mathematically incorrect value 0. See
+section 6.2.3.
+
+Except for exact, the operations described in this section must generally return inexact
+results when given any inexact arguments. An operation may, however, return an exact
+result if it can prove that the value of the result is unaffected by the inexactness of its
+arguments. For example, multiplication of any number by an exact zero may produce an
+exact zero result, even if the other argument is inexact.
+
+Specifically, the expression (* 0 +inf.0) may return 0, or +nan.0, or report that inexact
+numbers are not supported, or report that non-rational real numbers are not supported,
+or fail silently or noisily in other implementation-specific ways.
+
@node Implementation restrictions
@subsection Implementation restrictions
+
+Implementations of Scheme are not required to implement the whole tower of subtypes
+given in section 6.2.1, but they must implement a coherent subset consistent with both
+the purposes of the implementation and the spirit of the Scheme language. For example,
+implementations in which all numbers are real, or in which non-real numbers are always
+inexact, or in which exact numbers are always integer, are still quite useful.
+
+Implementations may also support only a limited range of numbers of any type, subject to
+the requirements of this section. The supported range for exact numbers of any type may
+be different from the supported range for inexact numbers of that type. For example, an
+implementation that uses IEEE binary double-precision floating-point numbers to
+represent all its inexact real numbers may also support a practically unbounded range of
+exact integers and rationals while limiting the range of inexact reals (and therefore the
+range of inexact integers and rationals) to the dynamic range of the IEEE binary double
+format. Furthermore, the gaps between the representable inexact integers and rationals
+are likely to be very large in such an implementation as the limits of this range are
+approached.
+
+An implementation of Scheme must support exact integers throughout the range of
+numbers permitted as indexes of lists, vectors, bytevectors, and strings or that result from
+computing the length of one of these. The length, vector-length, bytevector-length, and
+string-length procedures must return an exact integer, and it is an error to use anything
+but an exact integer as an index. Furthermore, any integer constant within the index
+range, if expressed by an exact integer syntax, must be read as an exact integer,
+regardless of any implementation restrictions that apply outside this range. Finally, the
+procedures listed below will always return exact integer results provided all their
+arguments are exact integers and the mathematically expected results are representable
+as exact integers within the implementation:
+
+- *
++ abs
+ceiling denominator
+exact-integer-sqrt expt
+floor floor/
+floor-quotient floor-remainder
+gcd lcm
+max min
+modulo numerator
+quotient rationalize
+remainder round
+square truncate
+truncate/ truncate-quotient
+truncate-remainder
+It is recommended, but not required, that implementations support exact integers and
+exact rationals of practically unlimited size and precision, and to implement the above
+procedures and the / procedure in such a way that they always return exact results when
+given exact arguments. If one of these procedures is unable to deliver an exact result
+when given exact arguments, then it may either report a violation of an implementation
+restriction or it may silently coerce its result to an inexact number; such a coercion can
+cause an error later. Nevertheless, implementations that do not provide exact rational
+numbers should return inexact rational numbers rather than reporting an
+implementation restriction.
+
+An implementation may use floating-point and other approximate representation
+strategies for inexact numbers. This report recommends, but does not require, that
+implementations that use floating-point representations follow the IEEE 754 standard,
+and that implementations using other representations should match or exceed the
+precision achievable using these floating-point standards [17]. In particular, the
+description of transcendental functions in IEEE 754-2008 should be followed by such
+implementations, particularly with respect to infinities and NaNs.
+
+Although Scheme allows a variety of written notations for numbers, any particular
+implementation may support only some of them. For example, an implementation in
+which all numbers are real need not support the rectangular and polar notations for
+complex numbers. If an implementation encounters an exact numerical constant that it
+cannot represent as an exact number, then it may either report a violation of an
+implementation restriction or it may silently represent the constant by an inexact
+number.
+
@node Implementation extensions
@subsection Implementation extensions
+
+Implementations may provide more than one representation of floating-point numbers
+with differing precisions. In an implementation which does so, an inexact result must be
+represented with at least as much precision as is used to express any of the inexact
+arguments to that operation. Although it is desirable for potentially inexact operations
+such as sqrt to produce exact answers when applied to exact arguments, if an exact
+number is operated upon so as to produce an inexact result, then the most precise
+representation available must be used. For example, the value of (sqrt 4) should be 2, but
+in an implementation that provides both single and double precision floating point
+numbers it may be the latter but must not be the former.
+
+It is the programmer’s responsibility to avoid using inexact number objects with
+magnitude or significand too large to be represented in the implementation.
+
+In addition, implementations may distinguish special numbers called positive infinity,
+negative infinity, NaN, and negative zero.
+
+Positive infinity is regarded as an inexact real (but not rational) number that represents an
+indeterminate value greater than the numbers represented by all rational numbers.
+Negative infinity is regarded as an inexact real (but not rational) number that represents
+an indeterminate value less than the numbers represented by all rational numbers.
+
+Adding or multiplying an infinite value by any finite real value results in an appropriately
+signed infinity; however, the sum of positive and negative infinities is a NaN. Positive
+infinity is the reciprocal of zero, and negative infinity is the reciprocal of negative zero.
+The behavior of the transcendental functions is sensitive to infinity in accordance with
+IEEE 754.
+
+A NaN is regarded as an inexact real (but not rational) number so indeterminate that it
+might represent any real value, including positive or negative infinity, and might even be
+greater than positive infinity or less than negative infinity. An implementation that does
+not support non-real numbers may use NaN to represent non-real values like (sqrt -1.0)
+and (asin 2.0).
+
+A NaN always compares false to any number, including a NaN. An arithmetic operation
+where one operand is NaN returns NaN, unless the implementation can prove that the
+result would be the same if the NaN were replaced by any rational number. Dividing zero
+by zero results in NaN unless both zeros are exact.
+
+Negative zero is an inexact real value written -0.0 and is distinct (in the sense of eqv?) from
+0.0. A Scheme implementation is not required to distinguish negative zero. If it does,
+however, the behavior of the transcendental functions is sensitive to the distinction in
+accordance with IEEE 754. Specifically, in a Scheme implementing both complex numbers
+and negative zero, the branch cut of the complex logarithm function is such that
+(imag-part (log -1.0-0.0i)) is −π rather than π.
+
+Furthermore, the negation of negative zero is ordinary zero and vice versa. This implies
+that the sum of two or more negative zeros is negative, and the result of subtracting
+(positive) zero from a negative zero is likewise negative. However, numerical comparisons
+treat negative zero as equal to zero.
+
+Note that both the real and the imaginary parts of a complex number can be infinities,
+NaNs, or negative zero.
+
@node Syntax of numerical constants
@subsection Syntax of numerical constants
+
+The syntax of the written representations for numbers is described formally in section
+7.1.1. Note that case is not significant in numerical constants.
+
+A number can be written in binary, octal, decimal, or hexadecimal by the use of a radix
+prefix. The radix prefixes are #b(binary), #o(octal), #d(decimal), and #x(hexadecimal). With
+no radix prefix, a number is assumed to be expressed in decimal.
+
+A numerical constant can be specified to be either exact or inexact by a prefix. The
+prefixes are #efor exact, and #ifor inexact. An exactness prefix can appear before or after
+any radix prefix that is used. If the written representation of a number has no exactness
+prefix, the constant is inexact if it contains a decimal point or an exponent. Otherwise, it is
+exact.
+
+In systems with inexact numbers of varying precisions it can be useful to specify the
+precision of a constant. For this purpose, implementations may accept numerical
+constants written with an exponent marker that indicates the desired precision of the
+inexact representation. If so, the letter s, f, d, or l, meaning
+
+short,
+
+single,
+
+double, or
+
+long precision, respectively, can be used in place of e. The default precision has at least as
+much precision as
+
+double, but implementations may allow this default to be set by the user.
+
+3.14159265358979F0
+ Round to single --- 3.141593
+0.6L0
+ Extend to long --- .600000000000000 The numbers positive infinity, negative infinity,
+and NaN are written +inf.0, -inf.0 and +nan.0 respectively. NaN may also be written -nan.0.
+The use of signs in the written representation does not necessarily reflect the underlying
+sign of the NaN value, if any. Implementations are not required to support these
+numbers, but if they do, they must do so in general conformance with IEEE 754. However,
+implementations are not required to support signaling NaNs, nor to provide a way to
+distinguish between different NaNs.
+
+There are two notations provided for non-real complex numbers: the rectangular notation
+
+a+
+
+bi, where
+
+a is the real part and
+
+b is the imaginary part; and the polar notation
+
+r@θ, where
+
+r is the magnitude and θ is the phase (angle) in radians. These are related by the equation
+a + bi = r cos θ + (r sin θ) i. All of
+
+a,
+
+b,
+
+r, and θ are real numbers.
+
@node Numerical operations
@subsection Numerical operations
-@node Numerical input and output
-@subsection Numerical input and output
-@node Booleans
-@section Booleans
-@node Pairs and lists
-@section Pairs and lists
-@node Symbols
-@section Symbols
-@node Characters
-@section Characters
-@node Strings
-@section Strings
-@node Vectors
-@section Vectors
-@node Bytevectors
-@section Bytevectors
-@node Control features
-@section Control features
-@node Exceptions
-@section Exceptions
-@node Environments and evaluation
-@section Environments and evaluation
-@node Input and output
-@section Input and output
-@node Ports
-@subsection Ports
-@node Input
-@subsection Input
-@node Output
-@subsection Output
-@node System interface
-@section System interface
+
+The reader is referred to section 1.3.3 for a summary of the naming conventions used to
+specify restrictions on the types of arguments to numerical routines. The examples used
+in this section assume that any numerical constant written using an exact notation is
+indeed represented as an exact number. Some examples also assume that certain
+numerical constants written using an inexact notation can be represented without loss of
+accuracy; the inexact constants were chosen so that this is likely to be true in
+implementations that use IEEE binary doubles to represent inexact numbers.
+
+procedure: (number? obj)
+procedure: (complex? obj)
+procedure: (real? obj)
+procedure: (rational? obj)
+procedure: (integer? obj)
+
+These numerical type predicates can be applied to any kind of argument, including
+non-numbers. They return #t if the object is of the named type, and otherwise they return
+#f. In general, if a type predicate is true of a number then all higher type predicates are
+also true of that number. Consequently, if a type predicate is false of a number, then all
+lower type predicates are also false of that number.
+
+If
+
+z is a complex number, then (real?
+
+z) is true if and only if (zero? (imag-part
+
+z)) is true. If
+
+x is an inexact real number, then (integer?
+
+x) is true if and only if (=
+
+x (round
+
+x)).
+
+The numbers +inf.0, -inf.0, and +nan.0 are real but not rational.
+
+(complex? 3+4i) ⟹ #t
+(complex? 3) ⟹ #t
+(real? 3) ⟹ #t
+(real? -2.5+0i) ⟹ #t
+(real? -2.5+0.0i) ⟹ #f
+(real? #e1e10) ⟹ #t
+(real? +inf.0) ⟹ #t
+(real? +nan.0) ⟹ #t
+(rational? -inf.0) ⟹ #f
+(rational? 3.5) ⟹ #t
+(rational? 6/10) ⟹ #t
+(rational? 6/3) ⟹ #t
+(integer? 3+0i) ⟹ #t
+(integer? 3.0) ⟹ #t
+(integer? 8/4) ⟹ #t
+
+ Note: The behavior of these type predicates on inexact numbers is unreliable, since
+ any inaccuracy might affect the result.
+
+ Note: In many implementations the complex? procedure will be the same as
+ number?, but unusual implementations may represent some irrational numbers
+ exactly or may extend the number system to support some kind of non-complex
+ numbers.
+
+procedure: (exact?
+
+z)
+
+
+procedure: (inexact?
+
+z)
+
+
+These numerical predicates provide tests for the exactness of a quantity. For any Scheme
+number, precisely one of these predicates is true.
+
+(exact? 3.0) ⟹ #f
+(exact? #e3.0) ⟹ #t
+(inexact? 3.) ⟹ #t
+
+procedure: (exact-integer?
+
+z)
+
+
+Returns #t if
+
+z is both exact and an integer; otherwise returns #f.
+
+(exact-integer? 32) ⟹ #t
+(exact-integer? 32.0) ⟹ #f
+(exact-integer? 32/5) ⟹ #f
+
+inexact library procedure: (finite?
+
+z)
+
+
+The finite? procedure returns #t on all real numbers except +inf.0, -inf.0, and +nan.0, and
+on complex numbers if their real and imaginary parts are both finite. Otherwise it returns
+#f.
+
+(finite? 3) ⟹ #t
+(finite? +inf.0) ⟹ #f
+(finite? 3.0+inf.0i) ⟹ #f
+
+inexact library procedure: (infinite?
+
+z)
+
+
+The infinite? procedure returns #t on the real numbers +inf.0 and -inf.0, and on complex
+numbers if their real or imaginary parts or both are infinite. Otherwise it returns #f.
+
+(infinite? 3) ⟹ #f
+(infinite? +inf.0) ⟹ #t
+(infinite? +nan.0) ⟹ #f
+(infinite? 3.0+inf.0i) ⟹ #t
+
+inexact library procedure: (nan?
+
+z)
+
+
+The nan? procedure returns #t on +nan.0, and on complex numbers if their real or
+imaginary parts or both are +nan.0. Otherwise it returns #f.
+
+(nan? +nan.0) ⟹ #t
+(nan? 32) ⟹ #f
+(nan? +nan.0+5.0i) ⟹ #t
+(nan? 1+2i) ⟹ #f
+
+procedure: (=
+
+z1
+
+z2
+
+z3 …)
+
+
+procedure: (<
+
+x1
+
+x2
+
+x3 …)
+
+
+procedure: (>
+
+x1
+
+x2
+
+x3 …)
+
+
+procedure: (<=
+
+x1
+
+x2
+
+x3 …)
+
+
+procedure: (>=
+
+x1
+
+x2
+
+x3 …)
+
+
+These procedures return #t if their arguments are (respectively): equal, monotonically
+increasing, monotonically decreasing, monotonically non-decreasing, or monotonically
+non-increasing, and #f otherwise. If any of the arguments are +nan.0, all the predicates
+return #f. They do not distinguish between inexact zero and inexact negative zero.
+
+These predicates are required to be transitive.
+
+ Note: The implementation approach of converting all arguments to inexact numbers
+ if any argument is inexact is not transitive. For example, let big be (expt 2 1000), and
+ assume that big is exact and that inexact numbers are represented by 64-bit IEEE
+ binary floating point numbers. Then (= (- big 1) (inexact big)) and (= (inexact big) (+ big
+ 1)) would both be true with this approach, because of the limitations of IEEE
+ representations of large integers, whereas (= (- big 1) (+ big 1)) is false. Converting
+ inexact values to exact numbers that are the same (in the sense of =) to them will
+ avoid this problem, though special care must be taken with infinities.
+
+ Note: While it is not an error to compare inexact numbers using these predicates, the
+ results are unreliable because a small inaccuracy can affect the result; this is
+ especially true of = and zero?. When in doubt, consult a numerical analyst.
+
+procedure: (zero?
+
+z)
+
+
+procedure: (positive?
+
+x)
+
+
+procedure: (negative?
+
+x)
+
+
+procedure: (odd?
+
+n)
+
+
+procedure: (even?
+
+n)
+
+
+These numerical predicates test a number for a particular property, returning #t or #f.
+See note above.
+
+procedure: (max
+
+x1
+
+x2 …)
+
+
+procedure: (min
+
+x1
+
+x2 …)
+
+
+These procedures return the maximum or minimum of their arguments.
+
+(max 3 4) ⟹ 4 ; exact
+(max 3.9 4) ⟹ 4.0 ; inexact
+
+ Note: If any argument is inexact, then the result will also be inexact (unless the
+ procedure can prove that the inaccuracy is not large enough to affect the result,
+ which is possible only in unusual implementations). If min or max is used to compare
+ numbers of mixed exactness, and the numerical value of the result cannot be
+ represented as an inexact number without loss of accuracy, then the procedure may
+ report a violation of an implementation restriction.
+
+procedure: (+
+
+z1 …)
+
+
+procedure: (*
+
+z1 …)
+
+
+These procedures return the sum or product of their arguments.
+
+(+ 3 4) ⟹ 7
+(+ 3) ⟹ 3
+(+) ⟹ 0
+(* 4) ⟹ 4
+(*) ⟹ 1
+
+procedure: (-
+
+z)
+
+
+procedure: (-
+
+z1
+
+z2 …)
+
+
+procedure: (/
+
+z)
+
+
+procedure: (/
+
+z1
+
+z2 …)
+
+
+With two or more arguments, these procedures return the difference or quotient of their
+arguments, associating to the left. With one argument, however, they return the additive
+or multiplicative inverse of their argument.
+
+It is an error if any argument of / other than the first is an exact zero. If the first
+argument is an exact zero, an implementation may return an exact zero unless one of the
+other arguments is a NaN.
+
+(- 3 4) ⟹ -1
+(- 3 4 5) ⟹ -6
+(- 3) ⟹ -3
+(/ 3 4 5) ⟹ 3/20
+(/ 3) ⟹ 1/3
+
+procedure: (abs x)
+
+The abs procedure returns the absolute value of its argument.
+
+(abs -7) ⟹ 7
+
+procedure: (floor/
+
+n1
+
+n2)
+
+
+procedure: (floor-quotient
+
+n1
+
+n2)
+
+
+procedure: (floor-remainder
+
+n1
+
+n2)
+
+
+procedure: (truncate/
+
+n1
+
+n2)
+
+
+procedure: (truncate-quotient
+
+n1
+
+n2)
+
+
+procedure: (truncate-remainder
+
+n1
+
+n2)
+
+
+These procedures implement number-theoretic (integer) division. It is an error if
+
+n2 is zero. The procedures ending in / return two integers; the other procedures return an
+integer. All the procedures compute a quotient
+
+nq and remainder
+
+nr such that
+
+n1 =
+
+n2
+
+nq +
+
+nr. For each of the division operators, there are three procedures defined as follows:
+
+(<operator>/
+
+n1
+
+n2) ⟹
+
+nq
+
+nr
+(<operator>-quotient
+
+n1
+
+n2) ⟹
+
+nq
+(<operator>-remainder
+
+n1
+
+n2) ⟹
+
+nr
+
+The remainder
+
+nr is determined by the choice of integer
+
+nq:
+
+nr =
+
+n1 −
+
+n2
+
+nq. Each set of operators uses a different choice of
+
+nq:
+
+ floor nq = ⌊
+
+ n1 /
+
+ n2⌋
+ truncate nq = texttruncate(
+
+ n1 /
+
+ n2)
+
+For any of the operators, and for integers
+
+n1 and
+
+n2 with
+
+n2 not equal to 0,
+
+(=
+
+n1 (+ (*
+
+n2 (<operator>-quotient
+
+n1
+
+n2))
+ (<operator>-remainder
+
+n1
+
+n2)))
+ ⟹ #t
+
+provided all numbers involved in that computation are exact.
+
+Examples:
+
+(floor/ 5 2) ⟹ 2 1
+(floor/ -5 2) ⟹ -3 1
+(floor/ 5 -2) ⟹ -3 -1
+(floor/ -5 -2) ⟹ 2 -1
+(truncate/ 5 2) ⟹ 2 1
+(truncate/ -5 2) ⟹ -2 -1
+(truncate/ 5 -2) ⟹ -2 1
+(truncate/ -5 -2) ⟹ 2 -1
+(truncate/ -5.0 -2) ⟹ 2.0 -1.0
+
+procedure: (quotient
+
+n1
+
+n2)
+
+
+procedure: (remainder
+
+n1
+
+n2)
+
+
+procedure: (modulo
+
+n1
+
+n2)
+
+
+The quotient and remainder procedures are equivalent to truncate-quotient and
+truncate-remainder, respectively, and modulo is equivalent to floor-remainder.
+
+ Note: These procedures are provided for backward compatibility with earlier
+ versions of this report.
+
+procedure: (gcd
+
+n1 …)
+
+
+procedure: (lcm
+
+n1 …)
+
+
+These procedures return the greatest common divisor or least common multiple of their
+arguments. The result is always non-negative.
+
+(gcd 32 -36) ⟹ 4
+(gcd) ⟹ 0
+(lcm 32 -36) ⟹ 288
+(lcm 32.0 -36) ⟹ 288.0 ; inexact
+(lcm) ⟹ 1
+
+procedure: (numerator
+
+q)
+
+
+procedure: (denominator
+
+q)
+
+
+These procedures return the numerator or denominator of their argument; the result is
+computed as if the argument was represented as a fraction in lowest terms. The
+denominator is always positive. The denominator of 0 is defined to be 1.
+
+(numerator (/ 6 4)) ⟹ 3
+(denominator (/ 6 4)) ⟹ 2
+(denominator
+ (inexact (/ 6 4))) ⟹ 2.0
+
+procedure: (floor x)
+procedure: (ceiling x)
+procedure: (truncate x)
+procedure: (round x)
+
+These procedures return integers. The floor procedure returns the largest integer not
+larger than
+
+x. The ceiling procedure returns the smallest integer not smaller than
+
+x, truncate returns the integer closest to
+
+x whose absolute value is not larger than the absolute value of
+
+x, and round returns the closest integer to
+
+x, rounding to even when
+
+x is halfway between two integers.
+
+ Rationale: The round procedure rounds to even for consistency with the default
+ rounding mode specified by the IEEE 754 IEEE floating-point standard.
+
+ Note: If the argument to one of these procedures is inexact, then the result will also
+ be inexact. If an exact value is needed, the result can be passed to the exact
+ procedure. If the argument is infinite or a NaN, then it is returned.
+
+(floor -4.3) ⟹ -5.0
+(ceiling -4.3) ⟹ -4.0
+(truncate -4.3) ⟹ -4.0
+(round -4.3) ⟹ -4.0
+
+(floor 3.5) ⟹ 3.0
+(ceiling 3.5) ⟹ 4.0
+(truncate 3.5) ⟹ 3.0
+(round 3.5) ⟹ 4.0 ; inexact
+
+(round 7/2) ⟹ 4 ; exact
+(round 7) ⟹ 7
+
+procedure: (rationalize x y)
+
+The rationalize procedure returns the simplest rational number differing from
+
+x by no more than
+
+y. A rational number r1 is simpler than another rational number r2 if r1 = p1/q1 and r2 =
+p2/q2 (in lowest terms) and |p1| ≤|p2| and |q1| ≤|q2|. Thus 3/5 is simpler than 4/7.
+Although not all rationals are comparable in this ordering (consider 2/7 and 3/5), any
+interval contains a rational number that is simpler than every other rational number in
+that interval (the simpler 2/5 lies between 2/7 and 3/5). Note that 0 = 0/1 is the simplest
+rational of all.
+
+(rationalize
+ (exact .3) 1/10) ⟹ 1/3 ; exact
+(rationalize .3 1/10) ⟹ #i1/3 ; inexact
+
+inexact library procedure: (exp
+
+z)
+
+
+inexact library procedure: (log
+
+z)
+
+
+inexact library procedure: (log
+
+z1
+
+z2)
+
+
+inexact library procedure: (sin
+
+z)
+
+
+inexact library procedure: (cos
+
+z)
+
+
+inexact library procedure: (tan
+
+z)
+
+
+inexact library procedure: (asin
+
+z)
+
+
+inexact library procedure: (acos
+
+z)
+
+
+inexact library procedure: (atan
+
+z)
+
+
+inexact library procedure: (atan
+
+y
+
+x)
+
+
+These procedures compute the usual transcendental functions. The log procedure
+computes the natural logarithm of
+
+z (not the base ten logarithm) if a single argument is given, or the base-
+
+z2 logarithm of
+
+z1 if two arguments are given. The asin, acos, and atan procedures compute arcsine (sin
+−1), arc-cosine (cos −1), and arctangent (tan −1), respectively. The two-argument variant
+of atan computes (angle (make-rectangular
+
+x
+
+y)) (see below), even in implementations that don’t support complex numbers.
+
+In general, the mathematical functions log, arcsine, arc-cosine, and arctangent are
+multiply defined. The value of log z is defined to be the one whose imaginary part lies in
+the range from −π (inclusive if -0.0 is distinguished, exclusive otherwise) to π (inclusive).
+The value of log 0 is mathematically undefined. With log defined this way, the values of
+sin −1z, cos −1z, and tan −1z are according to the following formulæ:
+
+ sin −1z = −i log (i z + (1 −
+ z2)1/2)
+
+ cos −1z = π/ 2 − sin −1z
+
+ tan −1z = (log (1 + i z) − log (1 − i z)) /
+ (2 i)
+
+However, (log 0.0) returns -inf.0 (and (log -0.0) returns -inf.0+πi) if the implementation
+supports infinities (and -0.0).
+
+The range of (atan
+
+y
+
+x) is as in the following table. The asterisk (*) indicates that the entry applies to
+implementations that distinguish minus zero.
+
+ y condition x condition range of result r
+ y = 0.0 x > 0.0 0.0
+ ∗ y = + 0.0 x > 0.0 + 0.0
+ ∗ y = −0.0 x > 0.0 −0.0
+ y > 0.0 x > 0.0 0.0 < r < π/2
+ y > 0.0 x = 0.0 π/2
+ y > 0.0 x < 0.0 π/2 < r < π
+ y = 0.0 x < 0 π
+ ∗ y = + 0.0 x < 0.0 π
+ ∗ y = −0.0 x < 0.0 −π
+ y < 0.0 x < 0.0 −π< r< −π/2
+ y < 0.0 x = 0.0 −π/2
+ y < 0.0 x > 0.0 −π/2 < r< 0.0
+ y = 0.0 x = 0.0 undefined
+ ∗ y = + 0.0 x = + 0.0 + 0.0
+ ∗ y = −0.0 x = + 0.0 −0.0
+ ∗ y = + 0.0 x = −0.0 π
+ ∗ y = −0.0 x = −0.0 −π
+ ∗ y = + 0.0 x = 0 π/2
+ ∗ y = −0.0 x = 0 −π/2
+The above specification follows [34], which in turn cites [26]; refer to these sources for
+more detailed discussion of branch cuts, boundary conditions, and implementation of
+these functions. When it is possible, these procedures produce a real result from a real
+argument.
+
+procedure: (square
+
+z)
+
+
+Returns the square of
+
+z. This is equivalent to (*
+
+z
+
+z).
+
+(square 42) ⟹ 1764
+(square 2.0) ⟹ 4.0
+
+inexact library procedure: (sqrt
+
+z)
+
+
+Returns the principal square root of
+
+z. The result will have either a positive real part, or a zero real part and a non-negative
+imaginary part.
+
+(sqrt 9) ⟹ 3
+(sqrt -1) ⟹ +i
+
+procedure: (exact-integer-sqrt k)
+
+Returns two non-negative exact integers s and r where
+
+k = s2 + r and
+
+k < (s + 1)2.
+
+(exact-integer-sqrt 4) ⟹ 2 0
+(exact-integer-sqrt 5) ⟹ 2 1
+
+procedure: (expt
+
+z1
+
+z2)
+
+
+Returns
+
+z1 raised to the power
+
+z2. For nonzero
+
+z1, this is
+
+ z1 z2 = ez2 log z1
+
+The value of 0z is 1 if (zero? z), 0 if (real-part z) is positive, and an error otherwise.
+Similarly for 0.0z, with inexact results.
+
+complex library procedure: (make-rectangular
+
+x1
+
+x2)
+
+
+complex library procedure: (make-polar
+
+x3
+
+x4)
+
+
+complex library procedure: (real-part
+
+z)
+
+
+complex library procedure: (imag-part
+
+z)
+
+
+complex library procedure: (magnitude
+
+z)
+
+
+complex library procedure: (angle
+
+z)
+
+
+Let
+
+x1,
+
+x2,
+
+x3, and
+
+x4 be real numbers and
+
+z be a complex number such that
+
+ z = x1 + x2 i = x3 ·
+ ei
+ x4
+
+Then all of
+
+(make-rectangular
+
+x1
+
+x2) ⟹
+
+z
+(make-polar
+
+x3
+
+x4) ⟹
+
+z
+(real-part
+
+z) ⟹
+
+x1
+(imag-part
+
+z) ⟹
+
+x2
+(magnitude
+
+z) ⟹ |
+
+x3|
+(angle
+
+z) ⟹ xangle
+
+are true, where −π≤xangle ≤π with xangle =
+
+x4 + 2πn for some integer n.
+
+The make-polar procedure may return an inexact complex number even if its arguments
+are exact. The real-part and imag-part procedures may return exact real numbers when
+applied to an inexact complex number if the corresponding argument passed to
+make-rectangular was exact.
+
+ Rationale: The magnitude procedure is the same as abs for a real argument, but abs
+ is in the base library, whereas magnitude is in the optional complex library.
+
+procedure: (inexact
+
+z)
+
+
+procedure: (exact
+
+z)
+
+
+The procedure inexact returns an inexact representation of
+
+z. The value returned is the inexact number that is numerically closest to the argument.
+For inexact arguments, the result is the same as the argument. For exact complex
+numbers, the result is a complex number whose real and imaginary parts are the result
+of applying inexact to the real and imaginary parts of the argument, respectively. If an
+exact argument has no reasonably close inexact equivalent (in the sense of =), then a
+violation of an implementation restriction may be reported.
+
+The procedure exact returns an exact representation of
+
+z. The value returned is the exact number that is numerically closest to the argument.
+For exact arguments, the result is the same as the argument. For inexact non-integral
+real arguments, the implementation may return a rational approximation, or may report
+an implementation violation. For inexact complex arguments, the result is a complex
+number whose real and imaginary parts are the result of applying exact to the real and
+imaginary parts of the argument, respectively. If an inexact argument has no reasonably
+close exact equivalent, (in the sense of =), then a violation of an implementation
+restriction may be reported.
+
+These procedures implement the natural one-to-one correspondence between exact and
+inexact integers throughout an implementation-dependent range. See section 6.2.3.
+
+ Note: These procedures were known in R5RS as exact->inexact and inexact->exact,
+ respectively, but they have always accepted arguments of any exactness. The new
+ names are clearer and shorter, as well as being compatible with R6RS.
+
+@node Numerical input and output
+@subsection Numerical input and output
+
+procedure: (number->string z)
+procedure: (number->string z radix)
+
+It is an error if
+
+radix is not one of 2, 8, 10, or 16.
+
+The procedure number->string takes a number and a radix and returns as a string an
+external representation of the given number in the given radix such that
+
+(let ((number
+
+number)
+ (radix
+
+radix))
+ (eqv? number
+ (string->number (number->string number
+ radix)
+ radix)))
+
+is true. It is an error if no possible result makes this expression true. If omitted,
+
+radix defaults to 10.
+
+If
+
+z is inexact, the radix is 10, and the above expression can be satisfied by a result that
+contains a decimal point, then the result contains a decimal point and is expressed using
+the minimum number of digits (exclusive of exponent and trailing zeroes) needed to
+make the above expression true [4, 5]; otherwise the format of the result is unspecified.
+
+The result returned by number->string never contains an explicit radix prefix.
+
+ Note: The error case can occur only when
+
+ z is not a complex number or is a complex number with a non-rational real or
+ imaginary part.
+
+ Rationale: If
+
+ z is an inexact number and the radix is 10, then the above expression is normally
+ satisfied by a result containing a decimal point. The unspecified case allows for
+ infinities, NaNs, and unusual representations.
+
+procedure: (string->number string)
+procedure: (string->number string radix)
+
+Returns a number of the maximally precise representation expressed by the given
+
+string.
+
+It is an error if
+
+radix is not 2, 8, 10, or 16.
+
+If supplied,
+
+radix is a default radix that will be overridden if an explicit radix prefix is present in
+
+string (e.g. "#o177"). If
+
+radix is not supplied, then the default radix is 10. If
+
+string is not a syntactically valid notation for a number, or would result in a number that
+the implementation cannot represent, then string->number returns #f. An error is never
+signaled due to the content of
+
+string.
+
+(string->number "100") ⟹ 100
+(string->number "100" 16) ⟹ 256
+(string->number "1e2") ⟹ 100.0
+
+ Note: The domain of string->number may be restricted by implementations in the
+ following ways. If all numbers supported by an implementation are real, then
+ string->number is permitted to return #f whenever
+
+ string uses the polar or rectangular notations for complex numbers. If all numbers
+ are integers, then string->number may return #f whenever the fractional notation is
+ used. If all numbers are exact, then string->number may return #f whenever an
+ exponent marker or explicit exactness prefix is used. If all inexact numbers are
+ integers, then string->number may return #f whenever a decimal point is used.
+
+ The rules used by a particular implementation for string->number must also be
+ applied to read and to the routine that reads programs, in order to maintain
+ consistency between internal numeric processing, I/O, and the processing of
+ programs. As a consequence, the R5RS permission to return #f when
+
+ string has an explicit radix prefix has been withdrawn.
+
+@node Booleans
+@section Booleans
+
+The standard boolean objects for true and false are written as #t and #f.Alternatively,
+they can be written #true and #false, respectively. What really matters, though, are the
+objects that the Scheme conditional expressions (if, cond, and, or, when, unless, do)
+treat as trueor false. The phrase “a true value”(or sometimes just “true”) means any
+object treated as true by the conditional expressions, and the phrase “a false value”(or
+“false”) means any object treated as false by the conditional expressions.
+
+Of all the Scheme values, only #f counts as false in conditional expressions. All other
+Scheme values, including #t, count as true.
+
+ Note: Unlike some other dialects of Lisp, Scheme distinguishes #f and the empty list
+ from each other and from the symbol nil.
+
+Boolean constants evaluate to themselves, so they do not need to be quoted in
+programs.
+
+#t ⟹ #t
+#f ⟹ #f
+'#f ⟹ #f
+
+procedure: (not obj)
+
+The not procedure returns #t if
+
+obj is false, and returns #f otherwise.
+
+(not #t) ⟹ #f
+(not 3) ⟹ #f
+(not (list 3)) ⟹ #f
+(not #f) ⟹ #t
+(not '()) ⟹ #f
+(not (list)) ⟹ #f
+(not 'nil) ⟹ #f
+
+procedure: (boolean? obj)
+
+The boolean? predicate returns #t if
+
+obj is either #t or #f and returns #f otherwise.
+
+(boolean? #f) ⟹ #t
+(boolean? 0) ⟹ #f
+(boolean? '()) ⟹ #f
+
+procedure: (boolean=?
+
+boolean1
+
+boolean2
+
+boolean3 …)
+
+
+Returns #t if all the arguments are #t or all are #f.
+
+@node Pairs and lists
+@section Pairs and lists
+
+A pair (sometimes called a dotted pair) is a record structure with two fields called the car
+and cdr fields (for historical reasons). Pairs are created by the procedure cons. The car
+and cdr fields are accessed by the procedures car and cdr. The car and cdr fields are
+assigned by the procedures set-car! and set-cdr!.
+
+Pairs are used primarily to represent lists. A list can be defined recursively as either the
+empty listor a pair whose cdr is a list. More precisely, the set of lists is defined as the
+smallest set
+
+X such that
+
+* The empty list is in
+
+ X.
+
+* If
+
+ list is in
+
+ X, then any pair whose cdr field contains
+
+ list is also in
+
+ X.
+
+The objects in the car fields of successive pairs of a list are the elements of the list. For
+example, a two-element list is a pair whose car is the first element and whose cdr is a
+pair whose car is the second element and whose cdr is the empty list. The length of a list
+is the number of elements, which is the same as the number of pairs.
+
+The empty listis a special object of its own type. It is not a pair, it has no elements, and its
+length is zero.
+
+ Note: The above definitions imply that all lists have finite length and are terminated
+ by the empty list.
+
+The most general notation (external representation) for Scheme pairs is the “dotted”
+notation (
+
+c1 .
+
+c2)
+
+where
+
+c1 is the value of the car field and
+
+c2 is the value of the cdr field. For example (4 . 5) is a pair whose car is 4 and whose cdr is
+5. Note that (4 . 5) is the external representation of a pair, not an expression that
+evaluates to a pair.
+
+A more streamlined notation can be used for lists: the elements of the list are simply
+enclosed in parentheses and separated by spaces. The empty listis written (). For
+example,
+
+(a b c d e) and
+
+(a . (b . (c . (d . (e . ()))))) are equivalent notations for a list of symbols.
+
+A chain of pairs not ending in the empty list is called an improper list. Note that an
+improper list is not a list. The list and dotted notations can be combined to represent
+improper lists:
+
+(a b c . d) is equivalent to
+
+(a . (b . (c . d))) Whether a given pair is a list depends upon what is stored in the cdr field.
+When the set-cdr! procedure is used, an object can be a list one moment and not the
+next:
+
+(define x (list 'a 'b 'c))
+(define y x)
+y ⟹ (a b c)
+(list? y) ⟹ #t
+(set-cdr! x 4) ⟹ unspecified
+x ⟹ (a . 4)
+(eqv? x y) ⟹ #t
+y ⟹ (a . 4)
+(list? y) ⟹ #f
+(set-cdr! x x) ⟹ unspecified
+(list? x) ⟹ #f Within literal expressions and representations of objects read by the
+read procedure, the forms '<datum>, `<datum>, ,<datum>, and ,@<datum> denote
+two-element lists whose first elements are the symbols quote, quasiquote, unquote, and
+unquote-splicing, respectively. The second element in each case is <datum>. This
+convention is supported so that arbitrary Scheme programs can be represented as lists.
+That is, according to Scheme’s grammar, every <expression> is also a <datum> (see
+section 7.1.2). Among other things, this permits the use of the read procedure to parse
+Scheme programs. See section 3.3.
+
+procedure: (pair? obj)
+
+The pair? predicate returns #t if
+
+obj is a pair, and otherwise returns #f.
+
+(pair? '(a . b)) ⟹ #t
+(pair? '(a b c)) ⟹ #t
+(pair? '()) ⟹ #f
+(pair? '#(a b)) ⟹ #f
+
+procedure: (cons
+
+obj1
+
+obj2)
+
+
+Returns a newly allocated pair whose car is
+
+obj1 and whose cdr is
+
+obj2. The pair is guaranteed to be different (in the sense of eqv?) from every existing
+object.
+
+(cons 'a '()) ⟹ (a)
+(cons '(a) '(b c d)) ⟹ ((a) b c d)
+(cons "a" '(b c)) ⟹ ("a" b c)
+(cons 'a 3) ⟹ (a . 3)
+(cons '(a b) 'c) ⟹ ((a b) . c)
+
+procedure: (car pair)
+
+Returns the contents of the car field of
+
+pair. Note that it is an error to take the car of the empty list.
+
+(car '(a b c)) ⟹ a
+(car '((a) b c d)) ⟹ (a)
+(car '(1 . 2)) ⟹ 1
+(car '()) ⟹ error
+
+procedure: (cdr pair)
+
+Returns the contents of the cdr field of
+
+pair. Note that it is an error to take the cdr of the empty list.
+
+(cdr '((a) b c d)) ⟹ (b c d)
+(cdr '(1 . 2)) ⟹ 2
+(cdr '()) ⟹ error
+
+procedure: (set-car! pair obj)
+
+Stores
+
+obj in the car field of
+
+pair.
+
+(define (f) (list 'not-a-constant-list))
+(define (g) '(constant-list))
+(set-car! (f) 3) ⟹ unspecified
+(set-car! (g) 3) ⟹ error
+
+procedure: (set-cdr! pair obj)
+
+Stores
+
+obj in the cdr field of
+
+pair.
+
+procedure: (caar pair)
+procedure: (cadr pair)
+procedure: (cdar pair)
+procedure: (cddr pair)
+
+These procedures are compositions of car and cdr as follows:
+
+(define (caar x) (car (car x)))
+(define (cadr x) (car (cdr x)))
+(define (cdar x) (cdr (car x)))
+(define (cddr x) (cdr (cdr x)))
+
+cxr library procedure: (caaar pair)
+cxr library procedure: (caadr pair)
+1 ⋮: 0 ⋮
+cxr library procedure: (cdddar pair)
+cxr library procedure: (cddddr pair)
+
+These twenty-four procedures are further compositions of car and cdr on the same
+principles. For example, caddr could be defined by
+
+(define caddr (lambda (x) (car (cdr (cdr x))))). Arbitrary compositions up to four deep are
+provided.
+
+procedure: (null? obj)
+
+Returns #t if
+
+obj is the empty list, otherwise returns #f.
+
+procedure: (list? obj)
+
+Returns #t if
+
+obj is a list. Otherwise, it returns #f. By definition, all lists have finite length and are
+terminated by the empty list.
+
+(list? '(a b c)) ⟹ #t
+ (list? '()) ⟹ #t
+ (list? '(a . b)) ⟹ #f
+ (let ((x (list 'a)))
+ (set-cdr! x x)
+ (list? x)) ⟹ #f
+
+procedure: (make-list k)
+procedure: (make-list k fill)
+
+Returns a newly allocated list of
+
+k elements. If a second argument is given, then each element is initialized to
+
+fill. Otherwise the initial contents of each element is unspecified.
+
+(make-list 2 3) ⟹ (3 3)
+
+procedure: (list
+
+obj …)
+
+
+Returns a newly allocated list of its arguments.
+
+(list 'a (+ 3 4) 'c) ⟹ (a 7 c)
+(list) ⟹ ()
+
+procedure: (length list)
+
+Returns the length of
+
+list.
+
+(length '(a b c)) ⟹ 3
+(length '(a (b) (c d e))) ⟹ 3
+(length '()) ⟹ 0
+
+procedure: (append list …)
+
+The last argument, if there is one, can be of any type.
+
+Returns a list consisting of the elements of the first
+
+list followed by the elements of the other
+
+lists. If there are no arguments, the empty list is returned. If there is exactly one
+argument, it is returned. Otherwise the resulting list is always newly allocated, except
+that it shares structure with the last argument. An improper list results if the last
+argument is not a proper list.
+
+(append '(x) '(y)) ⟹ (x y)
+(append '(a) '(b c d)) ⟹ (a b c d)
+(append '(a (b)) '((c))) ⟹ (a (b) (c))
+
+(append '(a b) '(c . d)) ⟹ (a b c . d)
+(append '() 'a) ⟹ a
+
+procedure: (reverse list)
+
+Returns a newly allocated list consisting of the elements of
+
+list in reverse order.
+
+(reverse '(a b c)) ⟹ (c b a)
+(reverse '(a (b c) d (e (f))))
+⟹ ((e (f)) d (b c) a)
+
+procedure: (list-tail list
+
+k)
+
+
+It is an error if
+
+list has fewer than
+
+k elements.
+
+Returns the sublist of
+
+list obtained by omitting the first
+
+k elements. The list-tail procedure could be defined by
+
+(define list-tail
+ (lambda (x k)
+ (if (zero? k)
+ x
+ (list-tail (cdr x) (- k 1)))))
+
+procedure: (list-ref list
+
+k)
+
+
+The
+
+list argument can be circular, but it is an error if
+
+list has
+
+k or fewer elements.
+
+Returns the
+
+kth element of
+
+list. (This is the same as the car of (list-tail
+
+list
+
+k).)
+
+(list-ref '(a b c d) 2) ⟹ c
+(list-ref '(a b c d)
+ (exact (round 1.8)))
+⟹ c
+
+procedure: (list-set! list k obj)
+
+It is an error if
+
+k is not a valid index of
+
+list.
+
+The list-set! procedure stores
+
+obj in element
+
+k of
+
+list.
+
+(let ((ls (list 'one 'two 'five!)))
+ (list-set! ls 2 'three)
+ ls)
+⟹ (one two three)
+
+(list-set! '(0 1 2) 1 "oops")
+⟹ error ; constant list
+
+procedure: (memq obj list)
+procedure: (memv obj list)
+procedure: (member obj list)
+procedure: (member obj list compare)
+
+These procedures return the first sublist of
+
+list whose car is
+
+obj, where the sublists of
+
+list are the non-empty lists returned by (list-tail
+
+list
+
+k) for
+
+k less than the length of
+
+list. If
+
+obj does not occur in
+
+list, then #f (not the empty list) is returned. The memq procedure uses eq? to compare
+
+obj with the elements of
+
+list, while memv uses eqv? and member uses
+
+compare, if given, and equal? otherwise.
+
+(memq 'a '(a b c)) ⟹ (a b c)
+(memq 'b '(a b c)) ⟹ (b c)
+(memq 'a '(b c d)) ⟹ #f
+(memq (list 'a) '(b (a) c)) ⟹ #f
+(member (list 'a)
+ '(b (a) c)) ⟹ ((a) c)
+(member "B"
+ '("a" "b" "c")
+ string-ci=?) ⟹ ("b" "c")
+(memq 101 '(100 101 102)) ⟹ unspecified
+(memv 101 '(100 101 102)) ⟹ (101 102)
+
+procedure: (assq obj alist)
+procedure: (assv obj alist)
+procedure: (assoc obj alist)
+procedure: (assoc obj alist compare)
+
+It is an error if
+
+alist (for “association list”) is not a list of pairs.
+
+These procedures find the first pair in
+
+alist whose car field is
+
+obj, and returns that pair. If no pair in
+
+alist has
+
+obj as its car, then #f (not the empty list) is returned. The assq procedure uses eq? to
+compare
+
+obj with the car fields of the pairs in
+
+alist, while assv uses eqv? and assoc uses
+
+compare if given and equal? otherwise.
+
+(define e '((a 1) (b 2) (c 3)))
+(assq 'a e) ⟹ (a 1)
+(assq 'b e) ⟹ (b 2)
+(assq 'd e) ⟹ #f
+(assq (list 'a) '(((a)) ((b)) ((c))))
+ ⟹ #f
+(assoc (list 'a) '(((a)) ((b)) ((c))))
+ ⟹ ((a))
+(assoc 2.0 '((1 1) (2 4) (3 9)) =)
+ ⟹ (2 4)
+(assq 5 '((2 3) (5 7) (11 13)))
+ ⟹ unspecified
+(assv 5 '((2 3) (5 7) (11 13)))
+ ⟹ (5 7)
+
+ Rationale: Although they are often used as predicates, memq, memv, member, assq,
+ assv, and assoc do not have question marks in their names because they return
+ potentially useful values rather than just #t or #f.
+
+procedure: (list-copy obj)
+
+Returns a newly allocated copy of the given
+
+obj if it is a list. Only the pairs themselves are copied; the cars of the result are the same
+(in the sense of eqv?) as the cars of
+
+list. If
+
+obj is an improper list, so is the result, and the final cdrs are the same in the sense of
+eqv?. An
+
+obj which is not a list is returned unchanged. It is an error if
+
+obj is a circular list.
+
+(define a '(1 8 2 8)) ; a may be immutable
+(define b (list-copy a))
+(set-car! b 3) ; b is mutable
+b ⟹ (3 8 2 8)
+a ⟹ (1 8 2 8)
+
+@node Symbols
+@section Symbols
+
+Symbols are objects whose usefulness rests on the fact that two symbols are identical (in
+the sense of eqv?) if and only if their names are spelled the same way. For instance, they
+can be used the way enumerated values are used in other languages.
+
+The rules for writing a symbol are exactly the same as the rules for writing an identifier;
+see sections 2.1 and 7.1.1.
+
+It is guaranteed that any symbol that has been returned as part of a literal expression,
+or read using the read procedure, and subsequently written out using the write
+procedure, will read back in as the identical symbol (in the sense of eqv?).
+
+ Note: Some implementations have values known as “uninterned symbols,” which
+ defeat write/read invariance, and also violate the rule that two symbols are the
+ same if and only if their names are spelled the same. This report does not specify
+ the behavior of implementation-dependent extensions.
+
+procedure: (symbol? obj)
+
+Returns #t if
+
+obj is a symbol, otherwise returns #f.
+
+(symbol? 'foo) ⟹ #t
+(symbol? (car '(a b))) ⟹ #t
+(symbol? "bar") ⟹ #f
+(symbol? 'nil) ⟹ #t
+(symbol? '()) ⟹ #f
+(symbol? #f) ⟹ #f
+
+procedure: (symbol=?
+
+symbol1
+
+symbol2
+
+symbol3 …)
+
+
+Returns #t if all the arguments all have the same names in the sense of string=?.
+
+ Note: The definition above assumes that none of the arguments are uninterned
+ symbols.
+
+procedure: (symbol->string symbol)
+
+Returns the name of
+
+symbol as a string, but without adding escapes. It is an error to apply mutation
+procedures like string-set! to strings returned by this procedure.
+
+(symbol->string 'flying-fish)
+ ⟹ "flying-fish"
+(symbol->string 'Martin) ⟹ "Martin"
+(symbol->string
+ (string->symbol "Malvina"))
+ ⟹ "Malvina"
+
+procedure: (string->symbol string)
+
+Returns the symbol whose name is
+
+string. This procedure can create symbols with names containing special characters that
+would require escaping when written, but does not interpret escapes in its input.
+
+(string->symbol "mISSISSIppi")
+⟹mISSISSIppi
+(eqv? 'bitBlt (string->symbol "bitBlt"))
+⟹ #t
+(eqv? 'LollyPop
+ (string->symbol
+ (symbol->string 'LollyPop)))
+⟹ #t
+(string=? "K. Harper, M.D."
+ (symbol->string
+ (string->symbol "K. Harper, M.D.")))
+⟹ #t
+
+@node Characters
+@section Characters
+
+Characters are objects that represent printed characters such as letters and digits. All
+Scheme implementations must support at least the ASCII character repertoire: that is,
+Unicode characters U+0000 through U+007F. Implementations may support any other
+Unicode characters they see fit, and may also support non-Unicode characters as well.
+Except as otherwise specified, the result of applying any of the following procedures to a
+non-Unicode character is implementation-dependent.
+
+Characters are written using the notation #\<character> or #\<character name> or
+#\x<hex scalar value>.
+
+The following character names must be supported by all implementations with the given
+values. Implementations may add other names provided they cannot be interpreted as
+hex scalar values preceded by x.
+
+ #\alarm ; U+0007
+ #\backspace ; U+0008
+ #\delete ; U+007F
+ #\escape ; U+001B
+ #\newline ; the
+ linefeed
+ character,
+ U+000A
+ #\null ; the null
+ character,
+ U+0000
+ #\return ; the
+ return
+ character,
+ U+000D
+ #\space ; the
+ preferred
+ way to
+ write a
+ space
+ #\tab ; the tab
+ character,
+ U+0009
+
+Here are some additional examples:
+
+ #\a ; lower case
+ letter
+ #\A ; upper case
+ letter
+ #\( ; left
+ parenthesis
+ #\ ; the space
+ character
+ #\x03BB ; λ (if
+ character is
+ supported)
+ #\iota ; ι (if
+ character
+ and name
+ are
+ supported)
+
+Case is significant in #\<character>, and in #\⟨character name⟩, but not in #\x<hex scalar
+value>. If <character> in #\<character> is alphabetic, then any character immediately
+following <character> cannot be one that can appear in an identifier. This rule resolves
+the ambiguous case where, for example, the sequence of characters “#\space” could be
+taken to be either a representation of the space character or a representation of the
+character “#\s” followed by a representation of the symbol “pace.”
+
+Characters written in the #\ notation are self-evaluating. That is, they do not have to be
+quoted in programs. Some of the procedures that operate on characters ignore the
+difference between upper case and lower case. The procedures that ignore case have
+“-ci” (for “case insensitive”) embedded in their names.
+
+procedure: (char? obj)
+
+Returns #t if
+
+obj is a character, otherwise returns #f.
+
+procedure: (char=?
+
+char1
+
+char2
+
+char3 …)
+
+
+procedure: (char<?
+
+char1
+
+char2
+
+char3 …)
+
+
+procedure: (char>?
+
+char1
+
+char2
+
+char3 …)
+
+
+procedure: (char<=?
+
+char1
+
+char2
+
+char3 …)
+
+
+procedure: (char>=?
+
+char1
+
+char2
+
+char3 …)
+
+
+These procedures return #t if the results of passing their arguments to char->integer
+are respectively equal, monotonically increasing, monotonically decreasing,
+monotonically non-decreasing, or monotonically non-increasing.
+
+These predicates are required to be transitive.
+
+char library procedure: (char-ci=?
+
+char1
+
+char2
+
+char3 …)
+
+
+char library procedure: (char-ci<?
+
+char1
+
+char2
+
+char3 …)
+
+
+char library procedure: (char-ci>?
+
+char1
+
+char2
+
+char3 …)
+
+
+char library procedure: (char-ci<=?
+
+char1
+
+char2
+
+char3 …)
+
+
+char library procedure: (char-ci>=?
+
+char1
+
+char2
+
+char3 …)
+
+
+These procedures are similar to char=? et cetera, but they treat upper case and lower
+case letters as the same. For example, (char-ci=? #\A #\a) returns #t.
+
+Specifically, these procedures behave as if char-foldcase were applied to their
+arguments before they were compared.
+
+char library procedure: (char-alphabetic? char)
+char library procedure: (char-numeric? char)
+char library procedure: (char-whitespace? char)
+char library procedure: (char-upper-case? letter)
+char library procedure: (char-lower-case? letter)
+
+These procedures return #t if their arguments are alphabetic, numeric, whitespace,
+upper case, or lower case characters, respectively, otherwise they return #f. Specifically,
+they must return #t when applied to characters with the Unicode properties Alphabetic,
+Numeric_Type=Decimal, White_Space, Uppercase, and Lowercase respectively, and #f
+when applied to any other Unicode characters. Note that many Unicode characters are
+alphabetic but neither upper nor lower case.
+
+char library procedure: (digit-value char)
+
+This procedure returns the numeric value (0 to 9) of its argument if it is a numeric digit
+(that is, if char-numeric? returns #t), or #f on any other character.
+
+(digit-value #\3) ⟹ 3
+(digit-value #\x0664) ⟹ 4
+(digit-value #\x0AE6) ⟹ 0
+(digit-value #\x0EA6) ⟹ #f
+
+procedure: (char->integer char)
+procedure: (integer->char
+
+n)
+
+
+Given a Unicode character, char->integer returns an exact integer between 0 and #xD7FF
+or between #xE000 and #x10FFFF which is equal to the Unicode scalar value of that
+character. Given a non-Unicode character, it returns an exact integer greater than
+#x10FFFF. This is true independent of whether the implementation uses the Unicode
+representation internally.
+
+Given an exact integer that is the value returned by a character when char->integer is
+applied to it, integer->char returns that character.
+
+char library procedure: (char-upcase char)
+char library procedure: (char-downcase char)
+char library procedure: (char-foldcase char)
+
+The char-upcase procedure, given an argument that is the lowercase part of a Unicode
+casing pair, returns the uppercase member of the pair, provided that both characters
+are supported by the Scheme implementation. Note that language-sensitive casing pairs
+are not used. If the argument is not the lowercase member of such a pair, it is returned.
+
+The char-downcase procedure, given an argument that is the uppercase part of a
+Unicode casing pair, returns the lowercase member of the pair, provided that both
+characters are supported by the Scheme implementation. Note that language-sensitive
+casing pairs are not used. If the argument is not the uppercase member of such a pair, it
+is returned.
+
+The char-foldcase procedure applies the Unicode simple case-folding algorithm to its
+argument and returns the result. Note that language-sensitive folding is not used. If the
+character that results from folding is not supported by the implementation, the
+argument is returned. See UAX #44 [11] (part of the Unicode Standard) for details.
+
+Note that many Unicode lowercase characters do not have uppercase equivalents.
+
+@node Strings
+@section Strings
+
+Strings are sequences of characters. Strings are written as sequences of characters
+enclosed within quotation marks ("). Within a string literal, various escape
+sequencesrepresent characters other than themselves. Escape sequences always start
+with a backslash (\):
+
+* \a : alarm, U+0007
+
+* \b : backspace, U+0008
+
+* \t : character tabulation, U+0009
+
+* \n : linefeed, U+000A
+
+* \r : return, U+000D
+
+* \" : double quote, U+0022
+
+* \\ : backslash, U+005C
+
+* \| : vertical line, U+007C
+
+* \<intraline whitespace>*<line ending> <intraline whitespace>* : nothing
+
+* \x<hex scalar value>; : specified character (note the terminating semi-colon).
+
+The result is unspecified if any other character in a string occurs after a backslash.
+
+Except for a line ending, any character outside of an escape sequence stands for itself in
+the string literal. A line ending which is preceded by \<intraline whitespace> expands to
+nothing (along with any trailing intraline whitespace), and can be used to indent strings
+for improved legibility. Any other line ending has the same effect as inserting a \n
+character into the string.
+
+Examples:
+
+"The word \"recursion\" has many meanings."
+"Another example:\ntwo lines of text"
+"Here's text \
+ containing just one line"
+"\x03B1; is named GREEK SMALL LETTER ALPHA." The length of a string is the number of
+characters that it contains. This number is an exact, non-negative integer that is fixed
+when the string is created. The valid indexes of a string are the exact non-negative
+integers less than the length of the string. The first character of a string has index 0, the
+second has index 1, and so on.
+
+Some of the procedures that operate on strings ignore the difference between upper
+and lower case. The names of the versions that ignore case end with “-ci” (for “case
+insensitive”).
+
+Implementations may forbid certain characters from appearing in strings. However, with
+the exception of #\null, ASCII characters must not be forbidden. For example, an
+implementation might support the entire Unicode repertoire, but only allow characters
+U+0001 to U+00FF (the Latin-1 repertoire without #\null) in strings.
+
+It is an error to pass such a forbidden character to make-string, string, string-set!, or
+string-fill!, as part of the list passed to list->string, or as part of the vector passed to
+vector->string (see section 6.8), or in UTF-8 encoded form within a bytevector passed to
+utf8->string (see section 6.9). It is also an error for a procedure passed to string-map
+(see section 6.10) to return a forbidden character, or for read-string (see section 6.13.2)
+to attempt to read one.
+
+procedure: (string? obj)
+
+Returns #t if
+
+obj is a string, otherwise returns #f.
+
+procedure: (make-string
+
+k)
+
+
+procedure: (make-string
+
+k char)
+
+
+The make-string procedure returns a newly allocated string of length
+
+k. If
+
+char is given, then all the characters of the string are initialized to
+
+char, otherwise the contents of the string are unspecified.
+
+procedure: (string char …)
+
+Returns a newly allocated string composed of the arguments. It is analogous to list.
+
+procedure: (string-length string)
+
+Returns the number of characters in the given
+
+string.
+
+procedure: (string-ref string
+
+k)
+
+
+It is an error if
+
+k is not a valid index of
+
+string.
+
+The string-ref procedure returns character
+
+k of
+
+string using zero-origin indexing.
+
+There is no requirement for this procedure to execute in constant time.
+
+procedure: (string-set! string k char)
+
+It is an error if
+
+k is not a valid index of
+
+string.
+
+The string-set! procedure stores
+
+char in element
+
+k of
+
+string. There is no requirement for this procedure to execute in constant time.
+
+(define (f) (make-string 3 #\*))
+(define (g) "***")
+(string-set! (f) 0 #\?) ⟹ unspecified
+(string-set! (g) 0 #\?) ⟹ error
+(string-set! (symbol->string 'immutable)
+ 0
+ #\?) ⟹ error
+
+procedure: (string=?
+
+string1
+
+string2
+
+string3 …)
+
+
+Returns #t if all the strings are the same length and contain exactly the same characters
+in the same positions, otherwise returns #f.
+
+char library procedure: (string-ci=?
+
+string1
+
+string2
+
+string3 …)
+
+
+Returns #t if, after case-folding, all the strings are the same length and contain the same
+characters in the same positions, otherwise returns #f. Specifically, these procedures
+behave as if string-foldcase were applied to their arguments before comparing them.
+
+procedure: (string<?
+
+string1
+
+string2
+
+string3 …)
+
+
+char library procedure: (string-ci<?
+
+string1
+
+string2
+
+string3 …)
+
+
+procedure: (string>?
+
+string1
+
+string2
+
+string3 …)
+
+
+char library procedure: (string-ci>?
+
+string1
+
+string2
+
+string3 …)
+
+
+procedure: (string<=?
+
+string1
+
+string2
+
+string3 …)
+
+
+char library procedure: (string-ci<=?
+
+string1
+
+string2
+
+string3 …)
+
+
+procedure: (string>=?
+
+string1
+
+string2
+
+string3 …)
+
+
+char library procedure: (string-ci>=?
+
+string1
+
+string2
+
+string3 …)
+
+
+These procedures return #t if their arguments are (respectively): monotonically
+increasing, monotonically decreasing, monotonically non-decreasing, or monotonically
+non-increasing.
+
+These predicates are required to be transitive.
+
+These procedures compare strings in an implementation-defined way. One approach is
+to make them the lexicographic extensions to strings of the corresponding orderings on
+characters. In that case, string<? would be the lexicographic ordering on strings induced
+by the ordering char<? on characters, and if the two strings differ in length but are the
+same up to the length of the shorter string, the shorter string would be considered to be
+lexicographically less than the longer string. However, it is also permitted to use the
+natural ordering imposed by the implementation’s internal representation of strings, or
+a more complex locale-specific ordering.
+
+In all cases, a pair of strings must satisfy exactly one of string<?, string=?, and string>?,
+and must satisfy string<=? if and only if they do not satisfy string>? and string>=? if and
+only if they do not satisfy string<?.
+
+The “-ci” procedures behave as if they applied string-foldcase to their arguments before
+invoking the corresponding procedures without “-ci”.
+
+char library procedure: (string-upcase string)
+char library procedure: (string-downcase string)
+char library procedure: (string-foldcase string)
+
+These procedures apply the Unicode full string uppercasing, lowercasing, and
+case-folding algorithms to their arguments and return the result. In certain cases, the
+result differs in length from the argument. If the result is equal to the argument in the
+sense of string=?, the argument may be returned. Note that language-sensitive
+mappings and foldings are not used. The Unicode Standard prescribes special
+treatment of the Greek letter Σ, whose normal lower-case form is σ but which becomes ς
+at the end of a word. See UAX #44 [11] (part of the Unicode Standard) for details.
+However, implementations of string-downcase are not required to provide this
+behavior, and may choose to change Σ to σ in all cases.
+
+procedure: (substring string start end)
+
+The substring procedure returns a newly allocated string formed from the characters of
+
+string beginning with index
+
+start and ending with index
+
+end. This is equivalent to calling string-copy with the same arguments, but is provided
+for backward compatibility and stylistic flexibility.
+
+procedure: (string-append
+
+string …)
+
+
+Returns a newly allocated string whose characters are the concatenation of the
+characters in the given strings.
+
+procedure: (string->list string)
+procedure: (string->list string start)
+procedure: (string->list string start end)
+procedure: (list->string list)
+
+It is an error if any element of
+
+list is not a character.
+
+The string->list procedure returns a newly allocated list of the characters of
+
+string between
+
+start and
+
+end. list->string returns a newly allocated string formed from the elements in the list
+
+list. In both procedures, order is preserved. string->list and list->string are inverses so
+far as equal? is concerned.
+
+procedure: (string-copy string)
+procedure: (string-copy string start)
+procedure: (string-copy string start end)
+
+Returns a newly allocated copy of the part of the given
+
+string between
+
+start and
+
+end.
+
+procedure: (string-copy! to at from)
+procedure: (string-copy! to at from start)
+procedure: (string-copy! to at from start end)
+
+It is an error if
+
+at is less than zero or greater than the length of
+
+to. It is also an error if (- (string-length
+
+to)
+
+at) is less than (-
+
+end
+
+start).
+
+Copies the characters of string
+
+from between
+
+start and
+
+end to string
+
+to, starting at
+
+at. The order in which characters are copied is unspecified, except that if the source and
+destination overlap, copying takes place as if the source is first copied into a temporary
+string and then into the destination. This can be achieved without allocating storage by
+making sure to copy in the correct direction in such circumstances.
+
+(define a "12345")
+(define b (string-copy "abcde"))
+(string-copy! b 1 a 0 2)
+b ⟹ "a12de"
+
+procedure: (string-fill! string fill)
+procedure: (string-fill! string fill start)
+procedure: (string-fill! string fill start end)
+
+It is an error if
+
+fill is not a character.
+
+The string-fill! procedure stores
+
+fill in the elements of
+
+string between
+
+start and
+
+end.
+
+@node Vectors
+@section Vectors
+
+Vectors are heterogeneous structures whose elements are indexed by integers. A vector
+typically occupies less space than a list of the same length, and the average time needed
+to access a randomly chosen element is typically less for the vector than for the list.
+
+The length of a vector is the number of elements that it contains. This number is a
+non-negative integer that is fixed when the vector is created. The valid indexesof a vector
+are the exact non-negative integers less than the length of the vector. The first element
+in a vector is indexed by zero, and the last element is indexed by one less than the length
+of the vector.
+
+Vectors are written using the notation #(
+
+obj …). For example, a vector of length 3 containing the number zero in element 0, the
+list (2 2 2 2) in element 1, and the string "Anna" in element 2 can be written as follows:
+
+#(0 (2 2 2 2) "Anna") Vector constants are self-evaluating, so they do not need to be
+quoted in programs.
+
+procedure: (vector? obj)
+
+Returns #t if
+
+obj is a vector; otherwise returns #f.
+
+procedure: (make-vector k)
+procedure: (make-vector k fill)
+
+Returns a newly allocated vector of
+
+k elements. If a second argument is given, then each element is initialized to
+
+fill. Otherwise the initial contents of each element is unspecified.
+
+procedure: (vector obj …)
+
+Returns a newly allocated vector whose elements contain the given arguments. It is
+analogous to list.
+
+(vector 'a 'b 'c) ⟹ #(a b c)
+
+procedure: (vector-length vector)
+
+Returns the number of elements in
+
+vector as an exact integer.
+
+procedure: (vector-ref vector k)
+
+It is an error if
+
+k is not a valid index of
+
+vector.
+
+The vector-ref procedure returns the contents of element
+
+k of
+
+vector.
+
+(vector-ref '#(1 1 2 3 5 8 13 21)
+ 5)
+⟹ 8
+(vector-ref '#(1 1 2 3 5 8 13 21)
+ (exact
+ (round (* 2 (acos -1)))))
+⟹ 13
+
+procedure: (vector-set! vector k obj)
+
+It is an error if
+
+k is not a valid index of
+
+vector.
+
+The vector-set! procedure stores
+
+obj in element
+
+k of
+
+vector.
+
+(let ((vec (vector 0 '(2 2 2 2) "Anna")))
+ (vector-set! vec 1 '("Sue" "Sue"))
+ vec)
+⟹ #(0 ("Sue" "Sue") "Anna")
+
+(vector-set! '#(0 1 2) 1 "doe")
+⟹ error ; constant vector
+
+procedure: (vector->list vector)
+procedure: (vector->list vector start)
+procedure: (vector->list vector start end)
+procedure: (list->vector list)
+
+The vector->list procedure returns a newly allocated list of the objects contained in the
+elements of
+
+vector between
+
+start and
+
+end. The list->vector procedure returns a newly created vector initialized to the elements
+of the list
+
+list.
+
+In both procedures, order is preserved.
+
+(vector->list '#(dah dah didah))
+⟹ (dah dah didah)
+(vector->list '#(dah dah didah) 1 2)
+⟹ (dah)
+(list->vector '(dididit dah))
+⟹ #(dididit dah)
+
+procedure: (vector->string vector)
+procedure: (vector->string vector start)
+procedure: (vector->string vector start end)
+procedure: (string->vector string)
+procedure: (string->vector string start)
+procedure: (string->vector string start end)
+
+It is an error if any element of
+
+vector between
+
+start and
+
+end is not a character.
+
+The vector->string procedure returns a newly allocated string of the objects contained in
+the elements of
+
+vector between
+
+start and
+
+end. The string->vector procedure returns a newly created vector initialized to the
+elements of the string
+
+string between
+
+start and
+
+end.
+
+In both procedures, order is preserved.
+
+(string->vector "ABC") ⟹ #(#\A #\B #\C)
+(vector->string
+ #(#\1 #\2 #\3) ⟹ "123"
+
+procedure: (vector-copy vector)
+procedure: (vector-copy vector start)
+procedure: (vector-copy vector start end)
+
+Returns a newly allocated copy of the elements of the given
+
+vector between
+
+start and
+
+end. The elements of the new vector are the same (in the sense of eqv?) as the elements
+of the old.
+
+(define a #(1 8 2 8)) ; a may be immutable
+(define b (vector-copy a))
+(vector-set! b 0 3) ; b is mutable
+b ⟹ #(3 8 2 8)
+(define c (vector-copy b 1 3))
+c ⟹ #(8 2)
+
+procedure: (vector-copy! to at from)
+procedure: (vector-copy! to at from start)
+procedure: (vector-copy! to at from start end)
+
+It is an error if
+
+at is less than zero or greater than the length of
+
+to. It is also an error if (- (vector-length
+
+to)
+
+at) is less than (-
+
+end
+
+start).
+
+Copies the elements of vector
+
+from between
+
+start and
+
+end to vector
+
+to, starting at
+
+at. The order in which elements are copied is unspecified, except that if the source and
+destination overlap, copying takes place as if the source is first copied into a temporary
+vector and then into the destination. This can be achieved without allocating storage by
+making sure to copy in the correct direction in such circumstances.
+
+(define a (vector 1 2 3 4 5))
+(define b (vector 10 20 30 40 50))
+(vector-copy! b 1 a 0 2)
+b ⟹ #(10 1 2 40 50)
+
+procedure: (vector-append
+
+vector …)
+
+
+Returns a newly allocated vector whose elements are the concatenation of the elements
+of the given vectors.
+
+(vector-append #(a b c) #(d e f))
+⟹ #(a b c d e f)
+
+procedure: (vector-fill! vector fill)
+procedure: (vector-fill! vector fill start)
+procedure: (vector-fill! vector fill start end)
+
+The vector-fill! procedure stores
+
+fill in the elements of
+
+vector between
+
+start and
+
+end.
+
+(define a (vector 1 2 3 4 5))
+(vector-fill! a 'smash 2 4)
+a
+⟹ #(1 2 smash smash 5)
+
+@node Bytevectors
+@section Bytevectors
+
+Bytevectors represent blocks of binary data. They are fixed-length sequences of bytes,
+where a byte is an exact integer in the range from 0 to 255 inclusive. A bytevector is
+typically more space-efficient than a vector containing the same values.
+
+The length of a bytevector is the number of elements that it contains. This number is a
+non-negative integer that is fixed when the bytevector is created. The valid indexesof a
+bytevector are the exact non-negative integers less than the length of the bytevector,
+starting at index zero as with vectors.
+
+Bytevectors are written using the notation #u8(
+
+byte …). For example, a bytevector of length 3 containing the byte 0 in element 0, the byte
+10 in element 1, and the byte 5 in element 2 can be written as follows:
+
+#u8(0 10 5) Bytevector constants are self-evaluating, so they do not need to be quoted in
+programs.
+
+procedure: (bytevector? obj)
+
+Returns #t if
+
+obj is a bytevector. Otherwise, #f is returned.
+
+procedure: (make-bytevector k)
+procedure: (make-bytevector k byte)
+
+The make-bytevector procedure returns a newly allocated bytevector of length
+
+k. If
+
+byte is given, then all elements of the bytevector are initialized to
+
+byte, otherwise the contents of each element are unspecified.
+
+(make-bytevector 2 12) ⟹ #u8(12 12)
+
+procedure: (bytevector
+
+byte …)
+
+
+Returns a newly allocated bytevector containing its arguments.
+
+(bytevector 1 3 5 1 3 5) ⟹ #u8(1 3 5 1 3 5)
+(bytevector) ⟹ #u8()
+
+procedure: (bytevector-length bytevector)
+
+Returns the length of
+
+bytevector in bytes as an exact integer.
+
+procedure: (bytevector-u8-ref bytevector k)
+
+It is an error if
+
+k is not a valid index of
+
+bytevector.
+
+Returns the
+
+kth byte of
+
+bytevector.
+
+(bytevector-u8-ref '#u8(1 1 2 3 5 8 13 21)
+ 5)
+⟹ 8
+
+procedure: (bytevector-u8-set! bytevector k byte)
+
+It is an error if
+
+k is not a valid index of
+
+bytevector.
+
+Stores
+
+byte as the
+
+kth byte of
+
+bytevector.
+
+(let ((bv (bytevector 1 2 3 4)))
+ (bytevector-u8-set! bv 1 3)
+ bv)
+⟹ #u8(1 3 3 4)
+
+procedure: (bytevector-copy bytevector)
+procedure: (bytevector-copy bytevector start)
+procedure: (bytevector-copy bytevector start end)
+
+Returns a newly allocated bytevector containing the bytes in
+
+bytevector between
+
+start and
+
+end.
+
+(define a #u8(1 2 3 4 5))
+(bytevector-copy a 2 4)) ⟹ #u8(3 4)
+
+procedure: (bytevector-copy! to at from)
+procedure: (bytevector-copy! to at from start)
+procedure: (bytevector-copy! to at from start end)
+
+It is an error if
+
+at is less than zero or greater than the length of
+
+to. It is also an error if (- (bytevector-length
+
+to)
+
+at) is less than (-
+
+end
+
+start).
+
+Copies the bytes of bytevector
+
+from between
+
+start and
+
+end to bytevector
+
+to, starting at
+
+at. The order in which bytes are copied is unspecified, except that if the source and
+destination overlap, copying takes place as if the source is first copied into a temporary
+bytevector and then into the destination. This can be achieved without allocating storage
+by making sure to copy in the correct direction in such circumstances.
+
+(define a (bytevector 1 2 3 4 5))
+(define b (bytevector 10 20 30 40 50))
+(bytevector-copy! b 1 a 0 2)
+b ⟹ #u8(10 1 2 40 50)
+
+ Note: This procedure appears in R6RS, but places the source before the destination,
+ contrary to other such procedures in Scheme.
+
+procedure: (bytevector-append
+
+bytevector …)
+
+
+Returns a newly allocated bytevector whose elements are the concatenation of the
+elements in the given bytevectors.
+
+(bytevector-append #u8(0 1 2) #u8(3 4 5))
+⟹ #u8(0 1 2 3 4 5)
+
+procedure: (utf8->string bytevector)
+procedure: (utf8->string bytevector start)
+procedure: (utf8->string bytevector start end)
+procedure: (string->utf8 string)
+procedure: (string->utf8 string start)
+procedure: (string->utf8 string start end)
+
+It is an error for
+
+bytevector to contain invalid UTF-8 byte sequences.
+
+These procedures translate between strings and bytevectors that encode those strings
+using the UTF-8 encoding. The utf8->string procedure decodes the bytes of a bytevector
+between
+
+start and
+
+end and returns the corresponding string; the string->utf8 procedure encodes the
+characters of a string between
+
+start and
+
+end and returns the corresponding bytevector.
+
+(utf8->string #u8(#x41)) ⟹ "A"
+(string->utf8 "λ") ⟹ #u8(#xCE #xBB)
+
+@node Control features
+@section Control features
+
+This section describes various primitive procedures which control the flow of program
+execution in special ways. Procedures in this section that invoke procedure arguments
+always do so in the same dynamic environment as the call of the original procedure. The
+procedure? predicate is also described here.
+
+procedure: (procedure? obj)
+
+Returns #t if
+
+obj is a procedure, otherwise returns #f.
+
+(procedure? car) ⟹ #t
+(procedure? 'car) ⟹ #f
+(procedure? (lambda (x) (* x x)))
+ ⟹ #t
+(procedure? '(lambda (x) (* x x)))
+ ⟹ #f
+(call-with-current-continuation procedure?)
+ ⟹ #t
+
+procedure: (apply proc
+
+arg1 … args)
+
+
+The apply procedure calls
+
+proc with the elements of the list (append (list
+
+arg1 …)
+
+args) as the actual arguments.
+
+(apply + (list 3 4)) ⟹ 7
+
+(define compose
+ (lambda (f g)
+ (lambda args
+ (f (apply g args)))))
+
+((compose sqrt *) 12 75) ⟹ 30
+
+procedure: (map proc
+
+list1
+
+list2 …)
+
+
+It is an error if
+
+proc does not accept as many arguments as there are lists and return a single value.
+
+The map procedure applies
+
+proc element-wise to the elements of the
+
+lists and returns a list of the results, in order. If more than one
+
+list is given and not all lists have the same length, map terminates when the shortest list
+runs out. The
+
+lists can be circular, but it is an error if all of them are circular. It is an error for
+
+proc to mutate any of the lists. The dynamic order in which
+
+proc is applied to the elements of the
+
+lists is unspecified. If multiple returns occur from map, the values returned by earlier
+returns are not mutated.
+
+(map cadr '((a b) (d e) (g h)))
+⟹ (b e h)
+
+(map (lambda (n) (expt n n))
+ '(1 2 3 4 5))
+⟹ (1 4 27 256 3125)
+
+(map + '(1 2 3) '(4 5 6 7)) ⟹ (5 7 9)
+
+(let ((count 0))
+ (map (lambda (ignored)
+ (set! count (+ count 1))
+ count)
+ '(a b))) ⟹ (1 2)
+
+or (2 1)
+
+procedure: (string-map proc
+
+string1
+
+string2 …)
+
+
+It is an error if
+
+proc does not accept as many arguments as there are strings and return a single
+character.
+
+The string-map procedure applies
+
+proc element-wise to the elements of the
+
+strings and returns a string of the results, in order. If more than one
+
+string is given and not all strings have the same length, string-map terminates when the
+shortest string runs out. The dynamic order in which
+
+proc is applied to the elements of the
+
+strings is unspecified. If multiple returns occur from string-map, the values returned by
+earlier returns are not mutated.
+
+(string-map char-foldcase "AbdEgH")
+⟹ "abdegh"
+
+(string-map
+ (lambda (c)
+ (integer->char (+ 1 (char->integer c))))
+ "HAL")
+⟹ "IBM"
+
+(string-map
+ (lambda (c k)
+ ((if (eqv? k #\u) char-upcase char-downcase)
+ c))
+ "studlycaps xxx"
+ "ululululul")
+⟹ "StUdLyCaPs"
+
+procedure: (vector-map proc
+
+vector1
+
+vector2 …)
+
+
+It is an error if
+
+proc does not accept as many arguments as there are vectors and return a single value.
+
+The vector-map procedure applies
+
+proc element-wise to the elements of the
+
+vectors and returns a vector of the results, in order. If more than one
+
+vector is given and not all vectors have the same length, vector-map terminates when the
+shortest vector runs out. The dynamic order in which
+
+proc is applied to the elements of the
+
+vectors is unspecified. If multiple returns occur from vector-map, the values returned by
+earlier returns are not mutated.
+
+(vector-map cadr '#((a b) (d e) (g h)))
+⟹ #(b e h)
+
+(vector-map (lambda (n) (expt n n))
+ '#(1 2 3 4 5))
+⟹ #(1 4 27 256 3125)
+
+(vector-map + '#(1 2 3) '#(4 5 6 7))
+⟹ #(5 7 9)
+
+(let ((count 0))
+ (vector-map
+ (lambda (ignored)
+ (set! count (+ count 1))
+ count)
+ '#(a b))) ⟹ #(1 2)
+
+or #(2 1)
+
+procedure: (for-each proc
+
+list1
+
+list2 …)
+
+
+It is an error if
+
+proc does not accept as many arguments as there are lists.
+
+The arguments to for-each are like the arguments to map, but for-each calls
+
+proc for its side effects rather than for its values. Unlike map, for-each is guaranteed to
+call
+
+proc on the elements of the
+
+lists in order from the first element(s) to the last, and the value returned by for-each is
+unspecified. If more than one
+
+list is given and not all lists have the same length, for-each terminates when the shortest
+list runs out. The
+
+lists can be circular, but it is an error if all of them are circular.
+
+It is an error for
+
+proc to mutate any of the lists.
+
+(let ((v (make-vector 5)))
+ (for-each (lambda (i)
+ (vector-set! v i (* i i)))
+ '(0 1 2 3 4))
+ v) ⟹ #(0 1 4 9 16)
+
+procedure: (string-for-each proc
+
+string1
+
+string2 …)
+
+
+It is an error if
+
+proc does not accept as many arguments as there are strings.
+
+The arguments to string-for-each are like the arguments to string-map, but
+string-for-each calls
+
+proc for its side effects rather than for its values. Unlike string-map, string-for-each is
+guaranteed to call
+
+proc on the elements of the
+
+strings in order from the first element(s) to the last, and the value returned by
+string-for-each is unspecified. If more than one
+
+string is given and not all strings have the same length, string-for-each terminates when
+the shortest string runs out. It is an error for
+
+proc to mutate any of the strings.
+
+(let ((v '()))
+ (string-for-each
+ (lambda (c) (set! v (cons (char->integer c) v)))
+ "abcde")
+ v) ⟹ (101 100 99 98 97)
+
+procedure: (vector-for-each proc
+
+vector1
+
+vector2 …)
+
+
+It is an error if
+
+proc does not accept as many arguments as there are vectors.
+
+The arguments to vector-for-each are like the arguments to vector-map, but
+vector-for-each calls
+
+proc for its side effects rather than for its values. Unlike vector-map, vector-for-each is
+guaranteed to call
+
+proc on the elements of the
+
+vectors in order from the first element(s) to the last, and the value returned by
+vector-for-each is unspecified. If more than one
+
+vector is given and not all vectors have the same length, vector-for-each terminates when
+the shortest vector runs out. It is an error for
+
+proc to mutate any of the vectors.
+
+(let ((v (make-list 5)))
+ (vector-for-each
+ (lambda (i) (list-set! v i (* i i)))
+ '#(0 1 2 3 4))
+ v) ⟹ (0 1 4 9 16)
+
+procedure: (call-with-current-continuation proc)
+procedure: (call/cc proc)
+
+It is an error if
+
+proc does not accept one argument.
+
+The procedure call-with-current-continuation (or its equivalent abbreviation call/cc)
+packages the current continuation (see the rationale below) as an “escape
+procedure”and passes it as an argument to
+
+proc. The escape procedure is a Scheme procedure that, if it is later called, will abandon
+whatever continuation is in effect at that later time and will instead use the continuation
+that was in effect when the escape procedure was created. Calling the escape procedure
+will cause the invocation of
+
+before and
+
+after thunks installed using dynamic-wind.
+
+The escape procedure accepts the same number of arguments as the continuation to
+the original call to call-with-current-continuation. Most continuations take only one
+value. Continuations created by the call-with-values procedure (including the initialization
+expressions of define-values, let-values, and let*-values expressions), take the number
+of values that the consumer expects. The continuations of all non-final expressions
+within a sequence of expressions, such as in lambda, case-lambda, begin, let, let*, letrec,
+letrec*, let-values, let*-values, let-syntax, letrec-syntax, parameterize, guard, case, cond,
+when, and unless expressions, take an arbitrary number of values because they discard
+the values passed to them in any event. The effect of passing no values or more than one
+value to continuations that were not created in one of these ways is unspecified.
+
+The escape procedure that is passed to
+
+proc has unlimited extent just like any other procedure in Scheme. It can be stored in
+variables or data structures and can be called as many times as desired. However, like
+the raise and error procedures, it never returns to its caller.
+
+The following examples show only the simplest ways in which
+call-with-current-continuation is used. If all real uses were as simple as these examples,
+there would be no need for a procedure with the power of
+call-with-current-continuation.
+
+(call-with-current-continuation
+ (lambda (exit)
+ (for-each (lambda (x)
+ (if (negative? x)
+ (exit x)))
+ '(54 0 37 -3 245 19))
+ #t)) ⟹ -3
+
+(define list-length
+ (lambda (obj)
+ (call-with-current-continuation
+ (lambda (return)
+ (letrec ((r
+ (lambda (obj)
+ (cond ((null? obj) 0)
+ ((pair? obj)
+ (+ (r (cdr obj)) 1))
+ (else (return #f))))))
+ (r obj))))))
+
+(list-length '(1 2 3 4)) ⟹ 4
+
+(list-length '(a b . c)) ⟹ #f
+
+ Rationale: A common use of call-with-current-continuation is for structured,
+ non-local exits from loops or procedure bodies, but in fact
+ call-with-current-continuation is useful for implementing a wide variety of advanced
+ control structures. In fact, raise and guard provide a more structured mechanism
+ for non-local exits.
+
+ Whenever a Scheme expression is evaluated there is a continuation wanting the
+ result of the expression. The continuation represents an entire (default) future for
+ the computation. If the expression is evaluated at the REPL, for example, then the
+ continuation might take the result, print it on the screen, prompt for the next input,
+ evaluate it, and so on forever. Most of the time the continuation includes actions
+ specified by user code, as in a continuation that will take the result, multiply it by the
+ value stored in a local variable, add seven, and give the answer to the REPL’s
+ continuation to be printed. Normally these ubiquitous continuations are hidden
+ behind the scenes and programmers do not think much about them. On rare
+ occasions, however, a programmer needs to deal with continuations explicitly. The
+ call-with-current-continuation procedure allows Scheme programmers to do that
+ by creating a procedure that acts just like the current continuation.
+
+procedure: (values obj …)
+
+Delivers all of its arguments to its continuation. The values procedure might be defined
+as follows:
+
+(define (values . things)
+ (call-with-current-continuation
+ (lambda (cont) (apply cont things))))
+
+procedure: (call-with-values producer consumer)
+
+Calls its
+
+producer argument with no arguments and a continuation that, when passed some
+values, calls the
+
+consumer procedure with those values as arguments. The continuation for the call to
+
+consumer is the continuation of the call to call-with-values.
+
+(call-with-values (lambda () (values 4 5))
+ (lambda (a b) b))
+ ⟹ 5
+
+(call-with-values * -) ⟹ -1
+
+procedure: (dynamic-wind before thunk after)
+
+Calls
+
+thunk without arguments, returning the result(s) of this call.
+
+Before and
+
+after are called, also without arguments, as required by the following rules. Note that, in
+the absence of calls to continuations captured using call-with-current-continuation, the
+three arguments are called once each, in order.
+
+Before is called whenever execution enters the dynamic extent of the call to
+
+thunk and
+
+after is called whenever it exits that dynamic extent. The dynamic extent of a procedure
+call is the period between when the call is initiated and when it returns. The
+
+before and
+
+after thunks are called in the same dynamic environment as the call to dynamic-wind. In
+Scheme, because of call-with-current-continuation, the dynamic extent of a call is not
+always a single, connected time period. It is defined as follows:
+
+* The dynamic extent is entered when execution of the body of the called procedure
+ begins.
+
+* The dynamic extent is also entered when execution is not within the dynamic extent
+ and a continuation is invoked that was captured (using call-with-current-continuation)
+ during the dynamic extent.
+
+* It is exited when the called procedure returns.
+
+* It is also exited when execution is within the dynamic extent and a continuation is
+ invoked that was captured while not within the dynamic extent.
+
+If a second call to dynamic-wind occurs within the dynamic extent of the call to
+
+thunk and then a continuation is invoked in such a way that the
+
+afters from these two invocations of dynamic-wind are both to be called, then the
+
+after associated with the second (inner) call to dynamic-wind is called first.
+
+If a second call to dynamic-wind occurs within the dynamic extent of the call to
+
+thunk and then a continuation is invoked in such a way that the
+
+befores from these two invocations of dynamic-wind are both to be called, then the
+
+before associated with the first (outer) call to dynamic-wind is called first.
+
+If invoking a continuation requires calling the
+
+before from one call to dynamic-wind and the
+
+after from another, then the
+
+after is called first.
+
+The effect of using a captured continuation to enter or exit the dynamic extent of a call
+to
+
+before or
+
+after is unspecified.
+
+(let ((path '())
+ (c #f))
+ (let ((add (lambda (s)
+ (set! path (cons s path)))))
+ (dynamic-wind
+ (lambda () (add 'connect))
+ (lambda ()
+ (add (call-with-current-continuation
+ (lambda (c0)
+ (set! c c0)
+ 'talk1))))
+ (lambda () (add 'disconnect)))
+ (if (< (length path) 4)
+ (c 'talk2)
+ (reverse path))))
+
+⟹ (connect talk1 disconnect
+ connect talk2 disconnect)
+
+@node Exceptions
+@section Exceptions
+
+This section describes Scheme’s exception-handling and exception-raising procedures.
+For the concept of Scheme exceptions, see section 1.3.2. See also 4.2.7 for the guard
+syntax.
+
+Exception handlers are one-argument procedures that determine the action the program
+takes when an exceptional situation is signaled. The system implicitly maintains a
+current exception handler in the dynamic environment.
+
+The program raises an exception by invoking the current exception handler, passing it an
+object encapsulating information about the exception. Any procedure accepting one
+argument can serve as an exception handler and any object can be used to represent an
+exception.
+
+procedure: (with-exception-handler
+
+handler
+
+thunk)
+
+
+It is an error if
+
+handler does not accept one argument. It is also an error if
+
+thunk does not accept zero arguments.
+
+The with-exception-handler procedure returns the results of invoking
+
+thunk.
+
+Handler is installed as the current exception handler in the dynamic environment used
+for the invocation of
+
+thunk.
+
+(call-with-current-continuation
+ (lambda (k)
+ (with-exception-handler
+ (lambda (x)
+ (display "condition: ")
+ (write x)
+ (newline)
+ (k 'exception))
+ (lambda ()
+ (+ 1 (raise 'an-error))))))
+ ⟹ exception
+ and prints condition: an-error
+
+(with-exception-handler
+ (lambda (x)
+ (display "something went wrong\n"))
+ (lambda ()
+ (+ 1 (raise 'an-error))))
+ prints something went wrong After printing, the second example then raises another
+exception.
+
+procedure: (raise
+
+obj)
+
+
+Raises an exception by invoking the current exception handler on
+
+obj. The handler is called with the same dynamic environment as that of the call to raise,
+except that the current exception handler is the one that was in place when the handler
+being called was installed. If the handler returns, a secondary exception is raised in the
+same dynamic environment as the handler. The relationship between
+
+obj and the object raised by the secondary exception is unspecified.
+
+procedure: (raise-continuable
+
+obj)
+
+
+Raises an exception by invoking the current exception handler on
+
+obj. The handler is called with the same dynamic environment as the call to
+raise-continuable, except that: (1) the current exception handler is the one that was in
+place when the handler being called was installed, and (2) if the handler being called
+returns, then it will again become the current exception handler. If the handler returns,
+the values it returns become the values returned by the call to raise-continuable.
+
+(with-exception-handler
+ (lambda (con)
+ (cond
+ ((string? con)
+ (display con))
+ (else
+ (display "a warning has been issued")))
+ 42)
+ (lambda ()
+ (+ (raise-continuable "should be a number")
+ 23)))
+ prints: should be a number
+ ⟹ 65
+
+procedure: (error
+
+message
+
+obj …)
+
+
+Message should be a string.
+
+Raises an exception as if by calling raise on a newly allocated implementation-defined
+object which encapsulates the information provided by
+
+message, as well as any
+
+objs, known as the irritants. The procedure error-object? must return #t on such objects.
+
+(define (null-list? l)
+ (cond ((pair? l) #f)
+ ((null? l) #t)
+ (else
+ (error
+ "null-list?: argument out of domain"
+ l))))
+
+procedure: (error-object? obj)
+
+Returns #t if
+
+obj is an object created by error or one of an implementation-defined set of objects.
+Otherwise, it returns #f. The objects used to signal errors, including those which satisfy
+the predicates file-error? and read-error?, may or may not satisfy error-object?.
+
+procedure: (error-object-message error-object)
+
+Returns the message encapsulated by
+
+error-object.
+
+procedure: (error-object-irritants error-object)
+
+Returns a list of the irritants encapsulated by
+
+error-object.
+
+procedure: (read-error? obj)
+procedure: (file-error? obj)
+
+Error type predicates. Returns #t if
+
+obj is an object raised by the read procedure or by the inability to open an input or
+output port on a file, respectively. Otherwise, it returns #f.
+
+@node Environments and evaluation
+@section Environments and evaluation
+
+eval library procedure: (environment
+
+list1 …)
+
+
+This procedure returns a specifier for the environment that results by starting with an
+empty environment and then importing each
+
+list, considered as an import set, into it. (See section 5.6 for a description of import sets.)
+The bindings of the environment represented by the specifier are immutable, as is the
+environment itself.
+
+r5rs library procedure: (scheme-report-environment version)
+
+If
+
+version is equal to 5, corresponding to R5RS, scheme-report-environment returns a
+specifier for an environment that contains only the bindings defined in the R5RS library.
+Implementations must support this value of
+
+version.
+
+Implementations may also support other values of
+
+version, in which case they return a specifier for an environment containing bindings
+corresponding to the specified version of the report. If
+
+version is neither 5 nor another value supported by the implementation, an error is
+signaled.
+
+The effect of defining or assigning (through the use of eval) an identifier bound in a
+scheme-report-environment (for example car) is unspecified. Thus both the
+environment and the bindings it contains may be immutable.
+
+r5rs library procedure: (null-environment version)
+
+If
+
+version is equal to 5, corresponding to R5RS, the null-environment procedure returns a
+specifier for an environment that contains only the bindings for all syntactic keywords
+defined in the R5RS library. Implementations must support this value of
+
+version.
+
+Implementations may also support other values of
+
+version, in which case they return a specifier for an environment containing appropriate
+bindings corresponding to the specified version of the report. If
+
+version is neither 5 nor another value supported by the implementation, an error is
+signaled.
+
+The effect of defining or assigning (through the use of eval) an identifier bound in a
+scheme-report-environment (for example car) is unspecified. Thus both the
+environment and the bindings it contains may be immutable.
+
+repl library procedure: (interaction-environment)
+
+This procedure returns a specifier for a mutable environment that contains an
+implementation-defined set of bindings, typically a superset of those exported by
+(scheme base). The intent is that this procedure will return the environment in which the
+implementation would evaluate expressions entered by the user into a REPL.
+
+eval library procedure: (eval expr-or-def environment-specifier)
+
+If
+
+expr-or-def is an expression, it is evaluated in the specified environment and its values are
+returned. If it is a definition, the specified identifier(s) are defined in the specified
+environment, provided the environment is not immutable. Implementations may extend
+eval to allow other objects.
+
+(eval '(* 7 3) (environment '(scheme base)))
+ ⟹ 21
+
+(let ((f (eval '(lambda (f x) (f x x))
+ (null-environment 5))))
+ (f + 10))
+ ⟹ 20
+(eval '(define foo 32)
+ (environment '(scheme base)))
+ ⟹ error is signaled
+
+@node Input and output
+@section Input and output
+
+@node Ports
+@subsection Ports
+
+Ports represent input and output devices. To Scheme, an input port is a Scheme object
+that can deliver data upon command, while an output port is a Scheme object that can
+accept data.Whether the input and output port types are disjoint is
+implementation-dependent.
+
+Different port types operate on different data. Scheme implementations are required to
+support textual ports and binary ports, but may also provide other port types.
+
+A textual port supports reading or writing of individual characters from or to a backing
+store containing characters using read-char and write-char below, and it supports
+operations defined in terms of characters, such as read and write.
+
+A binary port supports reading or writing of individual bytes from or to a backing store
+containing bytes using read-u8 and write-u8 below, as well as operations defined in
+terms of bytes. Whether the textual and binary port types are disjoint is
+implementation-dependent.
+
+Ports can be used to access files, devices, and similar things on the host system on which
+the Scheme program is running.
+
+procedure: (call-with-port port proc)
+
+It is an error if
+
+proc does not accept one argument.
+
+The call-with-port procedure calls
+
+proc with
+
+port as an argument. If
+
+proc returns, then the port is closed automatically and the values yielded by the
+
+proc are returned. If
+
+proc does not return, then the port must not be closed automatically unless it is possible
+to prove that the port will never again be used for a read or write operation.
+
+ Rationale: Because Scheme’s escape procedures have unlimited extent, it is possible
+ to escape from the current continuation but later to resume it. If implementations
+ were permitted to close the port on any escape from the current continuation, then
+ it would be impossible to write portable code using both
+ call-with-current-continuation and call-with-port.
+
+file library procedure: (call-with-input-file string proc)
+file library procedure: (call-with-output-file string proc)
+
+It is an error if
+
+proc does not accept one argument.
+
+These procedures obtain a textual port obtained by opening the named file for input or
+output as if by open-input-file or open-output-file. The port and
+
+proc are then passed to a procedure equivalent to call-with-port.
+
+procedure: (input-port? obj)
+procedure: (output-port? obj)
+procedure: (textual-port? obj)
+procedure: (binary-port? obj)
+procedure: (port? obj)
+
+These procedures return #t if
+
+obj is an input port, output port, textual port, binary port, or any kind of port,
+respectively. Otherwise they return #f.
+
+procedure: (input-port-open? port)
+procedure: (output-port-open? port)
+
+Returns #t if
+
+port is still open and capable of performing input or output, respectively, and #f
+otherwise.
+
+procedure: (current-input-port)
+procedure: (current-output-port)
+procedure: (current-error-port)
+
+Returns the current default input port, output port, or error port (an output port),
+respectively. These procedures are parameter objects, which can be overridden with
+parameterize (see section 4.2.6). The initial bindings for these are
+implementation-defined textual ports.
+
+file library procedure: (with-input-from-file string thunk)
+file library procedure: (with-output-to-file string thunk)
+
+The file is opened for input or output as if by open-input-file or open-output-file, and the
+new port is made to be the value returned by current-input-port or current-output-port
+(as used by (read), (write
+
+obj), and so forth). The
+
+thunk is then called with no arguments. When the
+
+thunk returns, the port is closed and the previous default is restored. It is an error if
+
+thunk does not accept zero arguments. Both procedures return the values yielded by
+
+thunk. If an escape procedure is used to escape from the continuation of these
+procedures, they behave exactly as if the current input or output port had been bound
+dynamically with parameterize.
+
+file library procedure: (open-input-file string)
+file library procedure: (open-binary-input-file string)
+
+Takes a
+
+string for an existing file and returns a textual input port or binary input port that is
+capable of delivering data from the file. If the file does not exist or cannot be opened, an
+error that satisfies file-error? is signaled.
+
+file library procedure: (open-output-file string)
+file library procedure: (open-binary-output-file string)
+
+Takes a
+
+string naming an output file to be created and returns a textual output port or binary
+output port that is capable of writing data to a new file by that name. If a file with the
+given name already exists, the effect is unspecified. If the file cannot be opened, an error
+that satisfies file-error? is signaled.
+
+procedure: (close-port port)
+procedure: (close-input-port port)
+procedure: (close-output-port port)
+
+Closes the resource associated with
+
+port, rendering the
+
+port incapable of delivering or accepting data. It is an error to apply the last two
+procedures to a port which is not an input or output port, respectively. Scheme
+implementations may provide ports which are simultaneously input and output ports,
+such as sockets; the close-input-port and close-output-port procedures can then be used
+to close the input and output sides of the port independently.
+
+These routines have no effect if the port has already been closed.
+
+procedure: (open-input-string string)
+
+Takes a string and returns a textual input port that delivers characters from the string. If
+the string is modified, the effect is unspecified.
+
+procedure: (open-output-string)
+
+Returns a textual output port that will accumulate characters for retrieval by
+get-output-string.
+
+procedure: (get-output-string port)
+
+It is an error if
+
+port was not created with open-output-string.
+
+Returns a string consisting of the characters that have been output to the port so far in
+the order they were output. If the result string is modified, the effect is unspecified.
+
+(parameterize
+ ((current-output-port
+ (open-output-string)))
+ (display "piece")
+ (display " by piece ")
+ (display "by piece.")
+ (newline)
+ (get-output-string (current-output-port)))
+
+⟹ "piece by piece by piece.\n"
+
+procedure: (open-input-bytevector bytevector)
+
+Takes a bytevector and returns a binary input port that delivers bytes from the
+bytevector.
+
+procedure: (open-output-bytevector)
+
+Returns a binary output port that will accumulate bytes for retrieval by
+get-output-bytevector.
+
+procedure: (get-output-bytevector port)
+
+It is an error if
+
+port was not created with open-output-bytevector.
+
+Returns a bytevector consisting of the bytes that have been output to the port so far in
+the order they were output.
+
+@node Input
+@subsection Input
+
+If
+
+port is omitted from any input procedure, it defaults to the value returned by
+(current-input-port). It is an error to attempt an input operation on a closed port.
+
+read library procedure: (read)
+read library procedure: (read port)
+
+The read procedure converts external representations of Scheme objects into the
+objects themselves. That is, it is a parser for the non-terminal <datum> (see sections
+7.1.2 and 6.4). It returns the next object parsable from the given textual input
+
+port, updating
+
+port to point to the first character past the end of the external representation of the
+object.
+
+Implementations may support extended syntax to represent record types or other types
+that do not have datum representations.
+
+If an end of file is encountered in the input before any characters are found that can
+begin an object, then an end-of-file object is returned. The port remains open, and
+further attempts to read will also return an end-of-file object. If an end of file is
+encountered after the beginning of an object’s external representation, but the external
+representation is incomplete and therefore not parsable, an error that satisfies
+read-error? is signaled.
+
+procedure: (read-char)
+procedure: (read-char port)
+
+Returns the next character available from the textual input
+
+port, updating the
+
+port to point to the following character. If no more characters are available, an end-of-file
+object is returned.
+
+procedure: (peek-char)
+procedure: (peek-char port)
+
+Returns the next character available from the textual input
+
+port, but without updating the
+
+port to point to the following character. If no more characters are available, an end-of-file
+object is returned.
+
+ Note: The value returned by a call to peek-char is the same as the value that would
+ have been returned by a call to read-char with the same
+
+ port. The only difference is that the very next call to read-char or peek-char on that
+
+ port will return the value returned by the preceding call to peek-char. In particular, a
+ call to peek-char on an interactive port will hang waiting for input whenever a call to
+ read-char would have hung.
+
+procedure: (read-line)
+procedure: (read-line port)
+
+Returns the next line of text available from the textual input
+
+port, updating the
+
+port to point to the following character. If an end of line is read, a string containing all of
+the text up to (but not including) the end of line is returned, and the port is updated to
+point just past the end of line. If an end of file is encountered before any end of line is
+read, but some characters have been read, a string containing those characters is
+returned. If an end of file is encountered before any characters are read, an end-of-file
+object is returned. For the purpose of this procedure, an end of line consists of either a
+linefeed character, a carriage return character, or a sequence of a carriage return
+character followed by a linefeed character. Implementations may also recognize other
+end of line characters or sequences.
+
+procedure: (eof-object? obj)
+
+Returns #t if
+
+obj is an end-of-file object, otherwise returns #f. The precise set of end-of-file objects
+will vary among implementations, but in any case no end-of-file object will ever be an
+object that can be read in using read.
+
+procedure: (eof-object)
+
+Returns an end-of-file object, not necessarily unique.
+
+procedure: (char-ready?)
+procedure: (char-ready? port)
+
+Returns #t if a character is ready on the textual input
+
+port and returns #f otherwise. If char-ready returns #t then the next read-char operation
+on the given
+
+port is guaranteed not to hang. If the
+
+port is at end of file then char-ready? returns #t.
+
+ Rationale: The char-ready? procedure exists to make it possible for a program to
+ accept characters from interactive ports without getting stuck waiting for input.
+ Any input editors associated with such ports must ensure that characters whose
+ existence has been asserted by char-ready? cannot be removed from the input. If
+ char-ready? were to return #f at end of file, a port at end of file would be
+ indistinguishable from an interactive port that has no ready characters.
+
+procedure: (read-string k)
+procedure: (read-string k port)
+
+Reads the next
+
+k characters, or as many as are available before the end of file, from the textual input
+
+port into a newly allocated string in left-to-right order and returns the string. If no
+characters are available before the end of file, an end-of-file object is returned.
+
+procedure: (read-u8)
+procedure: (read-u8 port)
+
+Returns the next byte available from the binary input
+
+port, updating the
+
+port to point to the following byte. If no more bytes are available, an end-of-file object is
+returned.
+
+procedure: (peek-u8)
+procedure: (peek-u8 port)
+
+Returns the next byte available from the binary input
+
+port, but without updating the
+
+port to point to the following byte. If no more bytes are available, an end-of-file object is
+returned.
+
+procedure: (u8-ready?)
+procedure: (u8-ready? port)
+
+Returns #t if a byte is ready on the binary input
+
+port and returns #f otherwise. If u8-ready? returns #t then the next read-u8 operation on
+the given
+
+port is guaranteed not to hang. If the
+
+port is at end of file then u8-ready? returns #t.
+
+procedure: (read-bytevector k)
+procedure: (read-bytevector k port)
+
+Reads the next
+
+k bytes, or as many as are available before the end of file, from the binary input
+
+port into a newly allocated bytevector in left-to-right order and returns the bytevector. If
+no bytes are available before the end of file, an end-of-file object is returned.
+
+procedure: (read-bytevector! bytevector)
+procedure: (read-bytevector! bytevector port)
+procedure: (read-bytevector! bytevector port start)
+procedure: (read-bytevector! bytevector port start end)
+
+Reads the next end − start bytes, or as many as are available before the end of file, from
+the binary input
+
+port into
+
+bytevector in left-to-right order beginning at the
+
+start position. If
+
+end is not supplied, reads until the end of
+
+bytevector has been reached. If
+
+start is not supplied, reads beginning at position 0. Returns the number of bytes read. If
+no bytes are available, an end-of-file object is returned.
+
+@node Output
+@subsection Output
+
+If
+
+port is omitted from any output procedure, it defaults to the value returned by
+(current-output-port). It is an error to attempt an output operation on a closed port.
+
+write library procedure: (write obj)
+write library procedure: (write obj port)
+
+Writes a representation of
+
+obj to the given textual output
+
+port. Strings that appear in the written representation are enclosed in quotation marks,
+and within those strings backslash and quotation mark characters are escaped by
+backslashes. Symbols that contain non-ASCII characters are escaped with vertical lines.
+Character objects are written using the #\ notation.
+
+If
+
+obj contains cycles which would cause an infinite loop using the normal written
+representation, then at least the objects that form part of the cycle must be represented
+using datum labels as described in section 2.4. Datum labels must not be used if there
+are no cycles.
+
+Implementations may support extended syntax to represent record types or other types
+that do not have datum representations.
+
+The write procedure returns an unspecified value.
+
+write library procedure: (write-shared obj)
+write library procedure: (write-shared obj port)
+
+The write-shared procedure is the same as write, except that shared structure must be
+represented using datum labels for all pairs and vectors that appear more than once in
+the output.
+
+write library procedure: (write-simple obj)
+write library procedure: (write-simple obj port)
+
+The write-simple procedure is the same as write, except that shared structure is never
+represented using datum labels. This can cause write-simple not to terminate if
+
+obj contains circular structure.
+
+write library procedure: (display obj)
+write library procedure: (display obj port)
+
+Writes a representation of
+
+obj to the given textual output
+
+port. Strings that appear in the written representation are output as if by write-string
+instead of by write. Symbols are not escaped. Character objects appear in the
+representation as if written by write-char instead of by write.
+
+The display representation of other objects is unspecified. However, display must not
+loop forever on self-referencing pairs, vectors, or records. Thus if the normal write
+representation is used, datum labels are needed to represent cycles as in write.
+
+Implementations may support extended syntax to represent record types or other types
+that do not have datum representations.
+
+The display procedure returns an unspecified value.
+
+ Rationale: The write procedure is intended for producing machine-readable output
+ and display for producing human-readable output.
+
+procedure: (newline)
+procedure: (newline port)
+
+Writes an end of line to textual output
+
+port. Exactly how this is done differs from one operating system to another. Returns an
+unspecified value.
+
+procedure: (write-char char)
+procedure: (write-char char port)
+
+Writes the character
+
+char (not an external representation of the character) to the given textual output
+
+port and returns an unspecified value.
+
+procedure: (write-string string)
+procedure: (write-string string port)
+procedure: (write-string string port start)
+procedure: (write-string string port start end)
+
+Writes the characters of
+
+string from
+
+start to
+
+end in left-to-right order to the textual output
+
+port.
+
+procedure: (write-u8 byte)
+procedure: (write-u8 byte port)
+
+Writes the
+
+byte to the given binary output
+
+port and returns an unspecified value.
+
+procedure: (write-bytevector bytevector)
+procedure: (write-bytevector bytevector port)
+procedure: (write-bytevector bytevector port start)
+procedure: (write-bytevector bytevector port start end)
+
+Writes the bytes of
+
+bytevector from
+
+start to
+
+end in left-to-right order to the binary output
+
+port.
+
+procedure: (flush-output-port)
+procedure: (flush-output-port port)
+
+Flushes any buffered output from the buffer of output-port to the underlying file or
+device and returns an unspecified value.
+
+@node System interface
+@section System interface
+
+Questions of system interface generally fall outside of the domain of this report.
+However, the following operations are important enough to deserve description here.
+
+load library procedure: (load filename)
+load library procedure: (load filename environment-specifier)
+
+It is an error if
+
+filename is not a string.
+
+An implementation-dependent operation is used to transform
+
+filename into the name of an existing file containing Scheme source code. The load
+procedure reads expressions and definitions from the file and evaluates them
+sequentially in the environment specified by
+
+environment-specifier. If
+
+environment-specifier is omitted, (interaction-environment) is assumed.
+
+It is unspecified whether the results of the expressions are printed. The load procedure
+does not affect the values returned by current-input-port and current-output-port. It
+returns an unspecified value.
+
+ Rationale: For portability, load must operate on source files. Its operation on other
+ kinds of files necessarily varies among implementations.
+
+file library procedure: (file-exists? filename)
+
+It is an error if
+
+filename is not a string.
+
+The file-exists? procedure returns #t if the named file exists at the time the procedure is
+called, and #f otherwise.
+
+file library procedure: (delete-file filename)
+
+It is an error if
+
+filename is not a string.
+
+The delete-file procedure deletes the named file if it exists and can be deleted, and
+returns an unspecified value. If the file does not exist or cannot be deleted, an error that
+satisfies file-error? is signaled.
+
+process-context library procedure: (command-line)
+
+Returns the command line passed to the process as a list of strings. The first string
+corresponds to the command name, and is implementation-dependent. It is an error to
+mutate any of these strings.
+
+process-context library procedure: (exit)
+process-context library procedure: (exit obj)
+
+Runs all outstanding dynamic-wind
+
+after procedures, terminates the running program, and communicates an exit value to
+the operating system. If no argument is supplied, or if
+
+obj is #t, the exit procedure should communicate to the operating system that the
+program exited normally. If
+
+obj is #f, the exit procedure should communicate to the operating system that the
+program exited abnormally. Otherwise, exit should translate
+
+obj into an appropriate exit value for the operating system, if possible.
+
+The exit procedure must not signal an exception or return to its continuation.
+
+ Note: Because of the requirement to run handlers, this procedure is not just the
+ operating system’s exit procedure.
+
+process-context library procedure: (emergency-exit)
+process-context library procedure: (emergency-exit obj)
+
+Terminates the program without running any outstanding dynamic-wind
+
+after procedures and communicates an exit value to the operating system in the same
+manner as exit.
+
+ Note: The emergency-exit procedure corresponds to the _exit procedure in Windows
+ and Posix.
+
+process-context library procedure: (get-environment-variable name)
+
+Many operating systems provide each running process with an environment consisting of
+environment variables. (This environment is not to be confused with the Scheme
+environments that can be passed to eval: see section 6.12.) Both the name and value of
+an environment variable are strings. The procedure get-environment-variable returns
+the value of the environment variable
+
+name, or #f if the named environment variable is not found. It may use locale information
+to encode the name and decode the value of the environment variable. It is an error if
+get-environment-variable can’t decode the value. It is also an error to mutate the
+resulting string.
+
+(get-environment-variable "PATH")
+⟹ "/usr/local/bin:/usr/bin:/bin"
+
+process-context library procedure: (get-environment-variables)
+
+Returns the names and values of all the environment variables as an alist, where the car
+of each entry is the name of an environment variable and the cdr is its value, both as
+strings. The order of the list is unspecified. It is an error to mutate any of these strings
+or the alist itself.
+
+(get-environment-variables)
+⟹ (("USER" . "root") ("HOME" . "/"))
+
+time library procedure: (current-second)
+
+Returns an inexact number representing the current time on the International Atomic
+Time (TAI) scale. The value 0.0 represents midnight on January 1, 1970 TAI (equivalent to
+8.000082 seconds before midnight Universal Time) and the value 1.0 represents one TAI
+second later. Neither high accuracy nor high precision are required; in particular,
+returning Coordinated Universal Time plus a suitable constant might be the best an
+implementation can do.
+
+As of 2018, a TAI-UTC offset table can be found at [40].
+
+time library procedure: (current-jiffy)
+
+Returns the number of jiffies as an exact integer that have elapsed since an arbitrary,
+implementation-defined epoch. A jiffy is an implementation-defined fraction of a second
+which is defined by the return value of the jiffies-per-second procedure. The starting
+epoch is guaranteed to be constant during a run of the program, but may vary between
+runs.
+
+ Rationale: Jiffies are allowed to be implementation-dependent so that current-jiffy
+ can execute with minimum overhead. It should be very likely that a compactly
+ represented integer will suffice as the returned value. Any particular jiffy size will be
+ inappropriate for some implementations: a microsecond is too long for a very fast
+ machine, while a much smaller unit would force many implementations to return
+ integers which have to be allocated for most calls, rendering current-jiffy less
+ useful for accurate timing measurements.
+
+time library procedure: (jiffies-per-second)
+
+Returns an exact integer representing the number of jiffies per SI second. This value is
+an implementation-specified constant.
+
+(define (time-length)
+ (let ((list (make-list 100000))
+ (start (current-jiffy)))
+ (length list)
+ (/ (- (current-jiffy) start)
+ (jiffies-per-second))))
+
+procedure: (features)
+
+Returns a list of the feature identifiers which cond-expand treats as true. It is an error to
+modify this list. Here is an example of what features might return:
+
+(features) ⟹
+ (r7rs ratios exact-complex full-unicode
+ gnu-linux little-endian
+ fantastic-scheme
+ fantastic-scheme-1.0
+ space-ship-control-system)
@node Formal syntax and semantics
@chapter Formal syntax and semantics