Equivalence predicatesA 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
)
procedure
The 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
)
procedure
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, 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
)
procedure
The 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. |