From: ············@gmail.com
Subject: CLOS method dispatch Q
Date: 
Message-ID: <d02b08c6-0cd5-4bdd-abcd-599c73527c0f@p25g2000hsf.googlegroups.com>
Hello friends,

In the context of a general CSP solver, I want to override default
method behavior -- originally defined in package A -- in another
package.  The following example shows the trouble I'm having.

>>> EXAMPLE <<<

CL-USER> (defpackage :a (:use :cl))

CL-USER> (in-package :a)

A> (defclass a () ())

A> (defmethod process-and-say-bye ((x a)) (process x) (print "bye"))

A> (defmethod process ((x a)) (print "processing a"))

A> (in-package :cl-user)

CL-USER> (defclass b (a::a) ())

CL-USER> (defmethod process ((x b)) (print "processing b"))

CL-USER> (a::process-and-say-bye (make-instance 'b))
"processing a"
"bye"

>>> END EXAMPLE <<<

I would like that last REP to print: "processing b" "bye".

In my definition of a::process-and-say-goodbye, it is a::process that
is being invoked.  Is there any way to create a class in package b
(here CL-USER) that will change the behavior of a::process-and-say-
goodbye by changing which process method is called?

Many thanks,

Andrew

From: Kenny
Subject: Re: CLOS method dispatch Q
Date: 
Message-ID: <4873aca6$0$7323$607ed4bc@cv.net>
············@gmail.com wrote:
> Hello friends,
> 
> In the context of a general CSP solver, I want to override default
> method behavior -- originally defined in package A -- in another
> package.  The following example shows the trouble I'm having.
> 
>>>> EXAMPLE <<<
> 
> CL-USER> (defpackage :a (:use :cl))
> 
> CL-USER> (in-package :a)
> 
> A> (defclass a () ())
> 
> A> (defmethod process-and-say-bye ((x a)) (process x) (print "bye"))
> 
> A> (defmethod process ((x a)) (print "processing a"))
> 
> A> (in-package :cl-user)
> 
> CL-USER> (defclass b (a::a) ())
> 
> CL-USER> (defmethod process ((x b)) (print "processing b"))

here you introduce a brandy new GF for the symbol cl-user::process, 
which is your problem. more below.

> 
> CL-USER> (a::process-and-say-bye (make-instance 'b))
> "processing a"
> "bye"
> 
>>>> END EXAMPLE <<<
> 
> I would like that last REP to print: "processing b" "bye".
> 
> In my definition of a::process-and-say-goodbye, it is a::process that
> is being invoked.  Is there any way to create a class in package b
> (here CL-USER) that will change the behavior of a::process-and-say-
> goodbye by changing which process method is called?

The problem is not the classes, the problem is having two GFs named 
process, one on the symbol a::process and one fbound to the symbol 
cl-user::process.

ie, unlike other object models methods are not associated with classes, 
they are associated with GFs by being bound to the same symbol.

So the main problem above is the package madness. Had you thought things 
through and not cheated with the :: probe you would have concluded you 
need to export the symbol process from package A. Maybe. :) Anyway, you 
would then have been a good programmer and /used/ package A instead of 
a:ing things. And then when you defined the process method it would have 
joined the others on the one true GF you had in mind.

hth,kzo
From: Rainer Joswig
Subject: Re: CLOS method dispatch Q
Date: 
Message-ID: <joswig-19C319.20200208072008@news-europe.giganews.com>
In article 
<····································@p25g2000hsf.googlegroups.com>,
 ·············@gmail.com" <············@gmail.com> wrote:

> Hello friends,
> 
> In the context of a general CSP solver, I want to override default
> method behavior -- originally defined in package A -- in another
> package.  The following example shows the trouble I'm having.
> 
> >>> EXAMPLE <<<
> 
> CL-USER> (defpackage :a (:use :cl))
> 
> CL-USER> (in-package :a)
> 
> A> (defclass a () ())
> 
> A> (defmethod process-and-say-bye ((x a)) (process x) (print "bye"))
> 
> A> (defmethod process ((x a)) (print "processing a"))
> 
> A> (in-package :cl-user)
> 
> CL-USER> (defclass b (a::a) ())
> 
> CL-USER> (defmethod process ((x b)) (print "processing b"))
> 
> CL-USER> (a::process-and-say-bye (make-instance 'b))
> "processing a"
> "bye"
> 
> >>> END EXAMPLE <<<
> 
> I would like that last REP to print: "processing b" "bye".
> 
> In my definition of a::process-and-say-goodbye, it is a::process that
> is being invoked.  Is there any way to create a class in package b
> (here CL-USER) that will change the behavior of a::process-and-say-
> goodbye by changing which process method is called?
> 
> Many thanks,
> 
> Andrew


Hi,

methods are assembled in generic functions.
You have two different generic functions:

1) a::process
2) cl-user::process

The function names are different. 

You may want to have only one!?!

Use:

(defmethod a::process ((x b)) (print "processing b"))

Actually you also may want to export a::process so you
can write:

(defmethod a:process ((x b)) (print "processing b"))

Note that there is only one colon.

You may also want to create your own package and import
functions like a:process.

-- 
http://lispm.dyndns.org/
From: ············@gmail.com
Subject: Re: CLOS method dispatch Q
Date: 
Message-ID: <9f4c2f45-db44-471b-9f34-474afa061b48@p25g2000hsf.googlegroups.com>
Thanks Rainer and Ken.  Your suggestion works great:

CL-USER> (defpackage :a
	   (:export :a :p-and-say-bye :p)
	   (:use :cl))

CL-USER> (in-package :a)

A> (defclass a () ())

A> (defmethod p ((x a))
     (print "processing a"))

A> (defmethod p-and-say-bye ((x a))
     (p x)
     (print "bye"))

A> (in-package :cl-user)

CL-USER> (defpackage :b (:use :cl :a))

CL-USER> (in-package :b)

B> (defclass b (a) ())

B> (defmethod p ((x b))
     (print "processing b"))

B> (p-and-say-bye (make-instance 'b))

"processing b"
"bye"
"bye"