29.3. Classes

29.3.1. Macro DEFCLASS
29.3.2. Inheritance Structure of class metaobject Classes
29.3.3. Introspection: Readers for class metaobjects
29.3.3.1. Generic Function CLASS-NAME
29.3.3.2. Generic Function CLOS:CLASS-DIRECT-SUPERCLASSES
29.3.3.3. Generic Function CLOS:CLASS-DIRECT-SLOTS
29.3.3.4. Generic Function CLOS:CLASS-DIRECT-DEFAULT-INITARGS
29.3.3.5. Generic Function CLOS:CLASS-PRECEDENCE-LIST
29.3.3.6. Generic Function CLOS:CLASS-DIRECT-SUBCLASSES
29.3.3.7. Generic Function CLOS:CLASS-SLOTS
29.3.3.8. Generic Function CLOS:CLASS-DEFAULT-INITARGS
29.3.3.9. Generic Function CLOS:CLASS-FINALIZED-P
29.3.3.10. Generic Function CLOS:CLASS-PROTOTYPE
29.3.3.11. Methods
29.3.4. Class Finalization Protocol
29.3.5. Class Initialization
29.3.5.1. Initialization of class metaobjects
29.3.5.1.1. Methods
29.3.5.1.2. Initialization of Anonymous Classes
29.3.5.2. Reinitialization of class metaobjects
29.3.6. Customization
29.3.6.1. Generic Function (SETF CLASS-NAME)
29.3.6.2. Generic Function CLOS:ENSURE-CLASS
29.3.6.3. Generic Function CLOS:ENSURE-CLASS-USING-CLASS
29.3.6.4. Generic Function CLOS:FINALIZE-INHERITANCE
29.3.6.5. Generic Function MAKE-INSTANCE
29.3.6.6. Generic Function ALLOCATE-INSTANCE
29.3.6.7. Generic Function CLOS:VALIDATE-SUPERCLASS
29.3.6.8. Generic Function CLOS:COMPUTE-DIRECT-SLOT-DEFINITION-INITARGS
29.3.6.9. Generic Function CLOS:DIRECT-SLOT-DEFINITION-CLASS
29.3.6.10. Generic Function CLOS:COMPUTE-CLASS-PRECEDENCE-LIST
29.3.6.11. Generic Function CLOS:COMPUTE-SLOTS
29.3.6.12. Generic Function CLOS:COMPUTE-EFFECTIVE-SLOT-DEFINITION
29.3.6.13. Generic Function CLOS:COMPUTE-EFFECTIVE-SLOT-DEFINITION-INITARGS
29.3.6.14. Generic Function CLOS:EFFECTIVE-SLOT-DEFINITION-CLASS
29.3.6.15. Generic Function CLOS:COMPUTE-DEFAULT-INITARGS
29.3.7. Updating Dependencies
29.3.7.1. Generic Function CLOS:ADD-DIRECT-SUBCLASS
29.3.7.2. Generic Function CLOS:REMOVE-DIRECT-SUBCLASS

29.3.1. Macro DEFCLASS

The evaluation or execution of a DEFCLASS form results in a call to the CLOS:ENSURE-CLASS function. The arguments received by CLOS:ENSURE-CLASS are derived from the DEFCLASS form in a defined way. The exact macro-expansion of the DEFCLASS form is not defined, only the relationship between the arguments to the DEFCLASS macro and the arguments received by the CLOS:ENSURE-CLASS function. Examples of typical DEFCLASS forms and sample expansions are shown in the following two examples:

A DEFCLASS form with standard slot and class options and an expansion of it that would result in the proper call to CLOS:ENSURE-CLASS.

(defclass plane (moving-object graphics-object)
  ((altitude :initform 0 :accessor plane-altitude)
   (speed))
  (:default-initargs :engine *jet*))

(ensure-class 'plane
  ':direct-superclasses '(moving-object graphics-object)
  ':direct-slots (list (list ':name 'altitude
                             ':initform '0
                             ':initfunction #'(lambda () 0)
                             ':readers '(plane-altitude)
                             ':writers '((setf plane-altitude)))
                       (list ':name 'speed))
  ':direct-default-initargs (list (list ':engine
                                        '*jet*
                                        #'(lambda () *jet*))))

A DEFCLASS form with non-standard class and slot options, and an expansion of it which results in the proper call to CLOS:ENSURE-CLASS. Note that the order of the slot options has not affected the order of the properties in the canonicalized slot specification, but has affected the order of the elements in the lists which are the values of those properties.

(defclass sst (plane)
  ((mach mag-step 2
         locator sst-mach
         locator mach-location
         :reader mach-speed
         :reader mach))
  (:metaclass faster-class)
  (another-option foo bar))

