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


     I see.  Here's another way to write it that might make what you're doing
     easier to understand:
         (defmethod compute-discriminator-code 
             ((generic-function standard-generic-function))
           (let ((f (get-handler-for #'compute-effective-method
     	  #'(lambda (&rest args)
     	      (let* ((applicable-methods 
     		       (compute-applicable-methods generic-function args))
     		       (funcall f generic-function
     				applicable-methods)) ....
     get-handler-for is a new primitive that provides a proper separation
     between the act of finding the effective method function and the act of
     applying it.  This pulls the generic dispatch for
     compute-effective-method out of the loop.  This is mere code hoisting,
     except that it shows where to put the special case to break the

I am not too concerned by the circularity.  It amounts to a bootstrapping
problem.  All the chapter 3 generic function are instances of
standard-generic-function.  An implementation will code the discriminator code
for standard generic functions in a way that it does not have to interpret its
way through compute-applicable-method, compute-effective-method, etc.  every
time those standard-generic-functions are called.  However it probably has to do
it at least once sometimes.

I don't think that the guts of compute-discriminator-code, and the code it
produces should be standardized.  I don't see any problem in exposing the sub
primitives as long as they don't have to be not called every time a generic
function is called.  I think it should be explained the same way make-instance
is explained: logically, things happen like this (gregor code, kempf code or
moon's code), but implementations can short cut any of this as long as the
desired effect is obtained.