From: Slava Akhmechet
Subject: AllegroCL and compute-discriminating-function
Date: 
Message-ID: <87myvpj22o.fsf@gmail.com>
I have a small example that works on SBCL and LispWorks but breaks down on ACL:

(use-package :mop)

(defclass my-generic-function (standard-generic-function)
  ()
  (:metaclass funcallable-standard-class))

(defmethod compute-applicable-methods-using-classes ((gf my-generic-function) classes)
  (warn "hala")
  (values nil nil))

(defmethod compute-discriminating-function ((gf my-generic-function))
  (let* ((default-discriminating-function (call-next-method)))
    (lambda (a)
      (let ((*test* 15))
	(declare (special *test*))
	(funcall default-discriminating-function a)))))

(defgeneric test (a)
  (:generic-function-class my-generic-function))

(defmethod test (a)
  (declare (special *test*))
  (+ a *test*))

Calling #'test the first time works. Calling it the second time (and
after that) fails because the special variable *test* is not bound. It
turns out that ACL only calls the discriminating function once. I am
not sure when it manages to install a different discriminating
function but I'm pretty sure it's not compliant with MOP.

Am I doing something wrong or is it a bug in ACL? Does anyone know of
a workaround?

-- 
Regards,
Slava Akhmechet.

From: Christophe
Subject: Re: AllegroCL and compute-discriminating-function
Date: 
Message-ID: <1189755169.398920.320480@50g2000hsm.googlegroups.com>
On 14 sep, 06:36, Slava Akhmechet <·········@gmail.com> wrote:
> I have a small example that works on SBCL and LispWorks but breaks down on ACL:
>
> (use-package :mop)
>
> (defclass my-generic-function (standard-generic-function)
>   ()
>   (:metaclass funcallable-standard-class))
>
> (defmethod compute-applicable-methods-using-classes ((gf my-generic-function) classes)
>   (warn "hala")
>   (values nil nil))
>
> (defmethod compute-discriminating-function ((gf my-generic-function))
>   (let* ((default-discriminating-function (call-next-method)))
>     (lambda (a)
>       (let ((*test* 15))
>         (declare (special *test*))
>         (funcall default-discriminating-function a)))))
>
> (defgeneric test (a)
>   (:generic-function-class my-generic-function))
>
> (defmethod test (a)
>   (declare (special *test*))
>   (+ a *test*))
>
> Calling #'test the first time works. Calling it the second time (and
> after that) fails because the special variable *test* is not bound. It
> turns out that ACL only calls the discriminating function once. I am
> not sure when it manages to install a different discriminating
> function but I'm pretty sure it's not compliant with MOP.
>
> Am I doing something wrong or is it a bug in ACL? Does anyone know of
> a workaround?
>
> --
> Regards,
> Slava Akhmechet.

Hello,

I try it with ACL 8.1 and that works fine.

Regards.
From: Kyle McGivney
Subject: Re: AllegroCL and compute-discriminating-function
Date: 
Message-ID: <1189773934.552971.310900@19g2000hsx.googlegroups.com>
On Sep 14, 3:32 am, Christophe
<····················@birdtechnology.net> wrote:
> On 14 sep, 06:36, Slava Akhmechet <·········@gmail.com> wrote:
>
>
>
>
>
> > I have a small example that works on SBCL and LispWorks but breaks down on ACL:
>
> > (use-package :mop)
>
> > (defclass my-generic-function (standard-generic-function)
> >   ()
> >   (:metaclass funcallable-standard-class))
>
> > (defmethod compute-applicable-methods-using-classes ((gf my-generic-function) classes)
> >   (warn "hala")
> >   (values nil nil))
>
> > (defmethod compute-discriminating-function ((gf my-generic-function))
> >   (let* ((default-discriminating-function (call-next-method)))
> >     (lambda (a)
> >       (let ((*test* 15))
> >         (declare (special *test*))
> >         (funcall default-discriminating-function a)))))
>
> > (defgeneric test (a)
> >   (:generic-function-class my-generic-function))
>
> > (defmethod test (a)
> >   (declare (special *test*))
> >   (+ a *test*))
>
> > Calling #'test the first time works. Calling it the second time (and
> > after that) fails because the special variable *test* is not bound. It
> > turns out that ACL only calls the discriminating function once. I am
> > not sure when it manages to install a different discriminating
> > function but I'm pretty sure it's not compliant with MOP.
>
> > Am I doing something wrong or is it a bug in ACL? Does anyone know of
> > a workaround?
>
> > --
> > Regards,
> > Slava Akhmechet.
>
> Hello,
>
> I try it with ACL 8.1 and that works fine.
>
> Regards.- Hide quoted text -
>
> - Show quoted text -

