Equality predicates tell whether one value is "the same as" another. There are actually several important senses of "the same as," so Scheme provides four equality predicates.
Sometimes you want to know whether two data structures are structurally
the same, with the same values in the same places. For example, you
may want to know whether a list has the same structure and elements
as another list. For this, you can use equal?
, which does
a deep, element-by-element structural comparison.
For example (equal? '(1 2 3) '(1 2 3))
returns #t
, because
the arguments are both lists containing 1
, 2
, 3
,
in that order. equal?
does a deep traversal of the data structure,
so you can hand it nested lists and other fairly complicated data
structures as well. (Don't hand it structures with directed cycles
of pointers, though, because it may loop forever without finding
the end.)
equal?
works to compare simple things, too. For example,
(equal? 22 22)
returns #t
, and (equal? #t 15)
returns #f
. (Note that equal?
can be used to compare things
that may or may not be of the same type, but if they're not, the answer
will always be #f
. Objects of different types are never
equal?
.)
Often you don't want to structurally compare two whole data structures--you just want to know if they're the exact same object. For example, given two pointers to lists, you may want to know if they're pointers to the very same list, not just two lists with the same elements.
For this, you use eq?
. eq?
compares two values to see
if they refer to the same object. Since all values in Scheme are
(conceptually) pointers, this is just a pointer comparison, so
eq?
is always fast.
(You might think that tagged immediate representations would require
eq?
to be slower than a simple pointer comparision, because it
would have to check whether things were really pointers. This isn't
actually true---eq?
just compares the bit patterns without
worrying whether they represent pointers or immediates.)
Equality tests for numbers are treated specially.
When comparing two values that are supposed to be numbers, =
is the appropriate predicate. Using =
has the advantage that
using it on non-numbers is an error, and Scheme will complain when
it happens. If you make a mistake and have a non-number where you
intend to have a number, this will often show you the problem.
(You could also use equal?
, but it won't signal an error
when applied to non-numbers, and may be a little bit slower.)
There is another equality predicate, eqv?
, which does numeric
comparisons on numbers (like =
), and identity comparisons
(like eq?
) on anything else.
================================================================== This is the end of Hunk G TIME TO TRY IT OUT At this point, you should go read Hunk H of the next chapter and work through the examples using a running Scheme system. Then return here and resume this chapter. ==================================================================
(Go to Hunk H, which starts at section Using Predicates (Hunk H).)