It is useful to understand, first, that the rules for keyword arguments accepted by generic functions are rather different and more complex than for non-generic functions, and second, why this is so.
A non-generic function is defined in one place, e.g. with a singe defun form, and its keyword processing can be determined from that single form. This remains true even if the function is redefined during run time.
A generic function is different in that it is (usually) specified by numerous defgeneric and defmethod and defclass forms. (All of these can add methods to a gf!) And methods can also be added and deleted programatically at run time. The intention of the rules is that the gf should accept a keyword arg iff there is a method willing to deal with it, and (very important) such a keyword arg should _not_ bother any method _not_ prepared to deal with it.
That's one reason why responsibility for keyword arg checking is placed upon the gf, and not upon individual method functions.
On Sun, Feb 9, 2014 at 1:10 AM, Didier Verna didier@lrde.epita.fr wrote:
Jean-Claude Beaudoin jean.claude.beaudoin@gmail.com wrote:
Hello CL Pros,
I am trying to understand the meaning in conforming ANSI CL of the following code snippet and I am not quite sure what to think of
it:
(defgeneric foo (a b &key))
(defmethod foo (a b &key c d) (or c d 42))
At this point should a call to foo accept any keyword argument, no keyword argument or only :c and/or :d? What would be the outcome of this:
(foo 1 2 :d 3)
Is it an error being signaled or the value 3 being returned? I am inclined to believe that an error should be signaled, since the generic function lambda-list contains no explicit keyword argument and no &allow-other-keys.
I think that's the opposite. From CLHS:
| 7.6.5 Keyword Arguments in Generic Functions and Methods | | When a generic function or any of its methods mentions &key in a lambda | list, the specific set of keyword arguments accepted by the generic | function varies according to the applicable methods. The set of keyword | arguments accepted by the generic function for a particular call is the | union of the keyword arguments accepted by all applicable methods and | the keyword arguments mentioned after &key in the generic function | definition, if any.
So because your method accepts :c and :d, then this particular call to foo does as well. The critical thing to understand here is that the valid keyword arguments may vary from one call to another.
-- Please help crowdfund my next Jazz quartet album !! http://www.kisskissbankbank.com/quartet-the-second-album
Lisp, Jazz, Aïkido: http://www.didierverna.info