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, 0 ≤ byte ≤ 255
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 of 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.
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.
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 term number object refers to a Scheme object representing a number. This report uses the types complex, real, rational, andinteger to refer to both mathematical numbers and number objects.[phm]: The term "number object" is confusing and pedantic. It should be removed and the terminology should be reverted back to the R5RS terminology. 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.
Number objects are organized as a corresponding tower of subtypes defined by the predicates number?, complex?, real?, rational?, and integer?; see section 1.6. Integer number objects are also called integer objects.
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 number objects that are known to correspond to a number exactly, and those number objects whose computation involved rounding or other errors. For example, index operations into data structures may need to know the index exactly, as may some 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 number objects. This distinction is orthogonal to the dimension of type.
A number object is exact if it is the value of an exact numerical literal or was derived from exact number objects using only exact operations. Exact number objects correspond to mathematical numbers in the obvious way.
Conversely, a number object is inexact if it is the value of an inexact numerical literal, or was derived from inexact number objects, or was derived using inexact operations. Thus inexactness is contagious.
Exact arithmetic is reliable in the following sense: If exact number objects 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 number objects 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 number objects for the entire tower of subtypes given in section 1.1. Moreover, implementations must support exact integer objects and exact rational number objects 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 real number objects (and therefore the range of inexact integer and rational number objects) to the dynamic range of the flonum format. Furthermore the gaps between the inexact integer objects and rationals are likely to be very large in such an implementation as the limits of this range are approached.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 im- plementations using other representations should match or exceed the precision achievable using these floating-point standards TODO: cite IEEE 754.
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.
TODO: Should we require IEEE 754?
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 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 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 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
[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 X such that
The objects in the car fields of successive pairs of a list are the elements of the list. For example, a two-element list is a pair whose car is the first element and whose cdr is a pair whose car is the second element and whose cdr is the empty list. The length of a list is the number of elements, which is the same as the number of pairs.
The empty list is a special object of its own type. It is not a pair, it has no elements, and its length is zero.
Note: The above definitions imply that all lists have finite length and are terminated by the empty list.
The most general notation (external representation) for
Scheme pairs is the “dotted
” notation (⟨datum1⟩ . ⟨datum2⟩)where ⟨datum1⟩ is the representation of the
value of the car field and ⟨datum2⟩ is the value of the cdr field. For example (4 . 5) is a pair whose car is 4 and whose cdr is 5.
A more streamlined notation can be used for lists: the
elements of the list are simply enclosed in parentheses and
separated by spaces. The empty list is represented by ().
For example,
(a b c d e)and
(a . (b . (c . (d . (e . ())))))are equivalent notations for a list of symbols. The general rule is that, if a dot is followed by an open parenthesis, the dot, open parenthesis, and matching closing parenthesis can be omitted in the external representation.
Note that (4 . 5)is the external representation of a pair, not an expression
that evaluates to a pair. Similarly, the sequence of characters (+ 2 6) is notan external representation of the
integer 8, even though it is an expression (in terms of the procedures
described here) evaluating to the integer 8; rather, it is a syntactic datum
representing a three-element list, the elements of which are the symbol
+ and the integers 2 and 6.[phm]: Derived from the R6RS description.
A chain of pairs not ending in the empty list is called an improper list. Note that an improper list is not a list. The list and dotted notations can be combined to represent improper lists:
(a b c . d)is equivalent to
(a . (b . (c . d)))The length of an improper list is the number of pairs before the non-list cdr. This number may be infinity. The elements of an improper list are the cars of each pair in the list.
Whether a given pair is a list depends upon what is stored in the cdr field. When the set-cdr! procedure is used, an object can be a list one moment and not the next:
(define x (list 'a 'b 'c))
(define y x)y⇒(a b c)
(list? y)⇒#t
(set-cdr! x 4)⇒unspecified
x⇒(a . 4)
(eqv? x y)⇒#t
y⇒(a . 4)
(list? y)⇒#f
(set-cdr! x x)⇒unspecified
(list? x)⇒#f
Within literal expressions and representations of
objects read by the read procedure, the forms '⟨datum⟩, `⟨datum⟩, ,⟨datum⟩, and ,@⟨datum⟩ denote two-element lists whose first
elements are the symbols quote, quasiquote, unquote, and unquote-splicing, respectively. The second element in each case
is ⟨datum⟩. This convention is supported so that arbitrary
Scheme programs can be represented as lists. That is, according to Scheme’s
grammar, every ⟨expression⟩ is also a ⟨datum⟩ (see section TODO). Among other
things, this permits the use of the read procedure to parse
Scheme programs. See section TODO.
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 sl of list such that (C obj (car sl)) returns true. The sublists of list are the non-empty
lists returned by (list-tail list k) for k less than the length of list. If the condition is never satisfied for any sublist,
then #f (not the empty list) is returned.
For memq, eq? is used. For memv, eqv? is used. For member, compare is used if given, otherwise equal? is used.
Compatability Note: The optional argument to member was in SRFI 1 and included in the R7RS-Small. The argument order to compare was unspecified in R7RS-Small, but was in SRFI 1. The R7RS-Large adopts the SRFI 1 behavior.
(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 p of alist such that (C obj (car p)) returns true.. If the condition is never satisfied for any pair,
then #f (not the empty list) is returned.
For assq, eq? is used. For assv, eqv? is used. For assoc, compare is used if given, otherwise equal? is used.
Compatability Note: The optional argument to assoc was in SRFI 1 and included in the R7RS-Small. The argument order to compare was unspecified in R7RS-Small, but was in SRFI 1. The R7RS-Large adopts the SRFI 1 behavior.
(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 S is written as a raw string
using the notation #"⟨delimiter⟩"⟨string data⟩"⟨delimiter⟩", where ⟨string data⟩ is the characters of S; with the restriction that S does not contain "⟨delimiter⟩" as a substring, and does not contain "⟨delimiter⟩ as a suffix. Since the ⟨delimiter⟩ can be freely chosen, any string can be
represented as a raw string with a suitable choice of delimiter. All
characters in S are repesented literally in the string.
#""""⇒""
#""\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 O(n) time, where n 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.
Returns #t if obj is
a bytevector. Otherwise, #f is returned.
It is a domain error if fill, when present, is not in [-128,255].
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. They are:
s8vector: signed exact integer in the range
[-27, 27−1]u8vector: signed exact integer in the range
[0, 28−1]s16vector: signed exact integer in the range
[-215, 215−1]u16vector: signed exact integer in the range
[0, 216−1]s32vector: signed exact integer in the range
[-231, 231−1]u32vector: signed exact integer in the range
[0, 232−1]s64vector: signed exact integer in the range
[-263, 263−1]u64vector: signed exact integer in the range
[0, 264−1]f32vector: TODOf64vector: TODOc64vector: TODOc128vector: TODOBytevectors and u8vectors are the same type of object.
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.
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.
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)