From: Yarek Kowalik
Subject: Is there a call-NEXT-next-method, or casting in CLOS?
Date: 
Message-ID: <429e8636-1b84-4130-965f-b16f70ff14f1@a2g2000prm.googlegroups.com>
This is a general CLOS question that I have run into a few times this
past week and I don't know how to solve.

I have a base class foo that has a method do-action.

(method do-action ((obj foo))
  .... )

I also have a subclass bar of foo that specializes the method do-
action

(method do-action ((obj bar))
  .... )

Now, I have a baz subclass of bar for which I don't want bar's do-
action, but instead I want base class foo's do-action.  Therefore, I
cannot call call-next-method, since that would invoke bar's do-action.

Is there a way to type cast baz to foo so that I can invoke do-action
for foo from baz?  Or is there a techique for makeing a call-next-next-
method or equivalent?

Thanks,

Yarek

From: Tim Bradshaw
Subject: Re: Is there a call-NEXT-next-method, or casting in CLOS?
Date: 
Message-ID: <b8d648bb-8b38-45f9-96d6-2c9701cbc880@c58g2000hsc.googlegroups.com>
On Aug 12, 7:37 am, Yarek Kowalik <·············@gmail.com> wrote:
> This is a general CLOS question that I have run into a few times this
> past week and I don't know how to solve.
>
> I have a base class foo that has a method do-action.
>
> (method do-action ((obj foo))
>   .... )
>
> I also have a subclass bar of foo that specializes the method do-
> action
>
> (method do-action ((obj bar))
>   .... )
>
> Now, I have a baz subclass of bar for which I don't want bar's do-
> action, but instead I want base class foo's do-action.  Therefore, I
> cannot call call-next-method, since that would invoke bar's do-action.

Why is BAZ a subclass of BAR if you want it to be a subclass of FOO?
If you want some behaviour (DO-ACTION) from FOO and some from BAR
(what?), then use MI.
From: Kenny
Subject: Re: Is there a call-NEXT-next-method, or casting in CLOS?
Date: 
Message-ID: <48a13352$0$20934$607ed4bc@cv.net>
Yarek Kowalik wrote:
> This is a general CLOS question that I have run into a few times this
> past week and I don't know how to solve.
> 
> I have a base class foo that has a method do-action.
> 
> (method do-action ((obj foo))
>   .... )
> 
> I also have a subclass bar of foo that specializes the method do-
> action
> 
> (method do-action ((obj bar))
>   .... )
> 
> Now, I have a baz subclass of bar for which I don't want bar's do-
> action, but instead I want base class foo's do-action.  Therefore, I
> cannot call call-next-method, since that would invoke bar's do-action.
> 
> Is there a way to type cast baz to foo so that I can invoke do-action
> for foo from baz?  Or is there a techique for makeing a call-next-next-
> method or equivalent?

I think you are just confused about either your class hierarchy or 
do-action or both. Or primary vs. around methods. It is hard to tell 
from the cheap seats.

I have never found any use for call-next-method on primary methods, tho 
it is legal, so just figuring out how you got to that point and 
refactoring it away might solve your problem.

Most likely your solution is to have two gf's, do-action and 
do-auxiliary-action. My second guess is that baz is not /really/ s 
subclass of bar.

hth, kt

-- 

$$$$$: http://www.theoryyalgebra.com/
Cells: http://common-lisp.net/project/cells/
BSlog: http://smuglispweeny.blogspot.com/
From: Kenny
Subject: Re: Is there a call-NEXT-next-method, or casting in CLOS?
Date: 
Message-ID: <48a138cd$0$7336$607ed4bc@cv.net>
Kenny wrote:
> Yarek Kowalik wrote:
>> This is a general CLOS question that I have run into a few times this
>> past week and I don't know how to solve.
>>
>> I have a base class foo that has a method do-action.
>>
>> (method do-action ((obj foo))
>>   .... )
>>
>> I also have a subclass bar of foo that specializes the method do-
>> action
>>
>> (method do-action ((obj bar))
>>   .... )
>>
>> Now, I have a baz subclass of bar for which I don't want bar's do-
>> action, but instead I want base class foo's do-action.  Therefore, I
>> cannot call call-next-method, since that would invoke bar's do-action.
>>
>> Is there a way to type cast baz to foo so that I can invoke do-action
>> for foo from baz?  Or is there a techique for makeing a call-next-next-
>> method or equivalent?
> 
> I think you are just confused about either your class hierarchy or 
> do-action or both. Or primary vs. around methods. It is hard to tell 
> from the cheap seats.
> 
> I have never found any use for call-next-method on primary methods, tho 
> it is legal, so just figuring out how you got to that point and 
> refactoring it away might solve your problem.
> 
> Most likely your solution is to have two gf's, do-action and 
> do-auxiliary-action. My second guess is that baz is not /really/ s 
> subclass of bar.
> 
> hth, kt
> 

I forgot to say, "no". :)

kt

-- 

$$$$$: http://www.theoryyalgebra.com/
Cells: http://common-lisp.net/project/cells/
BSlog: http://smuglispweeny.blogspot.com/
From: ·············@gmail.com
Subject: Re: Is there a call-NEXT-next-method, or casting in CLOS?
Date: 
Message-ID: <18107eae-62f5-475d-9a47-e1fcfd2298b7@p25g2000hsf.googlegroups.com>
On Aug 12, 2:52 am, Kenny <·········@gmail.com> wrote:
> Yarek Kowalik wrote:
> > This is a general CLOS question that I have run into a few times this
> > past week and I don't know how to solve.
>
> > I have a base class foo that has a method do-action.
>
> > (method do-action ((obj foo))
> >   .... )
>
> > I also have a subclass bar of foo that specializes the method do-
> > action
>
> > (method do-action ((obj bar))
> >   .... )
>
> > Now, I have a baz subclass of bar for which I don't want bar's do-
> > action, but instead I want base class foo's do-action.  Therefore, I
> > cannot call call-next-method, since that would invoke bar's do-action.
>
> > Is there a way to type cast baz to foo so that I can invoke do-action
> > for foo from baz?  Or is there a techique for makeing a call-next-next-
> > method or equivalent?
>
> I think you are just confused about either your class hierarchy or
> do-action or both. Or primary vs. around methods. It is hard to tell
> from the cheap seats.
>
> I have never found any use for call-next-method on primary methods, tho
> it is legal, so just figuring out how you got to that point and
> refactoring it away might solve your problem.
>
> Most likely your solution is to have two gf's, do-action and
> do-auxiliary-action. My second guess is that baz is not /really/ s
> subclass of bar.
>
> hth, kt
>
> --
>
> $$$$$:http://www.theoryyalgebra.com/
> Cells:http://common-lisp.net/project/cells/
> BSlog:http://smuglispweeny.blogspot.com/

Can't you do anything else but critique ;-)

But, seriously, I am wondering about the same thing too.  My head is
stuck in this, ..., um OO space, and I am struggling to come up for
some fresh air.  I came to lisp trying to escape these so complex oo
constructions, and I'm still trying to figure it out.   Maybe I should
spend time looking at other people's code.

When I look at my code, all of it could be done (I think) with some
decent macro programming, because after all, that is all I am doing:
Combining storage, and methods to achieve some kind of behavior.  But
I am only now getting semi comfortable with macros, and from
experience, that is the most dangerous phase :-)

Now it is too late to change the program.  I gotta deliver some
results.

Cheers,

