@c -*-texinfo-*-
@c This is part of the GNU Guile Reference Manual.
-@c Copyright (C) 2008, 2009
+@c Copyright (C) 2008, 2009, 2011
@c Free Software Foundation, Inc.
@c See the file guile.texi for copying conditions.
* Slot Description Example::
* Methods and Generic Functions::
* Inheritance::
-* Class Options::
-* Accessing Slots::
-* Generic Functions and Accessors::
-* Adding Methods to Generic Functions::
-* Invoking Generic Functions::
-* Redefining a Class::
-* Changing the Class of an Instance::
* Introspection::
* GOOPS Error Handling::
-* Object Comparisons::
-* Cloning Objects::
-* Write and Display::
+* GOOPS Object Miscellany::
* The Metaobject Protocol::
+* Redefining a Class::
+* Changing the Class of an Instance::
@end menu
@node Copyright Notice
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
+@deffn syntax define-class name (super @dots{}) @
+ slot-definition @dots{} class-option @dots{}
Define a class called @var{name} that inherits from @var{super}s, with
-direct slots defined by @var{slot-definition}s and class options
-@var{options}. The newly created class is bound to the variable name
-@var{name} in the current environment.
+direct slots defined by @var{slot-definition}s and @var{class-option}s.
+The newly created class is bound to the variable name @var{name} in the
+current environment.
Each @var{slot-definition} is either a symbol that names the slot or a
list,
@var{slot-options} (counting from zero) are slot option keywords; the
odd-numbered elements are the corresponding values for those keywords.
-@var{options} is a similarly structured list containing class option
-keywords and corresponding values.
+Each @var{class-option} is an option keyword and corresponding value.
@end deffn
As an example, let us define a type for representing a complex number
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
variable @code{c}.
@deffn generic make
-@deffnx method make (class <class>) . initargs
+@deffnx method make (class <class>) initarg @dots{}
Create and return a new instance of class @var{class}, initialized using
-@var{initargs}.
+@var{initarg} @enddots{}.
-In theory, @var{initargs} can have any structure that is understood by
-whatever methods get applied when the @code{initialize} generic function
-is applied to the newly allocated instance.
+In theory, @var{initarg} @dots{} can have any structure that is
+understood by whatever methods get applied when the @code{initialize}
+generic function is applied to the newly allocated instance.
In practice, specialized @code{initialize} methods would normally call
@code{(next-method)}, and so eventually the standard GOOPS
@end deffn
@deffn generic make-instance
-@deffnx method make-instance (class <class>) . initargs
+@deffnx method make-instance (class <class>) initarg @dots{}
@code{make-instance} is an alias for @code{make}.
@end deffn
@end lisp
-In this class definition, the magniture @code{m} and angle @code{a}
+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
and the question of which class the method is more associated with does
not need answering.
-A generic function is a collection of methods with the same name but
-different sets of specializing argument classes.
+There can simultaneously be several methods with the same name but
+different sets of specializing argument classes; for example:
+
+@lisp
+(define-method (+ (x <string>) (y <string)) ...)
+(define-method (+ (x <matrix>) (y <matrix>)) ...)
+(define-method (+ (f <fish>) (b <bicycle>)) ...)
+(define-method (+ (a <foo>) (b <bar>) (c <baz>)) ...)
+@end lisp
+
+@noindent
+A generic function is a container for the set of such methods that a
+program intends to use.
+
+If you look at a program's source code, and see @code{(+ x y)} somewhere
+in it, conceptually what is happening is that the program at that point
+calls a generic function (in this case, the generic function bound to
+the identifier @code{+}). When that happens, Guile works out which of
+the generic function's methods is the most appropriate for the arguments
+that the function is being called with; then it evaluates the method's
+code with the arguments as formal parameters. This happens every time
+that a generic function call is evaluated --- it isn't assumed that a
+given source code call will end up invoking the same method every time.
+
+Defining an identifier as a generic function is done with the
+@code{define-generic} macro. Definition of a new method is done with
+the @code{define-method} macro. Note that @code{define-method}
+automatically does a @code{define-generic} if the identifier concerned
+is not already a generic function, so often an explicit
+@code{define-generic} call is not needed.
+@findex define-generic
+@findex define-method
+
+@deffn syntax define-generic symbol
+Create a generic function with name @var{symbol} and bind it to the
+variable @var{symbol}. If @var{symbol} was previously bound to a Scheme
+procedure (or procedure-with-setter), the old procedure (and setter) is
+incorporated into the new generic function as its default procedure (and
+setter). Any other previous value, including an existing generic
+function, is discarded and replaced by a new, empty generic function.
+@end deffn
+
+@deffn syntax define-method (generic parameter @dots{}) body @dots{}
+Define a method for the generic function or accessor @var{generic} with
+parameters @var{parameter}s and body @var{body} @enddots{}.
+
+@var{generic} is a generic function. If @var{generic} is a variable
+which is not yet bound to a generic function object, the expansion of
+@code{define-method} will include a call to @code{define-generic}. If
+@var{generic} is @code{(setter @var{generic-with-setter})}, where
+@var{generic-with-setter} is a variable which is not yet bound to a
+generic-with-setter object, the expansion will include a call to
+@code{define-accessor}.
+
+Each @var{parameter} must be either a symbol or a two-element list
+@code{(@var{symbol} @var{class})}. The symbols refer to variables in
+the body forms that will be bound to the parameters supplied by the
+caller when calling this method. The @var{class}es, if present,
+specify the possible combinations of parameters to which this method
+can be applied.
+
+@var{body} @dots{} are the bodies of the method definition.
+@end deffn
+
+@code{define-method} expressions look a little like Scheme procedure
+definitions of the form
+
+@example
+(define (name formals @dots{}) . body)
+@end example
+
+The important difference is that each formal parameter, apart from the
+possible ``rest'' argument, can be qualified by a class name:
+@code{@var{formal}} becomes @code{(@var{formal} @var{class})}. The
+meaning of this qualification is that the method being defined
+will only be applicable in a particular generic function invocation if
+the corresponding argument is an instance of @code{@var{class}} (or one of
+its subclasses). If more than one of the formal parameters is qualified
+in this way, then the method will only be applicable if each of the
+corresponding arguments is an instance of its respective qualifying class.
+
+Note that unqualified formal parameters act as though they are qualified
+by the class @code{<top>}, which GOOPS uses to mean the superclass of
+all valid Scheme types, including both primitive types and GOOPS classes.
+
+For example, if a generic function method is defined with
+@var{parameter}s @code{(s1 <square>)} and @code{(n <number>)}, that
+method is only applicable to invocations of its generic function that
+have two parameters where the first parameter is an instance of the
+@code{<square>} class and the second parameter is a number.
@menu
-* Generic functions and methods::
+* Accessors::
+* Extending Primitives::
+* Merging Generics::
* Next-method::
-* Example::
+* Generic Function and Method Examples::
+* Handling Invocation Errors::
@end menu
-@node Generic functions and methods
-@subsection Generic functions and methods
-
-@c \label{gf-n-methods}
-Neither @goops{} nor CLOS use the message mechanism for methods as most
-Object Oriented language do. Instead, they use the notion of
-@dfn{generic functions}. A generic function can be seen as a methods
-``tanker''. When the evaluator requested the application of a generic
-function, all the methods of this generic function will be grabbed and
-the most specific among them will be applied. We say that a method
-@var{M} is @emph{more specific} than a method @var{M'} if the class of
-its parameters are more specific than the @var{M'} ones. To be more
-precise, when a generic function must be ``called'' the system will:
-
-@cindex generic function
-@enumerate
-@item
-search among all the generic function those which are applicable
-@item
-sort the list of applicable methods in the ``most specific'' order
-@item
-call the most specific method of this list (i.e. the first method of
-the sorted methods list).
-@end enumerate
-
-The definition of a generic function is done with the
-@code{define-generic} macro. Definition of a new method is done with the
-@code{define-method} macro. Note that @code{define-method} automatically
-defines the generic function if it has not been defined
-before. Consequently, most of the time, the @code{define-generic} needs
-not be used.
-@findex define-generic
-@findex define-method
-Consider the following definitions:
-@lisp
-(define-generic G)
-(define-method (G (a <integer>) b) 'integer)
-(define-method (G (a <real>) b) 'real)
-(define-method (G a b) 'top)
-@end lisp
+@node Accessors
+@subsection Accessors
-The @code{define-generic} call defines @var{G} as a generic
-function. Note that the signature of the generic function is not given
-upon definition, contrarily to CLOS. This will permit methods with
-different signatures for a given generic function, as we shall see
-later. The three next lines define methods for the @var{G} generic
-function. Each method uses a sequence of @dfn{parameter specializers}
-that specify when the given method is applicable. A specializer permits
-to indicate the class a parameter must belong to (directly or
-indirectly) to be applicable. If no specializer is given, the system
-defaults it to @code{<top>}. Thus, the first method definition is
-equivalent to
+An accessor is a generic function that can also be used with the
+generalized @code{set!} syntax (@pxref{Procedures with Setters}). Guile
+will handle a call like
-@cindex parameter specializers
-@lisp
-(define-method (G (a <integer>) (b <top>)) 'integer)
-@end lisp
+@example
+(set! (@code{accessor} @code{args}@dots{}) @code{value})
+@end example
-Now, let us look at some possible calls to generic function @var{G}:
+@noindent
+by calling the most specialized method of @code{accessor} that matches
+the classes of @code{args} and @code{value}. @code{define-accessor} is
+used to bind an identifier to an accessor.
-@lisp
-(G 2 3) @result{} integer
-(G 2 #t) @result{} integer
-(G 1.2 'a) @result{} real
-@c (G #3 'a) @result{} real @c was {\sharpsign}
-(G #t #f) @result{} top
-(G 1 2 3) @result{} error (since no method exists for 3 parameters)
-@end lisp
+@deffn syntax define-accessor symbol
+Create an accessor with name @var{symbol} and bind it to the variable
+@var{symbol}. If @var{symbol} was previously bound to a Scheme
+procedure (or procedure-with-setter), the old procedure (and setter) is
+incorporated into the new accessor as its default procedure (and
+setter). Any other previous value, including an existing generic
+function or accessor, is discarded and replaced by a new, empty
+accessor.
+@end deffn
-The preceding methods use only one specializer per parameter list. Of
-course, each parameter can use a specializer. In this case, the
-parameter list is scanned from left to right to determine the
-applicability of a method. Suppose we declare now
-@lisp
-(define-method (G (a <integer>) (b <number>)) 'integer-number)
-(define-method (G (a <integer>) (b <real>)) 'integer-real)
-(define-method (G (a <integer>) (b <integer>)) 'integer-integer)
-(define-method (G a (b <number>)) 'top-number)
-@end lisp
+@node Extending Primitives
+@subsection Extending Primitives
+
+Many of Guile's primitive procedures can be extended by giving them a
+generic function definition that operates in conjunction with their
+normal C-coded implementation. When a primitive is extended in this
+way, it behaves like a generic function with the C-coded implementation
+as its default method.
+
+This extension happens automatically if a method is defined (by a
+@code{define-method} call) for a variable whose current value is a
+primitive. But it can also be forced by calling
+@code{enable-primitive-generic!}.
+
+@deffn {primitive procedure} enable-primitive-generic! primitive
+Force the creation of a generic function definition for
+@var{primitive}.
+@end deffn
+
+Once the generic function definition for a primitive has been created,
+it can be retrieved using @code{primitive-generic-generic}.
+
+@deffn {primitive procedure} primitive-generic-generic primitive
+Return the generic function definition of @var{primitive}.
+
+@code{primitive-generic-generic} raises an error if @var{primitive}
+is not a primitive with generic capability.
+@end deffn
+
+@node Merging Generics
+@subsection Merging Generics
+
+GOOPS generic functions and accessors often have short, generic names.
+For example, if a vector package provides an accessor for the X
+coordinate of a vector, that accessor may just be called @code{x}. It
+doesn't need to be called, for example, @code{vector:x}, because
+GOOPS will work out, when it sees code like @code{(x @var{obj})}, that
+the vector-specific method of @code{x} should be called if @var{obj} is
+a vector.
-In this case,
+That raises the question, though, of what happens when different
+packages define a generic function with the same name. Suppose we work
+with a graphical package which needs to use two independent vector
+packages for 2D and 3D vectors respectively. If both packages export
+@code{x}, what does the code using those packages end up with?
+
+@ref{Creating Guile Modules,,duplicate binding handlers} explains how
+this is resolved for conflicting bindings in general. For generics,
+there is a special duplicates handler, @code{merge-generics}, which
+tells the module system to merge generic functions with the same name.
+Here is an example:
@lisp
-(G 1 2) @result{} integer-integer
-(G 1 1.0) @result{} integer-real
-(G 1 #t) @result{} integer
-(G 'a 1) @result{} top-number
+(define-module (math 2D-vectors)
+ #:use-module (oop goops)
+ #:export (x y ...))
+
+(define-module (math 3D-vectors)
+ #:use-module (oop goops)
+ #:export (x y z ...))
+
+(define-module (my-module)
+ #:use-module (oop goops)
+ #:use-module (math 2D-vectors)
+ #:use-module (math 3D-vectors)
+ #:duplicates (merge-generics))
@end lisp
+The generic function @code{x} in @code{(my-module)} will now incorporate
+all of the methods of @code{x} from both imported modules.
+
+To be precise, there will now be three distinct generic functions named
+@code{x}: @code{x} in @code{(math 2D-vectors)}, @code{x} in @code{(math
+3D-vectors)}, and @code{x} in @code{(my-module)}; and these functions
+share their methods in an interesting and dynamic way.
+
+To explain, let's call the imported generic functions (in @code{(math
+2D-vectors)} and @code{(math 3D-vectors)}) the @dfn{ancestors}, and the
+merged generic function (in @code{(my-module)}), the @dfn{descendant}.
+The general rule is that for any generic function G, the applicable
+methods are selected from the union of the methods of G's descendant
+functions, the methods of G itself and the methods of G's ancestor
+functions.
+
+Thus ancestor functions effectively share methods with their
+descendants, and vice versa. In the example above, @code{x} in
+@code{(math 2D-vectors)} will share the methods of @code{x} in
+@code{(my-module)} and vice versa.@footnote{But note that @code{x} in
+@code{(math 2D-vectors)} doesn't share methods with @code{x} in
+@code{(math 3D-vectors)}, so modularity is still preserved.} Sharing is
+dynamic, so adding another new method to a descendant implies adding it
+to that descendant's ancestors too.
+
@node Next-method
@subsection Next-method
lead to an infinite recursion, but this consideration is just the same
as in Scheme code in general.)
-@node Example
-@subsection Example
+@node Generic Function and Method Examples
+@subsection Generic Function and Method Examples
+
+Consider the following definitions:
+
+@lisp
+(define-generic G)
+(define-method (G (a <integer>) b) 'integer)
+(define-method (G (a <real>) b) 'real)
+(define-method (G a b) 'top)
+@end lisp
+
+The @code{define-generic} call defines @var{G} as a generic function.
+The three next lines define methods for @var{G}. Each method uses a
+sequence of @dfn{parameter specializers} that specify when the given
+method is applicable. A specializer permits to indicate the class a
+parameter must belong to (directly or indirectly) to be applicable. If
+no specializer is given, the system defaults it to @code{<top>}. Thus,
+the first method definition is equivalent to
+
+@cindex parameter specializers
+@lisp
+(define-method (G (a <integer>) (b <top>)) 'integer)
+@end lisp
+
+Now, let's look at some possible calls to the generic function @var{G}:
+
+@lisp
+(G 2 3) @result{} integer
+(G 2 #t) @result{} integer
+(G 1.2 'a) @result{} real
+@c (G #3 'a) @result{} real @c was {\sharpsign}
+(G #t #f) @result{} top
+(G 1 2 3) @result{} error (since no method exists for 3 parameters)
+@end lisp
+
+The methods above use only one specializer per parameter list. But in
+general, any or all of a method's parameters may be specialized.
+Suppose we define now:
+
+@lisp
+(define-method (G (a <integer>) (b <number>)) 'integer-number)
+(define-method (G (a <integer>) (b <real>)) 'integer-real)
+(define-method (G (a <integer>) (b <integer>)) 'integer-integer)
+(define-method (G a (b <number>)) 'top-number)
+@end lisp
+
+@noindent With these definitions:
+
+@lisp
+(G 1 2) @result{} integer-integer
+(G 1 1.0) @result{} integer-real
+(G 1 #t) @result{} integer
+(G 'a 1) @result{} top-number
+@end lisp
-In this section we shall continue to define operations on the @code{<my-complex>}
-class defined in Figure@ 2. Suppose that we want to use it to implement
-complex numbers completely. For instance a definition for the addition of
-two complexes could be
+As a further example we shall continue to define operations on the
+@code{<my-complex>} class. Suppose that we want to use it to implement
+complex numbers completely. For instance a definition for the addition
+of two complex numbers could be
@lisp
(define-method (new-+ (a <my-complex>) (b <my-complex>))
(+ (imag-part a) (imag-part b))))
@end lisp
-To be sure that the @code{+} used in the method @code{new-+} is the standard
-addition we can do:
+To be sure that the @code{+} used in the method @code{new-+} is the
+standard addition we can do:
@lisp
(define-generic new-+)
in the global environment. Once this is done, we can add methods to the
generic function @code{new-+} which make a closure on the @code{+}
symbol. A complete writing of the @code{new-+} methods is shown in
-Figure@ 3.
+@ref{fig:newplus}.
-@example
-@group
+@float Figure,fig:newplus
@lisp
(define-generic new-+)
(set! + new-+)
@end lisp
-@center @emph{Fig 3: Extending @code{+} for dealing with complex numbers}
-@end group
-@end example
-
-@sp 3
-We use here the fact that generic function are not obliged to have the
-same number of parameters, contrarily to CLOS. The four first methods
-implement the dyadic addition. The fifth method says that the addition
-of a single element is this element itself. The sixth method says that
-using the addition with no parameter always return 0. The last method
-takes an arbitrary number of parameters@footnote{The parameter list for
-a @code{define-method} follows the conventions used for Scheme
-procedures. In particular it can use the dot notation or a symbol to
-denote an arbitrary number of parameters}. This method acts as a kind
-of @code{reduce}: it calls the dyadic addition on the @emph{car} of the
-list and on the result of applying it on its rest. To finish, the
-@code{set!} permits to redefine the @code{+} symbol to our extended
-addition.
-
-@sp 3
-To terminate our implementation (integration?) of complex numbers, we can
-redefine standard Scheme predicates in the following manner:
+@caption{Extending @code{+} to handle complex numbers}
+@end float
+
+We take advantage here of the fact that generic function are not obliged
+to have a fixed number of parameters. The four first methods implement
+dyadic addition. The fifth method says that the addition of a single
+element is this element itself. The sixth method says that using the
+addition with no parameter always return 0 (as is also true for the
+primitive @code{+}). The last method takes an arbitrary number of
+parameters@footnote{The parameter list for a @code{define-method}
+follows the conventions used for Scheme procedures. In particular it can
+use the dot notation or a symbol to denote an arbitrary number of
+parameters}. This method acts as a kind of @code{reduce}: it calls the
+dyadic addition on the @emph{car} of the list and on the result of
+applying it on its rest. To finish, the @code{set!} permits to redefine
+the @code{+} symbol to our extended addition.
+
+To conclude our implementation (integration?) of complex numbers, we
+could redefine standard Scheme predicates in the following manner:
@lisp
(define-method (complex? c <my-complex>) #t)
(define-method (number? n <number>) #t)
(define-method (number? n) #f)
@dots{}
-@dots{}
@end lisp
Standard primitives in which complex numbers are involved could also be
redefined in the same manner.
+@node Handling Invocation Errors
+@subsection Handling Invocation Errors
+
+If a generic function is invoked with a combination of parameters for
+which there is no applicable method, GOOPS raises an error.
+
+@deffn generic no-method
+@deffnx method no-method (gf <generic>) args
+When an application invokes a generic function, and no methods at all
+have been defined for that generic function, GOOPS calls the
+@code{no-method} generic function. The default method calls
+@code{goops-error} with an appropriate message.
+@end deffn
+
+@deffn generic no-applicable-method
+@deffnx method no-applicable-method (gf <generic>) args
+When an application applies a generic function to a set of arguments,
+and no methods have been defined for those argument types, GOOPS calls
+the @code{no-applicable-method} generic function. The default method
+calls @code{goops-error} with an appropriate message.
+@end deffn
+
+@deffn generic no-next-method
+@deffnx method no-next-method (gf <generic>) args
+When a generic function method calls @code{(next-method)} to invoke the
+next less specialized method for that generic function, and no less
+specialized methods have been defined for the current generic function
+arguments, GOOPS calls the @code{no-next-method} generic function. The
+default method calls @code{goops-error} with an appropriate message.
+@end deffn
+
+
@node Inheritance
@section Inheritance
contains @code{<object>}, the root of all the classes defined by
@code{define-class}. @code{D}, @code{E}, @code{F} use multiple
inheritance: each class inherits from two previously defined classes.
-Those class definitions define a hierarchy which is shown in Figure@ 1.
-In this figure, the class @code{<top>} is also shown; this class is the
-superclass of all Scheme objects. In particular, @code{<top>} is the
-superclass of all standard Scheme types.
+Those class definitions define a hierarchy which is shown in
+@ref{fig:hier}. In this figure, the class @code{<top>} is also shown;
+this class is the superclass of all Scheme objects. In particular,
+@code{<top>} is the superclass of all standard Scheme
+types.
-@example
-@group
+@float Figure,fig:hier
@iftex
@center @image{hierarchy,5in}
@end iftex
@verbatiminclude hierarchy.txt
@end ifnottex
-@emph{Fig 1: A class hierarchy}@footnote{@code{<complex>}, which is the
-direct subclass of @code{<number>} and the direct superclass of
-@code{<real>}, has been omitted in this figure.}
-@end group
-@end example
+@caption{A class hierarchy.}
+@end float
When a class has superclasses, its set of slots is calculated by taking
the union of its own slots and those of all its superclasses. Thus each
The ordering of the returned slots is not significant.
@menu
-* Class precedence list::
+* Class Precedence List::
+* Sorting Methods::
@end menu
-@node Class precedence list
-@subsection Class precedence list
+@node Class Precedence List
+@subsection Class Precedence List
-A class may have more than one superclass. @footnote{This section is an
-adaptation of Jeff Dalton's (J.Dalton@@ed.ac.uk) @cite{Brief
-introduction to CLOS}} With single inheritance (one superclass), it is
-easy to order the superclasses from most to least specific. This is the
-rule:
+What happens when a class inherits from two or more superclasses that
+have a slot with the same name but incompatible definitions --- for
+example, different init values or slot allocations? We need a rule for
+deciding which slot definition the derived class ends up with, and this
+rule is provided by the class's @dfn{Class Precedence
+List}.@footnote{This section is an adaptation of material from Jeff
+Dalton's (J.Dalton@@ed.ac.uk) @cite{Brief introduction to CLOS}}
-@display
-@cartouche
-Rule 1: Each class is more specific than its superclasses.@c was \bf
-@end cartouche
-@end display
+Another problem arises when invoking a generic function, and there is
+more than one method that could apply to the call arguments. Here we
+need a way of ordering the applicable methods, so that Guile knows which
+method to use first, which to use next if that method calls
+@code{next-method}, and so on. One of the ingredients for this ordering
+is determining, for each given call argument, which of the specializing
+classes, from each applicable method's definition, is the most specific
+for that argument; and here again the class precedence list helps.
-With multiple inheritance, ordering is harder. Suppose we have
+If inheritance was restricted such that each class could only have one
+superclass --- which is known as @dfn{single} inheritance --- class
+ordering would be easy. The rule would be simply that a subclass is
+considered more specific than its superclass.
+
+With multiple inheritance, ordering is less obvious, and we have to
+impose an arbitrary rule to determine precedence. Suppose we have
@lisp
(define-class X ()
(@dots{}))
@end lisp
-In this case, the @code{Z} class is more specific than the @code{X} or
-@code{Y} class for instances of @code{Z}. However, the @code{#:init-value}
-specified in @code{X} and @code{Y} leads to a problem: which one
-overrides the other? The rule in @goops{}, as in CLOS, is that the
-superclasses listed earlier are more specific than those listed later.
-So:
-
-@display
-@cartouche
-Rule 2: For a given class, superclasses listed earlier are more
- specific than those listed later.
-@end cartouche
-@end display
-
-These rules are used to compute a linear order for a class and all its
-superclasses, from most specific to least specific. This order is
-called the ``class precedence list'' of the class. Given these two
-rules, we can claim that the initial form for the @code{x} slot of
-previous example is 1 since the class @code{X} is placed before @code{Y}
-in class precedence list of @code{Z}.
-
-These two rules are not always enough to determine a unique order,
-however, but they give an idea of how things work. Taking the @code{F}
-class shown in Figure@ 1, the class precedence list is
+@noindent
+Clearly the @code{Z} class is more specific than @code{X} or @code{Y},
+for instances of @code{Z}. But which is more specific out of @code{X}
+and @code{Y} --- and hence, for the definitions above, which
+@code{#:init-value} will take effect when creating an instance of
+@code{Z}? The rule in @goops{} is that the superclasses listed earlier
+are more specific than those listed later. Hence @code{X} is more
+specific than @code{Y}, and the @code{#:init-value} for slot @code{x} in
+instances of @code{Z} will be 1.
+
+Hence there is a linear ordering for a class and all its
+superclasses, from most specific to least specific, and this ordering is
+called the Class Precedence List of the class.
+
+In fact the rules above are not quite enough to always determine a
+unique order, but they give an idea of how things work. For example,
+for the @code{F} class shown in @ref{fig:hier}, the class precedence
+list is
@example
(f d e a c b <object> <top>)
@end example
-However, it is usually considered a bad idea for programmers to rely on
-exactly what the order is. If the order for some superclasses is important,
-it can be expressed directly in the class definition.
+@noindent
+In cases where there is any ambiguity (like this one), it is a bad idea
+for programmers to rely on exactly what the order is. If the order for
+some superclasses is important, it can be expressed directly in the
+class definition.
-The precedence list of a class can be obtained by the function
-@code{class-precedence-list}. This function returns a ordered
-list whose first element is the most specific class. For instance,
+The precedence list of a class can be obtained by calling
+@code{class-precedence-list}. This function returns a ordered list
+whose first element is the most specific class. For instance:
@lisp
(class-precedence-list B) @result{} (#<<class> B 401b97c8>
#<<class> <top> 4026a9d8>)
@end lisp
-However, this result is not too much readable; using the function
-@code{class-name} yields a clearer result:
+@noindent
+Or for a more immediately readable result:
@lisp
(map class-name (class-precedence-list B)) @result{} (B <object> <top>)
@end lisp
-@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
+@node Sorting Methods
+@subsection Sorting Methods
-@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.
+Now, with the idea of the class precedence list, we can state precisely
+how the possible methods are sorted when more than one of the methods of
+a generic function are applicable to the call arguments.
-If the @code{#:name} option is absent, GOOPS uses the first argument to
-@code{define-class} as the class name.
-@end deffn
+The rules are that
+@itemize
+@item
+the applicable methods are sorted in order of specificity, and the most
+specific method is used first, then the next if that method calls
+@code{next-method}, and so on
-@node Accessing Slots
-@section Accessing Slots
+@item
+a method M1 is more specific than another method M2 if the first
+specializing class that differs, between the definitions of M1 and M2,
+is more specific, in M1's definition, for the corresponding actual call
+argument, than the specializing class in M2's definition
-@menu
-* Instance Slots::
-* Class Slots::
-* Handling Slot Access Errors::
-@end menu
+@item
+a class C1 is more specific than another class C2, for an object of
+actual class C, if C1 comes before C2 in C's class precedence list.
+@end itemize
-@node Instance Slots
-@subsection Instance Slots
-Any slot, regardless of its allocation, can be queried, referenced and
-set using the following four primitive procedures.
+@node Introspection
+@section Introspection
-@deffn {primitive procedure} slot-exists? obj slot-name
-Return @code{#t} if @var{obj} has a slot with name @var{slot-name},
-otherwise @code{#f}.
-@end deffn
+@dfn{Introspection}, or @dfn{reflection}, means being able to obtain
+information dynamically about GOOPS objects. It is perhaps best
+illustrated by considering an object oriented language that does not
+provide any introspection, namely C++.
-@deffn {primitive procedure} slot-bound? obj slot-name
-Return @code{#t} if the slot named @var{slot-name} in @var{obj} has a
-value, otherwise @code{#f}.
+Nothing in C++ allows a running program to obtain answers to the following
+types of question:
-@code{slot-bound?} calls the generic function @code{slot-missing} if
-@var{obj} does not have a slot called @var{slot-name} (@pxref{Handling
-Slot Access Errors, slot-missing}).
-@end deffn
+@itemize @bullet
+@item
+What are the data members of this object or class?
-@deffn {primitive procedure} slot-ref obj slot-name
-Return the value of the slot named @var{slot-name} in @var{obj}.
+@item
+What classes does this class inherit from?
-@code{slot-ref} calls the generic function @code{slot-missing} if
-@var{obj} does not have a slot called @var{slot-name} (@pxref{Handling
-Slot Access Errors, slot-missing}).
+@item
+Is this method call virtual or non-virtual?
-@code{slot-ref} calls the generic function @code{slot-unbound} if the
-named slot in @var{obj} does not have a value (@pxref{Handling Slot
-Access Errors, slot-unbound}).
-@end deffn
+@item
+If I invoke @code{Employee::adjustHoliday()}, what class contains the
+@code{adjustHoliday()} method that will be applied?
+@end itemize
-@deffn {primitive procedure} slot-set! obj slot-name value
-Set the value of the slot named @var{slot-name} in @var{obj} to @var{value}.
+In C++, answers to such questions can only be determined by looking at
+the source code, if you have access to it. GOOPS, on the other hand,
+includes procedures that allow answers to these questions --- or their
+GOOPS equivalents --- to be obtained dynamically, at run time.
-@code{slot-set!} calls the generic function @code{slot-missing} if
-@var{obj} does not have a slot called @var{slot-name} (@pxref{Handling
-Slot Access Errors, slot-missing}).
-@end deffn
+@menu
+* Classes::
+* Instances::
+* Slots::
+* Generic Functions::
+* Accessing Slots::
+@end menu
-GOOPS stores information about slots in classes. Internally,
-all of these procedures work by looking up the slot definition for the
-slot named @var{slot-name} in the class @code{(class-of
-@var{obj})}, and then using the slot definition's ``getter'' and
-``setter'' closures to get and set the slot value.
+@node Classes
+@subsection Classes
-The next four procedures differ from the previous ones in that they take
-the class as an explicit argument, rather than assuming
-@code{(class-of @var{obj})}. Therefore they allow you to apply the
-``getter'' and ``setter'' closures of a slot definition in one class to
-an instance of a different class.
+A GOOPS class is itself an instance of the @code{<class>} class, or of a
+subclass of @code{<class>}. The definition of the @code{<class>} class
+has slots that are used to describe the properties of a class, including
+the following.
-@deffn {primitive procedure} slot-exists-using-class? class obj slot-name
-Return @code{#t} if @var{class} has a slot definition for a slot with
-name @var{slot-name}, otherwise @code{#f}.
+@deffn {primitive procedure} class-name class
+Return the name of class @var{class}. This is the value of
+@var{class}'s @code{name} slot.
@end deffn
-@deffn {primitive procedure} slot-bound-using-class? class obj slot-name
-Return @code{#t} if applying @code{slot-ref-using-class} to the same
-arguments would call the generic function @code{slot-unbound}, otherwise
-@code{#f}.
+@deffn {primitive procedure} class-direct-supers class
+Return a list containing the direct superclasses of @var{class}. This
+is the value of @var{class}'s @code{direct-supers} slot.
+@end deffn
-@code{slot-bound-using-class?} calls the generic function
-@code{slot-missing} if @var{class} does not have a slot definition for a
-slot called @var{slot-name} (@pxref{Handling Slot Access Errors,
-slot-missing}).
+@deffn {primitive procedure} class-direct-slots class
+Return a list containing the slot definitions of the direct slots of
+@var{class}. This is the value of @var{class}'s @code{direct-slots}
+slot.
@end deffn
-@deffn {primitive procedure} slot-ref-using-class class obj slot-name
-Apply the ``getter'' closure for the slot named @var{slot-name} in
-@var{class} to @var{obj}, and return its result.
+@deffn {primitive procedure} class-direct-subclasses class
+Return a list containing the direct subclasses of @var{class}. This is
+the value of @var{class}'s @code{direct-subclasses} slot.
+@end deffn
-@code{slot-ref-using-class} calls the generic function
-@code{slot-missing} if @var{class} does not have a slot definition for a
-slot called @var{slot-name} (@pxref{Handling Slot Access Errors,
-slot-missing}).
+@deffn {primitive procedure} class-direct-methods class
+Return a list of all the generic function methods that use @var{class}
+as a formal parameter specializer. This is the value of @var{class}'s
+@code{direct-methods} slot.
+@end deffn
-@code{slot-ref-using-class} calls the generic function
-@code{slot-unbound} if the application of the ``getter'' closure to
-@var{obj} returns an unbound value (@pxref{Handling Slot Access Errors,
-slot-unbound}).
+@deffn {primitive procedure} class-precedence-list class
+Return the class precedence list for class @var{class} (@pxref{Class
+Precedence List}). This is the value of @var{class}'s @code{cpl} slot.
@end deffn
-@deffn {primitive procedure} slot-set-using-class! class obj slot-name value
-Apply the ``setter'' closure for the slot named @var{slot-name} in
-@var{class} to @var{obj} and @var{value}.
+@deffn {primitive procedure} class-slots class
+Return a list containing the slot definitions for all @var{class}'s
+slots, including any slots that are inherited from superclasses. This
+is the value of @var{class}'s @code{slots} slot.
+@end deffn
-@code{slot-set-using-class!} calls the generic function
-@code{slot-missing} if @var{class} does not have a slot definition for a
-slot called @var{slot-name} (@pxref{Handling Slot Access Errors,
-slot-missing}).
+@deffn procedure class-subclasses class
+Return a list of all subclasses of @var{class}.
@end deffn
-@node Class Slots
-@subsection Class Slots
+@deffn procedure class-methods class
+Return a list of all methods that use @var{class} or a subclass of
+@var{class} as one of its formal parameter specializers.
+@end deffn
-Slots whose allocation is per-class rather than per-instance can be
-referenced and set without needing to specify any particular instance.
-@deffn procedure class-slot-ref class slot-name
-Return the value of the slot named @var{slot-name} in class @var{class}.
-The named slot must have @code{#:class} or @code{#:each-subclass}
-allocation (@pxref{Slot Options,, allocation}).
+@node Instances
+@subsection Instances
-If there is no such slot with @code{#:class} or @code{#:each-subclass}
-allocation, @code{class-slot-ref} calls the @code{slot-missing} generic
-function with arguments @var{class} and @var{slot-name}. Otherwise, if
-the slot value is unbound, @code{class-slot-ref} calls the
-@code{slot-unbound} generic function, with the same arguments.
+@deffn {primitive procedure} class-of value
+Return the GOOPS class of any Scheme @var{value}.
@end deffn
-@deffn procedure class-slot-set! class slot-name value
-Set the value of the slot named @var{slot-name} in class @var{class} to
-@var{value}. The named slot must have @code{#:class} or
-@code{#:each-subclass} allocation (@pxref{Slot Options,, allocation}).
+@deffn {primitive procedure} instance? object
+Return @code{#t} if @var{object} is any GOOPS instance, otherwise
+@code{#f}.
+@end deffn
-If there is no such slot with @code{#:class} or @code{#:each-subclass}
-allocation, @code{class-slot-ref} calls the @code{slot-missing} generic
-function with arguments @var{class} and @var{slot-name}.
+@deffn procedure is-a? object class
+Return @code{#t} if @var{object} is an instance of @var{class} or one of
+its subclasses.
@end deffn
-@node Handling Slot Access Errors
-@subsection Handling Slot Access Errors
+You can use the @code{is-a?} predicate to ask whether any given value
+belongs to a given class, or @code{class-of} to discover the class of a
+given value. Note that when GOOPS is loaded (by code using the
+@code{(oop goops)} module) built-in classes like @code{<string>},
+@code{<list>} and @code{<number>} are automatically set up,
+corresponding to all Guile Scheme types.
-GOOPS calls one of the following generic functions when a ``slot-ref''
-or ``slot-set!'' call specifies a non-existent slot name, or tries to
-reference a slot whose value is unbound.
+@lisp
+(is-a? 2.3 <number>) @result{} #t
+(is-a? 2.3 <real>) @result{} #t
+(is-a? 2.3 <string>) @result{} #f
+(is-a? '("a" "b") <string>) @result{} #f
+(is-a? '("a" "b") <list>) @result{} #t
+(is-a? (car '("a" "b")) <string>) @result{} #t
+(is-a? <string> <class>) @result{} #t
+(is-a? <class> <string>) @result{} #f
-@deffn generic slot-missing
-@deffnx method slot-missing (class <class>) slot-name
-@deffnx method slot-missing (class <class>) (object <object>) slot-name
-@deffnx method slot-missing (class <class>) (object <object>) slot-name value
-When an application attempts to reference or set a class or instance
-slot by name, and the slot name is invalid for the specified @var{class}
-or @var{object}, GOOPS calls the @code{slot-missing} generic function.
+(class-of 2.3) @result{} #<<class> <real> 908c708>
+(class-of #(1 2 3)) @result{} #<<class> <vector> 908cd20>
+(class-of <string>) @result{} #<<class> <class> 8bd3e10>
+(class-of <class>) @result{} #<<class> <class> 8bd3e10>
+@end lisp
-The default methods all call @code{goops-error} with an appropriate
-message.
-@end deffn
-@deffn generic slot-unbound
-@deffnx method slot-unbound (object <object>)
-@deffnx method slot-unbound (class <class>) slot-name
-@deffnx method slot-unbound (class <class>) (object <object>) slot-name
-When an application attempts to reference a class or instance slot, and
-the slot's value is unbound, GOOPS calls the @code{slot-unbound} generic
-function.
+@node Slots
+@subsection Slots
-The default methods all call @code{goops-error} with an appropriate
-message.
+@deffn procedure class-slot-definition class slot-name
+Return the slot definition for the slot named @var{slot-name} in class
+@var{class}. @var{slot-name} should be a symbol.
@end deffn
-@node Generic Functions and Accessors
-@section Generic Functions and Accessors
-
-A generic function is a collection of methods, with rules for
-determining which of the methods should be applied for any given
-invocation of the generic function. GOOPS represents generic functions
-as metaobjects of the class @code{<generic>} (or one of its subclasses).
+@deffn procedure slot-definition-name slot-def
+Extract and return the slot name from @var{slot-def}.
+@end deffn
-An accessor is a generic function that can also be used with the
-generalized @code{set!} syntax (@pxref{Procedures with Setters}). Guile
-will handle a call like
+@deffn procedure slot-definition-options slot-def
+Extract and return the slot options from @var{slot-def}.
+@end deffn
-@example
-(set! (@code{accessor} @code{args}@dots{}) @code{value})
-@end example
-
-@noindent
-by calling the most specialized method of @code{accessor} that matches
-the classes of @code{args} and @code{value}.
-
-The following forms define a variable as a generic function or accessor.
-Depending on that variable's previous value, the generic function may be
-created empty --- with no methods --- or with methods that are inferred
-from the previous value.
-
-@deffn syntax define-generic symbol
-Create a generic function with name @var{symbol} and bind it to the
-variable @var{symbol}. If @var{symbol} was previously bound to a Scheme
-procedure (or procedure-with-setter), the old procedure (and setter) is
-incorporated into the new generic function as its default procedure (and
-setter). Any other previous value, including an existing generic
-function, is discarded and replaced by a new, empty generic function.
-@end deffn
-
-@deffn syntax define-accessor symbol
-Create an accessor with name @var{symbol} and bind it to the variable
-@var{symbol}. If @var{symbol} was previously bound to a Scheme
-procedure (or procedure-with-setter), the old procedure (and setter) is
-incorporated into the new accessor as its default procedure (and
-setter). Any other previous value, including an existing generic
-function or accessor, is discarded and replaced by a new, empty
-accessor.
-@end deffn
-
-@menu
-* Extending Primitives::
-* Merging Generics::
-@end menu
-
-@node Extending Primitives
-@subsection Extending Primitives
-
-Many of Guile's primitive procedures can be extended by giving them a
-generic function definition that operates in conjunction with their
-normal C-coded implementation. When a primitive is extended in this
-way, it behaves like a generic function with the C-coded implementation
-as its default method.
-
-This extension happens automatically if a method is defined (by a
-@code{define-method} call) for a variable whose current value is a
-primitive. But it can also be forced by calling
-@code{enable-primitive-generic!}.
-
-@deffn {primitive procedure} enable-primitive-generic! primitive
-Force the creation of a generic function definition for
-@var{primitive}.
-@end deffn
-
-Once the generic function definition for a primitive has been created,
-it can be retrieved using @code{primitive-generic-generic}.
-
-@deffn {primitive procedure} primitive-generic-generic primitive
-Return the generic function definition of @var{primitive}.
-
-@code{primitive-generic-generic} raises an error if @var{primitive}
-is not a primitive with generic capability.
-@end deffn
-
-@node Merging Generics
-@subsection Merging Generics
-
-GOOPS generic functions and accessors often have short, generic names.
-For example, if a vector package provides an accessor for the X
-coordinate of a vector, that accessor may just be called @code{x}. It
-doesn't need to be called, for example, @code{vector:x}, because
-GOOPS will work out, when it sees code like @code{(x @var{obj})}, that
-the vector-specific method of @code{x} should be called if @var{obj} is
-a vector.
-
-That raises the question, however, of what happens when different
-packages define a generic function with the same name. Suppose we
-work with a graphical package which needs to use two independent vector
-packages for 2D and 3D vectors respectively. If both packages export
-@code{x}, what does the code using those packages end up with?
-
-@ref{Creating Guile Modules,,duplicate binding handlers} explains how
-this is resolved for conflicting bindings in general. For generics,
-there is a special duplicates handler, @code{merge-generics}, which
-tells the module system to merge generic functions with the same name.
-Here is an example:
-
-@lisp
-(define-module (math 2D-vectors)
- #:use-module (oop goops)
- #:export (x y ...))
-
-(define-module (math 3D-vectors)
- #:use-module (oop goops)
- #:export (x y z ...))
-
-(define-module (my-module)
- #:use-module (math 2D-vectors)
- #:use-module (math 3D-vectors)
- #:duplicates merge-generics)
-@end lisp
-
-The generic function @code{x} in @code{(my-module)} will now incorporate
-all of the methods of @code{x} from both imported modules.
-
-To be precise, there will now be three distinct generic functions named
-@code{x}: @code{x} in @code{(math 2D-vectors)}, @code{x} in @code{(math
-3D-vectors)}, and @code{x} in @code{(my-module)}; and these functions
-share their methods in an interesting and dynamic way.
-
-To explain, let's call the imported generic functions (in @code{(math
-2D-vectors)} and @code{(math 3D-vectors)}) the @dfn{ancestors}, and the
-merged generic function (in @code{(my-module)}), the @dfn{descendant}.
-The general rule is that for any generic function G, the applicable
-methods are selected from the union of the methods of G's descendant
-functions, the methods of G itself and the methods of G's ancestor
-functions.
-
-Thus ancestor functions effectively share methods with their
-descendants, and vice versa. In the example above, @code{x} in
-@code{(math 2D-vectors)} will share the methods of @code{x} in
-@code{(my-module)} and vice versa.@footnote{But note that @code{x} in
-@code{(math 2D-vectors)} doesn't share methods with @code{x} in
-@code{(math 3D-vectors)}, so modularity is still preserved.} Sharing is
-dynamic, so adding another new method to a descendant implies adding it
-to that descendant's ancestors too.
-
-@node Adding Methods to Generic Functions
-@section Adding Methods to Generic Functions
-
-To add a method to a generic function, use @code{define-method}.
-
-@deffn syntax define-method (generic parameter @dots{}) . body
-Define a method for the generic function or accessor @var{generic} with
-parameters @var{parameter}s and body @var{body}.
-
-@var{generic} is a generic function. If @var{generic} is a variable
-which is not yet bound to a generic function object, the expansion of
-@code{define-method} will include a call to @code{define-generic}. If
-@var{generic} is @code{(setter @var{generic-with-setter})}, where
-@var{generic-with-setter} is a variable which is not yet bound to a
-generic-with-setter object, the expansion will include a call to
-@code{define-accessor}.
-
-Each @var{parameter} must be either a symbol or a two-element list
-@code{(@var{symbol} @var{class})}. The symbols refer to variables in
-the @var{body} that will be bound to the parameters supplied by the
-caller when calling this method. The @var{class}es, if present,
-specify the possible combinations of parameters to which this method
-can be applied.
-
-@var{body} is the body of the method definition.
-@end deffn
-
-@code{define-method} expressions look a little like Scheme procedure
-definitions of the form
-
-@example
-(define (name formals @dots{}) . body)
-@end example
-
-The important difference is that each formal parameter, apart from the
-possible ``rest'' argument, can be qualified by a class name:
-@code{@var{formal}} becomes @code{(@var{formal} @var{class})}. The
-meaning of this qualification is that the method being defined
-will only be applicable in a particular generic function invocation if
-the corresponding argument is an instance of @code{@var{class}} (or one of
-its subclasses). If more than one of the formal parameters is qualified
-in this way, then the method will only be applicable if each of the
-corresponding arguments is an instance of its respective qualifying class.
-
-Note that unqualified formal parameters act as though they are qualified
-by the class @code{<top>}, which GOOPS uses to mean the superclass of
-all valid Scheme types, including both primitive types and GOOPS classes.
-
-For example, if a generic function method is defined with
-@var{parameter}s @code{((s1 <square>) (n <number>))}, that method is
-only applicable to invocations of its generic function that have two
-parameters where the first parameter is an instance of the
-@code{<square>} class and the second parameter is a number.
-
-@node Invoking Generic Functions
-@section Invoking Generic Functions
-
-When a variable with a generic function definition appears as the first
-element of a list that is being evaluated, the Guile evaluator tries
-to apply the generic function to the arguments obtained by evaluating
-the remaining elements of the list. [ *fixme* How do I put this in a
-more Schemely and less Lispy way? ]
-
-Usually a generic function contains several method definitions, with
-varying degrees of formal parameter specialization (@pxref{Adding
-Methods to Generic Functions,, define-method}). So it is necessary to
-sort these methods by specificity with respect to the supplied
-arguments, and then apply the most specific method definition. Less
-specific methods may be applied subsequently if a method that is being
-applied calls @code{next-method}.
-
-If a generic function is invoked with a combination of parameters for
-which there is no applicable method, GOOPS raises an error.
-
-@menu
-* Determining Which Methods to Apply::
-* Handling Invocation Errors::
-@end menu
-
-@node Determining Which Methods to Apply
-@subsection Determining Which Methods to Apply
-
-[ *fixme* Sorry - this is the area of GOOPS that I understand least of
-all, so I'm afraid I have to pass on this section. Would some other
-kind person consider filling it in? ]
-
-@deffn generic apply-generic
-@deffnx method apply-generic (gf <generic>) args
-@end deffn
-
-@deffn generic compute-applicable-methods
-@deffnx method compute-applicable-methods (gf <generic>) args
-@end deffn
-
-@deffn generic sort-applicable-methods
-@deffnx method sort-applicable-methods (gf <generic>) methods args
-@end deffn
-
-@deffn generic method-more-specific?
-@deffnx method method-more-specific? (m1 <method>) (m2 <method>) args
-@end deffn
-
-@deffn generic apply-method
-@deffnx method apply-method (gf <generic>) methods build-next args
-@end deffn
-
-@deffn generic apply-methods
-@deffnx method apply-methods (gf <generic>) (l <list>) args
-@end deffn
-
-@node Handling Invocation Errors
-@subsection Handling Invocation Errors
-
-@deffn generic no-method
-@deffnx method no-method (gf <generic>) args
-When an application invokes a generic function, and no methods at all
-have been defined for that generic function, GOOPS calls the
-@code{no-method} generic function. The default method calls
-@code{goops-error} with an appropriate message.
-@end deffn
-
-@deffn generic no-applicable-method
-@deffnx method no-applicable-method (gf <generic>) args
-When an application applies a generic function to a set of arguments,
-and no methods have been defined for those argument types, GOOPS calls
-the @code{no-applicable-method} generic function. The default method
-calls @code{goops-error} with an appropriate message.
-@end deffn
-
-@deffn generic no-next-method
-@deffnx method no-next-method (gf <generic>) args
-When a generic function method calls @code{(next-method)} to invoke the
-next less specialized method for that generic function, and no less
-specialized methods have been defined for the current generic function
-arguments, GOOPS calls the @code{no-next-method} generic function. The
-default method calls @code{goops-error} with an appropriate message.
-@end deffn
-
-@node Redefining a Class
-@section Redefining a Class
-
-Suppose that a class @code{<my-class>} is defined using @code{define-class}
-(@pxref{Class Definition,, define-class}), with slots that have
-accessor functions, and that an application has created several instances
-of @code{<my-class>} using @code{make} (@pxref{Instance Creation,,
-make}). What then happens if @code{<my-class>} is redefined by calling
-@code{define-class} again?
-
-@menu
-* Default Class Redefinition Behaviour::
-* Customizing Class Redefinition::
-@end menu
-
-@node Default Class Redefinition Behaviour
-@subsection Default Class Redefinition Behaviour
-
-GOOPS' default answer to this question is as follows.
-
-@itemize @bullet
-@item
-All existing direct instances of @code{<my-class>} are converted to be
-instances of the new class. This is achieved by preserving the values
-of slots that exist in both the old and new definitions, and
-initializing the values of new slots in the usual way (@pxref{Instance
-Creation,, make}).
-
-@item
-All existing subclasses of @code{<my-class>} are redefined, as though
-the @code{define-class} expressions that defined them were re-evaluated
-following the redefinition of @code{<my-class>}, and the class
-redefinition process described here is applied recursively to the
-redefined subclasses.
-
-@item
-Once all of its instances and subclasses have been updated, the class
-metaobject previously bound to the variable @code{<my-class>} is no
-longer needed and so can be allowed to be garbage collected.
-@end itemize
-
-To keep things tidy, GOOPS also needs to do a little housekeeping on
-methods that are associated with the redefined class.
-
-@itemize @bullet
-@item
-Slot accessor methods for slots in the old definition should be removed
-from their generic functions. They will be replaced by accessor methods
-for the slots of the new class definition.
-
-@item
-Any generic function method that uses the old @code{<my-class>} metaobject
-as one of its formal parameter specializers must be updated to refer to
-the new @code{<my-class>} metaobject. (Whenever a new generic function
-method is defined, @code{define-method} adds the method to a list stored
-in the class metaobject for each class used as a formal parameter
-specializer, so it is easy to identify all the methods that must be
-updated when a class is redefined.)
-@end itemize
-
-If this class redefinition strategy strikes you as rather counter-intuitive,
-bear in mind that it is derived from similar behaviour in other object
-systems such as CLOS, and that experience in those systems has shown it to be
-very useful in practice.
-
-Also bear in mind that, like most of GOOPS' default behaviour, it can
-be customized@dots{}
-
-@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
-@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
-be customized by defining a @code{class-redefinition} method that is
-specialized for the relevant metaclasses.
-
-@deffn generic class-redefinition
-Handle the class redefinition from @var{old-class} to @var{new-class},
-and return the new class metaobject that should be bound to the
-variable specified by @code{define-class}'s first argument.
-@end deffn
-
-@deffn method class-redefinition (old-class <class>) (new-class <class>)
-Implements GOOPS' default class redefinition behaviour, as described in
-@ref{Default Class Redefinition Behaviour}. Returns the metaobject
-for the new class definition.
-@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
-new definition. In this strategy, any existing subclasses could also
-be left as they are, on the understanding that they inherit from a nameless
-superclass.
-
-This strategy is easily implemented in GOOPS, by defining a new metaclass,
-that will be used as the metaclass for all classes to which the strategy
-should apply, and then defining a @code{class-redefinition} method that
-is specialized for this metaclass:
-
-@example
-(define-class <can-be-nameless> (<class>))
-
-(define-method (class-redefinition (old <can-be-nameless>)
- (new <class>))
- new)
-@end example
-
-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.
-
-@deffn generic change-class
-@end deffn
-
-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
-existing class and for the new class. If the new class has slots with
-the same name as slots in the existing class, the values for those slots
-are preserved. Slots that are present only in the existing class are
-discarded. Slots that are present only in the new class are initialized
-using the corresponding slot definition's init function (@pxref{Classes,,
-slot-init-function}).
-
-@deffn {method} change-class (obj <object>) (new <class>)
-Modify instance @var{obj} to make it an instance of class @var{new}.
-
-The value of each of @var{obj}'s slots is preserved only if a similarly named
-slot exists in @var{new}; any other slot values are discarded.
-
-The slots in @var{new} that do not correspond to any of @var{obj}'s
-pre-existing slots are initialized according to @var{new}'s slot definitions'
-init functions.
-@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.
-
-@node Introspection
-@section Introspection
-
-@dfn{Introspection}, also known as @dfn{reflection}, is the name given
-to the ability to obtain information dynamically about GOOPS metaobjects.
-It is perhaps best illustrated by considering an object oriented language
-that does not provide any introspection, namely C++.
-
-Nothing in C++ allows a running program to obtain answers to the following
-types of question:
-
-@itemize @bullet
-@item
-What are the data members of this object or class?
-
-@item
-What classes does this class inherit from?
-
-@item
-Is this method call virtual or non-virtual?
-
-@item
-If I invoke @code{Employee::adjustHoliday()}, what class contains the
-@code{adjustHoliday()} method that will be applied?
-@end itemize
-
-In C++, answers to such questions can only be determined by looking at
-the source code, if you have access to it. GOOPS, on the other hand,
-includes procedures that allow answers to these questions --- or their
-GOOPS equivalents --- to be obtained dynamically, at run time.
-
-@menu
-* Classes::
-* Slots::
-* Instances::
-* Built-in classes::
-* Generic Functions::
-* Generic Function Methods::
-@end menu
-
-@node Classes
-@subsection Classes
-
-@deffn {primitive procedure} class-name class
-Return the name of class @var{class}.
-This is the value of the @var{class} metaobject's @code{name} slot.
-@end deffn
-
-@deffn {primitive procedure} class-direct-supers class
-Return a list containing the direct superclasses of @var{class}.
-This is the value of the @var{class} metaobject's
-@code{direct-supers} slot.
-@end deffn
-
-@deffn {primitive procedure} class-direct-slots class
-Return a list containing the slot definitions of the direct slots of
-@var{class}.
-This is the value of the @var{class} metaobject's @code{direct-slots}
-slot.
-@end deffn
-
-@deffn {primitive procedure} class-direct-subclasses class
-Return a list containing the direct subclasses of @var{class}.
-This is the value of the @var{class} metaobject's
-@code{direct-subclasses} slot.
-@end deffn
-
-@deffn {primitive procedure} class-direct-methods class
-Return a list of all the generic function methods that use @var{class}
-as a formal parameter specializer.
-This is the value of the @var{class} metaobject's @code{direct-methods}
-slot.
-@end deffn
-
-@deffn {primitive procedure} class-precedence-list class
-Return the class precedence list for class @var{class} (@pxref{Class
-precedence list}).
-This is the value of the @var{class} metaobject's @code{cpl} slot.
-@end deffn
-
-@deffn {primitive procedure} class-slots class
-Return a list containing the slot definitions for all @var{class}'s slots,
-including any slots that are inherited from superclasses.
-This is the value of the @var{class} metaobject's @code{slots} slot.
-@end deffn
-
-@deffn {primitive procedure} class-environment class
-Return the value of @var{class}'s @code{environment} slot.
-[ *fixme* I don't know what this value is used for. ]
-@end deffn
-
-@deffn procedure class-subclasses class
-Return a list of all subclasses of @var{class}.
-@end deffn
-
-@deffn procedure class-methods class
-Return a list of all methods that use @var{class} or a subclass of
-@var{class} as one of its formal parameter specializers.
-@end deffn
-
-@node Slots
-@subsection Slots
-
-@deffn procedure class-slot-definition class slot-name
-Return the slot definition for the slot named @var{slot-name} in class
-@var{class}. @var{slot-name} should be a symbol.
-@end deffn
-
-@deffn procedure slot-definition-name slot-def
-Extract and return the slot name from @var{slot-def}.
-@end deffn
-
-@deffn procedure slot-definition-options slot-def
-Extract and return the slot options from @var{slot-def}.
-@end deffn
-
-@deffn procedure slot-definition-allocation slot-def
-Extract and return the slot allocation option from @var{slot-def}. This
-is the value of the @code{#:allocation} keyword (@pxref{Slot Options,,
-allocation}), or @code{#:instance} if the @code{#:allocation} keyword is
-absent.
-@end deffn
+@deffn procedure slot-definition-allocation slot-def
+Extract and return the slot allocation option from @var{slot-def}. This
+is the value of the @code{#:allocation} keyword (@pxref{Slot Options,,
+allocation}), or @code{#:instance} if the @code{#:allocation} keyword is
+absent.
+@end deffn
@deffn procedure slot-definition-getter slot-def
Extract and return the slot getter option from @var{slot-def}. This is
see @ref{Slot Options,, init-value}.
@end deffn
-@node Instances
-@subsection Instances
-@deffn {primitive procedure} class-of value
-Return the GOOPS class of any Scheme @var{value}.
+@node Generic Functions
+@subsection Generic Functions
+
+A generic function is an instance of the @code{<generic>} class, or of a
+subclass of @code{<generic>}. The definition of the @code{<generic>}
+class has slots that are used to describe the properties of a generic
+function.
+
+@deffn {primitive procedure} generic-function-name gf
+Return the name of generic function @var{gf}.
@end deffn
-@deffn {primitive procedure} instance? object
-Return @code{#t} if @var{object} is any GOOPS instance, otherwise
-@code{#f}.
+@deffn {primitive procedure} generic-function-methods gf
+Return a list of the methods of generic function @var{gf}. This is the
+value of @var{gf}'s @code{methods} slot.
@end deffn
-@deffn procedure is-a? object class
-Return @code{#t} if @var{object} is an instance of @var{class} or one of
-its subclasses.
+Similarly, a method is an instance of the @code{<method>} class, or of a
+subclass of @code{<method>}; and the definition of the @code{<method>}
+class has slots that are used to describe the properties of a method.
+
+@deffn {primitive procedure} method-generic-function method
+Return the generic function that @var{method} belongs to. This is the
+value of @var{method}'s @code{generic-function} slot.
@end deffn
-Implementation notes: @code{is-a?} uses @code{class-of} and
-@code{class-precedence-list} to obtain the class precedence list for
-@var{object}.
+@deffn {primitive procedure} method-specializers method
+Return a list of @var{method}'s formal parameter specializers . This is
+the value of @var{method}'s @code{specializers} slot.
+@end deffn
-@node Built-in classes
-@subsection Built-in classes
+@deffn {primitive procedure} method-procedure method
+Return the procedure that implements @var{method}. This is the value of
+@var{method}'s @code{procedure} slot.
+@end deffn
-There are built-in classes like @code{<string>}, @code{<list>} and
-@code{<number>} corresponding to all the Guile Scheme types. You can
-use the @code{is-a?} predicate to ask whether any given value belongs to
-a given class, or @code{class-of} to discover the class of a given
-value.
+@deffn generic method-source
+@deffnx method method-source (m <method>)
+Return an expression that prints to show the definition of method
+@var{m}.
-@lisp
-(is-a? 2.3 <number>) @result{} #t
-(is-a? 2.3 <real>) @result{} #t
-(is-a? 2.3 <string>) @result{} #f
-(is-a? '("a" "b") <string>) @result{} #f
-(is-a? '("a" "b") <list>) @result{} #t
-(is-a? (car '("a" "b")) <string>) @result{} #t
-(is-a? <string> <class>) @result{} #t
-(is-a? <class> <string>) @result{} #f
+@example
+(define-generic cube)
-(class-of 2.3) @result{} #<<class> <real> 908c708>
-(class-of #(1 2 3)) @result{} #<<class> <vector> 908cd20>
-(class-of <string>) @result{} #<<class> <class> 8bd3e10>
-(class-of <class>) @result{} #<<class> <class> 8bd3e10>
-@end lisp
+(define-method (cube (n <number>))
+ (* n n n))
+(map method-source (generic-function-methods cube))
+@result{}
+((method ((n <number>)) (* n n n)))
+@end example
+@end deffn
-@node Generic Functions
-@subsection Generic Functions
-@deffn {primitive procedure} generic-function-name gf
-Return the name of generic function @var{gf}.
+@node Accessing Slots
+@subsection Accessing Slots
+
+Any slot, regardless of its allocation, can be queried, referenced and
+set using the following four primitive procedures.
+
+@deffn {primitive procedure} slot-exists? obj slot-name
+Return @code{#t} if @var{obj} has a slot with name @var{slot-name},
+otherwise @code{#f}.
+@end deffn
+
+@deffn {primitive procedure} slot-bound? obj slot-name
+Return @code{#t} if the slot named @var{slot-name} in @var{obj} has a
+value, otherwise @code{#f}.
+
+@code{slot-bound?} calls the generic function @code{slot-missing} if
+@var{obj} does not have a slot called @var{slot-name} (@pxref{Accessing
+Slots, slot-missing}).
+@end deffn
+
+@deffn {primitive procedure} slot-ref obj slot-name
+Return the value of the slot named @var{slot-name} in @var{obj}.
+
+@code{slot-ref} calls the generic function @code{slot-missing} if
+@var{obj} does not have a slot called @var{slot-name} (@pxref{Accessing
+Slots, slot-missing}).
+
+@code{slot-ref} calls the generic function @code{slot-unbound} if the
+named slot in @var{obj} does not have a value (@pxref{Accessing Slots,
+slot-unbound}).
+@end deffn
+
+@deffn {primitive procedure} slot-set! obj slot-name value
+Set the value of the slot named @var{slot-name} in @var{obj} to @var{value}.
+
+@code{slot-set!} calls the generic function @code{slot-missing} if
+@var{obj} does not have a slot called @var{slot-name} (@pxref{Accessing
+Slots, slot-missing}).
+@end deffn
+
+GOOPS stores information about slots in classes. Internally,
+all of these procedures work by looking up the slot definition for the
+slot named @var{slot-name} in the class @code{(class-of
+@var{obj})}, and then using the slot definition's ``getter'' and
+``setter'' closures to get and set the slot value.
+
+The next four procedures differ from the previous ones in that they take
+the class as an explicit argument, rather than assuming
+@code{(class-of @var{obj})}. Therefore they allow you to apply the
+``getter'' and ``setter'' closures of a slot definition in one class to
+an instance of a different class.
+
+@deffn {primitive procedure} slot-exists-using-class? class obj slot-name
+Return @code{#t} if @var{class} has a slot definition for a slot with
+name @var{slot-name}, otherwise @code{#f}.
+@end deffn
+
+@deffn {primitive procedure} slot-bound-using-class? class obj slot-name
+Return @code{#t} if applying @code{slot-ref-using-class} to the same
+arguments would call the generic function @code{slot-unbound}, otherwise
+@code{#f}.
+
+@code{slot-bound-using-class?} calls the generic function
+@code{slot-missing} if @var{class} does not have a slot definition for a
+slot called @var{slot-name} (@pxref{Accessing Slots,
+slot-missing}).
+@end deffn
+
+@deffn {primitive procedure} slot-ref-using-class class obj slot-name
+Apply the ``getter'' closure for the slot named @var{slot-name} in
+@var{class} to @var{obj}, and return its result.
+
+@code{slot-ref-using-class} calls the generic function
+@code{slot-missing} if @var{class} does not have a slot definition for a
+slot called @var{slot-name} (@pxref{Accessing Slots,
+slot-missing}).
+
+@code{slot-ref-using-class} calls the generic function
+@code{slot-unbound} if the application of the ``getter'' closure to
+@var{obj} returns an unbound value (@pxref{Accessing Slots,
+slot-unbound}).
@end deffn
-@deffn {primitive procedure} generic-function-methods gf
-Return a list of the methods of generic function @var{gf}.
-This is the value of the @var{gf} metaobject's @code{methods} slot.
+@deffn {primitive procedure} slot-set-using-class! class obj slot-name value
+Apply the ``setter'' closure for the slot named @var{slot-name} in
+@var{class} to @var{obj} and @var{value}.
+
+@code{slot-set-using-class!} calls the generic function
+@code{slot-missing} if @var{class} does not have a slot definition for a
+slot called @var{slot-name} (@pxref{Accessing Slots, slot-missing}).
+@end deffn
+
+Slots whose allocation is per-class rather than per-instance can be
+referenced and set without needing to specify any particular instance.
+
+@deffn procedure class-slot-ref class slot-name
+Return the value of the slot named @var{slot-name} in class @var{class}.
+The named slot must have @code{#:class} or @code{#:each-subclass}
+allocation (@pxref{Slot Options,, allocation}).
+
+If there is no such slot with @code{#:class} or @code{#:each-subclass}
+allocation, @code{class-slot-ref} calls the @code{slot-missing} generic
+function with arguments @var{class} and @var{slot-name}. Otherwise, if
+the slot value is unbound, @code{class-slot-ref} calls the
+@code{slot-unbound} generic function, with the same arguments.
@end deffn
-@node Generic Function Methods
-@subsection Generic Function Methods
-
-@deffn {primitive procedure} method-generic-function method
-Return the generic function that @var{method} belongs to.
-This is the value of the @var{method} metaobject's
-@code{generic-function} slot.
-@end deffn
+@deffn procedure class-slot-set! class slot-name value
+Set the value of the slot named @var{slot-name} in class @var{class} to
+@var{value}. The named slot must have @code{#:class} or
+@code{#:each-subclass} allocation (@pxref{Slot Options,, allocation}).
-@deffn {primitive procedure} method-specializers method
-Return a list of @var{method}'s formal parameter specializers .
-This is the value of the @var{method} metaobject's
-@code{specializers} slot.
+If there is no such slot with @code{#:class} or @code{#:each-subclass}
+allocation, @code{class-slot-ref} calls the @code{slot-missing} generic
+function with arguments @var{class} and @var{slot-name}.
@end deffn
-@deffn {primitive procedure} method-procedure method
-Return the procedure that implements @var{method}.
-This is the value of the @var{method} metaobject's
-@code{procedure} slot.
-@end deffn
+When a @code{slot-ref} or @code{slot-set!} call specifies a non-existent
+slot name, or tries to reference a slot whose value is unbound, GOOPS
+calls one of the following generic functions.
-@deffn generic method-source
-@deffnx method method-source (m <method>)
-Return an expression that prints to show the definition of method
-@var{m}.
+@deffn generic slot-missing
+@deffnx method slot-missing (class <class>) slot-name
+@deffnx method slot-missing (class <class>) (object <object>) slot-name
+@deffnx method slot-missing (class <class>) (object <object>) slot-name value
+When an application attempts to reference or set a class or instance
+slot by name, and the slot name is invalid for the specified @var{class}
+or @var{object}, GOOPS calls the @code{slot-missing} generic function.
-@example
-(define-generic cube)
+The default methods all call @code{goops-error} with an appropriate
+message.
+@end deffn
-(define-method (cube (n <number>))
- (* n n n))
+@deffn generic slot-unbound
+@deffnx method slot-unbound (object <object>)
+@deffnx method slot-unbound (class <class>) slot-name
+@deffnx method slot-unbound (class <class>) (object <object>) slot-name
+When an application attempts to reference a class or instance slot, and
+the slot's value is unbound, GOOPS calls the @code{slot-unbound} generic
+function.
-(map method-source (generic-function-methods cube))
-@result{}
-((method ((n <number>)) (* n n n)))
-@end example
+The default methods all call @code{goops-error} with an appropriate
+message.
@end deffn
+
@node GOOPS Error Handling
@section Error Handling
@itemize @bullet
@item
-@code{slot-missing} (@pxref{Handling Slot Access Errors,, slot-missing})
+@code{slot-missing} (@pxref{Accessing Slots,, slot-missing})
@item
-@code{slot-unbound} (@pxref{Handling Slot Access Errors,, slot-unbound})
+@code{slot-unbound} (@pxref{Accessing Slots,, slot-unbound})
@item
@code{no-method} (@pxref{Handling Invocation Errors,, no-method})
you may still want to use @code{goops-error} to signal any error
conditions that you detect.
-@deffn procedure goops-error format-string . args
+@deffn procedure goops-error format-string arg @dots{}
Raise an error with key @code{goops-error} and error message constructed
-from @var{format-string} and @var{args}. Error message formatting is
-as done by @code{scm-error}.
-@end deffn
-
-@node Object Comparisons
-@section Object Comparisons
-
-@deffn generic eqv?
-@deffnx method eqv? ((x <top>) (y <top>))
-@deffnx generic equal?
-@deffnx method equal? ((x <top>) (y <top>))
-@deffnx generic =
-@deffnx method = ((x <number>) (y <number>))
-Generic functions and default (unspecialized) methods for comparing two
-GOOPS objects.
-
-The default method for @code{eqv?} returns @code{#t} for all values
-that are equal in the sense defined by R5RS and the Guile reference
-manual, otherwise @code{#f}. The default method for @code{equal?}
-returns @code{#t} or @code{#f} in the sense defined by R5RS and the
-Guile reference manual. If no such comparison is defined,
-@code{equal?} returns the result of a call to @code{eqv?}. The
-default method for = returns @code{#t} if @var{x} and @var{y} are
-numerically equal, otherwise @code{#f}.
-
-Application class authors may wish to define specialized methods for
-@code{eqv?}, @code{equal?} and @code{=} that compare instances of the
-same class for equality in whatever sense is useful to the
-application. Such methods will only be called if the arguments have
-the same class and the result of the comparison isn't defined by R5RS
-and the Guile reference manual.
-@end deffn
-
-@node Cloning Objects
-@section Cloning Objects
+from @var{format-string} and @var{arg} @enddots{}. Error message
+formatting is as done by @code{scm-error}.
+@end deffn
+
+
+@node GOOPS Object Miscellany
+@section GOOPS Object Miscellany
+
+Here we cover some points about GOOPS objects that aren't substantial
+enough to merit sections on their own.
+
+@subheading Object Equality
+
+When GOOPS is loaded, @code{eqv?}, @code{equal?} and @code{=} become
+generic functions, and you can define methods for them, specialized for
+your own classes, so as to control what the various kinds of equality
+mean for your classes.
+
+For example, the @code{assoc} procedure, for looking up an entry in an
+alist, is specified as using @code{equal?} to determine when the car of
+an entry in the alist is the same as the key parameter that @code{assoc}
+is called with. Hence, if you had defined a new class, and wanted to
+use instances of that class as the keys in an alist, you could define a
+method for @code{equal?}, for your class, to control @code{assoc}'s
+lookup precisely.
+
+@subheading Cloning Objects
@deffn generic shallow-clone
@deffnx method shallow-clone (self <object>)
or by reference.
@end deffn
-@node Write and Display
-@section Write and Display
+@subheading Write and Display
@deffn {primitive generic} write object port
@deffnx {primitive generic} display object port
as the Guile primitive @code{write} and @code{display} functions.
@end deffn
+In addition to the cases mentioned, you can of course define
+@code{write} and @code{display} methods for your own classes, to
+customize how instances of those classes are printed.
+
+
@node The Metaobject Protocol
@section The Metaobject Protocol
-GOOPS is based on a ``metaobject protocol'' (aka ``MOP'') derived from
-the ones used in CLOS (the Common Lisp Object 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.
+At this point, we've said about as much as can be said about GOOPS
+without having to confront the idea of the metaobject protocol. There
+are a couple more topics that could be discussed in isolation first ---
+class redefinition, and changing the class of existing instances --- but
+in practice developers using them will be advanced enough to want to
+understand the metaobject protocol too, and will probably be using the
+protocol to customize exactly what happens during these events.
+
+So let's plunge in. GOOPS is based on a ``metaobject protocol'' (aka
+``MOP'') derived from the ones used in CLOS (the Common Lisp Object
+System), tiny-clos (a small Scheme implementation of a subset of CLOS
+functionality) and STKlos.
+
+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))
+ (make <class> #:dsupers (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{#:dsupers} 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>
- (make <my-metaclass> #:supers (list <object>) #:slots slots))
+ (make <my-metaclass> #:dsupers (list <object>) #:slots slots))
@end example
In this case, the value of @code{<my-class2>} is an instance of the more
@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.
+
+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
-@code{initialize <class> @var{initargs}} (method)
+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
+
+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.
-@code{define-class} expands to an expression which
+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,
(@pxref{Redefining a Class}).
@end itemize
-@deffn syntax class name (super @dots{}) slot-definition @dots{} . options
+@deffn syntax class name (super @dots{}) @
+ slot-definition @dots{} class-option @dots{}
Return a newly created class that inherits from @var{super}s, with
-direct slots defined by @var{slot-definition}s and class options
-@var{options}. For the format of @var{slot-definition}s and
-@var{options}, see @ref{Class Definition,, define-class}.
+direct slots defined by @var{slot-definition}s and @var{class-option}s.
+For the format of @var{slot-definition}s and @var{class-option}s, see
+@ref{Class Definition,, define-class}.
@end deffn
@noindent @code{class} expands to an expression which
evaluated parameters.
@end itemize
-@deffn procedure make-class supers slots . options
+@deffn procedure make-class supers slots class-option @dots{}
Return a newly created class that inherits from @var{supers}, with
-direct slots defined by @var{slots} and class options @var{options}.
-For the format of @var{slots} and @var{options}, see @ref{Class
+direct slots defined by @var{slots} and @var{class-option}s. For the
+format of @var{slots} and @var{class-option}s, see @ref{Class
Definition,, define-class}, except note that for @code{make-class},
-@var{slots} and @var{options} are separate list parameters: @var{slots}
-here is a list of slot definitions.
+@var{slots} is a separate list of slot definitions.
@end deffn
@noindent @code{make-class}
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 initarg @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
-
-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
-
-@itemize @bullet
-@item
-(initialize @var{class} @dots{})
-@end itemize
+The @code{(make @var{metaclass} @var{initarg} @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>}.
-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 @code{initialize} method for classes (signature @code{(initialize
+<class> initargs)}) calls the following generic functions.
@itemize @bullet
@item
-(compute-cpl @var{class})
+@code{compute-cpl @var{class}} (generic)
-@item
-(compute-slots @var{class})
+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.
@item
-(compute-get-n-set @var{class} @var{slot-def}), for each of the slot
-definitions returned by @code{compute-slots}
+@code{compute-slots @var{class}} (generic)
-@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
+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-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.
-@end itemize
-
-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
-to define generic function methods, specialized for the new class's
-metaclass, that can modify or override the default behaviour of
-@code{initialize}, @code{compute-cpl} or @code{compute-get-n-set}.
-
-@code{compute-cpl} computes the class precedence list (``CPL'') for the
-new class (@pxref{Class precedence list}), and returns it as a list of
-class objects. The CPL is important because it defines a superclass
-ordering that is used, when a generic function is invoked upon an
-instance of the class, to decide which of the available generic function
-methods is the most specific. Hence @code{compute-cpl} could be
-customized in order to modify the CPL ordering algorithm for all classes
-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.
-
-@deffn procedure compute-std-cpl class
-Compute and return the class precedence list for @var{class} according
-to the algorithm described in @ref{Class precedence list}.
-@end deffn
-
-@code{compute-slots} computes and returns a list of all slot definitions
-for the new class. By default, this list includes the direct slot
-definitions from the @code{define-class} form, plus the slot definitions
-that are inherited from the new class's superclasses. The default
-@code{compute-slots} method uses the CPL computed by @code{compute-cpl}
-to calculate this union of slot definitions, with the rule that slots
-inherited from superclasses are shadowed by direct slots with the same
-name. One possible reason for customizing @code{compute-slots} would be
-to implement an alternative resolution strategy for slot name conflicts.
-
-@code{compute-get-n-set} computes the low-level closures that will be
-used to get and set the value of a particular slot, and returns them in
-a list with two elements.
+@code{compute-get-n-set @var{class} @var{slot-def}} (generic)
-The closures returned depend on how storage for that slot is allocated.
-The standard @code{compute-get-n-set} method, specialized for classes of
-type @code{<class>}, handles the standard GOOPS values for the
-@code{#:allocation} slot option (@pxref{Slot Options,, allocation}). By
-defining a new @code{compute-get-n-set} method for a more specialized
-metaclass, it is possible to support new types of slot allocation.
+@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})}.
-Suppose you wanted to create a large number of instances of some class
-with a slot that should be shared between some but not all instances of
-that class - say every 10 instances should share the same slot storage.
-The following example shows how to implement and use a new type of slot
-allocation to do this.
+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
-(define-class <batched-allocation-metaclass> (<class>))
-
-(let ((batch-allocation-count 0)
- (batch-get-n-set #f))
- (define-method (compute-get-n-set
- (class <batched-allocation-metaclass>) s)
- (case (slot-definition-allocation s)
- ((#:batched)
- ;; If we've already used the same slot storage for 10 instances,
- ;; reset variables.
- (if (= batch-allocation-count 10)
- (begin
- (set! batch-allocation-count 0)
- (set! batch-get-n-set #f)))
- ;; If we don't have a current pair of get and set closures,
- ;; create one. make-closure-variable returns a pair of closures
- ;; around a single Scheme variable - see goops.scm for details.
- (or batch-get-n-set
- (set! batch-get-n-set (make-closure-variable)))
- ;; Increment the batch allocation count.
- (set! batch-allocation-count (+ batch-allocation-count 1))
- batch-get-n-set)
-
- ;; Call next-method to handle standard allocation types.
- (else (next-method)))))
-
-(define-class <class-using-batched-slot> ()
- ...
- (c #:allocation #:batched)
- ...
- #:metaclass <batched-allocation-metaclass>)
+@code{(@var{slot-name-symbol} @var{init-function} . @var{index})}
@end example
-The usage of @code{compute-getter-method} and @code{compute-setter-method}
-is described in @ref{MOP Specification}.
-
-@code{compute-cpl} and @code{compute-get-n-set} are called by the
-standard @code{initialize} method for classes whose metaclass is
-@code{<class>}. But @code{initialize} itself can also be modified, by
-defining an @code{initialize} method specialized to the new class's
-metaclass. Such a method could complete override the standard
-behaviour, by not calling @code{(next-method)} at all, but more
-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
+or like
-@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.
+@example
+@code{(@var{slot-name-symbol} @var{init-function} @var{get} @var{set})}
+@end example
-Normally, however, the method for classes with metaclass @code{<class>}
-will be applied. This method calls two generic functions:
+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}.
-@itemize @bullet
-@item
-(allocate-instance @var{class} . @var{initargs})
+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
-(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.
+@code{compute-getter-method @var{class} @var{gns}} (generic)
-@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}.
+@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
-The method for instances of type @code{<class>} calls
-@code{(next-method)}, then performs the class initializations described
-in @ref{Customizing Class Definition}.
+@code{compute-setter-method @var{class} @var{gns}} (generic)
-@item
-and so on for generic functions, method, operator classes @dots{}
+@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
-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
+@node Customizing Class Definition
+@subsection Customizing Class Definition
-The default @code{class-redefinition} method, specialized for classes
-with the default metaclass @code{<class>}, has the following internal
-protocol.
+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
+to define generic function methods, specialized for the new class's
+metaclass, that can modify or override the default behaviour of
+@code{initialize}, @code{compute-cpl} or @code{compute-get-n-set}.
-@code{class-redefinition (@var{old <class>}) (@var{new <class>})}
-(method)
+@code{compute-cpl} computes the class precedence list (``CPL'') for the
+new class (@pxref{Class Precedence List}), and returns it as a list of
+class objects. The CPL is important because it defines a superclass
+ordering that is used, when a generic function is invoked upon an
+instance of the class, to decide which of the available generic function
+methods is the most specific. Hence @code{compute-cpl} could be
+customized in order to modify the CPL ordering algorithm for all classes
+with a special metaclass.
-@itemize @bullet
-@item
-@code{remove-class-accessors! @var{old}} (generic)
+The default CPL algorithm is encapsulated by the @code{compute-std-cpl}
+procedure, which is called by the default @code{compute-cpl} method.
-@item
-@code{update-direct-method! @var{method} @var{old} @var{new}} (generic)
+@deffn procedure compute-std-cpl class
+Compute and return the class precedence list for @var{class} according
+to the algorithm described in @ref{Class Precedence List}.
+@end deffn
-@item
-@code{update-direct-subclass! @var{subclass} @var{old} @var{new}} (generic)
-@end itemize
+@code{compute-slots} computes and returns a list of all slot definitions
+for the new class. By default, this list includes the direct slot
+definitions from the @code{define-class} form, plus the slot definitions
+that are inherited from the new class's superclasses. The default
+@code{compute-slots} method uses the CPL computed by @code{compute-cpl}
+to calculate this union of slot definitions, with the rule that slots
+inherited from superclasses are shadowed by direct slots with the same
+name. One possible reason for customizing @code{compute-slots} would be
+to implement an alternative resolution strategy for slot name conflicts.
-This protocol cleans up things that the definition of the old class
-once changed and modifies things to work with the new class.
+@code{compute-get-n-set} computes the low-level closures that will be
+used to get and set the value of a particular slot, and returns them in
+a list with two elements.
-The default @code{remove-class-accessors!} method removes the
-accessor methods of the old class from all classes which they
-specialize.
+The closures returned depend on how storage for that slot is allocated.
+The standard @code{compute-get-n-set} method, specialized for classes of
+type @code{<class>}, handles the standard GOOPS values for the
+@code{#:allocation} slot option (@pxref{Slot Options,, allocation}). By
+defining a new @code{compute-get-n-set} method for a more specialized
+metaclass, it is possible to support new types of slot allocation.
-The default @code{update-direct-method!} method substitutes the new
-class for the old in all methods specialized to the old class.
+Suppose you wanted to create a large number of instances of some class
+with a slot that should be shared between some but not all instances of
+that class - say every 10 instances should share the same slot storage.
+The following example shows how to implement and use a new type of slot
+allocation to do this.
-The default @code{update-direct-subclass!} method invokes
-@code{class-redefinition} recursively to handle the redefinition of
-subclasses.
+@example
+(define-class <batched-allocation-metaclass> (<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 slot is referenced or set. GOOPS modifies each
-instance by calling the generic function @code{change-class}.
+(let ((batch-allocation-count 0)
+ (batch-get-n-set #f))
+ (define-method (compute-get-n-set
+ (class <batched-allocation-metaclass>) s)
+ (case (slot-definition-allocation s)
+ ((#:batched)
+ ;; If we've already used the same slot storage for 10 instances,
+ ;; reset variables.
+ (if (= batch-allocation-count 10)
+ (begin
+ (set! batch-allocation-count 0)
+ (set! batch-get-n-set #f)))
+ ;; If we don't have a current pair of get and set closures,
+ ;; create one. make-closure-variable returns a pair of closures
+ ;; around a single Scheme variable - see goops.scm for details.
+ (or batch-get-n-set
+ (set! batch-get-n-set (make-closure-variable)))
+ ;; Increment the batch allocation count.
+ (set! batch-allocation-count (+ batch-allocation-count 1))
+ batch-get-n-set)
-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.
+ ;; Call next-method to handle standard allocation types.
+ (else (next-method)))))
-@code{change-class (@var{old-instance <object>}) (@var{new <class>})} (method)
+(define-class <class-using-batched-slot> ()
+ ...
+ (c #:allocation #:batched)
+ ...
+ #:metaclass <batched-allocation-metaclass>)
+@end example
-@itemize @bullet
-@item
-@code{update-instance-for-different-class @var{old-instance} @var{new-instance}} (generic)
+The usage of @code{compute-getter-method} and @code{compute-setter-method}
+is described in @ref{Class Definition Protocol}.
-@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.
+@code{compute-cpl} and @code{compute-get-n-set} are called by the
+standard @code{initialize} method for classes whose metaclass is
+@code{<class>}. But @code{initialize} itself can also be modified, by
+defining an @code{initialize} method specialized to the new class's
+metaclass. Such a method could complete override the standard
+behaviour, by not calling @code{(next-method)} at all, but more
+typically it would perform additional class initialization steps before
+and/or after calling @code{(next-method)} for the standard behaviour.
-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
function.
@end itemize
-@deffn syntax method (parameter @dots{}) . body
+@deffn syntax method (parameter @dots{}) body @dots{}
Make a method whose specializers are defined by the classes in
@var{parameter}s and whose procedure definition is constructed from the
@var{parameter} symbols and @var{body} forms.
The @var{parameter} and @var{body} parameters should be as for
-@code{define-method} (@pxref{Adding Methods to Generic Functions,,
+@code{define-method} (@pxref{Methods and Generic Functions,,
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.
+
+@noindent
+@code{apply-generic} (generic)
+
+@itemize @bullet
+@item
+@code{no-method} (generic)
+
+@item
+@code{compute-applicable-methods} (generic)
-@code{apply-generic}
+@item
+@code{sort-applicable-methods} (generic)
@itemize @bullet
@item
-@code{no-method}
+@code{method-more-specific?} (generic)
+@end itemize
@item
-@code{compute-applicable-methods}
+@code{apply-methods} (generic)
+@itemize @bullet
@item
-@code{sort-applicable-methods}
+@code{apply-method} (generic)
@item
-@code{apply-methods}
+@code{no-next-method} (generic)
+@end itemize
@item
@code{no-applicable-method}
@end itemize
-@code{sort-applicable-methods}
+We do not yet have full documentation for these. Please refer to the
+code (@file{oop/goops.scm}) for details.
+
+
+@node Redefining a Class
+@section Redefining a Class
+
+Suppose that a class @code{<my-class>} is defined using @code{define-class}
+(@pxref{Class Definition,, define-class}), with slots that have
+accessor functions, and that an application has created several instances
+of @code{<my-class>} using @code{make} (@pxref{Instance Creation,,
+make}). What then happens if @code{<my-class>} is redefined by calling
+@code{define-class} again?
+
+@menu
+* Default Class Redefinition Behaviour::
+* Customizing Class Redefinition::
+@end menu
+
+@node Default Class Redefinition Behaviour
+@subsection Default Class Redefinition Behaviour
+
+GOOPS' default answer to this question is as follows.
@itemize @bullet
@item
-@code{method-more-specific?}
-@end itemize
+All existing direct instances of @code{<my-class>} are converted to be
+instances of the new class. This is achieved by preserving the values
+of slots that exist in both the old and new definitions, and
+initializing the values of new slots in the usual way (@pxref{Instance
+Creation,, make}).
-@code{apply-methods}
+@item
+All existing subclasses of @code{<my-class>} are redefined, as though
+the @code{define-class} expressions that defined them were re-evaluated
+following the redefinition of @code{<my-class>}, and the class
+redefinition process described here is applied recursively to the
+redefined subclasses.
-@itemize @bullet
@item
-@code{apply-method}
+Once all of its instances and subclasses have been updated, the class
+metaobject previously bound to the variable @code{<my-class>} is no
+longer needed and so can be allowed to be garbage collected.
@end itemize
-@code{next-method}
+To keep things tidy, GOOPS also needs to do a little housekeeping on
+methods that are associated with the redefined class.
@itemize @bullet
@item
-@code{no-next-method}
+Slot accessor methods for slots in the old definition should be removed
+from their generic functions. They will be replaced by accessor methods
+for the slots of the new class definition.
+
+@item
+Any generic function method that uses the old @code{<my-class>} metaobject
+as one of its formal parameter specializers must be updated to refer to
+the new @code{<my-class>} metaobject. (Whenever a new generic function
+method is defined, @code{define-method} adds the method to a list stored
+in the class metaobject for each class used as a formal parameter
+specializer, so it is easy to identify all the methods that must be
+updated when a class is redefined.)
@end itemize
+
+If this class redefinition strategy strikes you as rather counter-intuitive,
+bear in mind that it is derived from similar behaviour in other object
+systems such as CLOS, and that experience in those systems has shown it to be
+very useful in practice.
+
+Also bear in mind that, like most of GOOPS' default behaviour, it can
+be customized@dots{}
+
+@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, 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
+be customized by defining a @code{class-redefinition} method that is
+specialized for the relevant metaclasses.
+
+@deffn generic class-redefinition
+Handle the class redefinition from @var{old-class} to @var{new-class},
+and return the new class metaobject that should be bound to the
+variable specified by @code{define-class}'s first argument.
+@end deffn
+
+@deffn method class-redefinition (old-class <class>) (new-class <class>)
+Implements GOOPS' default class redefinition behaviour, as described in
+@ref{Default Class Redefinition Behaviour}. Returns the metaobject
+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
+new definition. In this strategy, any existing subclasses could also
+be left as they are, on the understanding that they inherit from a nameless
+superclass.
+
+This strategy is easily implemented in GOOPS, by defining a new metaclass,
+that will be used as the metaclass for all classes to which the strategy
+should apply, and then defining a @code{class-redefinition} method that
+is specialized for this metaclass:
+
+@example
+(define-class <can-be-nameless> (<class>))
+
+(define-method (class-redefinition (old <can-be-nameless>)
+ (new <class>))
+ new)
+@end example
+
+When customization can be as easy as this, aren't you glad that GOOPS
+implements the far more difficult strategy as its default!
+
+
+@node Changing the Class of an Instance
+@section Changing the Class of an Instance
+
+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}.
+
+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
+existing class and for the new class. If the new class has slots with
+the same name as slots in the existing class, the values for those slots
+are preserved. Slots that are present only in the existing class are
+discarded. Slots that are present only in the new class are initialized
+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}.
+
+The value of each of @var{obj}'s slots is preserved only if a similarly named
+slot exists in @var{new}; any other slot values are discarded.
+
+The slots in @var{new} that do not correspond to any of @var{obj}'s
+pre-existing slots are initialized according to @var{new}'s slot definitions'
+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.