On the other hand, I tried it with ACL 8.1 and no such luck.
From: Pascal Costanza
Subject: Re: AllegroCL and compute-discriminating-function
Date: 
Message-ID: <5kulpjF5kj75U1@mid.individual.net>
Slava Akhmechet wrote:
> I have a small example that works on SBCL and LispWorks but breaks down on ACL:
> 
> (use-package :mop)
> 
> (defclass my-generic-function (standard-generic-function)
>   ()
>   (:metaclass funcallable-standard-class))
> 
> (defmethod compute-applicable-methods-using-classes ((gf my-generic-function) classes)
>   (warn "hala")
>   (values nil nil))
> 
> (defmethod compute-discriminating-function ((gf my-generic-function))
>   (let* ((default-discriminating-function (call-next-method)))
>     (lambda (a)
>       (let ((*test* 15))
> 	(declare (special *test*))
> 	(funcall default-discriminating-function a)))))
> 
> (defgeneric test (a)
>   (:generic-function-class my-generic-function))
> 
> (defmethod test (a)
>   (declare (special *test*))
>   (+ a *test*))
> 
> Calling #'test the first time works. Calling it the second time (and
> after that) fails because the special variable *test* is not bound. It
> turns out that ACL only calls the discriminating function once. I am
> not sure when it manages to install a different discriminating
> function but I'm pretty sure it's not compliant with MOP.
> 
> Am I doing something wrong or is it a bug in ACL? 

This is a bug in ACL, the discriminating function should always be 
called. My guess would be that they perform an optimization that is 
valid for standard-generic-function, but shouldn't be applied for 
generic function classes that specialize compute-discriminating-function.

I have already reported related bugs to Franz, you should probably file 
this one as well to help them fix this.

> Does anyone know of a workaround?

Here is a guess, untested:

(defmethod compute-discriminating-function ((gf my-generic-function))
   (let ((df (call-next-method)))
     (lambda (&rest args)
       (do-stuff)
       (multiple-value-prog1
         (apply df args)
         (reinitialize-instance gf)))))

In case this works, you will lose all method caching though, so 
performance will be seriously degraded for such generic functions.


Pascal

P.S.: I will add your test case to Closer to MOP.

-- 
My website: http://p-cos.net
Common Lisp Document Repository: http://cdr.eurolisp.org
Closer to MOP & ContextL: http://common-lisp.net/project/closer/
From: Slava Akhmechet
Subject: Re: AllegroCL and compute-discriminating-function
Date: 
Message-ID: <87hclxxizf.fsf@gmail.com>
Pascal Costanza <··@p-cos.net> writes:

> I have already reported related bugs to Franz, you should probably
> file this one as well to help them fix this.
I reported this yesterday, but I'm using the free edition of ACL so
there's strong likelyhood they'll ignore me :)

> In case this works, you will lose all method caching though, so
> performance will be seriously degraded for such generic functions.
A less radical workaround that I found is to reset the GF's
funcallable instance in the custom discriminating function back to
itself after it calls the default discriminating function. This works
too and shouldn't affect performance so much.

-- 
Regards,
Slava Akhmechet.
From: Pascal Costanza
Subject: Re: AllegroCL and compute-discriminating-function
Date: 
Message-ID: <5qracvF117omvU1@mid.individual.net>
Slava Akhmechet wrote:
> Pascal Costanza <··@p-cos.net> writes:
> 
>> I have already reported related bugs to Franz, you should probably
>> file this one as well to help them fix this.
> I reported this yesterday, but I'm using the free edition of ACL so
> there's strong likelyhood they'll ignore me :)
> 
>> In case this works, you will lose all method caching though, so
>> performance will be seriously degraded for such generic functions.
> A less radical workaround that I found is to reset the GF's
> funcallable instance in the custom discriminating function back to
> itself after it calls the default discriminating function. This works
> too and shouldn't affect performance so much.

That's probably what the 'inherited' discriminating function does as 
well, although it probably doesn't set it to itself, but to an optimized 
version of itself. There is actually nothing in the CLOS MOP 
specification that prohibits a discriminating function from doing that. 
So your workaround will probably also lose in terms of efficiency.

My impression by now is that the CLOS MOP designers assumed that you 
don't use the original discriminating function, but build a new one 
completely from scratch.

I don't see how I could provide a workaround in Closer to MOP with the 
current state of the CLOS MOP specification. Sorry...


Pascal

-- 
My website: http://p-cos.net
Common Lisp Document Repository: http://cdr.eurolisp.org
Closer to MOP & ContextL: http://common-lisp.net/project/closer/
From: Cor Gest
Subject: Re: AllegroCL and compute-discriminating-function
Date: 
Message-ID: <87r6ifxq67.fsf@cleopatra.clsnet.nl>
Some entity, AKA Slava Akhmechet <·········@gmail.com>,
wrote this mindboggling stuff:
(selectively-snipped-or-not-p)

> Pascal Costanza <··@p-cos.net> writes:
> 
> > I have already reported related bugs to Franz, you should probably
> > file this one as well to help them fix this.
> I reported this yesterday, but I'm using the free edition of ACL so
> there's strong likelyhood they'll ignore me :)

Well, as an acl8.0-trial (gratuit) user I had a very good follow-up and
_real_ help over an strange 'newlicence' issue which occured in my setup.   
all was solved whithin a couple of mails, ....kudo's to Franz.
  
Cor

-- 
Alle schraifvauden zijn opzettelijk, teneinde ieder lafaard de kans te 
 geven over spelling te zeuren in plaats van in te gaan op de inhoud.
    (defvar My-Computer '((OS . "GNU/Emacs") (IPL . "GNU/Linux")))
                http://www.clsnet.nl/mail.php