One of a symbol, a form denoting a setter
function or a converter function.
gf lambda list
The parameter list of the generic
function, which may be specialized to restrict the domain of methods to
be attached to the generic function.
level 0 init option
A sequence of options as specified
below.
Remarks
This defining form defines a new generic function. The
resulting generic function will be bound to gf name. The second
argument is the formal parameter list. The method's specialized lamba list
must be congruent to that of the generic function. Two lambda lists are said
to be congruent iff:
both have the same number of formal parameters, and
if one lambda list has a rest formal parameter then the other lambda list
has a rest formal parameter too, and vice versa.
An error is signalled (condition class:
<non-congruent-lambda-lists>) if any method defined on this
generic function does not have a lambda list congruent to that of
the generic function.
An error is signalled (condition class:
<incompatible-method-domain>) if the method's specialized
lambda list widens the domain of the generic function. In other words, the
lambda lists of all methods must specialize on subclasses of the classes in the
lambda list of the generic function.
An error is signalled (condition class:
<method-domain-clash>) if any methods defined on this
generic function have the same domain. These conditions apply both to
methods defined at the same time as the generic function and to any methods
added subsequently by codedefmethod. An init-option is an
identifier followed by a corresponding value.
An error is signalled (condition class:
<no-applicable-method>) if an attempt is made to apply a
generic function which has no applicable methods for the classes of the
arguments supplied.
The level 0 init option is:
method : method-spec
This option is
followed by a method description. A method description is a list
comprising the specialized lambda list of the method, which denotes the
domain, and a sequence of forms, denoting the method body. The
method body is closed in the lexical environment in which the generic
function definition appears. This option may be specified more than
once.
In the following example of the use of
defgeneric a generic function named gf-0 is
defined with three methods attached to it. The domain of
gf-0 is constrained to be <object>x<class-a>. In consequence, each method
added to the generic function, both here and later (by
defmethod), must have a domain which is a subclass of
<object>x<class-a>,
which is to say that <class-c>, <class-e> and
<class-g> must all be subclasses of <class-a>.
(defgeneric gf-0 (arg1 (arg2 ))
method: (((m1-arg1 ) (m1-arg2 )) ...)
method: (((m2-arg1 ) (m2-arg2 )) ...)
method: (((m3-arg1 ) (m3-arg2 )) ...))
This macro is used for defining new methods on generic
functions. A new method object is defined with the specified body and with
the domain given by the specialized lambda list. This method is added to the
generic function bound to the specified generic function. If the
specialized-lambda-list is not congruent with that of the generic function, an
error is signalled (condition class:
<non-congruent-lambda-lists>). An error is signalled
(condition class: <incompatible-method-domain>) if the
method's specialized lambda list would widen the domain of the generic
function. If there is a method with the same domain already defined on this
generic function, an error is signalled (condition class:
<method-domain-clash>).
generic-lambda creates and returns an
anonymous generic function that can be applied immediately, much like the
normal lambda. The gen lambda list and the
level 0 init options are interpreted exactly as for the level-0
definition of defgeneric.
Examples
In the following
example an anonymous version of gf-0 (see
defgeneric above) is defined. In all other respects the
resulting object is the same as gf-0.
(generic-lambda ((arg1
See also:
defgeneric.
Specializing Methods
The following two operators are used to specialize more general methods. The
more specialized method can do some additional computation before calling
these operators and can then carry out further computation before returning.
It is an error to use either of these operators outside a method body. Argument
bindings inside methods are immutable. Therefore an argument inside a
method retains its specialized class throughout the processing of the method.
call-next-method :
special form
Syntax
(call-next-method)
Result
The result of calling the next most specific applicable method.
Remarks
The next most specific applicable method is called with the
same arguments as the current method. An error is signalled (condition class:
<no-next-method>) if there is no next most specific method.
next-method-p :
special form
Syntax
(next-method-p)
Result
If there is a next most specific method,
next-method-p returns a non-() value,
otherwise, it returns ().
Method Lookup and Generic Dispatch
The system defined method lookup and generic function dispatch is purely
class based. eql methods known from CLOS are excluded.
The application behaviour of a generic function can be described in terms of
method lookup and generic dispatch. The method
lookup determines
which methods attached to the generic function are applicable to the
supplied arguments, and
the linear order of the applicable methods with respect to classes of the
arguments and the argument precedence order.
A class C1 is called more specific than class C2 with respect
to C3 iff C1 appears before C2 in the class precedence list (CPL) of
C3 (Note 1: This definition is required when multiple inheritance comes into
play. Then, two classes have to be compared with respect to a third class even
if they are not related to each other via the subclass relationship. Although,
multiple inheritance is not provided at level-0, the method lookup protocol is
independent of the inheritance strategy defined on classes. It depends on the
class precedence lists of the domains of methods attached to the generic
function and the argument classes involved.).
Two additional concepts are needed to explain the processes of method lookup
and generic dispatch: (i) whether a method is applicable, (ii) how
specific it is in relation to the other applicable methods. The
definitions of each of these terms is now given.
A method with the domain D-1 x ... x D-m x
<list> is applicable to the arguments
a-1 ... a-m [a-m+1 ... a-n] if the class of each argument,
C-i, is a subclass of D-i, which is to say,
D-i is a member of C-i's class precedence
list.
A method M-1 with the domain D-11 x ... x D-1m [
x <list>] is more specific than a method
M-2 with the domain D-21 x ... x D-2m [ x
<list>]with respect to the arguments
a-1 ... a-m [a-m+1 ... a-n] iff there exists an
i in 1 ... m such that
D-1i is more specific than D-2i with
respect to C-i, the class of a-i, and for all
j=1 ... i-1, D-2j is not more
specific than D-1j with respect to C-j, the
class of a-j.
Now, with the above definitions, we can describe the application behaviour of
a generic function (f a-1 ... a-m [a-m+1 ... a-n]):
Select the methods applicable to a-1 ... a-m [a-m+1 ...
a-n] from all methods attached to f.
Sort the applicable methods M-1...M-k into decreasing order of specificity
using left to right argument precedence order to resolve otherwise
equally specific methods.
If call-next-method appears in one of the method
bodies, make the sorted list of applicable methods available for it.
Apply the most specific method on a-1 ... a-m [a-m+1 ...
a-n].
Return the result of the previous step.
The first two steps are usually called method lookup and the first
four are usually called generic dispatch.
Julian Padget, jap@maths.bath.ac.uk, this version February 27, 1995