summaryrefslogtreecommitdiff
path: root/doc/ref
diff options
context:
space:
mode:
Diffstat (limited to 'doc/ref')
-rw-r--r--doc/ref/ChangeLog-goops-200876
-rw-r--r--doc/ref/Makefile.am4
-rw-r--r--doc/ref/goops-tutorial.texi837
-rw-r--r--doc/ref/goops.texi2802
-rw-r--r--doc/ref/guile.texi4
-rw-r--r--doc/ref/hierarchy.eps127
-rw-r--r--doc/ref/hierarchy.pdf74
-rw-r--r--doc/ref/hierarchy.pngbin0 -> 6251 bytes
-rw-r--r--doc/ref/hierarchy.txt14
-rw-r--r--doc/ref/libguile-smobs.texi6
-rw-r--r--doc/ref/mop.text66
-rw-r--r--doc/ref/preface.texi9
-rw-r--r--doc/ref/tools.texi4
13 files changed, 4016 insertions, 7 deletions
diff --git a/doc/ref/ChangeLog-goops-2008 b/doc/ref/ChangeLog-goops-2008
new file mode 100644
index 000000000..a5a637d7b
--- /dev/null
+++ b/doc/ref/ChangeLog-goops-2008
@@ -0,0 +1,76 @@
+2008-02-06 Neil Jerram <neil@ossau.uklinux.net>
+
+ * goops-tutorial.texi (Next-method): Minor improvements to the
+ text.
+
+2006-09-28 Neil Jerram <neil@ossau.uklinux.net>
+
+ * goops.texi (Slot Options): Added example from Ludovic Courts
+ about difference between init-value, -form and -thunk.
+
+2006-04-21 Kevin Ryde <user42@zip.com.au>
+
+ * hierarchy.pdf: New file, converted from hierarchy.eps using
+ epstopdf, to let "make pdf" work.
+ * Makefile.am: (goops_TEXINFOS): Add it.
+
+2006-03-08 Ludovic Courts <ludovic.courtes@laas.fr>
+
+ * goops.texi (Slot Options): Note init-value is shared.
+
+2006-02-06 Marius Vollmer <mvo@zagadka.de>
+
+ * goops.texi (Basic Generic Function Creation): Added blurb about
+ merge-generics duplicates handler from NEWS.
+
+2004-06-28 Marius Vollmer <marius.vollmer@uni-dortmund.de>
+
+ * Makefile.am: Removed home-grown code for HTML generation.
+ Automake does it for us now.
+ (goops_TEXINFOS): Added hierarchy.png
+
+ * hierarchy.png: New file.
+
+2004-05-19 Kevin Ryde <user42@zip.com.au>
+
+ * Makefile.am (CLEANFILES): Remove, goops.tmp goops.cps cleaned by
+ automake these days.
+
+2003-04-17 Mikael Djurfeldt <djurfeldt@nada.kth.se>
+
+ * goops.texi (Object Comparisons): Removed object-eqv? and
+ object-equal? and added eqv?, equal? and =.
+
+2003-01-10 Mikael Djurfeldt <djurfeldt@nada.kth.se>
+
+ * goops.texi (Class Redefinition): Clarifications; Removed
+ mentioning of change-object-class.
+
+2002-11-07 Neil Jerram <neil@ossau.uklinux.net>
+
+ * goops.texi (Top): Say "Indices" before index nodes in main menu.
+ (Index): Removed (it was empty). Generally remove unnecessary
+ padding text that looks bad in HTML.
+
+2002-04-17 Marius Vollmer <mvo@zagadka.ping.de>
+
+ * Makefile.am (CLEANFILES): Added goops.tmp, goops.cps.
+
+2001-12-03 Thien-Thi Nguyen <ttn@giblet.glug.org>
+
+ * goops.texi: Grammar fix.
+
+2001-08-27 Neil Jerram <neil@ossau.uklinux.net>
+
+ * Makefile.am (goops_TEXINFOS): Remove ../AUTHORS.
+ (TEXINFO_TEX): Added; avoids shipping multiple copies of
+ texinfo.tex in a single distribution.
+
+ * goops.texi: Incorporate text previously in separate AUTHORS
+ file.
+
+2001-08-27 Neil Jerram <neil@ossau.uklinux.net>
+
+ The change log for files in this directory continues backwards
+ from 2001-08-27 in ../ChangeLog, as all the Guile documentation
+ prior to this date was contained in a single directory.
diff --git a/doc/ref/Makefile.am b/doc/ref/Makefile.am
index abf42edfe..276dd8e54 100644
--- a/doc/ref/Makefile.am
+++ b/doc/ref/Makefile.am
@@ -78,7 +78,9 @@ guile_TEXINFOS = preface.texi \
libguile-linking.texi \
libguile-extensions.texi \
api-init.texi \
- mod-getopt-long.texi
+ mod-getopt-long.texi \
+ goops.texi \
+ goops-tutorial.texi
ETAGS_ARGS = $(info_TEXINFOS) $(guile_TEXINFOS)
diff --git a/doc/ref/goops-tutorial.texi b/doc/ref/goops-tutorial.texi
new file mode 100644
index 000000000..11155dfae
--- /dev/null
+++ b/doc/ref/goops-tutorial.texi
@@ -0,0 +1,837 @@
+@c Original attribution:
+
+@c
+@c STk Reference manual (Appendix: An Introduction to STklos)
+@c
+@c Copyright 1993-1999 Erick Gallesio - I3S-CNRS/ESSI <eg@unice.fr>
+@c Permission to use, copy, modify, distribute,and license this
+@c software and its documentation for any purpose is hereby granted,
+@c provided that existing copyright notices are retained in all
+@c copies and that this notice is included verbatim in any
+@c distributions. No written agreement, license, or royalty fee is
+@c required for any of the authorized uses.
+@c This software is provided ``AS IS'' without express or implied
+@c warranty.
+@c
+
+@c Adapted for use in Guile with the authors permission
+
+@c @macro goops @c was {\stklos}
+@c GOOPS
+@c @end macro
+
+@c @macro guile @c was {\stk}
+@c Guile
+@c @end macro
+
+This is chapter was originally written by Erick Gallesio as an appendix
+for the STk reference manual, and subsequently adapted to @goops{}.
+
+@menu
+* Copyright::
+* Intro::
+* Class definition and instantiation::
+* Inheritance::
+* Generic functions::
+@end menu
+
+@node Copyright, Intro, Tutorial, Tutorial
+@section Copyright
+
+Original attribution:
+
+STk Reference manual (Appendix: An Introduction to STklos)
+
+Copyright 1993-1999 Erick Gallesio - I3S-CNRS/ESSI <eg@@unice.fr>
+Permission to use, copy, modify, distribute,and license this
+software and its documentation for any purpose is hereby granted,
+provided that existing copyright notices are retained in all
+copies and that this notice is included verbatim in any
+distributions. No written agreement, license, or royalty fee is
+required for any of the authorized uses.
+This software is provided ``AS IS'' without express or implied
+warranty.
+
+Adapted for use in Guile with the authors permission
+
+@node Intro, Class definition and instantiation, Copyright, Tutorial
+@section Introduction
+
+@goops{} is the object oriented extension to @guile{}. Its
+implementation is derived from @w{STk-3.99.3} by Erick Gallesio and
+version 1.3 of the Gregor Kiczales @cite{Tiny-Clos}. It is very close
+to CLOS, the Common Lisp Object System (@cite{CLtL2}) but is adapted for
+the Scheme language.
+
+Briefly stated, the @goops{} extension gives the user a full object
+oriented system with multiple inheritance and generic functions with
+multi-method dispatch. Furthermore, the implementation relies on a true
+meta object protocol, in the spirit of the one defined for CLOS
+(@cite{Gregor Kiczales: A Metaobject Protocol}).
+
+The purpose of this tutorial is to introduce briefly the @goops{}
+package and in no case will it replace the @goops{} reference manual
+(which needs to be urgently written now@ @dots{}).
+
+Note that the operations described in this tutorial resides in modules
+that may need to be imported before being available. The main module is
+imported by evaluating:
+
+@lisp
+(use-modules (oop goops))
+@end lisp
+@findex (oop goops)
+@cindex main module
+@cindex loading
+@cindex preparing
+
+@node Class definition and instantiation, Inheritance, Intro, Tutorial
+@section Class definition and instantiation
+
+@menu
+* Class definition::
+@end menu
+
+@node Class definition, , Class definition and instantiation, Class definition and instantiation
+@subsection Class definition
+
+A new class is defined with the @code{define-class}@footnote{Don't
+forget to import the @code{(oop goops)} module} macro. The syntax of
+@code{define-class} is close to CLOS @code{defclass}:
+
+@findex define-class
+@cindex class
+@lisp
+(define-class @var{class} (@var{superclass} @dots{})
+ @var{slot-description} @dots{}
+ @var{class-option} @dots{})
+@end lisp
+
+Class options will not be discussed in this tutorial. The list of
+@var{superclass}es specifies which classes to inherit properties from
+@var{class} (see @ref{Inheritance} for more details). A
+@var{slot-description} gives the name of a slot and, eventually, some
+``properties'' of this slot (such as its initial value, the function
+which permit to access its value, @dots{}). Slot descriptions will be
+discussed in @ref{Slot description}.
+@cindex slot
+
+As an example, let us define a type for representation of complex
+numbers in terms of real numbers. This can be done with the following
+class definition:
+
+@lisp
+(define-class <complex> (<number>)
+ r i)
+@end lisp
+
+This binds the variable @code{<complex>}@footnote{@code{<complex>} is in
+fact a builtin class in GOOPS. Because of this, GOOPS will create a new
+class. The old class will still serve as the type for Guile's native
+complex numbers.} to a new class whose instances contain two
+slots. These slots are called @code{r} an @code{i} and we suppose here
+that they contain respectively the real part and the imaginary part of a
+complex number. Note that this class inherits from @code{<number>} which
+is a pre-defined class. (@code{<number>} is the direct super class of
+the pre-defined class @code{<complex>} which, in turn, is the super
+class of @code{<real>} which is the super of
+@code{<integer>}.)@footnote{With the new definition of @code{<complex>},
+a @code{<real>} is not a @code{<complex>} since @code{<real>} inherits
+from @code{ <number>} rather than @code{<complex>}. In practice,
+inheritance could be modified @emph{a posteriori}, if needed. However,
+this necessitates some knowledge of the meta object protocol and it will
+not be shown in this document}.
+
+@node Inheritance, Generic functions, Class definition and instantiation, Tutorial
+@section Inheritance
+@c \label{inheritance}
+
+@menu
+* Class hierarchy and inheritance of slots::
+* Instance creation and slot access::
+* Slot description::
+* Class precedence list::
+@end menu
+
+@node Class hierarchy and inheritance of slots, Instance creation and slot access, Inheritance, Inheritance
+@subsection Class hierarchy and inheritance of slots
+Inheritance is specified upon class definition. As said in the
+introduction, @goops{} supports multiple inheritance. Here are some
+class definitions:
+
+@lisp
+(define-class A () a)
+(define-class B () b)
+(define-class C () c)
+(define-class D (A B) d a)
+(define-class E (A C) e c)
+(define-class F (D E) f)
+@end lisp
+
+@code{A}, @code{B}, @code{C} have a null list of super classes. In this
+case, the system will replace it by the list which only contains
+@code{<object>}, the root of all the classes defined by
+@code{define-class}. @code{D}, @code{E}, @code{F} use multiple
+inheritance: each class inherits from two previously defined classes.
+Those class definitions define a hierarchy which is shown in Figure@ 1.
+In this figure, the class @code{<top>} is also shown; this class is the
+super class of all Scheme objects. In particular, @code{<top>} is the
+super class of all standard Scheme types.
+
+@example
+@group
+@image{hierarchy}
+@center @emph{Fig 1: A class hierarchy}
+@iftex
+@emph{(@code{<complex>} which is the direct subclass of @code{<number>}
+and the direct superclass of @code{<real>} has been omitted in this
+figure.)}
+@end iftex
+@end group
+@end example
+
+The set of slots of a given class is calculated by taking the union of the
+slots of all its super class. For instance, each instance of the class
+D, defined before will have three slots (@code{a}, @code{b} and
+@code{d}). The slots of a class can be obtained by the @code{class-slots}
+primitive. For instance,
+
+@lisp
+(class-slots A) @result{} ((a))
+(class-slots E) @result{} ((a) (e) (c))
+(class-slots F) @result{} ((e) (c) (b) (d) (a) (f))
+@c used to be ((d) (a) (b) (c) (f))
+@end lisp
+
+@emph{Note: } The order of slots is not significant.
+
+@node Instance creation and slot access, Slot description, Class hierarchy and inheritance of slots, Inheritance
+@subsection Instance creation and slot access
+
+Creation of an instance of a previously defined
+class can be done with the @code{make} procedure. This
+procedure takes one mandatory parameter which is the class of the
+instance which must be created and a list of optional
+arguments. Optional arguments are generally used to initialize some
+slots of the newly created instance. For instance, the following form
+
+@findex make
+@cindex instance
+@lisp
+(define c (make <complex>))
+@end lisp
+
+will create a new @code{<complex>} object and will bind it to the @code{c}
+Scheme variable.
+
+Accessing the slots of the new complex number can be done with the
+@code{slot-ref} and the @code{slot-set!} primitives. @code{Slot-set!}
+primitive permits to set the value of an object slot and @code{slot-ref}
+permits to get its value.
+
+@findex slot-set!
+@findex slot-ref
+@lisp
+@group
+(slot-set! c 'r 10)
+(slot-set! c 'i 3)
+(slot-ref c 'r) @result{} 10
+(slot-ref c 'i) @result{} 3
+@end group
+@end lisp
+
+Using the @code{describe} function is a simple way to see all the
+slots of an object at one time: this function prints all the slots of an
+object on the standard output.
+
+First load the module @code{(oop goops describe)}:
+
+@example
+@code{(use-modules (oop goops describe))}
+@end example
+
+The expression
+
+@smalllisp
+(describe c)
+@end smalllisp
+
+will now print the following information on the standard output:
+
+@lisp
+#<<complex> 401d8638> is an instance of class <complex>
+Slots are:
+ r = 10
+ i = 3
+@end lisp
+
+@node Slot description, Class precedence list, Instance creation and slot access, Inheritance
+@subsection Slot description
+@c \label{slot-description}
+
+When specifying a slot, a set of options can be given to the
+system. Each option is specified with a keyword. The list of authorized
+keywords is given below:
+
+@cindex keyword
+@itemize @bullet
+@item
+@code{#:init-value} permits to supply a default value for the slot. This
+default value is obtained by evaluating the form given after the
+@code{#:init-form} in the global environment, at class definition time.
+@cindex default slot value
+@findex #:init-value
+@cindex top level environment
+
+@item
+@code{#:init-thunk} permits to supply a thunk that will provide a
+default value for the slot. The value is obtained by evaluating the
+thunk a instance creation time.
+@c CHECKME: in the global environment?
+@findex default slot value
+@findex #:init-thunk
+@cindex top level environment
+
+@item
+@code{#:init-keyword} permits to specify the keyword for initializing a
+slot. The init-keyword may be provided during instance creation (i.e. in
+the @code{make} optional parameter list). Specifying such a keyword
+during instance initialization will supersede the default slot
+initialization possibly given with @code{#:init-form}.
+@findex #:init-keyword
+
+@item
+@code{#:getter} permits to supply the name for the
+slot getter. The name binding is done in the
+environment of the @code{define-class} macro.
+@findex #:getter
+@cindex top level environment
+@cindex getter
+
+@item
+@code{#:setter} permits to supply the name for the
+slot setter. The name binding is done in the
+environment of the @code{define-class} macro.
+@findex #:setter
+@cindex top level environment
+@cindex setter
+
+@item
+@code{#:accessor} permits to supply the name for the
+slot accessor. The name binding is done in the global
+environment. An accessor permits to get and
+set the value of a slot. Setting the value of a slot is done with the extended
+version of @code{set!}.
+@findex set!
+@findex #:accessor
+@cindex top level environment
+@cindex accessor
+
+@item
+@code{#:allocation} permits to specify how storage for
+the slot is allocated. Three kinds of allocation are provided.
+They are described below:
+
+@itemize @minus
+@item
+@code{#:instance} indicates that each instance gets its own storage for
+the slot. This is the default.
+@item
+@code{#:class} indicates that there is one storage location used by all
+the direct and indirect instances of the class. This permits to define a
+kind of global variable which can be accessed only by (in)direct
+instances of the class which defines this slot.
+@item
+@code{#:each-subclass} indicates that there is one storage location used
+by all the direct instances of the class. In other words, if two classes
+are not siblings in the class hierarchy, they will not see the same
+value.
+@item
+@code{#:virtual} indicates that no storage will be allocated for this
+slot. It is up to the user to define a getter and a setter function for
+this slot. Those functions must be defined with the @code{#:slot-ref}
+and @code{#:slot-set!} options. See the example below.
+@findex #:slot-set!
+@findex #:slot-ref
+@findex #:virtual
+@findex #:class
+@findex #:each-subclass
+@findex #:instance
+@findex #:allocation
+@end itemize
+@end itemize
+
+To illustrate slot description, we shall redefine the @code{<complex>} class
+seen before. A definition could be:
+
+@lisp
+(define-class <complex> (<number>)
+ (r #:init-value 0 #:getter get-r #:setter set-r! #:init-keyword #:r)
+ (i #:init-value 0 #:getter get-i #:setter set-i! #:init-keyword #:i))
+@end lisp
+
+With this definition, the @code{r} and @code{i} slot are set to 0 by
+default. Value of a slot can also be specified by calling @code{make}
+with the @code{#:r} and @code{#:i} keywords. Furthermore, the generic
+functions @code{get-r} and @code{set-r!} (resp. @code{get-i} and
+@code{set-i!}) are automatically defined by the system to read and write
+the @code{r} (resp. @code{i}) slot.
+
+@lisp
+(define c1 (make <complex> #:r 1 #:i 2))
+(get-r c1) @result{} 1
+(set-r! c1 12)
+(get-r c1) @result{} 12
+(define c2 (make <complex> #:r 2))
+(get-r c2) @result{} 2
+(get-i c2) @result{} 0
+@end lisp
+
+Accessors provide an uniform access for reading and writing an object
+slot. Writing a slot is done with an extended form of @code{set!}
+which is close to the Common Lisp @code{setf} macro. So, another
+definition of the previous @code{<complex>} class, using the
+@code{#:accessor} option, could be:
+
+@findex set!
+@lisp
+(define-class <complex> (<number>)
+ (r #:init-value 0 #:accessor real-part #:init-keyword #:r)
+ (i #:init-value 0 #:accessor imag-part #:init-keyword #:i))
+@end lisp
+
+Using this class definition, reading the real part of the @code{c}
+complex can be done with:
+@lisp
+(real-part c)
+@end lisp
+and setting it to the value contained in the @code{new-value} variable
+can be done using the extended form of @code{set!}.
+@lisp
+(set! (real-part c) new-value)
+@end lisp
+
+Suppose now that we have to manipulate complex numbers with rectangular
+coordinates as well as with polar coordinates. One solution could be to
+have a definition of complex numbers which uses one particular
+representation and some conversion functions to pass from one
+representation to the other. A better solution uses virtual slots. A
+complete definition of the @code{<complex>} class using virtual slots is
+given in Figure@ 2.
+
+@example
+@group
+@lisp
+(define-class <complex> (<number>)
+ ;; True slots use rectangular coordinates
+ (r #:init-value 0 #:accessor real-part #:init-keyword #:r)
+ (i #:init-value 0 #:accessor imag-part #:init-keyword #:i)
+ ;; Virtual slots access do the conversion
+ (m #:accessor magnitude #:init-keyword #:magn
+ #:allocation #:virtual
+ #:slot-ref (lambda (o)
+ (let ((r (slot-ref o 'r)) (i (slot-ref o 'i)))
+ (sqrt (+ (* r r) (* i i)))))
+ #:slot-set! (lambda (o m)
+ (let ((a (slot-ref o 'a)))
+ (slot-set! o 'r (* m (cos a)))
+ (slot-set! o 'i (* m (sin a))))))
+ (a #:accessor angle #:init-keyword #:angle
+ #:allocation #:virtual
+ #:slot-ref (lambda (o)
+ (atan (slot-ref o 'i) (slot-ref o 'r)))
+ #:slot-set! (lambda(o a)
+ (let ((m (slot-ref o 'm)))
+ (slot-set! o 'r (* m (cos a)))
+ (slot-set! o 'i (* m (sin a)))))))
+
+@end lisp
+@center @emph{Fig 2: A @code{<complex>} number class definition using virtual slots}
+@end group
+@end example
+
+@sp 3
+This class definition implements two real slots (@code{r} and
+@code{i}). Values of the @code{m} and @code{a} virtual slots are
+calculated from real slot values. Reading a virtual slot leads to the
+application of the function defined in the @code{#:slot-ref}
+option. Writing such a slot leads to the application of the function
+defined in the @code{#:slot-set!} option. For instance, the following
+expression
+
+@findex #:slot-set!
+@findex #:slot-ref
+@lisp
+(slot-set! c 'a 3)
+@end lisp
+
+permits to set the angle of the @code{c} complex number. This expression
+conducts, in fact, to the evaluation of the following expression
+
+@lisp
+((lambda o m)
+ (let ((m (slot-ref o 'm)))
+ (slot-set! o 'r (* m (cos a)))
+ (slot-set! o 'i (* m (sin a))))
+ c 3)
+@end lisp
+
+A more complete example is given below:
+
+@example
+@group
+@lisp
+(define c (make <complex> #:r 12 #:i 20))
+(real-part c) @result{} 12
+(angle c) @result{} 1.03037682652431
+(slot-set! c 'i 10)
+(set! (real-part c) 1)
+(describe c) @result{}
+ #<<complex> 401e9b58> is an instance of class <complex>
+ Slots are:
+ r = 1
+ i = 10
+ m = 10.0498756211209
+ a = 1.47112767430373
+@end lisp
+@end group
+@end example
+
+Since initialization keywords have been defined for the four slots, we
+can now define the @code{make-rectangular} and @code{make-polar} standard
+Scheme primitives.
+
+@lisp
+(define make-rectangular
+ (lambda (x y) (make <complex> #:r x #:i y)))
+
+(define make-polar
+ (lambda (x y) (make <complex> #:magn x #:angle y)))
+@end lisp
+
+@node Class precedence list, , Slot description, Inheritance
+@subsection Class precedence list
+
+A class may have more than one superclass. @footnote{This section is an
+adaptation of Jeff Dalton's (J.Dalton@@ed.ac.uk) @cite{Brief
+introduction to CLOS}} With single inheritance (one superclass), it is
+easy to order the super classes from most to least specific. This is the
+rule:
+
+@display
+@cartouche
+Rule 1: Each class is more specific than its superclasses.@c was \bf
+@end cartouche
+@end display
+
+With multiple inheritance, ordering is harder. Suppose we have
+
+@lisp
+(define-class X ()
+ (x #:init-value 1))
+
+(define-class Y ()
+ (x #:init-value 2))
+
+(define-class Z (X Y)
+ (@dots{}))
+@end lisp
+
+In this case, the @code{Z} class is more specific than the @code{X} or
+@code{Y} class for instances of @code{Z}. However, the @code{#:init-value}
+specified in @code{X} and @code{Y} leads to a problem: which one
+overrides the other? The rule in @goops{}, as in CLOS, is that the
+superclasses listed earlier are more specific than those listed later.
+So:
+
+@display
+@cartouche
+Rule 2: For a given class, superclasses listed earlier are more
+ specific than those listed later.
+@end cartouche
+@end display
+
+These rules are used to compute a linear order for a class and all its
+superclasses, from most specific to least specific. This order is
+called the ``class precedence list'' of the class. Given these two
+rules, we can claim that the initial form for the @code{x} slot of
+previous example is 1 since the class @code{X} is placed before @code{Y}
+in class precedence list of @code{Z}.
+
+These two rules are not always enough to determine a unique order,
+however, but they give an idea of how things work. Taking the @code{F}
+class shown in Figure@ 1, the class precedence list is
+
+@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.
+
+The precedence list of a class can be obtained by the function
+@code{class-precedence-list}. This function returns a ordered
+list whose first element is the most specific class. For instance,
+
+@lisp
+(class-precedence-list B) @result{} (#<<class> B 401b97c8>
+ #<<class> <object> 401e4a10>
+ #<<class> <top> 4026a9d8>)
+@end lisp
+
+However, this result is not too much readable; using the function
+@code{class-name} yields a clearer result:
+
+@lisp
+(map class-name (class-precedence-list B)) @result{} (B <object> <top>)
+@end lisp
+
+@node Generic functions, , Inheritance, Tutorial
+@section Generic functions
+
+@menu
+* Generic functions and methods::
+* Next-method::
+* Example::
+@end menu
+
+@node Generic functions and methods, Next-method, Generic functions, Generic functions
+@subsection Generic functions and methods
+
+@c \label{gf-n-methods}
+Neither @goops{} nor CLOS use the message mechanism for methods as most
+Object Oriented language do. Instead, they use the notion of
+@dfn{generic functions}. A generic function can be seen as a methods
+``tanker''. When the evaluator requested the application of a generic
+function, all the methods of this generic function will be grabbed and
+the most specific among them will be applied. We say that a method
+@var{M} is @emph{more specific} than a method @var{M'} if the class of
+its parameters are more specific than the @var{M'} ones. To be more
+precise, when a generic function must be ``called'' the system will:
+
+@cindex generic function
+@enumerate
+@item
+search among all the generic function those which are applicable
+@item
+sort the list of applicable methods in the ``most specific'' order
+@item
+call the most specific method of this list (i.e. the first method of
+the sorted methods list).
+@end enumerate
+
+The definition of a generic function is done with the
+@code{define-generic} macro. Definition of a new method is done with the
+@code{define-method} macro. Note that @code{define-method} automatically
+defines the generic function if it has not been defined
+before. Consequently, most of the time, the @code{define-generic} needs
+not be used.
+@findex define-generic
+@findex define-method
+Consider the following definitions:
+
+@lisp
+(define-generic G)
+(define-method (G (a <integer>) b) 'integer)
+(define-method (G (a <real>) b) 'real)
+(define-method (G a b) 'top)
+@end lisp
+
+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
+
+@cindex parameter specializers
+@lisp
+(define-method (G (a <integer>) (b <top>)) 'integer)
+@end lisp
+
+Now, let us look at some possible calls to generic function @var{G}:
+
+@lisp
+(G 2 3) @result{} integer
+(G 2 #t) @result{} integer
+(G 1.2 'a) @result{} real
+@c (G #3 'a) @result{} real @c was {\sharpsign}
+(G #t #f) @result{} top
+(G 1 2 3) @result{} error (since no method exists for 3 parameters)
+@end lisp
+
+The preceding methods use only one specializer per parameter list. Of
+course, each parameter can use a specializer. In this case, the
+parameter list is scanned from left to right to determine the
+applicability of a method. Suppose we declare now
+
+@lisp
+(define-method (G (a <integer>) (b <number>)) 'integer-number)
+(define-method (G (a <integer>) (b <real>)) 'integer-real)
+(define-method (G (a <integer>) (b <integer>)) 'integer-integer)
+(define-method (G a (b <number>)) 'top-number)
+@end lisp
+
+In this case,
+
+@lisp
+(G 1 2) @result{} integer-integer
+(G 1 1.0) @result{} integer-real
+(G 1 #t) @result{} integer
+(G 'a 1) @result{} top-number
+@end lisp
+
+@node Next-method, Example, Generic functions and methods, Generic functions
+@subsection Next-method
+
+When you call a generic function, with a particular set of arguments,
+GOOPS builds a list of all the methods that are applicable to those
+arguments and orders them by how closely the method definitions match
+the actual argument types. It then calls the method at the top of this
+list. If the selected method's code wants to call on to the next method
+in this list, it can do so by using @code{next-method}.
+
+@lisp
+(define-method (Test (a <integer>)) (cons 'integer (next-method)))
+(define-method (Test (a <number>)) (cons 'number (next-method)))
+(define-method (Test a) (list 'top))
+@end lisp
+
+With these definitions,
+
+@lisp
+(Test 1) @result{} (integer number top)
+(Test 1.0) @result{} (number top)
+(Test #t) @result{} (top)
+@end lisp
+
+@code{next-method} is always called as just @code{(next-method)}. The
+arguments for the next method call are always implicit, and always the
+same as for the original method call.
+
+If you want to call on to a method with the same name but with a
+different set of arguments (as you might with overloaded methods in C++,
+for example), you do not use @code{next-method}, but instead simply
+write the new call as usual:
+
+@lisp
+(define-method (Test (a <number>) min max)
+ (if (and (>= a min) (<= a max))
+ (display "Number is in range\n"))
+ (Test a))
+
+(Test 2 1 10)
+@print{}
+Number is in range
+@result{}
+(integer number top)
+@end lisp
+
+(You should be careful in this case that the @code{Test} calls do not
+lead to an infinite recursion, but this consideration is just the same
+as in Scheme code in general.)
+
+@node Example, , Next-method, Generic functions
+@subsection Example
+
+In this section we shall continue to define operations on the @code{<complex>}
+class defined in Figure@ 2. Suppose that we want to use it to implement
+complex numbers completely. For instance a definition for the addition of
+two complexes could be
+
+@lisp
+(define-method (new-+ (a <complex>) (b <complex>))
+ (make-rectangular (+ (real-part a) (real-part b))
+ (+ (imag-part a) (imag-part b))))
+@end lisp
+
+To be sure that the @code{+} used in the method @code{new-+} is the standard
+addition we can do:
+
+@lisp
+(define-generic new-+)
+
+(let ((+ +))
+ (define-method (new-+ (a <complex>) (b <complex>))
+ (make-rectangular (+ (real-part a) (real-part b))
+ (+ (imag-part a) (imag-part b)))))
+@end lisp
+
+The @code{define-generic} ensures here that @code{new-+} will be defined
+in the global environment. Once this is done, we can add methods to the
+generic function @code{new-+} which make a closure on the @code{+}
+symbol. A complete writing of the @code{new-+} methods is shown in
+Figure@ 3.
+
+@example
+@group
+@lisp
+(define-generic new-+)
+
+(let ((+ +))
+
+ (define-method (new-+ (a <real>) (b <real>)) (+ a b))
+
+ (define-method (new-+ (a <real>) (b <complex>))
+ (make-rectangular (+ a (real-part b)) (imag-part b)))
+
+ (define-method (new-+ (a <complex>) (b <real>))
+ (make-rectangular (+ (real-part a) b) (imag-part a)))
+
+ (define-method (new-+ (a <complex>) (b <complex>))
+ (make-rectangular (+ (real-part a) (real-part b))
+ (+ (imag-part a) (imag-part b))))
+
+ (define-method (new-+ (a <number>)) a)
+
+ (define-method (new-+) 0)
+
+ (define-method (new-+ . args)
+ (new-+ (car args)
+ (apply new-+ (cdr args)))))
+
+(set! + new-+)
+@end lisp
+
+@center @emph{Fig 3: Extending @code{+} for dealing with complex numbers}
+@end group
+@end example
+
+@sp 3
+We use here the fact that generic function are not obliged to have the
+same number of parameters, contrarily to CLOS. The four first methods
+implement the dyadic addition. The fifth method says that the addition
+of a single element is this element itself. The sixth method says that
+using the addition with no parameter always return 0. The last method
+takes an arbitrary number of parameters@footnote{The parameter list for
+a @code{define-method} follows the conventions used for Scheme
+procedures. In particular it can use the dot notation or a symbol to
+denote an arbitrary number of parameters}. This method acts as a kind
+of @code{reduce}: it calls the dyadic addition on the @emph{car} of the
+list and on the result of applying it on its rest. To finish, the
+@code{set!} permits to redefine the @code{+} symbol to our extended
+addition.
+
+@sp 3
+To terminate our implementation (integration?) of complex numbers, we can
+redefine standard Scheme predicates in the following manner:
+
+@lisp
+(define-method (complex? c <complex>) #t)
+(define-method (complex? c) #f)
+
+(define-method (number? n <number>) #t)
+(define-method (number? n) #f)
+@dots{}
+@dots{}
+@end lisp
+
+Standard primitives in which complex numbers are involved could also be
+redefined in the same manner.
+
diff --git a/doc/ref/goops.texi b/doc/ref/goops.texi
new file mode 100644
index 000000000..c20539f61
--- /dev/null
+++ b/doc/ref/goops.texi
@@ -0,0 +1,2802 @@
+@macro goops
+GOOPS
+@end macro
+
+@macro guile
+Guile
+@end macro
+
+@node GOOPS
+@chapter GOOPS
+
+@menu
+* Introduction::
+* Getting Started::
+* Reference Manual::
+* MOP Specification::
+* Tutorial::
+@end menu
+
+@node Introduction
+@section Introduction
+
+@goops{} is the object oriented extension to @guile{}. Its
+implementation is derived from @w{STk-3.99.3} by Erick Gallesio and
+version 1.3 of Gregor Kiczales @cite{Tiny-Clos}. It is very close in
+spirit to CLOS, the Common Lisp Object System (@cite{CLtL2}) but is
+adapted for the Scheme language. While GOOPS is not compatible with any
+of these systems, GOOPS contains a compatibility module which allows for
+execution of STKlos programs.
+
+Briefly stated, the @goops{} extension gives the user a full object
+oriented system with multiple inheritance and generic functions with
+multi-method dispatch. Furthermore, the implementation relies on a true
+meta object protocol, in the spirit of the one defined for CLOS
+(@cite{Gregor Kiczales: A Metaobject Protocol}).
+
+@node Getting Started
+@section Getting Started
+
+@menu
+* Running GOOPS::
+
+Examples of some basic GOOPS functionality.
+
+* Methods::
+* User-defined types::
+* Asking for the type of an object::
+
+See further in the GOOPS tutorial available in this distribution in
+info (goops.info) and texinfo format.
+@end menu
+
+@node Running GOOPS
+@subsection Running GOOPS
+
+@enumerate
+@item
+Type
+
+@smalllisp
+guile-oops
+@end smalllisp
+
+You should now be at the Guile prompt ("guile> ").
+
+@item
+Type
+
+@smalllisp
+(use-modules (oop goops))
+@end smalllisp
+
+to load GOOPS. (If your system supports dynamic loading, you
+should be able to do this not only from `guile-oops' but from an
+arbitrary Guile interpreter.)
+@end enumerate
+
+We're now ready to try some basic GOOPS functionality.
+
+@node Methods
+@subsection Methods
+
+@smalllisp
+@group
+(define-method (+ (x <string>) (y <string>))
+ (string-append x y))
+
+(+ 1 2) --> 3
+(+ "abc" "de") --> "abcde"
+@end group
+@end smalllisp
+
+@node User-defined types
+@subsection User-defined types
+
+@smalllisp
+(define-class <2D-vector> ()
+ (x #:init-value 0 #:accessor x-component #:init-keyword #:x)
+ (y #:init-value 0 #:accessor y-component #:init-keyword #:y))
+
+@group
+(use-modules (ice-9 format))
+
+(define-method (write (obj <2D-vector>) port)
+ (display (format #f "<~S, ~S>" (x-component obj) (y-component obj))
+ port))
+
+(define v (make <2D-vector> #:x 3 #:y 4))
+
+v --> <3, 4>
+@end group
+
+@group
+(define-method (+ (x <2D-vector>) (y <2D-vector>))
+ (make <2D-vector>
+ #:x (+ (x-component x) (x-component y))
+ #:y (+ (y-component x) (y-component y))))
+
+(+ v v) --> <6, 8>
+@end group
+@end smalllisp
+
+@node Asking for the type of an object
+@subsection Types
+
+@example
+(class-of v) --> #<<class> <2D-vector> 40241ac0>
+<2D-vector> --> #<<class> <2D-vector> 40241ac0>
+(class-of 1) --> #<<class> <integer> 401b2a98>
+<integer> --> #<<class> <integer> 401b2a98>
+
+(is-a? v <2D-vector>) --> #t
+@end example
+
+@node Reference Manual
+@section Reference Manual
+
+This chapter is the GOOPS reference manual. It aims to describe all the
+syntax, procedures, options and associated concepts that a typical
+application author would need to understand in order to use GOOPS
+effectively in their application. It also describes what is meant by
+the GOOPS ``metaobject protocol'' (aka ``MOP''), and indicates how
+authors can use the metaobject protocol to customize the behaviour of
+GOOPS itself.
+
+For a detailed specification of the GOOPS metaobject protocol, see
+@ref{MOP Specification}.
+
+@menu
+* Introductory Remarks::
+* Defining New Classes::
+* Creating Instances::
+* Accessing Slots::
+* Creating Generic Functions::
+* Adding Methods to Generic Functions::
+* Invoking Generic Functions::
+* Redefining a Class::
+* Changing the Class of an Instance::
+* Introspection::
+* Miscellaneous Functions::
+@end menu
+
+@node Introductory Remarks
+@subsection Introductory Remarks
+
+GOOPS is an object-oriented programming system based on a ``metaobject
+protocol'' 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 metaobject protocol (aka ``MOP'') is and how
+it works. On the other hand, the MOP underlies even the customizations
+that application authors are likely to make use of very quickly --- such
+as defining an @code{initialize} method to customize the initialization
+of instances of an application-defined class --- and an understanding of
+the MOP makes it much easier to explain such customizations in a precise
+way. And in the long run, understanding the MOP is the key both to
+understanding GOOPS at a deeper level and to taking full advantage of
+GOOPS' power, by customizing the behaviour of GOOPS itself.
+
+Each of the following sections of the reference manual is arranged
+such that the most basic usage is introduced first, and then subsequent
+subsubsections discuss the related internal functions and metaobject
+protocols, finishing with a description of how to customize that area of
+functionality.
+
+These introductory remarks continue with a few words about metaobjects
+and the MOP. Readers who do not want to be bothered yet with the MOP
+and customization could safely skip this subsubsection on a first reading,
+and should correspondingly skip subsequent subsubsections that are
+concerned with internals and customization.
+
+In general, this reference manual assumes familiarity with standard
+object oriented concepts and terminology. However, some of the terms
+used in GOOPS are less well known, so the Terminology subsubsection
+provides definitions for these terms.
+
+@menu
+* Metaobjects and the Metaobject Protocol::
+* Terminology::
+@end menu
+
+@node Metaobjects and the Metaobject Protocol
+@subsubsection Metaobjects and the Metaobject Protocol
+
+The conceptual building blocks of GOOPS are classes, slot definitions,
+instances, generic functions and methods. A class is a grouping of
+inheritance relations and slot definitions. An instance is an object
+with slots that are allocated following the rules implied by its class's
+superclasses and slot definitions. A generic function is a collection
+of methods and rules for determining which of those methods to apply
+when the generic function is invoked. A method is a procedure and a set
+of specializers that specify the type of arguments to which the
+procedure is applicable.
+
+Of these entities, GOOPS represents classes, generic functions and
+methods as ``metaobjects''. In other words, the values in a GOOPS
+program that describe classes, generic functions and methods, are
+themselves instances (or ``objects'') of special GOOPS classes that
+encapsulate the behaviour, respectively, of classes, generic functions,
+and methods.
+
+(The other two entities are slot definitions and instances. Slot
+definitions are not strictly instances, but every slot definition is
+associated with a GOOPS class that specifies the behaviour of the slot
+as regards accessibility and protection from garbage collection.
+Instances are of course objects in the usual sense, and there is no
+benefit from thinking of them as metaobjects.)
+
+The ``metaobject protocol'' (aka ``MOP'') is the specification of the
+generic functions which determine the behaviour of these metaobjects and
+the circumstances in which these generic functions are invoked.
+
+For a concrete example of what this means, consider how GOOPS calculates
+the set of slots for a class that is being defined using
+@code{define-class}. The desired set of slots is the union of the new
+class's direct slots and the slots of all its superclasses. But
+@code{define-class} itself does not perform this calculation. Instead,
+there is a method of the @code{initialize} generic function that is
+specialized for instances of type @code{<class>}, and it is this method
+that performs the slot calculation.
+
+@code{initialize} is a generic function which GOOPS calls whenever a new
+instance is created, immediately after allocating memory for a new
+instance, in order to initialize the new instance's slots. The sequence
+of steps is as follows.
+
+@itemize @bullet
+@item
+@code{define-class} uses @code{make} to make a new instance of the
+@code{<class>}, passing as initialization arguments the superclasses,
+slot definitions and class options that were specified in the
+@code{define-class} form.
+
+@item
+@code{make} allocates memory for the new instance, and then invokes the
+@code{initialize} generic function to initialize the new instance's
+slots.
+
+@item
+The @code{initialize} generic function applies the method that is
+specialized for instances of type @code{<class>}, and this method
+performs the slot calculation.
+@end itemize
+
+In other words, rather than being hardcoded in @code{define-class}, the
+behaviour of class definition is encapsulated by generic function
+methods that are specialized for the class @code{<class>}.
+
+It is possible to create a new class that inherits from @code{<class>},
+which is called a ``metaclass'', and to write a new @code{initialize}
+method that is specialized for instances of the new metaclass. Then, if
+the @code{define-class} form includes a @code{#:metaclass} class option
+whose value is the new metaclass, the class that is defined by the
+@code{define-class} form will be an instance of the new metaclass rather
+than of the default @code{<class>}, and will be defined in accordance
+with the new @code{initialize} method. Thus the default slot
+calculation, as well as any other aspect of the new class's relationship
+with its superclasses, can be modified or overridden.
+
+In a similar way, the behaviour of generic functions can be modified or
+overridden by creating a new class that inherits from the standard
+generic function class @code{<generic>}, writing appropriate methods
+that are specialized to the new class, and creating new generic
+functions that are instances of the new class.
+
+The same is true for method metaobjects. And the same basic mechanism
+allows the application class author to write an @code{initialize} method
+that is specialized to their application class, to initialize instances
+of that class.
+
+Such is the power of the MOP. Note that @code{initialize} is just one
+of a large number of generic functions that can be customized to modify
+the behaviour of application objects and classes and of GOOPS itself.
+Each subsequent section of the reference manual covers a particular area
+of GOOPS functionality, and describes the generic functions that are
+relevant for customization of that area.
+
+We conclude this subsubsection by emphasizing a point that may seem
+obvious, but contrasts with the corresponding situation in some other
+MOP implementations, such as CLOS. The point is simply that an
+identifier which represents a GOOPS class or generic function is a
+variable with a first-class value, the value being an instance of class
+@code{<class>} or @code{<generic>}. (In CLOS, on the other hand, a
+class identifier is a symbol that indexes the corresponding class
+metaobject in a separate namespace for classes.) This is, of course,
+simply an extension of the tendency in Scheme to avoid the unnecessary
+use of, on the one hand, syntactic forms that require unevaluated
+arguments and, on the other, separate identifier namespaces (e.g. for
+class names), but it is worth noting that GOOPS conforms fully to this
+Schemely principle.
+
+@node Terminology
+@subsubsection Terminology
+
+It is assumed that the reader is already familiar with standard object
+orientation concepts such as classes, objects/instances,
+inheritance/subclassing, generic functions and methods, encapsulation
+and polymorphism.
+
+This section explains some of the less well known concepts and
+terminology that GOOPS uses, which are assumed by the following sections
+of the reference manual.
+
+@subsubheading Metaclass
+
+A @dfn{metaclass} is the class of an object which represents a GOOPS
+class. Put more succinctly, a metaclass is a class's class.
+
+Most GOOPS classes have the metaclass @code{<class>} and, by default,
+any new class that is created using @code{define-class} has the
+metaclass @code{<class>}.
+
+But what does this really mean? To find out, let's look in more detail
+at what happens when a new class is created using @code{define-class}:
+
+@example
+(define-class <my-class> (<object>) . slots)
+@end example
+
+GOOPS actually expands the @code{define-class} form to something like
+this
+
+@example
+(define <my-class> (class (<object>) . slots))
+@end example
+
+and thence to
+
+@example
+(define <my-class>
+ (make <class> #:supers (list <object>) #:slots slots))
+@end example
+
+In other words, the value of @code{<my-class>} is in fact an instance of
+the class @code{<class>} with slot values specifying the superclasses
+and slot definitions for the class @code{<my-class>}. (@code{#:supers}
+and @code{#:slots} are initialization keywords for the @code{dsupers}
+and @code{dslots} slots of the @code{<class>} class.)
+
+In order to take advantage of the full power of the GOOPS metaobject
+protocol (@pxref{MOP Specification}), it is sometimes desirable to
+create a new class with a metaclass other than the default
+@code{<class>}. This is done by writing:
+
+@example
+(define-class <my-class2> (<object>)
+ slot @dots{}
+ #:metaclass <my-metaclass>)
+@end example
+
+GOOPS expands this to something like:
+
+@example
+(define <my-class2>
+ (make <my-metaclass> #:supers (list <object>) #:slots slots))
+@end example
+
+In this case, the value of @code{<my-class2>} is an instance of the more
+specialized class @code{<my-metaclass>}. Note that
+@code{<my-metaclass>} itself must previously have been defined as a
+subclass of @code{<class>}. For a full discussion of when and how it is
+useful to define new metaclasses, see @ref{MOP Specification}.
+
+Now let's make an instance of @code{<my-class2>}:
+
+@example
+(define my-object (make <my-class2> ...))
+@end example
+
+All of the following statements are correct expressions of the
+relationships between @code{my-object}, @code{<my-class2>},
+@code{<my-metaclass>} and @code{<class>}.
+
+@itemize @bullet
+@item
+@code{my-object} is an instance of the class @code{<my-class2>}.
+
+@item
+@code{<my-class2>} is an instance of the class @code{<my-metaclass>}.
+
+@item
+@code{<my-metaclass>} is an instance of the class @code{<class>}.
+
+@item
+The class of @code{my-object} is @code{<my-class2>}.
+
+@item
+The metaclass of @code{my-object} is @code{<my-metaclass>}.
+
+@item
+The class of @code{<my-class2>} is @code{<my-metaclass>}.
+
+@item
+The metaclass of @code{<my-class2>} is @code{<class>}.
+
+@item
+The class of @code{<my-metaclass>} is @code{<class>}.
+
+@item
+The metaclass of @code{<my-metaclass>} is @code{<class>}.
+
+@item
+@code{<my-class2>} is not a metaclass, since it is does not inherit from
+@code{<class>}.
+
+@item
+@code{<my-metaclass>} is a metaclass, since it inherits from
+@code{<class>}.
+@end itemize
+
+@subsubheading Class Precedence List
+
+The @dfn{class precedence list} of a class is the list of all direct and
+indirect superclasses of that class, including the class itself.
+
+In the absence of multiple inheritance, the class precedence list is
+ordered straightforwardly, beginning with the class itself and ending
+with @code{<top>}.
+
+For example, given this inheritance hierarchy:
+
+@example
+(define-class <invertebrate> (<object>) @dots{})
+(define-class <echinoderm> (<invertebrate>) @dots{})
+(define-class <starfish> (<echinoderm>) @dots{})
+@end example
+
+the class precedence list of <starfish> would be
+
+@example
+(<starfish> <echinoderm> <invertebrate> <object> <top>)
+@end example
+
+With multiple inheritance, the algorithm is a little more complicated.
+A full description is provided by the GOOPS Tutorial: see @ref{Class
+precedence list}.
+
+``Class precedence list'' is often abbreviated, in documentation and
+Scheme variable names, to @dfn{cpl}.
+
+@subsubheading Accessor
+
+An @dfn{accessor} is a generic function with both reference and setter
+methods.
+
+@example
+(define-accessor perimeter)
+@end example
+
+Reference methods for an accessor are defined in the same way as generic
+function methods.
+
+@example
+(define-method (perimeter (s <square>))
+ (* 4 (side-length s)))
+@end example
+
+Setter methods for an accessor are defined by specifying ``(setter
+<accessor-name>)'' as the first parameter of the @code{define-method}
+call.
+
+@example
+(define-method ((setter perimeter) (s <square>) (n <number>))
+ (set! (side-length s) (/ n 4)))
+@end example
+
+Once an appropriate setter method has been defined in this way, it can
+be invoked using the generalized @code{set!} syntax, as in:
+
+@example
+(set! (perimeter s1) 18.3)
+@end example
+
+@node Defining New Classes
+@subsection Defining New Classes
+
+[ *fixme* Somewhere in this manual there needs to be an introductory
+discussion about GOOPS classes, generic functions and methods, covering
+
+@itemize @bullet
+@item
+how classes encapsulate related items of data in @dfn{slots}
+
+@item
+why it is that, unlike in C++ and Java, a class does not encapsulate the
+methods that act upon the class (at least not in the C++/Java sense)
+
+@item
+how generic functions provide a more general solution that provides for
+dispatch on all argument types, and avoids idiosyncracies like C++'s
+friend classes
+
+@item
+how encapsulation in the sense of data- and code-hiding, or of
+distinguishing interface from implementation, is treated in Guile as an
+orthogonal concept to object orientation, and is the responsibility of
+the module system.
+@end itemize
+
+Some of this is covered in the Tutorial chapter, in @ref{Generic
+functions and methods} - perhaps the best solution would be to expand
+the discussion there. ]
+
+@menu
+* Basic Class Definition::
+* Class Options::
+* Slot Options::
+* Class Definition Internals::
+* Customizing Class Definition::
+* STKlos Compatibility::
+@end menu
+
+@node Basic Class Definition
+@subsubsection Basic Class Definition
+
+New classes are defined using the @code{define-class} syntax, with
+arguments that specify the classes that the new class should inherit
+from, the direct slots of the new class, and any required class options.
+
+@deffn syntax define-class name (super @dots{}) slot-definition @dots{} . options
+Define a class called @var{name} that inherits from @var{super}s, with
+direct slots defined by @var{slot-definition}s and class options
+@var{options}. The newly created class is bound to the variable name
+@var{name} in the current environment.
+
+Each @var{slot-definition} is either a symbol that names the slot or a
+list,
+
+@example
+(@var{slot-name-symbol} . @var{slot-options})
+@end example
+
+where @var{slot-name-symbol} is a symbol and @var{slot-options} is a
+list with an even number of elements. The even-numbered elements of
+@var{slot-options} (counting from zero) are slot option keywords; the
+odd-numbered elements are the corresponding values for those keywords.
+
+@var{options} is a similarly structured list containing class option
+keywords and corresponding values.
+@end deffn
+
+The standard GOOPS class and slot options are described in the following
+subsubsections: see @ref{Class Options} and @ref{Slot Options}.
+
+Example 1. Define a class that combines two pre-existing classes by
+inheritance but adds no new slots.
+
+@example
+(define-class <combined> (<tree> <bicycle>))
+@end example
+
+Example 2. Define a @code{regular-polygon} class with slots for side
+length and number of sides that have default values and can be accessed
+via the generic functions @code{side-length} and @code{num-sides}.
+
+@example
+(define-class <regular-polygon> ()
+ (sl #:init-value 1 #:accessor side-length)
+ (ns #:init-value 5 #:accessor num-sides))
+@end example
+
+Example 3. Define a class whose behavior (and that of its instances) is
+customized via an application-defined metaclass.
+
+@example
+(define-class <tcpip-fsm> ()
+ (s #:init-value #f #:accessor state)
+ ...
+ #:metaclass <finite-state-class>)
+@end example
+
+@node Class Options
+@subsubsection Class Options
+
+@deffn {class option} #:metaclass metaclass
+The @code{#:metaclass} class option specifies the metaclass of the class
+being defined. @var{metaclass} must be a class that inherits from
+@code{<class>}. For an introduction to the use of metaclasses, see
+@ref{Metaobjects and the Metaobject Protocol} and @ref{Terminology}.
+
+If the @code{#:metaclass} option is absent, GOOPS reuses or constructs a
+metaclass for the new class by calling @code{ensure-metaclass}
+(@pxref{Class Definition Internals,, ensure-metaclass}).
+@end deffn
+
+@deffn {class option} #:name name
+The @code{#:name} class option specifies the new class's name. This
+name is used to identify the class whenever related objects - the class
+itself, its instances and its subclasses - are printed.
+
+If the @code{#:name} option is absent, GOOPS uses the first argument to
+@code{define-class} as the class name.
+@end deffn
+
+@deffn {class option} #:environment environment
+*fixme* Not sure about this one, but I think that the
+@code{#:environment} option specifies the environment in which the
+class's getters and setters are computed and evaluated.
+
+If the @code{#:environment} option is not specified, the class's
+environment defaults to the top-level environment in which the
+@code{define-class} form appears.
+@end deffn
+
+@node Slot Options
+@subsubsection Slot Options
+
+@deffn {slot option} #:allocation allocation
+The @code{#:allocation} option tells GOOPS how to allocate storage for
+the slot. Possible values for @var{allocation} are
+
+@itemize @bullet
+@item @code{#:instance}
+
+Indicates that GOOPS should create separate storage for this slot in
+each new instance of the containing class (and its subclasses).
+
+@item @code{#:class}
+
+Indicates that GOOPS should create storage for this slot that is shared
+by all instances of the containing class (and its subclasses). In other
+words, a slot in class @var{C} with allocation @code{#:class} is shared
+by all @var{instance}s for which @code{(is-a? @var{instance} @var{c})}.
+
+@item @code{#:each-subclass}
+
+Indicates that GOOPS should create storage for this slot that is shared
+by all @emph{direct} instances of the containing class, and that
+whenever a subclass of the containing class is defined, GOOPS should
+create a new storage for the slot that is shared by all @emph{direct}
+instances of the subclass. In other words, a slot with allocation
+@code{#:each-subclass} is shared by all instances with the same
+@code{class-of}.
+
+@item @code{#:virtual}
+
+Indicates that GOOPS should not allocate storage for this slot. The
+slot definition must also include the @code{#:slot-ref} and
+@code{#:slot-set!} options to specify how to reference and set the value
+for this slot.
+@end itemize
+
+The default value is @code{#:instance}.
+
+Slot allocation options are processed when defining a new class by the
+generic function @code{compute-get-n-set}, which is specialized by the
+class's metaclass. Hence new types of slot allocation can be
+implemented by defining a new metaclass and a method for
+@code{compute-get-n-set} that is specialized for the new metaclass. For
+an example of how to do this, see @ref{Customizing Class Definition}.
+@end deffn
+
+@deffn {slot option} #:slot-ref getter
+@deffnx {slot option} #:slot-set! setter
+The @code{#:slot-ref} and @code{#:slot-set!} options must be specified
+if the slot allocation is @code{#:virtual}, and are ignored otherwise.
+
+@var{getter} should be a closure taking a single @var{instance} parameter
+that returns the current slot value. @var{setter} should be a closure
+taking two parameters - @var{instance} and @var{new-val} - that sets the
+slot value to @var{new-val}.
+@end deffn
+
+@deffn {slot option} #:getter getter
+@deffnx {slot option} #:setter setter
+@deffnx {slot option} #:accessor accessor
+These options, if present, tell GOOPS to create generic function and
+method definitions that can be used to get and set the slot value more
+conveniently than by using @code{slot-ref} and @code{slot-set!}.
+
+@var{getter} specifies a generic function to which GOOPS will add a
+method for getting the slot value. @var{setter} specifies a generic
+function to which GOOPS will add a method for setting the slot value.
+@var{accessor} specifies an accessor to which GOOPS will add methods for
+both getting and setting the slot value.
+
+So if a class includes a slot definition like this:
+
+@example
+(c #:getter get-count #:setter set-count #:accessor count)
+@end example
+
+GOOPS defines generic function methods such that the slot value can be
+referenced using either the getter or the accessor -
+
+@example
+(let ((current-count (get-count obj))) @dots{})
+(let ((current-count (count obj))) @dots{})
+@end example
+
+- and set using either the setter or the accessor -
+
+@example
+(set-count obj (+ 1 current-count))
+(set! (count obj) (+ 1 current-count))
+@end example
+
+Note that
+
+@itemize @bullet
+@item
+with an accessor, the slot value is set using the generalized
+@code{set!} syntax
+
+@item
+in practice, it is unusual for a slot to use all three of these options:
+read-only, write-only and read-write slots would typically use only
+@code{#:getter}, @code{#:setter} and @code{#:accessor} options
+respectively.
+@end itemize
+
+If the specified names are already bound in the top-level environment to
+values that cannot be upgraded to generic functions, those values are
+overwritten during evaluation of the @code{define-class} that contains
+the slot definition. For details, see @ref{Generic Function Internals,,
+ensure-generic}.
+@end deffn
+
+@deffn {slot option} #:init-value init-value
+@deffnx {slot option} #:init-form init-form
+@deffnx {slot option} #:init-thunk init-thunk
+@deffnx {slot option} #:init-keyword init-keyword
+These options provide various ways to specify how to initialize the
+slot's value at instance creation time. @var{init-value} is a fixed
+value (shared across all new instances of the class).
+@var{init-thunk} is a procedure of no arguments that is called
+when a new instance is created and should return the desired initial
+slot value. @var{init-form} is an unevaluated expression that gets
+evaluated when a new instance is created and should return the desired
+initial slot value. @var{init-keyword} is a keyword that can be used
+to pass an initial slot value to @code{make} when creating a new
+instance.
+
+Note that, since an @code{init-value} value is shared across all
+instances of a class, you should only use it when the initial value is
+an immutable value, like a constant. If you want to initialize a slot
+with a fresh, independently mutable value, you should use
+@code{init-thunk} or @code{init-form} instead. Consider the following
+example.
+
+@example
+(define-class <chbouib> ()
+ (hashtab #:init-value (make-hash-table)))
+@end example
+
+@noindent
+Here only one hash table is created and all instances of
+@code{<chbouib>} have their @code{hashtab} slot refer to it. In order
+to have each instance of @code{<chbouib>} refer to a new hash table, you
+should instead write:
+
+@example
+(define-class <chbouib> ()
+ (hashtab #:init-thunk make-hash-table))
+@end example
+
+@noindent
+or:
+
+@example
+(define-class <chbouib> ()
+ (hashtab #:init-form (make-hash-table)))
+@end example
+
+If more than one of these options is specified for the same slot, the
+order of precedence, highest first is
+
+@itemize @bullet
+@item
+@code{#:init-keyword}, if @var{init-keyword} is present in the options
+passed to @code{make}
+
+@item
+@code{#:init-thunk}, @code{#:init-form} or @code{#:init-value}.
+@end itemize
+
+If the slot definition contains more than one initialization option of
+the same precedence, the later ones are ignored. If a slot is not
+initialized at all, its value is unbound.
+
+In general, slots that are shared between more than one instance are
+only initialized at new instance creation time if the slot value is
+unbound at that time. However, if the new instance creation specifies
+a valid init keyword and value for a shared slot, the slot is
+re-initialized regardless of its previous value.
+
+Note, however, that the power of GOOPS' metaobject protocol means that
+everything written here may be customized or overridden for particular
+classes! The slot initializations described here are performed by the least
+specialized method of the generic function @code{initialize}, whose
+signature is
+
+@example
+(define-method (initialize (object <object>) initargs) ...)
+@end example
+
+The initialization of instances of any given class can be customized by
+defining a @code{initialize} method that is specialized for that class,
+and the author of the specialized method may decide to call
+@code{next-method} - which will result in a call to the next less
+specialized @code{initialize} method - at any point within the
+specialized code, or maybe not at all. In general, therefore, the
+initialization mechanisms described here may be modified or overridden by
+more specialized code, or may not be supported at all for particular
+classes.
+@end deffn
+
+@node Class Definition Internals
+@subsubsection Class Definition Internals
+
+Implementation notes: @code{define-class} expands to an expression which
+
+@itemize @bullet
+@item
+checks that it is being evaluated only at top level
+
+@item
+defines any accessors that are implied by the @var{slot-definition}s
+
+@item
+uses @code{class} to create the new class (@pxref{Class Definition
+Internals,, class})
+
+@item
+checks for a previous class definition for @var{name} and, if found,
+handles the redefinition by invoking @code{class-redefinition}
+(@pxref{Redefining a Class}).
+@end itemize
+
+@deffn syntax class name (super @dots{}) slot-definition @dots{} . options
+Return a newly created class that inherits from @var{super}s, with
+direct slots defined by @var{slot-definition}s and class options
+@var{options}. For the format of @var{slot-definition}s and
+@var{options}, see @ref{Basic Class Definition,, define-class}.
+@end deffn
+
+Implementation notes: @code{class} expands to an expression which
+
+@itemize @bullet
+@item
+processes the class and slot definition options to check that they are
+well-formed, to convert the @code{#:init-form} option to an
+@code{#:init-thunk} option, to supply a default environment parameter
+(the current top-level environment) and to evaluate all the bits that
+need to be evaluated
+
+@item
+calls @code{make-class} to create the class with the processed and
+evaluated parameters.
+@end itemize
+
+@deffn procedure make-class supers slots . options
+Return a newly created class that inherits from @var{supers}, with
+direct slots defined by @var{slots} and class options @var{options}.
+For the format of @var{slots} and @var{options}, see @ref{Basic Class
+Definition,, define-class}, except note that for @code{make-class},
+@var{slots} and @var{options} are separate list parameters: @var{slots}
+here is a list of slot definitions.
+@end deffn
+
+Implementation notes: @code{make-class}
+
+@itemize @bullet
+@item
+adds @code{<object>} to the @var{supers} list if @var{supers} is empty
+or if none of the classes in @var{supers} have @code{<object>} in their
+class precedence list
+
+@item
+defaults the @code{#:environment}, @code{#:name} and @code{#:metaclass}
+options, if they are not specified by @var{options}, to the current
+top-level environment, the unbound value, and @code{(ensure-metaclass
+@var{supers})} respectively (@pxref{Class Definition Internals,,
+ensure-metaclass})
+
+@item
+checks for duplicate classes in @var{supers} and duplicate slot names in
+@var{slots}, and signals an error if there are any duplicates
+
+@item
+calls @code{make}, passing the metaclass as the first parameter and all
+other parameters as option keywords with values.
+@end itemize
+
+@deffn procedure ensure-metaclass supers env
+Return a metaclass suitable for a class that inherits from the list of
+classes in @var{supers}. The returned metaclass is the union by
+inheritance of the metaclasses of the classes in @var{supers}.
+
+In the simplest case, where all the @var{supers} are straightforward
+classes with metaclass @code{<class>}, the returned metaclass is just
+@code{<class>}.
+
+For a more complex example, suppose that @var{supers} contained one
+class with metaclass @code{<operator-class>} and one with metaclass
+@code{<foreign-object-class>}. Then the returned metaclass would be a
+class that inherits from both @code{<operator-class>} and
+@code{<foreign-object-class>}.
+
+If @var{supers} is the empty list, @code{ensure-metaclass} returns the
+default GOOPS metaclass @code{<class>}.
+
+GOOPS keeps a list of the metaclasses created by
+@code{ensure-metaclass}, so that each required type of metaclass only
+has to be created once.
+
+The @code{env} parameter is ignored.
+@end deffn
+
+@deffn procedure ensure-metaclass-with-supers meta-supers
+@code{ensure-metaclass-with-supers} is an internal procedure used by
+@code{ensure-metaclass} (@pxref{Class Definition Internals,,
+ensure-metaclass}). It returns a metaclass that is the union by
+inheritance of the metaclasses in @var{meta-supers}.
+@end deffn
+
+The internals of @code{make}, which is ultimately used to create the new
+class object, are described in @ref{Customizing Instance Creation},
+which covers the creation and initialization of instances in general.
+
+@node Customizing Class Definition
+@subsubsection Customizing Class Definition
+
+During the initialization of a new class, GOOPS calls a number of generic
+functions with the newly allocated class instance as the first
+argument. Specifically, GOOPS calls the generic function
+
+@itemize @bullet
+@item
+(initialize @var{class} @dots{})
+@end itemize
+
+where @var{class} is the newly allocated class instance, and the default
+@code{initialize} method for arguments of type @code{<class>} calls the
+generic functions
+
+@itemize @bullet
+@item
+(compute-cpl @var{class})
+
+@item
+(compute-slots @var{class})
+
+@item
+(compute-get-n-set @var{class} @var{slot-def}), for each of the slot
+definitions returned by @code{compute-slots}
+
+@item
+(compute-getter-method @var{class} @var{slot-def}), for each of the
+slot definitions returned by @code{compute-slots} that includes a
+@code{#:getter} or @code{#:accessor} slot option
+
+@item
+(compute-setter-method @var{class} @var{slot-def}), for each of the
+slot definitions returned by @code{compute-slots} that includes a
+@code{#:setter} or @code{#:accessor} slot option.
+@end itemize
+
+If the metaclass of the new class is something more specialized than the
+default @code{<class>}, then the type of @var{class} in the calls above
+is more specialized than @code{<class>}, and hence it becomes possible
+to define generic function methods, specialized for the new class's
+metaclass, that can modify or override the default behaviour of
+@code{initialize}, @code{compute-cpl} or @code{compute-get-n-set}.
+
+@code{compute-cpl} computes the class precedence list (``CPL'') for the
+new class (@pxref{Class precedence list}), and returns it as a list of
+class objects. The CPL is important because it defines a superclass
+ordering that is used, when a generic function is invoked upon an
+instance of the class, to decide which of the available generic function
+methods is the most specific. Hence @code{compute-cpl} could be
+customized in order to modify the CPL ordering algorithm for all classes
+with a special metaclass.
+
+The default CPL algorithm is encapsulated by the @code{compute-std-cpl}
+procedure, which is in turn called by the default @code{compute-cpl}
+method.
+
+@deffn procedure compute-std-cpl class
+Compute and return the class precedence list for @var{class} according
+to the algorithm described in @ref{Class precedence list}.
+@end deffn
+
+@code{compute-slots} computes and returns a list of all slot definitions
+for the new class. By default, this list includes the direct slot
+definitions from the @code{define-class} form, plus the slot definitions
+that are inherited from the new class's superclasses. The default
+@code{compute-slots} method uses the CPL computed by @code{compute-cpl}
+to calculate this union of slot definitions, with the rule that slots
+inherited from superclasses are shadowed by direct slots with the same
+name. One possible reason for customizing @code{compute-slots} would be
+to implement an alternative resolution strategy for slot name conflicts.
+
+@code{compute-get-n-set} computes the low-level closures that will be
+used to get and set the value of a particular slot, and returns them in
+a list with two elements.
+
+The closures returned depend on how storage for that slot is allocated.
+The standard @code{compute-get-n-set} method, specialized for classes of
+type @code{<class>}, handles the standard GOOPS values for the
+@code{#:allocation} slot option (@pxref{Slot Options,, allocation}). By
+defining a new @code{compute-get-n-set} method for a more specialized
+metaclass, it is possible to support new types of slot allocation.
+
+Suppose you wanted to create a large number of instances of some class
+with a slot that should be shared between some but not all instances of
+that class - say every 10 instances should share the same slot storage.
+The following example shows how to implement and use a new type of slot
+allocation to do this.
+
+@example
+(define-class <batched-allocation-metaclass> (<class>))
+
+(let ((batch-allocation-count 0)
+ (batch-get-n-set #f))
+ (define-method (compute-get-n-set (class <batched-allocation-metaclass>) s)
+ (case (slot-definition-allocation s)
+ ((#:batched)
+ ;; If we've already used the same slot storage for 10 instances,
+ ;; reset variables.
+ (if (= batch-allocation-count 10)
+ (begin
+ (set! batch-allocation-count 0)
+ (set! batch-get-n-set #f)))
+ ;; If we don't have a current pair of get and set closures,
+ ;; create one. make-closure-variable returns a pair of closures
+ ;; around a single Scheme variable - see goops.scm for details.
+ (or batch-get-n-set
+ (set! batch-get-n-set (make-closure-variable)))
+ ;; Increment the batch allocation count.
+ (set! batch-allocation-count (+ batch-allocation-count 1))
+ batch-get-n-set)
+
+ ;; Call next-method to handle standard allocation types.
+ (else (next-method)))))
+
+(define-class <class-using-batched-slot> ()
+ ...
+ (c #:allocation #:batched)
+ ...
+ #:metaclass <batched-allocation-metaclass>)
+@end example
+
+The usage of @code{compute-getter-method} and @code{compute-setter-method}
+is described in @ref{MOP Specification}.
+
+@code{compute-cpl} and @code{compute-get-n-set} are called by the
+standard @code{initialize} method for classes whose metaclass is
+@code{<class>}. But @code{initialize} itself can also be modified, by
+defining an @code{initialize} method specialized to the new class's
+metaclass. Such a method could complete override the standard
+behaviour, by not calling @code{(next-method)} at all, but more
+typically it would perform additional class initialization steps before
+and/or after calling @code{(next-method)} for the standard behaviour.
+
+@node STKlos Compatibility
+@subsubsection STKlos Compatibility
+
+If the STKlos compatibility module is loaded, @code{define-class} is
+overwritten by a STKlos-specific definition; the standard GOOPS
+definition of @code{define-class} remains available in
+@code{standard-define-class}.
+
+@deffn syntax standard-define-class name (super @dots{}) slot-definition @dots{} . options
+@code{standard-define-class} is equivalent to the standard GOOPS
+@code{define-class}.
+@end deffn
+
+@node Creating Instances
+@subsection Creating Instances
+
+@menu
+* Basic Instance Creation::
+* Customizing Instance Creation::
+@end menu
+
+@node Basic Instance Creation
+@subsubsection Basic Instance Creation
+
+To create a new instance of any GOOPS class, use the generic function
+@code{make} or @code{make-instance}, passing the required class and any
+appropriate instance initialization arguments as keyword and value
+pairs. Note that @code{make} and @code{make-instances} are aliases for
+each other - their behaviour is identical.
+
+@deffn generic make
+@deffnx method make (class <class>) . initargs
+Create and return a new instance of class @var{class}, initialized using
+@var{initargs}.
+
+In theory, @var{initargs} can have any structure that is understood by
+whatever methods get applied when the @code{initialize} generic function
+is applied to the newly allocated instance.
+
+In practice, specialized @code{initialize} methods would normally call
+@code{(next-method)}, and so eventually the standard GOOPS
+@code{initialize} methods are applied. These methods expect
+@var{initargs} to be a list with an even number of elements, where
+even-numbered elements (counting from zero) are keywords and
+odd-numbered elements are the corresponding values.
+
+GOOPS processes initialization argument keywords automatically for slots
+whose definition includes the @code{#:init-keyword} option (@pxref{Slot
+Options,, init-keyword}). Other keyword value pairs can only be
+processed by an @code{initialize} method that is specialized for the new
+instance's class. Any unprocessed keyword value pairs are ignored.
+@end deffn
+
+@deffn generic make-instance
+@deffnx method make-instance (class <class>) . initargs
+@code{make-instance} is an alias for @code{make}.
+@end deffn
+
+@node Customizing Instance Creation
+@subsubsection Customizing Instance Creation
+
+@code{make} itself is a generic function. Hence the @code{make}
+invocation itself can be customized in the case where the new instance's
+metaclass is more specialized than the default @code{<class>}, by
+defining a @code{make} method that is specialized to that metaclass.
+
+Normally, however, the method for classes with metaclass @code{<class>}
+will be applied. This method calls two generic functions:
+
+@itemize @bullet
+@item
+(allocate-instance @var{class} . @var{initargs})
+
+@item
+(initialize @var{instance} . @var{initargs})
+@end itemize
+
+@code{allocate-instance} allocates storage for and returns the new
+instance, uninitialized. You might customize @code{allocate-instance},
+for example, if you wanted to provide a GOOPS wrapper around some other
+object programming system.
+
+To do this, you would create a specialized metaclass, which would act as
+the metaclass for all classes and instances from the other system. Then
+define an @code{allocate-instance} method, specialized to that
+metaclass, which calls a Guile primitive C function, which in turn
+allocates the new instance using the interface of the other object
+system.
+
+In this case, for a complete system, you would also need to customize a
+number of other generic functions like @code{make} and
+@code{initialize}, so that GOOPS knows how to make classes from the
+other system, access instance slots, and so on.
+
+@code{initialize} initializes the instance that is returned by
+@code{allocate-instance}. The standard GOOPS methods perform
+initializations appropriate to the instance class.
+
+@itemize @bullet
+@item
+At the least specialized level, the method for instances of type
+@code{<object>} performs internal GOOPS instance initialization, and
+initializes the instance's slots according to the slot definitions and
+any slot initialization keywords that appear in @var{initargs}.
+
+@item
+The method for instances of type @code{<class>} calls
+@code{(next-method)}, then performs the class initializations described
+in @ref{Customizing Class Definition}.
+
+@item
+and so on for generic functions, method, operator classes @dots{}
+@end itemize
+
+Similarly, you can customize the initialization of instances of any
+application-defined class by defining an @code{initialize} method
+specialized to that class.
+
+Imagine a class whose instances' slots need to be initialized at
+instance creation time by querying a database. Although it might be
+possible to achieve this a combination of @code{#:init-thunk} keywords
+and closures in the slot definitions, it is neater to write an
+@code{initialize} method for the class that queries the database once
+and initializes all the dependent slot values according to the results.
+
+@node Accessing Slots
+@subsection Accessing Slots
+
+The definition of a slot contains at the very least a slot name, and may
+also contain various slot options, including getter, setter and/or
+accessor functions for the slot.
+
+It is always possible to access slots by name, using the various
+``slot-ref'' and ``slot-set!'' procedures described in the following
+subsubsections. For example,
+
+@example
+(define-class <my-class> () ;; Define a class with slots
+ (count #:init-value 0) ;; named "count" and "cache".
+ (cache #:init-value '())
+ @dots{})
+
+(define inst (make <my-class>)) ;; Make an instance of this class.
+
+(slot-set! inst 'count 5) ;; Set the value of the "count"
+ ;; slot to 5.
+
+(slot-set! inst 'cache ;; Modify the value of the
+ (cons (cons "^it" "It") ;; "cache" slot.
+ (slot-ref inst 'cache)))
+@end example
+
+If a slot definition includes a getter, setter or accessor function,
+these can be used instead of @code{slot-ref} and @code{slot-set!} to
+access the slot.
+
+@example
+(define-class <adv-class> () ;; Define a new class whose slots
+ (count #:setter set-count) ;; use a getter, a setter and
+ (cache #:accessor cache) ;; an accessor.
+ (csize #:getter cache-size)
+ @dots{})
+
+(define inst (make <adv-class>)) ;; Make an instance of this class.
+
+(set-count inst 5) ;; Set the value of the "count"
+ ;; slot to 5.
+
+(set! (cache inst) ;; Modify the value of the
+ (cons (cons "^it" "It") ;; "cache" slot.
+ (cache inst)))
+
+(let ((size (cache-size inst))) ;; Get the value of the "csize"
+ @dots{}) ;; slot.
+@end example
+
+Whichever of these methods is used to access slots, GOOPS always calls
+the low-level @dfn{getter} and @dfn{setter} closures for the slot to get
+and set its value. These closures make sure that the slot behaves
+according to the @code{#:allocation} type that was specified in the slot
+definition (@pxref{Slot Options,, allocation}). (For more about these
+closures, see @ref{Customizing Class Definition,, compute-get-n-set}.)
+
+@menu
+* Instance Slots::
+* Class Slots::
+* Handling Slot Access Errors::
+@end menu
+
+@node Instance Slots
+@subsubsection Instance Slots
+
+Any slot, regardless of its allocation, can be queried, referenced and
+set using the following four primitive procedures.
+
+@deffn {primitive procedure} slot-exists? obj slot-name
+Return @code{#t} if @var{obj} has a slot with name @var{slot-name},
+otherwise @code{#f}.
+@end deffn
+
+@deffn {primitive procedure} slot-bound? obj slot-name
+Return @code{#t} if the slot named @var{slot-name} in @var{obj} has a
+value, otherwise @code{#f}.
+
+@code{slot-bound?} calls the generic function @code{slot-missing} if
+@var{obj} does not have a slot called @var{slot-name} (@pxref{Handling
+Slot Access Errors, slot-missing}).
+@end deffn
+
+@deffn {primitive procedure} slot-ref obj slot-name
+Return the value of the slot named @var{slot-name} in @var{obj}.
+
+@code{slot-ref} calls the generic function @code{slot-missing} if
+@var{obj} does not have a slot called @var{slot-name} (@pxref{Handling
+Slot Access Errors, slot-missing}).
+
+@code{slot-ref} calls the generic function @code{slot-unbound} if the
+named slot in @var{obj} does not have a value (@pxref{Handling Slot
+Access Errors, slot-unbound}).
+@end deffn
+
+@deffn {primitive procedure} slot-set! obj slot-name value
+Set the value of the slot named @var{slot-name} in @var{obj} to @var{value}.
+
+@code{slot-set!} calls the generic function @code{slot-missing} if
+@var{obj} does not have a slot called @var{slot-name} (@pxref{Handling
+Slot Access Errors, slot-missing}).
+@end deffn
+
+GOOPS stores information about slots in class metaobjects. Internally,
+all of these procedures work by looking up the slot definition for the
+slot named @var{slot-name} in the class metaobject for @code{(class-of
+@var{obj})}, and then using the slot definition's ``getter'' and
+``setter'' closures to get and set the slot value.
+
+The next four procedures differ from the previous ones in that they take
+the class metaobject as an explicit argument, rather than assuming
+@code{(class-of @var{obj})}. Therefore they allow you to apply the
+``getter'' and ``setter'' closures of a slot definition in one class to
+an instance of a different class.
+
+[ *fixme* I have no idea why this is useful! Perhaps when a slot in
+@code{(class-of @var{obj})} shadows a slot with the same name in one of
+its superclasses? There should be an enlightening example here. ]
+
+@deffn {primitive procedure} slot-exists-using-class? class obj slot-name
+Return @code{#t} if the class metaobject @var{class} has a slot
+definition for a slot with name @var{slot-name}, otherwise @code{#f}.
+@end deffn
+
+@deffn {primitive procedure} slot-bound-using-class? class obj slot-name
+Return @code{#t} if applying @code{slot-ref-using-class} to the same
+arguments would call the generic function @code{slot-unbound}, otherwise
+@code{#f}.
+
+@code{slot-bound-using-class?} calls the generic function
+@code{slot-missing} if @var{class} does not have a slot definition for a
+slot called @var{slot-name} (@pxref{Handling Slot Access Errors,
+slot-missing}).
+@end deffn
+
+@deffn {primitive procedure} slot-ref-using-class class obj slot-name
+Apply the ``getter'' closure for the slot named @var{slot-name} in
+@var{class} to @var{obj}, and return its result.
+
+@code{slot-ref-using-class} calls the generic function
+@code{slot-missing} if @var{class} does not have a slot definition for a
+slot called @var{slot-name} (@pxref{Handling Slot Access Errors,
+slot-missing}).
+
+@code{slot-ref-using-class} calls the generic function
+@code{slot-unbound} if the application of the ``getter'' closure to
+@var{obj} returns an unbound value (@pxref{Handling Slot Access Errors,
+slot-unbound}).
+@end deffn
+
+@deffn {primitive procedure} slot-set-using-class! class obj slot-name value
+Apply the ``setter'' closure for the slot named @var{slot-name} in
+@var{class} to @var{obj} and @var{value}.
+
+@code{slot-set-using-class!} calls the generic function
+@code{slot-missing} if @var{class} does not have a slot definition for a
+slot called @var{slot-name} (@pxref{Handling Slot Access Errors,
+slot-missing}).
+@end deffn
+
+@node Class Slots
+@subsubsection Class Slots
+
+Slots whose allocation is per-class rather than per-instance can be
+referenced and set without needing to specify any particular instance.
+
+@deffn procedure class-slot-ref class slot-name
+Return the value of the slot named @var{slot-name} in class @var{class}.
+The named slot must have @code{#:class} or @code{#:each-subclass}
+allocation (@pxref{Slot Options,, allocation}).
+
+If there is no such slot with @code{#:class} or @code{#:each-subclass}
+allocation, @code{class-slot-ref} calls the @code{slot-missing} generic
+function with arguments @var{class} and @var{slot-name}. Otherwise, if
+the slot value is unbound, @code{class-slot-ref} calls the
+@code{slot-missing} generic function, with the same arguments.
+@end deffn
+
+@deffn procedure class-slot-set! class slot-name value
+Set the value of the slot named @var{slot-name} in class @var{class} to
+@var{value}. The named slot must have @code{#:class} or
+@code{#:each-subclass} allocation (@pxref{Slot Options,, allocation}).
+
+If there is no such slot with @code{#:class} or @code{#:each-subclass}
+allocation, @code{class-slot-ref} calls the @code{slot-missing} generic
+function with arguments @var{class} and @var{slot-name}.
+@end deffn
+
+@node Handling Slot Access Errors
+@subsubsection 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.
+
+@deffn generic slot-missing
+@deffnx method slot-missing (class <class>) slot-name
+@deffnx method slot-missing (class <class>) (object <object>) slot-name
+@deffnx method slot-missing (class <class>) (object <object>) slot-name value
+When an application attempts to reference or set a class or instance
+slot by name, and the slot name is invalid for the specified @var{class}
+or @var{object}, GOOPS calls the @code{slot-missing} generic function.
+
+The default methods all call @code{goops-error} with an appropriate
+message.
+@end deffn
+
+@deffn generic slot-unbound
+@deffnx method slot-unbound (object <object>)
+@deffnx method slot-unbound (class <class>) slot-name
+@deffnx method slot-unbound (class <class>) (object <object>) slot-name
+When an application attempts to reference a class or instance slot, and
+the slot's value is unbound, GOOPS calls the @code{slot-unbound} generic
+function.
+
+The default methods all call @code{goops-error} with an appropriate
+message.
+@end deffn
+
+@node Creating Generic Functions
+@subsection Creating Generic Functions
+
+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).
+
+@menu
+* Basic Generic Function Creation::
+* Generic Function Internals::
+* Extending Guiles Primitives::
+@end menu
+
+@node Basic Generic Function Creation
+@subsubsection Basic Generic Function Creation
+
+The following forms may be used to bind a variable to a generic
+function. Depending on that variable's pre-existing value, the generic
+function may be created empty - with no methods - or it may contain
+methods that are inferred from the pre-existing value.
+
+It is not, in general, necessary to use @code{define-generic} or
+@code{define-accessor} before defining methods for the generic function
+using @code{define-method}, since @code{define-method} will
+automatically interpolate a @code{define-generic} call, or upgrade an
+existing generic to an accessor, if that is implied by the
+@code{define-method} call. Note in particular that,
+if the specified variable already has a @emph{generic function} value,
+@code{define-generic} and @code{define-accessor} will @emph{discard} it!
+Obviously it is application-dependent whether this is desirable or not.
+
+If, for example, you wanted to extend @code{+} for a class representing
+a new numerical type, you probably want to inherit any existing methods
+for @code{+} and so should not use @code{define-generic}. If, on the
+other hand, you do not want to risk inheriting methods whose behaviour
+might surprise you, you can use @code{define-generic} or
+@code{define-accessor} to wipe the slate clean.
+
+@deffn syntax define-generic symbol
+Create a generic function with name @var{symbol} and bind it to the
+variable @var{symbol}.
+
+If the variable @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 that was bound to @var{symbol},
+including an existing generic function, is overwritten by the new
+generic function.
+@end deffn
+
+@deffn syntax define-accessor symbol
+Create an accessor with name @var{symbol} and bind it to the variable
+@var{symbol}.
+
+If the variable @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 that was bound to @var{symbol},
+including an existing generic function or accessor, is overwritten by
+the new definition.
+@end deffn
+
+It is sometimes tempting to use GOOPS accessors with short names. For
+example, it is tempting to use the name @code{x} for the x-coordinate
+in vector packages.
+
+Assume that we work with a graphical package which needs to use two
+independent vector packages for 2D and 3D vectors respectively. If
+both packages export @code{x} we will encounter a name collision.
+
+This can be resolved automagically with the duplicates handler
+@code{merge-generics} which gives the module system license to merge
+all generic functions sharing a common name:
+
+@smalllisp
+(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 smalllisp
+
+The generic function @code{x} in @code{(my-module)} will now share
+methods with @code{x} in both imported modules.
+
+There will, in fact, now be three distinct generic functions named
+@code{x}: @code{x} in @code{(2D-vectors)}, @code{x} in
+@code{(3D-vectors)}, and @code{x} in @code{(my-module)}. The last
+function will be an @code{<extended-generic>}, extending the previous
+two functions.
+
+Let's call the imported generic functions the "ancestor functions".
+The generic function @code{x} in @code{(my-module)} is, in turn, a
+"descendant function" of the imported functions, extending its
+ancestors.
+
+For any generic function G, the applicable methods are selected from
+the union of the methods of the descendant functions, the methods of G
+itself and the methods of the ancestor functions.
+
+This, ancestor functions share methods with their descendants and vice
+versa. This implies that @code{x} in @code{(math 2D-vectors)} will
+share the methods of @code{x} in @code{(my-module)} and vice versa,
+while @code{x} in @code{(math 2D-vectors)} doesn't share the methods
+of @code{x} in @code{(math 3D-vectors)}, thus preserving modularity.
+
+Sharing is dynamic, so that adding new methods to a descendant implies
+adding it to the ancestor.
+
+If duplicates checking is desired in the above example, the following
+form of the @code{:duplicates} option can be used instead:
+
+@smalllisp
+ :duplicates (merge-generics check)
+@end smalllisp
+
+@node Generic Function Internals
+@subsubsection Generic Function Internals
+
+@code{define-generic} calls @code{ensure-generic} to upgrade a
+pre-existing procedure value, or @code{make} with metaclass
+@code{<generic>} to create a new generic function.
+
+@code{define-accessor} calls @code{ensure-accessor} to upgrade a
+pre-existing procedure value, or @code{make-accessor} to create a new
+accessor.
+
+@deffn procedure ensure-generic old-definition [name]
+Return a generic function with name @var{name}, if possible by using or
+upgrading @var{old-definition}. If unspecified, @var{name} defaults to
+@code{#f}.
+
+If @var{old-definition} is already a generic function, it is returned
+unchanged.
+
+If @var{old-definition} is a Scheme procedure or procedure-with-setter,
+@code{ensure-generic} returns a new generic function that uses
+@var{old-definition} for its default procedure and setter.
+
+Otherwise @code{ensure-generic} returns a new generic function with no
+defaults and no methods.
+@end deffn
+
+@deffn procedure make-generic [name]
+Return a new generic function with name @code{(car @var{name})}. If
+unspecified, @var{name} defaults to @code{#f}.
+@end deffn
+
+@code{ensure-generic} calls @code{make} with metaclasses
+@code{<generic>} and @code{<generic-with-setter>}, depending on the
+previous value of the variable that it is trying to upgrade.
+
+@code{make-generic} is a simple wrapper for @code{make} with metaclass
+@code{<generic>}.
+
+@deffn procedure ensure-accessor proc [name]
+Return an accessor with name @var{name}, if possible by using or
+upgrading @var{proc}. If unspecified, @var{name} defaults to @code{#f}.
+
+If @var{proc} is already an accessor, it is returned unchanged.
+
+If @var{proc} is a Scheme procedure, procedure-with-setter or generic
+function, @code{ensure-accessor} returns an accessor that reuses the
+reusable elements of @var{proc}.
+
+Otherwise @code{ensure-accessor} returns a new accessor with no defaults
+and no methods.
+@end deffn
+
+@deffn procedure make-accessor [name]
+Return a new accessor with name @code{(car @var{name})}. If
+unspecified, @var{name} defaults to @code{#f}.
+@end deffn
+
+@code{ensure-accessor} calls @code{make} with
+metaclass @code{<generic-with-setter>}, as well as calls to
+@code{ensure-generic}, @code{make-accessor} and (tail recursively)
+@code{ensure-accessor}.
+
+@code{make-accessor} calls @code{make} twice, first
+with metaclass @code{<generic>} to create a generic function for the
+setter, then with metaclass @code{<generic-with-setter>} to create the
+accessor, passing the setter generic function as the value of the
+@code{#:setter} keyword.
+
+@node Extending Guiles Primitives
+@subsubsection Extending Guile's Primitives
+
+When GOOPS is loaded, 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. For
+primitives that are extended in this way, the result from the user-
+or application-level point of view is that the extended primitive
+behaves exactly like a generic function with the C-coded implementation
+as its default method.
+
+The @code{generic-capability?} predicate should be used to determine
+whether a particular primitive is extensible in this way.
+
+@deffn {primitive procedure} generic-capability? primitive
+Return @code{#t} if @var{primitive} can be extended by giving it a
+generic function definition, otherwise @code{#f}.
+@end deffn
+
+Even when a primitive procedure is extensible like this, its generic
+function definition is not created until it is needed by a call to
+@code{define-method}, or until the application explicitly requests it
+by calling @code{enable-primitive-generic!}.
+
+@deffn {primitive procedure} enable-primitive-generic! primitive
+Force the creation of a generic function definition for
+@var{primitive}.
+@end deffn
+
+Once the generic function definition for a primitive has been created,
+it can be retrieved using @code{primitive-generic-generic}.
+
+@deffn {primitive procedure} primitive-generic-generic primitive
+Return the generic function definition of @var{primitive}.
+
+@code{primitive-generic-generic} raises an error if @var{primitive}
+is not a primitive with generic capability, or if its generic capability
+has not yet been enabled, whether implicitly (by @code{define-method})
+or explicitly (by @code{enable-primitive-generic!}).
+@end deffn
+
+Note that the distinction between, on the one hand, primitives with
+additional generic function definitions and, on the other hand, generic
+functions with a default method, may disappear when GOOPS is fully
+integrated into the core of Guile. Consequently, the
+procedures described in this section may disappear as well.
+
+@node Adding Methods to Generic Functions
+@subsection Adding Methods to Generic Functions
+
+@menu
+* Basic Method Definition::
+* Method Definition Internals::
+@end menu
+
+@node Basic Method Definition
+@subsubsection Basic Method Definition
+
+To add a method to a generic function, use the @code{define-method} form.
+
+@deffn syntax define-method (generic parameter @dots{}) . body
+Define a method for the generic function or accessor @var{generic} with
+parameters @var{parameter}s and body @var{body}.
+
+@var{generic} is a generic function. If @var{generic} is a variable
+which is not yet bound to a generic function object, the expansion of
+@code{define-method} will include a call to @code{define-generic}. If
+@var{generic} is @code{(setter @var{generic-with-setter})}, where
+@var{generic-with-setter} is a variable which is not yet bound to a
+generic-with-setter object, the expansion will include a call to
+@code{define-accessor}.
+
+Each @var{parameter} must be either a symbol or a two-element list
+@code{(@var{symbol} @var{class})}. The symbols refer to variables in
+the @var{body} that will be bound to the parameters supplied by the
+caller when calling this method. The @var{class}es, if present,
+specify the possible combinations of parameters to which this method
+can be applied.
+
+@var{body} is the body of the method definition.
+@end deffn
+
+@code{define-method} expressions look a little like normal Scheme
+procedure definitions of the form
+
+@example
+(define (name formals @dots{}) . body)
+@end example
+
+The most important difference is that each formal parameter, apart from the
+possible ``rest'' argument, can be qualified by a class name:
+@code{@var{formal}} becomes @code{(@var{formal} @var{class})}. The
+meaning of this qualification is that the method being defined
+will only be applicable in a particular generic function invocation if
+the corresponding argument is an instance of @code{@var{class}} (or one of
+its subclasses). If more than one of the formal parameters is qualified
+in this way, then the method will only be applicable if each of the
+corresponding arguments is an instance of its respective qualifying class.
+
+Note that unqualified formal parameters act as though they are qualified
+by the class @code{<top>}, which GOOPS uses to mean the superclass of
+all valid Scheme types, including both primitive types and GOOPS classes.
+
+For example, if a generic function method is defined with
+@var{parameter}s @code{((s1 <square>) (n <number>))}, that method is
+only applicable to invocations of its generic function that have two
+parameters where the first parameter is an instance of the
+@code{<square>} class and the second parameter is a number.
+
+If a generic function is invoked with a combination of parameters for which
+there is no applicable method, GOOPS raises an error. For more about
+invocation error handling, and generic function invocation in general,
+see @ref{Invoking Generic Functions}.
+
+@node Method Definition Internals
+@subsubsection Method Definition Internals
+
+@code{define-method}
+
+@itemize @bullet
+@item
+checks the form of the first parameter, and applies the following steps
+to the accessor's setter if it has the @code{(setter @dots{})} form
+
+@item
+interpolates a call to @code{define-generic} or @code{define-accessor}
+if a generic function is not already defined with the supplied name
+
+@item
+calls @code{method} with the @var{parameter}s and @var{body}, to make a
+new method instance
+
+@item
+calls @code{add-method!} to add this method to the relevant generic
+function.
+@end itemize
+
+@deffn syntax method (parameter @dots{}) . body
+Make a method whose specializers are defined by the classes in
+@var{parameter}s and whose procedure definition is constructed from the
+@var{parameter} symbols and @var{body} forms.
+
+The @var{parameter} and @var{body} parameters should be as for
+@code{define-method} (@pxref{Basic Method Definition,, define-method}).
+@end deffn
+
+@code{method}
+
+@itemize @bullet
+@item
+extracts formals and specializing classes from the @var{parameter}s,
+defaulting the class for unspecialized parameters to @code{<top>}
+
+@item
+creates a closure using the formals and the @var{body} forms
+
+@item
+calls @code{make} with metaclass @code{<method>} and the specializers
+and closure using the @code{#:specializers} and @code{#:procedure}
+keywords.
+@end itemize
+
+@deffn procedure make-method specializers procedure
+Make a method using @var{specializers} and @var{procedure}.
+
+@var{specializers} should be a list of classes that specifies the
+parameter combinations to which this method will be applicable.
+
+@var{procedure} should be the closure that will applied to the generic
+function parameters when this method is invoked.
+@end deffn
+
+@code{make-method} is a simple wrapper around @code{make} with metaclass
+@code{<method>}.
+
+@deffn generic add-method! target method
+Generic function for adding method @var{method} to @var{target}.
+@end deffn
+
+@deffn method add-method! (generic <generic>) (method <method>)
+Add method @var{method} to the generic function @var{generic}.
+@end deffn
+
+@deffn method add-method! (proc <procedure>) (method <method>)
+If @var{proc} is a procedure with generic capability (@pxref{Extending
+Guiles Primitives,, generic-capability?}), upgrade it to a
+primitive generic and add @var{method} to its generic function
+definition.
+@end deffn
+
+@deffn method add-method! (pg <primitive-generic>) (method <method>)
+Add method @var{method} to the generic function definition of @var{pg}.
+
+Implementation: @code{(add-method! (primitive-generic-generic pg) method)}.
+@end deffn
+
+@deffn method add-method! (whatever <top>) (method <method>)
+Raise an error indicating that @var{whatever} is not a valid generic
+function.
+@end deffn
+
+@node Invoking Generic Functions
+@subsection 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{Basic
+Method Definition,, 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}.
+
+@menu
+* Determining Which Methods to Apply::
+* Handling Invocation Errors::
+@end menu
+
+@node Determining Which Methods to Apply
+@subsubsection Determining Which Methods to Apply
+
+[ *fixme* Sorry - this is the area of GOOPS that I understand least of
+all, so I'm afraid I have to pass on this section. Would some other
+kind person consider filling it in? ]
+
+@deffn generic apply-generic
+@deffnx method apply-generic (gf <generic>) args
+@end deffn
+
+@deffn generic compute-applicable-methods
+@deffnx method compute-applicable-methods (gf <generic>) args
+@end deffn
+
+@deffn generic sort-applicable-methods
+@deffnx method sort-applicable-methods (gf <generic>) methods args
+@end deffn
+
+@deffn generic method-more-specific?
+@deffnx method method-more-specific? (m1 <method>) (m2 <method>) args
+@end deffn
+
+@deffn generic apply-method
+@deffnx method apply-method (gf <generic>) methods build-next args
+@end deffn
+
+@deffn generic apply-methods
+@deffnx method apply-methods (gf <generic>) (l <list>) args
+@end deffn
+
+@node Handling Invocation Errors
+@subsubsection Handling Invocation Errors
+
+@deffn generic no-method
+@deffnx method no-method (gf <generic>) args
+When an application invokes a generic function, and no methods at all
+have been defined for that generic function, GOOPS calls the
+@code{no-method} generic function. The default method calls
+@code{goops-error} with an appropriate message.
+@end deffn
+
+@deffn generic no-applicable-method
+@deffnx method no-applicable-method (gf <generic>) args
+When an application applies a generic function to a set of arguments,
+and no methods have been defined for those argument types, GOOPS calls
+the @code{no-applicable-method} generic function. The default method
+calls @code{goops-error} with an appropriate message.
+@end deffn
+
+@deffn generic no-next-method
+@deffnx method no-next-method (gf <generic>) args
+When a generic function method calls @code{(next-method)} to invoke the
+next less specialized method for that generic function, and no less
+specialized methods have been defined for the current generic function
+arguments, GOOPS calls the @code{no-next-method} generic function. The
+default method calls @code{goops-error} with an appropriate message.
+@end deffn
+
+@node Redefining a Class
+@subsection Redefining a Class
+
+Suppose that a class @code{<my-class>} is defined using @code{define-class}
+(@pxref{Basic 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{Basic Instance Creation,,
+make}). What then happens if @code{<my-class>} is redefined by calling
+@code{define-class} again?
+
+@menu
+* Default Class Redefinition Behaviour::
+* Customizing Class Redefinition::
+@end menu
+
+@node Default Class Redefinition Behaviour
+@subsubsection Default Class Redefinition Behaviour
+
+GOOPS' default answer to this question is as follows.
+
+@itemize @bullet
+@item
+All existing direct instances of @code{<my-class>} are converted to be
+instances of the new class. This is achieved by preserving the values
+of slots that exist in both the old and new definitions, and initializing the
+values of new slots in the usual way (@pxref{Basic Instance Creation,,
+make}).
+
+@item
+All existing subclasses of @code{<my-class>} are redefined, as though
+the @code{define-class} expressions that defined them were re-evaluated
+following the redefinition of @code{<my-class>}, and the class
+redefinition process described here is applied recursively to the
+redefined subclasses.
+
+@item
+Once all of its instances and subclasses have been updated, the class
+metaobject previously bound to the variable @code{<my-class>} is no
+longer needed and so can be allowed to be garbage collected.
+@end itemize
+
+To keep things tidy, GOOPS also needs to do a little housekeeping on
+methods that are associated with the redefined class.
+
+@itemize @bullet
+@item
+Slot accessor methods for slots in the old definition should be removed
+from their generic functions. They will be replaced by accessor methods
+for the slots of the new class definition.
+
+@item
+Any generic function method that uses the old @code{<my-class>} metaobject
+as one of its formal parameter specializers must be updated to refer to
+the new @code{<my-class>} metaobject. (Whenever a new generic function
+method is defined, @code{define-method} adds the method to a list stored
+in the class metaobject for each class used as a formal parameter
+specializer, so it is easy to identify all the methods that must be
+updated when a class is redefined.)
+@end itemize
+
+If this class redefinition strategy strikes you as rather counter-intuitive,
+bear in mind that it is derived from similar behaviour in other object
+systems such as CLOS, and that experience in those systems has shown it to be
+very useful in practice.
+
+Also bear in mind that, like most of GOOPS' default behaviour, it can
+be customized@dots{}
+
+@node Customizing Class Redefinition
+@subsubsection Customizing Class Redefinition
+
+When @code{define-class} notices that a class is being redefined,
+it constructs the new class metaobject as usual, and then invokes the
+@code{class-redefinition} generic function with the old and new classes
+as arguments. Therefore, if the old or new classes have metaclasses
+other than the default @code{<class>}, class redefinition behaviour can
+be customized by defining a @code{class-redefinition} method that is
+specialized for the relevant metaclasses.
+
+@deffn generic class-redefinition
+Handle the class redefinition from @var{old-class} to @var{new-class},
+and return the new class metaobject that should be bound to the
+variable specified by @code{define-class}'s first argument.
+@end deffn
+
+@deffn method class-redefinition (old-class <class>) (new-class <class>)
+Implements GOOPS' default class redefinition behaviour, as described in
+@ref{Default Class Redefinition Behaviour}. Returns the metaobject
+for the new class definition.
+@end deffn
+
+An alternative class redefinition strategy could be to leave all
+existing instances as instances of the old class, but accepting that the
+old class is now ``nameless'', since its name has been taken over by the
+new definition. In this strategy, any existing subclasses could also
+be left as they are, on the understanding that they inherit from a nameless
+superclass.
+
+This strategy is easily implemented in GOOPS, by defining a new metaclass,
+that will be used as the metaclass for all classes to which the strategy
+should apply, and then defining a @code{class-redefinition} method that
+is specialized for this metaclass:
+
+@example
+(define-class <can-be-nameless> (<class>))
+
+(define-method (class-redefinition (old <can-be-nameless>) (new <class>))
+ new)
+@end example
+
+When customization can be as easy as this, aren't you glad that GOOPS
+implements the far more difficult strategy as its default!
+
+Finally, note that, if @code{class-redefinition} itself is not customized,
+the default @code{class-redefinition} method invokes three further
+generic functions that could be individually customized:
+
+@itemize @bullet
+@item
+(remove-class-accessors! @var{old-class})
+
+@item
+(update-direct-method! @var{method} @var{old-class} @var{new-class})
+
+@item
+(update-direct-subclass! @var{subclass} @var{old-class} @var{new-class})
+@end itemize
+
+and the default methods for these generic functions invoke further
+generic functions, and so on@dots{} The detailed protocol for all of these
+is described in @ref{MOP Specification}.
+
+@node Changing the Class of an Instance
+@subsection Changing the Class of an Instance
+
+You can change the class of an existing instance by invoking the
+generic function @code{change-class} with two arguments: the instance
+and the new class.
+
+@deffn generic change-class
+@end deffn
+
+The default method for @code{change-class} decides how to implement the
+change of class by looking at the slot definitions for the instance's
+existing class and for the new class. If the new class has slots with
+the same name as slots in the existing class, the values for those slots
+are preserved. Slots that are present only in the existing class are
+discarded. Slots that are present only in the new class are initialized
+using the corresponding slot definition's init function (@pxref{Classes,,
+slot-init-function}).
+
+@deffn {method} change-class (obj <object>) (new <class>)
+Modify instance @var{obj} to make it an instance of class @var{new}.
+
+The value of each of @var{obj}'s slots is preserved only if a similarly named
+slot exists in @var{new}; any other slot values are discarded.
+
+The slots in @var{new} that do not correspond to any of @var{obj}'s
+pre-existing slots are initialized according to @var{new}'s slot definitions'
+init functions.
+@end deffn
+
+Customized change of class behaviour can be implemented by defining
+@code{change-class} methods that are specialized either by the class
+of the instances to be modified or by the metaclass of the new class.
+
+When a class is redefined (@pxref{Redefining a Class}), and the default
+class redefinition behaviour is not overridden, GOOPS (eventually)
+invokes the @code{change-class} generic function for each existing
+instance of the redefined class.
+
+@node Introspection
+@subsection Introspection
+
+@dfn{Introspection}, also known as @dfn{reflection}, is the name given
+to the ability to obtain information dynamically about GOOPS metaobjects.
+It is perhaps best illustrated by considering an object oriented language
+that does not provide any introspection, namely C++.
+
+Nothing in C++ allows a running program to obtain answers to the following
+types of question:
+
+@itemize @bullet
+@item
+What are the data members of this object or class?
+
+@item
+What classes does this class inherit from?
+
+@item
+Is this method call virtual or non-virtual?
+
+@item
+If I invoke @code{Employee::adjustHoliday()}, what class contains the
+@code{adjustHoliday()} method that will be applied?
+@end itemize
+
+In C++, answers to such questions can only be determined by looking at
+the source code, if you have access to it. GOOPS, on the other hand,
+includes procedures that allow answers to these questions --- or their
+GOOPS equivalents --- to be obtained dynamically, at run time.
+
+@menu
+* Classes::
+* Slots::
+* Instances::
+* Generic Functions::
+* Generic Function Methods::
+@end menu
+
+@node Classes
+@subsubsection Classes
+
+@deffn {primitive procedure} class-name class
+Return the name of class @var{class}.
+This is the value of the @var{class} metaobject's @code{name} slot.
+@end deffn
+
+@deffn {primitive procedure} class-direct-supers class
+Return a list containing the direct superclasses of @var{class}.
+This is the value of the @var{class} metaobject's
+@code{direct-supers} slot.
+@end deffn
+
+@deffn {primitive procedure} class-direct-slots class
+Return a list containing the slot definitions of the direct slots of
+@var{class}.
+This is the value of the @var{class} metaobject's @code{direct-slots}
+slot.
+@end deffn
+
+@deffn {primitive procedure} class-direct-subclasses class
+Return a list containing the direct subclasses of @var{class}.
+This is the value of the @var{class} metaobject's
+@code{direct-subclasses} slot.
+@end deffn
+
+@deffn {primitive procedure} class-direct-methods class
+Return a list of all the generic function methods that use @var{class}
+as a formal parameter specializer.
+This is the value of the @var{class} metaobject's @code{direct-methods}
+slot.
+@end deffn
+
+@deffn {primitive procedure} class-precedence-list class
+Return the class precedence list for class @var{class} (@pxref{Class
+precedence list}).
+This is the value of the @var{class} metaobject's @code{cpl} slot.
+@end deffn
+
+@deffn {primitive procedure} class-slots class
+Return a list containing the slot definitions for all @var{class}'s slots,
+including any slots that are inherited from superclasses.
+This is the value of the @var{class} metaobject's @code{slots} slot.
+@end deffn
+
+@deffn {primitive procedure} class-environment class
+Return the value of @var{class}'s @code{environment} slot.
+[ *fixme* I don't know what this value is used for. ]
+@end deffn
+
+@deffn procedure class-subclasses class
+Return a list of all subclasses of @var{class}.
+@end deffn
+
+@deffn procedure class-methods class
+Return a list of all methods that use @var{class} or a subclass of
+@var{class} as one of its formal parameter specializers.
+@end deffn
+
+@node Slots
+@subsubsection Slots
+
+@deffn procedure class-slot-definition class slot-name
+Return the slot definition for the slot named @var{slot-name} in class
+@var{class}. @var{slot-name} should be a symbol.
+@end deffn
+
+@deffn procedure slot-definition-name slot-def
+Extract and return the slot name from @var{slot-def}.
+@end deffn
+
+@deffn procedure slot-definition-options slot-def
+Extract and return the slot options from @var{slot-def}.
+@end deffn
+
+@deffn procedure slot-definition-allocation slot-def
+Extract and return the slot allocation option from @var{slot-def}. This
+is the value of the @code{#:allocation} keyword (@pxref{Slot Options,,
+allocation}), or @code{#:instance} if the @code{#:allocation} keyword is
+absent.
+@end deffn
+
+@deffn procedure slot-definition-getter slot-def
+Extract and return the slot getter option from @var{slot-def}. This is
+the value of the @code{#:getter} keyword (@pxref{Slot Options,,
+getter}), or @code{#f} if the @code{#:getter} keyword is absent.
+@end deffn
+
+@deffn procedure slot-definition-setter slot-def
+Extract and return the slot setter option from @var{slot-def}. This is
+the value of the @code{#:setter} keyword (@pxref{Slot Options,,
+setter}), or @code{#f} if the @code{#:setter} keyword is absent.
+@end deffn
+
+@deffn procedure slot-definition-accessor slot-def
+Extract and return the slot accessor option from @var{slot-def}. This
+is the value of the @code{#:accessor} keyword (@pxref{Slot Options,,
+accessor}), or @code{#f} if the @code{#:accessor} keyword is absent.
+@end deffn
+
+@deffn procedure slot-definition-init-value slot-def
+Extract and return the slot init-value option from @var{slot-def}. This
+is the value of the @code{#:init-value} keyword (@pxref{Slot Options,,
+init-value}), or the unbound value if the @code{#:init-value} keyword is
+absent.
+@end deffn
+
+@deffn procedure slot-definition-init-form slot-def
+Extract and return the slot init-form option from @var{slot-def}. This
+is the value of the @code{#:init-form} keyword (@pxref{Slot Options,,
+init-form}), or the unbound value if the @code{#:init-form} keyword is
+absent.
+@end deffn
+
+@deffn procedure slot-definition-init-thunk slot-def
+Extract and return the slot init-thunk option from @var{slot-def}. This
+is the value of the @code{#:init-thunk} keyword (@pxref{Slot Options,,
+init-thunk}), or @code{#f} if the @code{#:init-thunk} keyword is absent.
+@end deffn
+
+@deffn procedure slot-definition-init-keyword slot-def
+Extract and return the slot init-keyword option from @var{slot-def}.
+This is the value of the @code{#:init-keyword} keyword (@pxref{Slot
+Options,, init-keyword}), or @code{#f} if the @code{#:init-keyword}
+keyword is absent.
+@end deffn
+
+@deffn procedure slot-init-function class slot-name
+Return the initialization function for the slot named @var{slot-name} in
+class @var{class}. @var{slot-name} should be a symbol.
+
+The returned initialization function incorporates the effects of the
+standard @code{#:init-thunk}, @code{#:init-form} and @code{#:init-value}
+slot options. These initializations can be overridden by the
+@code{#:init-keyword} slot option or by a specialized @code{initialize}
+method, so, in general, the function returned by
+@code{slot-init-function} may be irrelevant. For a fuller discussion,
+see @ref{Slot Options,, init-value}.
+@end deffn
+
+@node Instances
+@subsubsection Instances
+
+@deffn {primitive procedure} class-of value
+Return the GOOPS class of any Scheme @var{value}.
+@end deffn
+
+@deffn {primitive procedure} instance? object
+Return @code{#t} if @var{object} is any GOOPS instance, otherwise
+@code{#f}.
+@end deffn
+
+@deffn procedure is-a? object class
+Return @code{#t} if @var{object} is an instance of @var{class} or one of
+its subclasses.
+@end deffn
+
+Implementation notes: @code{is-a?} uses @code{class-of} and
+@code{class-precedence-list} to obtain the class precedence list for
+@var{object}.
+
+@node Generic Functions
+@subsubsection Generic Functions
+
+@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.
+@end deffn
+
+@node Generic Function Methods
+@subsubsection Generic Function Methods
+
+@deffn {primitive procedure} method-generic-function method
+Return the generic function that @var{method} belongs to.
+This is the value of the @var{method} metaobject's
+@code{generic-function} slot.
+@end deffn
+
+@deffn {primitive procedure} method-specializers method
+Return a list of @var{method}'s formal parameter specializers .
+This is the value of the @var{method} metaobject's
+@code{specializers} slot.
+@end deffn
+
+@deffn {primitive procedure} method-procedure method
+Return the procedure that implements @var{method}.
+This is the value of the @var{method} metaobject's
+@code{procedure} slot.
+@end deffn
+
+@deffn generic method-source
+@deffnx method method-source (m <method>)
+Return an expression that prints to show the definition of method
+@var{m}.
+
+@example
+(define-generic cube)
+
+(define-method (cube (n <number>))
+ (* n n n))
+
+(map method-source (generic-function-methods cube))
+@result{}
+((method ((n <number>)) (* n n n)))
+@end example
+@end deffn
+
+@node Miscellaneous Functions
+@subsection Miscellaneous Functions
+
+@menu
+* Administrative Functions::
+* GOOPS Error Handling::
+* Object Comparisons::
+* Cloning Objects::
+* Write and Display::
+@end menu
+
+@node Administrative Functions
+@subsubsection Administration Functions
+
+This section describes administrative, non-technical GOOPS functions.
+
+@deffn primitive goops-version
+Return the current GOOPS version as a string, for example ``0.2''.
+@end deffn
+
+@node GOOPS Error Handling
+@subsubsection Error Handling
+
+The procedure @code{goops-error} is called to raise an appropriate error
+by the default methods of the following generic functions:
+
+@itemize @bullet
+@item
+@code{slot-missing} (@pxref{Handling Slot Access Errors,, slot-missing})
+
+@item
+@code{slot-unbound} (@pxref{Handling Slot Access Errors,, slot-unbound})
+
+@item
+@code{no-method} (@pxref{Handling Invocation Errors,, no-method})
+
+@item
+@code{no-applicable-method} (@pxref{Handling Invocation Errors,,
+no-applicable-method})
+
+@item
+@code{no-next-method} (@pxref{Handling Invocation Errors,,
+no-next-method})
+@end itemize
+
+If you customize these functions for particular classes or metaclasses,
+you may still want to use @code{goops-error} to signal any error
+conditions that you detect.
+
+@deffn procedure goops-error format-string . args
+Raise an error with key @code{goops-error} and error message constructed
+from @var{format-string} and @var{args}. Error message formatting is
+as done by @code{scm-error}.
+@end deffn
+
+@node Object Comparisons
+@subsubsection Object Comparisons
+
+@deffn generic eqv?
+@deffnx method eqv? ((x <top>) (y <top>))
+@deffnx generic equal?
+@deffnx method equal? ((x <top>) (y <top>))
+@deffnx generic =
+@deffnx method = ((x <number>) (y <number>))
+Generic functions and default (unspecialized) methods for comparing two
+GOOPS objects.
+
+The default method for @code{eqv?} returns @code{#t} for all values
+that are equal in the sense defined by R5RS and the Guile reference
+manual, otherwise @code{#f}. The default method for @code{equal?}
+returns @code{#t} or @code{#f} in the sense defined by R5RS and the
+Guile reference manual. If no such comparison is defined,
+@code{equal?} returns the result of a call to @code{eqv?}. The
+default method for = returns @code{#t} if @var{x} and @var{y} are
+numerically equal, otherwise @code{#f}.
+
+Application class authors may wish to define specialized methods for
+@code{eqv?}, @code{equal?} and @code{=} that compare instances of the
+same class for equality in whatever sense is useful to the
+application. Such methods will only be called if the arguments have
+the same class and the result of the comparison isn't defined by R5RS
+and the Guile reference manual.
+@end deffn
+
+@node Cloning Objects
+@subsubsection Cloning Objects
+
+@deffn generic shallow-clone
+@deffnx method shallow-clone (self <object>)
+Return a ``shallow'' clone of @var{self}. The default method makes a
+shallow clone by allocating a new instance and copying slot values from
+self to the new instance. Each slot value is copied either as an
+immediate value or by reference.
+@end deffn
+
+@deffn generic deep-clone
+@deffnx method deep-clone (self <object>)
+Return a ``deep'' clone of @var{self}. The default method makes a deep
+clone by allocating a new instance and copying or cloning slot values
+from self to the new instance. If a slot value is an instance
+(satisfies @code{instance?}), it is cloned by calling @code{deep-clone}
+on that value. Other slot values are copied either as immediate values
+or by reference.
+@end deffn
+
+@node Write and Display
+@subsubsection Write and Display
+
+@deffn {primitive generic} write object port
+@deffnx {primitive generic} display object port
+When GOOPS is loaded, @code{write} and @code{display} become generic
+functions with special methods for printing
+
+@itemize @bullet
+@item
+objects - instances of the class @code{<object>}
+
+@item
+foreign objects - instances of the class @code{<foreign-object>}
+
+@item
+classes - instances of the class @code{<class>}
+
+@item
+generic functions - instances of the class @code{<generic>}
+
+@item
+methods - instances of the class @code{<method>}.
+@end itemize
+
+@code{write} and @code{display} print non-GOOPS values in the same way
+as the Guile primitive @code{write} and @code{display} functions.
+@end deffn
+
+@node MOP Specification
+@section MOP Specification
+
+For an introduction to metaobjects and the metaobject protocol,
+see @ref{Metaobjects and the Metaobject Protocol}.
+
+The aim of the MOP specification in this chapter is to specify all the
+customizable generic function invocations that can be made by the standard
+GOOPS syntax, procedures and methods, and to explain the protocol for
+customizing such invocations.
+
+A generic function invocation is customizable if the types of the arguments
+to which it is applied are not all determined by the lexical context in
+which the invocation appears. For example,
+
+@itemize @bullet
+@item
+the @code{(initialize @var{instance} @var{initargs})} invocation in the
+default @code{make-instance} method is customizable, because the type of the
+@code{@var{instance}} argument is determined by the class that was passed to
+@code{make-instance}.
+
+@item
+the @code{(make <generic> #:name ',name)} invocation in @code{define-generic}
+is not customizable, because all of its arguments have lexically determined
+types.
+@end itemize
+
+When using this rule to decide whether a given generic function invocation
+is customizable, we ignore arguments that are expected to be handled in
+method definitions as a single ``rest'' list argument.
+
+For each customizable generic function invocation, the @dfn{invocation
+protocol} is explained by specifying
+
+@itemize @bullet
+@item
+what, conceptually, the applied method is intended to do
+
+@item
+what assumptions, if any, the caller makes about the applied method's side
+effects
+
+@item
+what the caller expects to get as the applied method's return value.
+@end itemize
+
+@menu
+* Class Definition::
+* Instance Creation::
+* Class Redefinition::
+* Method Definition::
+* Generic Function Invocation::
+@end menu
+
+@node Class Definition
+@subsection Class Definition
+
+@code{define-class} (syntax)
+
+@itemize @bullet
+@item
+@code{class} (syntax)
+
+@itemize @bullet
+@item
+@code{make-class} (procedure)
+
+@itemize @bullet
+@item
+@code{make @var{metaclass} @dots{}} (generic)
+
+@var{metaclass} is the metaclass of the class being defined, either
+taken from the @code{#:metaclass} class option or computed by
+@code{ensure-metaclass}. The applied method must create and return the
+fully initialized class metaobject for the new class definition.
+@end itemize
+
+@end itemize
+
+@item
+@code{class-redefinition @var{old-class} @var{new-class}} (generic)
+
+@code{define-class} calls @code{class-redefinition} if the variable
+specified by its first argument already held a GOOPS class definition.
+@var{old-class} and @var{new-class} are the old and new class metaobjects.
+The applied method should perform whatever is necessary to handle the
+redefinition, and should return the class metaobject that is to be bound
+to @code{define-class}'s variable. The default class redefinition
+protocol is described in @ref{Class Redefinition}.
+@end itemize
+
+The @code{(make @var{metaclass} @dots{})} invocation above will create
+an class metaobject with metaclass @var{metaclass}. By default, this
+metaobject will be initialized by the @code{initialize} method that is
+specialized for instances of type @code{<class>}.
+
+@code{initialize <class> @var{initargs}} (method)
+
+@itemize @bullet
+@item
+@code{compute-cpl @var{class}} (generic)
+
+The applied method should compute and return the class precedence list
+for @var{class} as a list of class metaobjects. When @code{compute-cpl}
+is called, the following @var{class} metaobject slots have all been
+initialized: @code{name}, @code{direct-supers}, @code{direct-slots},
+@code{direct-subclasses} (empty), @code{direct-methods}. The value
+returned by @code{compute-cpl} will be stored in the @code{cpl} slot.
+
+@item
+@code{compute-slots @var{class}} (generic)
+
+The applied method should compute and return the slots (union of direct
+and inherited) for @var{class} as a list of slot definitions. When
+@code{compute-slots} is called, all the @var{class} metaobject slots
+mentioned for @code{compute-cpl} have been initialized, plus the
+following: @code{cpl}, @code{redefined} (@code{#f}), @code{environment}.
+The value returned by @code{compute-slots} will be stored in the
+@code{slots} slot.
+
+@item
+@code{compute-get-n-set @var{class} @var{slot-def}} (generic)
+
+@code{initialize} calls @code{compute-get-n-set} for each slot computed
+by @code{compute-slots}. The applied method should compute and return a
+pair of closures that, respectively, get and set the value of the specified
+slot. The get closure should have arity 1 and expect a single argument
+that is the instance whose slot value is to be retrieved. The set closure
+should have arity 2 and expect two arguments, where the first argument is
+the instance whose slot value is to be set and the second argument is the
+new value for that slot. The closures should be returned in a two element
+list: @code{(list @var{get} @var{set})}.
+
+The closures returned by @code{compute-get-n-set} are stored as part of
+the value of the @var{class} metaobject's @code{getters-n-setters} slot.
+Specifically, the value of this slot is a list with the same number of
+elements as there are slots in the class, and each element looks either like
+
+@example
+@code{(@var{slot-name-symbol} @var{init-function} . @var{index})}
+@end example
+
+or like
+
+@example
+@code{(@var{slot-name-symbol} @var{init-function} @var{get} @var{set})}
+@end example
+
+Where the get and set closures are replaced by @var{index}, the slot is
+an instance slot and @var{index} is the slot's index in the underlying
+structure: GOOPS knows how to get and set the value of such slots and so
+does not need specially constructed get and set closures. Otherwise,
+@var{get} and @var{set} are the closures returned by @code{compute-get-n-set}.
+
+The structure of the @code{getters-n-setters} slot value is important when
+understanding the next customizable generic functions that @code{initialize}
+calls@dots{}
+
+@item
+@code{compute-getter-method @var{class} @var{gns}} (generic)
+
+@code{initialize} calls @code{compute-getter-method} for each of the class's
+slots (as determined by @code{compute-slots}) that includes a
+@code{#:getter} or @code{#:accessor} slot option. @var{gns} is the
+element of the @var{class} metaobject's @code{getters-n-setters} slot that
+specifies how the slot in question is referenced and set, as described
+above under @code{compute-get-n-set}. The applied method should create
+and return a method that is specialized for instances of type @var{class}
+and uses the get closure to retrieve the slot's value. [ *fixme Need
+to insert something here about checking that the value is not unbound. ]
+@code{initialize} uses @code{add-method!} to add the returned method to
+the generic function named by the slot definition's @code{#:getter} or
+@code{#:accessor} option.
+
+@item
+@code{compute-setter-method @var{class} @var{gns}} (generic)
+
+@code{compute-setter-method} is invoked with the same arguments as
+@code{compute-getter-method}, for each of the class's slots that includes
+a @code{#:setter} or @code{#:accessor} slot option. The applied method
+should create and return a method that is specialized for instances of
+type @var{class} and uses the set closure to set the slot's value.
+@code{initialize} then uses @code{add-method!} to add the returned method
+to the generic function named by the slot definition's @code{#:setter}
+or @code{#:accessor} option.
+@end itemize
+
+@node Instance Creation
+@subsection Instance Creation
+
+@code{make <class> . @var{initargs}} (method)
+
+@itemize @bullet
+@item
+@code{allocate-instance @var{class} @var{initargs}} (generic)
+
+The applied @code{allocate-instance} method should allocate storage for
+a new instance of class @var{class} and return the uninitialized instance.
+
+@item
+@code{initialize @var{instance} @var{initargs}} (generic)
+
+@var{instance} is the uninitialized instance returned by
+@code{allocate-instance}. The applied method should initialize the new
+instance in whatever sense is appropriate for its class. The method's
+return value is ignored.
+@end itemize
+
+@node Class Redefinition
+@subsection Class Redefinition
+
+The default @code{class-redefinition} method, specialized for classes
+with the default metaclass @code{<class>}, has the following internal
+protocol.
+
+@code{class-redefinition (@var{old <class>}) (@var{new <class>})}
+(method)
+
+@itemize @bullet
+@item
+@code{remove-class-accessors! @var{old}} (generic)
+
+@item
+@code{update-direct-method! @var{method} @var{old} @var{new}} (generic)
+
+@item
+@code{update-direct-subclass! @var{subclass} @var{old} @var{new}} (generic)
+@end itemize
+
+This protocol cleans up things that the definition of the old class
+once changed and modifies things to work with the new class.
+
+The default @code{remove-class-accessors!} method removes the
+accessor methods of the old class from all classes which they
+specialize.
+
+The default @code{update-direct-method!} method substitutes the new
+class for the old in all methods specialized to the old class.
+
+The default @code{update-direct-subclass!} method invokes
+@code{class-redefinition} recursively to handle the redefinition of
+subclasses.
+
+When a class is redefined, any existing instance of the redefined class
+will be modified for the new class definition before the next time that
+any of the instance's slot is referenced or set. GOOPS modifies each
+instance by calling the generic function @code{change-class}.
+
+The default @code{change-class} method copies slot values from the old
+to the modified instance, and initializes new slots, as described in
+@ref{Changing the Class of an Instance}. After doing so, it makes a
+generic function invocation that can be used to customize the instance
+update algorithm.
+
+@code{change-class (@var{old-instance <object>}) (@var{new <class>})} (method)
+
+@itemize @bullet
+@item
+@code{update-instance-for-different-class @var{old-instance} @var{new-instance}} (generic)
+
+@code{change-class} invokes @code{update-instance-for-different-class}
+as the last thing that it does before returning. The applied method can
+make any further adjustments to @var{new-instance} that are required to
+complete or modify the change of class. The return value from the
+applied method is ignored.
+
+The default @code{update-instance-for-different-class} method does
+nothing.
+@end itemize
+
+@node Method Definition
+@subsection Method Definition
+
+@code{define-method} (syntax)
+
+@itemize @bullet
+@item
+@code{add-method! @var{target} @var{method}} (generic)
+
+@code{define-method} invokes the @code{add-method!} generic function to
+handle adding the new method to a variety of possible targets. GOOPS
+includes methods to handle @var{target} as
+
+@itemize @bullet
+@item
+a generic function (the most common case)
+
+@item
+a procedure
+
+@item
+a primitive generic (@pxref{Extending Guiles Primitives})
+@end itemize
+
+By defining further methods for @code{add-method!}, you can
+theoretically handle adding methods to further types of target.
+@end itemize
+
+@node Generic Function Invocation
+@subsection Generic Function Invocation
+
+[ *fixme* Description required here. ]
+
+@code{apply-generic}
+
+@itemize @bullet
+@item
+@code{no-method}
+
+@item
+@code{compute-applicable-methods}
+
+@item
+@code{sort-applicable-methods}
+
+@item
+@code{apply-methods}
+
+@item
+@code{no-applicable-method}
+@end itemize
+
+@code{sort-applicable-methods}
+
+@itemize @bullet
+@item
+@code{method-more-specific?}
+@end itemize
+
+@code{apply-methods}
+
+@itemize @bullet
+@item
+@code{apply-method}
+@end itemize
+
+@code{next-method}
+
+@itemize @bullet
+@item
+@code{no-next-method}
+@end itemize
+
+@node Tutorial
+@section Tutorial
+@include goops-tutorial.texi
diff --git a/doc/ref/guile.texi b/doc/ref/guile.texi
index c152a0ca4..7bd5ace36 100644
--- a/doc/ref/guile.texi
+++ b/doc/ref/guile.texi
@@ -175,6 +175,8 @@ x
* Guile Modules::
+* GOOPS::
+
* Guile Implementation::
* Autoconf Support::
@@ -363,6 +365,8 @@ available through both Scheme and C interfaces.
@include scsh.texi
@include scheme-debugging.texi
+@include goops.texi
+
@node Guile Implementation
@chapter Guile Implementation
diff --git a/doc/ref/hierarchy.eps b/doc/ref/hierarchy.eps
new file mode 100644
index 000000000..7b1a98605
--- /dev/null
+++ b/doc/ref/hierarchy.eps
@@ -0,0 +1,127 @@
+%!PS-Adobe-2.0 EPSF
+%%Title: /tmp/xfig-fig016295
+%%Creator: fig2dev
+%%CreationDate: Fri Jun 10 23:18:16 1994
+%%For: eg@kaolin (Erick Gallesio)
+%%BoundingBox: 0 0 361 217
+%%Pages: 0
+%%EndComments
+/$F2psDict 200 dict def
+$F2psDict begin
+$F2psDict /mtrx matrix put
+/l {lineto} bind def
+/m {moveto} bind def
+/s {stroke} bind def
+/n {newpath} bind def
+/gs {gsave} bind def
+/gr {grestore} bind def
+/clp {closepath} bind def
+/graycol {dup dup currentrgbcolor 4 -2 roll mul 4 -2 roll mul
+4 -2 roll mul setrgbcolor} bind def
+/col-1 {} def
+/col0 {0 0 0 setrgbcolor} bind def
+/col1 {0 0 1 setrgbcolor} bind def
+/col2 {0 1 0 setrgbcolor} bind def
+/col3 {0 1 1 setrgbcolor} bind def
+/col4 {1 0 0 setrgbcolor} bind def
+/col5 {1 0 1 setrgbcolor} bind def
+/col6 {1 1 0 setrgbcolor} bind def
+/col7 {1 1 1 setrgbcolor} bind def
+ end
+/$F2psBegin {$F2psDict begin /$F2psEnteredState save def} def
+/$F2psEnd {$F2psEnteredState restore end} def
+%%EndProlog
+
+$F2psBegin
+0 setlinecap 0 setlinejoin
+-216.0 288.0 translate 0.900 -0.900 scale
+0.500 setlinewidth
+n 309 159 m 309 159 l gs col-1 s gr
+n 246.401 216.889 m 244.000 209.000 l 249.831 214.831 l gs 2 setlinejoin col-1 s gr
+% Polyline
+n 244 209 m 274 259 l gs col-1 s gr
+n 298.169 214.831 m 304.000 209.000 l 301.599 216.889 l gs 2 setlinejoin col-1 s gr
+% Polyline
+n 304 209 m 274 259 l gs col-1 s gr
+n 255.721 213.778 m 249.000 209.000 l 257.179 210.053 l gs 2 setlinejoin col-1 s gr
+% Polyline
+n 249 209 m 364 254 l gs col-1 s gr
+n 370.312 216.376 m 374.000 209.000 l 374.217 217.243 l gs 2 setlinejoin col-1 s gr
+% Polyline
+n 374 209 m 364 254 l gs col-1 s gr
+n 283.772 280.725 m 279.000 274.000 l 286.376 277.688 l gs 2 setlinejoin col-1 s gr
+% Polyline
+n 279 274 m 314 304 l gs col-1 s gr
+n 351.457 272.333 m 359.000 269.000 l 353.913 275.490 l gs 2 setlinejoin col-1 s gr
+% Polyline
+n 359 269 m 314 304 l gs col-1 s gr
+n 300.950 165.789 m 309.000 164.000 l 302.739 169.367 l gs 2 setlinejoin col-1 s gr
+% Polyline
+n 309 164 m 249 194 l gs col-1 s gr
+n 307.000 172.000 m 309.000 164.000 l 311.000 172.000 l gs 2 setlinejoin col-1 s gr
+% Polyline
+n 309 164 m 309 199 l gs col-1 s gr
+n 315.261 169.367 m 309.000 164.000 l 317.050 165.789 l gs 2 setlinejoin col-1 s gr
+% Polyline
+n 309 164 m 379 199 l gs col-1 s gr
+n 406.949 101.701 m 404.000 94.000 l 410.226 99.407 l gs 2 setlinejoin col-1 s gr
+% Polyline
+n 404 94 m 439 144 l gs col-1 s gr
+n 410.363 99.245 m 404.000 94.000 l 412.083 95.634 l gs 2 setlinejoin col-1 s gr
+% Polyline
+n 404 94 m 509 144 l gs col-1 s gr
+n 411.173 98.068 m 404.000 94.000 l 412.243 94.214 l gs 2 setlinejoin col-1 s gr
+% Polyline
+n 404 94 m 584 144 l gs col-1 s gr
+n 396.075 96.277 m 404.000 94.000 l 398.079 99.739 l gs 2 setlinejoin col-1 s gr
+% Polyline
+n 404 94 m 309 149 l gs col-1 s gr
+% Polyline
+n 584 229 m 584 204 l gs col-1 s gr
+n 582.000 212.000 m 584.000 204.000 l 586.000 212.000 l gs 2 setlinejoin col-1 s gr
+% Polyline
+n 584 189 m 584 159 l gs col-1 s gr
+n 582.000 167.000 m 584.000 159.000 l 586.000 167.000 l gs 2 setlinejoin col-1 s gr
+/Times-Bold findfont 12.00 scalefont setfont
+239 209 m
+gs 1 -1 scale (A) col-1 show gr
+/Times-Bold findfont 12.00 scalefont setfont
+274 274 m
+gs 1 -1 scale (D) col-1 show gr
+/Times-Bold findfont 12.00 scalefont setfont
+359 269 m
+gs 1 -1 scale (E) col-1 show gr
+/Times-Bold findfont 12.00 scalefont setfont
+304 209 m
+gs 1 -1 scale (B) col-1 show gr
+/Times-Bold findfont 12.00 scalefont setfont
+374 209 m
+gs 1 -1 scale (C) col-1 show gr
+/Times-Bold findfont 12.00 scalefont setfont
+314 319 m
+gs 1 -1 scale (F) col-1 show gr
+/Times-Bold findfont 12.00 scalefont setfont
+289 159 m
+gs 1 -1 scale (<object>) col-1 show gr
+/Times-Bold findfont 12.00 scalefont setfont
+389 89 m
+gs 1 -1 scale (<top>) col-1 show gr
+/Times-Bold findfont 12.00 scalefont setfont
+424 154 m
+gs 1 -1 scale (<pair>) col-1 show gr
+/Times-Bold findfont 12.00 scalefont setfont
+474 154 m
+gs 1 -1 scale (<procedure>) col-1 show gr
+/Times-Bold findfont 12.00 scalefont setfont
+559 154 m
+gs 1 -1 scale (<number>) col-1 show gr
+/Times-Bold findfont 12.00 scalefont setfont
+629 154 m
+gs 1 -1 scale (...) col-1 show gr
+/Times-Bold findfont 12.00 scalefont setfont
+569 199 m
+gs 1 -1 scale (<real>) col-1 show gr
+/Times-Bold findfont 12.00 scalefont setfont
+559 239 m
+gs 1 -1 scale (<integer>) col-1 show gr
+$F2psEnd
diff --git a/doc/ref/hierarchy.pdf b/doc/ref/hierarchy.pdf
new file mode 100644
index 000000000..3a19ba4eb
--- /dev/null
+++ b/doc/ref/hierarchy.pdf
@@ -0,0 +1,74 @@
+%PDF-1.3
+%쏢
+5 0 obj
+<</Length 6 0 R/Filter /FlateDecode>>
+stream
+xmn1 E
+-Ű(6-][. y)Ҽw(ug_o͇13l_Ml9bi}0(:U[|[-:s"V!zir E/N-#K5n[{ rE#]%w afJA<#"n J=uF$9"TZQAn*PmHXɎ+sd"st 1sU.a-<pS9ChፒcLe8tӮ*4"w!çJiMffi sz^]1&d=E8{^xㄖK=M!T͊kA${4'!k޻!W)M%D1ĂG\6d+񀉔PL52<dĪld.^n%LNaq5Oݜ$*7ɞaܙWt]zk/VbdWM?vR
+~V[\aƘoWf ZS-We#,>-b;{UijdS[gUfv^=(8|ٱGĄyTͦ PZA>cۨCx~2(8endstream
+endobj
+6 0 obj
+660
+endobj
+4 0 obj
+<</Type/Page/MediaBox [0 0 361 217]
+/Parent 3 0 R
+/Resources<</ProcSet[/PDF /Text]
+/ExtGState 9 0 R
+/Font 10 0 R
+>>
+/Contents 5 0 R
+>>
+endobj
+3 0 obj
+<< /Type /Pages /Kids [
+4 0 R
+] /Count 1
+>>
+endobj
+1 0 obj
+<</Type /Catalog /Pages 3 0 R
+>>
+endobj
+7 0 obj
+<</Type/ExtGState
+/OPM 1>>endobj
+9 0 obj
+<</R7
+7 0 R>>
+endobj
+10 0 obj
+<</R8
+8 0 R>>
+endobj
+8 0 obj
+<</BaseFont/Times-Bold/Type/Font
+/Subtype/Type1>>
+endobj
+2 0 obj
+<</Producer(GPL Ghostscript 8.15)
+/CreationDate(D:20060418115825)
+/ModDate(D:20060418115825)
+/Title(/tmp/xfig-fig016295)
+/Creator(fig2dev)
+/Author(eg@kaolin \(Erick Gallesio\))>>endobj
+xref
+0 11
+0000000000 65535 f
+0000000973 00000 n
+0000001186 00000 n
+0000000914 00000 n
+0000000764 00000 n
+0000000015 00000 n
+0000000745 00000 n
+0000001021 00000 n
+0000001121 00000 n
+0000001062 00000 n
+0000001091 00000 n
+trailer
+<< /Size 11 /Root 1 0 R /Info 2 0 R
+/ID [(Cce3fq\\[)(Cce3fq\\[)]
+>>
+startxref
+1379
+%%EOF
diff --git a/doc/ref/hierarchy.png b/doc/ref/hierarchy.png
new file mode 100644
index 000000000..46f58b051
--- /dev/null
+++ b/doc/ref/hierarchy.png
Binary files differ
diff --git a/doc/ref/hierarchy.txt b/doc/ref/hierarchy.txt
new file mode 100644
index 000000000..c7992df7b
--- /dev/null
+++ b/doc/ref/hierarchy.txt
@@ -0,0 +1,14 @@
+ <top>
+ / \\\_____________________
+ / \\___________ \
+ / \ \ \
+ <object> <pair> <procedure> <number>
+ / | \ |
+ / | \ |
+ A B C <complex>
+ |\__/__ | |
+ \ / \ / |
+ D E <real>
+ \ / |
+ F |
+ <integer>
diff --git a/doc/ref/libguile-smobs.texi b/doc/ref/libguile-smobs.texi
index 09b5446cd..05c72aff0 100644
--- a/doc/ref/libguile-smobs.texi
+++ b/doc/ref/libguile-smobs.texi
@@ -28,7 +28,7 @@ datatypes described here.)
@menu
* Describing a New Type::
-* Creating Instances::
+* Creating Smob Instances::
* Type checking::
* Garbage Collecting Smobs::
* Garbage Collecting Simple Smobs::
@@ -132,8 +132,8 @@ init_image_type (void)
@end example
-@node Creating Instances
-@subsection Creating Instances
+@node Creating Smob Instances
+@subsection Creating Smob Instances
Normally, smobs can have one @emph{immediate} word of data. This word
stores either a pointer to an additional memory block that holds the
diff --git a/doc/ref/mop.text b/doc/ref/mop.text
new file mode 100644
index 000000000..0180f2c1e
--- /dev/null
+++ b/doc/ref/mop.text
@@ -0,0 +1,66 @@
+*** NOTE: This information needs updating! ***
+
+P - procedure
+L - local procedure
+S - syntax
+G - generic
+M - method
+
+define-class (S)
+ make-class (S)
+ ensure-metaclass (P)
+ ensure-metaclass-with-supers (P)
+ make (G)
+ ensure-class (P)
+ make (G)
+ class-redefinition (G)
+ remove-class-accessors (G)
+ update-direct-method (G)
+ update-direct-subclass (G)
+
+define-generic (S)
+ make-generic-function (S)
+ ensure-generic-function (P)
+ make (G)
+
+define-method (S)
+ ensure-method (P)
+ ensure-generic-function (P)
+ make (G)
+ make (G)
+ add-method (P)
+
+method (S)
+ ensure-method (P)
+
+initialize (class) (M)
+ compute-cpl (P)
+ compute-slots (G)
+ compute-getters-n-setters (P)
+ compute-slot-init-function (L)
+ compute-get-n-set (G)
+ compute-slot-accessors (P)
+ ensure-method (P)
+ %inherit-magic! (P)
+ %prep-layout! (P)
+
+initialize (generic) (M)
+ make (G)
+
+change-class (G)
+ change-object-class (P)
+ update-instance-for-different-class (G)
+
+make = make-instance (G)
+ allocate-instance (G)
+ %allocate-instance (P)
+ initialize (G)
+ %initialize-object (P)
+
+apply-generic (G)
+ compute-applicable-methods (G)
+ find-method (P)
+ sort-applicable-methods (G)
+ sort (P)
+ apply-methods (G)
+ apply-method (G)
diff --git a/doc/ref/preface.texi b/doc/ref/preface.texi
index 7a89069fe..8552d388b 100644
--- a/doc/ref/preface.texi
+++ b/doc/ref/preface.texi
@@ -22,7 +22,7 @@ use Guile in many useful and interesting ways.
@node Manual Layout
@section Layout of this Manual
-The manual is divided into five chapters.
+The manual is divided into the following chapters.
@table @strong
@item Chapter 1: Introduction to Guile
@@ -58,6 +58,10 @@ Describes some important modules, distributed as part of the Guile
distribution, that extend the functionality provided by the Guile
Scheme core.
+@item Chapter 6: GOOPS
+Describes GOOPS, an object oriented extension to Guile that provides
+classes, multiple inheritance and generic functions.
+
@end table
@@ -141,6 +145,9 @@ filling out a lot of the documentation of Scheme data types, control
mechanisms and procedures. In addition, he wrote the documentation
for Guile's SRFI modules and modules associated with the Guile REPL.
+The chapter on GOOPS was written by Christian Lynbech, Mikael
+Djurfeldt and Neil Jerram.
+
@node Guile License
@section The Guile License
@cindex copying
diff --git a/doc/ref/tools.texi b/doc/ref/tools.texi
index f2116dd71..4a076bbf0 100644
--- a/doc/ref/tools.texi
+++ b/doc/ref/tools.texi
@@ -232,8 +232,8 @@ is a expression suitable for initializing a new variable.
For procedures, you can use @code{SCM_DEFINE} for most purposes. Use
@code{SCM_PROC} along with @code{SCM_REGISTER_PROC} when you don't
want to be bothered with docstrings. Use @code{SCM_GPROC} for generic
-functions (@pxref{Creating Generic Functions,,, goops, GOOPS}). All
-procedures are declared with return type @code{SCM}.
+functions (@pxref{Creating Generic Functions}). All procedures are
+declared with return type @code{SCM}.
For everything else, use the appropriate macro (@code{SCM_SYMBOL} for
symbols, and so on). Without "_GLOBAL_", the declarations are