29.5. Generic Functions

29.5.1. Inheritance Structure of generic function metaobject Classes
29.5.2. Introspection: Readers for generic function metaobjects
29.5.2.1. Generic Function CLOS:GENERIC-FUNCTION-NAME
29.5.2.2. Generic Function CLOS:GENERIC-FUNCTION-METHODS
29.5.2.3. Generic Function CLOS:GENERIC-FUNCTION-LAMBDA-LIST
29.5.2.4. Generic Function CLOS:GENERIC-FUNCTION-ARGUMENT-PRECEDENCE-ORDER
29.5.2.5. Generic Function CLOS:GENERIC-FUNCTION-DECLARATIONS
29.5.2.6. Generic Function CLOS:GENERIC-FUNCTION-METHOD-CLASS
29.5.2.7. Generic Function CLOS:GENERIC-FUNCTION-METHOD-COMBINATION
29.5.2.8. Methods
29.5.3. Initialization of Generic Functions
29.5.3.1. Macro DEFGENERIC
29.5.3.2. Generic Function Invocation Protocol
29.5.3.3. Initialization of generic function metaobjects
29.5.3.3.1. Methods
29.5.4. Customization
29.5.4.1. Generic Function (SETF CLOS:GENERIC-FUNCTION-NAME)
29.5.4.2. Generic Function ENSURE-GENERIC-FUNCTION
29.5.4.3. Generic Function CLOS:ENSURE-GENERIC-FUNCTION-USING-CLASS
29.5.4.4. Generic Function ADD-METHOD
29.5.4.5. Generic Function REMOVE-METHOD
29.5.4.6. Generic Function CLOS:COMPUTE-APPLICABLE-METHODS
29.5.4.7. Generic Function CLOS:COMPUTE-APPLICABLE-METHODS-USING-CLASSES
29.5.4.8. Generic Function CLOS:COMPUTE-EFFECTIVE-METHOD
29.5.4.9. Function CLOS:COMPUTE-EFFECTIVE-METHOD-AS-FUNCTION
29.5.4.10. Generic Function CLOS:MAKE-METHOD-LAMBDA
29.5.4.11. Generic Function CLOS:COMPUTE-DISCRIMINATING-FUNCTION

29.5.1. Inheritance Structure of generic function metaobject Classes

Figure 29.4. Inheritance structure of generic function metaobject classes

Inheritance structure of generic function metaobject classes

29.5.2. Introspection: Readers for generic function metaobjects

The reader generic functions which simply return information associated with generic function metaobjects are presented together here in the format described in Section 29.3.3, “Introspection: Readers for class metaobjects”.

Each of the reader generic functions for generic function metaobjects has the same syntax, accepting one required argument called generic-function, which must be a generic function metaobject; otherwise, an ERROR is SIGNALed. An ERROR is also SIGNALed if the generic function metaobject has not been initialized.

These generic functions can be called by the user or the implementation.

For any of these generic functions which returns a list, such lists will not be mutated by the implementation. The results are undefined if a portable program allows such a list to be mutated.

29.5.2.1. Generic Function CLOS:GENERIC-FUNCTION-NAME

(CLOS:GENERIC-FUNCTION-NAME generic-function)

Returns the name of the generic function, or NIL if the generic function has no name. This is the defaulted value of the :NAME initialization argument that was associated with the generic function metaobject during initialization or reinitialization. (See also (SETF CLOS:GENERIC-FUNCTION-NAME).)

29.5.2.2. Generic Function CLOS:GENERIC-FUNCTION-METHODS

Returns the set of methods currently connected to the generic function. This is a set of method metaobjects. This value is maintained by the generic functions ADD-METHOD and REMOVE-METHOD.

29.5.2.3. Generic Function CLOS:GENERIC-FUNCTION-LAMBDA-LIST

Returns the lambda list of the generic function. This is the defaulted value of the :LAMBDA-LIST initialization argument that was associated with the generic function metaobject during initialization or reinitialization. An ERROR is SIGNALed if the lambda list has yet to be supplied.

Returns the argument precedence order of the generic function. This value is a list of symbols, a permutation of the required parameters in the lambda list of the generic function. This is the defaulted value of the :ARGUMENT-PRECEDENCE-ORDER initialization argument that was associated with the generic function metaobject during initialization or reinitialization.

Implementation dependent: only in CLISP

An ERROR is SIGNALed if the lambda list has not yet been supplied.

29.5.2.5. Generic Function CLOS:GENERIC-FUNCTION-DECLARATIONS

Returns a possibly empty list of the declarations of the generic function. The elements of this list are declaration specifiers. This list is the defaulted value of the :DECLARATIONS initialization argument that was associated with the generic function metaobject during initialization or reinitialization.

29.5.2.6. Generic Function CLOS:GENERIC-FUNCTION-METHOD-CLASS

Returns the default method class of the generic function. This class must be a subclass of the class METHOD. This is the defaulted value of the :METHOD-CLASS initialization argument that was associated with the generic function metaobject during initialization or reinitialization.

Returns the method combination of the generic function. This is a method combination metaobject. This is the defaulted value of the :METHOD-COMBINATION initialization argument that was associated with the generic function metaobject during initialization or reinitialization.

29.5.2.8. Methods

The specified methods for the generic function metaobject reader generic functions

