guile-commits
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[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  12fe9fcf51fc8153c9ab4e18addd769e84180041 (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
Author: Neil Jerram <address@hidden>
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.

commit 12fe9fcf51fc8153c9ab4e18addd769e84180041
Author: Neil Jerram <address@hidden>
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
Author: Neil Jerram <address@hidden>
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
Author: Neil Jerram <address@hidden>
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
Author: Neil Jerram <address@hidden>
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
Author: Neil Jerram <address@hidden>
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
Author: Neil Jerram <address@hidden>
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
Author: Neil Jerram <address@hidden>
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
Author: Neil Jerram <address@hidden>
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
Author: Neil Jerram <address@hidden>
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::
 @end menu
 
 @node Copyright Notice
@@ -619,106 +613,226 @@ you'd just write
 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:
+
address@hidden
+(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>)) ...)
address@hidden lisp
+
address@hidden
+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
address@hidden call is not needed.
address@hidden define-generic
address@hidden define-method
+
address@hidden 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.
address@hidden deffn
+
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 @code{(setter @var{generic-with-setter})}, where
address@hidden is a variable which is not yet bound to a
+generic-with-setter object, the expansion will include a call to
address@hidden
+
+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 deffn
+
address@hidden expressions look a little like Scheme procedure
+definitions of the form
+
address@hidden
+(define (name formals @dots{}) . body)
address@hidden example
+
+The important difference is that each formal parameter, apart from the
+possible ``rest'' argument, can be qualified by a class name:
address@hidden@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 @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.
 
 @menu
-* Generic functions and methods::  
+* Accessors::
+* Extending Primitives::
+* Merging Generics::
 * Next-method::                 
-* Example::                     
+* Generic Function and Method Examples::                     
+* Handling Invocation Errors::
 @end menu
 
address@hidden Generic functions and methods
address@hidden Generic functions and methods
-
address@hidden \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
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:
-
address@hidden generic function
address@hidden
address@hidden
-search among all the generic function those which are applicable
address@hidden
-sort the list of applicable methods in the ``most specific'' order
address@hidden
-call the most specific method of this list (i.e. the first method of 
-the sorted methods list).
address@hidden enumerate
-
-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.
address@hidden define-generic
address@hidden define-method
-Consider the following definitions:
 
