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.
The major features of this fascicle:
Many sections have text adapted from the R6RS.
More examples.
Raw string literals.
List conversion procedures have been modified to take start and end arguments.
The addition of strictly-real? and other procedures, which has the semantics of real?, etc. in the R6RS.
The semantics of real? are now aligned with the intentions of the R7RS's Working Group 1.
Raw string literals will require changes to the reader. Some standard library procedures need redefinition.
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.
Undefined behaviour (and similar phrases such as the behaviour is undefined… is the direct equivalent of “it is an error” in the R7RS-Small and the R6RS. An implementation is allowed to behave in any way at all if instructed to evaluate code with undefined behaviour; however, implementers should be aware of the R6RS's guarantee of safety, a version of which is expected to be applied to the libraries defined by the R7RS-Large, including to situations which involve undefined behaviour.
Unspecified behaviour refers to situations in which the report allows implementations to choose one of a number of behaviours explicitly allowed by the report. Implementations are not required to choose the same option in all circumstances, nor are they required to document their choice.
Implementation-specified behaviour refers to situations in which the report allows implementations to choose between possible behaviours, but does require conforming implementations to document which behaviour they use.
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:
an association list (a list of pairs)
boolean
exact integer,
bytevector
character
exact, non-negative integer
alphabetic character
list
integer
any object
pair
procedure
rational number
string
symbol
thunk
vector
real number
complex number
An ⟨n⟩vector
A valid element to be passed to an⟨n⟩vector
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:
It is a domain error if start is greater than end.
It is a domain error if end is greater than the length of the object.
If start is omitted, it is assumed to be zero.
If end is omitted, it is assumed to be the length of the object. It is a domain error if end is omitted when operating on infinite objects like circular lists.
The index start is always inclusive, and the index end is always exclusive. As an example, consider a string. If start and end are the same, an empty substring is referred to, and if start is zero and end is the length of the string, then the entire string is referred to.
The name ⟨n⟩elem has different meanings for exact number vectors, real number vectors, and complex number vectors.
When ⟨n⟩ is the name for an exact number vector type, it is a domain error if ⟨n⟩elem is not a valid element of that type of number vector. (See section 12.
When ⟨n⟩ is the name for a real number vector type, it is a domain error if ⟨n⟩elem is not an inexact real.
When ⟨n⟩ is the name for a complex number vector type, it is a domain error if ⟨n⟩elem is not an inexact complex number.
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.
No object satisfies more than one of the following predicates:
⟨n⟩vector?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.
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.
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.
'⟨datum⟩ lexical syntax
(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.
'a⇒a
'#(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.
'145932⇒145932
145932⇒145932
'"abc"⇒"abc"
"abc"⇒"abc"
'#\a⇒#\a
#\a⇒#\a
'#(a 10)⇒#(a 10)
#(a 10)⇒#(a 10)
'#u8(64 65)⇒#u8(64 65)
#u8(64 65)⇒#u8(64 65)
'#t⇒#t
#t⇒#t
As noted in section 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!.
`⟨qq template⟩ lexical syntax,⟨expression⟩ lexical syntax,@⟨expression⟩ lexical syntax
“Quasiquote” expressions are useful for constructing a list
or vector structure when some but not all of the desired structure is
known in advance. If no 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
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?.
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
if obj1 and obj2 are both #t or #f.
if obj1 and obj2 are both symbols and are the same symbol according to symbol=? (section 7).
if obj1 and obj2 are both exact numbers and are numerically equal (in the sense of =.
if obj1 and obj2 are both inexact numbers such that they are numerically equal (in the sense of =) and they yield the same results (in the sense of eqv?) when passed as arguments to any other procedure that can be defined as a finite composition of Scheme’s standard arithmetic procedures, provided it does not result in a NaN value.
if obj1 and obj2 are both characters and are the same character according to the char=? procedure (section 8).
if obj1 and obj2 are both the empty list.
if obj1 and obj2 are both pairs, vectors, bytevectors, number vectors, records, or strings that denote the same location in the store (section 1.3).
if obj1 and obj2 are both
procedures that have the same location tag. It may also return #t if the implementation can prove that the two procedures
would behave the same for all arguments, even if they have different
location tags. Note that implementations are not required to make any
particular effort to prove that two procedures have equivalent behavior.
The eqv? procedure return #f:
if obj1 and obj2 are of different types (section 1.1).
if one of obj1 and obj2 is #t but the other is
#f.
if obj1 and obj2 are symbols but are not the same symbol according to the symbol=? procedure (section 7).
if one of obj1 and obj2 is an exact number but the other is an inexact number.
if obj1 and obj2 are both exact numbers and are numerically unequal (in the sense of =).
if obj1 and obj2 are both inexact numbers such that either they are numerically unequal (in the sense of =), or they do not yield the same results (in the sense of eqv?) when passed as arguments to any other procedure that can be defined as a finite composition of Scheme’s standard arithmetic procedures, provided it does not result in a NaN value. As an exception, the behavior of eqv? is unspecified when both obj1 and obj2 are NaN.
if obj1 and obj2 are both characters and the char=? procedure returns #f.
if one of obj1 and obj2 is the empty list but the other is not.
if obj1 and obj2 are pairs, vectors, number vectors, bytevectors, records, or strings that denote distinct locations.
if obj1 and obj2 are procedures that would behave differently (return different values or have different side effects) for some arguments.
(eqv? 'a 'a)⇒#t
(eqv? 'a 'b)⇒#f
(eqv? #\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.
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.
(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
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.
(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
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.
Numbers may be arranged into a tower of subsets in which each level is a subset of the level above it:
number
complex number
real number
rational number
integer
For example, 5 is an integer. Therefore 5 is also a rational, a real, and a complex. The same is true of the number objects that model 5.
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.
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.
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.
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).
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.
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.
[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
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.
(complex? 3+4i)⇒#t
(complex? 3)⇒#t
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?.
(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
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?
(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
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.
(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
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))))
(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
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.
(exact-integer? 32)⇒#t
(exact-integer? 32.0)⇒#f
(exact-integer? 32/5)⇒#f
(exact-integer? "32")⇒#f
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.
(finite? 3)⇒#t
(finite? +inf.0)⇒#f
(finite? 3.0+inf.0i)⇒#f
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.
(infinite? 3)⇒#f
(infinite? +inf.0)⇒#t
(infinite? +nan.0)⇒#f
(infinite? 3.0+inf.0i)⇒#t
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.
(nan? +nan.0)⇒#t
(nan? 32)⇒#f
(nan? +nan.0+5.0i)⇒#t
(nan? 1+2i)⇒#f
(nan? "+nan.0")⇒#f
Test if a number is numerically equal to zero. Equivalent to
(define (zero? z)
(= z 0))
(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
Test if the real number is positive or negative, respectively.
(positive? +inf.0⇒#t
(negative? -inf.0⇒#t
(positive? +nan.0⇒#f
(negative? -0.0⇒#f
Tests whether the argument is even or odd, respectively.
Test for the exactness of a quantity. For any Scheme number, precisely one of these predicates is true.
(exact? 3.0)⇒#f
(exact? #e3.0)⇒#t
(inexact? 3.)⇒#t
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.
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.
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.
(= +inf.0 +inf.0)⇒#t
(= -inf.0 +inf.0)⇒#f
(= -inf.0 -inf.0)⇒#t
(let ((x +nan.0)) (= x x))⇒#f
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.
(max 3 4)⇒4
(max 3.9 4)⇒4.0
(max 1 +inf.0)⇒+inf.0
(min 1 -inf.0)⇒-inf.0
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.
(+ 3 4)⇒7
(+ 3)⇒3
(+)⇒0
(+ +inf.0 +inf.0)⇒+inf.0
(+ 100 +inf.0)⇒+inf.0
(+ -inf.0 +inf.0)⇒+nan.0
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.
(* 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
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.
(- 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
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.
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.
(/ 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
Returns the square of z. Equivalent to (* z z).
(square 42)⇒1764
(square 2.0)⇒4.0
Returns the absolute value of its argument.
(abs -7)⇒7
(abs -inf.0)⇒+inf.0
(abs -0.0)⇒+0.0
Returns the greatest common divisor of the arguments. The result is always non-negative. If zero arguments are passed, return 0.
(gcd 32 -36)⇒4
(gcd)⇒0
Returns the least common multiple of the arguments. The result is always non-negative. If zero arguments are passed, return 1.
(lcm 32 -36)⇒288
(lcm 32.0 -36)⇒288.0
(lcm)⇒1
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 .
(sqrt 9)⇒3
(sqrt -1)⇒+i
Returns two non-negative exact integers and where
(exact-integer-sqrt 4)⇒2 0
(exact-integer-sqrt 5)⇒2 1
These procedures return the numerator or denominator of their argument; the result is computed as if the argument was represented as a fraction in lowest terms. The denominator is always positive. The denominator of 0 is defined to be 1.
(numerator (/ 6 4))⇒3
(denominator (/ 6 4))⇒2
(denominator (inexact (/ 6 4)))⇒2.0
This procedure returns the simplest rational number differing from x by no more than y. A rational
number is
simpler than another rational number if and (in lowest terms) and and .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 is the simplest rational of all.
A pair of operators for computing the integral quotients and remainders from the division of a numerator by a denominator should satisfy the relations
and is an integer.
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 , from which can be uniquely derived by the relation
provided that this choice of induced an satisfying . 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 in terms of the numerator and the denominator .
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
Returns and such that . Thus a nonzero is negative iff n1 is negative.
The modulo procedure is equivalent to the floor-remainder procedure. It is provided for backwards compatability.
Returns and such that . Thus a nonzero 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.
Returns and such that . Thus a nonzero 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.
Returns and such that . The function rounds to the nearest integer, breaking ties by choosing the nearest even integer. Nothing general can be said about the sign of . With the round operator pair, the quotient of +1, 0, or -1 by any non-unit denominator is 0.
If , then . If , then . This division operator pair satisfies the stronger property .
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.
This division operator pair satisfies the property
Rationale: When n2 is for some , this reduces to
This is the interval of integers representable in two’s-complement with bits.
Rationale: A version of these procedures appeared in the R6RS with the names div0-and-mod0, div0, and mod0.
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.
(floor -4.3)⇒-5.0
(floor 3.9)⇒3.0
(floor 3.5)⇒3.0
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.
(ceiling -4.3)⇒-4.0
(ceiling 3.1)⇒4.0
(ceiling 3.5)⇒4.0
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.
(truncate -4.3)⇒-4.0
(truncate 3.1)⇒3.0
(truncate 3.5)⇒3.0
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.
(round -4.3)⇒-4.0
(round 2.5)⇒2.0
(round 3.5)⇒4.0
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.
(round-away -4.3)⇒-4.0
(round-away 2.5)⇒3.0
(round-away 3.5)⇒4.0
In general, the trancendental functions such as log and arcsine are multiply defined.
The value of for non-real is defined in terms of as
where is the angle of specified as
with chosen such that .
With the one-argument version of log defined this way, the values of the two-argument-version of , , , , and the two-argument version of are according to the following formulæ
TODO: citations
The range of 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.
Returns the base-e exponential of z.
(exp -inf.0)⇒0.0
(exp +inf.0)⇒+inf.0
(exp +3.141592653589793116i)⇒-1.0 ; approximately
Returns z1 raised to the power of z2. For nonzero z1, this is 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.
(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
It is a domain error if z1 is exact zero.
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.
(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
Computes the corresponding trigonometric or inverse
trigonometric function. The two-argument version of atan computes (angle (make-rectangular x y).
(atan -inf.0)⇒-1.5707963267948965 ; approximately
(atan +inf.0)⇒1.5707963267948965 ; approximately
Computes the corresponding hyperbolic or inverse hyperbolic functions.
TODO
Returns a complex number whose real part is x1 and whose imaginary part is x2.
Returns the complex number . This procedure may return an inexact number even when given exact arguments.
Returns the complex conjugate of z.
(conjugate 1+2i)⇒1-2i
(conjugate 1+inf.0i)⇒1-inf.0i
(conjugate 1+0.0i)⇒1-0.0i
(conjugate 1)⇒1
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.
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.
Returns the magnitude of z.
(magnitude 3+4i)⇒5 ; approximately
(magnitude (make-polar 1.1 2.2))⇒1.1 ; approximately
Let the complex number z be , where . This procedure returns .
(angle -1.0+0.0i)⇒3.141592653589793116
(angle -1.0-0.0i)⇒-3.141592653589793116
[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
Returns #t if obj
is false, and #f otherwise.
(not #t)⇒#f
(not 3)⇒#f
(not (list 3))⇒#f
(not #f)⇒#t
(not '())⇒#f
(not (list))⇒#f
(not 'nil)⇒#f
Returns #t if obj
is either #t or #f and returns #f otherwise.
(boolean? #f)⇒#t
(boolean? 0)⇒#f
(boolean? ’())⇒#f
Returns #t if all the arguments are either
all #t or all #f.
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 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.
Returns #t if obj is
a pair, and otherwise returns #f.
(pair? '(a . b))⇒#t
(pair? (cons 'a 'b))⇒#t
(pair? '(a b c))⇒#t
(pair? '())⇒#f
(pair? '#(a b))⇒#f
Returns a newly allocated pair whose car is obj1 and whose cdr is obj2 . The pair is guaranteed to be different (in the sense of eqv?) from every existing object.
(cons 'a '())⇒(a)
(cons '(a) '(b c d))⇒((a) b c d)
(cons "a" '(b c))⇒("a" b c)
(cons 'a 3)⇒(a . 3)
(cons '(a b) 'c)⇒((a b) . c)
Returns the car or cdr field of the pair, respectively.[phm]: merged descriptions
(car '(a b c))⇒a
(car '((a) b c d))⇒(a)
(car '(1 . 2))⇒1
(car '())⇒domain error
Store obj in the car or cdr field of pair, respectively.[phm]: merged descriptions
(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
TODO
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.
Returns #t if obj is
the empty list, and otherwise returns #f.
Returns #t if obj is a list. Otherwise, it returns #f. By definition, all
lists have finite length and are terminated by the empty list.
(list? '(a b c))⇒#t
(list? '())⇒#t
(list? '(a . b))⇒#f
(list? '#1=(a . #1#))⇒#f
Returns a newly allocated list of its arguments.
(list 'a (+ 3 4) 'c)⇒(a 7 c)
(list)⇒()
Returns a newly allocated list of k elements. If a second argument is given, then each element is initialized to fill. Otherwise the initial contents of each element is unspecified.
(make-list 2 3)⇒(3 3)
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.
Returns the sublist of list obtained by omitting the first k elements.[phm]: Add share-structure statement?
(list-tail '(a b c d) 2)⇒(c d)
(define (list-tail list k)
(if (zero? k)
list
(list-tail (cdr list) (- k 1))))
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.
Returns the kth element of list.
(list-ref '(a b c d) 2)⇒c
(list-ref '(a b c d) (exact (round 1.8)))⇒c
(define (list-ref list k)
(car (list-tail list k)))
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.
Stores obj in element k of list.
(let ((ls (list 'one 'two 'five!))) (list-set! ls 2 'three) ls)⇒(one two three)
(list-set! '(0 1 2) 1 "oops")⇒domain error
(define (list-set! list obj k)
(set-car! (list-tail list k) obj))
Returns a newly allocated list of its arguments.
(list 'a (+ 3 4) 'c)⇒(a 7 c)
(list)⇒()
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.
(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
Returns a newly allocated list consisting of the elements of list in reverse order.
(reverse '(a b c))⇒(c b a)
(reverse '(a (b c) d (e (f))))⇒((e (f)) d (b c) a)
If neither start or end are given, the it is a domain error if obj is circular.
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.
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.
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.
(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)))⇒unspecifiedeither(1 2)or(2 1)
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.
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.
(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)
The compare, if present, must be a procedure that accepts two arguments and returns one value.
These procedures return the first sublist of list such that ( obj (car )) returns true. The sublists of list are the non-empty
lists returned by (list-tail list ) for 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.
(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)
The compare, if present, must be a procedure that accepts two arguments and returns one value. The alist must be a list of pairs.
These procedures return the first pair of alist such that ( obj (car )) 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.
(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)
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.
Returns #t if obj is
a symbol, and #f otherwise.
(symbol? 'foo)⇒#t
(symbol? (car '(a b)))⇒#t
(symbol? "bar")⇒#f
(symbol? 'nil)⇒#t
(symbol? '())⇒#f
(symbol? #f)⇒#f
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.
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?
(symbol->string 'flying-fish)⇒"flying-fish"
(symbol->string 'Martin)⇒"Martin"
(symbol->string (string->symbol "Malvina"))⇒Malvina
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?
(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
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 a“character” 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.
The grammar of character constants is:
The ⟨R6RS character name⟩s are used instead of the ⟨character name⟩s when the parser is set to R6RS mode.
Case is significant in #\⟨character⟩, and
in #\⟨character name⟩, but not in
#\x⟨hex scalar value⟩. A ⟨character⟩ must be followed by a ⟨delimiter⟩ or by the end of the
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#\backspace#\delete#\escape (#\esc)#\newline (#\linefeed)#\null (#\nul)#\page)#\return#\space#\tab#\vtab)
A character written as #\⟨hex scalar value⟩ is the character associated
with that Unicode scalar value.
[phm]: TODO: how to mark this up?
Returns #t if obj
is a character, or #f otherwise.
Returns the unicode scalar value of char as an exact integer.
(char->integer #\x10FFFF)⇒#x10FFFF
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))
Returns the character associated with the scalar value.
(integer->char 32)⇒#\space
(char->integer (integer->char 5000))⇒5000
(integer->char #xD800)⇒&assertion exception
These procedures return #t if the results
of passing their arguments to char->integer are respectively
equal, monotonically increasing, monotonically decreasing, monotonically
non-decreasing, or monotonically non-increasing.
These predicates are required to be transitive.
(char<? #\z #\ß)⇒#t
(char<? #\z #\Z)⇒#f
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.
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.
(char-upcase #\i)⇒#\I
(char-upcase #\ß)⇒#\ß
(char-upcase #\Σ)⇒#\Σ
(char-upcase #\ς)⇒#\Σ
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.
(char-downcase #\i)⇒#\i
(char-downcase #\ß)⇒#\ß
(char-downcase #\Σ)⇒#\σ
(char-downcase #\ς)⇒#\ς
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.
(char-downcase #\i)⇒#\i
(char-downcase #\ß)⇒#\ß
(char-downcase #\Σ)⇒#\σ
(char-downcase #\ς)⇒#\ς
These procedures are similar to char=?, etc., but operate on the case-folded versions of the characters.
(char-ci<? #\z #\Z)⇒#f
(char-ci=? #\z #\Z)⇒#t
(char-ci=? #\ς #\σ)⇒#t
Returns #t if it has the Unicode “Alphabetic” property. Otherwise returns #f.
char-alphabetic? #\a⇒#t
Returns #t if it has the Unicode “Numeric_Type” property equal to “Decimal”. Otherwise returns #f.
char-alphabetic? #\1⇒#t
Returns #t if it has the Unicode “White_Space” property. Otherwise returns #f.
char-whitespace? #\space⇒#t
char-whitespace? #\x00A0⇒#t
Returns #t if it has the Unicode “Uppercase” property. Otherwise returns #f.
char-uppercase? #\Σ⇒#t
Returns #t if it has the Unicode “Lowercase” property. Otherwise returns #f.
char-lowercase? #\σ⇒#t
char-lowercase? #\x00AA⇒#t
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.
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):
\a: alarm, U+0007
\b: backspace, U+0008
\t: character tabulation, U+0009
\n: line feed, U+000A
\r: return, U+000D
\": double quote, U+0022
\\: backslash, U+005C
\|: vertical line, U+007C
\⟨intraline whitespace⟩⟨line ending⟩⟨intraline whitespace⟩: nothing
\x⟨hex scalar value⟩;: specified character (note the
terminating semicolon)
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.
""⇒""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 exceptionout of range
"\xD800;"⇒&lexical exceptionin excluded range
"A bc"⇒"a\nbc"if no space appears afterA, 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"
Raw strings are an alternative syntax for string literals that do not interpret escape sequences inside of them.
The string is written as a raw string
using the notation #"⟨delimiter⟩"⟨string data⟩"⟨delimiter⟩", where ⟨string data⟩ is the characters of ; with the restriction that 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 are repesented literally in the string.
#""""⇒""
#""\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})"
[phm]: String mutation deprecated?
[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.
[phm]: These are new examples
(make-string 5 #\a)⇒"aaaaa"
(equal? "a" (make-string 1))⇒unspecified
Returns a newly allocated string composed of the arguments.
[phm]: These are new examples
(string)⇒""
(string #\a #\b #\c)⇒"abc"
[phm]: R6RS without integer object vocabulary
Returns the number of characters in the given string as an exact integer.
[phm]: These are new examples
(string-length "")⇒0
(string-length "abc")⇒3
[phm]: R7RS
The k must be a valid index of the string.
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 time, where is the length of the string. Implementers should make this procedure run in constant time.
[phm]: These are new examples
(string-ref "ab" 0)⇒#\a
(string-ref "ab" 1)⇒#\b
(string-ref "ab" 2)⇒&assertion exception
[phm]: R7RS
Returns #t if the strings are the same
length and contain the same characters in the same positions. Otherwise,
the string=? procedure returns #f.
[phm]: These are R6RS and new examples
(string=? "Straße" "Strasse")⇒#f
(string=? "abc" "aBc")⇒#f
[phm]: R6RS
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.
(string<? "z" "ß")⇒#t
(string<? "z" "zz")⇒#t
(string<? "z" "Z")⇒#f
[phm]: R7RS
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.
[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"
[phm]: R7RS with new examples
Returns a newly allocated string whose characters are the concatenation of the characters in the given strings.
(string-append "abc" "def")⇒"abcdef"
(string-append)⇒""
[phm]: R7RS with new examples
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.
(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"
[phm]: R7RS with new examples
The list must be a list of characters.
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.
(list->string '(#\s #\c #\m))⇒"scm"
(list->string '())⇒""
(string->list (list->string '(#\s #\c #\m)))⇒(#\s #\c #\m)
[phm]: R7RS using R6RS wording
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.
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.
(let ((v '())) (string-for-each (lambda (c) (set! v (cons (char->integer c) v))) "abcde") v)⇒(101 100 99 98 97)
[phm]: R7RS with reduced examples
The proc must accept as many characters as there are strings and return a single character.
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.
(string-map (lambda (c) (integer->char (+ 1 (char->integer c)))) "HAL")⇒"IBM"
This library provides access to locale-independent Unicode transformations for strings.
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.
(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σ")⇒"ΧΑΟΣ"
These procedures are similar to string=?, etc., but operate on the case-folded versions of the strings.
(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
[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.
[phm]: R7RS with modified examples
The k must be a valid index of the string.
Stores char in element k of string. There is no requirement for this procedure to execute in constant time.
(define (f) (make-string 3 #*))
(define s (f))
(string-set! s 0 #\?)⇒unspecified
s⇒"?**"
[phm]: Enforce immutablity of string literals?
[phm]: R7RS with new examples
The following must be satisfied:
(and (<= 0 at (string-length to))
(>= (- (string-length to) at) (- end start)))
Copies the characters of string from between start and end to string to, starting at at. The order in which characters are copied is unspecified, except that if the source and destination overlap, copying takes place as if the source is first copied into a temporary string and then into the destination. This can be achieved without allocating storage by making sure to copy in the correct direction in such circumstances.
(define a 12345)
(define b (string-copy "abcde"))
(string-copy! b 1 a 0 2)
b⇒"a12de"
[phm]: R7RS with new examples
The fill must be a character.
Stores fill in the elements of string between start and end.
(define s (string-copy "hello world"))
(string-fill! s #c 6)
s⇒"hello ccccc"
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.
Returns #t if obj
is a vector; otherwise returns #f.
(vector? '#())⇒#t
(vector? '(vector 1 2 3))⇒#f
(vector? '#(1 2 3))⇒#t
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.
(make-vector 3 0)⇒#(0 0 0)
Returns a newly allocated vector whose elements are the given arguments. It is analogous to list.
(vector 'a 'b 'c)⇒#(a b c)
Returns the number of elements in vector as an exact integer.
(vector-length '#())⇒0
(vector-length '#(a b c))⇒3
It is a domain error if k is not a valid index of vector.
Returns the contents of the element k of the vector.
(vector-ref '#(1 1 2 3 5 8 13 21) 5)⇒8
(vector-ref '#(1 1 2 3 5 8 13 21) (exact (round (* 2 (acos -1)))))⇒13
It is a domain error if kis not a valid index of vector.
Stores obj in element k of vector.
(let ((vec (vector 0 '(2 2 2 2) "Anna"))) (vector-set! vec 1 '("Sue" "Sue")) vec)⇒#(0 ("Sue" "Sue") "Anna")
(vector-set! '#(0 1 2) 1 "doe")⇒domain error
Returns a newly allocated list of objects contained of vector between start and end. Order is preserved.
(vector->list '#(dah dah didah))⇒(dah dah didah)
(vector->list '#(dah dah didah) 1 2)⇒(dah)
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.
(list->vector '(dididit dah))⇒#(dididit dah)
It is a domain error if any element of vector between start and end is not a character.
Returns a newly allocated string of the characters of vector between start and end. Order is preserved.
(vector->string '#(#\1 #\2 #\3)⇒"123"
Returns a newly created vector initialized to the characters of string between start and end. Order is preserved.
(string->vector "ABC")⇒#(#\A #\B #\C)
Returns a newly allocated copy of the elements of the given vector between start and end. The elements of the new vector are the same (in the sense of eqv?) as the elements of the old.
(define a #(1 8 2 8)) ; a may be immutable
(define b (vector-copy a)) ; b is mutable
(vector-set! b 0 3)⇒unspecified
(define c (vector-copy b 1 3))
c⇒#(8 2)
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).
Copies the elements of vector from between start and end to vector to, starting at at. The order in which elements are copied is unspecified, except that if the source and destination overlap, copying takes place as if the source is first copied into a temporary vector and then into the destination. This can be achieved without allocating storage by making sure to copy in the correct direction in such circumstances.
(define a (vector 1 2 3 4 5))
(define b (vector 10 20 30 40 50))
(vector-copy! b 1 a 0 2)⇒unspecified
b⇒#(10 1 2 40 50)
Returns a newly allocated vector whose elements are the concatenation of the elements of the given vectors.
(vector-append #(a b c) #(d e f))⇒#(a b c d e f)
Stores fill in the elements of vector between start and end.
(define a (vector 1 2 3 4 5))
(vector-fill! a 'smash 2 4)⇒unspecified
a⇒#(1 2 smash smash 5)
The proc must accept as many values as there are vectors and return a single value.
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.
(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)))⇒unspecifiedeither#(1 2)or#(2 1)
[phm]: R6RS with some R7RS
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.
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.
(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)
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
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.
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:
" or \⟩"\\⟨intraline whitespace⟩⟨line ending⟩⟨intraline whitespace⟩Within the contents of a string-notated bytevector:
the sequence \" represents the integer 34;
the sequence \\ represents the integer 92;
the sequence \a represents the integer 7;
the sequence \b represents the integer 8;
the sequence \t represents the integer 9;
the sequence \n represents the integer 10;
the sequence \r represents the integer 13;
the sequence \| represents the integer 124;
the sequence \x followed by zero or more 0 characters, followed by one or two hexadecimal digits, followed by ; represents the integer specified by the hexadecimal digits;
the sequence \ followed by zero or more intraline whitespace characters, followed by a newline, followed by zero or more further intraline whitespace characters, is ignored and corresponds to no entry in the resulting bytevector;
any other printable ASCII character represents the character number of that character in the ASCII/Unicode code chart.
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.
Returns #t if obj is
a bytevector. Otherwise, #f is returned.
It is a domain error if fill, when present, is not in .
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.
(make-bytevector 2 12)⇒#u8(12 12)
Returns a newly allocated bytevector whose elements are the given arguments. It is analogous to list.
(bytevector 1 3 5 1 3 5)⇒#u8(1 3 5 1 3 5)
(bytevector)⇒#u8()
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.
Returns the length of bytevector in bytes as an exact integer.
(bytevector-length #u8(1 1 2 3 5 8 13 21))⇒8
It is a domain error if k is not a valid index of bytevector.
Returns the kth byte of bytevector.
(bytevector-u8-ref #u8(1 1 2 3 5 8 13 21) 5)⇒8
It is a domain error if k is not a valid index of bytevector.
Stores byte as the kth byte of bytevector.
(let ((bv (bytevector 1 2 3 4))) (bytevector-u8-set! bv 1 3) bv)⇒#u8(1 3 3 4)
Returns a newly allocated bytevector containing the bytes in bytevector between start and end.
(define a #u8(1 2 3 4 5))
(bytevector-copy a 2 4))⇒#u8(3 4)
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)
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.
(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)
Returns a newly allocated bytevector whose elements are the concatenation of the elements in the given bytevectors.
(bytevector-append #u8(0 1 2) #u8(3 4 5))⇒#u8(0 1 2 3 4 5)
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
s8vector: signed exact integer in the range
u8vector: signed exact integer in the range
s16vector: signed exact integer in the range
u16vector: signed exact integer in the range
s32vector: signed exact integer in the range
u32vector: signed exact integer in the range
s64vector: signed exact integer in the range
u64vector: signed exact integer in the range
Bytevectors and u8vectors are the same type of object.
The real number vectors are
f32vector: inexact real numbers represented
as IEEE-754 binary32f64vector: inexact real numbers represented
as IEEE-754 binary64The complex number vectors are
c64vector: inexact complex numbers
represented as two IEEE-754 binary32sc128vector: inexact complex numbers
represented as two IEEE-754 binary64sThe inexact number vectors are the real number vectors and complex number vectors.
Number vectors may be written according to the following parameterized grammar:
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.
make-⟨n⟩vectorReturns an ⟨n⟩vector whose length is size. If ⟨n⟩elem is provided, all the elements of the ⟨n⟩vector are initialized to it.
(make-s8vector 5 -1)⇒#s8(-1 -1 -1 -1 -1
⟨n⟩vectorReturns a ⟨n⟩vector initialized with ⟨n⟩elems.
(f64vector 2.0 4.0)⇒#f64(2.0 4.0)
⟨n⟩vector?
Returns #t if obj
is an ⟨n⟩vector, and #f otherwise.
(f32vector? #f32(1.0 2.0))⇒
#t(f64vector? #f32(1.0 2.0))⇒
#f⟨n⟩?
Returns #t if obj
is a valid element of an ⟨n⟩vector, and #f otherwise.
(s8? -128)⇒#t
(s8? (abs -128))⇒#f
⟨n⟩vector-lengthReturns the length of the ⟨n⟩vector.
(u32vector-length #u32(100 200 300))⇒#t
⟨n⟩vector-refIt is a domain error if k is not a valid index of ⟨n⟩vector.
Returns the kth element of ⟨n⟩vector.
If the number vector is an inexact number vector, then the value returned is the closest inexact number to the stored value.
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
⟨n⟩vector-set!It is a domain error if k is not a valid index of ⟨n⟩vector.
Sets the kth element of ⟨n⟩vector to be ⟨n⟩elem.
For inexact number vectors, the set value in the vector will be the closest value to ⟨n⟩elem that the representation allows.
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)
⟨n⟩vector->listReturns a list whose elements are the elements of ⟨n⟩vector between start and end.
(u8vector->list #u8(#xFE #xFF 10 20 30) 2 4)⇒(#xFF 10)
list->⟨n⟩vectorIt is a domain error if the elements of list between start and end are not allowed elements of an ⟨n⟩vector.
Returns a ⟨n⟩vector whose elements are the elements of list between start and end.
(list->u8vector '(#xFE #xFF 10 20 30) 2 4)⇒#u8(#xFF 10)
⟨n⟩vector-appendReturns a newly allocated ⟨n⟩vector whose elements are the concatenation of the elements in the given ⟨n⟩vectors.
⟨n⟩vector-copyReturns a newly allocated ⟨n⟩vector containing the bytes in ⟨n⟩vector between start and end.
⟨n⟩vector-copy!
It is a domain error if to and
from are not ⟨n⟩vectors. It is a domain error if at is less than zero or greater than the length of
to. It is a domain error if (- (⟨n⟩vector-length to) at) is less than (- . end start)
Copies the elements of from between start and end to ⟨n⟩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 ⟨n⟩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.
We intend this report to belong to the entire Scheme community, and so we grant permission to copy it in whole or in part without fee. In particular, we encourage implementers of Scheme to use this report as a starting point for manuals and other documentation, modifying it as necessary.
Some parts of this document are derived from sources with other licenses.
Portions of this document were derived from SRFI 207.citation
© 2020 Daphne Preston-Kendal, John Cowan, and Wolfgang Corcoran-Mathe.
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice (including the next paragraph) shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Portions of this document were derived from SRFI 141.citation
Copyright (C) Taylor Campbell, John Cowan (2016). All Rights Reserved.
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice (including the next paragraph) shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.