From: Frank GOENNINGER
Subject: CLOS question re  :around method calling sequence
Date: 
Message-ID: <m2skioes6c.fsf@ccde007.de.goenninger.net>
To all CLOS elders:

I am seeing a method *not* getting called because there is am :around
method of a superclass of the class in question available. That's
something I did not expect to happen... I have (really, really
simplified):

Using Cells (yeah, baby) ...

CL-USER > (in-package cells)
#<The CELLS package>

CELLS> (defmd frgo (family)
         frgo-slot-1
         frgo-slot-2
         :md-name (gensym "FRGO-"))
#<STANDARD-CLASS FRGO>

CELLS> (defmd frgo-kid (frgo)
         frgo-kid-slot-1
         :md-name (gensym "FRGO-KID-"))
#<STANDARD-CLASS FRGO-KID>

CELLS> (defmd frgo-kid-kid (frgo-kid)
         frgo-kid-kid-slot-1
         :md-name (gensym "FRGO-KID-KID-"))
#<STANDARD-CLASS FRGO-KID-KID>

CELLS> (defmethod paint ((self family))
         (format *debug-io* "~%-> Painting ~S." self))
#<STANDARD-METHOD PAINT (FAMILY)>

CELLS> (defmethod paint :around ((self frgo))
         (format *debug-io* "~%-> AROUND Painting ~S." self))
#<STANDARD-METHOD PAINT :AROUND (FRGO)>

CELLS> (setq *kid-kid-1* (make-instance 'frgo-kid-kid 
                                        :md-name :frgo-kid-kid-1))
FRGO-KID-KID-1

CELLS> (describe *kid-kid-1*)
FRGO-KID-KID-1 is an instance of #<STANDARD-CLASS FRGO-KID-KID>:
 The following slots have :INSTANCE allocation:
  .MD-STATE             :AWAKE
  .AWAKEN-ON-INIT-P     NIL
  .CELLS                ((.KIDS . <0:A .KIDS/FRGO-KID-KID-1 = NIL>))
  .CELLS-FLUSHED        NIL
  ADOPT-CT              0
  .MD-NAME              :FRGO-KID-KID-1
  .FM-PARENT            NIL
  .DBG-PAR              NIL
  .VALUE                NIL
  REGISTER?             NIL
  ZDBG                  NIL
  .KID-SLOTS            NIL
  .KIDS                 NIL
  REGISTRY?             NIL
  REGISTRY              NIL
  FRGO-SLOT-1           NIL
  FRGO-SLOT-2           NIL
  FRGO-KID-SLOT-1       NIL
  FRGO-KID-KID-SLOT-1   NIL

CELLS> (paint *kid-kid-1*)

-> AROUND Painting FRGO-KID-KID-1.
NIL

CELLS> 

Why is my method #'paint for the kid-kid instance not called?

Inspecting the kid-kid instance shows that the precedence list is
FRGO-KID-KID, FRGO-KID, FRGO, FAMILY, MODEL, MODEL-OBJECT, STANDARD-OBJECT, T

So I tried to get the primary method for paint on the same precedence
level / class as the :around method:

(defmethod paint ((self frgo-kid-kid))
         (format *debug-io* "~%-> Painting ~S." self))
#<STANDARD-METHOD PAINT (FRGO-KID-KID)>

But:

CELLS> (paint *kid-kid-1*)

-> AROUND Painting FRGO-KID-KID-1.
NIL
CELLS> 

Hmmmmmm ?!? The :around method is supposed to be executed before the
primary method, yes, but the primary method should be called after the
:around method, no?

Yes, yeah, it's late here, but I seem to be either confused or just
misinformed or going wild and crazy (I learned that I better include
that last option for you guys not having to invent "better" wording ;-)

Appreciate a hint or two ...

TIA!

Frank

From: gugamilare
Subject: Re: CLOS question re :around method calling sequence
Date: 
Message-ID: <3581c8fe-d7f2-4d2f-b2a7-d2883e3abfc6@l28g2000vba.googlegroups.com>
On 28 maio, 20:14, Frank GOENNINGER <······@googlemail.com> wrote:
> Hmmmmmm ?!? The :around method is supposed to be executed before the
> primary method, yes, but the primary method should be called after the
> :around method, no?

In the :around method, you need to call (call-next-method) in order to
continue execution. If you want just to do something before the
primary method, use the :before qualifier instead.

the :around specializer is interesting to make some tests or to change
the value returned:

(defmethod find-element :around (elt place)
  (let ((found (call-next-method)))
    (unless found
      (error "Not found"))
    (values found t)))