(CLOS:GENERIC-FUNCTION-NAME (generic-function STANDARD-GENERIC-FUNCTION))
(CLOS:GENERIC-FUNCTION-LAMBDA-LIST (generic-function STANDARD-GENERIC-FUNCTION))
(CLOS:GENERIC-FUNCTION-ARGUMENT-PRECEDENCE-ORDER (generic-function STANDARD-GENERIC-FUNCTION))
(CLOS:GENERIC-FUNCTION-DECLARATIONS (generic-function STANDARD-GENERIC-FUNCTION))
(CLOS:GENERIC-FUNCTION-METHOD-CLASS (generic-function STANDARD-GENERIC-FUNCTION))
(CLOS:GENERIC-FUNCTION-METHOD-COMBINATION (generic-function STANDARD-GENERIC-FUNCTION))
No behavior is specified for these methods beyond that which is specified for their respective generic functions.
(CLOS:GENERIC-FUNCTION-METHODS (generic-function STANDARD-GENERIC-FUNCTION))

No behavior is specified for this method beyond that which is specified for the generic function.

The value returned by this method is maintained by ADD-METHOD(STANDARD-GENERIC-FUNCTION STANDARD-METHOD) and REMOVE-METHOD(STANDARD-GENERIC-FUNCTION STANDARD-METHOD).

29.5.3. Initialization of Generic Functions

29.5.3.1. Macro DEFGENERIC

The evaluation or execution of a DEFGENERIC form results in a call to the ENSURE-GENERIC-FUNCTION function. The arguments received by ENSURE-GENERIC-FUNCTION are derived from the DEFGENERIC form in a defined way. As with DEFCLASS and DEFMETHOD, the exact macro-expansion of the DEFGENERIC form is not defined, only the relationship between the arguments to the macro and the arguments received by ENSURE-GENERIC-FUNCTION.

  • The function-name argument to DEFGENERIC becomes the first argument to ENSURE-GENERIC-FUNCTION. This is the only positional argument accepted by ENSURE-GENERIC-FUNCTION; all other arguments are keyword arguments.
  • The lambda-list argument to DEFGENERIC becomes the value of the :LAMBDA-LIST keyword argument to ENSURE-GENERIC-FUNCTION.
  • For each of the options :ARGUMENT-PRECEDENCE-ORDER, :DOCUMENTATION, :GENERIC-FUNCTION-CLASS and :METHOD-CLASS, the value of the option becomes the value of the keyword argument with the same name. If the option does not appear in the macro form, the keyword argument does not appear in the resulting call to ENSURE-GENERIC-FUNCTION.

    Implementation dependent: only in CLISP

    If the option does not appear in the macro form, the keyword argument appears in the resulting call to ENSURE-GENERIC-FUNCTION, with a default value: the lambda-list for :ARGUMENT-PRECEDENCE-ORDER, NIL for :DOCUMENTATION, the class STANDARD-GENERIC-FUNCTION for :GENERIC-FUNCTION-CLASS, the class STANDARD-METHOD for :METHOD-CLASS. This is needed to make the generic function reflect the DEFGENERIC form.

  • For the option :DECLARE, the list of declarations becomes the value of the :DECLARATIONS keyword argument. If the :DECLARE option does not appear in the macro form, the :DECLARATIONS keyword argument does not appear in the call to ENSURE-GENERIC-FUNCTION.

    Implementation dependent: only in CLISP

    If the :DECLARE option does not appear in the macro form, the :DECLARATIONS keyword argument appears in the resulting call to ENSURE-GENERIC-FUNCTION, with a default value of NIL. This is needed to make the generic function reflect the DEFGENERIC form.

  • The handling of the :METHOD-COMBINATION option is not specified.

    Implementation dependent: only in CLISP

    If the :METHOD-COMBINATION option does not appear in the macro form, the :METHOD-COMBINATION keyword argument still appears in the resulting call to ENSURE-GENERIC-FUNCTION, but in a position where it can be overridden by user-defined initargs and default initargs.

  • Implementation dependent: only in CLISP

    The :DECLARE keyword is recognized as equivalent to the :DECLARATIONS keyword, for compatibility with ENSURE-GENERIC-FUNCTION in [ANSI CL standard]. If both :DECLARE and :DECLARATIONS keyword arguments are specified, an ERROR is SIGNALed.

    Any other generic function options become the value of keyword arguments with the same name. The value of the keyword argument is the tail of the generic function option. An ERROR is SIGNALed if any generic function option appears more than once in the DEFGENERIC form.

    The default initargs of the generic-function-class are added at the end of the list of arguments to pass to ENSURE-GENERIC-FUNCTION. This is needed to make the generic function reflect the DEFGENERIC form.

  • Implementation dependent: only in CLISP

    User-defined options. Any other options become the value of keyword arguments with the same name. The value of the keyword argument is the tail of the option. An ERROR is SIGNALed if any option appears more than once in the DEFGENERIC form.

The result of the call to ENSURE-GENERIC-FUNCTION is returned as the result of evaluating or executing the DEFGENERIC form.

29.5.3.2. Generic Function Invocation Protocol

Associated with each generic function is its discriminating function. Each time the generic function is called, the discriminating function is called to provide the behavior of the generic function. The discriminating function receives the full set of arguments received by the generic function. It must lookup and execute the appropriate methods, and return the appropriate values.

