guile-commits
[Top][All Lists]

## [Guile-commits] GNU Guile branch, master, updated. release_1-9-14-65-g0b

 From: Neil Jerram Subject: [Guile-commits] GNU Guile branch, master, updated. release_1-9-14-65-g0b452f2 Date: Sat, 15 Jan 2011 16:41:27 +0000

This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "GNU Guile".

http://git.savannah.gnu.org/cgit/guile.git/commit/?id=0b452f2c5326120fefc2ae15f5fa7fceaf103633

The branch, master has been updated
via  0b452f2c5326120fefc2ae15f5fa7fceaf103633 (commit)
via  9320479a188cc2758c9a6d12ecee46479aa315fa (commit)
via  2cb8cf04b9ecd03c0ce778a44875d7041d527f59 (commit)
via  5f9b75a35505d322305aa2b0b46f40078d80dc47 (commit)
via  3617da95abed21923b67fc7c355b4b7b25d32853 (commit)
via  c7b154588ba4694f49081cc491b8168cd88bd4d0 (commit)
via  dc08a490e355d6f2a674d39556947705d7464a34 (commit)
via  62d7cba3d5b1427dbeb815b157c7ccd8597f0fc6 (commit)
via  68f4fee187343d156381a8107fb8b6a6750dcc31 (commit)
from  2e6f5ea4cdd96bdc46ac579b1731e73ba3ae6024 (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
commit 0b452f2c5326120fefc2ae15f5fa7fceaf103633
Date:   Fri Jan 14 21:53:37 2011 +0000

Confront the MOP

* doc/ref/goops.texi (The Metaobject Protocol): Bring forward to
before Class Options', and add intro text to explain why.  All of
the sections now remaining are ones where the MOP is more likely to
be relevant than not.

Date:   Fri Jan 14 21:23:54 2011 +0000

Move GOOPS Error Handling' to after Introspection'

* doc/ref/goops.texi (GOOPS Error Handling): Move to just after
Introspection'.

commit 9320479a188cc2758c9a6d12ecee46479aa315fa
Date:   Fri Jan 14 21:19:51 2011 +0000

Move Handling Slot Access Errors' inside Accessing Slots'

* doc/ref/goops.texi (Accessing Slots): Move Handling Slot Access
Errors' here; update relevant references.

commit 2cb8cf04b9ecd03c0ce778a44875d7041d527f59
Date:   Fri Jan 14 20:34:41 2011 +0000

Merge small sections into GOOPS Object Miscellany'

* doc/ref/goops.texi (GOOPS Object Miscellany): New section, combining
previous Object Comparison', Cloning Objects' and Write and
Display'.  Replace Object Comparison' text with something that
makes sense.  Add a snippet to the end of the write/display section.

commit 5f9b75a35505d322305aa2b0b46f40078d80dc47
Date:   Fri Jan 14 20:10:33 2011 +0000

Remove content-free Generic Functions and Accessors'

* doc/ref/goops.texi (GOOPS): Remove Generic Functions and
Accessors'.  There was nothing here that wasn't better covered
elsewhere.

commit 3617da95abed21923b67fc7c355b4b7b25d32853
Date:   Fri Jan 14 20:06:34 2011 +0000

Move Accessing Slots' inside Introspection'.

* doc/ref/goops.texi (Introspection): Move Accessing Slots' into
here, and flatten it, except for Handling Slot Access Errors'.
(GOOPS Error Handling): Move Handling Slot Access Errors' here.

commit c7b154588ba4694f49081cc491b8168cd88bd4d0
Date:   Fri Jan 14 20:01:29 2011 +0000

Reorder Introspection'

* doc/ref/goops.texi (Instances): Move Instances' before Slots', as
it feels more important.

commit dc08a490e355d6f2a674d39556947705d7464a34
Date:   Fri Jan 14 19:45:38 2011 +0000

Edit Introspection'

* doc/ref/goops.texi (Introspection): Make a bit snappier.
(Classes): Add intro.  Remove "the" and "metaobject" everywhere.
Remove class-environment', since I don't know what it's useful for.
(Instances): Remove implementation notes.
(Built-in classes): Merge with Instances'.  Reorder text points.
(Generic Functions): Add intro.  Remove "the" and "metaobject"
everywhere.
(Generic Function Methods): Merge with Generic Functions'.

commit 62d7cba3d5b1427dbeb815b157c7ccd8597f0fc6
Date:   Fri Jan 14 19:08:46 2011 +0000

Move Introspection' earlier

* doc/ref/goops.texi (Introspection): Move to after Generic Functions
and Methods'.  The idea is to have all of that sections that make
sense without needing to understand the MOP, before sections that
really depend on the MOP.

commit 68f4fee187343d156381a8107fb8b6a6750dcc31
Date:   Wed Jan 12 23:42:40 2011 +0000

Improve doc on generic functions and inheritance

* doc/ref/goops.texi (Methods and Generic Functions): More explanation
of generic function invocation.  Created (or moved) subsections here
to cover material on the following that was previously spread elsewhere:
accessors; extending primitives; merging generics; generic function
examples; handling invocation errors.  Edited for clarity throughout.
(Generic functions and methods, Example): Nodes deleted, with their
material incorporated above.
(Class Precedence List): Edited to improve clarity.
(Sorting Methods): New subsection.

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

Summary of changes:
doc/ref/goops.texi | 1766 +++++++++++++++++++++++++---------------------------
1 files changed, 851 insertions(+), 915 deletions(-)

diff --git a/doc/ref/goops.texi b/doc/ref/goops.texi
index 60e07fa..0dd7b0e 100644
--- a/doc/ref/goops.texi
+++ b/doc/ref/goops.texi
@@ -44,19 +44,13 @@ module.  You can do this at the Guile REPL by evaluating:
* 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::
+* Class Options::
+* Redefining a Class::
+* Changing the Class of an Instance::

@@ -619,106 +613,226 @@ you'd just write
and the question of which class the method is more associated with does

-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:
+
+(define-method (+ (x <string>) (y <string)) ...)
+(define-method (+ (x <matrix>) (y <matrix>)) ...)
+(define-method (+ (f <fish>) (b <bicyle>)) ...)
+(define-method (+ (a <foo>) (b <bar>) (c <baz>)) ...)
+
+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
address@hidden 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
+
+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.
+
address@hidden 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}.
+
address@hidden is a generic function.  If @var{generic} is a variable
+which is not yet bound to a generic function object, the expansion of
address@hidden will include a call to @code{define-generic}.  If
address@hidden is a variable which is not yet bound to a
+generic-with-setter object, the expansion will include a call to
+
+Each @var{parameter} must be either a symbol or a two-element list
address@hidden(@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.
+
address@hidden is the body of the method definition.
+
address@hidden expressions look a little like Scheme procedure
+definitions of the form
+
+(define (name formals @dots{}) . body)
+
+The important difference is that each formal parameter, apart from the
+possible rest'' argument, can be qualified by a class name:
+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 @address@hidden (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
address@hidden @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
address@hidden<square>} class and the second parameter is a number.

-* Generic functions and methods::
+* Accessors::
+* Extending Primitives::
+* Merging Generics::
* Next-method::
-* Example::
+* Generic Function and Method Examples::
+* Handling Invocation Errors::

-
-Neither @goops{} nor CLOS use the message mechanism for methods as most
-Object Oriented language do. Instead, they use the notion of
address@hidden 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
address@hidden 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:
-
-search among all the generic function those which are applicable
-sort the list of applicable methods in the most specific'' order
-call the most specific method of this list (i.e. the first method of
-the sorted methods list).
-
-The definition of a generic function is done with the
address@hidden macro. Definition of a new method is done with the
address@hidden 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.
-Consider the following definitions:

-(define-generic G)
-(define-method  (G (a <integer>) b) 'integer)
-(define-method  (G (a <real>) b) 'real)
-(define-method  (G a b) 'top)

-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

-(define-method (G (a <integer>) (b <top>)) 'integer)

-Now, let us look at some possible calls to generic function @var{G}:
+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.

-(G 2 3)    @result{} integer
-(G 2 #t)   @result{} integer
-(G 1.2 'a) @result{} real
address@hidden (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)
+Create an accessor with name @var{symbol} and bind it to the variable
address@hidden  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.

-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

-(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)
+
+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
address@hidden call) for a variable whose current value is a
+primitive.  But it can also be forced by calling
+
+Force the creation of a generic function definition for
+
+Once the generic function definition for a primitive has been created,
+it can be retrieved using @code{primitive-generic-generic}.
+
+Return the generic function definition of @var{primitive}.
+
address@hidden raises an error if @var{primitive}
+is not a primitive with generic capability.
+
+
+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, 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
address@hidden, what does the code using those packages end up with?

-In this case,
address@hidden 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 (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
address@hidden: @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
address@hidden(math 2D-vectors)} will share the methods of @code{x} in
address@hidden(math 2D-vectors)} doesn't share methods with @code{x} in
address@hidden(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

@@ -769,13 +883,66 @@ Number is in range
lead to an infinite recursion, but this consideration is just the same
as in Scheme code in general.)

address@hidden Generic Function and Method Examples
address@hidden Generic Function and Method Examples
+
+Consider the following definitions:
+
+(define-generic G)
+(define-method (G (a <integer>) b) 'integer)
+(define-method (G (a <real>) b) 'real)
+(define-method (G a b) 'top)
+
+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
+
+(define-method (G (a <integer>) (b <top>)) 'integer)
+
+Now, let's look at some possible calls to the generic function @var{G}:

-In this section we shall continue to define operations on the
+(G 2 3)    @result{} integer
+(G 2 #t)   @result{} integer
+(G 1.2 'a) @result{} real
address@hidden (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)
+
+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:
+
+(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)
+
+
+(G 1 2)   @result{} integer-integer
+(G 1 1.0) @result{} integer-real
+(G 1 #t)  @result{} integer
+(G 'a 1)  @result{} top-number
+
+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 complexes could be
+of two complex numbers could be

@lisp
(define-method (new-+ (a <my-complex>) (b <my-complex>))
@@ -833,24 +1000,22 @@ symbol.  A complete writing of the @code{new-+} methods
is shown in
@caption{Extending @code{+} to handle complex numbers}
@end float

-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
-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 address@hidden 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
address@hidden permits to redefine the @code{+} symbol to our extended
-
-To terminate our implementation (integration?) of  complex numbers, we can
-redefine standard Scheme predicates in the following manner:
+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
+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
address@hidden 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)
@@ -859,13 +1024,44 @@ redefine standard Scheme predicates in the following
manner:
(define-method (number? n <number>) #t)
(define-method (number? n)          #f)
@dots{}
@end lisp

Standard primitives in which complex numbers are involved could also be
redefined in the same manner.

+
+If a generic function is invoked with a combination of parameters for
+which there is no applicable method, GOOPS raises an error.
+
address@hidden 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
address@hidden generic function.  The default method calls
+
address@hidden 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.
+
address@hidden 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.
+
+
@node Inheritance
@section Inheritance

@@ -920,26 +1116,38 @@ instance of D will have three slots, @code{a}, @code{b}
and
The ordering of the returned slots is not significant.

-* Class precedence list::
+* Class Precedence List::
+* Sorting Methods::

-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
+Dalton's (J.Dalton@@ed.ac.uk) @cite{Brief introduction to CLOS}}

-Rule 1: Each class is more specific than its address@hidden was \bf
+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
address@hidden, 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 ()
@@ -952,42 +1160,38 @@ With multiple inheritance, ordering is harder. Suppose
we have
(@dots{}))
@end lisp

-In this case, the @code{Z} class is more specific than the @code{X} or
address@hidden 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:
-
-Rule 2: For a given class, superclasses listed earlier are more
-        specific than those listed later.
-
-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 @ref{fig:hier}, the class precedence list is
+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
address@hidden:init-value} will take effect when creating an instance of
address@hidden  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.
+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
address@hidden 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
address@hidden  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>
@@ -995,656 +1199,47 @@ list whose first element is the most specific class.
For instance,
#<<class> <top> 4026a9d8>)
@end lisp

-However, this result is not too much readable; using the function
-
-(map class-name (class-precedence-list B)) @result{} (B <object> <top>)
-
-
-
-The @code{#:metaclass} class option specifies the metaclass of the class
-being defined.  @var{metaclass} must be a class that inherits from
address@hidden<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}).
-
-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
-
-
-* Instance Slots::
-* Class Slots::
-* Handling Slot Access Errors::
-
-
-Any slot, regardless of its allocation, can be queried, referenced and
-set using the following four primitive procedures.
-
address@hidden {primitive procedure} slot-exists? obj slot-name
-Return @code{#t} if @var{obj} has a slot with name @var{slot-name},
-otherwise @code{#f}.
-
address@hidden {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}.
-
address@hidden calls the generic function @code{slot-missing} if
address@hidden does not have a slot called @var{slot-name} (@pxref{Handling
-Slot Access Errors, slot-missing}).
-
address@hidden {primitive procedure} slot-ref obj slot-name
-Return the value of the slot named @var{slot-name} in @var{obj}.
-
address@hidden calls the generic function @code{slot-missing} if
address@hidden does not have a slot called @var{slot-name} (@pxref{Handling
-Slot Access Errors, slot-missing}).
-
address@hidden 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}).
-
address@hidden {primitive procedure} slot-set! obj slot-name value
-Set the value of the slot named @var{slot-name} in @var{obj} to @var{value}.
-
address@hidden calls the generic function @code{slot-missing} if
address@hidden does not have a slot called @var{slot-name} (@pxref{Handling
-Slot Access Errors, slot-missing}).
-
-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
address@hidden)}, 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
address@hidden(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.
-
address@hidden {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}.
-
address@hidden {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
-
address@hidden if @var{class} does not have a slot definition for a
-slot called @var{slot-name} (@pxref{Handling Slot Access Errors,
-slot-missing}).
-
address@hidden {primitive procedure} slot-ref-using-class class obj slot-name
-Apply the getter'' closure for the slot named @var{slot-name} in
address@hidden to @var{obj}, and return its result.
-
address@hidden if @var{class} does not have a slot definition for a
-slot called @var{slot-name} (@pxref{Handling Slot Access Errors,
-slot-missing}).
-
address@hidden if the application of the getter'' closure to
address@hidden returns an unbound value (@pxref{Handling Slot Access Errors,
-slot-unbound}).
-
address@hidden {primitive procedure} slot-set-using-class! class obj slot-name
value
-Apply the setter'' closure for the slot named @var{slot-name} in
-
address@hidden if @var{class} does not have a slot definition for a
-slot called @var{slot-name} (@pxref{Handling Slot Access Errors,
-slot-missing}).
-
-
-Slots whose allocation is per-class rather than per-instance can be
-referenced and set without needing to specify any particular instance.
-
-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
address@hidden generic function, with the same arguments.
-
address@hidden procedure class-slot-set! class slot-name value
-Set the value of the slot named @var{slot-name} in class @var{class} to
address@hidden  The named slot must have @code{#:class} or
-
-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}.
-
-
-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.
-
address@hidden method slot-missing (class <class>) slot-name
address@hidden method slot-missing (class <class>) (object <object>) slot-name
address@hidden 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.
-
-The default methods all call @code{goops-error} with an appropriate
-message.
-
address@hidden method slot-unbound (class <class>) slot-name
address@hidden 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.
-
-The default methods all call @code{goops-error} with an appropriate
-message.
-
-
-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).
-
-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
-
-
@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.
-
-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.
-
-Create an accessor with name @var{symbol} and bind it to the variable
address@hidden  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.
-
-* Extending Primitives::
-* Merging Generics::
-
-
-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
address@hidden call) for a variable whose current value is a
-primitive.  But it can also be forced by calling
-
-Force the creation of a generic function definition for
-
-Once the generic function definition for a primitive has been created,
-it can be retrieved using @code{primitive-generic-generic}.
-
-Return the generic function definition of @var{primitive}.
-
address@hidden raises an error if @var{primitive}
-is not a primitive with generic capability.
-
-
-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
address@hidden, what does the code using those packages end up with?
-
address@hidden 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:
+Or for a more immediately readable result:

@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)
+(map class-name (class-precedence-list B)) @result{} (B <object> <top>)
@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
address@hidden: @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
address@hidden(math 2D-vectors)} will share the methods of @code{x} in
address@hidden(math 2D-vectors)} doesn't share methods with @code{x} in
address@hidden(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.
-
-
-To add a method to a generic function, use @code{define-method}.
-
address@hidden 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}.
-
address@hidden is a generic function.  If @var{generic} is a variable
-which is not yet bound to a generic function object, the expansion of
address@hidden will include a call to @code{define-generic}.  If
address@hidden is a variable which is not yet bound to a
-generic-with-setter object, the expansion will include a call to
-
-Each @var{parameter} must be either a symbol or a two-element list
address@hidden(@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.
-
address@hidden is the body of the method definition.
-
address@hidden expressions look a little like Scheme procedure
-definitions of the form
-
-(define (name formals @dots{}) . body)
-
-The important difference is that each formal parameter, apart from the
-possible rest'' argument, can be qualified by a class name:
-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 @address@hidden (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
address@hidden @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
address@hidden<square>} class and the second parameter is a number.
-
-
-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.
-
-* Determining Which Methods to Apply::
-* Handling Invocation Errors::
-
address@hidden Determining Which Methods to Apply
address@hidden 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? ]
-
address@hidden method apply-generic (gf <generic>) args
-
address@hidden method compute-applicable-methods (gf <generic>) args
-
address@hidden method sort-applicable-methods (gf <generic>) methods args
-
address@hidden method method-more-specific? (m1 <method>) (m2 <method>) args
-
address@hidden method apply-method (gf <generic>) methods build-next args
-
address@hidden method apply-methods (gf <generic>) (l <list>) args
-
-
address@hidden 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
address@hidden generic function.  The default method calls
-
address@hidden 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.
-
address@hidden 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.
-
-
-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
-
-* Default Class Redefinition Behaviour::
-* Customizing Class Redefinition::

-
-GOOPS' default answer to this question is as follows.
-
-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}).
-
-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.
-
-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.
-
-To keep things tidy, GOOPS also needs to do a little housekeeping on
-methods that are associated with the redefined class.
-
-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.
-
-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.)
-
-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
-
-
-When @code{define-class} notices that a class is being redefined,
-it constructs the new class metaobject as usual, and then invokes the
address@hidden 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.
-
-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.
-
address@hidden method class-redefinition (old-class <class>) (new-class <class>)
-Implements GOOPS' default class redefinition behaviour, as described in
address@hidden Class Redefinition Behaviour}.  Returns the metaobject
-for the new class definition.
-
-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:
-
-(define-class <can-be-nameless> (<class>))
-
-(define-method (class-redefinition (old <can-be-nameless>)
-                                   (new <class>))
-  new)
-
-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:
+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.

+The rules are that
@item
-(remove-class-accessors! @var{old-class})
+the applicable methods are sorted in order of specificity, and the most
+specific method is used first, then the next if that method calls

@item
-(update-direct-method! @var{method} @var{old-class} @var{new-class})
+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

@item
-(update-direct-subclass! @var{subclass} @var{old-class} @var{new-class})
+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

-and the default methods for these generic functions invoke further
-generic functions, and so address@hidden  The detailed protocol for all of
these
-is described in @ref{MOP Specification}.
-
address@hidden Changing the Class of an Instance
address@hidden 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.
-
-
-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}).
-
address@hidden {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.
-
-Customized change of class behaviour can be implemented by defining
address@hidden 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

address@hidden, 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++.
address@hidden, 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++.

Nothing in C++ allows a running program to obtain answers to the following
types of question:
@@ -1671,62 +1266,56 @@ GOOPS equivalents --- to be obtained dynamically, at
run time.

* Classes::
-* Slots::
* Instances::
-* Built-in classes::
+* Slots::
* Generic Functions::
-* Generic Function Methods::
+* Accessing Slots::

@node Classes
@subsection Classes

+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} class-name class
-Return the name of class @var{class}.
-This is the value of the @var{class} metaobject's @code{name} slot.
+Return the name of class @var{class}.  This is the value of
@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
+Return a list containing the direct superclasses of @var{class}.  This
+is the value of @var{class}'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
-This is the value of the @var{class} metaobject's @code{direct-slots}
address@hidden  This is the value of @var{class}'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
+Return a list containing the direct subclasses of @var{class}.  This is
+the value of @var{class}'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.
+as a formal parameter specializer.  This is the value of @var{class}'s
@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.
+Precedence List}).  This is the value of @var{class}'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.
-
-Return the value of @var{class}'s @code{environment} slot.
-[ *fixme*  I don't know what this value is used for. ]
+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

@deffn procedure class-subclasses class
@@ -1738,6 +1327,48 @@ 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

+
+
+Return the GOOPS class of any Scheme @var{value}.
+
+Return @code{#t} if @var{object} is any GOOPS instance, otherwise
+
+Return @code{#t} if @var{object} is an instance of @var{class} or one of
+its subclasses.
+
+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
address@hidden(oop goops)} module) built-in classes like @code{<string>},
address@hidden<list>} and @code{<number>} are automatically set up,
+corresponding to all Guile Scheme types.
+
+(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
+
+(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>
+
+
@node Slots
@subsection Slots

@@ -1819,84 +1450,41 @@ method, so, in general, the function returned by
see @ref{Slot Options,, init-value}.
@end deffn

-
-Return the GOOPS class of any Scheme @var{value}.
-
-Return @code{#t} if @var{object} is any GOOPS instance, otherwise
-
-Return @code{#t} if @var{object} is an instance of @var{class} or one of
-its subclasses.
-
-Implementation notes: @code{is-a?} uses @code{class-of} and
address@hidden to obtain the class precedence list for
-
-
-There are built-in classes like @code{<string>}, @code{<list>} and
address@hidden<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.
-
-(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
-
-(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>
-

@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} 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.
+Return a list of the methods of generic function @var{gf}.  This is the
+value of @var{gf}'s @code{methods} slot.
@end deffn

+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 the @var{method} metaobject's
+Return the generic function that @var{method} belongs to.  This is the
+value of @var{method}'s @code{generic-function} slot.
@end deffn

@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
+Return a list of @var{method}'s formal parameter specializers .  This is
+the value of @var{method}'s @code{specializers} slot.
@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
+Return the procedure that implements @var{method}.  This is the value of
@end deffn

@deffn generic method-source
@@ -1916,6 +1504,153 @@ Return an expression that prints to show the definition
of method
@end example
@end deffn

+
+
+Any slot, regardless of its allocation, can be queried, referenced and
+set using the following four primitive procedures.
+
address@hidden {primitive procedure} slot-exists? obj slot-name
+Return @code{#t} if @var{obj} has a slot with name @var{slot-name},
+otherwise @code{#f}.
+
address@hidden {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}.
+
address@hidden calls the generic function @code{slot-missing} if
address@hidden does not have a slot called @var{slot-name} (@pxref{Accessing
+Slots, slot-missing}).
+
address@hidden {primitive procedure} slot-ref obj slot-name
+Return the value of the slot named @var{slot-name} in @var{obj}.
+
address@hidden calls the generic function @code{slot-missing} if
address@hidden does not have a slot called @var{slot-name} (@pxref{Accessing
+Slots, slot-missing}).
+
address@hidden calls the generic function @code{slot-unbound} if the
+named slot in @var{obj} does not have a value (@pxref{Accessing Slots,
+slot-unbound}).
+
address@hidden {primitive procedure} slot-set! obj slot-name value
+Set the value of the slot named @var{slot-name} in @var{obj} to @var{value}.
+
address@hidden calls the generic function @code{slot-missing} if
address@hidden does not have a slot called @var{slot-name} (@pxref{Accessing
+Slots, slot-missing}).
+
+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
address@hidden)}, 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
address@hidden(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.
+
address@hidden {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}.
+
address@hidden {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
+
address@hidden if @var{class} does not have a slot definition for a
+slot called @var{slot-name} (@pxref{Accessing Slots,
+slot-missing}).
+
address@hidden {primitive procedure} slot-ref-using-class class obj slot-name
+Apply the getter'' closure for the slot named @var{slot-name} in
address@hidden to @var{obj}, and return its result.
+
address@hidden if @var{class} does not have a slot definition for a
+slot called @var{slot-name} (@pxref{Accessing Slots,
+slot-missing}).
+
address@hidden if the application of the getter'' closure to
address@hidden returns an unbound value (@pxref{Accessing Slots,
+slot-unbound}).
+
address@hidden {primitive procedure} slot-set-using-class! class obj slot-name
value
+Apply the setter'' closure for the slot named @var{slot-name} in
+
address@hidden if @var{class} does not have a slot definition for a
+slot called @var{slot-name} (@pxref{Accessing Slots, slot-missing}).
+
+Slots whose allocation is per-class rather than per-instance can be
+referenced and set without needing to specify any particular instance.
+
+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
address@hidden generic function, with the same arguments.
+
address@hidden procedure class-slot-set! class slot-name value
+Set the value of the slot named @var{slot-name} in class @var{class} to
address@hidden  The named slot must have @code{#:class} or
+
+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}.
+
+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.
+
address@hidden method slot-missing (class <class>) slot-name
address@hidden method slot-missing (class <class>) (object <object>) slot-name
address@hidden 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.
+
+The default methods all call @code{goops-error} with an appropriate
+message.
+
address@hidden method slot-unbound (class <class>) slot-name
address@hidden 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.
+
+The default methods all call @code{goops-error} with an appropriate
+message.
+
+
@node GOOPS Error Handling
@section Error Handling

@@ -1924,10 +1659,10 @@ by the default methods of the following generic
functions:

@itemize @bullet
@item
address@hidden (@pxref{Handling Slot Access Errors,, slot-missing})

@item
address@hidden (@pxref{Handling Slot Access Errors,, slot-unbound})

@item
@code{no-method} (@pxref{Handling Invocation Errors,, no-method})
@@ -1951,37 +1686,29 @@ from @var{format-string} and @var{args}.  Error message
formatting is
as done by @code{scm-error}.
@end deffn

address@hidden method eqv? ((x <top>) (y <top>))
address@hidden method equal? ((x <top>) (y <top>))
address@hidden 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,
address@hidden 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}.
+Here we cover some points about GOOPS objects that aren't substantial
+enough to merit sections on their own.

-Application class authors may wish to define specialized methods for
address@hidden, @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.

+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
+
+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.
+

@deffn generic shallow-clone
@deffnx method shallow-clone (self <object>)
@@ -2001,8 +1728,7 @@ on that value.  Other slot values are copied either as
immediate values
or by reference.
@end deffn

@deffn {primitive generic} write object port
@deffnx {primitive generic} display object port
@@ -2030,13 +1756,26 @@ methods - instances of the class @code{<method>}.
as the Guile primitive @code{write} and @code{display} functions.
@end deffn

+In addition to the cases mentioned, you can of course define
+customize how they 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.
+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.

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,
@@ -2302,7 +2041,7 @@ the class precedence list of <starfish> would be

With multiple inheritance, the algorithm is a little more complicated.
A full description is provided by the GOOPS Tutorial: see @ref{Class
-precedence list}.
+Precedence List}.

Class precedence list'' is often abbreviated, in documentation and
Scheme variable names, to @dfn{cpl}.
@@ -2673,7 +2412,7 @@ 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
+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
@@ -2687,7 +2426,7 @@ 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}.
+to the algorithm described in @ref{Class Precedence List}.
@end deffn

@code{compute-slots} computes and returns a list of all slot definitions
@@ -2967,7 +2706,7 @@ Make a method whose specializers are defined by the
classes in
@var{parameter} symbols and @var{body} forms.

The @var{parameter} and @var{body} parameters should be as for
define-method}).
@end deffn

@@ -3138,3 +2877,200 @@ accessor, passing the setter generic function as the
value of the
@item
@code{no-next-method}
@end itemize
+
+
+
+The @code{#:metaclass} class option specifies the metaclass of the class
+being defined.  @var{metaclass} must be a class that inherits from
address@hidden<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}).
+
+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
+
+
+
+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
+
+* Default Class Redefinition Behaviour::
+* Customizing Class Redefinition::
+
+
+GOOPS' default answer to this question is as follows.
+
+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}).
+
+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.
+
+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.
+
+To keep things tidy, GOOPS also needs to do a little housekeeping on
+methods that are associated with the redefined class.
+
+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.
+
+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.)
+
+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
+
+
+When @code{define-class} notices that a class is being redefined,
+it constructs the new class metaobject as usual, and then invokes the
address@hidden 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.
+
+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.
+
address@hidden method class-redefinition (old-class <class>) (new-class <class>)
+Implements GOOPS' default class redefinition behaviour, as described in
address@hidden Class Redefinition Behaviour}.  Returns the metaobject
+for the new class definition.
+
+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:
+
+(define-class <can-be-nameless> (<class>))
+
+(define-method (class-redefinition (old <can-be-nameless>)
+                                   (new <class>))
+  new)
+
+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:
+
+(remove-class-accessors! @var{old-class})
+
+(update-direct-method! @var{method} @var{old-class} @var{new-class})
+
+(update-direct-subclass! @var{subclass} @var{old-class} @var{new-class})
+
+and the default methods for these generic functions invoke further
+generic functions, and so address@hidden  The detailed protocol for all of
these
+is described in @ref{MOP Specification}.
+
address@hidden Changing the Class of an Instance
address@hidden 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.
+
+
+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}).
+
address@hidden {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.
+
+Customized change of class behaviour can be implemented by defining
address@hidden 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.