Revised7 Report on the Algorithmic Language Scheme
The Valued Fascicle

draft

Editor's introduction to this fascicle

This section will not appear in the final report.

The Revised7 Report on the Algorithmic Language Scheme, Large Edition, is released in fascicles, which are incremental releases of the full standard.

This is the Valued Fascicle (fascicle 3 of 8) containing the description of the values that make up Scheme data, such as pairs, vectors, numbers, and strings.

Changes to the R7RS

The major features of this fascicle:

What Implementations Need To Do To Support These Changes

Raw string literals will require changes to the reader. Some standard library procedures need redefinition.

Editorial conventions

The phrase it is an error as traditionally used in Scheme reports has been retired in this fascicle. In its place we have adopted a three-way distinction between requirements on implementations, which should be familiar from the specifications of other languages including Common Lisp and C.

As in the R7RS-Small, the phrase an error is signalled continues to refer to a situation in which an exception is required to be raised.

The R7RS-Large Foundations will incorporate a revised version of the R6RS condition types which is compatible with the error objects defined by the small language report, but this is not yet specified and will be included in a future fascicle. However, the phrase it is a syntax violation or a syntax violation is signalled means that an exception is raised with condition type &syntax as in the R6RS.

The phrase domain error (or it is a domain error) refers to using a procedure with an argument value which is outside the specified range of possible values for that argument. It is not yet specified what concrete action implementations should take in this case in the R7RS-Large Foundations. Preliminarily, implementations are encouraged to signal an error with condition type &assertion as in the R6RS, but this is not a requirement. The circumstances, if any, in which a domain error is required to signal an error will likewise be established in a future fascicle.

This fascicle contains entries. Each entry describes one language feature or a group of related features, where a feature is either a syntactic construct or a procedure. An entry begins with one or more header lines, each with a category.

If the category is syntax, the entry describes an expression type, and the template gives the syntax of the expression type.

If the category is auxiliary syntax, then the entry describes a syntax binding that occurs only as part of specific surrounding expressions. Any use as an independent syntactic construct or variable is an &syntax error.

Components of expressions are designated by syntactic variables. Syntactic variables are intended to denote segments of program text; for example, expression stands for any string of characters which is a syntactically valid expression. The notation thing1 indicates zero or more of thing.

If the category is procedure, then the entry describes a procedure, and the header line gives a template for a call to the procedure. Square brackets [] are used to denote optional arguments. Ellipses are used to denote the repetition of zero or more of a group of arguments.

The following variable names are used in the specifications of procedures to imply the type of the argument named by that variable:

alist

an association list (a list of pairs)

boolean

boolean

byte

exact integer, 0byte255

bytevector

bytevector

char

character

k

exact, non-negative integer

letter

alphabetic character

list

list

n

integer

obj

any object

pair

pair

proc

procedure

q

rational number

string

string

symbol

symbol

thunk

thunk

vector

vector

x or y

real number

z

complex number

nvector

An nvector

nelem

A valid element to be passed to annvector

These conventions apply to the main component of the name of the argument. Some argument names contain subscripts to differentiate multiple arguments of the same type.

The names start and end are used as indexes into certain ordered objects (lists, vectors, bytevectors, and strings). Their use implies the following:

The name nelem has different meanings for exact number vectors, real number vectors, and complex number vectors.

It is a domain error if an argument to any procedure does not match the expected type, whether the expected type is implied by the use of a variable name listed in this table, or named explicitly in the specification text.

Here is an example of a syntax declaration with auxiliary syntax:

Here is an example of a procedure declaration with optional arguments:

Here is an example of a procedure declaration with repeated argmuents:

In the description of expression syntax, an extended Backus-Naur form is used to document the possible forms that a syntactic variable can take. Ellipses are used to denote zero or more occurences of a syntactic variable. Spaces are not significant.

Throughout the document, there are examples that contain both definitions and expressions. To the right hand side of some expressions are what that expression would evaluate to, given the previous expressions and definitions in that example being evaluated. The evaluation will usually result in a Scheme value, but could result in an error being raised, a value printed to standard output, or an unspecified value being returned. Here is an example of evaluation:

