Draft 11: July 30, 1990 Do Not Distribute

Common Lisp Object System Specification

3. Metaobject Protocol

Important note about this draft:

Since this document was last made publicly available, large parts of it have been extensively revised. The revised material is the same in spirit as the previous draft but is, we hope, much more clear and precise. In addition, a number of bugs and design flaws have been fixed.

Note that in many cases, the parts that have been revised provide a strong model for what will be done to parts that have not yet been revised. One example is that the section “Initialization of Class Metaobjects” has been revised, but the sections on initialization of other kinds of metaobjects have not yet been. Another example is that the generic functions named add-xxx have been revised, but the ones named remove-xxx have not yet been.

Don’t be confused by unrevised material! Only the following pages have been revised (all intervals are inclusive):

5 … 22 29 … 55 66 … 67 70 … 73 88 … 91

Send comments (via electronic mail) to: MOP@Xerox.com.

Authors: Gregor Kiczales and Daniel G. Bobrow

Draft Dated: July 30, 1990 All Rights Reserved

The authors wish to thank <<put the right people here>>. Metaobject Protocol 3–1

CONTENTS

Preface . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3–5 Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3–6 Metaobjects . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3–7

Classes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3–7 Slot Definitions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3–7 Generic Functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3–8 Methods . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3–9 Method Combinations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3–9

Inheritance Structure of Metaobject Classes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3–10

Implementation and User Specialization . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3–11 Restrictions on Implementations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3–12 Restrictions on Portable Programs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3–13

Processing of the User Interface Macros . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3–15 Compile-File Processing of the User Interface Macros . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3–15 The defclass Macro . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3–16 The defmethod Macro . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3–19 Processing Method Bodies . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3–21

Standard Protocol . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3–23 The Dependent Maintenance Protocol . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3–23 Class Metaobjects . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3–23

The Class Initialization Protocol . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3–24 Generic Function Metaobjects . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3–27

Special Metaclasses . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3–28 Functions in the Metaobject Protocol . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3–29 add-dependent . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3–30 add-direct-method . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3–33 add-direct-subclass . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3–35 add-method . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3–37 allocate-instance . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3–39 class-prototype . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3–40 compute-applicable-methods . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3–41 compute-applicable-methods-using-classes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3–43 compute-class-precedence-list . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3–46 compute-discriminating-function . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3–48 compute-effective-method . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3–50 compute-effective-slot-definition . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3–52 compute-slots . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3–54 ensure-class . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3–56 ensure-class-using-class . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3–58 ensure-generic-function . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3–61 ensure-generic-function-using-class . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3–63 extract-lambda-list . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3–66 extract-specializer-names . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3–67 finalize-inheritance . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3–68 find-method-combination . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3–69 Initialization of Class Metaobjects . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3–70 Initialization of Generic Function Metaobjects . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3–74

initialize-instance . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3–74 reinitialize-instance . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3–74 shared-initialize . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3–74

Initialization of Method Metaobjects . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3–77 initialize-instance . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3–77 reinitialize-instance . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3–77 shared-initialize . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3–77

Initialization of Method Combination Metaobjects . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3–79 Initialization of Slot Definition Metaobjects . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3–80

initialize-instance . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3–80 reinitialize-instance . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3–80 shared-initialize . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3–80

make-instance . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3–83 make-method-lambda . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3–84 map-dependents . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3–86 Readers for Class Metaobjects . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3–88 Readers for Generic Function Metaobjects . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3–92

Generic Functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3–92 Methods . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3–93

Readers for Method Metaobjects . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3–95 Generic Functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3–95 Methods . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3–96 Accessor Methods . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3–96

Readers for Method Combination Metaobjects . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3–97 Readers for Slot Definition Metaobjects . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3–98

Generic Functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3–98 Methods . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3–99 Direct Slot Definition Metaobjects . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3–99 Effective Slot Definition Metaobjects . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3–100

remove-dependent . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3–101 remove-direct-method . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3–102 remove-direct-subclass . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3–104 remove-method . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3–105 set-funcallable-instance-function . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3–107 slot-boundp-using-class . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3–108 direct-slot-definition-class . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3–110 slot-exists-p-using-class . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3–111 slot-makunbound-using-class . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3–113 slot-value-using-class . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3–115 (setf slot-value-using-class) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3–117 specializer-direct-generic-functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3–118 specializer-direct-methods . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3–119 update-dependent . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3–120 validate-generic-function-class-change . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3–122 validate-metaclass-change . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3–123 validate-superclass . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3–125

Preface

This document is being distributed as a report on the current design of the Common Lisp Object System (CLOS) Metaobject Protocol (MOP). This document is not intended to be a formal specification of the Metaobject Protocol. Instead, our goal in preparing this document is to pave the way for future MOP work by capturing the design as it exists today.

Our work with the MOP has always been rooted in our own CLOS implementation, PCL. This has made it possible for us to have a MOP user community, which in turn has provided us with feedback on the protocol as it has evolved. As a result, much of the design presented here is well-tested and stable. As this is being written, those parts have been implemented not only in PCL, but in at least three other CLOS implementations we know of. Other parts of the protocol, even though they have been implemented in one form or another in PCL and other implementations, are less well worked out. Work remains to improve not only the degree to which these parts support user extensions, but also the balance they provide between user extensibility and implementor freedom.

In addition, the specification technology used in this document needs further development. The concepts of object-oriented protocols and subclass specialization are intuitively familiar to programmers of object oriented systems; the protocols presented here fit quite naturally into this framework. Nonetheless, in preparing this document, we have found it difficult to give specification-quality descriptions of the protocols in a way that makes it clear what extensions users can and cannot write. Object-oriented protocol specification is inherently about specifying leeway, and this seems difficult using current technology. This appears to be a general challenge to the object-oriented community at large — we must develop ways of specifying the objectoriented systems and protocols we develop.

In preparing this document, it is our hope that it will provide a basis for the users and implementors who wish to work with the Metaobject Protocol. We hope that this document will not be construed as any sort of final word on the MOP design, but rather only as documentation of what has been done so far. We look forward to seeing the improvements, both small and large, to the Metobject Protocol which we hope this publication will catalyze.

Introduction

The first two chapters of this specification describe the standard Programmer Interface for the Common Lisp Object System (CLOS). This chapter presents the CLOS Metaobject Protocol: a description of CLOS as an extensible CLOS program. In this description, the fundamental components of CLOS programs (classes, generic functions, methods and method combinations) are represented by first-class objects. The behavior of CLOS is provided by these objects, or more precisely by methods specialized to the classes of these objects.

Because these objects represent pieces of CLOS programs, and because their behavior provides the behavior of the CLOS language itself, they are considered meta-level objects or metaobjects. The protocol followed by the metaobjects to provide the behavior of CLOS is called the CLOS Metaobject Protocol.

Metaobjects

For each kind of program element there is a corresponding basic metaobject class. These are the classes: class, slot-definition, generic-function, method and method-combination. A metaobject-class is a subclass of exactly one of these classes. The results are undefined if an attempt is made to define a class which is a subclass of more than one basic metaobject class. A metaobject is an instance of a metaobject class.

Each metaobject represents one program element. Associated with each metaobject is the information required to serve its role. This includes information that might be provided directly in a user interface macro such as defclass or defmethod. It also includes information computed indirectly from other metaobjects such as that computed from class inheritance or the full set of methods associated with a generic function.

Much of the information associated with a metaobject is represented using other metaobjects. This interconnection means that the role of a metaobject is always based on that of other metaobjects. As an introduction to this interconnected structure, this section presents a partial enumeration of the kinds of information associated with each kind of metaobject.

Classes

A class metaobject determines the structure and behavior of its instances. Associated with a class metaobject is its name, information describing its place in the directed acyclic graph of classes, its slots, its options, its documentation and information about the methods which mention this class as a specializer.

• The name is available as an object.

• The direct subclasses, direct superclasses and class precedence list are available as lists of class metaobjects.

• The slots defined directly in the class are available as a list of direct slot definition metaobjects. The slots which are accessible in instances of the class are available as a list of effective slot definition metaobjects.

• The documentation is available as a string or nil.

• The methods which use the class as a specializer, and the generic functions associated with those methods are available as lists of method and generic function metaobjects respectively.

Slot Definitions

A slot definition metaobject contains information about the definition of a slot. There are two kinds of slot definition metaobjects. A direct slot definition metaobject is used to represent the direct definition of a slot in a class. This corresponds roughly to the slot specifiers found in defclass forms. An effective slot definition metaobject is used to represent information, including inherited information, about a slot which is accessible in instances of a particular class.

Associated with each class metaobject is a list of direct slot definition metaobjects representing the slots defined directly in the class. Also associated with each class metaobject is a list of effective slot definition metaobjects representing the set of slots accessible in instances of that class.

Certain kinds of information is associated with both direct and effective slot definitions.

• The name, allocation, and type are available as forms that could appear in a defclass form.

• The initform, if there is one, is available as a form that could appear in a defclass form. The initform together with its lexical environment is available as a function of no arguments which, when called, returns the result of evaluating the initform in its lexical environment. This is called the initfunction of the slot.

• The slot filling initialization arguments are available as a list of symbols.

• The documentation is available as a string or nil.

Certain other information is only associated with direct slot definition metaobjects. This information applies only to the direct definition of the slot in the class, it is not inherited.

• The function names of those generic functions for which there are automatically generated reader and writer methods. This information is available as lists of function names. Any accessors specified in the defclass form are broken down into their equivalent readers and writers in the direct slot definition.

Information, including inherited information, which applies to the definition of a slot in a particular class in which it is accessible is associated only with effective slot definition metaobjects.

• Limited information about the location of the slot in instances of the class.

• A flag which controls optimization of slot access even in the presence of applicable user defined methods on the slot access generic functions.

Generic Functions

Associated with each generic function metaobject is its name, a set of methods, a lambda list, a method combination type and information about options like documentation, argument precedence order and declarations.

• The name is available as a function name.

• The methods associated with the generic function are available as a list of method metaobjects.

• The lambda list is available as a list.

• The method combination is available as a method combination metaobject.

• The documentation is available as a string or nil.

• The argument precedence order is available as a permutation of those symbols from the lambda list which name the required arguments of the generic function.

• The declarations are available as a list of declarations.

Methods

A method metaobject contains a list of qualifiers, a lambda list, a list of specializers, a function and a documentation string.

• The qualifiers are available as a list of of non-null atoms.

• The lambda list is available as a list.

• The specializers are available as a list whose elements are either class metaobjects, or lists of the form (eql object).

• The function is available as a function. This function can be applied to arguments using the result of an appropriate call to the generic function method-function-applier.

• When the method is associated with a generic function, that generic function metaobject is available. A method can be associated with at most one generic function at a time.

• The documentation is available as a string or nil.

Method Combinations

A method combination metaobject represents the information about the method combination being used by a generic function. A method combination metaobject contains information about both the type of method combination and the arguments being used with that type.

• The name of the method combination type is available as a symbol. This name may or may not be the same as the name of the class of the method combination metaobject.

• The arguments to the method combination are available as a list.

• The documentation is available as a string or nil.

Inheritance Structure of Metaobject Classes

The inheritance structure of the specified metaobject classes is shown in Figure 3-1.

Metaobject Class  Direct Superclasses
standard-object  (t)
funcallable-standard-object  (function)
metaobject  (standard-object)
generic-function  (metaobject function)
standard-generic-function  (generic-function)
method  (metaobject)
standard-method  (method)
standard-accessor-method  (standard-method)
standard-reader-method  (standard-accessor-method)
standard-writer-method  (standard-accessor-method)
method-combination  (metaobject)
slot-definition  (metaobject)
direct-slot-definition  (slot-definition)
effective-slot-definition  (slot-definition)
standard-slot-definition  (slot-definition)
standard-direct-slot-definition (standard-slot-definition direct-slot-definition)
standard-effective-slot-definition (standard-slot-definition effective-slot-definition)
class  (metaobject)
built-in-class  (class)
forward-referenced-class  (class)
standard-class  (class)
funcallable-standard-class  (class)

Figure 3–1.

Direct superclass relationships among the specified metaobject classes. The class of every class shown is standard-class except for the class t which is an instance of the class built-in-class and the classes generic-function and standard-generic-function which are instances of the class funcallable-standard-class.

The basic metaobject classes (class, slot-definition, generic-function, method and methodcombination) capture only the most basic behavior of each kind of metaobject. They are not themselves intended to be instantiated. The results are undefined if an attempt is made to make an instance of one of these classes with make-instance.

The classes standard-class, standard-direct-slot-definition, standard-effective-slot-definition, standard-method, and standard-generic-function are called standard metaobject classes. For each kind of metaobject, this is the class the user interface macros presented in Chapters 1 and 2 use by default. The default class of method combination metaobjects is not specified, but is always the class method-combination or one of its subclasses.

The classes built-in-class, funcallable-standard-class and forward-referenced-class are special purpose metaclasses described in the section “Special Metaclasses”.

The classes standard-object is the default direct superclass of the class standard-class. When an instance of the class standard-class is created, and no direct superclass is explicitly specified, it defaults to the class bf standard-object. In this way, any behavior associated with the class standard-object will be inherited, directly or indirectly, by all instances of the class standard-class. A subclass of standard-class may have a different class as its default direct superclass, but that class must be a subclass of the class standard-object.

The same is true for funcallable-standard-class and funcallable-standard-object.

Implementation and User Specialization

The purpose of the Metaobject Protocol is to provide users with a powerful mechanism for extending and customizing the basic behavior of the Common Lisp Object System. As an objectoriented description of the basic CLOS behavior, the Metaobject Protocol makes it possible to create these extensions by defining specialized subclasses of pre-existing metaobject classes.

The Metaobject Protocol provides this capability without interfering with the implementor’s ability to develop high-performance implementations. This balance between user extensibility and implementor freedom is mediated by placing explicit restrictions on each. Some of these restrictions are general — they apply to the entire class graph and the applicability of all methods. These are presented in this section.

