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?.
(eqv? obj1 obj2 ) procedureThe eqv? procedure defines a useful equivalence relation on objects. Briefly, it returns #t if obj1 and obj2 are normally 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:
(eqv? 'a 'a) ==> #t (eqv? 'a 'b) ==> #f (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? (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
Note that (eqv? 0.0 -0.0) will return #f if negative zero is distinguished, and #t if negative zero is not distinguished.
(eq? obj1 obj2 ) procedureThe 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, 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, and empty bytevectors, eq? may also behave differently from eqv?.
(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)
(equal? obj1 obj2 ) procedureThe equal? procedure, when applied to pairs, 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.
(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
Note: A rule of thumb is that objects are generally equal? if they print the same.