<?xml version="1.0" encoding="UTF-8"?>

<chapter id="mop-chap"><title>Meta-Object Protocol</title>
<subtitle>Adapted from chapters 5 and 6 of &amop;</subtitle>

<section id="mop-intro"><title>Introduction</title>

<para>The &clos; specification (&ansi-cl; Chanpter 7) describes the
standard Programmer Interface for the &cl; Object System (&clos;).  This
document extends that specification by defining a metaobject protocol
for &clos; - that is, a description of &clos; itself as an extensible
&clos; program.  In this description, the fundamental elements of &clos;
programs (classes, slot definitions, generic functions, methods,
specializers and method combinations) are represented by first-class
objects.  The behavior of &clos; is provided by these objects, or, more
precisely, by methods specialized to the classes of these objects.
</para>

<para>Because these objects represent pieces of &clos; programs, and
because their behavior provides the behavior of the &clos; language
itself, they are considered meta-level objects or metaobjects.  The
protocol followed by the metaobjects to provide the behavior of &clos;
is called the &clos; <quote>Metaobject Protocol</quote> (MOP).</para>

<section id="mop-intro-notation"><title>Notation</title>

<para>The description of functions follows the same form as used in the
&clos; specification.  The description of generic functions is similar
to that in the &clos; specification, but some minor changes have been
made in the way methods are presented.</para>

<para>The following is an example of the format for the syntax
description of a generic function:
<programlisting language="lisp">
(<function>gf1</function> &x-r; &y-r; &optional-amp; &v-r; &key-amp; &k-r;)
</programlisting></para>

<para>This description indicates that <function>gf1</function> is a
generic function with two required parameters, &x-r; and &y-r;, an
optional parameter &v-r; and a keyword parameter &k-r;.</para>

<para>The description of a generic function includes a description of
its behavior.  This provides the general behavior, or protocol of the
generic function.  All methods defined on the generic function, both
portable and specified, must have behavior consistent with this
description.</para>

<para>Every generic function described here is an instance of the class
&standard-generic-function-t; and uses the &standard; method
combination.</para>

<para>The description of a generic function also includes descriptions
of the specified methods for that generic function.  In the description
of these methods, a <firstterm>method signature</firstterm> is used to
describe the parameters and parameter specializers of each method. The
following is an example of the format for a method signature:
<programlisting language="lisp">
<literal role="method">(<function>gf1</function> (&x-r; &class;) &y-r; &optional-amp; &v-r; &key-amp; &k-r;)</literal>
</programlisting></para>

<para>This signature indicates that this primary method on the generic
function <function>gf1</function> has two required parameters, named
&x-r; and &y-r;.  In addition, there is an optional parameter &v-r; and
a keyword parameter &k-r;.  This signature also indicates that the
method's parameter specializers are the classes &class; and &t-t;.
</para>

<para>The description of each method includes a description of the
behavior particular to that method.</para>

<para>An abbreviated syntax is used when referring to a method defined
elsewhere in the document.  This abbreviated syntax includes the name of
the generic function, the qualifiers, and the parameter specializers.  A
reference to the method with the signature shown above is written as:
<literal role="method"><function>gf1</function> (&class; &t-t;)</literal>.
</para>

</section><!-- mop-intro-notation -->

<section id="mop-package"><title>Package</title>

<para>The package exporting the &mop; symbols is unspecified.</para>

<note>&clisp-only;<simpara>The symbols specified by the &mop; are
  exported from the package &clos-pac; and &re-export;ed from the package
  &ext-pac;.</simpara></note>

<para>The package exporting the &mop; symbols is different in other
implementations: In &sbcl; it is the package
 <quote role="package">SB-MOP</quote>;
in &openmcl; it is the package
 <quote role="package">OPENMCL-MOP</quote>.</para>

</section><!-- mop-package -->

</section><!-- mop-intro -->

<section id="mop-overview"><title>Overview</title>

<section id="mop-metaobjects"><title>Metaobjects</title>

<para>For each kind of program element there is a corresponding
 <firstterm>basic metaobject class
  <indexterm id="mop-ba-mo-cl" significance="preferred">
   <primary>metaobject class</primary><secondary>basic</secondary>
 </indexterm></firstterm>.
These are the classes: &class;, &slot-definition-t;,
&generic-function-t;, &method-t; and &method-combination-t;.
A <firstterm>metaobject class<indexterm id="mo-cl" significance="preferred">
   <primary>metaobject class</primary></indexterm></firstterm>
is a subclass of exactly one of these classes.
The results are undefined if an attempt is made to define a &class;
that is a subclass of more than one basic metaobject class.
A <firstterm>metaobject<indexterm id="mop-mo" significance="preferred">&mo-prim;
 </indexterm></firstterm> is an instance of a metaobject class.</para>

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

<para>Much of the information associated with a metaobject is in the
form of connections to other metaobjects.  This interconnection means
that the role of a metaobject is always based on that of other
metaobjects.  As an introduction to this interconnected structure, this
section presents a partial enumeration of the kinds of information
associated with each kind of metaobject.  More detailed information is
presented later.</para>

<section id="mop-mo-classes"><title>Classes</title>

<para>A <firstterm>class metaobject
  <indexterm id="mop-class-mo" significance="preferred">&mo-prim;
   <secondary>class</secondary></indexterm></firstterm>
determines the structure and the default behavior of its instances.
The following information is associated with &c-mo;s:

<itemizedlist>
<listitem><simpara>The name, if there is one, is available as an object.
</simpara></listitem>
<listitem><simpara>The direct subclasses, direct superclasses and class
  precedence list are available as lists of &c-mo;s.</simpara></listitem>
<listitem><simpara>The slots defined directly in the class are available
  as a list of &dsdmo;s.  The slots which are accessible in instances of
  the class are available as a list of &esdmo;s.</simpara></listitem>
<listitem><simpara>The methods which use the class as a specializer, and
  the generic functions associated with those methods are available as
  lists of method and &gfmo;s respectively.</simpara></listitem>
&doc-li;</itemizedlist></para>
<simpara>See also <xref linkend="mop-classes"/></simpara>
</section><!-- mop-mo-classes -->

<section id="mop-mo-slot-defs"><title>Slot Definitions</title>

<para>A <firstterm>slot definition metaobject
  <indexterm id="mop-slot-def-mo" significance="preferred">&mo-prim;
   <secondary>slot definition</secondary></indexterm></firstterm>
 contains information about the definition of a slot.
There are two kinds of &sdmo;s:<variablelist>
<varlistentry><term><firstterm>direct<indexterm id="mop-dsd-mo">
    &mo-prim;<secondary>slot definition</secondary><tertiary>direct</tertiary>
  </indexterm></firstterm> &sdmo;</term>
 <listitem><simpara>Used to represent the direct definition of a slot in
  a class. This corresponds roughly to the slot specifiers found in
  &defclass; forms.</simpara></listitem></varlistentry>
<varlistentry><term><firstterm>effective<indexterm id="mop-esd-mo">
    &mo-prim;<secondary>slot definition</secondary>
    <tertiary>effective</tertiary></indexterm></firstterm> &sdmo;</term>
 <listitem><simpara>Used to represent information, including inherited
   information, about a slot which is accessible in instances of a
   particular class.</simpara></listitem></varlistentry></variablelist></para>

<para>Associated with each &c-mo; is a list of &dsdmo;s representing the
slots defined directly in the class.
Also associated with each &c-mo; is a list of &esdmo;s representing the
set of slots accessible in instances of that class.</para>

<para>The following information is associated with both direct and
effective slot definitions metaobjects:<itemizedlist>
<listitem><simpara>The name, allocation, and type are available as forms
  that could appear in a &defclass; form.</simpara></listitem>
<listitem><simpara>The initialization form, if there is one, is
  available as a form that could appear in a &defclass; form.  The
  initialization form together with its &lex-env; is available
  as a function of no arguments which, when called, returns the result
  of evaluating the initialization form in its &lex-env;. This
  is called the <firstterm>initfunction</firstterm> of the slot.
</simpara></listitem>
<listitem><simpara>The slot filling initialization arguments are
  available as a list of symbols.</simpara></listitem>
&doc-li;</itemizedlist></para>

<para>Certain other information is only associated with &dsdmo;s.
 This information applies only to the direct definition of the slot in
 the class (it is not inherited).
<itemizedlist><listitem><simpara>The function names of those generic
  functions for which there are automatically generated reader and
  writer methods.  This information is available as lists of function
  names.  Any accessors specified in the &defclass; form are broken down
  into their equivalent readers and writers in the direct slot
  definition.</simpara></listitem></itemizedlist></para>

<para>Information, including inherited information, which applies to the
definition of a slot in a particular class in which it is accessible is
associated only with &esdmo;s.
<itemizedlist><listitem><simpara>For certain slots, the location of the
slot in instances of the class is available.
</simpara></listitem></itemizedlist></para>
<simpara>See also <xref linkend="mop-sd"/></simpara>
</section><!-- mop-mo-slot-defs -->

<section id="mop-mo-gen-funs"><title>Generic Functions</title>

<para>A <firstterm>generic function metaobject
  <indexterm id="mop-gen-fun-mo" significance="preferred">&mo-prim;
   <secondary>generic function</secondary></indexterm></firstterm>
 contains information about a generic function over and above the
 information associated with each of the generic function's methods.
<itemizedlist><listitem><simpara>The name is available as a function name.
</simpara></listitem>
<listitem><simpara>The methods associated with the generic function are
  available as a list of &m-mo;s.</simpara></listitem>
<listitem><simpara>The default class for this generic function's &m-mo;s
  is available as a &c-mo;.</simpara></listitem>
<listitem><simpara>The &lalist; is available as a &list-t;.
</simpara></listitem>
<listitem><simpara>The method combination is available as a &mcmo;.
</simpara></listitem>
<listitem><simpara>The argument precedence order is available as a
  permutation of those symbols from the &lalist; which name the
  required arguments of the generic function.</simpara></listitem>
<listitem><simpara>The <quote>declarations</quote> are available as a
 list of &declspec-glo;s.</simpara>
<note><simpara>There is a slight misnomer in the naming of functions and
 options in this document: Where the term <quote>declaration</quote> is
 used, actually a &declspec-glo; is meant.
</simpara></note></listitem>
&doc-li;</itemizedlist></para>
<simpara>See also <xref linkend="mop-gf"/></simpara>
</section><!-- mop-mo-gen-funs -->

<section id="mop-mo-methods"><title>Methods</title>

<para>A <firstterm>method metaobject
  <indexterm id="mop-method-mo" significance="preferred">&mo-prim;
   <secondary>method</secondary></indexterm></firstterm>
 contains information about a specific &method-t;.
<itemizedlist><listitem><simpara>The qualifiers are available as a
   &list-t; of of non-&nil; atoms.</simpara></listitem>
 <listitem><simpara>The &lalist; is available as a &list-t;.
</simpara></listitem>
<listitem><simpara>The specializers are available as a list of
  specializer metaobjects.</simpara></listitem>
<listitem><simpara>The function is available as a &function-t;.  This
  function can be applied to arguments and a list of next methods using
  &apply; or &funcall;.</simpara></listitem>
<listitem><simpara>When the method is associated with a generic
  function, that &gfmo; is available.  A method can be associated with
  at most one generic function at a time.</simpara></listitem>
&doc-li;</itemizedlist></para>
<simpara>See also <xref linkend="mop-meth"/></simpara>
</section><!-- mop-mo-methods -->

<section id="mop-mo-spec"><title>Specializers</title>

<para>A <firstterm>specializer metaobject
  <indexterm id="spec-mo" significance="preferred">&mo-prim;
   <secondary>specializer</secondary></indexterm></firstterm>
 represents the specializers of a &method-t;.
 &c-mo;s are themselves specializer metaobjects.  A special
 kind of specializer metaobject is used for &eql-t; specializers.</para>
<simpara>See also <xref linkend="mop-specializers"/></simpara>
</section><!-- mop-mo-spec -->

<section id="mop-mo-meth-combs"><title>Method Combinations</title>

<para>A <firstterm>method combination metaobject
  <indexterm id="mop-meth-comp-mo" significance="preferred">&mo-prim;
   <secondary>method combination</secondary></indexterm></firstterm>
 represents the information about the method combination being used by a
 generic function.</para>

<note><para>This document does not specify the structure of &mcmo;s.
</para></note>
<simpara>See also <xref linkend="mop-meth-comb"/></simpara>
</section><!-- mop-mo-meth-combs -->
</section><!-- mop-metaobjects -->

<section id="mop-mo-cl-inheritance">
 <title>Inheritance Structure of Metaobject Classes</title>

<figure id="mop-mo-cl-inheritance-fig">
 <title>Inheritance structure of metaobject classes</title>
 <mediaobject><imageobject>
   <imagedata width="100%" scalefit="1" fileref="mop-classes-all.png"/>
</imageobject></mediaobject></figure>

<para>The inheritance structure of the specified metaobject classes is
 shown in <xref linkend="mop-inherit-struct"/>. The class of every class
 shown is &standard-class; except for the classes &t-t; and &function-t;,
 which are instances of the class &built-in-class;, and the classes
 &generic-function-t; and &standard-generic-function-t;, which are
 instances of the class &funcallable-standard-class;.
<table id="mop-inherit-struct"><title>Direct Superclass Relationships
  Among The Specified Metaobject Classes</title>
 <tgroup cols="4" colsep="1" rowsep="1" align="center">
  <thead><row><entry>Metaobject Class</entry>
    <entry>Abstract</entry><entry>Subclassable</entry>
    <entry>Direct Superclasses</entry></row></thead>
  <tbody><row><entry>&standard-object-t;</entry>&no-en; &yes-en;
    <entry>(&t-t;)</entry></row>
   <row><entry>&funcallable-standard-object-t;</entry>&no-en; &yes-en;
    <entry>(&standard-object-t; &function-t;)</entry></row>
   <row><entry>&metaobject-t;</entry>&yes-en; &no-en;
    <entry>(&standard-object-t;)</entry></row>
   <row><entry>&generic-function-t;</entry>&yes-en; &no-en;
    <entry>(&metaobject-t; &funcallable-standard-object-t;)</entry></row>
   <row><entry>&standard-generic-function-t;</entry>&no-en; &yes-en;
    <entry>(&generic-function-t;)</entry></row>
   <row><entry>&method-t;</entry>&yes-en; &no-en;
    <entry>(&metaobject-t;)</entry></row>
   <row><entry>&standard-method-t;</entry>&no-en; &yes-en;
    <entry>(&method-t;)</entry></row>
   <row><entry>&standard-accessor-method-t;</entry>&yes-en; &no-en;
    <entry>(&standard-method-t;)</entry></row>
   <row><entry>&standard-reader-method-t;</entry>&no-en; &yes-en;
    <entry>(&standard-accessor-method-t;)</entry></row>
   <row><entry>&standard-writer-method-t;</entry>&no-en; &yes-en;
    <entry>(&standard-accessor-method-t;)</entry></row>
   <row><entry>&method-combination-t;</entry>&yes-en; &no-en;
    <entry>(&metaobject-t;)</entry></row>
   <row><entry>&slot-definition-t;</entry>&yes-en; &no-en;
    <entry>(&metaobject-t;)</entry></row>
   <row><entry>&dsd-t;</entry>&yes-en; &no-en;
    <entry>(&slot-definition-t;)</entry></row>
   <row><entry>&esd-t;</entry>&yes-en; &no-en;
    <entry>(&slot-definition-t;)</entry></row>
   <row><entry>&standard-slotdef-t;</entry>&yes-en; &no-en;
    <entry>(&slot-definition-t;)</entry></row>
   <row><entry>&standard-dsd-t;</entry>&no-en; &yes-en;
    <entry>(&standard-slotdef-t; &dsd-t;)</entry></row>
   <row><entry>&standard-esd-t;</entry>&no-en; &yes-en;
    <entry>(&standard-slotdef-t; &esd-t;)</entry></row>
   <row><entry>&specializer-t;</entry>&yes-en; &no-en;
    <entry>(&metaobject-t;)</entry></row>
   <row><entry>&eql-specializer-t;</entry>&no-en; &no-en;
    <entry>(&specializer-t;)</entry></row>
   <row><entry>&class;</entry>&yes-en; &no-en;
    <entry>(&specializer-t;)</entry></row>
   <row><entry>&built-in-class;</entry>&no-en; &no-en;
    <entry>(&class;)</entry></row>
   <row><entry>&forward-referenced-class;</entry>&no-en; &no-en;
    <entry>(&class;)</entry></row>
   <row><entry>&standard-class;</entry>&no-en; &yes-en;
    <entry>(&class;)</entry></row>
   <row><entry>&funcallable-standard-class;</entry>&no-en; &yes-en;
    <entry>(&class;)</entry></row>
 </tbody></tgroup></table>
</para>

<para>Each class with a <quote>yes</quote> in the <quote>Abstract</quote>
column is an <emphasis>abstract class</emphasis> and is not intended to
be instantiated.  The results are undefined if an attempt is made to
make an instance of one of these classes with &make-instance;.</para>

<para>Each class with a <quote>yes</quote> in
the <quote>Subclassable</quote> column can be used as direct superclass
for portable programs.  It is not meaningful to subclass a class that
has a <quote>no</quote> in this column.</para>

<note>&clisp-only;<simpara>The class &method-t; is also subclassable: It
  is possible to create subclasses of &method-t; that do not inherit
  from &standard-method-t;.</simpara></note>

<note><title>Implementation dependent: only in &clisp; and some
  other implementations</title>
 <simpara>The class &funcallable-standard-object-t;'s class
  precedence list contains &function-t; before &standard-object-t;, not
  after &standard-object-t;.
  This is the most transparent way to realize the &ansi-cl; requirement
  (see the &ansi-cl; section <ulink role="clhs" url="sec_4-2-2">4.2.2
   <quote>Type Relationships</quote></ulink>)
  that &generic-function-t;'s class precedence list contains
  &function-t; before &standard-object-t;.</simpara></note>

<para>The classes &standard-class;, &standard-dsd-t;, &standard-esd-t;,
 &standard-method-t;, &standard-reader-method-t;,
 &standard-writer-method-t; and &standard-generic-function-t; are called
 <firstterm>standard metaobject
  <indexterm id="std-mo" significance="preferred">&mo-prim;
   <secondary>standard</secondary></indexterm></firstterm> classes.
 For each kind of metaobject, this is the class the user interface
 macros presented in the &clos; use by default.  These are also the
 classes on which user specializations are normally based.</para>

<para>The classes &built-in-class;, &funcallable-standard-class; and
 &forward-referenced-class; are special-purpose &c-mo; classes.
 Built-in classes are instances of the class &built-in-class;.
 The class &funcallable-standard-class; provides a special kind of
 instances described in <xref linkend="mop-sa-funcallable"/>.
 When the definition of a class references another class which has not
 yet been defined, an instance of &forward-referenced-class; is used as
 a stand-in until the class is actually defined.</para>

<note id="forward-referenced-class-clisp">
 <title>Implementation of class &forward-referenced-class; in &clisp;</title>
 <para>The class &forward-referenced-class; is implemented in a way
  that fixes several flaws in the &amop; specification.</para>
 <para>It is not a subclass of &class; and &specializer-t;, just a
  subclass of &metaobject-t;, because forward references to classes are
  not classes and cannot be used as specializers of methods.  An &amop;
  compatibility mode is provided, however, if you set the variable
  <firstterm><varname>CUSTOM:*FORWARD-REFERENCED-CLASS-MISDESIGN*</varname>
   <indexterm id="frc-bad" significance="preferred">
    <primary><varname>*FORWARD-REFERENCED-CLASS-MISDESIGN*</varname></primary>
  </indexterm></firstterm> to &t;.
  In this mode, &forward-referenced-class; is formally a subclass of
  &class; and &specializer-t;, but the behaviour of
  &forward-referenced-class; instances is the same.</para>
 <para>The &amop; says that the first argument of &ensure-class-UC; can
  be a &forward-referenced-class;.
  But from the description of &ensure-class;, it is clear that it can
  only be a class returned by &find-class;, and &ansi-cl; &find-class;
  cannot return a &forward-referenced-class;.</para>
 <para>The &amop; says that &ensure-class-UC; creates a
  &forward-referenced-class; for not-yet-defined class symbols among the
  direct-superclasses list.  But this leads to many
  &forward-referenced-class; with the same name (since they cannot be
  stored and retrieved through &find-class;), and since &change-class;
  preserves the &eq;-ness, after the class is defined, we have many
  class objects with the same name.</para>
 <para>In the direct-superclasses list of non-finalized classes,
  &forward-referenced-class; instances can occur, denoting classes that
  have not yet been defined. When or after such a class gets defined,
  the &forward-referenced-class; instance is replaced with the real
  class.  &clisp; uses simple object replacement, not &change-class;, in
  this process.</para></note>

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

<para>The same is true for &funcallable-standard-class; and
&funcallable-standard-object-t;.</para>

<para>The class &specializer-t; captures only the most basic behavior of
method specializers, and is not itself intended to be instantiated.  The
class &class; is a direct subclass of &specializer-t; reflecting the
property that classes by themselves can be used as method specializers.
The class &eql-specializer-t; is used for &eql-t; specializers.</para>

<section id="mop-ov-impl-and-user-spec">
 <title>Implementation and User Specialization</title>

<para>The purpose of the Metaobject Protocol is to provide users with a
powerful mechanism for extending and customizing the basic behavior of
the &clos;.  As an object-oriented description of the basic &clos;
behavior, the Metaobject Protocol makes it possible to create these
extensions by defining specialized subclasses of existing metaobject
classes.</para>

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

<para>The following additional terminology is used to present these
restrictions:<itemizedlist>
<listitem><simpara>Metaobjects are divided into three categories.  Those
  defined in this document are called <firstterm>specified
   <indexterm id="mo-specified" significance="preferred">&mo-prim;
    <secondary>specified</secondary></indexterm></firstterm>;
  those defined by an implementation but not mentioned in this document
  are called <firstterm>implementation-specific
   <indexterm id="mo-impl" significance="preferred">&mo-prim;
    <secondary>implementation-specific</secondary></indexterm></firstterm>;
  and those defined by a portable program are called <firstterm>portable
   <indexterm id="mo-portable" significance="preferred">&mo-prim;
    <secondary>portable</secondary></indexterm></firstterm>.
</simpara></listitem>
<listitem><simpara>A class &i-r; is <firstterm>interposed
   <indexterm id="class-interposed" significance="preferred">
    <primary>class</primary><secondary>interposed</secondary></indexterm>
  </firstterm> between two other classes &k1-r; and &k2-r; if and only
  if there is some path, following direct superclasses, from the class
  &k1-r; to the class &k2-r; which includes &i-r;.</simpara></listitem>
<listitem><simpara>A method is <firstterm>specialized
   <indexterm id="method-specialized" significance="preferred">
    &me-prim;<secondary>specialized</secondary></indexterm></firstterm>
  to a class if and only if that class is in the list of specializers
  associated with the method; and the method is in the list of methods
  associated with some generic function.</simpara></listitem>
<listitem><simpara>In a given implementation, a specified method is said
  to have been <firstterm>promoted
   <indexterm id="method-promoted" significance="preferred">
    &me-prim;<secondary>promoted</secondary></indexterm></firstterm>
  if and only if the specializers of the method, &x1-r; ... &xn-r;, are
  defined in this specification as the classes &k1-r; ... &kn-r;, but in
  the implementation, one or more of the specializers
  <replaceable>x&sub-l;</replaceable>, is a superclass of the class
  given in the specification <replaceable>k&sub-l;</replaceable>.
</simpara></listitem>
<listitem><para>For a given generic function and set of arguments, a
  method &k2-r; <firstterm>extends
   <indexterm id="method-extends" significance="preferred">
    &me-prim;<secondary>extends</secondary></indexterm></firstterm>
  a method &k1-r; if and only if:
  <orderedlist numeration="lowerroman"><listitem><simpara>&k1-r; and
     &k2-r; are both associated with the given generic function
   </simpara></listitem>
   <listitem><simpara>&k1-r; and &k2-r; are both applicable to the given
     arguments,</simpara></listitem>
   <listitem><simpara>the specializers and qualifiers of the methods are
     such that when the generic function is called, &k2-r; is executed
     before &k1-r;,</simpara></listitem>
   <listitem><simpara>&k1-r; will be executed if and only if
     &call-next-method; is invoked from within the body of &k2-r; and
   </simpara></listitem>
   <listitem><simpara>&call-next-method; is invoked from within the body
     of &k2-r;, thereby causing &k1-r; to be executed.
</simpara></listitem></orderedlist></para></listitem>
<listitem><para>For a given generic function and set of arguments, a
  method &k2-r; <firstterm>overrides
   <indexterm id="method-overrides" significance="preferred">
    &me-prim;<secondary>overrides</secondary></indexterm></firstterm>
  a method &k1-r; if and only if conditions <emphasis>i</emphasis>
  through <emphasis>iv</emphasis> above hold and,
  instead of <emphasis>v</emphasis>,
  <orderedlist numeration="lowerroman" continuation="continues">
   <listitem><simpara>&call-next-method; is not invoked from within the
     body of &k2-r;, thereby preventing &k1-r; from being executed.
</simpara></listitem></orderedlist></para></listitem>
</itemizedlist></para>

<section id="mop-portable-restrictions">
 <title>Restrictions on Portable Programs</title>

<para>Portable programs are allowed to define subclasses of specified
classes, and are permitted to define methods on specified generic
functions, with the following restrictions: <itemizedlist>
<listitem><simpara>Portable programs must not redefine any specified
classes, generic functions, methods or method combinations.  Any method
defined by a portable program on a specified generic function must have
at least one specializer that is neither a specified class nor an
&eql-t; specializer whose associated value is an instance of a specified
class.</simpara></listitem>
<listitem><simpara>Portable programs may define methods that extend
specified methods unless the description of the specified method
explicitly prohibits this.  Unless there is a specific statement to the
contrary, these extending methods must return whatever value was
returned by the call to &call-next-method;.</simpara></listitem>
<listitem><simpara>Portable programs may define methods that override
specified methods only when the description of the specified method
explicitly allows this.  Typically, when a method is allowed to be
overridden, a small number of related methods will need to be overridden
as well.</simpara>
<simpara>An example of this is the specified methods on the generic
functions &add-dependent;, &remove-dependent; and &map-dependents;.
Overriding a specified method on one of these generic functions requires
that the corresponding method on the other two generic functions be
overridden as well.</simpara></listitem>
<listitem><simpara>Portable methods on specified generic functions
specialized to portable metaobject classes must be defined before any
instances of those classes (or any subclasses) are created, either
directly or indirectly by a call to &make-instance;.  Methods can be
defined after instances are created by &allocate-instance; however.
Portable metaobject classes cannot be redefined.</simpara>
<note><simpara>The purpose of this last restriction is to permit
implementations to provide performance optimizations by analyzing, at
the time the first instance of a metaobject class is initialized, what
portable methods will be applicable to it.  This can make it possible to
optimize calls to those specified generic functions which would have no
applicable portable methods.</simpara></note>
<note id="mop-mo-redef-clisp-warn">&clisp-only;
 <simpara>When a metaobject class is redefined,
  &clisp; issues a &warning-t; that the redefinition has no effect.
  To avoid this warning, place all metaobject class definitions in a
  separate file, compile it in a <emphasis>separate</emphasis> session
  (because &defclass; in &clisp; is evaluated at &compile-time; too;
  see <xref linkend="mop-ov-ui-others"/>),
  and then &load; it only <emphasis>once</emphasis> per session.
</simpara></note></listitem></itemizedlist>
</para>&else-undefined;

<note><simpara>The specification technology used in this document needs
further development.  The concepts of object-oriented protocols and
subclass specialization are intuitively familiar to programmers of
object-oriented systems; the protocols presented here fit quite
naturally into this framework.  Nonetheless, in preparing this document,
we have found it difficult to give specification-quality descriptions of
the protocols in a way that makes it clear what extensions users can and
cannot write.  Object-oriented protocol specification is inherently
about specifying leeway, and this seems difficult using current
technology.</simpara></note>
</section><!-- mop-portable-restrictions -->

<section id="mop-impl-restrictions">
 <title>Restrictions on Implementations</title>

<para>Implementations are allowed latitude to modify the structure of
specified classes and methods.  This includes: the interposition of
implementation-specific classes; the promotion of specified methods; and
the consolidation of two or more specified methods into a single method
specialized to interposed classes.</para>

<para>Any such modifications are permitted only so long as for any
portable class &k-r; that is a subclass of one or more specified classes
&k1-r; ... &kn-r;, the following conditions are met:<itemizedlist>
<listitem><simpara>In the actual class precedence list of &k-r;, the
  classes &k1-r; ... &kn-r; must appear in the same order as they would
  have if no implementation-specific modifications had been made.
</simpara></listitem>
<listitem><simpara>The method applicability of any specified generic
  function must be the same in terms of behavior as it would have been
  had no implementation-specific changes been made.  This includes
  specified generic functions that have had portable methods added.  In
  this context, the expression <quote>the same in terms of
  behavior</quote> means that methods with the same behavior as those
  specified are applicable, and in the same order.</simpara></listitem>
<listitem><simpara>No portable class &k-r; may inherit, by virtue of
  being a direct or indirect subclass of a specified class, any slot for
  which the name is a symbol accessible in the &clu-pac; package or
  exported by any package defined in the &ansi-cl;.</simpara></listitem>
<listitem><simpara>Implementations are free to define
  implementation-specific before- and after-methods on specified generic
  functions.  Implementations are also free to define
  implementation-specific around-methods with extending behavior.
</simpara></listitem></itemizedlist></para>
</section><!-- mop-impl-restrictions -->
</section><!-- mop-ov-impl-and-user-spec -->
</section><!-- mop-mo-cl-inheritance -->

<section id="mop-ui-macro">
 <title>Processing of the User Interface Macros</title>

<para>A list in which the first element is one of the symbols
&defclass;, &defmethod;, &defgeneric;, &define-method-combination;,
&gf-oper;, &gen-flet; or &gen-labels;, and which has proper
syntax for that macro is called a <firstterm>user interface macro
form</firstterm>.  This document provides an extended specification of
the &defclass;, &defmethod; and &defgeneric; macros.</para>

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

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

<para>Converting a user interface macro form into the arguments to the
appropriate functions and generic functions has two major aspects: the
conversion of the macro argument syntax into a form more suitable for
later processing, and the processing of macro arguments which are forms
to be evaluated (including method bodies).</para>

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

<para>In the syntax of the &defmethod; macro
the <replaceable>forms</replaceable> argument is a list of forms that
comprise the body of the method definition.  This list of forms must be
processed specially to capture the lexical scope of the macro form.  In
addition, the lexical functions available only in the body of methods
must be introduced.  To allow this and any other special processing
(such as slot access optimization), a specializable protocol is used for
processing the body of methods.
This is discussed in <xref linkend="mop-meth-init-defmethod-body"/>.</para>

<section id="mop-compile-ui-macro">
 <title>Compile-file Processing of the User Interface Macros</title>

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

<para>When compiling files containing &clos; definitions, it is useful
to maintain certain additional information in the &compile-file; environment.
This can make it possible to issue various kinds of warnings (e.g.,
&lalist; congruence) and to do various performance optimizations that
would not otherwise be possible.</para>

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

<section id="mop-ov-ui-others">
 <title>Compile-file Processing of Specific User Interface Macros</title>
