From: Paul F. Dietz
Subject: CALL-NEXT-METHOD with changed parameters
Date: 
Message-ID: <g6icnTYvbqSANkejXTWcow@dls.net>
According to the ANSI CL spec page for 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. Optimizations
    of the error checking are possible, but they must not change the semantics
    of call-next-method.

So, for example, the following method should cause an error:

    (:method ((x (eql 0))) (call-next-method 1))

However, *none* of the CL implementations I've tried signal an error
when this method is invoked.

Why is this requirement in the spec, and why has noone implemented it?

	Paul

From: james anderson
Subject: Re: CALL-NEXT-METHOD with changed parameters
Date: 
Message-ID: <3EDB79A9.99C222F5@setf.de>
my experience is that it has been implemented.

? (defgeneric bad-gf (unstable-parameter)
  (:method ((string string))
           (call-next-method string))
  (:method ((list list))
           (call-next-method (concatenate 'string list)))
  (:method ((seq sequence))
           (call-next-method seq))
  (:method ((number integer))
           (call-next-method number))
  (:method ((number (eql 1)))
           (call-next-method (float number)))
  (:method ((number float))
           (call-next-method (floor number)))
  (:method ((number number))
           (call-next-method number))
  (:method ((datum t))
           datum))
#<STANDARD-GENERIC-FUNCTION BAD-GF #x61D5D9E>
? (bad-gf 1)
> Error: Applicable-methods changed in call-next-method.
>        Should be: (#<STANDARD-METHOD BAD-GF ((EQL 1))> #3=#<STANDARD-METHOD BAD-GF (INTEGER)> #1=#<STANDARD-METHOD BAD-GF (NUMBER)> #2=#<STANDARD-METHOD BAD-GF (T)>)
>        Was: (#<STANDARD-METHOD BAD-GF (FLOAT)> #1# #2#)
>        Next-methods: (#3# #1# #2#)
> While executing: CCL::DO-IT
> Type Command-. to abort.
See the Restarts� menu item for further choices.
1 > 
Aborted
? (bad-gf '(#\a #\s #\d))
> Error: Applicable-methods changed in call-next-method.
>        Should be: (#<STANDARD-METHOD BAD-GF (LIST)> #1=#<STANDARD-METHOD BAD-GF (SEQUENCE)> #2=#<STANDARD-METHOD BAD-GF (T)>)
>        Was: (#<STANDARD-METHOD BAD-GF (STRING)> #1# #2#)
>        Next-methods: (#1# #2#)
> While executing: CCL::DO-IT
> Type Command-. to abort.
See the Restarts� menu item for further choices.
1 > 
Aborted
? (bad-gf 1.1)
> Error: Applicable-methods changed in call-next-method.
>        Should be: (#<STANDARD-METHOD BAD-GF (FLOAT)> #1=#<STANDARD-METHOD BAD-GF (NUMBER)> #2=#<STANDARD-METHOD BAD-GF (T)>)
>        Was: (#<STANDARD-METHOD BAD-GF ((EQL 1))> #<STANDARD-METHOD BAD-GF (INTEGER)> #1# #2#)
>        Next-methods: (#1# #2#)
> While executing: CCL::DO-IT
> Type Command-. to abort.
See the Restarts� menu item for further choices.
1 > 
Aborted
? (bad-gf #(should be ok))
#(SHOULD BE OK)
? 

it is not clear that a single method definition cannot trigger the error, as
there has to have been a next method, and

it has also never been clear why the constraint was specified for the full set
of applicable methods rather than just the remaining methods. the latter
avoids applying methods to types which they were not intended to accept.i
would be interested to hear why the constraint needs to be applied to the
entire set.

"Paul F. Dietz" wrote:
> 
> According to the ANSI CL spec page for 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. Optimizations
>     of the error checking are possible, but they must not change the semantics
>     of call-next-method.
> 
> So, for example, the following method should cause an error:
> 
>     (:method ((x (eql 0))) (call-next-method 1))
> 
> However, *none* of the CL implementations I've tried signal an error
> when this method is invoked.
> 
> Why is this requirement in the spec, and why has noone implemented it?
> 
>         Paul
From: Barry Margolin
Subject: Re: CALL-NEXT-METHOD with changed parameters
Date: 
Message-ID: <XQLCa.15$IF6.35@paloalto-snr1.gtei.net>
In article <·················@setf.de>,
james anderson  <··············@setf.de> wrote:
>it has also never been clear why the constraint was specified for the full set
>of applicable methods rather than just the remaining methods. the latter
>avoids applying methods to types which they were not intended to accept.i
>would be interested to hear why the constraint needs to be applied to the
>entire set.

I think the intent was that if there's a :BEFORE or :AROUND method, the
primary method can depend on it having been run.  But if you change the
argument types in the middle, this expectation may be violated.

-- 
Barry Margolin, ··············@level3.com
Level(3), Woburn, MA
*** DON'T SEND TECHNICAL QUESTIONS DIRECTLY TO ME, post them to newsgroups.
Please DON'T copy followups to me -- I'll assume it wasn't posted to the group.
From: Bruno Haible
Subject: Re: CALL-NEXT-METHOD with changed parameters
Date: 
Message-ID: <bbpvsd$qnr$1@laposte.ilog.fr>
Paul F. Dietz <·····@dls.net> wrote:
> So, for example, the following method should cause an error:
>
>    (:method ((x (eql 0))) (call-next-method 1))
>
> However, *none* of the CL implementations I've tried signal an error
> when this method is invoked.

CLISP gives an error for it:

[1]> (defgeneric foo (x)
       (:method ((x (eql 0))) (call-next-method 1))
       (:method ((x integer)) (* 10 x)))
#<GENERIC-FUNCTION FOO>
[2]> (foo 0)
*** - CALL-NEXT-METHOD in #<GENERIC-FUNCTION FOO>: the new arguments (1) have a different effective method than the old arguments (0)

Bruno