(ensure-class 'sst
  ':direct-superclasses '(plane)
  ':direct-slots (list (list ':name 'mach
                             ':readers '(mach-speed mach)
                             'mag-step '2
                             'locator '(sst-mach mach-location)))
  ':metaclass 'faster-class
  'another-option '(foo bar))
  • The name argument to DEFCLASS becomes the value of the first argument to CLOS:ENSURE-CLASS. This is the only positional argument accepted by CLOS:ENSURE-CLASS; all other arguments are keyword arguments.
  • The :DIRECT-SUPERCLASSES argument to DEFCLASS becomes the value of the :DIRECT-SUPERCLASSES keyword argument to CLOS:ENSURE-CLASS.
  • The :DIRECT-SLOTS argument to DEFCLASS becomes the value of the :DIRECT-SLOTS keyword argument to CLOS:ENSURE-CLASS. Special processing of this value is done to regularize the form of each slot specification and to properly capture the lexical scope of the initialization forms. This is done by converting each slot specification to a property list called a canonicalized slot specification. The resulting list of canonicalized slot specifications is the value of the :DIRECT-SLOTS keyword argument.

    Canonicalized slot specifications are later used as the keyword arguments to a generic function which will, in turn, pass them to MAKE-INSTANCE for use as a set of initialization arguments. Each canonicalized slot specification is formed from the corresponding slot specification as follows:

    • The name of the slot is the value of the :NAME property. This property appears in every canonicalized slot specification.
    • When the :INITFORM slot option is present in the slot specification, then both the :INITFORM and :INITFUNCTION properties are present in the canonicalized slot specification. The value of the :INITFORM property is the initialization form. The value of the :INITFUNCTION property is a function of zero arguments which, when called, returns the result of evaluating the initialization form in its proper lexical environment.
    • If the :INITFORM slot option is not present in the slot specification, then either the :INITFUNCTION property will not appear, or its value will be false. In such cases, the value of the :INITFORM property, or whether it appears, is unspecified.
    • The value of the :INITARGS property is a list of the values of each :INITARG slot option. If there are no :INITARG slot options, then either the :INITARGS property will not appear or its value will be the empty list.
    • The value of the :READERS property is a list of the values of each :READER and :ACCESSOR slot option. If there are no :READER or :ACCESSOR slot options, then either the :READERS property will not appear or its value will be the empty list.
    • The value of the :WRITERS property is a list of the values specified by each :WRITER and :ACCESSOR slot option. The value specified by a :WRITER slot option is just the value of the slot option. The value specified by an :ACCESSOR slot option is a two element list: the first element is the symbol SETF, the second element is the value of the slot option. If there are no :WRITER or :ACCESSOR slot options, then either the :WRITERS property will not appear or its value will be the empty list.
    • The value of the :DOCUMENTATION property is the value of the :DOCUMENTATION slot option. If there is no :DOCUMENTATION slot option, then either the :DOCUMENTATION property will not appear or its value will be false.
    • All other slot options appear as the values of properties with the same name as the slot option. Note that this includes not only the remaining standard slot options (:ALLOCATION and :TYPE), but also any other options and values appearing in the slot specification. If one of these slot options appears more than once, the value of the property will be a list of the specified values.
    • An implementation is free to add additional properties to the canonicalized slot specification provided these are not symbols accessible in the COMMON-LISP-USER package, or exported by any package defined in the [ANSI CL standard].
  • The default initargs class option, if it is present in the DEFCLASS form, becomes the value of the :DIRECT-DEFAULT-INITARGS keyword argument to CLOS:ENSURE-CLASS. Special processing of this value is done to properly capture the lexical scope of the default value forms. This is done by converting each default initarg in the class option into a canonicalized default initialization argument. The resulting list of canonicalized default initialization arguments is the value of the :DIRECT-DEFAULT-INITARGS keyword argument to CLOS:ENSURE-CLASS.

    A canonicalized default initarg is a list of three elements. The first element is the name; the second is the actual form itself; and the third is a function of zero arguments which, when called, returns the result of evaluating the default value form in its proper lexical environment.

    Implementation dependent: only in CLISP

    If a default initargs class option is not present in the DEFCLASS form, :DIRECT-DEFAULT-INITARGS NIL is passed to CLOS:ENSURE-CLASS.

    This is needed to fulfill the [ANSI CL standard] requirement (see Section 4.6, “Redefining Classes ”) that the resulting CLASS object reflects the DEFCLASS form.

  • The metaclass class option, if it is present in the DEFCLASS form, becomes the value of the :METACLASS keyword argument to CLOS:ENSURE-CLASS.

    Implementation dependent: only in CLISP

    If a metaclass class option is not present in the DEFCLASS form, :METACLASS STANDARD-CLASS is passed to CLOS:ENSURE-CLASS.

    This is needed to fulfill the [ANSI CL standard] requirement (see Section 4.6, “Redefining Classes ”) that the resulting CLASS object reflects the DEFCLASS form.

  • The documentation class option, if it is present in the DEFCLASS form, becomes the value of the :DOCUMENTATION keyword argument to CLOS:ENSURE-CLASS.

    Implementation dependent: only in CLISP

    If a documentation class option is not present in the DEFCLASS form, :DIRECT-DEFAULT-INITARGS NIL is passed to CLOS:ENSURE-CLASS.

    This is needed to fulfill the [ANSI CL standard] requirement (see Section 4.6, “Redefining Classes ”) that the resulting CLASS object reflects the DEFCLASS form.

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

    Implementation dependent: only in CLISP

    The default initargs of the metaclass are added at the end of the list of arguments to pass to CLOS:ENSURE-CLASS.

    This is needed to fulfill the [ANSI CL standard] requirement (see Section 4.6, “Redefining Classes ”) that the resulting CLASS object reflects the DEFCLASS form.

In the call to CLOS:ENSURE-CLASS, every element of its arguments appears in the same left-to-right order as the corresponding element of the DEFCLASS form, except that the order of the properties of canonicalized slot specifications is unspecified. The values of properties in canonicalized slot specifications do follow this ordering requirement. Other ordering relationships in the keyword arguments to CLOS:ENSURE-CLASS are unspecified.

The result of the call to CLOS:ENSURE-CLASS is returned as the result of evaluating or executing the DEFCLASS form.

29.3.2. Inheritance Structure of class metaobject Classes

Figure 29.2. Inheritance structure of class metaobject classes

Inheritance structure of class metaobject classes

29.3.3. Introspection: Readers for class metaobjects

In this and the following sections, the reader generic functions which simply return information associated with a particular kind of metaobject are presented together. General information is presented first, followed by a description of the purpose of each, and ending with the specified methods for these generic functions.

The reader generic functions which simply return information associated with class metaobjects are presented together in this section.

