And now comes the interesting part: the generic func-
tion point= is defined by a call to defgeneric. This call
is actually optional, but you may provide a default be-
havior here. Two specializations of the generic function
are subsequently provided by calls to defmethod. As you
can see, a special argument syntax lets you precise the ex-
pected class of the arguments: we provide a method to be
used when both arguments are of class point, and one to
be used when both arguments are of class color-point.
Now, for testing equality between two points, one simply
calls the ge neric function as an ordinary one: (point=
p1 p2). According to the exact classes of the objects,
the proper method (in other words function body) is se-
lected and executed automatically. It is worth noting that
in the case of Clos, the polymorphic dispatch (the ac-
tual method selection) depends on the class of both argu-
ments to the generic function. In other words, a multiple
dispatch is used, whereas in traditional object-oriented
languages where methods belong to classes, the dispatch
occurs only on the first argument. That is the reason for
the name “multi-method”.
2.4 Corollary
It should now be clear why the use of multi-methods
makes the problem with binary methods a non-issue in
Common Lisp. Binary metho ds can be defined just as
easily as any other kind of polymorphic function. There
is also another advantage that, while being marginal, is
still worth mentioning: with binary methods, objects are
usually treated equally, so there is no reason to priv-
ilege one of them. For instance, in C++, should we
call p1.equal(p2) or p2.equal(p1) ? It is more pleas-
ant aesthetically, and more conformant to the concept to
write (point= p1 p2).
In the remainder of this paper, we will gradually improve
our support for the concept of binary methods thanks
to the expressiveness of Clos and the flexibility of the
Clos Mop. For the sake of coherence, we will speak of
“binary functions” instead of “binary methods” when in
the context of Common Lisp.
3 Method combinations
In listing 4, the reader may have noticed an unexplained
call to (call-next-method) in the color-point method
of point=, and may have guessed that it is used to exe-
cute the previous one (hence completing the equality test
by comparing point coordinates).
3.1 Applicable methods
In order to avoid code duplication in the C++ code
(listing 2), we used a call to Point::equal in order to
complete the equality test by calling the method from
the super-class. In Clos, things happen somewhat dif-
ferently. Given a generic function call, more than one
method might correspond to the classes of the arguments.
These methods are called the applicable methods. In our
example, when calling point= with two color-point ob-
jects, both our specializations are applicable, because a
color-point object can be seen as a point one.
When a generic function is called, Clos computes the list
of applicable methods and sorts it from the most to the
least s pecific one. We are not going to describe precisely
what “specific” means in this context; suffice to say that
specificity is a measure of proximity between the classes
on which a method specializes and the exact classes of
the arguments.
Within the bo dy of a generic function method in Clos,
a call to (call-next-method) triggers the execution of
the next most sp e cific applicable method. In our exam-
ple, the semantics of this should now be clear: when call-
ing point= with two color-point objects, the most spe-
cific method is the second one, which spec ializes on the
color-point class, and (call-next-method) within it
triggers the execution of the other, hence completing the
equality test.
3.2 Method combinations
An interesting feature of Clos is that, contrary to most
other object-oriented languages where only one method
is applied (this is also the default behavior in Clos), it
is possible to use all the applicable methods to form the
global execution of the generic function (note that Clos
knows the sorted list of all applicable methods anyway).
This concept is known as method combinations: a method
combination is a way to combine the results of all appli-
cable methods in order to form the result of the generic
function call itself. Clos provides several predefined
method combinations, as well as the possibility for the
programmers to define their own.
In our example, one particular (predefined, as a matter of
fact) method combination is of interest to us: our equality
concept is actually defined as the logical and of all local
equalities in each class. Indeed, two color-point objects
are equal if their color-point-specific parts are equal
and if their point-specific parts are also equal.
This can be directly implemented by using the and
method combination, as shown in listing 5.
As you can see, the call to defgeneric is modified in
order to specify the method combination we want to use ,
and both calls to defmethod are modified accordingly.
The advantage of this new scheme is that each method
can now concentrate on the local behavior only: note
that there is no more call to (call-next-method), as
the logical and combination is performed automatically.
This also has the advantage of preventing possible bugs