address@hidden
-(define-generic G)
-(define-method  (G (a <integer>) b) 'integer)
-(define-method  (G (a <real>) b) 'real)
-(define-method  (G a b) 'top)
address@hidden lisp
address@hidden Accessors
address@hidden 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
 
address@hidden parameter specializers
address@hidden
-(define-method (G (a <integer>) (b <top>)) 'integer)
address@hidden lisp
address@hidden
+(set! (@code{accessor} @address@hidden) @code{value})
address@hidden example
 
-Now, let us look at some possible calls to generic function @var{G}:
address@hidden
+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.
 
address@hidden
-(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)
address@hidden lisp
address@hidden syntax define-accessor symbol
+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.
address@hidden 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
 
address@hidden
-(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)
address@hidden lisp
address@hidden Extending Primitives
address@hidden 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
address@hidden call) for a variable whose current value is a
+primitive.  But it can also be forced by calling
address@hidden
+
address@hidden {primitive procedure} enable-primitive-generic! primitive
+Force the creation of a generic function definition for
address@hidden
address@hidden deffn
+
+Once the generic function definition for a primitive has been created,
+it can be retrieved using @code{primitive-generic-generic}.
+
address@hidden {primitive procedure} primitive-generic-generic primitive
+Return the generic function definition of @var{primitive}.
+
address@hidden raises an error if @var{primitive}
+is not a primitive with generic capability.
address@hidden deffn
+
address@hidden Merging Generics
address@hidden 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, 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(my-module)} and vice address@hidden note that @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 Example
address@hidden Example
address@hidden Generic Function and Method Examples
address@hidden Generic Function and Method Examples
+
+Consider the following definitions:
+
address@hidden
+(define-generic G)
+(define-method (G (a <integer>) b) 'integer)
+(define-method (G (a <real>) b) 'real)
+(define-method (G a b) 'top)
address@hidden 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
+
address@hidden parameter specializers
address@hidden
+(define-method (G (a <integer>) (b <top>)) 'integer)
address@hidden lisp
+
+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
address@hidden
+(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)
address@hidden 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:
+
address@hidden
+(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)
address@hidden lisp
+
address@hidden With these definitions:
+
address@hidden
+(G 1 2)   @result{} integer-integer
+(G 1 1.0) @result{} integer-real
+(G 1 #t)  @result{} integer
+(G 'a 1)  @result{} top-number
address@hidden lisp
+
+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
 
address@hidden 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 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
-addition.
-
address@hidden 3
-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
+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
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{}
address@hidden
 @end lisp
 
 Standard primitives in which complex numbers are involved could also be
 redefined in the same manner.
 
 
address@hidden Handling Invocation Errors
address@hidden 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.
+
address@hidden generic no-method
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 with an appropriate message.
address@hidden deffn
+
address@hidden generic no-applicable-method
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 deffn
+
address@hidden generic no-next-method
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.
address@hidden deffn
+
+
 @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.
 
 @menu
-* Class precedence list::       
+* Class Precedence List::
+* Sorting Methods::
 @end menu
 
 
address@hidden Class precedence list
address@hidden Class precedence list
address@hidden Class Precedence List
address@hidden 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
address@hidden section is an adaptation of material from Jeff
+Dalton's (J.Dalton@@ed.ac.uk) @cite{Brief introduction to CLOS}}
 
address@hidden
address@hidden
-Rule 1: Each class is more specific than its address@hidden was \bf
address@hidden cartouche
address@hidden 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
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:
-
address@hidden
address@hidden
-Rule 2: For a given class, superclasses listed earlier are more
-        specific than those listed later.
address@hidden cartouche
address@hidden 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 @ref{fig:hier}, the class precedence list is
address@hidden
+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.
address@hidden
+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
address@hidden yields a clearer result:
-
address@hidden
-(map class-name (class-precedence-list B)) @result{} (B <object> <top>) 
address@hidden lisp
-
-
address@hidden Class Options
address@hidden Class Options
-
address@hidden {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
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}).
address@hidden deffn
-
address@hidden {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
address@hidden as the class name.
address@hidden deffn
-
address@hidden Accessing Slots
address@hidden Accessing Slots
-
address@hidden
-* Instance Slots::
-* Class Slots::
-* Handling Slot Access Errors::
address@hidden menu
-
address@hidden Instance Slots
address@hidden Instance Slots
-
-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 deffn
-
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 deffn
-
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 deffn
-
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}).
address@hidden 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
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 deffn
-
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
-
address@hidden calls the generic function
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 deffn
-
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 calls the generic function
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 calls the generic function
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 deffn
-
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 to @var{obj} and @var{value}.
-
address@hidden calls the generic function
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 deffn
-
address@hidden Class Slots
address@hidden Class Slots
-
-Slots whose allocation is per-class rather than per-instance can be
-referenced and set without needing to specify any particular instance.
-
address@hidden 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
address@hidden generic function, with the same arguments.
address@hidden deffn
-
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
address@hidden: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}.
address@hidden deffn
-
address@hidden Handling Slot Access Errors
address@hidden Handling Slot Access Errors
-
-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 generic slot-missing
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 deffn
-
address@hidden generic slot-unbound
address@hidden method slot-unbound (object <object>)
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.
address@hidden deffn
-
address@hidden Generic Functions and Accessors
address@hidden 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).
-
-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
-
address@hidden
-(set! (@code{accessor} @address@hidden) @code{value})
address@hidden 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.
-
address@hidden 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.
address@hidden deffn
-
address@hidden syntax define-accessor symbol
-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.
address@hidden deffn
-
address@hidden
-* Extending Primitives::
-* Merging Generics::
address@hidden menu
-
address@hidden Extending Primitives
address@hidden 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
address@hidden call) for a variable whose current value is a
-primitive.  But it can also be forced by calling
address@hidden
-
address@hidden {primitive procedure} enable-primitive-generic! primitive
-Force the creation of a generic function definition for
address@hidden
address@hidden deffn
-
-Once the generic function definition for a primitive has been created,
-it can be retrieved using @code{primitive-generic-generic}.
-
address@hidden {primitive procedure} primitive-generic-generic primitive
-Return the generic function definition of @var{primitive}.
-
address@hidden raises an error if @var{primitive}
-is not a primitive with generic capability.
address@hidden deffn
-
address@hidden Merging Generics
address@hidden 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
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(my-module)} and vice address@hidden note that @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.
-
address@hidden Adding Methods to Generic Functions
address@hidden Adding Methods to Generic Functions
-
-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 @code{(setter @var{generic-with-setter})}, where
address@hidden is a variable which is not yet bound to a
-generic-with-setter object, the expansion will include a call to
address@hidden
-
-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 deffn
-
address@hidden expressions look a little like Scheme procedure
-definitions of the form
-
address@hidden
-(define (name formals @dots{}) . body)
address@hidden example
-
-The important difference is that each formal parameter, apart from the
-possible ``rest'' argument, can be qualified by a class name:
address@hidden@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 @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.
-
address@hidden Invoking Generic Functions
address@hidden 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.
-
address@hidden
-* Determining Which Methods to Apply::
-* Handling Invocation Errors::
address@hidden menu
-
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 generic apply-generic
address@hidden method apply-generic (gf <generic>) args
address@hidden deffn
-
address@hidden generic compute-applicable-methods
address@hidden method compute-applicable-methods (gf <generic>) args
address@hidden deffn
-
address@hidden generic sort-applicable-methods
address@hidden method sort-applicable-methods (gf <generic>) methods args
address@hidden deffn
-
address@hidden generic method-more-specific?
address@hidden method method-more-specific? (m1 <method>) (m2 <method>) args
address@hidden deffn
-
address@hidden generic apply-method
address@hidden method apply-method (gf <generic>) methods build-next args
address@hidden deffn
-
address@hidden generic apply-methods
address@hidden method apply-methods (gf <generic>) (l <list>) args
address@hidden deffn
-
address@hidden Handling Invocation Errors
address@hidden Handling Invocation Errors
-
address@hidden generic no-method
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 with an appropriate message.
address@hidden deffn
-
address@hidden generic no-applicable-method
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 deffn
-
address@hidden generic no-next-method
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.
address@hidden deffn
-
address@hidden Redefining a Class
address@hidden 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
address@hidden again?
-
address@hidden
-* Default Class Redefinition Behaviour::
-* Customizing Class Redefinition::
address@hidden menu
 
address@hidden Default Class Redefinition Behaviour
address@hidden Default Class Redefinition Behaviour
-
-GOOPS' default answer to this question is as follows.
-
address@hidden @bullet
address@hidden
-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}).
-
address@hidden
-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.
-
address@hidden
-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.
address@hidden itemize
-
-To keep things tidy, GOOPS also needs to do a little housekeeping on
-methods that are associated with the redefined class.
-
address@hidden @bullet
address@hidden
-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.
-
address@hidden
-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.)
address@hidden 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 address@hidden
-
address@hidden Customizing Class Redefinition
address@hidden 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
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.
-
address@hidden 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.
address@hidden deffn
-
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.
address@hidden 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:
-
address@hidden
-(define-class <can-be-nameless> (<class>))
-
-(define-method (class-redefinition (old <can-be-nameless>)
-                                   (new <class>))
-  new)
address@hidden example
-
-When customization can be as easy as this, aren't you glad that GOOPS
-implements the far more difficult strategy as its default!
address@hidden Sorting Methods
address@hidden Sorting Methods
 
