Base library

This chapter describes Scheme’s (rnrs base (6))library, which exports many of the procedure and syntax bindings that are traditionally associated with Scheme.

Section 11.20 defines the rules that identify tail calls and tail contexts in constructs from the (rnrs base (6)) library.

11.1  Base types

No object satisfies more than one of the following predicates:

boolean?          pair?
symbol?           number?
char?             string?
vector?           procedure?
null?

These predicates define the base types boolean, pair, symbol, number, char (or character), string, vector, and procedure. Moreover, the empty list is a special object of its own type.

Note that, although there is a separate boolean type, any Scheme value can be used as a boolean value for the purpose of a conditional test; see section 5.7.

11.2  Definitions

Definitionsmay appear within a <top-level body> (section 8.1), at the top of a <library body> (section 7.1), or at the top of a <body> (section 11.3).

A <definition> may be a variable definition (section 11.2.1) or keyword definition (section 11.2.1). Macro uses that expand into definitions or groups of definitions (packaged in a begin, let-syntax, or letrec-syntax form; see section 11.4.7) may also appear wherever other definitions may appear.

11.2.1  Variable definitions

The define form described in this section is a <definition>used to create variable bindings and may appear anywhere other definitions may appear.

(define <variable> <expression>)    syntax 
(define <variable>)    syntax 
(define (<variable> <formals>) <body>)    syntax 
(define (<variable> . <formal>) <body>)    syntax 

The first from of define binds <variable> to a new location before assigning the value of <expression> to it.

(define add3
  (lambda (x) (+ x 3)))
(add3 3)                                    ⇒  6
(define first car)
(first ’(1 2))                              ⇒  1

The continuation of <expression> should not be invoked more than once.

Implementation responsibilities: Implementations should detect that the continuation of <expression> is invoked more than once. If the implementation detects this, it must raise an exception with condition type &assertion.

The second form of define is equivalent to

(define <variable> <unspecified>)

where <unspecified> is a side-effect-free expression returning an unspecified value.

In the third form of define, <formals> must be either a sequence of zero or more variables, or a sequence of one or more variables followed by a dot . and another variable (as in a lambda expression, see section 11.4.2). This form is equivalent to

(define <variable>
  (lambda (<formals>) <body>)).

In the fourth form of define, <formal> must be a single variable. This form is equivalent to

(define <variable>
  (lambda <formal> <body>)).

11.2.2  Syntax definitions

The define-syntax form described in this section is a <definition>used to create keyword bindings and may appear anywhere other definitions may appear.

(define-syntax <keyword> <expression>)    syntax 

Binds <keyword> to the value of <expression>, which must evaluate, at macro-expansion time, to a transformer. Macro transformers can be created using the syntax-rules and identifier-syntax forms described in section 11.19. See library section on “Transformers” for a more complete description of transformers.

Keyword bindings established by define-syntax are visible throughout the body in which they appear, except where shadowed by other bindings, and nowhere else, just like variable bindings established by define. All bindings established by a set of definitions, whether keyword or variable definitions, are visible within the definitions themselves.

Implementation responsibilities: The implementation should detect if the value of <expression> cannot possibly be a transformer.

Example:

(let ()
  (define even?
    (lambda (x)
      (or (= x 0) (odd? (- x 1)))))
  (define-syntax odd?
    (syntax-rules ()
      ((odd?  x) (not (even? x)))))
  (even? 10))                               ⇒ #t

An implication of the left-to-right processing order (section 10) is that one definition can affect whether a subsequent form is also a definition.

Example:

(let ()
  (define-syntax bind-to-zero
    (syntax-rules ()
      ((bind-to-zero id) (define id 0))))
  (bind-to-zero x)
  x)         ⇒ 0

The behavior is unaffected by any binding for bind-to-zero that might appear outside of the let expression.

11.3  Bodies and sequences

The <body> of a lambda, let, let*, let-values, let*-values, letrec, letrec* expression or that of a definition with a body consists of zero or more definitions followed by one or more expressions.

<definition> ... <expression1> <expression2> ...

Each identifier defined by a definition is local to the <body>. That is, the identifier is bound, and the region of the binding is the entire <body> (see section 5.2).

Example:

(let ((x 5))
  (define foo (lambda (y) (bar x y)))
  (define bar (lambda (a b) (+ (* a b) a)))
  (foo (+ x 3)))                        ⇒  45

When begin, let-syntax, or letrec-syntax forms occur in a body prior to the first expression, they are spliced into the body; see section 11.4.7. Some or all of the body, including portions wrapped in begin, let-syntax, or letrec-syntax forms, may be specified by a macro use (see section 9.2).

An expanded <body> (see chapter 10) containing variable definitions can always be converted into an equivalent letrec* expression. For example, the let expression in the above example is equivalent to

(let ((x 5))
  (letrec* ((foo (lambda (y) (bar x y)))
            (bar (lambda (a b) (+ (* a b) a))))
    (foo (+ x 3))))

11.4  Expressions

The entries in this section describe the expressions of the (rnrs base (6)) library, which may occur in the position of the <expression> syntactic variable in addition to the primitive expression types as described in section 9.1.

11.4.1  Quotation

(quote <datum>)    syntax 

Syntax: <Datum> should be a syntactic datum.

Semantics: (quote <datum>) evaluates to the datum value represented by <datum> (see section 4.3). This notation is used to include constants.

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