The discriminating function is computed by the highest layer of the generic function invocation protocol, CLOS:COMPUTE-DISCRIMINATING-FUNCTION. Whenever a generic function metaobject is initialized, reinitialized, or a method is added or removed, the discriminating function is recomputed. The new discriminating function is then stored with CLOS:SET-FUNCALLABLE-INSTANCE-FUNCTION.

Discriminating functions call CLOS:COMPUTE-APPLICABLE-METHODS and CLOS:COMPUTE-APPLICABLE-METHODS-USING-CLASSES to compute the methods applicable to the generic functions arguments. Applicable methods are combined by CLOS:COMPUTE-EFFECTIVE-METHOD to produce an effective method . Provisions are made to allow memoization of the method applicability and effective methods computations. (See the description of CLOS:COMPUTE-DISCRIMINATING-FUNCTION for details.)

The body of method definitions are processed by CLOS:MAKE-METHOD-LAMBDA. The result of this generic function is a lambda expression which is processed by either COMPILE or COMPILE-FILE to produce a method function. The arguments received by the method function are controlled by the CALL-METHOD forms appearing in the effective methods. By default, method functions accept two arguments: a list of arguments to the generic function, and a list of next methods. The list of next methods corresponds to the next methods argument to CALL-METHOD. If CALL-METHOD appears with additional arguments, these will be passed to the method functions as well; in these cases, CLOS:MAKE-METHOD-LAMBDA must have created the method lambdas to expect additional arguments.

29.5.3.3. Initialization of generic function metaobjects

A generic function metaobject can be created by calling MAKE-INSTANCE. The initialization arguments establish the definition of the generic function. A generic function metaobject can be redefined by calling REINITIALIZE-INSTANCE. Some classes of generic function metaobject do not support redefinition; in these cases, REINITIALIZE-INSTANCE SIGNALs an ERROR.

Initialization of a generic function metaobject must be done by calling MAKE-INSTANCE and allowing it to call INITIALIZE-INSTANCE. Reinitialization of a generic function metaobject must be done by calling REINITIALIZE-INSTANCE. Portable programs must not

Since metaobject classes may not be redefined, no behavior is specified for the result of calls to UPDATE-INSTANCE-FOR-REDEFINED-CLASS on generic function metaobjects. Since the class of a generic function metaobject may not be changed, no behavior is specified for the results of calls to UPDATE-INSTANCE-FOR-DIFFERENT-CLASS on generic function metaobjects.

During initialization or reinitialization, each initialization argument is checked for errors and then associated with the generic function metaobject. The value can then be accessed by calling the appropriate accessor as shown in Table 29.4, “Initialization arguments and accessors for generic function metaobjects”.

This section begins with a description of the error checking and processing of each initialization argument. This is followed by a table showing the generic functions that can be used to access the stored initialization arguments. The section ends with a set of restrictions on portable methods affecting generic function metaobject initialization and reinitialization.

In these descriptions, the phrase this argument defaults to value means that when that initialization argument is not supplied, initialization or reinitialization is performed as if value had been supplied. For some initialization arguments this could be done by the use of default initialization arguments, but whether it is done this way is not specified. Implementations are free to define default initialization arguments for specified generic function metaobject classes. Portable programs are free to define default initialization arguments for portable subclasses of the class GENERIC-FUNCTION.

Unless there is a specific note to the contrary, then during reinitialization, if an initialization argument is not supplied, the previously stored value is left unchanged.

  • The :ARGUMENT-PRECEDENCE-ORDER argument is a list of symbols.

    An ERROR is SIGNALed if this argument appears but the :LAMBDA-LIST argument does not appear. An ERROR is SIGNALed if this value is not a proper list or if this value is not a permutation of the symbols from the required arguments part of the :LAMBDA-LIST initialization argument.

    When the generic function is being initialized or reinitialized, and this argument is not supplied, but the :LAMBDA-LIST argument is supplied, this value defaults to the symbols from the required arguments part of the :LAMBDA-LIST argument, in the order they appear in that argument. If neither argument is supplied, neither are initialized (see the description of :LAMBDA-LIST.)

  • The :DECLARATIONS argument is a list of declaration specifiers.

    An ERROR is SIGNALed if this value is not a proper list or if each of its elements is not a legal declaration specifier.

    When the generic function is being initialized, and this argument is not supplied, it defaults to the empty list.

  • The :DOCUMENTATION argument is a STRING or NIL. An ERROR is SIGNALed if it is not. This argument default to NIL during initialization.
  • The :LAMBDA-LIST argument is a lambda list.

    An ERROR is SIGNALed if this value is not a proper generic function lambda list.

    When the generic function is being initialized, and this argument is not supplied, the generic function's lambda list is not initialized. The lambda list will be initialized later, either when the first method is added to the generic function, or a later reinitialization of the generic function.

  • The :METHOD-COMBINATION argument is a method combination metaobject.
  • The :METHOD-CLASS argument is a class metaobject.

    An ERROR is SIGNALed if this value is not a subclass of the class METHOD.

    When the generic function is being initialized, and this argument is not supplied, it defaults to the class STANDARD-METHOD.

  • The :NAME argument is an object.

    If the generic function is being initialized, this argument defaults to NIL.

