guile-commits
[Top][All Lists]
Advanced

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

[Guile-commits] GNU Guile branch, master, updated. release_1-9-13-141-gf


From: Neil Jerram
Subject: [Guile-commits] GNU Guile branch, master, updated. release_1-9-13-141-gf60a835
Date: Mon, 06 Dec 2010 22:31:15 +0000

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

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

The branch, master has been updated
       via  f60a835300834b0e2d8d5f272e1180231806b71b (commit)
      from  1dc43d57cc4f35bb67c175517554ce774ce339c2 (commit)

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

- Log -----------------------------------------------------------------
commit f60a835300834b0e2d8d5f272e1180231806b71b
Author: Neil Jerram <address@hidden>
Date:   Mon Dec 6 22:28:39 2010 +0000

    Merge `tutorial' and `reference' treatments of the same basic GOOPS
    material
    
    * doc/ref/goops.texi (GOOPS): Move use of (oop goops) here.
    
      (Class Definition): Merged with `Defining New Classes'
    
      (Instance Creation): Insert before covering slot options.  Merge in
      material from `Creating Instances'.
    
      (Slot Options): Merged some better wording and index entries from
      the tutorial version.
    
      (Slot Description Example): New node, containing the <my-complex>
      material from the tutorial.
    
      (Methods and Generic Functions, Inheritance): Tutorial sections
      moved into main line of the manual.
    
    * doc/ref/goops-tutorial.texi: Nothing left here now.

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

Summary of changes:
 doc/ref/goops-tutorial.texi |  798 --------------------------------------
 doc/ref/goops.texi          |  887 +++++++++++++++++++++++++++++++++++--------
 2 files changed, 722 insertions(+), 963 deletions(-)

diff --git a/doc/ref/goops-tutorial.texi b/doc/ref/goops-tutorial.texi
index 52b2931..d2cf640 100644
--- a/doc/ref/goops-tutorial.texi
+++ b/doc/ref/goops-tutorial.texi
@@ -29,801 +29,3 @@
 @c @macro guile                    @c was {\stk}
 @c Guile
 @c @end macro
