MCL's Metaobject Protocol
-------------------------

Macintosh Common Lisp version 2 implements CLOS as documented in the
second edition of Common Lisp: The Language. It also contains some
informational functions that are part of the Metaobject Protocol (MOP) as
described in The Art of the Metaobject Protocol (AMOP) by Gregor Kiczales
and others (MIT Press, 1991). 


MCL 2.0b1 differences
---------------------

MCL 2.0b1 does not define the slot definition accessors. You can
define them as follows:

(defmethod class-direct-instance-slots ((class standard-class))
  (ccl::%class-local-instance-slotds class))

(defmethod class-direct-class-slots ((class standard-class))
  (ccl::%class-local-shared-slotds class))

(defmethod class-instance-slots ((class standard-class))
  (ccl::%class-instance-slotds class))

(defmethod class-class-slots ((class standard-class))
  (ccl::%class-shared-slotds class))


Metaobject classes defined in Macintosh Common Lisp
---------------------------------------------------

Table A-1 shows the class structure of the metaobject classes defined in
Macintosh Common Lisp version 2. All the metaobject classes are instances
of standard-class except generic-function and standard-generic-function,
which are instances of funcallable-standard-class. They are not documented
in Common Lisp: The Language, but some of them are documented in The Art
of the Metaobject Protocol.


Structure of metaobject classes defined in Macintosh Common Lisp version 2
--------------------------------------------------------------------------

Class                        Direct superclasses
-----                        -------------------
standard-object	             t
structure-object             t
metaobject                   standard-object
method-combination           metaobject
long-method-combination      method-combination
short-method-combination     method-combination
standard-method-combination  method-combination
method                       metaobject
standard-method              method
standard-accessor-method     standard-method
standard-writer-method       standard-accessor-method
standard-reader-method       standard-accessor-method
generic-function             metaobject ccl::funcallable-standard-object
standard-generic-function    generic-function
specializer                  metaobject
class                        specializer
ccl::compile-time-class      class
structure-class              class
built-in-class               class
ccl::std-class               class
funcallable-standard-class   std-class
standard-class               std-class

During compilation, if a class definition is encountered for a previously
unknown class, an instance of the class named ccl::compile-time-class is
added to the compilation environment. This instance is a stub only. The
Common Lisp generic function class-name returns its name and find-class
finds it if given the compile- time environment as its third argument, but
none of the other MOP functions returns any kind of useful information.
For example, class-precedence-list signals an error when called with an
instance of ccl::compile-time-class. This way of handling defclass at
compile time is very likely to change in future versions of Macintosh
Common Lisp.

The class named ccl::std-class is an implementation detail that may change
in future versions of Macintosh Common Lisp; hence its name is not
exported. It is included in the above table for completeness.


Unsupported metaobject classes
------------------------------

The following metaobject classes do not exist in Macintosh Common Lisp
version 2.0:

	eql-specializer
	forward-referenced-class
	slot-definition
	standard-slot-definition
	standard-direct-slot-definition
	standard-effective-slot-definition


Unsupported Introspective MOP functions
---------------------------------------

The following functions, which are part of the de facto introspective MOP
standard, are not supported by Macintosh Common Lisp verson 2.0:

	class-default-initargs
	class-direct-default-initargs
	generic-function-argument-precedence-order
	generic-function-declarations
	generic-function-initial-methods
	generic-function-lambda-list
	method-lambda-list
	slot-boundp-using-class
	slot-definition-class
	slot-definition-allocation
	slot-definition-initargs
	slot-definition-initform
	slot-definition-initfunction
	slot-definition-name
	slot-definition-readers
	slot-definition-type
	slot-definition-writers
	slot-exists-p-using-class
	slot-makunbound-using-class
	slot-value-using-class

MCL functions relating to the Metaobject Protocol
-------------------------------------------------

The following MOP functions are supported in Macintosh Common Lisp.


CLASS-DIRECT-SUBCLASSES 	[Generic function]
Syntax	class-direct-subclasses (class class) 
Description
  The class-direct-subclasses generic function returns a list of 
  the direct subclasses of the given class, that is, all classes that 
  mention this class in their defclass forms.
Arguments	class	A class.

Example
-------

