From 04426527154e1f5dba4c0dddee5fc49cdb4264d4 Mon Sep 17 00:00:00 2001 From: Mikael Djurfeldt Date: Sat, 10 Mar 2001 03:08:28 +0000 Subject: [PATCH] * goops.texi (VERSION): Bumped to version 0.3. * goops-tutorial.texi, goops.texi: Updated to reflext new define-method syntax. --- doc/ChangeLog | 7 + doc/goops-tutorial.texi | 809 ---------------------------------------- doc/goops.texi | 46 ++- 3 files changed, 28 insertions(+), 834 deletions(-) diff --git a/doc/ChangeLog b/doc/ChangeLog index c06be02fa..324a86d6c 100644 --- a/doc/ChangeLog +++ b/doc/ChangeLog @@ -1,3 +1,10 @@ +2001-03-09 Mikael Djurfeldt + + * goops.texi (VERSION): Bumped to version 0.3. + + * goops-tutorial.texi, goops.texi: Updated to reflext new + define-method syntax. + 2001-03-09 Neil Jerram * Makefile.am: Change HTML to HTMLDOC, now that we're part of a diff --git a/doc/goops-tutorial.texi b/doc/goops-tutorial.texi index 7897b9f40..e69de29bb 100644 --- a/doc/goops-tutorial.texi +++ b/doc/goops-tutorial.texi @@ -1,809 +0,0 @@ -@c Original attribution: - -@c -@c STk Reference manual (Appendix: An Introduction to STklos) -@c -@c Copyright © 1993-1999 Erick Gallesio - I3S-CNRS/ESSI -@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 -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 () - r i) -@end lisp - -This binds the variable @code{}@footnote{@code{} 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{} which -is a pre-defined class. (@code{} is the direct super class of -the pre-defined class @code{} which, in turn, is the super -class of @code{} which is the super of -@code{}.)@footnote{With the new definition of @code{}, -a @code{} is not a @code{} since @code{} inherits -from @code{ } rather than @code{}. 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{}, 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{} is also shown; this class is the -super class of all Scheme objects. In particular, @code{} is the -super class of all standard Scheme types. - -@example -@group -@image{hierarchy} -@center @emph{Fig 1: A class hierarchy} -@iftex -@emph{(@code{} which is the direct subclass of @code{} -and the direct superclass of @code{} 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 )) -@end lisp - -will create a new @code{} 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 -#< 401d8638> is an instance of class -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{} class -seen before. A definition could be: - -@lisp -(define-class () - (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 #:r 1 #:i 2)) -(get-r c1) @result{} 1 -(set-r! c1 12) -(get-r c1) @result{} 12 -(define c2 (make #: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{} class, using the -@code{#:accessor} option, could be: - -@findex set! -@lisp -(define-class () - (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{} class using virtual slots is -given in Figure@ 2. - -@example -@group -@lisp -(define-class () - ;; 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{} 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 #: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{} - #< 401e9b58> is an instance of class - 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 #:r x #:i y))) - -(define make-polar - (lambda (x y) (make #: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 ) -@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{} (#< B 401b97c8> - #< 401e4a10> - #< 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 ) -@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 ) b) 'integer) -(define-method G ((a ) 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{}. Thus, the first method definition is -equivalent to - -@cindex parameter specializers -@lisp -(define-method G ((a ) (b )) '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 ) (b )) 'integer-number) -(define-method G ((a ) (b )) 'integer-real) -(define-method G ((a ) (b )) 'integer-integer) -(define-method G (a (b )) '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 a generic function is called, the list of applicable methods is -built. As mentioned before, the most specific method of this list is -applied (see@ @ref{Generic functions and methods}). This method may call -the next method in the list of applicable methods. This is done by using -the special form @code{next-method}. Consider the following definitions - -@lisp -(define-method Test ((a )) (cons 'integer (next-method))) -(define-method Test ((a )) (cons 'number (next-method))) -(define-method Test (a) (list 'top)) -@end lisp - -With those definitions, - -@lisp -(Test 1) @result{} (integer number top) -(Test 1.0) @result{} (number top) -(Test #t) @result{} (top) -@end lisp - -@node Example, , Next-method, Generic functions -@subsection Example - -In this section we shall continue to define operations on the @code{} -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 ) (b )) - (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 ) (b )) - (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 ) (b )) (+ a b)) - - (define-method new-+ ((a ) (b )) - (make-rectangular (+ a (real-part b)) (imag-part b))) - - (define-method new-+ ((a ) (b )) - (make-rectangular (+ (real-part a) b) (imag-part a))) - - (define-method new-+ ((a ) (b )) - (make-rectangular (+ (real-part a) (real-part b)) - (+ (imag-part a) (imag-part b)))) - - (define-method new-+ ((a )) 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 third parameter of -a @code{define-method} is a parameter list which follow the conventions -used for lambda expressions. 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 ) #t) -(define-method complex? (c) #f) - -(define-method number? (n ) #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/goops.texi b/doc/goops.texi index 918b4697a..981a7a77d 100644 --- a/doc/goops.texi +++ b/doc/goops.texi @@ -7,7 +7,7 @@ @paragraphindent 0 @c %**end of header -@set VERSION 0.2 +@set VERSION 0.3 @dircategory The Algorithmic Language Scheme @direntry @@ -25,7 +25,7 @@ Guile @ifinfo This file documents GOOPS, an object oriented extension for Guile. -Copyright (C) 1999, 2000 Free Software Foundation +Copyright (C) 1999, 2000, 2001 Free Software Foundation Permission is granted to make and distribute verbatim copies of this manual provided the copyright notice and this permission notice @@ -157,7 +157,7 @@ We're now ready to try some basic GOOPS functionality. @smalllisp @group -(define-method + ((x ) (y )) +(define-method (+ (x ) (y )) (string-append x y)) (+ 1 2) --> 3 @@ -176,7 +176,7 @@ We're now ready to try some basic GOOPS functionality. @group (use-modules (ice-9 format)) -(define-method write ((obj <2D-vector>) port) +(define-method (write (obj <2D-vector>) port) (display (format #f "<~S, ~S>" (x-component obj) (y-component obj)) port)) @@ -186,7 +186,7 @@ v --> <3, 4> @end group @group -(define-method + ((x <2D-vector>) (y <2D-vector>)) +(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)))) @@ -557,7 +557,7 @@ Reference methods for an accessor are defined in the same way as generic function methods. @example -(define-method perimeter ((s )) +(define-method (perimeter (s )) (* 4 (side-length s))) @end example @@ -566,7 +566,7 @@ Setter methods for an accessor are defined by specifying ``(setter call. @example -(define-method (setter perimeter) ((s ) (n )) +(define-method ((setter perimeter) (s ) (n )) (set! (side-length s) (/ n 4))) @end example @@ -864,7 +864,7 @@ specialized method of the generic function @code{initialize}, whose signature is @example -(define-method initialize ((object ) initargs) ...) +(define-method (initialize (object ) initargs) ...) @end example The initialization of instances of any given class can be customized by @@ -1086,7 +1086,7 @@ allocation to do this. (let ((batch-allocation-count 0) (batch-get-n-set #f)) - (define-method compute-get-n-set ((class ) s) + (define-method (compute-get-n-set (class ) s) (case (slot-definition-allocation s) ((#:batched) ;; If we've already used the same slot storage for 10 instances, @@ -1665,21 +1665,17 @@ procedures described in this section may disappear as well. To add a method to a generic function, use the @code{define-method} form. -@deffn syntax define-method symbol (parameter @dots{}) . body -Define a method for the generic function or accessor @var{symbol} with +@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{symbol} must be either a symbol for a variable bound to a generic -function or accessor, or @code{(setter @var{accessor-symbol})}, where -@var{accessor-symbol} is a symbol for a variable bound to an accessor. -If the former, @code{define-method} defines a reference method for the -specified generic function or accessor; if the latter, -@code{define-method} defines a setter method for the specified accessor. -The @var{symbol} parameter is subject to these restrictions (rather than -being allowed to be anything that evaluates to a generic function) so -that @code{define-method} can construct a call to @code{define-generic} -or @code{define-accessor} if @var{symbol} is not already defined as a -generic function. +@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 @@ -1695,7 +1691,7 @@ can be applied. procedure definitions of the form @example -(define name (lambda (formals @dots{}) . body)) +(define (name formals @dots{}) . body) @end example The most important difference is that each formal parameter, apart from the @@ -1997,7 +1993,7 @@ is specialized for this metaclass: @example (define-class ()) -(define-method class-redefinition ((old ) (new )) +(define-method (class-redefinition (old ) (new )) new) @end example @@ -2304,7 +2300,7 @@ Return an expression that prints to show the definition of method @example (define-generic cube) -(define-method cube ((n )) +(define-method (cube (n )) (* n n n)) (map method-source (generic-function-methods cube))