Gustavo.
From: Drew Crampsie
Subject: Re: CLOS question re  :around method calling sequence
Date: 
Message-ID: <878wkgkc2b.fsf@kronos.tech.coop>
Frank GOENNINGER <······@googlemail.com> writes:
>
> I am seeing a method *not* getting called because there is am :around
> method of a superclass of the class in question available. That's
> something I did not expect to happen...  


But that's what around methods do... if you want to continue down and
call the next method, you might want to insert a call to
CALL-NEXT-METHOD. You don't have this in your :around below.

Cheers, 

drewc

> I have (really, really
> simplified):
>
> Using Cells (yeah, baby) ...
>
> CL-USER > (in-package cells)
> #<The CELLS package>
>
> CELLS> (defmd frgo (family)
>          frgo-slot-1
>          frgo-slot-2
>          :md-name (gensym "FRGO-"))
> #<STANDARD-CLASS FRGO>
>
> CELLS> (defmd frgo-kid (frgo)
>          frgo-kid-slot-1
>          :md-name (gensym "FRGO-KID-"))
> #<STANDARD-CLASS FRGO-KID>
>
> CELLS> (defmd frgo-kid-kid (frgo-kid)
>          frgo-kid-kid-slot-1
>          :md-name (gensym "FRGO-KID-KID-"))
> #<STANDARD-CLASS FRGO-KID-KID>
>
> CELLS> (defmethod paint ((self family))
>          (format *debug-io* "~%-> Painting ~S." self))
> #<STANDARD-METHOD PAINT (FAMILY)>
>
> CELLS> (defmethod paint :around ((self frgo))
>          (format *debug-io* "~%-> AROUND Painting ~S." self))
> #<STANDARD-METHOD PAINT :AROUND (FRGO)>
>
> CELLS> (setq *kid-kid-1* (make-instance 'frgo-kid-kid 
>                                         :md-name :frgo-kid-kid-1))
> FRGO-KID-KID-1
>
> CELLS> (describe *kid-kid-1*)
> FRGO-KID-KID-1 is an instance of #<STANDARD-CLASS FRGO-KID-KID>:
>  The following slots have :INSTANCE allocation:
>   .MD-STATE             :AWAKE
>   .AWAKEN-ON-INIT-P     NIL
>   .CELLS                ((.KIDS . <0:A .KIDS/FRGO-KID-KID-1 = NIL>))
>   .CELLS-FLUSHED        NIL
>   ADOPT-CT              0
>   .MD-NAME              :FRGO-KID-KID-1
>   .FM-PARENT            NIL
>   .DBG-PAR              NIL
>   .VALUE                NIL
>   REGISTER?             NIL
>   ZDBG                  NIL
>   .KID-SLOTS            NIL
>   .KIDS                 NIL
>   REGISTRY?             NIL
>   REGISTRY              NIL
>   FRGO-SLOT-1           NIL
>   FRGO-SLOT-2           NIL
>   FRGO-KID-SLOT-1       NIL
>   FRGO-KID-KID-SLOT-1   NIL
>
> CELLS> (paint *kid-kid-1*)
>
> -> AROUND Painting FRGO-KID-KID-1.
> NIL
>
> CELLS> 
>
> Why is my method #'paint for the kid-kid instance not called?
>
> Inspecting the kid-kid instance shows that the precedence list is
> FRGO-KID-KID, FRGO-KID, FRGO, FAMILY, MODEL, MODEL-OBJECT, STANDARD-OBJECT, T
>
> So I tried to get the primary method for paint on the same precedence
> level / class as the :around method:
>
> (defmethod paint ((self frgo-kid-kid))
>          (format *debug-io* "~%-> Painting ~S." self))
> #<STANDARD-METHOD PAINT (FRGO-KID-KID)>
>
> But:
>
> CELLS> (paint *kid-kid-1*)
>
> -> AROUND Painting FRGO-KID-KID-1.
> NIL
> CELLS> 
>
> Hmmmmmm ?!? The :around method is supposed to be executed before the
> primary method, yes, but the primary method should be called after the
> :around method, no?
>
> Yes, yeah, it's late here, but I seem to be either confused or just
> misinformed or going wild and crazy (I learned that I better include
> that last option for you guys not having to invent "better" wording ;-)
>
> Appreciate a hint or two ...
>
> TIA!
>
> Frank
From: Kenneth Tilton
Subject: Re: CLOS question re  :around method calling sequence
Date: 
Message-ID: <4A1F5D5A.6000608@gmail.com>
Frank GOENNINGER wrote:
> To all CLOS elders:
> 
> I am seeing a method *not* getting called because there is am :around
> method of a superclass of the class in question available. That's
> something I did not expect to happen...

