goops-tutorial.texi 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838
  1. @c Original attribution:
  2. @c
  3. @c STk Reference manual (Appendix: An Introduction to STklos)
  4. @c
  5. @c Copyright © 1993-1999 Erick Gallesio - I3S-CNRS/ESSI <eg@unice.fr>
  6. @c Permission to use, copy, modify, distribute,and license this
  7. @c software and its documentation for any purpose is hereby granted,
  8. @c provided that existing copyright notices are retained in all
  9. @c copies and that this notice is included verbatim in any
  10. @c distributions. No written agreement, license, or royalty fee is
  11. @c required for any of the authorized uses.
  12. @c This software is provided ``AS IS'' without express or implied
  13. @c warranty.
  14. @c
  15. @c Adapted for use in Guile with the authors permission
  16. @c @macro goops @c was {\stklos}
  17. @c GOOPS
  18. @c @end macro
  19. @c @macro guile @c was {\stk}
  20. @c Guile
  21. @c @end macro
  22. This is chapter was originally written by Erick Gallesio as an appendix
  23. for the STk reference manual, and subsequently adapted to @goops{}.
  24. @menu
  25. * Copyright::
  26. * Intro::
  27. * Class definition and instantiation::
  28. * Inheritance::
  29. * Generic functions::
  30. @end menu
  31. @node Copyright, Intro, Tutorial, Tutorial
  32. @section Copyright
  33. Original attribution:
  34. STk Reference manual (Appendix: An Introduction to STklos)
  35. Copyright © 1993-1999 Erick Gallesio - I3S-CNRS/ESSI <eg@@unice.fr>
  36. Permission to use, copy, modify, distribute,and license this
  37. software and its documentation for any purpose is hereby granted,
  38. provided that existing copyright notices are retained in all
  39. copies and that this notice is included verbatim in any
  40. distributions. No written agreement, license, or royalty fee is
  41. required for any of the authorized uses.
  42. This software is provided ``AS IS'' without express or implied
  43. warranty.
  44. Adapted for use in Guile with the authors permission
  45. @node Intro, Class definition and instantiation, Copyright, Tutorial
  46. @section Introduction
  47. @goops{} is the object oriented extension to @guile{}. Its
  48. implementation is derived from @w{STk-3.99.3} by Erick Gallesio and
  49. version 1.3 of the Gregor Kiczales @cite{Tiny-Clos}. It is very close
  50. to CLOS, the Common Lisp Object System (@cite{CLtL2}) but is adapted for
  51. the Scheme language.
  52. Briefly stated, the @goops{} extension gives the user a full object
  53. oriented system with multiple inheritance and generic functions with
  54. multi-method dispatch. Furthermore, the implementation relies on a true
  55. meta object protocol, in the spirit of the one defined for CLOS
  56. (@cite{Gregor Kiczales: A Metaobject Protocol}).
  57. The purpose of this tutorial is to introduce briefly the @goops{}
  58. package and in no case will it replace the @goops{} reference manual
  59. (which needs to be urgently written now@ @dots{}).
  60. Note that the operations described in this tutorial resides in modules
  61. that may need to be imported before being available. The main module is
  62. imported by evaluating:
  63. @lisp
  64. (use-modules (oop goops))
  65. @end lisp
  66. @findex (oop goops)
  67. @cindex main module
  68. @cindex loading
  69. @cindex preparing
  70. @node Class definition and instantiation, Inheritance, Intro, Tutorial
  71. @section Class definition and instantiation
  72. @menu
  73. * Class definition::
  74. @end menu
  75. @node Class definition, , Class definition and instantiation, Class definition and instantiation
  76. @subsection Class definition
  77. A new class is defined with the @code{define-class}@footnote{Don't
  78. forget to import the @code{(oop goops)} module} macro. The syntax of
  79. @code{define-class} is close to CLOS @code{defclass}:
  80. @findex define-class
  81. @cindex class
  82. @lisp
  83. (define-class @var{class} (@var{superclass} @dots{})
  84. @var{slot-description} @dots{}
  85. @var{class-option} @dots{})
  86. @end lisp
  87. Class options will not be discussed in this tutorial. The list of
  88. @var{superclass}es specifies which classes to inherit properties from
  89. @var{class} (see @ref{Inheritance} for more details). A
  90. @var{slot-description} gives the name of a slot and, eventually, some
  91. ``properties'' of this slot (such as its initial value, the function
  92. which permit to access its value, @dots{}). Slot descriptions will be
  93. discussed in @ref{Slot description}.
  94. @cindex slot
  95. As an example, let us define a type for representation of complex
  96. numbers in terms of real numbers. This can be done with the following
  97. class definition:
  98. @lisp
  99. (define-class <complex> (<number>)
  100. r i)
  101. @end lisp
  102. This binds the variable @code{<complex>}@footnote{@code{<complex>} is in
  103. fact a builtin class in GOOPS. Because of this, GOOPS will create a new
  104. class. The old class will still serve as the type for Guile's native
  105. complex numbers.} to a new class whose instances contain two
  106. slots. These slots are called @code{r} an @code{i} and we suppose here
  107. that they contain respectively the real part and the imaginary part of a
  108. complex number. Note that this class inherits from @code{<number>} which
  109. is a pre-defined class. (@code{<number>} is the direct super class of
  110. the pre-defined class @code{<complex>} which, in turn, is the super
  111. class of @code{<real>} which is the super of
  112. @code{<integer>}.)@footnote{With the new definition of @code{<complex>},
  113. a @code{<real>} is not a @code{<complex>} since @code{<real>} inherits
  114. from @code{ <number>} rather than @code{<complex>}. In practice,
  115. inheritance could be modified @emph{a posteriori}, if needed. However,
  116. this necessitates some knowledge of the meta object protocol and it will
  117. not be shown in this document}.
  118. @node Inheritance, Generic functions, Class definition and instantiation, Tutorial
  119. @section Inheritance
  120. @c \label{inheritance}
  121. @menu
  122. * Class hierarchy and inheritance of slots::
  123. * Instance creation and slot access::
  124. * Slot description::
  125. * Class precedence list::
  126. @end menu
  127. @node Class hierarchy and inheritance of slots, Instance creation and slot access, Inheritance, Inheritance
  128. @subsection Class hierarchy and inheritance of slots
  129. Inheritance is specified upon class definition. As said in the
  130. introduction, @goops{} supports multiple inheritance. Here are some
  131. class definitions:
  132. @lisp
  133. (define-class A () a)
  134. (define-class B () b)
  135. (define-class C () c)
  136. (define-class D (A B) d a)
  137. (define-class E (A C) e c)
  138. (define-class F (D E) f)
  139. @end lisp
  140. @code{A}, @code{B}, @code{C} have a null list of super classes. In this
  141. case, the system will replace it by the list which only contains
  142. @code{<object>}, the root of all the classes defined by
  143. @code{define-class}. @code{D}, @code{E}, @code{F} use multiple
  144. inheritance: each class inherits from two previously defined classes.
  145. Those class definitions define a hierarchy which is shown in Figure@ 1.
  146. In this figure, the class @code{<top>} is also shown; this class is the
  147. super class of all Scheme objects. In particular, @code{<top>} is the
  148. super class of all standard Scheme types.
  149. @example
  150. @group
  151. @image{hierarchy}
  152. @center @emph{Fig 1: A class hierarchy}
  153. @iftex
  154. @emph{(@code{<complex>} which is the direct subclass of @code{<number>}
  155. and the direct superclass of @code{<real>} has been omitted in this
  156. figure.)}
  157. @end iftex
  158. @end group
  159. @end example
  160. The set of slots of a given class is calculated by taking the union of the
  161. slots of all its super class. For instance, each instance of the class
  162. D, defined before will have three slots (@code{a}, @code{b} and
  163. @code{d}). The slots of a class can be obtained by the @code{class-slots}
  164. primitive. For instance,
  165. @lisp
  166. (class-slots A) @result{} ((a))
  167. (class-slots E) @result{} ((a) (e) (c))
  168. (class-slots F) @result{} ((e) (c) (b) (d) (a) (f))
  169. @c used to be ((d) (a) (b) (c) (f))
  170. @end lisp
  171. @emph{Note: } The order of slots is not significant.
  172. @node Instance creation and slot access, Slot description, Class hierarchy and inheritance of slots, Inheritance
  173. @subsection Instance creation and slot access
  174. Creation of an instance of a previously defined
  175. class can be done with the @code{make} procedure. This
  176. procedure takes one mandatory parameter which is the class of the
  177. instance which must be created and a list of optional
  178. arguments. Optional arguments are generally used to initialize some
  179. slots of the newly created instance. For instance, the following form
  180. @findex make
  181. @cindex instance
  182. @lisp
  183. (define c (make <complex>))
  184. @end lisp
  185. will create a new @code{<complex>} object and will bind it to the @code{c}
  186. Scheme variable.
  187. Accessing the slots of the new complex number can be done with the
  188. @code{slot-ref} and the @code{slot-set!} primitives. @code{Slot-set!}
  189. primitive permits to set the value of an object slot and @code{slot-ref}
  190. permits to get its value.
  191. @findex slot-set!
  192. @findex slot-ref
  193. @lisp
  194. @group
  195. (slot-set! c 'r 10)
  196. (slot-set! c 'i 3)
  197. (slot-ref c 'r) @result{} 10
  198. (slot-ref c 'i) @result{} 3
  199. @end group
  200. @end lisp
  201. Using the @code{describe} function is a simple way to see all the
  202. slots of an object at one time: this function prints all the slots of an
  203. object on the standard output.
  204. First load the module @code{(oop goops describe)}:
  205. @example
  206. @code{(use-modules (oop goops describe))}
  207. @end example
  208. The expression
  209. @smalllisp
  210. (describe c)
  211. @end smalllisp
  212. will now print the following information on the standard output:
  213. @lisp
  214. #<<complex> 401d8638> is an instance of class <complex>
  215. Slots are:
  216. r = 10
  217. i = 3
  218. @end lisp
  219. @node Slot description, Class precedence list, Instance creation and slot access, Inheritance
  220. @subsection Slot description
  221. @c \label{slot-description}
  222. When specifying a slot, a set of options can be given to the
  223. system. Each option is specified with a keyword. The list of authorized
  224. keywords is given below:
  225. @cindex keyword
  226. @itemize @bullet
  227. @item
  228. @code{#:init-value} permits to supply a default value for the slot. This
  229. default value is obtained by evaluating the form given after the
  230. @code{#:init-form} in the global environment, at class definition time.
  231. @cindex default slot value
  232. @findex #:init-value
  233. @cindex top level environment
  234. @item
  235. @code{#:init-thunk} permits to supply a thunk that will provide a
  236. default value for the slot. The value is obtained by evaluating the
  237. thunk a instance creation time.
  238. @c CHECKME: in the global environment?
  239. @findex default slot value
  240. @findex #:init-thunk
  241. @cindex top level environment
  242. @item
  243. @code{#:init-keyword} permits to specify the keyword for initializing a
  244. slot. The init-keyword may be provided during instance creation (i.e. in
  245. the @code{make} optional parameter list). Specifying such a keyword
  246. during instance initialization will supersede the default slot
  247. initialization possibly given with @code{#:init-form}.
  248. @findex #:init-keyword
  249. @item
  250. @code{#:getter} permits to supply the name for the
  251. slot getter. The name binding is done in the
  252. environment of the @code{define-class} macro.
  253. @findex #:getter
  254. @cindex top level environment
  255. @cindex getter
  256. @item
  257. @code{#:setter} permits to supply the name for the
  258. slot setter. The name binding is done in the
  259. environment of the @code{define-class} macro.
  260. @findex #:setter
  261. @cindex top level environment
  262. @cindex setter
  263. @item
  264. @code{#:accessor} permits to supply the name for the
  265. slot accessor. The name binding is done in the global
  266. environment. An accessor permits to get and
  267. set the value of a slot. Setting the value of a slot is done with the extended
  268. version of @code{set!}.
  269. @findex set!
  270. @findex #:accessor
  271. @cindex top level environment
  272. @cindex accessor
  273. @item
  274. @code{#:allocation} permits to specify how storage for
  275. the slot is allocated. Three kinds of allocation are provided.
  276. They are described below:
  277. @itemize @minus
  278. @item
  279. @code{#:instance} indicates that each instance gets its own storage for
  280. the slot. This is the default.
  281. @item
  282. @code{#:class} indicates that there is one storage location used by all
  283. the direct and indirect instances of the class. This permits to define a
  284. kind of global variable which can be accessed only by (in)direct
  285. instances of the class which defines this slot.
  286. @item
  287. @code{#:each-subclass} indicates that there is one storage location used
  288. by all the direct instances of the class. In other words, if two classes
  289. are not siblings in the class hierarchy, they will not see the same
  290. value.
  291. @item
  292. @code{#:virtual} indicates that no storage will be allocated for this
  293. slot. It is up to the user to define a getter and a setter function for
  294. this slot. Those functions must be defined with the @code{#:slot-ref}
  295. and @code{#:slot-set!} options. See the example below.
  296. @findex #:slot-set!
  297. @findex #:slot-ref
  298. @findex #:virtual
  299. @findex #:class
  300. @findex #:each-subclass
  301. @findex #:instance
  302. @findex #:allocation
  303. @end itemize
  304. @end itemize
  305. To illustrate slot description, we shall redefine the @code{<complex>} class
  306. seen before. A definition could be:
  307. @lisp
  308. (define-class <complex> (<number>)
  309. (r #:init-value 0 #:getter get-r #:setter set-r! #:init-keyword #:r)
  310. (i #:init-value 0 #:getter get-i #:setter set-i! #:init-keyword #:i))
  311. @end lisp
  312. With this definition, the @code{r} and @code{i} slot are set to 0 by
  313. default. Value of a slot can also be specified by calling @code{make}
  314. with the @code{#:r} and @code{#:i} keywords. Furthermore, the generic
  315. functions @code{get-r} and @code{set-r!} (resp. @code{get-i} and
  316. @code{set-i!}) are automatically defined by the system to read and write
  317. the @code{r} (resp. @code{i}) slot.
  318. @lisp
  319. (define c1 (make <complex> #:r 1 #:i 2))
  320. (get-r c1) @result{} 1
  321. (set-r! c1 12)
  322. (get-r c1) @result{} 12
  323. (define c2 (make <complex> #:r 2))
  324. (get-r c2) @result{} 2
  325. (get-i c2) @result{} 0
  326. @end lisp
  327. Accessors provide an uniform access for reading and writing an object
  328. slot. Writing a slot is done with an extended form of @code{set!}
  329. which is close to the Common Lisp @code{setf} macro. So, another
  330. definition of the previous @code{<complex>} class, using the
  331. @code{#:accessor} option, could be:
  332. @findex set!
  333. @lisp
  334. (define-class <complex> (<number>)
  335. (r #:init-value 0 #:accessor real-part #:init-keyword #:r)
  336. (i #:init-value 0 #:accessor imag-part #:init-keyword #:i))
  337. @end lisp
  338. Using this class definition, reading the real part of the @code{c}
  339. complex can be done with:
  340. @lisp
  341. (real-part c)
  342. @end lisp
  343. and setting it to the value contained in the @code{new-value} variable
  344. can be done using the extended form of @code{set!}.
  345. @lisp
  346. (set! (real-part c) new-value)
  347. @end lisp
  348. Suppose now that we have to manipulate complex numbers with rectangular
  349. coordinates as well as with polar coordinates. One solution could be to
  350. have a definition of complex numbers which uses one particular
  351. representation and some conversion functions to pass from one
  352. representation to the other. A better solution uses virtual slots. A
  353. complete definition of the @code{<complex>} class using virtual slots is
  354. given in Figure@ 2.
  355. @example
  356. @group
  357. @lisp
  358. (define-class <complex> (<number>)
  359. ;; True slots use rectangular coordinates
  360. (r #:init-value 0 #:accessor real-part #:init-keyword #:r)
  361. (i #:init-value 0 #:accessor imag-part #:init-keyword #:i)
  362. ;; Virtual slots access do the conversion
  363. (m #:accessor magnitude #:init-keyword #:magn
  364. #:allocation #:virtual
  365. #:slot-ref (lambda (o)
  366. (let ((r (slot-ref o 'r)) (i (slot-ref o 'i)))
  367. (sqrt (+ (* r r) (* i i)))))
  368. #:slot-set! (lambda (o m)
  369. (let ((a (slot-ref o 'a)))
  370. (slot-set! o 'r (* m (cos a)))
  371. (slot-set! o 'i (* m (sin a))))))
  372. (a #:accessor angle #:init-keyword #:angle
  373. #:allocation #:virtual
  374. #:slot-ref (lambda (o)
  375. (atan (slot-ref o 'i) (slot-ref o 'r)))
  376. #:slot-set! (lambda(o a)
  377. (let ((m (slot-ref o 'm)))
  378. (slot-set! o 'r (* m (cos a)))
  379. (slot-set! o 'i (* m (sin a)))))))
  380. @end lisp
  381. @center @emph{Fig 2: A @code{<complex>} number class definition using virtual slots}
  382. @end group
  383. @end example
  384. @sp 3
  385. This class definition implements two real slots (@code{r} and
  386. @code{i}). Values of the @code{m} and @code{a} virtual slots are
  387. calculated from real slot values. Reading a virtual slot leads to the
  388. application of the function defined in the @code{#:slot-ref}
  389. option. Writing such a slot leads to the application of the function
  390. defined in the @code{#:slot-set!} option. For instance, the following
  391. expression
  392. @findex #:slot-set!
  393. @findex #:slot-ref
  394. @lisp
  395. (slot-set! c 'a 3)
  396. @end lisp
  397. permits to set the angle of the @code{c} complex number. This expression
  398. conducts, in fact, to the evaluation of the following expression
  399. @lisp
  400. ((lambda o m)
  401. (let ((m (slot-ref o 'm)))
  402. (slot-set! o 'r (* m (cos a)))
  403. (slot-set! o 'i (* m (sin a))))
  404. c 3)
  405. @end lisp
  406. A more complete example is given below:
  407. @example
  408. @group
  409. @lisp
  410. (define c (make <complex> #:r 12 #:i 20))
  411. (real-part c) @result{} 12
  412. (angle c) @result{} 1.03037682652431
  413. (slot-set! c 'i 10)
  414. (set! (real-part c) 1)
  415. (describe c) @result{}
  416. #<<complex> 401e9b58> is an instance of class <complex>
  417. Slots are:
  418. r = 1
  419. i = 10
  420. m = 10.0498756211209
  421. a = 1.47112767430373
  422. @end lisp
  423. @end group
  424. @end example
  425. Since initialization keywords have been defined for the four slots, we
  426. can now define the @code{make-rectangular} and @code{make-polar} standard
  427. Scheme primitives.
  428. @lisp
  429. (define make-rectangular
  430. (lambda (x y) (make <complex> #:r x #:i y)))
  431. (define make-polar
  432. (lambda (x y) (make <complex> #:magn x #:angle y)))
  433. @end lisp
  434. @node Class precedence list, , Slot description, Inheritance
  435. @subsection Class precedence list
  436. A class may have more than one superclass. @footnote{This section is an
  437. adaptation of Jeff Dalton's (J.Dalton@@ed.ac.uk) @cite{Brief
  438. introduction to CLOS}} With single inheritance (one superclass), it is
  439. easy to order the super classes from most to least specific. This is the
  440. rule:
  441. @display
  442. @cartouche
  443. Rule 1: Each class is more specific than its superclasses.@c was \bf
  444. @end cartouche
  445. @end display
  446. With multiple inheritance, ordering is harder. Suppose we have
  447. @lisp
  448. (define-class X ()
  449. (x #:init-value 1))
  450. (define-class Y ()
  451. (x #:init-value 2))
  452. (define-class Z (X Y)
  453. (@dots{}))
  454. @end lisp
  455. In this case, the @code{Z} class is more specific than the @code{X} or
  456. @code{Y} class for instances of @code{Z}. However, the @code{#:init-value}
  457. specified in @code{X} and @code{Y} leads to a problem: which one
  458. overrides the other? The rule in @goops{}, as in CLOS, is that the
  459. superclasses listed earlier are more specific than those listed later.
  460. So:
  461. @display
  462. @cartouche
  463. Rule 2: For a given class, superclasses listed earlier are more
  464. specific than those listed later.
  465. @end cartouche
  466. @end display
  467. These rules are used to compute a linear order for a class and all its
  468. superclasses, from most specific to least specific. This order is
  469. called the ``class precedence list'' of the class. Given these two
  470. rules, we can claim that the initial form for the @code{x} slot of
  471. previous example is 1 since the class @code{X} is placed before @code{Y}
  472. in class precedence list of @code{Z}.
  473. These two rules are not always enough to determine a unique order,
  474. however, but they give an idea of how things work. Taking the @code{F}
  475. class shown in Figure@ 1, the class precedence list is
  476. @example
  477. (f d e a c b <object> <top>)
  478. @end example
  479. However, it is usually considered a bad idea for programmers to rely on
  480. exactly what the order is. If the order for some superclasses is important,
  481. it can be expressed directly in the class definition.
  482. The precedence list of a class can be obtained by the function
  483. @code{class-precedence-list}. This function returns a ordered
  484. list whose first element is the most specific class. For instance,
  485. @lisp
  486. (class-precedence-list B) @result{} (#<<class> B 401b97c8>
  487. #<<class> <object> 401e4a10>
  488. #<<class> <top> 4026a9d8>)
  489. @end lisp
  490. However, this result is not too much readable; using the function
  491. @code{class-name} yields a clearer result:
  492. @lisp
  493. (map class-name (class-precedence-list B)) @result{} (B <object> <top>)
  494. @end lisp
  495. @node Generic functions, , Inheritance, Tutorial
  496. @section Generic functions
  497. @menu
  498. * Generic functions and methods::
  499. * Next-method::
  500. * Example::
  501. @end menu
  502. @node Generic functions and methods, Next-method, Generic functions, Generic functions
  503. @subsection Generic functions and methods
  504. @c \label{gf-n-methods}
  505. Neither @goops{} nor CLOS use the message mechanism for methods as most
  506. Object Oriented language do. Instead, they use the notion of
  507. @dfn{generic functions}. A generic function can be seen as a methods
  508. ``tanker''. When the evaluator requested the application of a generic
  509. function, all the methods of this generic function will be grabbed and
  510. the most specific among them will be applied. We say that a method
  511. @var{M} is @emph{more specific} than a method @var{M'} if the class of
  512. its parameters are more specific than the @var{M'} ones. To be more
  513. precise, when a generic function must be ``called'' the system will:
  514. @cindex generic function
  515. @enumerate
  516. @item
  517. search among all the generic function those which are applicable
  518. @item
  519. sort the list of applicable methods in the ``most specific'' order
  520. @item
  521. call the most specific method of this list (i.e. the first method of
  522. the sorted methods list).
  523. @end enumerate
  524. The definition of a generic function is done with the
  525. @code{define-generic} macro. Definition of a new method is done with the
  526. @code{define-method} macro. Note that @code{define-method} automatically
  527. defines the generic function if it has not been defined
  528. before. Consequently, most of the time, the @code{define-generic} needs
  529. not be used.
  530. @findex define-generic
  531. @findex define-method
  532. Consider the following definitions:
  533. @lisp
  534. (define-generic G)
  535. (define-method (G (a <integer>) b) 'integer)
  536. (define-method (G (a <real>) b) 'real)
  537. (define-method (G a b) 'top)
  538. @end lisp
  539. The @code{define-generic} call defines @var{G} as a generic
  540. function. Note that the signature of the generic function is not given
  541. upon definition, contrarily to CLOS. This will permit methods with
  542. different signatures for a given generic function, as we shall see
  543. later. The three next lines define methods for the @var{G} generic
  544. function. Each method uses a sequence of @dfn{parameter specializers}
  545. that specify when the given method is applicable. A specializer permits
  546. to indicate the class a parameter must belong to (directly or
  547. indirectly) to be applicable. If no specializer is given, the system
  548. defaults it to @code{<top>}. Thus, the first method definition is
  549. equivalent to
  550. @cindex parameter specializers
  551. @lisp
  552. (define-method (G (a <integer>) (b <top>)) 'integer)
  553. @end lisp
  554. Now, let us look at some possible calls to generic function @var{G}:
  555. @lisp
  556. (G 2 3) @result{} integer
  557. (G 2 #t) @result{} integer
  558. (G 1.2 'a) @result{} real
  559. @c (G #3 'a) @result{} real @c was {\sharpsign}
  560. (G #t #f) @result{} top
  561. (G 1 2 3) @result{} error (since no method exists for 3 parameters)
  562. @end lisp
  563. The preceding methods use only one specializer per parameter list. Of
  564. course, each parameter can use a specializer. In this case, the
  565. parameter list is scanned from left to right to determine the
  566. applicability of a method. Suppose we declare now
  567. @lisp
  568. (define-method (G (a <integer>) (b <number>)) 'integer-number)
  569. (define-method (G (a <integer>) (b <real>)) 'integer-real)
  570. (define-method (G (a <integer>) (b <integer>)) 'integer-integer)
  571. (define-method (G a (b <number>)) 'top-number)
  572. @end lisp
  573. In this case,
  574. @lisp
  575. (G 1 2) @result{} integer-integer
  576. (G 1 1.0) @result{} integer-real
  577. (G 1 #t) @result{} integer
  578. (G 'a 1) @result{} top-number
  579. @end lisp
  580. @node Next-method, Example, Generic functions and methods, Generic functions
  581. @subsection Next-method
  582. When you call a generic function, with a particular set of arguments,
  583. GOOPS builds a list of all the methods that are applicable to those
  584. arguments and orders them by how closely the method definitions match
  585. the actual argument types. It then calls the method at the top of this
  586. list. If the selected method's code wants to call on to the next method
  587. in this list, it can do so by using @code{next-method}.
  588. @lisp
  589. (define-method (Test (a <integer>)) (cons 'integer (next-method)))
  590. (define-method (Test (a <number>)) (cons 'number (next-method)))
  591. (define-method (Test a) (list 'top))
  592. @end lisp
  593. With these definitions,
  594. @lisp
  595. (Test 1) @result{} (integer number top)
  596. (Test 1.0) @result{} (number top)
  597. (Test #t) @result{} (top)
  598. @end lisp
  599. @code{next-method} is always called as just @code{(next-method)}. The
  600. arguments for the next method call are always implicit, and always the
  601. same as for the original method call.
  602. If you want to call on to a method with the same name but with a
  603. different set of arguments (as you might with overloaded methods in C++,
  604. for example), you do not use @code{next-method}, but instead simply
  605. write the new call as usual:
  606. @lisp
  607. (define-method (Test (a <number>) min max)
  608. (if (and (>= a min) (<= a max))
  609. (display "Number is in range\n"))
  610. (Test a))
  611. (Test 2 1 10)
  612. @print{}
  613. Number is in range
  614. @result{}
  615. (integer number top)
  616. @end lisp
  617. (You should be careful in this case that the @code{Test} calls do not
  618. lead to an infinite recursion, but this consideration is just the same
  619. as in Scheme code in general.)
  620. @node Example, , Next-method, Generic functions
  621. @subsection Example
  622. In this section we shall continue to define operations on the @code{<complex>}
  623. class defined in Figure@ 2. Suppose that we want to use it to implement
  624. complex numbers completely. For instance a definition for the addition of
  625. two complexes could be
  626. @lisp
  627. (define-method (new-+ (a <complex>) (b <complex>))
  628. (make-rectangular (+ (real-part a) (real-part b))
  629. (+ (imag-part a) (imag-part b))))
  630. @end lisp
  631. To be sure that the @code{+} used in the method @code{new-+} is the standard
  632. addition we can do:
  633. @lisp
  634. (define-generic new-+)
  635. (let ((+ +))
  636. (define-method (new-+ (a <complex>) (b <complex>))
  637. (make-rectangular (+ (real-part a) (real-part b))
  638. (+ (imag-part a) (imag-part b)))))
  639. @end lisp
  640. The @code{define-generic} ensures here that @code{new-+} will be defined
  641. in the global environment. Once this is done, we can add methods to the
  642. generic function @code{new-+} which make a closure on the @code{+}
  643. symbol. A complete writing of the @code{new-+} methods is shown in
  644. Figure@ 3.
  645. @example
  646. @group
  647. @lisp
  648. (define-generic new-+)
  649. (let ((+ +))
  650. (define-method (new-+ (a <real>) (b <real>)) (+ a b))
  651. (define-method (new-+ (a <real>) (b <complex>))
  652. (make-rectangular (+ a (real-part b)) (imag-part b)))
  653. (define-method (new-+ (a <complex>) (b <real>))
  654. (make-rectangular (+ (real-part a) b) (imag-part a)))
  655. (define-method (new-+ (a <complex>) (b <complex>))
  656. (make-rectangular (+ (real-part a) (real-part b))
  657. (+ (imag-part a) (imag-part b))))
  658. (define-method (new-+ (a <number>)) a)
  659. (define-method (new-+) 0)
  660. (define-method (new-+ . args)
  661. (new-+ (car args)
  662. (apply new-+ (cdr args)))))
  663. (set! + new-+)
  664. @end lisp
  665. @center @emph{Fig 3: Extending @code{+} for dealing with complex numbers}
  666. @end group
  667. @end example
  668. @sp 3
  669. We use here the fact that generic function are not obliged to have the
  670. same number of parameters, contrarily to CLOS. The four first methods
  671. implement the dyadic addition. The fifth method says that the addition
  672. of a single element is this element itself. The sixth method says that
  673. using the addition with no parameter always return 0. The last method
  674. takes an arbitrary number of parameters@footnote{The parameter list for
  675. a @code{define-method} follows the conventions used for Scheme
  676. procedures. In particular it can use the dot notation or a symbol to
  677. denote an arbitrary number of parameters}. This method acts as a kind
  678. of @code{reduce}: it calls the dyadic addition on the @emph{car} of the
  679. list and on the result of applying it on its rest. To finish, the
  680. @code{set!} permits to redefine the @code{+} symbol to our extended
  681. addition.
  682. @sp 3
  683. To terminate our implementation (integration?) of complex numbers, we can
  684. redefine standard Scheme predicates in the following manner:
  685. @lisp
  686. (define-method (complex? c <complex>) #t)
  687. (define-method (complex? c) #f)
  688. (define-method (number? n <number>) #t)
  689. (define-method (number? n) #f)
  690. @dots{}
  691. @dots{}
  692. @end lisp
  693. Standard primitives in which complex numbers are involved could also be
  694. redefined in the same manner.