After the processing and defaulting of initialization arguments described above, the value of each initialization argument is associated with the generic function metaobject. These values can then be accessed by calling the corresponding generic function. The correspondences are as follows:

Table 29.4. Initialization arguments and accessors for generic function metaobjects


29.5.3.3.1. Methods

It is not specified which methods provide the initialization and reinitialization behavior described above. Instead, the information needed to allow portable programs to specialize this behavior is presented as a set of restrictions on the methods a portable program can define. The model is that portable initialization methods have access to the generic function metaobject when either all or none of the specified initialization has taken effect.

These restrictions govern the methods that a portable program can define on the generic functions INITIALIZE-INSTANCE, REINITIALIZE-INSTANCE, and SHARED-INITIALIZE. These restrictions apply only to methods on these generic functions for which the first specializer is a subclass of the class GENERIC-FUNCTION. Other portable methods on these generic functions are not affected by these restrictions.

  • Portable programs must not define methods on SHARED-INITIALIZE.
  • For INITIALIZE-INSTANCE and REINITIALIZE-INSTANCE:

    • Portable programs must not define primary methods.
    • Portable programs may define around-methods, but these must be extending, not overriding methods.
    • Portable before-methods must assume that when they are run, none of the initialization behavior described above has been completed.
    • Portable after-methods must assume that when they are run, all of the initialization behavior described above has been completed.

The results are undefined if any of these restrictions are violated.

29.5.4. Customization

29.5.4.1. Generic Function (SETF CLOS:GENERIC-FUNCTION-NAME)

Syntax
((SETF CLOS:GENERIC-FUNCTION-NAME) new-name generic-function)
Arguments
generic-function
a generic function metaobject.
new-name
a function name or NIL.
Value
The new-name argument.
Purpose

This function changes the name of generic-function to new-name. This value is usually a function name or NIL, if the generic function is to have no name.

This function works by calling REINITIALIZE-INSTANCE with generic-function as its first argument, the symbol :NAME as its second argument and new-name as its third argument.

29.5.4.2. Generic Function ENSURE-GENERIC-FUNCTION

Syntax
(ENSURE-GENERIC-FUNCTION function-name &KEY &ALLOW-OTHER-KEYS)
Arguments
function-name
a function name
keyword arguments
Some of the keyword arguments accepted by this function are actually processed by CLOS:ENSURE-GENERIC-FUNCTION-USING-CLASS, others are processed during initialization of the generic function metaobject (as described in Section 29.5.3.3, “Initialization of generic function metaobjects”).
Value
A generic function metaobject.
Purpose

This function is called to define a globally named generic function or to specify or modify options and declarations that pertain to a globally named generic function as a whole. It can be called by the user or the implementation.

It is the functional equivalent of DEFGENERIC, and is called by the expansion of the DEFGENERIC and DEFMETHOD macros.

The behavior of this function is actually implemented by the generic function CLOS:ENSURE-GENERIC-FUNCTION-USING-CLASS. When ENSURE-GENERIC-FUNCTION is called, it immediately calls CLOS:ENSURE-GENERIC-FUNCTION-USING-CLASS and returns that result as its own.

The first argument to CLOS:ENSURE-GENERIC-FUNCTION-USING-CLASS is computed as follows:

  • If function-name names a non-generic function, a macro, or a special form, an ERROR is SIGNALed.
  • If function-name names a generic function, that generic function metaobject is used.
  • Otherwise, NIL is used.

The second argument is function-name. The remaining arguments are the complete set of keyword arguments received by ENSURE-GENERIC-FUNCTION.

29.5.4.3. Generic Function CLOS:ENSURE-GENERIC-FUNCTION-USING-CLASS

Syntax
(CLOS:ENSURE-GENERIC-FUNCTION-USING-CLASS generic-function function-name &KEY :ARGUMENT-PRECEDENCE-ORDER :DECLARATIONS :DOCUMENTATION :GENERIC-FUNCTION-CLASS :LAMBDA-LIST :METHOD-CLASS :METHOD-COMBINATION :NAME &ALLOW-OTHER-KEYS)
Arguments
generic-function
a generic function metaobject or NIL.
function-name
a function name
:GENERIC-FUNCTION-CLASS
a class metaobject or a class name. If it is not supplied, it defaults to the class named STANDARD-GENERIC-FUNCTION. If a class name is supplied, it is interpreted as the class with that name. If a class name is supplied, but there is no such class, an ERROR is SIGNALed.
additional keyword arguments

see Section 29.5.3.3, “Initialization of generic function metaobjects”.

Implementation dependent: only in CLISP

The :DECLARE keyword is recognized as equivalent to the :DECLARATIONS keyword, for compatibility with ENSURE-GENERIC-FUNCTION in [ANSI CL standard].

Value
A generic function metaobject.
Purpose

The generic function CLOS:ENSURE-GENERIC-FUNCTION-USING-CLASS is called to define or modify the definition of a globally named generic function. It is called by the ENSURE-GENERIC-FUNCTION function. It can also be called directly.