As noted in section 4.3.5, (quote <datum>) may be abbreviated as <datum>:

’"abc"                       ⇒  "abc"
’145932                      ⇒  145932
’a                           ⇒  a
’#(a b c)                   ⇒  #(a b c)
’()                          ⇒  ()
’(+ 1 2)                     ⇒  (+ 1 2)
’(quote a)                   ⇒  (quote a)
’’a                          ⇒  (quote a)

As noted in section 5.10, constants are immutable.

Note:   Different constants that are the value of a quote expression may share the same locations.

11.4.2  Procedures

(lambda <formals> <body>)    syntax 

Syntax: <Formals> must be a formal parameter list as described below, and <body> must be as described in section 11.3.

Semantics: A lambda expression evaluates to a procedure. The environment in effect when the lambda expression is evaluated is remembered as part of the procedure. When the procedure is later called with some arguments, the environment in which the lambda expression was evaluated is extended by binding the variables in the parameter list to fresh locations, and the resulting argument values are stored in those locations. Then, the expressions in the body of the lambda expression (which may contain definitions and thus represent a letrec* form, see section 11.3) are evaluated sequentially in the extended environment. The results of the last expression in the body are returned as the results of the procedure call.

(lambda (x) (+ x x))              ⇒  a procedure
((lambda (x) (+ x x)) 4)          ⇒  8

((lambda (x)
   (define (p y)
     (+ y 1))
   (+ (p x) x))
 5)         ⇒ 11

(define reverse-subtract
  (lambda (x y) (- y x)))
(reverse-subtract 7 10)                 ⇒  3

(define add4
  (let ((x 4))
    (lambda (y) (+ x y))))
(add4 6)                                ⇒  10

<Formals> must have one of the following forms:

((lambda x x) 3 4 5 6)                  ⇒  (3 4 5 6)
((lambda (x y . z) z)
 3 4 5 6)                               ⇒  (5 6)

Any <variable> must not appear more than once in <formals>.

11.4.3  Conditionals

(if <test> <consequent> <alternate>)    syntax 
(if <test> <consequent>)    syntax 

Syntax: <Test>, <consequent>, and <alternate> must be expressions.

Semantics: An if expression is evaluated as follows: first, <test> is evaluated. If it yields a true value(see section 5.7), then <consequent> is evaluated and its values are returned. Otherwise <alternate> is evaluated and its values are returned. If <test> yields #f and no <alternate> is specified, then the result of the expression is unspecified.

(if (> 3 2) ’yes ’no)                   ⇒  yes
(if (> 2 3) ’yes ’no)                   ⇒  no
(if (> 3 2)
    (- 3 2)
    (+ 3 2))                            ⇒  1
