[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |

## 6.1 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. ‘`Eqv?`’ is
slightly less discriminating than ‘`eq?`’.

- procedure:
**eqv?***obj1 obj2* -
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. This relation is left slightly open to interpretation, but the following partial specification of ‘`eqv?`’ holds for all implementations of Scheme.The ‘

`eqv?`’ procedure returns`#t`if:-
`obj1`and`obj2`are both`#t`or both`#f`. -
`obj1`and`obj2`are both symbols and(string=? (symbol->string obj1) (symbol->string obj2)) ⇒ #t

*Note:*This assumes that neither`obj1`nor`obj2`is an “uninterned symbol” as alluded to in section Symbols. This report does not presume to specify the behavior of ‘`eqv?`’ on implementation-dependent extensions. -
`obj1`and`obj2`are both numbers, are numerically equal (see ‘`=`’, section Numbers), and are either both exact or both inexact. -
`obj1`and`obj2`are both characters and are the same character according to the ‘`char=?`’ procedure (section Characters). -
both
`obj1`and`obj2`are the empty list. -
`obj1`and`obj2`are pairs, vectors, or strings that denote the same locations in the store (section Storage model). -
`obj1`and`obj2`are procedures whose location tags are equal (section Procedures).

The ‘

`eqv?`’ procedure returns`#f`if:-
`obj1`and`obj2`are of different types (section Disjointness of types). -
one of
`obj1`and`obj2`is`#t`but the other is`#f`. -
`obj1`and`obj2`are symbols but(string=? (symbol->string

`obj1`) (symbol->string`obj2`)) ⇒ #f -
one of
`obj1`and`obj2`is an exact number but the other is an inexact number. -
`obj1`and`obj2`are numbers for which the ‘`=`’ procedure returns`#f`. -
`obj1`and`obj2`are characters for which the ‘`char=?`’ procedure returns`#f`. -
one of
`obj1`and`obj2`is the empty list but the other is not. -
`obj1`and`obj2`are pairs, vectors, or strings that denote distinct locations. -
`obj1`and`obj2`are procedures that would behave differently (return different value(s) or have different side effects) for some 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 (let ((p (lambda (x) x))) (eqv? p p)) ⇒ #t

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*The next set of examples shows the use of ‘

`eqv?`’ with procedures that have local state. ‘`Gen-counter`’ must return a distinct procedure every time, since each procedure has its own internal counter. ‘`Gen-loser`’, however, returns equivalent procedures each time, since the local state does not affect the value or side effects of the procedures.(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)) ⇒ #fSince it is an error to modify constant objects (those returned by literal expressions), implementations are permitted, though not required, to 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

*Rationale:*The above definition of ‘`eqv?`’ allows implementations latitude in their treatment of procedures and literals: implementations are free either to detect or to 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. -

- procedure:
**eq?***obj1 obj2* -
‘

`Eq?`’ is similar to ‘`eqv?`’ except that in some cases it is capable of discerning distinctions finer than those detectable by ‘`eqv?`’.‘

`Eq?`’ and ‘`eqv?`’ are guaranteed to have the same behavior on symbols, booleans, the empty list, pairs, procedures, and non-empty strings and vectors. ‘`Eq?`’’s behavior on numbers and characters is implementation-dependent, but it will always return either true or false, and will return true only when ‘`eqv?`’ would also return true. ‘`Eq?`’ may also behave differently from ‘`eqv?`’ on empty vectors 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)) ⇒ #t (let ((p (lambda (x) x))) (eq? p p)) ⇒ #t

*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 may not be possible to compute ‘`eqv?`’ of two numbers in constant time, whereas ‘`eq?`’ implemented as pointer comparison will always finish in constant time. ‘`Eq?`’ may be used like ‘`eqv?`’ in applications using procedures to implement objects with state since it obeys the same constraints as ‘`eqv?`’.

- library procedure:
**equal?***obj1 obj2* -
‘

`Equal?`’ recursively compares the contents of pairs, vectors, and strings, applying ‘`eqv?`’ on other objects such as numbers and symbols. A rule of thumb is that objects are generally ‘`equal?`’ if they print the same. ‘`Equal?`’ may fail to terminate if its arguments are circular data structures.(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? (lambda (x) x) (lambda (y) y)) ⇒

*unspecified*

[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |

This document was generated on *October 23, 2011* using *texi2html 5.0*.