All equals are not created equal
EQ? is the most discriminating test of equality. If EQ? can't tell the
difference between two things, then nothing else in Scheme can
either. Pairs are EQ? only if they share the same box and pointer
structure. The behavior of EQ? on numbers is not defined -- it's
implementation dependent. You shouldn't use EQ? for numbers.
= works only on numbers. It isn't a "true predicate." It generates
errors when given something that isn't a number.
EQV? is "the usual" test for equality of atomic items. It uses EQ? for
symbols and booleans, = for numbers, char=? for characters, etc. For
procedures it isn't well defined (but uses EQ? in MIT Scheme). For
pairs it uses EQ?, so it will return true only if both items share the
same box and pointer structure. For strings, uses EQ?.
EQUAL? tests "whether they print the same". It uses EQV? for
everything except pairs. It recurses on the CAR and CDR.
See pp.13-15 of the Revised4 Report on the Algorithmic Language Scheme
for a complete description of eq?, eqv? and equal?.
Examples:
EQ?
(eq? 'a 'a) => #t
(eq? 100000000 100000000) => unspecified (probably #f)
(eq? car car) => #t
(eq? '() '()) => #t
(eq? (list 'a) (list 'a)) => #f
(let ((x '(a)))
(eq? x x)) => #t
EQV?
(eqv? 'a 'a) => #t
(eqv? 100000000 100000000) => #t
(eqv? '() '()) => #t
(eqv? (cons 1 2) (cons 1 2)) => #f
(let ((a (cons 1 2)))
(eqv? a a)) => #t
EQUAL?
(equal? 'a 'a) => #t
(equal? 2 2) => #t
(equal? "abc" "abc") => #t
(equal? '(a) '(a)) => #t
(equal? '(a (b) c)
'(a (b) c)) => #t
(modified from Holly Yanko's recitation notes)