Creates a generic function and bind it to name.
You don’t usually need to use this, since the
macro implicitly creates a generic function if it doesn’t exist yet.
You can pass a subclass of
<generic> to the class
keyword argument so that the created generic function will be the
instance of the passed class, instead of the default
It is useful when you defined a subclass of
<generic> to customize
generic function application behavior.
Defines a method whose name is name. If there’s already a generic function object globally bound to name, the created method is added to the generic function. If name is unbound, or bound to an object except a generic function, then a new generic function is created, bound to name, then a new method is added to it.
Specs specifies the arguments and their types for this method. It’s like the argument list of lambda form, except you can specify the type of each argument.
specs : ( arg … ) | ( arg … . symbol ) | ( arg … extended-spec …) | symbol arg : ( symbol class ) | symbol
Class specifies the class that the argument has to belong to.
arg is just a symbol, it is equivalent to
(arg <top>). You can’t specify the type for
the “rest” argument, for it is always bound to a list.
You can use extended argument specifications such as
:rest as well.
(See Making Procedures, for the explanation of extended
argument specifications). Those extended arguments are treated
as if a single “rest” argument in terms of dispatching; they
aren’t used for method dispatch, and you can’t specify classes for
these optional and keyword arguments.
The list of classes of the argument list is called
method specializer list, based on which the generic
function will select appropriate methods(s).
Here are some examples of specs and the corresponding
specializer list (note that the rest argument isn’t considered
as a part of specializer list; we know it’s always a list.)
optional item indiecates whether the method takes
rest arguments or not.
specs: ((self <myclass>) (index <integer>) value) specializers: (<myclas> <integer> <top>) optional: #f specs: (obj (attr <string>)) specializers: (<top> <string>) optional: #f specs: ((self <myclass>) obj . options) specializers: (<myclas> <top>) optional: #t specs: ((self <myclass>) obj :optional (a 0) (b 1) :key (c 2)) specializers: (<myclas> <top>) optional: #t specs: args specializers: () optional: #t
If you define a method on name whose specializer list, and whether it takes rest argumetns, matche with one in the generic function’s methods, then the existing method is replaced by the newly defined one.
When a generic function is applied, first it selects
methods whose specializer list matches the given arguments.
For example, suppose a generic function
three methods, whose specializer lists are
(<top> <top>), respectively.
foo is applied like
(foo "abc" 3),
the first and the third method will be selected.
Then the selected methods are sorted from the most specific method to the least specific method. It is calculated as follows:
athat has specializers
(A1 A2 …), and a method
(B1 B2 …).
Bndiffer. Then the class of n-th argument is taken, and its class precedence list is checked. If
Bnin the CPL, then method
ais more specific than
bis more specific than
bare the same, except that one has an improper tail ("rest" argument) and another doesn’t, then the method that doesn’t have an improper tail is more specific than the one that has.
Once methods are sorted, the body of the first method is called with the actual argument.
Within the method body, a special local variable
is bound implicitly.
This variable is bound within a method body to a special object that encapsulates the next method in the sorted method list.
Calling without arguments invokes the next method with the same arguments as this method is called with. Passing args … explicitly invokes the next method with the passed arguments.
next-method is called in the least specific method,
i.e. there’s no "next method", an error is signaled.