Mirko
From: Kenny
Subject: Re: Is there a call-NEXT-next-method, or casting in CLOS?
Date: 
Message-ID: <48dd3d5f$0$4904$607ed4bc@cv.net>
·············@gmail.com wrote:
> On Aug 12, 2:52 am, Kenny <·········@gmail.com> wrote:
> 
>>Yarek Kowalik wrote:
>>
>>>This is a general CLOS question that I have run into a few times this
>>>past week and I don't know how to solve.
>>
>>>I have a base class foo that has a method do-action.
>>
>>>(method do-action ((obj foo))
>>>  .... )
>>
>>>I also have a subclass bar of foo that specializes the method do-
>>>action
>>
>>>(method do-action ((obj bar))
>>>  .... )
>>
>>>Now, I have a baz subclass of bar for which I don't want bar's do-
>>>action, but instead I want base class foo's do-action.  Therefore, I
>>>cannot call call-next-method, since that would invoke bar's do-action.
>>
>>>Is there a way to type cast baz to foo so that I can invoke do-action
>>>for foo from baz?  Or is there a techique for makeing a call-next-next-
>>>method or equivalent?
>>
>>I think you are just confused about either your class hierarchy or
>>do-action or both. Or primary vs. around methods. It is hard to tell
>>from the cheap seats.
>>
>>I have never found any use for call-next-method on primary methods, tho
>>it is legal, so just figuring out how you got to that point and
>>refactoring it away might solve your problem.
>>
>>Most likely your solution is to have two gf's, do-action and
>>do-auxiliary-action. My second guess is that baz is not /really/ s
>>subclass of bar.
>>
>>hth, kt
>>
>>--
>>
>>$$$$$:http://www.theoryyalgebra.com/
>>Cells:http://common-lisp.net/project/cells/
>>BSlog:http://smuglispweeny.blogspot.com/
> 
> 
> Can't you do anything else but critique ;-)

Sure. Try reversing the order of the arguments, then the integer 
specialization will decide the dispatch. Kludgy? Not at all. Your 
requirement /says/ that that being an integer is more important than the 
class of I forget. There ya go. If you simplified the example and in 
fact there are five parameters and sometimes when there is an integer 
you do want the class to decide the dispatch then things fall apart and 
TfB the Younger gets the last word.

hth,kxo
From: Russell McManus
Subject: Re: Is there a call-NEXT-next-method, or casting in CLOS?
Date: 
Message-ID: <874p42mv7l.fsf@thelonious.cl-user.org>
Kenny <·········@gmail.com> writes:

> Sure. Try reversing the order of the arguments, then the integer
> specialization will decide the dispatch. Kludgy? Not at all. 

There is a DEFGENERIC option to determine precedence order as well,
IIRC.

-russ
From: Kenny
Subject: Re: Is there a call-NEXT-next-method, or casting in CLOS?
Date: 
Message-ID: <48dd7326$0$4977$607ed4bc@cv.net>
Russell McManus wrote:
> Kenny <·········@gmail.com> writes:
> 
> 
>>Sure. Try reversing the order of the arguments, then the integer
>>specialization will decide the dispatch. Kludgy? Not at all. 
> 
> 
> There is a DEFGENERIC option to determine precedence order as well,
> IIRC.

Nonsense!......Good lord, he's right. argument-precedence-order. What a 
great way to obfuscate my code!

However I now must concede that Common Lisp is a bloated beluga of a 
language -- I have found the feature I would never... well, hang on, 
doesn't count, this is CLOS-y, post lean-mean, brought to you by 
Kiczales who like Steele went on to fame in fortune in <spit> Java, full 
of features I would never use hence the best salesman Intel ever 
had...where was I?

You know, I think argument-precedence-order is useless unless we can 
make it method specific..... I'm afraid to look...

kzo
From: Pascal Costanza
Subject: Re: Is there a call-NEXT-next-method, or casting in CLOS?
Date: 
Message-ID: <6k6d7eF686vsU1@mid.individual.net>
Kenny wrote:
> You know, I think argument-precedence-order is useless unless we can 
> make it method specific..... I'm afraid to look...

Just because you don't know about a use for argument-precedence-order 
doesn't mean there isn't one.

I know of two uses:

+ If you have setter functions, the value to set is the first argument, 
and the object that 'receives' the new value is the second argument. You 
  can define generic setters like this:

(defgeneric (setf some-value) (new-value object))

However, this would mean that dispatch is based on new-value first, and 
then object, which is wrong. Argument-precedence-order can fix this:

(defgeneric (setf some-value) (new-value object)
   (:argument-precedence-order object new-value))

You could argue that this is an unfortunate implication caused by the 
fact that the new value in setters has to be the first argument, but 
that's how it is.


+ I also use argument-precedence-order in layered functions in ContextL 
to ensure that the layer argument has least precedence, which has to be 
added as the first implicit parameter in layered functions, for pretty 
much the same reason why new values in setters are first arguments as well.

Just because you don't know about a use for argument-precedence-order 
doesn't mean there isn't one.

If you want a variant of CLOS with less features, check out Swindle, 
which is part of PLT Scheme. Swindle doesn't have 
argument-precedence-order, if I recall correctly.


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: Kenny
Subject: Re: Is there a call-NEXT-next-method, or casting in CLOS?
Date: 
Message-ID: <48de3e2a$0$4961$607ed4bc@cv.net>
Pascal Costanza wrote:
> Kenny wrote:
> 
>> You know, I think argument-precedence-order is useless unless we can 
>> make it method specific..... I'm afraid to look...
> 
> 
> Just because you don't know about a use for argument-precedence-order 

...is a very bad sign for it.

> ... doesn't mean there isn't one.

You are just mad because I am going to have a black President before you 
have a Jewish Prime Minister.

kenny
From: Kenny
Subject: Re: Is there a call-NEXT-next-method, or casting in CLOS?
Date: 
Message-ID: <48dfcecf$0$5645$607ed4bc@cv.net>
Kenny wrote:
> Pascal Costanza wrote:
> 
>> Kenny wrote:
>>
>>> You know, I think argument-precedence-order is useless unless we can 
>>> make it method specific..... I'm afraid to look...
>>
>>
>>
>> Just because you don't know about a use for argument-precedence-order 
> 
> 
> ...is a very bad sign for it.
> 
>> ... doesn't mean there isn't one.
> 
> 
> You are just mad because I am going to have a black President before you 
> have a Jewish Prime Minister.

