[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Issue: EVAL-OTHER (Version 2)



I don't know about making EVAL a generic function due to the ramifications
this has on the compiler, but there are several other places in CL in which
functions should be required to be generic. 

One example might be in the equality area.  Common Lisp seems to have a
wealth of equality predicates, EQ, EQL, EQUAL, EQUALP, =, STRING=, CHAR=
... and you kind of pick and choose based on what you know about the
application.  It would be nice to have at least one version of equality
which did the right thing based on what it was comparing.  Perhaps this is
EQUALP.  EQUALP already looks inside both cons cells and arrays, why not
extend it to look inside objects too.  I suggest the following definition
of EQUALP:

	(defmethod equalp ((x t) (y t))
	  (eq x y))

        (defmethod equalp ((x character) (y character))
	  (char-equal x y))

        (defmethod equalp ((x number) (y number))
	  (= x y))

        (defmethod equalp ((x cons) (y cons))
	  (or (eq x y)
	      (and (equalp (car x) (car y))
		   (equalp (cdr x) (cdr y)))))

        (defmethod equalp ((x object) (y object))
	  (let ((cx (class-of x))
		(cy (class-of y)))
	    (or (eq x y)
		(and (eq cx cy)
		     (every #'(lambda (slotd)
				(let ((name (slotd-name slotd)))
				  (equalp (slot-value-using-class cx
								  x
								  name)
					  (slot-value-using-class cx
								  y
								  name))))
			    (class-slots cx))))))

        (defmethod equalp ((x array) (y array))
	  ...)

COERCE is another good candidate for being made generic.  Like the print
system which is required to go through the PRINT-OBJECT method, COERCE
could ultimately invoke a generic layer:

	(defun coerce (thing type)
	  (case type
	    <old coerce code ...>
	    (t
	     (coerce-object thing (find-class type)))))

	(defmethod coerce-object ((thing t) (c class))
	  (error "~S cannot be coerced to type ~S."
		 thing (class-name c)))

This would allow the user to write class specific coercion routines.  One
objection has been raised to this proposal by Moon:

> But it's meaningful for COERCE's second argument to be a type specifier that
> does not name a class.  CLtL gives as an example (vector (complex short-float)).
> It would be inconsistent to do some coercions with classes and others through
> some other mechanism.  I don't think your idea will work without a larger
> recasting of Common Lisp in object-oriented terms.  While that's an interesting
> project for investigation, I suspect it would quickly go way beyond the
> proper charter of a standardization effort.

I think the above code demonstrates how this can indeed work given CL's
non-class type specifiers.  COERCE itself is not required to be generic, it
is simplied required to ultimately call COERCE-OBJECT.  This is exactly the
requirement placed on PRINT. 

> One minor procedural matter: You're more likely to get this considered if
> you write up the proposal in full rather than just as a little fragment.

How do I do this?  How does it look, and who do I send it to?

Warren Harris
HP Labs