[Openmcl-devel] GF invocation protocol

Vyacheslav Akhmechet coffeemug at gmail.com
Tue Sep 18 10:42:48 PDT 2007


On 9/18/07, Pascal Costanza <pc at p-cos.net> wrote:
> This looks very interesting. Maybe I'll add this to Closer to MOP -
> or are there plans to add this to OpenMCL directly?
I'd be happy to hack this into OpenMCL if the dev team finds this
approach acceptable. The only thing that really needs to be done
(beyond adding a default specialization of
compute-discriminating-function) is adding a case to add-method,
remove-method, initialize-instance, and reinitialize-instance to
set-funcallable-instance if their argument is a subclass of
standard-generic-function. Since this will only affect performance at
load-time (and it's a single branch) this probably isn't a big deal.

This still doesn't account for compute-applicable-methods and
compute-applicable-methods-using-classes but it it's a start.

> The two cases %%one-arg-dcode and %%1st-two-arg-dcode look the same
> to me, but it seems to be that this is correct, right?
Yes, the case is the same. This can really be an OR.

> Have you been able to "convince" other CL implementations as well to
> make compute-discriminating-function work?
This morning I received an email from Franz saying that their
treatment of compute-discriminating-function is a bug and they're
working on a patch. Meanwhile, I put in a workaround that sets the
funcallable-instance back to the custom discriminating function after
it is called. I could do this because I use a custom macro instead of
defmethod, but without that I don't think it can work (you can't just
do it in discriminating function itself because of possibility of
recursive calls). It also requires a lock to prevent another thread
from calling the function between the time it's been set to a custom
trampoline by ACL and was reset back by my code. It works very well
for me but I'm not sure if it's generic enough to be put into
CloserMOP.

I also found a workaround for CMUCL. Main issue is that it's not
possible to get a default discriminating function via call-next-method
because their version of compute-discriminating-function returns a
trampoline. A workaround is to call
pcl::default-secondary-dispatch-function instead. It's pretty easy to
make it generic: just shadow CMUCL's version of
compute-discriminating-function with your own that calls CMU's version
for standard-generic-function and calls
pcl::default-secondary-dispatch-function for its subclasses. This way
call-next-method will work correctly on specializations of
compute-discriminating-function.

Another CMUCL issue is that it's not possible to return a closure
(this works in some cases but not in others, not sure why). So,
instead of returning a closure I call COMPILE. I'm not sure how to
make this workaround generic.

This CMUCL solution is rather slow for subclasses of
standard-generic-function because A)
pcl::default-secondary-generic-function doesn't cache the effective
method and needs to determine it and compile it on the stop and B)
compile needs to be called because closures can't be returned. The
speed hit is acceptable to me. A different way to fix this in CMUCL
which doesn't require any runtime compilation is to set the
funcallable instance to the result of compute-discriminating-function,
storing the original funcallable instance value somewhere. Then,
instead of calling call-next-method one can reset back the value of
funcallable-instance and simply call the generic function. This works,
but unfortunately requires a lock to prevent threading issues. I
decided not to use this for Weblocks, but it might be an acceptable
solution for CloserMOP. A Weblocks patch that achieves this is here:
http://groups.google.com/group/weblocks/browse_thread/thread/660c7e1977c586fb
(note that I chose not to use this solution, but I verified that it
works).



More information about the Openmcl-devel mailing list