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

Re: MOP Comments (Repost) - 2 3 4 5a



    Date: Wed, 09 Dec 87 15:54:15 MST
    From: kempf%hplabsz@hplabs.HP.COM

    Yes, this will work if the implementor of CLOS implements 
    COMPUTE-DISCRIMINATOR-CODE with the optimizations I've outlined, but here's 
    another example. A user wants to implement a discrimintor which caches 
    and uncaches data before and after a method invocation, if the method 
    being invoked references a persistent object. Unless there is some interface for
    generating discriminators, the only way to do this is by :BEFORE and
    :AFTER methods around COMPUTE-DISCRIMINATOR-CODE, which might have to undo
    things done by the primary, if the user wants to continue using the default
    STANDARD-GENERIC-FUNCTION. 

Well :before and :after methods on compute-discriminator-code won't do
any good since compute-discriminator-code is called at defmethod time
not generic function invocation time.
			       
			       Of course, it would be possible to say that
    user accessable MOP hooks are not available at that low a level (which
    essentially corresponds to hooks at the level of FUNCALLABLE-INSTANCE-CLASS).
    But this example is something which came up in a real application, and
    the only solution, if we wanted to continue using the standard generic
    function class,  we could find using the current CLOS is to define user
    level :BEFORE and :AFTER daemons around *every* method which accesses
    a  persistent object. This seems like a less elegent solution than
    providing a metaclass hook.

I see.  I think the real problem is that compute-effective-method-body
isn't receiving the variables which will hold the actual arguments as
arguments.  In other words it doesn't have access to the same facility
make-method-call does.  Suppose there were a function called
make-function-call which took one argument (a function) and called it on
the arguments received by the generic function.  Like make-method-call,
these could be used in the body of effective-methods.  Then you could
get the behavior you want by saying:

(defmethod compute-effective-method ((gf my-gf) ...)
  `(progn ,(make-function-call #'encache-data)
          ,(call-next-method)
          ,(make-function-call #'decache-data)))

You wouldn't lose any of the performance of the native method lookup
mechanism.  There wouldn't have to be :before and :after methods for
every method.  This would be something that would work with any method
combination type, you could change the method combination type out from
under this and everything would still be fine.

I will try to add something like this to the next round of the mop
draft.  Clearly it is important.  building a better abstraction for
make-function-call and make-method-call is what is required.  The
difficulty is going to be keeping the way the particular implementation
of effective methods chooses to pass around the arguments abstract.

    > Extending the defclass and slot options for a class already works.  I
    > think the sentence "If there are any syntactic errors in the defclass
    > form an error is signalled" is confusing.  All this sentence is saying
    > is that it takes the cadr of the defclass form and makes it be the name,
    > the caddr and its the supers, the cadddr is the slots and the cddddr is
    > the options.  If for some reason it can't do that minimal parsing an
    > error is signalled.  

    What about slot parsing? Is any error checking done on the options before
    calling EXPAND-DEFCLASS?

No error checking is done before calling expand-defclass.
slot-description-class and the initialize-instance method for the
slot-description class do all the error checking on the slot options.
legal-class-option-p does all the error-checking on class options.

-------