The following additional terminology is used to present these restrictions:

• Metaobjects are divided into three categories. Those defined in this document are called specified; those defined by an implementation but not mentioned in this document are called implementation-specific; and those defined by a portable program are called portable.

• A class I is interposed between two other classes C_{1} and C_{2} if and only if there is some path, following direct superclasses, from the class C_{1} to the class C_{2} which includes I.

• A method is specialized to a class if and only if that class is in the list of specializers associated with the method; and the method is in the list of methods associated with some

generic function.

• In a given implementation, a specified method is promoted if and only if the specializers of the method, S_{1} … S_{n}, are defined in this specification as the classes C_{1} … C_{n}; but in the implementation, one or more of the specializers S_{i}, is a superclass of the class given in the specification C_{i}.

• For a given generic function and set of arguments, a method M_{2} extends a method M_{1} if

and only if:

M_{1} and M_{2} are both associated with the given generic function; and M_{1} and M_{2} are both applicable to the given arguments; and the specializers and qualifiers of the methods are such that when the generic function is called, M_{2} is executed before M_{1}; and M_{1} will be executed if and only if call-next-method is invoked from from within the body of M_{2}. and in fact call-next-method \underline{is} invoked from within the body of M_{2}.

• For a given generic function and set of arguments a method M_{2} overrides a method M_{1} if

and only if:

M_{1} and M_{2} are both associated with the given generic function; and M_{1} and M_{2} are both applicable to the given arguments; and the specializers and qualifiers of the methods are such that when the generic function is called, M_{2} is executed before M_{1}; and M_{1} will be executed if and only if call-next-method is invoked from from within the body of M_{2}. and in fact call-next-method \underline{is not} invoked from within the body of M_{2}.

Restrictions on Implementations

Implementations are allowed to modify the structure of specified classes and methods. Typically, this will mean one or more of: the interposition of implementation-specific classes; the promotion of specified methods; and the consolidation of two or more specified methods into a single method specialized to interposed classes. But, this description permits any implementation modifications provided provided that for any portable class Cp that is a subclass of one or more specified classes C_{0} … C_{i}, the following are true:

• In the class precedence list of Cp, the classes C_{0} … C_{i} appear in the same order as they would have had no implementation-specific modifications been made.

3–12 Common Lisp Object System Specification • The method applicability of any specified generic function is the same in terms of behavior

as it would have been had no implementation-specific changes been made. This includes specified generic functions which have had portable methods added. In this context, the expression “the same in terms of behavior” means that methods with the same behavior as those specified are applicable, and in the same order.

• Implementations are always free to define implementation-specific :before and :after methods on specified generic functions. Implementations are also free to define implementationspecific :around methods with extending behavior.

• No portable class Cp inherits, by virtue of being a direct or indirect subclass of a specified class, any slot for which the name is a symbol accessible in the common-lisp-user package or exported by any package defined in the ANSI Common Lisp standard.

Restrictions on Portable Programs

Portable programs are free to define subclasses of specified classes, and are permitted to define methods on specified generic functions, with the following restrictions. The results are undefined if any of these restrictions is violated.

• Portable programs must not redefine any specified classes, generic functions, methods or method combination. Any method, defined by a portable program on a specified generic function, must have at least one specializer which is not a specified class.

• Specified methods can be extended unless the description of the method explicitly prohibits this. Any restrictions on the value the extending method must return are explicitly mentioned in the description of the generic function.

• Specified methods can be overridden only when the description of the method explicitly allows this. Typically, when a method is allowed to be overridden, a small number of related will need to be overridden as well.

An example of this is the specified methods on the generic functions add-dependent, remove-dependent and map-dependents. Overriding a specified method on one of these generic functions requires that the corresponding method on the other two generic functions be overridden as well.

• Methods on portable metaobject classes must be defined before any instances of those classes (or any subclasses) are created, either directly or indirectly by a call to make-instance. Methods can be defined after instances are created by allocate-instance however. Portable metaobject classes cannot be redefined.

Implementation Note:

The purpose of this last bullet is to permit implementations to provide performance optimizations by analyzing, at the time the first instance of a metaobject class is initialized, what portable Metaobject Protocol methods will be applicable to it. This can make it possible to elide calls to those Metaobject Protocol generic functions which will have no applicable portable

Draft 11: July 30, 1990 Do Not Distribute

methods.

Processing of the User Interface Macros

A list in which the first element is one of the symbols defclass, defmethod, defgeneric, define-method-combination, generic-function, generic-flet or generic-labels; and which has proper syntax for that macro is called a user interface macro form. For convenience, when the meaning is unambiguous, this terminology is often abbreviated. A user interface macro form may be called a macro form or, for example, a defclass user interface macro form may be called a defclass form.

The user interface macros defclass, defgeneric and defmethod can be used not only to define metaobjects that are instances the corresponding standard metaobject class, but also to define metaobjects that are instances of appropriate portable metaobject classes. To make it possible for portable metaobject classes to properly process the information appearing in the macro form, this document provides a limited specification of the processing of these macro forms.

User interface macro forms can be evaluated or compiled and later executed. The effect of evaluating or executing a user interface macro form is specified in terms of calls to specified functions and generic functions which actually provide the behavior of the macro. The arguments received by these functions and generic functions are derived in a specified way from the macro form.

Converting a user interface macro form into the arguments to the appropriate functions and generic functions involves two major issues. The first is the conversion of the macro argument syntax into a form more suitable for later processing. The second is the processing of macro arguments which are forms to be evaluated (including method bodies).

In the syntax of the defclass macro, the initform and default-initarg-initial-value-form arguments are forms which will be evaluated one or more times after the macro form is evaluated or executed. Special processing must be done on these arguments to ensure that the lexical scope of the forms is captured properly. This is done by building a function of zero arguments which, when called, returns the result of evaluating the form in the proper lexical environment.

In the syntax of the defmethod and defgeneric macros the form* arguments are lists of forms which comprise the body of the method definitions. This list of forms must be processed specially to capture the lexical scope of the macro form. In addition, the lexical functions available only in the body of methods must be introduced. To allow this and any other special processing (such as slot access optimization), a specializable protocol is used for the body of methods. This is discussed in the section “Processing the Bodies of Methods”.

Compile-File Processing of the User Interface Macros

It is common practice for Common Lisp compilers, while processing a file or set of files, to maintain information about the definitions that have been compiled so far. Among other things, this makes it possible to ensure that a global macro definition (defmacro form) which appears in a file will affect uses of the macro later in that file. This information about the state of the compilation is called the compile-file environment.

When compiling files containing CLOS definitions, it is useful to maintain certain additional information in the compile-file environment. This can make it possible to issue various kinds of style warnings (e.g. lambda list congruence) and to do various performance optimizations that would not otherwise be possible.

At this time, there is such significant variance in the way existing Common Lisp implementations handle compile-file environments that it would be premature to specify this mechanism. Consequently, this document specifies only the behavior of evaluating or executing user interface macro forms. What functions and generic functions are called during compile-file processing of a user interface macro form is not specified. Implementations are free to define and document their own behavior. Users may need to check implementation-specific behavior before attempting to compiler certain portable programs.

The defclass Macro

The evaluation or execution of a defclass form results in a call to the ensure-class function. The arguments received by ensure-class are derived from the defclass form in a defined way. The exact macroexpansion of the defclass form is not defined, only the relationship between the arguments to the defclass macro and the arguments received by the ensure-class function.

• The name argument to defclass becomes the name (first required) argument to ensureclass. This is the only positional argument accepted by ensure-class, all other arguments are keyword arguments.

• The direct superclasses argument to defclass becomes the value of the :direct-superclasses keyword argument to ensure-class.

• The direct slots argument to defclass becomes the value of the :direct-slots keyword argument to 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 initforms. 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. Each canonicalized slot specification is formed from the corresponding slot specification as follows:

Note:

A canonicalized slot specification is a property list. It will be 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.

• The name of the slot is the value of the :name property. This property always 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 initform. The value of the :initfunction property is a function of zero arguments which, when called, returns the result of evaluating the initform in its proper lexical environment.

If the :initform slot option does not appear, 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.

• 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 specified 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 Common Lisp 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 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 initarg. The resulting list of canonicalized default initargs is the value of the :directdefault-initargs keyword argument to 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.

• The metaclass class option, if it is present in the defclass form, becomes the value of the :metaclass keyword argument to ensure-class.

• 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. If any class option appears more than once in the defclass form an error is signalled.

In the call to 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 ensure-class are unspecified.

The result of the call to ensure-class is returned as the result of evaluating or executing the defclass form.

Examples of typical defclass forms and expansions are shown in Figures 3-2 and 3-3. Note that these are only sample expansions, what is defined is not the form of the expansion, but rather the arguments received by 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))
                 ':default-initargs (list (list ':engine #'(lambda () *jet*) '*jet*)))

Figure 3–2.

A defclass form with standard slot and class options and an expansion of it which results in the proper call to ensure-class.

   (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))

Figure 3–3.

A defclass form with non-standard class and slot options, and an expansion of it which results in the proper call to ensure-class. Note that the order of the slot options has not effected 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.

The defmethod Macro

The evaluation or execution of a defmethod form requires first that the body of the method be converted to a method function. This process is described in the section “Processing of Method Bodies”. The result of this process is a method function and a set of additional initialization arguments to be used when creating the new method. Given these two values, the evaluation or execution of a defmethod form proceeds in three steps.

The first step ensures the existence of a generic function with the specified name. This is done by calling the function ensure-generic-function. The first argument in this call is the generic function name specified in the defmethod form.

The second step is the creation of the new method metaobject by calling make-instance. The class of the new method metaobject is determined by calling generic-function-method-class on the result of the call to ensure-generic-function from the first step.

The initialization arguments received by the call to make-instance are as follows:

• The value of the :qualifiers initarg is a list of the qualifiers which appeared in the defmethod form. No special processing is done on these values. The order of the elements of this list is the same as in the defmethod form.

• The value of the :lambda-list initarg is the unspecialized lambda list from the defmethod form.

• The value of the :specializers initarg is a list of the specializers for the method. For eql specializers, the specializer is a list in which the first element is the symbol eql and the second element is the result of evaluating the eql specializer form in the lexical environment of the defmethod form. For specializers which are classes, the specializer is the class metaobject itself.

• The value of the :function initarg is the method function.

• Any other initargs produced in conjunction with the method function are also included.

• The implementation is free to include additional initialization arguments provided these are not symbols accessible in the common-lisp-user package, or exported by any package defined in the ANSI Common Lisp standard.

In the third step, add-method is called to add the newly created method to the set of methods associated with the generic function metaobject.

The result of the call to add-method is returned as the result of evaluating or executing the defmethod form.