-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.
 
address@hidden @bullet
+The rules are that
address@hidden
 @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
address@hidden, and so on
 
 @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.
-
address@hidden generic change-class
address@hidden 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}).
-
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.
address@hidden deffn
-
-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.
 
 @menu
 * Classes::
-* Slots::
 * Instances::
-* Built-in classes::
+* Slots::
 * Generic Functions::
-* Generic Function Methods::
+* Accessing Slots::
 @end menu
 
 @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
address@hidden'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
address@hidden slot.
+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
address@hidden
-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
address@hidden slot.
+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
address@hidden 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.
+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.
address@hidden deffn
-
address@hidden {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. ]
+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
 
+
address@hidden Instances
address@hidden Instances
+
address@hidden {primitive procedure} class-of value
+Return the GOOPS class of any Scheme @var{value}.
address@hidden deffn
+
address@hidden {primitive procedure} instance? object
+Return @code{#t} if @var{object} is any GOOPS instance, otherwise
address@hidden
address@hidden deffn
+
address@hidden procedure is-a? object class
+Return @code{#t} if @var{object} is an instance of @var{class} or one of
+its subclasses.
address@hidden deffn
+
+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.
+
address@hidden
+(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>
address@hidden lisp
+
+
 @node Slots
 @subsection Slots
 
@@ -1819,84 +1450,41 @@ method, so, in general, the function returned by
 see @ref{Slot Options,, init-value}.
 @end deffn
 
address@hidden Instances
address@hidden Instances
-
address@hidden {primitive procedure} class-of value
-Return the GOOPS class of any Scheme @var{value}.
address@hidden deffn
-
address@hidden {primitive procedure} instance? object
-Return @code{#t} if @var{object} is any GOOPS instance, otherwise
address@hidden
address@hidden deffn
-
address@hidden procedure is-a? object class
-Return @code{#t} if @var{object} is an instance of @var{class} or one of
-its subclasses.
address@hidden deffn
-
-Implementation notes: @code{is-a?} uses @code{class-of} and
address@hidden to obtain the class precedence list for
address@hidden
-
address@hidden Built-in classes
address@hidden Built-in classes
-
-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.
-
address@hidden
-(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>
address@hidden lisp
-
 
 @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
 
address@hidden Generic Function Methods
address@hidden Generic Function Methods
+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
address@hidden slot.
+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
address@hidden slot.
+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
address@hidden slot.
+Return the procedure that implements @var{method}.  This is the value of
address@hidden's @code{procedure} slot.
 @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
 
+
address@hidden Accessing Slots
address@hidden Accessing Slots
+
+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 deffn
+
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 deffn
+
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 deffn
+
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}).
address@hidden 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
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 deffn
+
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
+
address@hidden calls the generic function
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 deffn
+
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 calls the generic function
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 calls the generic function
address@hidden if the application of the ``getter'' closure to
address@hidden returns an unbound value (@pxref{Accessing Slots,
+slot-unbound}).
address@hidden deffn
+
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 to @var{obj} and @var{value}.
+
address@hidden calls the generic function
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 deffn
+
+Slots whose allocation is per-class rather than per-instance can be
+referenced and set without needing to specify any particular instance.
+
address@hidden 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
address@hidden generic function, with the same arguments.
address@hidden deffn
+
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
address@hidden: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}.
address@hidden 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.
+
address@hidden generic slot-missing
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 deffn
+
address@hidden generic slot-unbound
address@hidden method slot-unbound (object <object>)
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.
address@hidden deffn
+
+
 @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})
address@hidden (@pxref{Accessing Slots,, slot-missing})
 
 @item
address@hidden (@pxref{Handling Slot Access Errors,, slot-unbound})
address@hidden (@pxref{Accessing Slots,, 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 Object Comparisons
address@hidden Object Comparisons
 
address@hidden generic eqv?
address@hidden method eqv? ((x <top>) (y <top>))
address@hidden generic equal?
address@hidden method equal? ((x <top>) (y <top>))
address@hidden generic =
address@hidden method = ((x <number>) (y <number>))
-Generic functions and default (unspecialized) methods for comparing two
-GOOPS objects.
address@hidden GOOPS Object Miscellany
address@hidden GOOPS Object Miscellany
 
-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.
address@hidden deffn
address@hidden Object Equality
 
address@hidden Cloning Objects
address@hidden Cloning Objects
+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.
+
address@hidden Cloning Objects
 
 @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
 
address@hidden Write and Display
address@hidden Write and Display
address@hidden Write and Display
 
 @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
address@hidden and @code{display} methods for your own classes, to
+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
address@hidden (@pxref{Adding Methods to Generic Functions,,
address@hidden (@pxref{Methods and Generic Functions,,
 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
+
+
address@hidden Class Options
address@hidden Class Options
+
address@hidden {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
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}).
address@hidden deffn
+
address@hidden {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
address@hidden as the class name.
address@hidden deffn
+
+
address@hidden Redefining a Class
address@hidden 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
address@hidden again?
+
address@hidden
+* Default Class Redefinition Behaviour::
+* Customizing Class Redefinition::
address@hidden menu
+
address@hidden Default Class Redefinition Behaviour
address@hidden Default Class Redefinition Behaviour
+
+GOOPS' default answer to this question is as follows.
+
address@hidden @bullet
address@hidden
+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}).
+
address@hidden
+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.
+
address@hidden
+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.
address@hidden itemize
+
+To keep things tidy, GOOPS also needs to do a little housekeeping on
+methods that are associated with the redefined class.
+
address@hidden @bullet
address@hidden
+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.
+
address@hidden
+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.)
address@hidden 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 address@hidden
+
address@hidden Customizing Class Redefinition
address@hidden 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
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.
+
address@hidden 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.
address@hidden deffn
+
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.
address@hidden 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:
+
address@hidden
+(define-class <can-be-nameless> (<class>))
+
+(define-method (class-redefinition (old <can-be-nameless>)
+                                   (new <class>))
+  new)
address@hidden 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:
+
address@hidden @bullet
address@hidden
+(remove-class-accessors! @var{old-class})
+
address@hidden
+(update-direct-method! @var{method} @var{old-class} @var{new-class})
+
address@hidden
+(update-direct-subclass! @var{subclass} @var{old-class} @var{new-class})
address@hidden 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.
+
address@hidden generic change-class
address@hidden 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}).
+
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.
address@hidden deffn
+
+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.


hooks/post-receive
-- 
GNU Guile



reply via email to

[Prev in Thread] Current Thread [Next in Thread]