Each of the reader generic functions for class metaobjects has the same syntax, accepting one required argument called class, which must be a class metaobject; otherwise, an ERROR is SIGNALed. An ERROR is also SIGNALed if the class 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.3.3.1. Generic Function CLASS-NAME

(CLASS-NAME class)

Returns the name of class. This value can be any Lisp object, but is usually a symbol, or NIL if the class has no name. This is the defaulted value of the :NAME initialization argument that was associated with the class during initialization or reinitialization. (Also see (SETF CLASS-NAME).)

Returns a list of the direct superclasses of class. The elements of this list are class metaobjects. The empty list is returned if class has no direct superclasses. This is the defaulted value of the :DIRECT-SUPERCLASSES initialization argument that was associated with the class during initialization or reinitialization.

Implementation dependent: only in CLISP

For a class that has not yet been finalized, the returned list may contain CLOS:FORWARD-REFERENCED-CLASS instances as placeholder for classes that were not yet defined when finalization of the class was last attempted.

29.3.3.3. Generic Function CLOS:CLASS-DIRECT-SLOTS

Returns a set of the direct slots of class. The elements of this set are direct slot definition metaobjects. If the class has no direct slots, the empty set is returned. This is the defaulted value of the :DIRECT-SLOTS initialization argument that was associated with the class during initialization and reinitialization.

Returns a list of the direct default initialization arguments for class. Each element of this list is a canonicalized default initialization argument. The empty list is returned if class has no direct default initialization arguments. This is the defaulted value of the :DIRECT-DEFAULT-INITARGS initialization argument that was associated with the class during initialization or reinitialization.

29.3.3.5. Generic Function CLOS:CLASS-PRECEDENCE-LIST

Returns the class precedence list of class. The elements of this list are class metaobjects.

During class finalization CLOS:FINALIZE-INHERITANCE calls CLOS:COMPUTE-CLASS-PRECEDENCE-LIST to compute the class precedence list of the class. That value is associated with the class metaobject and is returned by CLOS:CLASS-PRECEDENCE-LIST.

This generic function SIGNALs an ERROR if class has not been finalized.

Returns a set of the direct subclasses of class. The elements of this set are class metaobjects that all mention this class among their direct superclasses. The empty set is returned if class has no direct subclasses. This value is maintained by the generic functions CLOS:ADD-DIRECT-SUBCLASS and CLOS:REMOVE-DIRECT-SUBCLASS.

Implementation dependent: only in CLISP

The set of direct subclasses of a class is internally managed as a EXT:WEAK-LIST. Therefore the existence of the CLOS:CLASS-DIRECT-SUBCLASSES function does not prevent otherwise unreferenced classes from being garbage-collected.

29.3.3.7. Generic Function CLOS:CLASS-SLOTS

Returns a possibly empty set of the slots accessible in instances of class. The elements of this set are effective slot definition metaobjects.

During class finalization CLOS:FINALIZE-INHERITANCE calls CLOS:COMPUTE-SLOTS to compute the slots of the class. That value is associated with the class metaobject and is returned by CLOS:CLASS-SLOTS.

This generic function SIGNALs an ERROR if class has not been finalized.

29.3.3.8. Generic Function CLOS:CLASS-DEFAULT-INITARGS

Returns a list of the default initialization arguments for class. Each element of this list is a canonicalized default initialization argument. The empty list is returned if class has no default initialization arguments.

During finalization CLOS:FINALIZE-INHERITANCE calls CLOS:COMPUTE-DEFAULT-INITARGS to compute the default initialization arguments for the class. That value is associated with the class metaobject and is returned by CLOS:CLASS-DEFAULT-INITARGS.

This generic function SIGNALs an ERROR if class has not been finalized.

29.3.3.9. Generic Function CLOS:CLASS-FINALIZED-P

Returns true if class has been finalized. Returns false otherwise. Also returns false if the class has not been initialized.

29.3.3.10. Generic Function CLOS:CLASS-PROTOTYPE

Returns a prototype instance of class. Whether the instance is initialized is not specified. The results are undefined if a portable program modifies the binding of any slot of a prototype instance.

This generic function SIGNALs an ERROR if class has not been finalized.

This allows non-consing[3] access to slots with allocation :CLASS:

(defclass counter ()
  ((count :allocation :class :initform 0 :reader how-many)))
