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

6.1 Equivalence

Scheme has three different general equivalence test predicates. Other than these, some types have their own comarison predicates.

Function: eq? obj1 obj2
[R5RS] This is the fastest and finest predicate. Returns #t if obj1 and obj2 are allocated objects of the same types, and denote the same location. Returns #t if both objects are #f, #t, or (). You can think eq? as a pointer comparison. Note that the result is unspecified in Scheme standard when both objects are characters or numbers.

(eq? #t #t)               => #t
(eq? #t #f)               => #f
(eq? 'a 'a)               => #t
(eq? 'a 'b)               => #f
(eq? (list 'a) (list 'a)) => #f
(let ((x (list 'a)))
  (eq? x x))              => #t

Function: eqv? obj1 obj2
[R5RS] When obj1 and obj2 are both exact or both inexact numbers, eqv? returns #t iff (= obj1 obj2) is true. When obj1 and obj2 are both characters, eqv? returns #t iff (char=? obj1 obj2) is true. Otherwise, eqv? is the same as eq? on Gauche.

(eqv? #\a #\a)             => #t
(eqv? #\a #\b)             => #f
(eqv? 1.0 1.0)             => #t
(eqv? 1 1)                 => #t
(eqv? 1 1.0)               => #f
(eqv? (list 'a) (list 'a)) => #f
(let ((x (list 'a)))
  (eqv? x x))              => #t

Function: equal? obj1 obj2
[R5RS+] If obj1 and obj2 are both aggregate types, equal? compares its elements recursively. Otherwise, equal? behaves the same as eqv?.

If obj1 and obj2 are other than booleans, numbers, characters, pairs, strings and vectors, and the class of both objects are the same, equal? calls the generic function object-equal?. By defining the method, users can extend the behavior of equal? for user-defined classes.

(equal? (list 1 2) (list 1 2)) => #t
(equal? "abc" "abc")           => #t
(equal? 100 100)               => #t
(equal? 100 100.0)             => #f

Generic Function: object-equal? obj1 obj2
This generic function is called when equal? is called on the objects it doesn't know about. You can define this method on your class so that equal? can check equivalence. This method is supposed to return #t if obj1 is equal to obj2, #f otherwise. If you want to check equivalence of elements recursively, do not call object-equal? directly; call equal? on each element.

(define-class <foo> ()
  ((x :init-keyword :x)
   (y :init-keyword :y)))

(define-method object-equal? ((a <foo>) (b <foo>))
  (and (equal? (slot-ref a 'x) (slot-ref b 'x))
       (equal? (slot-ref a 'y) (slot-ref b 'y))))

(equal? (make <foo> :x 1 :y (list 'a 'b))
        (make <foo> :x 1 :y (list 'a 'b)))
  => #t

(equal? (make <foo> :x 1 :y (make <foo> :x 3 :y 4))
        (make <foo> :x 1 :y (make <foo> :x 3 :y 4)))
  => #t

Sometimes you want to test if two aggregate structures are topologically equal, i.e., if one has a shared substructure, the other has a shared substructure in the same way. Equal? can't handle it; module util.isomorph provides a procedure isomorphic? which does the job (See section 11.21 util.isomorph - Determine isomorphism).

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

This document was generated by Ken Dickey on November, 28 2002 using texi2html