1
Fork 0
mirror of https://git.savannah.gnu.org/git/guile.git synced 2025-05-20 11:40:18 +02:00

Work on GOOPS MOP documentation

* doc/ref/goops.texi (The Metaobject Protocol): Simplify intro text.
  Minor edits and simplifications throughout this section.
  (Metaobjects and the Metaobject Protocol): Insert "default".
  (Metaclasses): Renamed from `Terminology', and deleted the material
  on CPL and accessors, which just duplicated what has already been
  covered earlier in the chapter.  Remove statements that confuse
  whether "metaclass of" means "class of class of" or "class of
  (something that is itself a class)".  (I think it's actually the
  latter.)
  (Class Definition Protocol): Renamed from `Class Definition
  Internals'.
This commit is contained in:
Neil Jerram 2011-02-17 21:36:10 +00:00
parent 8fa6525e82
commit a46f77f95c

View file

@ -1777,21 +1777,19 @@ So let's plunge in. GOOPS is based on a ``metaobject protocol'' (aka
System), tiny-clos (a small Scheme implementation of a subset of CLOS System), tiny-clos (a small Scheme implementation of a subset of CLOS
functionality) and STKlos. functionality) and STKlos.
GOOPS can be used by application authors at a basic level without any The MOP underlies many possible GOOPS customizations --- such as
need to understand what the MOP is and how it works. On the other hand, defining an @code{initialize} method to customize the initialization of
the MOP underlies even very simple customizations --- such as defining instances of an application-defined class --- and an understanding of
an @code{initialize} method to customize the initialization of instances the MOP makes it much easier to explain such customizations in a precise
of an application-defined class --- and an understanding of the MOP way. And at a deeper level, understanding the MOP is a key part of
makes it much easier to explain such customizations in a precise way. understanding GOOPS, and of taking full advantage of GOOPS' power, by
And in the long run, understanding the MOP is the key both to customizing the behaviour of GOOPS itself.
understanding GOOPS at a deeper level and to taking full advantage of
GOOPS' power, by customizing the behaviour of GOOPS itself.
@menu @menu
* Metaobjects and the Metaobject Protocol:: * Metaobjects and the Metaobject Protocol::
* Terminology:: * Metaclasses::
* MOP Specification:: * MOP Specification::
* Class Definition Internals:: * Class Definition Protocol::
* Customizing Class Definition:: * Customizing Class Definition::
* Customizing Instance Creation:: * Customizing Instance Creation::
* Class Redefinition:: * Class Redefinition::
@ -1828,7 +1826,7 @@ as regards accessibility and protection from garbage collection.
Instances are of course objects in the usual sense, and there is no Instances are of course objects in the usual sense, and there is no
benefit from thinking of them as metaobjects.) benefit from thinking of them as metaobjects.)
The ``metaobject protocol'' (aka ``MOP'') is the specification of the The ``metaobject protocol'' (or ``MOP'') is the specification of the
generic functions which determine the behaviour of these metaobjects and generic functions which determine the behaviour of these metaobjects and
the circumstances in which these generic functions are invoked. the circumstances in which these generic functions are invoked.
@ -1854,7 +1852,7 @@ superclasses, slot definitions and class options that were specified in
the @code{define-class} form. the @code{define-class} form.
@item @item
@code{make} allocates memory for the new instance, and then invokes the @code{make} allocates memory for the new instance, and invokes the
@code{initialize} generic function to initialize the new instance's @code{initialize} generic function to initialize the new instance's
slots. slots.
@ -1865,8 +1863,8 @@ performs the slot calculation.
@end itemize @end itemize
In other words, rather than being hardcoded in @code{define-class}, the In other words, rather than being hardcoded in @code{define-class}, the
behaviour of class definition is encapsulated by generic function default behaviour of class definition is encapsulated by generic
methods that are specialized for the class @code{<class>}. function methods that are specialized for the class @code{<class>}.
It is possible to create a new class that inherits from @code{<class>}, It is possible to create a new class that inherits from @code{<class>},
which is called a ``metaclass'', and to write a new @code{initialize} which is called a ``metaclass'', and to write a new @code{initialize}
@ -1897,19 +1895,8 @@ Each following section covers a particular area of GOOPS functionality,
and describes the generic functions that are relevant for customization and describes the generic functions that are relevant for customization
of that area. of that area.
@node Terminology @node Metaclasses
@subsection Terminology @subsection Metaclasses
It is assumed that the reader is already familiar with standard object
orientation concepts such as classes, objects/instances,
inheritance/subclassing, generic functions and methods, encapsulation
and polymorphism.
This section explains some of the less well known concepts and
terminology that GOOPS uses, which are assumed by the following sections
of the reference manual.
@subsubheading Metaclass
A @dfn{metaclass} is the class of an object which represents a GOOPS A @dfn{metaclass} is the class of an object which represents a GOOPS
class. Put more succinctly, a metaclass is a class's class. class. Put more succinctly, a metaclass is a class's class.
@ -1925,30 +1912,29 @@ at what happens when a new class is created using @code{define-class}:
(define-class <my-class> (<object>) . slots) (define-class <my-class> (<object>) . slots)
@end example @end example
GOOPS actually expands the @code{define-class} form to something like @noindent
this Guile expands this to something like:
@example @example
(define <my-class> (class (<object>) . slots)) (define <my-class> (class (<object>) . slots))
@end example @end example
and thence to @noindent
which in turn expands to:
@example @example
(define <my-class> (define <my-class>
(make <class> #:supers (list <object>) #:slots slots)) (make <class> #:supers (list <object>) #:slots slots))
@end example @end example
In other words, the value of @code{<my-class>} is in fact an instance of As this expansion makes clear, the resulting value of @code{<my-class>}
the class @code{<class>} with slot values specifying the superclasses is an instance of the class @code{<class>} with slot values specifying
and slot definitions for the class @code{<my-class>}. (@code{#:supers} the superclasses and slot definitions for the class @code{<my-class>}.
and @code{#:slots} are initialization keywords for the @code{dsupers} (@code{#:supers} and @code{#:slots} are initialization keywords for the
and @code{dslots} slots of the @code{<class>} class.) @code{dsupers} and @code{dslots} slots of the @code{<class>} class.)
In order to take advantage of the full power of the GOOPS metaobject Now suppose that you want to define a new class with a metaclass other
protocol (@pxref{MOP Specification}), it is sometimes desirable to than the default @code{<class>}. This is done by writing:
create a new class with a metaclass other than the default
@code{<class>}. This is done by writing:
@example @example
(define-class <my-class2> (<object>) (define-class <my-class2> (<object>)
@ -1956,7 +1942,8 @@ create a new class with a metaclass other than the default
#:metaclass <my-metaclass>) #:metaclass <my-metaclass>)
@end example @end example
GOOPS expands this to something like: @noindent
and Guile expands @emph{this} to something like:
@example @example
(define <my-class2> (define <my-class2>
@ -1992,92 +1979,13 @@ relationships between @code{my-object}, @code{<my-class2>},
@item @item
The class of @code{my-object} is @code{<my-class2>}. The class of @code{my-object} is @code{<my-class2>}.
@item
The metaclass of @code{my-object} is @code{<my-metaclass>}.
@item @item
The class of @code{<my-class2>} is @code{<my-metaclass>}. The class of @code{<my-class2>} is @code{<my-metaclass>}.
@item
The metaclass of @code{<my-class2>} is @code{<class>}.
@item @item
The class of @code{<my-metaclass>} is @code{<class>}. The class of @code{<my-metaclass>} is @code{<class>}.
@item
The metaclass of @code{<my-metaclass>} is @code{<class>}.
@item
@code{<my-class2>} is not a metaclass, since it is does not inherit from
@code{<class>}.
@item
@code{<my-metaclass>} is a metaclass, since it inherits from
@code{<class>}.
@end itemize @end itemize
@subsubheading Class Precedence List
The @dfn{class precedence list} of a class is the list of all direct and
indirect superclasses of that class, including the class itself.
In the absence of multiple inheritance, the class precedence list is
ordered straightforwardly, beginning with the class itself and ending
with @code{<top>}.
For example, given this inheritance hierarchy:
@example
(define-class <invertebrate> (<object>) @dots{})
(define-class <echinoderm> (<invertebrate>) @dots{})
(define-class <starfish> (<echinoderm>) @dots{})
@end example
the class precedence list of <starfish> would be
@example
(<starfish> <echinoderm> <invertebrate> <object> <top>)
@end example
With multiple inheritance, the algorithm is a little more complicated.
A full description is provided by the GOOPS Tutorial: see @ref{Class
Precedence List}.
``Class precedence list'' is often abbreviated, in documentation and
Scheme variable names, to @dfn{cpl}.
@subsubheading Accessor
An @dfn{accessor} is a generic function with both reference and setter
methods.
@example
(define-accessor perimeter)
@end example
Reference methods for an accessor are defined in the same way as generic
function methods.
@example
(define-method (perimeter (s <square>))
(* 4 (side-length s)))
@end example
Setter methods for an accessor are defined by specifying ``(setter
<accessor-name>)'' as the first parameter of the @code{define-method}
call.
@example
(define-method ((setter perimeter) (s <square>) (n <number>))
(set! (side-length s) (/ n 4)))
@end example
Once an appropriate setter method has been defined in this way, it can
be invoked using the generalized @code{set!} syntax, as in:
@example
(set! (perimeter s1) 18.3)
@end example
@node MOP Specification @node MOP Specification
@subsection MOP Specification @subsection MOP Specification
@ -2087,22 +1995,17 @@ customizable generic function invocations that can be made by the standard
GOOPS syntax, procedures and methods, and to explain the protocol for GOOPS syntax, procedures and methods, and to explain the protocol for
customizing such invocations. customizing such invocations.
A generic function invocation is customizable if the types of the arguments A generic function invocation is customizable if the types of the
to which it is applied are not all determined by the lexical context in arguments to which it is applied are not completely determined by the
which the invocation appears. For example, lexical context in which the invocation appears. For example, the
@code{(initialize @var{instance} @var{initargs})} invocation in the
default @code{make-instance} method is customizable, because the type of
the @code{@var{instance}} argument is determined by the class that was
passed to @code{make-instance}.
@itemize @bullet (Whereas --- to give a counter-example --- the @code{(make <generic>
@item #:name ',name)} invocation in @code{define-generic} is not customizable,
the @code{(initialize @var{instance} @var{initargs})} invocation in the because all of its arguments have lexically determined types.)
default @code{make-instance} method is customizable, because the type of the
@code{@var{instance}} argument is determined by the class that was passed to
@code{make-instance}.
@item
the @code{(make <generic> #:name ',name)} invocation in @code{define-generic}
is not customizable, because all of its arguments have lexically determined
types.
@end itemize
When using this rule to decide whether a given generic function invocation When using this rule to decide whether a given generic function invocation
is customizable, we ignore arguments that are expected to be handled in is customizable, we ignore arguments that are expected to be handled in
@ -2123,8 +2026,8 @@ effects
what the caller expects to get as the applied method's return value. what the caller expects to get as the applied method's return value.
@end itemize @end itemize
@node Class Definition Internals @node Class Definition Protocol
@subsection Class Definition Internals @subsection Class Definition Protocol
@code{define-class} (syntax) @code{define-class} (syntax)
@ -2267,7 +2170,7 @@ defines any accessors that are implied by the @var{slot-definition}s
@item @item
uses @code{class} to create the new class (@pxref{Class Definition uses @code{class} to create the new class (@pxref{Class Definition
Internals,, class}) Protocol,, class})
@item @item
checks for a previous class definition for @var{name} and, if found, checks for a previous class definition for @var{name} and, if found,
@ -2318,7 +2221,7 @@ class precedence list
defaults the @code{#:environment}, @code{#:name} and @code{#:metaclass} defaults the @code{#:environment}, @code{#:name} and @code{#:metaclass}
options, if they are not specified by @var{options}, to the current options, if they are not specified by @var{options}, to the current
top-level environment, the unbound value, and @code{(ensure-metaclass top-level environment, the unbound value, and @code{(ensure-metaclass
@var{supers})} respectively (@pxref{Class Definition Internals,, @var{supers})} respectively (@pxref{Class Definition Protocol,,
ensure-metaclass}) ensure-metaclass})
@item @item
@ -2357,7 +2260,7 @@ The @code{env} parameter is ignored.
@deffn procedure ensure-metaclass-with-supers meta-supers @deffn procedure ensure-metaclass-with-supers meta-supers
@code{ensure-metaclass-with-supers} is an internal procedure used by @code{ensure-metaclass-with-supers} is an internal procedure used by
@code{ensure-metaclass} (@pxref{Class Definition Internals,, @code{ensure-metaclass} (@pxref{Class Definition Protocol,,
ensure-metaclass}). It returns a metaclass that is the union by ensure-metaclass}). It returns a metaclass that is the union by
inheritance of the metaclasses in @var{meta-supers}. inheritance of the metaclasses in @var{meta-supers}.
@end deffn @end deffn
@ -2886,11 +2789,11 @@ accessor, passing the setter generic function as the value of the
The @code{#:metaclass} class option specifies the metaclass of the class The @code{#:metaclass} class option specifies the metaclass of the class
being defined. @var{metaclass} must be a class that inherits from being defined. @var{metaclass} must be a class that inherits from
@code{<class>}. For the use of metaclasses, see @ref{Metaobjects and @code{<class>}. For the use of metaclasses, see @ref{Metaobjects and
the Metaobject Protocol} and @ref{Terminology}. the Metaobject Protocol} and @ref{Metaclasses}.
If the @code{#:metaclass} option is absent, GOOPS reuses or constructs a If the @code{#:metaclass} option is absent, GOOPS reuses or constructs a
metaclass for the new class by calling @code{ensure-metaclass} metaclass for the new class by calling @code{ensure-metaclass}
(@pxref{Class Definition Internals,, ensure-metaclass}). (@pxref{Class Definition Protocol,, ensure-metaclass}).
@end deffn @end deffn
@deffn {class option} #:name name @deffn {class option} #:name name