(if #f #f)                            ⇒ unspecified

The <consequent> and <alternate> expressions are in tail context if the if expression itself is; see section 11.20.

11.4.4  Assignments

(set! <variable> <expression>)    syntax 

<Expression> is evaluated, and the resulting value is stored in the location to which <variable> is bound. <Variable> must be bound either in some regionenclosing the set! expression or at the top level. The result of the set! expression is unspecified.

(let ((x 2))
  (+ x 1)
  (set! x 4)
  (+ x 1))         ⇒  5

It is a syntax violation if <variable> refers to an immutable binding.

Note:   The identifier set! is exported with level 1 as well. See section 11.19.

11.4.5  Derived conditionals

(cond <cond clause1> <cond clause2> ...)    syntax 
=>    auxiliary syntax 
else    auxiliary syntax 

Syntax: Each <cond clause> must be of the form

(<test> <expression1...)

where <test> is an expression. Alternatively, a <cond clause> may be of the form

(<test> => <expression>)

The last <cond clause> may be an “else clause”, which has the form

(else <expression1> <expression2...).

Semantics: A cond expression is evaluated by evaluating the <test> expressions of successive <cond clause>s in order until one of them evaluates to a true value(see section 5.7). When a <test> evaluates to a true value, then the remaining <expression>s in its <cond clause> are evaluated in order, and the results of the last <expression> in the <cond clause> are returned as the results of the entire cond expression. If the selected <cond clause> contains only the <test> and no <expression>s, then the value of the <test> is returned as the result. If the selected <cond clause> uses the => alternate form, then the <expression> is evaluated. Its value must be a procedure. This procedure should accept one argument; it is called on the value of the <test> and the values returned by this procedure are returned by the cond expression. If all <test>s evaluate to #f, and there is no else clause, then the conditional expression returns unspecified values; if there is an else clause, then its <expression>s are evaluated, and the values of the last one are returned.

(cond ((> 3 2) ’greater)
      ((< 3 2) ’less))                 ⇒  greater

(cond ((> 3 3) ’greater)
      ((< 3 3) ’less)
      (else ’equal))                    ⇒  equal

(cond (’(1 2 3) => cadr)
      (else #f))                 ⇒  2

For a <cond clause> of one of the following forms

(<test> <expression1...)
(else <expression1> <expression2...)

the last <expression> is in tail context if the cond form itself is. For a <cond clause> of the form

(<test> => <expression>)

the (implied) call to the procedure that results from the evaluation of <expression> is in a tail context if the cond form itself is. See section 11.20.

A sample definition of cond in terms of simpler forms is in appendix B.

(case <key> <case clause1> <case clause2> ...)    syntax 

Syntax: <Key> must be an expression. Each <case clause> must have one of the following forms:

((<datum1...) <expression1> <expression2...)
(else <expression1> <expression2...)

The second form, which specifies an “else clause”, may only appear as the last <case clause>. Each <datum> is an external representation of some object. The data represented by the <datum>s need not be distinct.

Semantics: A case expression is evaluated as follows. <Key> is evaluated and its result is compared using eqv? (see section 11.5) against the data represented by the <datum>s of each <case clause> in turn, proceeding in order from left to right through the set of clauses. If the result of evaluating <key> is equivalent to a datum of a <case clause>, the corresponding <expression>s are evaluated from left to right and the results of the last expression in the <case clause> are returned as the results of the case expression. Otherwise, the comparison process continues. If the result of evaluating <key> is different from every datum in each set, then if there is an else clause its expressions are evaluated and the results of the last are the results of the case expression; otherwise the case expression returns unspecified values.

(case (* 2 3)
  ((2 3 5 7) ’prime)
  ((1 4 6 8 9) ’composite))             ⇒  composite
(case (car ’(c d))
  ((a) ’a)
  ((b) ’b))                             ⇒  unspecified
(case (car ’(c d))
  ((a e i o u) ’vowel)
  ((w y) ’semivowel)
  (else ’consonant))                    ⇒  consonant

The last <expression> of a <case clause> is in tail context if the case expression itself is; see section 11.20.

(and <test1> ...)    syntax 

Syntax: The <test>s must be expressions.

Semantics: If there are no <test>s, #t is returned. Otherwise, the <test> expressions are evaluated from left to right until a <test> returns #f or the last <test> is reached. In the former case, the and expression returns #f without evaluating the remaining expressions. In the latter case, the last expression is evaluated and its values are returned.

(and (= 2 2) (> 2 1))                   ⇒  #t
(and (= 2 2) (< 2 1))                   ⇒  #f
(and 1 2 ’c ’(f g))                     ⇒  (f g)
(and)                                   ⇒  #t

The and keyword could be defined in terms of if using syntax-rules (see section 11.19) as follows:

(define-syntax and
  (syntax-rules ()
    ((and) #t)
    ((and test) test)
    ((and test1 test2 ...)
     (if test1 (and test2 ...) #f))))

The last <test> expression is in tail context if the and expression itself is; see section 11.20.

(or <test1> ...)    syntax 

Syntax: The <test>s must be expressions.

Semantics: If there are no <test>s, #f is returned. Otherwise, the <test> expressions are evaluated from left to right until a <test> returns a true value val (see section 5.7) or the last <test> is reached. In the former case, the or expression returns val without evaluating the remaining expressions. In the latter case, the last expression is evaluated and its values are returned.

(or (= 2 2) (> 2 1))                    ⇒  #t
(or (= 2 2) (< 2 1))                    ⇒  #t
(or #f #f #f)         ⇒  #f
(or ’(b c) (/ 3 0))                     ⇒  (b c)

The or keyword could be defined in terms of if using syntax-rules (see section 11.19) as follows:

(define-syntax or
  (syntax-rules ()
    ((or) #f)
    ((or test) test)
    ((or test1 test2 ...)
     (let ((x test1))
       (if x x (or test2 ...))))))

The last <test> expression is in tail context if the or expression itself is; see section 11.20.

11.4.6  Binding constructs

The binding constructs described in this section create local bindings for variables that are visible only in a delimited region. The syntax of the constructs let, let*, letrec, and letrec* is identical, but they differ in the regions(see section 5.2) they establish for their variable bindings and in the order in which the values for the bindings are computed. In a let expression, the initial values are computed before any of the variables become bound; in a let* expression, the bindings and evaluations are performed sequentially. In a letrec or letrec* expression, all the bindings are in effect while their initial values are being computed, thus allowing mutually recursive definitions. In a letrec expression, the initial values are computed before being assigned to the variables; in a letrec*, the evaluations and assignments are performed sequentially.

In addition, the binding constructs let-values and let*-values generalize let and let* to allow multiple variables to be bound to the results of expressions that evaluate to multiple values. They are analogous to let and let* in the way they establish regions: in a let-values expression, the initial values are computed before any of the variables become bound; in a let*-values expression, the bindings are performed sequentially.

(let <bindings> <body>)    syntax 

Syntax: <Bindings> must have the form

((<variable1> <init1>) ...),

where each <init> is an expression, and <body> is as described in section 11.3. Any variable must not appear more than once in the <variable>s.

Semantics: The <init>s are evaluated in the current environment (in some unspecified order), the <variable>s are bound to fresh locations holding the results, the <body> is evaluated in the extended environment, and the values of the last expression of <body> are returned. Each binding of a <variable> has <body> as its region.

(let ((x 2) (y 3))
  (* x y))                              ⇒  6

(let ((x 2) (y 3))
  (let ((x 7)
        (z (+ x y)))
    (* z x)))                           ⇒  35

See also named let, section 11.16.

(let* <bindings> <body>)    syntax 

Syntax: <Bindings> must have the form

((<variable1> <init1>) ...),

where each <init> is an expression, and <body> is as described in section 11.3.

Semantics: The let* form is similar to let, but the <init>s are evaluated and bindings created sequentially from left to right, with the regionof each binding including the bindings to its right as well as <body>. Thus the second <init> is evaluated in an environment in which the first binding is visible and initialized, and so on.

(let ((x 2) (y 3))
  (let* ((x 7)
         (z (+ x y)))
    (* z x)))                     ⇒  70

Note:   While the variables bound by a let expression must be distinct, the variables bound by a let* expression need not be distinct.

The let* keyword could be defined in terms of let using syntax-rules (see section 11.19) as follows:

A sample definition of let* in terms of simpler forms is in appendix B.

(letrec <bindings> <body>)    syntax 

Syntax: <Bindings> must have the form

((<variable1> <init1>) ...),

where each <init> is an expression, and <body> is as described in section 11.3. Any variable must not appear more than once in the <variable>s.

Semantics: The <variable>s are bound to fresh locations, the <init>s are evaluated in the resulting environment (in some unspecified order), each <variable> is assigned to the result of the corresponding <init>, the <body> is evaluated in the resulting environment, and the values of the last expression in <body> are returned. Each binding of a <variable> has the entire letrec expression as its region, making it possible to define mutually recursive procedures.

(letrec ((even?
          (lambda (n)
            (if (zero? n)
                #t
                (odd? (- n 1)))))
         (odd?
          (lambda (n)
            (if (zero? n)
                #f
                (even? (- n 1))))))
  (even? 88))   
                        ⇒  #t

It should be possible to evaluate each <init> without assigning or referring to the value of any <variable>. In the most common uses of letrec, all the <init>s are lambda expressions and the restriction is satisfied automatically. Another restriction is that the continuation of each <init> should not be invoked more than once.

Implementation responsibilities: Implementations must detect references to a <variable> during the evaluation of the <init> expressions (using one particular evaluation order and order of evaluating the <init> expressions). If an implementation detects such a violation of the restriction, it must raise an exception with condition type &assertion. Implementations may or may not detect that the continuation of each <init> is invoked more than once. However, if the implementation detects this, it must raise an exception with condition type &assertion.

A sample definition of letrec in terms of simpler forms is in appendix B.

(letrec* <bindings> <body>)    syntax 

Syntax: <Bindings> must have the form

((<variable1> <init1>) ...),

where each <init> is an expression, and <body> is as described in section 11.3. Any variable must not appear more than once in the <variable>s.

Semantics: The <variable>s are bound to fresh locations, each <variable> is assigned in left-to-right order to the result of evaluating the corresponding <init>, the <body> is evaluated in the resulting environment, and the values of the last expression in <body> are returned. Despite the left-to-right evaluation and assignment order, each binding of a <variable> has the entire letrec* expression as its region, making it possible to define mutually recursive procedures.

(letrec* ((p
           (lambda (x)
             (+ 1 (q (- x 1)))))
          (q
           (lambda (y)
             (if (zero? y)
                 0
                 (+ 1 (p (- y 1))))))
          (x (p 5))
          (y x))
  y)
                        ⇒  5

It must be possible to evaluate each <init> without assigning or referring to the value of the corresponding <variable> or the <variable> of any of the bindings that follow it in <bindings>. Another restriction is that the continuation of each <init> should not be invoked more than once.

Implementation responsibilities: Implementations must detect references to a <variable> during the evaluation of the <init> expressions (using one particular evaluation order). If an implementation detects such a violation of the restriction, it must raise an exception with condition type &assertion. Implementations may or may not detect that the continuation of each <init> is invoked more than once. However, if the implementation detects this, it must raise an exception with condition type &assertion.

(let-values <mv-bindings> <body>)    syntax 

Syntax: <Mv-bindings> must have the form

((<formals1> <init1>) ...),

where each <init> is an expression, and <body> is as described in section 11.3. Any variable must not appear more than once in the set of <formals>.

Semantics: The <init>s are evaluated in the current environment (in some unspecified order), and the variables occurring in the <formals> are bound to fresh locations containing the values returned by the <init>s, where the <formals> are matched to the return values in the same way that the <formals> in a lambda expression are matched to the arguments in a procedure call. Then, the <body> is evaluated in the extended environment, and the values of the last expression of <body> are returned. Each binding of a variable has <body> as its region.If the <formals> do not match, an exception with condition type &assertion is raised.

(let-values (((a b) (values 1 2))
             ((c d) (values 3 4)))
  (list a b c d))         ⇒ (1 2 3 4)

(let-values (((a b . c) (values 1 2 3 4)))
  (list a b c))                    ⇒ (1 2 (3 4))

(let ((a ’a) (b ’b) (x ’x) (y ’y))
  (let-values (((a b) (values x y))
               ((x y) (values a b)))
    (list a b x y)))               ⇒ (x y a b)

A sample definition of let-values in terms of simpler forms is in appendix B.

(let*-values <mv-bindings> <body>)    syntax 

Syntax: <Mv-bindings> must have the form

((<formals1> <init1>) ...),

where each <init> is an expression, and <body> is as described in section 11.3. In each <formals>, any variable must not appear more than once.

Semantics: The let*-values form is similar to let-values, but the <init>s are evaluated and bindings created sequentially from left to right, with the regionof the bindings of each <formals> including the bindings to its right as well as <body>. Thus the second <init> is evaluated in an environment in which the bindings of the first <formals> is visible and initialized, and so on.

(let ((a ’a) (b ’b) (x ’x) (y ’y))
  (let*-values (((a b) (values x y))
                ((x y) (values a b)))
    (list a b x y)))          ⇒ (x y x y)

Note:   While all of the variables bound by a let-values expression must be distinct, the variables bound by different <formals> of a let*-values expression need not be distinct.

11.4.7  Sequencing

(begin <form> ...)    syntax 
(begin <expression> <expression> ...)    syntax 

The <begin> keyword has two different roles, depending on its context:

(define x 0)

(begin (set! x 5)
       (+ x 1))                          ⇒  6

(begin (display "4 plus 1 equals ")
       (display (+ 4 1)))              ⇒  unspecified
  and prints  4 plus 1 equals 5

11.5  Equivalence predicates

A predicate is a procedure that always returns a boolean value (#t or #f). An equivalence predicate is the computational analogue of a mathematical equivalence relation (it is symmetric, reflexive, and transitive). Of the equivalence predicates described in this section, eq? is the finest or most discriminating, and equal? is the coarsest. The eqv? predicate is slightly less discriminating than eq?.

(eqv? obj1 obj2)    procedure 

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 one of the following holds:

The eqv? procedure returns #f if one of the following holds:

Note:   The eqv? procedure returning #t when obj1 and obj2 are number objects does not imply that = would also return #t when called with obj1 and obj2 as arguments.

(eqv? ’a ’a)                             ⇒  #t
(eqv? ’a ’b)                             ⇒  #f
(eqv? 2 2)                               ⇒  #t
(eqv? ’() ’())                           ⇒  #t
(eqv? 100000000 100000000)               ⇒  #t
(eqv? (cons 1 2) (cons 1 2))             ⇒  #f
(eqv? (lambda () 1)
      (lambda () 2))                     ⇒  #f
(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.

(let ((p (lambda (x) x)))
  (eqv? p p))                            ⇒  unspecified
(eqv? "" "")                     ⇒  unspecified
(eqv? ’#() ’#())                 ⇒  unspecified
(eqv? (lambda (x) x)
      (lambda (x) x))            ⇒  unspecified
(eqv? (lambda (x) x)
      (lambda (y) y))            ⇒  unspecified
(eqv? +nan.0 +nan.0)                     ⇒ unspecified

The next set of examples shows the use of eqv? with procedures that have local state. Calls to gen-counter must return a distinct procedure every time, since each procedure has its own internal counter. Calls to gen-loser return procedures that behave equivalently when called. However, eqv? 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))                   ⇒  unspecified
(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))                   ⇒  unspecified
(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

Implementations may share structure between constants where appropriate. Furthermore, a constant may be copied at any time by the implementation so as to exist simultaneously in different sets of locations, as noted in section 11.4.1. 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

(eq? obj1 obj2)    procedure 

The eq? predicate is similar to eqv? except that in some cases it is capable of discerning distinctions finer than those detectable by eqv?.

The eq? and eqv? predicates are guaranteed to have the same behavior on symbols, booleans, the empty list, pairs, procedures, non-empty strings, bytevectors, and vectors, and records. The behavior of eq? on number objects and characters is implementation-dependent, but it always returns either #t or #f, and returns #t only when eqv? would also return #t. The eq? predicate may also behave differently from eqv? on empty vectors, empty bytevectors, and empty strings.

(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))              ⇒  unspecified
(let ((p (lambda (x) x)))
  (eq? p p))              ⇒  unspecified

(equal? obj1 obj2)    procedure 

The equal? predicate returns #t if and only if the (possibly infinite) unfoldings of its arguments into regular trees are equal as ordered trees.

The equal? predicate treats pairs and vectors as nodes with outgoing edges, uses string=? to compare strings, uses bytevector=? to compare bytevectors (see library chapter on “Bytevectors”), and uses eqv? to compare other nodes.

(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? ’#vu8(1 2 3 4 5)
        (u8-list->bytevector
         ’(1 2 3 4 5))                  ⇒  #t
(equal? (lambda (x) x)
        (lambda (y) y))          ⇒  unspecified

(let* ((x (list ’a))
       (y (list ’a))
       (z (list x y)))
  (list (equal? z (list y x))
        (equal? z (list x x))))             
                ⇒  (#t #t)

Note:   The equal? procedure must always terminate, even if its arguments contain cycles.

11.6  Procedure predicate

(procedure? obj)    procedure 

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

(procedure? car)                    ⇒  #t
(procedure? ’car)                   ⇒  #f
(procedure? (lambda (x) (* x x)))   
                                    ⇒  #t
(procedure? ’(lambda (x) (* x x)))  
                                    ⇒  #f

11.7  Arithmetic

The procedures described here implement arithmetic that is generic over the numerical tower described in chapter 3. The generic procedures described in this section accept both exact and inexact number objects as arguments, performing coercions and selecting the appropriate operations as determined by the numeric subtypes of their arguments.

Library chapter on “Arithmetic” describes libraries that define other numerical procedures.

11.7.1  Propagation of exactness and inexactness

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

+            -            *
max          min          abs
numerator    denominator  gcd
lcm          floor        ceiling
truncate     round        rationalize
expt         real-part    imag-part
make-rectangular

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

/
div          mod           div-and-mod
div0         mod0          div0-and-mod0

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

11.7.2  Representability of infinities and NaNs

The specification of the numerical operations is written as though infinities and NaNs are representable, and specifies many operations with respect to these number objects in ways that are consistent with the IEEE 754 standard for binary floating-point arithmetic. An implementation of Scheme may or may not represent infinities and NaNs; however, an implementation must raise a continuable exception with condition type &no-infinities or &no-nans (respectively; see library section on “Flonums”) whenever it is unable to represent an infinity or NaN as specified. In this case, the continuation of the exception handler is the continuation that otherwise would have received the infinity or NaN value. This requirement also applies to conversions between number objects and external representations, including the reading of program source code.

11.7.3  Semantics of common operations

Some operations are the semantic basis for several arithmetic procedures. The behavior of these operations is described in this section for later reference.

11.7.3.1  Integer division

Scheme’s operations for performing integer division rely on mathematical operations div, mod, div0, and mod0, that are defined as follows:

div, mod, div0, and mod0 each accept two real numbers x1 and x2 as operands, where x2 must be nonzero.

div returns an integer, and mod returns a real. Their results are specified by

x1 div x2 = nd
x1 mod x2 = xm

* where

[r6rs-Z-G-2.gif]

Examples:

123 div 10 = 12
123 mod 10 = 3
123 div  - 10 = - 12
123 mod  - 10 = 3
- 123 div 10 = - 13
- 123 mod 10 = 7
- 123 div  - 10 = 13
- 123 mod  - 10 = 7

* div0 and mod0 are like div and mod, except the result of mod0 lies within a half-open interval centered on zero. The results are specified by

x1 div0 x2 = nd
x1 mod0 x2 = xm

* where:

[r6rs-Z-G-3.gif]

Examples:

123 div0 10 = 12
123 mod0 10 = 3
123 div0  - 10 = - 12
123 mod0  - 10 = 3
- 123 div0 10 = - 12
- 123 mod0 10 = - 3
- 123 div0  - 10 = 12
- 123 mod0  - 10 = - 3

*

11.7.3.2  Transcendental functions

In general, the transcendental functions log, sin-1 (arcsine), cos-1 (arccosine), and tan-1 are multiply defined. The value of log z is defined to be the one whose imaginary part lies in the range from - [r6rs-Z-G-D-3.gif] (inclusive if - 0.0 is distinguished, exclusive otherwise) to [r6rs-Z-G-D-3.gif] (inclusive). log 0 is undefined.

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

[r6rs-Z-G-4.gif]

where angle z is the angle of z = a · eib specified as:

angle z = b + 2[r6rs-Z-G-D-3.gif] n

with - [r6rs-Z-G-D-3.gif]angle z[r6rs-Z-G-D-3.gif] and angle z = b + 2[r6rs-Z-G-D-3.gif] n for some integer n.

With the one-argument version of log defined this way, the values of the two-argument-version of log, sin-1 z, cos-1 z, tan-1 z, and the two-argument version of tan-1 are according to the following formulæ:

log z b = (log z/log b)
sin-1 z = - i log (i z + (1 - z2)1/2)
cos-1 z = [r6rs-Z-G-D-3.gif] / 2 - sin-1 z
tan-1 z = (log (1 + i z) - log (1 - i z)) / (2 i)
tan-1 x y = angle(x + yi)

*

The range of tan-1 x y is as in the following table. The asterisk (*) indicates that the entry applies to implementations that distinguish minus zero.

y condition x condition range of result r
y = 0.0 x > 0.0 0.0
y = + 0.0 x > 0.0 + 0.0
y = - 0.0 x > 0.0 - 0.0
y > 0.0 x > 0.0 0.0 < r < ([r6rs-Z-G-D-3.gif]/2)
y > 0.0 x = 0.0 ([r6rs-Z-G-D-3.gif]/2)
y > 0.0 x < 0.0 ([r6rs-Z-G-D-3.gif]/2) < r < [r6rs-Z-G-D-3.gif]
y = 0.0 x < 0 [r6rs-Z-G-D-3.gif]
y = + 0.0 x < 0.0 [r6rs-Z-G-D-3.gif]
y = - 0.0 x < 0.0 - [r6rs-Z-G-D-3.gif]
y < 0.0 x < 0.0 - [r6rs-Z-G-D-3.gif]< r< - ([r6rs-Z-G-D-3.gif]/2)
y < 0.0 x = 0.0 - ([r6rs-Z-G-D-3.gif]/2)
y < 0.0 x > 0.0 - ([r6rs-Z-G-D-3.gif]/2) < r< 0.0
y = 0.0 x = 0.0 undefined
y = + 0.0 x = + 0.0 + 0.0
y = - 0.0 x = + 0.0 - 0.0
y = + 0.0 x = - 0.0 [r6rs-Z-G-D-3.gif]
y = - 0.0 x = - 0.0 - [r6rs-Z-G-D-3.gif]
y = + 0.0 x = 0 ([r6rs-Z-G-D-3.gif]/2)
y = - 0.0 x = 0 - ([r6rs-Z-G-D-3.gif]/2)

11.7.4  Numerical operations

11.7.4.1  Numerical type predicates

(number? obj)    procedure 
(complex? obj)    procedure 
(real? obj)    procedure 
(rational? obj)    procedure 
(integer? obj)    procedure 

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.

If z is a complex number object, then (real? z) is true if and only if (zero? (imag-part z)) and (exact? (imag-part z)) are both true.

If x is a real number object, then (rational? x) is true if and only if there exist exact integer objects k1 and k2 such that (= x (/ k1 k2)) and (= (numerator x) k1) and (= (denominator x) k2) are all true. Thus infinities and NaNs are not rational number objects.

If q is a rational number objects, then (integer? q) is true if and only if (= (denominator q) 1) is true. If q is not a rational number object, then (integer? q) is #f.

(complex? 3+4i)                                ⇒  #t
(complex? 3)                                   ⇒  #t
(real? 3)                                      ⇒  #t
(real? -2.5+0.0i)                              ⇒  #f
(real? -2.5+0i)                                ⇒  #t
(real? -2.5)                                   ⇒  #t
(real? #e1e10)                                 ⇒  #t
(rational? 6/10)                               ⇒  #t
(rational? 6/3)                                ⇒  #t
(rational? 2)                                  ⇒  #t
(integer? 3+0i)                                ⇒  #t
(integer? 3.0)                                 ⇒  #t
(integer? 8/4)                                 ⇒  #t

(number? +nan.0)                               ⇒  #t
(complex? +nan.0)                              ⇒  #t
(real? +nan.0)                                 ⇒  #t
(rational? +nan.0)                             ⇒  #f
(complex? +inf.0)                              ⇒  #t
(real? -inf.0)                                 ⇒  #t
(rational? -inf.0)                             ⇒  #f
(integer? -inf.0)                              ⇒  #f

Note:   Except for number?, the behavior of these type predicates on inexact number objects is unreliable, because any inaccuracy may affect the result.

(real-valued? obj)    procedure 
(rational-valued? obj)    procedure 
(integer-valued? obj)    procedure 

These numerical type predicates can be applied to any kind of argument. The real-valued? procedure returns #t if the object is a number object and is equal in the sense of = to some real number object, or if the object is a NaN, or a complex number object whose real part is a NaN and whose imaginary part is zero in the sense of zero?. The rational-valued? and integer-valued? procedures return #t if the object is a number object and is equal in the sense of = to some object of the named type, and otherwise they return #f.

(real-valued? +nan.0)                          ⇒  #t
(real-valued? +nan.0+0i)                          ⇒  #t
(real-valued? -inf.0)                          ⇒  #t
(real-valued? 3)                               ⇒  #t
(real-valued? -2.5+0.0i)                       ⇒  #t
(real-valued? -2.5+0i)                         ⇒  #t
(real-valued? -2.5)                            ⇒  #t
(real-valued? #e1e10)                          ⇒  #t

(rational-valued? +nan.0)                      ⇒  #f
(rational-valued? -inf.0)                      ⇒  #f
(rational-valued? 6/10)                        ⇒  #t
(rational-valued? 6/10+0.0i)                   ⇒  #t
(rational-valued? 6/10+0i)                     ⇒  #t
(rational-valued? 6/3)                         ⇒  #t

(integer-valued? 3+0i)                         ⇒  #t
(integer-valued? 3+0.0i)                       ⇒  #t
(integer-valued? 3.0)                          ⇒  #t
(integer-valued? 3.0+0.0i)                     ⇒  #t
(integer-valued? 8/4)                          ⇒  #t

Note:   These procedures test whether a given number object can be coerced to the specified type without loss of numerical accuracy. Specifically, the behavior of these predicates differs from the behavior of real?, rational?, and integer? on complex number objects whose imaginary part is inexact zero.

Note:   The behavior of these type predicates on inexact number objects is unreliable, because any inaccuracy may affect the result.

(exact? z)    procedure 
(inexact? z)    procedure 

These numerical predicates provide tests for the exactness of a quantity. For any number object, precisely one of these predicates is true.

(exact? 5)                           ⇒  #t
(inexact? +inf.0)                    ⇒  #t

11.7.4.2  Generic conversions

(inexact z)    procedure 
(exact z)    procedure 

The inexact procedure returns an inexact representation of z. If inexact number objects of the appropriate type have bounded precision, then the value returned is an inexact number object that is nearest to the argument. If an exact argument has no reasonably close inexact equivalent, an exception with condition type &implementation-violation may be raised.

Note:   For a real number object whose magnitude is finite but so large that it has no reasonable finite approximation as an inexact number, a reasonably close inexact equivalent may be +inf.0 or -inf.0. Similarly, the inexact representation of a complex number object whose components are finite may have infinite components.

The exact procedure returns an exact representation of z. The value returned is the exact number object that is numerically closest to the argument; in most cases, the result of this procedure should be numerically equal to its argument. If an inexact argument has no reasonably close exact equivalent, an exception with condition type &implementation-violation may be raised.

These procedures implement the natural one-to-one correspondence between exact and inexact integer objects throughout an implementation-dependent range.

The inexact and exact procedures are idempotent.

11.7.4.3  Arithmetic operations

(= z1 z2 z3 ...)    procedure 
(< x1 x2 x3 ...)    procedure 
(> x1 x2 x3 ...)    procedure 
(<= x1 x2 x3 ...)    procedure 
(>= x1 x2 x3 ...)    procedure 

These procedures return #t if their arguments are (respectively): equal, monotonically increasing, monotonically decreasing, monotonically nondecreasing, or monotonically nonincreasing, and #f otherwise.

(= +inf.0 +inf.0)                   ⇒  #t
(= -inf.0 +inf.0)                   ⇒  #f
(= -inf.0 -inf.0)                   ⇒  #t

For any real number object x that is neither infinite nor NaN:

(< -inf.0 x +inf.0))                ⇒  #t
(> +inf.0 x -inf.0))                ⇒  #t

For any number object z:

(= +nan.0 z)                       ⇒  #f

For any real number object x:

(< +nan.0 x)                       ⇒  #f
(> +nan.0 x)                       ⇒  #f

These predicates must be transitive.

Note:   The traditional implementations of these predicates in Lisp-like languages are not transitive.

Note:   While it is possible to compare inexact number objects using these predicates, the results may be unreliable because a small inaccuracy may affect the result; this is especially true of = and zero? (below).

When in doubt, consult a numerical analyst.

(zero? z)    procedure 
(positive? x)    procedure 
(negative? x)    procedure 
(odd? n)    procedure 
(even? n)    procedure 
(finite? x)    procedure 
(infinite? x)    procedure 
(nan? x)    procedure 

These numerical predicates test a number object for a particular property, returning #t or #f. The zero? procedure tests if the number object is = to zero, positive? tests whether it is greater than zero, negative? tests whether it is less than zero, odd? tests whether it is odd, even? tests whether it is even, finite? tests whether it is not an infinity and not a NaN, infinite? tests whether it is an infinity, nan? tests whether it is a NaN.

(zero? +0.0)                          ⇒  #t
(zero? -0.0)                          ⇒  #t
(zero? +nan.0)                        ⇒  #f
(positive? +inf.0)                    ⇒  #t
(negative? -inf.0)                    ⇒  #t
(positive? +nan.0)                    ⇒  #f
(negative? +nan.0)                    ⇒  #f
(finite? +inf.0)                      ⇒  #f
(finite? 5)                           ⇒  #t
(finite? 5.0)                         ⇒  #t
(infinite? 5.0)                       ⇒  #f
(infinite? +inf.0)                    ⇒  #t

Note:   As with the predicates above, the results may be unreliable because a small inaccuracy may affect the result.

(max x1 x2 ...)    procedure 
(min x1 x2 ...)    procedure 

These procedures return the maximum or minimum of their arguments.

(max 3 4)                                      ⇒  4
(max 3.9 4)                                    ⇒  4.0

For any real number object x:

(max +inf.0 x)                                 ⇒  +inf.0
(min -inf.0 x)                                 ⇒  -inf.0

Note:   If any argument is inexact, then the result is also 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 number objects of mixed exactness, and the numerical value of the result cannot be represented as an inexact number object without loss of accuracy, then the procedure may raise an exception with condition type &implementation-restriction.

(+ z1 ...)    procedure 
(* z1 ...)    procedure 

These procedures return the sum or product of their arguments.

(+ 3 4)                                        ⇒  7
(+ 3)                                          ⇒  3
(+)                                            ⇒  0
(+ +inf.0 +inf.0)                              ⇒  +inf.0
(+ +inf.0 -inf.0)                              ⇒  +nan.0

(* 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
(* 0 +inf.0)                                   ⇒  0 or +nan.0
(* 0 +nan.0)                                   ⇒  0 or +nan.0
(* 1.0 0)                                      ⇒  0 or 0.0

For any real number object x that is neither infinite nor NaN:

(+ +inf.0 x)                                   ⇒  +inf.0
(+ -inf.0 x)                                   ⇒  -inf.0

For any real number object x:

(+ +nan.0 x)                                   ⇒  +nan.0

For any real number object x that is not an exact 0:

(* +nan.0 x)                                   ⇒  +nan.0

If any of these procedures are applied to mixed non-rational real and non-real complex arguments, they either raise an exception with condition type &implementation-restriction or return an unspecified number object.

Implementations that distinguish - 0.0 should adopt behavior consistent with the following examples:

(+ 0.0 -0.0)          ⇒ 0.0
(+ -0.0 0.0)          ⇒ 0.0
(+ 0.0 0.0)           ⇒ 0.0
(+ -0.0 -0.0)         ⇒ -0.0

(- z)    procedure 
(- z1 z2 ...)    procedure 

With two or more arguments, this procedures returns the difference of its arguments, associating to the left. With one argument, however, it returns the additive inverse of its argument.

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

If this procedure is applied to mixed non-rational real and non-real complex arguments, it either raises an exception with condition type &implementation-restriction or returns an unspecified number object.

Implementations that distinguish - 0.0 should adopt behavior consistent with the following examples:

(- 0.0)               ⇒ -0.0
(- -0.0)              ⇒ 0.0
(- 0.0 -0.0)          ⇒ 0.0
(- -0.0 0.0)          ⇒ -0.0
(- 0.0 0.0)           ⇒ 0.0
(- -0.0 -0.0)         ⇒ 0.0

(/ z)    procedure 
(/ z1 z2 ...)    procedure 

If all of the arguments are exact, then the divisors must all be nonzero. With two or more arguments, this procedure returns the quotient of its arguments, associating to the left. With one argument, however, it returns the multiplicative inverse of its argument.

(/ 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)                                  &assertion exception
(/ 3 0)                                  &assertion exception
(/ 0 3.5)                    &