-
-To start using @goops{} you first need to import the @code{(oop goops)}
-module.  You can do this at the Guile REPL by evaluating:
-
address@hidden
-(use-modules (oop goops))
address@hidden lisp
address@hidden (oop goops)
-
address@hidden
-* Class definition::  
-* Instance creation and slot access::  
-* Slot description::            
-* Inheritance::                 
-* Generic functions::           
address@hidden menu
-
address@hidden Class definition
address@hidden Class definition
-
-A new class is defined with the @code{define-class} syntax:
-
address@hidden define-class
address@hidden class
address@hidden
-(define-class @var{class} (@var{superclass} @dots{})
-   @var{slot-description} @dots{}
-   @var{class-option} @dots{})
address@hidden lisp
-
address@hidden is the class being defined.  The list of @var{superclass}es
-specifies which existing classes, if any, to inherit slots and
-properties from.  @dfn{Slots} hold address@hidden --- but
-see also the @code{#:allocation} slot option.} data, for instances of
-that class --- like ``fields'' or ``member variables'' in other object
-oriented systems.  Each @var{slot-description} gives the name of a slot
-and optionally some ``properties'' of this slot; for example its initial
-value, the name of a function which will access its value, and so on.
-Slot descriptions and inheritance are discussed more below.  For class
-options, see @ref{Class Options}.
address@hidden slot
-
-As an example, let us define a type for representing a complex number
-in terms of two real address@hidden course Guile already
-provides complex numbers, and @code{<complex>} is in fact a predefined
-class in GOOPS; but the definition here is still useful as an
-example.}  This can be done with the following class definition:
-
address@hidden
-(define-class <my-complex> (<number>)
-   r i)
address@hidden lisp
-
-This binds the variable @code{<my-complex>} to a new class whose
-instances will contain two slots.  These slots are called @code{r} and
address@hidden and will hold the real and imaginary parts of a complex
-number. Note that this class inherits from @code{<number>}, which is a
-predefined address@hidden@code{<number>} is the direct superclass of
-the predefined class @code{<complex>}; @code{<complex>} is the
-superclass of @code{<real>}, and @code{<real>} is the superclass of
address@hidden<integer>}.}
-
address@hidden Instance creation and slot access
address@hidden Instance creation and slot access
-
-Creation of an instance of a previously defined class can be done with
address@hidden  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 of
-the slots of the newly created instance. For instance, the following
-form
-
address@hidden make
address@hidden instance
address@hidden
-(define c (make <my-complex>))
address@hidden lisp
-
address@hidden
-will create a new @code{<my-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
address@hidden and the @code{slot-set!}  primitives. @code{slot-set!}
-sets the value of an object slot and @code{slot-ref} retrieves it.
-
address@hidden slot-set!
address@hidden slot-ref
address@hidden
address@hidden
-(slot-set! c 'r 10)
-(slot-set! c 'i 3)
-(slot-ref c 'r) @result{} 10
-(slot-ref c 'i) @result{} 3
address@hidden group
address@hidden 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)}:
-
address@hidden
address@hidden(use-modules (oop goops describe))}
address@hidden example
-
address@hidden
-Then the expression
-
address@hidden
-(describe c)
address@hidden lisp
-
address@hidden
-will print the following information on the standard output:
-
address@hidden
-#<<my-complex> 401d8638> is an instance of class <my-complex>
-Slots are: 
-     r = 10
-     i = 3
address@hidden smalllisp
-
address@hidden Slot description
address@hidden Slot description
address@hidden \label{slot-description}
-
-When specifying a slot (in a @code{(define-class @dots{})} form),
-various options can be specified in addition to the slot's name.  Each
-option is specified by a keyword.  The list of authorized keywords is
-given below:
-
address@hidden keyword
address@hidden @bullet
address@hidden
address@hidden:init-value} permits to supply a constant default value for the
-slot.  The value is obtained by evaluating the form given after the
address@hidden:init-value} at class definition time.
address@hidden default slot value
address@hidden #:init-value
-
address@hidden
address@hidden:init-form} specifies a form that, when evaluated, will return
-an initial value for the slot.  The form is evaluated each time that
-an instance of the class is created, in the lexical environment of the
-containing @code{define-class} expression.
address@hidden default slot value
address@hidden #:init-form
-
address@hidden
address@hidden:init-thunk} permits to supply a thunk that will provide a
-default value for the slot.  The value is obtained by invoking the
-thunk at instance creation time.
address@hidden default slot value
address@hidden #:init-thunk
-
address@hidden
address@hidden:init-keyword} permits to specify a keyword for initializing the
-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}.
address@hidden #:init-keyword
-
address@hidden
address@hidden:getter} permits to supply the name for the 
-slot getter. The name binding is done in the
-environment of the @code{define-class} macro.
address@hidden #:getter
address@hidden top level environment
address@hidden getter
-
address@hidden
address@hidden:setter} permits to supply the name for the 
-slot setter. The name binding is done in the
-environment of the @code{define-class} macro.
address@hidden #:setter
address@hidden top level environment
address@hidden setter
-
address@hidden
address@hidden: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!}.
address@hidden set!
address@hidden #:accessor
address@hidden top level environment
address@hidden accessor
-
address@hidden
address@hidden:allocation} permits to specify how storage for
-the slot is allocated. Three kinds of allocation are provided. 
-They are described below:
-
address@hidden @minus
address@hidden
address@hidden:instance} indicates that each instance gets its own storage for
-the slot. This is the default.
address@hidden
address@hidden: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.
address@hidden
address@hidden: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.
address@hidden
address@hidden: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.
address@hidden #:slot-set!
address@hidden #:slot-ref
address@hidden #:virtual
address@hidden #:class
address@hidden #:each-subclass
address@hidden #:instance
address@hidden #:allocation
address@hidden itemize
address@hidden itemize
-
-To illustrate slot description, we shall redefine the @code{<my-complex>} 
class 
-seen before. A definition could be:
-
address@hidden
-(define-class <my-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))
address@hidden 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
address@hidden) are automatically defined by the system to read and write
-the @code{r} (resp. @code{i}) slot.
-
address@hidden
-(define c1 (make <my-complex> #:r 1 #:i 2))
-(get-r c1) @result{} 1
-(set-r! c1 12)
-(get-r c1) @result{} 12
-(define c2 (make <my-complex> #:r 2))
-(get-r c2) @result{} 2
-(get-i c2) @result{} 0
address@hidden 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{<my-complex>} class, using the
address@hidden:accessor} option, could be:
-
address@hidden set!
address@hidden
-(define-class <my-complex> (<number>) 
-   (r #:init-value 0 #:accessor real-part #:init-keyword #:r)
-   (i #:init-value 0 #:accessor imag-part #:init-keyword #:i))
address@hidden lisp
-
-Using this class definition, reading the real part of the @code{c}
-complex can be done with:
address@hidden
-(real-part c)
address@hidden lisp
-and setting it to the value contained in the @code{new-value} variable
-can be done using the extended form of @code{set!}.
address@hidden
-(set! (real-part c) new-value)
address@hidden 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{<my-complex>} class using virtual slots is
-given in Figure@ 2.
-
address@hidden
address@hidden
address@hidden
-(define-class <my-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)))))))
-
address@hidden lisp
address@hidden @emph{Fig 2: A @code{<my-complex>} number class definition using 
virtual slots}
address@hidden group
address@hidden example
-
address@hidden 3
-This class definition implements two real slots (@code{r} and
address@hidden). 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
-
address@hidden #:slot-set!
address@hidden #:slot-ref
address@hidden
-(slot-set! c 'a 3)
address@hidden lisp
-
-permits to set the angle of the @code{c} complex number. This expression
-conducts, in fact, to the evaluation of the following expression
-
address@hidden
-((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)
address@hidden lisp
-
-A more complete example is given below:
-
address@hidden
address@hidden
address@hidden
-(define c (make <my-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)
address@hidden
-#<<my-complex> 401e9b58> is an instance of class <my-complex>
-Slots are: 
-     r = 1
-     i = 10
-     m = 10.0498756211209
-     a = 1.47112767430373
address@hidden smalllisp
address@hidden group
address@hidden 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.
-
address@hidden
-(define make-rectangular 
-   (lambda (x y) (make <my-complex> #:r x #:i y)))
-
-(define make-polar
-   (lambda (x y) (make <my-complex> #:magn x #:angle y)))
address@hidden lisp
-
address@hidden Inheritance
address@hidden Inheritance
address@hidden \label{inheritance}
-
address@hidden
-* Class hierarchy and inheritance of slots::  
-* Class precedence list::       
address@hidden menu
-
address@hidden Class hierarchy and inheritance of slots
address@hidden 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:
-
address@hidden
-(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)
address@hidden lisp
-
address@hidden, @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
address@hidden<object>}, the root of all the classes defined by
address@hidden @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.
-
address@hidden
address@hidden
address@hidden
address@hidden @image{hierarchy,5in}
address@hidden iftex
address@hidden
address@hidden hierarchy.txt
address@hidden ifnottex
-
address@hidden 1: A class hierarchy}
address@hidden(@code{<complex>} which is the direct subclass of @code{<number>}
-and the direct superclass of @code{<real>} has been omitted in this
-figure.)}
address@hidden group
address@hidden 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
address@hidden). The slots of a class can be obtained by the @code{class-slots}
-primitive.  For instance,
-
address@hidden
-(class-slots A) @result{} ((a))
-(class-slots E) @result{} ((a) (e) (c))
-(class-slots F) @result{} ((e) (c) (b) (d) (a) (f))
address@hidden used to be ((d) (a) (b) (c) (f))
address@hidden lisp
-
address@hidden: } The order of slots is not significant.
-
address@hidden Class precedence list
address@hidden Class precedence list
-
-A class may have more than one superclass.  @footnote{This section is an
-adaptation of Jeff Dalton's (J.Dalton@@ed.ac.uk) @cite{Brief
-introduction to CLOS}} With single inheritance (one superclass), it is
-easy to order the super classes from most to least specific. This is the
-rule:
-
address@hidden
address@hidden
-Rule 1: Each class is more specific than its address@hidden was \bf
address@hidden cartouche
address@hidden display
-
-With multiple inheritance, ordering is harder. Suppose we have
-
address@hidden
-(define-class X ()
-   (x #:init-value 1))
-
-(define-class Y ()
-   (x #:init-value 2))
-
-(define-class Z (X Y)
-   (@dots{}))
address@hidden lisp
-
-In this case, the @code{Z} class is more specific than the @code{X} or
address@hidden class for instances of @code{Z}. However, the @code{#:init-value}
-specified in @code{X} and @code{Y} leads to a problem: which one
-overrides the other?  The rule in @goops{}, as in CLOS, is that the
-superclasses listed earlier are more specific than those listed later.
-So:
-
address@hidden
address@hidden
-Rule 2: For a given class, superclasses listed earlier are more
-        specific than those listed later.
address@hidden cartouche
address@hidden display
-
-These rules are used to compute a linear order for a class and all its
-superclasses, from most specific to least specific.  This order is
-called the ``class precedence list'' of the class. Given these two
-rules, we can claim that the initial form for the @code{x} slot of
-previous example is 1 since the class @code{X} is placed before @code{Y}
-in class precedence list of @code{Z}.
-
-These two rules are not always enough to determine a unique order,
-however, but they give an idea of how things work.  Taking the @code{F}
-class shown in Figure@ 1, the class precedence list is
-
address@hidden
-(f d e a c b <object> <top>)
address@hidden 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 
address@hidden This function returns a ordered 
-list whose first element is the most specific class. For instance,
-
address@hidden
-(class-precedence-list B) @result{} (#<<class> B 401b97c8> 
-                                     #<<class> <object> 401e4a10> 
-                                     #<<class> <top> 4026a9d8>)
address@hidden lisp
-
-However, this result is not too much readable; using the function
address@hidden yields a clearer result:
-
address@hidden
-(map class-name (class-precedence-list B)) @result{} (B <object> <top>) 
address@hidden lisp
-
address@hidden Generic functions
address@hidden Generic functions
-
-A GOOPS method is like a Scheme procedure except that it is specialized
-for a particular set of argument classes, and will only be used when the
-actual arguments in a call match the classes in the method definition.
-
address@hidden
-(define-method (+ (x <string>) (y <string>))
-  (string-append x y))
-
-(+ "abc" "de") @result{} "abcde"
address@hidden lisp
-
-A method is not formally associated with any single class (as it is in
-many other object oriented languages), because a method can be
-specialized for a combination of several classes.  If you've studied
-object orientation in non-Lispy languages, you may remember discussions
-such as whether a method to stretch a graphical image around a surface
-should be a method of the image class, with a surface as a parameter, or
-a method of the surface class, with an image as a parameter.  In GOOPS
-you'd just write
-
address@hidden
-(define-method (stretch (im <image>) (sf <surface>))
-  ...)
address@hidden lisp
-
address@hidden
-and the question of which class the method is more associated with does
-not need answering.
-
-A generic function is a collection of methods with the same name but
-different sets of specializing argument classes.
-
address@hidden
-* Generic functions and methods::  
-* Next-method::                 
-* Example::                     
address@hidden menu
-
address@hidden Generic functions and methods
address@hidden Generic functions and methods
-
address@hidden \label{gf-n-methods}
-Neither @goops{} nor CLOS use the message mechanism for methods as most
-Object Oriented language do. Instead, they use the notion of
address@hidden functions}.  A generic function can be seen as a methods
-``tanker''. When the evaluator requested the application of a generic
-function, all the methods of this generic function will be grabbed and
-the most specific among them will be applied. We say that a method
address@hidden is @emph{more specific} than a method @var{M'} if the class of
-its parameters are more specific than the @var{M'} ones.  To be more
-precise, when a generic function must be ``called'' the system will:
-
address@hidden generic function
address@hidden
address@hidden
-search among all the generic function those which are applicable
address@hidden
-sort the list of applicable methods in the ``most specific'' order
address@hidden
-call the most specific method of this list (i.e. the first method of 
-the sorted methods list).
address@hidden enumerate
-
-The definition of a generic function is done with the
address@hidden macro. Definition of a new method is done with the
address@hidden macro.  Note that @code{define-method} automatically
-defines the generic function if it has not been defined
-before. Consequently, most of the time, the @code{define-generic} needs
-not be used.
address@hidden define-generic
address@hidden define-method
-Consider the following definitions:
-
address@hidden
-(define-generic G)
-(define-method  (G (a <integer>) b) 'integer)
-(define-method  (G (a <real>) b) 'real)
-(define-method  (G a b) 'top)
address@hidden lisp
-
-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
-
address@hidden parameter specializers
address@hidden
-(define-method (G (a <integer>) (b <top>)) 'integer)
address@hidden lisp
-
-Now, let us look at some possible calls to generic function @var{G}:
-
address@hidden
-(G 2 3)    @result{} integer
-(G 2 #t)   @result{} integer
-(G 1.2 'a) @result{} real
address@hidden (G #3 'a) @result{} real       @c was {\sharpsign}
-(G #t #f)  @result{} top
-(G 1 2 3)  @result{} error (since no method exists for 3 parameters)
address@hidden lisp
-
-The preceding methods use only one specializer per parameter list. Of
-course, each parameter can use a specializer. In this case, the
-parameter list is scanned from left to right to determine the
-applicability of a method. Suppose we declare now
-
address@hidden
-(define-method (G (a <integer>) (b <number>))  'integer-number)
-(define-method (G (a <integer>) (b <real>))    'integer-real)
-(define-method (G (a <integer>) (b <integer>)) 'integer-integer)
-(define-method (G a (b <number>))              'top-number)
address@hidden lisp
-
-In this case,
-
address@hidden
-(G 1 2)   @result{} integer-integer
-(G 1 1.0) @result{} integer-real
-(G 1 #t)  @result{} integer
-(G 'a 1)  @result{} top-number
address@hidden lisp
-
address@hidden Next-method
address@hidden 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}.
-
address@hidden
-(define-method (Test (a <integer>)) (cons 'integer (next-method)))
-(define-method (Test (a <number>))  (cons 'number  (next-method)))
-(define-method (Test a)             (list 'top))
address@hidden lisp
-
-With these definitions,
-
address@hidden
-(Test 1)   @result{} (integer number top)
-(Test 1.0) @result{} (number top)
-(Test #t)  @result{} (top)
address@hidden lisp
-
address@hidden 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:
-
address@hidden
-(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)
address@hidden
-Number is in range
address@hidden
-(integer number top)
address@hidden 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.)
-
address@hidden Example
address@hidden Example
-
-In this section we shall continue to define operations on the 
@code{<my-complex>}
-class defined in Figure@ 2. Suppose that we want to use it to implement 
-complex numbers completely. For instance a definition for the addition of 
-two complexes could be
-
address@hidden
-(define-method (new-+ (a <my-complex>) (b <my-complex>))
-  (make-rectangular (+ (real-part a) (real-part b))
-                    (+ (imag-part a) (imag-part b))))
address@hidden lisp
-
-To be sure that the @code{+} used in the method @code{new-+} is the standard
-addition we can do:
-
address@hidden
-(define-generic new-+)
-
-(let ((+ +))
-  (define-method (new-+ (a <my-complex>) (b <my-complex>))
-    (make-rectangular (+ (real-part a) (real-part b))
-                      (+ (imag-part a) (imag-part b)))))
address@hidden 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.
-
address@hidden
address@hidden
address@hidden
-(define-generic new-+)
-
-(let ((+ +))
-
-  (define-method (new-+ (a <real>) (b <real>)) (+ a b))
-
-  (define-method (new-+ (a <real>) (b <my-complex>)) 
-    (make-rectangular (+ a (real-part b)) (imag-part b)))
-
-  (define-method (new-+ (a <my-complex>) (b <real>))
-    (make-rectangular (+ (real-part a) b) (imag-part a)))
-
-  (define-method (new-+ (a <my-complex>) (b <my-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-+)
address@hidden lisp
-
address@hidden @emph{Fig 3: Extending @code{+} for dealing with complex numbers}
address@hidden group
address@hidden example
-
address@hidden 3
-We use here the fact that generic function are not obliged to have the
-same number of parameters, contrarily to CLOS.  The four first methods
-implement the dyadic addition. The fifth method says that the addition
-of a single element is this element itself. The sixth method says that
-using the addition with no parameter always return 0. The last method
-takes an arbitrary number of address@hidden parameter list for
-a @code{define-method} follows the conventions used for Scheme
-procedures. In particular it can use the dot notation or a symbol to
-denote an arbitrary number of parameters}.  This method acts as a kind
-of @code{reduce}: it calls the dyadic addition on the @emph{car} of the
-list and on the result of applying it on its rest.  To finish, the
address@hidden permits to redefine the @code{+} symbol to our extended
-addition.
-
address@hidden 3
-To terminate our implementation (integration?) of  complex numbers, we can 
-redefine standard Scheme predicates in the following manner:
-
address@hidden
-(define-method (complex? c <my-complex>) #t)
-(define-method (complex? c)           #f)
-
-(define-method (number? n <number>) #t)
-(define-method (number? n)          #f)
address@hidden
address@hidden
address@hidden 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
index a0494db..1160e5c 100644
--- a/doc/ref/goops.texi
+++ b/doc/ref/goops.texi
@@ -28,11 +28,23 @@ protocol --- which means that @goops{}'s core operations 
are themselves
 defined as methods on relevant classes, and can be customised by
 overriding or redefining those methods.
 
+To start using @goops{} you first need to import the @code{(oop goops)}
+module.  You can do this at the Guile REPL by evaluating:
+
address@hidden
+(use-modules (oop goops))
address@hidden lisp
address@hidden (oop goops)
+
 @menu
 * Copyright Notice::
-* Tutorial::
-* Defining New Classes::
-* Creating Instances::
+* Class Definition::
+* Instance Creation::  
+* Slot Options::
+* Slot Description Example::
+* Methods and Generic Functions::           
+* Inheritance::                 
+* Class Options::
 * Accessing Slots::
 * Generic Functions and Accessors::
 * Adding Methods to Generic Functions::
@@ -67,17 +79,30 @@ The material has been adapted for use in Guile, with the 
author's
 permission.
 
 
address@hidden Tutorial
address@hidden Tutorial
address@hidden goops-tutorial.texi
address@hidden Class Definition
address@hidden Class Definition
 
+A new class is defined with the @code{define-class} syntax:
 
address@hidden Defining New Classes
address@hidden Defining New Classes
address@hidden define-class
address@hidden class
address@hidden
+(define-class @var{class} (@var{superclass} @dots{})
+   @var{slot-description} @dots{}
+   @var{class-option} @dots{})
address@hidden lisp
 
-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 class options.
address@hidden is the class being defined.  The list of @var{superclass}es
+specifies which existing classes, if any, to inherit slots and
+properties from.  @dfn{Slots} hold address@hidden --- but
+see also the @code{#:allocation} slot option.} data, for instances of
+that class --- like ``fields'' or ``member variables'' in other object
+oriented systems.  Each @var{slot-description} gives the name of a slot
+and optionally some ``properties'' of this slot; for example its initial
+value, the name of a function which will access its value, and so on.
+Slot descriptions and inheritance are discussed more below.  For class
+options, see @ref{Class Options}.
address@hidden slot
 
 @deffn syntax define-class name (super @dots{}) slot-definition @dots{} . 
options
 Define a class called @var{name} that inherits from @var{super}s, with
@@ -101,59 +126,136 @@ odd-numbered elements are the corresponding values for 
those keywords.
 keywords and corresponding values.
 @end deffn
 
-Example 1.  Define a class that combines two pre-existing classes by
-inheritance but adds no new slots.
+As an example, let us define a type for representing a complex number
+in terms of two real address@hidden course Guile already
+provides complex numbers, and @code{<complex>} is in fact a predefined
+class in GOOPS; but the definition here is still useful as an
+example.}  This can be done with the following class definition:
 
address@hidden
-(define-class <combined> (<tree> <bicycle>))
address@hidden example
address@hidden
+(define-class <my-complex> (<number>)
+   r i)
address@hidden lisp
 
-Example 2.  Define a @code{regular-polygon} class with slots for side
-length and number of sides.  The slots have default values and can be
-accessed via the generic functions @code{side-length} and
address@hidden
+This binds the variable @code{<my-complex>} to a new class whose
+instances will contain two slots.  These slots are called @code{r} and
address@hidden and will hold the real and imaginary parts of a complex
+number. Note that this class inherits from @code{<number>}, which is a
+predefined address@hidden@code{<number>} is the direct superclass of
+the predefined class @code{<complex>}; @code{<complex>} is the
+superclass of @code{<real>}, and @code{<real>} is the superclass of
address@hidden<integer>}.}
 
address@hidden
-(define-class <regular-polygon> ()
-  (sl #:init-value 1 #:accessor side-length)
-  (ns #:init-value 5 #:accessor num-sides))
address@hidden example
+The possible slot and class options are described in the following
+sections.
 
-Example 3.  Define a class whose behavior (and that of its instances) is
-customized via an application-defined metaclass.
 
address@hidden
-(define-class <tcpip-fsm> ()
-  (s #:init-value #f #:accessor state)
-  ...
-  #:metaclass <finite-state-class>)
address@hidden example
address@hidden Instance Creation
address@hidden Instance Creation and Slot Access
 
-The possible slot and class options are described in the following
-subsections.
+An instance (or object) of a defined class can be created with
address@hidden  @code{make} takes one mandatory parameter, which is the
+class of the instance to create, and a list of optional arguments that
+will be used to initialize the slots of the new instance.  For instance
+the following form
+
address@hidden make
address@hidden instance
address@hidden
+(define c (make <my-complex>))
address@hidden lisp
+
address@hidden
+creates a new @code{<my-complex>} object and binds it to the Scheme
+variable @code{c}.
+
address@hidden generic make
address@hidden method make (class <class>) . initargs
+Create and return a new instance of class @var{class}, initialized using
address@hidden
+
+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
address@hidden(next-method)}, and so eventually the standard GOOPS
address@hidden methods are applied.  These methods expect
address@hidden 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.
address@hidden deffn
+
address@hidden generic make-instance
address@hidden method make-instance (class <class>) . initargs
address@hidden is an alias for @code{make}.
address@hidden deffn
+
+The slots of the new complex number can be accessed using
address@hidden and @code{slot-set!}.  @code{slot-set!}  sets the value
+of an object slot and @code{slot-ref} retrieves it.
+
address@hidden slot-set!
address@hidden slot-ref
address@hidden
address@hidden
+(slot-set! c 'r 10)
+(slot-set! c 'i 3)
+(slot-ref c 'r) @result{} 10
+(slot-ref c 'i) @result{} 3
address@hidden group
address@hidden lisp
+
+The @code{(oop goops describe)} module provides a @code{describe}
+function that is useful for seeing all the slots of an object; it prints
+the slots and their values to standard output.
+
address@hidden
+(describe c)
address@hidden
+#<<my-complex> 401d8638> is an instance of class <my-complex>
+Slots are: 
+     r = 10
+     i = 3
address@hidden lisp
 
address@hidden
-* Slot Options::
-* Class Options::
address@hidden menu
 
 @node Slot Options
address@hidden Slot Options
address@hidden Slot Options
+
+When specifying a slot (in a @code{(define-class @dots{})} form),
+various options can be specified in addition to the slot's name.  Each
+option is specified by a keyword.  The list of possible keywords is
+as follows.
 
 @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).
address@hidden 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.
+slot's value at instance creation time.
address@hidden default slot value
+
address@hidden specifies a fixed initial slot value (shared across all
+new instances of the class).
+
address@hidden specifies a thunk that will provide a default value for
+the slot.  The thunk is called when a new instance is created and should
+return the desired initial slot value.
+
address@hidden specifies a form that, when evaluated, will return
+an initial value for the slot.  The form is evaluated each time that
+an instance of the class is created, in the lexical environment of the
+containing @code{define-class} expression.
+
address@hidden specifies 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
@@ -286,10 +388,11 @@ read-only, write-only and read-write slots would 
typically use only
 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,,
+The binding of the specified names is done in the environment of the
address@hidden expression.  If the names are already bound (in that
+environment) to values that cannot be upgraded to generic functions,
+those values are overwritten when the @code{define-class} expression is
+evaluated.  For more detail, see @ref{Generic Function Internals,,
 ensure-generic}.
 @end deffn
 
@@ -300,18 +403,24 @@ the slot.  Possible values for @var{allocation} are
 @itemize @bullet
 @item @code{#:instance}
 
address@hidden #:instance
 Indicates that GOOPS should create separate storage for this slot in
-each new instance of the containing class (and its subclasses).
+each new instance of the containing class (and its subclasses).  This is
+the default.
 
 @item @code{#:class}
 
address@hidden #: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})}.
+This permits defining a kind of global variable which can be accessed
+only by (in)direct instances of the class which defines the slot.
 
 @item @code{#:each-subclass}
 
address@hidden #: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
@@ -322,14 +431,15 @@ instances of the subclass.  In other words, a slot with 
allocation
 
 @item @code{#:virtual}
 
address@hidden #:slot-set!
address@hidden #:slot-ref
address@hidden #: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.
+for this slot.  See the example below.
 @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
@@ -349,123 +459,578 @@ taking two parameters - @var{instance} and 
@var{new-val} - that sets the
 slot value to @var{new-val}.
 @end deffn
 
address@hidden Class Options
address@hidden Class Options
address@hidden Slot Description Example
address@hidden Illustrating Slot Description
 
address@hidden {class option} #:metaclass metaclass
-The @code{#:metaclass} class option specifies the metaclass of the class
-being defined.  @var{metaclass} must be a class that inherits from
address@hidden<class>}.  For the use of metaclasses, see @ref{Metaobjects and
-the Metaobject Protocol} and @ref{Terminology}.
+To illustrate slot description, we can redefine the @code{<my-complex>}
+class seen before. A definition could be:
 
-If the @code{#:metaclass} option is absent, GOOPS reuses or constructs a
-metaclass for the new class by calling @code{ensure-metaclass}
-(@pxref{Class Definition Internals,, ensure-metaclass}).
address@hidden deffn
address@hidden
+(define-class <my-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))
address@hidden lisp
 
address@hidden {class option} #:name name
-The @code{#:name} class option specifies the new class's name.  This
-name is used to identify the class whenever related objects - the class
-itself, its instances and its subclasses - are printed.
address@hidden
+With this definition, the @code{r} and @code{i} slots are set to 0 by
+default, and can be initialised to other values by calling @code{make}
+with the @code{#:r} and @code{#:i} keywords.  Also the generic functions
address@hidden, @code{set-r!}, @code{get-i} and @code{set-i!}  are
+automatically defined to read and write the slots.
 
-If the @code{#:name} option is absent, GOOPS uses the first argument to
address@hidden as the class name.
address@hidden deffn
address@hidden
+(define c1 (make <my-complex> #:r 1 #:i 2))
+(get-r c1) @result{} 1
+(set-r! c1 12)
+(get-r c1) @result{} 12
+(define c2 (make <my-complex> #:r 2))
+(get-r c2) @result{} 2
+(get-i c2) @result{} 0
address@hidden lisp
 
address@hidden Creating Instances
address@hidden Creating Instances
+Accessors can both read and write a slot.  So, another definition of the
address@hidden<my-complex>} class, using the @code{#:accessor} option, could be:
 
-To create a new instance of any GOOPS class, use the generic function
address@hidden 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.
address@hidden set!
address@hidden
+(define-class <my-complex> (<number>) 
+   (r #:init-value 0 #:accessor real-part #:init-keyword #:r)
+   (i #:init-value 0 #:accessor imag-part #:init-keyword #:i))
address@hidden lisp
 
address@hidden generic make
address@hidden method make (class <class>) . initargs
-Create and return a new instance of class @var{class}, initialized using
address@hidden
address@hidden
+With this definition, the @code{r} slot can be read with:
address@hidden
+(real-part c)
address@hidden lisp
address@hidden
+and set with:
address@hidden
+(set! (real-part c) new-value)
address@hidden lisp
 
-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.
+Suppose now that we want to manipulate complex numbers with both
+rectangular and 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 is to use virtual slots, like this:
 
-In practice, specialized @code{initialize} methods would normally call
address@hidden(next-method)}, and so eventually the standard GOOPS
address@hidden methods are applied.  These methods expect
address@hidden 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.
address@hidden
+(define-class <my-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)))))))
 
-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.
address@hidden deffn
address@hidden lisp
 
address@hidden generic make-instance
address@hidden method make-instance (class <class>) . initargs
address@hidden is an alias for @code{make}.
address@hidden deffn
+In this class definition, the magniture @code{m} and angle @code{a}
+slots are virtual, and are calculated, when referenced, from the normal
+(i.e. @code{#:allocation #:instance}) slots @code{r} and @code{i}, by
+calling the function defined in the relevant @code{#:slot-ref} option.
+Correspondingly, writing @code{m} or @code{a} leads to calling the
+function defined in the @code{#:slot-set!} option.  Thus the
+following expression
 
address@hidden Accessing Slots
address@hidden Accessing Slots
address@hidden #:slot-set!
address@hidden #:slot-ref
address@hidden
+(slot-set! c 'a 3)
address@hidden lisp
+
address@hidden
+permits to set the angle of the @code{c} complex number.
+
address@hidden
+(define c (make <my-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)
address@hidden
+#<<my-complex> 401e9b58> is an instance of class <my-complex>
+Slots are: 
+     r = 1
+     i = 10
+     m = 10.0498756211209
+     a = 1.47112767430373
address@hidden lisp
+
+Since initialization keywords have been defined for the four slots, we
+can now define the standard Scheme primitives @code{make-rectangular}
+and @code{make-polar}.
 
-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.
address@hidden
+(define make-rectangular 
+   (lambda (x y) (make <my-complex> #:r x #:i y)))
+
+(define make-polar
+   (lambda (x y) (make <my-complex> #:magn x #:angle y)))
address@hidden lisp
 
-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,
+
address@hidden Methods and Generic Functions
address@hidden Methods and Generic Functions
+
+A GOOPS method is like a Scheme procedure except that it is specialized
+for a particular set of argument classes, and will only be used when the
+actual arguments in a call match the classes in the method definition.
+
address@hidden
+(define-method (+ (x <string>) (y <string>))
+  (string-append x y))
+
+(+ "abc" "de") @result{} "abcde"
address@hidden lisp
+
+A method is not formally associated with any single class (as it is in
+many other object oriented languages), because a method can be
+specialized for a combination of several classes.  If you've studied
+object orientation in non-Lispy languages, you may remember discussions
+such as whether a method to stretch a graphical image around a surface
+should be a method of the image class, with a surface as a parameter, or
+a method of the surface class, with an image as a parameter.  In GOOPS
+you'd just write
+
address@hidden
+(define-method (stretch (im <image>) (sf <surface>))
+  ...)
address@hidden lisp
+
address@hidden
+and the question of which class the method is more associated with does
+not need answering.
+
+A generic function is a collection of methods with the same name but
+different sets of specializing argument classes.
+
address@hidden
+* Generic functions and methods::  
+* Next-method::                 
+* Example::                     
address@hidden menu
+
address@hidden Generic functions and methods
address@hidden Generic functions and methods
+
address@hidden \label{gf-n-methods}
+Neither @goops{} nor CLOS use the message mechanism for methods as most
+Object Oriented language do. Instead, they use the notion of
address@hidden functions}.  A generic function can be seen as a methods
+``tanker''. When the evaluator requested the application of a generic
+function, all the methods of this generic function will be grabbed and
+the most specific among them will be applied. We say that a method
address@hidden is @emph{more specific} than a method @var{M'} if the class of
+its parameters are more specific than the @var{M'} ones.  To be more
+precise, when a generic function must be ``called'' the system will:
+
address@hidden generic function
address@hidden
address@hidden
+search among all the generic function those which are applicable
address@hidden
+sort the list of applicable methods in the ``most specific'' order
address@hidden
+call the most specific method of this list (i.e. the first method of 
+the sorted methods list).
address@hidden enumerate
+
+The definition of a generic function is done with the
address@hidden macro. Definition of a new method is done with the
address@hidden macro.  Note that @code{define-method} automatically
+defines the generic function if it has not been defined
+before. Consequently, most of the time, the @code{define-generic} needs
+not be used.
address@hidden define-generic
address@hidden define-method
+Consider the following definitions:
+
address@hidden
+(define-generic G)
+(define-method  (G (a <integer>) b) 'integer)
+(define-method  (G (a <real>) b) 'real)
+(define-method  (G a b) 'top)
address@hidden lisp
+
+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
+
address@hidden parameter specializers
address@hidden
+(define-method (G (a <integer>) (b <top>)) 'integer)
address@hidden lisp
+
+Now, let us look at some possible calls to generic function @var{G}:
+
address@hidden
+(G 2 3)    @result{} integer
+(G 2 #t)   @result{} integer
+(G 1.2 'a) @result{} real
address@hidden (G #3 'a) @result{} real       @c was {\sharpsign}
+(G #t #f)  @result{} top
+(G 1 2 3)  @result{} error (since no method exists for 3 parameters)
address@hidden lisp
+
+The preceding methods use only one specializer per parameter list. Of
+course, each parameter can use a specializer. In this case, the
+parameter list is scanned from left to right to determine the
+applicability of a method. Suppose we declare now
+
address@hidden
+(define-method (G (a <integer>) (b <number>))  'integer-number)
+(define-method (G (a <integer>) (b <real>))    'integer-real)
+(define-method (G (a <integer>) (b <integer>)) 'integer-integer)
+(define-method (G a (b <number>))              'top-number)
address@hidden lisp
+
+In this case,
+
address@hidden
+(G 1 2)   @result{} integer-integer
+(G 1 1.0) @result{} integer-real
+(G 1 #t)  @result{} integer
+(G 'a 1)  @result{} top-number
address@hidden lisp
+
address@hidden Next-method
address@hidden 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}.
+
address@hidden
+(define-method (Test (a <integer>)) (cons 'integer (next-method)))
+(define-method (Test (a <number>))  (cons 'number  (next-method)))
+(define-method (Test a)             (list 'top))
address@hidden lisp
+
+With these definitions,
+
address@hidden
+(Test 1)   @result{} (integer number top)
+(Test 1.0) @result{} (number top)
+(Test #t)  @result{} (top)
address@hidden lisp
+
address@hidden 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:
+
address@hidden
+(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)
address@hidden
+Number is in range
address@hidden
+(integer number top)
address@hidden 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.)
+
address@hidden Example
address@hidden Example
+
+In this section we shall continue to define operations on the 
@code{<my-complex>}
+class defined in Figure@ 2. Suppose that we want to use it to implement 
+complex numbers completely. For instance a definition for the addition of 
+two complexes could be
+
address@hidden
+(define-method (new-+ (a <my-complex>) (b <my-complex>))
+  (make-rectangular (+ (real-part a) (real-part b))
+                    (+ (imag-part a) (imag-part b))))
address@hidden lisp
+
+To be sure that the @code{+} used in the method @code{new-+} is the standard
+addition we can do:
+
address@hidden
+(define-generic new-+)
+
+(let ((+ +))
+  (define-method (new-+ (a <my-complex>) (b <my-complex>))
+    (make-rectangular (+ (real-part a) (real-part b))
+                      (+ (imag-part a) (imag-part b)))))
address@hidden 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
-(define-class <my-class> ()      ;; Define a class with slots
-  (count #:init-value 0)         ;; named "count" and "cache".
-  (cache #:init-value '())
-  @dots{})
address@hidden
address@hidden
+(define-generic new-+)
+
+(let ((+ +))
+
+  (define-method (new-+ (a <real>) (b <real>)) (+ a b))
+
+  (define-method (new-+ (a <real>) (b <my-complex>)) 
+    (make-rectangular (+ a (real-part b)) (imag-part b)))
+
+  (define-method (new-+ (a <my-complex>) (b <real>))
+    (make-rectangular (+ (real-part a) b) (imag-part a)))
 
-(define inst (make <my-class>))  ;; Make an instance of this class.
+  (define-method (new-+ (a <my-complex>) (b <my-complex>))
+    (make-rectangular (+ (real-part a) (real-part b))
+                      (+ (imag-part a) (imag-part b))))
 
-(slot-set! inst 'count 5)        ;; Set the value of the "count"
-                                 ;; slot to 5.
+  (define-method (new-+ (a <number>))  a)
+  
+  (define-method (new-+) 0)
 
-(slot-set! inst 'cache           ;; Modify the value of the
-  (cons (cons "^it" "It")        ;; "cache" slot.
-        (slot-ref inst 'cache)))
+  (define-method (new-+ . args)
+    (new-+ (car args) 
+      (apply new-+ (cdr args)))))
+
+(set! + new-+)
address@hidden lisp
+
address@hidden @emph{Fig 3: Extending @code{+} for dealing with complex numbers}
address@hidden group
 @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.
address@hidden 3
+We use here the fact that generic function are not obliged to have the
+same number of parameters, contrarily to CLOS.  The four first methods
+implement the dyadic addition. The fifth method says that the addition
+of a single element is this element itself. The sixth method says that
+using the addition with no parameter always return 0. The last method
+takes an arbitrary number of address@hidden parameter list for
+a @code{define-method} follows the conventions used for Scheme
+procedures. In particular it can use the dot notation or a symbol to
+denote an arbitrary number of parameters}.  This method acts as a kind
+of @code{reduce}: it calls the dyadic addition on the @emph{car} of the
+list and on the result of applying it on its rest.  To finish, the
address@hidden permits to redefine the @code{+} symbol to our extended
+addition.
+
address@hidden 3
+To terminate our implementation (integration?) of  complex numbers, we can 
+redefine standard Scheme predicates in the following manner:
+
address@hidden
+(define-method (complex? c <my-complex>) #t)
+(define-method (complex? c)           #f)
+
+(define-method (number? n <number>) #t)
+(define-method (number? n)          #f)
address@hidden
address@hidden
address@hidden lisp
+
+Standard primitives in which complex numbers are involved could also be
+redefined in the same manner.
+
+
address@hidden Inheritance
address@hidden Inheritance
+
+Here are some class definitions to help illustrate inheritance:
+
address@hidden
+(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)
address@hidden lisp
+
address@hidden, @code{B}, @code{C} have a null list of superclasses.  In this
+case, the system will replace the null list by a list which only
+contains @code{<object>}, the root of all the classes defined by
address@hidden  @code{D}, @code{E}, @code{F} use multiple
+inheritance: each class inherits from two previously defined classes.
+Those class definitions define a hierarchy which is shown in Figure@ 1.
+In this figure, the class @code{<top>} is also shown; this class is the
+superclass of all Scheme objects.  In particular, @code{<top>} is the
+superclass of all standard Scheme types.
 
 @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{})
address@hidden
address@hidden
address@hidden @image{hierarchy,5in}
address@hidden iftex
address@hidden
address@hidden hierarchy.txt
address@hidden ifnottex
+
address@hidden 1: A class address@hidden@code{<complex>}, which is the
+direct subclass of @code{<number>} and the direct superclass of
address@hidden<real>}, has been omitted in this figure.}
address@hidden group
address@hidden example
+
+When a class has superclasses, its set of slots is calculated by taking
+the union of its own slots and those of all its superclasses.  Thus each
+instance of D will have three slots, @code{a}, @code{b} and
address@hidden). The slots of a class can be discovered using the
address@hidden primitive.  For instance,
+
address@hidden
+(class-slots A) @result{} ((a))
+(class-slots E) @result{} ((a) (e) (c))
+(class-slots F) @result{} ((e) (c) (b) (d) (a) (f))
address@hidden lisp
+
address@hidden
+The ordering of the returned slots is not significant.
+
address@hidden
+* Class precedence list::       
address@hidden menu
+
+
address@hidden Class precedence list
address@hidden Class precedence list
 
-(define inst (make <adv-class>)) ;; Make an instance of this class.
+A class may have more than one superclass.  @footnote{This section is an
+adaptation of Jeff Dalton's (J.Dalton@@ed.ac.uk) @cite{Brief
+introduction to CLOS}} With single inheritance (one superclass), it is
+easy to order the superclasses from most to least specific. This is the
+rule:
 
-(set-count inst 5)               ;; Set the value of the "count"
-                                 ;; slot to 5.
address@hidden
address@hidden
+Rule 1: Each class is more specific than its address@hidden was \bf
address@hidden cartouche
address@hidden display
 
-(set! (cache inst)               ;; Modify the value of the
-  (cons (cons "^it" "It")        ;; "cache" slot.
-        (cache inst)))
+With multiple inheritance, ordering is harder. Suppose we have
 
-(let ((size (cache-size inst)))  ;; Get the value of the "csize"
-  @dots{})                           ;; slot.
address@hidden
+(define-class X ()
+   (x #:init-value 1))
+
+(define-class Y ()
+   (x #:init-value 2))
+
+(define-class Z (X Y)
+   (@dots{}))
address@hidden lisp
+
+In this case, the @code{Z} class is more specific than the @code{X} or
address@hidden class for instances of @code{Z}. However, the @code{#:init-value}
+specified in @code{X} and @code{Y} leads to a problem: which one
+overrides the other?  The rule in @goops{}, as in CLOS, is that the
+superclasses listed earlier are more specific than those listed later.
+So:
+
address@hidden
address@hidden
+Rule 2: For a given class, superclasses listed earlier are more
+        specific than those listed later.
address@hidden cartouche
address@hidden display
+
+These rules are used to compute a linear order for a class and all its
+superclasses, from most specific to least specific.  This order is
+called the ``class precedence list'' of the class. Given these two
+rules, we can claim that the initial form for the @code{x} slot of
+previous example is 1 since the class @code{X} is placed before @code{Y}
+in class precedence list of @code{Z}.
+
+These two rules are not always enough to determine a unique order,
+however, but they give an idea of how things work.  Taking the @code{F}
+class shown in Figure@ 1, the class precedence list is
+
address@hidden
+(f d e a c b <object> <top>)
 @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}.)
+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 
address@hidden This function returns a ordered 
+list whose first element is the most specific class. For instance,
+
address@hidden
+(class-precedence-list B) @result{} (#<<class> B 401b97c8> 
+                                     #<<class> <object> 401e4a10> 
+                                     #<<class> <top> 4026a9d8>)
address@hidden lisp
+
+However, this result is not too much readable; using the function
address@hidden yields a clearer result:
+
address@hidden
+(map class-name (class-precedence-list B)) @result{} (B <object> <top>) 
address@hidden lisp
+
+
address@hidden Class Options
address@hidden Class Options
+
address@hidden {class option} #:metaclass metaclass
+The @code{#:metaclass} class option specifies the metaclass of the class
+being defined.  @var{metaclass} must be a class that inherits from
address@hidden<class>}.  For the use of metaclasses, see @ref{Metaobjects and
+the Metaobject Protocol} and @ref{Terminology}.
+
+If the @code{#:metaclass} option is absent, GOOPS reuses or constructs a
+metaclass for the new class by calling @code{ensure-metaclass}
+(@pxref{Class Definition Internals,, ensure-metaclass}).
address@hidden deffn
+
address@hidden {class option} #:name name
+The @code{#:name} class option specifies the new class's name.  This
+name is used to identify the class whenever related objects - the class
+itself, its instances and its subclasses - are printed.
+
+If the @code{#:name} option is absent, GOOPS uses the first argument to
address@hidden as the class name.
address@hidden deffn
+
address@hidden Accessing Slots
address@hidden Accessing Slots
 
 @menu
 * Instance Slots::
@@ -908,9 +1473,9 @@ default method calls @code{goops-error} with an 
appropriate message.
 @section Redefining a Class
 
 Suppose that a class @code{<my-class>} is defined using @code{define-class}
-(@pxref{Defining New Classes,, define-class}), with slots that have
+(@pxref{Class Definition,, define-class}), with slots that have
 accessor functions, and that an application has created several instances
-of @code{<my-class>} using @code{make} (@pxref{Creating Instances,,
+of @code{<my-class>} using @code{make} (@pxref{Instance Creation,,
 make}).  What then happens if @code{<my-class>} is redefined by calling
 @code{define-class} again?
 
@@ -928,9 +1493,9 @@ GOOPS' default answer to this question is as follows.
 @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{Creating Instances,,
-make}).
+of slots that exist in both the old and new definitions, and
+initializing the values of new slots in the usual way (@pxref{Instance
+Creation,, make}).
 
 @item
 All existing subclasses of @code{<my-class>} are redefined, as though
@@ -1490,10 +2055,8 @@ GOOPS' power, by customizing the behaviour of GOOPS 
itself.
 * Metaobjects and the Metaobject Protocol::
 * Terminology::
 * MOP Specification::
-* Class Definition::
 * Class Definition Internals::
 * Customizing Class Definition::
-* Instance Creation::
 * Customizing Instance Creation::
 * Class Redefinition::
 * Method Definition::
@@ -1824,8 +2387,8 @@ effects
 what the caller expects to get as the applied method's return value.
 @end itemize
 
address@hidden Class Definition
address@hidden Class Definition
address@hidden Class Definition Internals
address@hidden Class Definition Internals
 
 @code{define-class} (syntax)
 
@@ -1957,9 +2520,6 @@ to the generic function named by the slot definition's 
@code{#:setter}
 or @code{#:accessor} option.
 @end itemize
 
address@hidden Class Definition Internals
address@hidden Class Definition Internals
-
 @code{define-class} expands to an expression which
 
 @itemize @bullet
@@ -1983,7 +2543,7 @@ handles the redefinition by invoking 
@code{class-redefinition}
 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
address@hidden, see @ref{Defining New Classes,, define-class}.
address@hidden, see @ref{Class Definition,, define-class}.
 @end deffn
 
 @noindent @code{class} expands to an expression which
@@ -2004,8 +2564,8 @@ evaluated parameters.
 @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{Defining New
-Classes,, define-class}, except note that for @code{make-class},
+For the format of @var{slots} and @var{options}, see @ref{Class
+Definition,, define-class}, except note that for @code{make-class},
 @var{slots} and @var{options} are separate list parameters: @var{slots}
 here is a list of slot definitions.
 @end deffn
@@ -2206,8 +2766,8 @@ 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.
 
address@hidden Instance Creation
address@hidden Instance Creation
address@hidden Customizing Instance Creation
address@hidden Customizing Instance Creation
 
 @code{make <class> . @var{initargs}} (method)
 
@@ -2227,9 +2787,6 @@ instance in whatever sense is appropriate for its class.  
The method's
 return value is ignored.
 @end itemize
 
address@hidden Customizing Instance Creation
address@hidden 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


hooks/post-receive
-- 
GNU Guile



reply via email to

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