(defmethod initialize-instance :after ((obj counter) &rest args)
  (incf (slot-value obj 'count)))
(defclass counted-object (counter) ((name :initarg :name)))
 

Now one can find out how many COUNTED-OBJECTs have been created by using (HOW-MANY (CLOS:CLASS-PROTOTYPE (FIND-CLASS 'COUNTER))):

(MAKE-INSTANCE 'counted-object :name 'foo)
⇒ #<COUNTED-OBJECT #x203028C9>
(HOW-MANY (CLOS:CLASS-PROTOTYPE (FIND-CLASS 'counter)))
⇒ 1
(MAKE-INSTANCE 'counted-object :name 'bar)
⇒ #<COUNTED-OBJECT #x20306CB1>
(HOW-MANY (CLOS:CLASS-PROTOTYPE (FIND-CLASS 'counter)))
⇒ 2

29.3.3.11. Methods

The specified methods for the class metaobject reader generic functions are presented below.

Each entry in the table indicates a method on one of the reader generic functions, specialized to a specified class. The number in each entry is a reference to the full description of the method. The full descriptions appear after the table.

Class Reader Methods

  1. This method returns the value which was associated with the class metaobject during initialization or reinitialization.
  2. This method returns the value associated with the class metaobject by CLOS:FINALIZE-INHERITANCE (STANDARD-CLASS) or CLOS:FINALIZE-INHERITANCE (CLOS:FUNCALLABLE-STANDARD-CLASS)
  3. This method SIGNALs an ERROR.
  4. This method returns the empty list.
  5. This method returns true.
  6. This method returns false.
  7. This method returns a value derived from the information in Table 29.1, “Direct Superclass Relationships Among The Specified Metaobject Classes”, except that implementation-specific modifications are permitted as described in Section 29.2.2.1, “Implementation and User Specialization”.
  8. This method returns the name of the built-in class.
  9. This method returns a value which is maintained by CLOS:ADD-DIRECT-SUBCLASS(CLASS CLASS) and CLOS:REMOVE-DIRECT-SUBCLASS (CLASS CLASS). This method can be overridden only if those methods are overridden as well.
  10. No behavior is specified for this method beyond that which is specified for the generic function.

29.3.4. Class Finalization Protocol

Class finalization is the process of computing the information a class inherits from its superclasses and preparing to actually allocate instances of the class. The class finalization process includes computing the class's class precedence list, the full set of slots accessible in instances of the class and the full set of default initialization arguments for the class. These values are associated with the class metaobject and can be accessed by calling the appropriate reader. In addition, the class finalization process makes decisions about how instances of the class will be implemented.

To support forward-referenced superclasses, and to account for the fact that not all classes are actually instantiated, class finalization is not done as part of the initialization of the class metaobject. Instead, finalization is done as a separate protocol, invoked by calling the generic function CLOS:FINALIZE-INHERITANCE. The exact point at which CLOS:FINALIZE-INHERITANCE is called depends on the class of the class metaobject; for STANDARD-CLASS it is called sometime after all the classes superclasses are defined, but no later than when the first instance of the class is allocated (by ALLOCATE-INSTANCE).

The first step of class finalization is computing the class precedence list. Doing this first allows subsequent steps to access the class precedence list. This step is performed by calling the generic function CLOS:COMPUTE-CLASS-PRECEDENCE-LIST. The value returned from this call is associated with the class metaobject and can be accessed by calling the CLOS:CLASS-PRECEDENCE-LIST generic function.

The second step is computing the full set of slots that will be accessible in instances of the class. This step is performed by calling the generic function CLOS:COMPUTE-SLOTS. The result of this call is a list of effective slot definition metaobjects. This value is associated with the class metaobject and can be accessed by calling the CLOS:CLASS-SLOTS generic function.

The behavior of CLOS:COMPUTE-SLOTS is itself layered, consisting of calls to CLOS:EFFECTIVE-SLOT-DEFINITION-CLASS and CLOS:COMPUTE-EFFECTIVE-SLOT-DEFINITION.

The final step of class finalization is computing the full set of initialization arguments for the class. This is done by calling the generic function CLOS:COMPUTE-DEFAULT-INITARGS. The value returned by this generic function is associated with the class metaobject and can be accessed by calling CLOS:CLASS-DEFAULT-INITARGS.

If the class was previously finalized, CLOS:FINALIZE-INHERITANCE may call MAKE-INSTANCES-OBSOLETE. The circumstances under which this happens are described in the [ANSI CL standard] section Section 4.6, “Redefining Classes ”.

Forward-referenced classes, which provide a temporary definition for a class which has been referenced but not yet defined, can never be finalized. An ERROR is SIGNALed if CLOS:FINALIZE-INHERITANCE is called on a forward-referenced class.

29.3.5. Class Initialization

29.3.5.1. Initialization of class metaobjects

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

Initialization of a class metaobject must be done by calling MAKE-INSTANCE and allowing it to call INITIALIZE-INSTANCE. Reinitialization of a class 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 class metaobjects. Since the class of class metaobjects may not be changed, no behavior is specified for the result of calls to UPDATE-INSTANCE-FOR-DIFFERENT-CLASS on class metaobjects.

During initialization or reinitialization, each initialization argument is checked for errors and then associated with the class metaobject. The value can then be accessed by calling the appropriate accessor as shown in Table 29.2, “Initialization arguments and accessors for class 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. Initialization behavior specific to the different specified class metaobject classes comes next. The section ends with a set of restrictions on portable methods affecting class 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 class metaobject classes. Portable programs are free to define default initialization arguments for portable subclasses of the class CLASS.

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.

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

Table 29.2. Initialization arguments and accessors for class metaobjects

Initialization ArgumentGeneric Function
:DIRECT-DEFAULT-INITARGSCLOS:CLASS-DIRECT-DEFAULT-INITARGS
:DIRECT-SLOTSCLOS:CLASS-DIRECT-SLOTS
:DIRECT-SUPERCLASSESCLOS:CLASS-DIRECT-SUPERCLASSES
:DOCUMENTATIONDOCUMENTATION
:NAMECLASS-NAME


Instances of the class STANDARD-CLASS support multiple inheritance and reinitialization. Instances of the class CLOS:FUNCALLABLE-STANDARD-CLASS support multiple inheritance and reinitialization. For forward referenced classes, all of the initialization arguments default to NIL.

Implementation dependent: only in CLISP

Instances of the class STRUCTURE-CLASS do not support multiple inheritance and reinitialization.

Since built-in classes cannot be created or reinitialized by the user, an ERROR is SIGNALed if INITIALIZE-INSTANCE or REINITIALIZE-INSTANCE are called to initialize or reinitialize a derived instance of the class BUILT-IN-CLASS.

29.3.5.1.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 class 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 CLASS. 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.3.5.1.2. Initialization of Anonymous Classes

class metaobjects created with MAKE-INSTANCE are usually anonymous ; that is, they have no proper name. An anonymous class metaobject can be given a proper name using (SETF FIND-CLASS) and (SETF CLASS-NAME).

When a class metaobject is created with MAKE-INSTANCE, it is initialized in the usual way. The initialization arguments passed to MAKE-INSTANCE are use to establish the definition of the class. Each initialization argument is checked for errors and associated with the class metaobject. The initialization arguments correspond roughly to the arguments accepted by the DEFCLASS macro, and more closely to the arguments accepted by the CLOS:ENSURE-CLASS function.

Some class metaobject classes allow their instances to be redefined. When permissible, this is done by calling REINITIALIZE-INSTANCE. This is discussed in the next section.

An example of creating an anonymous class directly using MAKE-INSTANCE follows:

(flet ((zero () 0)
       (propellor () *propellor*))
  (make-instance 'standard-class
    :name '(my-class foo)
    :direct-superclasses (list (find-class 'plane)
                               another-anonymous-class)
    :direct-slots `((:name x
                     :initform 0
                     :initfunction ,#'zero
                     :initargs (:x)
                     :readers (position-x)
                     :writers ((setf position-x)))
                    (:name y
                     :initform 0
                     :initfunction ,#'zero
                     :initargs (:y)
                     :readers (position-y)
                     :writers ((setf position-y))))
    :direct-default-initargs `((:engine *propellor* ,#'propellor))))

29.3.5.2. Reinitialization of class metaobjects

Some class metaobject classes allow their instances to be reinitialized. This is done by calling REINITIALIZE-INSTANCE. The initialization arguments have the same interpretation as in class initialization.

If the class metaobject was finalized before the call to REINITIALIZE-INSTANCE, CLOS:FINALIZE-INHERITANCE will be called again once all the initialization arguments have been processed and associated with the class metaobject. In addition, once finalization is complete, any dependents of the class metaobject will be updated by calling CLOS:UPDATE-DEPENDENT.

29.3.6. Customization

29.3.6.1. Generic Function (SETF CLASS-NAME)

Syntax
((SETF CLASS-NAME) new-name class)
Arguments
class
a class metaobject.
new-name
any Lisp object.
Value
The new-name argument.
Purpose

This function changes the name of class to new-name. This value is usually a symbol, or NIL if the class has no name.

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

29.3.6.2. Generic Function CLOS:ENSURE-CLASS

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

This function is called to define or redefine a class with the specified name, and can be called by the user or the implementation. It is the functional equivalent of DEFCLASS, and is called by the expansion of the DEFCLASS macro.

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

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

  • If name names a class (FIND-CLASS returns a class when called with name) use that class.
  • Otherwise use NIL.

The second argument is name. The remaining arguments are the complete set of keyword arguments received by the CLOS:ENSURE-CLASS function.

29.3.6.3. Generic Function CLOS:ENSURE-CLASS-USING-CLASS

Syntax
(CLOS:ENSURE-CLASS-USING-CLASS class name &KEY :DIRECT-DEFAULT-INITARGS :DIRECT-SLOTS :DIRECT-SUPERCLASSES :NAME :METACLASS &ALLOW-OTHER-KEYS)
Arguments
class
a class metaobject or NIL.
name
a class name.
:METACLASS
a class metaobject class or a class metaobject class name. If this argument is not supplied, it defaults to the class named STANDARD-CLASS. 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.
:DIRECT-SUPERCLASSES
a list of which each element is a class metaobject or a class name. An ERROR is SIGNALed if this argument is not a proper list.
additional keyword arguments
See Section 29.3.5.1, “Initialization of class metaobjects”
Value
a class metaobject.
Purpose

This generic function is called to define or modify the definition of a named class. It is called by the CLOS:ENSURE-CLASS 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 named class. The initialization arguments are computed from the full set of keyword arguments received by this generic function as follows:

If the class argument is NIL, a new class metaobject is created by calling the MAKE-INSTANCE generic function with the value of the :METACLASS argument as its first argument, and the previously computed initialization arguments. The proper name of the newly created class metaobject is set to name. The newly created class metaobject is returned.

If the class argument is a forward referenced class, CHANGE-CLASS is called to change its class to the value specified by the :METACLASS argument. The class metaobject is then reinitialized with the previously initialization arguments. (This is a documented violation of the general constraint that CHANGE-CLASS may not be used with class metaobjects.)

Implementation dependent: only in CLISP

The class argument cannot be a forward referenced class. See Implementation of class CLOS:FORWARD-REFERENCED-CLASS in CLISP.

If the class of the class argument is not the same as the class specified by the :METACLASS argument, an ERROR is SIGNALed.

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

Methods

(CLOS:ENSURE-CLASS-USING-CLASS (class CLASS) name &KEY :METACLASS :DIRECT-SUPERCLASSES &ALLOW-OTHER-KEYS)

This method implements the behavior of the generic function in the case where the class argument is a class.

This method can be overridden.

(CLOS:ENSURE-CLASS-USING-CLASS (class CLOS:FORWARD-REFERENCED-CLASS) name &KEY :METACLASS :DIRECT-SUPERCLASSES &ALLOW-OTHER-KEYS)

This method implements the behavior of the generic function in the case where the class argument is a forward referenced class.

Implementation dependent: only in CLISP

This method does not exist. See Implementation of class CLOS:FORWARD-REFERENCED-CLASS in CLISP. Use the method specialized on NULL instead.

(CLOS:ENSURE-CLASS-USING-CLASS (class NULL) name &KEY :METACLASS :DIRECT-SUPERCLASSES &ALLOW-OTHER-KEYS)
This method implements the behavior of the generic function in the case where the class argument is NIL.

29.3.6.4. Generic Function CLOS:FINALIZE-INHERITANCE

Syntax
(CLOS:FINALIZE-INHERITANCE class)
Arguments
Values
The values returned by this generic function are unspecified.
Purpose

This generic function is called to finalize a class metaobject. This is described in Section 29.3.4, “Class Finalization Protocol”

After CLOS:FINALIZE-INHERITANCE returns, the class metaobject is finalized and the result of calling CLOS:CLASS-FINALIZED-P on the class metaobject will be true.

Methods

(CLOS:FINALIZE-INHERITANCE (class STANDARD-CLASS))
(CLOS:FINALIZE-INHERITANCE (class CLOS:FUNCALLABLE-STANDARD-CLASS))
No behavior is specified for these methods beyond that which is specified for their respective generic functions.
(CLOS:FINALIZE-INHERITANCE (class CLOS:FORWARD-REFERENCED-CLASS))
This method SIGNALs an ERROR.

29.3.6.5. Generic Function MAKE-INSTANCE

Syntax
(MAKE-INSTANCE class &REST initargs)
Arguments
class
a class metaobject or a class name.
initargs
a list of alternating initialization argument names and values.
Value
A newly allocated and initialized instance of class.
Purpose
The generic function MAKE-INSTANCE creates and returns a new instance of the given class. Its behavior and use is described in the [ANSI CL standard].

Methods

(MAKE-INSTANCE (class SYMBOL) &REST initargs)
This method simply invokes MAKE-INSTANCE recursively on the arguments (FIND-CLASS class) and initargs.
(MAKE-INSTANCE (class STANDARD-CLASS) &REST initargs)
(MAKE-INSTANCE (class CLOS:FUNCALLABLE-STANDARD-CLASS) &REST initargs)
These methods implement the behavior of MAKE-INSTANCE described in the [ANSI CL standard] section 7.1 Object Creation and Initialization.

29.3.6.6. Generic Function ALLOCATE-INSTANCE

Syntax
(ALLOCATE-INSTANCE class &REST initargs)
Arguments
class
a class metaobject.
initargs
alternating initialization argument names and values.
Value
A newly allocated instance of class
Purpose

This generic function is called to create a new, uninitialized instance of a class. The interpretation of the concept of an uninitialized instance depends on the class metaobject class.

Before allocating the new instance, CLOS:CLASS-FINALIZED-P is called to see if class has been finalized. If it has not been finalized, CLOS:FINALIZE-INHERITANCE is called before the new instance is allocated.

Methods

(ALLOCATE-INSTANCE (class STANDARD-CLASS) &REST initargs
This method allocates storage in the instance for each slot with allocation :INSTANCE. These slots are unbound. Slots with any other allocation are ignored by this method (no ERROR is SIGNALed).
(ALLOCATE-INSTANCE (class CLOS:FUNCALLABLE-STANDARD-CLASS) &REST initargs)

This method allocates storage in the instance for each slot with allocation :INSTANCE. These slots are unbound. Slots with any other allocation are ignored by this method (no ERROR is SIGNALed).

The funcallable instance function of the instance is undefined - the results are undefined if the instance is applied to arguments before CLOS:SET-FUNCALLABLE-INSTANCE-FUNCTION has been used to set the funcallable instance function.

(ALLOCATE-INSTANCE (class BUILT-IN-CLASS) &REST initargs)
This method SIGNALs an ERROR.

29.3.6.7. Generic Function CLOS:VALIDATE-SUPERCLASS

Syntax
(CLOS:VALIDATE-SUPERCLASS class superclass)
Arguments
Value
BOOLEAN.
Purpose

This generic function is called to determine whether the class superclass is suitable for use as a superclass of class.

This generic function can be be called by the implementation or user code. It is called during class metaobject initialization and reinitialization, before the direct superclasses are stored. If this generic function returns false, the initialization or reinitialization will signal an error.

Methods

(CLOS:VALIDATE-SUPERCLASS (class CLASS) (superclass CLASS))

This method returns true in three situations:

  1. If the superclass argument is the class named T,
  2. if the class of the class argument is the same as the class of the superclass argument, or
  3. if the class of one of the arguments is STANDARD-CLASS and the class of the other is CLOS:FUNCALLABLE-STANDARD-CLASS.

In all other cases, this method returns false.

This method can be overridden.

Implementation dependent: only in CLISP

This method also returns true in a fourth situation:

  1. If the class of the class argument is a subclass of the class of the superclass argument.

Remarks. Defining a method on CLOS:VALIDATE-SUPERCLASS requires detailed knowledge of of the internal protocol followed by each of the two class metaobject classes. A method on CLOS:VALIDATE-SUPERCLASS which returns true for two different class metaobject classes declares that they are compatible.

Implementation dependent: only in CLISP

Syntax
(CLOS:COMPUTE-DIRECT-SLOT-DEFINITION-INITARGS class &REST slot-spec)
Arguments
Value
A list of initialization arguments for a direct slot definition metaobject.
Purpose

This generic function determines the initialization arguments for the direct slot definition for a slot in a class. It is called during initialization of a class. The resulting initialization arguments are passed to CLOS:DIRECT-SLOT-DEFINITION-CLASS and then to MAKE-INSTANCE.

This generic function uses the supplied canonicalized slot specification. The value of :NAME in the returned initargs is the same as the value of :NAME in the supplied slot-spec argument.

Methods

(CLOS:COMPUTE-DIRECT-SLOT-DEFINITION-INITARGS (class STANDARD-CLASS) &REST slot-spec)
(CLOS:COMPUTE-DIRECT-SLOT-DEFINITION-INITARGS (class CLOS:FUNCALLABLE-STANDARD-CLASS) &REST slot-spec)

This method returns slot-spec unmodified.

This method can be overridden.

29.3.6.9. Generic Function CLOS:DIRECT-SLOT-DEFINITION-CLASS

Syntax
(CLOS:DIRECT-SLOT-DEFINITION-CLASS class &REST initargs)
Arguments
class
a class metaobject.
initargs
a set of initialization arguments and values.
Value
A subclass of the class CLOS:DIRECT-SLOT-DEFINITION.
Purpose

When a class is initialized, each of the canonicalized slot specifications must be converted to a direct slot definition metaobject. This generic function is called to determine the class of that direct slot definition metaobject.

The initargs argument is simply the canonicalized slot specification for the slot.

Methods

(CLOS:DIRECT-SLOT-DEFINITION-CLASS (class STANDARD-CLASS) &REST initargs)
(CLOS:DIRECT-SLOT-DEFINITION-CLASS (class CLOS:FUNCALLABLE-STANDARD-CLASS) &REST initargs)

These methods return the class CLOS:STANDARD-DIRECT-SLOT-DEFINITION.

These methods can be overridden.

29.3.6.10. Generic Function CLOS:COMPUTE-CLASS-PRECEDENCE-LIST

Syntax
(CLOS:COMPUTE-CLASS-PRECEDENCE-LIST class)
Arguments
Value
A list of class metaobjects.
Purpose

This generic-function is called to determine the class precedence list of a class.

The result is a list which contains each of class and its superclasses once and only once. The first element of the list is class and the last element is the class named T.

All methods on this generic function must compute the class precedence list as a function of the ordered direct superclasses of the superclasses of class. The results are undefined if the rules used to compute the class precedence list depend on any other factors.

When a class is finalized, CLOS:FINALIZE-INHERITANCE calls this generic function and associates the returned value with the class metaobject. The value can then be accessed by calling CLOS:CLASS-PRECEDENCE-LIST.

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-CLASS-PRECEDENCE-LIST (class CLASS))

This method computes the class precedence list according to the rules described in the [ANSI CL standard] section 4.3.5 Determining the Class Precedence List.

This method SIGNALs an ERROR if class or any of its superclasses is a forward referenced class.

This method can be overridden.

29.3.6.11. Generic Function CLOS:COMPUTE-SLOTS

Syntax
(CLOS:COMPUTE-SLOTS class)
Arguments
Value
A set of effective slot definition metaobjects.
Purpose

This generic function computes a set of effective slot definition metaobjects for the class class. The result is a list of effective slot definition metaobjects: one for each slot that will be accessible in instances of class.

This generic function proceeds in 3 steps:

The first step collects the full set of direct slot definitions from the superclasses of class.

The direct slot definitions are then collected into individual lists, one list for each slot name associated with any of the direct slot definitions. The slot names are compared with EQL. Each such list is then sorted into class precedence list order. Direct slot definitions coming from classes earlier in the class precedence list of class appear before those coming from classes later in the class precedence list. For each slot name, the generic function CLOS:COMPUTE-EFFECTIVE-SLOT-DEFINITION is called to compute an effective slot definition. The result of CLOS:COMPUTE-SLOTS is a list of these effective slot definitions, in unspecified order.

In the final step, the location for each effective slot definition is set. This is done by specified around-methods; portable methods cannot take over this behavior. For more information on the slot definition locations, see Section 29.10.1, “Instance Structure Protocol”.

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-SLOTS (class STANDARD-CLASS))
(CLOS:COMPUTE-SLOTS (class CLOS:FUNCALLABLE-STANDARD-CLASS)}

These methods implement the specified behavior of the generic function.

These methods can be overridden.

(CLOS:COMPUTE-SLOTS :AROUND (class STANDARD-CLASS))
(CLOS:COMPUTE-SLOTS :AROUND (class CLOS:FUNCALLABLE-STANDARD-CLASS))
These methods implement the specified behavior of computing and storing slot locations. These methods cannot be overridden.

29.3.6.12. Generic Function CLOS:COMPUTE-EFFECTIVE-SLOT-DEFINITION

Syntax
(CLOS:COMPUTE-EFFECTIVE-SLOT-DEFINITION class name direct-slot-definitions)
Arguments
class
a class metaobject.
name
a slot name.
direct-slot-definitions
an ordered list of direct slot definition metaobjects. The most specific direct slot definition metaobject appears first in the list.
Value
An effective slot definition metaobject.
Purpose

This generic function determines the effective slot definition for a slot in a class. It is called by CLOS:COMPUTE-SLOTS once for each slot accessible in instances of class.

This generic function uses the supplied list of direct slot definition metaobjects to compute the inheritance of slot properties for a single slot. The returned effective slot definition represents the result of computing the inheritance. The name of the new effective slot definition is the same as the name of the direct slot definitions supplied.

The class of the effective slot definition metaobject is determined by calling CLOS:EFFECTIVE-SLOT-DEFINITION-CLASS. The effective slot definition is then created by calling MAKE-INSTANCE. The initialization arguments passed in this call to MAKE-INSTANCE are used to initialize the new effective slot definition metaobject. See Section 29.4, “Slot Definitions” for details.

Methods

(CLOS:COMPUTE-EFFECTIVE-SLOT-DEFINITION (class STANDARD-CLASS) name direct-slot-definitions)
(CLOS:COMPUTE-EFFECTIVE-SLOT-DEFINITION (class CLOS:FUNCALLABLE-STANDARD-CLASS) name direct-slot-definitions)

This method implements the inheritance and defaulting of slot options following the rules described in the [ANSI CL standard] section 7.5.3 Inheritance of Slots and Options.

This method can be extended, but the value returned by the extending method must be the value returned by this method.

Implementation dependent: only in CLISP

The initialization arguments that are passed to CLOS:EFFECTIVE-SLOT-DEFINITION-CLASS and MAKE-INSTANCE are computed through a call to CLOS:COMPUTE-EFFECTIVE-SLOT-DEFINITION-INITARGS. It is the CLOS:COMPUTE-EFFECTIVE-SLOT-DEFINITION-INITARGS method that implements the inheritance rules.

Implementation dependent: only in CLISP

Syntax
(CLOS:COMPUTE-EFFECTIVE-SLOT-DEFINITION-INITARGS class direct-slot-definitions)
Arguments
class
a class metaobject.
direct-slot-definitions
an ordered list of direct slot definition metaobjects. The most specific direct slot definition metaobject appears first in the list.
Value
A list of initialization arguments for an effective slot definition metaobject.
Purpose

This generic function determines the initialization arguments for the effective slot definition for a slot in a class. It is called by CLOS:COMPUTE-EFFECTIVE-SLOT-DEFINITION. The resulting initialization arguments are passed to CLOS:EFFECTIVE-SLOT-DEFINITION-CLASS and then to MAKE-INSTANCE.

This generic function uses the supplied list of direct slot definition metaobjects to compute the inheritance of slot properties for a single slot. The returned effective slot definition initargs represent the result of computing the inheritance. The value of :NAME in the returned initargs is the same as the name of the direct slot definitions supplied.

Methods

(CLOS:COMPUTE-EFFECTIVE-SLOT-DEFINITION-INITARGS (class STANDARD-CLASS) direct-slot-definitions)
(CLOS:COMPUTE-EFFECTIVE-SLOT-DEFINITION-INITARGS (class CLOS:FUNCALLABLE-STANDARD-CLASS) direct-slot-definitions)

This method implements the inheritance and defaulting of slot options following the rules described in the [ANSI CL standard] section 7.5.3 Inheritance of Slots and Options.

This method can be extended.

29.3.6.14. Generic Function CLOS:EFFECTIVE-SLOT-DEFINITION-CLASS

Syntax
(CLOS:EFFECTIVE-SLOT-DEFINITION-CLASS class &REST initargs)
Arguments
class
a class metaobject.
initargs
set of initialization arguments and values.
Value
A subclass of the class CLOS:EFFECTIVE-SLOT-DEFINITION-CLASS.
Purpose
This generic function is called by CLOS:COMPUTE-EFFECTIVE-SLOT-DEFINITION to determine the class of the resulting effective slot definition metaobject. The initargs argument is the set of initialization arguments and values that will be passed to MAKE-INSTANCE when the effective slot definition metaobject is created.

Methods

(CLOS:EFFECTIVE-SLOT-DEFINITION-CLASS (class STANDARD-CLASS) &REST initargs)
(CLOS:EFFECTIVE-SLOT-DEFINITION-CLASS (class CLOS:FUNCALLABLE-STANDARD-CLASS) &REST initargs)

These methods return the class CLOS:STANDARD-EFFECTIVE-SLOT-DEFINITION.

These methods can be overridden.

29.3.6.15. Generic Function CLOS:COMPUTE-DEFAULT-INITARGS

Syntax
(CLOS:COMPUTE-DEFAULT-INITARGS class)
Arguments
Value
A list of canonicalized default initialization arguments.
Purpose

This generic-function is called to determine the default initialization arguments for a class.

The result is a list of canonicalized default initialization arguments, with no duplication among initialization argument names.

All methods on this generic function must compute the default initialization arguments as a function of only:

  1. the class precedence list of class, and
  2. the direct default initialization arguments of each class in that list.

The results are undefined if the rules used to compute the default initialization arguments depend on any other factors.

When a class is finalized, CLOS:FINALIZE-INHERITANCE calls this generic function and associates the returned value with the class metaobject. The value can then be accessed by calling CLOS:CLASS-DEFAULT-INITARGS.

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-DEFAULT-INITARGS (class STANDARD-CLASS))
(CLOS:COMPUTE-DEFAULT-INITARGS (class CLOS:FUNCALLABLE-STANDARD-CLASS))

These methods compute the default initialization arguments according to the rules described in the [ANSI CL standard] section 7.1.3 Defaulting of Initialization Arguments.

These methods signal an error if class or any of its superclasses is a forward referenced class.

These methods can be overridden.

29.3.7. Updating Dependencies

29.3.7.1. Generic Function CLOS:ADD-DIRECT-SUBCLASS

Syntax
(CLOS:ADD-DIRECT-SUBCLASS superclass subclass)
Arguments
superclass
a class metaobject.
subclass
a class metaobject.
Values
The values returned by this generic function are unspecified.
Purpose

This generic function is called to maintain a set of backpointers from a class to its direct subclasses. This generic function adds subclass to the set of direct subclasses of superclass.

When a class is initialized, this generic function is called once for each direct superclass of the class.

When a class is reinitialized, this generic function is called once for each added direct superclass of the class. The generic function CLOS:REMOVE-DIRECT-SUBCLASS is called once for each deleted direct superclass of the class.

Methods

(CLOS:ADD-DIRECT-SUBCLASS (superclass CLASS) (subclass CLASS))

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

This method cannot be overridden unless the following methods are overridden as well:

29.3.7.2. Generic Function CLOS:REMOVE-DIRECT-SUBCLASS

Syntax
(CLOS:REMOVE-DIRECT-SUBCLASS superclass subclass)
Arguments
superclass
a class metaobject.
subclass
a class metaobject.
Values
The values returned by this generic function are unspecified.
Purpose

This generic function is called to maintain a set of backpointers from a class to its direct subclasses. It removes subclass from the set of direct subclasses of superclass. No ERROR is SIGNALed if subclass is not in this set.

Whenever a class is reinitialized, this generic function is called once with each deleted direct superclass of the class.

Methods

(CLOS:REMOVE-DIRECT-SUBCLASS (superclass CLASS) (subclass CLASS))

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

This method cannot be overridden unless the following methods are overridden as well:


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