* GOOPS Error Handling::
* GOOPS Object Miscellany::
* The Metaobject Protocol::
-* Class Options::
* Redefining a Class::
* Changing the Class of an Instance::
@end menu
oriented systems. Each @var{slot-description} gives the name of a slot
and optionally some ``properties'' of this slot; for example its initial
value, the name of a function which will access its value, and so on.
-Slot descriptions and inheritance are discussed more below. For class
-options, see @ref{Class Options}.
+Class options, slot descriptions and inheritance are discussed more
+below.
@cindex slot
@deffn syntax define-class name (super @dots{}) slot-definition @dots{} . options
superclass of @code{<real>}, and @code{<real>} is the superclass of
@code{<integer>}.}
-The possible slot and class options are described in the following
-sections.
+Slot options are described in the next section. The possible class
+options are as follows.
+
+@deffn {class option} #:metaclass metaclass
+The @code{#:metaclass} class option specifies the metaclass of the class
+being defined. @var{metaclass} must be a class that inherits from
+@code{<class>}. For the use of metaclasses, see @ref{Metaobjects and
+the Metaobject Protocol} and @ref{Metaclasses}.
+
+If the @code{#:metaclass} option is absent, GOOPS reuses or constructs a
+metaclass for the new class by calling @code{ensure-metaclass}
+(@pxref{Class Definition Protocol,, ensure-metaclass}).
+@end deffn
+
+@deffn {class option} #:name name
+The @code{#:name} class option specifies the new class's name. This
+name is used to identify the class whenever related objects - the class
+itself, its instances and its subclasses - are printed.
+
+If the @code{#:name} option is absent, GOOPS uses the first argument to
+@code{define-class} as the class name.
+@end deffn
@node Instance Creation
In this class definition, the magnitude @code{m} and angle @code{a}
slots are virtual, and are calculated, when referenced, from the normal
-(i.e. @code{#:allocation #:instance}) slots @code{r} and @code{i}, by
+(i.e.@: @code{#:allocation #:instance}) slots @code{r} and @code{i}, by
calling the function defined in the relevant @code{#:slot-ref} option.
Correspondingly, writing @code{m} or @code{a} leads to calling the
function defined in the @code{#:slot-set!} option. Thus the
In addition to the cases mentioned, you can of course define
@code{write} and @code{display} methods for your own classes, to
-customize how they are printed.
+customize how instances of those classes are printed.
@node The Metaobject Protocol
System), tiny-clos (a small Scheme implementation of a subset of CLOS
functionality) and STKlos.
-GOOPS can be used by application authors at a basic level without any
-need to understand what the MOP is and how it works. On the other hand,
-the MOP underlies even very simple customizations --- such as defining
-an @code{initialize} method to customize the initialization of instances
-of an application-defined class --- and an understanding of the MOP
-makes it much easier to explain such customizations in a precise way.
-And in the long run, understanding the MOP is the key both to
-understanding GOOPS at a deeper level and to taking full advantage of
-GOOPS' power, by customizing the behaviour of GOOPS itself.
+The MOP underlies many possible GOOPS customizations --- such as
+defining an @code{initialize} method to customize the initialization of
+instances of an application-defined class --- and an understanding of
+the MOP makes it much easier to explain such customizations in a precise
+way. And at a deeper level, understanding the MOP is a key part of
+understanding GOOPS, and of taking full advantage of GOOPS' power, by
+customizing the behaviour of GOOPS itself.
@menu
* Metaobjects and the Metaobject Protocol::
-* Terminology::
+* Metaclasses::
* MOP Specification::
-* Class Definition Internals::
+* Instance Creation Protocol::
+* Class Definition Protocol::
* Customizing Class Definition::
-* Customizing Instance Creation::
-* Class Redefinition::
* Method Definition::
* Method Definition Internals::
* Generic Function Internals::
Instances are of course objects in the usual sense, and there is no
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
the circumstances in which these generic functions are invoked.
the @code{define-class} form.
@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
slots.
@end itemize
In other words, rather than being hardcoded in @code{define-class}, the
-behaviour of class definition is encapsulated by generic function
-methods that are specialized for the class @code{<class>}.
+default behaviour of class definition is encapsulated by generic
+function methods that are specialized for the class @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}
and describes the generic functions that are relevant for customization
of that area.
-@node Terminology
-@subsection Terminology
-
-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
+@node Metaclasses
+@subsection Metaclasses
A @dfn{metaclass} is the class of an object which represents a GOOPS
class. Put more succinctly, a metaclass is a class's class.
(define-class <my-class> (<object>) . slots)
@end example
-GOOPS actually expands the @code{define-class} form to something like
-this
+@noindent
+Guile expands this to something like:
@example
(define <my-class> (class (<object>) . slots))
@end example
-and thence to
+@noindent
+which in turn expands to:
@example
(define <my-class>
(make <class> #:supers (list <object>) #:slots slots))
@end example
-In other words, the value of @code{<my-class>} is in fact an instance of
-the class @code{<class>} with slot values specifying the superclasses
-and slot definitions for the class @code{<my-class>}. (@code{#:supers}
-and @code{#:slots} are initialization keywords for the @code{dsupers}
-and @code{dslots} slots of the @code{<class>} class.)
+As this expansion makes clear, the resulting value of @code{<my-class>}
+is an instance of the class @code{<class>} with slot values specifying
+the superclasses and slot definitions for the class @code{<my-class>}.
+(@code{#:supers} and @code{#:slots} are initialization keywords for the
+@code{dsupers} and @code{dslots} slots of the @code{<class>} class.)
-In order to take advantage of the full power of the GOOPS metaobject
-protocol (@pxref{MOP Specification}), it is sometimes desirable to
-create a new class with a metaclass other than the default
-@code{<class>}. This is done by writing:
+Now suppose that you want to define a new class with a metaclass other
+than the default @code{<class>}. This is done by writing:
@example
(define-class <my-class2> (<object>)
#:metaclass <my-metaclass>)
@end example
-GOOPS expands this to something like:
+@noindent
+and Guile expands @emph{this} to something like:
@example
(define <my-class2>
@item
The class of @code{my-object} is @code{<my-class2>}.
-@item
-The metaclass of @code{my-object} is @code{<my-metaclass>}.
-
@item
The class of @code{<my-class2>} is @code{<my-metaclass>}.
-@item
-The metaclass of @code{<my-class2>} is @code{<class>}.
-
@item
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
-@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
@subsection MOP Specification
GOOPS syntax, procedures and methods, and to explain the protocol for
customizing such invocations.
-A generic function invocation is customizable if the types of the arguments
-to which it is applied are not all determined by the lexical context in
-which the invocation appears. For example,
+A generic function invocation is customizable if the types of the
+arguments to which it is applied are not completely determined by the
+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
-@item
-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}.
-
-@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
+(Whereas --- to give a counter-example --- the @code{(make <generic>
+#:name ',name)} invocation in @code{define-generic} is not customizable,
+because all of its arguments have lexically determined types.)
When using this rule to decide whether a given generic function invocation
is customizable, we ignore arguments that are expected to be handled in
what the caller expects to get as the applied method's return value.
@end itemize
-@node Class Definition Internals
-@subsection Class Definition Internals
-@code{define-class} (syntax)
+@node Instance Creation Protocol
+@subsection Instance Creation Protocol
+
+@code{make <class> . @var{initargs}} (method)
@itemize @bullet
@item
-@code{class} (syntax)
+@code{allocate-instance @var{class} @var{initargs}} (generic)
+
+The applied @code{allocate-instance} method should allocate storage for
+a new instance of class @var{class} and return the uninitialized instance.
-@itemize @bullet
@item
-@code{make-class} (procedure)
+@code{initialize @var{instance} @var{initargs}} (generic)
+
+@var{instance} is the uninitialized instance returned by
+@code{allocate-instance}. The applied method should initialize the new
+instance in whatever sense is appropriate for its class. The method's
+return value is ignored.
+@end itemize
+
+@code{make} itself is a generic function. Hence the @code{make}
+invocation itself can be customized in the case where the new instance's
+metaclass is more specialized than the default @code{<class>}, by
+defining a @code{make} method that is specialized to that metaclass.
+
+Normally, however, the method for classes with metaclass @code{<class>}
+will be applied. This method calls two generic functions:
@itemize @bullet
@item
-@code{make @var{metaclass} @dots{}} (generic)
+(allocate-instance @var{class} . @var{initargs})
-@var{metaclass} is the metaclass of the class being defined, either
-taken from the @code{#:metaclass} class option or computed by
-@code{ensure-metaclass}. The applied method must create and return the
-fully initialized class metaobject for the new class definition.
+@item
+(initialize @var{instance} . @var{initargs})
@end itemize
-@end itemize
+@code{allocate-instance} allocates storage for and returns the new
+instance, uninitialized. You might customize @code{allocate-instance},
+for example, if you wanted to provide a GOOPS wrapper around some other
+object programming system.
+
+To do this, you would create a specialized metaclass, which would act as
+the metaclass for all classes and instances from the other system. Then
+define an @code{allocate-instance} method, specialized to that
+metaclass, which calls a Guile primitive C function (or FFI code), which
+in turn allocates the new instance using the interface of the other
+object system.
+
+In this case, for a complete system, you would also need to customize a
+number of other generic functions like @code{make} and
+@code{initialize}, so that GOOPS knows how to make classes from the
+other system, access instance slots, and so on.
+
+@code{initialize} initializes the instance that is returned by
+@code{allocate-instance}. The standard GOOPS methods perform
+initializations appropriate to the instance class.
+
+@itemize @bullet
+@item
+At the least specialized level, the method for instances of type
+@code{<object>} performs internal GOOPS instance initialization, and
+initializes the instance's slots according to the slot definitions and
+any slot initialization keywords that appear in @var{initargs}.
@item
-@code{class-redefinition @var{old-class} @var{new-class}} (generic)
+The method for instances of type @code{<class>} calls
+@code{(next-method)}, then performs the class initializations described
+in @ref{Class Definition Protocol}.
-@code{define-class} calls @code{class-redefinition} if the variable
-specified by its first argument already held a GOOPS class definition.
-@var{old-class} and @var{new-class} are the old and new class metaobjects.
-The applied method should perform whatever is necessary to handle the
-redefinition, and should return the class metaobject that is to be bound
-to @code{define-class}'s variable. The default class redefinition
-protocol is described in @ref{Class Redefinition}.
+@item
+and so on for generic functions, methods, operator classes @dots{}
@end itemize
-The @code{(make @var{metaclass} @dots{})} invocation above will create
-an class metaobject with metaclass @var{metaclass}. By default, this
-metaobject will be initialized by the @code{initialize} method that is
-specialized for instances of type @code{<class>}.
+Similarly, you can customize the initialization of instances of any
+application-defined class by defining an @code{initialize} method
+specialized to that class.
-@code{initialize <class> @var{initargs}} (method)
+Imagine a class whose instances' slots need to be initialized at
+instance creation time by querying a database. Although it might be
+possible to achieve this a combination of @code{#:init-thunk} keywords
+and closures in the slot definitions, it may be neater to write an
+@code{initialize} method for the class that queries the database once
+and initializes all the dependent slot values according to the results.
+
+
+@node Class Definition Protocol
+@subsection Class Definition Protocol
+
+Here is a summary diagram of the syntax, procedures and generic
+functions that may be involved in class definition.
+
+@noindent
+@code{define-class} (syntax)
@itemize @bullet
@item
-@code{compute-cpl @var{class}} (generic)
+@code{class} (syntax)
-The applied method should compute and return the class precedence list
-for @var{class} as a list of class metaobjects. When @code{compute-cpl}
-is called, the following @var{class} metaobject slots have all been
-initialized: @code{name}, @code{direct-supers}, @code{direct-slots},
-@code{direct-subclasses} (empty), @code{direct-methods}. The value
-returned by @code{compute-cpl} will be stored in the @code{cpl} slot.
+@itemize @bullet
+@item
+@code{make-class} (procedure)
+@itemize @bullet
@item
-@code{compute-slots @var{class}} (generic)
+@code{ensure-metaclass} (procedure)
-The applied method should compute and return the slots (union of direct
-and inherited) for @var{class} as a list of slot definitions. When
-@code{compute-slots} is called, all the @var{class} metaobject slots
-mentioned for @code{compute-cpl} have been initialized, plus the
-following: @code{cpl}, @code{redefined} (@code{#f}), @code{environment}.
-The value returned by @code{compute-slots} will be stored in the
-@code{slots} slot.
+@item
+@code{make @var{metaclass} @dots{}} (generic)
+@itemize @bullet
@item
-@code{compute-get-n-set @var{class} @var{slot-def}} (generic)
+@code{allocate-instance} (generic)
-@code{initialize} calls @code{compute-get-n-set} for each slot computed
-by @code{compute-slots}. The applied method should compute and return a
-pair of closures that, respectively, get and set the value of the specified
-slot. The get closure should have arity 1 and expect a single argument
-that is the instance whose slot value is to be retrieved. The set closure
-should have arity 2 and expect two arguments, where the first argument is
-the instance whose slot value is to be set and the second argument is the
-new value for that slot. The closures should be returned in a two element
-list: @code{(list @var{get} @var{set})}.
+@item
+@code{initialize} (generic)
-The closures returned by @code{compute-get-n-set} are stored as part of
-the value of the @var{class} metaobject's @code{getters-n-setters} slot.
-Specifically, the value of this slot is a list with the same number of
-elements as there are slots in the class, and each element looks either like
+@itemize @bullet
+@item
+@code{compute-cpl} (generic)
-@example
-@code{(@var{slot-name-symbol} @var{init-function} . @var{index})}
-@end example
+@itemize @bullet
+@item
+@code{compute-std-cpl} (procedure)
+@end itemize
-or like
+@item
+@code{compute-slots} (generic)
-@example
-@code{(@var{slot-name-symbol} @var{init-function} @var{get} @var{set})}
-@end example
+@item
+@code{compute-get-n-set} (generic)
-Where the get and set closures are replaced by @var{index}, the slot is
-an instance slot and @var{index} is the slot's index in the underlying
-structure: GOOPS knows how to get and set the value of such slots and so
-does not need specially constructed get and set closures. Otherwise,
-@var{get} and @var{set} are the closures returned by @code{compute-get-n-set}.
+@item
+@code{compute-getter-method} (generic)
-The structure of the @code{getters-n-setters} slot value is important when
-understanding the next customizable generic functions that @code{initialize}
-calls@dots{}
+@item
+@code{compute-setter-method} (generic)
+@end itemize
+@end itemize
+@end itemize
+@end itemize
@item
-@code{compute-getter-method @var{class} @var{gns}} (generic)
+@code{class-redefinition} (generic)
-@code{initialize} calls @code{compute-getter-method} for each of the class's
-slots (as determined by @code{compute-slots}) that includes a
-@code{#:getter} or @code{#:accessor} slot option. @var{gns} is the
-element of the @var{class} metaobject's @code{getters-n-setters} slot that
-specifies how the slot in question is referenced and set, as described
-above under @code{compute-get-n-set}. The applied method should create
-and return a method that is specialized for instances of type @var{class}
-and uses the get closure to retrieve the slot's value. [ *fixme Need
-to insert something here about checking that the value is not unbound. ]
-@code{initialize} uses @code{add-method!} to add the returned method to
-the generic function named by the slot definition's @code{#:getter} or
-@code{#:accessor} option.
+@itemize @bullet
+@item
+@code{remove-class-accessors} (generic)
@item
-@code{compute-setter-method @var{class} @var{gns}} (generic)
+@code{update-direct-method!} (generic)
-@code{compute-setter-method} is invoked with the same arguments as
-@code{compute-getter-method}, for each of the class's slots that includes
-a @code{#:setter} or @code{#:accessor} slot option. The applied method
-should create and return a method that is specialized for instances of
-type @var{class} and uses the set closure to set the slot's value.
-@code{initialize} then uses @code{add-method!} to add the returned method
-to the generic function named by the slot definition's @code{#:setter}
-or @code{#:accessor} option.
+@item
+@code{update-direct-subclass!} (generic)
+@end itemize
@end itemize
-@code{define-class} expands to an expression which
+Wherever a step above is marked as ``generic'', it can be customized,
+and the detail shown below it is only ``correct'' insofar as it
+describes what the default method of that generic function does. For
+example, if you write an @code{initialize} method, for some metaclass,
+that does not call @code{next-method} and does not call
+@code{compute-cpl}, then @code{compute-cpl} will not be called when a
+class is defined with that metaclass.
+
+A @code{(define-class ...)} form (@pxref{Class Definition}) expands to
+an expression which
@itemize @bullet
@item
defines any accessors that are implied by the @var{slot-definition}s
@item
-uses @code{class} to create the new class (@pxref{Class Definition
-Internals,, class})
+uses @code{class} to create the new class
@item
checks for a previous class definition for @var{name} and, if found,
defaults the @code{#:environment}, @code{#:name} and @code{#:metaclass}
options, if they are not specified by @var{options}, to the current
top-level environment, the unbound value, and @code{(ensure-metaclass
-@var{supers})} respectively (@pxref{Class Definition Internals,,
-ensure-metaclass})
+@var{supers})} respectively
@item
checks for duplicate classes in @var{supers} and duplicate slot names in
The @code{env} parameter is ignored.
@end deffn
-@deffn procedure ensure-metaclass-with-supers meta-supers
-@code{ensure-metaclass-with-supers} is an internal procedure used by
-@code{ensure-metaclass} (@pxref{Class Definition Internals,,
-ensure-metaclass}). It returns a metaclass that is the union by
-inheritance of the metaclasses in @var{meta-supers}.
+@deffn generic make metaclass @dots{}
+@var{metaclass} is the metaclass of the class being defined, either
+taken from the @code{#:metaclass} class option or computed by
+@code{ensure-metaclass}. The applied method must create and return the
+fully initialized class metaobject for the new class definition.
@end deffn
-The internals of @code{make}, which is ultimately used to create the new
-class object, are described in @ref{Customizing Instance Creation},
-which covers the creation and initialization of instances in general.
-
-@node Customizing Class Definition
-@subsection Customizing Class Definition
+The @code{(make @var{metaclass} @dots{})} invocation is a particular
+case of the instance creation protocol covered in the previous section.
+It will create an class metaobject with metaclass @var{metaclass}. By
+default, this metaobject will be initialized by the @code{initialize}
+method that is specialized for instances of type @code{<class>}.
-During the initialization of a new class, GOOPS calls a number of generic
-functions with the newly allocated class instance as the first
-argument. Specifically, GOOPS calls the generic function
+The @code{initialize} method for classes (signature @code{(initialize
+<class> initargs)}) calls the following generic functions.
@itemize @bullet
@item
-(initialize @var{class} @dots{})
-@end itemize
+@code{compute-cpl @var{class}} (generic)
-where @var{class} is the newly allocated class instance, and the default
-@code{initialize} method for arguments of type @code{<class>} calls the
-generic functions
+The applied method should compute and return the class precedence list
+for @var{class} as a list of class metaobjects. When @code{compute-cpl}
+is called, the following @var{class} metaobject slots have all been
+initialized: @code{name}, @code{direct-supers}, @code{direct-slots},
+@code{direct-subclasses} (empty), @code{direct-methods}. The value
+returned by @code{compute-cpl} will be stored in the @code{cpl} slot.
-@itemize @bullet
@item
-(compute-cpl @var{class})
+@code{compute-slots @var{class}} (generic)
-@item
-(compute-slots @var{class})
+The applied method should compute and return the slots (union of direct
+and inherited) for @var{class} as a list of slot definitions. When
+@code{compute-slots} is called, all the @var{class} metaobject slots
+mentioned for @code{compute-cpl} have been initialized, plus the
+following: @code{cpl}, @code{redefined} (@code{#f}), @code{environment}.
+The value returned by @code{compute-slots} will be stored in the
+@code{slots} slot.
@item
-(compute-get-n-set @var{class} @var{slot-def}), for each of the slot
-definitions returned by @code{compute-slots}
+@code{compute-get-n-set @var{class} @var{slot-def}} (generic)
+
+@code{initialize} calls @code{compute-get-n-set} for each slot computed
+by @code{compute-slots}. The applied method should compute and return a
+pair of closures that, respectively, get and set the value of the specified
+slot. The get closure should have arity 1 and expect a single argument
+that is the instance whose slot value is to be retrieved. The set closure
+should have arity 2 and expect two arguments, where the first argument is
+the instance whose slot value is to be set and the second argument is the
+new value for that slot. The closures should be returned in a two element
+list: @code{(list @var{get} @var{set})}.
+
+The closures returned by @code{compute-get-n-set} are stored as part of
+the value of the @var{class} metaobject's @code{getters-n-setters} slot.
+Specifically, the value of this slot is a list with the same number of
+elements as there are slots in the class, and each element looks either like
+
+@example
+@code{(@var{slot-name-symbol} @var{init-function} . @var{index})}
+@end example
+
+or like
+
+@example
+@code{(@var{slot-name-symbol} @var{init-function} @var{get} @var{set})}
+@end example
+
+Where the get and set closures are replaced by @var{index}, the slot is
+an instance slot and @var{index} is the slot's index in the underlying
+structure: GOOPS knows how to get and set the value of such slots and so
+does not need specially constructed get and set closures. Otherwise,
+@var{get} and @var{set} are the closures returned by @code{compute-get-n-set}.
+
+The structure of the @code{getters-n-setters} slot value is important when
+understanding the next customizable generic functions that @code{initialize}
+calls@dots{}
@item
-(compute-getter-method @var{class} @var{slot-def}), for each of the
-slot definitions returned by @code{compute-slots} that includes a
-@code{#:getter} or @code{#:accessor} slot option
+@code{compute-getter-method @var{class} @var{gns}} (generic)
+
+@code{initialize} calls @code{compute-getter-method} for each of the
+class's slots (as determined by @code{compute-slots}) that includes a
+@code{#:getter} or @code{#:accessor} slot option. @var{gns} is the
+element of the @var{class} metaobject's @code{getters-n-setters} slot
+that specifies how the slot in question is referenced and set, as
+described above under @code{compute-get-n-set}. The applied method
+should create and return a method that is specialized for instances of
+type @var{class} and uses the get closure to retrieve the slot's value.
+@code{initialize} uses @code{add-method!} to add the returned method to
+the generic function named by the slot definition's @code{#:getter} or
+@code{#:accessor} option.
@item
-(compute-setter-method @var{class} @var{slot-def}), for each of the
-slot definitions returned by @code{compute-slots} that includes a
-@code{#:setter} or @code{#:accessor} slot option.
+@code{compute-setter-method @var{class} @var{gns}} (generic)
+
+@code{compute-setter-method} is invoked with the same arguments as
+@code{compute-getter-method}, for each of the class's slots that includes
+a @code{#:setter} or @code{#:accessor} slot option. The applied method
+should create and return a method that is specialized for instances of
+type @var{class} and uses the set closure to set the slot's value.
+@code{initialize} then uses @code{add-method!} to add the returned method
+to the generic function named by the slot definition's @code{#:setter}
+or @code{#:accessor} option.
@end itemize
+@node Customizing Class Definition
+@subsection Customizing Class Definition
+
If the metaclass of the new class is something more specialized than the
default @code{<class>}, then the type of @var{class} in the calls above
is more specialized than @code{<class>}, and hence it becomes possible
with a special metaclass.
The default CPL algorithm is encapsulated by the @code{compute-std-cpl}
-procedure, which is in turn called by the default @code{compute-cpl}
-method.
+procedure, which is called by the default @code{compute-cpl} method.
@deffn procedure compute-std-cpl class
Compute and return the class precedence list for @var{class} according
@end example
The usage of @code{compute-getter-method} and @code{compute-setter-method}
-is described in @ref{MOP Specification}.
+is described in @ref{Class Definition Protocol}.
@code{compute-cpl} and @code{compute-get-n-set} are called by the
standard @code{initialize} method for classes whose metaclass is
typically it would perform additional class initialization steps before
and/or after calling @code{(next-method)} for the standard behaviour.
-@node Customizing Instance Creation
-@subsection Customizing Instance Creation
-
-@code{make <class> . @var{initargs}} (method)
-
-@itemize @bullet
-@item
-@code{allocate-instance @var{class} @var{initargs}} (generic)
-
-The applied @code{allocate-instance} method should allocate storage for
-a new instance of class @var{class} and return the uninitialized instance.
-
-@item
-@code{initialize @var{instance} @var{initargs}} (generic)
-
-@var{instance} is the uninitialized instance returned by
-@code{allocate-instance}. The applied method should initialize the new
-instance in whatever sense is appropriate for its class. The method's
-return value is ignored.
-@end itemize
-
-@code{make} itself is a generic function. Hence the @code{make}
-invocation itself can be customized in the case where the new instance's
-metaclass is more specialized than the default @code{<class>}, by
-defining a @code{make} method that is specialized to that metaclass.
-
-Normally, however, the method for classes with metaclass @code{<class>}
-will be applied. This method calls two generic functions:
-
-@itemize @bullet
-@item
-(allocate-instance @var{class} . @var{initargs})
-
-@item
-(initialize @var{instance} . @var{initargs})
-@end itemize
-
-@code{allocate-instance} allocates storage for and returns the new
-instance, uninitialized. You might customize @code{allocate-instance},
-for example, if you wanted to provide a GOOPS wrapper around some other
-object programming system.
-
-To do this, you would create a specialized metaclass, which would act as
-the metaclass for all classes and instances from the other system. Then
-define an @code{allocate-instance} method, specialized to that
-metaclass, which calls a Guile primitive C function, which in turn
-allocates the new instance using the interface of the other object
-system.
-
-In this case, for a complete system, you would also need to customize a
-number of other generic functions like @code{make} and
-@code{initialize}, so that GOOPS knows how to make classes from the
-other system, access instance slots, and so on.
-
-@code{initialize} initializes the instance that is returned by
-@code{allocate-instance}. The standard GOOPS methods perform
-initializations appropriate to the instance class.
-
-@itemize @bullet
-@item
-At the least specialized level, the method for instances of type
-@code{<object>} performs internal GOOPS instance initialization, and
-initializes the instance's slots according to the slot definitions and
-any slot initialization keywords that appear in @var{initargs}.
-
-@item
-The method for instances of type @code{<class>} calls
-@code{(next-method)}, then performs the class initializations described
-in @ref{Customizing Class Definition}.
-
-@item
-and so on for generic functions, method, operator classes @dots{}
-@end itemize
-
-Similarly, you can customize the initialization of instances of any
-application-defined class by defining an @code{initialize} method
-specialized to that class.
-
-Imagine a class whose instances' slots need to be initialized at
-instance creation time by querying a database. Although it might be
-possible to achieve this a combination of @code{#:init-thunk} keywords
-and closures in the slot definitions, it is neater to write an
-@code{initialize} method for the class that queries the database once
-and initializes all the dependent slot values according to the results.
-
-@node Class Redefinition
-@subsection Class Redefinition
-
-The default @code{class-redefinition} method, specialized for classes
-with the default metaclass @code{<class>}, has the following internal
-protocol.
-
-@code{class-redefinition (@var{old <class>}) (@var{new <class>})}
-(method)
-
-@itemize @bullet
-@item
-@code{remove-class-accessors! @var{old}} (generic)
-
-@item
-@code{update-direct-method! @var{method} @var{old} @var{new}} (generic)
-
-@item
-@code{update-direct-subclass! @var{subclass} @var{old} @var{new}} (generic)
-@end itemize
-
-This protocol cleans up things that the definition of the old class
-once changed and modifies things to work with the new class.
-
-The default @code{remove-class-accessors!} method removes the
-accessor methods of the old class from all classes which they
-specialize.
-
-The default @code{update-direct-method!} method substitutes the new
-class for the old in all methods specialized to the old class.
-
-The default @code{update-direct-subclass!} method invokes
-@code{class-redefinition} recursively to handle the redefinition of
-subclasses.
-
-When a class is redefined, any existing instance of the redefined class
-will be modified for the new class definition before the next time that
-any of the instance's slot is referenced or set. GOOPS modifies each
-instance by calling the generic function @code{change-class}.
-
-The default @code{change-class} method copies slot values from the old
-to the modified instance, and initializes new slots, as described in
-@ref{Changing the Class of an Instance}. After doing so, it makes a
-generic function invocation that can be used to customize the instance
-update algorithm.
-
-@code{change-class (@var{old-instance <object>}) (@var{new <class>})} (method)
-
-@itemize @bullet
-@item
-@code{update-instance-for-different-class @var{old-instance} @var{new-instance}} (generic)
-
-@code{change-class} invokes @code{update-instance-for-different-class}
-as the last thing that it does before returning. The applied method can
-make any further adjustments to @var{new-instance} that are required to
-complete or modify the change of class. The return value from the
-applied method is ignored.
-
-The default @code{update-instance-for-different-class} method does
-nothing.
-@end itemize
@node Method Definition
@subsection Method Definition
@itemize @bullet
@item
@code{add-method! @var{target} @var{method}} (generic)
+@end itemize
+@noindent
@code{define-method} invokes the @code{add-method!} generic function to
handle adding the new method to a variety of possible targets. GOOPS
includes methods to handle @var{target} as
By defining further methods for @code{add-method!}, you can
theoretically handle adding methods to further types of target.
-@end itemize
+
@node Method Definition Internals
@subsection Method Definition Internals
-@code{define-method}
+@code{define-method}:
@itemize @bullet
@item
define-method}).
@end deffn
-@code{method}
+@noindent
+@code{method}:
@itemize @bullet
@item
function parameters when this method is invoked.
@end deffn
+@noindent
@code{make-method} is a simple wrapper around @code{make} with metaclass
@code{<method>}.
@node Generic Function Invocation
@subsection Generic Function Invocation
-[ *fixme* Description required here. ]
+There is a detailed and customizable protocol involved in the process of
+invoking a generic function --- i.e., in the process of deciding which
+of the generic function's methods are applicable to the current
+arguments, and which one of those to apply. Here is a summary diagram
+of the generic functions involved.
-@code{apply-generic}
+@noindent
+@code{apply-generic} (generic)
@itemize @bullet
@item
-@code{no-method}
+@code{no-method} (generic)
@item
-@code{compute-applicable-methods}
+@code{compute-applicable-methods} (generic)
@item
-@code{sort-applicable-methods}
-
-@item
-@code{apply-methods}
+@code{sort-applicable-methods} (generic)
+@itemize @bullet
@item
-@code{no-applicable-method}
+@code{method-more-specific?} (generic)
@end itemize
-@code{sort-applicable-methods}
+@item
+@code{apply-methods} (generic)
@itemize @bullet
@item
-@code{method-more-specific?}
-@end itemize
-
-@code{apply-methods}
+@code{apply-method} (generic)
-@itemize @bullet
@item
-@code{apply-method}
+@code{no-next-method} (generic)
@end itemize
-@code{next-method}
-
-@itemize @bullet
@item
-@code{no-next-method}
+@code{no-applicable-method}
@end itemize
-
-@node Class Options
-@section Class Options
-
-@deffn {class option} #:metaclass metaclass
-The @code{#:metaclass} class option specifies the metaclass of the class
-being defined. @var{metaclass} must be a class that inherits from
-@code{<class>}. For the use of metaclasses, see @ref{Metaobjects and
-the Metaobject Protocol} and @ref{Terminology}.
-
-If the @code{#:metaclass} option is absent, GOOPS reuses or constructs a
-metaclass for the new class by calling @code{ensure-metaclass}
-(@pxref{Class Definition Internals,, ensure-metaclass}).
-@end deffn
-
-@deffn {class option} #:name name
-The @code{#:name} class option specifies the new class's name. This
-name is used to identify the class whenever related objects - the class
-itself, its instances and its subclasses - are printed.
-
-If the @code{#:name} option is absent, GOOPS uses the first argument to
-@code{define-class} as the class name.
-@end deffn
+We do not yet have full documentation for these. Please refer to the
+code (@file{oop/goops.scm}) for details.
@node Redefining a Class
@node Customizing Class Redefinition
@subsection Customizing Class Redefinition
-When @code{define-class} notices that a class is being redefined,
-it constructs the new class metaobject as usual, and then invokes the
+When @code{define-class} notices that a class is being redefined, it
+constructs the new class metaobject as usual, then invokes the
@code{class-redefinition} generic function with the old and new classes
as arguments. Therefore, if the old or new classes have metaclasses
other than the default @code{<class>}, class redefinition behaviour can
for the new class definition.
@end deffn
+The default @code{class-redefinition} method, for classes with the
+default metaclass @code{<class>}, calls the following generic functions,
+which could of course be individually customized.
+
+@deffn generic remove-class-accessors! old
+The default @code{remove-class-accessors!} method removes the accessor
+methods of the old class from all classes which they specialize.
+@end deffn
+
+@deffn generic update-direct-method! method old new
+The default @code{update-direct-method!} method substitutes the new
+class for the old in all methods specialized to the old class.
+@end deffn
+
+@deffn generic update-direct-subclass! subclass old new
+The default @code{update-direct-subclass!} method invokes
+@code{class-redefinition} recursively to handle the redefinition of
+subclasses.
+@end deffn
+
An alternative class redefinition strategy could be to leave all
existing instances as instances of the old class, but accepting that the
old class is now ``nameless'', since its name has been taken over by the
When customization can be as easy as this, aren't you glad that GOOPS
implements the far more difficult strategy as its default!
-Finally, note that, if @code{class-redefinition} itself is not customized,
-the default @code{class-redefinition} method invokes three further
-generic functions that could be individually customized:
-
-@itemize @bullet
-@item
-(remove-class-accessors! @var{old-class})
-
-@item
-(update-direct-method! @var{method} @var{old-class} @var{new-class})
-
-@item
-(update-direct-subclass! @var{subclass} @var{old-class} @var{new-class})
-@end itemize
-
-and the default methods for these generic functions invoke further
-generic functions, and so on@dots{} The detailed protocol for all of these
-is described in @ref{MOP Specification}.
@node Changing the Class of an Instance
@section Changing the Class of an Instance
-You can change the class of an existing instance by invoking the
-generic function @code{change-class} with two arguments: the instance
-and the new class.
+When a class is redefined, any existing instance of the redefined class
+will be modified for the new class definition before the next time that
+any of the instance's slots is referenced or set. GOOPS modifies each
+instance by calling the generic function @code{change-class}.
-@deffn generic change-class
-@end deffn
+More generally, you can change the class of an existing instance at any
+time by invoking the generic function @code{change-class} with two
+arguments: the instance and the new class.
The default method for @code{change-class} decides how to implement the
change of class by looking at the slot definitions for the instance's
using the corresponding slot definition's init function (@pxref{Classes,,
slot-init-function}).
+@deffn generic change-class instance new-class
+@end deffn
+
@deffn {method} change-class (obj <object>) (new <class>)
Modify instance @var{obj} to make it an instance of class @var{new}.
init functions.
@end deffn
+The default @code{change-class} method also invokes another generic
+function, @code{update-instance-for-different-class}, as the last thing
+that it does before returning. The applied
+@code{update-instance-for-different-class} method can make any further
+adjustments to @var{new-instance} that are required to complete or
+modify the change of class. The return value from the applied method is
+ignored.
+
+@deffn generic update-instance-for-different-class old-instance new-instance
+A generic function that can be customized to put finishing touches to an
+instance whose class has just been changed. The default
+@code{update-instance-for-different-class} method does nothing.
+@end deffn
+
Customized change of class behaviour can be implemented by defining
@code{change-class} methods that are specialized either by the class
of the instances to be modified or by the metaclass of the new class.
-
-When a class is redefined (@pxref{Redefining a Class}), and the default
-class redefinition behaviour is not overridden, GOOPS (eventually)
-invokes the @code{change-class} generic function for each existing
-instance of the redefined class.