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


    Date: Mon, 4 Apr 88 11:20 PDT
    From: Gregor.pa@Xerox.COM

    At our last meeting, there was some sentiment for making the behavior of
    add-named-class, ensure-generic-function and add-named-method more
    uniform.  This message attempts to address those issues.

    I have spent some time thinking about this, and I still feel that while
    add-named-class and ensure-generic-function are similar, add-named-method
    is different.  

    One way to see this is to think about the defining forms which these
    functions are the analog of.  add-named-class is the analog of defclass;
    ensure-generic-function is the analog of defgeneric; add-named-method is
    the analog of defmethod.

    defclass and defgeneric each provide a way to specify the class of the
    metaobject created....
    On the other hand, defmethod provides no mechanism for controlling the
    class of the generic function or the method it creates.  For this reason
    it doesn't make sense for add-named-method to have that ability.

Wait a minute.  I thought the only reason defmethod didn't allow one to
specify the class of the method is that there is no good place to stick it
in the syntax.  I could easily imagine someone defining an alternate version
of defmethod, with different syntax, that allowed the method class to be
specified.  They would be chagrined if they could not use add-named-method
to implement this macro, but had to make an unmodular copy of the body of
add-named-method in order to do it.

Are you saying that it is fundamentally wrong to specify the class of
the method object when defining a method?  I admit that I've only seen
one application of this, in a paper from some folks at BBN who were
using PCL, and what they were doing was confused (they didn't want meta
objects at all, just plain Lisp macros).  However I assume that use of
method meta object classes does make sense sometimes and that specifying
the class when defining a method does make sense sometimes.

    On the other hand, it is possible to make add-named-method a little more
    uniform by having it take keyword arguments which get passed on to the
    make-instance of the method.

    (defun add-named-method (generic-function-name &rest keys
						   &key qualifiers
      (let* ((gf (ensure-generic-function 
		   (class-prototype (class-named 'standard-generic-function))
		   :name generic-function-name))
	     (new-method (apply #'make-instance
				(generic-function-method-class gf)
	     (old-method (get-method gf qualifiers specializers)))
	(when old-method (remove-method gf old-method))
	(add-method gf new-method)))

    An alternate proposal would be to give the caller of add-named-method
    more control over the arguments passed to ensure-generic-function.  My
    feeling is that it isn't worth cluttering up add-named-method to do
    that.  If someone wants more control over the arguments to
    ensure-generic-function they can call it directly.

After thinking about the above three paragraphs a bit, I think this is
wrong modularity, by your own arguments.  I think the caller of
add-named-method should -always- call ensure-generic-function himself.
That is, defmethod really consists of two parts, defining the generic
function if not already defined, and defining/replacing the method.
These two parts should not be combined in the macro expansion.  Thus
the arguments to add-named-method should be a prototype method (the
usual kludge for class-discriminating methods) and some keyword arguments
that include a generic function object, qualifiers, specializers, the
method function, and some others that are optional.

The way that add-named-method -is- different from add-named-class and
add-named-generic-function (ahem) is that add-named-method doesn't have
a symbol as a name, instead the conceptual name (something that
identifies a prior object to be replaced) is composed of the generic
function, the specializers, and the qualifiers.  That difference is
inherent, but the other differences in your most recent draft are
accidental and should be eliminated.  I think this is the reasoning
behind the sentiment for making these things more uniform.

Does this make sense to you?