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 7) containing the description of the values that make up Scheme data, such as pairs, vectors, numbers, and strings.
The major features of this fascicle:
The whole numeric tower is now required (similar to the R6RS).
Infinities, signed zeros, and NaNs are now required.
Underscores in numbers (adapted from SRFI 169).
Fixnum and flonum libraries (SRFI 143 and 144, expanded versions of the libraries in R6RS). More operations will be defined in the Batteries and Environments volumes.
An extended set of division operations (adapted from SRFI 141).
The addition of strictly-real? and other procedures, which have 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.
Hyperbolic functions.
List conversion procedures have been modified to take start and end arguments (SRFI 264). For examples, see list-copy and list->string.
Bitwise operations on integers of arbitrary size (adapted from SRFI 151, an extended version of the library in the R6RS). More operations will be defined in the Batteries.
Full Unicode support. Procedures like char-foldcase and char-upper-case? return values based off of Unicode data. Characters, strings, and symbols must be able to store any Unicode scalar value.
Raw string literals (adapted from SRFI 267).
String-notated bytevectors (SRFI 207).
Unicode decoding procedures such as utf8->string have defined semantics when encountering invalid data.
Type specific number vectors (SRFI 160). More operations will be available in the Batteries.
Raw string literals (section 9.2), the syntax of symbols extended to Unicode (section 7.1), the addition of #\page as a character name (section 8.1), the addition of \f as a mnemonic escape (section 9.1), string-notated bytevectors (section 11.2), the syntax of number vectors (section 12.1)
and support for the #!r6rs lexical mode require changes to the
reader.
Full support for Unicode will require using an internal representation of characters, strings, and symbols that supports all Unicode scalar values.
Support for the full numeric tower will require implementations to support arbitrarily large integers, arbitrarily precise rationals, and both exact and inexact complex numbers.
The error-handling-mode macro cannot be implemented with syntax-rules. It needs a low-level system such as syntax-case (described in the Macrological Fascicle).
Many new procedures, such as the bitwise operations and the fixnum operations, are technically implementable in portable R7RS, but should be implemented as primitives.
Some standard library procedures, such as exact-integer?, require redefinition. Almost all of these redefinitions can be done in portable Scheme.
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 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 integer
exact, non-negative integer
flonum
fixnum
integer flonum
exact, non-negative integer
alphabetic character
list
integer
any object
pair
procedure
rational number
exact, non-negative integer
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 arguments:
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 occurrences 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
There is one exception to the disjointness of number vector types: u8vectors and bytevectors are the same type.
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.
(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.
The following grammar for quasiquote expressions is not context-free. It is presented as a recipe for generating an infinite number of production rules. Imagine a copy of the following rules for D = 1, 2, 3, …, where D is the nesting depth.
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 returns #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 both to a mathematical number and 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, and integer to refer to both mathematical numbers and number objects.
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 are 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 all representable
rationals. Negative infinity is regarded as an inexact real (not rational) that represents
an indeterminate number less than all representable rationals.
The behavior of the procedures in this section 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.
Implementations should support all quiet and signalling NaNs that are available in their inexact number formats, to propagate NaN values in the way that IEEE 754-2019 specifies, and to return the appropriate NaN values when a value cannot be represented. No procedures are supplied that allow the user to inspect a NaN, except for comparing them for equality using eqv?.
Implementation Note: Some implementation strategies, such as NaN boxing, make supporting multiple NaN values difficult.
For implementations that support the whole range of NaN values, SRFI 208 cite has an API for accessing and manipulating NaNs.
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), and 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.
Compatibility 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 number 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).
When a rule ends with R, the rule is implicitly replicated for R equal to 2, 8, 10, and 16. Although not shown below, all alphabetic characters used in the grammar of numbers can appear in either upper or lower case.
Between any two digits of a number, a single underscore may appear.
@⟨real R⟩When the R6RS lexical mode is enabled, the following productions are modified:
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 attempted 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 transcendental 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
A number is rational? if it is
real and if there exist exact integers k1 and k2 such that (= obj (/ k1 k2)). Thus infinities and NaNs
are not rational numbers.
A number is strictly-rational? if it is rational? and strictly-real?.
Returns #t if the object is an integer
object, and #f otherwise. Equivalent to:
(define (integer? obj)
(and (rational? obj)
(= 1 (denominator obj))))
An object is strictly-integer? iff it is strictly-rational? and integer?.
(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
(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
Fixnums are an implementation-defined subset of the exact integers. Every implementation must define its fixnum range as a closed interval , where is an integer greater than or equal to 24. Every mathematical integer within an implementation's fixnum range must correspond to an exact integer that is representable within the implementation. A fixnum is an exact integer whose value lies within this fixnum range. Exact integers outside of the fixnum range are generally called bignums.
Fixnum operations perform integer arithmetic on their fixnum arguments. If any argument is not a fixnum, or if the mathematical result is not representable as a fixnum, it is a domain error: this is known as the fixnum rule.
Fixnum procedures are listed next to generic arithmetic procedures that they are equivalent to. The description of such procedures applies to the fixnum procedures when the generic procedure on two exact integers would produce a number in the fixnum range.
Returns #t if obj is
an exact integer within the fixnum range, and #f otherwise.
Bound to the value that specifies the implementation-defined range.
Note: In the R6RS, fixnum-width is a procedure that always returns this value.
Bound to the value , the largest representable fixnum.
Note: In the R6RS, greatest-fixnum is a procedure that always returns this value.
Bound to the value , the smallest representable fixnum.
Note: In the R6RS, least-fixnum is a procedure that always returns this value.
The flonums are a subset of the inexact real numbers. It is required that all flonums have the same range and precision. When a variable is bound to, or a procedure returns, a mathematical expression, it is understood that the value is the best flonum approximation to the mathematically correct value.This is unrealistic: for example, only Intel's proprietary library has correctly rounded bessel functions. We should change this to an explicit list of procedures that are rounded correctly.
All flonums are radix-2.
If the mathematically correct result of a flonum operation is not a real number, the result is a NaN that is a flonum.
The examples for flonum procedures are written as if all inexact real numbers are flonums for simplicity. For implementations where this is not the case, replace each inexact real constant with flonum applied to that constant, or with whatever implementation specific syntax needed to create a flonum.
Need to be more specific about the flonum behavior of functions with generic arithmetic equivalents, such as sin.
Bound to the largest positive finite flonum.
For example, if flonums are binary64 numbers, then this number is
about 1.7976931348623157e+308.
Bound to the smallest positive finite flonum.
For example, if flonums are binary64 numbers, then this number is
about 4.9406564584124654e-324. This number may be
subnormal.
Bound to the difference between the flonum 1.0 and the least normalized flonum greater than 1.0.
For example, if flonums are binary64 numbers, then this number is
2.220446049250313e-16. This is commonly called the machine epsilon.
If z is not real, returns a NaN. If there is a flonum that is the same (in the sense of =) as z, returns that flonum. If such a flonum does not exist, returns the nearest flonum, where “nearest” is implementation-dependent. If z is exact, applies inexact to z first.
Returns the next representable flonum after fl1 in the direction of fl2.
If fl1 is equal to fl2 (in the sense of =), returns fl2.
If there is no representable flonum in that direction, return the appropriately signed infinity.
Compatibility Note: This procedure corresponds to the nextafter procedure in C, and to the nextUp and nextDown operations in IEEE 754-2019.
(fladjacent 0.0 -0.0)⇒-0.0
(fladjacent -0.0 0.0)⇒0.0
(fladjacent #x1.0p+0 2.0)⇒#x1.0000000000001p+0 ; binary64, uses hex float
(fladjacent fl-greatest +inf.0)⇒+inf.0
(fl=? (fladjacent +inf.0 0.0) fl-greatest)⇒#t
Returns a flonum with the magnitude of fl1 and the sign of fl2.
Compatibility Note: This procedure corresponds to the copysign procedure in C and IEEE 754-2019.
(flcopysign 1.0 2.0)⇒1.0
(flcopysign 1.0 0.0)⇒1.0
(flcopysign 1.0 -0.0)⇒-1.0
(flcopysign +inf.0 -1.0)⇒-inf.0
It is a domain error if n is outside of an implementation dependent range.This should be tightened such that it round-trips with flnormalized-fraction-exponent.
Returns the flonum .
Compatibility Note: This procedure corresponds to the ldexp procedure in C and scaleB in IEEE 754-2019.
Returns two values, the integral part of fl and the fractional part of fl as flonums. Each value has the same sign as the input argument.
If fl is infinite, then the fractional part is the appropriate signed zero, and the integer part is the appropriate signed infinity.
Compatibility Note: This procedure corresponds to the modf procedure in C.
(flinteger-fraction +inf.0)⇒+inf.0 +0.0
(flinteger-fraction -inf.0)⇒-inf.0 -0.0
(flinteger-fraction 1.5)⇒1.0 0.5
Returns the exponent of fl as an integer flonum.
When passed any inexact zero, this procedure returns negative infinity.
When passed infinity, this procedure returns positive infinity.
If the input is subnormal, then the returned value is the exponent if the number were represented mathematically as a normalized number.
Compatibility Note: This procedure corresponds to the logb procedure in C and the logB operation (on floating point formats) in IEEE 754-2019.
(flexponent 1.0)⇒0.0
(flexponent 1e-300)⇒-997.0
(flexponent 0.0)⇒-inf.0
(flexponent -0.0)⇒-inf.0
(flexponent +inf.0)⇒+inf.0
(flexponent -inf.0)⇒+inf.0
If flexponent applied to fl would return an integer flonum, return that integer as an exact integer.
If fl is zero, then fl-integer-exponent-zero is returned. If fl is a NaN, then fl-integer-exponent-nan is returned. If fl is infinite, then an unspecified integer is returned. This value is outside of the range of exponents returned by finite values.
Compatibility Note: This procedure corresponds to the ilogb procedure in C and the logB operation (on integer formats) in IEEE 754-2019.
Returns two values: a correctly signed flonum whose absolute value is in , and an exact integer exponent such that .
When fl is zero, this procedure returns that zero as and 0 as .
When fl is infinite, this procedure returns that infinity as and an unspecified value as .
When fl is a NaN, this procedure returns a NaN as and an unspecified value as .
Compatibility Note: This procedure corresponds to the frexp function in C.
Note: This does not return the mantissa and exponent of
the representation of the number. For example, 4.25 is
represented with a mantissa of 1.0625 and an exponent of 2, but the
mantissa is not between 0.5 and 1 like the description above.
(flnormalized-fraction-exponent 4.25)⇒0.53125 3
Returns 0 for positive flonums and
1 for negative flonums and -0.0. The value
for a NaN is unspecified, but must be a 1 or a 0.
Compatibility Note: This procedure corresponds to the signbit macro in C and the isSignMinus operation in IEEE 754-2019.
(flsign-bit +inf.0)⇒0
(flsign-bit -inf.0)⇒1
(flsign-bit +0.0)⇒0
(flsign-bit -0.0)⇒1
Returns #t if obj
is a flonum and #f otherwise.
Tests whether the flonum is normalized: i.e. if the number is not subnormal, zero, infinite, or NaN.
Compatibility Note: This procedure corresponds to the isnormal macro in C and the isNormal operation in IEEE 754-2019.
Tests whether the flonum is subnormal, i.e. a nonzero number whose magnitude is less than the smallest normal number.
Compatibility Note: This procedure corresponds to the issubnormal macro in C and the isSubnormal operation in IEEE 754-2019. The name is subject to change.
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.
Compatibility 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.3.
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.3.
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 non-decreasing,
monotonically 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 x 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.
Rationale: Because of the fixnum rule, fx+ is not associative. Hence the procedure only takes exactly two arguments.
(+ 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 nonzero finite real number multiplied with an infinite number 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 inexact zero.
Exact zero multiplied with an infinite number returns either exact zero or a NaN.
Rationale: Because of the fixnum rule, fx* is not associative. Hence the procedure only takes exactly two arguments.
(* 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.
Note: For the fixnum equivalent, see fxquotient.
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.
Note: The absolute value of the least fixnum is not a fixnum.
(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, the result must 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
Note: The fxsqrt procedure implements the behavior of exact-integer-sqrt, not sqrt.
(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.
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 the 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 a domain 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 n2 is negative.
The modulo procedure is equivalent to the floor-remainder procedure. It is provided for backwards compatibility.
Returns and such that . Thus a nonzero is negative iff n2 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 compatibility.
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 transcendental 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 logarithm of z1.
The logarithm of positive inexact zero is negative infinity. The logarithm of negative inexact zero is a complex number, whose real part is negative infinity 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
Bitwise operations treat exact integers as infinite two's complement bitstrings. They always return exact integers.
Note: A larger set of bitwise operations will be available in another volume.
Returns the bitwise complement of ei; that is, all 1 bits are changed to 0 bits and all 0 bits to 1 bits.
Note in this evaluation example that the
textual representation of the inverted integer does not look like each
bit was flipped from zero to one. Since exact integers are infinite
bitstrings, it would not be possible to represent all of the bits being
flipped. Instead, the numbers are written with the -
representing two's-complement negation. Hence if one were to apply
two's complement negation to #b1011, one would get the
formal base-2 number 1111…0101, which has the correct bits.
(bitwise-not #b1010)⇒#b-1011
(bitwise-not -37)⇒36
Returns the logical AND of the arguments. That is, the th bit in the returned value is 1 if the th bit in each of the arguments is 1, and 0 otherwise. This operation is associative.
(bitwise-and)⇒-1
(bitwise-and #b1011 #b11010)⇒#b1010
Returns the logical inclusive OR of the arguments. That is, the th bit in the returned value is 0 if the th bit in each of the arguments is 0, and 1 otherwise. This operation is associative.
(bitwise-ior)⇒0
(bitwise-ior 3 10)⇒11
Returns the logical exclusive OR of the arguments. That is, the th bit in the returned value is 1 if the number of arguments with 1 in their th bit is odd, and 0 otherwise. This operation is associative.
(bitwise-xor)⇒0
(bitwise-xor 3 10)⇒9
When ei2 is positive, shift ei1 by ei2 bits to the left. When ei2 is negative, shift ei1 by (- ei2) bits to the right. When zero,
return ei1.
Note: Logical right or left shift operations are excluded because they are not well defined on general integers; they are only defined on integers in some finite range. Integers are interpreted as semi-infinite bit strings that have only a finite number of ones or a finite number of zeros. Logical shifting operates on bit strings of some fixed size. If we shift left, then leftmost bits “fall off” the end (and zeros shift in on the right). If we shift right, then zeros shift into the string on the left (and rightmost bits fall off the end). So to define a logical shift operation, we must specify the size of the window.
(arithmetic-shift 8 2)⇒32
(arithmetic-shift 4 0)⇒4
(arithmetic-shift 8 -1)⇒4
(arithmetic-shift -100000000000000000000000000000000 -100)⇒-79
Returns the number of bits needed to represent
ei. When ei is non-negative, this is
the number of bits needed to represent ei in an
unsigned binary representation. For all ei, (+ 1 (integer-length ei)) is the number of
bits needed to represent ei in a signed two’s-complement
representation.
(integer-length 0)⇒0
(integer-length 1)⇒1
(integer-length -1)⇒0
(integer-length 7)⇒3
(integer-length -7)⇒3
(integer-length 8)⇒4
(integer-length -8)⇒3
When ei is less than 0, return the population count of 0s. Otherwise, return the population count of 1s. The result is always non-negative.
Note: The R6RS analogue bitwise-bit-count applies bitwise-not to the population count before returning it if ei is negative.
(bit-count 0)⇒0
(bit-count -1)⇒0
(bit-count 7)⇒3
;; Two's complement binary: …001101 (bit-count 13)⇒3
;; Two's complement binary: …1110011 (bit-count -13)⇒2
;; Two's complement binary: …0011110 (bit-count 30)⇒4
;; Two's complement binary: …1100010 (bit-count -30)⇒4
(bit-count (expt 2 100))⇒1
(bit-count (- (expt 2 100)))⇒100
(bit-count (- (1+ (expt 2 100))))⇒1
It is a domain error if radix is not 2, 8, 10, or 16.
This procedure takes a number and a radix (defaults
to 10) and returns as a string an external representation
of the given number in the given radix such thatTODO: typesetting in scheme listing
(let ((number z) (radix radix))
(eqv? z
(string->number (number->string z radix)
radix)))
If no possible result makes this expression true, then the implementation raises an implementation restriction.
If z is inexact, the radix is 10, and the above expression can be satisfied by a result that contains a decimal point, then the result contains a decimal point and is expressed using the minimum number of digits (exclusive of exponent and trailing zeroes) needed to make the above expression true todo: citations; otherwise the format of the result is unspecified.
The result returned by number->string never contains an explicit radix prefix.
Note: The error case can occur only when z is not a complex number or is a complex number with a non-rational real or imaginary part.
Rationale: If z is an inexact number and the radix is 10, then the above expression is normally satisfied by a result containing a decimal point. The unspecified case allows for infinities, NaNs, and unusual representations.
Compatibility Note: This procedure takes an optional precision argument in the R6RS.
It is a domain error if radix is not 2, 8, 10, or 16.
Returns a number of the maximally precise representation expressed by the given string.
If supplied, radix is a default radix that will be
overridden if an explicit radix prefix is present in string (e.g. "#o177"). If radix is not supplied, then
the default radix is 10. If string is not a
syntactically valid notation for a number, or would be a rational number with
a zero denominator, then string->number returns
#f. An error is never signaled due to the content of string.
Note: The rules used by a particular implementation for string->number must also be applied to read and to the routine that
reads programs, in order to maintain consistency between internal numeric
processing, I/O, and the processing of programs. As a consequence, the
R5RS permission to return #f when string has an
explicit radix prefix has been withdrawn.
Compatibility Note: The R7RS-Large adopts some of the language of the R6RS for this procedure, because both require the full numeric tower.
(string->number "100")⇒100
(string->number "100" 16)⇒256
(string->number "1e2")⇒100.0
[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
Case is not significant.
When the R6RS lexical mode is enabled, the grammar is:
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 representation of 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 not an 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.
When the R6RS lexical mode is enabled, the following productions are added:
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 are 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 k obj)
(set-car! (list-tail list k) obj))
Returns the length of list.
(length '(a b c))⇒3
(length '(a (b) (c d e)))⇒3
(length '())⇒0
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 end is not given, then 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 obj 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.
Compatibility 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.
Compatibility 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.
Compatibility 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.
The syntax for symbols is the same as the syntax for identifiers.
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 values, 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:
0 and #x10FFFF,
excluding the range #xD800 to #xDFFF⟩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 #\⟨any character⟩, and
in #\⟨character name⟩, but not in
⟨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?
Compatibility 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, but also includes the form feed character due to its common use in source code.
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.txt from 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.
Compatibility Note: The definitions of these procedures come 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. If the argument is not the uppercase member of such a pair, it is returned.
Note: Many Unicode lowercase characters do not have uppercase equivalents. Language-sensitive casing pairs are not used.
(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-foldcase #\i)⇒#\i
(char-foldcase #\ß)⇒#\ß
(char-foldcase #\Σ)⇒#\σ
(char-foldcase #\ς)⇒#\σ
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 char has the Unicode “Alphabetic” property. Otherwise returns #f.
(char-alphabetic? #\a)⇒#t
Returns #t if char has the Unicode “Numeric_Type” property equal to “Decimal”. Otherwise returns #f.
(char-numeric? #\1)⇒#t
Returns #t if char has the Unicode “White_Space” property. Otherwise returns #f.
(char-whitespace? #\space)⇒#t
(char-whitespace? #\x00A0)⇒#t
Returns #t if char has the Unicode “Uppercase” property. Otherwise returns #f.
(char-upper-case? #\Σ)⇒#t
Returns #t if char has the Unicode “Lowercase” property. Otherwise returns #f.
(char-lower-case? #\σ)⇒#t
(char-lower-case? #\x00AA)⇒#t
This procedure returns the numeric value (0 to 9) of its argument if it
is a numeric digit (that is, if char-numeric? returns #t), or #f on any other character.
(digit-value #\3)⇒3
(digit-value #\x0664)⇒4
(digit-value #\x0AE6)⇒0
(digit-value #\x0EA6)⇒#f
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 indices 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.
Compatibility 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+22). Within a string literal, various escape sequences
represent characters other than themselves. Escape sequences always
start with a backslash (\, U+5C):
\a: alarm, U+0007
\b: backspace, U+0008
\t: character tabulation, U+0009
\n: line feed, U+000A
\f: form feed, U+000C
\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.
Compatibility 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 formal account of the syntax is given below.
" and \⟩""⇒""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+0041, 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 represented literally in the string.
The formal grammar of raw strings is not context free. The following grammar describes the creation of a raw string literal for any X produced from ⟨valid delimiter⟩.
"X" as a subsequence, and
does not have "X as a suffix⟩"⟩TODO: generate examples automatically from file
#""""⇒""
#""\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.
Compatibility 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.
Compatibility 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 required.
Compatibility Note: The procedure string-copy 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.
Compatibility 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 is 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 arguments 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
Compatibility 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 "ΧΑΟΣ")⇒"χαος"
(string-downcase "ΧΑΟΣΣ")⇒"χαοσς"
(string-downcase "ΧΑΟΣ Σ")⇒"χαος σ"
(string-foldcase "ΧΑΟΣΣ")⇒"χαοσσ"
(string-upcase "χαος")⇒"ΧΑΟΣ"
(string-upcase "χαοσ")⇒"ΧΑΟΣ"
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=? "ΧΑΟΣ" "χαοσ")⇒#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 code point.
[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.
The following is a formal account of the vector syntax.
When the R6RS lexical mode is enabled, the following production is added to the above grammar.
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 k is 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.
Compatibility 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 in 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 arguments 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.
Compatibility 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 vectors, 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 vectors for its side effects, in order from the first elements to the last. The proc is 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?
Compatibility 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.
When the R6RS lexical mode is enabled, the grammar is modified to be
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 \f represents the integer 12;
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(#x89 #x50 #x4E #x47 #x0D #x0A #x1A #x0A)
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 code point. 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 two's complement representation of that negative number.
Compatibility 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.
Compatibility 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)
If ⟨error-handling-mode symbol⟩ is one of raise, replace, or ignore, then return
that symbol. Only the name of the symbol is significant. If ⟨error-handling-mode symbol⟩ is another symbol, it is
implementation-specified if a symbol with defined semantics is returned,
or if a syntax error is signalled.
The error-handling mode of a transcoder specifies the behavior of textual I/O and conversion operations in the presence of encoding or decoding errors.
If the ⟨error-handling-mode symbol⟩ is raise, then the
procedure will raise an error satisfying i/o-decoding-error?
if invalid text is encountered.
If the ⟨error-handling-mode symbol⟩ is replace,
then the procedure will insert one or more replacement characters in
place of an invalid sequence. When decoding into Scheme characters, or
encoding into UTF-8, the replacement character is U+FFFD. Implementations
should add replacement characters according to the Unicode Standard's
“U+FFFD Substitution of Maximal Subparts,” which is the same method
specified by the W3C.
If the ⟨error-handling-mode symbol⟩ is ignore, then
an encoder/decoder will ignore characters it cannot encode/decode.
Users should note that this may cause security issues.
Predicate for errors raised by procedures that decode bytes in some encoding into Scheme characters.
This procedure returns a bytevector that contains the string between start and end encoded as UTF-8.
Note: Scheme strings can only contain Unicode scalar values. Hence, this procedure never fails.
It is a domain error if error-handling-mode is not supported by error-handling-mode: see section 11.4.1.
This procedure decodes the bytes of bytevector between start and end into a string and returns
it. Invalid sequences are handled according to error-handling-mode, which defaults to raise.
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.
Compatibility 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 homogeneous, 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: unsigned exact integer in the range
s16vector: signed exact integer in the range
u16vector: unsigned exact integer in the range
s32vector: signed exact integer in the range
u32vector: unsigned exact integer in the range
s64vector: signed exact integer in the range
u64vector: unsigned 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.
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.
Number vectors may be written according to the following parameterized grammar:
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. Otherwise the elements are initialized to unspecified elements.
(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))⇒3
⟨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)⇒(10 20)
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(10 20)
⟨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 numbers 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.
A datum is a string representation of certain Scheme data that read parses.
This section sets out the formal syntax of Scheme data. It is based off the formal grammars included in previous sections.
#⟨uinteger 10⟩=⟨datum⟩ lexical syntax#⟨uinteger 10⟩# lexical syntax
The lexical syntax #⟨n⟩=⟨datum⟩ reads the
same as ⟨datum⟩, but also results in ⟨datum⟩ being
labelled by ⟨n⟩. It is a syntax error if ⟨n⟩ is not a sequence of digits.
The lexical syntax #⟨n⟩#
serves as a reference to some object labelled by #⟨n⟩=; the result is the same object as the #⟨n⟩= in the sense of eqv?
(see section 3.1).
Together, these syntaxes permit the notation of structures with shared or circular substructure.
(let ((x (list 'a 'b 'c))) (set-cdr! (cddr x) x) x)⇒#0=(a b c . #0#)
The scope of a datum label is the portion of the outermost datum in which
it appears that is to the right of the label. Consequently, a reference
#⟨n⟩# can occur only after a label
#⟨n⟩=; it is a syntax error to attempt a
forward reference. In addition, it is a syntax error if the reference appears
as the labelled object itself (as in #⟨n⟩=#⟨n⟩#), because the object
labelled by #⟨n⟩= is not well
defined in this case.
This section will be extended in the Bibliothecarial fascicle, when discussing circular syntax in programs and libraries.
This procedure converts external representations of Scheme objects into the objects themselves. That is, it is a parser for the non-terminal ⟨datum⟩ (see section 13.1). It returns the next object parsable from the given textual-input-port, updating textual-input-port to point to the first character past the end of the external representation of the object. If not supplied, textual-input-port defaults to current-input-port.
Implementations may support extended syntax to represent record types or other types that do not have datum representations.
If an end of file is encountered in the input before any characters are found that can begin an object, then an end-of-file object is returned. The port remains open, and further attempts to read will also return an end-of-file object. If an end of file is encountered after the beginning of an object’s external representation, but the external representation is incomplete and therefore not parsable, an error that satisfies read-error? is signaled.
Writes a representation of obj to the given textual-output-port. Strings that appear in the
written representation are enclosed in quotation marks, and within
those strings backslash and quotation mark characters are escaped by
backslashes. Symbols that contain non-ASCII characters are escaped with
vertical lines. Character objects are written using the #\ notation.
If obj contains cycles which would cause an infinite loop using the normal written representation, then at least the objects that form part of the cycle must be represented using datum labels as described in section 13.2. Datum labels must not be used if there are no cycles.
Implementations may support extended syntax to represent record types or other types that do not have datum representations.
The write-shared procedure is the same as write except that shared structure must be written using datum labels for all pairs and vectors that appear more than once in the output.
The write-simple procedure is the same as write except that shared structure is never represented using datum labels. This can cause write-simple to not terminate if obj contains circular structure.
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.
Portions of this document were derived from SRFI 143, 144, and 151, which all have the following copyright notice.citation
Copyright (C) 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.