Caching of effective methods in custom method combinations

Pascal Costanza pc at p-cos.net
Tue Jul 21 10:16:40 UTC 2015


> On 21 Jul 2015, at 09:46, Edi Weitz <edi at weitz.de> wrote:
> 
> Hi everybody,
> 
> Here's some behavior I see on SBCL as well as LispWorks, so I'm
> assuming for now they're right in doing so.  My question would be why
> they are.
> 
> I start with the following code which I compile and load:
> 
>  ;;;;;;;;;;;;;;;;;;;;;;;;
> 
>  (defvar *current-qualifiers* '(:a :b :c))
> 
>  (define-method-combination test ()
>      ((methods *))
>    (let ((selected-methods (loop for method in methods
>                                  when (intersection (method-qualifiers method)
>                                                     *current-qualifiers*)
>                                    collect method)))
>      `(call-method ,(first selected-methods)
>                    ,(rest selected-methods))))
> 
>  (defgeneric foo (thing)
>    (:method-combination test))
>  (defmethod foo :a (thing)
>    '(:red))
>  (defmethod foo :b (thing)
>    '(:blue))
> 
>  ;;;;;;;;;;;;;;;;;;;;;;;;;;
> 
> Now, in the REPL I do the following:
> 
>  CL-USER> (foo 42)
>  (:BLUE)
>  CL-USER> (setq *current-qualifiers* '(:a :c))
>  (:A :C)
>  CL-USER> (foo 42)
>  (:BLUE)
> 
> I almost expected this.  The effective method obviously isn't computed
> anew but was cached.  But even if I now re-evaluate the
> DEFINE-METHOD-COMBINATION form, (FOO 42) will still return (:BLUE).
> Only if I re-evaluate the DEFGENERIC form will the return value change
> to (:RED).

There is no protocol, neither in Common Lisp, nor in AMOP, that specifies what happens when a method combination is redefined. I believe an implementation would even be right to completely ignore redefinitions. What you’re seeing when you evaluate the defgeneric form again is that this triggers a reinitialize-instance of the generic function metaobject with the new method combination object.

> My question is if the standard somewhere allows this caching to
> happen.  That would for example mean that any kind of "dynamic method
> combination" (for example based on the time of the day, just for
> grins) is impossible.

The standard doesn’t /disallow/ this form of caching to happen. You can indeed not express something like “dynamic method combinations” - you should rather define your own generic function metaobject class to do something like this.

Pascal

--
Pascal Costanza
The views expressed in this email are my own, and not those of my employer.






More information about the pro mailing list