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

notice-methods-change and my lexical environment too



(NOTICE-METHODS-CHANGE generic-function) contains the warning:

;; Note that because this closure will be the discriminator code
;; of a generic function it must be careful about how it changes
;; the discriminator code of that same generic function.  If it
;; isn't careful, it could change its closure variables out from
;; under itself.

So it is careful to be sure that any call to the generic function
after NOTICE-METHODS-CHANGE has returned will work even while the
discriminator is being changed.

However, NOTICE-METHODS-CHANGE calls
SET-FUNCALLABLE-INSTANCE-FUNCTION, which at least in #+Genera, will
smash the closure variables of the discriminator of the generic
function.  So if that discriminator happens to be running during the
call to NOTICE-METHODS-CHANGE, you suddenly have new free variables.

It is possible to avoid this by changing the defintion of funcallable
instances slightly, with probably little performance penalty.
However, it seems that all uses of NOTICE-METHODS-CHANGE (except
INVALIDATE-GENERIC-FUNCTION) really only want to flush the cache.

So, i propose that:

1.  the use of NOTICE-METHODS-CHANGE should be replaced with
    FLUSH-GENERIC-FUNCTION-CACHES (which should be atomic).

2.  INVALIDATE-GENERIC-FUNCTION should only be used inside DEFGENERIC,
    or places where you really want to change the generic function.  This
    could either:

  2.1  Smash the generic function, or,
  2.2  Change the generic function in a way that will not effect any
       running discriminators.


k