\input macros \drafttrue \def\bookline{\CLOS\ Specification} \def\chapline{Functions in the Programmer Interface} \beginChapter 2.{Common Lisp Object System Specification}% {Functions in the Programmer Interface}{Functions in the Programmer Interface} Authors: Daniel G. Bobrow, Linda G. DeMichiel, Richard P. Gabriel,\hfil\break Sonya E. Keene, Gregor Kiczales, and David A. Moon. Draft Dated: June 15, 1988\hfil\break All Rights Reserved The distribution and publication of this document are not restricted. In order to preserve the integrity of the specification, any publication or distribution must reproduce this document in its entirety, preserve its formatting, and include this title page. For information about obtaining the sources for this document, send an Internet message to common-lisp-object-system-specification-request@sail.stanford.edu. The authors wish to thank Patrick Dussud, Kenneth Kahn, Jim Kempf,\hfil\break Larry Masinter, Mark Stefik, Daniel L. Weinreb, and Jon L White\hfil\break for their contributions to this document. \vskip 2pc At the X3J13 meeting on June 15, 1988, the following motion was adopted: ``The X3J13 Committee hereby accepts chapters 1 and 2 of the Common Lisp Object System, as defined in document 88-002R, for inclusion in the Common Lisp language being specified by this committee. Subsequent changes will be handled through the usual editorial and cleanup processes.'' \endTitlePage \beginSection{Introduction} This chapter describes the functions, macros, special forms, and generic functions provided by the \CLOS\ Programmer Interface. The Programmer Interface comprises the functions and macros that are sufficient for writing most object-oriented programs. This chapter is reference material that requires an understanding of the basic concepts of the Common Lisp Object System. The functions are arranged in alphabetical order for convenient reference. The description of each function, macro, special form, and generic function includes its purpose, its syntax, the semantics of its arguments and returned values, and often an example and cross-references to related functions. The syntax description for a function, macro, or special form describes its parameters. The following is an example of the format for the syntax description of a function: \label Syntax: \Defgen {F} {{\it x\/} {\it y\/} {\opt} {\it z\/} \key {\it k\/}} \noindent This description indicates that the generic function {\bf F} has two required parameters, {\it x\/} and {\it y}. In addition, there is an optional parameter {\it z\/} and a keyword parameter {\it k}. The generic functions described in this chapter are all standard generic functions. They all use standard method combination. The description of a generic function includes descriptions of the methods that are defined on that generic function by the \CLOS. A {\bit method signature\/} is used to describe the parameters and parameter specializers for each method. The following is an example of the format for a method signature: \label Method Signature: \Defmeth {F} {({\it x\/} {\it class}) ({\it y\/} t) \&optional {\it z\/} \&key {\it k\/}} \noindent This signature indicates that this method on the generic function {\bf F} has two required parameters, {\it x\/}, which must be an instance of the class {\it class}, and {\it y}, which can be any object. In addition, there is an optional parameter {\it z\/} and a keyword parameter {\it k}. This signature also indicates that this method on {\bf F} is a primary method and 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. Any implementation of the \CLOS\ is allowed to provide additional methods on the generic functions described in this chapter. \vfill\eject It is useful to categorize the functions and macros according to their role in this standard: \Vskip 2pc! \beginlist \item{\bull} {Tools used for simple object-oriented programming} These tools allow for defining new classes, methods, and generic functions, and for making instances. Some tools used within method bodies are also listed here. Some of the macros listed here have a corresponding function that performs the same task at a lower level of abstraction. {\bf call-next-method}\hfil\break {\bf change-class}\hfil\break {\bf defclass}\hfil\break {\bf defgeneric}\hfil\break {\bf defmethod}\hfil\break {\bf generic-flet}\hfil\break {\bf generic-function}\hfil\break {\bf generic-labels}\hfil\break {\bf initialize-instance}\hfil\break {\bf make-instance}\hfil\break {\bf next-method-p}\hfil\break {\bf slot-boundp}\hfil\break {\bf slot-value}\hfil\break {\bf with-accessors}\hfil\break {\bf with-added-methods}\hfil\break {\bf with-slots} \item{\bull} {Functions underlying the commonly used macros} {\bf add-method}\hfil\break {\bf class-name}\hfil\break {\bf compute-applicable-methods}\hfil\break {\bf ensure-generic-function}\hfil\break {\bf find-class}\hfil\break {\bf find-method}\hfil\break {\bf function-keywords}\hfil\break {\bf make-instances-obsolete}\hfil\break {\bf no-applicable-method}\hfil\break {\bf no-next-method}\hfil\break {\bf reinitialize-instance}\hfil\break {\bf remove-method}\hfil\break {\bf shared-initialize}\hfil\break {\bf slot-exists-p}\hfil\break {\bf slot-makunbound}\hfil\break {\bf slot-missing}\hfil\break {\bf slot-unbound}\hfil\break {\bf update-instance-for-different-class}\hfil\break {\bf update-instance-for-redefined-class} \item{\bull} {Tools for declarative method combination} {\bf call-method}\hfil\break {\bf define-method-combination}\hfil\break {\bf invalid-method-error}\hfil\break {\bf method-combination-error}\hfil\break {\bf method-qualifiers} \item{\bull} {General Common Lisp support tools} {\bf class-of}\hfil\break {\bf describe}\hfil\break {\bf documentation}\hfil\break {\bf print-object}\hfil\break {\bf symbol-macrolet} \endlist \vfill \endSection%{Introduction} \beginSection{Notation} This specification uses an extended Backus Normal Form (BNF) to describe the syntax of the \OS. This section discusses the syntax of BNF expressions. The primary extension used is the following: $$\lbrack\!\lbrack\, O\,\rbrack\!\rbrack$$ An expression of this form will appear whenever a list of elements is to be spliced into a larger structure and the elements can appear in any order. The symbol $O$ represents a description of the syntax of some number of syntactic elements to be spliced; that description must be of the form $$O\sub 1\ \vert\ \ldots\ \vert\ O\sub N$$ \noindent where each $O\sub i$ can be either of the form $S$ or of the form $S{\rm *}$. The expression $\lbrack\!\lbrack O\,\rbrack\!\rbrack$ means that a list of the form $$(O\sub{i\sub 1}\ldots O\sub{i\sub j})\quad 1\leq j$$ \noindent is spliced into the enclosing expression, such that if $n \neq m$ and $1\leq n,m\leq j$, then either $O\sub{i\sub n}\neq O\sub{i\sub m}$ or $O\sub{i\sub n} = O\sub{i\sub m} = Q\sub{k}$, where for some $1\leq k \leq N$, $O\sub{k}$ is of the form $Q\sub{k}{\rm *}$. For example, the expression $$(\hbox{{\tt x}}\ {\lbrack\!\lbrack}\,\hbox{{\tt A}}\ \vert\ \hbox{{\tt B}}{\rm *}\ \vert\ \hbox{{\tt C}}\, {\rbrack\!\rbrack}\ \hbox{{\tt y}})$$ \noindent means that at most one {\tt A}, any number of {\tt B}'s, and at most one {\tt C} can occur in any order. It is a description of any of these: \screen! (x y) (x B A C y) (x A B B B B B C y) (x C B A B B B y) \endscreen! \noindent but not any of these: \screen! (x B B A A C C y) (x C B C y) \endscreen! \noindent In the first case, both {\tt A} and {\tt C} appear too often, and in the second case {\tt C} appears too often. \vfill\eject A simple indirection extension is introduced in order to make this new syntax more readable: $$\downarrow\!O$$ \noindent If $O$ is a non-terminal symbol, the right-hand side of its definition is substituted for the entire expression $\downarrow\negthinspace O$. For example, the following BNF is equivalent to the BNF in the previous example: $$(\hbox{{\tt x}}\ {\lbrack\!\lbrack}\downarrow\!O\, {\rbrack\!\rbrack}\ \hbox{{\tt y}})$$ $$O::= \hbox{{\tt A}}\ \vert\ \hbox{{\tt B}}{\rm *}\ \vert\ \hbox{{\tt C}}$$ \endSection \begincom{add-method}\ftype{Standard Generic Function} \label Purpose: The generic function {\bf add-method} adds a method to a generic function. It destructively modifies the generic function and returns the modified generic function as its result. \label Syntax: \Defgen {add-method} {generic-function method} \label Method Signatures: \Defmeth {add-method} {\vtop{\hbox{({\it generic-function\/} standard-generic-function)} \hbox{({\it method\/} method)}}} \label Arguments: The {\it generic-function\/} argument is a generic function object. The {\it method\/} argument is a method object. The lambda-list of the method function must be congruent with the lambda-list of the generic function, or an error is signaled. \label Values: The modified generic function is returned. The result of {\bf add-method} is {\bf eq} to the {\it generic-function\/} argument. \label Remarks: If the given method agrees with an existing method of the generic function on parameter specializers and qualifiers, the existing method is replaced. See the section ``Agreement on Parameter Specializers and Qualifiers'' for a definition of agreement in this context. If the method object is a method object of another generic function, an error is signaled. \label See Also: ``Agreement on Parameter Specializers and Qualifiers'' {\bf defmethod defgeneric find-method remove-method} \endcom \begincom{call-method}\ftype{Macro} \label Purpose: The macro {\bf call-method} is used in method combination. It hides the implementation-dependent details of how methods are called. The macro {\bf call-method} has lexical scope and can only be used within an effective method form. The macro {\bf call-method} invokes the specified method, supplying it with arguments and with definitions for {\bf call-next-method} and for {\bf next-method-p}. The arguments are the arguments that were supplied to the effective method form containing the invocation of {\bf call-method}. The definitions of {\bf call-next-method} and {\bf next-method-p} rely on the list of method objects given as the second argument to {\bf call-method}. The {\bf call-next-method} function available to the method that is the first subform will call the first method in the list that is the second subform. The {\bf call-next-method} function available in that method, in turn, will call the second method in the list that is the second subform, and so on, until the list of next methods is exhausted. \label Syntax: \Defmac {call-method} {method next-method-list} \label Arguments: The {\it method\/} argument is a method object; the {\it next-method-list\/} argument is a list of method objects. A list whose first element is the symbol {\bf make-method} and whose second element is a Lisp form can be used instead of a method object as the first subform of {\bf call-method} or as an element of the second subform of {\bf call-method}. Such a list specifies a method object whose method function has a body that is the given form. \label Values: The result of {\bf call-method} is the value or values returned by the method invocation. \label See Also: {\bf call-next-method} {\bf define-method-combination} {\bf next-method-p} \endcom \begincom{call-next-method}\ftype{Function} \label Purpose: The function {\bf call-next-method} can be used within the body of a method defined by a method-defining form to call the next method. The function {\bf call-next-method} returns the value or values returned by the method it calls. If there is no next method, the generic function {\bf no-next-method} is called. The type of method combination used determines which methods can invoke {\bf call-next-method}. The standard method combination type allows {\bf call-next-method} to be used within primary methods and {\bf :around} methods. The standard method combination type defines the next method as follows: \beginlist \item{\bull} If {\bf call-next-method} is used in an {\bf :around} method, the next method is the next most specific {\bf :around} method, if one is applicable. \item{\bull} If there are no {\bf :around} methods at all or if {\bf call-next-method} is called by the least specific {\bf :around} method, other methods are called as follows: \itemitem{--} All the {\bf :before} methods are called, in most-specific-first order. The function {\bf call-next-method} cannot be used in {\bf :before} methods. \itemitem{--} The most specific primary method is called. Inside the body of a primary method, {\bf call-next-method} may be used to pass control to the next most specific primary method. The generic function {\bf no-next-method} is called if {\bf call-next-method} is used and there are no more primary methods. \itemitem{--} All the {\bf :after} methods are called in most-specific-last order. The function {\bf call-next-method} cannot be used in {\bf :after} methods. \endlist For further discussion of {\bf call-next-method}, see the sections ``Standard Method Combination'' and ``Built-in Method Combination Types.'' \label Syntax: \Defun {call-next-method} {{\rest} args} \label Arguments: When {\bf call-next-method} is called with no arguments, it passes the current method's original arguments to the next method. Neither argument defaulting, nor using {\bf setq}, nor rebinding variables with the same names as parameters of the method affects the values {\bf call-next-method} passes to the method it calls. \vfill\eject When {\bf call-next-method} is called with arguments, the next method is called with those arguments. When providing arguments to {\bf call-next-method}, the following rule must be satisfied or an error is signaled: The ordered set of methods applicable for a changed set of arguments for {\bf call-next-method} must be the same as the ordered set of applicable methods for the original arguments to the generic function. Optimizations of the error checking are possible, but they must not change the semantics of {\bf call-next-method}. If {\bf call-next-method} is called with arguments but omits optional arguments, the next method called defaults those arguments. \label Values: The function {\bf call-next-method} returns the value or values returned by the method it calls. \label Remarks: Further computation is possible after {\bf call-next-method} returns. The function {\bf call-next-method} has lexical scope and indefinite extent. For generic functions using a type of method combination defined by the short form of {\bf define-method-combination}, {\bf call-next-method} can be used in {\bf :around} methods only. The function {\bf next-method-p} can be used to test whether there is a next method. If {\bf call-next-method} is used in methods that do not support it, an error is signaled. \label See Also: ``Method Selection and Combination'' ``Standard Method Combination'' ``Built-in Method Combination Types'' {\bf define-method-combination} {\bf next-method-p} {\bf no-next-method} \endcom \begincom{change-class}\ftype{Standard Generic Function} \label Purpose: The generic function {\bf change-class} changes the class of an instance to a new class. It destructively modifies and returns the instance. If in the old class there is any slot of the same name as a local slot in the new class, the value of that slot is retained. This means that if the slot has a value, the value returned by {\bf slot-value} after {\bf change-class} is invoked is {\bf eql} to the value returned by {\bf slot-value} before {\bf change-class} is invoked. Similarly, if the slot was unbound, it remains unbound. The other slots are initialized as described in the section ``Changing the Class of an Instance.'' \label Syntax: \Defgen {change-class} {instance new-class} \label Method Signatures: \Defmeth {change-class} {({\it instance\/} standard-object) ({\it new-class\/} standard-class)} \Defmeth {change-class} {({\it instance\/} t) ({\it new-class\/} symbol)} \label Arguments: The {\it instance\/} argument is a Lisp object. The {\it new-class\/} argument is a class object or a symbol that names a class. If the second of the above methods is selected, that method invokes {\bf change-class} on {\it instance\/} and {\tt (find-class {\it new-class\/})}. \label Values: The modified instance is returned. The result of {\bf change-class} is {\bf eq} to the {\it instance} argument. \label Examples: \screen! (defclass position () ()) (defclass x-y-position (position) ((x :initform 0 :initarg :x) (y :initform 0 :initarg :y))) \endscreen! \vfill\eject \screen! (defclass rho-theta-position (position) ((rho :initform 0) (theta :initform 0))) (defmethod update-instance-for-different-class :before ((old x-y-position) (new rho-theta-position) &key) ;; Copy the position information from old to new to make new ;; be a rho-theta-position at the same position as old. (let ((x (slot-value old 'x)) (y (slot-value old 'y))) (setf (slot-value new 'rho) (sqrt (+ (* x x) (* y y))) (slot-value new 'theta) (atan y x)))) ;;; At this point an instance of the class x-y-position can be ;;; changed to be an instance of the class rho-theta-position using ;;; change-class: (setq p1 (make-instance 'x-y-position :x 2 :y 0)) (change-class p1 'rho-theta-position) ;;; The result is that the instance bound to p1 is now an instance of ;;; the class rho-theta-position. The update-instance-for-different-class ;;; method performed the initialization of the rho and theta slots based ;;; on the value of the x and y slots, which were maintained by ;;; the old instance. \endscreen! \label Remarks: After completing all other actions, {\bf change-class} invokes the generic function {\bf update-instance-for-different-class}. The generic function {\bf update-instance-for-different-class} can be used to assign values to slots in the transformed instance. The generic function {\bf change-class} has several semantic difficulties. First, it performs a destructive operation that can be invoked within a method on an instance that was used to select that method. When multiple methods are involved because methods are being combined, the methods currently executing or about to be executed may no longer be applicable. Second, some implementations might use compiler optimizations of slot access, and when the class of an instance is changed the assumptions the compiler made might be violated. This implies that a programmer must not use {\bf change-class} inside a method if any methods for that generic function access any slots, or the results are undefined. \vfill\eject \label See Also: ``Changing the Class of an Instance'' {\bf update-instance-for-different-class} \endcom \begincom{class-name, (setf class-name)}\ftype{Standard Generic Function} \label Purpose: The generic function {\bf class-name} takes a class object and returns its name. The generic function {\bf (setf class-name)} takes a class object and sets its name. \label Syntax: \Defgen {class-name} {class} \Defgen {(setf class-name)} {new-value class} \label Method Signatures: \Defmeth {class-name} {({\it class\/} class)} \Defmeth {(setf class-name)} {{\it new-value\/} ({\it class\/} class)} \label Arguments: The {\it class\/} argument is a class object. The {\it new-value\/} argument is any object. \label Values: The name of the given class is returned. \label Remarks: The name of an anonymous class is {\bf nil}. If $S$ is a symbol such that $S =${\tt (class-name $C$)} and $C =${\tt (find-class $S$)}, then $S$ is the proper name of $C$. For further discussion, see the section ``Classes.'' \label See Also: ``Classes'' {\bf find-class} \endcom \begincom{class-of}\ftype{Function} \label Purpose: The function {\bf class-of} returns the class of which the given object is an instance. \label Syntax: \Defun {class-of} {object} \label Arguments: The argument to {\bf class-of} may be any Common Lisp object. \label Values: The function {\bf class-of} returns the class of which the argument is an instance. \endcom \begincom{compute-applicable-methods}\ftype{Function} \label Purpose: Given a generic function and a set of arguments, the function {\bf compute-applicable-methods} returns the set of methods that are applicable for those arguments. The methods are sorted according to precedence order. See the section ``Method Selection and Combination.'' \label Syntax: \Defun {compute-applicable-methods} {generic-function function-arguments} \label Arguments: The {\it generic-function\/} argument is a generic function object. The {\it function-arguments\/} argument is a list of the arguments to that generic function. \label Values: The result is a list of the applicable methods in order of precedence. \label See Also: ``Method Selection and Combination'' \endcom \begincom{defclass}\ftype{Macro} \label Purpose: The macro {\bf defclass} defines a new named class. It returns the new class object as its result. The syntax of {\bf defclass} provides options for specifying initialization arguments for slots, for specifying default initialization values for slots, and for requesting that methods on specified generic functions be automatically generated for reading and writing the values of slots. No reader or writer functions are defined by default; their generation must be explicitly requested. Defining a new class also causes a type of the same name to be defined. The predicate {\tt (typep {\it object class-name\/})} returns true if the class of the given object is {\it class-name\/} itself or a subclass of the class {\it class-name}. A class object can be used as a type specifier. Thus {\tt (typep {\it object class\/})} returns true if the class of the {\it object\/} is {\it class\/} itself or a subclass of {\it class}. \eject \label Syntax: \cboxfig{ \leftskip 2pc \cleartabs\settabs\+\hskip\leftskip&\cr \+&{\bf defclass} {\it class-name} \paren{\star{\curly{superclass-name}}} \paren{\star{\curly{slot-specifier}}}% $\lbrack\!\lbrack\downarrow\!\hbox{{\it class-option}}\,\rbrack\!\rbrack$\cr \Vskip 1pc! \+&{\it class-name\/}::$=$ {\it symbol\/}\cr \Vskip 1pc! \+&{\it superclass-name\/}::$=$ {\it symbol\/}\cr \Vskip 1pc! \+&\cleartabs{\it slot-specifier\/}::$=$ &{\it slot-name\/} $\vert$ ({\it slot-name\/} $\lbrack\!\lbrack\downarrow\!\hbox{{\it slot-option}}\,\rbrack\!\rbrack$)\cr \Vskip 1pc! \+&{\it slot-name\/}::$=$ {\it symbol\/}\cr \Vskip 1pc! \+&\cleartabs{\it slot-option\/}::$=$ &\star{\curly{{\tt :reader} {\it reader-function-name\/}}} $\vert$ \cr \+&&\star{\curly{{\tt :writer} {\it writer-function-name\/}}} $\vert$ \cr \+&&\star{\curly{{\tt :accessor} {\it reader-function-name\/}}} $\vert$ \cr \+&&\curly{{\tt :allocation} {\it allocation-type\/}} $\vert$ \cr \+&&\star{\curly{{\tt :initarg} {\it initarg-name\/}}} $\vert$ \cr \+&&\curly{{\tt :initform} {\it form\/}} $\vert$ \cr \+&&\curly{{\tt :type} {\it type-specifier\/}} $\vert$ \cr \+&&\curly{{\tt :documentation} {\it string\/}} \cr \Vskip 1pc! \+&{\it reader-function-name\/}::$=$ {\it symbol\/}\cr \Vskip 1pc! \+&{\it writer-function-name\/}::$=$ {\it function-specifier\/}\cr \Vskip 1pc! \+&{\it function-specifier\/}::$=$ \curly{{\it symbol\/} $\vert$ {\tt (setf {\it symbol\/})}}\cr \Vskip 1pc! \+&{\it initarg-name\/}::$=$ {\it symbol\/}\cr \Vskip 1pc! \+&{\it allocation-type\/}::$=$ {\tt :instance $\vert$ :class}\cr \Vskip 1pc! \+&\cleartabs{\it class-option\/}::$=$ &({\tt :default-initargs} {\it initarg-list\/}) $\vert$ \cr \+&&({\tt :documentation} {\it string\/}) $\vert$ \cr \+&&({\tt :metaclass} {\it class-name\/}) \cr \Vskip 1pc! \+&{\it initarg-list\/}::$=$ \star{\curly{\it initarg-name default-initial-value-form}} \cr } \caption{Syntax for defclass} \endfig \vfill\eject \label Arguments: The {\it class-name\/} argument is a non-{\bf nil} symbol. It becomes the proper name of the new class. If a class with the same proper name already exists and that class is an instance of {\bf standard-class}, and if the {\bf defclass} form for the definition of the new class specifies a class of class {\bf standard-class}, the definition of the existing class is replaced. Each {\it superclass-name\/} argument is a non-{\bf nil} symbol that specifies a direct superclass of the new class. The new class will inherit slots and methods from each of its direct superclasses, from their direct superclasses, and so on. See the section ``Inheritance'' for a discussion of how slots and methods are inherited. Each {\it slot-specifier\/} argument is the name of the slot or a list consisting of the slot name followed by zero or more slot options. The {\it slot-name\/} argument is a symbol that is syntactically valid for use as a Common Lisp variable name. If there are any duplicate slot names, an error is signaled. The following slot options are available: \beginlist \item{\bull} The {\bf :reader} slot option specifies that an unqualified method is to be defined on the generic function named {\it reader-function-name\/} to read the value of the given slot. The {\it reader-function-name\/} argument is a non-{\bf nil} symbol. The {\bf :reader} slot option may be specified more than once for a given slot. \item{\bull} The {\bf :writer} slot option specifies that an unqualified method is to be defined on the generic function named {\it writer-function-name\/} to write the value of the slot. The {\it writer-function-name\/} argument is a function specifier. The {\bf :writer} slot option may be specified more than once for a given slot. \item{\bull} The {\bf :accessor} slot option specifies that an unqualified method is to be defined on the generic function named {\it reader-function-name\/} to read the value of the given slot and that an unqualified method is to be defined on the generic function named {\tt (setf {\it reader-function-name\/})} to be used with {\bf setf} to modify the value of the slot. The {\it reader-function-name\/} argument is a non-{\bf nil} symbol. The {\bf :accessor} slot option may be specified more than once for a given slot. \item{\bull} The {\bf :allocation} slot option is used to specify where storage is to be allocated for the given slot. Storage for a slot may be located in each instance or in the class object itself. The value of the {\it allocation-type\/} argument can be either the keyword {\bf :instance} or the keyword {\bf :class}. The {\bf :allocation} slot option may be specified once at most for a given slot. If the {\bf :allocation} slot option is not specified, the effect is the same as specifying {\bf :allocation :instance}. \itemitem{--} If {\it allocation-type\/} is {\bf :instance}, a local slot of the given name is allocated in each instance of the class. \itemitem{--} If {\it allocation-type\/} is {\bf :class}, a shared slot of the given name is allocated in the class object created by this {\bf defclass} form. The value of the slot is shared by all instances of the class. If a class $C\sub1$ defines such a shared slot, any subclass $C\sub2$ of $C\sub1$ will share this single slot unless the {\bf defclass} form for $C\sub2$ specifies a slot of the same name or there is a superclass of $C\sub2$ that precedes $C\sub1$ in the class precedence list of $C\sub2$ and that defines a slot of the same name. \item{\bull} The {\bf :initform} slot option is used to provide a default initial value form to be used in the initialization of the slot. The {\bf :initform} slot option may be specified once at most for a given slot. This form is evaluated every time it is used to initialize the slot. The lexical environment in which this form is evaluated is the lexical environment in which the {\bf defclass} form was evaluated. Note that the lexical environment refers both to variables and to functions. For local slots, the dynamic environment is the dynamic environment in which {\bf make-instance} was called; for shared slots, the dynamic environment is the dynamic environment in which the {\bf defclass} form was evaluated. See the section ``Object Creation and Initialization.'' No implementation is permitted to extend the syntax of {\bf defclass} to allow {\tt ({\it slot-name form\/})} as an abbreviation for {\tt ({\it slot-name\/} :initform {\it form\/})}. \item{\bull} The {\bf :initarg} slot option declares an initialization argument named {\it initarg-name\/} and specifies that this initialization argument initializes the given slot. If the initialization argument has a value in the call to {\bf initialize-instance}, the value will be stored into the given slot, and the slot's {\bf :initform} slot option, if any, is not evaluated. If none of the initialization arguments specified for a given slot has a value, the slot is initialized according to the {\bf :initform} slot option, if specified. The {\bf :initarg} slot option can be specified more than once for a given slot. The {\it initarg-name\/} argument can be any symbol. \item{\bull} The {\bf :type} slot option specifies that the contents of the slot will always be of the specified data type. It effectively declares the result type of the reader generic function when applied to an object of this class. The result of attempting to store in a slot a value that does not satisfy the type of the slot is undefined. The {\bf :type} slot option may be specified once at most for a given slot. The {\bf :type} slot option is further discussed in the section ``Inheritance of Slots and Slot Options.'' \item{\bull} The {\bf :documentation} slot option provides a documentation string for the slot. \endlist Each class option is an option that refers to the class as a whole or to all class slots. The following class options are available: \beginlist \item{\bull} The {\bf :default-initargs} class option is followed by a list of alternating initialization argument names and default initial value forms. If any of these initialization arguments does not appear in the initialization argument list supplied to {\bf make-instance}, the corresponding default initial value form is evaluated, and the initialization argument name and the form's value are added to the end of the initialization argument list before the instance is created (see the section ``Object Creation and Initialization''). The default initial value form is evaluated each time it is used. The lexical environment in which this form is evaluated is the lexical environment in which the {\bf defclass} form was evaluated. The dynamic environment is the dynamic environment in which {\bf make-instance} was called. If an initialization argument name appears more than once in a {\bf :default-initargs} class option, an error is signaled. The {\bf :default-initargs} class option may be specified at most once. \item{\bull} The {\bf :documentation} class option causes a documentation string to be attached to the class name. The documentation type for this string is {\bf type}. The form {\tt (documentation {\it class-name\/} 'type)} may be used to retrieve the documentation string. The {\bf :documentation} class option may be specified once at most. \item{\bull} The {\bf :metaclass} class option is used to specify that instances of the class being defined are to have a different metaclass than the default provided by the system (the class {\bf standard-class}). The {\it class-name} argument is the name of the desired metaclass. The {\bf :metaclass} class option may be specified once at most. \endlist \label Values: The new class object is returned as the result. \label Remarks: If a class with the same proper name already exists and that class is an instance of {\bf standard-class}, and if the {\bf defclass} form for the definition of the new class specifies a class of class {\bf standard-class}, the existing class is redefined, and instances of it (and its subclasses) are updated to the new definition at the time that they are next accessed. For details, see ``Redefining Classes.'' Note the following rules of {\bf defclass} for standard classes: \beginlist \item{\bull} It is not required that the superclasses of a class be defined before the {\bf defclass} form for that class is evaluated. \item{\bull} All the superclasses of a class must be defined before an instance of the class can be made. \item{\bull} A class must be defined before it can be used as a parameter specializer in a {\bf defmethod} form. \endlist The \OS\ may be extended to cover situations where these rules are not obeyed. Some slot options are inherited by a class from its superclasses, and some can be shadowed or altered by providing a local slot description. No class options except {\bf :default-initargs} are inherited. For a detailed description of how slots and slot options are inherited, see the section ``Inheritance of Slots and Slot Options.'' The options to {\bf defclass} can be extended. It is required that all implementations signal an error if they observe a class option or a slot option that is not implemented locally. It is valid to specify more than one reader, writer, accessor, or initialization argument for a slot. No other slot option may appear more than once in a single slot description, or an error is signaled. If no reader, writer, or accessor is specified for a slot, the slot can only be accessed by the function {\bf slot-value}. \vfill\eject \label See Also: ``Classes'' ``Inheritance'' ``Redefining Classes'' ``Determining the Class Precedence List'' ``Object Creation and Initialization'' {\bf slot-value make-instance initialize-instance} \endcom \begincom{defgeneric}\ftype{Macro} \label Purpose: The macro {\bf defgeneric} is used to define a generic function or to specify options and declarations that pertain to a generic function as a whole. If {\tt (fboundp {\it function-specifier\/})} is {\bf nil}, a new generic function is created. If {\tt (symbol-function {\it function-specifier\/})} is a generic function, that generic function is modified. If {\it function-specifier\/} names a non-generic function, a macro, or a special form, an error is signaled. Each {\it method-description\/} defines a method on the generic function. The lambda-list of each method must be congruent with the lambda-list specified by the {\it lambda-list\/} option. If this condition does not hold, an error is signaled. See the section ``Congruent Lambda-Lists for All Methods of a Generic Function'' for a definition of congruence in this context. The macro {\bf defgeneric} returns the generic function object as its result. \label Syntax: \Defmac {defgeneric} {function-specifier lambda-list\/ $\lbrack\!\lbrack\downarrow\!$ option $\vert$ \star{method-description} $\rbrack\!\rbrack$} {\it function-specifier\/}::$=$ \curly{{\it symbol\/} $\vert$ {\tt (setf {\it symbol\/})}} \Vskip 1pc! \settabs\+\hskip\leftskip&\cr \+&{\it lambda-list\/}::$=$ (&\star{\curly{var}} \cr \+&&\ttbrac{{\opt} \star{\curly{var $\vert$ {\rm (}var\/{\rm )}}}} \cr \+&&\ttbrac{{\tt\&rest} {\it var\/}} \cr \+&&{\tt [}{\key{}}&\star{\curly{var $\vert$ {\rm (}\curly{var $\vert$ {\rm (}keyword var\/{\rm )}}{\rm )}}}\cr \+&&&\brac{\tt\&allow-other-keys} {\tt ]} {\rm )} \cr \Vskip 1pc! {\it option\/}::$=$ {\tt\vtop{\hbox{(:argument-precedence-order \plus{\curly{parameter-name}}) $\vert$} \hbox{(declare \plus{\curly{declaration\/}}) $\vert$} \hbox{(:documentation {\it string\/}) $\vert$} \hbox{(:method-combination {\it symbol\/} \star{\curly{arg\/}}) $\vert$} \hbox{(:generic-function-class {\it class-name\/}) $\vert$} \hbox{(:method-class {\it class-name\/})}}} \Vskip 1pc! {\it method-description\/}::$=$ {\tt (:method} \vtop{\hbox{\it \star{\curly{method-qualifier\/}} specialized-lambda-list\/} \hbox{\star{\curly{declaration\/ $\vert$ documentation\/}} \star{\curly{form\/}}{\tt )}}} \Vskip1pc!\null {\it method-qualifier\/}::$=$ {\it non-nil-atom} \vfill\eject %\Vskip1pc!\null \settabs\+\hskip\leftskip&\cr \+&{\it specialized-lambda-list\/}::$=$ (&\star{\curly{var $\vert$ {\rm (}var parameter-specializer-name\/{\rm )}}} \cr \+&&\ttbrac{{\opt} \star{\curly{var $\vert$ {\rm (}var \ttbrac{initform {\brac{supplied-p-parameter}} }{\rm )}}}} \cr \+&&\ttbrac{{\tt\&rest} {\it var\/}} \cr \+&&{\tt [}{\key{}}&\star{\curly{var $\vert$ {\rm (}\curly{var $\vert$ {\rm (}keyword var{\rm )}} \ttbrac{initform \brac{supplied-p-parameter} }{\rm )}}}\cr \+&&&\brac{\tt\&allow-other-keys} {\tt ]} \cr \+&&\ttbrac{{\tt\&aux} \star{\curly{var $\vert$ {\rm (}var \brac{initform} {\rm )}}}} {\rm )} \cr \settabs\+\hskip\leftskip&\cr \Vskip1pc!\null \+&{\it parameter-specializer-name\/}::$=$ {\it symbol} $\vert$ {\rm (}{\tt eql} {\it eql-specializer-form\/}{\rm )}\cr \Vskip 1pc! \label Arguments: The {\it function-specifier} argument is a non-{\bf nil} symbol or a list of the form {\tt (setf {\it symbol\/})}. The {\it lambda-list\/} argument is an ordinary function lambda-list with these exceptions: \beginlist \item{\bull} The use of {\bf \&aux} is not allowed. \item{\bull} Optional and keyword arguments may not have default initial value forms nor use supplied-p parameters. The generic function passes to the method all the argument values passed to it, and only those; default values are not supported. Note that optional and keyword arguments in method definitions, however, can have default initial value forms and can use supplied-p parameters. \endlist The following options are provided. A given option may occur only once, or an error is signaled. \beginlist \item{\bull} The {\bf :argument-precedence-order} option is used to specify the order in which the required arguments in a call to the generic function are tested for specificity when selecting a particular method. Each required argument, as specified in the {\it lambda-list\/} argument, must be included exactly once as a {\it parameter-name} so that the full and unambiguous precedence order is supplied. If this condition is not met, an error is signaled. \item{\bull} The {\bf declare} option is used to specify declarations that pertain to the generic function. The following standard Common Lisp declaration is allowed: \itemitem{--} An {\bf optimize} declaration specifies whether method selection should be optimized for speed or space, but it has no effect on methods. To control how a method is optimized, an {\bf optimize} declaration must be placed directly in the {\bf defmethod} form or method description. The optimization qualities {\bf speed} and {\bf space} are the only qualities this standard requires, but an implementation can extend the \CLOS\ to recognize other qualities. A simple implementation that has only one method selection technique and ignores the {\bf optimize} declaration is valid. \item{} The {\bf special}, {\bf ftype}, {\bf function}, {\bf inline}, {\bf notinline}, and {\bf declaration} declarations are not permitted. Individual implementations can extend the {\bf declare} option to support additional declarations. If an implementation notices a declaration that it does not support and that has not been proclaimed as a non-standard declaration name in a {\bf declaration} proclamation, it should issue a warning. \item{\bull} The {\bf :documentation} argument associates a documentation string with the generic function. The documentation type for this string is {\bf function}. The form {\tt (documentation {\it function-specifier\/} 'function)} may be used to retrieve this string. \item{\bull} The {\bf :generic-function-class} option may be used to specify that the generic function is to have a different class than the default provided by the system (the class {\bf standard-generic-function}). The {\it class-name\/} argument is the name of a class that can be the class of a generic function. If {\it function-specifier\/} specifies an existing generic function that has a different value for the {\bf :generic-function-class} argument and the new generic function class is compatible with the old, {\bf change-class} is called to change the class of the generic function; otherwise an error is signaled. \item{\bull} The {\bf :method-class} option is used to specify that all methods on this generic function are to have a different class from the default provided by the system (the class {\bf standard-method}). The {\it class-name\/} argument is the name of a class that is capable of being the class of a method. \item{\bull} The {\bf :method-combination} option is followed by a symbol that names a type of method combination. The arguments (if any) that follow that symbol depend on the type of method combination. Note that the standard method combination type does not support any arguments. However, all types of method combination defined by the short form of {\bf define-method-combination} accept an optional argument named {\it order\/}, defaulting to {\bf :most-specific-first}, where a value of {\bf :most-specific-last} reverses the order of the primary methods without affecting the order of the auxiliary methods. \endlist The {\it method-description\/} arguments define methods that will be associated with the generic function. The {\it method-qualifier} and {\it specialized-lambda-list} arguments in a method description are the same as for {\bf defmethod}. The {\it form\/} arguments specify the method body. The body of the method is enclosed in an implicit block. If {\it function-specifier\/} is a symbol, this block bears the same name as the generic function. If {\it function-specifier\/} is a list of the form {\tt (setf {\it symbol\/})}, the name of the block is {\it symbol}. \label Values: The generic function object is returned as the result. \label Remarks: The effect of the {\bf defgeneric} macro is as if the following three steps were performed: first, methods defined by previous {\bf defgeneric} forms are removed; second, {\bf ensure-generic-function} is called; and finally, methods specified by the current {\bf defgeneric} form are added to the generic function. If no method descriptions are specified and a generic function of the same name does not already exist, a generic function with no methods is created. \vfill\eject The {\it lambda-list\/} argument of {\bf defgeneric} specifies the shape of lambda-lists for the methods on this generic function. All methods on the resulting generic function must have lambda-lists that are congruent with this shape. If a {\bf defgeneric} form is evaluated and some methods for that generic function have lambda-lists that are not congruent with that given in the {\bf defgeneric} form, an error is signaled. For further details on method congruence, see ``Congruent Lambda-Lists for All Methods of a Generic Function'' Implementations can extend {\bf defgeneric} to include other options. It is required that an implementation signal an error if it observes an option that is not implemented locally. \label See Also: ``Congruent Lambda-Lists for All Methods of a Generic Function'' {\bf defmethod ensure-generic-function generic-function} \endcom \begincom{define-method-combination}\ftype{Macro} \label Purpose: The macro {\bf define-method-combination} is used to define new types of method combination. There are two forms of {\bf define-method-combination}. The short form is a simple facility for the cases that are expected to be most commonly needed. The long form is more powerful but more verbose. It resembles {\bf defmacro} in that the body is an expression, usually using backquote, that computes a Lisp form. Thus arbitrary control structures can be implemented. The long form also allows arbitrary processing of method qualifiers. \label Syntax: \Defmac {define-method-combination} {name $\lbrack\!\lbrack\downarrow\!$ short-form-option $\rbrack\!\rbrack$} \Vskip 1pc! {\it short-form-option\/}::$=$ {\tt\vtop{\hbox{:documentation {\it string\/} $\vert$} \hbox{:identity-with-one-argument {\it boolean\/} $\vert$} \hbox{:operator {\it operator\/} $\vert$}}} \Vskip1pc! \Defmac {define-method-combination} {\vtop{\hbox{name lambda-list } \hbox{\paren{\star{\curly{method-group-specifier}}} } \hbox{\brac{\paren{{\tt :arguments .} {\it lambda-list }}}} \hbox{\brac{\paren{{\tt :generic-function} {\it generic-function-symbol }}}} \hbox{\star{\curly {declaration $\vert$ doc-string}}} \hbox{\star{\curly{form}}}}} \vbox {\halign {\hskip \leftskip#\hfil&#\hfil\cr {\it method-group-specifier\/}::$=$ (&{\it variable\/} \curly{\plus{\curly{qualifier-pattern}} $\vert$ predicate}\cr & $\lbrack\!\lbrack\downarrow\!$ {\it long-form-option\/} $\rbrack\!\rbrack$)\cr}} \Vskip 1pc! {\it long-form-option\/}::$=$ {\tt\vtop{\hbox{:description {\it format-string\/} $\vert$} \hbox{:order {\it order\/} $\vert$} \hbox{:required {\it boolean\/}}}} \Vskip1pc!\null \label Arguments: In both the short and long forms, {\it name\/} is a symbol. By convention, non-keyword, non-{\bf nil} symbols are usually used. \vfill\eject \label Arguments of the Short Form: The short form syntax of {\bf define-method-combination} is recognized when the second subform is a non-{\bf nil} symbol or is not present. When the short form is used, {\it name\/} is defined as a type of method combination that produces a Lisp form {\tt ({\it operator method-call method-call $\ldots$ })}. The {\it operator\/} is a symbol that can be the name of a function, macro, or special form. The {\it operator\/} can be specified by a keyword option; it defaults to {\it name}. Keyword options for the short form are the following: \beginlist \item{\bull} The {\bf :documentation} option is used to document the method-combination type. \item{\bull} The {\bf :identity-with-one-argument} option enables an optimization when {\it boolean\/} is true (the default is false). If there is exactly one applicable method and it is a primary method, that method serves as the effective method and {\it operator\/} is not called. This optimization avoids the need to create a new effective method and avoids the overhead of a function call. This option is designed to be used with operators such as {\bf progn}, {\bf and}, {\bf $+$}, and {\bf max}. \item{\bull} The {\bf :operator} option specifies the name of the operator. The {\it operator\/} argument is a symbol that can be the name of a function, macro, or special form. By convention, {\it name\/} and {\it operator\/} are often the same symbol. This is the default, but it is not required. \endlist None of the subforms is evaluated. These types of method combination require exactly one qualifier per method. An error is signaled if there are applicable methods with no qualifiers or with qualifiers that are not supported by the method combination type. A method combination procedure defined in this way recognizes two roles for methods. A method whose one qualifier is the symbol naming this type of method combination is defined to be a primary method. At least one primary method must be applicable or an error is signaled. A method with {\bf :around} as its one qualifier is an auxiliary method that behaves the same as a {\bf :around} method in standard method combination. The function {\bf call-next-method} can only be used in {\bf :around} methods; it cannot be used in primary methods defined by the short form of the {\bf define-method-combination} macro. A method combination procedure defined in this way accepts an optional argument named {\it order}, which defaults to {\bf :most-specific-first}. A value of {\bf :most-specific-last} reverses the order of the primary methods without affecting the order of the auxiliary methods. The short form automatically includes error checking and support for {\bf :around} methods. For a discussion of built-in method combination types, see the section ``Built-in Method Combination Types.'' \vfill\eject \label Arguments of the Long Form: The long form syntax of {\bf define-method-combination} is recognized when the second subform is a list. The {\it lambda-list\/} argument is an ordinary lambda-list. It receives any arguments provided after the name of the method combination type in the {\bf :method-combination} option to {\bf defgeneric}. A list of method group specifiers follows. Each specifier selects a subset of the applicable methods to play a particular role, either by matching their qualifiers against some patterns or by testing their qualifiers with a predicate. These method group specifiers define all method qualifiers that can be used with this type of method combination. If an applicable method does not fall into any method group, the system signals the error that the method is invalid for the kind of method combination in use. Each method group specifier names a variable. During the execution of the forms in the body of {\bf define-method-combination}, this variable is bound to a list of the methods in the method group. The methods in this list occur in most-specific-first order. A qualifier pattern is a list or the symbol {\bf *}. A method matches a qualifier pattern if the method's list of qualifiers is {\bf equal} to the qualifier pattern (except that the symbol {\bf *} in a qualifier pattern matches anything). Thus a qualifier pattern can be one of the following: the empty list {\bf ()}, which matches unqualified methods; the symbol {\bf *}, which matches all methods; a true list, which matches methods with the same number of qualifiers as the length of the list when each qualifier matches the corresponding list element; or a dotted list that ends in the symbol {\bf *} (the {\bf *} matches any number of additional qualifiers). Each applicable method is tested against the qualifier patterns and predicates in left-to-right order. As soon as a qualifier pattern matches or a predicate returns true, the method becomes a member of the corresponding method group and no further tests are made. Thus if a method could be a member of more than one method group, it joins only the first such group. If a method group has more than one qualifier pattern, a method need only satisfy one of the qualifier patterns to be a member of the group. The name of a predicate function can appear instead of qualifier patterns in a method group specifier. The predicate is called for each method that has not been assigned to an earlier method group; it is called with one argument, the method's qualifier list. The predicate should return true if the method is to be a member of the method group. A predicate can be distinguished from a qualifier pattern because it is a symbol other than {\bf nil} or {\bf *}. If there is an applicable method whose qualifiers are not valid for the method combination type, the function {\bf invalid-method-error} is called. Method group specifiers can have keyword options following the qualifier patterns or predicate. Keyword options can be distinguished from additional qualifier patterns because they are neither lists nor the symbol {\bf *}. The keyword options are as follows: \beginlist \item{\bull} The {\bf :description} option is used to provide a description of the role of methods in the method group. Programming environment tools use {\tt (apply \#'format stream {\it format-string\/} (method-qualifiers {\it method\/}))} to print this description, which is expected to be concise. This keyword option allows the description of a method qualifier to be defined in the same module that defines the meaning of the method qualifier. In most cases, {\it format-string\/} will not contain any format directives, but they are available for generality. If {\bf :description} is not specified, a default description is generated based on the variable name and the qualifier patterns and on whether this method group includes the unqualified methods. The argument {\it format-string\/} is not evaluated. \item{\bull} The {\bf :order} option specifies the order of methods. The {\it order\/} argument is a form that evaluates to {\bf :most-specific-first} or {\bf :most-specific-last}. If it evaluates to any other value, an error is signaled. This keyword option is a convenience and does not add any expressive power. If {\bf :order} is not specified, it defaults to {\bf :most-specific-first}. \item{\bull} The {\bf :required} option specifies whether at least one method in this method group is required. If the {\it boolean\/} argument is non-{\bf nil} and the method group is empty (that is, no applicable methods match the qualifier patterns or satisfy the predicate), an error is signaled. This keyword option is a convenience and does not add any expressive power. If {\bf :required} is not specified, it defaults to {\bf nil}. The {\it boolean\/} argument is not evaluated. \endlist The use of method group specifiers provides a convenient syntax to select methods, to divide them among the possible roles, and to perform the necessary error checking. It is possible to perform further filtering of methods in the body forms by using normal list-processing operations and the functions {\bf method-qualifiers} and {\bf invalid-method-error}. It is permissible to use {\bf setq} on the variables named in the method group specifiers and to bind additional variables. It is also possible to bypass the method group specifier mechanism and do everything in the body forms. This is accomplished by writing a single method group with {\bf *} as its only qualifier pattern; the variable is then bound to a list of all of the applicable methods, in most-specific-first order. The body {\it forms\/} compute and return the Lisp form that specifies how the methods are combined, that is, the effective method. The effective method uses the macro {\bf call-method}. This macro has lexical scope and is available only in an effective method form. Given a method object in one of the lists produced by the method group specifiers and a list of next methods, the macro {\bf call-method} will invoke the method such that {\bf call-next-method} has available the next methods. When an effective method has no effect other than to call a single method, some implementations employ an optimization that uses the single method directly as the effective method, thus avoiding the need to create a new effective method. This optimization is active when the effective method form consists entirely of an invocation of the {\bf call-method} macro whose first subform is a method object and whose second subform is {\bf nil}. Each {\bf define-method-combination} body is responsible for stripping off redundant invocations of {\bf progn}, {\bf and}, {\bf multiple-value-prog1}, and the like, if this optimization is desired. \vfill\eject The list {\tt (:arguments . {\it lambda-list\/})} can appear before any declarations or documentation string. This form is useful when the method combination type performs some specific behavior as part of the combined method and that behavior needs access to the arguments to the generic function. Each parameter variable defined by {\it lambda-list\/} is bound to a form that can be inserted into the effective method. When this form is evaluated during execution of the effective method, its value is the corresponding argument to the generic function. If {\it lambda-list\/} is not congruent to the generic function's lambda-list, additional ignored parameters are automatically inserted until it is congruent. Thus it is permissible for {\it lambda-list\/} to receive fewer arguments than the number that the generic function expects. Erroneous conditions detected by the body should be reported with {\bf method-combination-error} or {\bf invalid-method-error}; these functions add any necessary contextual information to the error message and will signal the appropriate error. The body {\it forms\/} are evaluated inside of the bindings created by the lambda-list and method group specifiers. Declarations at the head of the body are positioned directly inside of bindings created by the lambda-list and outside of the bindings of the method group variables. Thus method group variables cannot be declared. Within the body {\it forms\/}, {\it generic-function-symbol} is bound to the generic function object. If a {\it doc-string\/} argument is present, it provides the documentation for the method-combination type. The functions {\bf method-combination-error} and {\bf invalid-method-error} can be called from the body {\it forms\/} or from functions called by the body {\it forms\/}. The actions of these two functions can depend on implementation-dependent dynamic variables automatically bound before the generic function {\bf compute-effective-method} is called. Note that two methods with identical specializers, but with different qualifiers, are not ordered by the algorithm described in Step 2 of the method selection and combination process described in the section ``Method Selection and Combination.'' Normally the two methods play different roles in the effective method because they have different qualifiers, and no matter how they are ordered in the result of Step 2, the effective method is the same. If the two methods play the same role and their order matters, an error is signaled. This happens as part of the qualifier pattern matching in {\bf define-method-combination}. \label Values: The value returned by the {\bf define-method-combination} macro is the new method combination object. \vfill\eject \label Examples: Most examples of the long form of {\bf define-method-combination} also illustrate the use of the related functions that are provided as part of the declarative method combination facility. \screen! ;;; Examples of the short form of define-method-combination (define-method-combination and :identity-with-one-argument t) (defmethod func and ((x class1) y) ...) ;;; The equivalent of this example in the long form is: (define-method-combination and (&optional (order ':most-specific-first)) ((around (:around)) (primary (and) :order order :required t)) (let ((form (if (rest primary) `(and ,@(mapcar #'(lambda (method) `(call-method ,method ())) primary)) `(call-method ,(first primary) ())))) (if around `(call-method ,(first around) (,@(rest around) (make-method ,form))) form))) ;;; Examples of the long form of define-method-combination ;The default method-combination technique (define-method-combination standard () ((around (:around)) (before (:before)) (primary () :required t) (after (:after))) (flet ((call-methods (methods) (mapcar #'(lambda (method) `(call-method ,method ())) methods))) (let ((form (if (or before after (rest primary)) `(multiple-value-prog1 (progn ,@(call-methods before) (call-method ,(first primary) ,(rest primary))) ,@(call-methods (reverse after))) `(call-method ,(first primary) ())))) (if around `(call-method ,(first around) (,@(rest around) (make-method ,form))) form)))) ;A simple way to try several methods until one returns non-nil (define-method-combination or () ((methods (or))) `(or ,@(mapcar #'(lambda (method) `(call-method ,method ())) methods))) ;A more complete version of the preceding (define-method-combination or (&optional (order ':most-specific-first)) ((around (:around)) (primary (or))) ;; Process the order argument (case order (:most-specific-first) (:most-specific-last (setq primary (reverse primary))) (otherwise (method-combination-error "~S is an invalid order.~@ :most-specific-first and :most-specific-last are the possible values." order))) ;; Must have a primary method (unless primary (method-combination-error "A primary method is required.")) ;; Construct the form that calls the primary methods (let ((form (if (rest primary) `(or ,@(mapcar #'(lambda (method) `(call-method ,method ())) primary)) `(call-method ,(first primary) ())))) ;; Wrap the around methods around that form (if around `(call-method ,(first around) (,@(rest around) (make-method ,form))) form))) ;The same thing, using the :order and :required keyword options (define-method-combination or (&optional (order ':most-specific-first)) ((around (:around)) (primary (or) :order order :required t)) (let ((form (if (rest primary) `(or ,@(mapcar #'(lambda (method) `(call-method ,method ())) primary)) `(call-method ,(first primary) ())))) (if around `(call-method ,(first around) (,@(rest around) (make-method ,form))) form))) ;This short-form call is behaviorally identical to the preceding (define-method-combination or :identity-with-one-argument t) ;Order methods by positive integer qualifiers ;:around methods are disallowed to keep the example small (define-method-combination example-method-combination () ((methods positive-integer-qualifier-p)) `(progn ,@(mapcar #'(lambda (method) `(call-method ,method ())) (stable-sort methods #'< :key #'(lambda (method) (first (method-qualifiers method))))))) (defun positive-integer-qualifier-p (method-qualifiers) (and (= (length method-qualifiers) 1) (typep (first method-qualifiers) '(integer 0 *)))) ;;; Example of the use of :arguments (define-method-combination progn-with-lock () ((methods ())) (:arguments object) `(unwind-protect (progn (lock (object-lock ,object)) ,@(mapcar #'(lambda (method) `(call-method ,method ())) methods)) (unlock (object-lock ,object)))) \endscreen! \vfill\eject \label Remarks: The {\bf :method-combination} option of {\bf defgeneric} is used to specify that a generic function should use a particular method combination type. The argument to the {\bf :method-combination} option is the name of a method combination type. \label See Also: ``Method Selection and Combination'' ``Built-in Method Combination Types'' {\bf call-method} {\bf method-qualifiers} {\bf method-combination-error} {\bf invalid-method-error} {\bf defgeneric} \endcom \begincom{defmethod}\ftype{Macro} \label Purpose: The macro {\bf defmethod} defines a method on a generic function. If {\tt (fboundp {\it function-specifier\/})} is {\bf nil}, a generic function is created with default values for the argument precedence order (each argument is more specific than the arguments to its right in the argument list), for the generic function class (the class {\bf standard-generic-function}), for the method class (the class {\bf standard-method}), and for the method combination type (the standard method combination type). The lambda-list of the generic function is congruent with the lambda-list of the method being defined; if the {\bf defmethod} form mentions keyword arguments, the lambda-list of the generic function will mention {\bf \&key} (but no keyword arguments). If {\it function-specifier\/} names a non-generic function, a macro, or a special form, an error is signaled. If a generic function is currently named by {\it function-specifier\/}, where {\it function-specifier\/} is a symbol or a list of the form {\tt (setf {\it symbol\/})}, the lambda-list of the method must be congruent with the lambda-list of the generic function. If this condition does not hold, an error is signaled. See the section ``Congruent Lambda-Lists for All Methods of a Generic Function'' for a definition of congruence in this context. \label Syntax: \Defmac {defmethod} {\vtop{\hbox{function-specifier \star{\curly{method-qualifier\/}} specialized-lambda-list} \hbox{\star{\curly{declaration $\vert$ documentation}} \star\form}}} \Vskip1pc!\null {\it function-specifier\/}::$=$ \curly{{\it symbol\/} $\vert$ {\tt (setf {\it symbol\/})}} \Vskip1pc!\null {\it method-qualifier\/}::$=$ {\it non-nil-atom} \Vskip1pc!\null \settabs\+\hskip\leftskip&\cr \+&{\it specialized-lambda-list\/}::$=$ (&\star{\curly{var $\vert$ {\rm (}var parameter-specializer-name\/{\rm )}}} \cr \+&&\ttbrac{{\opt} \star{\curly{var $\vert$ {\rm (}var \ttbrac{initform {\brac{supplied-p-parameter}} }{\rm )}}}} \cr \+&&\ttbrac{{\tt\&rest} {\it var\/}} \cr \+&&{\tt [}{\key{}}&\star{\curly{var $\vert$ {\rm (}\curly{var $\vert$ {\rm (}keyword var{\rm )}} \ttbrac{initform \brac{supplied-p-parameter} }{\rm )}}}\cr \+&&&\brac{\tt\&allow-other-keys} {\tt ]} \cr \+&&\ttbrac{{\tt\&aux} \star{\curly{var $\vert$ {\rm (}var \brac{initform} {\rm )}}}} {\rm )} \cr \Vskip1pc!\null \+&{\it parameter-specializer-name\/}::$=$ {\it symbol} $\vert$ {\rm (}{\tt eql} {\it eql-specializer-form\/}{\rm )}\cr \Vskip 1pc! \vfill\eject \label Arguments: The {\it function-specifier\/} argument is a non-{\bf nil} symbol or a list of the form {\tt (setf {\it symbol\/})}. It names the generic function on which the method is defined. Each {\it method-qualifier\/} argument is an object that is used by method combination to identify the given method. A method qualifier is a non-{\bf nil} atom. The method combination type may further restrict what a method qualifier may be. The standard method combination type allows for unqualified methods or methods whose sole qualifier is the keyword {\bf :before}, the keyword {\bf :after}, or the keyword {\bf :around}. The {\it specialized-lambda-list\/} argument is like an ordinary function lambda-list except that the names of required parameters can be replaced by specialized parameters. A specialized parameter is a list of the form {\tt ({\it variable-name parameter-specializer-name\/})}. Only required parameters may be specialized. A parameter specializer name is a symbol that names a class or {\tt (eql {\it eql-specializer-form\/})}. The parameter specializer name {\tt (eql {\it eql-specializer-form\/})} indicates that the corresponding argument must be {\bf eql} to the object that is the value of {\it eql-specializer-form\/} for the method to be applicable. If no parameter specializer name is specified for a given required parameter, the parameter specializer defaults to the class named {\bf t}. See the section ``Introduction to Methods'' for further discussion. The {\it form\/} arguments specify the method body. The body of the method is enclosed in an implicit block. If {\it function-specifier\/} is a symbol, this block bears the same name as the generic function. If {\it function-specifier\/} is a list of the form {\tt (setf {\it symbol\/})}, the name of the block is {\it symbol}. \label Values: The result of {\bf defmethod} is the method object. \label Remarks: The class of the method object that is created is that given by the method class option of the generic function on which the method is defined. If the generic function already has a method that agrees with the method being defined on parameter specializers and qualifiers, {\bf defmethod} replaces the existing method with the one now being defined. See the section ``Agreement on Parameter Specializers and Qualifiers'' for a definition of agreement in this context. The parameter specializers are derived from the parameter specializer names as described in the section ``Introduction to Methods.'' The expansion of the {\bf defmethod} macro ``refers to'' each specialized parameter (see the description of {\bf ignore} in {\it Common Lisp: The Language}, p. 160). This includes parameters that have an explicit parameter specializer name of {\bf t}. This means that a compiler warning does not occur if the body of the method does not refer to a specialized parameter. Note that a parameter that specializes on {\bf t} is not synonymous with an unspecialized parameter in this context. \label See Also: ``Introduction to Methods'' ``Congruent Lambda-Lists for All Methods of a Generic Function'' ``Agreement on Parameter Specializers and Qualifiers'' \endcom \begincom{describe}\ftype{Standard Generic Function} \label Purpose: The Common Lisp function {\bf describe} is replaced by a generic function. The generic function {\bf describe} prints information about a given object on the standard output. Each implementation is required to provide a method on the class {\bf standard-object} and methods on enough other classes so as to ensure that there is always an applicable method. Implementations are free to add methods for other classes. Users can write methods for {\bf describe} for their own classes if they do not wish to inherit an implementation-supplied method. These methods must conform to the definition of {\bf describe} as specified in {\it Common Lisp: The Language}. \label Syntax: \Defgen {describe} {object} \label Method Signatures: \Defmeth {describe} {({\it object\/} standard-object)} \label Arguments: The {\it object\/} argument may be any Common Lisp object. \label Values: The generic function {\bf describe} returns no values. \endcom \begincom{documentation, (setf documentation)}\ftype{Standard Generic Function} \label Purpose: The Common Lisp function {\bf documentation} is replaced by a generic function. The generic function {\bf documentation} returns the documentation string associated with the given object if it is available; otherwise it returns {\bf nil}. The generic function {\bf (setf documentation)} is used to update the documentation. \label Syntax: \Defgen documentation {x {\opt} doc-type} \Defgen {(setf documentation)} {new-value x {\opt} doc-type} \label Method Signatures: \Defmeth {documentation} {({\it method\/} standard-method) \&optional {\it doc-type}} \Defmeth {(setf documentation)} {\vtop{\hbox{{\it new-value\/} ({\it method\/} standard-method)} \hbox{\&optional {\it doc-type}}}} \Defmeth {documentation} {\vtop{\hbox{({\it generic-function\/} standard-generic-function)} \hbox{\&optional {\it doc-type}}}} \Defmeth {(setf documentation)} {\vtop{\hbox{{\it new-value\/}} \hbox{({\it generic-function\/} standard-generic-function)} \hbox{\&optional {\it doc-type}}}} \Defmeth {documentation} {({\it class\/} standard-class) \&optional {\it doc-type}} \Defmeth {(setf documentation)} {\vtop{\hbox{{\it new-value\/} ({\it class\/} standard-class)} \hbox{\&optional {\it doc-type}}}} \Defmeth {documentation} {\vtop{\hbox{({\it method-combination\/} method-combination)} \hbox{\&optional {\it doc-type}}}} \Defmeth {(setf documentation)} {\vtop{\hbox{{\it new-value\/}} \hbox{({\it method-combination\/} method-combination)} \hbox{\&optional {\it doc-type}}}} \Defmeth {documentation} {\vtop{\hbox{({\it slot-description\/} standard-slot-description)} \hbox{\&optional {\it doc-type}}}} \Defmeth {(setf documentation)} {\vtop{\hbox{{\it new-value\/}} \hbox{({\it slot-description\/} standard-slot-description)} \hbox{\&optional {\it doc-type}}}} \Defmeth {documentation} {({\it symbol\/} symbol) \&optional {\it doc-type}} \Defmeth {(setf documentation)} {\vtop{\hbox{{\it new-value\/} ({\it symbol\/} symbol)} \hbox{\&optional {\it doc-type}}}} \Defmeth {documentation} {({\it list\/} list) \&optional {\it doc-type}} \Defmeth {(setf documentation)} {\vtop{\hbox{{\it new-value\/} ({\it list\/} list)} \hbox{\&optional {\it doc-type}}}} \label Arguments: The first argument of {\bf documentation} is either a symbol, a function specifier list of the form {\tt (setf {\it symbol\/})}, a method object, a class object, a generic function object, a method combination object, or a slot description object. \beginlist \item{\bull} If the first argument is a method object, a class object, a generic function object, a method combination object, or a slot description object, the second argument must not be supplied, or an error is signaled. \item{\bull} If the first argument is a symbol or a list of the form {\tt (setf {\it symbol\/})}, the second argument must be supplied. \itemitem{--} The forms {\tt (documentation {\it symbol\/} 'function)} and {\tt (documentation '(setf {\it symbol\/}) 'function)} return the documentation string of the function, generic function, special form, or macro named by the symbol or list. \itemitem{--} The form {\tt (documentation {\it symbol\/} 'variable)} returns the documentation string of the special variable or constant named by the symbol. \itemitem{--} The form {\tt (documentation {\it symbol\/} 'structure)} returns the documentation string of the {\bf defstruct} structure named by the symbol. \itemitem{--} The form {\tt (documentation {\it symbol\/} 'type)} returns the documentation string of the class object named by the symbol, if there is such a class. If there is no such class, it returns the documentation string of the type specifier named by the symbol. \itemitem{--} The form {\tt (documentation {\it symbol\/} 'setf)} returns the documentation string of the {\bf defsetf} or {\bf define-setf-method} definition associated with the symbol. \itemitem{--} The form {\tt (documentation {\it symbol\/} 'method-combination)} returns the documentation string of the method combination type named by the symbol. \item{} An implementation may extend the set of symbols that are acceptable as the second argument. If a symbol is not recognized as an acceptable argument by the implementation, an error must be signaled. \endlist \label Values: The documentation string associated with the given object is returned unless none is available, in which case {\bf documentation} returns {\bf nil}. \endcom \begincom{ensure-generic-function}\ftype{Function} \label Purpose: The function {\bf ensure-generic-function} is used to define a globally named generic function with no methods or to specify or modify options and declarations that pertain to a globally named generic function as a whole. If {\tt (fboundp {\it function-specifier\/})} is {\bf nil}, a new generic function is created. If {\tt (symbol-function {\it function-specifier\/})} is a non-generic function, a macro, or a special form, an error is signaled. If {\it function-specifier\/} specifies a generic function that has a different value for any of the following arguments, the generic function is modified to have the new value: {\bf :argument-precedence-order}, {\bf :declare}, {\bf :documentation}, {\bf :method-combination}. If {\it function-specifier\/} specifies a generic function that has a different value for the {\bf :lambda-list} argument, and the new value is congruent with the lambda-lists of all existing methods or there are no methods, the value is changed; otherwise an error is signaled. If {\it function-specifier\/} specifies a generic function that has a different value for the {\bf :generic-function-class} argument and if the new generic function class is compatible with the old, {\bf change-class} is called to change the class of the generic function; otherwise an error is signaled. If {\it function-specifier\/} specifies a generic function that has a different value for the {\bf :method-class} argument, the value is changed, but any existing methods are not changed. \label Syntax: \Defun {ensure-generic-function} {function-specifier\/ \key \vtop{\hbox{:lambda-list} \hbox{:argument-precedence-order} \hbox{:declare} \hbox{:documentation} \hbox{:generic-function-class} \hbox{:method-combination} \hbox{:method-class} \hbox{:environment}}} \Vskip1pc!\null {\it function-specifier\/}::$=$ \curly{{\it symbol\/} $\vert$ {\tt (setf {\it symbol\/})}} \label Arguments: The {\it function-specifier\/} argument is a symbol or a list of the form {\tt (setf {\it symbol\/})}. The keyword arguments correspond to the {\it option\/} arguments of {\bf defgeneric}, except that the {\bf :method-class} and {\bf :generic-function-class} arguments can be class objects as well as names. \vfill\eject The {\bf :environment\/} argument is the same as the {\bf \&environment} argument to macro expansion functions. It is typically used to distinguish between compile-time and run-time environments. The {\bf :method-combination} argument is a method combination object. \label Values: The generic function object is returned. \label See Also: {\bf defgeneric} \endcom \begincom{find-class}\ftype{Function} \label Purpose: The function {\bf find-class} returns the class object named by the given symbol in the given environment. \label Syntax: \Defun {find-class} {symbol {\opt} errorp environment} \label Arguments: The first argument to {\bf find-class} is a symbol. If there is no such class and the {\it errorp\/} argument is not supplied or is non-{\bf nil}, {\bf find-class} signals an error. If there is no such class and the {\it errorp\/} argument is {\bf nil}, {\bf find-class} returns {\bf nil}. The default value of {\it errorp\/} is {\bf t}. The optional {\it environment\/} argument is the same as the {\bf \&environment} argument to macro expansion functions. It is typically used to distinguish between compile-time and run-time environments. \label Values: The result of {\bf find-class} is the class object named by the given symbol. \label Remarks: The class associated with a particular symbol can be changed by using {\bf setf} with {\bf find-class}. The results are undefined if the user attempts to change the class associated with a symbol that is defined as a type specifier by {\it Common Lisp: The Language}. See the section ``Integrating Types and Classes.'' \endcom \begincom{find-method}\ftype{Standard Generic Function} \label Purpose: The generic function {\bf find-method} takes a generic function and returns the method object that agrees on method qualifiers and parameter specializers with the {\it method-qualifiers\/} and {\it specializers\/} arguments of {\bf find-method}. See the section ``Agreement on Parameter Specializers and Qualifiers'' for a definition of agreement in this context. \label Syntax: \Defgen {find-method} {generic-function method-qualifiers specializers {\opt} errorp} \label Method Signatures: \Defmeth{find-method} { \vtop{\hbox{({\it generic-function\/} standard-generic-function)} \hbox{\it method-qualifiers specializers {\opt} errorp}}} \label Arguments: The {\it generic-function\/} argument is a generic function. The {\it method-qualifiers\/} argument is a list of the method qualifiers for the method. The order of the method qualifiers is significant. The {\it specializers\/} argument is a list of the parameter specializers for the method. It must correspond in length to the number of required arguments of the generic function, or an error is signaled. This means that to obtain the default method on a given generic function, a list whose elements are the class named {\bf t} must be given. If there is no such method and the {\it errorp\/} argument is not supplied or is non-{\bf nil}, {\bf find-method} signals an error. If there is no such method and the {\it errorp\/} argument is {\bf nil}, {\bf find-method} returns {\bf nil}. The default value of {\it errorp\/} is {\bf t}. \label Values: The result of {\bf find-method} is the method object with the given method qualifiers and parameter specializers. \label See Also: ``Agreement on Parameter Specializers and Qualifiers'' \endcom \begincom{function-keywords}\ftype{Standard Generic Function} \label Purpose: The generic function {\bf function-keywords} is used to return the keyword parameter specifiers for a given method. \label Syntax: \Defgen {function-keywords} {method} \label Method Signatures: \Defmeth {function-keywords} {({\it method\/} standard-method)} \label Arguments: The {\it method\/} argument is a method object. \label Values: The generic function {\bf function-keywords} returns two values: a list of the explicitly named keywords and a boolean that states whether {\bf \&allow-other-keys} had been specified in the method definition. \endcom \begincom{generic-flet}\ftype{Special Form} \label Purpose: The {\bf generic-flet} special form is analogous to the Common Lisp {\bf flet} special form. It produces new generic functions and establishes new lexical function definition bindings. Each generic function is created with the set of methods specified by its method descriptions. The special form {\bf generic-flet} is used to define functions whose names are meaningful only locally and to execute a series of forms with these function definition bindings. Any number of such local generic functions may be defined. The names of functions defined by {\bf generic-flet} have lexical scope; they retain their local definitions only within the body of the {\bf generic-flet}. Any references within the body of the {\bf generic-flet} to functions whose names are the same as those defined within the {\bf generic-flet} are thus references to the local functions instead of to any global functions of the same names. The scope of these generic function definition bindings, however, includes only the body of {\bf generic-flet}, not the definitions themselves. Within the method bodies, local function names that match those being defined refer to global functions defined outside the {\bf generic-flet}. It is thus not possible to define recursive functions with {\bf generic-flet}. \label Syntax: \Defspec {generic-flet} { \vtop{\hbox{\lparen{\rm$\{$}\lparen function-specifier lambda-list $\lbrack\!\lbrack\downarrow\!$ option $\vert$ \star{method-description} $\rbrack\!\rbrack$\rparen\star{\rm$\}$}\rparen} \hbox{\star\form}}} \Vskip 1pc! {\it function-specifier\/}::$=$ \curly{{\it symbol\/} $\vert$ {\tt (setf {\it symbol\/})}} \Vskip 1pc! \settabs\+\hskip\leftskip&\cr \+&{\it lambda-list\/}::$=$ (&\star{\curly{var}} \cr \+&&\ttbrac{{\opt} \star{\curly{var $\vert$ {\rm (}var\/{\rm )}}}} \cr \+&&\ttbrac{{\tt\&rest} {\it var\/}} \cr \+&&{\tt [}{\key{}}&\star{\curly{var $\vert$ {\rm (}\curly{var $\vert$ {\rm (}keyword var\/{\rm )}}{\rm )}}}\cr \+&&&\brac{\tt\&allow-other-keys} {\tt ]} {\rm )} \cr \Vskip 1pc! {\it option\/}::$=$ {\tt\vtop{\hbox{(:argument-precedence-order \plus{\curly{parameter-name}}) $\vert$} \hbox{(declare \plus{\curly{declaration\/}}) $\vert$} \hbox{(:documentation {\it string\/}) $\vert$} \hbox{(:method-combination {\it symbol\/} \star{\curly{arg\/}}) $\vert$} \hbox{(:generic-function-class {\it class-name\/}) $\vert$} \hbox{(:method-class {\it class-name\/})}}} %\Vskip 1pc! \vfill\eject {\it method-description\/}::$=$ {\tt (:method} \vtop{\hbox{\it \star{\curly{method-qualifier\/}} specialized-lambda-list\/} \hbox{\star{\curly{declaration\/ $\vert$ documentation\/}} \star{\curly{form\/}}{\tt )}}} \label Arguments: The {\it function-specifier\/}, {\it lambda-list\/}, {\it option}, {\it method-qualifier}, and {\it specialized-lambda-list\/} arguments are the same as for {\bf defgeneric}. A {\bf generic-flet} local method definition is identical in form to the method definition part of a {\bf defmethod}. The body of each method is enclosed in an implicit block. If {\it function-specifier\/} is a symbol, this block bears the same name as the generic function. If {\it function-specifier\/} is a list of the form {\tt (setf {\it symbol\/})}, the name of the block is {\it symbol}. \label Values: The result returned by {\bf generic-flet} is the value or values returned by the last form executed. If no forms are specified, {\bf generic-flet} returns {\bf nil}. \label See Also: {\bf generic-labels defmethod defgeneric generic-function} \endcom \begincom{generic-function}\ftype{Macro} \label Purpose: The {\bf generic-function} macro creates an anonymous generic function. The generic function is created with the set of methods specified by its method descriptions. \label Syntax: \Defmac {generic-function} {\vtop{\hbox{\it lambda-list} \hbox{$\lbrack\!\lbrack\downarrow\!$ option $\vert$ \star{method-description} $\rbrack\!\rbrack$}}} \Vskip 1pc! \settabs\+\hskip\leftskip&\cr \+&{\it lambda-list\/}::$=$ (&\star{\curly{var}} \cr \+&&\ttbrac{{\opt} \star{\curly{var $\vert$ {\rm (}var\/{\rm )}}}} \cr \+&&\ttbrac{{\tt\&rest} {\it var\/}} \cr \+&&{\tt [}{\key{}}&\star{\curly{var $\vert$ {\rm (}\curly{var $\vert$ {\rm (}keyword var\/{\rm )}}{\rm )}}}\cr \+&&&\brac{\tt\&allow-other-keys} {\tt ]} {\rm )} \cr \Vskip 1pc! {\it option\/}::$=$ {\tt\vtop{\hbox{(:argument-precedence-order \plus{\curly{parameter-name}}) $\vert$} \hbox{(declare \plus{\curly{declaration\/}}) $\vert$} \hbox{(:documentation {\it string\/}) $\vert$} \hbox{(:method-combination {\it symbol\/} \star{\curly{arg\/}}) $\vert$} \hbox{(:generic-function-class {\it class-name\/}) $\vert$} \hbox{(:method-class {\it class-name\/})}}} \Vskip 1pc! {\it method-description\/}::$=$ {\tt (:method} \vtop{\hbox{\it \star{\curly{method-qualifier\/}} specialized-lambda-list\/} \hbox{\star{\curly{declaration\/ $\vert$ documentation\/}} \star{\curly{form\/}}{\tt )}}} \label Arguments: The {\it option}, {\it method-qualifier}, and {\it specialized-lambda-list\/} arguments are the same as for {\bf defgeneric}. \label Values: The generic function object is returned as the result. \label Remarks: If no method descriptions are specified, an anonymous generic function with no methods is created. \vfill\eject \label See Also: {\bf defgeneric generic-flet generic-labels defmethod} \endcom \begincom{generic-labels}\ftype{Special Form} \label Purpose: The {\bf generic-labels} special form is analogous to the Common Lisp {\bf labels} special form. It produces new generic functions and establishes new lexical function definition bindings. Each generic function is created with the set of methods specified by its method descriptions. The special form {\bf generic-labels} is used to define functions whose names are meaningful only locally and to execute a series of forms with these function definition bindings. Any number of such local functions may be defined. The names of functions defined by {\bf generic-labels} have lexical scope; they retain their local definitions only within the body of the {\bf generic-labels} construct. Any references within the body of the {\bf generic-labels} construct to functions whose names are the same as those defined within the {\bf generic-labels} form are thus references to the local functions instead of to any global functions of the same names. The scope of these generic function definition bindings includes the method bodies themselves as well as the body of the {\bf generic-labels} construct. \label Syntax: \Defspec {generic-labels} { \vtop{\hbox{\lparen{\rm$\{$}\lparen function-specifier lambda-list} \hbox{\ \ \ $\lbrack\!\lbrack\downarrow\!$ option $\vert$ \star{method-description}$\rbrack\!\rbrack$\rparen\star{\rm$\}$}\rparen} \hbox{\star\form}}} \Vskip 1pc! {\it function-specifier\/}::$=$ \curly{{\it symbol\/} $\vert$ {\tt (setf {\it symbol\/})}} \Vskip 1pc! \settabs\+\hskip\leftskip&\cr \+&{\it lambda-list\/}::$=$ (&\star{\curly{var}} \cr \+&&\ttbrac{{\opt} \star{\curly{var $\vert$ {\rm (}var\/{\rm )}}}} \cr \+&&\ttbrac{{\tt\&rest} {\it var\/}} \cr \+&&{\tt [}{\key{}}&\star{\curly{var $\vert$ {\rm (}\curly{var $\vert$ {\rm (}keyword var\/{\rm )}}{\rm )}}}\cr \+&&&\brac{\tt\&allow-other-keys} {\tt ]} {\rm )} \cr \Vskip 1pc! {\it option\/}::$=$ {\tt\vtop{\hbox{(:argument-precedence-order \plus{\curly{parameter-name}}) $\vert$} \hbox{(declare \plus{\curly{declaration\/}}) $\vert$} \hbox{(:documentation {\it string\/}) $\vert$} \hbox{(:method-combination {\it symbol\/} \star{\curly{arg\/}}) $\vert$} \hbox{(:generic-function-class {\it class-name\/}) $\vert$} \hbox{(:method-class {\it class-name\/})}}} \Vskip 1pc! {\it method-description\/}::$=$ {\tt (:method} \vtop{\hbox{\it \star{\curly{method-qualifier\/}} specialized-lambda-list\/} \hbox{\star{\curly{declaration\/ $\vert$ documentation\/}} \star{\curly{form\/}}{\tt )}}} \label Arguments: The {\it function-specifier\/}, {\it lambda-list\/}, {\it option}, {\it method-qualifier}, and {\it specialized-lambda-list\/} arguments are the same as for {\bf defgeneric}. A {\bf generic-labels} local method definition is identical in form to the method definition part of a {\bf defmethod}. The body of each method is enclosed in an implicit block. If {\it function-specifier\/} is a symbol, this block bears the same name as the generic function. If {\it function-specifier\/} is a list of the form {\tt (setf {\it symbol\/})}, the name of the block is {\it symbol}. \label Values: The result returned by {\bf generic-labels} is the value or values returned by the last form executed. If no forms are specified, {\bf generic-labels} returns {\bf nil}. \label See Also: {\bf generic-flet defmethod defgeneric generic-function} \endcom \begincom{initialize-instance}\ftype{Standard Generic Function} \label Purpose: The generic function {\bf initialize-instance} is called by {\bf make-instance} to initialize a newly created instance. The generic function {\bf initialize-instance} is called with the new instance and the defaulted initialization arguments. The system-supplied primary method on {\bf initialize-instance} initializes the slots of the instance with values according to the initialization arguments and the {\bf :initform} forms of the slots. It does this by calling the generic function {\bf shared-initialize} with the following arguments: the instance, {\bf t} (this indicates that all slots for which no initialization arguments are provided should be initialized according to their {\bf :initform} forms), and the defaulted initialization arguments. \label Syntax: \Defgen {initialize-instance} {instance {\tt \&rest {\it initargs}}} \label Method Signatures: \Defmeth {initialize-instance} {({\it instance\/} standard-object) {\rest} {\it initargs}} \label Arguments: The {\it instance\/} argument is the object to be initialized. The {\it initargs\/} argument consists of alternating initialization argument names and values. \label Values: The modified instance is returned as the result. \label Remarks: Programmers can define methods for {\bf initialize-instance} to specify actions to be taken when an instance is initialized. If only {\bf :after} methods are defined, they will be run after the system-supplied primary method for initialization and therefore will not interfere with the default behavior of {\bf initialize-instance}. \label See Also: ``Object Creation and Initialization'' ``Rules for Initialization Arguments'' ``Declaring the Validity of Initialization Arguments'' {\bf shared-initialize make-instance slot-boundp slot-makunbound} \endcom \begincom{invalid-method-error}\ftype{Function} \label Purpose: The function {\bf invalid-method-error} is used to signal an error when there is an applicable method whose qualifiers are not valid for the method combination type. The error message is constructed by using a format string and any arguments to it. Because an implementation may need to add additional contextual information to the error message, {\bf invalid-method-error} should be called only within the dynamic extent of a method combination function. The function {\bf invalid-method-error} is called automatically when a method fails to satisfy every qualifier pattern and predicate in a {\bf define-method-combination} form. A method combination function that imposes additional restrictions should call {\bf invalid-method-error} explicitly if it encounters a method it cannot accept. \label Syntax: \Defun {invalid-method-error} {method format-string {\rest} args} \label Arguments: The {\it method\/} argument is the invalid method object. The {\it format-string\/} argument is a control string that can be given to {\bf format}, and {\it args\/} are any arguments required by that string. \label Remarks: Whether {\bf invalid-method-error} returns to its caller or exits via {\bf throw} is implementation dependent. \label See Also: {\bf define-method-combination} \endcom \begincom{make-instance}\ftype{Standard Generic Function} \label Purpose: The generic function {\bf make-instance} creates and returns a new instance of the given class. The generic function {\bf make-instance} may be used as described in the section ``Object Creation and Initialization.'' \label Syntax: \Defgen {make-instance} {class\/ {\tt \&rest {\it initargs}}} \label Method Signatures: \Defmeth {make-instance} {({\it class\/} standard-class) \&rest {\it initargs}} \Defmeth {make-instance} {({\it class\/} symbol) \&rest {\it initargs}} \label Arguments: The {\it class\/} argument is a class object or a symbol that names a class. The remaining arguments form a list of alternating initialization argument names and values. If the second of the above methods is selected, that method invokes {\bf make-instance} on the arguments {\tt (find-class {\it class\/})} and {\it initargs}. The initialization arguments are checked within {\bf make-instance}. See the section ``Object Creation and Initialization.'' \label Values: The new instance is returned. \label Remarks: The meta-object protocol can be used to define new methods on {\bf make-instance} to replace the object-creation protocol. \label See Also: ``Object Creation and Initialization'' {\bf defclass initialize-instance class-of} \endcom \begincom{make-instances-obsolete}\ftype{Standard Generic Function} \label Purpose: The generic function {\bf make-instances-obsolete} is invoked automatically by the system when {\bf defclass} has been used to redefine an existing standard class and the set of local slots accessible in an instance is changed or the order of slots in storage is changed. It can also be explicitly invoked by the user. The function {\bf make-instances-obsolete} has the effect of initiating the process of updating the instances of the class. During updating, the generic function {\bf update-instance-for-redefined-class} will be invoked. \label Syntax: \Defgen {make-instances-obsolete} {class} \label Method Signatures: \Defmeth {make-instances-obsolete} {({\it class\/} standard-class)} \Defmeth {make-instances-obsolete} {({\it class\/} symbol)} \label Arguments: The {\it class\/} argument is a class object or a symbol that names the class whose instances are to be made obsolete. If the second of the above methods is selected, that method invokes {\bf make-instances-obsolete} on {\tt (find-class {\it class\/})}. \label Values: The modified class is returned. The result of {\bf make-instances-obsolete} is {\bf eq} to the {\it class} argument supplied to the first of the above methods. \label See Also: ``Redefining Classes'' {\bf update-instance-for-redefined-class} \endcom \begincom{method-combination-error}\ftype{Function} \label Purpose: The function {\bf method-combination-error} is used to signal an error in method combination. The error message is constructed by using a format string and any arguments to it. Because an implementation may need to add additional contextual information to the error message, {\bf method-combination-error} should be called only within the dynamic extent of a method combination function. \label Syntax: \Defun {method-combination-error} {format-string {\rest} args} \label Arguments: The {\it format-string\/} argument is a control string that can be given to {\bf format}, and {\it args\/} are any arguments required by that string. \label Remarks: Whether {\bf method-combination-error} returns to its caller or exits via {\bf throw} is implementation dependent. \label See Also: {\bf define-method-combination} \endcom \begincom{method-qualifiers}\ftype{Standard Generic Function} \label Purpose: The generic function {\bf method-qualifiers} returns a list of the qualifiers of the given method. \label Syntax: \Defgen {method-qualifiers} {method} \label Method Signatures: \Defmeth {method-qualifiers} {({\it method\/} standard-method)} \label Arguments: The {\it method\/} argument is a method object. \label Values: A list of the qualifiers of the given method is returned. \label Examples: \screen! (setq methods (remove-duplicates methods :from-end t :key #'method-qualifiers :test #'equal)) \endscreen! \label See Also: {\bf define-method-combination} \endcom \begincom{next-method-p}\ftype{Function} \label Purpose: The locally defined function {\bf next-method-p} can be used within the body of a method defined by a method-defining form to determine whether a next method exists. \label Syntax: \Defun {next-method-p} {} \label Arguments: The function {\bf next-method-p} takes no arguments. \label Values: The function {\bf next-method-p} returns true or false. \label Remarks: Like {\bf call-next-method}, the function {\bf next-method-p} has lexical scope and indefinite extent. \label See Also: {\bf call-next-method} \endcom \begincom{no-applicable-method}\ftype{Standard Generic Function} \label Purpose: The generic function {\bf no-applicable-method} is called when a generic function of the class {\bf standard-generic-function} is invoked and no method on that generic function is applicable. The default method signals an error. The generic function {\bf no-applicable-method} is not intended to be called by programmers. Programmers may write methods for it. \label Syntax: \Defgen {no-applicable-method} {generic-function {\rest} function-arguments} \label Method Signatures: \Defmeth {no-applicable-method} {\vtop{\hbox{({\it generic-function\/} t)} \hbox{\&rest {\it function-arguments\/}}}} \label Arguments: The {\it generic-function\/} argument of {\bf no-applicable-method} is the generic function object on which no applicable method was found. The {\it function-arguments} argument is a list of the arguments to that generic function. \endcom \begincom{no-next-method}\ftype{Standard Generic Function} \label Purpose: The generic function {\bf no-next-method} is called by {\bf call-next-method} when there is no next method. The system-supplied method on {\bf no-next-method} signals an error. The generic function {\bf no-next-method} is not intended to be called by programmers. Programmers may write methods for it. \label Syntax: \Defgen {no-next-method} {generic-function method {\rest} args} \label Method Signatures: \Defmeth {no-next-method} {\vtop{\hbox{({\it generic-function\/} standard-generic-function)} \hbox{({\it method\/} standard-method)} \hbox{\&rest {\it args\/}}}} \label Arguments: The {\it generic-function\/} argument is the generic function object to which the method that is the second argument belongs. The {\it method\/} argument is the method that contained the call to {\bf call-next-method} for which there is no next method. The {\it args\/} argument is a list of the arguments to {\bf call-next-method}. \label See Also: {\bf call-next-method} \endcom \begincom{print-object}\ftype{Standard Generic Function} \label Purpose: The generic function {\bf print-object} writes the printed representation of an object to a stream. The function {\bf print-object} is called by the print system; it should not be called by the user. Each implementation is required to provide a method on the class {\bf standard-object} and methods on enough other classes so as to ensure that there is always an applicable method. Implementations are free to add methods for other classes. Users can write methods for {\bf print-object} for their own classes if they do not wish to inherit an implementation-supplied method. \label Syntax: \Defgen {print-object} {object stream} \label Method Signatures: \Defmeth {print-object} {({\it object\/} standard-object) {\it stream\/}} \label Arguments: The first argument is any Lisp object. The second argument is a stream; it cannot be {\bf t} or {\bf nil}. \label Values: The function {\bf print-object} returns its first argument, the object. \label Remarks: Methods on {\bf print-object} must obey the print control special variables described in {\it Common Lisp: The Language}. The specific details are the following: \beginlist \item{\bull} Each method must implement {\bf *print-escape*}. \item{\bull} The {\bf *print-pretty*} control variable can be ignored by most methods other than the one for lists. \item{\bull} The {\bf *print-circle*} control variable is handled by the printer and can be ignored by methods. \item{\bull} The printer takes care of {\bf *print-level*} automatically, provided that each method handles exactly one level of structure and calls {\bf write} (or an equivalent function) recursively if there are more structural levels. The printer's decision of whether an object has components (and therefore should not be printed when the printing depth is not less than {\bf *print-level*}) is implementation dependent. In some implementations its {\bf print-object} method is not called; in others the method is called, and the determination that the object has components is based on what it tries to write to the stream. \item{\bull} Methods that produce output of indefinite length must obey {\bf *print-length*}, but most methods other than the one for lists can ignore it. \item{\bull} The {\bf *print-base*}, {\bf *print-radix*}, {\bf *print-case*}, {\bf *print-gensym*}, and {\bf *print-array*} control variables apply to specific types of objects and are handled by the methods for those objects. \endlist If these rules are not obeyed, the results are undefined. In general, the printer and the {\bf print-object} methods should not rebind the print control variables as they operate recursively through the structure, but this is implementation dependent. In some implementations the stream argument passed to a {\bf print-object} method is not the original stream, but is an intermediate stream that implements part of the printer. Methods should therefore not depend on the identity of this stream. All of the existing printing functions ({\bf write}, {\bf prin1}, {\bf print}, {\bf princ}, {\bf pprint}, {\bf write-to-string}, {\bf prin1-to-string}, {\bf princ-to-string}, the {\tt ~}{\bf S} and {\tt ~}{\bf A} format operations, and the {\tt ~}{\bf B}, {\tt ~}{\bf D}, {\tt ~}{\bf E}, {\tt ~}{\bf F}, {\tt ~}{\bf G}, {\tt ~}{\bf \$}, {\tt ~}{\bf O}, {\tt ~}{\bf R}, and {\tt ~}{\bf X} format operations when they encounter a non-numeric value) are required to be changed to go through the {\bf print-object} generic function. Each implementation is required to replace its former implementation of printing with one or more {\bf print-object} methods. Exactly which classes have methods for {\bf print-object} is not specified; it would be valid for an implementation to have one default method that is inherited by all system-defined classes. \endcom \begincom{reinitialize-instance}\ftype{Standard Generic Function} \label Purpose: The generic function {\bf reinitialize-instance} can be used to change the values of local slots according to initialization arguments. This generic function is called by the Meta-Object Protocol. It can also be called by users. The system-supplied primary method for {\bf reinitialize-instance} checks the validity of initialization arguments and signals an error if an initialization argument is supplied that is not declared as valid. The method then calls the generic function {\bf shared-initialize} with the following arguments: the instance, {\bf nil} (which means no slots should be initialized according to their initforms), and the initialization arguments it received. \label Syntax: \Defgen {reinitialize-instance} {instance {\tt \&rest {\it initargs}}} \label Method Signatures: \Defmeth {reinitialize-instance} {({\it instance\/} standard-object) {\rest} {\it initargs}} \label Arguments: The {\it instance\/} argument is the object to be initialized. The {\it initargs\/} argument consists of alternating initialization argument names and values. \label Values: The modified instance is returned as the result. \label Remarks: Initialization arguments are declared as valid by using the {\bf :initarg} option to {\bf defclass}, or by defining methods for {\bf reinitialize-instance} or {\bf shared-initialize}. The keyword name of each keyword parameter specifier in the lambda-list of any method defined on {\bf reinitialize-instance} or {\bf shared-initialize} is declared as a valid initialization argument name for all classes for which that method is applicable. \label See Also: ``Reinitializing an Instance'' ``Rules for Initialization Arguments'' ``Declaring the Validity of Initialization Arguments'' {\bf initialize-instance shared-initialize update-instance-for-redefined-class update-instance-for-different-class slot-boundp slot-makunbound} \endcom \begincom{remove-method}\ftype{Standard Generic Function} \label Purpose: The generic function {\bf 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. \label Syntax: \Defgen {remove-method} {generic-function method} \label Method Signatures: \Defmeth {remove-method} {\vtop{\hbox{({\it generic-function\/} standard-generic-function)} \hbox{\it method}}} \label Arguments: The {\it generic-function\/} argument is a generic function object. The {\it method\/} argument is a method object. The function {\bf remove-method} does not signal an error if the method is not one of the methods on the generic function. \label Values: The modified generic function is returned. The result of {\bf remove-method} is {\bf eq} to the {\it generic-function\/} argument. \label See Also: {\bf find-method} \endcom \begincom{shared-initialize}\ftype{Standard Generic Function} \label Purpose: The generic function {\bf shared-initialize} is used to fill the slots of an instance using initialization arguments and {\bf :initform} forms. It is called when an instance is created, when an instance is re-initialized, when an instance is updated to conform to a redefined class, and when an instance is updated to conform to a different class. The generic function {\bf shared-initialize} is called by the system-supplied primary method for {\bf initialize-instance}, {\bf reinitialize-instance}, {\bf update-instance-for-redefined-class}, and {\bf update-instance-for-different-class}. The generic function {\bf shared-initialize} takes the following arguments: the instance to be initialized, a specification of a set of names of slots accessible in that instance, and any number of initialization arguments. The arguments after the first two must form an initialization argument list. The system-supplied primary method on {\bf shared-initialize} initializes the slots with values according to the initialization arguments and specified {\bf :initform} forms. The second argument indicates which slots should be initialized according to their {\bf :initform} forms if no initialization arguments are provided for those slots. The system-supplied primary method behaves as follows, regardless of whether the slots are local or shared: \beginlist \item{\bull} If an initialization argument in the initialization argument list specifies a value for that slot, that value is stored into the slot, even if a value has already been stored in the slot before the method is run. \item{\bull} Any slots indicated by the second argument that are still unbound at this point are initialized according to their {\bf :initform} forms. For any such slot that has an {\bf :initform} form, that form is evaluated in the lexical environment of its defining {\bf defclass} form and the result is stored into the slot. For example, if a {\bf :before} method stores a value in the slot, the {\bf :initform} form will not be used to supply a value for the slot. \item{\bull} The rules mentioned in the section ``Rules for Initialization Arguments'' are obeyed. \endlist \label Syntax: \Defgen {shared-initialize} {instance slot-names {\tt \&rest {\it initargs}}} \label Method Signatures: \Defmeth {shared-initialize} {({\it instance\/} standard-object) {\it slot-names\/} {\rest} {\it initargs}} \label Arguments: The {\it instance\/} argument is the object to be initialized. The {\it slots-names\/} argument specifies the slots that are to be initialized according to their {\bf :initform} forms if no initialization arguments apply. It is supplied in one of three forms as follows: \beginlist \item{\bull} It can be list of slot names, which specifies the set of those slot names. \item{\bull} It can be {\bf nil}, which specifies the empty set of slot names. \item{\bull} It can be the symbol {\bf t}, which specifies the set of all of the slots. \endlist The {\it initargs\/} argument consists of alternating initialization argument names and values. \label Values: The modified instance is returned as the result. \label Remarks: Initialization arguments are declared as valid by using the {\bf :initarg} option to {\bf defclass}, or by defining methods for {\bf shared-initialize}. The keyword name of each keyword parameter specifier in the lambda-list of any method defined on {\bf shared-initialize} is declared as a valid initialization argument name for all classes for which that method is applicable. Implementations are permitted to optimize {\bf :initform} forms that neither produce nor depend on side effects, by evaluating these forms and storing them into slots before running any {\bf initialize-instance} methods, rather than by handling them in the primary {\bf initialize-instance} method. (This optimization might be implemented by having the {\bf allocate-instance} method copy a prototype instance.) Implementations are permitted to optimize default initial value forms for initialization arguments associated with slots by not actually creating the complete initialization argument list when the only method that would receive the complete list is the method on {\bf standard-object}. In this case default initial value forms can be treated like {\bf :initform} forms. This optimization has no visible effects other than a performance improvement. \label See Also: ``Object Creation and Initialization'' ``Rules for Initialization Arguments'' ``Declaring the Validity of Initialization Arguments'' {\bf initialize-instance reinitialize-instance update-instance-for-redefined-class update-instance-for-different-class slot-boundp slot-makunbound} \endcom \begincom{slot-boundp}\ftype{Function} \label Purpose: The function {\bf slot-boundp} tests whether a specific slot in an instance is bound. \label Syntax: \Defun {slot-boundp} {instance slot-name} \label Arguments: The arguments are the instance and the name of the slot. \label Values: The function {\bf slot-boundp} returns true or false. \label Remarks: The function {\bf slot-boundp} allows for writing {\bf :after} methods on {\bf initialize-instance} in order to initialize only those slots that have not already been bound. If no slot of the given name exists in the instance, {\bf slot-missing} is called as follows:\hfil\break {\tt (slot-missing (class-of {\it instance\/}) {\it instance slot-name\/} 'slot-boundp)} The function {\bf slot-boundp} is implemented using {\bf slot-boundp-using-class}. \label See Also: {\bf slot-missing} \endcom \begincom{slot-exists-p}\ftype{Function} \label Purpose: The function {\bf slot-exists-p} tests whether the specified object has a slot of the given name. \label Syntax: \Defun {slot-exists-p} {object slot-name} \label Arguments: The {\it object\/} argument is any object. The {\it slot-name\/} argument is a symbol. \label Values: The function {\bf slot-exists-p} returns true or false. \label Remarks: The function {\bf slot-exists-p} is implemented using {\bf slot-exists-p-using-class}. \endcom \begincom{slot-makunbound}\ftype{Function} \label Purpose: The function {\bf slot-makunbound} restores a slot in an instance to the unbound state. \label Syntax: \Defun {slot-makunbound} {instance slot-name} \label Arguments: The arguments to {\bf slot-makunbound} are the instance and the name of the slot. \label Values: The instance is returned as the result. \label Remarks: If no slot of the given name exists in the instance, {\bf slot-missing} is called as follows:\hfil\break {\tt (slot-missing (class-of {\it instance\/}) {\it instance slot-name\/} 'slot-makunbound)} The function {\bf slot-makunbound} is implemented using {\bf slot-makunbound-using-class}. \label See Also: {\bf slot-missing} \endcom \begincom{slot-missing}\ftype{Standard Generic Function} \label Purpose: The generic function {\bf slot-missing} is invoked when an attempt is made to access a slot in an object whose metaclass is {\bf standard-class} and the name of the slot provided is not a name of a slot in that class. The default method signals an error. The generic function {\bf slot-missing} is not intended to be called by programmers. Programmers may write methods for it. \label Syntax: \Defgen {slot-missing} {class object slot-name operation {\opt} new-value} \label Method Signatures: \Defmeth {slot-missing} {\vtop{\hbox{({\it class\/} t) {\it object slot-name}} \hbox{{\it operation\/} {\opt} {\it new-value}}}} \label Arguments: The required arguments to {\bf slot-missing} are the class of the object that is being accessed, the object, the slot name, and a symbol that indicates the operation that caused {\bf slot-missing} to be invoked. The optional argument to {\bf slot-missing} is used when the operation is attempting to set the value of the slot. \label Values: If a method written for {\bf slot-missing} returns values, these values get returned as the values of the original function invocation. \label Remarks: The generic function {\bf slot-missing} may be called during evaluation of {\bf slot-value}, {\bf (setf slot-value)}, {\bf slot-boundp}, and {\bf slot-makunbound}. For each of these operations the corresponding symbol for the {\it operation\/} argument is {\bf slot-value}, {\bf setf}, {\bf slot-boundp}, and {\bf slot-makunbound} respectively. The set of arguments (including the class of the instance) facilitates defining methods on the metaclass for {\bf slot-missing}. \endcom \begincom{slot-unbound}\ftype{Standard Generic Function} \label Purpose: The generic function {\bf slot-unbound} is called when an unbound slot is read in an instance whose metaclass is {\bf standard-class}. The default method signals an error. The generic function {\bf slot-unbound} is not intended to be called by programmers. Programmers may write methods for it. The function {\bf slot-unbound} is called only by the function {\bf slot-value-using-class} and thus indirectly by {\bf slot-value}. \label Syntax: \Defgen {slot-unbound} {class instance slot-name} \label Method Signatures: \Defmeth {slot-unbound} {({\it class\/} t) {\it instance slot-name}} \label Arguments: The arguments to {\bf slot-unbound} are the class of the instance whose slot was accessed, the instance itself, and the name of the slot. \label Values: If a method written for {\bf slot-unbound} returns values, these values get returned as the values of the original function invocation. \label Remarks: An unbound slot may occur if no {\bf :initform} form was specified for the slot and the slot value has not been set, or if {\bf slot-makunbound} has been called on the slot. \label See Also: {\bf slot-makunbound} \endcom \begincom{slot-value}\ftype{Function} \label Purpose: The function {\bf slot-value} returns the value contained in the slot {\it slot-name\/} of the given object. If there is no slot with that name, {\bf slot-missing} is called. If the slot is unbound, {\bf slot-unbound} is called. The macro {\bf setf} can be used with {\bf slot-value} to change the value of a slot. \label Syntax: \Defun {slot-value} {object slot-name} \label Arguments: The arguments are the object and the name of the given slot. \label Values: The result is the value contained in the given slot. \label Remarks: If an attempt is made to read a slot and no slot of the given name exists in the instance, {\bf slot-missing} is called as follows: {\tt (slot-missing (class-of {\it instance\/}) {\it instance slot-name\/} 'slot-value)} If an attempt is made to write a slot and no slot of the given name exists in the instance, {\bf slot-missing} is called as follows: {\tt (slot-missing (class-of {\it instance\/}) {\it instance slot-name\/} 'setf {\it new-value\/})} The function {\bf slot-value} is implemented using {\bf slot-value-using-class}. Implementations may optimize {\bf slot-value} by compiling it inline. \label See Also: {\bf slot-missing} {\bf slot-unbound} \endcom \begincom{symbol-macrolet}\ftype{Macro} \label Purpose: The macro {\bf symbol-macrolet} provides a mechanism for the substitution of forms for variable names within a lexical scope. \label Syntax: \Defmac {symbol-macrolet} {\paren{\star{\paren{symbol expansion\/}}} {\body} {\it body\/}} \label Arguments: The {\it symbol\/} argument specifies the symbol with which the form specified by the {\it expansion\/} argument is to be associated. \label Values: The result returned is that obtained by executing the forms specified by the {\it body\/} argument. \label Examples: \screen! (symbol-macrolet ((x 'foo)) (list x (let ((x 'bar)) x))) ;;; The result is (foo bar), not (foo foo). ;;; The expansion is (list 'foo (let ((x 'bar)) x)), ;;; not (list 'foo (let (('foo 'bar)) 'foo)). (symbol-macrolet ((x (1+ x))) (print x)) ;;; The expansion is (print (1+ x)), ;;; not (print (1+ (1+ (1+ .... \endscreen! \label Remarks: The lexical scope of {\bf symbol-macrolet} is {\it body\/}; it does not include {\it expansion}. Each reference to {\it symbol\/} as a variable within the lexical scope of {\bf symbol-macrolet} is replaced by {\it expansion\/} (not the result of evaluating {\it expansion\/}). The use of {\bf symbol-macrolet} can be shadowed by {\bf let}. In other words, {\bf symbol-macrolet} only substitutes for occurrences of {\it symbol\/} that would be in the scope of a lexical binding of {\it symbol\/} surrounding the body. The macro {\bf symbol-macrolet} is the basic mechanism that is used to implement {\bf with-slots}. When the body of the {\bf symbol-macrolet} form is expanded, any use of {\bf setq} to set the value of one of the specified variables is converted to a use of {\bf setf}. \label See Also: {\bf with-slots} \endcom \begincom{update-instance-for-different-class}\ftype{Standard Generic Function} \label Purpose: The generic function {\bf update-instance-for-different-class} is not intended to be called by programmers. Programmers may write methods for it. The function {\bf update-instance-for-different-class} is called only by the function {\bf change-class}. The system-supplied primary method on {\bf update-instance-for-different-class} checks the validity of initialization arguments and signals an error if an initialization argument is supplied that is not declared as valid. This method then initializes slots with values according to the initialization arguments, and initializes the newly added slots with values according to their {\bf :initform} forms. It does this by calling the generic function {\bf shared-initialize} with the following arguments: the instance, a list of names of the newly added slots, and the initialization arguments it received. Newly added slots are those local slots for which no slot of the same name exists in the previous class. Methods for {\bf update-instance-for-different-class} can be defined to specify actions to be taken when an instance is updated. If only {\bf :after} methods for {\bf update-instance-for-different-class} are defined, they will be run after the system-supplied primary method for initialization and therefore will not interfere with the default behavior of {\bf update-instance-for-different-class}. \label Syntax: \Defgen {update-instance-for-different-class} {previous current {\tt \&rest {\it initargs}}} \label Method Signatures: \Defmeth {update-instance-for-different-class} {\vtop{\hbox{({\it previous\/} standard-object)} \hbox{({\it current\/} standard-object)} \hbox{{\tt \&rest {\it initargs}}}}} \label Arguments: The arguments to {\bf update-instance-for-different-class} are computed by {\bf change-class}. When {\bf change-class} is invoked on an instance, a copy of that instance is made; {\bf change-class} then destructively alters the original instance. The first argument to {\bf update-instance-for-different-class}, {\it previous\/}, is that copy; it holds the old slot values temporarily. This argument has dynamic extent within {\bf change-class}; if it is referenced in any way once {\bf update-instance-for-different-class} returns, the results are undefined. The second argument to {\bf update-instance-for-different-class}, {\it current}, is the altered original instance. \vfill\eject The intended use of {\it previous\/} is to extract old slot values by using {\bf slot-value} or {\bf with-slots} or by invoking a reader generic function, or to run other methods that were applicable to instances of the original class. The {\it initargs\/} argument consists of alternating initialization argument names and values. \label Values: The value returned by {\bf update-instance-for-different-class} is ignored by {\bf change-class}. \label Examples: See the example for the function {\bf change-class}. \label Remarks: Initialization arguments are declared as valid by using the {\bf :initarg} option to {\bf defclass}, or by defining methods for {\bf update-instance-for-different-class} or {\bf shared-initialize}. The keyword name of each keyword parameter specifier in the lambda-list of any method defined on {\bf update-instance-for-different-class} or {\bf shared-initialize} is declared as a valid initialization argument name for all classes for which that method is applicable. Methods on {\bf update-instance-for-different-class} can be defined to initialize slots differently from {\bf change-class}. The default behavior of {\bf change-class} is described in ``Changing the Class of an Instance.'' \label See Also: ``Changing the Class of an Instance'' ``Rules for Initialization Arguments'' ``Declaring the Validity of Initialization Arguments'' {\bf change-class shared-initialize} \endcom \begincom{update-instance-for-redefined-class}\ftype{Standard Generic Function} \label Purpose: The generic function {\bf update-instance-for-redefined-class} is not intended to be called by programmers. Programmers may write methods for it. The generic function {\bf update-instance-for-redefined-class} is called by the mechanism activated by {\bf make-instances-obsolete}. The system-supplied primary method on {\bf update-instance-for-different-class} checks the validity of initialization arguments and signals an error if an initialization argument is supplied that is not declared as valid. This method then initializes slots with values according to the initialization arguments, and initializes the newly added slots with values according to their {\bf :initform} forms. It does this by calling the generic function {\bf shared-initialize} with the following arguments: the instance, a list of names of the newly added slots, and the initialization arguments it received. Newly added slots are those local slots for which no slot of the same name exists in the old version of the class. \label Syntax: \Defgen {update-instance-for-redefined-class} {\vtop{\hbox{instance} \hbox{added-slots discarded-slots} \hbox{property-list} \hbox{{\tt \&rest {\it initargs}}}}} \label Method Signatures: \Defmeth {update-instance-for-redefined-class} {\vtop{\hbox{({\it instance\/} standard-object)} \hbox{\it added-slots discarded-slots} \hbox{\it property-list} \hbox{\&rest {\it initargs}}}} \label Arguments: When {\bf make-instances-obsolete} is invoked or when a class has been redefined and an instance is being updated, a property list is created that captures the slot names and values of all the discarded slots with values in the original instance. The structure of the instance is transformed so that it conforms to the current class definition. The arguments to {\bf update-instance-for-redefined-class} are this transformed instance, a list of the names of the new slots added to the instance, a list of the names of the old slots discarded from the instance, and the property list containing the slot names and values for slots that were discarded and had values. Included in this list of discarded slots are slots that were local in the old class and are shared in the new class. The {\it initargs\/} argument consists of alternating initialization argument names and values. \label Values: The value returned by {\bf update-instance-for-redefined-class} is ignored. \label Remarks: Initialization arguments are declared as valid by using the {\bf :initarg} option to {\bf defclass}, or by defining methods for {\bf update-instance-for-redefined-class} or {\bf shared-initialize}. The keyword name of each keyword parameter specifier in the lambda-list of any method defined on {\bf update-instance-for-redefined-class} or {\bf shared-initialize} is declared as a valid initialization argument name for all classes for which that method is applicable. \label Examples: \screen! (defclass position () ()) (defclass x-y-position (position) ((x :initform 0 :accessor position-x) (y :initform 0 :accessor position-y))) ;;; It turns out polar coordinates are used more than Cartesian ;;; coordinates, so the representation is altered and some new ;;; accessor methods are added. (defmethod update-instance-for-redefined-class :before ((pos x-y-position) added deleted plist &key) ;; Transform the x-y coordinates to polar coordinates ;; and store into the new slots. (let ((x (getf plist 'x)) (y (getf plist 'y))) (setf (position-rho pos) (sqrt (+ (* x x) (* y y))) (position-theta pos) (atan y x)))) (defclass x-y-position (position) ((rho :initform 0 :accessor position-rho) (theta :initform 0 :accessor position-theta))) ;;; All instances of the old x-y-position class will be updated ;;; automatically. ;;; The new representation is given the look and feel of the old one. (defmethod position-x ((pos x-y-position)) (with-slots (rho theta) pos (* rho (cos theta)))) \endscreen! \vfill\eject \screen! (defmethod (setf position-x) (new-x (pos x-y-position)) (with-slots (rho theta) pos (let ((y (position-y pos))) (setq rho (sqrt (+ (* new-x new-x) (* y y))) theta (atan y new-x)) new-x))) (defmethod position-y ((pos x-y-position)) (with-slots (rho theta) pos (* rho (sin theta)))) (defmethod (setf position-y) (new-y (pos x-y-position)) (with-slots (rho theta) pos (let ((x (position-x pos))) (setq rho (sqrt (+ (* x x) (* new-y new-y))) theta (atan new-y x)) new-y))) \endscreen! \label See Also: ``Redefining Classes'' ``Rules for Initialization Arguments'' ``Declaring the Validity of Initialization Arguments'' {\bf make-instances-obsolete shared-initialize } \endcom \begincom{with-accessors}\ftype{Macro} \label Purpose: The macro {\bf with-accessors} creates a lexical environment in which specified slots are lexically available through their accessors as if they were variables. The macro {\bf with-accessors} invokes the appropriate accessors to access the specified slots. Both {\bf setf} and {\bf setq} can be used to set the value of the slot. \label Syntax: \Defmac {with-accessors} {{\paren{\star{\curly{slot-entry\/}}}} instance-form\/ {\body} body} {\it slot-entry\/}::$=$ {\paren{variable-name accessor-name\/}} \label Values: The result returned is that obtained by executing the forms specified by the {\it body\/} argument. \label Examples: \screen! (with-accessors ((x position-x) (y position-y)) p1 (setq x y)) \endscreen! \label Remarks: A {\bf with-accessors} expression of the form: $$\openup1\jot\vbox{\settabs\+\cr \+{\tt (with-accessors} (${\hbox{{\it slot-entry}}}\sub 1% \ldots{\hbox{{\it slot-entry}}}\sub n$) {\it instance\/} ${\hbox{{\it form}}}\sub 1% \ldots{\hbox{{\it form}}}\sub k$)\cr}$$ \noindent expands into the equivalent of $$\openup1\jot\vbox{\settabs\+\cr \+{\tt (}&{\tt let ((}$in$ {\it instance}{\tt ))}\cr \+&{\tt (symbol-macrolet (}${\hbox{{\it Q}}}\sub 1\ldots% {\hbox{{\it Q}}}\sub n${\tt )} ${\hbox{{\it form}}}\sub 1% \ldots{\hbox{{\it form}}}\sub k${\tt ))}\cr}$$ \noindent where ${\hbox{{\it Q}}}\sub i$ is $${\vbox{\hbox{{\tt (}${\hbox{{\it variable-name}}}\sub i$ % {\tt (${\hbox{{\it accessor-name}}}\sub{i}\ in$))}}}}$$ \vfill\eject \label See Also: {\bf with-slots symbol-macrolet} \endcom \begincom{with-added-methods}\ftype{Special Form} \label Purpose: The {\bf with-added-methods} special form produces new generic functions and establishes new lexical function definition bindings. Each generic function is created by adding the set of methods specified by its method definitions to a copy of the lexically visible generic function of the same name and its methods. If such a generic function does not already exist, a new generic function is created; this generic function has lexical scope. The special form {\bf with-added-methods} is used to define functions whose names are meaningful only locally and to execute a series of forms with these function definition bindings. The names of functions defined by {\bf with-added-methods} have lexical scope; they retain their local definitions only within the body of the {\bf with-added-methods} construct. Any references within the body of the {\bf with-added-methods} construct to functions whose names are the same as those defined within the {\bf with-added-methods} form are thus references to the local functions instead of to any global functions of the same names. The scope of these generic function definition bindings includes the method bodies themselves as well as the body of the {\bf with-added-methods} construct. \label Syntax: \Defspec {with-added-methods} { \vtop{\hbox{\lparen function-specifier lambda-list\/} \hbox{\ $\lbrack\!\lbrack\downarrow\!$ option $\vert$ \star{method-description}\thinspace $\rbrack\!\rbrack$\thinspace\rparen} \hbox{\star\form}}} \Vskip 1pc! {\it function-specifier\/}::$=$ \curly{{\it symbol\/} $\vert$ {\tt (setf {\it symbol\/})}} \Vskip 1pc! {\it option\/}::$=$ {\tt\vtop{\hbox{(:argument-precedence-order \plus{\curly{parameter-name}}) $\vert$} \hbox{(declare \plus{\curly{declaration\/}}) $\vert$} \hbox{(:documentation {\it string\/}) $\vert$} \hbox{(:method-combination {\it symbol\/} \star{\curly{arg\/}}) $\vert$} \hbox{(:generic-function-class {\it class-name\/}) $\vert$} \hbox{(:method-class {\it class-name\/})}}} \Vskip 1pc! {\it method-description\/}::$=$ {\tt (:method} \vtop{\hbox{\it \star{\curly{method-qualifier\/}} specialized-lambda-list\/} \hbox{\star{\curly{declaration\/ $\vert$ documentation\/}} \star{\curly{form\/}}{\tt )}}} \vfill\eject \label Arguments: The {\it function-specifier\/}, {\it option}, {\it method-qualifier}, and {\it specialized-lambda-list\/} arguments are the same as for {\bf defgeneric}. The body of each method is enclosed in an implicit block. If {\it function-specifier\/} is a symbol, this block bears the same name as the generic function. If {\it function-specifier\/} is a list of the form {\tt (setf {\it symbol\/})}, the name of the block is {\it symbol}. \label Values: The result returned by {\bf with-added-methods} is the value or values returned by the last form executed. If no forms are specified, {\bf with-added-methods} returns {\bf nil}. \label Remarks: If a generic function with the given name already exists, the lambda-list specified in the {\bf with-added-methods} form must be congruent with the lambda-lists of all existing methods on that function as well as with the lambda-lists of all methods defined by the {\bf with-added-methods} form; otherwise an error is signaled. If {\it function-specifier\/} specifies an existing generic function that has a different value for any of the following {\it option\/} arguments, the copy of that generic function is modified to have the new value: {\bf :argument-precedence-order}, {\bf declare}, {\bf :documentation}, {\bf :generic-function-class}, {\bf :method-combination}. If {\it function-specifier\/} specifies an existing generic function that has a different value for the {\bf :method-class} {\it option\/} argument, that value is changed in the copy of that generic function, but any methods copied from the existing generic function are not changed. If a function of the given name already exists, that function is copied into the default method for a generic function of the given name. Note that this behavior differs from that of {\bf defgeneric}. If a macro or special form of the given name already exists, an error is signaled. If there is no existing generic function, the {\it option\/} arguments have the same default values as the {\it option\/} arguments to {\bf defgeneric}. %\vfill\eject \label See Also: {\bf generic-labels generic-flet defmethod defgeneric ensure-generic-function} \endcom \begincom{with-slots}\ftype{Macro} \label Purpose: The macro {\bf with-slots} creates a lexical context for referring to specified slots as though they were variables. Within such a context the value of the slot can be specified by using its slot name, as if it were a lexically bound variable. Both {\bf setf} and {\bf setq} can be used to set the value of the slot. The macro {\bf with-slots} translates an appearance of the slot name as a variable into a call to {\bf slot-value}. \label Syntax: \Defmac {with-slots} {{\paren{\star{\curly{slot-entry\/}}}} instance-form\/ {\body} body} {\it slot-entry\/}::$=$ {\it slot-name $\vert$ {\paren{variable-name slot-name\/}}} \label Values: The result returned is that obtained by executing the forms specified by the {\it body\/} argument. \label Examples: \screen! (with-slots (x y) position-1 (sqrt (+ (* x x) (* y y)))) (with-slots ((x1 x) (y1 y)) position-1 (with-slots ((x2 x) (y2 y)) position-2 (psetf x1 x2 y1 y2)))) (with-slots (x y) position (setq x (1+ x) y (1+ y))) \endscreen! %\vfill\eject \label Remarks: A {\bf with-slots} expression of the form: $$\openup1\jot\vbox{\settabs\+\cr \+{\tt (with-slots} (${\hbox{{\it slot-entry}}}\sub 1% \ldots{\hbox{{\it slot-entry}}}\sub n$) {\it instance\/} ${\hbox{{\it form}}}\sub 1% \ldots{\hbox{{\it form}}}\sub k$)\cr}$$ \noindent expands into the equivalent of $$\openup1\jot\vbox{\settabs\+\cr \+{\tt (}&{\tt let ((}$in$ {\it instance}{\tt ))}\cr \+&{\tt (symbol-macrolet (}${\hbox{{\it Q}}}\sub 1\ldots% {\hbox{{\it Q}}}\sub n${\tt )} ${\hbox{{\it form}}}\sub 1% \ldots{\hbox{{\it form}}}\sub k${\tt ))}\cr}$$ \noindent where ${\hbox{{\it Q}}}\sub i$ is $$\vbox{\hbox{{\tt (}${\hbox{{\it slot-entry}}}\sub i$ {\tt (slot-value }$in$ '${\hbox{{\it slot-entry}}}\sub i${\tt ))}}}$$ \noindent if ${\hbox{{\it slot-entry}}}\sub i$ is a symbol and is $${\vbox{\hbox{{\tt (}${\hbox{{\it variable-name}}}\sub i$ % {\tt (slot-value }$in$ '${\hbox{{\it slot-name}}}\sub i${\tt ))}}}}$$ \noindent if ${\hbox{{\it slot-entry}}}\sub i$ is of the form $$\vbox{\hbox{{\tt (}${\hbox{{\it variable-name}}}\sub i$ % ${\hbox{{\it slot-name}}}\sub i${\tt )}}}$$ \label See Also: {\bf with-accessors symbol-macrolet} \endcom \endChapter \bye