(car '(1 . 2))1
(values 1 2)1 2
(car '())domain error

By convention, ? is the final character of the names of procedures that always return a boolean value. Such procedures are called predicates. Predicates are generally understood to be side-effect free, except that they may raise an exception when passed the wrong type of argument.

Similarly, ! is the final character of the names of procedures that store values into previously allocated locations TODO: storage model. Such procedures are called mutation procedures. The value returned by a mutation procedure is unspecified.

By convention, -> appears within the names of procedures that take an object of one type and return an analogous object of another type. For example, list->vector takes a list and returns a vector whose elements are the same as those of the list.

A command is a procedure that does not return useful values to its continuation.

A thunk is a procedure that does not accept arguments.

The key words must, must not, required, shall, shall not, should, should not, recommended, may, and optional in this document, although not capitalized in this report, are to be interpreted as described in RFC 2119. TODO: Bradner97

Comments of the form ... are editorial notes marking places requiring revision in the final report.

1: Basic concepts

1.1: Disjointness of types

No object satisfies more than one of the following predicates:

and all predicates created by define-record-type.TODO: Link to records section, and maybe add other types

Although there is a separate boolean type, any Scheme value can be used as a boolean value for the purpose of a conditional test. As explained in section 5, all values count as true in such a test except for #f. This report uses the word true to refer to any Scheme value except #f, and the word false to refer to #f.

1.2: External representations

An important concept in Scheme (and Lisp) is that of the external representation of an object as a sequence of characters. For example, an external representation of the integer 28 is the sequence of characters 28, and an external representation of a list consisting of the integers 8 and 13 is the sequence of characters (8 13).

The external representation of an object is not necessarily unique. The integer 28 also has representations #e28.000 and #x1c, and the list in the previous paragraph also has the representations ( 08 13 ) and (8 . (13 . ())) (see section 6).

Many objects have standard external representations, but some, such as procedures, do not have standard representations (although particular implementations may define representations for them).

An external representation can be written in a program to obtain the corresponding object (see quote, section TODO).

TODO: read and write

Note that the sequence of characters (+ 2 6) is not an external representation of the integer 8, even though it is an expression evaluating to the integer 8; rather, it is an external representation of a three-element list, the elements of which are the symbol + and the integers 2 and 6. Scheme’s syntax has the property that any sequence of characters that is an expression is also the external representation of some object. This can lead to confusion, since it is not always obvious out of context whether a given sequence of characters is intended to denote data or program, but it is also a source of power, since it facilitates writing programs such as interpreters and compilers that treat programs as data (or vice versa).

The syntax of external representations of various kinds of objects accompanies the description of the primitives for manipulating the objects in the appropriate sections.

1.3: Storage model

Every object that denotes locations is either mutable or immutable. Literal constants, and other values explicitly designated as immutable are immutable objects. All objects created by the other procedures listed in this report are mutable. It is undefined behavior to attempt to store a new value into a location that is denoted by an immutable object. An attempt to store a new value into a location referred to by an immutable object should raise an exception.

Rationale: In many systems it is desirable for constants (i.e. the values of literal expressions) to reside in read-only memory. Making it undefined behavior to alter constants permits this implementation strategy, while not requiring other systems to distinguish between mutable and immutable objects.

Another purpose for immutable objects is to prevent mutation from spreading across abstraction boundaries.

2: Quotation

2.1: quote

Semantics

(quote datum) evaluates to datum. The datum can be any external representation of a Scheme object (see section 1.2). This notation is used to include literal constants in Scheme code.

(quote a)a
(quote #(a b c))#(a b c)
(quote (+ 1 2))(+ 1 2)

(quote datum can be abbreviated as 'datum. The two notations are equivalent in all respects.

'aa
'#(a b c)#(a b c)
'()()
'(+ 1 2)(+ 1 2)
'(quote a)(quote a)
''a(quote a)

Constants, such as numerical constants, string constants, character constants, and boolean constants evaluate to themselves; they need not be quoted.

'145932145932
145932145932
'"abc""abc"
"abc""abc"
'#\a#\a
#\a#\a
'#(a 10)#(a 10)
#(a 10)#(a 10)
'#u8(64 65)#u8(64 65)
#u8(64 65)#u8(64 65)
'#t#t
#t#t

As noted in section 1.3, it is undefined behavior to attempt to alter a constant (i.e. the value of a literal expression) using a mutation procedure like set-car! or string-set!.

2.2: Quasiquotation

  • (quasiquote qq template) syntax
  • `qq template lexical syntax
  • unquote auxiliary syntax
  • ,expression lexical syntax
  • unquote-splicing auxiliary syntax
  • ,@expression lexical syntax

Semantics

Quasiquote expressions are useful for constructing a list or vector structure when some but not all of the desired structure is known in advance. If no commas appear within the qq template, the result of evaluating `qq template is equivalent to the result of evaluating 'qq template. If a comma appears within the qq template, however, the expression following the comma is evaluated (unquoted) and its result is inserted into the structure instead of the comma and the expression. If a comma appears followed without intervening whitespace by a commercial at-sign (@), then it is a syntax error if the following expression does not evaluate to a list; the opening and closing parentheses of the list are then stripped away and the elements of the list are inserted in place of the comma at-sign expression sequence. A comma at-sign normally appears only within a list or vector qq template.

Note: In order to unquote an identifier beginning with @, it is necessary to use either an explicit unquote or to put whitespace after the comma, to avoid colliding with the comma at-sign sequence.

`(list ,(+ 1 2) 4)(list 3 4)
(let ((name 'a)) `(list ,name ',name))(list a (quote a))
`(a ,(+ 1 2) ,@(map abs '(4 -5 6)) b)(a 3 4 5 6 b)
`(( foo ,(- 10 3)) ,@(cdr '(c)) . ,(car '(cons)))((foo 7) . cons)
`#(10 5 ,(sqrt 4) ,@(map sqrt '(16 9)) 8)#(10 5 2 4 3 8)
(let ((foo '(foo bar)) (@baz 'baz))
  `(list ,@foo , @baz))(list foo bar baz)

Quasiquote expressions can be nested. Substitutions are made only for unquoted components appearing at the same nesting level as the outermost quasiquote. The nesting level increases by one inside each successive quasiquotation, and decreases by one inside each unquotation.

`(a `(b ,(+ 1 2) ,(foo ,(+ 1 3) d) e) f)(a `(b ,(+ 1 2) ,(foo 4 d) e) f)
(let ((name1 'x)
      (name2 'y))
  `(a `(b ,,name1 ,',name2 d) e))(a `(b ,x ,'y d) e)

A quasiquote expression may return either newly allocated, mutable objects or literal structure for any structure that is constructed at run time during the evaluation of the expression. Portions that do not need to be rebuilt are always literal. Thus,

(let ((a 3)) `((1 2) ,a ,4 ,'five 6))

may be treated as equivalent to either of the following expressions:

`((1 2) 3 4 five 6)
(let ((a 3))
  (cons '(1 2)
        (cons a (cons 4 (cons 'five '(6))))))

However, it is not equivalent to this expression:

(let ((a 3)) (list (list 1 2) a 4 'five 6))

The two notations `qq template and (quasiquote qq template) are identical in all respects. In addition, ,expression is identical to (unquote expression), and ,@expression is identical to (unquote-splicing expression). The write procedure may output either format.

TODO: examples

It is a syntax error if any of the identifiers quasiquote, unquote, or unquote-splicing appear in positions within a qq template otherwise than as described above.TODO: grammar

3: 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?.

3.1: eqv?

The eqv? procedure defines a useful equivalence relation on objects. Briefly, it returns #t if obj1 and obj2 should normally be regarded as the same object and #f otherwise. This relation is left slightly open to interpretation, but the following partial specification of eqv? must hold for all implementations.

The eqv? procedure returns #t

The eqv? procedure return #f:

(eqv? 'a 'a)#t
(eqv? 'a 'b)#f
(eqv? #\a #\a)#t
(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? 0.0 -0.0)#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

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 undefined behavior 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.

3.2: eq?

Description

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, number 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, empty number vectors, and empty bytevectors, eq? may also behave differently from eqv?.

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.

Examples

(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

3.3: equal?

Description

The equal? procedure, when applied to pairs, vectors, number 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.

Note: A rule of thumb is that objects are generally equal? if they print the same.

Compatability Note: The R6RS required that eqv? be used to compare record objects. The R7RS-Small require that if two objects were eqv?, they must be equal?, but allowed equal? to return #t for non-eqv? record objects. The R7RS-Large adopts the R7RS-Small behavior.TODO: issue #361, #360, #329

Examples

(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

4: Numbers

This chapter describes Scheme’s model for numbers. It is important to distinguish between the mathematical numbers, the Scheme objects that attempt to model them, the machine representations used to implement the numbers, and notations used to write numbers. In this report, the term number refers to a mathematical number and the to a Scheme object representing a number. When the distinction is important, the Scheme object is called a number object.This report uses the types complex, real, rational, andinteger to refer to both mathematical numbers and number objects. The fixnum and flonum refer to special subsets of the number objects, as determined by common machine representations, as explained below.

4.1: Numerical tower

Numbers may be arranged into a tower of subsets in which each level is a subset of the level above it:

For example, 5 is an integer. Therefore 5 is also a rational, a real, and a complex. The same is true of the number objects that model 5.

Numbers are organized as a corresponding tower of subtypes defined by the predicates number?, complex?, real?, rational?, and integer?; see section 4.6.

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.

4.2: Exactness

It is useful to distinguish between numbers that are represented exactly, and those that might not be. For example, index operations into data structures may need to know the index exactly, as may some operations on 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 numbers known only inexactly where exact numbers are required, Scheme explicitly distinguishes exact from inexact numbers . This distinction is orthogonal to the dimension of type.

A number is exact if it is the value of an exact numerical literal or was derived from exact numbers using only exact operations. Exact numbers correspond to mathematical numbers in the obvious way.

Conversely, a number is inexact if it is the value of an inexact numerical literal, or was derived from inexact numbers , or was derived using inexact operations. Thus inexactness is contagious.

Exact arithmetic is reliable in the following sense: If exact numbers are passed to any of the arithmetic procedures described in section TODO, and an exact number object is returned, then the result is mathematically correct. This is generally not true of computations involving inexact numbers because 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.

4.3: Fixnums and flonums

TODO

4.4: Implementation requirements

Implementations of Scheme must support numbers for the entire tower of subtypes given in section 4.1. Moreover, implementations must support exact integers and exact rationals of practically unlimited size and precision, and to implement certain procedures (listed in section TODO) so they always return exact results when given exact arguments. ( Practically unlimited means that the size and precision of these numbers should only be limited by the size of the available memory.)

Implementations may support only a limited range of inexact number objects of any type, subject to the requirements of this section. For example, an implementation may limit the range of the inexact reals (and therefore the range of inexact integers and rationals) to the dynamic range of the flonum format. Furthermore the gaps between the inexact integers and rationals are likely to be very large in such an implementation as the limits of this range are approached.Where does this leave mixed-exactness complex numbers? I read this as making them optional. Also how does "range" apply to complex numbers?

An implementation may use floating point and other approximate representation strategies for inexact numbers. This report recommends, but does not require, that the IEEE floating-point standards be followed by implementations that use floating-point representations, and that implementations using other representations should match or exceed the precision achievable using these floating-point standards TODO: cite IEEE 754.

Implementations must distinguish between 0.0 and -0.0, i.e., positive and negative inexact zero. These two numbers not eqv?. The behavior of the transcendental functions is sensitive to the distinction in accordance with IEEE 754. 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.

Implementations must also distinguish +inf.0, -inf.0, i.e. positive and negative infinity. Positive infinity is an inexact real (not rational) number that represents an indeterminate number greater than the all representable rationals. Negative infinity is regarded as an inexact real (not rational) that represents an indeterminate number less than all representable rationals. 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.

Implementations must also supply a NaN value, which is an inexact real (not rational) so indeterminate that it might represent any real number, including positive or negative infinity, and might even be greater than positive infinity or less than negative infinity. 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.

Implementations may supply more than one of the above numbers, for example if the implementation has multiple different floating point representations.

In particular, implementations that use floating-point representations must follow these rules: A floating-point result must be represented with at least as much precision as is used to express any of the inexact arguments to that operation. Potentially inexact operations such as sqrt, when applied to exact arguments, should produce exact answers whenever possible (for example the square root of an exact 4 ought to be an exact 2). However, this is not required.Should the following two sentences be removed?If, on the other hand, an exact number object is operated upon so as to produce an inexact result (as by sqrt), nd if the result is represented in floating point, then the most precise floating-point format available must be used; but if the result is represented in some other way then the representation must have at least as much precision as the most precise floating-point format available.

It is the programmer’s responsibility to avoid using inexact number objects with magnitude or significand too large to be represented in the implementation.

Compatbility Note: The R6RS required exact integers and rationals of practically unlimited size and precision, and the whole numerical tower. The R7RS-Small did not. The R7RS-Large adopts the R6RS behavior.

the R6RS and R7RS-Small allowed but did not require signed inexact zeroes, signed infinities, and NaNs. The R7RS-Large requires them.

4.5: Propagation of exactness

The procedures listed below must return the mathematically correct exact result provided all their arguments are exact:

The procedures listed below must return the correct exact result provided all their arguments are exact, and no divisors are zero:

Moreover, the procedure expt must return the correct exact result provided its first argument is an exact real num- ber object and its second argument is an exact integer.

The general rule is that the generic operations return the correct exact result when all of their arguments are exact and the result is mathematically well-defined, but return an inexact result when any argument is inexact. Exceptions to this rule include sqrt, exp, log, sin, cos, tan, asin, acos , atan, expt, make-polar, magnitude , and angle, which may (but are not required to) return inexact results even when given exact arguments, as indicated in the specification of these procedures.

One general exception to the rule above is that an implementation may return an exact result despite inexact arguments if that exact result would be the correct result for all possible substitutions of exact arguments for the inexact ones. An example is (* 1.0 0) which may return either 0 (exact) or 0.0 (inexact).

4.6: Number predicates

These numerical type predicates can be applied to any kind of argument. They return #t if the object is a number object of the named type, and #f otherwise. In general, if a type predicate is true of a number object then all higher type predicates are also true of that number object. Consequently, if a type predicate is false of a number object, then all lower type predicates are also false of that number object.

4.6.1: number?

  • (number? obj) procedure
Semantics

Returns #t if the object is a number object, and #f otherwise.[phm]: Depending on the allowed extensions, this should have description similar to that in the R7RS-Small.

Examples

[phm]: These examples are not in previous reports.

(number? 0)#t
(number? 0.0)#t
(number? 1/2)#t
(number? 1+2i)#t
(number? "1")#f
(number? '(1))#f

4.6.2: complex?

  • (complex? obj) procedure
Semantics

Returns #t if the object is a complex number object, and #f otherwise.[phm]: Depending on allowed extensions, this should have discussion similar to the R7RS-Small.

Examples
(complex? 3+4i)#t
(complex? 3)#t

4.6.3: real?

  • (real? obj) procedure
Semantics

Returns #t if the object is a real number object, and #f otherwise. Equivalent to: [phm]: In a break from previous Reports, and more in-line with how SRFIs are written, this is written as a implementation.

(define (real? x)
  (and (complex? x)
       (zero? (imag-part x))))

Rationale: The R6RS defined a complex number object to be real if and only if it had an exact zero imaginary part. This differed from the R5RS definition. One of the reasons given for this change in the rationale of the R6RS is that real? could be used as a representational predicate separate from the usual representation of complex numbers. The R5RS definition was given the name real-valued?.

The R7RS-Small attemped to change the definition back to the R5RS definition, but the examples made it unclear if the R5RS or R6RS definition was required. Working Group 2 voted to restore the R5RS definition and give the R6RS definition the name strictly-real?.

Examples
(real? 3+4i)#f
(real? 3)#t
(real? -2.5+0i)#t
(real? -2.5+0.0i)#t
(real? -2.5-0.0i)#t
(real? #e1e10)#t
(real? +inf.0)#t
(real? +nan.0)#t

4.6.4: integer?

  • (integer? obj) procedure
Semantics

Returns #t if the object is an integer object, and #f otherwise. Equivalent to:

(define (integer? obj)
  (and (real? obj)
       (= obj (round obj))))

[phm]: This definition is taken from the R7RS-Small. Is the R6RS definition better?

Examples
(integer? 3+0i)#t
(integer? 3.0)#t
(integer? 8/4)#t
(integer? 3.1)#f
(integer? 3+1i)#f
(integer? 3+0.0i)#t
(integer? 3-0.0i)#t

4.7: Derived number predicates

4.7.1: strictly-real?

  • (strictly-real? obj) procedure
Semantics

Returns #t iff the object is a real number object with an imaginary part that is exactly zero. Equivalent to

(define (strictly-real? obj)
  (and (real? obj)
       (exact? (imag-part obj))))

Rationale: The sign of the zero in the imaginary part of a complex number can change the behavior of the number when applied to trancendental functions, as the real number line is a common branch cut cite Kahan's paper. This predicate returns true when the number is exactly on the real line, and not possibly infinitesimally off of it.

Examples
(strictly-real? 3+4i)#f
(strictly-real? 3)#t
(strictly-real? -2.5+0i)#t
(strictly-real? -2.5+0.0i)#f
(strictly-real? -2.5-0.0i)#f
(strictly-real? #e1e10)#t
(strictly-real? +inf.0)#t
(strictly-real? +nan.0)#t

4.7.2: strictly-integer?

  • (strictly-integer? obj) procedure
Semantics

Returns #t iff the object is an integer object with an imaginary part that is exactly zero. Equivalent to

(define (strictly-integer? obj)
  (and (integer? obj)
       (exact? (imag-part obj))))
Examples
(strictly-integer? 3+0i)#t
(strictly-integer? 3.0)#t
(strictly-integer? 8/4)#t
(strictly-integer? 3.1)#f
(strictly-integer? 3+1i)#f
(strictly-integer? 3+0.0i)#f
(strictly-integer? 3-0.0i)#f

4.7.3: exact-integer?

  • (exact-integer? obj) procedure
Semantics

Returns #t if the object is an exact integer, and #f otherwise. Equivalent to, but may be faster than,

(define (exact-integer? obj)
  (and (integer? obj) (exact? obj)))

Compatability Note: This procedure appeared in the R7RS-Small, where it was an error if its argument was not a complex number. The R7RS-Large requires exact-integer? to return #f if it is passed a non-number object.

Examples
(exact-integer? 32)#t
(exact-integer? 32.0)#f
(exact-integer? 32/5)#f
(exact-integer? "32")#f

4.8: Arithmetic predicates

4.8.1: finite?

  • (finite? z) procedure
Description

This procedure returns #t on all real numbers except infinities and NaNs. On complex numbers, this procedure returns #t if both the real and imaginary parts of z are finite. Otherwise it returns #f.

Examples
(finite? 3)#t
(finite? +inf.0)#f
(finite? 3.0+inf.0i)#f

4.8.2: infinite?

  • (infinite? z) procedure
Description

For real numbers this procedure returns #t on infinities. For complex numbers, this procedure returns #t when either the real or imaginary parts (or both) of z are infinite. Otherwise it returns #f.

Examples
(infinite? 3)#f
(infinite? +inf.0)#t
(infinite? +nan.0)#f
(infinite? 3.0+inf.0i)#t

4.8.3: nan?

  • (nan? obj) procedure
Description

For real numbers, this procedure returns #t when the argument is a NaN. For complex numbers, this procedure returns #t when either the real or imaginary parts (or both) of obj are NaNs. For other real and complex numbers, it returns #f. If obj is not a number object, then the procedure returns #f.

Compatability Note: In the R7RS-Small, it is an error to pass a non-complex number to this procedure. In the R7RS-Large, this procedure will return #f when passed a non-number object.

Examples
(nan? +nan.0)#t
(nan? 32)#f
(nan? +nan.0+5.0i)#t
(nan? 1+2i)#f
(nan? "+nan.0")#f

4.8.4: zero?

  • (zero? z) procedure
Semantics

Test if a number is numerically equal to zero. Equivalent to

(define (zero? z)
  (= z 0))
Examples
(zero? 0)#t
(zero? 0.0)#t
(zero? -0.0)#t
(zero? 0.0+0.0i)#t
(zero? 0.0-0.0i)#t
(zero? +nan.0)#f

4.8.5: positive? and negative?

  • (positive? x) procedure
  • (negative? x) procedure
Description

Test if the real number is positive or negative, respectively.

Examples
(positive? +inf.0#t
(negative? -inf.0#t
(positive? +nan.0#f
(negative? -0.0#f

4.8.6: even? and odd?

  • (even? n) procedure
  • (odd? n) procedure
Description

Tests whether the argument is even or odd, respectively.

4.9: Exactness procedures

4.9.1: Exactness predicates

  • (exact? z) procedure
  • (inexact? z) procedure
Description

Test for the exactness of a quantity. For any Scheme number, precisely one of these predicates is true.

Examples
(exact? 3.0)#f
(exact? #e3.0)#t
(inexact? 3.)#t

4.9.2: exact

  • (exact z) procedure
Description

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.

This procedure (along with inexact) implements the natural one-to-one correspondence between exact and inexact integers throughout an implementation-dependent range. See 4.4.

Note: This procedure was known in the R5RS as inexact->exact, but it has always accepted arguments of any exactness. The new name is clearer and shorter, as well as compatible with the R6RS.

4.9.3: inexact

  • (inexact z) procedure
Description

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.

This procedure (along with exact) implements the natural one-to-one correspondence between exact and inexact integers throughout an implementation-dependent range. See 4.4.

Note: This procedure was known in the R5RS as exact->inexact, but it has always accepted arguments of any exactness. The new name is clearer and shorter, as well as compatible with the R6RS.

4.10: Order predicates

Description

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, all the predicates return #f. They do not distinguish between inexact zero and inexact negative zero.

Let x be a finite real number. Then (< -inf.0 x +inf.0) and (> +inf.0 x -inf.0) evaluate to true. Similarly, if y is a non-NaN real number, then (<= -inf.0 x +inf.0) and (>= +inf.0 x -inf.0) evaluate to true.

These predicates are required to be transitive.

Implementation 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 evaluate to true with this approach, because of the limitations of IEEE representations of large integers, whereas (= (- big 1) (+ big 1)) evaluates to 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 comparsion of inexact numbers is defined 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.

Examples

(= +inf.0 +inf.0)#t
(= -inf.0 +inf.0)#f
(= -inf.0 -inf.0)#t
(let ((x +nan.0))
  (= x x))#f

4.11: Generic arithmetic

4.11.1: max and min

  • (max x1 x1) procedure
  • (min x1 x1) procedure
Description

These procedures return the maximum or minimum of their arguments.

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.

Examples
(max 3 4)4
(max 3.9 4)4.0
(max 1 +inf.0)+inf.0
(min 1 -inf.0)-inf.0

4.11.2: +

  • (+ z1) procedure
Description

Returns the sum of the arguments. If no arguments are given, return 0 (the additive identity). The following special cases apply:

  • Any finite real number added to a positive infinity returns a positive infinity.

  • Any finite real number added to a negative infinity returns a negative infinity.

  • Any real number added to a NaN returns a NaN.

  • Negative zero added to negative zero returns a negative zero.

  • Negative zero added to positive zero returns a positive zero.

  • Positive infinity added to positive infinity returns positive infinity.

  • Negative infinity added to negative infinity returns negative infinity.

  • Positive infinity added to negative infinity returns a NaN.

If this procedure is applied to mixed non-rational real and non-real complex arguments, it may raise an implementation restriction.

Examples
(+ 3 4)7
(+ 3)3
(+)0
(+ +inf.0 +inf.0)+inf.0
(+ 100 +inf.0)+inf.0
(+ -inf.0 +inf.0)+nan.0

4.11.3: *

  • (* z1) procedure
Description

Returns the product of the arguments. If no arguments are given, return 1 (the multiplicative identity). The following special cases apply:

  • Any real number multiplied with a NaN returns a NaN.

  • Any real number multiplied with an infinite returns an infinite number whose sign is the result of multiplying the sign of the real number and the sign of the infinite number.

  • An inexact zero multiplied with an infinite number returns a NaN.

  • An inexact zero multiplied with a finite real number returns a zero whose sign is the result of multiplying the sign of the real number and the sign of the infinite number.

  • Exact zero multiplied with an infinite number returns either exact zero or a NaN.

Examples
(* 4)4
(*)1
(* 5 +inf.0)+inf.0
(* -5 +inf.0)-inf.0
(* +inf.0 +inf.0)+inf.0
(* +inf.0 -inf.0)-inf.0
(* +inf.0 0.0)+nan.0
(* 0.0 -1)-0.0
(* -0.0 1)-0.0
(* -0.0 0.0)-0.0
(* -0.0 -0.0)0.0

4.11.4: -

  • (- z1 z2) procedure
Description

With one argument, returns the number with the sign flipped. For finite nonzero numbers, this is the additive inverse. With two or more arguments, returns the difference of the arguments, associating to the left. The special cases of + apply, mutatis mutandis.

Examples
(- 0.0)-0.0
(- -0.0)0.0
(- 3 4)-1
(- 3 4 5)-6
(- 0.0 -0.0)0.0
(- -0.0 0.0)-0.0
(- 0.0 0.0)0.0
(- -0.0 -0.0)0.0
(- +inf.0)-inf.0
(- +nan.0)+nan.0

4.11.5: /

  • (/ z1 z2) procedure
Restrictions

It is a domain error if this procedure is called with exact zero as a single argument, or if it is called with multiple arguments, all exact, with exact zero in any argument after the first.

Description

When called with one finite argument, returns the multiplicative inverse of the argument. When called with two or more arguments, it calculates the quotient of its arguments, associating to the left. The following special cases apply:TODO: check with IEEE 754. What about when one part of a complex number is infinity?

  • The inverse of 0.0 is positive infinity.

  • The inverse of positive infinity is 0.0.

  • The inverse of -0.0 is negative infinity.

  • The inverse of negative infinity is -0.0.

  • Dividing a finite, nonzero number by inexact zero returns an infinity whose sign is the sign of the finite number times the sign of the inexact zero.

  • Dividing a zero by an inexact zero returns a NaN.

If this procedure is applied to mixed non-rational real and non-real complex arguments, it may raise an implementation restriction.

Examples
(/ 3 4 5)3/20
(/ 3)1/3
(/ 0.0)+inf.0
(/ 1.0 0)+inf.0
(/ -1 0.0)-inf.0
(/ +inf.0)0.0
(/ 0 0)domain error
(/ 3 0)domain error
(/ 0 3.5)0.0
(/ 0 0.0)+nan.0
(/ 0.0 0)+nan.0
(/ 0.0 0.0)+nan.0

4.11.6: square

  • (square z) procedure
Description

Returns the square of z. Equivalent to (* z z).

Examples
(square 42)1764
(square 2.0)4.0

4.11.7: abs

  • (abs x) procedure
Description

Returns the absolute value of its argument.

Examples
(abs -7)7
(abs -inf.0)+inf.0
(abs -0.0)+0.0

4.11.8: gcd

  • (gcd n1) procedure
Description

Returns the greatest common divisor of the arguments. The result is always non-negative. If zero arguments are passed, return 0.

Examples
(gcd 32 -36)4
(gcd)0

4.11.9: lcm

  • (lcm n1) procedure
Description

Returns the least common multiple of the arguments. The result is always non-negative. If zero arguments are passed, return 1.

Examples
(lcm 32 -36)288
(lcm 32.0 -36)288.0
(lcm)1

4.11.10: sqrt

  • (sqrt z) procedure
Description

Returns the principal square root of z. When the argument is a rational number, have either a positive real part, or a zero real part and a non-negative imaginary part. For complex z, the value can be defined as elogz2.

Examples
(sqrt 9)3
(sqrt -1)+i

4.11.11: exact-integer-sqrt

  • (exact-integer-sqrt n) procedure
Description

Returns two non-negative exact integers s and r where

k=s2+randk<(s+1)2.
Examples
(exact-integer-sqrt 4)2 0
(exact-integer-sqrt 5)2 1

4.12: Rational procedures

4.12.1: numerator and denominator

  • (numerator q) procedure
  • (denominator q) procedure
Description

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.

Examples
(numerator (/ 6 4))3
(denominator (/ 6 4))2
(denominator
 (inexact (/ 6 4)))2.0

4.12.2: rationalize

  • (rationalize x y) procedure

This 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=p1q1 and r2=p2q2 (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.

4.13: Division procedures

A pair of operators for computing the integral quotients q and remainders r from the division of a numerator n by a denominator d should satisfy the relations

Such a pair of operators will be called a division operation pair. Many programming languages provide only one division operator pair. Some, such as C, leave the semantics unspecified when either or each of the numerator and the denominator is negative. If the numerator and denominator are both integers, then the remainder will also be an integer.

To describe the semantics of a division operator pair, it suffices to define the integer q, from which r can be uniquely derived by the relation

r=ndq,

provided that this choice of q induced an r satisfying |r|<|d|. For an extensive discussion of five of the six division operator pairs defined here, see TODO: Boute1992.

For each of six division operator pairs — floor, ceiling, truncate, round, Euclidean and balanced — there is a family of three procedures: one, named operator/, to compute the division and to return both quotient and remainder as multiple return values; one, named operator-quotient, to return only the quotient; and one, named operator-remainder, to return only the remainder. Each division operator pair except for the balanced/ pair is specified by defining the quotient q in terms of the numerator n and the denominator d.

It is a domain error if any of the arguments are not integers (exact or inexact). It is also an error to supply zero as a denominator to any of these procedures. If any argument is inexact, the result is inexact, unless the implementation can prove that the inexactness cannot affect the result, as in the case of dividing an exact zero by an inexact number.TODO: examples

4.13.1: floor division

  • (floor/ n1 n2) procedure
  • (floor-quotient n1 n2) procedure
  • (floor-remainder n1 n2) procedure
  • (modulo n1 n2) procedure
Description

Returns q and r such that q=n1n2. Thus a nonzero r is negative iff n1 is negative.

The modulo procedure is equivalent to the floor-remainder procedure. It is provided for backwards compatability.

4.13.2: ceiling division

  • (ceiling/ n1 n2) procedure
  • (ceiling-quotient n1 n2) procedure
  • (ceiling-remainder n1 n2) procedure
Description

Returns q and r such that q=ceiling(n1n2). Thus a nonzero r is negative iff n1 is non-negative.

Rationale: If n2 is the number of units in a block, and n1; is some number of units, then (ceiling-quotient n1 n2) gives the number of blocks needed to cover n1 units. For example, n2 might be the number of bytes in a disk sector, and n1 the number of bytes in a file; then the quotient is the number of disk sectors needed to store the contents of the file. For another example, n2 might be the number of octets in the output of a cryptographic hash function, and n1 the number of octets desired in a key for a symmetric cipher, to be derived using the cryptographic hash function; then the quotient is the number of hash values needed to concatenate to make a key.

4.13.3: truncate division

  • (truncate/ n1 n2) procedure
  • (truncate-quotient n1 n2) procedure
  • (truncate-remainder n1 n2) procedure
  • (quotient n1 n2) procedure
  • (remainder n1 n2) procedure
Description

Returns q and r such that q=truncate(n1n2). Thus a nonzero r is negative iff n1 is negative. With the truncate operator pair, the quotient of +1, 0, or -1 by any non-unit denominator is 0.

The procedures quotient and remainder are equivalent to truncate-quotient and truncate-remainder, respectively. They are provided for backwards compatability.

4.13.4: round division

  • (round/ n1 n2) procedure
  • (round-quotient n1 n2) procedure
  • (round-remainder n1 n2) procedure
Description

Returns q and r such that q=round(n1n2). The round function rounds to the nearest integer, breaking ties by choosing the nearest even integer. Nothing general can be said about the sign of r. With the round operator pair, the quotient of +1, 0, or -1 by any non-unit denominator is 0.

4.13.5: euclidean division

  • (euclidean/ n1 n2) procedure
  • (euclidean-quotient n1 n2) procedure
  • (euclidean-remainder n1 n2) procedure
Description

If n2>0, then q=n1n2. If n2>0, then q=ceiling(n1n2). This division operator pair satisfies the stronger property 0r<|n2|.

Rationale: The requirement on the remainder is used often in mathematics. For example, (euclidean-remainder n1 n2) is always a valid index into a vector whose length is at least the absolute value of n2. This division operator pair is so named because it is the subject of the Euclidean division algorithm.

4.13.6: balanced division

  • (balanced/ n1 n2) procedure
  • (balanced-quotient n1 n2) procedure
  • (balanced-remainder n1 n2) procedure
Description

This division operator pair satisfies the property

|n22|r<|n22|

Rationale: When n2 is 2k for some k, this reduces to |2k1|r<|2k1|

This is the interval of integers representable in two’s-complement with k bits.

Rationale: A version of these procedures appeared in the R6RS with the names div0-and-mod0, div0, and mod0.

4.14: Rounding procedures

4.14.1: floor

  • (floor x) procedure
Description

Returns the largest integer not larger than x. If the argument is inexact, the result will also be inexact. If the argument is infinity or NaN, the argument is returned.

Examples
(floor -4.3)-5.0
(floor 3.9)3.0
(floor 3.5)3.0

4.14.2: ceiling

  • (ceiling x) procedure
Description

Returns the smallest integer not smaller than x. If the argument is inexact, the result will also be inexact. If the argument is infinity or NaN, the argument is returned.

Examples
(ceiling -4.3)-4.0
(ceiling 3.1)4.0
(ceiling 3.5)4.0

4.14.3: truncate

  • (truncate x) procedure
Description

Returns the integer closest to x whose absolute value is not larger than the absolute value of x. If the argument is inexact, the result will also be inexact. If the argument is infinity or NaN, the argument is returned.

Examples
(truncate -4.3)-4.0
(truncate 3.1)3.0
(truncate 3.5)3.0

4.14.4: round

  • (round x) procedure
Description

Returns the integer closest to x, rounding to even when x is halfway between two integers. If the argument is inexact, the result will also be inexact. If the argument is infinity or NaN, the argument is returned.

Note: The round procedure rounds to even for consistency with the default rounding mode specified by the IEEE 754 floating-point standard.

Examples
(round -4.3)-4.0
(round 2.5)2.0
(round 3.5)4.0

4.14.5: round-away

  • (round-away x) procedure
Description

Returns the integer closest to x, rounding to the integer larger in absolute value when x is halfway between two integers. If the argument is inexact, the result will also be inexact. If the argument is infinity or NaN, the argument is returned.

Note: This procedure corresponds to roundTiesToAway in the IEEE 754-2008 standard, and also to how rounding is normally defined for decimal numbers.

Examples
(round-away -4.3)-4.0
(round-away 2.5)3.0
(round-away 3.5)4.0

4.15: Transcendental procedures

In general, the trancendental functions such as log and arcsine are multiply defined.

The value of logz for non-real z is defined in terms of log as

logz=log|z|+(anglez)i

where anglez is the angle of z=aeiθ specified as

anglez=b+2in

with n chosen such that πanglezπ.

With the one-argument version of log defined this way, the values of the two-argument-version of log, sin1, cos1, tan1, and the two-argument version of tan1 are according to the following formulæ

log(z,b)=logzlogbsin1z=ilog(iz+1-z)cos1z=π2sin1ztan1z=log(1+iz)log(1iz)2itan1(x,y)=angle(x+yi)tanh1z=log(1+z)log(1-z)2sinh1z=log(z+1+z2)cosh1z=2ilog(1+z2+iz-12)

TODO: citations

The range of tan1(x,y) is as in the following table. Note that this table distinguishes the sign of zero. When a result is an unsigned zero, it is either positive zero or exact integer (unsigned) zero.

yconditionxconditionrange of resultry=0.0x>0.0r=0.0y=+0.0x>0.0r=+0.0y=0.0x>0.0r=−0.0y>0.0x>0.00.0<r<π2y>0.0x=0.0r=π2y>0.0x<0.0π2<r<πy=0.0x<0.0r=πy=+0.0x<0.0r=πy=−0.0x<0.0r=πy<0.0x<0.0π<r<π2y<0.0x=0.0r=π2y<0.0x>0.0π2<r<0.0y=0.0x=0.0ris undefinedy=+0.0x=+0.0r=+0.0y=−0.0x=+0.0r=−0.0y=+0.0x=−0.0r=πy=−0.0x=−0.0r=πy=+0.0x=0r=π2y=−0.0x=0r=π2

4.15.1: exp

  • (exp z) procedure
Description

Returns the base-e exponential of z.

Examples
(exp -inf.0)0.0
(exp +inf.0)+inf.0
(exp +3.141592653589793116i)-1.0 ; approximately

4.15.2: expt

  • (expt z1 z 2) procedure
Description

Returns z1 raised to the power of z2. For nonzero z1, this is ez2logz1 For zero z1 and z2, the returned value is 1 with the appropriate exactness. For zero z1 and a z2 with a positive real part, the returned value is zero with the appropriate sign and exactness. In other cases where the first argument is zero, an implementation violation may be signalled.

Examples
(expt 5 3)125
(expt 5 -3)1/125
(expt 5 0)1
(expt 0 5)0
(expt 0 5+.0000312i)0
(expt 0 -5)unspecified
(expt 0 -5+.0000312i)unspecified
(expt 0 0)1
(expt 0.0 0.0)1.0

4.15.3: log

  • (log z1 [z2]) procedure
Restrictions

It is a domain error if z1 is exact zero.

Description

With a single argument, computes the base-e logarithm of z1. With two arguments, computes the base-z2 of z1.

The logarithm of positive inexact zero is positive infinity. The logarithm of negative inexact zero is a complex number, whose real part is negative infinite and whose imaginary part is approximately pi.

Examples
(log +inf.0)+inf.0
(log 0.0)-inf.0
(log 0)domain error
(log -inf.0)+inf.0+3.141592653589793i ; approximately
(log -inf.0-0.0i)+inf.0-3.141592653589793i ; approximately

4.15.4: Trigonometric procedures

  • (sin z) procedure
  • (asin z) procedure
  • (cos z) procedure
  • (acos z) procedure
  • (tan z) procedure
  • (atan z) procedure
  • (atan x y) procedure
Description

Computes the corresponding trigonometric or inverse trigonometric function. The two-argument version of atan computes (angle (make-rectangular x y).

Examples
(atan -inf.0) -1.5707963267948965 ; approximately
(atan +inf.0) 1.5707963267948965 ; approximately

4.15.5: Hyperbolic procedures

  • (sinh z) procedure
  • (asinh z) procedure
  • (cosh z) procedure
  • (acosh z) procedure
  • (tanh z) procedure
  • (atanh z) procedure
Description

Computes the corresponding hyperbolic or inverse hyperbolic functions.

Examples

TODO

4.16: Complex number procedures

4.16.1: make-rectangular

  • (make-rectangular x1 x2) procedure
Description

Returns a complex number whose real part is x1 and whose imaginary part is x2.

4.16.2: make-polar

  • (make-polar x1 x2) procedure
Description

Returns the complex number x1ex2. This procedure may return an inexact number even when given exact arguments.

4.16.3: conjugate

  • (conjugate z) procedure
Semantics

Returns the complex conjugate of z.

Examples
(conjugate 1+2i)1-2i
(conjugate 1+inf.0i)1-inf.0i
(conjugate 1+0.0i)1-0.0i
(conjugate 1)1

4.16.4: real-part

  • (real-part z) procedure
Description

Returns the real part of z. This procedure can return an exact number given an inexact complex number, if the complex number was constructed with an exact real part. For example, it is allowed for (real-part +1.0i)to return exact zero.

4.16.5: imag-part

  • (imag-part z) procedure
Description

Returns the imaginary part of z. This procedure can return an exact number given an inexact complex number, if the complex number was constructed with an exact imaginary part. For example, it is allowed for (imag-part +1.0)to return exact zero.

4.16.6: magnitude

  • (magnitude z) procedure
Description

Returns the magnitude of z.

Examples
(magnitude 3+4i)5 ; approximately
(magnitude (make-polar 1.1 2.2))1.1 ; approximately

4.16.7: angle

  • (angle z) procedure
Description

Let the complex number z be x1ex2, where πx2π. This procedure returns x2.

Examples
(angle -1.0+0.0i)3.141592653589793116
(angle -1.0-0.0i)-3.141592653589793116

5: Booleans

[phm]: R7RS with minor modifications

The standard boolean objects for true and false are written as #t and #f. Alternatively, when the R6RS lexical mode is not enabled, 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 true or 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

5.1: Boolean procedures

5.1.1: not

  • (not obj) procedure
Semantics

Returns #t if obj is false, and #f otherwise.

Examples
(not #t)#f
(not 3)#f
(not (list 3))#f
(not #f)#t
(not '())#f
(not (list))#f
(not 'nil)#f

5.1.2: boolean?

  • (boolean? obj) procedure
Semantics

Returns #t if obj is either #t or #f and returns #f otherwise.

Examples
(boolean? #f)#t
(boolean? 0)#f
(boolean? ’())#f

5.1.3: boolean=?

  • (boolean? boolean1 boolean2 boolean3) procedure
Semantics

Returns #t if all the arguments are either all #t or all #f.

6: 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 list or a pair whose cdr is a list. More precisely, the set of lists is defined as the smallest set X such that

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 list is a special object of its own type. It is not a pair, it has no elements, and its length is zero.

Note: The above 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 (datum1 . datum2)where datum1 is the representation of the value of the car field and datum2 is the value of the cdr field. For example (4 . 5) is a pair whose car is 4 and whose cdr is 5.

A more streamlined notation can be used for lists: the elements of the list are simply enclosed in parentheses and separated by spaces. The empty list is represented by (). For example,

(a b c d e)

and

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

are equivalent notations for a list of symbols. The general rule is that, if a dot is followed by an open parenthesis, the dot, open parenthesis, and matching closing parenthesis can be omitted in the external representation.

Note that (4 . 5)is the external representation of a pair, not an expression that evaluates to a pair. Similarly, the sequence of characters (+ 2 6) is notan external representation of the integer 8, even though it is an expression (in terms of the procedures described here) evaluating to the integer 8; rather, it is a syntactic datum representing a three-element list, the elements of which are the symbol + and the integers 2 and 6.[phm]: Derived from the R6RS description.

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)))

The length of an improper list is the number of pairs before the non-list cdr. This number may be infinity. The elements of an improper list are the cars of each pair in the list.

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 TODO). Among other things, this permits the use of the read procedure to parse Scheme programs. See section TODO.

6.1: Pair procedures

6.1.1: pair?

  • (pair? obj) procedure
Semantics

Returns #t if obj is a pair, and otherwise returns #f.

Examples
(pair? '(a . b))#t
(pair? (cons 'a 'b))#t
(pair? '(a b c))#t
(pair? '())#f
(pair? '#(a b))#f

6.1.2: cons

  • (cons obj1 obj2) procedure
Semantics

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.

Examples
(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)

6.1.3: car and cdr

  • (car pair) procedure
  • (cdr pair) procedure
Semantics

Returns the car or cdr field of the pair, respectively.[phm]: merged descriptions

Examples
(car '(a b c))a
(car '((a) b c d))(a)
(car '(1 . 2))1
(car '())domain error

6.1.4: set-car! and set-cdr!

  • (set-car! pair obj) procedure
  • (set-cdr! pair obj) procedure
Semantics

Store obj in the car or cdr field of pair, respectively.[phm]: merged descriptions

Examples
(define f (list 'not-a-constant-list))
(set-car! f 3)unspecified
f(3)
(set-cdr! f 4)unspecified
f(3 . 4)
(set-car! '(constant-list) 3)domain error

6.1.5: Compositions

  • (ccompositionr pair) procedure
Restrictions

TODO

Semantics

These procedures are compositions of car and cdr. The composition is any string of a and d from two to four (inclusive) characters. For example, caddr could be defined as

(define (caddr pair) (car (cdr (cdr pair))))

Arbitrary compositions up to four deep are provided. There are twenty-eight of these procedures in all.

6.2: Basic list procedures

6.2.1: null?

  • (null? obj) procedure
Semantics

Returns #t if obj is the empty list, and otherwise returns #f.

6.2.2: list?

  • (list? obj) procedure
Semantics

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.

Examples
(list? '(a b c))#t
(list? '())#t
(list? '(a . b))#f
(list? '#1=(a . #1#))#f

6.2.3: list

  • (list obj) procedure
Semantics

Returns a newly allocated list of its arguments.

Examples
(list 'a (+ 3 4) 'c)(a 7 c)
(list)()

6.2.4: make-list

  • (make-list k [fill]) procedure
Semantics

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.

Examples
(make-list 2 3)(3 3)

6.2.5: list-tail

  • (list-tail list k) procedure
Restrictions

The list can be improper, but it must start with a chain of at least k pairs. Otherwise, it is a domain error.[phm]: Modified to allow circular and dotted lists.

Semantics

Returns the sublist of list obtained by omitting the first k elements.[phm]: Add share-structure statement?

Examples
(list-tail '(a b c d) 2)(c d)
Sample Implementation
(define (list-tail list k)
  (if (zero? k)
      list
      (list-tail (cdr list) (- k 1))))

6.2.6: list-ref

  • (list-ref list k) procedure
Restrictions

The list argument can be improper, but it must start with a chain of more than k elements. Otherwise, it is a domain error.[phm]: Modified to allow circular and dotted lists.

Semantics

Returns the kth element of list.

Examples
(list-ref '(a b c d) 2)c
(list-ref '(a b c d) (exact (round 1.8)))c
Sample Implementation
(define (list-ref list k)
  (car (list-tail list k)))

6.2.7: list-set!

  • (list-set! list k obj) procedure
Restrictions

The list argument can be improper, but it must start with a chain of more than k elements. Otherwise, it is a domain error.[phm]: Modified to allow circular and dotted lists.

Semantics

Stores obj in element k of list.

Examples
(let ((ls (list 'one 'two 'five!)))
  (list-set! ls 2 'three)
  ls)(one two three)
(list-set! '(0 1 2) 1 "oops")domain error
Sample Implementation
(define (list-set! list obj k)
  (set-car! (list-tail list k) obj))

6.3: Bulk list procedures

6.3.1: length

  • (length list) procedure
Semantics

Returns a newly allocated list of its arguments.

Examples
(list 'a (+ 3 4) 'c)(a 7 c)
(list)()

6.3.2: append

  • (append list [obj]) procedure
Semantics

Returns a (possibly improper) 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.

Examples
(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

6.3.3: reverse

  • (reverse list) procedure
Semantics

Returns a newly allocated list consisting of the elements of list in reverse order.

Examples
(reverse '(a b c))(c b a)
(reverse '(a (b c) d (e (f)))) ((e (f)) d (b c) a)

6.3.4: list-copy

  • (list-copy obj [start [end]]) procedure
Restrictions

If neither start or end are given, the it is a domain error if obj is circular.

Semantics

Copies a list or improper list.

If neither start nor end is supplied, then this procedure returns a newly allocated copy of the sequence of pairs at the start of obj. 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.

If start but not end is supplied, this procedure is equivalent to(list-copy (list-tail im-list start)).

If both start and end are supplied, then the startth pair to the endth pair are copied, and the list is terminated with an empty list.

In any case, only the pairs themselves are copied; the cars of the pairs in the result are the same (in the sense of eqv?) as the cars of the corresponding pairs that were copied from obj.

Compatability Note: This procedure originally appeared in SRFI 1 and was added to R7RS Small. The R7RS Large extended the procedure to take start and end arguments.

6.4: Higher order list procedures

6.4.1: map

  • (map proc list1 list2) procedure
Restrictions

It is a domain error if proc does not accept as many arguments as there are lists and return a single value.

The lists can be circular, but if all of them are circular, it is undefined behavior.

If proc mutates any of the lists, it is undefined behavior.

Semantics

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 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.

The procedure proc is always called in the same dynamic environment as the call to map.

Examples
(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)))unspecified
either (1 2) or (2 1)

6.4.2: for-each

  • (for-each proc list1 list2) procedure
Restrictions

It is a domain error if proc does not accept as many arguments as there are lists.

The lists can be circular, but if all of them are circular, it is undefined behavior.

If proc mutates any of the lists, it is undefined behavior.

Semantics

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.[phm]: Because for-each cannot returned unspecified values, an implementation cannot tail-call proc on the last element(s).

The procedure proc is always called in the same dynamic environment as the call to for-each.

Examples
(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)

6.5: List query procedures

6.5.1: memq, memv, and member

[phm]: This is PROPOSED, NOT final.
  • (memq obj list) procedure
  • (memv obj list) procedure
  • (member obj list [compare]) procedure
Restrictions

The compare, if present, must be a procedure that accepts two arguments and returns one value.

Semantics

These procedures return the first sublist sl of list such that (C obj (car sl)) returns true. The sublists of list are the non-empty lists returned by (list-tail list k) for k less than the length of list. If the condition is never satisfied for any sublist, then #f (not the empty list) is returned.

For memq, eq? is used. For memv, eqv? is used. For member, compare is used if given, otherwise equal? is used.

Compatability Note: The optional argument to member was in SRFI 1 and included in the R7RS-Small. The argument order to compare was unspecified in R7RS-Small, but was in SRFI 1. The R7RS-Large adopts the SRFI 1 behavior.

Examples
(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)
(member 5 '(1 2 3 4 5 6 7 8) <)(6 7 8)

6.5.2: assq, assv, and assoc

[phm]: This is PROPOSED, NOT final.
  • (assq obj list) procedure
  • (assv obj list) procedure
  • (assoc obj list [compare]) procedure
Restrictions

The compare, if present, must be a procedure that accepts two arguments and returns one value. The alist must be a list of pairs.

Semantics

These procedures return the first pair p of alist such that (C obj (car p)) returns true.. If the condition is never satisfied for any pair, then #f (not the empty list) is returned.

For assq, eq? is used. For assv, eqv? is used. For assoc, compare is used if given, otherwise equal? is used.

Compatability Note: The optional argument to assoc was in SRFI 1 and included in the R7RS-Small. The argument order to compare was unspecified in R7RS-Small, but was in SRFI 1. The R7RS-Large adopts the SRFI 1 behavior.

Examples
(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)
(assoc 3 '((1 a) (2 b) (3 c) (4 d) (5 e)) <)(4 d)

7: 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 TODO.

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.

7.1: Symbol procedures

7.1.1: symbol?

  • (symbol? obj) procedure
Semantics

Returns #t if obj is a symbol, and #f otherwise.

Examples
(symbol? 'foo)#t
(symbol? (car '(a b)))#t
(symbol? "bar")#f
(symbol? 'nil)#t
(symbol? '())#f
(symbol? #f)#f

7.1.2: symbol=?

  • (symbol=? symbol1 symbol2 symbol3) procedure
Semantics

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.

7.1.3: symbol->string

  • (symbol->string symbol) procedure
Semantics

Returns the name of symbol as a string, but without adding escapes.[phm]: Is that "escapes" part necessary?

The returned string may either be immutable or freshly allocated.[phm]: Merge with some other section on immutable values?

Examples
(symbol->string 'flying-fish)"flying-fish"
(symbol->string 'Martin)"Martin"
(symbol->string (string->symbol "Malvina"))Malvina

7.1.4: string->symbol

  • (string->symbol string) procedure
Semantics

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.[phm]: Is the escaping text redundant?

Examples
(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

8: Characters

[phm]: From R6RS

Characters are objects that represent Unicode scalar values.

Note: Unicode defines a standard mapping between sequences of Unicode scalar values (integers in the range 0 to #x10FFFF, excluding the range #xD800 to #xDFFF) in the latest version of the standard and human-readable characters.[phm]: That previous sentence should be reworded. More precisely, Unicode distinguishes between glyphs, which are printed for humans to read, and characters, which are abstract entities that map to glyphs (sometimes in a way that’s sensitive to surrounding characters). Furthermore, different sequences of scalar values sometimes correspond to the same character. The relationships among scalar, characters, and glyphs are subtle and complex.

Despite this complexity, most things that a literate human would call acharacter can be represented by a single Unicode scalar value (although several sequences of Unicode scalar values may represent that same character). For example, Roman letters, Cyrillic letters, Hebrew consonants, and most Chinese characters fall into this category.

Unicode scalar values exclude the range #xD800 to #xDFFF, which are part of the range of Unicode code points. However, the Unicode code points in this range, the so-called surrogates, are an artifact of the UTF-16 encoding, and can only appear in specific Unicode encodings, and even then only in pairs that encode scalar values. Consequently, all characters represent code points, but the surrogate code points do not have representations as characters.

Compatibility Note: The R6RS required Scheme programs to be written in sequences of Unicode scalar values. The R7RS-Small allowed for non-Unicode characters as long as #x0 and #x7F were the ASCII characters, that char->integer and integer->char treated non-Unicode characters as having integer values greater than Unicode characters, and that certain procedures were defined on Unicode scalar values according to certain properties and annexes of the Unicode standard. The R7RS-Large adopts the R6RS behavior.

8.1: Syntax

The grammar of character constants is:

character
::= #\any character
::= #\character name
::= #\xhex scalar value
character name
::= alarm
::= backspace
::= delete
::= escape
::= newline
::= null
::= return
::= space
::= tab
R6RS character name
::= alarm
::= backspace
::= delete
::= esc
::= linefeed
::= newline
::= nul
::= page
::= return
::= space
::= tab
::= vtab

The R6RS character names are used instead of the character names when the parser is set to R6RS mode.

Case is significant in #\character, and in #\character name, but not in #\xhex scalar value. A character must be followed by a delimiter or by the end of the input. This rule resolves various ambiguous cases involving named characters, requiring, for example, the sequence of characters #\space to be interpreted as the space character rather than as the character #s followed by the identifier pace.

Characters written in the #\ notation are self-evaluating. That is, they do not have to be quoted in programs.[phm]: Extension paragraph?

Compatability Note: The R6RS introduced more control characters for the ASCII control characters that commonly had escape sequences in other programming languages. The R7RS-Small adopted a different set of names and escape sequences, intended to be more mnemonic, and to remove rarely used codes such as vertical tab and form feed. The R7RS-Large adopts the R7RS-Small convention.

The meaning of each escape sequence (R6RS-specific escape sequence in parentheses) is:

#\alarm
U+0007
#\backspace
U+0008
#\delete
U+007F
#\escape (#\esc)
U+001B
#\newline (#\linefeed)
U+000A (the linefeed character)
#\null (#\nul)
U+0000 (the NUL character)
(#\page)
U+000C (the form feed character)
#\return
U+000D (the return character)
#\space
U+0020 (the space character)
#\tab
U+0009 (the horiziontal tab character)
(#\vtab)
U+000B (the vertical tab character)

A character written as #\hex scalar value is the character associated with that Unicode scalar value.

8.1.1: Examples

[phm]: TODO: how to mark this up?

8.2: Character procedures

8.2.1: char?

  • (char? obj) procedure
[phm]: From R6RS/R7RS
Semantics

Returns #t if obj is a character, or #f otherwise.

8.2.2: char->integer

  • (char->integer char) procedure
[phm]: From R6RS
Semantics

Returns the unicode scalar value of char as an exact integer.

Examples
[phm]: New example
(char->integer #\x10FFFF)#x10FFFF

8.2.3: integer->char

  • (integer->char sv) procedure
[phm]: From R6RS
Restrictions

The sv must be an exact integer Unicode scalar value, which is equivalent to the following evaluating to true:

(or (<= 0 sv #xD7FF) (<= #xE000 sv #x10FFFF))
Semantics

Returns the character associated with the scalar value.

Examples
(integer->char 32)#\space
(char->integer (integer->char 5000))5000
(integer->char #xD800)&assertion exception

8.2.4: Character comparisions

  • (char=? char1 char2 charn) procedure
  • (char<? char1 char2 charn) procedure
  • (char>? char1 char2 charn) procedure
  • (char<=? char1 char2 charn) procedure
  • (char>=? char1 char2 charn) procedure
[phm]: From R6RS, second paragraph is from R7RS
Semantics

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.

Examples
(char<? #\z #\ß)#t
(char<? #\z #\Z)#f

8.3: Unicode

This library provides access to locale-independent Unicode transformations for characters.

These procedures are consistent with Unicode’s locale- independent mappings from scalar values to scalar values for upcase, downcase, titlecase, and case-folding operations. These mappings can be extracted from UnicodeData.txt and CaseFolding.txtfrom the Unicode Consortium, ignoring language-dependent mappings in the latter.

These character-based procedures are an incomplete approximation to case conversion, even ignoring the user’s locale. In general, case mappings require the context of a string, both in arguments and in result. The string-upcase, string-downcase, and string-foldcase procedures add section perform more general case conversion.

Compatability Note: The definitions of these procedures comes from the R7RS-Small, modified for current Unicode support. Titlecasing procedures are not included.

8.3.1: char-upcase

  • (char-upcase string) procedure
Semantics

Given an argument that is the lowercase part of a Unicode casing pair, returns the uppercase member of the pair. Note that language-sensitive casing pairs are not used. If the argument is not the lowercase member of such a pair, it is returned.

Examples
(char-upcase #\i)#\I
(char-upcase #\ß)#\ß
(char-upcase #\Σ)#\Σ
(char-upcase #\ς)#\Σ

8.3.2: char-downcase

  • (char-downcase string) procedure
Semantics

Given an argument that is the uppercase part of a Unicode casing pair, returns the lowercase member of the pair. Note that language-sensitive casing pairs are not used. If the argument is not the uppercase member of such a pair, it is returned.

Note: Note that many Unicode lowercase characters do not have uppercase equivalents.

Examples
(char-downcase #\i)#\i
(char-downcase #\ß)#\ß
(char-downcase #\Σ)#\σ
(char-downcase #\ς)#\ς

8.3.3: char-foldcase

  • (char-foldcase string) procedure
Semantics

Applies the Unicode simple case-folding algorithm to its argument and returns the result. Note that language-sensitive folding is not used.

Note: Note that many Unicode lowercase characters do not have uppercase equivalents.

Examples
(char-downcase #\i)#\i
(char-downcase #\ß)#\ß
(char-downcase #\Σ)#\σ
(char-downcase #\ς)#\ς

8.3.4: Case-insensitive comparisons

  • (char-ci=? char1 char2 char3) procedure
  • (char-ci<? char1 char2 char3) procedure
  • (char-ci>? char1 char2 char3) procedure
  • (char-ci<=? char1 char2 char3) procedure
  • (char-ci>=? char1 char2 char3) procedure
Semantics

These procedures are similar to char=?, etc., but operate on the case-folded versions of the characters.

Examples
(char-ci<? #\z #\Z)#f
(char-ci=? #\z #\Z)#t
(char-ci=? #\ς #\σ)#t

8.3.5: char-alphabetic?

  • (char-alphabetic? char) procedure
Semantics

Returns #t if it has the Unicode Alphabetic property. Otherwise returns #f.

Examples
char-alphabetic? #\a#t

8.3.6: char-numeric?

  • (char-numeric? char) procedure
Semantics

Returns #t if it has the Unicode Numeric_Type property equal to Decimal. Otherwise returns #f.

Examples
char-alphabetic? #\1#t

8.3.7: char-whitespace?

  • (char-whitespace? char) procedure
Semantics

Returns #t if it has the Unicode White_Space property. Otherwise returns #f.

Examples
char-whitespace? #\space#t
char-whitespace? #\x00A0#t

8.3.8: char-upper-case?

  • (char-upper-case? char) procedure
Semantics

Returns #t if it has the Unicode Uppercase property. Otherwise returns #f.

Examples
char-uppercase? #\Σ#t

8.3.9: char-lower-case?

  • (char-lower-case? char) procedure
Semantics

Returns #t if it has the Unicode Lowercase property. Otherwise returns #f.

Examples
char-lowercase? #\σ#t
char-lowercase? #\x00AA#t

9: Strings

Strings are sequences of characters.

The length of a string is the number of characters that it contains. This number is fixed when the string is created. The valid indicies 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.

Compatability Note: The R7RS-Small allowed implementations to forbid certain characters in strings, as long as every ASCII character that was not U+0000 (ASCII NUL) was allowed. The R6RS allows all characters in a string. The R7RS-Large adopts the R6RS behavior.

9.1: String Syntax

String literals are written as sequences of characters enclosed within quotation marks (", U+0022). Within a string literal, various escape sequences represent characters other than themselves. Escape sequences always start with a backslash (\, U+005C):

These escape sequences are case-sensitive, except that the alphabetic digits of a hex scalar value can be uppercase or lowercase.

Compatability Note: The R6RS made it a &lexical violation to use any other character than the ones specified as an escape character. The R7RS-Small made it unspecified what happens when a character not listed above was used in an escape sequence.[phm]: TODO: specify that extension is OK, except for code using #!r7rs or similar. Also specify behavior when using #!r6rs.

Examples

""""
a string with zero length
"abc""abc"
a string of three characters, U+0061, U+0062, and U+0063
"A"a string with one character, U+0041
"\x41;bc""Abc"
a string of three characters, U+0041, U+0062, and U+0063
"\x41; bc""A bc"
a string of four characters, U+0041, U+0020, U+0062, and U+0063
"\x41bc;""\x41bc;"
a string of one character, U+41BC
"\x41Bc;""\x41bc;"
a string of one character, U+41BC
"\x41"&lexical exception
"\x;"&lexical exception
"\x00000041;""A"
a string with one character, U+0041
"\x0010FFFF;""\x10ffff;"
a string with one character, U+10FFFF
"\x00110000;"&lexical exception
out of range
"\xD800;"&lexical exception
in excluded range
"A
bc""a\nbc"
if no space appears after A, a string of four characters, U+0061, U+000A, U+0062, and U+0063
"ΧΑΟΣ""ΧΑΟΣ"
a string of four characters, U+03A7, U+0391, U+039F, and U+03A3
"\n"a string of one character, U+000A
"Here's text \
  containing just one line""Here's text containing just one line"

9.2: Raw String Syntax

Raw strings are an alternative syntax for string literals that do not interpret escape sequences inside of them.

The string S is written as a raw string using the notation #"delimiter"string data"delimiter", where string data is the characters of S; with the restriction that S does not contain "delimiter" as a substring, and does not contain "delimiter as a suffix. Since the delimiter can be freely chosen, any string can be represented as a raw string with a suitable choice of delimiter. All characters in S are repesented literally in the string.

Examples

#""""""
#""\begin{document}"""\\begin{document}"
#"--")")")"-""--"")\")\")-\")"
#""a"""a"
#""\"""\\"
#"-"""-""\""
#"-" " "-"" \" "
#"-"#""a"""-""#\"\"a\"\""
#"-"ends with \""-""ends with \\\""
#""multiline
string"""multiline\nstring"
#""
    no whitespace stripping"""\n    no whitespace stripping"
#""{"first_name" : "John",
"last_name" : "Doe"}"""{\"first_name\" : \"John\",\n\"last_name\" : \"Doe\"}"
#""\(?(\d{3})\D{0,3}(\d{3})\D{0,3}(\d{4})"""\\(?(\\d{3})\\D{0,3}(\\d{3})\\D{0,3}(\\d{4})"

9.3: Fundamental string procedures

[phm]: String mutation deprecated?

9.3.1: string?

  • (string? obj) procedure
Semantics

Returns #t if obj is a string, and #f otherwise.

9.3.2: make-string

  • (make-string k [char]) procedure
Semantics

[phm]: Require fixnums here and everywhere else.

Returns a newly allocated string of length k. If char is given, then all elements of the string are initialized to char, otherwise the contents of the string are unspecified.

Examples

[phm]: These are new examples

(make-string 5 #\a)"aaaaa"
(equal? "a" (make-string 1))unspecified

9.3.3: string

  • (string char) procedure
Semantics

Returns a newly allocated string composed of the arguments.

Examples

[phm]: These are new examples

(string)""
(string #\a #\b #\c)"abc"

9.3.4: string-length

  • (string-length string) procedure

[phm]: R6RS without integer object vocabulary

Semantics

Returns the number of characters in the given string as an exact integer.

Examples

[phm]: These are new examples

(string-length "")0
(string-length "abc")3

9.3.5: string-ref

  • (string-ref string k) procedure

[phm]: R7RS

Restrictions

The k must be a valid index of the string.

Semantics

Returns character k of string using zero-origin indexing.

Compatability Note: Some implementations may use variable-length string encodings, like UTF-8, for all of their strings. Hence, this procedure may run in O(n) time, where n is the length of the string. Implementers should make this procedure run in constant time.

Examples

[phm]: These are new examples

(string-ref "ab" 0)#\a
(string-ref "ab" 1)#\b
(string-ref "ab" 2)&assertion exception

9.4: Bulk string procedures

9.4.1: string=?

  • (string=? string1 string2 stringn) procedure

[phm]: R7RS

Semantics

Returns #t if the strings are the same length and contain the same characters in the same positions. Otherwise, the string=? procedure returns #f.

Examples

[phm]: These are R6RS and new examples

(string=? "Straße" "Strasse")#f
(string=? "abc" "aBc")#f

9.4.2: String ordering predicates

[phm]: R6RS

  • (string<? string1 string2 stringn) procedure
  • (string>? string1 string2 stringn) procedure
  • (string<=? string1 string2 stringn) procedure
  • (string>=? string1 string2 stringn) procedure
Semantics

These procedures are the lexicographic extensions to strings of the corresponding orderings on characters. For example, string<? is the lexicographic ordering on strings induced by the ordering char<? on characters. If two strings differ in length but are the same up to the length of the shorter string, the shorter string is considered to be lexicographically less than the longer string.

Compatability Note: The R7RS-Large uses the behavior of the R5RS and the R6RS for these procedures. The R7RS-Small left it implementation defined what specific ordering was used for strings.

Examples
(string<? "z" "ß")#t
(string<? "z" "zz")#t
(string<? "z" "Z")#f

9.4.3: string-copy and substring

[phm]: R7RS

  • (string-copy string [start [end]]) procedure
  • (substring string start end) procedure
Semantics

Returns a newly allocated copy of part of string from start to end.

The procedure substring is an alias for string-copy except that all arguments are requied.

Compatability Note: The procedure substring was introduced in the R6RS. The R7RS-Small extended the string-copy procedure to take optional arguments.

Examples

[phm]: SRFI-13 examples

(string-copy "Beta substitution")"Beta substitution"
(let* ((s1 (string-copy "abc"))
       (s2 (string-copy s1)))
  (string-set! s1 0 #\A)
  (values s1 s2))"Abc" "abc"
(string-copy "Beta substitution" 1 10)"eta subst"
(string-copy "Beta substitution" 5)"substitution"

9.4.4: string-append

  • (string-append string) procedure

[phm]: R7RS with new examples

Semantics

Returns a newly allocated string whose characters are the concatenation of the characters in the given strings.

Examples
(string-append "abc" "def")"abcdef"
(string-append)""

9.5: String conversion procedures

9.5.1: string->list

  • (string->list string [start [end]]) procedure

[phm]: R7RS with new examples

Semantics

Returns a newly allocated list of the characters of string between start and end in order.

This procedure and list->string are inverses so far as equal? is concerned.

Examples
(string->list "abcdef")(#\a #\b #\c #\d #\e #\f)
(string->list "abcdef" 2)(#\c #\d #\e #\f)
(string->list "abcdef" 2 5)(#\c #\d #\e)
(string->list "abcdef" 0 0)()
(list->string (string->list "abcdef"))"abcdef"

9.5.2: list->string

  • (list->string list [start [end]]) procedure

[phm]: R7RS with new examples

Restrictions

The list must be a list of characters.

Semantics

Returns a newly allocated string formed from the characters in list between start and end in order.

This procedure and string->list are inverses so far as equal? is concerned.

Compatability Note: The R7RS Large added start and end arguments to this procedure.

Examples
(list->string '(#\s #\c #\m))"scm"
(list->string '())""
(string->list (list->string '(#\s #\c #\m)))(#\s #\c #\m)

9.6: Higher order string procedures

9.6.1: string-for-each

  • (string-for-each proc string1 string2) procedure

[phm]: R7RS using R6RS wording

Restrictions

The proc must accept as many arguments as there are strings, otherwise it is a domain error. It is undefined behavior for proc to mutate any of the strings.

Semantics

Applies proc element-wise to the characters of the strings for its side effects, in order from the first characters to the last. The proc always called in the same dynamic environment as the call to string-for-each. 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.

This procedure returns an unspecified value.

Examples
(let ((v '()))
  (string-for-each
   (lambda (c) (set! v (cons (char->integer c) v)))
   "abcde")
  v)(101 100 99 98 97)

9.6.2: string-map

  • (string-map proc string1 string2) procedure

[phm]: R7RS with reduced examples

Restrictions

The proc must accept as many characters as there are strings and return a single character.

Semantics

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 proc is always called in the same dynamic environment as the call to string-map. 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.

Examples
(string-map
 (lambda (c)
   (integer->char (+ 1 (char->integer c))))
 "HAL")"IBM"

9.7: Unicode procedures

This library provides access to locale-independent Unicode transformations for strings.

9.7.1: Case conversion

  • (string-upcase string) procedure
  • (string-downcase string) procedure
  • (string-titlecase string) procedure
Semantics

These procedures take a string argument and return a string result. They are defined in terms of Unicode’s locale-independent case mappings from Unicode scalar-value sequences to scalar-value sequences. In particular, the length of the result string can be different from the length of the input string. When the specified result is equal in the sense of string=? to the argument, these procedures may return the argument instead of a newly allocated string.

The procedures convert the string to uppercase, lowercase, and case-folded versions respectively. Case folding is done using the full case-folding mapping, but without the special mappings for Turkic languages.

Note: The case mappings needed for implementing these procedures can be extracted from UnicodeData.txt, SpecialCasing.txt, WordBreakProperty.txt, (the MidLetter property partly defines case-ignorable characters), and CaseFolding.txt from the Unicode Consortium.

Since these procedures are locale-independent, they may not be appropriate for some locales.

Note: Word breaking, as needed for the correct casing of Σ, is specified in Unicode Standard Annex #29.cite unicode

Compatability Note: These procedures have the semantics of the ones in the R6RS. The titlecasing procedures are not included.

Examples
(string-upcase "Hi")"HI"
(string-downcase "Hi")"hi"
(string-foldcase "Hi")"hi"
(string-upcase "Straße")"STRASSE"
(string-downcase "Straße")"straße"
(string-foldcase "Straße")"strasse"
(string-downcase "STRASSE")"strasse"
(string-downcase "Σ")"σ"
(string-upcase "ΧΑΟΣ")"ΧΑΟΣ"
(string-downcase "ΧΑΟΣ")"χαoς"
(string-downcase "ΧΑΟΣΣ")"χαoσς"
(string-downcase "ΧΑΟΣ Σ")"χαoς σ"
(string-foldcase "ΧΑΟΣΣ")"χαoσσ"
(string-upcase "χαoς")"ΧΑΟΣ"
(string-upcase "χαoσ")"ΧΑΟΣ"

9.7.2: Case-insensitive comparisons

  • (string-ci=? string1 string2 string3) procedure
  • (string-ci<? string1 string2 string3) procedure
  • (string-ci>? string1 string2 string3) procedure
  • (string-ci<=? string1 string2 string3) procedure
  • (string-ci>=? string1 string2 string3) procedure
Semantics

These procedures are similar to string=?, etc., but operate on the case-folded versions of the strings.

Examples
(string-ci<? "z" "Z")#f
(string-ci=? "z" "Z")#t
(string-ci=? "Straße" "Strasse")#t
(string-ci=? "Straße" "STRASSE")#t
(string-ci=? "XAOΣ" "χαoσ")#t

9.8: Mutating string procedures

[phm]: Say this explicitly?String mutation is deprecated.

Implementations are allowed to store strings in variable length encodings such as UTF-8. A user-visible Unicode character may not be a single Unicode codepoint.

9.8.1: string-set!

  • (string-set! string k char) procedure

[phm]: R7RS with modified examples

Restrictions

The k must be a valid index of the string.

Semantics

Stores char in element k of string. There is no requirement for this procedure to execute in constant time.

Examples
(define (f) (make-string 3 #*))
(define s (f))
(string-set! s 0 #\?)unspecified
s"?**"

[phm]: Enforce immutablity of string literals?

9.8.2: string-copy!

  • (string-copy! to at from [start [end]]) procedure

[phm]: R7RS with new examples

Restrictions

The following must be satisfied:

(and (<= 0 at (string-length to))
     (>= (- (string-length to) at) (- end start)))
Semantics

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.

Examples
(define a 12345)
(define b (string-copy "abcde"))
(string-copy! b 1 a 0 2)
b"a12de"

9.8.3: string-fill!

  • (string-fill! string fill [start [end]]) procedure

[phm]: R7RS with new examples

Restrictions

The fill must be a character.

Semantics

Stores fill in the elements of string between start and end.

Examples
(define s (string-copy "hello world"))
(string-fill! s #c 6)
s"hello ccccc"

10: 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 indexes of a vector are the exact non-negative integers less than the length of the vector. The first element in a vector is indexed by zero, and the last element is indexed by one less than the length of the vector.

Vectors are written using the notation #(datum). 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.

10.1: Fundamental vector procedures

10.1.1: vector?

  • (vector? obj) procedure
Semantics

Returns #t if obj is a vector; otherwise returns #f.

Examples
(vector? '#())#t
(vector? '(vector 1 2 3))#f
(vector? '#(1 2 3))#t

10.1.2: make-vector

  • (make-vector k [fill]) procedure
Semantics

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.

Examples
(make-vector 3 0)#(0 0 0)

10.1.3: vector

  • (vector obj) procedure
Semantics

Returns a newly allocated vector whose elements are the given arguments. It is analogous to list.

Examples
(vector 'a 'b 'c)#(a b c)

10.1.4: vector-length

  • (vector-length vector) procedure
Semantics

Returns the number of elements in vector as an exact integer.

Examples
(vector-length '#())0
(vector-length '#(a b c))3

10.1.5: vector-ref

  • (vector-ref vector k) procedure
Restrictions

It is a domain error if k is not a valid index of vector.

Semantics

Returns the contents of the element k of the vector.

Examples
(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

10.1.6: vector-set!

  • (vector-set! vector k obj) procedure
Restrictions

It is a domain error if kis not a valid index of vector.

Semantics

Stores obj in element k of vector.

Examples
(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")domain error

10.2: Vector conversion procedures

10.2.1: vector->list

  • (vector->list vector [start [end]]) procedure
Semantics

Returns a newly allocated list of objects contained of vector between start and end. Order is preserved.

Examples
(vector->list '#(dah dah didah))(dah dah didah)
(vector->list '#(dah dah didah) 1 2)(dah)

10.2.2: list->vector

  • (list->vector list [start [end]]) procedure
Semantics

Returns a newly created vector initialized to the elements of list between start and end. Order is preserved.

Compatability Note: The R7RS Large added start and end arguments to this procedure.

Examples
(list->vector '(dididit dah))#(dididit dah)

10.2.3: vector->string

  • (vector->string vector [start [end]]) procedure
Restrictions

It is a domain error if any element of vector between start and end is not a character.

Semantics

Returns a newly allocated string of the characters of vector between start and end. Order is preserved.

Examples
(vector->string
 '#(#\1 #\2 #\3)"123"

10.2.4: string->vector

  • (string->vector vector [start [end]]) procedure
Semantics

Returns a newly created vector initialized to the characters of string between start and end. Order is preserved.

Examples
(string->vector "ABC")#(#\A #\B #\C)

10.3: Bulk vector procedures

10.3.1: vector-copy

  • (vector-copy vector [start [end]]) procedure
Semantics

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.

Examples
(define a #(1 8 2 8)) ; a may be immutable
(define b (vector-copy a)) ; b is mutable
(vector-set! b 0 3)unspecified
(define c (vector-copy b 1 3))
c#(8 2)

10.3.2: vector-copy!

  • (vector-copy! to at from [start [end]]) procedure
Restrictions

It is a domain error if at is less than zero or greater than the length of to. It is also a domain error if (- (vector-length to) at) is less than (- end start).

Semantics

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.

Examples
(define a (vector 1 2 3 4 5))
(define b (vector 10 20 30 40 50))
(vector-copy! b 1 a 0 2)unspecified
b#(10 1 2 40 50)

10.3.3: vector-append

  • (vector-append vector) procedure
Semantics

Returns a newly allocated vector whose elements are the concatenation of the elements of the given vectors.

Examples
(vector-append #(a b c) #(d e f))#(a b c d e f)

10.3.4: vector-fill!

  • (vector-fill! vector fill [start [end]]) procedure
Semantics

Stores fill in the elements of vector between start and end.

Examples
(define a (vector 1 2 3 4 5))
(vector-fill! a 'smash 2 4)unspecified
a#(1 2 smash smash 5)

10.4: Higher order vector procedures

10.4.1: vector-map

  • (vector-map proc vector1 vector2) procedure
Restrictions

The proc must accept as many values as there are vectors and return a single value.

Semantics

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 proc is always called in the same dynamic environment as the call to vector-map. 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.

Compatability Note: The R6RS version of this procedure did not allow the vectors to be of different lengths. The behavior here is from the R7RS-Small.

Examples
(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)))unspecified
either #(1 2)
or #(2 1)

10.4.2: vector-for-each

  • (vector-for-each proc vector1 vector2) procedure

[phm]: R6RS with some R7RS

Restrictions

The proc must accept as many arguments as there are vectorss, otherwise it is a domain error. It is undefined behavior for proc to mutate any of the vectors.

Semantics

Applies proc element-wise to the elements of the vectorss for its side effects, in order from the first elements to the last. The proc always called in the same dynamic environment as the call to vector-for-each. 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.

This procedure returns an unspecified value.[phm]: Unspecified values?

Compatability Note: The R6RS version of this procedure did not allow the vectors to be of different lengths. The behavior here is from the R7RS-Small.

Examples
(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)

11: 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 indexes of a bytevector are the exact non-negative integers less than the length of the bytevector, starting at index zero as with vectors.

The grammar of bytevectors is

byte
::= any exact integer between 0 inclusive and 255 inclusive
bytevector
::= #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.

11.1: String notated bytevectors

Bytevectors can also be written in a string notation, where characters are interpreted as their ASCII values. The grammar of a string-notated bytevector is:

string-notated bytevector
::= #u8"string-notated bytevector element
string-notated bytevector element
::= any printable ASCII character other than " or \
::= mnemonic escape
::= "
::= \
::= \intraline whitespaceline endingintraline whitespace
::= inline hex escape

Within the contents of a string-notated bytevector:

It is a lexical syntax error if any other character or any other character sequence is used.

For example, the complete 8-byte PNG file header can be written as:

#u8"\x89;PNG\r\n\x1A;\n"

When the Scheme reader encounters a string-notated bytevector, it produces a datum as if that bytevector had been written out in full. For example, the PNG file header is exactly equivalent to

#u8(0x89 0x50 0x4E 0x47 0x0D 0x0A 0x1A 0x0A)

A Scheme implementation which supports string-notated bytevectors may not by default use this notation when any of the write family of procedures is called upon a bytevector or upon another datum containing a bytevector.must not?

Note: The \| sequence is provided so that string parsing, symbol parsing, and string-notated bytevector parsing can all use the same sequences.

The \x notation is parsed differently in string-notated bytevectors than in strings or escaped identifiers. The \x notation denotes a byte, not a Unicode codepoint. This is because many sequences of visually equivalent Unicode characters may have different UTF-8 representations. In addition, Unicode characters outside of ASCII are rarely mixed with non-Unicode binary data.

11.2: Fundamental bytevector procedures

11.2.1: bytevector?

  • (bytevector? obj) procedure
Description

Returns #t if obj is a bytevector. Otherwise, #f is returned.

11.2.2: make-bytevector

  • (make-bytevector k [fill]) procedure
Restrictions

It is a domain error if fill, when present, is not in [−128,255].

Description

Returns a newly allocated bytevector of length k. If fill is given, then all elements of the bytevector are initialized to fill, otherwise the contents of each element are unspecified.

If fill is negative, then the bytevector is filled with the twos compliment representation of that negative number.

Compatability Note: The behavior when fill is negative comes from the R6RS.

Examples
(make-bytevector 2 12)#u8(12 12)

11.2.3: bytevector

  • (bytevector byte) procedure
Description

Returns a newly allocated bytevector whose elements are the given arguments. It is analogous to list.

Examples
(bytevector 1 3 5 1 3 5)#u8(1 3 5 1 3 5)
(bytevector)#u8()

11.2.4: bytevector=?

  • (bytevector=? bytevector1 bytevector2 bytevector3) procedure
Description

Returns #t if all bytevectors are the same—that is, they have the same length and have equal bytes at all valid indices.

Compatability Note: This is an extension of the procedure in the R6RS Standard Libraries.

11.2.5: bytevector-length

  • (bytevector-length bytevector) procedure
Description

Returns the length of bytevector in bytes as an exact integer.

Examples
(bytevector-length #u8(1 1 2 3 5 8 13 21))8

11.2.6: bytevector-u8-ref

  • (bytevector-u8-ref bytevector k) procedure
Restrictions

It is a domain error if k is not a valid index of bytevector.

Description

Returns the kth byte of bytevector.

Examples
(bytevector-u8-ref #u8(1 1 2 3 5 8 13 21) 5)8

11.2.7: bytevector-u8-set!

  • (bytevector-u8-set! bytevector k byte) procedure
Restrictions

It is a domain error if k is not a valid index of bytevector.

Description

Stores byte as the kth byte of bytevector.

Examples
(let ((bv (bytevector 1 2 3 4)))
  (bytevector-u8-set! bv 1 3)
  bv)#u8(1 3 3 4)

11.3: Bulk bytevector procedures

11.3.1: bytevector-copy

  • (bytevector-copy bytevector [start [end]]) procedure
Description

Returns a newly allocated bytevector containing the bytes in bytevector between start and end.

Examples
(define a #u8(1 2 3 4 5))
(bytevector-copy a 2 4))#u8(3 4)

11.3.2: bytevector-copy!

  • (bytevector-copy! to at from [start [end]]) procedure
Restrictions

It is a domain error if to and from are not bytevectors. It is a domain error if at is less than zero or greater than the length of to. It is a domain error if (- (bytevector-length to) at) is less than (- end start).

Description

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.

Compatability Note: This procedure appears in the R6RS, but places the source before the destination, contrary to other such procedures in Scheme.

Examples
(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)

11.3.3: bytevector-append

  • (bytevector-append bytevector) procedure
Description

Returns a newly allocated bytevector whose elements are the concatenation of the elements in the given bytevectors.

Examples
(bytevector-append #u8(0 1 2) #u8(3 4 5))#u8(0 1 2 3 4 5)

12: Number vectors

Number vectors are homogenous, fixed-length blocks of certain types of numbers. A number vector is typically more efficient than a vector containing numbers of the specified type.

The exact number vectors are

Bytevectors and u8vectors are the same type of object.

The real number vectors are

The complex number vectors are

The inexact number vectors are the real number vectors and complex number vectors.

Number vectors may be written according to the following parameterized grammar:

n
::= s8
::= u8
::= s16
::= u16
::= s32
::= u32
::= s64
::= u64
::= f32
::= f64
::= c64
::= c128
number vector (prefix)
::= #prefix(elements valid for (prefix)

The length of a number vector is the number of elements that it contains. The valid indexes of a number vector are the exact non-negative integers less than the length of the number vector, starting at index zero.

Number vector constants are self-evaluating, so they do not need to be quoted in programs.

For simplicity, n is used in the name of procedures to describe procedures defined for all possible types of number vector.

12.1: Fundamental nvector procedures

12.1.1: make-nvector

  • (make-nvector size [nelem]) procedure
Description

Returns an nvector whose length is size. If nelem is provided, all the elements of the nvector are initialized to it.

Examples
(make-s8vector 5 -1)#s8(-1 -1 -1 -1 -1

12.1.2: nvector

  • (nvector nelem) procedure
Description

Returns a nvector initialized with nelems.

Examples
(f64vector 2.0 4.0)#f64(2.0 4.0)

12.1.3: nvector?

  • (nvector? obj) procedure
Description

Returns #t if obj is an nvector, and #f otherwise.

Examples
(f32vector? #f32(1.0 2.0))
#t
(f64vector? #f32(1.0 2.0))
#f

12.1.4: n?

  • (n? obj) procedure
Description

Returns #t if obj is a valid element of an nvector, and #f otherwise.

Examples
(s8? -128)#t
(s8? (abs -128))#f

12.1.5: nvector-length

  • (nvector-length nvector) procedure
Description

Returns the length of the nvector.

Examples
(u32vector-length #u32(100 200 300))#t

12.1.6: nvector-ref

  • (nvector-length nvector k) procedure
Restrictions

It is a domain error if k is not a valid index of nvector.

Description

Returns the kth element of nvector.

If the number vector is an inexact number vector, then the value returned is the closest inexact number to the stored value.

Examples

This section assumes that the stored c64 numbers can be round-tripped.

(c64vector-ref #c64(1.0+2.0i 3.0+4.0i) 0)1.0+2.0i

12.1.7: nvector-set!

  • (nvector-set! nvector k nelem) procedure
Restrictions

It is a domain error if k is not a valid index of nvector.

Description

Sets the kth element of nvector to be nelem.

For inexact number vectors, the set value in the vector will be the closest value to nelem that the representation allows.

Examples

This section assumes that the stored c64 numbers can be round-tripped.

(let ((v (make-c64vector 2 1.0+1.0i)))
  (c64vector-set! v 0 2.0+2.0i)
  v)#c64(2.0+2.0i 1.0+1.0i)

12.2: Bulk nvector procedures

12.2.1: nvector->list

  • (nvector->list nvector [start [end]]) procedure
Description

Returns a list whose elements are the elements of nvector between start and end.

Examples
(u8vector->list #u8(#xFE #xFF 10 20 30) 2 4)(#xFF 10)

12.2.2: list->nvector

  • (list->nvector list [start [end]]) procedure
Restrictions

It is a domain error if the elements of list between start and end are not allowed elements of an nvector.

Description

Returns a nvector whose elements are the elements of list between start and end.

Examples
(list->u8vector '(#xFE #xFF 10 20 30) 2 4)#u8(#xFF 10)

12.2.3: nvector-append

  • (nector-append nvector) procedure
Description

Returns a newly allocated nvector whose elements are the concatenation of the elements in the given nvectors.

12.2.4: nvector-copy

  • (bytevector-copy nvector [start [end]]) procedure
Description

Returns a newly allocated nvector containing the bytes in nvector between start and end.

12.2.5: nvector-copy!

  • (nvector-copy! to at from [start [end]]) procedure
Restrictions

It is a domain error if to and from are not nvectors. It is a domain error if at is less than zero or greater than the length of to. It is a domain error if (- (nvector-length to) at) is less than (- end start).

Description

Copies the elements of from between start and end to nvector 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 nvector and then into the destination. This can be achieved without allocating storage by making sure to copy in the correct direction in such circumstances.