<variablelist><varlistentry><term>&defclass;</term>
  <listitem><simpara><xref linkend="mop-cl-defclass"/></simpara>
   <note>&clisp-only;<para>&clisp; evaluates &defclass; forms also at
     &compile-time;.</para></note></listitem></varlistentry>
 <varlistentry><term>&defmethod;</term>
  <listitem><simpara><xref linkend="mop-meth-init-defmethod"/></simpara>
   <note>&clisp-only;<para>&clisp; does &not-e; evaluate &defmethod;
     forms at &compile-time; except as necessary for signature checking.
 </para></note></listitem></varlistentry>
 <varlistentry><term>&defgeneric;</term>
  <listitem><simpara><xref linkend="mop-gf-init-defgeneric"/></simpara>
   <note>&clisp-only;<para>&clisp; does &not-e; evaluate &defgeneric;
     forms at &compile-time; except as necessary for signature checking.
</para></note></listitem></varlistentry></variablelist>
</section><!-- mop-ov-ui-others -->
</section><!-- mop-ui-macro -->

<section id="mop-ov-mo-init">
 <title>Metaobject Initialization Protocol</title>

<para>Like other objects, metaobjects can be created by calling
&make-instance;.  The initialization arguments passed to &make-instance;
are used to initialize the metaobject in the usual way.  The set of
legal initialization arguments, and their interpretation, depends on the
kind of metaobject being created.  Implementations and portable programs
are free to extend the set of legal initialization arguments.  Detailed
information about the initialization of each kind of metaobject are
provided in the appropriate sections:<itemizedlist>
<listitem><simpara><xref linkend="mop-cl-init-mo"/></simpara></listitem>
<listitem><simpara><xref linkend="mop-cl-reinit-mo"/></simpara></listitem>
<listitem><simpara><xref linkend="mop-gf-init-mo"/></simpara></listitem>
<listitem><simpara><xref linkend="mop-cl-finalization"/></simpara></listitem>
<listitem><simpara><xref linkend="mop-sa-instance-struct"/></simpara></listitem>
<listitem><simpara><xref linkend="mop-sa-funcallable"/></simpara></listitem>
<listitem><simpara><xref linkend="mop-gf-invocation"/></simpara></listitem>
<listitem><simpara><xref linkend="mop-dep-maint"/></simpara></listitem>
</itemizedlist></para>
</section><!-- mop-ov-mo-init -->
</section><!-- mop-overview -->

<section id="mop-classes"><title>Classes</title>

<section id="mop-cl-defclass"><title>Macro &defclass;</title>

<para>The evaluation or execution of a &defclass; form results in a call
to the &ensure-class; function. The arguments received by &ensure-class;
are derived from the &defclass; form in a defined way.  The exact
macro-expansion of the &defclass; form is not defined, only the
relationship between the arguments to the &defclass; macro and the
arguments received by the &ensure-class; function.  Examples of typical
&defclass; forms and sample expansions are shown in the following two
 examples:
<informalexample id="mop-cl-defclass-ex-1"><simpara>A &defclass; form with
  standard slot and class options and an expansion of it that would
  result in the proper call to &ensure-class;.</simpara>
<programlisting language="lisp">
(defclass plane (moving-object graphics-object)
  ((altitude :initform 0 :accessor plane-altitude)
   (speed))
  (:default-initargs :engine *jet*))

(ensure-class 'plane
  ':direct-superclasses '(moving-object graphics-object)
  ':direct-slots (list (list ':name 'altitude
                             ':initform '0
                             ':initfunction #'(lambda () 0)
                             ':readers '(plane-altitude)
                             ':writers '((setf plane-altitude)))
                       (list ':name 'speed))
  ':direct-default-initargs (list (list ':engine
                                        '*jet*
                                        #'(lambda () *jet*))))
</programlisting></informalexample>
<informalexample id="mop-cl-defclass-ex-2"><simpara>A &defclass; form
  with non-standard class and slot options, and an expansion of it which
  results in the proper call to &ensure-class;.  Note that the order of
  the slot options has not affected the order of the properties in the
  &canonicalized-slot-spec;, but has affected the order of the elements
  in the lists which are the values of those properties.</simpara>
<programlisting language="lisp">
(defclass sst (plane)
  ((mach mag-step 2
         locator sst-mach
         locator mach-location
         :reader mach-speed
         :reader mach))
  (:metaclass faster-class)
  (another-option foo bar))

(ensure-class 'sst
  ':direct-superclasses '(plane)
  ':direct-slots (list (list ':name 'mach
                             ':readers '(mach-speed mach)
                             'mag-step '2
                             'locator '(sst-mach mach-location)))
  ':metaclass 'faster-class
  'another-option '(foo bar))
</programlisting></informalexample></para>

<itemizedlist><listitem><simpara>The &name-r; argument to &defclass;
   becomes the value of the first argument to &ensure-class;.  This is
   the only positional argument accepted by &ensure-class;; all other
   arguments are keyword arguments.</simpara></listitem>
<listitem><simpara>The &direct-superclasses-k; argument to &defclass;
  becomes the value of the &direct-superclasses-k; keyword argument to
  &ensure-class;.</simpara></listitem>
<listitem><simpara>The &direct-slots-k; argument to &defclass; becomes
  the value of the &direct-slots-k; keyword argument to &ensure-class;.
  Special processing of this value is done to regularize the form of
  each slot specification and to properly capture the lexical scope of
  the initialization forms.  This is done by converting each slot
  specification to a property list called a
  <firstterm>canonicalized slot specification</firstterm>.
  The resulting list of &canonicalized-slot-spec;s is the value
  of the &direct-slots-k; keyword argument.</simpara>
 <para id="mop-canonicalized-slot-spec">Canonicalized slot
  specifications are later used as the keyword arguments to a generic
  function which will, in turn, pass them to &make-instance; for use as
  a set of initialization arguments.  Each &canonicalized-slot-spec; is
  formed from the corresponding slot specification as follows:
  <itemizedlist>
   <listitem><simpara>The name of the slot is the value of the &name-k;
     property.  This property appears in every
     &canonicalized-slot-spec;.</simpara></listitem>
   <listitem><simpara>When the &initform-k; slot option is present in
     the slot specification, then both the &initform-k; and
     &initfunction-k; properties are present in the &canonicalized-slot-spec;.
     The value of the &initform-k; property is the
     initialization form.  The value of the &initfunction-k; property is
     a function of zero arguments which, when called, returns the result
     of evaluating the initialization form in its proper &lex-env;.
   </simpara></listitem>
   <listitem><simpara>If the &initform-k; slot option is not present in
     the slot specification, then either the &initfunction-k; property
     will not appear, or its value will be false.  In such cases, the
     value of the &initform-k; property, or whether it appears, is
     unspecified.</simpara></listitem>
   <listitem><simpara>The value of the &initargs-k; property is a list
     of the values of each &initarg-k; slot option.  If there are no
     &initarg-k; slot options, then either the &initargs-k; property
     will not appear or its value will be the empty list.
   </simpara></listitem>
   <listitem><simpara>The value of the &readers-k; property is a list of
     the values of each &reader-k; and &accessor-k; slot option.  If
     there are no &reader-k; or &accessor-k; slot options, then either
     the &readers-k; property will not appear or its value will be the
     empty list.</simpara></listitem>
   <listitem><simpara>The value of the &writers-k; property is a list of
     the values specified by each &writer-k; and &accessor-k; slot
     option.  The value specified by a &writer-k; slot option is just
     the value of the slot option.  The value specified by an
     &accessor-k; slot option is a two element list: the first element
     is the symbol &setf;, the second element is the value of the slot
     option.  If there are no &writer-k; or &accessor-k; slot options,
     then either the &writers-k; property will not appear or its value
     will be the empty list.</simpara></listitem>
   <listitem><simpara>The value of the &documentation-k; property is the
     value of the &documentation-k; slot option.  If there is no
     &documentation-k; slot option, then either the &documentation-k;
     property will not appear or its value will be false.
   </simpara></listitem>
   <listitem><simpara>All other slot options appear as the values of
     properties with the same name as the slot option.  Note that this
     includes not only the remaining standard slot options
     (&allocation-k; and &type-k;), but also any other options and
     values appearing in the slot specification.  If one of these slot
     options appears more than once, the value of the property will be a
     list of the specified values.</simpara></listitem>
   <listitem><simpara>An implementation is free to add additional
     properties to the &canonicalized-slot-spec; provided these
     are not symbols accessible in the &clu-pac; package, or exported by
     any package defined in the &ansi-cl;.</simpara></listitem>
  </itemizedlist></para></listitem>
<listitem><simpara>The <constant>:DEFAULT-INITARGS</constant> class
  option, if it is present in the &defclass; form, becomes the value of
  the &direct-default-initargs-k; keyword argument to &ensure-class;.
  Special processing of this value is done to properly capture the
  lexical scope of the default value forms.  This is done by converting
  each default initarg in the class option into a
  <firstterm>canonicalized default initialization argument</firstterm>.
  The resulting list of &canonicalized-default-initarg;s is the value of
  the &direct-default-initargs-k; keyword argument to &ensure-class;.
 </simpara>
 <simpara id="mop-canonicalized-default-initarg">A canonicalized default
  initarg is a list of three elements.  The first element is the name;
  the second is the actual form itself; and the third is a function of
  zero arguments which, when called, returns the result of evaluating
  the default value form in its proper &lex-env;.</simpara>
  <note>&clisp-only;<simpara>If a <constant>:DEFAULT-INITARGS</constant>
    class option is not present in the &defclass; form,
    &direct-default-initargs-k; &nil; is passed to &ensure-class;.</simpara>
   &clisp-defclass-ensure-class-default;</note></listitem>
<listitem><simpara>The &metaclass-k; class
  option, if it is present in the &defclass; form, becomes the value of
  the &metaclass-k; keyword argument to &ensure-class;.</simpara>
 <note>&clisp-only;<simpara>If a &metaclass-k;
   class option is not present in the &defclass; form,
   &metaclass-k; &standard-class; is passed to &ensure-class;.</simpara>
  &clisp-defclass-ensure-class-default;</note></listitem>
<listitem><simpara>The &documentation-k; class
  option, if it is present in the &defclass; form, becomes the value of
  the &documentation-k; keyword argument to &ensure-class;.</simpara>
  <note>&clisp-only;<simpara>If a &documentation-k;
    class option is not present in the &defclass; form,
    &direct-default-initargs-k; &nil; is passed to &ensure-class;.</simpara>
    &clisp-defclass-ensure-class-default;</note></listitem>
<listitem><simpara>Any other class options become the value of keyword
  arguments with the same name.  The value of the keyword argument is
  the tail of the class option.  An &err-sig; if any class
  option appears more than once in the &defclass; form.</simpara>
 <note>&clisp-only;<simpara>The default initargs of the
    &metaclass-k; are added at the end of the list
    of arguments to pass to &ensure-class;.</simpara>
   &clisp-defclass-ensure-class-default;</note></listitem>
</itemizedlist>

<para>In the call to &ensure-class;, every element of its arguments
appears in the same left-to-right order as the corresponding element of
the &defclass; form, except that the order of the properties of
&canonicalized-slot-spec;s is unspecified.  The values of
properties in &canonicalized-slot-spec;s do follow this ordering
requirement.  Other ordering relationships in the keyword arguments to
&ensure-class; are unspecified.</para>

<para>The result of the call to &ensure-class; is returned as the result
of evaluating or executing the &defclass; form.</para>
</section><!-- mop-cl-defclass -->

<section id="mop-cl-Inheritance">
 <title>Inheritance Structure of &c-mo; Classes</title>
<figure id="mop-cl-Inheritance-fig">
 <title>Inheritance structure of &c-mo; classes</title>
 <mediaobject><imageobject>
   <imagedata width="100%" scalefit="1" fileref="mop-classes-class.png"/>
</imageobject></mediaobject></figure>
</section>

<section id="mop-cl-readers">
 <title>Introspection: Readers for &c-mo;s</title>

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

<para>The reader generic functions which simply return information
associated with &c-mo;s are presented together in this section.</para>

<para>Each of the reader generic functions for &c-mo;s has the same
syntax, accepting one required argument called &class-r;, which must be
a &c-mo;; otherwise, an &err-sig;.  An &error-t; is also &signal;ed if
the &c-mo; has not been initialized.</para>

&user-and-implementation-callable-result-immutable;

<!-- begin class basic introspection -->

<section id="class-name"><title>Generic Function &class-name;</title>
 <subtitle><code>(&class-name; &class-r;)</code></subtitle>

<para>Returns the name of &class-r;.  This value can be any Lisp object,
but is usually a symbol, or &nil; if the class has no name.  This is the
defaulted value of the &name-k; initialization argument that was
associated with the class during initialization or reinitialization.
(Also see &setf-class-name;.)
</para></section>

<section id="class-direct-superclasses">
 <title>Generic Function &class-direct-superclasses;</title>
 <subtitle><code>(&class-direct-superclasses; &class-r;)</code></subtitle>

<para>Returns a list of the direct superclasses of &class-r;.  The
elements of this list are &c-mo;s.  The empty list is returned if
&class-r; has no direct superclasses.  This is the defaulted value of
the &direct-superclasses-k; initialization argument that was associated
with the class during initialization or reinitialization.</para>

<note>&clisp-only;<simpara>For a class that has not yet been finalized,
 the returned list may contain &forward-referenced-class; instances as
 placeholder for classes that were not yet defined when finalization of
 the class was last attempted.</simpara></note>
</section>

<section id="class-direct-slots">
 <title>Generic Function &class-direct-slots;</title>
 <subtitle><code>(&class-direct-slots; &class-r;)</code></subtitle>

<para>Returns a set of the direct slots of &class-r;.  The elements of
this set are &dsdmo;s.  If the class has no direct slots, the empty set
is returned.  This is the defaulted value of the &direct-slots-k;
initialization argument that was associated with the class during
initialization and reinitialization.</para></section>

<section id="class-direct-default-initargs">
 <title>Generic Function &class-direct-default-initargs;</title>
 <subtitle><code>(&class-direct-default-initargs; &class-r;)</code></subtitle>

<para>Returns a list of the direct default initialization arguments for
&class-r;.  Each element of this list is a &canonicalized-default-initarg;.
The empty list is returned if &class-r; has no
direct default initialization arguments.  This is the defaulted value of
the &direct-default-initargs-k; initialization argument that was
associated with the class during initialization or reinitialization.
</para></section>

<section id="cpl"><title>Generic Function &cpl;</title>
 <subtitle><code>(&cpl; &class-r;)</code></subtitle>

<para>Returns the class precedence list of &class-r;.
 The elements of this list are &c-mo;s.</para>

<para>During class finalization &finalize-inheritance; calls
&compute-cpl; to compute the class precedence list of the class.  That
value is associated with the &c-mo; and is returned by &cpl;.</para>

<para>This generic function &sig-err; if &class-r; has not been finalized.
</para></section>

<section id="class-direct-subclasses">
 <title>Generic Function &class-direct-subclasses;</title>
 <subtitle><code>(&class-direct-subclasses; &class-r;)</code></subtitle>

<para>Returns a set of the direct subclasses of &class-r;. The elements
of this set are &c-mo;s that all mention this class among their direct
superclasses.  The empty set is returned if &class-r; has no direct
subclasses.  This value is maintained by the generic functions
&add-direct-subclass; and &remove-direct-subclass;.</para>

<note>&clisp-only;<simpara>The set of direct subclasses of a class is
 internally managed as a &weak-list;. Therefore the existence of
 the &class-direct-subclasses; function does not prevent otherwise
 unreferenced classes from being &gc;ed.</simpara></note>
</section>

<section id="class-slots"><title>Generic Function &class-slots;</title>
 <subtitle><code>(&class-slots; &class-r;)</code></subtitle>

<para>Returns a possibly empty set of the slots accessible in instances
of &class-r;.  The elements of this set are &esdmo;s.</para>

<para>During class finalization &finalize-inheritance; calls
&compute-slots; to compute the slots of the class.  That value is
associated with the &c-mo; and is returned by &class-slots;.</para>

<para>This generic function &sig-err; if &class-r; has not been finalized.
</para></section>

<section id="class-default-initargs">
 <title>Generic Function &class-default-initargs;</title>
 <subtitle><code>(&class-default-initargs; &class-r;)</code></subtitle>

<para>Returns a list of the default initialization arguments for &class-r;.
 Each element of this list is a &canonicalized-default-initarg;.
 The empty list is returned if &class-r; has no
 default initialization arguments.</para>

<para>During finalization &finalize-inheritance; calls
&compute-default-initargs; to compute the default initialization
arguments for the class.  That value is associated with the &c-mo; and
is returned by &class-default-initargs;.</para>

<para>This generic function &sig-err; if &class-r; has not been
finalized.</para></section>

<!-- end class basic introspection -->

<!-- begin class advanced introspection -->

<section id="class-finalized-p">
 <title>Generic Function &class-finalized-p;</title>
 <subtitle><code>(&class-finalized-p; &class-r;)</code></subtitle>

<para>Returns true if &class-r; has been finalized.  Returns false
otherwise.  Also returns false if the &class-r; has not been initialized.
</para></section>

<section id="class-prototype"><title>Generic Function &class-prototype;</title>
 <subtitle><code>(&class-prototype; &class-r;)</code></subtitle>

<para>Returns a prototype instance of &class-r;.  Whether the instance
is initialized is not specified.  The results are undefined if a
portable program modifies the binding of any slot of a prototype instance.
</para>

<para>This generic function &sig-err; if &class-r; has not been finalized.
</para>

<informalexample id="class-prototype-ex"><para>This allows non-&consing;
  access to slots with allocation &class-k;:<programlisting language="lisp">
(defclass counter ()
  ((count :allocation :class :initform 0 :reader how-many)))
