(Equality): Revise for clarity.
authorKevin Ryde <user42@zip.com.au>
Wed, 15 Sep 2004 22:30:59 +0000 (22:30 +0000)
committerKevin Ryde <user42@zip.com.au>
Wed, 15 Sep 2004 22:30:59 +0000 (22:30 +0000)
doc/ref/api-utility.texi

index 669bf1b..5d09e83 100644 (file)
@@ -26,65 +26,150 @@ applications, they are collected in a @dfn{utility} chapter.
 
 @node Equality
 @subsection Equality
-
-@c FIXME::martin: Review me!
-
 @cindex sameness
 @cindex equality
 
-Three different kinds of @dfn{sameness} are defined in Scheme.
+There are three kinds of core equality predicates in Scheme, described
+below.  The same kinds of comparisons arise in other functions, like
+@code{memq} and friends (@pxref{List Searching}).
+
+For all three tests, objects of different types are never equal.  So
+for instance a list and a vector are not @code{equal?}, even if their
+contents are the same.  Exact and inexact numbers are considered
+different types too, and are hence not equal even if their values are
+the same.
+
+@code{eq?} tests just for the same object (essentially a pointer
+comparison).  This is fast, and can be used when searching for a
+particular object, or when working with symbols or keywords (which are
+always unique objects).
+
+@code{eqv?} extends @code{eq?} to look at the value of numbers and
+characters.  It can for instance be used somewhat like @code{=}
+(@pxref{Comparison}) but without an error if one operand isn't a
+number.
+
+@code{equal?} goes further, it looks (recursively) into the contents
+of lists, vectors, etc.  This is good for instance on lists that have
+been read or calculated in various places and are the same, just not
+made up of the same pairs.  Such lists look the same (when printed),
+and @code{equal?} will consider them the same.
+
+@sp 1
+@deffn {Scheme Procedure} eq? x y
+@deffnx {C Function} scm_eq_p (x, y)
+@rnindex eq?
+Return @code{#t} if @var{x} and @var{y} are the same object, except
+for numbers and characters.  For example,
+
+@example
+(define x (vector 1 2 3))
+(define y (vector 1 2 3))
+
+(eq? x x)  @result{} #t
+(eq? x y)  @result{} #f
+@end example
+
+Numbers and characters are not equal to any other object, but the
+problem is they're not necessarily @code{eq?} to themselves either.
+This is even so when the number comes directly from a variable,
 
-@itemize @bullet
-@item
-Two values can refer to exactly the same object.
+@example
+(let ((n (+ 2 3)))
+  (eq? n n))       @result{} *unspecified*
+@end example
 
-@item
-Two objects can have the same @dfn{value}.
+Generally @code{eqv?} below should be used when comparing numbers or
+characters.  @code{=} (@pxref{Comparison}) or @code{char=?}
+(@pxref{Characters}) can be used too.
 
-@item
-Two objects can be structurally equivalent.
-@end itemize
+It's worth noting that end-of-list @code{()}, @code{#t}, @code{#f}, a
+symbol of a given name, and a keyword of a given name, are unique
+objects.  There's just one of each, so for instance no matter how
+@code{()} arises in a program, it's the same object and can be
+compared with @code{eq?},
 
-The differentiation between these three kinds is important, because
-determining whether two values are the same objects is very efficient,
-while determining structural equivalence can be quite expensive
-(consider comparing two very long lists).  Therefore, three different
-procedures for testing for equality are provided, which correspond to
-the three kinds of @dfn{sameness} defined above.
+@example
+(define x (cdr '(123)))
+(define y (cdr '(456)))
+(eq? x y) @result{} #t
 
-@rnindex eq?
-@deffn {Scheme Procedure} eq? x y
-@deffnx {C Function} scm_eq_p (x, y)
-Return @code{#t} iff @var{x} references the same object as @var{y}.
-@code{eq?} is similar to @code{eqv?} except that in some cases it is
-capable of discerning distinctions finer than those detectable by
-@code{eqv?}.
+(define x (string->symbol "foo"))
+(eq? x 'foo) @result{} #t
+@end example
 @end deffn
 
 @deftypefn {C Function} int scm_is_eq (SCM x, SCM y)
 Return @code{1} when @var{x} and @var{y} are equal in the sense of
-@code{eq?}, else return @code{0}.
+@code{eq?}, otherwise return @code{0}.
+
+@findex ==
+The @code{==} operator should not be used on @code{SCM} values, an
+@code{SCM} is a C type which cannot necessarily be compared using
+@code{==} (@pxref{The SCM Type}).
 @end deftypefn
 
-@rnindex eqv?
+@sp 1
 @deffn {Scheme Procedure} eqv? x y
 @deffnx {C Function} scm_eqv_p (x, y)
-The @code{eqv?} procedure defines a useful equivalence relation on objects.
-Briefly, it returns @code{#t} if @var{x} and @var{y} should normally be
-regarded as the same object.  This relation is left slightly open to
-interpretation, but works for comparing immediate integers, characters,
-and inexact numbers.
+@rnindex eqv?
+Return @code{#t} if @var{x} and @var{y} are the same object, or for
+characters and numbers the same value.
+
+On objects except characters and numbers, @code{eqv?} is the same as
+@code{eq?} above, it's true if @var{x} and @var{y} are the same
+object.
+
+If @var{x} and @var{y} are numbers or characters, @code{eqv?} compares
+their type and value.  An exact number is not @code{eqv?} to an
+inexact number (even if their value is the same).
+
+@example
+(eqv? 3 (+ 1 2)) @result{} #t
+(eqv? 1 1.0)     @result{} #f
+@end example
 @end deffn
 
-@rnindex equal?
+@sp 1
 @deffn {Scheme Procedure} equal? x y
 @deffnx {C Function} scm_equal_p (x, y)
-Return @code{#t} iff @var{x} and @var{y} are recursively @code{eqv?}
-equivalent.  @code{equal?} recursively compares the contents of pairs,
-vectors, and strings, applying @code{eqv?} on other objects such as
-numbers and symbols.  A rule of thumb is that objects are generally
-@code{equal?}  if they print the same.  @code{equal?} may fail to
-terminate if its arguments are circular data structures.
+@rnindex equal?
+Return @code{#t} if @var{x} and @var{y} are the same type, and their
+contents or value are equal.
+
+For a pair, string, vector or array, @code{equal?} compares the
+contents, and does so using using the same @code{equal?} recursively,
+so a deep structure can be traversed.
+
+@example
+(equal? (list 1 2 3) (list 1 2 3))   @result{} #t
+(equal? (list 1 2 3) (vector 1 2 3)) @result{} #f
+@end example
+
+For other objects, @code{equal?} compares as per @code{eqv?} above,
+which means characters and numbers are compared by type and value (and
+like @code{eqv?}, exact and inexact numbers are not @code{equal?},
+even if their value is the same).
+
+@example
+(equal? 3 (+ 1 2)) @result{} #t
+(equal? 1 1.0)     @result{} #f
+@end example
+
+Hash tables are currently only compared as per @code{eq?}, so two
+different tables are not @code{equal?}, even if their contents are the
+same.
+
+@code{equal?} does not support circular data structures, it may go
+into an infinite loop if asked to compare two circular lists or
+similar.
+
+New application-defined object types (@pxref{Defining New Types
+(Smobs)}) have an @code{equalp} handler which is called by
+@code{equal?}.  This lets an application traverse the contents or
+control what is considered @code{equal?} for two objects of such a
+type.  If there's no such handler, the default is to just compare as
+per @code{eq?}.
 @end deffn