I only have cmucl and clisp, and apparently combination types
are not implmented in clisp 19a. But i get a strange error in cmcl.
Is this something strange about cmucl, or is it a stardard limitation?
I would expect calling the method FUN on an object of class c1
to return the list ( before_c1 primary_c1).
Would anyone else expect the same thing?
(defclass c1 nil nil)
(defgeneric fun ( self)
(:method-combination list))
(defmethod fun :before (( self c1))
'before_c1)
(defmethod fun (( self c1))
'primary_c1)
* (defclass c1 nil nil)
#<STANDARD-CLASS C1 {580195E5}>
* (defgeneric fun ( self)
(:method-combination list))
#<STANDARD-GENERIC-FUNCTION FUN (0) {580796E9}>
* (defmethod fun :before (( self c1))
'before_c1)
; Compiling LAMBDA (PCL::.PV-CELL. PCL::.NEXT-METHOD-CALL. SELF):
; Compiling Top-Level Form:
Warning:
Method #<STANDARD-METHOD FUN :BEFORE (C1) {580DF12D}> contains invalid
qualifiers for the method combination LIST.
#<STANDARD-METHOD FUN :BEFORE (C1) {580DF12D}>
> (defgeneric fun ( self)
> (:method-combination list))
> (defmethod fun :before (( self c1))
> 'before_c1)
When the method combination of your function is LIST, the only allowed
method qualifiers are LIST and :AROUND, not :BEFORE. See ANSI CL 7.6.6.4.
Bruno
I even get a similar error/warning when i define my own method
combination type.
(define-method-combination jimka
:operator list
:identity-with-one-argument nil)
(defclass c1 nil nil)
(defgeneric fun ( self)
(:method-combination jimka))
(defmethod fun :before (( self c1))
'before_c1)
> Warning:
> Method #<STANDARD-METHOD FUN (C1) {583FC875}> contains invalid
> qualifiers
> for the method combination JIMKA.
(defmethod fun (( self c1))
'primary_c1)
Jim Newton <·····@rdrop.com> writes:
> I even get a similar error/warning when i define my own method
> combination type.
>
>
> (define-method-combination jimka
> :operator list
> :identity-with-one-argument nil)
According to the dictionary entry for DEFINE-METHOD-COMBINATION,
this defines a method combination type that "recognizes two roles
for methods": each method must have a qualifier that is either
:AROUND or JIMKA. Thus, :BEFORE and :AFTER are not allowed.
The same applies to the built-in method combination type LIST,
and to others except STANDARD. See section 7.6.6.4.
If you need to support :BEFORE and :AFTER, then I guess you have
to use the long form of DEFINE-METHOD-COMBINATION.
Hi Kalle, that is not how i read the definition.
http://www.lisp.org/HyperSpec/Body/mac_define-me_-combination.html#define-method-combination
> The short form syntax of define-method-combination is recognized
> when the second subform is a non-nil symbol or is not present.
> When the short form is used, name is defined as a type of method
> combination that produces a Lisp form (operator method-call
> method-call ...). The operator is a symbol that can be the name
> of a function, macro, or special operator. The operator can
> be supplied by a keyword option; it defaults to name.
What I want is operator = list
so that a call to the generic function works like
(list method-call method-call ...)
As I understand the definition of the short-form, the first
argument of define-method-combination is a symbol which can
later be used as a value of :method-combination in defgeneric
and the :operator if specified is the function used to
combine the values of the before methods and the primary
method. I also get this impression from reading
Chapter 5 of Keene. Controlling the Generic Dispatch.
Is my understanding wrong?
-jim
Kalle Olavi Niemitalo wrote:
> Jim Newton <·····@rdrop.com> writes:
>
>
>>I even get a similar error/warning when i define my own method
>>combination type.
>>
>>
>>(define-method-combination jimka
>> :operator list
>> :identity-with-one-argument nil)
>
>
> According to the dictionary entry for DEFINE-METHOD-COMBINATION,
> this defines a method combination type that "recognizes two roles
> for methods": each method must have a qualifier that is either
> :AROUND or JIMKA. Thus, :BEFORE and :AFTER are not allowed.
>
> The same applies to the built-in method combination type LIST,
> and to others except STANDARD. See section 7.6.6.4.
>
> If you need to support :BEFORE and :AFTER, then I guess you have
> to use the long form of DEFINE-METHOD-COMBINATION.
start quoting Jim Newton :
> As I understand the definition of the short-form, the first
> argument of define-method-combination is a symbol which can
> later be used as a value of :method-combination in defgeneric
> and the :operator if specified is the function used to
> combine the values of the before methods and the primary
> method. I also get this impression from reading
> Chapter 5 of Keene. Controlling the Generic Dispatch.
>
> Is my understanding wrong?
>
A bit out of my depth, but here's a thought:
A generic function using list method combination returns a list of the
return values of applicable methods, run in most-specific to least-specific
order.
:before methods and :after methods don't normally return values, so there's
nothing to put in the list. You could of course write a custom combinator
that does include their return values, but programmers don't
*expect* :before methods to influence the return value unless they have
appropriate side-effects, which is a large part of why they're so useful.
The idea, then, might be that forcing you to write your own combinator will
also make you take a hard look at what you're doing, and possibly avoid
using the :before and :after names - I suggest :prologue and :epilogue as
possible alternatives.
Well, it could be something entirely different. I won't claim to understand
the minds of those who built Lisp.
Hi Kalle, i have reread the chapter of Keene, and the
section in the hyper spec and your input is very very
useful. It is amazing how the light comes on with a
little bit of clarification. thanks.
I see now that method combination types are not
intended to combine the before methods with the
primary method, but in stead to combine the
primary methods.
Seems like to declare my JIMKA method combination
I must
1) declare it with define-method-combination
2) specify it with :method-combination with defgeneric
and 3) specify JIMKA as the qualifier in a defmethod call.
However, the syntax is still confusing to me.
It is not clear why it must be used in the defmethod
if it is already given in the defgeneric? Is it allowed to
have some methods have the method combination and others
have :around and others have none? Which method calls
get operated on by the method-combination operator?
All the primary methods? or simply the ones specified
with the method-combination qualifier? What happens
to the ones without a qualifier?
-jim
Kalle Olavi Niemitalo wrote:
> Jim Newton <·····@rdrop.com> writes:
>
>
>>I even get a similar error/warning when i define my own method
>>combination type.
>>
>>
>>(define-method-combination jimka
>> :operator list
>> :identity-with-one-argument nil)
>
>
> According to the dictionary entry for DEFINE-METHOD-COMBINATION,
> this defines a method combination type that "recognizes two roles
> for methods": each method must have a qualifier that is either
> :AROUND or JIMKA. Thus, :BEFORE and :AFTER are not allowed.
>
> The same applies to the built-in method combination type LIST,
> and to others except STANDARD. See section 7.6.6.4.
>
> If you need to support :BEFORE and :AFTER, then I guess you have
> to use the long form of DEFINE-METHOD-COMBINATION.
Jim Newton <·····@rdrop.com> writes:
(About the name of the method combination type:)
> It is not clear why it must be used in the defmethod
> if it is already given in the defgeneric?
I believe it is a reminder to people reading or modifying those
methods. The value returned by the method will often be combined
with others, rather than just passed through, and you need to
remember this so that you can make the method return a suitable
value. For example, with NCONC method combination, each primary
method must return a value that can be destructively modified.
Also, primary methods in generic functions that use standard
method combination can call NEXT-METHOD-P and CALL-NEXT-METHOD,
but those in generic functions that use simple built-in method
combination types cannot.
If you change the generic function to use a different method
combination type, then it is likely that you need to change the
primary methods too. Having the name of the method combination
as a qualifier of each primary method lets the Lisp detect
methods that you haven't yet changed.
> Is it allowed to have some methods have the method combination
> and others have :around and others have none?
No, it isn't. SBCL gives a rather clear error message:
| * (defgeneric fun (arg) (:method-combination jimka))
|
| #<STANDARD-GENERIC-FUNCTION FUN (0)>
| * (defmethod fun (arg) t)
| WARNING:
| Invalid qualifiers for JIMKA method combination in method
| #<STANDARD-METHOD FUN (T) {91E5761}>:
| NIL.
|
| #<STANDARD-METHOD FUN (T) {91E5761}>
| * (fun 42)
|
| debugger invoked on a SIMPLE-ERROR in thread 20347:
| invalid method error for
| #<STANDARD-METHOD FUN (T) {91E5761}>
| method:
| The method #<STANDARD-METHOD FUN (T) {91E5761}> on #<STANDARD-GENERIC-FUNCTION FUN (1)> has no qualifiers.
| The method combination type JIMKA was defined with the
| short form of DEFINE-METHOD-COMBINATION and so requires
| all methods have either the single qualifier JIMKA or the
| single qualifier :AROUND.
> Which method calls
> get operated on by the method-combination operator?
> All the primary methods? or simply the ones specified
> with the method-combination qualifier?
If the generic function uses a method combination type defined
with the short form of DEFINE-METHOD-COMBINATION, then the
primary methods are those that have the name of the method
combination type as the only qualifier. Methods without any
qualifiers are then not primary methods, although they would in
standard method combination.
> What happens to the ones without a qualifier?
If any such method is applicable when the generic function is
called, an error is signalled. This is specified in the
dictionary entry for DEFINE-METHOD-COMBINATION ("An error is
signaled if there are applicable"...) and in section 7.6.6.1.3
("If an applicable method has"...).