The first step performed by this generic function is to compute the set of initialization arguments which will be used to create or reinitialize the globally named generic function. These initialization arguments are computed from the full set of keyword arguments received by this generic function as follows:

  • The :GENERIC-FUNCTION-CLASS argument is not included in the initialization arguments.
  • If the :METHOD-CLASS argument was received by this generic function, it is converted into a class metaobject. This is done by looking up the class name with FIND-CLASS. If there is no such class, an ERROR is SIGNALed.
  • All other keyword arguments are included directly in the initialization arguments.

If the generic-function argument is NIL, an instance of the class specified by the :GENERIC-FUNCTION-CLASS argument is created by calling MAKE-INSTANCE with the previously computed initialization arguments. The function name function-name is set to name the generic function. The newly created generic function metaobject is returned.

If the class of the generic-function argument is not the same as the class specified by the :GENERIC-FUNCTION-CLASS argument, an ERROR is SIGNALed.

Implementation dependent: only in CLISP

The description of ENSURE-GENERIC-FUNCTION in [ANSI CL standard] specifies that in this case, CHANGE-CLASS is called if the class of the generic-function argument and the class specified by the :GENERIC-FUNCTION-CLASS argument are compatible. Given the description of ENSURE-GENERIC-FUNCTION, this also applies to the CLOS:ENSURE-GENERIC-FUNCTION-USING-CLASS function. CLISP's implementation calls CHANGE-CLASS always, and leaves it to the CHANGE-CLASS function to signal an error if needed.

Otherwise the generic function generic-function is redefined by calling the REINITIALIZE-INSTANCE generic function with generic-function and the initialization arguments. The generic-function argument is then returned.

Methods

(CLOS:ENSURE-GENERIC-FUNCTION-USING-CLASS (generic-function GENERIC-FUNCTION) function-name &KEY :GENERIC-FUNCTION-CLASS &ALLOW-OTHER-KEYS)

This method implements the behavior of the generic function in the case where function-name names an existing generic function.

This method can be overridden.

(CLOS:ENSURE-GENERIC-FUNCTION-USING-CLASS (generic-function NULL) function-name &KEY :GENERIC-FUNCTION-CLASS &ALLOW-OTHER-KEYS)
This method implements the behavior of the generic function in the case where function-name names no function, generic function, macro or special form.

29.5.4.4. Generic Function ADD-METHOD

Syntax
(ADD-METHOD generic-function method)
Arguments
Value
The generic-function argument.
Purpose

This generic function associates an unattached method with a generic function.

An ERROR is SIGNALed if the lambda list of the method is not congruent with the lambda list of the generic function.

An ERROR is SIGNALed if the method is already associated with some other generic function.

If the given method agrees with an existing method of the generic function on parameter specializers and qualifiers, the existing method is removed by calling REMOVE-METHOD before the new method is added. See the [ANSI CL standard] section 7.6.3 Agreement on Parameter Specializers and Qualifiers for a definition of agreement in this context.

Associating the method with the generic function then proceeds in four steps:

  1. add method to the set returned by CLOS:GENERIC-FUNCTION-METHODS and arrange for CLOS:METHOD-GENERIC-FUNCTION to return generic-function;
  2. call CLOS:ADD-DIRECT-METHOD for each of the method's specializers;
  3. call CLOS:COMPUTE-DISCRIMINATING-FUNCTION and install its result with CLOS:SET-FUNCALLABLE-INSTANCE-FUNCTION; and
  4. update the dependents of the generic function.

The generic function ADD-METHOD can be called by the user or the implementation.

Methods

(ADD-METHOD (generic-function STANDARD-GENERIC-FUNCTION) (method STANDARD-METHOD))
No behavior is specified for this method beyond that which is specified for the generic function.
(ADD-METHOD (generic-function STANDARD-GENERIC-FUNCTION) (method METHOD))
This method is specified by [ANSI CL standard].

29.5.4.5. Generic Function REMOVE-METHOD

Syntax
(REMOVE-METHOD generic-function method)
Arguments
Value
The generic-function argument.
Purpose

This generic function breaks the association between a generic function and one of its methods.

No ERROR is SIGNALed if the method is not among the methods of the generic function.

Breaking the association between the method and the generic function proceeds in four steps:

  1. remove method from the set returned by CLOS:GENERIC-FUNCTION-METHODS and arrange for CLOS:METHOD-GENERIC-FUNCTION to return NIL;
  2. call CLOS:REMOVE-DIRECT-METHOD for each of the method's specializers;
  3. call CLOS:COMPUTE-DISCRIMINATING-FUNCTION and install its result with CLOS:SET-FUNCALLABLE-INSTANCE-FUNCTION; and
  4. update the dependents of the generic function.

The generic function REMOVE-METHOD can be called by the user or the implementation.

Methods

(REMOVE-METHOD (generic-function STANDARD-GENERIC-FUNCTION) (method STANDARD-METHOD))
No behavior is specified for this method beyond that which is specified for the generic function.
(REMOVE-METHOD (generic-function STANDARD-GENERIC-FUNCTION) (method METHOD))
This method is specified by [ANSI CL standard].

29.5.4.6. Generic Function CLOS:COMPUTE-APPLICABLE-METHODS

Syntax
(CLOS:COMPUTE-APPLICABLE-METHODS generic-function arguments)
Arguments
generic-function
a generic function metaobject.
arguments
a list of objects.
Value
A possibly empty list of method metaobjects.
Purpose

