From: Jimka
Subject: values passed to call-next-method
Date: 
Message-ID: <1132439372.982061.219500@g14g2000cwa.googlegroups.com>
Does anyone know whether the consequenses of changing the values
of function parameters before calling call-next-method are well
defined or implementation dependent?

I'm using sbcl, and don't have any other lisp installed at the moment.

(defgeneric foo (a b))
(defmethod foo (a b)
  (list a b))
(defmethod foo ((a number) (b number))
    (call-next-method 1 2))

In this case (foo 7 8) reurns (1 2) as expected.

(defmethod foo ((a number) (b number))
    (call-next-method a b))

In this case (foo 7 8) returns (7 8) as expected.


(defmethod foo ((a number) (b number))
   (setf a 100)
   (call-next-method a b))

In this case (foo 7 8) returns (100 8) as expected.

(defmethod foo ((a number) (b number))
   (setf a 100)
   (call-next-method))

In this case (foo 7 8) returns (7 8) and i am suprised.

Can someone explain to me why this should be so?
Is it the same in other lisps?

-jim

From: Jimka
Subject: Re: values passed to call-next-method
Date: 
Message-ID: <1132439948.536990.202680@g49g2000cwa.googlegroups.com>
Indeed i found this statement in the hyperspec.

> When call-next-method is called with no arguments, it passes the current
> method's original arguments to the next method. Neither argument defaulting,
> nor using setq, nor rebinding variables with the same names as parameters
> of the method affects the values call-next-method passes to the method
> it calls.

So it appears there should indeed be a different behavior between
(call-next-method) and (call-next-method a b) in my example.

However, i'm still puzzled as to how that behavior is implemented.
Is defmethod expanding to something like the following.

