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

## 6.2 Equivalence

Scheme has three different general equivalence test predicates. Other than these, some types have their own comparison 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 (except NaN), 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 ```

Note that comparison of NaNs has some peculiarity. Any numeric comparison fails if there’s at least one NaN in its argument. Therefore, `(= +nan.0 +nan.0)` is always `#f`. However, Gauche may return `#t` for `(eq? +nan.0 +nan.0)` or `(eqv? +nan.0 +nan.0)`.

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 ```

Note: If both obj1 and obj2 have circular structure, `equal?` may diverge. You might want to use `isomorph?` instead (see `util.isomorph` - Determine isomorphism).

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 () ((x :init-keyword :x) (y :init-keyword :y))) (define-method object-equal? ((a ) (b )) (and (equal? (slot-ref a 'x) (slot-ref b 'x)) (equal? (slot-ref a 'y) (slot-ref b 'y)))) (equal? (make :x 1 :y (list 'a 'b)) (make :x 1 :y (list 'a 'b))) ⇒ #t (equal? (make :x 1 :y (make :x 3 :y 4)) (make :x 1 :y (make :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 `util.isomorph` - Determine isomorphism).

 [ < ] [ > ] [ << ] [ Up ] [ >> ]

This document was generated by Shiro Kawai on May 28, 2012 using texi2html 1.82.