This generic function determines the method applicability of a generic function given a list of required arguments. The returned list of method metaobjects is sorted by precedence order with the most specific method appearing first. If no methods are applicable to the supplied arguments the empty list is returned.

When a generic function is invoked, the discriminating function must determine the ordered list of methods applicable to the arguments. Depending on the generic function and the arguments, this is done in one of three ways: using a memoized value; calling CLOS:COMPUTE-APPLICABLE-METHODS-USING-CLASSES; or calling CLOS:COMPUTE-APPLICABLE-METHODS. (Refer to the description of CLOS:COMPUTE-DISCRIMINATING-FUNCTION for the details of this process.)

The arguments argument is permitted to contain more elements than the generic function accepts required arguments; in these cases the extra arguments will be ignored. An ERROR is SIGNALed if arguments contains fewer elements than the generic function accepts required arguments.

The list returned by this function will not be mutated by the implementation. The results are undefined if a portable program mutates the list returned by this function.

Methods

(CLOS:COMPUTE-APPLICABLE-METHODS (generic-function STANDARD-GENERIC-FUNCTION) arguments)

This method SIGNALs an ERROR if any method of the generic function has a specializer which is neither a class metaobject nor an EQL specializer metaobject.

Otherwise, this method computes the sorted list of applicable methods according to the rules described in the [ANSI CL standard] section 7.6.6 Method Selection and Combination

This method can be overridden. Because of the consistency requirements between this generic function and CLOS:COMPUTE-APPLICABLE-METHODS-USING-CLASSES, doing so may require also overriding CLOS:COMPUTE-APPLICABLE-METHODS-USING-CLASSES (STANDARD-GENERIC-FUNCTION T).

Remarks.  See also the [ANSI CL standard] function COMPUTE-APPLICABLE-METHODS.

Syntax
(CLOS:COMPUTE-APPLICABLE-METHODS-USING-CLASSES generic-function classes)
Arguments
generic-function
a generic function metaobject.
classes
a list of class metaobjects.
Values
  1. A possibly empty list of method metaobjects.
  2. BOOLEAN
Purpose

This generic function is called to attempt to determine the method applicability of a generic function given only the classes of the required arguments.

If it is possible to completely determine the ordered list of applicable methods based only on the supplied classes, this generic function returns that list as its primary value and true as its second value. The returned list of method metaobjects is sorted by precedence order, the most specific method coming first. If no methods are applicable to arguments with the specified classes, the empty list and true are returned.

If it is not possible to completely determine the ordered list of applicable methods based only on the supplied classes, this generic function returns an unspecified primary value and false as its second value.

When a generic function is invoked, the discriminating function must determine the ordered list of methods applicable to the arguments. Depending on the generic function and the arguments, this is done in one of three ways: using a memoized value; calling CLOS:COMPUTE-APPLICABLE-METHODS-USING-CLASSES; or calling CLOS:COMPUTE-APPLICABLE-METHODS. (Refer to the description of CLOS:COMPUTE-DISCRIMINATING-FUNCTION for the details of this process.)

The following consistency relationship between CLOS:COMPUTE-APPLICABLE-METHODS-USING-CLASSES and CLOS:COMPUTE-APPLICABLE-METHODS must be maintained: for any given generic function and set of arguments, if CLOS:COMPUTE-APPLICABLE-METHODS-USING-CLASSES returns a second value of true, the primary value must be equal to the value that would be returned by a corresponding call to CLOS:COMPUTE-APPLICABLE-METHODS. The results are undefined if a portable method on either of these generic functions causes this consistency to be violated.

The list returned by this function will not be mutated by the implementation. The results are undefined if a portable program mutates the list returned by this function.

Methods

(CLOS:COMPUTE-APPLICABLE-METHODS-USING-CLASSES (generic-function STANDARD-GENERIC-FUNCTION) classes)

If any method of the generic function has a specializer which is neither a class metaobject nor an EQL specializer metaobject, this method SIGNALs an ERROR.

In cases where the generic function has no methods with EQL specializers, or has no methods with EQL specializers that could be applicable to arguments of the supplied classes, this method returns the ordered list of applicable methods as its first value and true as its second value.

Otherwise this method returns an unspecified primary value and false as its second value.

This method can be overridden. Because of the consistency requirements between this generic function and CLOS:COMPUTE-APPLICABLE-METHODS, doing so may require also overriding CLOS:COMPUTE-APPLICABLE-METHODS (STANDARD-GENERIC-FUNCTION T) .

Remarks

This generic function exists to allow user extensions which alter method lookup rules, but which base the new rules only on the classes of the required arguments, to take advantage of the class-based method lookup memoization found in many implementations. (There is of course no requirement for an implementation to provide this optimization.)

Such an extension can be implemented by two methods, one on this generic function and one on CLOS:COMPUTE-APPLICABLE-METHODS. Whenever the user extension is in effect, the first method will return a second value of true. This should allow the implementation to absorb these cases into its own memoization scheme.

To get appropriate performance, other kinds of extensions may require methods on CLOS:COMPUTE-DISCRIMINATING-FUNCTION which implement their own memoization scheme.

29.5.4.8. Generic Function CLOS:COMPUTE-EFFECTIVE-METHOD