Damn, a one-punch knockout. I was hoping to pound on you for weeks. 
Well, to help the noobs (yeah, that's just an excuse):

> Kenny wrote:
> 
>> You know, I think argument-precedence-order is useless unless we can make it method specific..... I'm afraid to look...
> 
> 
> Just because you don't know about a use for argument-precedence-order doesn't mean there isn't one.
> 
> I know of two uses:
> 
> + If you have setter functions, the value to set is the first
> argument, and the object that 'receives' the new value is the second
> argument. You can define generic setters like this:
> 
> (defgeneric (setf some-value) (new-value object))

Dude that is not a "use". I cannot justify having a screen door on a 
submarine by saying "hey, what if I need a screen door on a submarine?"

What you need to do is come with a real-world case where there is a need 
to specialize a method on the value being set, there is a need to 
specialize on the object of the slot being set, and one needs the second 
method to take precedence over the first. You are not done. You also 
have to make sure that this example does not prove my point (or was it 
tfb's) that CLOS is probably being forced worse than sarah palin into 
the wrong role. To save iterations, please make sure :before and :around 
methods are not better ideas given the Deep Semantics of the semantics 
(assuming you are able to salvage the propriety of CLOS for this task, 
otherwise you are free to beat sarah to the voluntary withdrawal after 
the debate Thursday).

> 
> However, this would mean that dispatch is based on new-value first,
> and then object, which is wrong.

Wow, in the absolute? So we have that and the speed of light in a 
vacuum? Dude, you brilliantly demolished my argument in the last 
paragraph with an amazing example of two methods being mis-dispatched 
because of a vital specialization on the value being set. How can you 
say the default precedence is absolutely wrong? Maybe in the next 
example it is right?

Well, I am not smart like you PhD guys, maybe a case can be made, but I 
can never figure these things out without a concrete example.

> Argument-precedence-order can fix this:
> 
> (defgeneric (setf some-value) (new-value object)
>   (:argument-precedence-order object new-value))
> 
> You could argue that this is an unfortunate implication caused by the
> 
> fact that the new value in setters has to be the first argument, but
> that's how it is.

You mean the exception proves the rule? If the legislative history 
reveals :a-p-o was added to apologize for the argument order of setf I 
will call back the helicopters.

> + I also use argument-precedence-order in layered functions in
> ContextL... 

The product of someone obsessed with CLOS? I guess you would expect me 
to listen to Wall Street on the need for regulation.

>to ensure that the layer argument has least precedence, which
>has to be added as the first implicit parameter in layered functions,
for pretty much the same reason why new values in setters are first
arguments as well.
> 
> Just because you don't know about a use for argument-precedence-order doesn't mean there isn't one.
> 
> If you want a variant of CLOS with less features,..

...RDF is my life.

kt
From: ·············@gmail.com
Subject: Re: Is there a call-NEXT-next-method, or casting in CLOS?
Date: 
Message-ID: <7e008939-55be-478b-be0b-081c2722f988@z72g2000hsb.googlegroups.com>
On Sep 26, 3:51 pm, Kenny <·········@gmail.com> wrote:
> ·············@gmail.com wrote:
> > On Aug 12, 2:52 am, Kenny <·········@gmail.com> wrote:
>
> >>Yarek Kowalik wrote:
>
> >>>This is a general CLOS question that I have run into a few times this
> >>>past week and I don't know how to solve.
>
> >>>I have a base class foo that has a method do-action.
>
> >>>(method do-action ((obj foo))
> >>>  .... )
>
> >>>I also have a subclass bar of foo that specializes the method do-
> >>>action
>
> >>>(method do-action ((obj bar))
> >>>  .... )
>
> >>>Now, I have a baz subclass of bar for which I don't want bar's do-
> >>>action, but instead I want base class foo's do-action.  Therefore, I
> >>>cannot call call-next-method, since that would invoke bar's do-action.
>
> >>>Is there a way to type cast baz to foo so that I can invoke do-action
> >>>for foo from baz?  Or is there a techique for makeing a call-next-next-
> >>>method or equivalent?
>
> >>I think you are just confused about either your class hierarchy or
> >>do-action or both. Or primary vs. around methods. It is hard to tell
> >>from the cheap seats.
>
> >>I have never found any use for call-next-method on primary methods, tho
> >>it is legal, so just figuring out how you got to that point and
> >>refactoring it away might solve your problem.
>
> >>Most likely your solution is to have two gf's, do-action and
> >>do-auxiliary-action. My second guess is that baz is not /really/ s
> >>subclass of bar.
>
> >>hth, kt
>
> >>--
>
> >>$$$$$:http://www.theoryyalgebra.com/
> >>Cells:http://common-lisp.net/project/cells/
> >>BSlog:http://smuglispweeny.blogspot.com/
>
> > Can't you do anything else but critique ;-)
>
> Sure. Try reversing the order of the arguments, then the integer
> specialization will decide the dispatch. Kludgy? Not at all. Your
> requirement /says/ that that being an integer is more important than the
> class of I forget. There ya go. If you simplified the example and in
> fact there are five parameters and sometimes when there is an integer
> you do want the class to decide the dispatch then things fall apart and
> TfB the Younger gets the last word.
>
> hth,kxo

I apologize.  I thought you were responding to my post of Sep. 25, and
I was replying in jest (fist sentence) and seriously (following
paragraph).

Mirko
From: Rainer Joswig
Subject: Re: Is there a call-NEXT-next-method, or casting in CLOS?
Date: 
Message-ID: <joswig-E21DA5.10022412082008@news-europe.giganews.com>
In article 
<····································@a2g2000prm.googlegroups.com>,
 Yarek Kowalik <·············@gmail.com> wrote:

> This is a general CLOS question that I have run into a few times this
> past week and I don't know how to solve.
> 
> I have a base class foo that has a method do-action.
> 
> (method do-action ((obj foo))
>   .... )

Classes don't have methods in CLOS. That model is not applicable for CLOS.
Methods are defined outside of classes as parts of generic functions.
Methods can be specialized for more than one parameter, which makes the
'belongs to a class' idea even more false.

(defmethod do-something ((a foo) (b bar)) ... )
 
To which class should above method belong ?


> I also have a subclass bar of foo that specializes the method do-
> action
> 
> (method do-action ((obj bar))
>   .... )

Again, bar can't specialize methods, since classes don't
define methods and methods don't belong to classes.

You really need to be object-reoriented (see Peter Seibel's book
for that).

> Now, I have a baz subclass of bar for which I don't want bar's do-
> action, but instead I want base class foo's do-action.  Therefore, I
> cannot call call-next-method, since that would invoke bar's do-action.
> 
> Is there a way to type cast baz to foo so that I can invoke do-action
> for foo from baz?  Or is there a techique for makeing a call-next-next-
> method or equivalent?

Your problem looks a bit weird and you might want to redesign the whole thing.

But...


(defclass c1 () ())

(defclass c2 () ())

(defclass c3 () ())

See above, no methods. Classes don't take any methods.

I also haven't defined any inheritance above. 


(defmethod m1 ((a c1)) (print 'm1))

First Method m1 takes one argument of class c1.

(defmethod m1 ((a c2)) (print 'm2))

Second Method m1 takes one argument of class c2.


(defmethod m1 ((a c3)) 
  (funcall (method-function (find-method #'m1 () (list (find-class 'c1)))) a)
  (print 'm3))

Third method m3 takes one argument of class c3

FIND-METHOD finds a method based on a list of method-qualifiers and a list of specializers.
In this case the specializers list is just a list of the class c1.

METHOD-FUNCTION is a MOP function (not in ANSI CL, but defined by many CL implementations)
that gets the function of a method, funcall calls it with a.

This allows you to find a specific method and call it.


For your problem also:


(defclass c1 () ())

(defclass c2 (c1) ())

(defclass c3 (c2) ())

(defmethod m1 ((a c1))
  (print 'm1))

(defmethod m1 ((a c2))
  (if (eq (class-of a) (find-class 'c2))
      (print 'm2)
    (call-next-method)))

(defmethod m1 ((a c3))
  (call-next-method)
  (print 'm3))

If that's a really important pattern, you could make it a method combination where
you write in user code something like this:

(defmethod m1 :skip-if-not-exact-class-match ((a c2))
  (print 'm2))

> 
> Thanks,
> 
> Yarek

-- 
http://lispm.dyndns.org/
From: Yarek Kowalik
Subject: Re: Is there a call-NEXT-next-method, or casting in CLOS?
Date: 
Message-ID: <a2f9e64c-66a4-4ca2-a0ea-f558e1ba61ec@o40g2000prn.googlegroups.com>
Thanks for the useful feedback.  I'm in agreement that perhaps a
redesign is needed.   The trouble is that the foo and bar classes in
my case are somewhat outside of my direct control, yet I need to reuse
functionality of the generic function as applicable to foo.   I'm
going to think about this and suggest redesign to the code.
meanwhile,  The FIND-METHOD approach looks promising.

Thank you!!!

Yarek


On Aug 12, 1:02 am, Rainer Joswig <······@lisp.de> wrote:
> In article
> <····································@a2g2000prm.googlegroups.com>,
>  Yarek Kowalik <·············@gmail.com> wrote:
>
> > This is a general CLOS question that I have run into a few times this
> > past week and I don't know how to solve.
>
> > I have a base class foo that has a method do-action.
>
> > (method do-action ((obj foo))
> >   .... )
>
> Classes don't have methods in CLOS. That model is not applicable for CLOS.
> Methods are defined outside of classes as parts of generic functions.
> Methods can be specialized for more than one parameter, which makes the
> 'belongs to a class' idea even more false.
>
> (defmethod do-something ((a foo) (b bar)) ... )
>
> To which class should above method belong ?
>
> > I also have a subclass bar of foo that specializes the method do-
> > action
>
> > (method do-action ((obj bar))
> >   .... )
>
> Again, bar can't specialize methods, since classes don't
> define methods and methods don't belong to classes.
>
> You really need to be object-reoriented (see Peter Seibel's book
> for that).
>
> > Now, I have a baz subclass of bar for which I don't want bar's do-
> > action, but instead I want base class foo's do-action.  Therefore, I
> > cannot call call-next-method, since that would invoke bar's do-action.
>
> > Is there a way to type cast baz to foo so that I can invoke do-action
> > for foo from baz?  Or is there a techique for makeing a call-next-next-
> > method or equivalent?
>
> Your problem looks a bit weird and you might want to redesign the whole thing.
>
> But...
>
> (defclass c1 () ())
>
> (defclass c2 () ())
>
> (defclass c3 () ())
>
> See above, no methods. Classes don't take any methods.
>
> I also haven't defined any inheritance above.
>
> (defmethod m1 ((a c1)) (print 'm1))
>
> First Method m1 takes one argument of class c1.
>
> (defmethod m1 ((a c2)) (print 'm2))
>
> Second Method m1 takes one argument of class c2.
>
> (defmethod m1 ((a c3))
>   (funcall (method-function (find-method #'m1 () (list (find-class 'c1)))) a)
>   (print 'm3))
>
> Third method m3 takes one argument of class c3
>
> FIND-METHOD finds a method based on a list of method-qualifiers and a list of specializers.
> In this case the specializers list is just a list of the class c1.
>
> METHOD-FUNCTION is a MOP function (not in ANSI CL, but defined by many CL implementations)
> that gets the function of a method, funcall calls it with a.
>
> This allows you to find a specific method and call it.
>
> For your problem also:
>
> (defclass c1 () ())
>
> (defclass c2 (c1) ())
>
> (defclass c3 (c2) ())
>
> (defmethod m1 ((a c1))
>   (print 'm1))
>
> (defmethod m1 ((a c2))
>   (if (eq (class-of a) (find-class 'c2))
>       (print 'm2)
>     (call-next-method)))
>
> (defmethod m1 ((a c3))
>   (call-next-method)
>   (print 'm3))
>
> If that's a really important pattern, you could make it a method combination where
> you write in user code something like this:
>
> (defmethod m1 :skip-if-not-exact-class-match ((a c2))
>   (print 'm2))
>
>
>
> > Thanks,
>
> > Yarek
>
> --http://lispm.dyndns.org/
From: ·············@gmail.com
Subject: Re: Is there a call-NEXT-next-method, or casting in CLOS?
Date: 
Message-ID: <d80f6ae8-abd7-4e99-b8b6-30d7a0c1539b@e39g2000hsf.googlegroups.com>
On Aug 12, 4:02 am, Rainer Joswig <······@lisp.de> wrote:
> In article
> <····································@a2g2000prm.googlegroups.com>,
>  Yarek Kowalik <·············@gmail.com> wrote:
>
> > This is a general CLOS question that I have run into a few times this
> > past week and I don't know how to solve.
>
> > I have abaseclass foo that has amethoddo-action.
>
> > (methoddo-action ((obj foo))
> >   .... )
>
> Classes don't have methods in CLOS. That model is not applicable for CLOS.
> Methods are defined outside of classes as parts of generic functions.
> Methods can be specialized for more than one parameter, which makes the
> 'belongs to a class' idea even more false.
>
> (defmethod do-something ((a foo) (b bar)) ... )
>
> To which class should abovemethodbelong ?
>
> > I also have a subclass bar of foo that specializes themethoddo-
> > action
>
> > (methoddo-action ((obj bar))
> >   .... )
>
> Again, bar can't specialize methods, since classes don't
> define methods and methods don't belong to classes.
>
> You really need to be object-reoriented (see Peter Seibel's book
> for that).
>
> > Now, I have a baz subclass of bar for which I don't want bar's do-
> > action, but instead I wantbaseclass foo's do-action.  Therefore, I
> > cannotcallcall-next-method, since that would invoke bar's do-action.
>
> > Is there a way to type cast baz to foo so that I can invoke do-action
> > for foo from baz?  Or is there a techique for makeing acall-next-next-
> >methodor equivalent?
>
> Your problem looks a bit weird and you might want to redesign the whole thing.
>
> But...
>
> (defclass c1 () ())
>
> (defclass c2 () ())
>
> (defclass c3 () ())
>
> See above, no methods. Classes don't take any methods.
>
> I also haven't defined any inheritance above.
>
> (defmethod m1 ((a c1)) (print 'm1))
>
> FirstMethodm1 takes one argument of class c1.
>
> (defmethod m1 ((a c2)) (print 'm2))
>
> SecondMethodm1 takes one argument of class c2.
>
> (defmethod m1 ((a c3))
>   (funcall (method-function (find-method#'m1 () (list (find-class 'c1)))) a)
>   (print 'm3))
>
> Thirdmethodm3 takes one argument of class c3
>
> FIND-METHODfinds amethodbased on a list ofmethod-qualifiers and a list of specializers.
> In this case the specializers list is just a list of the class c1.
>
> METHOD-FUNCTION is a MOP function (not in ANSI CL, but defined by many CL implementations)
> that gets the function of amethod, funcall calls it with a.
>
> ... stuff deleted

I am having trouble extending this example  (I am mindful of the
comments other have made about the need to re-arrange the object
hierarchy, and I will say a bit about my problem below).

Anyway, here is my simple hierarchy.  (The difference from the above,
is that I am passing arguments to the methods, and that is where
things are braking.)
(in-package :cl-user)

(defclass base ()
  ((base-prop-1 :initform nil :accessor base-prop-1)))

(defclass super1a (base)
  ((super1a-prop-1 :initform 2
	:accessor super1a-prop-1)))

(defgeneric method1 (class arg &key &allow-other-keys)
  (:documentation "Execute operation"))

(defmethod method1 ((this base) (arg integer)  &key &allow-other-keys)
  arg)

(defmethod method1 ((this super1a) arg &key key1)
  (expt arg (or key1 (super1a-prop-1 this))))

;; invocation that does not work:
(let ((b (make-instance 'base))
	       (s (make-instance 'super1a)))
	   (print (method1 b 5))
	   (print (method1 s 5 :key1 3))
	   (apply (sb-mop:method-function
		     (find-method #'method1 '()
				  (list (find-class 'base) 'integer)))
		 s 5))

You can see that I specialized method1 on base & integer (following
the example from hyperspec), because that was the only way that I
could make find-method find the method.  I would prefer to leave the
integer specification blank for now, but then I did not know how to
specify the last argument of find-method.  It needed a two element
list, and I did not know how to specify the un-typed second argument.

My second problem is that apply fails. I am passing it the superobject
and the numeric argument, but it is asking for a type of list.

So much about the example itself.  Now a few words about why I need
this method overriding.  I am writing a simple 1D partial differential
equation solver.  For the un-initiated, this reduces to a linear
algebra problem (and here is a plug for the excellent gsll lisp
library) which consists of specifying how to fill out a matrix M and
its right hand side vector B:

M X = B

Our solution is X.

When solving differential equations, one also needs to specify
boundary conditions (like what is the temperature at the boundaries,
or how much heat is flowing in and out).  This amounts to specifying
the contents of the first and last rows of the matrix and the right
hand side vector.

My problem has to deal with the boundary conditions and the hierarchy
of solvers.  My solver hierarchy progresses from a base class that
sets up storage, and several supperclasses that add additional
properties based on the physics (ok, and chemistry) that I am solving,
such as diffusion, diffusion + drift, time dependence.

Each of these superclasses has their way of specifying the boundary
conditions in terms of the matrix problem.  The base class also has a
way of specifying the boundary conditions in the most "naive" way,
naive in the sense that it does not take into account the physics of
the problem (remember, the physics is in the superclasses).

So, I have a generic method calc-bc-coeffs.  The base class and the
superclasses each have their own method that is specialized to their
case.

However, there are cases (and these are really exceptions that I use
for testing purposes mainly), where I would like the superclasses to
use the base class' calc-bc-coeffs instead of its own.  In pseudo-
code:
(let ((solver (make-instance '1d-diff-solver))
  (load-bulk-mat solver)
  (load-left-bc (base-class solver) left-bc)
  (load-right-bc (base-class solver) right-bc))

It is for those cases that I am interested in this thread.

Thanks

Mirko
From: Kenny
Subject: Re: Is there a call-NEXT-next-method, or casting in CLOS?
Date: 
Message-ID: <48dcda80$0$4907$607ed4bc@cv.net>
·············@gmail.com wrote:
> On Aug 12, 4:02 am, Rainer Joswig <······@lisp.de> wrote:
> 
>>In article
>><····································@a2g2000prm.googlegroups.com>,
>> Yarek Kowalik <·············@gmail.com> wrote:
>>
>>
>>>This is a general CLOS question that I have run into a few times this
>>>past week and I don't know how to solve.
>>
>>>I have abaseclass foo that has amethoddo-action.
>>
>>>(methoddo-action ((obj foo))
>>>  .... )
>>
>>Classes don't have methods in CLOS. That model is not applicable for CLOS.
>>Methods are defined outside of classes as parts of generic functions.
>>Methods can be specialized for more than one parameter, which makes the
>>'belongs to a class' idea even more false.
>>
>>(defmethod do-something ((a foo) (b bar)) ... )
>>
>>To which class should abovemethodbelong ?
>>
>>
>>>I also have a subclass bar of foo that specializes themethoddo-
>>>action
>>
>>>(methoddo-action ((obj bar))
>>>  .... )
>>
>>Again, bar can't specialize methods, since classes don't
>>define methods and methods don't belong to classes.
>>
>>You really need to be object-reoriented (see Peter Seibel's book
>>for that).
>>
>>
>>>Now, I have a baz subclass of bar for which I don't want bar's do-
>>>action, but instead I wantbaseclass foo's do-action.  Therefore, I
>>>cannotcallcall-next-method, since that would invoke bar's do-action.
>>
>>>Is there a way to type cast baz to foo so that I can invoke do-action
>>>for foo from baz?  Or is there a techique for makeing acall-next-next-
>>>methodor equivalent?
>>
>>Your problem looks a bit weird and you might want to redesign the whole thing.
>>
>>But...
>>
>>(defclass c1 () ())
>>
>>(defclass c2 () ())
>>
>>(defclass c3 () ())
>>
>>See above, no methods. Classes don't take any methods.
>>
>>I also haven't defined any inheritance above.
>>
>>(defmethod m1 ((a c1)) (print 'm1))
>>
>>FirstMethodm1 takes one argument of class c1.
>>
>>(defmethod m1 ((a c2)) (print 'm2))
>>
>>SecondMethodm1 takes one argument of class c2.
>>
>>(defmethod m1 ((a c3))
>>  (funcall (method-function (find-method#'m1 () (list (find-class 'c1)))) a)
>>  (print 'm3))
>>
>>Thirdmethodm3 takes one argument of class c3
>>
>>FIND-METHODfinds amethodbased on a list ofmethod-qualifiers and a list of specializers.
>>In this case the specializers list is just a list of the class c1.
>>
>>METHOD-FUNCTION is a MOP function (not in ANSI CL, but defined by many CL implementations)
>>that gets the function of amethod, funcall calls it with a.
>>
>>... stuff deleted
> 
> 
> I am having trouble extending this example  (I am mindful of the
> comments other have made about the need to re-arrange the object
> hierarchy, and I will say a bit about my problem below).
> 
> Anyway, here is my simple hierarchy.  (The difference from the above,
> is that I am passing arguments to the methods, and that is where
> things are braking.)
> (in-package :cl-user)
> 
> (defclass base ()
>   ((base-prop-1 :initform nil :accessor base-prop-1)))
> 
> (defclass super1a (base)
>   ((super1a-prop-1 :initform 2
> 	:accessor super1a-prop-1)))
> 
> (defgeneric method1 (class arg &key &allow-other-keys)
>   (:documentation "Execute operation"))
> 
> (defmethod method1 ((this base) (arg integer)  &key &allow-other-keys)
>   arg)
> 
> (defmethod method1 ((this super1a) arg &key key1)
>   (expt arg (or key1 (super1a-prop-1 this))))
> 
> ;; invocation that does not work:
> (let ((b (make-instance 'base))
> 	       (s (make-instance 'super1a)))
> 	   (print (method1 b 5))
> 	   (print (method1 s 5 :key1 3))
> 	   (apply (sb-mop:method-function
> 		     (find-method #'method1 '()
> 				  (list (find-class 'base) 'integer)))
> 		 s 5))
> 
> You can see that I specialized method1 on base & integer (following
> the example from hyperspec), because that was the only way that I
> could make find-method find the method.  I would prefer to leave the
> integer specification blank for now, but then I did not know how to
> specify the last argument of find-method.  It needed a two element
> list, and I did not know how to specify the un-typed second argument.
> 
> My second problem is that apply fails. I am passing it the superobject
> and the numeric argument, but it is asking for a type of list.
> 
> So much about the example itself.  Now a few words about why I need
> this method overriding.  I am writing a simple 1D partial differential
> equation solver.  For the un-initiated, this reduces to a linear
> algebra problem (and here is a plug for the excellent gsll lisp
> library) which consists of specifying how to fill out a matrix M and
> its right hand side vector B:
> 
> M X = B
> 
> Our solution is X.
> 
> When solving differential equations, one also needs to specify
> boundary conditions (like what is the temperature at the boundaries,
> or how much heat is flowing in and out).  This amounts to specifying
> the contents of the first and last rows of the matrix and the right
> hand side vector.
> 
> My problem has to deal with the boundary conditions and the hierarchy
> of solvers.  My solver hierarchy progresses from a base class that
> sets up storage, and several supperclasses that add additional
> properties based on the physics (ok, and chemistry) that I am solving,
> such as diffusion, diffusion + drift, time dependence.
> 
> Each of these superclasses has their way of specifying the boundary
> conditions in terms of the matrix problem.  The base class also has a
> way of specifying the boundary conditions in the most "naive" way,
> naive in the sense that it does not take into account the physics of
> the problem (remember, the physics is in the superclasses).
> 
> So, I have a generic method calc-bc-coeffs.  The base class and the
> superclasses each have their own method that is specialized to their
> case.
> 
> However, there are cases (and these are really exceptions that I use
> for testing purposes mainly), where I would like the superclasses to
> use the base class' calc-bc-coeffs instead of its own.  In pseudo-
> code:
> (let ((solver (make-instance '1d-diff-solver))
>   (load-bulk-mat solver)
>   (load-left-bc (base-class solver) left-bc)
>   (load-right-bc (base-class solver) right-bc))
> 
> It is for those cases that I am interested in this thread.

You have locked onto CLOS as the implementation technology and won't let 
go, perhaps because of where your RtL originated. You can tell something 
has gone wrong when fixes lead to things like find-method-combination. 
The tail is now wagging the dog and the falcon cannot hear the falconer. 
Just let go of the fruit you think you have and you'll be able to get 
your hand out of the basket and go find another piece of fruit instead 
of being captured and leashed to an organ.

hth,kzo
From: Rainer Joswig
Subject: Re: Is there a call-NEXT-next-method, or casting in CLOS?
Date: 
Message-ID: <joswig-6607C4.10113526092008@news-europe.giganews.com>
In article 
<····································@e39g2000hsf.googlegroups.com>,
 ·············@gmail.com wrote:

> On Aug 12, 4:02�am, Rainer Joswig <······@lisp.de> wrote:
> > In article
> > <····································@a2g2000prm.googlegroups.com>,
> > �Yarek Kowalik <·············@gmail.com> wrote:
> >
> > > This is a general CLOS question that I have run into a few times this
> > > past week and I don't know how to solve.
> >
> > > I have abaseclass foo that has amethoddo-action.
> >
> > > (methoddo-action ((obj foo))
> > > � .... )
> >
> > Classes don't have methods in CLOS. That model is not applicable for CLOS.
> > Methods are defined outside of classes as parts of generic functions.
> > Methods can be specialized for more than one parameter, which makes the
> > 'belongs to a class' idea even more false.
> >
> > (defmethod do-something ((a foo) (b bar)) ... )
> >
> > To which class should abovemethodbelong ?
> >
> > > I also have a subclass bar of foo that specializes themethoddo-
> > > action
> >
> > > (methoddo-action ((obj bar))
> > > � .... )
> >
> > Again, bar can't specialize methods, since classes don't
> > define methods and methods don't belong to classes.
> >
> > You really need to be object-reoriented (see Peter Seibel's book
> > for that).
> >
> > > Now, I have a baz subclass of bar for which I don't want bar's do-
> > > action, but instead I wantbaseclass foo's do-action. �Therefore, I
> > > cannotcallcall-next-method, since that would invoke bar's do-action.
> >
> > > Is there a way to type cast baz to foo so that I can invoke do-action
> > > for foo from baz? �Or is there a techique for makeing acall-next-next-
> > >methodor equivalent?
> >
> > Your problem looks a bit weird and you might want to redesign the whole thing.
> >
> > But...
> >
> > (defclass c1 () ())
> >
> > (defclass c2 () ())
> >
> > (defclass c3 () ())
> >
> > See above, no methods. Classes don't take any methods.
> >
> > I also haven't defined any inheritance above.
> >
> > (defmethod m1 ((a c1)) (print 'm1))
> >
> > FirstMethodm1 takes one argument of class c1.
> >
> > (defmethod m1 ((a c2)) (print 'm2))
> >
> > SecondMethodm1 takes one argument of class c2.
> >
> > (defmethod m1 ((a c3))
> > � (funcall (method-function (find-method#'m1 () (list (find-class 'c1)))) a)
> > � (print 'm3))
> >
> > Thirdmethodm3 takes one argument of class c3
> >
> > FIND-METHODfinds amethodbased on a list ofmethod-qualifiers and a list of specializers.
> > In this case the specializers list is just a list of the class c1.
> >
> > METHOD-FUNCTION is a MOP function (not in ANSI CL, but defined by many CL implementations)
> > that gets the function of amethod, funcall calls it with a.
> >
> > ... stuff deleted
> 
> I am having trouble extending this example  (I am mindful of the
> comments other have made about the need to re-arrange the object
> hierarchy, and I will say a bit about my problem below).
> 
> Anyway, here is my simple hierarchy.  (The difference from the above,
> is that I am passing arguments to the methods, and that is where
> things are braking.)
> (in-package :cl-user)
> 
> (defclass base ()
>   ((base-prop-1 :initform nil :accessor base-prop-1)))
> 
> (defclass super1a (base)
>   ((super1a-prop-1 :initform 2
> 	:accessor super1a-prop-1)))

Note that usually SUPER1A is said to be a subclass of the class BASE.
Not a superclass.

CL-USER 262 > (class-direct-subclasses (find-class 'base))
(#<STANDARD-CLASS SUPER1A 41F066845B>)

> 
> (defgeneric method1 (class arg &key &allow-other-keys)
>   (:documentation "Execute operation"))
> 
> (defmethod method1 ((this base) (arg integer)  &key &allow-other-keys)
>   arg)
> 
> (defmethod method1 ((this super1a) arg &key key1)
>   (expt arg (or key1 (super1a-prop-1 this))))
> 
> ;; invocation that does not work:
> (let ((b (make-instance 'base))
> 	       (s (make-instance 'super1a)))
> 	   (print (method1 b 5))
> 	   (print (method1 s 5 :key1 3))
> 	   (apply (sb-mop:method-function
> 		     (find-method #'method1 '()
> 				  (list (find-class 'base) 'integer)))
> 		 s 5))

You would need to use the class INTEGER, not the symbol:

CL-USER 260 > (find-method #'method1 nil (list (find-class 'base) (find-class 'integer)))
#<STANDARD-METHOD METHOD1 NIL (BASE INTEGER) 41F066815B>

This finds the other method:
CL-USER 261 > (find-method #'method1 nil (list (find-class 'super1a) (find-class 't)))
#<STANDARD-METHOD METHOD1 NIL (SUPER1A T) 41F066C293>

CL-USER 276 > (let ((b (make-instance 'base))
                    (s (make-instance 'super1a)))
                (print (method1 b 5))
                (print (method1 s 5 :key1 3))
                (funcall (method-function (find-method #'method1 '() (list (find-class 'base) (find-class 'integer))))
                         s 5 nil))
5 
125 
5

I guess how to call the METHOD-FUNCTION is implementation dependent (I haven't
checked that).

> 
> You can see that I specialized method1 on base & integer (following
> the example from hyperspec), because that was the only way that I
> could make find-method find the method.  I would prefer to leave the
> integer specification blank for now, but then I did not know how to
> specify the last argument of find-method.  It needed a two element
> list, and I did not know how to specify the un-typed second argument.
> 
> My second problem is that apply fails. I am passing it the superobject
> and the numeric argument, but it is asking for a type of list.
> 
> So much about the example itself.  Now a few words about why I need
> this method overriding.  I am writing a simple 1D partial differential
> equation solver.  For the un-initiated, this reduces to a linear
> algebra problem (and here is a plug for the excellent gsll lisp
> library) which consists of specifying how to fill out a matrix M and
> its right hand side vector B:
> 
> M X = B
> 
> Our solution is X.
> 
> When solving differential equations, one also needs to specify
> boundary conditions (like what is the temperature at the boundaries,
> or how much heat is flowing in and out).  This amounts to specifying
> the contents of the first and last rows of the matrix and the right
> hand side vector.
> 
> My problem has to deal with the boundary conditions and the hierarchy
> of solvers.  My solver hierarchy progresses from a base class that
> sets up storage, and several supperclasses that add additional
> properties based on the physics (ok, and chemistry) that I am solving,
> such as diffusion, diffusion + drift, time dependence.
> 
> Each of these superclasses has their way of specifying the boundary
> conditions in terms of the matrix problem.  The base class also has a
> way of specifying the boundary conditions in the most "naive" way,
> naive in the sense that it does not take into account the physics of
> the problem (remember, the physics is in the superclasses).
> 
> So, I have a generic method calc-bc-coeffs.  The base class and the
> superclasses each have their own method that is specialized to their
> case.
> 
> However, there are cases (and these are really exceptions that I use
> for testing purposes mainly), where I would like the superclasses to
> use the base class' calc-bc-coeffs instead of its own.  In pseudo-
> code:
> (let ((solver (make-instance '1d-diff-solver))
>   (load-bulk-mat solver)
>   (load-left-bc (base-class solver) left-bc)
>   (load-right-bc (base-class solver) right-bc))
> 
> It is for those cases that I am interested in this thread.
> 
> Thanks
> 
> Mirko

Probably you might want to start thinking learning about
METHOD-COMBINATIONs. You think you need a special way
of method ordering and calling.

CLOS

a) allows multiple arguments to be used for dispatching -> methods don't belong to classes
b) CLOS sorts the applicable methods (to the provided arguments) in some order
c) with normal method combination you can specify primary, :around, :before and :after methods
d) :around methods and primary methods can use CALL-NEXT-METHOD to call the next method

Method combinations allow you to provide other machineries that the above.

But a simpler version would be (a sketch):

(defclass base-class () ())

(defclass subclass-1 (base-class) ())

(defmethod foo-base ((base base-class) bar)
   ...)

(defmethod foo ((base base-class) bar)
   (foo-base base bar))

(defmethod foo ((sub-1 subclass-1) bar)
   .....
   )

(let ((i (make-instance 'subclass-1)))
  (foo i 15)
  (foo-base i 15))

-- 
http://lispm.dyndns.org/
From: ·············@gmail.com
Subject: Re: Is there a call-NEXT-next-method, or casting in CLOS?
Date: 
Message-ID: <a0b8c601-ec81-46bc-ab97-820e544db631@25g2000hsx.googlegroups.com>
On Sep 26, 4:11 am, Rainer Joswig <······@lisp.de> wrote:
> In article
> <····································@e39g2000hsf.googlegroups.com>,
>
>
>
>  ·············@gmail.com wrote:
> > On Aug 12, 4:02 am, Rainer Joswig <······@lisp.de> wrote:
> > > In article
> > > <····································@a2g2000prm.googlegroups.com>,
> > >  Yarek Kowalik <·············@gmail.com> wrote:
>
> > > > This is a general CLOS question that I have run into a few times this
> > > > past week and I don't know how to solve.
>
> > > > I have abaseclass foo that has amethoddo-action.
>
> > > > (methoddo-action ((obj foo))
> > > >   .... )
>
> > > Classes don't have methods in CLOS. That model is not applicable for CLOS.
> > > Methods are defined outside of classes as parts of generic functions.
> > > Methods can be specialized for more than one parameter, which makes the
> > > 'belongs to a class' idea even more false.
>
> > > (defmethod do-something ((a foo) (b bar)) ... )
>
> > > To which class should abovemethodbelong ?
>
> > > > I also have a subclass bar of foo that specializes themethoddo-
> > > > action
>
> > > > (methoddo-action ((obj bar))
> > > >   .... )
>
> > > Again, bar can't specialize methods, since classes don't
> > > define methods and methods don't belong to classes.
>
> > > You really need to be object-reoriented (see Peter Seibel's book
> > > for that).
>
> > > > Now, I have a baz subclass of bar for which I don't want bar's do-
> > > > action, but instead I wantbaseclass foo's do-action.  Therefore, I
> > > > cannotcallcall-next-method, since that would invoke bar's do-action.
>
> > > > Is there a way to type cast baz to foo so that I can invoke do-action
> > > > for foo from baz?  Or is there a techique for makeing acall-next-next-
> > > >methodor equivalent?
>
> > > Your problem looks a bit weird and you might want to redesign the whole thing.
>
> > > But...
>
> > > (defclass c1 () ())
>
> > > (defclass c2 () ())
>
> > > (defclass c3 () ())
>
> > > See above, no methods. Classes don't take any methods.
>
> > > I also haven't defined any inheritance above.
>
> > > (defmethod m1 ((a c1)) (print 'm1))
>
> > > FirstMethodm1 takes one argument of class c1.
>
> > > (defmethod m1 ((a c2)) (print 'm2))
>
> > > SecondMethodm1 takes one argument of class c2.
>
> > > (defmethod m1 ((a c3))
> > >   (funcall (method-function (find-method#'m1 () (list (find-class 'c1)))) a)
> > >   (print 'm3))
>
> > > Thirdmethodm3 takes one argument of class c3
>
> > > FIND-METHODfinds amethodbased on a list ofmethod-qualifiers and a list of specializers.
> > > In this case the specializers list is just a list of the class c1.
>
> > > METHOD-FUNCTION is a MOP function (not in ANSI CL, but defined by many CL implementations)
> > > that gets the function of amethod, funcall calls it with a.
>
> > > ... stuff deleted
>
> > I am having trouble extending this example  (I am mindful of the
> > comments other have made about the need to re-arrange the object
> > hierarchy, and I will say a bit about my problem below).
>
> > Anyway, here is my simple hierarchy.  (The difference from the above,
> > is that I am passing arguments to the methods, and that is where
> > things are braking.)
> > (in-package :cl-user)
>
> > (defclass base ()
> >   ((base-prop-1 :initform nil :accessor base-prop-1)))
>
> > (defclass super1a (base)
> >   ((super1a-prop-1 :initform 2
> >    :accessor super1a-prop-1)))
>
> Note that usually SUPER1A is said to be a subclass of the class BASE.
> Not a superclass.

I always get confused.  Thanks for the clarification.

>
> CL-USER 262 > (class-direct-subclasses (find-class 'base))
> (#<STANDARD-CLASS SUPER1A 41F066845B>)
>
>
>
>
>
> > (defgeneric method1 (class arg &key &allow-other-keys)
> >   (:documentation "Execute operation"))
>
> > (defmethod method1 ((this base) (arg integer)  &key &allow-other-keys)
> >   arg)
>
> > (defmethod method1 ((this super1a) arg &key key1)
> >   (expt arg (or key1 (super1a-prop-1 this))))
>
> > ;; invocation that does not work:
> > (let ((b (make-instance 'base))
> >           (s (make-instance 'super1a)))
> >       (print (method1 b 5))
> >       (print (method1 s 5 :key1 3))
> >       (apply (sb-mop:method-function
> >                 (find-method #'method1 '()
> >                              (list (find-class 'base) 'integer)))
> >             s 5))
>
> You would need to use the class INTEGER, not the symbol:
>
> CL-USER 260 > (find-method #'method1 nil (list (find-class 'base) (find-class 'integer)))
> #<STANDARD-METHOD METHOD1 NIL (BASE INTEGER) 41F066815B>
>
> This finds the other method:
> CL-USER 261 > (find-method #'method1 nil (list (find-class 'super1a) (find-class 't)))
> #<STANDARD-METHOD METHOD1 NIL (SUPER1A T) 41F066C293>
>
> CL-USER 276 > (let ((b (make-instance 'base))
>                     (s (make-instance 'super1a)))
>                 (print (method1 b 5))
>                 (print (method1 s 5 :key1 3))
>                 (funcall (method-function (find-method #'method1 '() (list (find-class 'base) (find-class 'integer))))
>                          s 5 nil))
> 5
> 125
> 5
>
> I guess how to call the METHOD-FUNCTION is implementation dependent (I haven't
> checked that).


Aaah, thanks.
>
>
>
>
>
> > You can see that I specialized method1 on base & integer (following
> > the example from hyperspec), because that was the only way that I
> > could make find-method find the method.  I would prefer to leave the
> > integer specification blank for now, but then I did not know how to
> > specify the last argument of find-method.  It needed a two element
> > list, and I did not know how to specify the un-typed second argument.
>
> > My second problem is that apply fails. I am passing it the superobject
> > and the numeric argument, but it is asking for a type of list.
>
> > So much about the example itself.  Now a few words about why I need
> > this method overriding.  I am writing a simple 1D partial differential
> > equation solver.  For the un-initiated, this reduces to a linear
> > algebra problem (and here is a plug for the excellent gsll lisp
> > library) which consists of specifying how to fill out a matrix M and
> > its right hand side vector B:
>
> > M X = B
>
> > Our solution is X.
>
> > When solving differential equations, one also needs to specify
> > boundary conditions (like what is the temperature at the boundaries,
> > or how much heat is flowing in and out).  This amounts to specifying
> > the contents of the first and last rows of the matrix and the right
> > hand side vector.
>
> > My problem has to deal with the boundary conditions and the hierarchy
> > of solvers.  My solver hierarchy progresses from a base class that
> > sets up storage, and several supperclasses that add additional
> > properties based on the physics (ok, and chemistry) that I am solving,
> > such as diffusion, diffusion + drift, time dependence.
>
> > Each of these superclasses has their way of specifying the boundary
> > conditions in terms of the matrix problem.  The base class also has a
> > way of specifying the boundary conditions in the most "naive" way,
> > naive in the sense that it does not take into account the physics of
> > the problem (remember, the physics is in the superclasses).
>
> > So, I have a generic method calc-bc-coeffs.  The base class and the
> > superclasses each have their own method that is specialized to their
> > case.
>
> > However, there are cases (and these are really exceptions that I use
> > for testing purposes mainly), where I would like the superclasses to
> > use the base class' calc-bc-coeffs instead of its own.  In pseudo-
> > code:
> > (let ((solver (make-instance '1d-diff-solver))
> >   (load-bulk-mat solver)
> >   (load-left-bc (base-class solver) left-bc)
> >   (load-right-bc (base-class solver) right-bc))
>
> > It is for those cases that I am interested in this thread.
>
> > Thanks
>
> > Mirko
>
> Probably you might want to start thinking learning about
> METHOD-COMBINATIONs. You think you need a special way
> of method ordering and calling.
>
> CLOS
>
> a) allows multiple arguments to be used for dispatching -> methods don't belong to classes
> b) CLOS sorts the applicable methods (to the provided arguments) in some order
> c) with normal method combination you can specify primary, :around, :before and :after methods
> d) :around methods and primary methods can use CALL-NEXT-METHOD to call the next method
>
> Method combinations allow you to provide other machineries that the above.
>
> But a simpler version would be (a sketch):
>
> (defclass base-class () ())
>
> (defclass subclass-1 (base-class) ())
>
> (defmethod foo-base ((base base-class) bar)
>    ...)
>
> (defmethod foo ((base base-class) bar)
>    (foo-base base bar))
>
> (defmethod foo ((sub-1 subclass-1) bar)
>    .....
>    )
>
> (let ((i (make-instance 'subclass-1)))
>   (foo i 15)
>   (foo-base i 15))
>
> --http://lispm.dyndns.org/

Actually, I was thinking just to create a new generic method and its
implementation attached to the base class, that does the thing, and is
not over-ridden by subclasses.

Thanks again,

Mirko
From: Pascal Costanza
Subject: Re: Is there a call-NEXT-next-method, or casting in CLOS?
Date: 
Message-ID: <6gd4j9Ffc7acU1@mid.individual.net>
Yarek Kowalik wrote:
> This is a general CLOS question that I have run into a few times this
> past week and I don't know how to solve.
> 
> I have a base class foo that has a method do-action.
> 
> (method do-action ((obj foo))
>   .... )
> 
> I also have a subclass bar of foo that specializes the method do-
> action
> 
> (method do-action ((obj bar))
>   .... )
> 
> Now, I have a baz subclass of bar for which I don't want bar's do-
> action, but instead I want base class foo's do-action.  Therefore, I
> cannot call call-next-method, since that would invoke bar's do-action.
> 
> Is there a way to type cast baz to foo so that I can invoke do-action
> for foo from baz?  Or is there a techique for makeing a call-next-next-
> method or equivalent?

You could probably do something with the CLOS MOP, especially with 
make-method-lambda, or similar hooks into modifying the body of a 
method. See http://elw2008.bknr.net/submission/28

I agree with the other comments in this thread that there is probably 
something wrong in the design of your class hierarchy. Maybe drop trying 
to force something into a class hierarchy first, and try to think about 
how you would do this without inheritance. It could become clearer then 
what the actual structure of your problem is.


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: Tim Bradshaw
Subject: Re: Is there a call-NEXT-next-method, or casting in CLOS?
Date: 
Message-ID: <69dccf65-19e3-42c9-bcf6-5a44ec482333@m36g2000hse.googlegroups.com>
On Aug 12, 10:48 am, Pascal Costanza <····@p-cos.net> wrote:

> I agree with the other comments in this thread that there is probably
> something wrong in the design of your class hierarchy. Maybe drop trying
> to force something into a class hierarchy first, and try to think about
> how you would do this without inheritance. It could become clearer then
> what the actual structure of your problem is.

I think that the underlying point here is that a method has the option
at various points of saying "I don't want to deal with this, so I'll
just rely on someone else to do so", which is CALL-NEXT-METHOD, but it
shouldn't be saying "I know all about the class graph and I want
*this* class to deal with it for me".  That's the OO equivalent of
GOTO...
From: Dimiter "malkia" Stanev
Subject: Re: Is there a call-NEXT-next-method, or casting in CLOS?
Date: 
Message-ID: <6ge602FfhpkrU1@mid.individual.net>
> I think that the underlying point here is that a method has the option
> at various points of saying "I don't want to deal with this, so I'll
> just rely on someone else to do so", which is CALL-NEXT-METHOD, but it
> shouldn't be saying "I know all about the class graph and I want
> *this* class to deal with it for me".  That's the OO equivalent of
> GOTO...

Well said :)

But in general I'm a goto user (in my daily job, C++ without exceptions 
makes you use it in the places, where you cleanup after failure).
From: Kenny
Subject: Re: Is there a call-NEXT-next-method, or casting in CLOS?
Date: 
Message-ID: <48a1e7c6$0$29510$607ed4bc@cv.net>
Dimiter "malkia" Stanev wrote:
>> I think that the underlying point here is that a method has the option
>> at various points of saying "I don't want to deal with this, so I'll
>> just rely on someone else to do so", which is CALL-NEXT-METHOD, but it
>> shouldn't be saying "I know all about the class graph and I want
>> *this* class to deal with it for me".  That's the OO equivalent of
>> GOTO...
> 
> Well said :)
> 
> But in general I'm a goto user (in my daily job, C++ without exceptions 
> makes you use it in the places, where you cleanup after failure).

Overcoming language limitations is one thing, overcoming misdesign 
another. You'll have a better application after you figure out how to 
get the job done without (effectively) casting.

kt



-- 

$$$$$: http://www.theoryyalgebra.com/
Cells: http://common-lisp.net/project/cells/
BSlog: http://smuglispweeny.blogspot.com/
From: Tim Bradshaw
Subject: Re: Is there a call-NEXT-next-method, or casting in CLOS?
Date: 
Message-ID: <11f9df81-d3c6-4807-b721-f73e5ef27d3a@a70g2000hsh.googlegroups.com>
On Aug 12, 8:18 pm, "Dimiter \"malkia\" Stanev" <······@gmail.com>
wrote:

> But in general I'm a goto user (in my daily job, C++ without exceptions
> makes you use it in the places, where you cleanup after failure).

Actually, so am I.  I've used in CL even (and not just in macro
definitions where it's reasonably common).  So I really have nothing
against it.  So I was taking a cheap shot really.  The problem is
actually more subtle and to do with locality (or lack of it) in code.
From: Thomas F. Burdick
Subject: Re: Is there a call-NEXT-next-method, or casting in CLOS?
Date: 
Message-ID: <7f989c5f-0190-45c0-965d-ab58e5cba186@z72g2000hsb.googlegroups.com>
On Aug 13, 8:41 am, Tim Bradshaw <··········@tfeb.org> wrote:
> On Aug 12, 8:18 pm, "Dimiter \"malkia\" Stanev" <······@gmail.com>
> wrote:
>
> > But in general I'm a goto user (in my daily job, C++ without exceptions
> > makes you use it in the places, where you cleanup after failure).
>
> Actually, so am I.  I've used in CL even (and not just in macro
> definitions where it's reasonably common).  So I really have nothing
> against it.  So I was taking a cheap shot really.  The problem is
> actually more subtle and to do with locality (or lack of it) in code.

I think it's a legit point. Pointing method dispatch to a known point
in the class graph is very much like goto. There's nothing necessarily
wrong with goto; if it's used to make control flow clearer, it's a
huge win (cf Knuth's examples contrasting with switching on state
variables). If it's used to break an abstraction, it's not so good.
Object orientation is a huge bureaucratic overhead that forces the
programmer to jump through all kinds of hoops. The advantage is that
the model lets you extend and swap out certain parts. If you carefully
engineer your OO system to break the normal OO contracts and require
the poor maintainer to understand all interactions between all parts
at all times -- why bother with OO? All this business about methods
and classes becomes essentially a lie which can only mislead someone
looking at that code later.
From: Tim Bradshaw
Subject: Re: Is there a call-NEXT-next-method, or casting in CLOS?
Date: 
Message-ID: <6849000c-b2eb-46f0-9ef3-8b3aeb08b0d6@s50g2000hsb.googlegroups.com>
On Aug 13, 12:14 pm, "Thomas F. Burdick" <········@gmail.com> wrote:
> [...] All this business about methods
> and classes becomes essentially a lie which can only mislead someone
> looking at that code later.

This was really well put.
From: Daniel Pitts
Subject: Re: Is there a call-NEXT-next-method, or casting in CLOS?
Date: 
Message-ID: <48a22a49$0$12147$7836cce5@newsrazor.net>
Yarek Kowalik wrote:
> This is a general CLOS question that I have run into a few times this
> past week and I don't know how to solve.
> 
> I have a base class foo that has a method do-action.
> 
> (method do-action ((obj foo))
>   .... )
> 
> I also have a subclass bar of foo that specializes the method do-
> action
> 
> (method do-action ((obj bar))
>   .... )
> 
> Now, I have a baz subclass of bar for which I don't want bar's do-
> action, but instead I want base class foo's do-action.  Therefore, I
> cannot call call-next-method, since that would invoke bar's do-action.
> 
> Is there a way to type cast baz to foo so that I can invoke do-action
> for foo from baz?  Or is there a techique for makeing a call-next-next-
> method or equivalent?
> 
> Thanks,
> 
> Yarek
> 

It sounds like you're missing a class here:

What you have:
foo [do-action]
   \
    bar [do-action + barstuff]
      \
       baz [foo's do-action]

What you want:

foo [do-action]
    \
     \
      abstract-bar [barstuff]
      /                 \
  bar[do-action]      baz

At least, that's how I would model it in Java :-)
-- 
Daniel Pitts' Tech Blog: <http://virtualinfinity.net/wordpress/>
From: Kaz Kylheku
Subject: Re: Is there a call-NEXT-next-method, or casting in CLOS?
Date: 
Message-ID: <20080926092230.586@gmail.com>
On 2008-08-12, Yarek Kowalik <·············@gmail.com> wrote:
> This is a general CLOS question that I have run into a few times this
> past week and I don't know how to solve.
>
> I have a base class foo that has a method do-action.
>
> (method do-action ((obj foo))
>   .... )
>
> I also have a subclass bar of foo that specializes the method do-
> action
>
> (method do-action ((obj bar))
>   .... )
>
> Now, I have a baz subclass of bar for which I don't want bar's do-
> action, but instead I want base class foo's do-action.

The fix is to derive BAZ from FOO rather than BAR. 

Doh?

If you want methods to use foo specializations for baz arguments
(whenever these methods don't have a baz specialization) you should derive the
baz class directly from foo.

Maybe the foo flavor of do-action should not be a method at all, but a regular
function (with some other name).

;;
;; utility function used over all objects in the foo hierarchy
;; helps implement do-action methods
;;
(defun do-action-utility (foo-obj)
  ...)

(defmethod do-action ((obj class-deeply-derived-from-foo))
  ...
  (do-action-utility obj)
  ...
  )