Barry Margolin <barmar@genuity.net> wrote:
+---------------
| Then use EQ, which doesn't have to check the type codes first to determine
| if it can just do a pointer comparison. Think of EQL as being something
| like:
|
| (defun eql (x y)
| (and (same-type-p x y)
| (typecase x
| (number (= x y))
| (character (char= x y))
| (t (eq x y)))))
|
| If you know a priori that the typecase would just fall through to the last
| case, there's no point in doing it.
+---------------
Exactly, which is why I'd think you'd want EQL to start with an EQ check
*first*, since it's cheap. And since I don't find SAME-TYPE-P anywhere in
CLHS, I'd probably suggest something like this:
(defun eql (x y)
(or (eq x y)
(and (eq (type-of x) (type-of y))
(typecase x
(number (= x y))
(character (char= x y))
(t nil)))))
Unfortunately, I think this might contain a potential subtle bug for
some implementations (though not, I think, CMUCL or CLISP). TYPE-OF
might return the list form of type specifier for some numbers or
characters [per examples on the CLHS page for TYPE-OF], and if said
list is freshly cons'd, "(eql foo foo)" might return NIL. (Oops!)
One could change the EQ in the type equality test to EQUAL, but
that just pushes the problem to the definition of EQUAL (and slows
things down at the same time).
-Rob
-----
Rob Warnock, 30-3-510 <rpw3@sgi.com>
SGI Network Engineering <http://reality.sgi.com/rpw3/>
1600 Amphitheatre Pkwy. Phone: 650-933-1673
Mountain View, CA 94043 PP-ASEL-IA
[Note: aaanalyst@sgi.com and zedwatch@sgi.com aren't for humans ]