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
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")
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")
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
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