Syntax
(CLOS:COMPUTE-EFFECTIVE-METHOD generic-function method-combination methods)
Arguments
generic-function
a generic function metaobject.
method-combination
a method combination metaobject.
methods
a list of method metaobjects.
Values
  1. An effective method
  2. A list of effective method options
Purpose

This generic function is called to determine the effective method from a sorted list of method metaobjects.

An effective method is a form that describes how the applicable methods are to be combined. Inside of effective method forms are CALL-METHOD forms which indicate that a particular method is to be called. The arguments to the CALL-METHOD form indicate exactly how the method function of the method should be called. (See CLOS:MAKE-METHOD-LAMBDA for more details about method functions.)

An effective method option has the same interpretation and syntax as either the :ARGUMENTS or the :GENERIC-FUNCTION option in the long form of DEFINE-METHOD-COMBINATION.

More information about the form and interpretation of effective methods and effective method options can be found under the description of the DEFINE-METHOD-COMBINATION macro in the CLOS specification.

This generic function can be called by the user or the implementation. It is called by discriminating functions whenever a sorted list of applicable methods must be converted to an effective method.

Methods

(CLOS:COMPUTE-EFFECTIVE-METHOD (generic-function STANDARD-GENERIC-FUNCTION) method-combination methods)

This method computes the effective method according to the rules of the method combination type implemented by method-combination.

This method can be overridden.

Implementation dependent: only in CLISP

The second return value may contain only one :ARGUMENTS option and only one :GENERIC-FUNCTION option. When overriding a CLOS:COMPUTE-EFFECTIVE-METHOD method, before adding an :ARGUMENTS or :GENERIC-FUNCTION option, you therefore need to check whether it this option is already present.

Implementation dependent: only in CLISP

Syntax
(CLOS:COMPUTE-EFFECTIVE-METHOD-AS-FUNCTION generic-function methods arguments)
Arguments
generic-function
a generic function metaobject.
methods
a list of method metaobjects.
arguments
a list of arguments.
Value
The effective method as a function, accepting any set of arguments for which all of the given methods are applicable.
Purpose

This function is called to determine the effective method from a sorted list of method metaobjects, and convert it to a function. The arguments are a set of arguments to which the methods are applicable, and are used solely for error message purposes.

This function calls CLOS:COMPUTE-EFFECTIVE-METHOD using the generic-function's method combination, wraps local macro definitions for CALL-METHOD and MAKE-METHOD around it, handles the :ARGUMENTS and :GENERIC-FUNCTION options, and compiles the resulting form to a function.

29.5.4.10. Generic Function CLOS:MAKE-METHOD-LAMBDA

Syntax
(CLOS:MAKE-METHOD-LAMBDA generic-function method lambda-expression environment)
Arguments
generic-function
a generic function metaobject.
method
a (possibly uninitialized) method metaobject.
lambda-expression
a lambda expression.
environment
the same as the &ENVIRONMENT argument to macro expansion functions.
Values
  1. A lambda expression
  2. A list of initialization arguments and values
Purpose

This generic function is called to produce a lambda expression which can itself be used to produce a method function for a method and generic function with the specified classes. The generic function and method the method function will be used with are not required to be the given ones. Moreover, the method metaobject may be uninitialized.

Either the function COMPILE, the special form FUNCTION or the function COERCE must be used to convert the lambda expression a method function. The method function itself can be applied to arguments with APPLY or FUNCALL.

When a method is actually called by an effective method, its first argument will be a list of the arguments to the generic function. Its remaining arguments will be all but the first argument passed to CALL-METHOD. By default, all method functions must accept two arguments: the list of arguments to the generic function and the list of next methods.

For a given generic function and method class, the applicable methods on CLOS:MAKE-METHOD-LAMBDA and CLOS:COMPUTE-EFFECTIVE-METHOD must be consistent in the following way: each use of CALL-METHOD returned by the method on CLOS:COMPUTE-EFFECTIVE-METHOD must have the same number of arguments, and the method lambda returned by the method on CLOS:MAKE-METHOD-LAMBDA must accept a corresponding number of arguments.

Note that the system-supplied implementation of CALL-NEXT-METHOD is not required to handle extra arguments to the method function. Users who define additional arguments to the method function must either redefine or forego CALL-NEXT-METHOD. (See the example below.)

When the method metaobject is created with MAKE-INSTANCE, the method function must be the value of the :FUNCTION initialization argument. The additional initialization arguments, returned as the second value of this generic function, must also be passed in this call to MAKE-INSTANCE.

Methods

(CLOS:MAKE-METHOD-LAMBDA (generic-function STANDARD-GENERIC-FUNCTION) (method STANDARD-METHOD) lambda-expression environment)

This method returns a method lambda which accepts two arguments, the list of arguments to the generic function, and the list of next methods. What initialization arguments may be returned in the second value are unspecified.

This method can be overridden.

This example shows how to define a kind of method which, from within the body of the method, has access to the actual method metaobject for the method. This simplified code overrides whatever method combination is specified for the generic function, implementing a simple method combination supporting only primary methods, CALL-NEXT-METHOD and NEXT-METHOD-P. (In addition, its a simplified version of CALL-NEXT-METHOD which does no error checking.)

Notice that the extra lexical function bindings get wrapped around the body before CALL-NEXT-METHOD is called. In this way, the user's definition of CALL-NEXT-METHOD and NEXT-METHOD-P are sure to override the system's definitions.