(defmethod-expansion ((a number) (b number))
  (flet ((call-next-method ....)
          (next-method-p ...))
    (let ((a a) (b b))
      ... ))
From: Edi Weitz
Subject: Re: values passed to call-next-method
Date: 
Message-ID: <uk6f4tfdj.fsf@agharta.de>
On 19 Nov 2005 14:39:08 -0800, "Jimka" <·····@rdrop.com> wrote:

> However, i'm still puzzled as to how that behavior is implemented.
> Is defmethod expanding to something like the following.
>
> (defmethod-expansion ((a number) (b number))
>   (flet ((call-next-method ....)
>           (next-method-p ...))
>     (let ((a a) (b b))
>       ... ))

The CLHS says that CALL-NEXT-METHOD is a "local function."  Although I
couldn't find this term in the glossary I think it's pretty clear that
they mean something like your example above.

Why don't you just macroexpand some DEFMETHOD forms in your favorite
Lisp?

Cheers,
Edi.

-- 

Lisp is not dead, it just smells funny.

Real email: (replace (subseq ·········@agharta.de" 5) "edi")
From: Jimka
Subject: Re: values passed to call-next-method
Date: 
Message-ID: <1132442158.973232.92190@o13g2000cwo.googlegroups.com>
the macro expansion is not very enlightening :-(

(PROGN
 (SB-PCL::LOAD-DEFMETHOD STANDARD-METHOD
                         'FOO
                         'NIL
                         (LIST 'NUMBER 'NUMBER)
                         '(A B)
                         (LIST* :FAST-FUNCTION
                                (SB-INT:NAMED-LAMBDA
                                 (SB-PCL::FAST-METHOD FOO (NUMBER
NUMBER))
                                 (SB-PCL::.PV-CELL.
SB-PCL::.NEXT-METHOD-CALL.
                                                    A
                                                    B)
                                 (DECLARE
                                  (IGNORABLE SB-PCL::.PV-CELL.

SB-PCL::.NEXT-METHOD-CALL.))
                                 (DECLARE
                                  (SB-PCL::%METHOD-LAMBDA-LIST (A
NUMBER)
                                                               (B
NUMBER)))
                                 (DECLARE
                                  (SB-PCL::%METHOD-NAME (FOO (NUMBER
NUMBER))))
                                 (DECLARE (TYPE NUMBER B))
                                 (DECLARE (TYPE NUMBER A))
                                 (DECLARE (IGNORABLE B A))
                                 (DECLARE
                                  (DISABLE-PACKAGE-LOCKS
SB-PCL::PV-ENV))
                                 (MACROLET ((SB-PCL::PV-ENV
                                                ((SB-PCL::PV
SB-PCL::CALLS

SB-PCL::PV-TABLE-SYMBOL

SB-PCL::PV-PARAMETERS)
                                                 &REST SB-PCL::FORMS)
                                              (DECLARE
                                               (IGNORE
SB-PCL::PV-TABLE-SYMBOL

SB-PCL::PV-PARAMETERS))
                                              (DECLARE
                                               (ENABLE-PACKAGE-LOCKS
                                                SB-PCL::PV-ENV))
                                              `(LET ((,SB-PCL::PV
                                                      (CAR
SB-PCL::.PV-CELL.))
                                                     (,SB-PCL::CALLS
                                                      (CDR
SB-PCL::.PV-CELL.)))
                                                 (DECLARE

,(SB-PCL::MAKE-PV-TYPE-DECLARATION
                                                    SB-PCL::PV)

,(SB-PCL::MAKE-CALLS-TYPE-DECLARATION
                                                    SB-PCL::CALLS))
                                                 ,SB-PCL::PV
                                                 ,SB-PCL::CALLS
                                                 ,@SB-PCL::FORMS)))
                                   (DECLARE
                                    (ENABLE-PACKAGE-LOCKS
SB-PCL::PV-ENV))

(SB-PCL::FAST-LEXICAL-METHOD-FUNCTIONS
                                    ((A B) SB-PCL::.NEXT-METHOD-CALL.
(A B) NIL
                                     :CALL-NEXT-METHOD-P T
:NEXT-METHOD-P-P NIL
                                     :SETQ-P T :METHOD-NAME-DECLARATION
                                     ((FOO (NUMBER NUMBER))) :CLOSUREP
NIL
                                     :APPLYP NIL)
                                    (DECLARE (SB-PCL::%CLASS B NUMBER))
                                    (DECLARE (SB-PCL::%CLASS A NUMBER))
                                    (BLOCK FOO
                                      (SETF A 100)
                                      (CALL-NEXT-METHOD)))))
                                '(:PLIST
                                  (:ARG-INFO (2) :NEEDS-NEXT-METHODS-P
T)))
                         'NIL))
From: Edi Weitz
Subject: Re: values passed to call-next-method
Date: 
Message-ID: <ubr0gte31.fsf@agharta.de>
On 19 Nov 2005 15:15:59 -0800, "Jimka" <·····@rdrop.com> wrote:

> the macro expansion is not very enlightening :-(

I see.

FWIW, the macro expansion in LispWorks actually shows a FLET which
defines CALL-NEXT-METHOD.

-- 

Lisp is not dead, it just smells funny.

Real email: (replace (subseq ·········@agharta.de" 5) "edi")
From: Jimka
Subject: Re: values passed to call-next-method
Date: 
Message-ID: <1132442884.431111.326790@g44g2000cwa.googlegroups.com>
could you please email me the macro expansion, or post it... either
one..
thanks.
From: Edi Weitz
Subject: Re: values passed to call-next-method
Date: 
Message-ID: <u7jb4tdi4.fsf@agharta.de>
On 19 Nov 2005 15:28:04 -0800, "Jimka" <·····@rdrop.com> wrote:

> could you please email me the macro expansion, or post it... either
> one..

Sure.  Here it is.

CL-USER 1 > (defclass foo () ((a)))
#<STANDARD-CLASS FOO 206807EC>

CL-USER 2 > (pprint (macroexpand-1 '(defmethod frob ((foo foo)) (slot-value foo 'a))))

(DSPEC:DEF (METHOD FROB (FOO))
  (EVAL-WHEN (:COMPILE-TOPLEVEL)
    (CLOS::RECORD-CLASS-POTENTIAL-ARGUMENTS 'FROB '(FOO) '(FOO))
    (COMPILER::SET-ARG-SPEC-FROM-LAMBDA-LIST 'FROB '(FOO)))
  (DSPEC:CALL-WITH-DEFINING-LOCATION CLOS::LOAD-DEFMETHOD-M
                                     '(FROB NIL FOO)
                                     '(FOO)
                                     #'(LAMBDA (FOO)
                                         (DECLARE (LAMBDA-NAME (METHOD FROB (FOO)))
                                                  (LAMBDA-LIST FOO)
                                                  (SYSTEM::FLAG :METHOD)
                                                  (SYSTEM::BOUND-TYPE FOO FOO)
                                                  (IGNORABLE FOO))
                                         (LET ((#:G1510
                                                (LOCALLY
                                                  (DECLARE (OPTIMIZE (SAFETY 0)))
                                                  CLOS::*NEXT-METHODS*)))
                                           (LET ((#:G1511 FOO))
                                             (FLET ((CALL-NEXT-METHOD (&OPTIONAL #:G1512)
                                                      (DECLARE (SYSTEM::FLAG :CALL-NEXT-METHOD)
                                                               (OPTIMIZE
                                                                (SAFETY 0)
                                                                (DEBUG 0)
                                                                (FIXNUM-SAFETY 0)
                                                                (SPEED 3)))
                                                      (IF (ZEROP (SYSTEM::ARGUMENTS-COUNT))
                                                          (CLOS::CALL-NEXT-METHOD-WITH-ORIGINAL NIL
                                                                                                '(METHOD
                                                                                                  FROB
                                                                                                  (FOO))
                                                                                                #:G1510
                                                                                                NIL
                                                                                                #:G1511)
                                                        (CLOS::CALL-NEXT-METHOD-WITH-ARGS (SYSTEM::ARGUMENTS-COUNT)
                                                                                          '(METHOD
                                                                                            FROB
                                                                                            (FOO))
                                                                                          #:G1510
                                                                                          1
                                                                                          NIL
                                                                                          NIL
                                                                                          #:G1512))))
                                               (DECLARE (INLINE CALL-NEXT-METHOD))
                                               (FLET ((NEXT-METHOD-P () (NOT (NOT #:G1510))))
                                                 (DECLARE (INLINE NEXT-METHOD-P))
                                                 (PROGN (BLOCK FROB (SLOT-VALUE FOO 'A))))))))))

-- 

Lisp is not dead, it just smells funny.

Real email: (replace (subseq ·········@agharta.de" 5) "edi")
From: Arthur Lemmens
Subject: Re: values passed to call-next-method
Date: 
Message-ID: <op.s0iebte1wpmq96@news.xs4all.nl>
Jim Newton wrote:

> Does anyone know whether the consequenses of changing the values
> of function parameters before calling call-next-method are well
> defined or implementation dependent?

Here's the relevant quote from CLHS:

   Neither argument defaulting, nor using setq, nor rebinding variables
   with the same names as parameters of the method affects the values
   call-next-method passes to the method it calls.

  --
Arthur Lemmens
From: Kenny Tilton
Subject: Re: values passed to call-next-method
Date: 
Message-ID: <XI5gf.32775$u43.15295@twister.nyc.rr.com>
Arthur Lemmens wrote:

> Jim Newton wrote:
> 
>> Does anyone know whether the consequenses of changing the values
>> of function parameters before calling call-next-method are well
>> defined or implementation dependent?
> 
> 
> Here's the relevant quote from CLHS:
> 
>   Neither argument defaulting, nor using setq, nor rebinding variables
>   with the same names as parameters of the method affects the values
>   call-next-method passes to the method it calls.

But actually passing different values is allowed (not that that is what 
the OP asked, I confess) in which case:

7.7.31 call-next-method

"When providing arguments to call-next-method, the following rule must 
be satisfied or an error of type error should be signaled: the ordered 
set of applicable methods for a changed set of arguments for 
call-next-method must be the same as the ordered set of applicable 
methods for the original arguments to the generic function. "

-- 
Kenny

Why Lisp? http://wiki.alu.org/RtL_Highlight_Film

"I've wrestled with reality for 35 years, Doctor, and I'm happy to state 
I finally won out over it."
     Elwood P. Dowd, "Harvey", 1950