If you want to call specific methods of classes you are defeating the purpose of CLOS. Note also that CLOS is more general than this, since it does not only support multiple inheritance, but also multiple dispatch. Dispatch can work on more than one argument. Thus methods don't belong to classes and inheritance of methods is not based on class inheritance, but on method combinations (which usually uses class inheritance to order methods in some way).
Let's see methods which dispatch on two arguments:
(defmethod m1 ((obj1 C1.0) (obj2 C1.0)) ...)
(defmethod m1 ((obj1 C2.1) (obj2 C1.0)) ...)
(defmethod m1 ((obj1 C2.2) (obj2 C3.0)) ...)
(defmethod m1 ((obj1 C3.0) (obj2 C3.0)) ...)
Note that we talk about standard method combination, where typically the most specific primary method gets called, when you call the generic function. In CLOS the applicable methods in standard method combination can call the next method via call-next-method
. That's the usual mechanism to directly invoke inherited functionality (there are also :before
, :after
and :around
methods which may provide inherited functionality).
But what about another (simple) method combination, like +
, progn
or and
? In the case of +
all applicable methods get called and the results are added.
Then we have methods like:
(defmethod m1 + ((obj1 C1.0) (obj2 C1.0)) 1)
(defmethod m1 + ((obj1 C2.1) (obj2 C1.0)) 2)
(defmethod m1 + ((obj1 C2.2) (obj2 C3.0)) 10)
(defmethod m1 + ((obj1 C3.0) (obj2 C3.0)) 20)
Simple method combinations like that are not often used in applications or libraries. CLOS also provides a way for user-specified complex method combinations (example: design by contract functionality can be implemented by the user in CLOS).
You can work around it in CLOS: You can get access to specific methods of a generic function and call its method function, but this is rarely used and already a meta-level functionality. You can also write your own method combination, where you can provide a more complex calling method. But that is also quite difficult.
Thus it may make sense to think of a 'diamond problem' in CLOS only if you think in terms of class-oriented object systems and try to use CLOS as such - which is kind of possible by limiting CLOS usage to simple cases. But then CLOS does not have a solution to the diamond problem. CLOS avoids it for slots by merging same slots into one. CLOS avoids it for methods by providing a different way to organize methods into generic classes and calling them, by first assembling them via method combination.