12.2.7 Keyword-argument checking
When a function is called, Dylan determines which keyword arguments, if any, are permitted for that function call. The set of permitted keyword arguments depends on whether or not a generic function is being called:
If a method is called directly, rather than through a generic function, the specific keywords in the method's parameter list are permitted. If the parameter list includes
#all-keys, any keyword argument is permitted.If a generic function is called, all the specific keywords in the parameter lists of all applicable methods are permitted. If the parameter list of the generic function or of any applicable method includes
#all-keys, any keyword argument is permitted.
When a generic function is called, one of its methods is applicable if every required argument is an instance of the type of the corresponding parameter of the method. For more information on applicable methods, see Section 5.5, page 63.
Consider the following definitions:
define generic g (arg1 :: <real>, #key); // Method 1 define method g (arg1 :: <real>, #key real-key) ... end method g; // Method 2 define method g (arg1 :: <float>, #key float-key) ... end method g; // Method 3 define method g (arg1 :: <integer>, #key integer-key) ... end method g;
Now, if we call the generic function g with an instance of <float>, we can supply the keyword arguments real-key: and float-key:, because the methods that have those keyword parameters are both applicable. If we call g with an instance of <integer>, we can supply the keyword arguments real-key: and integer-key:.
Suppose that, in this same example, we call the generic function g with an instance of <float>, and supply the keyword arguments real-key: and float-key:. Method 2 is most specific, and is called as a result of Dylan's method dispatch. But method 2 does not have a real-key: parameter. If we were calling this method directly, Dylan would signal an error. In this case, method 2 simply ignores the real-key: argument, because Dylan checks keyword arguments for a generic function call as a whole, rather than for a particular method chosen as a result of method dispatch.
There is an important subtlety of keyword-parameter specifications to note in this example. Because of the rules for parameter-list congruence, the generic function and all its methods must accept keyword arguments — that is, they must all have #key in their parameter lists. Notice that we terminated the generic function's parameter list with #key. This use indicates that the generic function permits — but does not require — individual methods to specify keyword parameters.
Suppose that we had instead terminated the generic function's parameter list with #key, #all-keys. This use also would have permitted, but would not have required, individual methods to specify keyword parameters. But it also would have allowed a caller of the generic function to supply any keyword argument. In the earlier example, only a small set of keyword arguments was permitted, and the members of the set varied with the applicable methods.
In general, when you define a generic function or a method that accepts keyword arguments, it is advisable not to specify #all-keys unnecessarily, because doing so defeats Dylan's keyword-argument checking. If a method needs to accept keyword arguments because of the rules of parameter-list congruence, but does not need to recognize any keywords itself, you should terminate its parameter list with #key.