? (defclass foo () ())
#<STANDARD-CLASS FOO>
? (defclass bratch (foo) ())
#<STANDARD-CLASS BRATCH>
? (defclass gronk (foo) ())
#<STANDARD-CLASS GRONK>
? (class-direct-subclasses (find-class 'foo))
(#<STANDARD-CLASS GRONK> #<STANDARD-CLASS BRATCH>)
? ? (class-direct-subclasses (find-class 'standard-object))
(#<STANDARD-CLASS FOO> 
 #<STANDARD-CLASS INSPECTOR::ERROR-FRAME>
 #<STANDARD-CLASS INSPECTOR::UNDO-VIEW-MIXIN>
 #<STANDARD-CLASS INSPECTOR::BOTTOM-LINE-MIXIN>
 #<STANDARD-CLASS INSPECTOR::CACHE-ENTRY>
 #<STANDARD-CLASS INSPECTOR::BASICS-FIRST-MIXIN>
 #<STANDARD-CLASS INSPECTOR::OBJECT-FIRST-MIXIN>
 #<STANDARD-CLASS INSPECTOR::UNBOUND-MARKER>
 #<STANDARD-CLASS INSPECTOR::INSPECTOR> #<STANDARD-CLASS MENUBAR>
 #<STANDARD-CLASS KEY-HANDLER-MIXIN> #<STANDARD-CLASS APPLICATION>
 #<STANDARD-CLASS CONDITION> #<STANDARD-CLASS SCRAP-HANDLER>
 #<STANDARD-CLASS CCL::LISP-WDEF-MIXIN>
 #<STANDARD-CLASS CCL::INSTANCE-INITIALIZE-MIXIN>
 #<STANDARD-CLASS FUNCALLABLE-STANDARD-OBJECT>
 #<STANDARD-CLASS METAOBJECT>)

The file grapher.lisp, in your MCL Examples folder, contains a good example of 
the use of class-direct-subclasses.


CLASS-DIRECT-SUPERCLASSES 	[Generic function]
Syntax	class-direct-superclasses (class class) 
Description
  The class-direct-superclasses generic function returns a list of the
  direct superclasses of the given class, that is, all classes that are
  specified in the classs defclass form.
Arguments	class	A class.

Example
-------

? (defclass my-io-stream (input-stream output-stream) ())
#<STANDARD-CLASS MY-IO-STREAM>
? (class-direct-superclasses *)
(#<STANDARD-CLASS INPUT-STREAM> #<STANDARD-CLASS OUTPUT-STREAM>)
class-precedence-list 	[Generic function]
Syntax	class-precedence-list (class class) 
class-precedence-list (class standard-class) 
Description	The class-precedence-list generic function returns the class 
precedence list for the given class.  This list is used by compute-
applicable-methods to determine the order of precedence of 
methods specialized on the class..i.CLASS-PRECEDENCE-LIST 
generic function;.i.classes:precedence list of methods specialized on 
class;
Arguments	class	A class.
Example
? (defclass foo () ())
#<STANDARD-CLASS FOO>
? (class-precedence-list *)
(#<STANDARD-CLASS FOO> #<STANDARD-CLASS STANDARD-OBJECT> #<BUILT-IN-
CLASS T>)
? (defclass bar () ())
#<STANDARD-CLASS BAR>
? (class-precedence-list *)
(#<STANDARD-CLASS BAR> #<STANDARD-CLASS STANDARD-OBJECT> #<BUILT-IN-
CLASS T>)
? (defclass gronk (foo bar) ())
#<STANDARD-CLASS GRONK>
? (class-precedence-list *)
(#<STANDARD-CLASS GRONK> #<STANDARD-CLASS FOO> #<STANDARD-CLASS BAR>
 #<STANDARD-CLASS STANDARD-OBJECT> #<BUILT-IN-CLASS T>)


CLASS-PROTOTYPE 	[Generic function]
Syntax	class-prototype (class  ccl::std-class) 
        class-prototype (class structure-class) 
Description
  The class-prototype generic function returns a prototype instance of the
  given class. The contents of the instance are undefined, though it has the
  same number of instance slots as an instance created with make-instance
  (or a structure creator function), and all class slots are accessible.
Arguments	class	A class.

Example
-------

In this example, y is bound only because of :allocation :class.
? (defclass foo ()
            ((x :initform 1 :accessor foo-x)
             (y :allocation :class 
                :initform 2 :accessor foo-y)))
#<STANDARD-CLASS FOO>
? (foo-y (class-prototype (find-class 'foo)))
2


CLASS-DIRECT-INSTANCE-SLOTS 	[Generic function]
Syntax	class-direct-instance-slots (class  ccl::std-class) 
Description	
  The class-direct-instance-slots generic function returns a list of slot
  definition objects describing the instance slots that were declared in the
  classs defclass forms. MCL slot definitions are represented as lists. The
  only supported accessor for a slot definition object is
  slot-definition-name.
Arguments	class	A class.

Example
-------
See the example in the definition of slot-definition-name.


CLASS-DIRECT-CLASS-SLOTS 	[Generic function]
Syntax	class-direct-class-slots (class  ccl::std-class) 
Description
  The class-direct-class-slots generic function returns a list of slot
  definition objects describing the class slots that were declared in the
  classs defclass forms. MCL slot definitions are represented as lists. The
  only supported accessor for a slot definition object is
  slot-definition-name.
Arguments	class	A class.


CLASS-INSTANCE-SLOTS 	[Generic function]
Syntax	class-instance-slots (class  ccl::std-class) 
Description
  The class-instance-slots generic function returns a list of slot
  definition objects describing all the instance slots, direct and
  inherited, that were declared in the defclass for the class. MCL slot
  definitions are represented as lists. The only supported accessor for a
  slot definition object is slot-definition-name.
Arguments	class	A class.


CLASS-CLASS-SLOTS 	[Generic function]
Syntax	class-class-slots (class  ccl::std-class) 
Description
  The class-class-slots generic function returns a list of slot definition
  objects describing all the class slots, direct and inherited, that were
  declared in the defclass for the class. MCL slot definitions are
  represented as lists. The only supported accessor for a slot definition
  object is slot-definition-name.
Arguments	class	A class.

Example
-------

? (defclass foo ()
    ((x :accessor foo-x
        :initarg :x
        :initform 1)
     (y :allocation :class
        :accessor foo-y
        :initarg :y
        :initform 2)))
#<STANDARD-CLASS FOO>
? (defclass bar (foo)
    ((m :accessor bar-m
        :initarg :m
        :initform 3)
     (n :allocation :class
        :accessor bar-n
        :initarg :n
        :initform (log 4))))
#<STANDARD-CLASS BAR>
? (class-direct-instance-slots (find-class 'bar))
((M (3) (:M)))
? (class-direct-class-slots (find-class 'bar))
((N #<Anonymous Function #xDF2EA6> (:N)))
? (class-instance-slots (find-class 'bar))
((M (3) (:M)) (X (1) (:X)))
? (class-class-slots (find-class 'bar))
((N (1.3862943611198906) (:N)) (Y (2) (:Y)))


SPECIALIZER-DIRECT-METHODS 	[Generic function]
Syntax	specializer-direct-methods (specializer  class) 
        specializer-direct-methods (specializer  list) 
Description
  The specializer-direct-methods generic function returns a list of all
  methods that specialize on the given specializer. An eql specializer is
  represented as a list of length 2 whose car is the symbol eql and whose
  cadr is an MCL object. In the default world, the
  specializer-direct-methods lists are not cached. The first time you call
  specializer-direct-methods or specializer-direct-generic-functions, it
  maps over all the generic functions, computing the direct methods lists
  for all specializers. It also enables caching of this information for
  subsequent calls to add-method and remove-method. This caching is
  preserved across calls to save-application. The function
  clear-class-direct-methods-caches clears all the cached information and
  stops add-method from keeping track of it until the next call to
  specializer-direct-methods or specializer-direct-generic-functions.
Arguments	specializer	A class or a list of the form (eql object).


SPECIALIZER-DIRECT-GENERIC-FUNCTIONS 	[Generic function]
Syntax	specializer-direct-generic-functions (specializer  class)  
        specializer-direct-generic-functions(specializer  list) 
Description
  The specializer-direct-generic-functions generic function returns a list
  of all generic functions that specialize on the given specializer. An
  eql specializer is represented as a list of length 2 whose car is the
  symbol eql and whose cadr is an MCL object. In the default world, the
  specializer-direct-generic- functions lists are not cached. The first
  time you call specializer-direct-methods or specializer-direct-
  generic-functions, it maps over all the generic functions, computing the
  direct methods lists for all specializers. It also enables caching of
  this information for subsequent calls to add- method and remove-method.
  This caching is preserved across calls to save-application. The function
  clear-class-direct- methods-caches clears all the cached information and
  stops add- method from keeping track of it until the next call to
  specializer- direct-methods or specializer-direct-generic- functions.
Arguments	specializer	A class or a list of the form (eql object).


GENERIC-FUNCTION-METHODS 	[Generic function]
Syntax	generic-function-methods (generic-function  standard-generic-function) 
Description 
  The generic-function-methods generic function returns a list of the
  methods for generic-function.
Arguments	generic-function	A generic function.

Example
-------

? (defmethod foo ((x integer)) x)
#<STANDARD-METHOD FOO (INTEGER)>
? (defmethod foo ((x fixnum)) (+ x (call-next-method)))
#<STANDARD-METHOD FOO (FIXNUM)>
? (generic-function-methods #'foo)
(#<STANDARD-METHOD FOO (FIXNUM)> #<STANDARD-METHOD FOO (INTEGER)>)


METHOD-FUNCTION 	[Generic function]
Syntax	method-function (method  standard-method) 
Description
  The method-function generic function returns the function that runs when
  method is invoked. This function takes the same number of arguments as
  the generic function. If it was generated from code containing a call to
  call-next-method, function-calling it with funcall will cause Macintosh
  Common Lisp to crash. (Otherwise it can be function-called safely.)
Arguments	method	A standard method.


METHOD-GENERIC-FUNCTION 	[Generic function]
Syntax	method-generic-function (method  standard-method) 
Description
  The method-generic-function generic function returns the generic
  function associated with method, or nil if there is none.
Arguments	method	A standard method.

Example
-------

? (setq m (defmethod foo ((x integer)) x))
#<STANDARD-METHOD FOO (INTEGER)>
? (method-generic-function m)
#<STANDARD-GENERIC-FUNCTION FOO #xD61B66>
? (remove-method (method-generic-function m) m)
#<STANDARD-GENERIC-FUNCTION FOO #xD61B66>
? (method-generic-function m)
NIL


METHOD-NAME 	[Generic function]
Syntax	method-name (method  standard-method) 
Description
  The method-name generic function returns the name of method.
Arguments	method	A standard method.

Example
-------

? (defmethod foo ((x integer)) x)
#<STANDARD-METHOD FOO (INTEGER)>
? (method-name *)
FOO


METHOD-QUALIFIERS 	[Generic function]
Syntax	method-qualifiers (method  standard-method) 
Description
  The method-qualifiers generic function returns a list of the qualifiers
  for method. (See Common Lisp: The Language, pages 839, 849.)
Arguments	method	A standard method.


METHOD-SPECIALIZERS 	[Generic function]
Syntax	method-specializers (method  standard-method) 
Description
  The method-specializers generic function returns a list of the
  specializers for method.
Arguments	method	A standard method.

Example
-------

? (defmethod bar ((x integer) (y list)) (cons x y))
#<STANDARD-METHOD BAR (INTEGER LIST)>
? (method-specializers *)
(#<BUILT-IN-CLASS INTEGER> #<BUILT-IN-CLASS LIST>)


SLOT-DEFINITION-NAME 	[Generic function]
Syntax	slot-definition-name (slot-definition  list) 
Description
  The slot-definition-name generic function returns the name of
  slot-definition. Future versions of Macintosh Common Lisp will fully
  support the slot-definition class.
Arguments	slot-definition	A slot definition object.

Example
-------

? (defclass foo () (x y))
#<STANDARD-CLASS FOO>
? (mapcar 'slot-definition-name 
     (class-direct-instance-slots *))
(X Y)


COPY-INSTANCE 	[Generic function]
Syntax	copy-instance (instance  standard-object) 
Description
  The copy-instance generic function returns a copy of the given instance.
  The default method merely copies the vector used to store the instance
  slots for the instance. Users may add methods to perform additional
  initialization for the copied method.
Arguments	instance	An instance of standard-object or one
				of its subclasses.

Example
-------

There are examples of copy-instance in the Interface Toolkit source code.


CLEAR-SPECIALIZER-DIRECT-METHODS-CACHES 	[Function]
Syntax	clear-specializer-direct-methods-caches 
Description
  The clear-specializer-direct-methods-caches function clears all the
  cached information returned by specializer- direct-methods and
  specializer-direct-generic- functions, preventing subsequent calls to
  add-method from caching this information. The next call to either of
  these functions recomputes the caches and reenables maintenance of them
  by add- method.


CLEAR-CLOS-CACHES 	[Function]
Syntax	clear-clos-caches 
Description
  The clear-clos-caches function clears CLOS caches in preparation for
  doing a save-application if the value of the :clear-clos-caches keyword
  argument to save-application is true (the default). (See Appendix B,
  Snapshots and Application Versions of Macintosh Common Lisp.) This
  function clears the effective method caches stored inside generic
  functions and the valid initialization argument caches stored inside
  classes.


CLEAR-GF-CACHES 	[Function]
Syntax	clear-gf-caches generic-function
Description
  The clear-gf-caches function clears the cached effective methods for
  generic-function. This function saves space but causes subsequent
  invocations of the generic function to be slower until the cache is
  filled again.
Arguments	generic-function     A generic function.


CLEAR-ALL-GF-CACHES 	[Function]
Syntax	clear-all-gf-caches 
Description
  The clear-all-gf-caches function calls clear-gf-caches on all generic
  functions. This function is called by clear-clos- caches.


METHOD-EXISTS-P 	[Function]
Syntax	method-exists-p generic-function &rest args
Description
  The method-exists-p function returns nil if generic-function is not a
  generic function or a symbol naming a generic function, or if (apply
  generic-function args) would cause an error because there are no
  applicable primary methods for the given arguments to the generic
  function. Otherwise, it returns one of the applicable primary methods
  for generic-function. This function is faster than compute-
  applicable-methods and does not cons.
Arguments	generic-function	A generic function or a symbol
					naming a generic function.
		args			One or more arguments to the generic
					function.


*CHECK-CALL-NEXT-METHOD-WITH-ARGS*	[Variable]
Description
  The *check-call-next-method-with-args* variable determines whether a
  runtime check is made during calls to call-next-method. When the value
  of this variable is true (the default), then the check is made to ensure
  that new arguments do not change the set of methods that are applicable
  for the generic function. When the value of this variable is nil, then
  no check is made. The checking is not completely strict. If the required
  arguments that are passed to call-next-method are eq to the original
  required arguments passed to the generic function, then the test passes.
  For effective methods that have already been cached, changes to
  *check-call-next-method-with-args* will not take effect until
  clear-all-gf-caches is invoked.


*DEFMETHOD-CONGRUENCY-OVERRIDE*	[Variable]
Description
  The *defmethod-congruency-override* variable allows you to override
  standard MCL behavior when you define global generic functions. When the
  value of this variable is nil (the default), then an error is signaled.
  When the value of this variable is true, then Macintosh Common Lisp does
  not signal an error if the function binding of the generic functions
  name is not a generic function or if a methods lambda list is not
  congruent to its generic functions lambda list. If
  *defmethod-congruency-override* is a function, then it is called with
  two arguments as described below. If an attempt is made by defmethod or
  ensure-generic- function to redefine a regular function, macro, or
  special form, the *defmethod-congruency-override* is called with two
  arguments, the function name (a symbol) and nil. If nil is returned, an
  error is signaled. Otherwise, the redefinition is performed. If
  add-method is instructed to add a method to a generic function and the
  lambda lists of the method and the generic function are not congruent,
  *defmethod-congruency-override* is called with two arguments, the
  generic function and the method. If it returns nil, an error is
  signaled. Otherwise, all methods are removed from the generic function,
  the generic functions lambda list is redefined to be congruent with the
  methods lambda list, and the method is added. If
  *defmethod-congruency-override* is not nil and not a function, it
  behaves as if it were a function that always returns non- nil. Hence,
  redefinitions are performed silently. This is very dangerous and should
  usually be done only by patch files.


MCL class hierarchy
-------------------

The file print-class-tree.lisp in the MCL Examples folder contains
functions to print the class hierarchy of an MCL class in a way that makes
the direct superclasses and the class precedence list apparent. It
includes, as a comment, a hierarchy diagram for every class in the MCL
system, sorted by class name. 