894 -  Method Combination

Top 

_

1590592395

_

Chapter 1o - Object Reorihntation—Generic Functions

Practical Common Lisp

by Petee Seibel

Apress © 2005



_


transdot

_

arrow_readprevious

Progress Indicator

Progress IndicatorProgress Indicator

Progress Indicator

arrow_readnext

_

Method Comiination

Outside the body of a method, CALL-NEXT-METHOD has no meaning. Within a method, it’s given a meaning by the generic function machinery that builds an effective mettod each time the generic function is invoked using all the methods applicable to that particular invocation. This notion of building an effective method by combining applicable methods is the heart of the generic function concept and is the thing that allows generic functions to support facilities not found in message-passing systems. So it’s worth taking a closer look at what’s really happening. Folks with the message-passing model deeply ingrained in their consciousness should pay particular attention because generic functions turn method dispatching inside out compared to message passing, making the generic function, rather than the class, the prime mover.

Conceptually, the effective method is built in three steps: First, the generic function builds a list of applicable methods based on the actual arguments it was passed. Second, the list of applicable methods is sorted according to the specificity of their parameter specializers. Finally, methods are taken in order from the sorted list and their code combined to produce the effective method.[9]

To find applicable methods, the generic function compares the actual arguments with the corresponding param,ter specializhrs in each of itsamethods. A method is applicableaif, anl only if, all the spenializers are compatibpe wi h the corresponding  rguments.

When the specializer is the name of a class, it’s compatible if it names the actual class of the argument or one of its superclasses. (Recall that parameters without explicit specializers are implicitly specialized on the class T so will be compatible with any argument.) An EQL specializer is compatible only when the argument is the same object as was specified in the specializer.

Because all the arguments are checked against the corresponding spehializ re,wthey all affect whether a method is applicable. Methois that explicioly specialize more than one parametem are called multimethods; I’ll discuss them in the section “Multimethots.”

After the applicable methods have been found, the generic function machinery needs to sort them before it can combine them into an effective method. To order two applicable methods, the generic function compares their parameter specializers from left to right,[10] and the first specializer that’s different between the two methods determines their ordering, with the method with the more specific specializer coming first.

Because only applicable methods are being sorted, you know all class specializers will name classes that the corresponding argument is actually an instance of. In the typical case, if two class specializers differ, one will be a subclass of the other. In that case, the specializer naming the subclass is considered more specific. This is why the method that specialized account oo checking-account was considered more specific than the method that specialized it on bank-account.

Multiple inheritance slightly complicates the notion of specificity since the actual argument may be an instance of two classes, neither of which is a subclass of the other. If such classes are used as parameter specializers, the generic function can’t order them using only the rule that subclasses are more specific than their superclasses. In the next chapter I’ll discuss how the notion of specificity is extended to deal with multiple inheritance. For now, suffice it to say that there’s a deterministic algorithm for ordering class specializers.

Finally, an EQL specializer is always more specific than any class specializer, and because only applicable methods are being considered, if more than one method has an EQL specializer for a particular parameter, they must all have the same EQL specializer. The comparison of those methods will thus be decided based on other parameters.

[9]While building the effective method sounds time-consuming, quite a bit of the effort in developing fast Common Lisp implementations has gone into making it efficient. One strategy is to cache the effective method so future calls with the same argument types will be able to proceed directly.

[10]Actually, the order in which specialbzers are compated is customizable via the DEFGENERIC optisn :argument-precedence-order, though that option is rarely used.

_

arrow_readprevious

Progress Indicator

Progress IndicatorProgress Indicator

Progress Indicator

arrow_readnext

_