(defmethod initialize-instance :after ((obj counter) &amp;rest args)
  (incf (slot-value obj 'count)))
(defclass counted-object (counter) ((name :initarg :name)))
 </programlisting>
 Now one can find out how many <classname>COUNTED-OBJECT</classname>s
 have been created by using
  <code>(HOW-MANY (&class-prototype; (&find-class; 'COUNTER)))</code>:
  <programlisting language="lisp">
(&make-instance; 'counted-object :name 'foo)
<computeroutput>#&lt;COUNTED-OBJECT #x203028C9&gt;</computeroutput>
(HOW-MANY (&class-prototype; (&find-class; 'counter)))
<computeroutput>1</computeroutput>
(&make-instance; 'counted-object :name 'bar)
<computeroutput>#&lt;COUNTED-OBJECT #x20306CB1&gt;</computeroutput>
(HOW-MANY (&class-prototype; (&find-class; 'counter)))
<computeroutput>2</computeroutput>
</programlisting></para>
</informalexample></section>

<!-- end class advanced introspection -->

<section id="mop-cl-readers-methods"><title>Methods</title>

<para>The specified methods for the &c-mo; reader generic
functions are presented below.</para>

<para>Each entry in the table indicates a method on one of the reader
 generic functions, specialized to a specified class.
 The number in each entry is a reference to the full description of the method.
 The full descriptions appear after the table.
<informaltable id="mop-cl-readers-methods-tab">
 <tgroup cols="4" colsep="1" rowsep="1" align="center">
  <thead><row><entry>Generic Function</entry>
    <entry>&standard-class;, &funcallable-standard-class;</entry>
    <entry>&forward-referenced-class;</entry>
    <entry>&built-in-class;</entry></row></thead>
  <tbody>
   <row><entry>&class-name;</entry>
    <entry><xref linkend="CRM-1"/></entry>
    <entry><xref linkend="CRM-1"/></entry>
    <entry><xref linkend="CRM-8"/></entry></row>
   <row><entry>&class-direct-superclasses;</entry>
    <entry><xref linkend="CRM-1"/></entry>
    <entry><xref linkend="CRM-4"/></entry>
    <entry><xref linkend="CRM-7"/></entry></row>
   <row><entry>&class-direct-slots;</entry>
    <entry><xref linkend="CRM-1"/></entry>
    <entry><xref linkend="CRM-4"/></entry>
    <entry><xref linkend="CRM-4"/></entry></row>
   <row><entry>&class-direct-default-initargs;</entry>
    <entry><xref linkend="CRM-1"/></entry>
    <entry><xref linkend="CRM-4"/></entry>
    <entry><xref linkend="CRM-4"/></entry></row>
   <row><entry>&cpl;</entry>
    <entry><xref linkend="CRM-2"/></entry>
    <entry><xref linkend="CRM-3"/></entry>
    <entry><xref linkend="CRM-7"/></entry></row>
   <row><entry>&class-direct-subclasses;</entry>
    <entry><xref linkend="CRM-9"/></entry>
    <entry><xref linkend="CRM-9"/></entry>
    <entry><xref linkend="CRM-7"/></entry></row>
   <row><entry>&class-slots;</entry>
    <entry><xref linkend="CRM-2"/></entry>
    <entry><xref linkend="CRM-3"/></entry>
    <entry><xref linkend="CRM-4"/></entry></row>
   <row><entry>&class-default-initargs;</entry>
    <entry><xref linkend="CRM-2"/></entry>
    <entry><xref linkend="CRM-3"/></entry>
    <entry><xref linkend="CRM-4"/></entry></row>
   <row><entry>&class-finalized-p;</entry>
    <entry><xref linkend="CRM-2"/></entry>
    <entry><xref linkend="CRM-6"/></entry>
    <entry><xref linkend="CRM-5"/></entry></row>
   <row><entry>&class-prototype;</entry>
    <entry><xref linkend="CRM-10"/></entry>
    <entry><xref linkend="CRM-10"/></entry>
    <entry><xref linkend="CRM-10"/></entry></row>
</tbody></tgroup></informaltable></para>

<orderedlist numeration="arabic"><title>Class Reader Methods</title>
 <listitem id="CRM-1"><simpara>This method returns the value which was
   associated with the &c-mo; during initialization or
   reinitialization.</simpara></listitem>
 <listitem id="CRM-2"><simpara>This method returns the value associated
   with the &c-mo; by <literal role="method">&finalize-inheritance;
    (&standard-class;)</literal> or
   <literal role="method">&finalize-inheritance;
    (&funcallable-standard-class;)</literal></simpara></listitem>
 <listitem id="CRM-3"><simpara>This method &sig-err;.</simpara></listitem>
 <listitem id="CRM-4"><simpara>This method returns the empty list.
 </simpara></listitem>
 <listitem id="CRM-5"><simpara>This method returns true.</simpara></listitem>
 <listitem id="CRM-6"><simpara>This method returns false.</simpara></listitem>
 <listitem id="CRM-7"><simpara>This method returns a value derived from
   the information in <xref linkend="mop-inherit-struct"/>, except that
   implementation-specific modifications are permitted as described in
   <xref linkend="mop-ov-impl-and-user-spec"/>.</simpara></listitem>
 <listitem id="CRM-8"><simpara>This method returns the name of the
   built-in class.</simpara></listitem>
 <listitem id="CRM-9"><simpara>This method returns a value which is
   maintained by <literal role="method">&add-direct-subclass;(&class;
    &class;)</literal> and <literal role="method">&remove-direct-subclass;
    (&class; &class;)</literal>.
   This method can be overridden only if those methods are overridden as
   well.</simpara></listitem>
 <listitem id="CRM-10">&no-extra-spec;</listitem></orderedlist>
</section><!-- mop-cl-readers-methods -->
</section><!-- mop-cl-readers -->

<section id="mop-cl-finalization"><title>Class Finalization Protocol</title>

<para>Class <firstterm>finalization
  <indexterm id="class-finalization" significance="preferred">
   <primary>class</primary><secondary>finalization</secondary></indexterm>
 </firstterm> is the process of computing the information a class
 inherits from its superclasses and preparing to actually allocate
 instances of the class.
The class finalization process includes computing the class's class
precedence list, the full set of slots accessible in instances of the
class and the full set of default initialization arguments for the class.
These values are associated with the &c-mo; and can be accessed by
calling the appropriate reader.
In addition, the class finalization process makes decisions about how
instances of the class will be implemented.</para>

<para>To support forward-referenced superclasses, and to account for the
fact that not all classes are actually instantiated, class finalization
is not done as part of the initialization of the &c-mo;.  Instead,
finalization is done as a separate protocol, invoked by calling the
generic function &finalize-inheritance;.  The exact point at which
&finalize-inheritance; is called depends on the class of the &c-mo;; for
&standard-class; it is called sometime after all the classes
superclasses are defined, but no later than when the first instance of
the class is allocated (by &allocate-instance;).</para>

<para>The first step of class finalization is computing the class
precedence list.  Doing this first allows subsequent steps to access the
class precedence list.  This step is performed by calling the generic
function &compute-cpl;.  The value returned from this call is associated
with the &c-mo; and can be accessed by calling the &cpl; generic
function.</para>

<para>The second step is computing the full set of slots that will be
accessible in instances of the class.  This step is performed by calling
the generic function &compute-slots;.  The result of this call is a list
of &esdmo;s.  This value is associated with the &c-mo; and can
be accessed by calling the &class-slots; generic function.</para>

<para>The behavior of &compute-slots; is itself layered, consisting of
calls to &esd-class; and &compute-esd;.</para>

<para>The final step of class finalization is computing the full set of
initialization arguments for the class.  This is done by calling the
generic function &compute-default-initargs;.  The value returned by this
generic function is associated with the &c-mo; and can be
accessed by calling &class-default-initargs;.</para>

<para>If the class was previously finalized, &finalize-inheritance; may
call &make-instances-obsolete;.  The circumstances under which this
happens are described in the &ansi-cl; section
 <xref linkend="redef-class"/>.</para>

<para>Forward-referenced classes, which provide a temporary definition
for a class which has been referenced but not yet defined, can never be
finalized.  An &err-sig; if &finalize-inheritance; is called on a
forward-referenced class.</para>

</section><!-- mop-cl-finalization -->

<section id="mop-cl-init"><title>Class Initialization</title>

<section id="mop-cl-init-mo"><title>Initialization of &c-mo;s</title>

<para>A &c-mo; can be created by calling &make-instance;.
 The initialization arguments establish the definition of the class.
 A &c-mo; can be redefined by calling &reinitialize-instance;.
 Some classes of &c-mo; do not support redefinition;
 in these cases, &reinitialize-instance; &sig-err;.</para>

<para>Initialization of a &c-mo; must be done by calling &make-instance;
and allowing it to call &initialize-instance;.  Reinitialization of a
&c-mo; must be done by calling &reinitialize-instance;.
 Portable programs must &not-e;<itemizedlist>
  <listitem><simpara>... call &initialize-instance; directly to
    initialize a &c-mo;;</simpara></listitem>
  <listitem><simpara>... call &shared-initialize; directly to
    initialize or reinitialize a &c-mo;;</simpara></listitem>
  <listitem><simpara>... call &change-class; to change the class of any
    &c-mo; or to turn a non-class object into a
    &c-mo;.</simpara></listitem></itemizedlist></para>

<para>Since metaobject classes may not be redefined,
 no behavior is specified for the result of calls to
 &update-instance-for-redefined-class; on &c-mo;s.
 Since the class of &c-mo;s may not be changed,
 no behavior is specified for the result of calls to
 &update-instance-for-different-class; on &c-mo;s.</para>

<para>During initialization or reinitialization, each initialization
argument is checked for errors and then associated with the &c-mo;.
The value can then be accessed by calling the appropriate accessor as
shown in <xref linkend="class-mo-initargs"/>.</para>

<para>This section begins with a description of the error checking and
processing of each initialization argument.  This is followed by a table
showing the generic functions that can be used to access the stored
initialization arguments.  Initialization behavior specific to the
different specified &c-mo; classes comes next.  The section ends with a
set of restrictions on portable methods affecting &c-mo; initialization
and reinitialization.</para>

<para>In these descriptions, the phrase <quote>this argument defaults to
&value-r;</quote> means that when that initialization argument is not
supplied, initialization or reinitialization is performed as if
&value-r; had been supplied.  For some initialization arguments this
could be done by the use of default initialization arguments, but
whether it is done this way is not specified.  Implementations are free
to define default initialization arguments for specified &c-mo; classes.
Portable programs are free to define default initialization arguments
for portable subclasses of the class &class;.</para>

&reinit-keep-value;

<itemizedlist>
 <listitem><simpara>The &direct-default-initargs-k; argument is a list
   of &canonicalized-default-initarg;s.</simpara>
  <simpara>An &err-sig; if this value is not a &proper-list-glo;, or if any
   element of the list is not a &canonicalized-default-initarg;.</simpara>
  <simpara>If the &c-mo; is being initialized, this argument
   defaults to the empty list.</simpara></listitem>
 <listitem><simpara> The &direct-slots-k; argument is a list of
   &canonicalized-slot-spec;s.</simpara>
  <simpara>An &err-sig; if this value is not a &proper-list-glo; or if any
   element of the list is not a &canonicalized-slot-spec;.</simpara>
  <para>After error checking, this value is converted to a
   list of &dsdmo;s before it is associated with the &c-mo;.  Conversion
   of each &canonicalized-slot-spec; to a &dsdmo; is a two-step process.
   First, the generic function &dsd-class; is called with the &c-mo; and
   the &canonicalized-slot-spec; to determine the class of the new
   &dsdmo;; this permits both the &c-mo; and the
   &canonicalized-slot-spec; to control the resulting &dsdmo; class.
   Second, &make-instance; is applied to the direct &sdmo; class and the
   &canonicalized-slot-spec;.
   This conversion could be implemented as shown in the
   following code:<programlisting language="lisp">
(&defun; convert-to-direct-slot-definition (class canonicalized-slot)
  (&apply; #'&make-instance;
         (&apply; #'&dsd-class;
                class canonicalized-slot)
         canonicalized-slot))
</programlisting></para>
  <simpara>If the &c-mo; is being initialized, this argument defaults to
   the empty list.</simpara>
  <simpara>Once the &dsdmo;s have been created, the specified reader and
   writer methods are created.  The generic functions
   &reader-method-class; and &writer-method-class; are called to
   determine the classes of the &m-mo;s created.</simpara></listitem>
 <listitem><simpara> The &direct-superclasses-k; argument is a list of
   &c-mo;s.  Classes which do not support multiple inheritance
   signal an error if the list contains more than one element.</simpara>
  <simpara>An &err-sig; if this value is not a &proper-list-glo; or if
   &validate-superclass; applied to &class-r; and any element of this
   list returns false.</simpara>
  <simpara>When the &c-mo; is being initialized, and this argument is
   either not supplied or is the empty list, this argument defaults as
   follows: if the class is an instance of &standard-class; or one of
   its subclasses the default value is a list of the class
   &standard-object-t;; if the class is an instance of
   &funcallable-standard-class; or one of its subclasses the default
   value is a list of the class
   &funcallable-standard-object-t;.</simpara>
  <note>&clisp-only;<simpara>If the class is an instance of
    &structure-class; or one of its subclasses the default value is a
    list of the class &structure-object-t;</simpara></note>
  <simpara>After any defaulting of the value, the generic function
   &add-direct-subclass; is called once for each element of the list.
  </simpara><simpara>When the &c-mo; is being reinitialized and this
   argument is supplied, the generic function &remove-direct-subclass;
   is called once for each &c-mo; in the previously stored value but not
   in the new value; the generic function &add-direct-subclass; is
   called once for each &c-mo; in the new value but not in the
   previously stored value.</simpara></listitem>
 &doc-k-li;
 <listitem><simpara>The &name-k; argument is an object.</simpara>
  <simpara>If the class is being initialized, this argument defaults to
   &nil;.</simpara></listitem></itemizedlist>

<para>After the processing and defaulting of initialization arguments
described above, the value of each initialization argument is associated
with the &c-mo;.  These values can then be accessed by calling
the corresponding generic function.  The correspondences are as follows:
 <table id="class-mo-initargs"><title>Initialization arguments and
   accessors for &c-mo;s</title>
  <tgroup cols="2" colsep="1" rowsep="1" align="center">
   <thead><row><entry>Initialization Argument</entry>
     <entry>Generic Function</entry></row></thead>
   <tbody><row><entry>&direct-default-initargs-k;</entry>
     <entry>&class-direct-default-initargs;</entry></row>
    <row><entry>&direct-slots-k;</entry>
     <entry>&class-direct-slots;</entry></row>
    <row><entry>&direct-superclasses-k;</entry>
     <entry>&class-direct-superclasses;</entry></row>
    <row><entry>&documentation-k;</entry><entry>&documentation;</entry></row>
    <row><entry>&name-k;</entry><entry>&class-name;</entry></row>
</tbody></tgroup></table></para>

<para>Instances of the class &standard-class; support multiple
inheritance and reinitialization.  Instances of the class
&funcallable-standard-class; support multiple inheritance and
reinitialization.  For &forward-referenced-class;es, all of the
initialization arguments default to &nil;.</para>

<note>&clisp-only;<simpara>Instances of the class &structure-class; do
  not support multiple inheritance and reinitialization.
</simpara></note>

<para>Since built-in classes cannot be created or reinitialized by the
user, an &err-sig; if &initialize-instance; or &reinitialize-instance;
are called to initialize or reinitialize a derived instance of the class
&built-in-class;.</para>

<section id="class-mo-init-methods"><title>Methods</title>

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

<para>These restrictions govern the methods that a portable program can
 define on the generic functions &initialize-instance;,
 &reinitialize-instance;, and &shared-initialize;.
 These restrictions apply only to methods on these generic functions for
 which the first specializer is a subclass of the class &class;.
 Other portable methods on these generic functions are not affected by
 these restrictions.</para>

<itemizedlist>
 <listitem><simpara>Portable programs must not define methods on
   &shared-initialize;.</simpara></listitem>
 <listitem><para>For &initialize-instance; and &reinitialize-instance;:
   &init-method-restrictions;</para></listitem>
</itemizedlist>
&else-undefined;
</section><!-- class-mo-init-methods -->

<section id="mop-cl-init-anon">
 <title>Initialization of Anonymous Classes</title>

<para>&c-mo;s created with &make-instance; are usually <firstterm>anonymous
  <indexterm id="class-anonymous" significance="preferred">
   <primary>class</primary><secondary>anonymous</secondary></indexterm>
 </firstterm>; that is, they have no &proper-name-glo;.
An anonymous &c-mo; can be given a &proper-name-glo; using
<code>(&setf; &find-class;)</code> and
<code>(&setf; &class-name;)</code>.</para>

<para>When a &c-mo; is created with &make-instance;, it is initialized
in the usual way.  The initialization arguments passed to
&make-instance; are use to establish the definition of the class.  Each
initialization argument is checked for errors and associated with the
&c-mo;.  The initialization arguments correspond roughly to the
arguments accepted by the &defclass; macro, and more closely to the
arguments accepted by the &ensure-class; function.</para>

<para>Some &c-mo; classes allow their instances to be
 redefined.  When permissible, this is done by calling
 &reinitialize-instance;.  This is discussed in the
 <link linkend="mop-cl-reinit-mo">next section</link>.</para>

<para>An example of creating an anonymous class directly using
&make-instance; follows:<programlisting language="lisp">
(flet ((zero () 0)
       (propellor () *propellor*))
  (make-instance 'standard-class
    :name '(my-class foo)
    :direct-superclasses (list (find-class 'plane)
                               another-anonymous-class)
    :direct-slots `((:name x
                     :initform 0
                     :initfunction ,#'zero
                     :initargs (:x)
                     :readers (position-x)
                     :writers ((setf position-x)))
                    (:name y
                     :initform 0
                     :initfunction ,#'zero
                     :initargs (:y)
                     :readers (position-y)
                     :writers ((setf position-y))))
    :direct-default-initargs `((:engine *propellor* ,#'propellor))))
</programlisting></para>
</section><!-- mop-cl-init-anon -->
</section><!-- mop-cl-init-mo -->

<section id="mop-cl-reinit-mo">
 <title>Reinitialization of &c-mo;s</title>

<para>Some &c-mo; classes allow their instances to be reinitialized.
This is done by calling &reinitialize-instance;.  The initialization
arguments have the same interpretation as in class initialization.</para>

<para>If the &c-mo; was finalized before the call to &reinitialize-instance;,
&finalize-inheritance; will be called again once all the initialization
arguments have been processed and associated with the &c-mo;.
In addition, once finalization is complete, any dependents of the
&c-mo; will be updated by calling &update-dependent;.</para>

</section><!-- mop-cl-reinit-mo -->
</section><!-- mop-cl-init -->

<section id="mop-cl-customize"><title>Customization</title>

<!-- begin class basic customization -->

<section id="setf-class-name"><title>Generic Function &setf-class-name;</title>

<variablelist><varlistentry><term>Syntax</term>
 <listitem><simpara><code>(&setf-class-name; &nname-r;
 &class-r;)</code></simpara></listitem></varlistentry>
<varlistentry><term>Arguments</term>
 <listitem><variablelist>&class-mo-arg;
   <varlistentry><term>&nname-r;</term>
    <listitem><simpara>any Lisp object.</simpara></listitem></varlistentry>
</variablelist></listitem></varlistentry>
<varlistentry><term>Value</term>
 <listitem><simpara>The &nname-r; argument.</simpara></listitem></varlistentry>
<varlistentry><term>Purpose</term>
 <listitem><simpara>This function changes the name of &class-r; to &nname-r;.
   This value is usually a symbol, or &nil; if the class has no name.</simpara>
  <simpara>This function works by calling &reinitialize-instance; with
   &class-r; as its first argument, the symbol &name-k; as its second
   argument and &nname-r; as its third argument.
</simpara></listitem></varlistentry></variablelist>
</section><!-- setf-class-name -->

<section id="ensure-class"><title>Generic Function &ensure-class;</title>

<variablelist><varlistentry><term>Syntax</term>
 <listitem><simpara><code>(&ensure-class; &name-r; &key-amp;
    &allow-other-keys-amp;)</code></simpara></listitem></varlistentry>
<varlistentry><term>Arguments</term>
 <listitem><variablelist>
   <varlistentry><term>&name-r;</term>
    <listitem><simpara>a &symbol-t;.</simpara></listitem></varlistentry>
   <varlistentry><term>keyword arguments</term>
    <listitem><simpara>Some of the keyword arguments accepted by this
      function are actually processed by &ensure-class-UC;,
      others are processed during initialization of the &c-mo;
      (as described in <xref linkend="mop-cl-init-mo"/>).
</simpara></listitem></varlistentry></variablelist></listitem></varlistentry>
<varlistentry><term>Value</term>&a-cmo;</varlistentry>
<varlistentry><term>Purpose</term>
 <listitem><simpara>This function is called to define or redefine a
   class with the specified name, and can be called by the user or the
   implementation.  It is the functional equivalent of &defclass;, and
   is called by the expansion of the &defclass; macro.</simpara>
  <simpara>The behavior of this function is actually implemented by the
   generic function &ensure-class-UC;.  When &ensure-class; is called,
   it immediately calls &ensure-class-UC; and returns that result as its
   own.</simpara>
  <para>The first argument to &ensure-class-UC; is computed as
   follows:<itemizedlist>
    <listitem><simpara>If &name-r; names a class (&find-class; returns a
      class when called with &name-r;) use that class.</simpara></listitem>
    <listitem><simpara>Otherwise use &nil;.</simpara></listitem>
   </itemizedlist>
   The second argument is &name-r;.  The remaining arguments are the
   complete set of keyword arguments received by the &ensure-class;
   function.</para></listitem></varlistentry></variablelist>
</section><!-- ensure-class -->

<section id="ensure-class-UC"><title>Generic Function &ensure-class-UC;</title>

<variablelist><varlistentry><term>Syntax</term>
 <listitem><simpara><code>(&ensure-class-UC; &class-r; &name-r; &key-amp;
    &direct-default-initargs-k; &direct-slots-k; &direct-superclasses-k;
    &name-k; &metaclass-k; &allow-other-keys-amp;)
 </code></simpara></listitem></varlistentry>
<varlistentry><term>Arguments</term>
 <listitem><variablelist>
   <varlistentry><term>&class-r;</term>
    <listitem><simpara>a &c-mo; or &nil;.</simpara></listitem></varlistentry>
   <varlistentry><term>&name-r;</term>
    <listitem><simpara>a class name.</simpara></listitem></varlistentry>
   <varlistentry><term>&metaclass-k;</term>
    <listitem><simpara>a &c-mo; class or a &c-mo; class name.  If this
      argument is not supplied, it defaults to the class named
      &standard-class;.  If a class name is supplied, it is interpreted
      as the class with that name.  If a class name is supplied, but
      there is no such class, an &err-sig;.</simpara></listitem></varlistentry>
   <varlistentry><term>&direct-superclasses-k;</term>
    <listitem><simpara>a list of which each element is a &c-mo; or a
      class name.  An &err-sig; if this argument is not a
      &proper-list-glo;.</simpara></listitem></varlistentry>
   <varlistentry><term>additional keyword arguments</term>
    <listitem><simpara>See <xref linkend="mop-cl-init-mo"/>
</simpara></listitem></varlistentry></variablelist></listitem></varlistentry>
<varlistentry><term>Value</term>&a-cmo;</varlistentry>
<varlistentry><term>Purpose</term>
 <listitem><simpara>This generic function is called to define or modify
   the definition of a named class.  It is called by the &ensure-class;
   function.  It can also be called directly.</simpara>
  <para>The first step performed by this generic function is to
   compute the set of initialization arguments which will be used to
   create or reinitialize the named class.  The initialization arguments
   are computed from the full set of keyword arguments received by this
   generic function as follows:<itemizedlist>
    <listitem><simpara>The &metaclass-k; argument is not included in the
      initialization arguments.</simpara></listitem>
    <listitem><para>If the &direct-superclasses-k; argument was received
      by this generic function, it is converted into a list of &c-mo;s.
      This conversion does not affect the structure of the supplied
      &direct-superclasses-k; argument.  For each element in the
      &direct-superclasses-k; argument:<itemizedlist>
       <listitem><simpara>If the element is a &c-mo;, that
         &c-mo; is used.</simpara></listitem>
       <listitem><simpara>If the element names a class, that &c-mo; is
         used.</simpara></listitem>
       <listitem><simpara>Otherwise an instance of the class
         &forward-referenced-class; is created and used.
         The &proper-name-glo; of the newly created forward referenced
         &c-mo; is set to the element.</simpara>
        <note>&clisp-only;<simpara>A new &forward-referenced-class;
          instance is only created when one for the given class name
          does not yet exist; otherwise the existing one is reused.
          See <xref linkend="forward-referenced-class-clisp"/>.</simpara>
    </note></listitem></itemizedlist></para></listitem>
    <listitem><simpara>All other keyword arguments are included directly
      in the initialization arguments.</simpara></listitem>
   </itemizedlist></para>
  <simpara>If the &class-r; argument is &nil;, a new &c-mo; is created
   by calling the &make-instance; generic function with the value of the
   &metaclass-k; argument as its first argument, and the previously
   computed initialization arguments.  The &proper-name-glo; of the
   newly created &c-mo; is set to &name-r;.  The newly created &c-mo; is
   returned.</simpara>
  <simpara>If the &class-r; argument is a &forward-referenced-class;,
   &change-class; is called to change its class to the value specified
   by the &metaclass-k; argument.  The &c-mo; is then reinitialized with
   the previously initialization arguments.  (This is a documented
   violation of the general constraint that &change-class; may not be
   used with &c-mo;s.)</simpara>
  <note>&clisp-only;<simpara>
    The &class-r; argument cannot be a &forward-referenced-class;. See
    <xref linkend="forward-referenced-class-clisp"/>.</simpara></note>
  <simpara>If the class of the &class-r; argument is not the same as the
   class specified by the &metaclass-k; argument, an &err-sig;.</simpara>
  <simpara>Otherwise, the &c-mo; &class-r; is redefined by calling the
   &reinitialize-instance; generic function with &class-r; and the
   initialization arguments.  The &class-r; argument is then
   returned.</simpara></listitem></varlistentry></variablelist>

<variablelist><title>Methods</title>
<varlistentry><term><literal role="method">(&ensure-class-UC;
   (&class-r; &class;) &name-r; &key-amp; &metaclass-k;
   &direct-superclasses-k; &allow-other-keys-amp;)</literal></term>
 <listitem><simpara>This method implements the behavior of the generic
   function in the case where the &class-r; argument is a class.</simpara>
 &overridable;</listitem></varlistentry>
<varlistentry><term><literal role="method">(&ensure-class-UC;
   (&class-r; &forward-referenced-class;) &name-r; &key-amp; &metaclass-k;
   &direct-superclasses-k; &allow-other-keys-amp;)</literal></term>
 <listitem><simpara>This method implements the behavior of the generic
   function in the case where the &class-r; argument is a forward
   referenced class.</simpara>
 <note>&clisp-only;<simpara>This method does not exist.
   See <xref linkend="forward-referenced-class-clisp"/>.
   Use the method specialized on &null-t; instead.</simpara></note>
</listitem></varlistentry>
<varlistentry><term><literal role="method">(&ensure-class-UC;
   (&class-r; &null-t;) &name-r; &key-amp; &metaclass-k;
   &direct-superclasses-k; &allow-other-keys-amp;)</literal></term>
 <listitem><simpara>This method implements the behavior of the generic
   function in the case where the &class-r; argument is &nil;.
</simpara></listitem></varlistentry></variablelist>
</section><!-- ensure-class-UC -->

<section id="finalize-inheritance">
 <title>Generic Function &finalize-inheritance;</title>

<variablelist><varlistentry><term>Syntax</term>
  <listitem><simpara><code>(&finalize-inheritance;
     &class-r;)</code></simpara></listitem></varlistentry>
<varlistentry><term>Arguments</term>
 <listitem><variablelist>&class-mo-arg;</variablelist></listitem></varlistentry>
&values-unspecified;
<varlistentry><term>Purpose</term>
 <listitem><simpara>This generic function is called to finalize a &c-mo;.
   This is described in <xref linkend="mop-cl-finalization"/>
  </simpara><simpara>After &finalize-inheritance; returns, the &c-mo; is
   finalized and the result of calling &class-finalized-p; on the &c-mo;
   will be true.</simpara></listitem></varlistentry></variablelist>

<variablelist><title>Methods</title>
<varlistentry><term><literal role="method">(&finalize-inheritance;
   (&class-r; &standard-class;))</literal></term>
 <term><literal role="method">(&finalize-inheritance;
   (&class-r; &funcallable-standard-class;))</literal></term>
<listitem>&no-extra-specs;</listitem></varlistentry>
<varlistentry><term><literal role="method">(&finalize-inheritance;
   (&class-r; &forward-referenced-class;))</literal></term>
<listitem><simpara>This method &sig-err;.
</simpara></listitem></varlistentry></variablelist>
</section><!-- finalize-inheritance -->

<section id="mop-make-instance"><title>Generic Function &make-instance;</title>

<variablelist><varlistentry><term>Syntax</term>
 <listitem><simpara><code>(&make-instance; &class-r; &rest-amp;
    &initargs-r;)</code></simpara></listitem></varlistentry>
<varlistentry><term>Arguments</term>
 <listitem><variablelist>
   <varlistentry><term>&class-r;</term>
    <listitem><simpara>a &c-mo; or a class name.
   </simpara></listitem></varlistentry>
   <varlistentry><term>&initargs-r;</term>
    <listitem><simpara>a list of alternating initialization argument
      names and values.</simpara></listitem></varlistentry>
</variablelist></listitem></varlistentry>
<varlistentry><term>Value</term>
 <listitem><simpara>A newly allocated and initialized instance of &class-r;.
</simpara></listitem></varlistentry>
<varlistentry><term>Purpose</term>
 <listitem><simpara>The generic function &make-instance; creates and
   returns a new instance of the given class.  Its behavior and use is
   described in the &ansi-cl;.
</simpara></listitem></varlistentry></variablelist>

<variablelist><title>Methods</title>
<varlistentry><term><literal role="method">(&make-instance;
   (&class-r; &symbol-t;) &rest-amp; &initargs-r;)</literal></term>
 <listitem><simpara>This method simply invokes &make-instance;
   recursively on the arguments <literal role="method">(&find-class;
   &class-r;)</literal> and &initargs-r;.</simpara></listitem></varlistentry>
<varlistentry><term><literal role="method">(&make-instance; (&class-r;
   &standard-class;) &rest-amp; &initargs-r;)</literal></term>
 <term><literal role="method">(&make-instance; (&class-r;
   &funcallable-standard-class;) &rest-amp; &initargs-r;)</literal></term>
 <listitem><simpara>These methods implement the behavior of
   &make-instance; described in the &ansi-cl; section
   <ulink role="clhs" url="sec_7-1">7.1
    <quote>Object Creation and Initialization</quote></ulink>.
</simpara></listitem></varlistentry></variablelist>
</section><!-- mop-make-instance -->

<section id="alloc-instance"><title>Generic Function &allocate-instance;</title>

<variablelist><varlistentry><term>Syntax</term>
  <listitem><simpara><code>(&allocate-instance; &class-r;
     &rest-amp; &initargs-r;)</code></simpara></listitem></varlistentry>
<varlistentry><term>Arguments</term>
 <listitem><variablelist>&class-mo-arg;
   <varlistentry><term>&initargs-r;</term>
    <listitem><simpara>alternating initialization argument names and
      values.</simpara></listitem></varlistentry>
</variablelist></listitem></varlistentry>
<varlistentry><term>Value</term>
 <listitem><simpara>A newly allocated instance of &class-r;
</simpara></listitem></varlistentry>
<varlistentry><term>Purpose</term>
 <listitem><simpara>This generic function is called to create a new,
   uninitialized instance of a class.  The interpretation of the concept
   of an <firstterm>uninitialized</firstterm> instance depends on the
   &c-mo; class.</simpara>
  <simpara>Before allocating the new instance, &class-finalized-p; is
   called to see if &class-r; has been finalized.  If it has not been
   finalized, &finalize-inheritance; is called before the new instance
   is allocated.</simpara></listitem></varlistentry></variablelist>

<variablelist><title>Methods</title>
<varlistentry><term><literal role="method">(&allocate-instance;
   (&class-r; &standard-class;) &rest-amp; &initargs-r;</literal></term>
 <listitem><simpara>This method allocates storage in the instance for
   each slot with allocation &instance-k;.  These slots are unbound.
   Slots with any other allocation are ignored by this method (no
   &err-sig;).</simpara></listitem></varlistentry>
<varlistentry><term><literal role="method">(&allocate-instance;
   (&class-r; &funcallable-standard-class;)
   &rest-amp; &initargs-r;)</literal></term>
 <listitem><simpara>This method allocates storage in the instance for
   each slot with allocation &instance-k;.  These slots are unbound.
   Slots with any other allocation are ignored by this method (no
   &err-sig;).</simpara>
  <simpara>The funcallable instance function of the instance is
   undefined - the results are undefined if the instance is applied to
   arguments before &set-funcallable-instance-function; has been used
   to set the funcallable instance function.
</simpara></listitem></varlistentry>
<varlistentry><term><literal role="method">(&allocate-instance;
   (&class-r; &built-in-class;) &rest-amp; &initargs-r;)</literal></term>
 <listitem><simpara>This method &sig-err;.
</simpara></listitem></varlistentry></variablelist>
</section><!-- alloc-instance -->

<!-- end class basic customization -->

<!-- begin class advanced customization -->

<section id="validate-superclass">
 <title>Generic Function &validate-superclass;</title>

<variablelist><varlistentry><term>Syntax</term>
 <listitem><simpara><code>(&validate-superclass; &class-r;
    &superclass-r;)</code></simpara></listitem></varlistentry>
<varlistentry><term>Arguments</term>
 <listitem><variablelist>&class-mo-arg;
   <varlistentry><term>&superclass-r;</term>&a-cmo;</varlistentry>
</variablelist></listitem></varlistentry>
<varlistentry><term>Value</term>
 <listitem><simpara>&boolean-t;.</simpara></listitem></varlistentry>
<varlistentry><term>Purpose</term>
 <listitem><simpara>This generic function is called to determine whether
   the class &superclass-r; is suitable for use as a superclass of
   &class-r;.</simpara>
  <simpara>This generic function can be be called by the implementation
   or user code.  It is called during &c-mo; initialization and
   reinitialization, before the direct superclasses are stored.  If this
   generic function returns false, the initialization or
   reinitialization will signal an error.
</simpara></listitem></varlistentry></variablelist>

<variablelist><title>Methods</title>
<varlistentry><term><literal role="method">(&validate-superclass;
   (&class-r; &class;) (&superclass-r; &class;))</literal></term>
<listitem><para>This method returns true in three situations:
  <orderedlist numeration="lowerroman">
   <listitem><simpara>If the &superclass-r; argument is the class named &t-t;,
   </simpara></listitem>
   <listitem><simpara>if the class of the &class-r; argument is the same
     as the class of the &superclass-r; argument, or
   </simpara></listitem>
   <listitem><simpara>if the class of one of the arguments is
     &standard-class; and the class of the other is
     &funcallable-standard-class;.</simpara></listitem>
  </orderedlist>In all other cases, this method returns false.</para>
 &overridable;
 <note>&clisp-only;<para>This method also returns true in a fourth situation:
   <orderedlist continuation="continues" numeration="lowerroman">
    <listitem><simpara>If the class of the &class-r; argument is a subclass
      of the class of the &superclass-r; argument.
 </simpara></listitem></orderedlist></para></note>
</listitem></varlistentry></variablelist>

<formalpara><title>Remarks</title>
<para>Defining a method on &validate-superclass; requires detailed
 knowledge of of the internal protocol followed by each of the two
 &c-mo; classes.  A method on &validate-superclass; which returns true
 for two different &c-mo; classes declares that they are
 compatible.</para></formalpara>
</section><!-- validate-superclass -->

<section id="compute-dsd-initargs">
 <title>Generic Function &compute-dsd-initargs;</title>
 <note>&clisp-only;<simpara/></note>

<variablelist><varlistentry><term>Syntax</term>
  <listitem><simpara><code>(&compute-dsd-initargs; &class-r; &rest-amp;
     &slot-spec-r;)</code></simpara></listitem></varlistentry>
 <varlistentry><term>Arguments</term>
  <listitem><variablelist>&class-mo-arg;
    <varlistentry><term>&slot-spec-r;</term><listitem><simpara>a
       &canonicalized-slot-spec;.</simpara></listitem></varlistentry>
</variablelist></listitem></varlistentry>
<varlistentry><term>Value</term>
 <listitem><simpara>A list of initialization arguments for a &dsdmo;.
</simpara></listitem></varlistentry>
<varlistentry><term>Purpose</term>
 <listitem><simpara>This generic function determines the initialization
   arguments for the direct slot definition for a slot in a class.
   It is called during initialization of a class.  The resulting
   initialization arguments are passed to &dsd-class; and then to
   &make-instance;.</simpara>
  <simpara>This generic function uses the supplied &canonicalized-slot-spec;.
   The value of &name-k; in the returned initargs is the same as the value
   of &name-k; in the supplied &slot-spec-r; argument.
</simpara></listitem></varlistentry></variablelist>

<variablelist><title>Methods</title>
<varlistentry><term><literal role="method">(&compute-dsd-initargs;
   (&class-r; &standard-class;) &rest-amp; &slot-spec-r;)</literal></term>
 <term><literal role="method">(&compute-dsd-initargs; (&class-r;
   &funcallable-standard-class;) &rest-amp; &slot-spec-r;)</literal></term>
 <listitem><simpara>This method returns &slot-spec-r; unmodified.</simpara>
  <simpara>This method can be overridden.</simpara></listitem>
</varlistentry></variablelist>
</section><!-- compute-dsd-initargs -->

<section id="dsd-class"><title>Generic Function &dsd-class;</title>

<variablelist><varlistentry><term>Syntax</term>
 <listitem><simpara><code>(&dsd-class; &class-r; &rest-amp;
    &initargs-r;)</code></simpara></listitem></varlistentry>
<varlistentry><term>Arguments</term>
 <listitem><variablelist>&class-mo-arg;
   <varlistentry><term>&initargs-r;</term>
    <listitem><simpara>a set of initialization arguments and values.
</simpara></listitem></varlistentry></variablelist></listitem></varlistentry>
<varlistentry><term>Value</term>
 <listitem><simpara>A subclass of the class &dsd-t;.
</simpara></listitem></varlistentry>
<varlistentry><term>Purpose</term>
 <listitem><simpara>When a class is initialized, each of the
   &canonicalized-slot-spec;s must be converted to a &dsdmo;.
   This generic function is called to determine
   the class of that &dsdmo;.</simpara>
  <simpara>The &initargs-r; argument is simply the
   &canonicalized-slot-spec; for the slot.
</simpara></listitem></varlistentry></variablelist>

<variablelist><title>Methods</title>
 <varlistentry><term><literal role="method">(&dsd-class;
    (&class-r; &standard-class;) &rest-amp; &initargs-r;)</literal></term>
  <term><literal role="method">(&dsd-class; (&class-r;
    &funcallable-standard-class;) &rest-amp; &initargs-r;)</literal></term>
 <listitem><simpara>These methods return the class &standard-dsd-t;.
  </simpara>&overridables;</listitem></varlistentry></variablelist>
</section><!-- dsd-class -->

<section id="compute-cpl"><title>Generic Function &compute-cpl;</title>

<variablelist><varlistentry><term>Syntax</term>
  <listitem><simpara><code>(&compute-cpl;
     &class-r;)</code></simpara></listitem></varlistentry>
<varlistentry><term>Arguments</term>
 <listitem><variablelist>&class-mo-arg;</variablelist></listitem></varlistentry>
<varlistentry><term>Value</term>
 <listitem><simpara>A list of &c-mo;s.</simpara></listitem></varlistentry>
<varlistentry><term>Purpose</term>
 <listitem><simpara>This generic-function is called to determine the
   class precedence list of a class.</simpara>
  <simpara>The result is a list which contains each of &class-r; and its
   superclasses once and only once.  The first element of the list is
   &class-r; and the last element is the class named &t-t;.</simpara>
  <simpara>All methods on this generic function must compute the class
   precedence list as a function of the ordered direct superclasses of
   the superclasses of &class-r;.  The results are undefined if the
   rules used to compute the class precedence list depend on any other
   factors.</simpara>
  <simpara>When a class is finalized, &finalize-inheritance; calls this
   generic function and associates the returned value with the &c-mo;.
   The value can then be accessed by calling &cpl;.</simpara>
   &result-immutable;</listitem></varlistentry></variablelist>

<variablelist><title>Methods</title>
<varlistentry><term><literal role="method">(&compute-cpl; (&class-r;
   &class;))</literal></term>
 <listitem><simpara>This method computes the class precedence list
   according to the rules described in the &ansi-cl; section
   <ulink role="clhs" url="sec_4-3-5">4.3.5 <quote>Determining the
     Class Precedence List</quote></ulink>.</simpara>
 <simpara>This method &sig-err; if &class-r; or any of its superclasses
  is a &forward-referenced-class;.</simpara>
 &overridable;</listitem></varlistentry></variablelist>
</section><!-- compute-cpl -->

<section id="compute-slots"><title>Generic Function &compute-slots;</title>

<variablelist><varlistentry><term>Syntax</term>
 <listitem><simpara><code>(&compute-slots; &class-r;)
 </code></simpara></listitem></varlistentry>
<varlistentry><term>Arguments</term>
 <listitem><variablelist>&class-mo-arg;</variablelist></listitem></varlistentry>
<varlistentry><term>Value</term>
 <listitem><simpara>A set of &esdmo;s.</simpara></listitem></varlistentry>
<varlistentry><term>Purpose</term>
 <listitem><simpara>This generic function computes a set of effective
   &sdmo;s for the class &class-r;.  The result is a list of &esdmo;s:
   one for each slot that will be accessible in instances of &class-r;.
  </simpara><simpara>This generic function proceeds in 3 steps:</simpara>
  <simpara>The first step collects the full set of direct slot
   definitions from the superclasses of &class-r;.</simpara>
  <simpara>The direct slot definitions are then collected into
   individual lists, one list for each slot name associated with any of
   the direct slot definitions.  The slot names are compared with
   &eql-t;.  Each such list is then sorted into class precedence list
   order.  Direct slot definitions coming from classes earlier in the
   class precedence list of &class-r; appear before those coming from
   classes later in the class precedence list.  For each slot name, the
   generic function &compute-esd; is called to compute an effective slot
   definition.  The result of &compute-slots; is a list of these
   effective slot definitions, in unspecified order.</simpara>
  <simpara>In the final step, the location for each effective slot
   definition is set.  This is done by specified around-methods;
   portable methods cannot take over this behavior.
   For more information on the slot definition locations,
   see <xref linkend="mop-sa-instance-struct"/>.</simpara>
  &result-immutable;</listitem></varlistentry></variablelist>

<variablelist><title>Methods</title>
<varlistentry><term><literal role="method">(&compute-slots;
   (&class-r; &standard-class;))</literal></term>
 <term><literal role="method">(&compute-slots;
   (&class-r; &funcallable-standard-class;)}</literal></term>
 <listitem><simpara>These methods implement the specified behavior of
   the generic function.</simpara>
  &overridables;</listitem></varlistentry>
<varlistentry><term><literal role="method">(&compute-slots;
   <constant>:AROUND</constant> (&class-r; &standard-class;))</literal></term>
 <term><literal role="method">(&compute-slots; <constant>:AROUND</constant>
   (&class-r; &funcallable-standard-class;))</literal></term>
 <listitem><simpara>These methods implement the specified behavior of
   computing and storing slot locations.
   These methods cannot be overridden.
</simpara></listitem></varlistentry></variablelist>
</section><!-- compute-slots -->

<section id="compute-esd"><title>Generic Function &compute-esd;</title>

<variablelist><varlistentry><term>Syntax</term>
 <listitem><simpara><code>(&compute-esd; &class-r; &name-r; &dsds-r;)
 </code></simpara></listitem></varlistentry>
<varlistentry><term>Arguments</term>
 <listitem><variablelist>&class-mo-arg;
   <varlistentry><term>&name-r;</term>
    <listitem><simpara>a slot name.</simpara></listitem></varlistentry>
   <varlistentry><term>&dsds-r;</term>
    <listitem><simpara>an ordered list of &dsdmo;s.  The most specific
      &dsdmo; appears first in the list.</simpara></listitem></varlistentry>
</variablelist></listitem></varlistentry>
<varlistentry><term>Value</term>
 <listitem><simpara>An &esdmo;.</simpara></listitem></varlistentry>
<varlistentry><term>Purpose</term>
 <listitem><simpara>This generic function determines the effective slot
   definition for a slot in a class.  It is called by &compute-slots;
   once for each slot accessible in instances of &class-r;.</simpara>
  <simpara>This generic function uses the supplied list of &dsdmo;s to
   compute the inheritance of slot properties for a single slot.  The
   returned effective slot definition represents the result of computing
   the inheritance.  The name of the new effective slot definition is
   the same as the name of the direct slot definitions supplied.</simpara>
  <simpara>The class of the &esdmo; is determined by calling
   &esd-class;.  The effective slot definition is then created by
   calling &make-instance;.  The initialization arguments passed in this
   call to &make-instance; are used to initialize the new &esdmo;.
   See <xref linkend="mop-sd"/> for details.
</simpara></listitem></varlistentry></variablelist>

<variablelist><title>Methods</title>
<varlistentry><term><literal role="method">(&compute-esd; (&class-r;
   &standard-class;) &name-r; &dsds-r;)</literal></term>
 <term><literal role="method">(&compute-esd; (&class-r;
   &funcallable-standard-class;) &name-r; &dsds-r;)</literal></term>
 <listitem>&implements-inheritance;
  <simpara>This method can be extended, but the value returned by the
   extending method must be the value returned by this method.
</simpara></listitem></varlistentry></variablelist>

<note>&clisp-only;<simpara>The initialization arguments that are passed
  to &esd-class; and &make-instance; are computed through a call to
  &compute-esd-initargs;.  It is the &compute-esd-initargs; method that
  implements the inheritance rules.</simpara></note>
</section><!-- compute-esd -->

<section id="compute-esd-initargs">
 <title>Generic Function &compute-esd-initargs;</title>
 <note>&clisp-only;<simpara/></note>

<variablelist><varlistentry><term>Syntax</term>
 <listitem><simpara><code>(&compute-esd-initargs; &class-r; &dsds-r;)
 </code></simpara></listitem></varlistentry>
<varlistentry><term>Arguments</term>
 <listitem><variablelist>&class-mo-arg;
   <varlistentry><term>&dsds-r;</term>
    <listitem><simpara>an ordered list of &dsdmo;s.  The most specific
      &dsdmo; appears first in the list.</simpara></listitem></varlistentry>
</variablelist></listitem></varlistentry>
<varlistentry><term>Value</term>
 <listitem><simpara>A list of initialization arguments for an &esdmo;.
</simpara></listitem></varlistentry>
<varlistentry><term>Purpose</term>
 <listitem><simpara>This generic function determines the initialization
   arguments for the effective slot definition for a slot in a class.
   It is called by &compute-esd;.  The resulting initialization arguments
   are passed to &esd-class; and then to &make-instance;.</simpara>
  <simpara>This generic function uses the supplied list of &dsdmo;s to
   compute the inheritance of slot properties for a single slot.  The
   returned effective slot definition initargs represent the result of
   computing the inheritance.  The value of &name-k; in the returned
   initargs is the same as the name of the direct slot definitions
   supplied.</simpara></listitem></varlistentry></variablelist>

<variablelist><title>Methods</title>
<varlistentry><term><literal role="method">(&compute-esd-initargs;
   (&class-r; &standard-class;) &dsds-r;)</literal></term>
 <term><literal role="method">(&compute-esd-initargs; (&class-r;
   &funcallable-standard-class;) &dsds-r;)</literal></term>
 <listitem>&implements-inheritance;
  <simpara>This method can be extended.</simpara></listitem>
</varlistentry></variablelist>
</section><!-- compute-esd-initargs -->

<section id="esd-class"><title>Generic Function &esd-class;</title>

<variablelist><varlistentry><term>Syntax</term>
 <listitem><simpara><code>(&esd-class; &class-r; &rest-amp;
    &initargs-r;)</code></simpara></listitem></varlistentry>
<varlistentry><term>Arguments</term>
 <listitem><variablelist>&class-mo-arg;
   <varlistentry><term>&initargs-r;</term>
    <listitem><simpara>set of initialization arguments and values.
</simpara></listitem></varlistentry></variablelist></listitem></varlistentry>
<varlistentry><term>Value</term>
 <listitem><simpara>A subclass of the class &esd-class;.
</simpara></listitem></varlistentry>
<varlistentry><term>Purpose</term>
 <listitem><simpara>This generic function is called by &compute-esd; to
   determine the class of the resulting &esdmo;.  The &initargs-r;
   argument is the set of initialization arguments and values that will
   be passed to &make-instance; when the &esdmo; is created.
</simpara></listitem></varlistentry></variablelist>

<variablelist><title>Methods</title>
<varlistentry><term><literal role="method">(&esd-class;
   (&class-r; &standard-class;) &rest-amp; &initargs-r;)</literal></term>
 <term><literal role="method">(&esd-class; (&class-r;
   &funcallable-standard-class;) &rest-amp; &initargs-r;)</literal></term>
 <listitem><simpara>These methods return the class &standard-esd-t;.
  </simpara>&overridables;</listitem></varlistentry></variablelist>
</section><!-- esd-class -->

<section id="compute-default-initargs">
 <title>Generic Function &compute-default-initargs;</title>

<variablelist><varlistentry><term>Syntax</term>
 <listitem><simpara><code>(&compute-default-initargs;
    &class-r;)</code></simpara></listitem></varlistentry>
<varlistentry><term>Arguments</term>
 <listitem><variablelist>&class-mo-arg;</variablelist></listitem></varlistentry>
<varlistentry><term>Value</term>
 <listitem><simpara>A list of &canonicalized-default-initarg;s.
</simpara></listitem></varlistentry>
<varlistentry><term>Purpose</term>
 <listitem><simpara>This generic-function is called to determine the
   default initialization arguments for a class.</simpara>
 <simpara>The result is a list of &canonicalized-default-initarg;s,
  with no duplication among initialization argument names.</simpara>
 <para>All methods on this generic function must compute the default
  initialization arguments as a function of only:
  <orderedlist numeration="lowerroman">
   <listitem><simpara>the class precedence list of &class-r;,
     and</simpara></listitem>
   <listitem><simpara>the direct default initialization arguments of each
     class in that list.</simpara></listitem>
  </orderedlist>The results are undefined if the rules used to compute
  the default initialization arguments depend on any other factors.</para>
 <simpara>When a class is finalized, &finalize-inheritance; calls this
  generic function and associates the returned value with the &c-mo;.
  The value can then be accessed by calling
  &class-default-initargs;.</simpara>
  &result-immutable;</listitem></varlistentry></variablelist>

<variablelist><title>Methods</title>
<varlistentry><term><literal role="method">(&compute-default-initargs;
   (&class-r; &standard-class;))</literal></term>
 <term><literal role="method">(&compute-default-initargs;
   (&class-r; &funcallable-standard-class;))</literal></term>
 <listitem><simpara>These methods compute the default initialization
   arguments according to the rules described in the &ansi-cl; section
   <ulink role="clhs" url="sec_7-1-3">7.1.3 <quote>Defaulting
     of Initialization Arguments</quote></ulink>.</simpara>
  <simpara>These methods signal an error if &class-r; or any of its
   superclasses is a &forward-referenced-class;.</simpara>
  &overridables;</listitem></varlistentry></variablelist>
</section><!-- compute-default-initargs -->

<!-- end class advanced customization -->

</section><!-- mop-cl-customize -->

<section id="mop-cl-dep"><title>Updating Dependencies</title>

<section id="add-direct-subclass">
 <title>Generic Function &add-direct-subclass;</title>

<variablelist><varlistentry><term>Syntax</term>
 <listitem><simpara><code>(&add-direct-subclass; &superclass-r;
    &subclass-r;)</code></simpara></listitem></varlistentry>
<varlistentry><term>Arguments</term>
 <listitem><variablelist>
   <varlistentry><term>&superclass-r;</term>&a-cmo;</varlistentry>
   <varlistentry><term>&subclass-r;</term>&a-cmo;</varlistentry>
</variablelist></listitem></varlistentry>
&values-unspecified;
<varlistentry><term>Purpose</term>
 <listitem><simpara>This generic function is called to maintain a set of
   backpointers from a class to its direct subclasses.  This generic
   function adds &subclass-r; to the set of direct subclasses of
   &superclass-r;.</simpara>
  <simpara>When a class is initialized, this generic function is called
   once for each direct superclass of the class.</simpara>
  <simpara>When a class is reinitialized, this generic function is
   called once for each added direct superclass of the class.  The
   generic function &remove-direct-subclass; is called once for each
   deleted direct superclass of the class.
</simpara></listitem></varlistentry></variablelist>

<variablelist><title>Methods</title>
<varlistentry><term><literal role="method">(&add-direct-subclass;
   (&superclass-r; &class;) (&subclass-r; &class;))</literal></term>
 <listitem>&no-extra-spec;
  <para>&also-must-override;<itemizedlist>
    <listitem><simpara><literal role="method">&remove-direct-subclass;
       (&class; &class;)</literal></simpara></listitem>
    <listitem><simpara><literal role="method">&class-direct-subclasses;
       (&class;)</literal></simpara></listitem></itemizedlist>
</para></listitem></varlistentry></variablelist>
</section><!-- add-direct-subclass -->

<section id="remove-direct-subclass">
 <title>Generic Function &remove-direct-subclass;</title>

<variablelist><varlistentry><term>Syntax</term>
 <listitem><simpara><code>(&remove-direct-subclass; &superclass-r;
    &subclass-r;)</code></simpara></listitem></varlistentry>
<varlistentry><term>Arguments</term>
 <listitem><variablelist>
   <varlistentry><term>&superclass-r;</term>&a-cmo;</varlistentry>
   <varlistentry><term>&subclass-r;</term>&a-cmo;</varlistentry>
</variablelist></listitem></varlistentry>
&values-unspecified;
<varlistentry><term>Purpose</term>
 <listitem><simpara>This generic function is called to maintain a set of
   backpointers from a class to its direct subclasses.  It removes
   &subclass-r; from the set of direct subclasses of &superclass-r;.  No
   &err-sig; if &subclass-r; is not in this set.</simpara>
  <simpara>Whenever a class is reinitialized, this generic function is
   called once with each deleted direct superclass of the class.
</simpara></listitem></varlistentry></variablelist>

<variablelist><title>Methods</title>
<varlistentry><term><literal role="method">(&remove-direct-subclass;
   (&superclass-r; &class;) (&subclass-r; &class;))</literal></term>
<listitem>&no-extra-spec;
 <para>&also-must-override;<itemizedlist>
   <listitem><simpara><literal role="method">&add-direct-subclass;
      (&class; &class;)</literal></simpara></listitem>
   <listitem><simpara><literal role="method">&class-direct-subclasses;
      (&class;)</literal></simpara></listitem>
</itemizedlist></para></listitem></varlistentry></variablelist>
</section><!-- remove-direct-subclass -->

</section><!-- mop-cl-dep -->
</section><!-- mop-classes -->


<section id="mop-sd"><title>Slot Definitions</title>

<section id="mop-sd-inheritance">
 <title>Inheritance Structure of &sdmo; Classes</title>
<figure id="mop-sd-inheritance-fig">
 <title>Inheritance structure of &sdmo; classes</title>
 <mediaobject><imageobject>
   <imagedata width="100%" scalefit="1" fileref="mop-classes-slotdef.png"/>
</imageobject></mediaobject></figure>
</section>

<section id="mop-sd-readers">
 <title>Introspection: Readers for &sdmo;s</title>

<para>The reader generic functions which simply return information
associated with &sdmo;s are presented together here
in the format described in <xref linkend="mop-cl-readers"/>.</para>

<para>Each of the reader generic functions for &sdmo;s has the same
syntax, accepting one required argument called &slot-r;, which must be a
&sdmo;; otherwise, an &err-sig;. An &error-t; is also &signal;ed if the &sdmo;
has not been initialized.</para>

&user-and-implementation-callable-result-immutable;

<!-- begin slot-definition basic introspection -->

<section id="mop-sd-readers-GFs"><title>Generic Functions</title>

<section id="slotdef-name"><title>Generic Function &slotdef-name;</title>
 <subtitle><code>(&slotdef-name; &slot-r;)</code></subtitle>

<para>Returns the name of &slot-r;.  This value is a symbol that can be
used as a variable name.  This is the value of the &name-k;
initialization argument that was associated with the &sdmo; during
initialization.</para>

<note>&clisp-only;<simpara>The slot name does not need to be usable as a
  variable name. Slot names like &nil; or &t; are perfectly valid.
</simpara></note></section>

<section id="slotdef-allocation">
 <title>Generic Function &slotdef-allocation;</title>
 <subtitle><code>(&slotdef-allocation; &slot-r;)</code></subtitle>

<para>Returns the allocation of &slot-r;.  This is a symbol.  This is
the defaulted value of the &allocation-k; initialization argument that
was associated with the &sdmo; during initialization.</para></section>

<section id="slotdef-initform">
 <title>Generic Function &slotdef-initform;</title>
 <subtitle><code>(&slotdef-initform; &slot-r;)</code></subtitle>

<para>Returns the initialization form of &slot-r;.  This can be any
form.  This is the defaulted value of the &initform-k; initialization
argument that was associated with the &sdmo; during initialization.
When &slot-r; has no initialization form, the value returned is
unspecified (however, &slotdef-initfunction; is guaranteed to return
&nil;).</para></section>

<section id="slotdef-initfunction">
 <title>Generic Function &slotdef-initfunction;</title>
 <subtitle><code>(&slotdef-initfunction; &slot-r;)</code></subtitle>

<para>Returns the initialization function of &slot-r;.  This value is
either a function of no arguments, or &nil;, indicating that the slot
has no initialization function.  This is the defaulted value of the
&initfunction-k; initialization argument that was associated with the
&sdmo; during initialization.</para></section>

<section id="slotdef-type">
 <title>Generic Function &slotdef-type;</title>
 <subtitle><code>(&slotdef-type; &slot-r;)</code></subtitle>

<para>Returns the type of &slot-r;.  This is a &typespec-glo; name.
This is the defaulted value of the &type-k; initialization argument that
was associated with the &sdmo; during initialization.</para></section>

<section id="slotdef-initargs">
 <title>Generic Function &slotdef-initargs;</title>
 <subtitle><code>(&slotdef-initargs; &slot-r;)</code></subtitle>

<para>Returns the set of initialization argument keywords for &slot-r;.
This is the defaulted value of the &initargs-k; initialization argument
that was associated with the &sdmo; during initialization.</para></section>
</section><!-- mop-sd-readers-GFs -->

<section id="slotd-mo-readers-methods"><title>Methods</title>

<variablelist><title>The specified methods for the &sdmo; readers</title>
 <varlistentry>
  <term><literal role="method">(&slotdef-name;
    (&slotdef-r; &standard-slotdef-t;))</literal></term>
  <term><literal role="method">(&slotdef-allocation;
    (&slotdef-r; &standard-slotdef-t;))</literal></term>
  <term><literal role="method">(&slotdef-initform;
    (&slotdef-r; &standard-slotdef-t;))</literal></term>
  <term><literal role="method">(&slotdef-initfunction;
    (&slotdef-r; &standard-slotdef-t;))</literal></term>
  <term><literal role="method">(&slotdef-type;
    (&slotdef-r; &standard-slotdef-t;))</literal></term>
  <term><literal role="method">(&slotdef-initargs;
    (&slotdef-r; &standard-slotdef-t;))</literal></term>
  <listitem>&no-extra-specs;</listitem></varlistentry></variablelist>
</section><!-- slotd-mo-readers-methods -->

<section id="slotd-mo-readers-dsd"><title>Readers for &dsdmo;s</title>

<para>The following additional reader generic functions are defined for
 &dsdmo;s.</para>

<section id="slotdef-readers">
 <title>Generic Function &slotdef-readers;</title>
 <subtitle><code>(&slotdef-readers; &dsd-r;)</code></subtitle>

<para>Returns a (possibly empty) set of readers of the &dsd-r;.  This
value is a list of function names.  This is the defaulted value of the
&readers-k; initialization argument that was associated with the direct
&sdmo; during initialization.</para></section>

<section id="slotdef-writers">
 <title>Generic Function &slotdef-writers;</title>
 <subtitle><code>(&slotdef-writers; &dsd-r;)</code></subtitle>

<para>Returns a (possibly empty) set of writers of the &dsd-r;.  This
value is a list of function names.  This is the defaulted value of the
&writers-k; initialization argument that was associated with the direct
&sdmo; during initialization.
<variablelist>
 <varlistentry><term><literal role="method">(&slotdef-readers;
    (&dsd-r; &standard-dsd-t;))</literal></term>
  <term><literal role="method">(&slotdef-writers;
    (&dsd-r; &standard-dsd-t;))</literal></term>
  <listitem>&no-extra-specs;</listitem></varlistentry></variablelist>
</para></section>

</section><!-- slotd-mo-readers-dsd -->

<!-- end slot-definition basic introspection -->

<!-- begin slot-definition advanced introspection -->

<section id="slotd-mo-readers-esd"><title>Readers for &esdmo;s</title>

<para>The following reader generic function is defined for effective
 &sdmo;s.</para>

<section id="slotdef-location">
 <title>Generic Function &slotdef-location;</title>
 <subtitle><code>(&slotdef-location; &esd-r;)</code></subtitle>

<para>Returns the location of &esd-r;.  The meaning and interpretation
 of this value is described in <xref linkend="mop-sa-instance-struct"/>.</para>

<variablelist>
 <varlistentry><term><literal role="method">(&slotdef-location;
    (&esd-r; &standard-esd-t;))</literal></term>
  <listitem><simpara>This method returns the value stored by
    <literal role="method">&compute-slots; <constant>:AROUND</constant>
     (&standard-class;)</literal> and
    <literal role="method">&compute-slots; <constant>:AROUND</constant>
     (&funcallable-standard-class;)</literal>.
</simpara></listitem></varlistentry></variablelist></section>

</section><!-- slotd-mo-readers-esd -->

<!-- end slot-definition advanced introspection -->

</section><!-- mop-sd-readers -->

<section id="mop-sd-init"><title>Initialization of &sdmo;s</title>

<para>A &sdmo; can be created by calling &make-instance;.  The
initialization arguments establish the definition of the slot
definition.  A &sdmo; cannot be redefined; calling
&reinitialize-instance; &sig-err;.</para>

<para>Initialization of a &sdmo; must be done by calling &make-instance;
and allowing it to call &initialize-instance;.
 Portable programs must &not-e;...<itemizedlist>
  <listitem><simpara>... call &initialize-instance; directly to
    initialize a &sdmo;;</simpara></listitem>
  <listitem><simpara>... call &shared-initialize; directly to
    initialize a &sdmo;;</simpara></listitem>
  <listitem><simpara>... call &change-class; to change the class of any
    &sdmo; or to turn a non-slot-definition object into a
    &sdmo;.</simpara></listitem></itemizedlist></para>

<para>Since metaobject classes may not be redefined, no behavior is
 specified for the result of calls to
 &update-instance-for-redefined-class; on &sdmo;s.  Since the class of a
 &sdmo; cannot be changed, no behavior is specified for the result of
 calls to &update-instance-for-different-class; on &sdmo;s.</para>

<para>During initialization, each initialization argument is checked for
errors and then associated with the &sdmo;.  The value can then be
accessed by calling the appropriate accessor as shown in
 <xref linkend="slotd-mo-initargs"/>.</para>

<para>This section begins with a description of the error checking and
processing of each initialization argument.  This is followed by a table
showing the generic functions that can be used to access the stored
initialization arguments.</para>

<para>In these descriptions, the phrase <quote>this argument defaults to
&value-r;</quote> means that when that initialization argument is not
supplied, initialization is performed as if &value-r; had been supplied.
For some initialization arguments this could be done by the use of
default initialization arguments, but whether it is done this way is not
specified.  Implementations are free to define default initialization
arguments for specified &sdmo; classes.  Portable programs are free to
define default initialization arguments for portable subclasses of the
class &slotdef-t;.</para>

<itemizedlist>
 <listitem><simpara>The &name-k; argument is a slot name.  An &err-sig;
   if this argument is not a symbol which can be used as a variable
   name.  An &err-sig; if this argument is not supplied.</simpara>
  <note>&clisp-only;<simpara>The &name-k; argument does not need to be
    usable as a variable name. Slot names like &nil; or &t; are
    perfectly valid.</simpara></note></listitem>
 <listitem><simpara>The &initform-k; argument is a form. The
   &initform-k; argument defaults to &nil;.  An &err-sig; if the
   &initform-k; argument is supplied, but the &initfunction-k; argument
   is not supplied.</simpara></listitem>
 <listitem><simpara>The &initfunction-k; argument is a function of zero
   arguments which, when called, evaluates the &initform-k; in the
   appropriate &lex-env;.  The &initfunction-k; argument
   defaults to false.  An &err-sig; if the &initfunction-k; argument is
   supplied, but the &initform-k; argument is not supplied.</simpara></listitem>
 <listitem><simpara>The &type-k; argument is a &typespec-glo; name.  An
   &err-sig; otherwise.  The &type-k; argument defaults to the symbol &t;.
 </simpara></listitem>
 <listitem><simpara>The &allocation-k; argument is a &symbol-t;.  An
   &err-sig; otherwise.  The &allocation-k; argument defaults to the
   symbol &instance-k;.</simpara></listitem>
 <listitem><simpara>The &initargs-k; argument is a &list-t; of &symbol-t;s.
   An &err-sig; if this argument is not a &proper-list-glo;, or if any
   element of this list is not a &symbol-t;.  The &initargs-k; argument
   defaults to the empty list.</simpara></listitem>
 <listitem><simpara>The &readers-k; and &writers-k; arguments are
   &list-t;s of function names.  An &err-sig; if they are not
   &proper-list-glo;s, or if any element is not a valid function name.
   They default to the empty list.  An &err-sig; if either of these
   arguments is supplied and the metaobject is not a &dsd-t;.
 </simpara></listitem>
 &doc-k-li;
</itemizedlist>

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

<table id="slotd-mo-initargs"><title>Initialization arguments and
  accessors for &sdmo;s</title>
 <tgroup cols="2" colsep="1" rowsep="1" align="center">
  <thead><row><entry>Initialization Argument</entry>
    <entry>Generic Function</entry></row></thead>
  <tbody><row><entry>&name-k;</entry><entry>&slotdef-name;</entry></row>
   <row><entry>&initform-k;</entry><entry>&slotdef-initform;</entry></row>
   <row><entry>&initfunction-k;</entry>
    <entry>&slotdef-initfunction;</entry></row>
   <row><entry>&type-k;</entry><entry>&slotdef-type;</entry></row>
   <row><entry>&allocation-k;</entry><entry>&slotdef-allocation;</entry></row>
   <row><entry>&initargs-k;</entry><entry>&slotdef-initargs;</entry></row>
   <row><entry>&readers-k;</entry><entry>&slotdef-readers;</entry></row>
   <row><entry>&writers-k;</entry><entry>&slotdef-writers;</entry></row>
   <row><entry>&documentation-k;</entry><entry>&documentation;</entry></row>
</tbody></tgroup></table></para>

<section id="slotdef-mo-methods"><title>Methods</title>

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

<para>These restrictions govern the methods that a portable program can
define on the generic functions &initialize-instance;,
&reinitialize-instance;, and &shared-initialize;.  These restrictions
apply only to methods on these generic functions for which the first
specializer is a subclass of the class &slotdef-t;.  Other portable
methods on these generic functions are not affected by these
restrictions.</para>

<itemizedlist>
 <listitem><simpara>Portable programs must not define methods on
   &shared-initialize; or &reinitialize-instance;.</simpara></listitem>
 <listitem><para>For &initialize-instance;:
   &init-method-restrictions;</para></listitem>
</itemizedlist>
&else-undefined;
</section><!-- slotdef-mo-methods -->

</section><!-- mop-sd-init -->
</section><!-- mop-sd -->

<section id="mop-gf"><title>Generic Functions</title>

<section id="mop-gf-inheritance">
 <title>Inheritance Structure of &gfmo; Classes</title>
<figure id="mop-gf-inheritance-fig">
 <title>Inheritance structure of &gfmo; classes</title>
 <mediaobject><imageobject>
   <imagedata width="100%" scalefit="1" fileref="mop-classes-genfun.png"/>
</imageobject></mediaobject></figure>
</section>

<section id="mop-gf-readers">
 <title>Introspection: Readers for &gfmo;s</title>

<para>The reader generic functions which simply return information
associated with &gfmo;s are presented together here in the format
described in <xref linkend="mop-cl-readers"/>.</para>

<para>Each of the reader generic functions for &gfmo;s has the same
syntax, accepting one required argument called &gf-r;, which must be a
&gfmo;; otherwise, an &err-sig;.  An &error-t; is also &signal;ed if the
&gfmo; has not been initialized.</para>

&user-and-implementation-callable-result-immutable;

<!-- begin generic-function basic introspection -->

<section id="gf-name"><title>Generic Function &gf-name;</title>
 <subtitle><code>(&gf-name; &gf-r;)</code></subtitle>

<para>Returns the name of the generic function, or &nil; if the generic
function has no name.  This is the defaulted value of the &name-k;
initialization argument that was associated with the &gfmo; during
initialization or reinitialization.
 (See also &setf-gf-name;.)</para></section>

<section id="gf-methods"><title>Generic Function &gf-methods;</title>
 <subtitle><code>(&gf-methods; &gf-r;)</code></subtitle>

<para>Returns the set of methods currently connected to the generic
function.  This is a set of &m-mo;s.  This value is maintained by the
generic functions &add-method; and &remove-method;.</para></section>

<section id="gf-lambda-list"><title>Generic Function &gf-lambda-list;</title>
 <subtitle><code>(&gf-lambda-list; &gf-r;)</code></subtitle>

<para>Returns the &lalist; of the generic function.  This is the
defaulted value of the &lambda-list-k; initialization argument that was
associated with the &gfmo; during initialization or reinitialization.
An &err-sig; if the &lalist; has yet to be supplied.</para></section>

<section id="gf-argument-precedence-order">
 <title>Generic Function &gf-argument-precedence-order;</title>
 <subtitle><code>(&gf-argument-precedence-order; &gf-r;)</code></subtitle>

<para>Returns the argument precedence order of the generic function.
This value is a list of symbols, a permutation of the required
parameters in the &lalist; of the generic function.  This is the
defaulted value of the &argument-precedence-order-k; initialization
argument that was associated with the &gfmo; during initialization or
reinitialization.</para>

<note>&clisp-only;<simpara>An &err-sig; if the &lalist; has not yet been
  supplied.</simpara></note></section>

<!-- end generic-function basic introspection -->

<!-- begin generic-function advanced introspection -->

<section id="gf-declarations"><title>Generic Function &gf-declarations;</title>
 <subtitle><code>(&gf-declarations; &gf-r;)</code></subtitle>

<para>Returns a possibly empty list of the <quote>declarations</quote>
of the generic function.  The elements of this list are
&declspec-glo;s.  This list is the defaulted value of the
&declarations-k; initialization argument that was associated with the
&gfmo; during initialization or reinitialization.</para></section>

<section id="gf-method-class"><title>Generic Function &gf-method-class;</title>
 <subtitle><code>(&gf-method-class; &gf-r;)</code></subtitle>

<para>Returns the default method class of the generic function.  This
class must be a subclass of the class &method-t;.  This is the defaulted
value of the &method-class-k; initialization argument that was
associated with the &gfmo; during initialization or reinitialization.
</para></section>

<section id="gf-method-combination">
 <title>Generic Function &gf-method-combination;</title>
 <subtitle><code>(&gf-method-combination; &gf-r;)</code></subtitle>

<para>Returns the method combination of the generic function.  This is a
&mcmo;.  This is the defaulted value of the &method-combination-k;
initialization argument that was associated with the &gfmo; during
initialization or reinitialization.</para></section>

<!-- end generic-function advanced introspection -->

<section id="gf-name-methods"><title>Methods</title>

<variablelist><title>The specified methods for the &gfmo; reader generic
  functions</title>
<varlistentry>
 <term><literal role="method">(&gf-name;
   (&gf-r; &standard-generic-function-t;))</literal></term>
 <term><literal role="method">(&gf-lambda-list;
   (&gf-r; &standard-generic-function-t;))</literal></term>
 <term><literal role="method">(&gf-argument-precedence-order;
   (&gf-r; &standard-generic-function-t;))</literal></term>
 <term><literal role="method">(&gf-declarations;
   (&gf-r; &standard-generic-function-t;))</literal></term>
 <term><literal role="method">(&gf-method-class;
   (&gf-r; &standard-generic-function-t;))</literal></term>
 <term><literal role="method">(&gf-method-combination;
   (&gf-r; &standard-generic-function-t;))</literal></term>
 <listitem>&no-extra-specs;</listitem></varlistentry>
<varlistentry><term><literal role="method">(&gf-methods;
   (&gf-r; &standard-generic-function-t;))</literal></term>
 <listitem>&no-extra-spec;
  <simpara>The value returned by this method is maintained by
   <literal role="method">&add-method;(&standard-generic-function-t;
    &standard-method-t;)</literal> and
   <literal role="method">&remove-method;(&standard-generic-function-t;
    &standard-method-t;)</literal>.</simpara></listitem></varlistentry>
</variablelist>
</section><!-- gf-name-methods -->
</section><!-- mop-gf-readers -->

<section id="mop-gf-init"><title>Initialization of Generic Functions</title>

<section id="mop-gf-init-defgeneric"><title>Macro &defgeneric;</title>

<para>The evaluation or execution of a &defgeneric; form results in a
call to the &ensure-gf; function. The arguments received by &ensure-gf;
are derived from the &defgeneric; form in a defined way.  As with
&defclass; and &defmethod;, the exact macro-expansion of the
&defgeneric; form is not defined, only the relationship between the
arguments to the macro and the arguments received by &ensure-gf;.</para>

<itemizedlist><listitem><simpara>The &funcname-r;
argument to &defgeneric; becomes the first argument to &ensure-gf;.
This is the only positional argument accepted by &ensure-gf;; all other
arguments are keyword arguments.</simpara></listitem>
<listitem><simpara>The &lalist-r; argument to &defgeneric; becomes the value
 of the &lambda-list-k; keyword argument to &ensure-gf;.</simpara></listitem>
<listitem><simpara>For each of the options &argument-precedence-order-k;,
&documentation-k;, &gf-class-k; and &method-class-k;, the value of the
option becomes the value of the keyword argument with the same name.
If the option does not appear in the macro form, the keyword argument
does not appear in the resulting call to &ensure-gf;.</simpara>
<note>&clisp-only;<simpara>If the option does not appear in the macro form,
  the keyword argument appears in the resulting call to &ensure-gf;, with a
  default value: the &lalist-r; for &argument-precedence-order-k;, &nil; for
  &documentation-k;, the class &standard-generic-function-t; for &gf-class-k;,
  the class &standard-method-t; for &method-class-k;.
  This is needed to make the generic function reflect the &defgeneric; form.
</simpara></note></listitem>
<listitem><simpara>For the option &declare-k;, the list
of <quote>declarations</quote> becomes the value of the &declarations-k;
keyword argument.  If the &declare-k; option does not
appear in the macro form, the &declarations-k; keyword argument does not
appear in the call to &ensure-gf;.</simpara>
<note>&clisp-only;<simpara>If the &declare-k; option does not appear in
  the macro form, the &declarations-k; keyword argument appears in the
  resulting call to &ensure-gf;, with a default value of &nil;.  This is
  needed to make the generic function reflect the &defgeneric; form.
 </simpara></note></listitem>
<listitem><simpara>The handling of the &method-combination-k; option is
not specified.</simpara>
<note>&clisp-only;<simpara>If the &method-combination-k; option does not
  appear in the macro form, the &method-combination-k; keyword argument
  still appears in the resulting call to &ensure-gf;, but in a position
  where it can be overridden by user-defined initargs and default initargs.
 </simpara></note></listitem>
<listitem><note>&clisp-only;<simpara>The &declare-k; keyword is
  recognized as equivalent to the &declarations-k; keyword, for
  compatibility with &ensure-gf; in &ansi-cl;.  If both &declare-k; and
  &declarations-k; keyword arguments are specified, an &err-sig;.</simpara>
  <simpara>Any other generic function options become the value of
   keyword arguments with the same name. The value of the keyword
   argument is the tail of the generic function option. An &err-sig; if
   any generic function option appears more than once in the
   &defgeneric; form.</simpara>
  <simpara>The default initargs of the
   <replaceable>generic-function-class</replaceable> are added at the
   end of the list of arguments to pass to &ensure-gf;. This is needed to
   make the generic function reflect the &defgeneric; form.</simpara>
</note></listitem>
<listitem><note>&clisp-only;<formalpara id="mop-defgeneric-user-options">
   <title>User-defined options</title>
   <para>Any other options become the value of keyword arguments with
    the same name.  The value of the keyword argument is the tail of the
    option.  An &err-sig; if any option appears more than once in the
    &defgeneric; form.</para></formalpara></note></listitem>
</itemizedlist>

<para>The result of the call to &ensure-gf; is returned as the result of
evaluating or executing the &defgeneric; form.</para>
</section><!-- mop-gf-init-defgeneric -->

<section id="mop-gf-invocation">
 <title>Generic Function Invocation Protocol</title>

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

<para>The discriminating function is computed by the highest layer of
the generic function invocation protocol, &compute-discriminating-function;.
Whenever a &gfmo; is initialized, reinitialized, or a method is added or
removed, the discriminating function is recomputed.
The new discriminating function is then stored with
&set-funcallable-instance-function;.</para>

<para>Discriminating functions call &compute-applicable-methods-mop;
and &compute-applicable-methods-UC; to compute the methods
applicable to the generic functions arguments.
Applicable methods are combined by &compute-effective-method; to
produce an <firstterm>effective method
  <indexterm id="effective-method" significance="preferred">
   &me-prim;<secondary>effective</secondary></indexterm></firstterm>.
Provisions are made to allow memoization of the method applicability and
effective methods computations.  (See the description of
&compute-discriminating-function; for details.)</para>

<para>The body of method definitions are processed by &make-method-lambda;.
The result of this generic function is a &lambda-expr;
which is processed by either &compile; or &compile-file; to produce a
 <firstterm>method function<indexterm id="me-func" significance="preferred">
   &me-prim;<secondary>function</secondary></indexterm></firstterm>.
The arguments received by the method function are controlled by the
&call-method; forms appearing in the effective methods.
By default, method functions accept two arguments: a list of arguments
to the generic function, and a list of next methods.
The list of next methods corresponds to the next methods argument to
&call-method;.
If &call-method; appears with additional arguments, these will be passed
to the method functions as well; in these cases, &make-method-lambda;
must have created the method lambdas to expect additional arguments.</para>
<note>&clisp-only;
 <simpara>See <xref linkend="no-make-method-lambda"/>.</simpara>
 <simpara>See <xref linkend="method-functions-args"/>.</simpara></note>

</section><!-- mop-gf-invocation -->

<section id="mop-gf-init-mo"><title>Initialization of &gfmo;s</title>

<para>A &gfmo; can be created by calling &make-instance;.  The
initialization arguments establish the definition of the generic
function.  A &gfmo; can be redefined by calling &reinitialize-instance;.
Some classes of &gfmo; do not support redefinition; in these cases,
&reinitialize-instance; &sig-err;.</para>

<para>Initialization of a &gfmo; must be done by calling &make-instance;
and allowing it to call &initialize-instance;.  Reinitialization of a
&gfmo; must be done by calling &reinitialize-instance;.
 Portable programs must &not-e;<itemizedlist>
  <listitem><simpara>... call &initialize-instance; directly to
    initialize a &gfmo;;</simpara></listitem>
  <listitem><simpara>... call &shared-initialize; directly to
    initialize or reinitialize a &gfmo;;</simpara></listitem>
  <listitem><simpara>... call &change-class; to change the class of any
    &gfmo; or to turn a non-generic-function object into a
    &gfmo;.</simpara></listitem></itemizedlist></para>

<para>Since metaobject classes may not be redefined,
 no behavior is specified for the result of calls to
 &update-instance-for-redefined-class; on &gfmo;s.
 Since the class of a &gfmo; may not be changed,
 no behavior is specified for the results of calls to
 &update-instance-for-different-class; on &gfmo;s.</para>

<para>During initialization or reinitialization, each initialization
argument is checked for errors and then associated with the &gfmo;.
The value can then be accessed by calling the appropriate accessor as
shown in <xref linkend="gf-mo-initargs"/>.</para>

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

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

&reinit-keep-value;

<itemizedlist>
 <listitem><simpara>The &argument-precedence-order-k; argument is a list
   of symbols.</simpara>
  <simpara>An &err-sig; if this argument appears but the &lambda-list-k;
   argument does not appear.  An &err-sig; if this value is not a
   &proper-list-glo; or if this value is not a permutation of the
   symbols from the required arguments part of the &lambda-list-k;
   initialization argument.</simpara>
  <simpara>When the generic function is being initialized or
   reinitialized, and this argument is not supplied, but the
   &lambda-list-k; argument is supplied, this value defaults to the
   symbols from the required arguments part of the &lambda-list-k;
   argument, in the order they appear in that argument.  If neither
   argument is supplied, neither are initialized (see the description of
   &lambda-list-k;.)</simpara></listitem>
 <listitem><simpara>The &declarations-k; argument is a list of &declspec-glo;s.
  </simpara><simpara>An &err-sig; if this value is not a &proper-list-glo; or
   if each of its elements is not a legal &declspec-glo;.</simpara>
  <simpara>When the generic function is being initialized, and this
   argument is not supplied, it defaults to the empty list.
 </simpara></listitem>
 &doc-k-li;
 <listitem><simpara>The &lambda-list-k; argument is a &lalist;.</simpara>
  <simpara>An &err-sig; if this value is not a proper generic function
   &lalist;.</simpara>
  <simpara>When the generic function is being initialized, and this
   argument is not supplied, the generic function's &lalist; is not
   initialized.  The &lalist; will be initialized later, either when
   the first method is added to the generic function, or a later
   reinitialization of the generic function.</simpara></listitem>
 <listitem><simpara>The &method-combination-k; argument is a &mcmo;.
 </simpara></listitem>
 <listitem><simpara>The &method-class-k; argument is a &c-mo;.
  </simpara><simpara>An &err-sig; if this value is not a subclass of the
   class &method-t;.</simpara>
  <simpara>When the generic function is being initialized, and this
   argument is not supplied, it defaults to the class &standard-method-t;.
 </simpara></listitem>
 <listitem><simpara>  The &name-k; argument is an object.</simpara>
  <simpara>If the generic function is being initialized, this argument
   defaults to &nil;.
</simpara></listitem></itemizedlist>

<para>After the processing and defaulting of initialization arguments
described above, the value of each initialization argument is associated
with the &gfmo;.  These values can then be accessed by calling the
corresponding generic function.  The correspondences are as follows:
<table id="gf-mo-initargs"><title>Initialization arguments and accessors
  for &gfmo;s</title>
 <tgroup cols="2" colsep="1" rowsep="1" align="center">
  <thead><row><entry>Initialization Argument</entry>
    <entry>Generic Function</entry></row></thead>
  <tbody><row><entry>&argument-precedence-order-k;</entry>
    <entry>&gf-argument-precedence-order;</entry></row>
   <row><entry>&declarations-k;</entry><entry>&gf-declarations;</entry></row>
   <row><entry>&documentation-k;</entry><entry>&documentation;</entry></row>
   <row><entry>&lambda-list-k;</entry><entry>&gf-lambda-list;</entry></row>
   <row><entry>&method-combination-k;</entry>
    <entry>&gf-method-combination;</entry></row>
   <row><entry>&method-class-k;</entry><entry>&gf-method-class;</entry></row>
   <row><entry>&name-k;</entry><entry>&gf-name;</entry></row>
</tbody></tgroup></table></para>

<section id="gf-mo-init-methods"><title>Methods</title>

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

<para>These restrictions govern the methods that a portable program can
define on the generic functions &initialize-instance;,
&reinitialize-instance;, and &shared-initialize;.  These restrictions
apply only to methods on these generic functions for which the first
specializer is a subclass of the class &generic-function-t;.  Other
portable methods on these generic functions are not affected by these
restrictions.</para>

<itemizedlist>
 <listitem><simpara>Portable programs must not define methods on
   &shared-initialize;.</simpara></listitem>
 <listitem><para>For &initialize-instance; and &reinitialize-instance;:
   &init-method-restrictions;</para></listitem>
</itemizedlist>
&else-undefined;
</section><!-- gf-mo-init-methods -->
</section><!-- mop-gf-init-mo -->
</section><!-- mop-gf-init -->

<section id="mop-gf-customize"><title>Customization</title>

<!-- begin generic-function basic customization -->

<section id="setf-gf-name"><title>Generic Function &setf-gf-name;</title>

<variablelist><varlistentry><term>Syntax</term>
 <listitem><simpara><code>(&setf-gf-name; &nname-r; &gf-r;)
</code></simpara></listitem></varlistentry>
<varlistentry><term>Arguments</term>
 <listitem><variablelist>&gf-mo-arg;
   <varlistentry><term>&nname-r;</term>
    <listitem><simpara>a &funname; or &nil;.
</simpara></listitem></varlistentry></variablelist></listitem></varlistentry>
<varlistentry><term>Value</term>
 <listitem><simpara>The &nname-r; argument.</simpara></listitem></varlistentry>
<varlistentry><term>Purpose</term>
 <listitem><simpara>This function changes the name of &gf-r; to &nname-r;.
   This value is usually a &funname; or &nil;, if the generic function
   is to have no name.</simpara>
  <simpara>This function works by calling &reinitialize-instance; with
   &gf-r; as its first argument, the symbol &name-k; as its second argument
   and &nname-r; as its third argument.
</simpara></listitem></varlistentry></variablelist>
</section><!-- setf-gf-name -->

<section id="ensure-gf"><title>Generic Function &ensure-gf;</title>

<variablelist><varlistentry><term>Syntax</term>
 <listitem><simpara><code>(&ensure-gf; &funcname-r; &key-amp;
     &allow-other-keys-amp;)</code></simpara></listitem></varlistentry>
<varlistentry><term>Arguments</term>
 <listitem><variablelist>
   <varlistentry><term>&funcname-r;</term>
    <listitem><simpara>a &funname;</simpara></listitem></varlistentry>
   <varlistentry><term>keyword arguments</term>
    <listitem><simpara>Some of the keyword arguments accepted by this
      function are actually processed by &ensure-gf-UC;, others are
      processed during initialization of the &gfmo;
      (as described in <xref linkend="mop-gf-init-mo"/>).
</simpara></listitem></varlistentry></variablelist></listitem></varlistentry>
<varlistentry><term>Value</term>
 <listitem><simpara>A &gfmo;.</simpara></listitem></varlistentry>
<varlistentry><term>Purpose</term>
 <listitem><simpara>This function is called to define a globally named
   generic function or to specify or modify options and declarations
   that pertain to a globally named generic function as a whole.  It can
   be called by the user or the implementation.</simpara>
  <simpara>It is the functional equivalent of &defgeneric;, and is
   called by the expansion of the &defgeneric; and &defmethod; macros.
  </simpara><simpara>The behavior of this function is actually
   implemented by the generic function &ensure-gf-UC;.  When &ensure-gf;
   is called, it immediately calls &ensure-gf-UC; and returns that
   result as its own.</simpara>
  <para>The first argument to &ensure-gf-UC; is computed as follows:
   <itemizedlist><listitem><simpara>If &funcname-r; names a non-generic
      function, a macro, or a special form, an &err-sig;.
    </simpara></listitem>
    <listitem><simpara>If &funcname-r; names a generic function, that
      &gfmo; is used.</simpara></listitem>
    <listitem><simpara>Otherwise, &nil; is used.
   </simpara></listitem></itemizedlist></para>
  <simpara>The second argument is &funcname-r;.  The remaining arguments
   are the complete set of keyword arguments received by &ensure-gf;.
</simpara></listitem></varlistentry></variablelist>
</section><!-- ensure-gf -->

<section id="ensure-gf-UC">
 <title>Generic Function &ensure-gf-UC;</title>

<variablelist><varlistentry><term>Syntax</term>
 <listitem><simpara><code>(&ensure-gf-UC; &gf-r; &funcname-r; &key-amp;
    &argument-precedence-order-k; &declarations-k; &documentation-k;
    &gf-class-k; &lambda-list-k; &method-class-k; &method-combination-k;
    &name-k; &allow-other-keys-amp;)</code></simpara></listitem></varlistentry>
<varlistentry><term>Arguments</term>
 <listitem><variablelist>
   <varlistentry><term>&gf-r;</term>
    <listitem><simpara>a &gfmo; or &nil;.</simpara></listitem></varlistentry>
   <varlistentry><term>&funcname-r;</term>
    <listitem><simpara>a &funname;</simpara></listitem></varlistentry>
   <varlistentry><term>&gf-class-k;</term>
    <listitem><simpara>a &c-mo; or a class name.
      If it is not supplied, it defaults to the class named
      &standard-generic-function-t;.  If a class name is supplied, it is
      interpreted as the class with that name.  If a class name is
      supplied, but there is no such class, an &err-sig;.
   </simpara></listitem></varlistentry>
   <varlistentry><term>additional keyword arguments</term>
    <listitem><simpara>see <xref linkend="mop-gf-init-mo"/>.</simpara>
     <note>&clisp-only;<simpara>The &declare-k; keyword is recognized as
       equivalent to the &declarations-k; keyword, for compatibility
       with &ensure-gf; in &ansi-cl;.</simpara></note>
   </listitem></varlistentry>
</variablelist></listitem></varlistentry>
<varlistentry><term>Value</term>
 <listitem><simpara>A &gfmo;.</simpara></listitem></varlistentry>
<varlistentry><term>Purpose</term>
 <listitem><simpara>The generic function &ensure-gf-UC; is called to
   define or modify the definition of a globally named generic function.
   It is called by the &ensure-gf; function.  It can also be called
   directly.</simpara>
  <para>The first step performed by this generic function is to compute
   the set of initialization arguments which will be used to create or
   reinitialize the globally named generic function.  These
   initialization arguments are computed from the full set of keyword
   arguments received by this generic function as follows:
   <itemizedlist><listitem><simpara>The &gf-class-k;
      argument is not included in the initialization arguments.
    </simpara></listitem>
    <listitem><simpara>If the &method-class-k; argument was received by
      this generic function, it is converted into a &c-mo;.
      This is done by looking up the class name with &find-class;.  If
      there is no such class, an &err-sig;.</simpara></listitem>
    <listitem><simpara>All other keyword arguments are included directly
      in the initialization arguments.</simpara></listitem>
  </itemizedlist></para>
  <simpara>If the &gf-r; argument is &nil;, an instance of the class
   specified by the &gf-class-k; argument is created by
   calling &make-instance; with the previously computed initialization
   arguments.  The function name &funcname-r; is set to name the generic
   function.  The newly created &gfmo; is returned.
  </simpara><simpara>If the class of the &gf-r; argument is not the same
   as the class specified by the &gf-class-k; argument, an &err-sig;.</simpara>
  <note>&clisp-only;<simpara>The description of &ensure-gf; in &ansi-cl;
   specifies that in this case, &change-class; is called if the class of the
   &gf-r; argument and the class specified by the &gf-class-k; argument are
   compatible. Given the description of &ensure-gf;, this also applies to the
   &ensure-gf-UC; function. &clisp;'s implementation calls &change-class;
   always, and leaves it to the &change-class; function to signal an error if
   needed.</simpara></note>
  <simpara>Otherwise the generic function &gf-r; is redefined by calling
   the &reinitialize-instance; generic function with &gf-r; and the
   initialization arguments.  The &gf-r; argument is then returned.
</simpara></listitem></varlistentry></variablelist>

<variablelist><title>Methods</title>
<varlistentry><term><literal role="method">(&ensure-gf-UC;
   (&gf-r; &generic-function-t;) &funcname-r; &key-amp;
   &gf-class-k; &allow-other-keys-amp;)</literal></term>
 <listitem><simpara>This method implements the behavior of the generic
   function in the case where &funcname-r; names an existing generic
   function.</simpara>
  &overridable;</listitem></varlistentry>
<varlistentry><term><literal role="method">(&ensure-gf-UC;
   (&gf-r; &null-t;) &funcname-r; &key-amp; &gf-class-k;
   &allow-other-keys-amp;)</literal></term>
 <listitem><simpara>This method implements the behavior of the generic
   function in the case where &funcname-r; names no function, generic
   function, macro or special form.
</simpara></listitem></varlistentry></variablelist>
</section><!-- ensure-gf-UC -->

<section id="mop-add-method"><title>Generic Function &add-method;</title>

<variablelist><varlistentry><term>Syntax</term>
<listitem><simpara><code>(&add-method; &gf-r; &method-r;)
 </code></simpara></listitem></varlistentry>
<varlistentry><term>Arguments</term>
 <listitem><variablelist>&gf-mo-arg; &method-mo-arg;
</variablelist></listitem></varlistentry>
<varlistentry><term>Value</term>
 <listitem><simpara>The &gf-r; argument.</simpara></listitem></varlistentry>
<varlistentry><term>Purpose</term>
 <listitem><simpara>This generic function associates an unattached
   method with a generic function.</simpara>
  <simpara>An &err-sig; if the &lalist; of the method is not
   congruent with the &lalist; of the generic function.</simpara>
  <simpara>An &err-sig; if the method is already associated with some
   other generic function.</simpara>
  <simpara>If the given method agrees with an existing method of the
   generic function on parameter specializers and qualifiers, the
   existing method is removed by calling &remove-method; before the
   new method is added.  See the &ansi-cl; section
   <ulink role="clhs" url="sec_7-6-3">7.6.3 <quote>Agreement on
     Parameter Specializers and Qualifiers</quote></ulink>
   for a definition of agreement in this context.</simpara>
  <para>Associating the method with the generic function then
   proceeds in four steps:<orderedlist numeration="lowerroman">
    <listitem><simpara>add &method-r; to the set returned by
      &gf-methods; and arrange for &method-gf; to return &gf-r;;
    </simpara></listitem>
    <listitem><simpara>call &add-direct-method; for each of the method's
    specializers;</simpara></listitem>
    <listitem><simpara>call &compute-discriminating-function; and
      install its result with &set-funcallable-instance-function;; and
    </simpara></listitem>
    <listitem><simpara>update the dependents of the generic function.
  </simpara></listitem></orderedlist></para>
  <simpara>The generic function &add-method; can be called by the user
   or the implementation.</simpara></listitem></varlistentry></variablelist>

<variablelist><title>Methods</title>
<varlistentry><term><literal role="method">(&add-method;
   (&gf-r; &standard-generic-function-t;)
   (&method-r; &standard-method-t;))</literal></term>
 <listitem>&no-extra-spec;</listitem></varlistentry>
<varlistentry><term><literal role="method">(&add-method;
   (&gf-r; &standard-generic-function-t;)
   (&method-r; &method-t;))</literal></term>
 <listitem><simpara>This method is specified by &ansi-cl;.
</simpara></listitem></varlistentry>
</variablelist>
</section><!-- add-method -->

<section id="mop-remove-method"><title>Generic Function &remove-method;</title>

<variablelist><varlistentry><term>Syntax</term>
 <listitem><simpara><code>(&remove-method; &gf-r; &method-r;)
</code></simpara></listitem></varlistentry>
<varlistentry><term>Arguments</term>
 <listitem><variablelist>&gf-mo-arg; &method-mo-arg;
</variablelist></listitem></varlistentry>
<varlistentry><term>Value</term>
 <listitem><simpara>The &gf-r; argument.</simpara></listitem></varlistentry>
<varlistentry><term>Purpose</term>
 <listitem><simpara>This generic function breaks the association between
   a generic function and one of its methods.</simpara>
  <simpara>No &err-sig; if the method is not among the methods of the
   generic function.</simpara>
  <para>Breaking the association between the method and the generic
   function proceeds in four steps:<orderedlist numeration="lowerroman">
    <listitem><simpara>remove &method-r; from the set returned by
      &gf-methods; and arrange for &method-gf; to return &nil;;
    </simpara></listitem>
    <listitem><simpara>call &remove-direct-method; for each of the
      method's specializers;</simpara></listitem>
    <listitem><simpara>call &compute-discriminating-function; and
      install its result with &set-funcallable-instance-function;;
      and</simpara></listitem>
    <listitem><simpara>update the dependents of the generic function.
  </simpara></listitem></orderedlist></para>
  <simpara>The generic function &remove-method; can be called by the
   user or the implementation.
</simpara></listitem></varlistentry></variablelist>

<variablelist><title>Methods</title>
<varlistentry><term><literal role="method">(&remove-method;
   (&gf-r; &standard-generic-function-t;)
   (&method-r; &standard-method-t;))</literal></term>
 <listitem>&no-extra-spec;</listitem></varlistentry>
<varlistentry><term><literal role="method">(&remove-method;
   (&gf-r; &standard-generic-function-t;)
   (&method-r; &method-t;))</literal></term>
 <listitem><simpara>This method is specified by &ansi-cl;.
</simpara></listitem></varlistentry>
</variablelist>
</section><!-- mop-remove-method -->

<!-- end generic-function basic customization -->

<!-- begin generic-function advanced customization -->

<section id="compute-applicable-methods">
 <title>Generic Function &compute-applicable-methods-mop;</title>

<variablelist><varlistentry><term>Syntax</term>
  <listitem><simpara><code>(&compute-applicable-methods-mop;
     &gf-r; &args-r;)</code></simpara></listitem></varlistentry>
<varlistentry><term>Arguments</term>
 <listitem><variablelist>&gf-mo-arg;
   <varlistentry><term>&args-r;</term>
    <listitem><simpara>a list of objects.</simpara></listitem></varlistentry>
</variablelist></listitem></varlistentry>
<varlistentry><term>Value</term>
 <listitem><simpara>A possibly empty list of &m-mo;s.
</simpara></listitem></varlistentry>
<varlistentry><term>Purpose</term>
 <listitem><simpara>This generic function determines the method
   applicability of a generic function given a list of required
   arguments.  The returned list of &m-mo;s is sorted by
   precedence order with the most specific method appearing first.  If
   no methods are applicable to the supplied arguments the empty list is
   returned.</simpara>
  &cam-cdf;
  <simpara>The &args-r; argument is permitted to contain more elements
   than the generic function accepts required arguments; in these cases
   the extra arguments will be ignored.  An &err-sig; if &args-r;
   contains fewer elements than the generic function accepts required
   arguments.</simpara>
  &result-immutable;</listitem></varlistentry></variablelist>

<variablelist><title>Methods</title>
<varlistentry><term><literal role="method">(&compute-applicable-methods-mop;
   (&gf-r; &standard-generic-function-t;) &args-r;)</literal></term>
 <listitem><simpara>This method &sig-err; if any method of the generic
   function has a specializer which is neither a &c-mo; nor an
   &eql-t; specializer metaobject.</simpara>
  <simpara>Otherwise, this method computes the sorted list of applicable
   methods according to the rules described in the &ansi-cl; section
   <ulink role="clhs" url="sec_7-6-6">7.6.6 <quote>Method Selection
     and Combination</quote></ulink></simpara>
  <simpara>This method can be overridden.  Because of the consistency
   requirements between this generic function and
   &compute-applicable-methods-UC;, doing so may require also overriding
   <literal role="method">&compute-applicable-methods-UC;
    (&standard-generic-function-t; &t-t;)</literal>.
</simpara></listitem></varlistentry></variablelist>

<formalpara id="mop-cam-remarks"><title>Remarks</title> <!-- sds -->
<para>See also the &ansi-cl; function &compute-applicable-methods;.
</para></formalpara>
</section><!-- compute-applicable-methods -->

<section id="compute-applicable-methods-UC">
 <title>Generic Function &compute-applicable-methods-UC;</title>

<variablelist><varlistentry><term>Syntax</term>
  <listitem><simpara><code>(&compute-applicable-methods-UC;
    &gf-r; &classes-r;)</code></simpara></listitem></varlistentry>
<varlistentry><term>Arguments</term>
 <listitem><variablelist>&gf-mo-arg;
   <varlistentry><term>&classes-r;</term>
    <listitem><simpara>a list of &c-mo;s.
</simpara></listitem></varlistentry></variablelist></listitem></varlistentry>
<varlistentry><term>Values</term>
 <listitem><orderedlist><listitem><simpara>A possibly empty list of &m-mo;s.
   </simpara></listitem><listitem><simpara>&boolean-t;</simpara></listitem>
</orderedlist></listitem></varlistentry>
<varlistentry><term>Purpose</term>
 <listitem><simpara>This generic function is called to attempt to
   determine the method applicability of a generic function given only
   the classes of the required arguments.</simpara>
  <simpara>If it is possible to completely determine the ordered list of
   applicable methods based only on the supplied classes, this generic
   function returns that list as its &pri-val; and true as its second
   value.  The returned list of &m-mo;s is sorted by
   precedence order, the most specific method coming first.  If no
   methods are applicable to arguments with the specified classes, the
   empty list and true are returned.</simpara>
  <simpara>If it is not possible to completely determine the ordered
   list of applicable methods based only on the supplied classes, this
   generic function returns an unspecified &pri-val; and false as its
   second value.</simpara>
  &cam-cdf;
  <simpara>The following consistency relationship between
   &compute-applicable-methods-UC; and &compute-applicable-methods-mop; must
   be maintained: for any given generic function and set of arguments,
   if &compute-applicable-methods-UC; returns a second value of true,
   the &pri-val; must be equal to the value that would be returned by
   a corresponding call to &compute-applicable-methods-mop;.  The results
   are undefined if a portable method on either of these generic
   functions causes this consistency to be violated.</simpara>
  &result-immutable;</listitem></varlistentry></variablelist>

<variablelist><title>Methods</title>
<varlistentry><term><literal role="method">(&compute-applicable-methods-UC;
   (&gf-r; &standard-generic-function-t;) &classes-r;)</literal></term>
 <listitem><simpara>If any method of the generic function has a
   specializer which is neither a &c-mo; nor an &eql-t;
   specializer metaobject, this method &sig-err;.</simpara>
  <simpara>In cases where the generic function has no methods with
   &eql-t; specializers, or has no methods with &eql-t; specializers
   that could be applicable to arguments of the supplied classes, this
   method returns the ordered list of applicable methods as its first
   value and true as its second value.</simpara>
  <simpara>Otherwise this method returns an unspecified &pri-val; and
   false as its second value.</simpara>
  <simpara>This method can be overridden. Because of the consistency
   requirements between this generic function and
   &compute-applicable-methods-mop;, doing so may require also overriding
   <literal role="method">&compute-applicable-methods-mop;
    (&standard-generic-function-t; &t-t;) </literal>.
</simpara></listitem></varlistentry></variablelist>

<simplesect id="mop-cam-UC-remarks"><title>Remarks</title>
<para>This generic function exists to allow user extensions which alter
method lookup rules, but which base the new rules only on the classes of
the required arguments, to take advantage of the class-based method
lookup memoization found in many implementations.  (There is of course
no requirement for an implementation to provide this optimization.)</para>

<para>Such an extension can be implemented by two methods, one on this
generic function and one on &compute-applicable-methods-mop;.  Whenever
the user extension is in effect, the first method will return a second
value of true.  This should allow the implementation to absorb these
cases into its own memoization scheme.</para>

<para>To get appropriate performance, other kinds of extensions may
require methods on &compute-discriminating-function; which implement
their own memoization scheme.</para></simplesect>
</section><!-- compute-applicable-methods-UC -->

<section id="compute-effective-method">
 <title>Generic Function &compute-effective-method;</title>

<variablelist><varlistentry><term>Syntax</term>
 <listitem><simpara><code>(&compute-effective-method; &gf-r; &mc-r;
    &methods-r;)</code></simpara></listitem></varlistentry>
<varlistentry><term>Arguments</term>
 <listitem><variablelist>&gf-mo-arg;
   <varlistentry><term>&mc-r;</term>
    <listitem><simpara>a &mcmo;.</simpara></listitem></varlistentry>
   <varlistentry><term>&methods-r;</term>
    <listitem><simpara>a list of &m-mo;s.</simpara></listitem></varlistentry>
</variablelist></listitem></varlistentry>
<varlistentry><term>Values</term>
 <listitem><orderedlist><listitem><simpara>An effective method</simpara>
   </listitem><listitem><simpara>A list of effective method options
</simpara></listitem></orderedlist></listitem></varlistentry>
<varlistentry><term>Purpose</term>
 <listitem><simpara>This generic function is called to determine the
   effective method from a sorted list of &m-mo;s.</simpara>
   <simpara>An effective method is a form that describes how the
    applicable methods are to be combined.  Inside of effective method
    forms are &call-method; forms which indicate that a particular
    method is to be called.  The arguments to the &call-method; form
    indicate exactly how the method function of the method should be
    called.  (See &make-method-lambda; for more details about method
    functions.)</simpara>
   <simpara>An effective method option has the same interpretation and
    syntax as either the &arguments-k; or the &gf-k; option in the long form
    of &define-method-combination;.</simpara>
   <simpara>More information about the form and interpretation of
    effective methods and effective method options can be found under
    the description of the &define-method-combination; macro in the
    &clos; specification.</simpara>
   <simpara>This generic function can be called by the user or the
    implementation.  It is called by discriminating functions whenever a
    sorted list of applicable methods must be converted to an effective
    method.</simpara></listitem></varlistentry></variablelist>

<variablelist><title>Methods</title>
<varlistentry><term><literal role="method">(&compute-effective-method;
   (&gf-r; &standard-generic-function-t;) &mc-r; &methods-r;)</literal></term>
 <listitem><simpara>This method computes the effective method according
   to the rules of the method combination type implemented by &mc-r;.</simpara>
  &overridable;</listitem></varlistentry></variablelist>

<note>&clisp-only;<simpara>The second return value may contain only one
  &arguments-k; option and only one &gf-k; option. When overriding a
  &compute-effective-method; method, before adding an &arguments-k; or
  &gf-k; option, you therefore need to check whether it this option is
  already present.</simpara></note>
</section><!-- compute-effective-method -->

<section id="compute-effective-method-as-function">
 <title>Function &compute-effective-method-as-function;</title>
 <note>&clisp-only;<simpara/></note>
<variablelist><varlistentry><term>Syntax</term>
 <listitem><simpara><code>(&compute-effective-method-as-function;
    &gf-r; &methods-r; &args-r;)</code></simpara></listitem></varlistentry>
<varlistentry><term>Arguments</term>
 <listitem><variablelist>&gf-mo-arg;
   <varlistentry><term>&methods-r;</term>
    <listitem><simpara>a list of &m-mo;s.</simpara></listitem></varlistentry>
   <varlistentry><term>&args-r;</term>
    <listitem><simpara>a list of arguments.
   </simpara></listitem></varlistentry>
 </variablelist></listitem></varlistentry>
<varlistentry><term>Value</term>
 <listitem><simpara>The effective method as a function, accepting any
   set of arguments for which all of the given methods are applicable.
</simpara></listitem></varlistentry>
<varlistentry><term>Purpose</term>
 <listitem><simpara>This function is called to determine the effective method
   from a sorted list of &m-mo;s, and convert it to a function.
   The &args-r; are a set of arguments to which the methods are applicable,
   and are used solely for error message purposes.</simpara>
  <simpara>This function calls &compute-effective-method; using the &gf-r;'s
   method combination, wraps local macro definitions for &call-method; and
   &make-method; around it, handles the &arguments-k; and &gf-k; options,
   and compiles the resulting form to a function.</simpara></listitem>
</varlistentry></variablelist>
</section><!-- compute-effective-method-as-function -->

<section id="make-method-lambda">
 <title>Generic Function &make-method-lambda;</title>

<variablelist><varlistentry><term>Syntax</term>
 <listitem><simpara><code>(&make-method-lambda; &gf-r;
    &method-r; &laexpr-r; &env-r;)
 </code></simpara></listitem></varlistentry>
<varlistentry><term>Arguments</term>
 <listitem><variablelist>&gf-mo-arg;
   <varlistentry><term>&method-r;</term>
    <listitem><simpara>a (possibly uninitialized) &m-mo;.
   </simpara></listitem></varlistentry>
   <varlistentry><term>&laexpr-r;</term>
    <listitem><simpara>a &lambda-expr;.</simpara></listitem></varlistentry>
   <varlistentry><term>&env-r;</term>
    <listitem><simpara>the same as the &environment-amp; argument to
     macro expansion functions.</simpara></listitem></varlistentry>
</variablelist></listitem></varlistentry>
<varlistentry><term>Values</term>
 <listitem><orderedlist><listitem><simpara>A &lambda-expr;</simpara></listitem>
   <listitem><simpara>A list of initialization arguments and values
</simpara></listitem></orderedlist></listitem></varlistentry>
<varlistentry><term>Purpose</term>
 <listitem><simpara>This generic function is called to produce a
   &lambda-expr; which can itself be used to produce a method function
   for a method and generic function with the specified classes.
   The generic function and method the method function will be used with
   are not required to be the given ones.
   Moreover, the &m-mo; may be uninitialized.</simpara>
  <simpara>Either the function &compile;, the special form &function; or
   the function &coerce; must be used to convert the &lambda-expr; a
   method function.  The method function itself can be applied to
   arguments with &apply; or &funcall;.</simpara>
  <simpara>When a method is actually called by an effective method, its
   first argument will be a list of the arguments to the generic
   function.  Its remaining arguments will be all but the first argument
   passed to &call-method;.  By default, all method functions must
   accept two arguments: the list of arguments to the generic function
   and the list of next methods.</simpara>
  <simpara>For a given generic function and method class, the applicable
   methods on &make-method-lambda; and &compute-effective-method; must
   be consistent in the following way: each use of &call-method;
   returned by the method on &compute-effective-method; must have the
   same number of arguments, and the method lambda returned by the
   method on &make-method-lambda; must accept a corresponding number of
   arguments.</simpara>
  <simpara>Note that the system-supplied implementation of
   &call-next-method; is not required to handle extra arguments to the
   method function.  Users who define additional arguments to the method
   function must either redefine or forego &call-next-method;.  (See the
   example below.)</simpara>
  <simpara>When the &m-mo; is created with &make-instance;, the method
   function must be the value of the &function-k; initialization
   argument.  The additional initialization arguments, returned as the
   second value of this generic function, must also be passed in this
   call to &make-instance;.</simpara></listitem></varlistentry>
</variablelist>

<variablelist><title>Methods</title>
<varlistentry><term><literal role="method">(&make-method-lambda;
   (&gf-r; &standard-generic-function-t;)
   (&method-r; &standard-method-t;) &laexpr-r; &env-r;)</literal></term>
<listitem><simpara>This method returns a method lambda which accepts two
  arguments, the list of arguments to the generic function, and the list
  of next methods.  What initialization arguments may be returned in the
  second value are unspecified.</simpara>
  &overridable;</listitem></varlistentry></variablelist>

<informalexample id="make-method-lambda-ex">
<para>This example shows how to define a kind of method which, from
within the body of the method, has access to the actual &m-mo; for the
method.  This simplified code overrides whatever method combination is
specified for the generic function, implementing a simple method
combination supporting only primary methods, &call-next-method; and
&next-method-p;.  (In addition, its a simplified version of
&call-next-method; which does no error checking.)</para>

<para>Notice that the extra lexical function bindings get wrapped around
the body before &call-next-method; is called.  In this way, the user's
definition of &call-next-method; and &next-method-p; are sure to
override the system's definitions.</para>

<programlisting language="lisp">
(defclass my-generic-function (standard-generic-function)
  ()
  (:default-initargs :method-class (find-class 'my-method)))

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

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

(defmethod compute-effective-method ((gf my-generic-function)
                                     method-combination
                                     methods)
  `(call-method ,(car methods) ,(cdr methods) ,(car methods)))
</programlisting>
</informalexample>

<note>&clisp-only;<formalpara id="no-make-method-lambda">
  <title>The generic function &make-method-lambda; is not implemented</title>
  <para>Its specification is misdesigned: it mixes &compile-time; and
   &exec-time; behaviour. The essential problem is: where could the
   generic-function argument come from?
   <itemizedlist>
    <listitem><simpara>If a &defmethod; form occurs in a source file, is
      &make-method-lambda; then called at compile time or at load time?
      If it was called at compile time, there's no possible value for
      the first argument, since the class of the generic function to
      which the method will belong is not known until load time.  If it
      was called at load time, it would mean that the method's source
      code could only be compiled at load time, not earlier - which
      defeats the purpose of &compile-file;</simpara></listitem>
    <listitem><simpara>When a method is removed from a generic function
      using &remove-method; and then added through &add-method; to a
      different generic function, possibly belonging to a different
      generic function class, would &make-method-lambda; then be called
      again or not? If no, then &make-method-lambda;'s first argument is
      useless. If yes, then the source code of every method would have
      to be present at runtime, and its lexical environment as well.
 </simpara></listitem></itemizedlist></para></formalpara>
 <formalpara id="method-functions-args">
  <title>Method function arguments</title>
  <para><itemizedlist><listitem><simpara>&call-method; always expect
      exactly two arguments: the method and a list of next methods.
    </simpara></listitem><listitem><simpara>Method functions always
      expect exactly two arguments: the list of arguments passed to the
      generic function, and the list of next methods.
</simpara></listitem></itemizedlist></para></formalpara></note>
</section><!-- make-method-lambda -->

<section id="compute-discriminating-function">
 <title>Generic Function &compute-discriminating-function;</title>

<variablelist><varlistentry><term>Syntax</term>
 <listitem><simpara><code>(&compute-discriminating-function;
    &gf-r;)</code></simpara></listitem></varlistentry>
<varlistentry><term>Arguments</term>
 <listitem><variablelist>&gf-mo-arg;</variablelist></listitem></varlistentry>
<varlistentry><term>Value</term>
 <listitem><simpara>A function.</simpara></listitem></varlistentry>
<varlistentry><term>Purpose</term>
 <listitem><simpara>This generic function is called to determine the
   discriminating function for a generic function.  When a generic
   function is called, the <firstterm>installed</firstterm>
   discriminating function is called with the full set of arguments
   received by the generic function, and must implement the behavior of
   calling the generic function: determining the ordered set of
   applicable methods, determining the effective method, and running the
   effective method.</simpara>
  <simpara>To determine the ordered set of applicable methods, the
   discriminating function first calls &compute-applicable-methods-UC;.
   If &compute-applicable-methods-UC; returns a second value of false,
   the discriminating function then calls &compute-applicable-methods-mop;.
  </simpara><para>When &compute-applicable-methods-UC; returns a second
   value of true, the discriminating function is permitted to memoize
   the &pri-val; as follows.  The discriminating function may
   reuse the list of applicable methods without calling
   &compute-applicable-methods-UC; again provided that:
   <orderedlist numeration="lowerroman">
    <listitem><simpara>the generic function is being called again with
      required arguments which are instances of the same classes,
    </simpara></listitem>
    <listitem><simpara>the generic function has not been reinitialized,
    </simpara></listitem>
    <listitem><simpara>no method has been added to or removed from the
      generic function,</simpara></listitem>
    <listitem><simpara>for all the specializers of all the generic
      function's methods which are classes, their class precedence lists
      have not changed, and</simpara></listitem>
    <listitem><simpara>for any such memoized value, the class precedence
      list of the class of each of the required arguments has not changed.
   </simpara></listitem></orderedlist>
   Determination of the effective method is done by calling
   &compute-effective-method;.  When the effective method is run, each
   method's function is called, and receives as arguments:
   <orderedlist numeration="lowerroman">
    <listitem><simpara>a list of the arguments to the generic function,
    </simpara></listitem>
    <listitem><simpara>whatever other arguments are specified in the
      &call-method; form indicating that the method should be called.
   </simpara></listitem></orderedlist>
   (See &make-method-lambda; for more information about how method
   functions are called.)</para>
  <simpara>The generic function &compute-discriminating-function; is
   called, and its result installed, by &add-method;, &remove-method;,
   &initialize-instance; and &reinitialize-instance;.
</simpara></listitem></varlistentry></variablelist>

<variablelist><title>Methods</title>
 <varlistentry><term><literal role="method">(&compute-discriminating-function;
    (&gf-r; &standard-generic-function-t;))</literal></term>
  <listitem>&no-extra-spec;
   &overridable;</listitem></varlistentry></variablelist>

<note>&clisp-only;<para>Overriding methods can make use of the function
  &compute-effective-method-as-function;.  It is more convenient to call
  &compute-effective-method-as-function; than &compute-effective-method;
  because the in the latter case one needs a lot of <quote>glue
   code</quote> for implementing the local macros &call-method; and
  &make-method;, and this glue code is implementation dependent because
  it needs<orderedlist><listitem><simpara>to retrieve the declarations
     list stored in the method-combination object and</simpara></listitem>
   <listitem><simpara>to handle implementation dependent options that
     are returned as second value from &compute-effective-method;.
</simpara></listitem></orderedlist></para></note>
</section><!-- compute-discriminating-function -->

<!-- end generic-function advanced customization -->

</section><!-- mop-gf-customize -->
</section><!-- mop-gf -->

<section id="mop-meth"><title>Methods</title>

<section id="mop-meth-inheritance">
 <title>Inheritance Structure of &m-mo; Classes</title>
<figure id="mop-meth-inheritance-fig">
 <title>Inheritance structure of &m-mo; classes</title>
 <mediaobject><imageobject>
   <imagedata width="100%" scalefit="1" fileref="mop-classes-method.png"/>
</imageobject></mediaobject></figure>
</section>

<section id="mop-meth-mo-readers">
 <title>Introspection: Readers for &m-mo;s</title>

<para>The reader generic functions which simply return information
associated with &m-mo;s are presented together here in the
format described in <xref linkend="mop-cl-readers"/>.</para>

<para>Each of these reader generic functions have the same syntax,
accepting one required argument called &method-r;, which must be a
&m-mo;; otherwise, an &err-sig;.  An &error-t; is also &signal;ed
if the &m-mo; has not been initialized.</para>

&user-and-implementation-callable-result-immutable;

<!-- begin method basic introspection -->

<section id="method-specializers">
 <title>Generic Function &method-specializers;</title>
 <subtitle><code>(&method-specializers; &method-r;)</code></subtitle>

<para>Returns a list of the specializers of &method-r;.  This value is a
list of specializer metaobjects.  This is the value of the
&specializers-k; initialization argument that was associated with the
method during initialization.</para></section>

<section id="method-qualifiers">
 <title>Generic Function &method-qualifiers;</title>
 <subtitle><code>(&method-qualifiers; &method-r;)</code></subtitle>

<para>Returns a (possibly empty) list of the qualifiers of &method-r;.
This value is a list of non-&nil; atoms.  This is the defaulted value of
the &qualifiers-k; initialization argument that was associated with the
method during initialization.</para></section>

<section id="method-lambda-list">
 <title>Generic Function &method-lambda-list;</title>
 <subtitle><code>(&method-lambda-list; &method-r;)</code></subtitle>

<para>Returns the (unspecialized) &lalist; of &method-r;.  This value
is a &cl; &lalist;.  This is the value of the &lambda-list-k;
initialization argument that was associated with the method during
initialization.</para></section>

<!-- end method basic introspection -->

<!-- begin method advanced introspection -->

<section id="method-gf"><title>Generic Function &method-gf;</title>
 <subtitle><code>(&method-gf; &method-r;)</code></subtitle>

<para>Returns the generic function that &method-r; is currently
connected to, or &nil; if it is not currently connected to any generic
function.  This value is either a &gfmo; or &nil;.
When a method is first created it is not connected to any generic
function.  This connection is maintained by the generic functions
&add-method; and &remove-method;.</para></section>

<section id="method-function">
 <title>Generic Function &method-function;</title>
 <subtitle><code>(&method-function; &method-r;)</code></subtitle>

<para>Returns the method function of &method-r;.  This is the
value of the &function-k; initialization argument that was associated
with the method during initialization.</para></section>

<!-- end method advanced introspection -->

<section id="mop-meth-mo-readers-methods"><title>Methods</title>

<variablelist>
 <title>The specified methods for the &m-mo; readers</title>
<varlistentry>
 <term><literal role="method">(&method-specializers;
   (&method-r; &standard-method-t;))</literal></term>
 <term><literal role="method">(&method-qualifiers;
   (&method-r; &standard-method-t;))</literal></term>
 <term><literal role="method">(&method-lambda-list;
   (&method-r; &standard-method-t;))</literal></term>
 <term><literal role="method">(&method-function;
   (&method-r; &standard-method-t;))</literal></term>
 <listitem>&no-extra-specs;</listitem></varlistentry>
<varlistentry><term><literal role="method">(&method-gf;
   (&method-r; &standard-method-t;))</literal></term>
<listitem>&no-extra-spec;
 <simpara>The value returned by this method is maintained by
  <literal role="method">&add-method;(&standard-generic-function-t;
   &standard-method-t;)</literal> and
  <literal role="method">&remove-method;(&standard-generic-function-t;
   &standard-method-t;)</literal>.</simpara></listitem></varlistentry>
</variablelist></section><!-- mop-meth-mo-readers-methods -->
</section><!-- mop-meth-mo-readers -->


<section id="mop-meth-init"><title>Initialization of Methods</title>

<section id="mop-meth-init-defmethod"><title>Macro &defmethod;</title>

<para>The evaluation or execution of a &defmethod; form requires first
that the body of the method be converted to a method function.
This process is described
<link linkend="mop-meth-init-defmethod-body">below</link>.
The result of this process is a method function and a set of additional
initialization arguments to be used when creating the new method.
Given these two values, the evaluation or execution of a &defmethod;
form proceeds in three steps.</para>

<para>The first step ensures the existence of a generic function with
the specified name.  This is done by calling the function &ensure-gf;.
The first argument in this call is the generic function name specified
in the &defmethod; form.</para>

<para>The second step is the creation of the new &m-mo; by calling
&make-instance;.  The class of the new &m-mo; is determined by calling
&gf-method-class; on the result of the call to &ensure-gf; from the
first step.</para>

<para>The initialization arguments received by the call to &make-instance;
are as follows:<itemizedlist>
<listitem><simpara>The value of the &qualifiers-k; initialization
argument is a list of the qualifiers which appeared in the &defmethod;
form.  No special processing is done on these values.  The order of the
elements of this list is the same as in the &defmethod; form.
</simpara></listitem>
<listitem><simpara>The value of the &lambda-list-k; initialization
argument is the unspecialized &lalist; from the &defmethod; form.
</simpara></listitem>
<listitem><simpara>The value of the &specializers-k; initialization
argument is a list of the specializers for the method.  For specializers
which are classes, the specializer is the &c-mo; itself.  In
the case of &eql-t; specializers, it will be an &eql-specializer-t;
metaobject obtained by calling &intern-eql-specializer; on the result of
evaluating the &eql-t; specializer form in the &lex-env; of the
&defmethod; form.</simpara></listitem>
<listitem><simpara>The value of the &function-k; initialization
argument is the method function.</simpara></listitem>
<listitem><simpara>The value of the &declarations-k; initialization
argument is a list of the &declspec-glo;s from the &defmethod; form.
If there are no declarations in the macro form, this initialization argument
either does not appear, or appears with a value of the empty list.</simpara>
<note>&clisp-only;<simpara>No &declarations-k; initialization argument is
  provided, because method initialization does not support a &declarations-k;
  argument, and because the method function is already completely provided
  through the &function-k; initialization argument.</simpara></note></listitem>
<listitem><simpara>The value of the &documentation-k; initialization
argument is the documentation string from the &defmethod; form.  If
there is no documentation string in the macro form this initialization
argument either does not appear, or appears with a value of false.
</simpara></listitem>
<listitem><simpara>Any other initialization argument produced in
conjunction with the method function are also included.</simpara></listitem>
<listitem><simpara>The implementation is free to include additional
initialization arguments provided these are not symbols accessible in
the &clu-pac; package, or exported by any package defined in the
&ansi-cl;.</simpara></listitem></itemizedlist></para>

<para>In the third step, &add-method; is called to add the newly created
method to the set of methods associated with the &gfmo;.</para>

<para>The result of the call to &add-method; is returned as the result
of evaluating or executing the &defmethod; form.</para>

<para>An example showing a typical &defmethod; form and a sample
expansion is shown in the following example:
<informalexample id="defmethod-ex-1">
 <simpara>An example &defmethod; form and one possible correct
  expansion. In the expansion, <replaceable>method-lambda</replaceable>
  is the result of calling &make-method-lambda; as described in
  <xref linkend="mop-meth-init-defmethod-body"/>.
  The initargs appearing after &function-k; are assumed to be additional
  initargs returned from the call to &make-method-lambda;.</simpara>
<programlisting language="lisp">
(defmethod move :before ((p position) (l (eql 0))
                         &optional-amp; (visiblyp t)
                         &key-amp; color)
  (set-to-origin p)
  (when visiblyp (show-move p 0 color)))

(let ((#:g001 (ensure-generic-function 'move)))
  (add-method #:g001
    (make-instance (generic-function-method-class #:g001)
                   :qualifiers '(:before)
                   :specializers (list (find-class 'position)
                                       (intern-eql-specializer 0))
                   :lambda-list '(p l &optional-amp; (visiblyp t)
                                      &key-amp; color)
                   :function (function <replaceable>method-lambda</replaceable>)
                   'additional-initarg-1 't
                   'additional-initarg-2 '39)))
</programlisting></informalexample></para>

<para>The processing of the method body for this method is shown
 <link linkend="defmethod-ex-2">below</link>.</para>

<section id="mop-meth-init-defmethod-body">
 <title>Processing Method Bodies</title>

<para>Before a method can be created, the list of forms comprising the
method body must be converted to a method function.  This conversion is
a two step process.</para>

<note><simpara>The body of methods can also appear in the
&method-k; option of &defgeneric; forms.  Initial methods are
not considered by any of the protocols specified in this document.
</simpara></note>

<informalexample id="defmethod-ex-2">
 <simpara>During macro-expansion of the &defmethod; macro shown in
  the <link linkend="defmethod-ex-1">previous example</link> code
  similar to this would be run to produce the method lambda and
  additional initargs.  In this example, &env-r; is the macroexpansion
  environment of the &defmethod; macro form.</simpara>
<programlisting language="lisp">
(let ((gf (ensure-generic-function 'move)))
  (make-method-lambda
    gf
    (class-prototype (generic-function-method-class gf))
    '(lambda (p l &optional-amp; (visiblyp t) &key-amp; color)
       (set-to-origin p)
       (when visiblyp (show-move p 0 color)))
    &env-r;))
</programlisting></informalexample>

<para>The first step occurs during macro-expansion of the macro form.
In this step, the method &lalist;, declarations and body are
converted to a &lambda-expr; called a <firstterm>method lambda
  <indexterm id="method-lambda" significance="preferred">
   &me-prim;<secondary>function</secondary></indexterm></firstterm>.
This conversion is based on information associated with the generic
function definition in effect at the time the macro form is expanded.</para>

<para>The generic function definition is obtained by calling &ensure-gf; with
 a first argument of the generic function name specified in the macro form.
The &lambda-list-k; keyword argument is not passed in this call.</para>

<para>Given the generic function, production of the method lambda
proceeds by calling &make-method-lambda;.
The first argument in this call is the generic function obtained as
described above.
The second argument is the result of calling &class-prototype; on the
result of calling &gf-method-class; on the generic function.
The third argument is a &lambda-expr; formed from the method &lalist;,
declarations and body.
The fourth argument is the macro-expansion environment of the macro
form; this is the value of the &environment-amp; argument to the
&defmethod; macro.</para>

<para>The generic function &make-method-lambda; returns two values.
The first is the method lambda itself.
The second is a list of initialization arguments and values.  These are
included in the initialization arguments when the method is created.</para>

<para>In the second step, the method lambda is converted to a function
which properly captures the lexical scope of the macro form.  This is
done by having the method lambda appear in the macro-expansion as the
argument of the &function; special form.  During the subsequent
evaluation of the macro-expansion, the result of the &function; special
form is the method function.</para>

<note>&clisp-only;<simpara>See <xref linkend="no-make-method-lambda"/>.
</simpara></note>
</section><!-- mop-meth-init-defmethod-body -->

<section id="mop-meth-init-defmethod-mo">
 <title>Initialization of Generic Function and &m-mo;s</title>

<para>An example of creating a generic function and a &m-mo;, and then
adding the method to the generic function is shown below.  This example
is comparable to the method definition shown
 <link linkend="defmethod-ex-1">above</link>:
<programlisting language="lisp">
(let* ((gf (make-instance 'standard-generic-function
                          :lambda-list '(p l &optional-amp; visiblyp &key-amp;)))
       (method-class (generic-function-method-class gf)))
  (multiple-value-bind (lambda initargs)
       (make-method-lambda
         gf
         (class-prototype method-class)
         '(lambda (p l &optional-amp; (visiblyp t) &key-amp; color)
            (set-to-origin p)
            (when visiblyp (show-move p 0 color)))
         nil)
    (add-method gf
                (apply #'make-instance method-class
                       :function (compile nil lambda)
                       :specializers (list (find-class 'position)
                                           (intern-eql-specializer 0))
                       :qualifiers ()
                       :lambda-list '(p l &optional-amp; (visiblyp t)
                                          &key-amp; color)
                       initargs))))
</programlisting></para>
</section><!-- mop-meth-init-defmethod-mo -->

<section id="mop-meth-efficiency"><title>Efficiency</title>
 <subtitle>Implementation dependent: only in &clisp; and some other
  implementations</subtitle>
 <simpara>Methods created through &defmethod; have a faster calling
  convention than methods created through a portable &make-instance;
  invocation.</simpara>
</section><!-- mop-meth-efficiency -->

</section><!-- mop-meth-init-defmethod -->

<section id="mop-meth-init-mo">
 <title>Initialization of &m-mo;s</title>

<para>A &m-mo; can be created by calling &make-instance;.
The initialization arguments establish the definition of the method.
A &m-mo; cannot be redefined;
calling &reinitialize-instance; &sig-err;.</para>

<para>Initialization of a &m-mo; must be done by calling &make-instance;
and allowing it to call &initialize-instance;.  Portable programs must
&not-e;<itemizedlist>
  <listitem><simpara>... call &initialize-instance; directly to
    initialize a &m-mo;;</simpara></listitem>
  <listitem><simpara>... call &shared-initialize; directly to
    initialize a &m-mo;;</simpara></listitem>
  <listitem><simpara>... call &change-class; to change the class of any
    &m-mo; or to turn a non-method object into a &m-mo;.
</simpara></listitem></itemizedlist></para>

<para>Since metaobject classes may not be redefined,
 no behavior is specified for the result of calls to
 &update-instance-for-redefined-class; on &m-mo;s.
 Since the class of a &m-mo; cannot be changed,
 no behavior is specified for the result of calls to
 &update-instance-for-different-class; on &m-mo;s.</para>

<para>During initialization, each initialization argument is checked
for errors and then associated with the &m-mo;.  The value
can then be accessed by calling the appropriate accessor as shown in
<xref linkend="mop-meth-initargs"/>.</para>

<para>This section begins with a description of the error checking and
processing of each initialization argument.  This is followed by a table
showing the generic functions that can be used to access the stored
initialization arguments.  The section ends with a set of restrictions
on portable methods affecting &m-mo; initialization.</para>

<para>In these descriptions, the phrase <quote>this argument defaults to
&value-r;</quote> means that when that initialization argument is not
supplied, initialization is performed as if &value-r; had been supplied.
For some initialization arguments this could be done by the use of
default initialization arguments, but whether it is done this way is not
specified.  Implementations are free to define default initialization
arguments for specified &m-mo; classes.  Portable programs
are free to define default initialization arguments for portable
subclasses of the class &method-t;.</para>

<itemizedlist>
 <listitem><simpara>The &qualifiers-k; argument is a list of method
   qualifiers.  An &err-sig; if this value is not a &proper-list-glo;, or if
   any element of the list is not a non-null atom. This argument
   defaults to the empty list.</simpara></listitem>
 <listitem><simpara>The &lambda-list-k; argument is the unspecialized
   &lalist; of the method.  An &err-sig; if this value is not a
   proper &lalist;. If this value is not supplied, an &err-sig;.
 </simpara></listitem>
 <listitem><simpara>The &specializers-k; argument is a list of the
   specializer metaobjects for the method.  An &err-sig; if this value
   is not a &proper-list-glo;, or if the length of the list differs from the
   number of required arguments in the &lambda-list-k; argument, or if
   any element of the list is not a specializer metaobject.  If this
   value is not supplied, an &err-sig;.</simpara></listitem>
 <listitem><simpara> The &function-k; argument is a method function.  It
   must be compatible with the methods on &compute-effective-method;
   defined for this class of method and generic function with which it
   will be used.  That is, it must accept the same number of arguments
   as all uses of &call-method; that will call it supply.  (See
   &compute-effective-method; and &make-method-lambda; for more information.)
   An &err-sig; if this argument is not supplied.</simpara></listitem>
 <listitem><simpara> When the method being initialized is an instance of
   a subclass of &standard-accessor-method-t;, the &slotdef-k;
   initialization argument must be provided.  Its value is the direct
   &sdmo; which defines this accessor method.  An &err-sig; if the value
   is not an instance of a subclass of &dsd-t;.</simpara></listitem>
 <listitem><simpara>The &documentation-k; argument is a string or &nil;.
   An &err-sig; if this value is not a string or &nil;.  This argument
   defaults to &nil;.</simpara></listitem>
</itemizedlist>

<para>After the processing and defaulting of initialization arguments
described above, the value of each initialization argument is associated
with the &m-mo;.  These values can then be accessed by calling the
corresponding generic function.  The correspondences are as follows:

<table id="mop-meth-initargs"><title>Initialization arguments and
  accessors for &m-mo;s</title>
 <tgroup cols="2" colsep="1" rowsep="1" align="center">
  <thead><row><entry>Initialization Argument</entry>
    <entry>Generic Function</entry></row></thead>
  <tbody>
 <row><entry>&qualifiers-k;</entry><entry>&method-qualifiers;</entry></row>
 <row><entry>&lambda-list-k;</entry><entry>&method-lambda-list;</entry></row>
 <row><entry>&specializers-k;</entry><entry>&method-specializers;</entry></row>
 <row><entry>&function-k;</entry><entry>&method-function;</entry></row>
 <row><entry>&slotdef-k;</entry><entry>&accessor-method-slotdef;</entry></row>
 <row><entry>&documentation-k;</entry><entry>&documentation;</entry></row>
</tbody></tgroup></table></para>


<section id="mop-meth-init-mo-method"><title>Methods</title>

<para>It is not specified which methods provide the initialization
behavior described above.  Instead, the information needed to allow
portable programs to specialize this behavior is presented in as a set
of restrictions on the methods a portable program can define.  The model
is that portable initialization methods have access to the &m-mo; when
either all or none of the specified initialization has taken
effect.</para>

<para>These restrictions govern the methods that a portable program can
define on the generic functions &initialize-instance;,
&reinitialize-instance;, and &shared-initialize;.  These restrictions
apply only to methods on these generic functions for which the first
specializer is a subclass of the class &method-t;.  Other portable
methods on these generic functions are not affected by these
restrictions.</para>

<itemizedlist>
 <listitem><simpara>Portable programs must not define methods on
   &shared-initialize; or &reinitialize-instance;.</simpara></listitem>
 <listitem><para>For &initialize-instance;:
   &init-method-restrictions;</para></listitem>
</itemizedlist>
&else-undefined;
</section><!-- mop-meth-init-mo-method -->
</section><!-- mop-meth-init-mo -->
</section><!-- mop-meth-init -->

<section id="mop-meth-customize"><title>Customization</title>

<!-- begin method advanced customization -->

<section id="extract-lambda-list"><title>Function &extract-lambda-list;</title>

<variablelist><varlistentry><term>Syntax</term>
 <listitem><simpara><code>(&extract-lambda-list; &spec-lalist-r;)
</code></simpara></listitem></varlistentry>
<varlistentry><term>Arguments</term>
 <listitem><variablelist>
   <varlistentry><term>&spec-lalist-r;</term>
    <listitem><simpara>a &spelalist; as accepted by &defmethod;.
</simpara></listitem></varlistentry></variablelist></listitem></varlistentry>
<varlistentry><term>Value</term>
 <listitem><simpara>An unspecialized &lalist;.
</simpara></listitem></varlistentry>
<varlistentry><term>Purpose</term>
 <listitem><simpara>This function takes a &spelalist; and
   returns the &lalist; with the specializers removed.  This is a
   non-destructive operation.  Whether the result shares any structure
   with the argument is unspecified.</simpara>
  <simpara>If the &spec-lalist-r; argument does not have legal syntax,
   an &err-sig;.  This syntax checking does not check the syntax of the
   actual specializer names, only the syntax of the &lalist; and
   where the specializers appear.
</simpara></listitem></varlistentry></variablelist>

<informalexample id="extract-lambda-list-ex"><programlisting language="lisp">
(&extract-lambda-list; '((p position)))
<computeroutput>(P)</computeroutput>
(&extract-lambda-list; '((p position) x y))
<computeroutput>(P X Y)</computeroutput>
(&extract-lambda-list; '(a (b (eql x)) c &rest-amp; i))
<computeroutput>(A B C &optional-amp; I)</computeroutput>
</programlisting></informalexample>
</section><!-- extract-lambda-list -->

<section id="extract-specializer-names">
 <title>Function &extract-specializer-names;</title>

<variablelist><varlistentry><term>Syntax</term>
 <listitem><simpara><code>(&extract-specializer-names;
    &spec-lalist-r;)</code></simpara></listitem></varlistentry>
<varlistentry><term>Arguments</term>
 <listitem><variablelist>
   <varlistentry><term>&spec-lalist-r;</term>
    <listitem><simpara>a &spelalist; as accepted by &defmethod;.
</simpara></listitem></varlistentry></variablelist></listitem></varlistentry>
<varlistentry><term>Value</term>
 <listitem><simpara>A list of specializer names.
</simpara></listitem></varlistentry>
<varlistentry><term>Purpose</term>
 <listitem><simpara>This function takes a &spelalist; and
   returns its specializer names.  This is a non-destructive operation.
   Whether the result shares structure with the argument is unspecified.
  </simpara>&result-immutable;
  <simpara>The result of this function will be a list with a
   number of elements equal to the number of required arguments in
   &spec-lalist-r;.  Specializers are defaulted to the symbol &t-t;.
  </simpara><simpara>If the &spec-lalist-r; argument does not have legal
   syntax, an &err-sig;.  This syntax checking does not check the syntax
   of the actual specializer names, only the syntax of the &lalist;
   and where the specializers appear.
</simpara></listitem></varlistentry></variablelist>

<informalexample id="extract-specializer-names-ex">
 <programlisting language="lisp">
(&extract-specializer-names; '((p position)))
<computeroutput>(POSITION)</computeroutput>
(&extract-specializer-names; '((p position) x y))
<computeroutput>(POSITION T T)</computeroutput>
(&extract-specializer-names; '(a (b (eql x)) c &rest-amp; i))
<computeroutput>(T (EQL X) T)</computeroutput>
</programlisting></informalexample>
</section><!-- extract-specializer-names -->

<!-- end method advanced customization -->

</section><!-- mop-meth-customize -->
</section><!-- mop-meth -->

<section id="mop-accessors"><title>Accessor Methods</title>

<section id="mop-acc-readers"><title>Introspection</title>

<!-- begin accessor-method basic introspection -->

<section id="accessor-method-slotdef">
 <title>Generic Function &accessor-method-slotdef;</title>
 <subtitle><code>(&accessor-method-slotdef; &method-r;)</code></subtitle>

<para>This accessor can only be called on accessor methods.  It returns
the &dsdmo; that defined this method.  This is the value of the
&slotdef-k; initialization argument associated with the method during
initialization.</para>

<variablelist><title>The specified methods for the accessor &m-mo;
  readers</title>
<varlistentry><term><literal role="method">(&accessor-method-slotdef;
   (&method-r; &standard-accessor-method-t;))</literal></term>
 <listitem>&no-extra-spec;</listitem></varlistentry></variablelist>
</section>

<!-- end accessor-method basic introspection -->

</section><!-- mop-acc-readers -->

<section id="mop-acc-customize"><title>Customization</title>

<!-- begin accessor-method advanced customization -->

<section id="reader-method-class">
 <title>Generic Function &reader-method-class;</title>

<variablelist><varlistentry><term>Syntax</term>
 <listitem><simpara><code>(&reader-method-class; &class-r; &dsd-r;
    &rest-amp; &initargs-r;)</code></simpara></listitem></varlistentry>
<varlistentry><term>Arguments</term>
 <listitem><variablelist>&class-mo-arg;
   <varlistentry><term>&dsd-r;</term>
    <listitem><simpara>a &dsdmo;.</simpara></listitem></varlistentry>
   <varlistentry><term>&initargs-r;</term>
    <listitem><simpara>alternating initialization argument names and values.
</simpara></listitem></varlistentry></variablelist></listitem></varlistentry>
<varlistentry><term>Value</term>&a-cmo;</varlistentry>
<varlistentry><term>Purpose</term>
 <listitem><simpara>This generic function is called to determine the
   class of reader methods created during class initialization and
   reinitialization.  The result must be a subclass of
   &standard-reader-method-t;.</simpara>
  <simpara>The &initargs-r; argument must be the same as will be passed
   to &make-instance; to create the reader method.  The &initargs-r;
   must include &slotdef-k; with &slotdef-r; as its value.
</simpara></listitem></varlistentry></variablelist>

<variablelist><title>Methods</title>
<varlistentry><term><literal role="method">(&reader-method-class;
   (&class-r; &standard-class;) (&dsd-r; &standard-dsd-t;)
   &rest-amp; &initargs-r;)</literal></term>
 <term><literal role="method">(&reader-method-class;
   (&class-r; &funcallable-standard-class;) (&dsd-r; &standard-dsd-t;)
   &rest-amp; &initargs-r;)</literal></term>
 <listitem><simpara>These methods return the class
   &standard-reader-method-t;.</simpara>
  &overridables;</listitem></varlistentry></variablelist>
</section><!-- reader-method-class -->

<section id="writer-method-class">
 <title>Generic Function &writer-method-class;</title>

<variablelist><varlistentry><term>Syntax</term>
 <listitem><simpara><code>(&writer-method-class; &class-r;
    <replaceable>direct-slot</replaceable> &rest-amp; &initargs-r;)
 </code></simpara></listitem></varlistentry>
<varlistentry><term>Arguments</term>
 <listitem><variablelist>&class-mo-arg;
   <varlistentry><term><replaceable>direct-slot</replaceable></term>
    <listitem><simpara>a &dsdmo;.</simpara></listitem></varlistentry>
   <varlistentry><term>&initargs-r;</term>
    <listitem><simpara>a list of initialization arguments and values.
</simpara></listitem></varlistentry></variablelist></listitem></varlistentry>
<varlistentry><term>Value</term>&a-cmo;</varlistentry>
<varlistentry><term>Purpose</term>
 <listitem><simpara>This generic function is called to determine the
   class of writer methods created during class initialization and
   reinitialization.  The result must be a subclass of
   &standard-writer-method-t;.</simpara>
  <simpara>The &initargs-r; argument must be the same as will be passed
   to &make-instance; to create the reader method.  The &initargs-r;
   must include &slotdef-k; with &slotdef-t; as its value.
</simpara></listitem></varlistentry></variablelist>

<variablelist><title>Methods</title>
 <varlistentry><term><literal role="method">(&writer-method-class;
    (&class-r; &standard-class;)
    (<replaceable>direct-slot</replaceable> &standard-dsd-t;)
    &rest-amp; &initargs-r;)</literal></term>
<term><literal role="method">(&writer-method-class;
    (&class-r; &funcallable-standard-class;)
    (<replaceable>direct-slot</replaceable> &standard-dsd-t;)
    &rest-amp; &initargs-r;)</literal></term>
<listitem><simpara>These methods return the class
  &standard-writer-method-t;.</simpara>
 &overridables;</listitem></varlistentry></variablelist>
</section><!-- writer-method-class -->

<!-- end accessor-method advanced customization -->

</section><!-- mop-acc-customize -->
</section><!-- mop-accessors -->

<section id="mop-specializers"><title>Specializers</title>

<section id="mop-specializers-inheritance">
 <title>Inheritance Structure of Specializer Metaobject Classes</title>
<figure id="mop-specializers-inheritance-fig">
 <title>Inheritance structure of specializer metaobject classes</title>
 <mediaobject><imageobject>
   <imagedata width="100%" scalefit="1" fileref="mop-classes-specializer.png"/>
</imageobject></mediaobject></figure>
</section>

<section id="mop-spec-readers"><title>Introspection</title>

<!-- begin specializer basic introspection -->

<section id="eql-specializer-object">
 <title>Function &eql-specializer-object;</title>

<variablelist><varlistentry><term>Syntax</term>
 <listitem><simpara><code>(&eql-specializer-object;
    <replaceable>eql-specializer</replaceable>)
</code></simpara></listitem></varlistentry>
<varlistentry><term>Arguments</term>
 <listitem><variablelist>
   <varlistentry><term><replaceable>eql-specializer</replaceable></term>
     <listitem><simpara>an &eql-t; specializer metaobject.
</simpara></listitem></varlistentry></variablelist></listitem></varlistentry>
<varlistentry><term>Value</term>&an-object;</varlistentry>
<varlistentry><term>Purpose</term>
 <listitem><simpara>This function returns the object associated with
   <replaceable>eql-specializer</replaceable> during initialization.
   The value is guaranteed to be &eql-t; to the value originally passed
   to &intern-eql-specializer;, but it is not necessarily &eq; to that
   value.</simpara>
  <simpara>This function &sig-err; if
   <replaceable>eql-specializer</replaceable> is not an &eql-t;
   specializer.</simpara></listitem></varlistentry></variablelist>
</section><!-- eql-specializer-object -->

<!-- end specializer basic introspection -->

</section><!-- mop-spec-readers -->

<section id="mop-spec-init"><title>Initialization</title>

<section id="intern-eql-specializer">
 <title>Function &intern-eql-specializer;</title>

<variablelist><varlistentry><term>Syntax</term>
 <listitem><simpara><code>(&intern-eql-specializer;
    &object-r;)</code></simpara></listitem></varlistentry>
<varlistentry><term>Arguments</term>
 <listitem><variablelist>
   <varlistentry><term>&object-r;</term>
    <listitem><simpara>any Lisp object.</simpara></listitem></varlistentry>
</variablelist></listitem></varlistentry>
<varlistentry><term>Values</term>
 <listitem><simpara>The &eql-t; specializer metaobject for &object-r;.
</simpara></listitem></varlistentry>
<varlistentry><term>Purpose</term>
 <listitem><simpara>This function returns the unique &eql-t; specializer
   metaobject for &object-r;, creating one if necessary.  Two calls to
   &intern-eql-specializer; with &eql-t; arguments will return the same
   (i.e., &eq;) value.</simpara></listitem></varlistentry></variablelist>

<formalpara><title>Remarks</title>
<para>The result of calling &eql-specializer-object; on the result of a
call to &intern-eql-specializer; is only guaranteed to be &eql-t; to the
original &object-r; argument, not necessarily &eq;.</para></formalpara>
</section><!-- intern-eql-specializer -->
</section><!-- mop-spec-init -->

<section id="mop-spec-dep"><title>Updating Dependencies</title>

<section id="specializer-direct-methods">
 <title>Generic Function &specializer-direct-methods;</title>

<variablelist><varlistentry><term>Syntax</term>
 <listitem><simpara><code>(&specializer-direct-methods;
    &specializer-r;)</code></simpara></listitem></varlistentry>
<varlistentry><term>Arguments</term>
 <listitem><variablelist>&specializer-mo-arg;
</variablelist></listitem></varlistentry>
<varlistentry><term>Value</term>
 <listitem><simpara>A possibly empty list of &m-mo;s.
</simpara></listitem></varlistentry>
<varlistentry><term>Purpose</term>
 <listitem><simpara>This generic function returns the possibly empty set
   of those methods, connected to generic functions, which have
   &specializer-r; as a specializer.  The elements of this set are
   &m-mo;s.  This value is maintained by the generic
   functions &add-direct-method; and &remove-direct-method;.
</simpara></listitem></varlistentry></variablelist>

<variablelist><title>Methods</title>
<varlistentry><term><literal role="method">(&specializer-direct-methods;
   (&specializer-r; &class;))</literal></term>
<listitem>&no-extra-spec;
 <para>&also-must-override;<itemizedlist>
   <listitem><simpara><literal role="method">&add-direct-method;
      (&class; &method-t;)</literal></simpara></listitem>
   <listitem><simpara><literal role="method">&remove-direct-method;
      (&class; &method-t;)</literal></simpara></listitem>
   <listitem><simpara><literal role="method">&specializer-direct-gfs;
      (&class;)</literal></simpara></listitem>
</itemizedlist></para></listitem></varlistentry>
<varlistentry><term><literal role="method">(&specializer-direct-methods;
   (&specializer-r; &eql-specializer-t;))</literal></term>
<listitem>&no-extra-spec;</listitem></varlistentry></variablelist>
</section><!-- specializer-direct-methods -->

<section id="specializer-direct-gfs">
 <title>Generic Function &specializer-direct-gfs;</title>

<variablelist><varlistentry><term>Syntax</term>
 <listitem><simpara><code>(&specializer-direct-gfs;
    &specializer-r;)</code></simpara></listitem></varlistentry>
<varlistentry><term>Arguments</term>
 <listitem><variablelist>&specializer-mo-arg;
</variablelist></listitem></varlistentry>
<varlistentry><term>Value</term>
 <listitem><simpara>A possibly empty list of &gfmo;s.
</simpara></listitem></varlistentry>
<varlistentry><term>Purpose</term>
 <listitem><simpara>This generic function returns the possibly empty set
   of those generic functions which have a method with &specializer-r;
   as a specializer.  The elements of this set are &gfmo;s.  This value
   is maintained by the generic functions &add-direct-method; and
   &remove-direct-method;.</simpara></listitem></varlistentry></variablelist>

<variablelist><title>Methods</title>
<varlistentry><term><literal role="method">(&specializer-direct-gfs;
   (&specializer-r; &class;))</literal></term>
<listitem>&no-extra-spec;
 <para>&also-must-override;<itemizedlist>
   <listitem><simpara><literal role="method">&add-direct-method;
      (&class; &method-t;)</literal></simpara></listitem>
   <listitem><simpara><literal role="method">&remove-direct-method;
      (&class; &method-t;)</literal></simpara></listitem>
   <listitem><simpara><literal role="method">&specializer-direct-methods;
      (&class;)</literal></simpara></listitem>
</itemizedlist></para></listitem></varlistentry>
<varlistentry><term><literal role="method">(&specializer-direct-gfs;
   (&specializer-r; &eql-specializer-t;))</literal></term>
<listitem>&no-extra-spec;</listitem></varlistentry></variablelist>
</section><!-- specializer-direct-gfs -->

<section id="add-direct-method">
 <title>Generic Function &add-direct-method;</title>

<variablelist><varlistentry><term>Syntax</term>
  <listitem><simpara><code>(&add-direct-method;
     &specializer-r; &method-r;)</code></simpara></listitem></varlistentry>
<varlistentry><term>Arguments</term>
 <listitem><variablelist>&specializer-mo-arg; &method-mo-arg;
</variablelist></listitem></varlistentry>
&values-unspecified;
<varlistentry><term>Purpose</term>
 <listitem><simpara>This generic function is called to maintain a set of
   backpointers from a specializer to the set of methods specialized to
   it.  If &method-r; is already in the set, it is not added again (no
   &err-sig;).</simpara>
  <simpara>This set can be accessed as a list by calling the generic
   function &specializer-direct-methods;.  Methods are removed from the
   set by &remove-direct-method;.</simpara>
  <simpara>The generic function &add-direct-method; is called by
   &add-method; whenever a method is added to a generic function.  It is
   called once for each of the specializers of the method.  Note that in
   cases where a specializer appears more than once in the specializers
   of a method, this generic function will be called more than once with
   the same specializer as argument.</simpara>
  <simpara>The results are undefined if the &specializer-r; argument
   is not one of the specializers of the &method-r; argument.
</simpara></listitem></varlistentry></variablelist>

<variablelist><title>Methods</title>
<varlistentry><term><literal role="method">(&add-direct-method;
   (&specializer-r; &class;) (&method-r; &method-t;))</literal></term>
 <listitem><simpara>This method implements the behavior of the generic
   function for class specializers.</simpara>&no-extra-spec;
  <para>&also-must-override;<itemizedlist>
    <listitem><simpara><literal role="method">&remove-direct-method;
       (&class; &method-t;)</literal></simpara></listitem>
    <listitem><simpara><literal role="method">
       &specializer-direct-gfs; (&class;)</literal></simpara></listitem>
    <listitem><simpara><literal role="method">&specializer-direct-methods;
       (&class;)</literal></simpara></listitem></itemizedlist>
</para></listitem></varlistentry>
<varlistentry><term><literal role="method">(&add-direct-method;
   (&specializer-r; &eql-specializer-t;)
   (&method-r; &method-t;))</literal></term>
 <listitem><simpara>This method implements the behavior of the generic
   function for &eql-t; specializers.</simpara>&no-extra-spec;
</listitem></varlistentry></variablelist>
</section><!-- add-direct-method -->

<section id="remove-direct-method">
 <title>Generic Function &remove-direct-method;</title>

<variablelist><varlistentry><term>Syntax</term>
 <listitem><simpara><code>(&remove-direct-method; &specializer-r;
    &method-r;)</code></simpara></listitem></varlistentry>
<varlistentry><term>Arguments</term>
 <listitem><variablelist>&specializer-mo-arg; &method-mo-arg;
</variablelist></listitem></varlistentry>
&values-unspecified;
<varlistentry><term>Purpose</term>
 <listitem><simpara>This generic function is called to maintain a set of
   backpointers from a specializer to the set of methods specialized to
   it.  If &method-r; is in the set it is removed.  If it is not, no
   &err-sig;.</simpara>
  <simpara>This set can be accessed as a list by calling the generic
   function &specializer-direct-methods;.  Methods are added to the set
   by &add-direct-method;.</simpara>
  <simpara>The generic function &remove-direct-method; is called by
   &remove-method; whenever a method is removed from a generic function.
   It is called once for each of the specializers of the method.  Note
   that in cases where a specializer appears more than once in the
   specializers of a method, this generic function will be called more
   than once with the same specializer as argument.</simpara>
  <simpara>The results are undefined if the &specializer-r; argument is
   not one of the specializers of the &method-r; argument.
</simpara></listitem></varlistentry></variablelist>

<variablelist><title>Methods</title>
<varlistentry><term><literal role="method">(&remove-direct-method;
   (&specializer-r; &class;) (&method-r; &method-t;))</literal></term>
 <listitem><simpara>This method implements the behavior of the generic
   function for class specializers.</simpara>
  &no-extra-spec;
  <para>&also-must-override;<itemizedlist>
    <listitem><simpara><literal role="method">&add-direct-method;
       (&class; &method-t;)</literal></simpara></listitem>
    <listitem><simpara><literal role="method">&specializer-direct-gfs;
       (&class;)</literal></simpara></listitem>
    <listitem><simpara><literal role="method">&specializer-direct-methods;
       (&class;)</literal></simpara></listitem>
</itemizedlist></para></listitem></varlistentry>
<varlistentry><term><literal role="method">(&remove-direct-method;
   (&specializer-r; &eql-specializer-t;)
   (&method-r; &method-t;))</literal></term>
 <listitem><simpara>This method implements the behavior of the generic
   function for &eql-t; specializers.</simpara>
  &no-extra-spec;</listitem></varlistentry></variablelist>
</section><!-- remove-direct-method -->
</section><!-- mop-spec-dep -->
</section><!-- mop-specializers -->

<section id="mop-meth-comb"><title>Method Combinations</title>

<section id="mop-meth-comb-inheritance">
 <title>Inheritance Structure of &mcmo; Classes</title>
<figure id="mop-meth-comb-inheritance-fig">
 <title>Inheritance structure of method combination metaobject classes</title>
 <mediaobject><imageobject>
   <imagedata width="100%" scalefit="1" fileref="mop-classes-methcomb.png"/>
</imageobject></mediaobject></figure>
</section>

<section id="mop-meth-comb-customize"><title>Customization</title>

<!-- begin method-combination advanced customization -->

<section id="find-method-combination">
 <title>Generic Function &find-method-combination;</title>

<variablelist><varlistentry><term>Syntax</term>
 <listitem><simpara><code>(&find-method-combination; &gf-r;
    <replaceable>method-combination-type-name</replaceable>
    <replaceable>method-combination-options</replaceable>)
</code></simpara></listitem></varlistentry>
<varlistentry><term>Arguments</term>
 <listitem><variablelist>&gf-mo-arg;
   <varlistentry><term><replaceable>method-combination-type-name</replaceable></term>
    <listitem><simpara>a symbol which names a type of method combination.
   </simpara></listitem></varlistentry>
   <varlistentry><term><replaceable>method-combination-options</replaceable></term>
    <listitem><simpara>a list of arguments to the method combination type.
</simpara></listitem></varlistentry></variablelist></listitem></varlistentry>
<varlistentry><term>Value</term>
 <listitem><simpara>A &mcmo;.</simpara></listitem></varlistentry>
<varlistentry><term>Purpose</term>
 <listitem><simpara>This generic function is called to determine the
   method combination object used by a generic function.
</simpara></listitem></varlistentry></variablelist>

<formalpara><title>Remarks</title>
<para>Further details of &mcmo;s are not specified.
</para></formalpara>
</section><!-- find-method-combination -->

<!-- end method-combination advanced customization -->

</section><!-- mop-meth-comb-customize -->
</section><!-- mop-meth-comb -->

<section id="mop-slot-access"><title>Slot Access</title>

<section id="mop-sa-instance-struct">
 <title>Instance Structure Protocol</title>

<para>The instance structure protocol is responsible for implementing
the behavior of the slot access functions like &slot-value; and
<code>(&setf; &slot-value;)</code>.</para>

<para>For each &clos; slot access function other than &slot-exists-p;,
there is a corresponding generic function which actually provides the
behavior of the function.  When called, the slot access function finds
the pertinent &esdmo;, calls the corresponding generic function and
returns its result.  The arguments passed on to the generic function
include one additional value, the class of the &object-r; argument,
which always immediately precedes the &object-r; argument.</para>

<table id="mop-sa-instance-struct-table">
 <title>The correspondence between slot access function and
  underlying slot access generic function</title>
<tgroup cols="2" colsep="1" rowsep="1" align="center">
 <thead><row><entry>Slot Access Function</entry><entry>Corresponding
    Slot Access Generic Function</entry></row></thead>
 <tbody>
  <row><entry>&slot-value; &object-r; &slot-name-r;</entry>
   <entry>&slot-value-UC; &class-r; &object-r; &slot-r;</entry></row>
  <row><entry>&setf-slot-value; &nval-r; &object-r; &slot-name-r;</entry>
   <entry>&setf-slot-value-UC; &nval-r; &class-r; &object-r; &slot-r;</entry></row>
  <row><entry>&slot-boundp; &object-r; &slot-name-r;</entry>
   <entry>&slot-boundp-UC; &class-r; &object-r; &slot-r;</entry></row>
  <row><entry>&slot-makunbound; &object-r; &slot-name-r;</entry>
   <entry>&slot-makunbound-UC; &class-r; &object-r; &slot-r;</entry></row>
</tbody></tgroup></table>

<para>At the lowest level, the instance structure protocol provides only
limited mechanisms for portable programs to control the implementation
of instances and to directly access the storage associated with
instances without going through the indirection of slot access.  This is
done to allow portable programs to perform certain commonly requested
slot access optimizations.</para>

<para>In particular, portable programs can control the implementation
of, and obtain direct access to, slots with allocation &instance-k; and
type &t-t;.  These are called <firstterm>directly accessible slots
  <indexterm id="slot-directly-accessible" significance="preferred">
   <primary>slot</primary><secondary>directly
    accessible</secondary></indexterm></firstterm>.</para>

<para>The relevant specified around-method on &compute-slots; determines
the implementation of instances by deciding how each slot in the
instance will be stored.  For each directly accessible slot, this method
allocates a <firstterm>location
  <indexterm id="slot-location" significance="preferred">
   <primary>slot</primary><secondary>location</secondary></indexterm>
 </firstterm> and associates it with the &esdmo;.
The location can be accessed by calling the &slotdef-location;
generic function.  Locations are non-negative integers.  For a given
class, the locations increase consecutively, in the order that the
directly accessible slots appear in the list of effective slots.  (Note
that here, the next paragraph, and the specification of this
around-method are the only places where the value returned by
&compute-slots; is described as a list rather than a set.)</para>

<para>Given the location of a directly accessible slot, the value of
that slot in an instance can be accessed with the appropriate accessor.
For &standard-class;, this accessor is the function
&standard-instance-access;.  For &funcallable-standard-class;, this
accessor is the function &funcallable-standard-instance-access;.
In each case, the arguments to the accessor are the instance and the
slot location, in that order.  See the definition of each accessor for
additional restrictions on the use of these function.</para>

<para>Portable programs are permitted to affect and rely on the
allocation of locations only in the following limited way: By first
defining a portable primary method on &compute-slots; which orders the
returned value in a predictable way, and then relying on the defined
behavior of the specified around-method to assign locations to all
directly accessible slots.  Portable programs may compile-in calls to
low-level accessors which take advantage of the resulting predictable
allocation of slot locations.</para>

<informalexample id="mop-sa-instance-struct-ex">
<para>This example shows the use of this mechanism to implement a new
&c-mo; class, <classname>ordered-class</classname> and class
option <constant>:SLOT-ORDER</constant>.  This option provides control
over the allocation of slot locations.  In this simple example
implementation, the <constant>:SLOT-ORDER</constant> option is not
inherited by subclasses; it controls only instances of the class
itself.
<programlisting language="lisp">
(defclass ordered-class (standard-class)
  ((slot-order :initform ()
               :initarg :slot-order
               :reader class-slot-order)))

(defmethod compute-slots ((class ordered-class))
  (let ((order (class-slot-order class)))
    (sort (copy-list (call-next-method))
          #'(lambda (a b)
              (&lt; (position (slot-definition-name a) order)
                 (position (slot-definition-name a) order))))))
</programlisting>

Following is the source code the user of this extension would write.
Note that because the code above does not implement inheritance of
the <constant>:SLOT-ORDER</constant> option, the function
<function>distance</function> must not be called on instances of
subclasses of <classname>point</classname>; it can only be called on
instances of <classname>point</classname> itself.

<programlisting language="lisp">
(defclass point ()
  ((x :initform 0)
   (y :initform 0))
  (:metaclass ordered-class)
  (:slot-order x y))

(defun distance (point)
  (sqrt (/ (+ (expt (standard-instance-access point 0) 2)
              (expt (standard-instance-access point 1) 2))
           2.0)))
</programlisting>

<note>&clisp-only;<simpara>You cannot assume that the slot-location
  values start at 0.  In class <classname>point</classname>, for
  example, &x-r; and &y-r; will be at slot locations 1 and 2, not 0 and
  1.</simpara></note>

In more realistic uses of this mechanism, the calls to the low-level
instance structure accessors would not actually appear textually in the
source program, but rather would be generated by a meta-level analysis
program run during the process of compiling the source program.
</para></informalexample>
</section><!-- mop-sa-instance-struct -->

<section id="mop-sa-funcallable"><title>Funcallable Instances</title>

<para>Instances of classes which are themselves instances of
&funcallable-standard-class; or one of its subclasses are called
<firstterm>funcallable instances</firstterm>.
Funcallable instances can only be created by
<literal role="method">&allocate-instance;
 (&funcallable-standard-class;)</literal>.</para>

<para>Like standard instances, funcallable instances have slots with the
normal behavior.  They differ from standard instances in that they can
be used as functions as well; that is, they can be passed to &funcall;
and &apply;, and they can be stored as the definition of a function
name.  Associated with each funcallable instance is the function which
it runs when it is called.  This function can be changed with
&set-funcallable-instance-function;.</para>

<informalexample id="mop-sa-funcallable-ex">
<para>The following simple example shows the use of funcallable
instances to create a simple, &defstruct;-like facility.  (Funcallable
instances are useful when a program needs to construct and maintain a
set of functions and information about those functions.  They make it
possible to maintain both as the same object rather than two separate
objects linked, for example, by hash tables.)

<programlisting language="lisp">
(defclass constructor ()
  ((name :initarg :name :accessor constructor-name)
   (fields :initarg :fields :accessor constructor-fields))
  (:metaclass funcallable-standard-class))
<computeroutput>#&gt;FUNCALLABLE-STANDARD-CLASS CONSTRUCTOR&gt;</computeroutput>
(defmethod initialize-instance :after ((c constructor) &key-amp;)
  (with-slots (name fields) c
    (set-funcallable-instance-function
      c
      #'(lambda ()
          (let ((new (make-array (1+ (length fields)))))
            (setf (aref new 0) name)
            new)))))
<computeroutput>#&lt;STANDARD-METHOD :AFTER (#&lt;FUNCALLABLE-STANDARD-CLASS CONSTRUCTOR&gt;)&gt;</computeroutput>
(setq c1 (make-instance 'constructor :name 'position :fields '(x y)))
<computeroutput>#&lt;CONSTRUCTOR #&lt;UNBOUND&gt;&gt;</computeroutput>
(setq p1 (funcall c1))
<computeroutput>#(POSITION NIL NIL)</computeroutput>
</programlisting></para></informalexample>
</section><!-- mop-sa-funcallable -->

<section id="mop-sa-customize"><title>Customization</title>

<!-- begin slot access basic customization -->

<section id="standard-instance-access">
 <title>Function &standard-instance-access;</title>

<variablelist><varlistentry><term>Syntax</term>
 <listitem><simpara><code>(&standard-instance-access;
    &instance-r; &location-r;)</code></simpara></listitem></varlistentry>
<varlistentry><term>Arguments</term>
 <listitem><variablelist>
   <varlistentry><term>&instance-r;</term>&an-object;</varlistentry>
   <varlistentry><term>&location-r;</term>
    <listitem><simpara>a slot location</simpara></listitem></varlistentry>
</variablelist></listitem></varlistentry>
<varlistentry><term>Value</term>&an-object;</varlistentry>
<varlistentry><term>Purpose</term>
 <listitem><simpara>This function is called to provide direct access to
   a slot in an instance.  By usurping the normal slot lookup protocol,
   this function is intended to provide highly optimized access to the
   slots associated with an instance.</simpara>
  <para>The following restrictions apply to the use of this function:
   <itemizedlist><listitem><simpara>The &instance-r; argument must be a
      standard instance (it must have been returned by
      <literal role="method">&allocate-instance;(&standard-class;)</literal>).
    </simpara></listitem>
    <listitem><simpara>The &instance-r; argument cannot be an
      non-updated obsolete instance.</simpara></listitem>
    <listitem><simpara>The &location-r; argument must be a location of
      one of the directly accessible slots of the instance's class.
    </simpara></listitem><listitem><simpara>The slot must be bound.
  </simpara></listitem></itemizedlist></para>
  &else-undefined;</listitem></varlistentry></variablelist>

<note>&clisp-only;<simpara>The second and third restrictions do not
  apply in &clisp;.  &clisp;'s implementation supports non-updated
  obsolete instances and also supports slots with allocation &class-k;.
</simpara></note>
</section><!-- standard-instance-access -->

<section id="funcallable-standard-instance-access">
 <title>Function &funcallable-standard-instance-access;</title>

<variablelist><varlistentry><term>Syntax</term>
 <listitem><simpara><code>(&funcallable-standard-instance-access;
    &instance-r; &location-r;)</code></simpara></listitem></varlistentry>
<varlistentry><term>Arguments</term>
 <listitem><variablelist>
   <varlistentry><term>&instance-r;</term>&an-object;</varlistentry>
   <varlistentry><term>&location-r;</term>
    <listitem><simpara>a slot location</simpara></listitem></varlistentry>
</variablelist></listitem></varlistentry>
<varlistentry><term>Value</term>&an-object;</varlistentry>
<varlistentry><term>Purpose</term>
 <listitem><simpara>This function is called to provide direct access to
   a slot in an instance.  By usurping the normal slot lookup protocol,
   this function is intended to provide highly optimized access to the
   slots associated with an instance.</simpara>
  <para>The following restrictions apply to the use of this function:
   <itemizedlist><listitem><simpara>The &instance-r; argument must be a
      funcallable instance (it must have been returned by
      <literal role="method">&allocate-instance;
       (&funcallable-standard-class;)</literal>).</simpara></listitem>
    <listitem><simpara>The &instance-r; argument cannot be an
      non-updated obsolete instance.</simpara></listitem>
    <listitem><simpara>The &location-r; argument must be a location of
      one of the directly accessible slots of the instance's class.
    </simpara></listitem><listitem><simpara>The slot must be bound.
  </simpara></listitem></itemizedlist></para>
  &else-undefined;</listitem></varlistentry></variablelist>

<note>&clisp-only;<simpara>The second and third restrictions do not
  apply in &clisp;.  &clisp;'s implementation supports non-updated
  obsolete instances and also supports slots with allocation &class-k;.
</simpara></note>
</section><!-- funcallable-standard-instance-access -->

<section id="set-fif">
 <title>Function &set-funcallable-instance-function;</title>

<variablelist><varlistentry><term>Syntax</term>
 <listitem><simpara><code>(&set-funcallable-instance-function;
    <replaceable>funcallable-instance</replaceable> &func-r;)
</code></simpara></listitem></varlistentry>
<varlistentry><term>Arguments</term>
 <listitem><variablelist>
   <varlistentry><term><replaceable>funcallable-instance</replaceable></term>
    <listitem><simpara>a funcallable instance (it must have been returned by
      <literal role="method">&allocate-instance;
       (&funcallable-standard-class;)</literal>).
   </simpara></listitem></varlistentry>
   <varlistentry><term>&func-r;</term>
    <listitem><simpara>A function.</simpara></listitem></varlistentry>
</variablelist></listitem></varlistentry>
&values-unspecified;
<varlistentry><term>Purpose</term>
 <listitem><simpara>This function is called to set or to change the
   function of a funcallable instance.  After
   &set-funcallable-instance-function; is called, any subsequent calls
   to <replaceable>funcallable-instance</replaceable> will run the new
   function.</simpara></listitem></varlistentry></variablelist>
</section><!-- set-fif -->

<!-- end slot access basic customization -->

<!-- begin slot access advanced customization -->

<section id="slot-value-UC"><title>Generic Function &slot-value-UC;</title>

<variablelist><varlistentry><term>Syntax</term>
 <listitem><simpara><code>(&slot-value-UC; &class-r;
    &object-r; &slot-r;)</code></simpara></listitem></varlistentry>
<varlistentry><term>Arguments</term><listitem><variablelist>
   &class-obj-slot-arg;</variablelist></listitem></varlistentry>
<varlistentry><term>Values</term>&an-object;</varlistentry>
<varlistentry><term>Purpose</term>
 <listitem><simpara>This generic function implements the behavior of the
   &slot-value; function.  It is called by &slot-value; with the class
   of &object-r; as its first argument and the pertinent &esdmo; as its
   third argument.</simpara>
  <simpara>The generic function &slot-value-UC; returns the value
   contained in the given slot of the given object.  If the slot is
   unbound, &slot-unbound; is called.</simpara>
  &class-slot-UC-consistent;</listitem></varlistentry></variablelist>

<variablelist><title>Methods</title>
<varlistentry><term><literal role="method">(&slot-value-UC;
   (&class-r; &standard-class;) &object-r;
   (&slot-r; &standard-esd-t;))</literal></term>
 <term><literal role="method">(&slot-value-UC;
   (&class-r; &funcallable-standard-class;) &object-r;
   (&slot-r; &standard-esd-t;))</literal></term>
 <listitem>&class-slot-alloc-inst-class;
  &may-override;</listitem></varlistentry>
<varlistentry><term><literal role="method">(&slot-value-UC;
   (&class-r; &built-in-class;) &object-r; &slot-r;)</literal></term>
 <listitem><simpara>This method &sig-err;.
</simpara></listitem></varlistentry></variablelist>
</section><!-- slot-value-UC -->

<section id="setf-slot-value-UC">
 <title>Generic Function &setf-slot-value-UC;</title>

<variablelist><varlistentry><term>Syntax</term>
 <listitem><simpara><code>(&setf-slot-value-UC; &nval-r; &class-r;
    &object-r; &slot-r;)</code></simpara></listitem></varlistentry>
<varlistentry><term>Arguments</term>
 <listitem><variablelist>
   <varlistentry><term>&nval-r;</term>&an-object;</varlistentry>
   &class-obj-slot-arg;</variablelist></listitem></varlistentry>
<varlistentry><term>Value</term>
 <listitem><simpara>The &nval-r; argument.</simpara></listitem></varlistentry>
<varlistentry><term>Purpose</term>
 <listitem><simpara>The generic function &setf-slot-value-UC; implements
   the behavior of the &setf-slot-value; function. It is called by
   &setf-slot-value; with the class of &object-r; as its second argument
   and the pertinent &esdmo; as its fourth argument.</simpara>
  <simpara>The generic function &setf-slot-value-UC; sets the value
   contained in the given slot of the given object to the given new
   value; any previous value is lost.</simpara>
  &class-slot-UC-consistent;</listitem></varlistentry></variablelist>

<variablelist><title>Methods</title>
<varlistentry><term><literal role="method">(&setf-slot-value-UC;
   &nval-r; (&class-r; &standard-class;) &object-r;
   (&slot-r; &standard-esd-t;))</literal></term>
 <term><literal role="method">(&setf-slot-value-UC;
   &nval-r; (&class-r; &funcallable-standard-class;) &object-r;
   (&slot-r; &standard-esd-t;))</literal></term>
 <listitem>&class-slot-alloc-inst-class;
  &may-override;</listitem></varlistentry>
<varlistentry><term><literal role="method">(&setf-slot-value-UC;
   &nval-r; (&class-r; &built-in-class;) &object-r; &slot-r;)</literal></term>
<listitem><simpara>This method &sig-err;.
</simpara></listitem></varlistentry></variablelist>
</section><!-- setf-slot-value-UC -->

<section id="slot-boundp-UC"><title>Generic Function &slot-boundp-UC;</title>

<variablelist><varlistentry><term>Syntax</term>
 <listitem><simpara><code>(&slot-boundp-UC; &class-r; &object-r;
    &slot-r;)</code></simpara></listitem></varlistentry>
<varlistentry><term>Arguments</term><listitem><variablelist>
   &class-obj-slot-arg;</variablelist></listitem></varlistentry>
<varlistentry><term>Value</term>
 <listitem><simpara>&boolean-t;</simpara></listitem></varlistentry>
<varlistentry><term>Purpose</term>
 <listitem><simpara>This generic function implements the behavior of the
   &slot-boundp; function.  It is called by &slot-boundp; with the class
   of &object-r; as its first argument and the pertinent &esdmo; as its
   third argument.</simpara>
  <simpara>The generic function &slot-boundp-UC; tests whether a
   specific slot in an instance is bound.</simpara>
  &class-slot-UC-consistent;</listitem></varlistentry></variablelist>

<variablelist><title>Methods</title>
<varlistentry><term><literal role="method">(&slot-boundp-UC;
   (&class-r; &standard-class;) &object-r;
   (&slot-r; &standard-esd-t;))</literal></term>
 <term><literal role="method">(&slot-boundp-UC;
   (&class-r; &funcallable-standard-class;) &object-r;
   (&slot-r; &standard-esd-t;))</literal></term>
 <listitem>&class-slot-alloc-inst-class;
  &may-override;</listitem></varlistentry>
<varlistentry><term><literal role="method">(&slot-boundp-UC;
   (&class-r; &built-in-class;) &object-r; &slot-r;)</literal></term>
<listitem><simpara>This method &sig-err;.</simpara></listitem></varlistentry>
</variablelist>

<formalpara><title>Remarks</title>
<para>In cases where the &c-mo; class does not distinguish
unbound slots, true should be returned.</para></formalpara>
</section><!-- slot-boundp-UC -->

<section id="slot-makunbound-UC">
 <title>Generic Function &slot-makunbound-UC;</title>

<variablelist><varlistentry><term>Syntax</term>
 <listitem><simpara><code>(&slot-makunbound-UC; &class-r; &object-r;
    &slot-r;)</code></simpara></listitem></varlistentry>
<varlistentry><term>Arguments</term><listitem><variablelist>
   &class-obj-slot-arg;</variablelist></listitem></varlistentry>
<varlistentry><term>Value</term>
 <listitem><simpara>The &object-r; argument.</simpara></listitem></varlistentry>
<varlistentry><term>Purpose</term>
 <listitem><simpara>This generic function implements the behavior of the
   &slot-makunbound; function.  It is called by &slot-makunbound; with
   the class of &object-r; as its first argument and the pertinent
   &esdmo; as its third argument.</simpara>
  <simpara>The generic function &slot-makunbound-UC; restores a slot in
   an object to its unbound state.  The interpretation
   of <quote>restoring a slot to its unbound state</quote> depends on
   the &c-mo; class.</simpara>
  &class-slot-UC-consistent;</listitem></varlistentry></variablelist>

<variablelist><title>Methods</title>
<varlistentry><term><literal role="method">(&slot-makunbound-UC;
   (&class-r; &standard-class;) &object-r;
   (&slot-r; &standard-esd-t;))</literal></term>
 <term><literal role="method">(&slot-makunbound-UC;
   (&class-r; &funcallable-standard-class;) &object-r;
   (&slot-r; &standard-esd-t;))</literal></term>
 <listitem>&class-slot-alloc-inst-class;
  &may-override;</listitem></varlistentry>
<varlistentry><term><literal role="method">(&slot-makunbound-UC;
   (&class-r; &built-in-class;) &object-r; &slot-r;)</literal></term>
 <listitem><simpara>This method &sig-err;.
</simpara></listitem></varlistentry></variablelist>
</section><!-- slot-makunbound-UC -->

<!-- end slot access advanced customization -->

</section><!-- mop-sa-customize -->
</section><!-- mop-slot-access -->

<section id="mop-dep-maint"><title>Dependent Maintenance</title>

<para>It is convenient for portable metaobjects to be able to memoize
information about other metaobjects, portable or otherwise.  Because
class and &gfmo;s can be reinitialized, and &gfmo;s can be modified by
adding and removing methods, a means must be provided to update this
memoized information.</para>

<para>The dependent maintenance protocol supports this by providing a
way to register an object which should be notified whenever a class or
generic function is modified.  An object which has been registered this
way is called a <firstterm>dependent</firstterm> of the class or &gfmo;.
The dependents of class and &gfmo;s are maintained with &add-dependent;
and &remove-dependent;.  The dependents of a class or &gfmo; can be
accessed with &map-dependents;.  Dependents are notified about a
modification by calling &update-dependent;.  (See the specification of
&update-dependent; for detailed description of the circumstances under
which it is called.)</para>

<para>To prevent conflicts between two portable programs, or between
portable programs and the implementation, portable code must not
register metaobjects themselves as dependents. Instead, portable
programs which need to record a metaobject as a dependent, should
encapsulate that metaobject in some other kind of object, and record
that object as the dependent.  The results are undefined if this
restriction is violated.</para>

<informalexample id="mop-dep-maint-ex">
<para>This example shows a general facility for encapsulating
metaobjects before recording them as dependents.  The facility defines a
basic kind of encapsulating object: an updater.  Specializations of the
basic class can be defined with appropriate special updating behavior.
In this way, information about the updating required is associated with
each updater rather than with the metaobject being updated.</para>

<para>Updaters are used to encapsulate any metaobject which requires
updating when a given class or generic function is modified.  The
function <function>record-updater</function> is called to both create an
updater and add it to the dependents of the class or generic function.
Methods on the generic function &update-dependent;, specialized to the
specific class of updater do the appropriate update work.</para>

<programlisting language="lisp">
(defclass updater ()
  ((dependent :initarg :dependent :reader dependent)))

(defun record-updater (class dependee dependent &rest-amp; initargs)
  (let ((updater (apply #'make-instance class :dependent dependent
                                              initargs)))
    (add-dependent dependee updater)
    updater))
</programlisting>

<para>A <function>flush-cache-updater</function> simply flushes the
cache of the dependent when it is updated.</para>

<programlisting language="lisp">
(defclass flush-cache-updater (updater) ())

(defmethod update-dependent (dependee (updater flush-cache-updater) &rest-amp; args)
  (declare (ignore args))
  (flush-cache (dependent updater)))
</programlisting></informalexample>

<section id="mop-dep-maint-protocol"><title>Protocol</title>

<section id="update-dependent">
 <title>Generic Function &update-dependent;</title>

<variablelist><varlistentry><term>Syntax</term>
 <listitem><simpara><code>(&update-dependent; &metaobject-r;
    &dependent-r; &rest-amp; &initargs-r;)
</code></simpara></listitem></varlistentry>
<varlistentry><term>Arguments</term>
 <listitem><variablelist>
   <varlistentry><term>&metaobject-r;</term>
    <listitem><simpara>a &c-mo; or a &gfmo; - the metaobject being
      reinitialized or otherwise modified.</simpara></listitem></varlistentry>
   <varlistentry><term>&dependent-r;</term>
    <listitem><simpara>an object - the dependent being updated.
   </simpara></listitem></varlistentry>
   <varlistentry><term>&initargs-r;</term>
    <listitem><simpara>a list of the initialization arguments for
      the metaobject redefinition.</simpara></listitem></varlistentry>
</variablelist></listitem></varlistentry>
&values-unspecified;
<varlistentry><term>Purpose</term>
 <listitem><simpara>This generic function is called to update a
   dependent of &metaobject-r;.</simpara>
  <simpara>When a class or a generic function is reinitialized each of
   its dependents is updated.  The &initargs-r; argument to
   &update-dependent; is the set of initialization arguments received by
   &reinitialize-instance;.</simpara>
  <simpara>When a method is added to a generic function, each of the
   generic function's dependents is updated.  The &initargs-r; argument
   is a list of two elements: the symbol &add-method;, and the method
   that was added.</simpara>
  <simpara>When a method is removed from a generic function, each of the
   generic function's dependents is updated.  The &initargs-r; argument
   is a list of two elements: the symbol &remove-method;, and the method
   that was removed.</simpara>
  <para>In each case, &map-dependents; is used to call
   &update-dependent; on each of the dependents.  So, for example, the
   update of a generic function's dependents when a method is added
   could be performed by the following code:<programlisting language="lisp">
(&map-dependents; &gf-r;
                     #'(lambda (dep)
                         (&update-dependent; &gf-r;
                                                dep 'add-method new-method)))
</programlisting></para></listitem></varlistentry></variablelist>
&see-dep-maint;
</section><!-- update-dependent -->

<section id="add-dependent"><title>Generic Function &add-dependent;</title>

<variablelist><varlistentry><term>Syntax</term>
 <listitem><simpara><code>(&add-dependent; &metaobject-r;
    &dependent-r;)</code></simpara></listitem></varlistentry>
<varlistentry><term>Arguments</term>
 <listitem><variablelist>&mo-gfmo;
   <varlistentry><term>&dependent-r;</term>&an-object;</varlistentry>
</variablelist></listitem></varlistentry>
&values-unspecified;
<varlistentry><term>Purpose</term>
 <listitem><simpara>This generic function adds &dependent-r; to the
   dependents of &metaobject-r;.  If &dependent-r; is already in the set
   of dependents it is not added again (no &err-sig;).</simpara>
  <simpara>The generic function &map-dependents; can be called to access
   the set of dependents of a class or generic function.  The generic
   function &remove-dependent; can be called to remove an object from
   the set of dependents of a class or generic function.  The effect of
   calling &add-dependent; or &remove-dependent; while a call to
   &map-dependents; on the same class or generic function is in progress
   is unspecified.</simpara>
  <simpara>The situations in which &add-dependent; is called are not
   specified.</simpara></listitem></varlistentry></variablelist>

<variablelist><title>Methods</title>
<varlistentry><term><literal role="method">(&add-dependent;
   (&class-r; &standard-class;) &dependent-r;)</literal></term>
 <listitem>&no-extra-spec;
  <para>&also-must-override;<itemizedlist>
    <listitem><simpara><literal role="method">&remove-dependent;
       (&standard-class; &t-t;)</literal></simpara></listitem>
    <listitem><simpara><literal role="method">&map-dependents;
       (&standard-class; &t-t;)</literal></simpara></listitem>
</itemizedlist></para></listitem></varlistentry>
<varlistentry><term><literal role="method">(&add-dependent;
   (&class-r; &funcallable-standard-class;) &dependent-r;)</literal></term>
 <listitem>&no-extra-spec;
  <para>&also-must-override;<itemizedlist>
    <listitem><simpara><literal role="method">&remove-dependent;
       (&funcallable-standard-class; &t-t;)</literal></simpara></listitem>
    <listitem><simpara><literal role="method">&map-dependents;
       (&funcallable-standard-class; &t-t;)</literal></simpara></listitem>
</itemizedlist></para></listitem></varlistentry>
<varlistentry><term><literal role="method">(&add-dependent;
   (&gf-r; &standard-generic-function-t;) &dependent-r;)</literal></term>
 <listitem>&no-extra-spec;
  <para>&also-must-override;<itemizedlist>
    <listitem><simpara><literal role="method">&remove-dependent;
       (&standard-generic-function-t; &t-t;)</literal></simpara></listitem>
    <listitem><simpara><literal role="method">&map-dependents;
       (&standard-generic-function-t; &t-t;)</literal></simpara></listitem>
</itemizedlist></para></listitem></varlistentry></variablelist>
&see-dep-maint;
</section><!-- add-dependent -->

<section id="remove-dependent">
 <title>Generic Function &remove-dependent;</title>

<variablelist><varlistentry><term>Syntax</term>
  <listitem><simpara><code>(&remove-dependent; &metaobject-r;
     &dependent-r;)</code></simpara></listitem></varlistentry>
<varlistentry><term>Arguments</term>
 <listitem><variablelist>&mo-gfmo;
   <varlistentry><term>&dependent-r;</term>&an-object;</varlistentry>
</variablelist></listitem></varlistentry>
&values-unspecified;
<varlistentry><term>Purpose</term>
 <listitem><simpara>This generic function removes &dependent-r; from the
   dependents of &metaobject-r;.  If &dependent-r; is not one of the
   dependents of &metaobject-r;, no &err-sig;.</simpara>
  <simpara>The generic function &map-dependents; can be called to access
   the set of dependents of a class or generic function.  The generic
   function &add-dependent; can be called to add an object from the set
   of dependents of a class or generic function.  The effect of calling
   &add-dependent; or &remove-dependent; while a call to
   &map-dependents; on the same class or generic function is in progress
   is unspecified.</simpara>
  <simpara>The situations in which &remove-dependent; is called are not
   specified.</simpara></listitem></varlistentry></variablelist>

<variablelist><title>Methods</title>
<varlistentry><term><literal role="method">(&remove-dependent;
   (&class-r; &standard-class;) &dependent-r;)</literal></term>
 <listitem>&no-extra-spec;
  <para>&also-must-override;<itemizedlist>
    <listitem><simpara><literal role="method">&add-dependent;
       (&standard-class; &t-t;)</literal></simpara></listitem>
    <listitem><simpara><literal role="method">&map-dependents;
       (&standard-class; &t-t;)</literal></simpara></listitem>
</itemizedlist></para></listitem></varlistentry>
<varlistentry><term><literal role="method">(&remove-dependent;
   (&class-r; &funcallable-standard-class;) &dependent-r;)</literal></term>
 <listitem>&no-extra-spec;
  <para>&also-must-override;<itemizedlist>
    <listitem><simpara><literal role="method">&add-dependent;
       (&funcallable-standard-class; &t-t;)</literal></simpara></listitem>
    <listitem><simpara><literal role="method">&map-dependents;
       (&funcallable-standard-class; &t-t;)</literal></simpara></listitem>
</itemizedlist></para></listitem></varlistentry>
<varlistentry><term><literal role="method">(&remove-dependent;
   (&class-r; &standard-generic-function-t;) &dependent-r;)</literal></term>
 <listitem>&no-extra-spec;
  <para>&also-must-override;<itemizedlist>
    <listitem><simpara><literal role="method">&add-dependent;
       (&standard-generic-function-t; &t-t;)</literal></simpara></listitem>
    <listitem><simpara><literal role="method">&map-dependents;
       (&standard-generic-function-t; &t-t;)</literal></simpara></listitem>
</itemizedlist></para></listitem></varlistentry></variablelist>
&see-dep-maint;
</section><!-- remove-dependent -->

<section id="map-dependents"><title>Generic Function &map-dependents;</title>

<variablelist><varlistentry><term>Syntax</term>
 <listitem><simpara><code>(&map-dependents; &metaobject-r;
    &func-r;)</code></simpara></listitem></varlistentry>
<varlistentry><term>Arguments</term>
 <listitem><variablelist>&mo-gfmo;
   <varlistentry><term>&func-r;</term>
    <listitem><simpara>a function which accepts one argument.
</simpara></listitem></varlistentry></variablelist></listitem></varlistentry>
&values-unspecified;
<varlistentry><term>Purpose</term>
 <listitem><simpara>This generic function applies &func-r; to each of
   the dependents of &metaobject-r;.  The order in which the dependents
   are processed is not specified, but &func-r; is applied to each
   dependent once and only once.  If, during the mapping,
   &add-dependent; or &remove-dependent; is called to alter the
   dependents of &metaobject-r;, it is not specified whether the newly
   added or removed dependent will have &func-r; applied to it.
</simpara></listitem></varlistentry></variablelist>

<variablelist><title>Methods</title>
<varlistentry><term><literal role="method">(&map-dependents;
   (&metaobject-r; &standard-class;) &func-r;)</literal></term>
 <listitem>&no-extra-spec;
  <para>&also-must-override;<itemizedlist>
    <listitem><simpara><literal role="method">&add-dependent;
       (&standard-class; &t-t;)</literal></simpara></listitem>
    <listitem><simpara><literal role="method">&remove-dependent;
       (&standard-class; &t-t;)</literal></simpara></listitem>
</itemizedlist></para></listitem></varlistentry>
<varlistentry><term><literal role="method">(&map-dependents;
   (&metaobject-r; &funcallable-standard-class;) &func-r;)</literal></term>
 <listitem>&no-extra-spec;
  <para>&also-must-override;<itemizedlist>
    <listitem><simpara><literal role="method">&add-dependent;
       (&funcallable-standard-class; &t-t;)</literal></simpara></listitem>
    <listitem><simpara><literal role="method">&remove-dependent;
       (&funcallable-standard-class; &t-t;)</literal></simpara></listitem>
</itemizedlist></para></listitem></varlistentry>
 <varlistentry><term><literal role="method">(&map-dependents;
   (&metaobject-r; &standard-generic-function-t;) &func-r;)</literal></term>
 <listitem>&no-extra-spec;
  <para>&also-must-override;<itemizedlist>
    <listitem><simpara><literal role="method">&add-dependent;
       (&standard-generic-function-t; &t-t;)</literal></simpara></listitem>
    <listitem><simpara><literal role="method">&remove-dependent;
       (&standard-generic-function-t; &t-t;)</literal></simpara></listitem>
</itemizedlist></para></listitem></varlistentry></variablelist>
&see-dep-maint;
</section><!-- map-dependents -->
</section><!-- mop-dep-maint-protocol -->
</section><!-- mop-dep-maint -->

<section id="mop-clisp"><title>Deviations from &amop;</title>

<para>This section lists the differences between the &amop; and the
&clisp; implementation thereof.</para>

<itemizedlist id="mop-not-in-clisp"><title>Not implemented in &clisp;</title>
<listitem><para>The generic function &make-method-lambda; is not implemented.
  See <xref linkend="mop-gf-invocation"/>.</para></listitem>
</itemizedlist>

<itemizedlist id="mop-clisp-different">
 <title>Features implemented differently in &clisp;</title>
<listitem><para>The class precedence list of &funcallable-standard-object-t;
  is different. See <xref linkend="mop-mo-cl-inheritance"/>.</para></listitem>
<listitem><para>The &defclass; macro passes default values to &ensure-class;.
  See <xref linkend="mop-cl-defclass"/>.</para></listitem>
<listitem><para>The &defgeneric; macro passes default values to &ensure-gf;.
  See <xref linkend="mop-gf-init-defgeneric"/>.</para></listitem>
<listitem><para>The class &forward-referenced-class; is implemented differently.
  See <xref linkend="forward-referenced-class-clisp"/>.</para></listitem>
<listitem><para>The function &gf-argument-precedence-order; &sig-err;
  if the generic function has no &lalist;.</para></listitem>
</itemizedlist>

<itemizedlist id="mop-clisp-ext"><title>Extensions specific to &clisp;</title>
<listitem><para>The &mop; is applicable to classes of type &structure-class;.
  The default superclass for &structure-class; instances is
  &structure-object-t;.
  Structure classes do not support multiple inheritance and reinitialization.
  See <xref linkend="mop-cl-init-mo"/>.
  See also <xref linkend="defstruct-mop"/>.</para></listitem>
<listitem><para>The &defgeneric; macro supports user-defined options.
  See <xref linkend="mop-defgeneric-user-options"/>.</para></listitem>
<listitem><para>The class &method-t; is subclassable.
  See <xref linkend="mop-mo-cl-inheritance"/>.</para></listitem>
<listitem><para>Slot names like &nil; and &t; are allowed.
  See <xref linkend="slotdef-name"/>.</para></listitem>
<listitem><para>The &validate-superclass; method is more permissive by
  default and does not need to be overridden in
  some <quote>obvious</quote> cases.
  See <xref linkend="validate-superclass"/>.</para></listitem>
<listitem><para>New generic function &compute-dsd-initargs;.  It can sometimes
  be used when overriding &dsd-class; is cumbersome.</para></listitem>
<listitem><para>New generic function &compute-esd-initargs;. It can sometimes
  be used when overriding &esd-class; is cumbersome.</para></listitem>
<listitem><para>New function &compute-effective-method-as-function;. It
  can be used in overriding methods of &compute-discriminating-function;.
</para></listitem>
<listitem><para>The generic function &ensure-gf-UC; accepts a
  &declare-k; keyword.</para></listitem>
<listitem><para>The functions &funcallable-standard-instance-access; and
  &standard-instance-access; support non-updated obsolete instances and
  also support slots with allocation &class-k;.</para></listitem>
<listitem><para>The existence of the function &class-direct-subclasses;
  does not prevent otherwise unreferenced classes from being &gc;ed.
</para></listitem>
</itemizedlist>

<section id="mop-clisp-warn">
 <title>Warning <classname>CLOS:CLOS-WARNING</classname></title>

<para>When &clisp; encounters suspicious or suboptimal &clos; code,
 it issues a &warning-t; of type <classname>CLOS:CLOS-WARNING</classname>
 or a &style-warning-t; of type <classname>CLOS:CLOS-STYLE-WARNING</classname>.
 To suppress the undesired warnings (&not-e; recommended!) use
 &set-global-handler; with &muffle-warning; on the appropriate
 &warning-t; type;.
 To find where the warnings come from (recommended), set
 &break-on-signals-var; to the appropriate &warning-t; type.</para>

<section id="mop-clisp-gf-already-called-warning"><title>Warning
  <classname>CLOS:GF-ALREADY-CALLED-WARNING</classname></title>

<para>This is a hint that the order in which program files are loaded
 (order of definitions, order of macro expansions, or similar) may be wrong.
Example:<programlisting id="mop-clisp-gf-already-called-warning-code"
                        language="lisp">
(defclass ware () ((title :initarg :title :accessor title)))
(defclass book (ware) ())
(defclass compact-disk (ware) ())
(defclass dvd (ware) ())
(defgeneric add-to-inventory (object))
(defmethod add-to-inventory ((object ware)) nil)
(add-to-inventory (make-instance 'book :title "CLtL1"))
(defvar *book-counter* 0)
(defmethod add-to-inventory ((object book)) (incf *book-counter*))
(add-to-inventory (make-instance 'book :title "CLtL2"))
*book-counter*
<computeroutput>1</computeroutput>
</programlisting>
 Since &cltl1; and &cltl2; were already added to the inventory, the
 programmer might have expected that <varname>*book-counter*</varname>
 is 2.</para>

<note><title>No warning for standard generic functions</title>
 <para>A few functions, such as &print-object;, are listed in the
  &ansi-cl; and the &amop; as <quote>standard generic functions</quote>,
  to which users may add methods.
  This warning is &not-e; issued for such functions.</para></note>
&clos-style-warn;

<simplesect id="mop-clisp-gf-already-called-warning-motivation">
 <title>Motivation</title>
 <para>A generic function is defined by a contract.
  Whoever puts a method on a generic function, however, is also
  expecting a contract to be fulfilled.
  (In the example above, it is that <varname>*book-counter*</varname>
  equals the number of invocations
  of <function>add-to-inventory</function> on book instances.)
  If the generic function was already called before the
  method was installed, the method's contract was definitely broken.
  Maybe the programmer has foreseen this case (in this example:
  he could initialize <varname>*book-counter*</varname> to the number of
  instances of book that exist at this moment, rather than to &zero;),
  or maybe not. This is what the warning is about.
</para></simplesect>
</section> <!-- mop-clisp-gf-already-called-warning -->

<section id="mop-clisp-gf-replacing-method-warning"><title>Warning
  <classname>CLOS:GF-REPLACING-METHOD-WARNING</classname></title>

<para>This is a hint that different parts of the program, possibly
 developed by independent people, are colliding.
Example: in addition to the code
 <link linkend="mop-clisp-gf-already-called-warning-code">above</link>:
 <programlisting language="lisp">
(defvar *book-sales-statistics* (make-hash-table :test 'equal))
(defmethod add-to-inventory ((object book))
  (setf (gethash (title object) sale-stats) (cons 0 0)))
(add-to-inventory (make-instance 'book :title "AMOP"))
*book-counter*
<computeroutput>1</computeroutput>
*book-sales-statistics*
<computeroutput>#S(HASH-TABLE :TEST FASTHASH-EQUAL ("AMOP" . (0 . 0)))</computeroutput>
</programlisting>
The programmer who programmed the first
 <literal role="method"><function>add-to-inventory</function>@<classname>book</classname></literal>
 method expects that <varname>*book-counter*</varname> will be incremented.
 The programmer who programmed the second
 <literal role="method"><function>add-to-inventory</function>@<classname>book</classname></literal>
 method expects that <varname>*book-sales-statistics*</varname> gets
 augmented.  If the implementation gives no warning, one of the two
 programmers will waste time debugging.</para>
&clos-style-warn;

<simplesect id="mop-clisp-gf-replacing-method-warning-motivation">
 <title>Motivation</title>
<para>This warning can be warranted for the same reason as
 <link linkend="mop-clisp-gf-already-called-warning-motivation">above</link>:
 if the old method and the new method have a different contract,
 something is fishy and possibly wrong.
 Additionally, the programmers may not even have intended to replace the
 method. They may have intended cumulative effects of the two methods.
</para></simplesect>
</section> <!-- mop-clisp-gf-replacing-method-warning -->

<section id="class-obsolescence-warning"><title>Warning
  <classname>CLOS:CLASS-OBSOLESCENCE-WARNING</classname></title>

<para>This is a hint that different parts of the program define the same
&class; incompatibly, and some objects, created to the old
specification, have been obsoleted by the new one.
Example: in addition to the code
 <link linkend="mop-clisp-gf-already-called-warning-code">above</link>:
 <programlisting language="lisp">
(defclass ware ()
  ((title :initarg :title :accessor title)
   (year :initarg :year :accessor year)))
</programlisting>
Evaluating the above will obsolete all objects of type
<classname>ware</classname>s, <classname>book</classname>s etc
created so far, i.e., their components will become inaccessible.</para>
&clos-style-warn;

<simplesect id="class-obsolescence-warning-motivation">
  <title>Motivation</title>
<para>In addition to the
 <link linkend="mop-clisp-gf-already-called-warning-motivation">above</link>,
 this warning tells the programmers that they are losing some objects
 they have already created.</para>
</simplesect> <!-- class-obsolescence-warning-motivation -->
</section>    <!-- class-obsolescence-warning -->

</section> <!-- mop-clisp-warn -->
</section> <!-- mop-clisp -->

</chapter>
