29.5. Generic Functions
Prev | Chapter 29. Meta-Object Protocol | Next

## 29.5. Generic Functions

### 29.5.1. Inheritance Structure of generic function metaobject Classes

Figure 29.4. 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 `SIGNAL`ed. An `ERROR` is also `SIGNAL`ed 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`

##### `(`CLOS:GENERIC-FUNCTION-METHODS` `generic-function`)`

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`

##### `(`CLOS:GENERIC-FUNCTION-LAMBDA-LIST` `generic-function`)`

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 `SIGNAL`ed if the lambda list has yet to be supplied.

#### 29.5.2.4. Generic Function `CLOS:GENERIC-FUNCTION-ARGUMENT-PRECEDENCE-ORDER`

##### `(`CLOS:GENERIC-FUNCTION-ARGUMENT-PRECEDENCE-ORDER` `generic-function`)`

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 `SIGNAL`ed if the lambda list has not yet been supplied.

#### 29.5.2.5. Generic Function `CLOS:GENERIC-FUNCTION-DECLARATIONS`

##### `(`CLOS:GENERIC-FUNCTION-DECLARATIONS` `generic-function`)`

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`

##### `(`CLOS:GENERIC-FUNCTION-METHOD-CLASS` `generic-function`)`

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.

#### 29.5.2.7. Generic Function `CLOS:GENERIC-FUNCTION-METHOD-COMBINATION`

##### `(`CLOS:GENERIC-FUNCTION-METHOD-COMBINATION` `generic-function`)`

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 `SIGNAL`ed.

  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 `SIGNAL`ed 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 `SIGNAL`ed 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.

### Implementation dependent: only in CLISP

See The generic function `CLOS:MAKE-METHOD-LAMBDA` is not implemented.

See Method function 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` `SIGNAL`s 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

- ... call `INITIALIZE-INSTANCE` directly to initialize a generic function metaobject;
- ... call `SHARED-INITIALIZE` directly to initialize or reinitialize a generic function metaobject;
- ... call `CHANGE-CLASS` to change the class of any generic function metaobject or to turn a non-generic-function object into a generic function metaobject.

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 `SIGNAL`ed if this argument appears but the `:LAMBDA-LIST` argument does not appear. An `ERROR` is `SIGNAL`ed 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 `SIGNAL`ed 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 `SIGNAL`ed if it is not. This argument default to `NIL` during initialization.

- The `:LAMBDA-LIST` argument is a lambda list.

  An `ERROR` is `SIGNAL`ed 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 `SIGNAL`ed 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

Initialization Argument | Generic Function
--- | ---
`:ARGUMENT-PRECEDENCE-ORDER` | `CLOS:GENERIC-FUNCTION-ARGUMENT-PRECEDENCE-ORDER`
`:DECLARATIONS` | `CLOS:GENERIC-FUNCTION-DECLARATIONS`
`:DOCUMENTATION` | `DOCUMENTATION`
`:LAMBDA-LIST` | `CLOS:GENERIC-FUNCTION-LAMBDA-LIST`
`:METHOD-COMBINATION` | `CLOS:GENERIC-FUNCTION-METHOD-COMBINATION`
`:METHOD-CLASS` | `CLOS:GENERIC-FUNCTION-METHOD-CLASS`
`:NAME` | `CLOS:GENERIC-FUNCTION-NAME`

##### 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 `SIGNAL`ed.
  - 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 `SIGNAL`ed.
  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 `SIGNAL`ed.
  - 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 `SIGNAL`ed.

  ### 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
  `generic-function`
    a generic function metaobject.
  `method`
    a method metaobject.
Value
  The `generic-function` argument.
Purpose

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

  An `ERROR` is `SIGNAL`ed if the lambda list of the method is not congruent with the lambda list of the generic function.

  An `ERROR` is `SIGNAL`ed 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
  `generic-function`
    a generic function metaobject.
  `method`
    a method metaobject.
Value
  The `generic-function` argument.
Purpose

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

  No `ERROR` is `SIGNAL`ed 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 `SIGNAL`ed 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 `SIGNAL`s 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`.

#### 29.5.4.7. Generic Function `CLOS:COMPUTE-APPLICABLE-METHODS-USING-CLASSES`

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 `SIGNAL`s 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.

#### 29.5.4.9. Function `CLOS:COMPUTE-EFFECTIVE-METHOD-AS-FUNCTION`

### 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.45 | Last modified: 2008-05-14

Enter your search termsSubmit search form
Webclisp.cons.orgclisp.podval.orgwww.lisp.org

Prev | Up | Next
29.4. Slot Definitions | Home | 29.6. Methods