An example showing a typical defmethod form and its expansion is shown in Figure 3-4. The processing of the method body for this method is shown in Figure 3-5.

   (defmethod move :before ((p position) (l (eql 0)) &optional (visiblyp t) &key color)
     (set-to-origin p)
     (when visiblyp (show-move p 0 color)))
   (let ((#:g001 (ensure-generic-function 'move)))
     (add-method #:g001
                 (make-instance (generic-function-default-method-class #:g001)
                                ':qualifiers '(:before)
                                ':specializers (list (find-class 'position)
                                                     (list 'eql 0))
                                ':lambda-list '(p l &optional (visiblyp t) &key color)
                                ':function (function <method-lambda>)
                                'additional-initarg-1 't
                                'additional-initarg-2 '39)))

Figure 3–4.

A sample defmethod form and one possible correct expansion. In the expansion, <methodlambda> is the result of calling make-method-lambda as described in the section “Processing Method Bodies”. The initargs appearing after :function are the additional initargs returned from the call to make-method-lambda.

Processing Method Bodies

The body of a defmethod macro or :method argument to a defgeneric macro is a list of forms. Before a method can be created, this list of forms must be converted to a method function. This conversion is a two step process.

The first step occurs during macroexpansion of the macro form. In this step, the method body is converted to a lambda expression called a method lambda. This conversion is based on information associated with the generic function definition in effect at the time the macro form is expanded.

For defmethod forms, the generic function definition is obtained by calling ensure-generic-function with a first argument of the generic function name specified in the macro form. The :lambda-list keyword argument is not passed in this call. If the defmethod form is being expanded by the file compiler, so that it can be executed later, the call also includes a non-null value for the :environment keyword argument.

For defgeneric forms, the generic function definition is obtained by calling ensure-generic function with arguments derived from the macro form as described in the section “The defgeneric Macro” except that the :initial-methods keyword argument is not included. If the defgeneric form is being expanded by the file compiler, so that it can be executed later, the call to ensure-generic-function also includes a non-null value for the :environment keyword argument.

Given the generic function, production of the method lambda proceeds by calling make-method-lambda. The first argument in this call is the generic function obtained as described above. The second argument is the result of calling class-prototype on the result of calling genericfunction-method-class on the generic function. The third argument is a lambda expression formed from the method lambda list and body. The fourth argument is the macroexpansion environment of the macro form, this is the value of the &environment argument to the macro.

The generic function make-method-lambda returns two arguments. The first is the method lambda itself. The second is a list of initialization arguments and values. These will be included in the initialization arguments when the method is created. Note that because these initialization arguments appear in the expansion of the macro form, and because this can happen as part of a file compilation, all of the initialization argument values must have applicable methods for the generic function make-load-form.

In the second step, the method lambda is converted to a function which properly captures the lexical scope of the macro form. This is done by having the method lambda appear in the macroexpansion as the argument of the function special form. During the subsequent evaluation or execution of the macroexpansion, the result of the function special form is the method function.

   (let ((gf (ensure-generic-function 'move)))
     (make-method-lambda gf
                         (class-prototype (generic-function-method-class gf))
                         '(lambda (p l &optional (visiblyp t) &key color)
                            (set-to-origin p)
                            (when visiblyp (show-move p 0 color)))
                 <environment>))

Figure 3–5.

During macroexpansion of the defmethod macro shown in Figure 3-4, code similar to this would be run to produce the method lambda and additional initargs. In this example, the value of <environment> is the macroexpansion environment of the defmethod macro form.

Standard Protocol

The Dependent Maintenance Protocol

For each kind of metaobject, a subset of the properties associated with each metaobject are said to define it. For most metaobjects, these properties are those which can be specified by initialization arguments when the object is created. For generic function properties, the set of methods associated with the generic function is also considered to be a defining property.

Class and generic function metaobjects can be redefined. Once a class or generic function object is created, its definining properties can be altered. The most general mechanism for redefining these metaobjects is the reinitialize-instance generic function, but there are other, more special-purpose, mechanisms as well.

Slot definition, method and method combination objects cannot be redefined. Once one of these objects has been created, its defining properties cannot be altered. Non-defining properties of these metaobject can be altered. The reinitialize-instance generic function signals an error if it is applied to any of these metaobjects.

When a redefinable metaobject is redefined, there may be other objects which had previously internalized some aspects of the previous definition of the redefined metaobject. These objects must be updated to conform to the new definition of the redefined metaobject. Such objects are said to depend on the state of the redefined metaobject and are called dependents of the redefined metaobject.

The mechanism used by specified and implementation dependent classes to update dependents of redefined metaobjects is not specified.

Portable programs use the Dependent Maintenance Protocol to update those portable objects that are dependents of a redefined metaobject. The dependent maintenance protocol provides a mechanism for recording that a specified object, is a dependent of a redefinable metaobject. Once a dependent has been recorded, the update-dependent generic function will be called to update it whenever the redefinable metaobject on which it depends is redefined. This update is not recursive, dependents of dependents are not themselves updated.

Class Metaobjects

A class object determines the structure and behavior of its instances. There are protocols which manipulate the information associated with a class object. Other, related, protocols manipulate the instances of the class. These protocols communicate through information associated with the class object.

When a class object is defined or redefined, the initialization arguments specify the defining properties of the class. Each of these properties is checked for errors, internalized in its own way and then associated with the class. This processing of initialization arguments is done by the Class Initialization Protocol.

Before instances of a class can be created the all of the superclasses of the class must be defined. Information inherited from these superclasses, including information about slots accesible in instances of the class, must be collected and associated with the class object. This process is called class finalization and is implemented by the Class Finalization Protocol. A class which has undergone class finalization is called a finalized class.

The class initialization and class finalization protocols are separate protocols. Because a class can be defined before its superclasses are defined, a class can be initialized before it is possible to finalize it. Because a change to a class can propagate to its subclasses, a class must sometimes be re-finalized even though it has not, itself been redefined. When a finalized class is redefined, it must be re-finalized.

The Class Initialization Protocol

Class objects are created by calling the make-instance generic function. In general, class objects can be redefined. Certain metaclasses restrict class redefinition, this is done by defining a method on the reinitialize-instance generic function which signals an error if the redefinition is not permitted.

When a class object is defined or redefined, the initialization arguments specify the new class definition. These initialization arguments must be error-checked and associated with the class object. Initialization arguments which define the slots for the class must be converted to direct slot definition objects before they are stored.

When a class is initialized, each of the specified superclasses is checked for validity. This check is done to ensure that metaclass of the class is compatible with the metaclass of each of the specified superclasses. This validity checking is done by the validate-superclass generic function. If any specified superclass is not validated, an error is signalled. Otherwise, the specified superclasses are associated with the class object and can be accessed by calling the class-direct-superclasses generic function.

When a class is initialized, the slots defined directly in the class are specified as a list of canonicalized slot definitions. Each canonicalized slot definition is converted to a corresponding direct slot definition object. The resulting direct slot definition objects are then associated with the class. Error checking of the canonicalized slot definitions is done during the process of creating the direct slot definition objects.

Converting each canonicalized slot definition into a direct slot definition object is a two step process. The first step determines the appropriate class of the resulting object, the second step creates the object itself. The first step is done by calling the direct-slot-definition-class generic function. This generic function receives the class and the canonicalized slot definition as arguments. This allows the metaclass or slot options which appear directly in the canonicalized slot definition to control the class of the resulting direct slot definition object. The second step is done by calling the make-instance generic function. The make-instance generic function receives the result of the call to the direct-slot-definition-class generic function as its first argument, and the canonicalized slot definition as initialization arguments.

Once each canonicalized slot definition has been converted, the resulting direct slot definition objects are associated with the class and can be accessed by calling the class-direct-slots generic function.

When a class is initialized, the default initargs defined directly in the class are specified as a list of canonicalized default initialization arguments. Each of these is error checked, and the result is associated with the class and can be accessed by calling the class-direct-default-initargs generic function.

If the class being initialized was previously finalized, it is finalized again by calling the finalizeinheritance generic function.

When a class is being reinitialized, any dependents are updated.

The Class Finalization Protocol collects the class precedence list of a class, the slots accessible in instances of the class, the default initargs and any other information the class inherits from its superclasses. The Class Finalization Protocol also determines the implementation of the instances of the class, specifically the location in instances of any slots with :instance allocation.

The first step performed by the class finalization protocol is the determination of the class precedence list of the class. This is done first so that subsequent parts of the finalization process can access the class precedence list. This step is performed by calling the compute-class-precedence-list generic function. The value returned from this call is associated with the class and can be accessed by calling the class-precedence-list generic function.

The second step performed by the class finalization protocol is the determination of the set of slots that will be accessible in instances of the class. This step is performed by calling the generic function compute-slots. The result of this call is a list of effective slot definition objects. Associated with each effective slot definition object is information about one of the slots which will be accessible in instances of the class.

The generic function compute-slots collects the effective slots of the class in a two step process. The first step collects the direct slot definition objects from each class in the class precedence list. The second step combines direct slot definition objects with the same slot name into a single effective slot definition object for the slot with that name. The second step is performed by calling the compute-effective-slot-definition generic function. In turn, this generic function calls the effective-slot-definition-class generic function to determine the class of the effective slot definition object.

The instance structure protocol is a three layer protocol. The upper layer of this protocol is responsible for implementing the slot access functions like slot-value, (setf slot-value), slotboundp etc. The middle layer controls the optimization of calls to the slot-value and (setf slot-value). The lowest layer controls the implementation of instances of the class, and provides limited mechanisms for direct access to the storage associated with an instance.

The slot-xxx-using-class functions are implemented by corresponding generic functions as described in chapter 1. Portable methods on each of these generic functions can control the corresponding slot behavior.

It is expected that most implementations will have some mechanism for optimizing slot access. This mechanism will have the effect of in-lining the behavior of the specified methods on slotvalue-using-class and (setf slot-value-using-class). This optimization will be usurped when there are applicable, portable methods on either of these generic functions. In such cases those methods must be called.

In many cases, portable methods on slot-value-using-class and (setf slot-value-using-class) do not affect the behavior of access to slots with :instance or :class allocation. Many such methods only implement the access behavior for slots with an allocation particular to a portable metaclass. In such cases, it is desirable to allow the implementation’s optimization mechanism to avoid the call to the portable method. This makes it possible for portable metaclasses which define special allocation types to inherit the implementation’s slot access optimization for slots with :instance or :class allocation.

For any given class, this mechanism is controlled on a per slot basis, by the effective slots of the class. When the class is finalized, the generic function slot-definition-elide-access-method-p is called on each of the effective slots. For any slot with :instance or :class allocation, if this generic function returns false, applicable portable methods on slot-value-using-class and (setf slot-value-using-class) will be called. If this generic function returns true, the implementation is permitted not to call such applicable methods. Certain calls to slot-value or (setf slot-value) may have the effect of calling only the specified methods.

The specified method on the generic function slot-definition-elide-access-method-p for the class standard-effective-slot-definition returns false. This has the effect that the default behavior for standard classes is to always call user defined methods on the slot access generic functions.

The value returned by the specified method on the generic function slot-definition-elide-access-method-p for the class structure-effective-slot-definition is not specified. This method cannot be overridden. This has the effect that portable programs cannot define methods on the slot access generic functions for subclasses of structure-class.

At the lower level, the instance structure protocol controls certain limited aspects of the implementation of instances of the class. This provides the ability for portable metaclasses to optimize certain accesses to slots of a class that have allocation :instance.

Associated with each effective slot definition object is the location of that slot. This value can be used to access the storage associated with instances directly.

• For slots with allocation :instance and type t, the location must be a positive integer. No two slots in a class can have the same integer for a location.

• For any other slots with :instance allocation, the location returned by specified methods on the slot-definition-location generic function is not specified. The value may be an integer, but is not required to be.

• Portable methods on the slot-definition-location generic function must only return integers.

The location of a slot can be used with the low level accessor for the corresponding metaclass to access the value of a slot.

standard-class standard-instance-access funcallable-standard-class funcallable-standard-instance-access structure-class structure-instance-access

There are a number of restrictions on the use of these low level accessors. The results are undefined if any of these restrictions are violated. The instance argument to each accessors must be an instance with the appropriate metaclass. The instance cannot be an obsolete instance which has not yet been updated. The location argument must be a location of one of the effective slots of the class with :instance allocation. When the location is being read, the slot at the specified location must be bound.

Generic Function Metaobjects

Associated with a generic function is information about the method combination used by the generic function... There are protocols which manipulate the information associated with a generic function. Other, related, protocols determine the behavior of the generic function when it is invoked.

Associated with each generic function object is a function which implements the behavior of the generic function. This is called the discriminating function of a generic function. The discriminating function of a generic function object can be changed using the set-funcallable-instance function, but there is no accessor for reading the discriminating function of a generic function.

Draft 11: July 30, 1990 Do Not Distribute

Special Metaclasses

built-in-class funcallable-standard-class forward-referenced-class

Functions in the Metaobject Protocol

This section describes the functions, and generic functions in the metaobject protocol.

The syntax description for a function, or generic function describes its parameters. The following is an example of the format for the syntax description of a generic function:

gf1 x y &optional z &key k [Generic Function]

This description indicates that the generic function gf1 has two required parameters, x and y. In addition, there is an optional parameter z and a keyword parameter k. Every generic function described in this section is an instance of the class standard-generic-function and uses standard method combination, so this information is not duplicated in each description.

The description of a function or generic function includes a description of its behavior. In the case of a function, this is a complete description of the behavior of the function. In the case of a generic function, this provides the general behavior, or protocol of the generic function. Any methods defined on the generic function must have behavior consistent with this description, but will have some variances appropriate to the subclass specialization being implemented.

The description of a generic function also includes descriptions of the specified methods for that generic function. In the description of these methods, a method signature is used to describe the parameters and parameter specializers of each method. The following is an example of the format for a method signature:

gf1 (x class) (y t) &optional z &key k [Primary Method]

This signature indicates that this method on the generic function gf1 has two required parameters, x and y. In addition, there is an optional parameter z and a keyword parameter k. This signature also indicates that the parameter specializers of the method are the classes named class and t and that the method has no qualifiers.

The syntax description for a generic function describes the lambda-list of the generic function itself, while the method signatures describe the lambda-lists of the defined methods.

The description of each method includes a a description of the behavior particular to that method.

An abbreviated syntax is used when referring to a method for which the definition appears somewhere else in the document. This abbreviated syntax includes the name of the generic function, the qualifiers, and the parameter specializers. A reference to the method with the signature shown above is written as: method gf1 (class t).

add-dependent Generic Function

Syntax:

add-dependent metaobject dependent [Generic Function]

Arguments:

The metaobject argument is a class or generic function metaobject. The dependent argument is an object.

Values:

The value returned by this generic function is unspecified.

Purpose:

The generic function add-dependent updates the set of dependents of metaobject to include dependent. If dependent is already in the set of dependents it is not added again (no error is signalled). The generic function map-dependents can be called to access the set of dependents of a class or generic function. The generic function remove-dependent can be called to remove an object from the set of dependents of a class or generic function. The effect of calling add-dependent or remove-dependent while a call to map-dependents on the same class or generic function is in progress is unspecified. When metaobject is reinitialized by reinitialize-instance each of its dependents is updated. This is done by calling map-dependents so that update-dependent can be called on each dependent. The situations in which add-dependent is called are not specified.

Methods:

add-dependent (class standard-class) dependent [Primary Method] No behavior is specified for this method beyond that specified for the generic function. This method cannot be overridden unless the following methods are overridden as well:

method remove-dependent (standard-class t) method map-dependents (standard-class t)

add-dependent

add-dependent (generic-function standard-generic-function) dependent [Primary Method]

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

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

method remove-dependent (standard-generic-function t) method map-dependents (standard-generic-function t)

Remarks:

Portable code must not use metaobjects themselves as dependents. Instead, portable programs which need to record a metaobject as a dependent, should encapsulate that metaobject in some other kind of object, and record that object as the dependent.

This requirement prevents two portable programs, or a portable program and the implementation from inadvertently removing dependents recorded by one another.

Example:

This example shows a general facility for encapsulating metaobjects before recording them as dependents. The facility defines a basic kind of encapsulating object: an updater. Specializations of the basic class can be defined with appropriate special updating behavior. In this way, information about the updating required is associated with each updater rather than with the metaobject being updated.

;;;
;;; Updaters are used to encapsulate any metaobject which needs updating
;;; when a given class or generic function is modified. RECORD-UPDATER
;;; is called to both create an updater and add it to the dependents of
;;; the class or generic functions.  Methods on the generic function
;;; UPDATE-DEPENDENT, specialized to the specific class of updater do
;;; the appropriate update work.
;;;
(defclass updater ()
     ((dependee  :initarg :dependee  :reader dependee)
      (dependent :initarg :dependent :reader dependent)))
(defun record-updater (class dependee dependent &rest initargs)
  (let ((updater (apply #'make-instance class :dependee dependee
                                              :dependent dependent
                                              initargs)))
    (add-dependent dependee updater)
    updater))
;;;
;;; A FLUSH-CACHE-UPDATER simply flushes the cache of the dependent
;;; when it is updated.

add-dependent

;;;
(defclass flush-cache-updater (updater) ())
(defmethod update-dependent ((updater flush-cache-updater) &rest args)
  (declare (ignore args))
  (flush-cache (dependent updater)))

See Also:

“The Dependent Maintenance Protocol” remove-dependent map-dependents update-dependent

add-direct-method Generic Function

Syntax:

add-direct-method specializer method [Generic Function]

Arguments:

The specializer argument is a method specializer. The results are undefined if it is not one of the specializers of method. The method argument is a method metaobject.

Values:

The value returned by this generic function is unspecified.

Purpose:

The generic function add-direct-method is called to maintain a set of backpointers from a specializer to the set of methods specialized to it. When called, if method is already in the set, it is not added again (no error is signalled). This set can be accessed as a list by calling the generic function specializer-direct-methods. Methods can be removed from the set by calling remove-direct-method. The generic function add-direct-method is called by add-method whenever a method is added to a generic function. It is called once for each of the specializers of the method. Note that in cases where a class appears more than once in the specializers of a method, this generic function will be called more than once with the same class and specializer as arguments.

Methods:

add-direct-method (specializer class) (method method) [Primary Method]

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:

method remove-direct-method (class method) method specializer-direct-methods (class)

add-direct-method

add-direct-method (specializer cons) (method method) [Primary Method]

This method implements the behavior of the generic function for eql specializers. When specializer is a list of the form (eql object), method is added to a list of methods associated with object. This list is returned by method specializer-direct-methods (cons). If specializer is not a list of the form (eql object), the behavior of this method is unspecified. This method cannot be overridden.

See Also:

remove-direct-method specializer-direct-methods

add-direct-subclass Generic Function

Syntax:

add-direct-subclass superclass subclass [Generic Function]

Arguments:

The superclass argument is a class metaobject. The subclass argument is a class metaobject.

Values:

The value returned by this generic function is unspecified.

Purpose:

The generic function add-direct-subclass 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. The generic function class-direct-subclasses returns the set as a list. A class can be removed from the set by calling remove-direct-subclass. 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 remove-direct-subclass is called once for each deleted direct superclass of the class.

Methods:

add-direct-subclass (superclass class) (subclass class) [Primary Method]

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:

method remove-direct-subclass (class class) method class-direct-subclasses (class)

add-direct-subclass

See Also:

remove-direct-subclass class-direct-subclasses

add-method Generic Function

Syntax:

add-method generic-function method [Generic Function]

Arguments:

The generic-function argument is a generic function metaobject.

The method argument is a method metaobject. The lambda-list of the method function must be congruent with the lambda-list of the generic function, or an error is signaled.

Values:

The generic function argument is returned.

Purpose:

The generic function add-method adds a method to the set of methods associated with a generic function. After adding the method to this set, compute-discriminating-function is called and its result is installed by calling set-funcallable-instance-function. The generic-function argument is destructively modified and returned as the result.

If the method metaobject is already associated with a generic function an error is signalled.

The set of methods associated with the generic function can be accessed as a list by calling generic-function-methods. A method can be removed from the set by calling removemethod.

The generic function add-method can be called by the user or the implementation. It is called whenever a method must be added to a generic function.

Methods:

add-method (generic-function standard-generic-function) (method method) [Primary Method]

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 section of Chapter 1 called “Agreement on Parameter Specializers and Qualifiers” for a definition of agreement in this context.

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

method remove-method (standard-generic-function method)

add-method

method generic-function-methods (standard-generic-function)

See Also:

Chapter 1 section—“Agreement on Parameter Specializers and Qualifiers” remove-method generic-function-methods compute-discriminating-function

allocate-instance Generic Function

Syntax:

allocate-instance class &rest initargs [Generic Function]

Arguments:

The class argument is a class metaobject. The initargs argument consists of alternating initialization argument names and values.

Values:

The value returned by allocate-instance is a newly allocated instance.

Purpose:

The generic function allocate-instance is called to create a new, uninitialized instance of a class. The interpretation of the concept of an “unitialized instance” depends on the method. Before allocating the new instance, class-finalized-p is called to see if class has been finalized. If it has not been finalized, finalize-inheritance is called before the new instance is allocated.

Methods:

allocate-instance (class standard-class) &rest initargs [Primary Method] The instance returned by this method has slots which are unbound.

allocate-instance (class funcallable-standard-class) &rest initargs [Primary Method] The instance returned by this method has slots which are unbound. The funcallable instance function of the instance is undefined — the results are undefined if the instance is applied to arguments before set-funcallable-instance-function has been used to set the funcallable instance function.

allocate-instance (class built-in-class) &rest initargs [Primary Method] This method signals an error.

class-prototype Generic Function

Syntax:

compute-applicable-methods class [Generic Function]

Arguments:

The class argument is a class metaobject.

Values:

This generic function returns an object which is an instance of the class class.

compute-applicable-methods Generic Function

Syntax:

compute-applicable-methods generic-function arguments [Generic Function]

Arguments:

The generic-function argument is a generic function metaobject.

The arguments argument is a list of objects.

Values:

This generic function returns a possibly empty list of method metaobjects.

Purpose:

The generic function compute-applicable-methods determines the method applicability of a generic function given a list of required arguments for the generic function. 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 compute-applicable-methods-using-classes; or calling compute-applicable-methods. Refer to the description of computediscriminating-function for the details of this process.

For any given generic function and set of arguments, if compute-applicable-methods-using-classes returns a second value of true, the first value must be equal to the value that would have been returned by a corresponding call to compute-applicable-methods. The results are undefined if this is not the case.

The arguments argument must have at least as many elements as the generic function accepts required arguments. If fewer arguments are supplied, an error is signalled.

The list returned by this generic function will not be mutated by any call to any other function or generic function defined in this specification. The results are undefined if a portable program mutates the list returned by this generic function.

compute-applicable-methods

Methods:

compute-applicable-methods (generic-function standard-generic-function) arguments [Primary Method]

This method signals an error if any method of the generic function has a specializer which is neither a class metaobject nor a list of the form (eql object).

Otherwise, this method computes the sorted list of applicable methods according to the rules described in the section of Chapter 1 called “Method Selection and Combination”.

This method can be overridden. Because of the consistency requirements between this generic function and compute-applicable-methods-using-classes, doing so may require also overidding method compute-applicable-methods-using-classes (standard-generic-function t).

See Also:

“Method Lookup Protocol”

compute-applicable-methods-using-classes

compute-discriminating-function

compute-applicable-methods-using-classes Generic Function

Syntax:

compute-applicable-methods-using-classes generic-function classes [Generic Function]

Arguments:

The generic-function argument is a generic function metaobject.

The classes argument is a list of class metaobjects.

Values:

This generic function returns two values. The first is a possibly empty list of method metaobjects. The second is either true or false.

Purpose:

The generic function compute-applicable-methods-using-classes is called to attempt to determine the method applicability given only the classes of the required arguments to the generic function.

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 first value and true as its second value. The returned list of method metaobjects is sorted by precedence order, the most specific method is 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 first 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 compute-applicable-methods-using-classes; or calling compute-applicable-methods. Refer to the description of computediscriminating-function for the details of this process.

For any given generic function and set of arguments, if compute-applicable-methods-using-classes returns a second value of true, the first value must be equal to the value that would have been returned by compute-applicable-methods. The results are undefined if this is not the case.

The list returned by this generic function will not be mutated by any call to any other function or generic function defined in this specification. The results are undefined if a portable program

compute-applicable-methods-using-classes

mutates the list returned by this generic function.

Methods:

compute-applicable-methods-using-classes (generic-function standard-generic-function) classes

[Primary Method]

If any method of the generic function has a specializer which is neither a class metaobject nor a list of the form (eql object), this method returns an unspecified first value and false as its second value.

In cases where the generic function has no methods with eql specializers, or has no methods with eql specializers which 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 first value and false as its second value.

This method can be overridden. Because of the consistency requirements between this generic function and compute-applicable-methods, doing so may require also overidding method compute-applicable-methods (standard-generic-function t).

Remarks:

This generic function exists to support extensions which modify the rules of method applicability but which base the new, modified rules only on the classes of the arguments to the generic function. Such extensions can be implemented by two methods, one on this generic function and another on compute-applicable-methods.

An extension which bases method applicability on properties of the arguments to the generic function other than their class, as is the case with eql specializers, can be implemented in one of two ways.

The first involves two methods definitions. One method on this generic function which returns a second value of false as appropriate together with a method on compute-applicable-methods which computes the ordered set of applicable methods using the desired method applicability rules.

The second involves defining a method on compute-discriminating-function. The discriminating function returned by this method implements the desired method applicability rules directly without making any calls to compute-applicable-methods or compute-applicable-methods-using-classes.

See Also:

“Method Lookup Protocol”

compute-applicable-methods

Draft 11: July 30, 1990 Do Not Distribute

compute-applicable-methods-using-classes

compute-discriminating-function

compute-class-precedence-list Generic Function

Syntax:

compute-class-precedence-list class [Generic Function]

Arguments:

The class argument is a class metaobject.

Values:

The value returned by this generic function is a list of class metaobjects.

Purpose:

The generic-function compute-class-precedence-list is called to determine the class precedence list of a class. The result is a proper 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, finalize-inheritance calls this generic function and associates the returned value with the class metaobject. The value can then be accessed by calling classprecedence-list. The list returned by this generic function will not be mutated by any call to any other function or generic function defined in this specification. The results are undefined if a portable program mutates the list returned by this generic function.

Methods:

compute-class-precedence-list (class class) [Primary Method] This method computes the class precedence list according to the rules described in the section of Chapter 1 called “Determining the Class Precedence List”. If the specified class or any of its superclasses is a forward referenced class an error is signalled. This method can be overridden.

See Also:

compute-class-precedence-list

Chapter 1 section—“Determining the Class Precedence List” finalize-inheritance class-precedence-list

compute-discriminating-function Generic Function

Syntax:

compute-discriminating-function generic-function [Generic Function]

Arguments:

The generic-function argument is a generic function metaobject.

Values:

The value returned by this generic function is a function.

Purpose:

The generic function compute-discriminating-function is called to determine the discriminating function for a generic function. When a generic function is called, it is the installed discriminating function which implements the behavior of calling the generic function: determining the ordered set of applicable methods, determining the effective method, and running the effective method. A discriminating function can be installed by calling set-funcallable-instance-function.

To determine the ordered set of applicable methods, the discriminating function first calls compute-applicable-methods-using-classes. If compute-applicable-methods-using-classes returns a second value of false, the discriminating function then calls computeapplicable-methods.

When compute-applicable-methods-using-classes returns a second value of true, the discriminating function is permitted to memoize the first returned value as follows. If the generic function is called again with required arguments which are instances of the same classes; and the generic function has not been reinitialized; and no method has been added to the generic function; and no method has been removed from the generic function; and for all the specializers of all the generic function’s methods which are classes the class precedence list has not changed; for any such memoized value, no class precedence list of the required argument classes has changed; then the discriminating function may reuse the list of applicable methods without calling computeapplicable-methods-using-classes again.

Determination of the the effective method is done by calling compute-effective-method.

When the effective method is run, each method’s function is called using the result of calling method-function-applier.

This generic function is called, and the result is installed by add-method, remove-method, initialize-instance and reinitialize-instance.

compute-discriminating-function

Methods:

compute-discriminating-function (generic-function standard-generic-function) [Primary Method] This method returns a discriminating function as described above. This method can be extended. The extending method is permitted to call call-next-method and return a result which itself calls the result of this method. This method can be overridden.

See Also:

“The Method Lookup Protocol” compute-applicable-methods compute-applicable-methods-using-classes compute-effective-method make-method-lambda method-function-applier

compute-effective-method Generic Function

Syntax:

compute-effective-method generic-function method-combination methods [Generic Function]

Arguments:

The generic-function argument is a generic function metaobject.

The method-combination argument is a method combination metaobject.

The methods argument is a list of method metaobjects.

Values:

This generic function returns two values. The first is an effective method, the second is a list of effective method options.

Effective methods and effective method options are defined in the description of the definemethod-combination macro in chapter 2. An effective method is a form, consisting of, among other things, calls to call-method, which describes how the applicable methods are to be combined. An effective-method option is either the :arguments or the :generic-function options in the long form of define-method-combination.

Purpose:

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

The first value returned by this generic function is the effective method. The second is a list of effective method options, these have the same syntax and interpretation as the :genericfunction and :arguments options in the long form of define method combination.

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

Because neither method nor method combination metaobjects can be reinitialized, the results of this generic function may be memoized.

Methods:

compute-effective-method (generic-function standard-generic-function) (method-combination standard-method-combination) methods [Primary

compute-effective-method

Method] This method computes the effective method according to the rules of the method combination type implemented by method-combination. This method can be overridden.

compute-effective-method (generic-function standard-generic-function) (method-combination standard-simple-method-combination) methods

[Primary Method] This method computes the effective method according to the rules of the method combination type implemented by method-combination. This method can be overridden.

See Also:

“Method Lookup Protocol” Chapter 1 section—“Applying Method Combination to the Sorted List of Applicable Methods” define-method-combination compute-discriminating-function

compute-effective-slot-definition Generic Function

Syntax:

compute-effective-slot-definition class name direct-slot-definitions [Generic Function]

Arguments:

The class argument is a class metaobject. The name argument is a slot name. The direct-slot-definitions argument is an ordered list of direct slot definition metaobjects. The most specific direct slot definition metaobject appears first in the list.

Values:

The value returned by this generic function is an effective slot definition metaobject.

Purpose:

This generic function determines the effective slot definition for each slot in a class. It is called by 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 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 “Initialization of Slot Definition Metaobjects” for details.

Methods:

compute-effective-slot-definition (class standard-class) name direct-slot-definitions [Primary Method]

This method implements the inheritance and defaulting of slot options following the rules described in the “Inheritance of Slots and Options” section of Chapter 1. This method signals an error if the value returned by effective-slot-definition-class is not the class standard-effective-slot-definition or one of its subclasses.

compute-effective-slot-definition

This method cannot be overridden; it can be extended, but the value returned by the extending method must be the value returned by this method.

See Also:

compute-slots effective-slot-definition-class

compute-slots Generic Function

Syntax:

compute-slots class [Generic Function]

Arguments:

The class argument is a class metaobject.

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 4 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 compute-effective-slot-definition is called to compute an effective slot definition. The result of 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. For more information on the slot definition locations, see the section “Accessing Slots Directly”.

The list returned by this generic function will not be mutated by any call to any other function or generic function defined in this specification. The results are undefined if a portable program mutates the list returned by this generic function.

Methods:

compute-slots (class standard-class) [Primary Method]

This method implements the specified behavior of the generic function.

This method can be overriden.

See Also:

Draft 11: July 30, 1990 Do Not Distribute

compute-slots

compute-effective-slot-definition effective-slot-definition-class

ensure-class Function

Syntax:

ensure-class name &key :environment &allow-other-keys  [Function]

Arguments:

The name argument is a class name. The :environment argument is the same as the &environment argument to macro expansion functions. It is used to distinguish between compile-time and run-time environments.

Values:

The result of ensure-class is a class metaobject.

Purpose:

The function ensure-class is called to define or redefine a class with the specified name in the specified environment. It is the functional equivalent of defclass. This function can be called by the user or the implementation. It is called by the expansion of the defclass macro. The function ensure-class is implemented by the generic function ensure-class-using-class. The first agument to the ensure-class-using-class generic function is computed as follows:

• If the class name name names a class in the environment :environment use that class.

• Otherwise use false. The second argument is name. The remaining arguments are the complete set of keyword arguments received by the ensureclass function.

Remarks: See Also:

“Expansion of the User Interface Macros” defclass

Draft 11: July 30, 1990 Do Not Distribute

ensure-class

ensure-class-using-class find-class

ensure-class-using-class Generic Function

Syntax:

ensure-class-using-class class name &key :metaclass :environment :superclasses &allow-other-keys  [Generic Function]

Arguments:

The class argument is a class metaobject or false. The name argument is a class name. The :metaclass argument is a class metaobject or a 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 in the environment specified by the :environment argument. If a class name is supplied, but there is no such class an error is signalled. The :environment argument is the same as for the ensure-class function. The :superclasses argument is a list of which each element is a class metaobject or a class name. An error is signalled if this argument is not a proper list. Additional keyword arguments accepted by this generic function are interpreted by generic functions in the Class Initialization Protocol.

Purpose:

The generic function ensure-class-using-class is called to define or modify the definition of a named class. It is called by the 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:

• The :metaclass argument is not included in the initialization arguments.

• The :environment argument is not included in the initialization arguments.

• If the :superclasses argument was received by this generic function, it is converted into a list of class metaobjects. This conversion does not affect the structure of the supplied :superclasses argument. For each element in the :superclasses argument:

• If the element is a class metaobject, that class metaobject is used.

3–58 Common Lisp Object System Specification

ensure-class-using-class

• Otherwise the element is a class name. If there is a class with that name in the environment :environment that class metaobject is used.

• Otherwise an instance of the class forward-referenced-class is created and used. The proper name of the newly created class metaobject is set to the class name in the environment :environment.

• All other keyword arguments are included directly in the initialization arguments.

If the class argument is false, a new class metaobject is created by calling the make-instance generic function. The make-instance generic function is called with the value of the :metaclass argument as its first argument, and the previously computed initialization arguments as initialization arguments. The proper name of the newly created class metaobject is set to the name name in the environment :environment. The newly created class metaobject is returned.

Otherwise, if the class of the class argument is not eq to the class specified by the :metaclass argument, the class of the class argument must be changed. This is done by calling the changeclass generic function. The change-class generic function will signal an error if the class change is invalid.

If the class change is valid, or no class change was required, the class metaobject class is redefined by calling the reinitialize-instance generic function with the class argument and the initialization arguments. The class argument is then returned.

ensure-class-using-class

Methods:

ensure-class-using-class (class class) name &key :metaclass :environment :superclasses &allow-other-keys  [Primary Method]

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

ensure-class-using-class (class null) name &key :metaclass :environment :superclasses &allow-other-keys  [Primary Method]

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

Remarks:

Methods can be defined on this generic function to control the behavior when certain classes of named classes are redefined. Methods should be defined on functions in the Class Initialization Protocol to control the initial creation of classes.

See Also:

“Expansion of the User Interface Macros” defclass ensure-class find-class

ensure-generic-function Function

Syntax:

ensure-generic-function function-name &key :environment &allow-other-keys &rest all-keys [Function]

function-name::= {symbol | (setf symbol)}

Arguments:

The function-name argument is a symbol or a list of the form (setf symbol). The :environment argument is the same as the &environment argument to macro expansion functions. It is used to distinguish between compile-time and run-time environments.

Values:

The result of ensure-generic-function is a generic function metaobject.

Purpose:

The function ensure-generic-function is used 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 is the functional equivalent of defgeneric. This function can be called by the user or the implementation. It is called by the expansion of the defgeneric and defmethod macros. The function ensure-generic-function is implemented by the generic function ensure-generic-function-using-class. The first argument to ensure-generic-function-using-class is computed as follows:

• If (symbol-function function-name) is a non-generic function, a macro, or a special form, an error is signaled.

• If function-name names a generic function in the environment :environment, that generic function is used.

• Otherwise, false is used. The second argument is function-name. The remaining arguments are the complete set of keyword arguments received by ensure-

ensure-generic-function

generic-function.

Remarks: See Also:

“Expansion of the User Interface Macros” defgeneric ensure-generic-function-using-class symbol-function

ensure-generic-function-using-class Generic Function

Syntax:

ensure-generic-function-using-class (generic-function standard-generic-function) function-name &key :generic-function-class :environment &allow-other-keys [Generic

Function] function-name::= {symbol | (setf symbol)}

Arguments:

The generic-function argument is a generic function metaobject or false. The function-name argument is a symbol or a list of the form (setf symbol). The :generic-function-class argument is 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 in the environment specified by the :environment argument. If a class name is supplied, but there is no such class an error is signalled. The :environment argument is the same as for the ensure-generic-function function . Additional keyword arguments accepted by this generic function are interpreted by generic functions in the Generic Function Initialization Protocol.

Purpose:

The generic function 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. The 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.

• The :environment argument is not included in the initialization arguments.

• All other keyword arguments are included directly in the initialization arguments.

ensure-generic-function-using-class

If the generic-function argument is false, an instance of the class specified by the :genericfunction-class argument is created. The function name function-name is set to name the generic function in the environment :environment. The newly created generic function metaobject is returned.

Otherwise, if the class of the generic-function argument is not eq to the class specified by the :generic-function-class argument, the class of generic-function must be changed. This is done by calling the change-class generic function. The change-class generic function will signal an error if this class change is invalid.

If the class change is valid, or no class change is required, the generic function generic-function is redefined by calling the reinitialize-instance generic function. The generic function genericfunction is then returned.

Methods:

ensure-generic-function-using-class (generic-function generic-function) function-name &key :generic-function-class :environment &allow-other-keys [Primary Method]

function-name::= {symbol | (setf symbol)}

This method implements the behavior of the generic function in the case where function-name does name a generic function in the environment :environment.

ensure-generic-function-using-class (generic-function null) function-name &key :generic-function-class :environment &allow-other-keys [Primary Method]

function-name::= {symbol | (setf symbol)}

This method implements the behavior of the generic function in the case where function-name names no function, generic function, macro or special form in the environment :environment.

Remarks:

See Also:

“Expansion of the User Interface Macros”

ensure-generic-function-using-class

defgeneric ensure-generic-function symbol-function

extract-lambda-list Function

Syntax:

extract-lambda-list specialized-lambda-list [Function]

Arguments:

The specialized-lambda-list argument is a specialized lambda list as accepted by defmethod.

Values:

The result of extract-lambda-list is the specialized lambda list with the specializers removed.

Purpose:

The function extract-lambda-list takes a specialized lambda list and returns the lambda list with the specializers removed. This is a non-destructive operation. Whether the result shares any structure with the input is undefined. If the specialized-lambda-list argument does not have legal syntax, an error is signalled. This syntax checking does not check the syntax of the actual specializers, only the syntax of the lambda list and where the specializers appear.

Examples:

(extract-lambda-list '((p position)))                 ==> (P)
(extract-lambda-list '((p position) x y))             ==> (P X Y)
(extract-lambda-list '(a (b (eql x)) c &optional i))  ==> (A B C &OPTIONAL I)

See Also:

defmethod extract-specializer-names

extract-specializer-names Function

Syntax:

extract-specializer-names specialized-lambda-list [Function]

Arguments:

The specialized-lambda-list argument is a specialized lambda list as accepted by defmethod.

Values:

The result is a list of the specializers in the specialized-lambda-list argument.

Purpose:

The function extract-specializer-names takes a specialized lambda list and returns its specializers. This is a non-destructive operation. Whether the result shares structure with any other list is unspecified. The results are undefined if the result of this function is modified. The result of this function will be a list with a number of elements equal to the number of required arguments in specialized-lambda-list. Specializers are defaulted to the symbol t. If the specialized-lambda-list argument does not have legal syntax, an error is signalled. This syntax checking does not check the syntax of the actual specializers, only the syntax of the lambda list and where the specializers appear.

Remarks: Examples:

(extract-specializer-names '((p position)))                 ==> (POSITION)
(extract-specializer-names '((p position) x y))             ==> (POSITION T T)
(extract-specializer-names '(a (b (eql x)) c &optional i))  ==> (T (EQL X) T)

See Also:

defmethod extract-lambda-list

finalize-inheritance Generic Function

Syntax:

finalize-inheritance class [Generic Function]

Arguments:

The class argument is a class metaobject.

Purpose: Values:

The value returned by this generic function is unspecified.

Methods:

The standard method does the following in this order:

• Calls compute-class-precedence-list and stores the result.

• Calls compute-slots and stores the result.

• Calls slot-accesses-to-deoptimize and deoptimizes specified slots.

• Maybe calls make-instances-obsolete. It isn’t specified how to tell whether makeinstances-obsolete will be called or not.

• Marks the class as being finalized.

Remarks:

find-method-combination Generic Function

Syntax:

find-method-combination generic-function method-combination-type method-combination-options [Generic Function]

Arguments:

The generic-function argument is a generic function metaobject. The method-combination-type argument is a symbol which names a type of method combination. The method-combination-options argument is a list of arguments to the method combination type.

Values:

The value returned by this generic function is a method combination metaobject.

Purpose: Methods: Remarks:

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 reinitialized by calling reinitializeinstance. Some classes of class metaobject do not support reinitialization; in these cases, reinitialize-instance signals an error.

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. The class of a class metaobject may be changed with change-class, but the results are unspecified if any of the initialization arguments described below appear in the resulting call to update-instance-for-different-class.

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 call initialize-instance directly to initialize a class metaboject. Portable programs must not call shared-initialize directly to initialize or reinitialize a class metaboject.

A description of the interpretation of each initialization argument is presented first, this is followed by a description of the special behavior of each of the specified classes of class metaobject.

In these descriptions, the phrase “this argument defaults to value” means that when the initialization argument is not supplied, initialization or reinitialization proceeds as if value had been supplied. Whether this is done through the use of default initialization arguments is not specified. Whether any specified class of class metaobjects has default initialization arguments is not specified. Implementations are free to do so. Portable programs are free to define default initialization arguments on portable subclasses of the class class.

• The :direct-superclasses argument is a list of class metaobjects. Classes which do not support multiple inheritance signal an error if the list contains more than one element.

An error is signalled under the following conditions: if this value is not a proper list, if it is the empty list, or if validate-superclass applied to class and any element of this list returns false.

When the class is being initialized, and this argument is not supplied, an error is signalled. If this argument is supplied, the generic function add-direct-subclass is called once for each element of the list.

When the class is being reinitialized, and this argument is not supplied, it defaults to the result of calling class-direct-superclasses with the class metaobject as the argument. If this argument is supplied, the generic function remove-direct-subclass is called once for each class in the result of calling class-direct-superclasses but not in the list; and the generic function add-direct-subclass is called once for each class which is in the list but not in the result of class-direct-superclasses.

initialization of class metaobjects

• The :direct-slots argument is a list of direct slot definition metaobjects.

An error is signalled if this value is not a proper list or if any element of the list is not an instance of the class direct-slot-definition or one of its subclasses. If the class is being initialized, this argument defaults to the empty list. If the class is being reinitialized, this argument defaults to the result of calling class-direct-slots with the class metaobject as the argument.

• The :direct-default-initargs argument is a list of canonicalized default initialization arguments. An error is signalled if this value is not a proper list; or if any element of the list is not a canonicalized default initialization argument. If the class is being initialized, this argument defaults to the empty list. If the class is being reinitialized, this argument defaults to the result of calling class-direct-default-initargs with the class metaobject as the argument.

• The :documentation argument is a string or nil.

An error is signalled if this value is not a string or nil. If the class is being initialized, this argument defaults to nil. If the class is being reinitialized, this argument defaults to the result of calling documentation with the class metaobject as the argument.

• The :name argument is an object.

If the class is being initialized, this argument defaults to false. If the class is being reinitialized, this argument defaults to the result of calling class-name with the class metaobject as the argument.

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

Initialization Argument  Generic Function
:direct-superclasses  class-direct-superclasses
:direct-slots  class-direct-slots
:direct-default-initargs  class-default-initargs
:documentation  documentation
:name  class-name

initialization of class metaobjects

Standard Classes:

Standard classes support multiple inheritance and reinitialization.

Built-in Classes:

Built-in classes cannot be created by the user, and cannot be reinitialized. An error is signalled if initialize-instance or reinitialize-instance are called to initialize or reinitialize a built-in class metaobject.

Methods:

It is not specified what methods provide the initialization and reinitialization behavior described above. Instead, the information needed to allow portable programs to specialize this behavior is presented in terms of a set of restrictions on the methods a portable program can define. 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. The results are undefined if any of these restrictions are violated.

• Portable programs must not define methods on shared-initialize.

• Portable programs must not define primary methods on the generic function initializeinstance.

• Portable programs must not define primary methods on the generic function reinitializeinstance.

• Portable programs must not define primary methods on the generic function updateinstance-for-different-class.

• Portable programs may define around methods on the generic function initialize-instance, but these must be extending, not overriding methods.

• Portable programs may define around methods on the generic function reinitialize-instance, but these must be extending, not overriding methods.

• Portable programs may define around methods on the generic function update-instance-for-different-class, but these must be extending, not overriding methods.

• A portable before method on the generic function initialize-instance must assume that when it is run, the class metaobject has not been initialized.

• A portable after method on the generic function initialize-instance must assume that when it is run, the class metaobject has been completely initialized.

• A portable before method on the generic function reinitialize-instance must assume that

3–72 Common Lisp Object System Specification

Draft 11: July 30, 1990 Do Not Distribute

initialization of class metaobjects

when it is run, no reinitialization of the class metaobject has been done.

• A portable after method on the generic function reinitialize-instance must assume that when it is run, the class metaobject has been completely reinitialized.

Initialization of Generic Function Metaobjects

Methods for generic function metaobjects on the generic functions shared-initialize and reinitialize-instance are presented together here.

Implementations are free to have other, implementation specific keyword arguments accepted by these methods. Those keyword arguments must not be in the lisp, user or keyword packages.

initialize-instance

No method applicable to generic function metaobjects is specified for the initialize-instance generic function.

reinitialize-instance

reinitialize-instance (generic-function generic-function) &rest reinitargs [:After Method]

This method updates the dependents of the reinitialized generic function. This is done by using map-dependents to call update-dependent on all the dependents of generic-function.

shared-initialize

shared-initialize (generic-function standard-generic-function) function-name &key :lambda-list :argument-precedence-order :declarations :documentation :initial-methods :method-combination :method-class  [:After Method]

The first step performed by this method is the defaulting of any unsupplied keyword arguments. If generic function has previously been initialized, unsupplied keyword arguments default to the result of calling the corresponding generic function.

If generic-function has not previously been initialized, unsupplied keyword arguments default as follows:

If the :lambda-list argument is not supplied, an error is signalled.

The :argument-precedence-order argument defaults to a list of the required arguments from the :lambda-list argument.

The :declarations argument defaults to the empty list.

initialization of generic function metaobjects

The :documentation argument defaults to false. The :initial-methods argument defaults to the empty list. The :method-combination argument defaults to the result of: (find-method-combination

'standard ()).

The :method-class argument defaults to the class named standard-method. Once unsupplied keyword arguments have been defaulted, initialization of generic function proceeds as follows:

• The :lambda-list argument is a lambda list, an error is signalled otherwise. If the generic function has any existing methods, the lambda list must be congruent with the lambda list of each of those methods. An error is signalled otherwise.

• The :argument-precedence-order argument is a list of symbols. Each symbol must be one of the required parameters in the :lambda-list argument. An error is signalled otherwise.

• The :declarations argument is a list of declarations. An error is signalled otherwise.

• The :documentation argument is a string or false. An error is signalled otherwise.

• The :initial-methods argument is a list of canonicalized initial method specifications.

• The :method-combination argument is a method combination metaobject. An error is signalled otherwise.

• The :method-class argument is a class metaobject. It must be a subclass of the class method. An error is signalled otherwise.

• If generic-function has already been initialized, and previously had a different value for the :method-class argument, the value is changed, but any existing methods are not changed.

• The value of each keyword argument is stored so that it will be the result of the correspond-

ing method. These correspondences are as follows:

Keyword Argument  Generic Function
:lambda-list  generic-function-lambda-list
:argument-precedence-order  generic-function-argument-precedence-order
:declarations  generic-function-declarations
:documentation  documentation
:initial-methods  generic-function-initial-methods
:method-combination  generic-function-method-combination
:method-class  generic-function-method-class

• Previously defined initial methods are all removed. Initial methods are then re-defined. The value of the :method-class argument does affect the creation of these methods.

initialization of generic function metaobjects

• The generic function update-dismcrinating-function is called to update the discriminating function of the generic function.

Remarks:

Except for any initial methods which are re-created, the :method-class argument does not affect any exisiting methods of the generic function.

Initialization of Method Metaobjects

Methods for method metaobjects on the generic functions shared-initialize and reinitializeinstance are presented together here.

initialize-instance

No method applicable to method metaobjects is specified for the initialize-instance generic function.

reinitialize-instance

reinitialize-instance (method method) &rest reinitargs [:After Method] This method signals an error.

shared-initialize

shared-initialize (method standard-method) &key :lambda-list :qualifiers :specializers :function :documentation  [:After Method]

The first step performed by this method is the defaulting of any unsupplied keyword arguments. These default as follows:

If the :lambda-list argument is not specified, an error is signalled.

The :qualifiers argument defaults to the empty list.

If the :specializers argument is not supplied an error is signalled. If the :function argument is not supplied an error is signalled. The :documentation argument defaults to false.

Once unsupplied keyword arguments have been defaulted, initialization of method proceeds as follows:

• The :lambda-list argument is a lambda list, otherwise an error is signalled.

• The :qualifiers argument is a list of method combination qualifiers. An error is signalled if this argument is not a proper list, or if any element of this argument is not syntactically valid for use as a method combination qualifier.

Metaobject Protocol 3–77

initialization of method metaobjects

• The :specializers argument is a list of method specializers. An error is signalled if this argument is not a proper list, or if any elemet of this argument is neither a class metaobject or a list of the form (eql object).

• The function argument is a method function.

• The :documentation argument is a string or false. An error is signalled otherwise.

• The value of each keyword argument is stored so that it will be the result of the corresponding method. These correspondences are as follows:

Argument  Method
:qualifiers  generic-function-qualifiers (standard-method)
:specializers  generic-function-specializers (standard-method)
:function  generic-function-function (standard-method)
:documentation  documentation (method)

Initialization of Method Combination Metaobjects

reinitialize-instance (method method) &rest reinitargs [:After Method] This method calls map-dependents so that update-dependent can be called on each of the dependents of method. shared-initialize standard-method-combination [Primary Method]

shared-initialize standard-simple-method-combination  [Primary Method]

Initialization of Slot Definition Metaobjects

Methods for slot definition metaobjects on the generic function shared-initialize, and the generic function reinitialize-instance are presented together here. This is done to make the relationship between the behavior of these generic functions more clear.

initialize-instance

No method applicable to slot definition metaobjects is specified for the initialize-instance generic function.

reinitialize-instance

reinitialize-instance (slot-definition slot-definition) &rest reinitargs [Primary Method] This method signals an error.

shared-initialize

shared-initialize (slot-definition standard-slot-definition) &key :name :initform :initfunction :type :allocation :initargs :documentation  [:After Method]

The first step performed by this method is the defaulting of any unsupplied keyword arguments: If the :name argument is not specified an error is signalled. The :initform argument defaults to false. An error is signalled if the :initfunction argument is supplied, but the :initform argument is not supplied. The :initfunction argument defaults to false. An error is signalled if the :initform argument is supplied, but the :initfunction argument is not supplied. The :type argument defaults to the symbol t. The :allocation argument defaults to the symbol :instance. The :initargs argument defaults to the empty list. The :documentation argument defaults to false.

initialization of slot definition metaobjects

Once unsupplied keyword arguments have been defaulted, initialization of slot-definition proceeds as follows:

• The :name argument is a slot name. An error is signalled if this argument is not a symbol which can be used as a variable name.

• The :initform argument is a lisp form.

• The :initfunction argument is a function which accepts no arguments, and when called, evaluates the :initform in the appropriate lexical context. The results are undefined if the :initform and :initfunction arguments do not correspond in this way.

• The :type argument is a type specifier name. An error is signalled otherwise.

• The :allocation argument is a symbol. An error is signalled otherwise.

• The :initargs argument is a list of symbols. An error is signalled if this argument is not a proper list, or if any element of this argument is not a symbol.

• The :documentation argument is a string or false. An error is signalled otherwise.

• The value of each keyword argument is stored so that it will be the result of the corresponding method. These correspondences are as follows:

Argument  Method
:name  slot-definition-name (standard-slot-definition)
:initform  slot-definition-initform (standard-slot-definition)
:type  slot-definition-type (standard-slot-definition)
:allocation  slot-definition-allocation (standard-slot-definition)
:initargs  slot-definition-initargs (standard-slot-definition)
:documentation  slot-definition-documentation (standard-slot-definition)

shared-initialize (slot-definition standard-direct-slot-definition) &key :readers :writers  [:After Method]

The first step performed by this method is the defaulting of unspecified keyword arguments. Both the :readers and the :writers argument default to the empty list.

Both the :readers and :writers arguments are list of function names. An error is signalled if either argument is not a proper list, or if any element of either argument is not a valid function name.

Draft 11: July 30, 1990 Do Not Distribute

initialization of slot definition metaobjects

Initialization of slot-definition proceeds by storing the value of each keyword argument so that it will be the result of the corresponding method. These correspondences are as follows:

Argument  Method
:readers  slot-definition-readers (standard-direct-slot-definition)
:writers  slot-definition-writers (standard-direct-slot-definition)

make-instance Generic Function

Syntax:

make-instance class &rest initargs [Generic Function]

Arguments:

The class argument is a class metaobject or a class name. The initargs argument is a list of alternating initialization argument names and values.

Purpose:

The generic function make-instance creates and returns a new instance of the given class. The generic function make-instance may be used as described in the section “Object Creation and Initialization.” This generic function can be called by the user or the implementation.

Methods:

make-instance (class symbol) &rest initargs [Primary Method] This method invokes make-instance recursively on the arguments (find-class class) and initargs.

make-instance (class class) &rest initargs [Primary Method] This method implements the behavior of make-instance described in the section “Object Creation and Initialization”.

Remarks: See Also:

“Object Creation and Initialization” defclass initialize-instance class-of

make-method-lambda Generic Function

Syntax:

make-method-lambda generic-function method lambda-expression environment [Generic Function]

Arguments:

The generic-function argument is a generic function metaobject.

The method argument is a method metaobject.

The lambda-expression argument is a lambda expression.

Values:

The result is a lambda expression.

Purpose:

The make-method-lambda 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 specified ones.

Either the function compile, the special form function or the function coerce must be used to convert the lambda expression to such a method function. The method function itself can only be called with apply-method-function. The results are undefined if the method function is applied to arguments using the apply or funcall functions.

Methods:

make-method-lambda (generic-function standard-generic-function) (method standard-method) lambda-list body [Primary Method]

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

The method function produced from the result of this method can only be applied by method apply-method-function (standard-generic-function standard-method t t). The results are undefined otherwise.

This method cannot be overridden unless the following method is overridden as well:

make-method-lambda

method apply-method-function (standard-generic-function standard-method t t)

See Also:

“Function Type: X3J13-March-88” apply-method-function compute-discriminating-function

map-dependents Generic Function

Syntax:

map-dependents metaobject function [Generic Function]

Arguments:

The metaobject argument is a redefinable metaobject. The function argument is a function which accepts one argument.

Values:

The value returned by map-dependents is unspecified.

Purpose:

The generic function map-dependents is called to apply function to each of the dependents of metaobject. The order in which the dependents are processed is not specified, but function is applied to each dependent once and only once. If add-dependent or remove-dependent is called during a call to map-dependents, it is not specified whether the newly added or removed dependent will have function applied to it. This generic function can be called by the user or the implementation. When a metaobject is reinitialized, map-dependents is used to call update-dependent on each of the metaobject’s dependents.

Methods:

map-dependents (metaobject dependee-mixin) function [Primary Method] This method has no specified behavior beyond that specified for the generic function. This method cannot be overridden unless the following methods are overridden as well:

method add-dependent (dependee-mixin t) method remove-dependent (dependee-mixin t)

Remarks:

Only one method is specified for this generic function, but implementations are free to have additional methods on specified classes.

See Also:

“The Dependent Maintenance Protocol”

map-dependents

add-dependent remove-dependent update-dependent

Readers for Class Metaobjects

There are a number of generic functions which simply return information associated with class metaobjects. Because the methods on such generic functions are naturally thought of as being implemented using the :reader slot option in defclass, the generic functions themselves are commonly called reader generic functions.

The reader generic functions for class metaobjects are presented together here. General information about these generic functions is presented first. This is followed by a description of the purpose of each generic function. Finally, the specified methods for these generic functions are presented.

Each of the reader generic functions for class metaobjects has the same syntax, accepting one required argument called class. This argument is a class metaobject.

For any of these generic functions which returns a list, such lists will not be mutated by any call to any other function or generic function defined in this specification. The results are undefined if a portable program mutates such a list.

class-default-initargs class [Generic Function]

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 finalize-inheritance calls compute-default-initargs to compute the default initialization arguments for the class. That value is associated with the class metaobject and is returned by class-default-initargs.

This generic function signals an error if class has not been finalized or is a forward referenced class.

class-direct-default-initargs class [Generic Function]

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.

During class initialization or reinitialization, the defaulted value of the :direct-default-initargs initialization argument is associated with the class. That value is returned by class-direct-default-initargs.

readers for class metaobjects

This generic function signals an error if class has not been initialized or is a forward referenced class.

class-direct-slots class [Generic Function] Returns a list of the direct slots of class. The elements of this list are direct slot definition metaobjects. If the class has no direct slots, the empty list is returned. During class initialization or reinitialization, the defaulted value of the :direct-slots initialization argument is associated with the class. That value is returned by class-direct-slots. This generic function signals an error if class has not been initialized or is a forward referenced class.

class-direct-subclasses class [Generic Function] Returns a list of the direct subclasses of class. The elements of this list are class metaobjects. This list contains no duplicates. The empty list is returned if class has no direct subclasses. This value is maintained by the generic functions add-direct-subclass and remove-direct-subclass. This generic function signals an error if class has not been initialized.

class-direct-superclasses class [Generic Function] 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. During class initialization or reinitialization, the defaulted value of the :direct-superclasses initialization argument is associated with the class. That value is returned by class-direct-superclasses. This generic function signals an error if class has not been initialized.

class-finalized-p class [Generic Function] Returns true if class has been finalized. Returns false otherwise.

readers for class metaobjects

class-name class [Generic Function] Returns the name of class. This value is a symbol, or false if the class has no name. During class initialization or reinitialization, the defaulted value of the :name initialization argument is associated with the class. That value is returned by class-name. This generic function signals an error if class has not been initialized.

class-precedence-list class [Generic Function] Returns the class precedence list of class. The elements of this list are class metaobjects. During class finalization finalize-inheritance calls 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 class-precedence-list. This generic function signals an error if class has not been finalized or is a forward referenced class.

class-slots class [Generic Function] Returns a possibly empty list of the slots accessible in instances of class. The elements of this list are effective slot definition metaobjects. During class finalization finalize-inheritance calls compute-slots to compute the slots of the class. That value is associated with the class metaobject and is returned by class-slots. This generic function signals an error if class has not been finalized or is a forward referenced class.

readers for class metaobjects

Methods:

The specified methods for the class metaobject reader generic functions are presented below. All of these methods may be may be extended, but the extending method must return the value returned by the specified method. 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.

standard-class  forward-
and  referenced- built-in-class
funcallable-standard-class  class
class-default-initargs  2  3  4
class-direct-default-initargs  1  3  4
class-direct-slots  1  3  4
class-direct-subclasses  9  9  7
class-direct-superclasses  1  3  7
class-finalized-p  2  6  5
class-name  1  1  8
class-precedence-list  2  3  7
class-slots  2  3  4

1 This method returns the value which was associated with the class metaobject during initial-

ization or reinitialization. 2 This method returns the value associated with the class metaobject by method finalize-

inheritance (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 Figure 3-1, except that

implementation-specific modifications are permitted as described in section “Implementation and User Specialization”.

8 This method returns the name of the built in class. 9 This methods returns a value which is maintained by method add-direct-subclass (class

class) and method remove-direct-subclass (class class). This method can be overridden only if those methods are overridden as well.

Readers for Generic Function Metaobjects

A number of the reader generic functions which simply return information associated with generic function metaobjects are presented together here.

Each of these reader generic functions have the same syntax. Each accepts one required argument called generic-function. This argument is a generic function metaobject.

The purpose of these reader generic functions is to access information associated with a generic function metaobject. This information is maintained by generic functions described elsewhere in this this document.

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

For those reader generic functions which return lists, the results are undefined if the structure of such a list is modified.

Each of these generic functions signals an error if the generic function generic-function has not been initialized.

Generic Functions

generic-function-argument-precedence-order generic-function [Generic Function]

Returns the argument precedence order of the generic function. This list is a permutation of the required parameters in the lambda list of the generic function. This value is a list of symbols.

generic-function-declarations generic-function [Generic Function]

Returns a possibly empty list of the declarations for generic function. The elements of this list are declarations as defined in the description of defgeneric.

generic-function-initial-methods generic-function [Generic Function]

Returns a possibly empty list of the initial methods of generic function. The elements of this list are initial method specifications. See the section “Expansion of the User Interface Macros” for a description of converting the :method argument to defgeneric into an initial method specification.

generic-function-lambda-list generic-function [Generic Function]

readers for generic function metaobjects

Returns the lambda list of the generic function.

generic-function-method-class generic-function [Generic Function]

Returns the default method class of the generic function. This is a class metaobject.

generic-function-method-combination generic-function [Generic Function]

Returns the method combination of the generic function. This is a method combination metaobject.

generic-function-methods generic-function [Generic Function]

Returns a list of the methods currently connected to the generic function. This is a list of method metaobjects.

generic-function-name generic-function [Generic Function]

Returns the name of the generic function. False is returned if the generic function has no name.

Methods

These reader generic functions have a specified method for the class standard-generic-function.

Unless otherwise indicated below, these methods may be extended, but the extending method must return the value returned by the specified method.

generic-function-argument-precedence-order (std-gf) [Primary Method] generic-function-declarations (standard-generic-function) [Primary Method] generic-function-lambda-list (standard-generic-function) [Primary Method] generic-function-method-class (standard-generic-function) [Primary Method] generic-function-method-combination (standard-generic-function) [Primary Method]

Each of these methods returns a value which is maintained by method shared-initialize (standard-generic-function).

readers for generic function metaobjects

generic-function-initial-methods (standard-generic-function) [Primary Method]

This method returns a value which is maintained by method shared-initialize (standardgeneric-function). This method may be overridden.

generic-function-methods (standard-generic-function) [Primary Method]

The value returned by this method is maintained by method add-method (standard-generic-function standard-method) and method remove-method (standard-generic-function standard-method).

generic-function-name (standard-generic-function) [Primary Method]

The value returned by this method is maintained by method (setf generic-function-name) (standard-generic-function).

This method can be overridden only if the following method is overridden as well:

method (setf generic-function-name) (standard-generic-function)

Readers for Method Metaobjects

A number of the reader generic functions which simply return information associated with method metaobjects are presented together here. Each of these reader generic functions have the same syntax. Each accepts one required argument call method. This argument is a method metaobject. The purpose of these reader generic functions is to access information associated with a method metaobject. This information is maintained by generic functions described elsewhere in this this document. These generic functions can be called by the user or the implementation. For those reader generic functions which return lists, the results are undefined if the structure of such a list is modified. Each of these generic functions signals an error if the method method has not been initialized.

Generic Functions

method-function method [Generic Function] Returns the function of method.

method-generic-function method [Generic Function] Returns the generic function method is connected to. False is returned if method is not currently connected to a generic function.

method-lambda-list method [Generic Function] Returns the lambda list of the method. This is not a specialized lamba list.

method-specializers method [Generic Function] Returns a list of the specializers of method.

method-qualifiers method [Generic Function]

readers for method metaobjects

Returns a possibly empty list of the qualifiers of method.

Methods

method-function (standard-method) [Primary Method] method-lambda-list (standard-method) [Primary Method] method-specializers (standard-method) [Primary Method] method-qualifiers (standard-method) [Primary Method] Each of these methods return a value which is maintained by method shared-initialize (standard-method).

These methods can be overridden.

method-generic-function (standard-method) [Primary Method]

The value returned by this method is maintained by method add-method (standard-generic-function standard-method) and method remove-method (standard-generic-function standard-method).

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

method add-method (standard-generic-function method) method remove-method (standard-generic-function method) method compute-discriminating-function (standard-generic-function) method compute-applicable-methods (standard-generic-function)

Accessor Methods

method-slot-name accessor-method [Generic Function]

Returns the slot name accessed by a reader or writer method.

method-slot-name (standard-reader-method) [Primary Method] method-slot-name (standard-writer-method) [Primary Method]

These methods returns a value maintained by the corresponding method on shared-initialize.

Draft 11: July 30, 1990 Do Not Distribute

Readers for Method Combination Metaobjects

method-combination-name method-combination-options method-combination-order method-combination-operator method-combination-identity-with-one-argument

Readers for Slot Definition Metaobjects

A number of the reader generic functions which simply return information associated with slot definition metaobjects are presented together here. Each of these reader generic functions has the same syntax. Each accepts one required argument called slot-definition. This argument is a slot definition metaobject. The purpose of these reader generic functions is to access information associated with a slot definition metaobject. This information is maintained by generic functions described elsewhere in this document. These generic functions can be called by the user or the implementation. For those reader generic functions which return lists, the results are undefined if the structure of such a list is modified. Each of these generic functions signals an error if the slot definition slot-definition has not been initialized.

Generic Functions

slot-definition-name slot-definition [Generic Function] Returns the name of slot-definition. This is the name of the slot slot-definition describes. This can be any object.

slot-definition-initform slot-definition [Generic Function] Returns the initform of slot-definition. This can be any Lisp expression.

slot-definition-initfunction slot-definition [Generic Function] Returns the initfunction of slot-definition. False is returned when a slot definition has no initform.

slot-definition-type slot-definition [Generic Function] Returns the type of slot-definition.

slot-definition-allocation slot-definition [Generic Function]

3–98 Common Lisp Object System Specification

readers for slot definition metaobjects

Returns the allocation of slot-definition.

slot-definition-initargs slot-definition [Generic Function]

Returns the slot filling initargs of slot-definition.

Methods

These reader generic functions has a specified method for the class slot-definition.

slot-definition-name (slot-definition) [Primary Method] slot-definition-initform (slot-definition) [Primary Method] slot-definition-initfunction (slot-definition) [Primary Method] slot-definition-type (slot-definition) [Primary Method] slot-definition-allocation (slot-definition) [Primary Method] slot-definition-initargs (slot-definition) [Primary Method]

Each of these methods returns a value which is maintained by method shared-initialize (slotdefinition).

These methods can be overridden if method shared-initialize (slot-definition) is overridden as well.

Direct Slot Definition Metaobjects

The following reader generic functions are defined for direct slot definition metaobjects.

slot-definition-readers direct-slot-definition [Generic Function]

Returns the readers of the direct slot definition metaobject. This value is a list of function names.

slot-definition-writers direct-slot-definition [Generic Function]

Returns the writers of the direct slot definition metaobject. This value is a list of function names.

slot-definition-readers (slot-definition slot-definition) [Primary Method]

slot-definition-writers (slot-definition slot-definition) [Primary Method]

readers for slot definition metaobjects

Effective Slot Definition Metaobjects

The following reader generic function is defined for effective slot definition metaobjects. slot-definition-location effective-slot-definition [Generic Function] Returns the location of effective-slot-definition. The meaning and interpretation of this value is described in the section “The Instance Structure Protocol”

slot-definition-location (effective-slot-definition standard-effective-slot-definition) [Primary Method] This method returns the value stored by method compute-slots (standard-class).

slot-definition-location (effective-slot-definition structure-effective-slot-definition) [Primary Method] This method returns the value stored by method compute-slots (structure-class).

remove-dependent Generic Function

Syntax:

remove-dependent metaobject dependent [Generic Function]

Arguments:

The metaobject argument is a redefinable metaobject. The dependent argument is an object.

Values:

The value returned by this generic function is unspecified.

Purpose:

The generic function remove-dependent removes dependent from the dependents of metaobject. If dependent is not one of the dependents of metaobject, no error is signalled. This generic function can be called by the user or the implementation. The situations in which the implementation calls remove-dependent are unspecified. The results are undefined if a dependent which was added by the implementation is removed by the user.

Methods:

remove-dependent (metaobject dependee-mixin) dependent [Primary Method] This method has no specified behavior beyond that specified for the generic function. This method cannot be overridden unless the following methods are overridden as well:

method add-dependent (dependee-mixin t) method map-dependents (dependee-mixin t)

Remarks:

Only one method is specified for this generic function, but implementations are free to have additional methods on specified classes.

See Also:

“The Dependent Maintenance Protocol” add-dependent map-dependents

Metaobject Protocol 3–101

remove-direct-method Generic Function

Syntax:

remove-direct-method specializer method [Generic Function]

Arguments:

The specializer argument is a method specializer. The results are undefined if it is not one of the specializers of method. The method argument is a method metaobject.

Values:

The value returned by remove-direct-method is unspecified.

Purpose:

The generic function remove-direct-method is called to maintain a list of backpointers from a specializer to the set of methods, actually on generic functions, which use that specializer. When specializer is a class metaobject, this generic function removes method from the direct methods of that class. If method is not a member of the direct methods of the class, no error is signalled. This list can be obtained by calling the generic function class-direct-methods. This generic function can be called by the user or the implementation. It is called whenever a method is removed from a generic function, to remove the backpointer from each of the method’s specializers to the method.

Methods:

remove-direct-method (specializer t) (method method) [Primary Method]

The behavior of this method is unspecified.

remove-direct-method (specializer class) (method method) [Primary Method]

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:

remove-direct-method

method add-direct-method (class method) method class-direct-methods (class)

Remarks: See Also:

add-direct-method class-direct-methods

remove-direct-subclass Generic Function

Syntax:

remove-direct-subclass superclass subclass [Generic Function]

Arguments:

The superclass argument is a class metaobject. The subclass argument is a class metaobject.

Values:

The value returned by remove-direct-subclass is unspecified.

Purpose:

The generic function remove-direct-subclass is called to maintain a list of backpointers from a class to its direct subclasses. This generic function removes subclass from the direct subclasses of superclass. If subclass is not one of the direct subclasses of superclass, no error is signalled. The effect of this operation on previous returned values of class-direct-subclasses is undefined. Whenever a class is modified, and the set of direct superclasses is changed, this generic function is called with each discarded superclass.

Methods:

remove-direct-subclass (superclass class) (subclass class) [Primary Method]

No behavior is specified for this method beyond that which is specified for the generic function. This method can only be overridden if the following methods are overridden as well:

method add-direct-subclass (class class) method class-direct-subclasses (class)

See Also:

add-direct-subclass class-direct-subclasses

remove-method Generic Function

Syntax:

remove-method generic-function method [Generic Function]

Arguments:

The generic-function argument is a generic function metaobject. The method argument is a method metaobject.

Values:

The modified generic function is returned. The result of remove-method is eq to the genericfunction argument.

Purpose:

The generic function remove-method removes a method from a generic function. It destructively modifies the specified generic function and returns the modified generic function as its result. No error is signalled if the method is not one of the methods on the generic function. This generic function can be called by the user or the implementation. It is called whenever a method must be removed from a generic function.

Methods:

remove-method (generic-function standard-generic-function) (method method) [Primary Method]

No behavior is specified for this method beyond that specified for the generic function. This method can only be overridden if the following methods are overridden as well:

method add-method (standard-generic-function method)

method compute-discriminating-function (standard-generic-function) method compute-applicable-methods (standard-generic-function t)

See Also:

“Method Lookup Protocol” compute-applicable-methods

remove-method

compute-discriminating-function defmethod find-method

Draft 11: July 30, 1990 Do Not Distribute

set-funcallable-instance-function Function

Syntax:

set-funcallable-instance-function funcallable-instance function [Function]

slot-boundp-using-class Generic Function

Syntax:

slot-boundp-using-class class object slot-name [Generic Function]

Arguments:

The class argument is a class metaobject. It is the class of the object argument.

The object argument is an object.

The slot-name argument is a slot-name.

Values:

This generic function returns true or false.

Purpose:

The generic function slot-boundp-using-class implements the behavior of the slot-boundp function. It is called by slot-boundp with the class of object as its first argument to allow methods specialized to the metaclass to control this behavior. User programs may call this generic function directly, the results are undefined if class is not the class of object.

The generic function slot-boundp-using-class tests whether a specific slot in an instance is bound. If there is no slot with that name, slot-missing is called. If the metaclass of the object does not support slots an error is signalled. If the metaclass of the object does not distinguish unbound slots true is returned.

Methods:

slot-boundp-using-class (class standard-class) (object standard-object) slot-name [Primary Method]

The metaclass standard-class supports unbound slots, this method implements the full behavior of this generic function.

slot-boundp-using-class (class structure-class) (object structure-object) slot-name [Primary Method]

The metaclass structure-class does not distinguish unbound slots. This method returns true if a slot with the given name exists, regardless of the contents of that slot.

slot-boundp-using-class

slot-boundp-using-class (class built-in-class) object slot-name) [Primary Method] The metaclass built-in-class does not support slots. This method signals an error.

Remarks:

Overriding method slot-boundp-using-class (standard-class standard-object t) may require overridding other methods in the standard implementation of the slot access protocol. See the section “The Slot Access Protocol”.

See Also:

“The Slot Access Protocol” slot-boundp slot-makunbound-using-class

direct-slot-definition-class Generic Function

Syntax:

direct-slot-definition-class class canonicalized-slot-specification [Generic Function]

Arguments:

The class argument is a class metaobject. The canonicalized-slot-specification argument is a canonicalized slot specification.

Purpose:

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

Methods: Remarks:

slot-exists-p-using-class Generic Function

Syntax:

slot-exists-p-using-class class object slot-name [Generic Function]

Arguments:

The class argument is a class metaobject. It is the class of the object argument.

The object argument is any lisp object.

The slot-name argument is a slot-name.

Values:

This generic function returns a boolean value.

Purpose:

The generic function slot-exists-p-using-class implements the behavior of the slot-exists-p function. It is called by slot-exists-p with the class of object as its first argument to allow methods specialized to the metaclass to control this behavior. User programs may call this generic function directly, the results are undefined if class is not the class of object.

The generic function slot-exists-p-using-class tests whether the specified object has a slot with the given name. If a slot named slot-name is accessible in object true is returned. If no such slot is accessible in object false is returned. If the metaclass of the object does not support slots, false is returned. If slots are supported, but the slot-name argument is not a legal slot-name an error is signalled.

Methods:

slot-exists-p-using-class (class standard-class) (object standard-object) slot-name [Primary Method]

The metaclass standard-class supports slots. An error is signalled if slot-name is not a symbol which is syntactically valid for use as a Common Lisp variable name.

slot-exists-p-using-class (class structure-class) (object structure-object) slot-name [Primary Method]

The metaclass structure-class supports slots. An error is signalled if slot-name is not a symbol.

slot-exists-p-using-class

slot-exists-p-using-class (class built-in-class) object slot-name) [Primary Method] The metaclass built-in-class does not support slots. This method returns false.

Remarks:

Overriding method slot-exists-p-using-class (standard-class standard-object t) may require overridding other methods in the standard implementation of the slot access protocol. See the section “The Slot Access Protocol”.

See Also:

“The Slot Access Protocol” slot-exists-p

slot-makunbound-using-class Generic Function

Syntax:

slot-makunbound-using-class class object slot-name [Generic Function]

Arguments:

The class argument is a class metaobject. It is the class of the object argument.

The object argument is any lisp object.

The slot-name argument is a slot-name.

Values:

This generic function returns its object argument.

Purpose:

The generic function slot-makunbound-using-class implements the behavior of the slotmakunbound function. It is called by slot-makunbound with the class of object as its first argument to allow methods specialized to the metaclass to control this behavior. User programs may call this generic function directly, the results are undefined if class is not the class of object.

The generic function slot-makunbound-using-class restores a slot in an object to its unbound state. If the metaclass doesn’t support slots, an error is signalled. If the metaclass supports slots, but no slot with the given name is accessible in object, slot-missing is called. If slots are supported, and a slot of the given name is accessible in the object, the interpretation of “restoring a slot to its unbound” state depends on the method which runs.

Methods:

slot-makunbound-using-class (class standard-class) (object standard-object) slot-name [Primary Method]

The metaclass standard-class supports unbound slots, if a slot with the given name exists it is restored to its unbound state.

slot-makunbound-using-class (class structure-class) (object structure-object) slot-name [Primary Method]

slot-makunbound-using-class

The metaclass structure-class does not support unbound slots, the behavior of this method is unspecified.

slot-makunbound-using-class (class built-in-class) object slot-name) [Primary Method]

The metaclass built-in-class does not support slots, this method signals an error.

Remarks:

Overriding method slot-makunbound-using-class (standard-class standard-object

t) may require overridding other methods in the standard implementation of the slot access protocol. See the section “The Slot Access Protocol”.

See Also:

“The Slot Access Protocol”

slot-makunbound

slot-value-using-class Generic Function

Syntax:

slot-value-using-class class object slot-name [Generic Function]

Arguments:

The class argument is a class metaobject. It is the class of the object argument. The object argument is any lisp object. The slot-name argument is a slot-name.

Values:

The value returned by this generic function is an object.

Purpose:

The generic function slot-value-using-class returns the value contained in the slot named slotname of the given object. If there is no slot with that name, slot-missing is called. If the slot is unbound slot-unbound is called. If the metaclass of the object does not support slots an error is signalled.

Methods:

slot-value-using-class (class standard-class) object slot-name [Primary Method] This method implements the slot-value behavior for objects with metaclass standard-class described in Chapter 1.

slot-value-using-class (class structure-class) (object slot-name) [Primary Method] This method does not check for unbound slots. If an attempt is made to access a slot which has not been initialized the results are undefined.

slot-value-using-class (class built-in-class) object slot-name [Primary Method] This method signals an error.

Remarks:

slot-value-using-class

Overriding method slot-value-using-class (standard-class standard-object t) may require overridding other methods in the standard implementation of the slot access protocol. See the section “The Slot Access Protocol”.

See Also:

“The Slot Access Protocol”

slot-value

(setf slot-value-using-class)

Draft 11: July 30, 1990 Do Not Distribute

(setf slot-value-using-class) Generic Function_{Metaobject Protocol 3–117} specializer-direct-generic-functions Generic Function

Syntax:

specializer-direct-generic-functions specializer [Generic Function]

Arguments:

The specializer argument is a method specializer.

Values:

The result of this generic function is a list of generic function objects.

Purpose:

This generic function is called to return a possibly empty list of those generic functions which have a method which has specializer as a specializer. This list contains no duplicates. The elements of this list are generic function objects. Whether this list shares structure with any other lists is not specified. The structure of the returned list may be modified by subsequent calls to the generic function add-direct-method or the generic function remove-direct-method.

Methods:

specializer-direct-generic-functions (specializer class) [Primary Method] This method returns the result which is maintained by the methods:

method add-direct-method (class method) and method remove-direct-method (class method).

This method can be overridden only when those methods are overridden as well. specializer-direct-generic-functions (specializer t) [Primary Method] This method returns the result which is maintained by the methods:

method add-direct-method (t method) and method remove-direct-method (t method).

This method can be overridden only when those methods are overridden as well.

specializer-direct-methods Generic Function

Syntax:

specializer-direct-methods specializer [Generic Function]

Arguments:

The specializer argument is a method specializer.

Values:

The result of this generic function is a list of method metaobjects.

Purpose:

This generic function is called to return a possibly empty list of those methods, connected to generic functions, which have specializer as a specializer. This list contains no duplicates. The elements of this list are method metaobjects. Whether this list shares structure with any other lists is not specified. The structure of the returned list may be modified by subsequent calls to the generic function add-direct-method or the generic function remove-direct-method.

Methods:

specializer-direct-methods (specializer class) [Primary Method] This method returns the result which is maintained by the methods:

method add-direct-method (class method) and method remove-direct-method (class method).

This method can be overridden only when those methods are overridden as well. specializer-direct-methods (specializer t) [Primary Method] This method returns the result which is maintained by the methods:

method add-direct-method (t method) and method remove-direct-method (t method).

This method can be overridden only when those methods are overridden as well.

update-dependent Generic Function

Syntax:

update-dependent metaobject dependent &rest reinitargs [Generic Function]

Arguments:

The metaobject argument is a redefinable metaobject. It is the metaobject that was redefined.

The dependent argument is an metaobject, it is the dependent being updated.

The reinitargs argument is a list of the initialization arguments for the metaobject redefinition.

Values:

The value returned by update-dependent is unspecified.

Purpose:

When a metaobject is reinitialized, the generic function update-dependent is called to update each object which depends on the state of that metaobject.

When a class or a generic function is redefined by calling the reinitialize-instance generic function, the reinitargs argument is the initialization arguments that were passed to reinitializeinstance.

When a generic function is redefined by calling the add-method generic function, the reinitargs argument is a list of two elements, the first element is the symbol add-method, the second element is the method that was added.

When a generic function is redefined by calling the remove-method generic function, the reinitargs argument is a list of two elements, the first element is the symbol remove-method, the second element is the method that was removed.

Methods:

This generic function uses progn method combination. The results are undefined if any method is overridden. It is permissible to define around methods on this generic fuction, but those methods must invoke call-next-method.

update-dependent (metaobject dependee-mixin) dependent &rest reinitargs [progn Method]

This method has unspecified behavior, and returns an unspecified result. This method is specified to ensure that there will be an applicable method whenever the dependents of a redefinable metaobject are updated.

update-dependent

Remarks:

Only one method is specified for this generic function, but implementations are free to have additional methods on specified classes.

See Also:

“The Dependent Update Protocol” reinitialize-instance add-dependent remove-dependent map-dependents

validate-generic-function-class-change Generic Function

Syntax:

validate-generic-function-class-change generic-function prototype-of-new-class [Generic Function]

Arguments:

The generic-function argument is a generic function metaobject. The prototype-of-new-class argument is a generic function metaobject.

Values:

This generic function returns a boolean value.

Purpose:

This generic function is called by :before method change-class (generic-function class) before the class of a generic function metaobject is changed. If this generic function returns false, an error is signalled by :before method change-class (generic-function class). If this generic function returns true, the class change proceeds normally.

Methods:

validate-generic-function-class-change (generic-function generic-function) (prototype-new-class generic-function) [Primary

Method] This method returns false.

validate-generic-function-class-change (generic-function standard-generic-function) (prototype-new-class standard-generic-function)

[Primary Method] This method returns true.

Remarks:

validate-metaclass-change Generic Function

Syntax:

validate-metaclass-change class prototype-of-new-class [Generic Function]

Arguments:

The class argument is a class metaobject. The prototype-of-new-class argument is a class metaobject.

Values:

This generic function returns a boolean value.

Purpose:

This generic function is called by :before method change-class (class class) before the class of a class metaobject is changed. If this generic function returns false, an error is signalled by :before method change-class (class class). If this generic function returns true, the class change proceeds normally.

Methods:

validate-metaclass-change (class class) (prototype-of-new-class class) [Primary Method] This method returns false. validate-metaclass-change (class forward-referenced-class) (prototype-of-new-class class) [Primary Method] This method returns true. validate-metaclass-change (class standard-class) (prototype-of-new-class standard-class) [Primary Method] This method returns true.

Metaobject Protocol 3–123

Draft 11: July 30, 1990 Do Not Distribute

validate-metaclass-change

validate-metaclass-change (class structure-class) (prototype-of-new-class structure-class) [Primary Method] This method returns true.

Remarks:

validate-superclass Generic Function

Syntax:

validate-superclass class superclass [Generic Function]

Arguments:

The class argument is a class metaobject. The superclass argument is a class metaobject.

Values:

This generic function returns true or false.

Purpose:

The generic function validate-superclass 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 whenever the superclasses of a class are changed, to check that each of the proposed new superclasses is valid.

Methods:

validate-superclass (class class) (superclass class) [Primary Method]

This method returns true in three situations.

If the superclass argument is the class named t.

Or if the class of the class argument is eq to the class of the superclass argument.

Or if the two metaclasses are funcallable-standard-class and standard-class, and the superclass has no slots.

In all other cases, this method returns false.

Remarks:

Defining a method on validate-superclass requires detailed knowledge of of the internal protocol followed by each of the two metaclasses. A method on validate-superclass which returns true for two different metaclasses declares that those metaclasses are compatible.

Draft 11: July 30, 1990 Do Not Distribute

validate-superclass

See Also:

“Checking the Validity of A Superclass”