Cue Naggum! Please adjust your expectations (by going back to school on 
GF dispatch, committing this to static memory (in re standard method 
combo)):

:around literally around anything else, but ya gots to call-next-method 
to get anything else.

multiple :arounds in order of decreasing class precedence (most specific 
first)

:before most specific first

primary

:after most specific last

before/after cannot alter the return value or execution of other methods

primaries can get weird and call-next-method as if they were arounds, 
but unlike arounds cannot head off beofre/afters.

kt
From: Pascal Costanza
Subject: Re: CLOS question re  :around method calling sequence
Date: 
Message-ID: <789dk8F1idd2iU1@mid.individual.net>
Frank GOENNINGER wrote:
> To all CLOS elders:
> 
> I am seeing a method *not* getting called because there is am :around
> method of a superclass of the class in question available. That's
> something I did not expect to happen... I have (really, really
> simplified):
> 
> Using Cells (yeah, baby) ...

...that explains. :-P


Pascal


-- 
ELS'09: http://www.european-lisp-symposium.org/
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: Frank GOENNINGER
Subject: Re: CLOS question re  :around method calling sequence
Date: 
Message-ID: <m2octce147.fsf@ccde007.de.goenninger.net>
Pascal Costanza <··@p-cos.net> writes:

> Frank GOENNINGER wrote:
>> To all CLOS elders:
>>
>> I am seeing a method *not* getting called because there is am :around
>> method of a superclass of the class in question available. That's
>> something I did not expect to happen... I have (really, really
>> simplified):
>>
>> Using Cells (yeah, baby) ...
>
> ...that explains. :-P

;-) Yes, somehow it does: I expected CLOS to be as simple as Cells -
  which it is not. Hehe ...

Cheers
   Frank

P.S. BTW all now works as CLOS was designed. I just had - as several
pointed out - to add a (call-next-method) at the end of the :around
method.

P.P.S. Wow, I am really proud we had an on-topic thread with no language
bashing so far. Well, maybe this last remark just sets off another one...
From: Pascal Costanza
Subject: Re: CLOS question re  :around method calling sequence
Date: 
Message-ID: <78csqgF1l3rmpU1@mid.individual.net>
Frank GOENNINGER wrote:
> Pascal Costanza <··@p-cos.net> writes:
> 
>> Frank GOENNINGER wrote:
>>> To all CLOS elders:
>>>
>>> I am seeing a method *not* getting called because there is am :around
>>> method of a superclass of the class in question available. That's
>>> something I did not expect to happen... I have (really, really
>>> simplified):
>>>
>>> Using Cells (yeah, baby) ...
>> ...that explains. :-P
> 
> ;-) Yes, somehow it does: I expected CLOS to be as simple as Cells -
>   which it is not. Hehe ...
> 
> Cheers
>    Frank
> 
> P.S. BTW all now works as CLOS was designed. I just had - as several
> pointed out - to add a (call-next-method) at the end of the :around
> method.

If you have to put it at the end, a :before method is actually simpler.


Pascal

-- 
ELS'09: http://www.european-lisp-symposium.org/
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: MarkH
Subject: Re: CLOS question re :around method calling sequence
Date: 
Message-ID: <8ffa1d95-3b4f-4344-983c-8cb57e759a34@g20g2000vba.googlegroups.com>
On May 28, 6:14 pm, Frank GOENNINGER <······@googlemail.com> wrote:
> To all CLOS elders:
>

CLOS elders rule.
From: Thomas A. Russ
Subject: Re: CLOS question re  :around method calling sequence
Date: 
Message-ID: <ymir5y7fvqh.fsf@blackcat.isi.edu>
Paul Foley <···@below.invalid> (http://public.xdi.org/=pf) writes:

> Frank GOENNINGER <······@googlemail.com> writes:
> 
> > Hmmmmmm ?!? The :around method is supposed to be executed before the
> > primary method, yes, but the primary method should be called after the
> > :around method, no?
> 
> No...then it would be a :before method.  An :around method goes _around_
> the primary method (i.e., instead of...you have to use CALL-NEXT-METHOD)

Amplifying.  An :AROUND method allows you to put some of your code
around the primary method, in other words both before and after it.  But
without the CALL-NEXT-METHOD there wouldn't be any way for the compiler
to know what part of your around method is supposed to be done before
the primary method and what part is supposed to be after.

-- 
Thomas A. Russ,  USC/Information Sciences Institute