(defclass my-generic-function (standard-generic-function)
  ()
  (:default-initargs :method-class (find-class 'my-method)))

(defclass my-method (standard-method) ())

(defmethod make-method-lambda ((gf my-generic-function)
                               (method my-method)
                               lambda-expression
                               environment)
  (declare (ignore environment))
  `(lambda (args next-methods this-method)
     (,(call-next-method gf method
         `(lambda ,(cadr lambda-expression)
            (flet ((this-method () this-method)
                   (call-next-method (&REST cnm-args)
                     (funcall (method-function (car next-methods))
                              (or cnm-args args)
                              (cdr next-methods)
                              (car next-methods)))
                   (next-method-p ()
                     (not (null next-methods))))
              ,@(cddr lambda-expression)))
          environment)
       args next-methods)))

(defmethod compute-effective-method ((gf my-generic-function)
                                     method-combination
                                     methods)
  `(call-method ,(car methods) ,(cdr methods) ,(car methods)))

Implementation dependent: only in CLISP

The generic function CLOS:MAKE-METHOD-LAMBDA is not implemented. Its specification is misdesigned: it mixes compile time and execution time behaviour. The essential problem is: where could the generic-function argument come from?

  • If a DEFMETHOD form occurs in a source file, is CLOS:MAKE-METHOD-LAMBDA then called at compile time or at load time? If it was called at compile time, there's no possible value for the first argument, since the class of the generic function to which the method will belong is not known until load time. If it was called at load time, it would mean that the method's source code could only be compiled at load time, not earlier - which defeats the purpose of COMPILE-FILE
  • When a method is removed from a generic function using REMOVE-METHOD and then added through ADD-METHOD to a different generic function, possibly belonging to a different generic function class, would CLOS:MAKE-METHOD-LAMBDA then be called again or not? If no, then CLOS:MAKE-METHOD-LAMBDA's first argument is useless. If yes, then the source code of every method would have to be present at runtime, and its lexical environment as well.

Method function arguments. 

  • CALL-METHOD always expect exactly two arguments: the method and a list of next methods.
  • Method functions always expect exactly two arguments: the list of arguments passed to the generic function, and the list of next methods.

29.5.4.11. Generic Function CLOS:COMPUTE-DISCRIMINATING-FUNCTION

Syntax
(CLOS:COMPUTE-DISCRIMINATING-FUNCTION generic-function)
Arguments
generic-function
a generic function metaobject.
Value
A function.
Purpose

This generic function is called to determine the discriminating function for a generic function. When a generic function is called, the installed discriminating function is called with the full set of arguments received by the generic function, and must implement the behavior of calling the generic function: determining the ordered set of applicable methods, determining the effective method, and running the effective method.

To determine the ordered set of applicable methods, the discriminating function first calls CLOS:COMPUTE-APPLICABLE-METHODS-USING-CLASSES. If CLOS:COMPUTE-APPLICABLE-METHODS-USING-CLASSES returns a second value of false, the discriminating function then calls CLOS:COMPUTE-APPLICABLE-METHODS.

When CLOS:COMPUTE-APPLICABLE-METHODS-USING-CLASSES returns a second value of true, the discriminating function is permitted to memoize the primary value as follows. The discriminating function may reuse the list of applicable methods without calling CLOS:COMPUTE-APPLICABLE-METHODS-USING-CLASSES again provided that:

  1. the generic function is being called again with required arguments which are instances of the same classes,
  2. the generic function has not been reinitialized,
  3. no method has been added to or removed from the generic function,
  4. for all the specializers of all the generic function's methods which are classes, their class precedence lists have not changed, and
  5. for any such memoized value, the class precedence list of the class of each of the required arguments has not changed.

Determination of the effective method is done by calling CLOS:COMPUTE-EFFECTIVE-METHOD. When the effective method is run, each method's function is called, and receives as arguments:

  1. a list of the arguments to the generic function,
  2. whatever other arguments are specified in the CALL-METHOD form indicating that the method should be called.

(See CLOS:MAKE-METHOD-LAMBDA for more information about how method functions are called.)

The generic function CLOS:COMPUTE-DISCRIMINATING-FUNCTION is called, and its result installed, by ADD-METHOD, REMOVE-METHOD, INITIALIZE-INSTANCE and REINITIALIZE-INSTANCE.

Methods

(CLOS:COMPUTE-DISCRIMINATING-FUNCTION (generic-function STANDARD-GENERIC-FUNCTION))

No behavior is specified for this method beyond that which is specified for the generic function.

This method can be overridden.

Implementation dependent: only in CLISP

Overriding methods can make use of the function CLOS:COMPUTE-EFFECTIVE-METHOD-AS-FUNCTION. It is more convenient to call CLOS:COMPUTE-EFFECTIVE-METHOD-AS-FUNCTION than CLOS:COMPUTE-EFFECTIVE-METHOD because the in the latter case one needs a lot of glue code for implementing the local macros CALL-METHOD and MAKE-METHOD, and this glue code is implementation dependent because it needs

  1. to retrieve the declarations list stored in the method-combination object and
  2. to handle implementation dependent options that are returned as second value from CLOS:COMPUTE-EFFECTIVE-METHOD.

These notes document CLISP version 2.49Last modified: 2010-07-07