[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

intro material



This message includes more new MOP material for review.

Included are the Introduction (which will need more work later), the
overview of metaobjects, the specified class structure and constraints
on user specialization and implementation flexibility.

This material goes at the beginning of the full document and the
macroexpansion section immediately follows it.

The file arisia.xerox.com: /pcl/mop/intro.ps is a postscript version of
this material.  This message contains the TeX source.

Comments please.

----------------

\beginSection{Introduction}

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

Because these objects represent pieces of CLOS programs, and because
their behavior provides the behavior of the CLOS language itself, they
are considered meta-level objects.  In this document, the term {\bit
metaobject} is used to refer precisely to an object which represent a
CLOS class, slot definition, generic function, method or method
combination.  The protocol followed by the metaobjects to provide the
behavior of CLOS is called the {\bit CLOS Metaobject Protocol}.

\endSection%{Introduction}


\beginSection{Metaobjects}

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

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 {\bf defclass} or {\bf defmethod}.  Also included is indirect
information such as that computed from class inheritance or the full set
of methods associated with a generic function.

Much of the information associated with a metaobject is represented
using other metaobjects.  This interconnected structure of metaobjects
parallels that of the directed acyclic class graph and associated
methods and generic functions.  This section provides an overview of
this structure by presenting a partial enumeration of the kinds of
information associated with each kind of metaobject.

\beginSubsection{Classes}

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

\beginlist

\item{\bull} The name is available as a symbol.

\item{\bull} The direct subclasses, direct superclasses and class
precedence list are available as lists of class metaobjects.  

\item{\bull} The slots defined directly in the class are available as a
list of direct slot definition metaobjects.  The slots which are
accessible in instances of the class are available as a list of
effective slot definition metaobjects.

\item{\bull} The documentation is available as a string.

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

\endlist

\endSubsection%{Classes}

\beginSubsection{Slot Definitions}

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

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

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

\beginlist

\item{\bull} The name, allocation, and type are available as forms that
could appear in a {\bf defclass} form. 

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

\item{\bull} The slot filling initialization arguments are available as a
list of symbols.

\item{\bull} The documentation is available as a string.

\endlist

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

\beginlist

\item{\bull} The function specifiers of those generic functions for
which there are automatically generated reader and writer methods.  This
information is available as lists of function specifiers.  The so-called
accessors specified in the {\bf defclass} form are broken down into
their equivalent readers and writers in the direct slot definition.

\endlist

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

\beginlist

\item{\bull} Limited information about the location of the slot in
instances of the class.

\item{\bull} A flag which permits optimization of slot access even in
the presence of applicable user defined methods on the slot access
generic functions.

\endlist

\endSubsection%{Slot Definitions}

\beginSubsection{Generic Functions}

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

\beginlist

\item{\bull} The name is available as a function specifier.

\item{\bull} The methods associated with the generic function are
available as a list of method metaobjects. 

\item{\bull} The lambda list is available as a list.

\item{\bull} The method combination is available as a method combination
metaobject.

\item{\bull} The documentation is available as a string.

\item{\bull} The argument precedence order is available as a permutation
of those symbols from the lambda list which name the required arguments
of the generic function.

\item{\bull} The declarations are available as a list of declarations.

\endlist

\endSubsection%{Generic Functions}

\beginSubsection{Methods}

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

\beginlist

\item{\bull} The qualifiers are available as a list of of non-null
atoms.

\item{\bull} The lambda list is available as a list.

\item{\bull} The specializers are available as a list whose elements are
either class metaobjects, or lists of the form {\tt ({\bf eql} {\it
object\/})}.

\item{\bull} The function is available as a function.  This function can
be applied to arguments using the result of an appropriate call to the
generic function {\bf method-function-applier}.

\item{\bull} When the method is associated with a generic function, that
generic function metaobject is available.  A method can be associated
with at most one generic function at a time.

\item{\bull} The documentation is available as a string.

\endlist

\endSubsection%{Methods}

\beginSubsection{Method Combinations}

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

\beginlist

\item{\bull} The name of the method combination type is available as a
symbol.  This name may or may not be the same as the name of the class
of the method combination metaobject.

\item{\bull} The arguments to the method combination are available as a
list.

\item{\bull} The documentation is available as a string.

\endlist

\endSubsection%{Method Combinations}

\endSection%{Metaobjects}


\beginSection{Inheritance Structure of Metaobject Classes}

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

\boxfig
{\dimen0=.5pc
\tabskip \dimen0 plus .5 fil
\halign to \hsize {#\hfil&#\hfil\cr
\noalign{\vskip -9pt}
\bf  Metaobject Class&\bf Direct Superclasses\cr
\noalign{\vskip 2pt\hrule\vskip 2pt}
\bf structure-object&\bf (t)\cr
\bf standard-object&\bf (t)\cr
\bf metaobject&\bf (standard-object)\cr
\bf dependee-mixin&\bf (standard-object)\cr
\bf generic-function&\bf (metaobject function)\cr
\bf standard-generic-function&\bf (generic-function dependee-mixin)\cr
\bf method&\bf (metaobject)\cr
\bf standard-method&\bf (method)\cr
\bf standard-accessor-method&\bf (standard-method)\cr
\bf standard-reader-method&\bf (standard-accessor-method)\cr
\bf standard-writer-method&\bf (standard-accessor-method)\cr
\bf method-combination&\bf (metaobject)\cr
\bf slot-definition&\bf (metaobject)\cr
\bf direct-slot-definition&\bf (slot-definition)\cr
\bf effective-slot-definition&\bf (slot-definition)\cr
\bf standard-slot-definition&\bf (slot-definition)\cr
\bf structure-slot-definition&\bf (slot-definition)\cr
\bf standard-direct-slot-definition&\bf (standard-slot-definition direct-slot-definition)\cr
\bf standard-effective-slot-definition&\bf (standard-slot-definition effective-slot-definition)\cr
\bf structure-direct-slot-definition&\bf (structure-slot-definition direct-slot-definition)\cr
\bf structure-effective-slot-definition&\bf (structure-slot-definition effective-slot-definition)\cr
\bf class&\bf (metaobject)\cr
\bf built-in-class&\bf (class)\cr
\bf structure-class&\bf (class)\cr
\bf forward-referenced-class&\bf (class dependee-mixin)\cr
\bf standard-class&\bf (class dependee-mixin)\cr
\bf funcallable-standard-class&\bf (class dependee-mixin)\cr
\noalign{\vskip -9pt}
}}
\caption{}
\endfig

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

\newpage

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

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

The classes {\bf built-in-class}, {\bf structure-class}, {\bf
funcallable-standard-class} and {\bf forward-referenced-class} are
special purpose metaclasses described in the section ``Special
Metaclasses''.

The classes {\bf standard-object} and {\bf structure-object} capture
default behavior for instances of {\bf standard-class} and {\bf
structure-class} respectively.  The class {\bf standard-object} is the 
the default superclass for standard classes; the class {\bf
structure-object} is the default superclass for structure classes.

\beginSubSection{Implementation and User Specialization}

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

The Metaobject Protocol provides this capability without interfering
with the implementor's ability to develop high-performance
implementations.  This balance between user extensibility and
implementor freedom is mediated by placing explicit restrictions on
each.  These restrictions are presented in this section.

The following additional terminology is used to present these
restrictions:

\beginlist

\item{\bull} Class, generic function and method definitions are divided
into three categories.  Definitions included in this document are called
{\bit specified}; definitions defined by an implementation but not
mentioned in this document are called {\bit implementation-specific}; and
definitions which are part of a portable program are called {\bit
portable}.

\item{\bull} A class $I$ is {\bit interposed} between two other classes
$C\sub{1}$ and $C\sub{2}$ if and only if there is some path, following
direct superclasses, from the class $C\sub{1}$ to the class $C\sub{2}$
which includes $I$.

\item{\bull} A method is {\bit specialized to} a class if and only if that
class is in the list of specializers associated with the method; and the
method is in the list of methods associated with some generic function.

\item{\bull} In a given implementation, a specified method is {\bit
promoted} to an implementation-specific class if and only if one or more
of the specializers of the method is an implementation-specific
superclass of the class listed in this specification.

\item{\bull} For a given set of arguments, a method $M\sub{2}$ {\bit
shadows} a method $M\sub{1}$ if and only if $M\sub{1}$ and $M\sub{2}$
are both associated with the same generic function; and either
$M\sub{1}$ and $M\sub{2}$ are both primary methods or $M\sub{1}$ and
$M\sub{2}$ are both {\bf :around} methods or $M\sub{2}$ is an {\bf
:around} method and $M\sub{1}$ is a primary method; and when $M\sub{2}$
is invoked, {\bf call-next-method} is called from within its body.

\item{\bull} For a given set of arguments, a method $M\sub{2}$ {\bit
overrides} a method $M\sub{1}$ if and only if $M\sub{1}$ and $M\sub{2}$
are both associated with the same generic function; and either
$M\sub{1}$ and $M\sub{2}$ are both primary methods or $M\sub{1}$ and
$M\sub{2}$ are both {\bf :around} methods or $M\sub{2}$ is an {\bf
:around} method and $M\sub{1}$ is a primary method; and when $M\sub{2}$
is invoked, {\bf call-next-method} is not called from within its body.

\endlist

\beginsubsubsection{Restrictions on Implementations}

Implementations are allowed to modify the structure of specified classes
and methods.  Typically, this will mean one or more of:  the
interposition of implementation-specific classes; the promotion of
specified methods; and the consolidation of two or more specified
methods into a single method specialized to interposed classes.

But, this description permits any implementation modifications provided
provided that for any portable class $C\sub{\hbox{p}}$ that is a
subclass of one or more specified classes $C\sub{0} \ldots C\sub{i}$,
the following are true:

\beginlist

\item{\bull} In the class precedence of $C\sub{\hbox{p}}$, the
classes $C\sub{0} \ldots C\sub{i}$ appear in the same order as they
would have had no implementation-specific modifications been made.

\item{\bull} The method applicability of any specified generic function
is the same in terms of behavior as it would had no
implementation-specific changes been made.  This includes specified
generic functions which have had portable methods added.  In this
context, the expression ``the same in terms of behavior'' means that
methods with the same behavior as those specified.

\item{\bull} Implementations are always free to define
implementation-specific {\bf :before} and {\bf :after} methods on
specified generic functions.  Implementations are also free to define
implementation-specific {\bf :around} methods with shadowing behavior.

\item{\bull} No portable class $C\sub{\hbox{p}}$ inherits from a
specified class any slot with a name accessible in the {\bf
common-lisp-user} package.

\endlist

\beginsubsubsection{Restrictions on Portable Programs}

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

\beginlist

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

\item{\bull} Specified methods can be shadowed unless the description
of the method explicitly prohibits this.  Any restrictions on the value
the shadowing method must return are explicitly mentioned in the
description of the generic function.

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

An example of this is the specified methods on the generic functions
{\bf add-dependent}, {\bf remove-dependent} and {\bf 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.

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

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

\endlist

\endsubsubsection%{Restrictions on Portable Programs}

\endSubSection%{Implementation and User Specialization}

\endSection%{Inheritance Structure of Metaobject Classes}