[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: MAKE-METHOD-FUNCTION and APPLY-METHOD
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
generic-function
(generic-function-method-combination
generic-function)
nil)))
#'(lambda (&rest args)
(let* ((applicable-methods
(compute-applicable-methods generic-function args))
(effective-method-form
(funcall f generic-function
(generic-function-method-combination
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
circularity.
Reactions?
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.
Patrick.