Commit | Line | Data |
---|---|---|
d99832a2 NJ |
1 | @c -*-texinfo-*- |
2 | @c This is part of the GNU Guile Reference Manual. | |
3 | @c Copyright (C) 2008, 2009 | |
4 | @c Free Software Foundation, Inc. | |
5 | @c See the file guile.texi for copying conditions. | |
6 | ||
a0e07ba4 NJ |
7 | @macro goops |
8 | GOOPS | |
9 | @end macro | |
10 | ||
11 | @macro guile | |
12 | Guile | |
13 | @end macro | |
14 | ||
eb12b401 NJ |
15 | @node GOOPS |
16 | @chapter GOOPS | |
a0e07ba4 | 17 | |
a0e07ba4 NJ |
18 | @goops{} is the object oriented extension to @guile{}. Its |
19 | implementation is derived from @w{STk-3.99.3} by Erick Gallesio and | |
56664c08 | 20 | version 1.3 of Gregor Kiczales' @cite{Tiny-Clos}. It is very close in |
b997e7f5 NJ |
21 | spirit to CLOS, the Common Lisp Object System, but is adapted for the |
22 | Scheme language. | |
23 | ||
24 | @goops{} is a full object oriented system, with classes, objects, | |
25 | multiple inheritance, and generic functions with multi-method | |
26 | dispatch. Furthermore its implementation relies on a meta object | |
27 | protocol --- which means that @goops{}'s core operations are themselves | |
28 | defined as methods on relevant classes, and can be customised by | |
29 | overriding or redefining those methods. | |
a0e07ba4 | 30 | |
f60a8353 NJ |
31 | To start using @goops{} you first need to import the @code{(oop goops)} |
32 | module. You can do this at the Guile REPL by evaluating: | |
33 | ||
34 | @lisp | |
35 | (use-modules (oop goops)) | |
36 | @end lisp | |
37 | @findex (oop goops) | |
38 | ||
769be03f | 39 | @menu |
b65ff721 | 40 | * Copyright Notice:: |
f60a8353 NJ |
41 | * Class Definition:: |
42 | * Instance Creation:: | |
43 | * Slot Options:: | |
44 | * Slot Description Example:: | |
45 | * Methods and Generic Functions:: | |
46 | * Inheritance:: | |
62d7cba3 | 47 | * Introspection:: |
f60a8353 | 48 | * Class Options:: |
c34d74ff | 49 | * Accessing Slots:: |
17285a7c | 50 | * Generic Functions and Accessors:: |
c34d74ff NJ |
51 | * Redefining a Class:: |
52 | * Changing the Class of an Instance:: | |
1905db2b NJ |
53 | * GOOPS Error Handling:: |
54 | * Object Comparisons:: | |
55 | * Cloning Objects:: | |
56 | * Write and Display:: | |
a9bf12c2 | 57 | * The Metaobject Protocol:: |
769be03f NJ |
58 | @end menu |
59 | ||
b65ff721 NJ |
60 | @node Copyright Notice |
61 | @section Copyright Notice | |
62 | ||
63 | The material in this chapter is partly derived from the STk Reference | |
64 | Manual written by Erick Gallesio, whose copyright notice is as follows. | |
65 | ||
66 | Copyright © 1993-1999 Erick Gallesio - I3S-CNRS/ESSI <eg@@unice.fr> | |
67 | Permission to use, copy, modify, distribute,and license this | |
68 | software and its documentation for any purpose is hereby granted, | |
69 | provided that existing copyright notices are retained in all | |
70 | copies and that this notice is included verbatim in any | |
71 | distributions. No written agreement, license, or royalty fee is | |
72 | required for any of the authorized uses. | |
73 | This software is provided ``AS IS'' without express or implied | |
74 | warranty. | |
75 | ||
76 | The material has been adapted for use in Guile, with the author's | |
77 | permission. | |
78 | ||
79 | ||
f60a8353 NJ |
80 | @node Class Definition |
81 | @section Class Definition | |
e946b0b9 | 82 | |
f60a8353 | 83 | A new class is defined with the @code{define-class} syntax: |
8445eb1d | 84 | |
f60a8353 NJ |
85 | @findex define-class |
86 | @cindex class | |
87 | @lisp | |
88 | (define-class @var{class} (@var{superclass} @dots{}) | |
89 | @var{slot-description} @dots{} | |
90 | @var{class-option} @dots{}) | |
91 | @end lisp | |
a0e07ba4 | 92 | |
f60a8353 NJ |
93 | @var{class} is the class being defined. The list of @var{superclass}es |
94 | specifies which existing classes, if any, to inherit slots and | |
95 | properties from. @dfn{Slots} hold per-instance@footnote{Usually --- but | |
96 | see also the @code{#:allocation} slot option.} data, for instances of | |
97 | that class --- like ``fields'' or ``member variables'' in other object | |
98 | oriented systems. Each @var{slot-description} gives the name of a slot | |
99 | and optionally some ``properties'' of this slot; for example its initial | |
100 | value, the name of a function which will access its value, and so on. | |
101 | Slot descriptions and inheritance are discussed more below. For class | |
102 | options, see @ref{Class Options}. | |
103 | @cindex slot | |
a0e07ba4 | 104 | |
a9bf12c2 NJ |
105 | @deffn syntax define-class name (super @dots{}) slot-definition @dots{} . options |
106 | Define a class called @var{name} that inherits from @var{super}s, with | |
107 | direct slots defined by @var{slot-definition}s and class options | |
108 | @var{options}. The newly created class is bound to the variable name | |
109 | @var{name} in the current environment. | |
a0e07ba4 | 110 | |
a9bf12c2 NJ |
111 | Each @var{slot-definition} is either a symbol that names the slot or a |
112 | list, | |
a0e07ba4 | 113 | |
a9bf12c2 NJ |
114 | @example |
115 | (@var{slot-name-symbol} . @var{slot-options}) | |
116 | @end example | |
a0e07ba4 | 117 | |
a9bf12c2 NJ |
118 | where @var{slot-name-symbol} is a symbol and @var{slot-options} is a |
119 | list with an even number of elements. The even-numbered elements of | |
120 | @var{slot-options} (counting from zero) are slot option keywords; the | |
121 | odd-numbered elements are the corresponding values for those keywords. | |
a0e07ba4 | 122 | |
a9bf12c2 NJ |
123 | @var{options} is a similarly structured list containing class option |
124 | keywords and corresponding values. | |
125 | @end deffn | |
a0e07ba4 | 126 | |
f60a8353 NJ |
127 | As an example, let us define a type for representing a complex number |
128 | in terms of two real numbers.@footnote{Of course Guile already | |
129 | provides complex numbers, and @code{<complex>} is in fact a predefined | |
130 | class in GOOPS; but the definition here is still useful as an | |
131 | example.} This can be done with the following class definition: | |
a0e07ba4 | 132 | |
f60a8353 NJ |
133 | @lisp |
134 | (define-class <my-complex> (<number>) | |
135 | r i) | |
136 | @end lisp | |
a0e07ba4 | 137 | |
f60a8353 NJ |
138 | This binds the variable @code{<my-complex>} to a new class whose |
139 | instances will contain two slots. These slots are called @code{r} and | |
140 | @code{i} and will hold the real and imaginary parts of a complex | |
141 | number. Note that this class inherits from @code{<number>}, which is a | |
142 | predefined class.@footnote{@code{<number>} is the direct superclass of | |
143 | the predefined class @code{<complex>}; @code{<complex>} is the | |
144 | superclass of @code{<real>}, and @code{<real>} is the superclass of | |
145 | @code{<integer>}.} | |
a0e07ba4 | 146 | |
f60a8353 NJ |
147 | The possible slot and class options are described in the following |
148 | sections. | |
a0e07ba4 | 149 | |
a0e07ba4 | 150 | |
f60a8353 NJ |
151 | @node Instance Creation |
152 | @section Instance Creation and Slot Access | |
a0e07ba4 | 153 | |
f60a8353 NJ |
154 | An instance (or object) of a defined class can be created with |
155 | @code{make}. @code{make} takes one mandatory parameter, which is the | |
156 | class of the instance to create, and a list of optional arguments that | |
157 | will be used to initialize the slots of the new instance. For instance | |
158 | the following form | |
159 | ||
160 | @findex make | |
161 | @cindex instance | |
162 | @lisp | |
163 | (define c (make <my-complex>)) | |
164 | @end lisp | |
165 | ||
166 | @noindent | |
167 | creates a new @code{<my-complex>} object and binds it to the Scheme | |
168 | variable @code{c}. | |
169 | ||
170 | @deffn generic make | |
171 | @deffnx method make (class <class>) . initargs | |
172 | Create and return a new instance of class @var{class}, initialized using | |
173 | @var{initargs}. | |
174 | ||
175 | In theory, @var{initargs} can have any structure that is understood by | |
176 | whatever methods get applied when the @code{initialize} generic function | |
177 | is applied to the newly allocated instance. | |
178 | ||
179 | In practice, specialized @code{initialize} methods would normally call | |
180 | @code{(next-method)}, and so eventually the standard GOOPS | |
181 | @code{initialize} methods are applied. These methods expect | |
182 | @var{initargs} to be a list with an even number of elements, where | |
183 | even-numbered elements (counting from zero) are keywords and | |
184 | odd-numbered elements are the corresponding values. | |
185 | ||
186 | GOOPS processes initialization argument keywords automatically for slots | |
187 | whose definition includes the @code{#:init-keyword} option (@pxref{Slot | |
188 | Options,, init-keyword}). Other keyword value pairs can only be | |
189 | processed by an @code{initialize} method that is specialized for the new | |
190 | instance's class. Any unprocessed keyword value pairs are ignored. | |
191 | @end deffn | |
192 | ||
193 | @deffn generic make-instance | |
194 | @deffnx method make-instance (class <class>) . initargs | |
195 | @code{make-instance} is an alias for @code{make}. | |
196 | @end deffn | |
197 | ||
198 | The slots of the new complex number can be accessed using | |
199 | @code{slot-ref} and @code{slot-set!}. @code{slot-set!} sets the value | |
200 | of an object slot and @code{slot-ref} retrieves it. | |
201 | ||
202 | @findex slot-set! | |
203 | @findex slot-ref | |
204 | @lisp | |
205 | @group | |
206 | (slot-set! c 'r 10) | |
207 | (slot-set! c 'i 3) | |
208 | (slot-ref c 'r) @result{} 10 | |
209 | (slot-ref c 'i) @result{} 3 | |
210 | @end group | |
211 | @end lisp | |
212 | ||
213 | The @code{(oop goops describe)} module provides a @code{describe} | |
214 | function that is useful for seeing all the slots of an object; it prints | |
215 | the slots and their values to standard output. | |
216 | ||
217 | @lisp | |
218 | (describe c) | |
219 | @print{} | |
220 | #<<my-complex> 401d8638> is an instance of class <my-complex> | |
221 | Slots are: | |
222 | r = 10 | |
223 | i = 3 | |
224 | @end lisp | |
a0e07ba4 | 225 | |
a0e07ba4 NJ |
226 | |
227 | @node Slot Options | |
f60a8353 NJ |
228 | @section Slot Options |
229 | ||
230 | When specifying a slot (in a @code{(define-class @dots{})} form), | |
231 | various options can be specified in addition to the slot's name. Each | |
232 | option is specified by a keyword. The list of possible keywords is | |
233 | as follows. | |
a0e07ba4 | 234 | |
a0e07ba4 NJ |
235 | @deffn {slot option} #:init-value init-value |
236 | @deffnx {slot option} #:init-form init-form | |
237 | @deffnx {slot option} #:init-thunk init-thunk | |
238 | @deffnx {slot option} #:init-keyword init-keyword | |
239 | These options provide various ways to specify how to initialize the | |
f60a8353 NJ |
240 | slot's value at instance creation time. |
241 | @cindex default slot value | |
242 | ||
243 | @var{init-value} specifies a fixed initial slot value (shared across all | |
244 | new instances of the class). | |
245 | ||
246 | @var{init-thunk} specifies a thunk that will provide a default value for | |
247 | the slot. The thunk is called when a new instance is created and should | |
248 | return the desired initial slot value. | |
249 | ||
250 | @var{init-form} specifies a form that, when evaluated, will return | |
251 | an initial value for the slot. The form is evaluated each time that | |
252 | an instance of the class is created, in the lexical environment of the | |
253 | containing @code{define-class} expression. | |
254 | ||
255 | @var{init-keyword} specifies a keyword that can be used to pass an | |
256 | initial slot value to @code{make} when creating a new instance. | |
5695ccd4 NJ |
257 | |
258 | Note that, since an @code{init-value} value is shared across all | |
259 | instances of a class, you should only use it when the initial value is | |
260 | an immutable value, like a constant. If you want to initialize a slot | |
261 | with a fresh, independently mutable value, you should use | |
262 | @code{init-thunk} or @code{init-form} instead. Consider the following | |
263 | example. | |
264 | ||
265 | @example | |
266 | (define-class <chbouib> () | |
267 | (hashtab #:init-value (make-hash-table))) | |
268 | @end example | |
269 | ||
270 | @noindent | |
271 | Here only one hash table is created and all instances of | |
272 | @code{<chbouib>} have their @code{hashtab} slot refer to it. In order | |
273 | to have each instance of @code{<chbouib>} refer to a new hash table, you | |
274 | should instead write: | |
275 | ||
276 | @example | |
277 | (define-class <chbouib> () | |
278 | (hashtab #:init-thunk make-hash-table)) | |
279 | @end example | |
280 | ||
281 | @noindent | |
282 | or: | |
283 | ||
284 | @example | |
285 | (define-class <chbouib> () | |
286 | (hashtab #:init-form (make-hash-table))) | |
287 | @end example | |
a0e07ba4 NJ |
288 | |
289 | If more than one of these options is specified for the same slot, the | |
290 | order of precedence, highest first is | |
291 | ||
292 | @itemize @bullet | |
293 | @item | |
294 | @code{#:init-keyword}, if @var{init-keyword} is present in the options | |
295 | passed to @code{make} | |
296 | ||
297 | @item | |
298 | @code{#:init-thunk}, @code{#:init-form} or @code{#:init-value}. | |
299 | @end itemize | |
300 | ||
301 | If the slot definition contains more than one initialization option of | |
302 | the same precedence, the later ones are ignored. If a slot is not | |
303 | initialized at all, its value is unbound. | |
304 | ||
305 | In general, slots that are shared between more than one instance are | |
306 | only initialized at new instance creation time if the slot value is | |
307 | unbound at that time. However, if the new instance creation specifies | |
308 | a valid init keyword and value for a shared slot, the slot is | |
309 | re-initialized regardless of its previous value. | |
310 | ||
311 | Note, however, that the power of GOOPS' metaobject protocol means that | |
312 | everything written here may be customized or overridden for particular | |
313 | classes! The slot initializations described here are performed by the least | |
314 | specialized method of the generic function @code{initialize}, whose | |
315 | signature is | |
316 | ||
317 | @example | |
318 | (define-method (initialize (object <object>) initargs) ...) | |
319 | @end example | |
320 | ||
321 | The initialization of instances of any given class can be customized by | |
322 | defining a @code{initialize} method that is specialized for that class, | |
323 | and the author of the specialized method may decide to call | |
324 | @code{next-method} - which will result in a call to the next less | |
325 | specialized @code{initialize} method - at any point within the | |
326 | specialized code, or maybe not at all. In general, therefore, the | |
327 | initialization mechanisms described here may be modified or overridden by | |
328 | more specialized code, or may not be supported at all for particular | |
329 | classes. | |
330 | @end deffn | |
331 | ||
8445eb1d NJ |
332 | @deffn {slot option} #:getter getter |
333 | @deffnx {slot option} #:setter setter | |
334 | @deffnx {slot option} #:accessor accessor | |
335 | Given an object @var{obj} with slots named @code{foo} and @code{bar}, it | |
336 | is always possible to read and write those slots by calling | |
337 | @code{slot-ref} and @code{slot-set!} with the relevant slot name; for | |
338 | example: | |
339 | ||
340 | @example | |
341 | (slot-ref @var{obj} 'foo) | |
342 | (slot-set! @var{obj} 'bar 25) | |
343 | @end example | |
344 | ||
345 | The @code{#:getter}, @code{#:setter} and @code{#:accessor} options, if | |
346 | present, tell GOOPS to create generic function and method definitions | |
347 | that can be used to get and set the slot value more conveniently. | |
348 | @var{getter} specifies a generic function to which GOOPS will add a | |
349 | method for getting the slot value. @var{setter} specifies a generic | |
350 | function to which GOOPS will add a method for setting the slot value. | |
351 | @var{accessor} specifies an accessor to which GOOPS will add methods for | |
352 | both getting and setting the slot value. | |
353 | ||
354 | So if a class includes a slot definition like this: | |
355 | ||
356 | @example | |
357 | (c #:getter get-count #:setter set-count #:accessor count) | |
358 | @end example | |
359 | ||
360 | GOOPS defines generic function methods such that the slot value can be | |
361 | referenced using either the getter or the accessor - | |
362 | ||
363 | @example | |
364 | (let ((current-count (get-count obj))) @dots{}) | |
365 | (let ((current-count (count obj))) @dots{}) | |
366 | @end example | |
367 | ||
368 | - and set using either the setter or the accessor - | |
369 | ||
370 | @example | |
371 | (set-count obj (+ 1 current-count)) | |
372 | (set! (count obj) (+ 1 current-count)) | |
373 | @end example | |
374 | ||
375 | Note that | |
376 | ||
377 | @itemize @bullet | |
378 | @item | |
379 | with an accessor, the slot value is set using the generalized | |
380 | @code{set!} syntax | |
381 | ||
382 | @item | |
383 | in practice, it is unusual for a slot to use all three of these options: | |
384 | read-only, write-only and read-write slots would typically use only | |
385 | @code{#:getter}, @code{#:setter} and @code{#:accessor} options | |
386 | respectively. | |
387 | @end itemize | |
388 | ||
f60a8353 NJ |
389 | The binding of the specified names is done in the environment of the |
390 | @code{define-class} expression. If the names are already bound (in that | |
391 | environment) to values that cannot be upgraded to generic functions, | |
392 | those values are overwritten when the @code{define-class} expression is | |
393 | evaluated. For more detail, see @ref{Generic Function Internals,, | |
8445eb1d NJ |
394 | ensure-generic}. |
395 | @end deffn | |
396 | ||
397 | @deffn {slot option} #:allocation allocation | |
398 | The @code{#:allocation} option tells GOOPS how to allocate storage for | |
399 | the slot. Possible values for @var{allocation} are | |
400 | ||
401 | @itemize @bullet | |
402 | @item @code{#:instance} | |
403 | ||
f60a8353 | 404 | @findex #:instance |
8445eb1d | 405 | Indicates that GOOPS should create separate storage for this slot in |
f60a8353 NJ |
406 | each new instance of the containing class (and its subclasses). This is |
407 | the default. | |
8445eb1d NJ |
408 | |
409 | @item @code{#:class} | |
410 | ||
f60a8353 | 411 | @findex #:class |
8445eb1d NJ |
412 | Indicates that GOOPS should create storage for this slot that is shared |
413 | by all instances of the containing class (and its subclasses). In other | |
414 | words, a slot in class @var{C} with allocation @code{#:class} is shared | |
415 | by all @var{instance}s for which @code{(is-a? @var{instance} @var{c})}. | |
f60a8353 NJ |
416 | This permits defining a kind of global variable which can be accessed |
417 | only by (in)direct instances of the class which defines the slot. | |
8445eb1d NJ |
418 | |
419 | @item @code{#:each-subclass} | |
420 | ||
f60a8353 | 421 | @findex #:each-subclass |
8445eb1d NJ |
422 | Indicates that GOOPS should create storage for this slot that is shared |
423 | by all @emph{direct} instances of the containing class, and that | |
424 | whenever a subclass of the containing class is defined, GOOPS should | |
425 | create a new storage for the slot that is shared by all @emph{direct} | |
426 | instances of the subclass. In other words, a slot with allocation | |
427 | @code{#:each-subclass} is shared by all instances with the same | |
428 | @code{class-of}. | |
429 | ||
430 | @item @code{#:virtual} | |
431 | ||
f60a8353 NJ |
432 | @findex #:slot-set! |
433 | @findex #:slot-ref | |
434 | @findex #:virtual | |
8445eb1d NJ |
435 | Indicates that GOOPS should not allocate storage for this slot. The |
436 | slot definition must also include the @code{#:slot-ref} and | |
437 | @code{#:slot-set!} options to specify how to reference and set the value | |
f60a8353 | 438 | for this slot. See the example below. |
8445eb1d NJ |
439 | @end itemize |
440 | ||
8445eb1d NJ |
441 | Slot allocation options are processed when defining a new class by the |
442 | generic function @code{compute-get-n-set}, which is specialized by the | |
443 | class's metaclass. Hence new types of slot allocation can be | |
444 | implemented by defining a new metaclass and a method for | |
445 | @code{compute-get-n-set} that is specialized for the new metaclass. For | |
446 | an example of how to do this, see @ref{Customizing Class Definition}. | |
447 | @end deffn | |
448 | ||
449 | @deffn {slot option} #:slot-ref getter | |
450 | @deffnx {slot option} #:slot-set! setter | |
451 | The @code{#:slot-ref} and @code{#:slot-set!} options must be specified | |
452 | if the slot allocation is @code{#:virtual}, and are ignored otherwise. | |
453 | ||
454 | @var{getter} should be a closure taking a single @var{instance} parameter | |
455 | that returns the current slot value. @var{setter} should be a closure | |
456 | taking two parameters - @var{instance} and @var{new-val} - that sets the | |
457 | slot value to @var{new-val}. | |
458 | @end deffn | |
459 | ||
f60a8353 NJ |
460 | @node Slot Description Example |
461 | @section Illustrating Slot Description | |
8445eb1d | 462 | |
f60a8353 NJ |
463 | To illustrate slot description, we can redefine the @code{<my-complex>} |
464 | class seen before. A definition could be: | |
8445eb1d | 465 | |
f60a8353 NJ |
466 | @lisp |
467 | (define-class <my-complex> (<number>) | |
468 | (r #:init-value 0 #:getter get-r #:setter set-r! #:init-keyword #:r) | |
469 | (i #:init-value 0 #:getter get-i #:setter set-i! #:init-keyword #:i)) | |
470 | @end lisp | |
8445eb1d | 471 | |
f60a8353 NJ |
472 | @noindent |
473 | With this definition, the @code{r} and @code{i} slots are set to 0 by | |
474 | default, and can be initialised to other values by calling @code{make} | |
475 | with the @code{#:r} and @code{#:i} keywords. Also the generic functions | |
476 | @code{get-r}, @code{set-r!}, @code{get-i} and @code{set-i!} are | |
477 | automatically defined to read and write the slots. | |
8445eb1d | 478 | |
f60a8353 NJ |
479 | @lisp |
480 | (define c1 (make <my-complex> #:r 1 #:i 2)) | |
481 | (get-r c1) @result{} 1 | |
482 | (set-r! c1 12) | |
483 | (get-r c1) @result{} 12 | |
484 | (define c2 (make <my-complex> #:r 2)) | |
485 | (get-r c2) @result{} 2 | |
486 | (get-i c2) @result{} 0 | |
487 | @end lisp | |
8445eb1d | 488 | |
f60a8353 NJ |
489 | Accessors can both read and write a slot. So, another definition of the |
490 | @code{<my-complex>} class, using the @code{#:accessor} option, could be: | |
a0e07ba4 | 491 | |
f60a8353 NJ |
492 | @findex set! |
493 | @lisp | |
494 | (define-class <my-complex> (<number>) | |
495 | (r #:init-value 0 #:accessor real-part #:init-keyword #:r) | |
496 | (i #:init-value 0 #:accessor imag-part #:init-keyword #:i)) | |
497 | @end lisp | |
a0e07ba4 | 498 | |
f60a8353 NJ |
499 | @noindent |
500 | With this definition, the @code{r} slot can be read with: | |
501 | @lisp | |
502 | (real-part c) | |
503 | @end lisp | |
504 | @noindent | |
505 | and set with: | |
506 | @lisp | |
507 | (set! (real-part c) new-value) | |
508 | @end lisp | |
a0e07ba4 | 509 | |
f60a8353 NJ |
510 | Suppose now that we want to manipulate complex numbers with both |
511 | rectangular and polar coordinates. One solution could be to have a | |
512 | definition of complex numbers which uses one particular representation | |
513 | and some conversion functions to pass from one representation to the | |
514 | other. A better solution is to use virtual slots, like this: | |
a0e07ba4 | 515 | |
f60a8353 NJ |
516 | @lisp |
517 | (define-class <my-complex> (<number>) | |
518 | ;; True slots use rectangular coordinates | |
519 | (r #:init-value 0 #:accessor real-part #:init-keyword #:r) | |
520 | (i #:init-value 0 #:accessor imag-part #:init-keyword #:i) | |
521 | ;; Virtual slots access do the conversion | |
522 | (m #:accessor magnitude #:init-keyword #:magn | |
523 | #:allocation #:virtual | |
524 | #:slot-ref (lambda (o) | |
525 | (let ((r (slot-ref o 'r)) (i (slot-ref o 'i))) | |
526 | (sqrt (+ (* r r) (* i i))))) | |
527 | #:slot-set! (lambda (o m) | |
528 | (let ((a (slot-ref o 'a))) | |
529 | (slot-set! o 'r (* m (cos a))) | |
530 | (slot-set! o 'i (* m (sin a)))))) | |
531 | (a #:accessor angle #:init-keyword #:angle | |
532 | #:allocation #:virtual | |
533 | #:slot-ref (lambda (o) | |
534 | (atan (slot-ref o 'i) (slot-ref o 'r))) | |
535 | #:slot-set! (lambda(o a) | |
536 | (let ((m (slot-ref o 'm))) | |
537 | (slot-set! o 'r (* m (cos a))) | |
538 | (slot-set! o 'i (* m (sin a))))))) | |
a0e07ba4 | 539 | |
f60a8353 | 540 | @end lisp |
a0e07ba4 | 541 | |
f60a8353 NJ |
542 | In this class definition, the magniture @code{m} and angle @code{a} |
543 | slots are virtual, and are calculated, when referenced, from the normal | |
544 | (i.e. @code{#:allocation #:instance}) slots @code{r} and @code{i}, by | |
545 | calling the function defined in the relevant @code{#:slot-ref} option. | |
546 | Correspondingly, writing @code{m} or @code{a} leads to calling the | |
547 | function defined in the @code{#:slot-set!} option. Thus the | |
548 | following expression | |
a0e07ba4 | 549 | |
f60a8353 NJ |
550 | @findex #:slot-set! |
551 | @findex #:slot-ref | |
552 | @lisp | |
553 | (slot-set! c 'a 3) | |
554 | @end lisp | |
555 | ||
556 | @noindent | |
557 | permits to set the angle of the @code{c} complex number. | |
558 | ||
559 | @lisp | |
560 | (define c (make <my-complex> #:r 12 #:i 20)) | |
561 | (real-part c) @result{} 12 | |
562 | (angle c) @result{} 1.03037682652431 | |
563 | (slot-set! c 'i 10) | |
564 | (set! (real-part c) 1) | |
565 | (describe c) | |
566 | @print{} | |
567 | #<<my-complex> 401e9b58> is an instance of class <my-complex> | |
568 | Slots are: | |
569 | r = 1 | |
570 | i = 10 | |
571 | m = 10.0498756211209 | |
572 | a = 1.47112767430373 | |
573 | @end lisp | |
574 | ||
575 | Since initialization keywords have been defined for the four slots, we | |
576 | can now define the standard Scheme primitives @code{make-rectangular} | |
577 | and @code{make-polar}. | |
a0e07ba4 | 578 | |
f60a8353 NJ |
579 | @lisp |
580 | (define make-rectangular | |
581 | (lambda (x y) (make <my-complex> #:r x #:i y))) | |
582 | ||
583 | (define make-polar | |
584 | (lambda (x y) (make <my-complex> #:magn x #:angle y))) | |
585 | @end lisp | |
a0e07ba4 | 586 | |
f60a8353 NJ |
587 | |
588 | @node Methods and Generic Functions | |
589 | @section Methods and Generic Functions | |
590 | ||
591 | A GOOPS method is like a Scheme procedure except that it is specialized | |
592 | for a particular set of argument classes, and will only be used when the | |
593 | actual arguments in a call match the classes in the method definition. | |
594 | ||
595 | @lisp | |
596 | (define-method (+ (x <string>) (y <string>)) | |
597 | (string-append x y)) | |
598 | ||
599 | (+ "abc" "de") @result{} "abcde" | |
600 | @end lisp | |
601 | ||
602 | A method is not formally associated with any single class (as it is in | |
603 | many other object oriented languages), because a method can be | |
604 | specialized for a combination of several classes. If you've studied | |
605 | object orientation in non-Lispy languages, you may remember discussions | |
606 | such as whether a method to stretch a graphical image around a surface | |
607 | should be a method of the image class, with a surface as a parameter, or | |
608 | a method of the surface class, with an image as a parameter. In GOOPS | |
609 | you'd just write | |
610 | ||
611 | @lisp | |
612 | (define-method (stretch (im <image>) (sf <surface>)) | |
613 | ...) | |
614 | @end lisp | |
615 | ||
616 | @noindent | |
617 | and the question of which class the method is more associated with does | |
618 | not need answering. | |
619 | ||
68f4fee1 NJ |
620 | There can simultaneously be several methods with the same name but |
621 | different sets of specializing argument classes; for example: | |
622 | ||
623 | @lisp | |
624 | (define-method (+ (x <string>) (y <string)) ...) | |
625 | (define-method (+ (x <matrix>) (y <matrix>)) ...) | |
626 | (define-method (+ (f <fish>) (b <bicyle>)) ...) | |
627 | (define-method (+ (a <foo>) (b <bar>) (c <baz>)) ...) | |
628 | @end lisp | |
629 | ||
630 | @noindent | |
631 | A generic function is a container for the set of such methods that a | |
632 | program intends to use. | |
633 | ||
634 | If you look at a program's source code, and see @code{(+ x y)} somewhere | |
635 | in it, conceptually what is happening is that the program at that point | |
636 | calls a generic function (in this case, the generic function bound to | |
637 | the identifier @code{+}). When that happens, Guile works out which of | |
638 | the generic function's methods is the most appropriate for the arguments | |
639 | that the function is being called with; then it evaluates the method's | |
640 | code with the arguments as formal parameters. This happens every time | |
641 | that a generic function call is evaluated --- it isn't assumed that a | |
642 | given source code call will end up invoking the same method every time. | |
643 | ||
644 | Defining an identifier as a generic function is done with the | |
645 | @code{define-generic} macro. Definition of a new method is done with | |
646 | the @code{define-method} macro. Note that @code{define-method} | |
647 | automatically does a @code{define-generic} if the identifier concerned | |
648 | is not already a generic function, so often an explicit | |
649 | @code{define-generic} call is not needed. | |
650 | @findex define-generic | |
651 | @findex define-method | |
652 | ||
653 | @deffn syntax define-generic symbol | |
654 | Create a generic function with name @var{symbol} and bind it to the | |
655 | variable @var{symbol}. If @var{symbol} was previously bound to a Scheme | |
656 | procedure (or procedure-with-setter), the old procedure (and setter) is | |
657 | incorporated into the new generic function as its default procedure (and | |
658 | setter). Any other previous value, including an existing generic | |
659 | function, is discarded and replaced by a new, empty generic function. | |
660 | @end deffn | |
661 | ||
662 | @deffn syntax define-method (generic parameter @dots{}) . body | |
663 | Define a method for the generic function or accessor @var{generic} with | |
664 | parameters @var{parameter}s and body @var{body}. | |
665 | ||
666 | @var{generic} is a generic function. If @var{generic} is a variable | |
667 | which is not yet bound to a generic function object, the expansion of | |
668 | @code{define-method} will include a call to @code{define-generic}. If | |
669 | @var{generic} is @code{(setter @var{generic-with-setter})}, where | |
670 | @var{generic-with-setter} is a variable which is not yet bound to a | |
671 | generic-with-setter object, the expansion will include a call to | |
672 | @code{define-accessor}. | |
673 | ||
674 | Each @var{parameter} must be either a symbol or a two-element list | |
675 | @code{(@var{symbol} @var{class})}. The symbols refer to variables in | |
676 | the @var{body} that will be bound to the parameters supplied by the | |
677 | caller when calling this method. The @var{class}es, if present, | |
678 | specify the possible combinations of parameters to which this method | |
679 | can be applied. | |
680 | ||
681 | @var{body} is the body of the method definition. | |
682 | @end deffn | |
683 | ||
684 | @code{define-method} expressions look a little like Scheme procedure | |
685 | definitions of the form | |
686 | ||
687 | @example | |
688 | (define (name formals @dots{}) . body) | |
689 | @end example | |
690 | ||
691 | The important difference is that each formal parameter, apart from the | |
692 | possible ``rest'' argument, can be qualified by a class name: | |
693 | @code{@var{formal}} becomes @code{(@var{formal} @var{class})}. The | |
694 | meaning of this qualification is that the method being defined | |
695 | will only be applicable in a particular generic function invocation if | |
696 | the corresponding argument is an instance of @code{@var{class}} (or one of | |
697 | its subclasses). If more than one of the formal parameters is qualified | |
698 | in this way, then the method will only be applicable if each of the | |
699 | corresponding arguments is an instance of its respective qualifying class. | |
700 | ||
701 | Note that unqualified formal parameters act as though they are qualified | |
702 | by the class @code{<top>}, which GOOPS uses to mean the superclass of | |
703 | all valid Scheme types, including both primitive types and GOOPS classes. | |
704 | ||
705 | For example, if a generic function method is defined with | |
706 | @var{parameter}s @code{(s1 <square>)} and @code{(n <number>)}, that | |
707 | method is only applicable to invocations of its generic function that | |
708 | have two parameters where the first parameter is an instance of the | |
709 | @code{<square>} class and the second parameter is a number. | |
f60a8353 NJ |
710 | |
711 | @menu | |
68f4fee1 NJ |
712 | * Accessors:: |
713 | * Extending Primitives:: | |
714 | * Merging Generics:: | |
f60a8353 | 715 | * Next-method:: |
68f4fee1 NJ |
716 | * Generic Function and Method Examples:: |
717 | * Handling Invocation Errors:: | |
f60a8353 NJ |
718 | @end menu |
719 | ||
f60a8353 | 720 | |
68f4fee1 NJ |
721 | @node Accessors |
722 | @subsection Accessors | |
f60a8353 | 723 | |
68f4fee1 NJ |
724 | An accessor is a generic function that can also be used with the |
725 | generalized @code{set!} syntax (@pxref{Procedures with Setters}). Guile | |
726 | will handle a call like | |
f60a8353 | 727 | |
68f4fee1 NJ |
728 | @example |
729 | (set! (@code{accessor} @code{args}@dots{}) @code{value}) | |
730 | @end example | |
f60a8353 | 731 | |
68f4fee1 NJ |
732 | @noindent |
733 | by calling the most specialized method of @code{accessor} that matches | |
734 | the classes of @code{args} and @code{value}. @code{define-accessor} is | |
735 | used to bind an identifier to an accessor. | |
f60a8353 | 736 | |
68f4fee1 NJ |
737 | @deffn syntax define-accessor symbol |
738 | Create an accessor with name @var{symbol} and bind it to the variable | |
739 | @var{symbol}. If @var{symbol} was previously bound to a Scheme | |
740 | procedure (or procedure-with-setter), the old procedure (and setter) is | |
741 | incorporated into the new accessor as its default procedure (and | |
742 | setter). Any other previous value, including an existing generic | |
743 | function or accessor, is discarded and replaced by a new, empty | |
744 | accessor. | |
745 | @end deffn | |
f60a8353 | 746 | |
f60a8353 | 747 | |
68f4fee1 NJ |
748 | @node Extending Primitives |
749 | @subsection Extending Primitives | |
750 | ||
751 | Many of Guile's primitive procedures can be extended by giving them a | |
752 | generic function definition that operates in conjunction with their | |
753 | normal C-coded implementation. When a primitive is extended in this | |
754 | way, it behaves like a generic function with the C-coded implementation | |
755 | as its default method. | |
756 | ||
757 | This extension happens automatically if a method is defined (by a | |
758 | @code{define-method} call) for a variable whose current value is a | |
759 | primitive. But it can also be forced by calling | |
760 | @code{enable-primitive-generic!}. | |
761 | ||
762 | @deffn {primitive procedure} enable-primitive-generic! primitive | |
763 | Force the creation of a generic function definition for | |
764 | @var{primitive}. | |
765 | @end deffn | |
766 | ||
767 | Once the generic function definition for a primitive has been created, | |
768 | it can be retrieved using @code{primitive-generic-generic}. | |
769 | ||
770 | @deffn {primitive procedure} primitive-generic-generic primitive | |
771 | Return the generic function definition of @var{primitive}. | |
f60a8353 | 772 | |
68f4fee1 NJ |
773 | @code{primitive-generic-generic} raises an error if @var{primitive} |
774 | is not a primitive with generic capability. | |
775 | @end deffn | |
776 | ||
777 | @node Merging Generics | |
778 | @subsection Merging Generics | |
779 | ||
780 | GOOPS generic functions and accessors often have short, generic names. | |
781 | For example, if a vector package provides an accessor for the X | |
782 | coordinate of a vector, that accessor may just be called @code{x}. It | |
783 | doesn't need to be called, for example, @code{vector:x}, because | |
784 | GOOPS will work out, when it sees code like @code{(x @var{obj})}, that | |
785 | the vector-specific method of @code{x} should be called if @var{obj} is | |
786 | a vector. | |
787 | ||
788 | That raises the question, though, of what happens when different | |
789 | packages define a generic function with the same name. Suppose we work | |
790 | with a graphical package which needs to use two independent vector | |
791 | packages for 2D and 3D vectors respectively. If both packages export | |
792 | @code{x}, what does the code using those packages end up with? | |
793 | ||
794 | @ref{Creating Guile Modules,,duplicate binding handlers} explains how | |
795 | this is resolved for conflicting bindings in general. For generics, | |
796 | there is a special duplicates handler, @code{merge-generics}, which | |
797 | tells the module system to merge generic functions with the same name. | |
798 | Here is an example: | |
f60a8353 NJ |
799 | |
800 | @lisp | |
68f4fee1 NJ |
801 | (define-module (math 2D-vectors) |
802 | #:use-module (oop goops) | |
803 | #:export (x y ...)) | |
804 | ||
805 | (define-module (math 3D-vectors) | |
806 | #:use-module (oop goops) | |
807 | #:export (x y z ...)) | |
808 | ||
809 | (define-module (my-module) | |
810 | #:use-module (math 2D-vectors) | |
811 | #:use-module (math 3D-vectors) | |
812 | #:duplicates merge-generics) | |
f60a8353 NJ |
813 | @end lisp |
814 | ||
68f4fee1 NJ |
815 | The generic function @code{x} in @code{(my-module)} will now incorporate |
816 | all of the methods of @code{x} from both imported modules. | |
817 | ||
818 | To be precise, there will now be three distinct generic functions named | |
819 | @code{x}: @code{x} in @code{(math 2D-vectors)}, @code{x} in @code{(math | |
820 | 3D-vectors)}, and @code{x} in @code{(my-module)}; and these functions | |
821 | share their methods in an interesting and dynamic way. | |
822 | ||
823 | To explain, let's call the imported generic functions (in @code{(math | |
824 | 2D-vectors)} and @code{(math 3D-vectors)}) the @dfn{ancestors}, and the | |
825 | merged generic function (in @code{(my-module)}), the @dfn{descendant}. | |
826 | The general rule is that for any generic function G, the applicable | |
827 | methods are selected from the union of the methods of G's descendant | |
828 | functions, the methods of G itself and the methods of G's ancestor | |
829 | functions. | |
830 | ||
831 | Thus ancestor functions effectively share methods with their | |
832 | descendants, and vice versa. In the example above, @code{x} in | |
833 | @code{(math 2D-vectors)} will share the methods of @code{x} in | |
834 | @code{(my-module)} and vice versa.@footnote{But note that @code{x} in | |
835 | @code{(math 2D-vectors)} doesn't share methods with @code{x} in | |
836 | @code{(math 3D-vectors)}, so modularity is still preserved.} Sharing is | |
837 | dynamic, so adding another new method to a descendant implies adding it | |
838 | to that descendant's ancestors too. | |
839 | ||
f60a8353 NJ |
840 | @node Next-method |
841 | @subsection Next-method | |
842 | ||
843 | When you call a generic function, with a particular set of arguments, | |
844 | GOOPS builds a list of all the methods that are applicable to those | |
845 | arguments and orders them by how closely the method definitions match | |
846 | the actual argument types. It then calls the method at the top of this | |
847 | list. If the selected method's code wants to call on to the next method | |
848 | in this list, it can do so by using @code{next-method}. | |
849 | ||
850 | @lisp | |
851 | (define-method (Test (a <integer>)) (cons 'integer (next-method))) | |
852 | (define-method (Test (a <number>)) (cons 'number (next-method))) | |
853 | (define-method (Test a) (list 'top)) | |
854 | @end lisp | |
855 | ||
856 | With these definitions, | |
857 | ||
858 | @lisp | |
859 | (Test 1) @result{} (integer number top) | |
860 | (Test 1.0) @result{} (number top) | |
861 | (Test #t) @result{} (top) | |
862 | @end lisp | |
863 | ||
864 | @code{next-method} is always called as just @code{(next-method)}. The | |
865 | arguments for the next method call are always implicit, and always the | |
866 | same as for the original method call. | |
867 | ||
868 | If you want to call on to a method with the same name but with a | |
869 | different set of arguments (as you might with overloaded methods in C++, | |
870 | for example), you do not use @code{next-method}, but instead simply | |
871 | write the new call as usual: | |
872 | ||
873 | @lisp | |
874 | (define-method (Test (a <number>) min max) | |
875 | (if (and (>= a min) (<= a max)) | |
876 | (display "Number is in range\n")) | |
877 | (Test a)) | |
878 | ||
879 | (Test 2 1 10) | |
880 | @print{} | |
881 | Number is in range | |
882 | @result{} | |
883 | (integer number top) | |
884 | @end lisp | |
885 | ||
886 | (You should be careful in this case that the @code{Test} calls do not | |
887 | lead to an infinite recursion, but this consideration is just the same | |
888 | as in Scheme code in general.) | |
889 | ||
68f4fee1 NJ |
890 | @node Generic Function and Method Examples |
891 | @subsection Generic Function and Method Examples | |
892 | ||
893 | Consider the following definitions: | |
f60a8353 | 894 | |
68f4fee1 NJ |
895 | @lisp |
896 | (define-generic G) | |
897 | (define-method (G (a <integer>) b) 'integer) | |
898 | (define-method (G (a <real>) b) 'real) | |
899 | (define-method (G a b) 'top) | |
900 | @end lisp | |
901 | ||
902 | The @code{define-generic} call defines @var{G} as a generic function. | |
903 | The three next lines define methods for @var{G}. Each method uses a | |
904 | sequence of @dfn{parameter specializers} that specify when the given | |
905 | method is applicable. A specializer permits to indicate the class a | |
906 | parameter must belong to (directly or indirectly) to be applicable. If | |
907 | no specializer is given, the system defaults it to @code{<top>}. Thus, | |
908 | the first method definition is equivalent to | |
909 | ||
910 | @cindex parameter specializers | |
911 | @lisp | |
912 | (define-method (G (a <integer>) (b <top>)) 'integer) | |
913 | @end lisp | |
914 | ||
915 | Now, let's look at some possible calls to the generic function @var{G}: | |
916 | ||
917 | @lisp | |
918 | (G 2 3) @result{} integer | |
919 | (G 2 #t) @result{} integer | |
920 | (G 1.2 'a) @result{} real | |
921 | @c (G #3 'a) @result{} real @c was {\sharpsign} | |
922 | (G #t #f) @result{} top | |
923 | (G 1 2 3) @result{} error (since no method exists for 3 parameters) | |
924 | @end lisp | |
925 | ||
926 | The methods above use only one specializer per parameter list. But in | |
927 | general, any or all of a method's parameters may be specialized. | |
928 | Suppose we define now: | |
929 | ||
930 | @lisp | |
931 | (define-method (G (a <integer>) (b <number>)) 'integer-number) | |
932 | (define-method (G (a <integer>) (b <real>)) 'integer-real) | |
933 | (define-method (G (a <integer>) (b <integer>)) 'integer-integer) | |
934 | (define-method (G a (b <number>)) 'top-number) | |
935 | @end lisp | |
936 | ||
937 | @noindent With these definitions: | |
938 | ||
939 | @lisp | |
940 | (G 1 2) @result{} integer-integer | |
941 | (G 1 1.0) @result{} integer-real | |
942 | (G 1 #t) @result{} integer | |
943 | (G 'a 1) @result{} top-number | |
944 | @end lisp | |
945 | ||
946 | As a further example we shall continue to define operations on the | |
4431a337 NJ |
947 | @code{<my-complex>} class. Suppose that we want to use it to implement |
948 | complex numbers completely. For instance a definition for the addition | |
68f4fee1 | 949 | of two complex numbers could be |
f60a8353 NJ |
950 | |
951 | @lisp | |
952 | (define-method (new-+ (a <my-complex>) (b <my-complex>)) | |
953 | (make-rectangular (+ (real-part a) (real-part b)) | |
954 | (+ (imag-part a) (imag-part b)))) | |
955 | @end lisp | |
956 | ||
4431a337 NJ |
957 | To be sure that the @code{+} used in the method @code{new-+} is the |
958 | standard addition we can do: | |
f60a8353 NJ |
959 | |
960 | @lisp | |
961 | (define-generic new-+) | |
962 | ||
963 | (let ((+ +)) | |
964 | (define-method (new-+ (a <my-complex>) (b <my-complex>)) | |
965 | (make-rectangular (+ (real-part a) (real-part b)) | |
966 | (+ (imag-part a) (imag-part b))))) | |
967 | @end lisp | |
968 | ||
969 | The @code{define-generic} ensures here that @code{new-+} will be defined | |
970 | in the global environment. Once this is done, we can add methods to the | |
971 | generic function @code{new-+} which make a closure on the @code{+} | |
972 | symbol. A complete writing of the @code{new-+} methods is shown in | |
4431a337 | 973 | @ref{fig:newplus}. |
a0e07ba4 | 974 | |
4431a337 | 975 | @float Figure,fig:newplus |
f60a8353 NJ |
976 | @lisp |
977 | (define-generic new-+) | |
978 | ||
979 | (let ((+ +)) | |
980 | ||
981 | (define-method (new-+ (a <real>) (b <real>)) (+ a b)) | |
982 | ||
983 | (define-method (new-+ (a <real>) (b <my-complex>)) | |
984 | (make-rectangular (+ a (real-part b)) (imag-part b))) | |
985 | ||
986 | (define-method (new-+ (a <my-complex>) (b <real>)) | |
987 | (make-rectangular (+ (real-part a) b) (imag-part a))) | |
a0e07ba4 | 988 | |
f60a8353 NJ |
989 | (define-method (new-+ (a <my-complex>) (b <my-complex>)) |
990 | (make-rectangular (+ (real-part a) (real-part b)) | |
991 | (+ (imag-part a) (imag-part b)))) | |
a0e07ba4 | 992 | |
f60a8353 NJ |
993 | (define-method (new-+ (a <number>)) a) |
994 | ||
995 | (define-method (new-+) 0) | |
a0e07ba4 | 996 | |
f60a8353 NJ |
997 | (define-method (new-+ . args) |
998 | (new-+ (car args) | |
999 | (apply new-+ (cdr args))))) | |
1000 | ||
1001 | (set! + new-+) | |
1002 | @end lisp | |
1003 | ||
4431a337 NJ |
1004 | @caption{Extending @code{+} to handle complex numbers} |
1005 | @end float | |
a0e07ba4 | 1006 | |
68f4fee1 NJ |
1007 | We take advantage here of the fact that generic function are not obliged |
1008 | to have a fixed number of parameters. The four first methods implement | |
1009 | dyadic addition. The fifth method says that the addition of a single | |
1010 | element is this element itself. The sixth method says that using the | |
1011 | addition with no parameter always return 0 (as is also true for the | |
1012 | primitive @code{+}). The last method takes an arbitrary number of | |
1013 | parameters@footnote{The parameter list for a @code{define-method} | |
1014 | follows the conventions used for Scheme procedures. In particular it can | |
1015 | use the dot notation or a symbol to denote an arbitrary number of | |
1016 | parameters}. This method acts as a kind of @code{reduce}: it calls the | |
1017 | dyadic addition on the @emph{car} of the list and on the result of | |
1018 | applying it on its rest. To finish, the @code{set!} permits to redefine | |
1019 | the @code{+} symbol to our extended addition. | |
1020 | ||
1021 | To conclude our implementation (integration?) of complex numbers, we | |
1022 | could redefine standard Scheme predicates in the following manner: | |
f60a8353 NJ |
1023 | |
1024 | @lisp | |
1025 | (define-method (complex? c <my-complex>) #t) | |
1026 | (define-method (complex? c) #f) | |
1027 | ||
1028 | (define-method (number? n <number>) #t) | |
1029 | (define-method (number? n) #f) | |
1030 | @dots{} | |
f60a8353 NJ |
1031 | @end lisp |
1032 | ||
1033 | Standard primitives in which complex numbers are involved could also be | |
1034 | redefined in the same manner. | |
1035 | ||
1036 | ||
68f4fee1 NJ |
1037 | @node Handling Invocation Errors |
1038 | @subsection Handling Invocation Errors | |
1039 | ||
1040 | If a generic function is invoked with a combination of parameters for | |
1041 | which there is no applicable method, GOOPS raises an error. | |
1042 | ||
1043 | @deffn generic no-method | |
1044 | @deffnx method no-method (gf <generic>) args | |
1045 | When an application invokes a generic function, and no methods at all | |
1046 | have been defined for that generic function, GOOPS calls the | |
1047 | @code{no-method} generic function. The default method calls | |
1048 | @code{goops-error} with an appropriate message. | |
1049 | @end deffn | |
1050 | ||
1051 | @deffn generic no-applicable-method | |
1052 | @deffnx method no-applicable-method (gf <generic>) args | |
1053 | When an application applies a generic function to a set of arguments, | |
1054 | and no methods have been defined for those argument types, GOOPS calls | |
1055 | the @code{no-applicable-method} generic function. The default method | |
1056 | calls @code{goops-error} with an appropriate message. | |
1057 | @end deffn | |
1058 | ||
1059 | @deffn generic no-next-method | |
1060 | @deffnx method no-next-method (gf <generic>) args | |
1061 | When a generic function method calls @code{(next-method)} to invoke the | |
1062 | next less specialized method for that generic function, and no less | |
1063 | specialized methods have been defined for the current generic function | |
1064 | arguments, GOOPS calls the @code{no-next-method} generic function. The | |
1065 | default method calls @code{goops-error} with an appropriate message. | |
1066 | @end deffn | |
1067 | ||
1068 | ||
f60a8353 NJ |
1069 | @node Inheritance |
1070 | @section Inheritance | |
1071 | ||
1072 | Here are some class definitions to help illustrate inheritance: | |
1073 | ||
1074 | @lisp | |
1075 | (define-class A () a) | |
1076 | (define-class B () b) | |
1077 | (define-class C () c) | |
1078 | (define-class D (A B) d a) | |
1079 | (define-class E (A C) e c) | |
1080 | (define-class F (D E) f) | |
1081 | @end lisp | |
1082 | ||
1083 | @code{A}, @code{B}, @code{C} have a null list of superclasses. In this | |
1084 | case, the system will replace the null list by a list which only | |
1085 | contains @code{<object>}, the root of all the classes defined by | |
1086 | @code{define-class}. @code{D}, @code{E}, @code{F} use multiple | |
1087 | inheritance: each class inherits from two previously defined classes. | |
4431a337 NJ |
1088 | Those class definitions define a hierarchy which is shown in |
1089 | @ref{fig:hier}. In this figure, the class @code{<top>} is also shown; | |
1090 | this class is the superclass of all Scheme objects. In particular, | |
1091 | @code{<top>} is the superclass of all standard Scheme | |
1092 | types.@footnote{@code{<complex>}, which is the direct subclass of | |
1093 | @code{<number>} and the direct superclass of @code{<real>}, has been | |
1094 | omitted in this figure.} | |
1095 | ||
1096 | @float Figure,fig:hier | |
f60a8353 NJ |
1097 | @iftex |
1098 | @center @image{hierarchy,5in} | |
1099 | @end iftex | |
1100 | @ifnottex | |
1101 | @verbatiminclude hierarchy.txt | |
1102 | @end ifnottex | |
1103 | ||
4431a337 NJ |
1104 | @caption{A class hierarchy.} |
1105 | @end float | |
f60a8353 NJ |
1106 | |
1107 | When a class has superclasses, its set of slots is calculated by taking | |
1108 | the union of its own slots and those of all its superclasses. Thus each | |
1109 | instance of D will have three slots, @code{a}, @code{b} and | |
1110 | @code{d}). The slots of a class can be discovered using the | |
1111 | @code{class-slots} primitive. For instance, | |
1112 | ||
1113 | @lisp | |
1114 | (class-slots A) @result{} ((a)) | |
1115 | (class-slots E) @result{} ((a) (e) (c)) | |
1116 | (class-slots F) @result{} ((e) (c) (b) (d) (a) (f)) | |
1117 | @end lisp | |
1118 | ||
1119 | @noindent | |
1120 | The ordering of the returned slots is not significant. | |
1121 | ||
1122 | @menu | |
68f4fee1 NJ |
1123 | * Class Precedence List:: |
1124 | * Sorting Methods:: | |
f60a8353 NJ |
1125 | @end menu |
1126 | ||
1127 | ||
68f4fee1 NJ |
1128 | @node Class Precedence List |
1129 | @subsection Class Precedence List | |
1130 | ||
1131 | What happens when a class inherits from two or more superclasses that | |
1132 | have a slot with the same name but incompatible definitions --- for | |
1133 | example, different init values or slot allocations? We need a rule for | |
1134 | deciding which slot definition the derived class ends up with, and this | |
1135 | rule is provided by the class's @dfn{Class Precedence | |
1136 | List}.@footnote{This section is an adaptation of material from Jeff | |
1137 | Dalton's (J.Dalton@@ed.ac.uk) @cite{Brief introduction to CLOS}} | |
a0e07ba4 | 1138 | |
68f4fee1 NJ |
1139 | Another problem arises when invoking a generic function, and there is |
1140 | more than one method that could apply to the call arguments. Here we | |
1141 | need a way of ordering the applicable methods, so that Guile knows which | |
1142 | method to use first, which to use next if that method calls | |
1143 | @code{next-method}, and so on. One of the ingredients for this ordering | |
1144 | is determining, for each given call argument, which of the specializing | |
1145 | classes, from each applicable method's definition, is the most specific | |
1146 | for that argument; and here again the class precedence list helps. | |
a0e07ba4 | 1147 | |
68f4fee1 NJ |
1148 | If inheritance was restricted such that each class could only have one |
1149 | superclass --- which is known as @dfn{single} inheritance --- class | |
1150 | ordering would be easy. The rule would be simply that a subclass is | |
1151 | considered more specific than its superclass. | |
a0e07ba4 | 1152 | |
68f4fee1 NJ |
1153 | With multiple inheritance, ordering is less obvious, and we have to |
1154 | impose an arbitrary rule to determine precedence. Suppose we have | |
a0e07ba4 | 1155 | |
f60a8353 NJ |
1156 | @lisp |
1157 | (define-class X () | |
1158 | (x #:init-value 1)) | |
1159 | ||
1160 | (define-class Y () | |
1161 | (x #:init-value 2)) | |
1162 | ||
1163 | (define-class Z (X Y) | |
1164 | (@dots{})) | |
1165 | @end lisp | |
1166 | ||
68f4fee1 NJ |
1167 | @noindent |
1168 | Clearly the @code{Z} class is more specific than @code{X} or @code{Y}, | |
1169 | for instances of @code{Z}. But which is more specific out of @code{X} | |
1170 | and @code{Y} --- and hence, for the definitions above, which | |
1171 | @code{#:init-value} will take effect when creating an instance of | |
1172 | @code{Z}? The rule in @goops{} is that the superclasses listed earlier | |
1173 | are more specific than those listed later. Hence @code{X} is more | |
1174 | specific than @code{Y}, and the @code{#:init-value} for slot @code{x} in | |
1175 | instances of @code{Z} will be 1. | |
1176 | ||
1177 | Hence there is a linear ordering for a class and all its | |
1178 | superclasses, from most specific to least specific, and this ordering is | |
1179 | called the Class Precedence List of the class. | |
1180 | ||
1181 | In fact the rules above are not quite enough to always determine a | |
1182 | unique order, but they give an idea of how things work. For example, | |
1183 | for the @code{F} class shown in @ref{fig:hier}, the class precedence | |
1184 | list is | |
f60a8353 NJ |
1185 | |
1186 | @example | |
1187 | (f d e a c b <object> <top>) | |
a0e07ba4 NJ |
1188 | @end example |
1189 | ||
68f4fee1 NJ |
1190 | @noindent |
1191 | In cases where there is any ambiguity (like this one), it is a bad idea | |
1192 | for programmers to rely on exactly what the order is. If the order for | |
1193 | some superclasses is important, it can be expressed directly in the | |
1194 | class definition. | |
f60a8353 | 1195 | |
68f4fee1 NJ |
1196 | The precedence list of a class can be obtained by calling |
1197 | @code{class-precedence-list}. This function returns a ordered list | |
1198 | whose first element is the most specific class. For instance: | |
f60a8353 NJ |
1199 | |
1200 | @lisp | |
1201 | (class-precedence-list B) @result{} (#<<class> B 401b97c8> | |
1202 | #<<class> <object> 401e4a10> | |
1203 | #<<class> <top> 4026a9d8>) | |
1204 | @end lisp | |
1205 | ||
68f4fee1 NJ |
1206 | @noindent |
1207 | Or for a more immediately readable result: | |
f60a8353 NJ |
1208 | |
1209 | @lisp | |
1210 | (map class-name (class-precedence-list B)) @result{} (B <object> <top>) | |
1211 | @end lisp | |
1212 | ||
1213 | ||
68f4fee1 NJ |
1214 | @node Sorting Methods |
1215 | @subsection Sorting Methods | |
1216 | ||
1217 | Now, with the idea of the class precedence list, we can state precisely | |
1218 | how the possible methods are sorted when more than one of the methods of | |
1219 | a generic function are applicable to the call arguments. | |
1220 | ||
1221 | The rules are that | |
1222 | @itemize | |
1223 | @item | |
1224 | the applicable methods are sorted in order of specificity, and the most | |
1225 | specific method is used first, then the next if that method calls | |
1226 | @code{next-method}, and so on | |
1227 | ||
1228 | @item | |
1229 | a method M1 is more specific than another method M2 if the first | |
1230 | specializing class that differs, between the definitions of M1 and M2, | |
1231 | is more specific, in M1's definition, for the corresponding actual call | |
1232 | argument, than the specializing class in M2's definition | |
1233 | ||
1234 | @item | |
1235 | a class C1 is more specific than another class C2, for an object of | |
1236 | actual class C, if C1 comes before C2 in C's class precedence list. | |
1237 | @end itemize | |
1238 | ||
1239 | ||
62d7cba3 NJ |
1240 | @node Introspection |
1241 | @section Introspection | |
f60a8353 | 1242 | |
62d7cba3 NJ |
1243 | @dfn{Introspection}, also known as @dfn{reflection}, is the name given |
1244 | to the ability to obtain information dynamically about GOOPS metaobjects. | |
1245 | It is perhaps best illustrated by considering an object oriented language | |
1246 | that does not provide any introspection, namely C++. | |
f60a8353 | 1247 | |
62d7cba3 NJ |
1248 | Nothing in C++ allows a running program to obtain answers to the following |
1249 | types of question: | |
f60a8353 | 1250 | |
62d7cba3 NJ |
1251 | @itemize @bullet |
1252 | @item | |
1253 | What are the data members of this object or class? | |
f60a8353 | 1254 | |
62d7cba3 NJ |
1255 | @item |
1256 | What classes does this class inherit from? | |
f60a8353 | 1257 | |
62d7cba3 NJ |
1258 | @item |
1259 | Is this method call virtual or non-virtual? | |
1260 | ||
1261 | @item | |
1262 | If I invoke @code{Employee::adjustHoliday()}, what class contains the | |
1263 | @code{adjustHoliday()} method that will be applied? | |
1264 | @end itemize | |
1265 | ||
1266 | In C++, answers to such questions can only be determined by looking at | |
1267 | the source code, if you have access to it. GOOPS, on the other hand, | |
1268 | includes procedures that allow answers to these questions --- or their | |
1269 | GOOPS equivalents --- to be obtained dynamically, at run time. | |
a0e07ba4 NJ |
1270 | |
1271 | @menu | |
62d7cba3 NJ |
1272 | * Classes:: |
1273 | * Slots:: | |
1274 | * Instances:: | |
1275 | * Built-in classes:: | |
1276 | * Generic Functions:: | |
1277 | * Generic Function Methods:: | |
a0e07ba4 NJ |
1278 | @end menu |
1279 | ||
62d7cba3 NJ |
1280 | @node Classes |
1281 | @subsection Classes | |
a0e07ba4 | 1282 | |
62d7cba3 NJ |
1283 | @deffn {primitive procedure} class-name class |
1284 | Return the name of class @var{class}. | |
1285 | This is the value of the @var{class} metaobject's @code{name} slot. | |
1286 | @end deffn | |
a0e07ba4 | 1287 | |
62d7cba3 NJ |
1288 | @deffn {primitive procedure} class-direct-supers class |
1289 | Return a list containing the direct superclasses of @var{class}. | |
1290 | This is the value of the @var{class} metaobject's | |
1291 | @code{direct-supers} slot. | |
a0e07ba4 NJ |
1292 | @end deffn |
1293 | ||
62d7cba3 NJ |
1294 | @deffn {primitive procedure} class-direct-slots class |
1295 | Return a list containing the slot definitions of the direct slots of | |
1296 | @var{class}. | |
1297 | This is the value of the @var{class} metaobject's @code{direct-slots} | |
1298 | slot. | |
1299 | @end deffn | |
a0e07ba4 | 1300 | |
62d7cba3 NJ |
1301 | @deffn {primitive procedure} class-direct-subclasses class |
1302 | Return a list containing the direct subclasses of @var{class}. | |
1303 | This is the value of the @var{class} metaobject's | |
1304 | @code{direct-subclasses} slot. | |
a0e07ba4 NJ |
1305 | @end deffn |
1306 | ||
62d7cba3 NJ |
1307 | @deffn {primitive procedure} class-direct-methods class |
1308 | Return a list of all the generic function methods that use @var{class} | |
1309 | as a formal parameter specializer. | |
1310 | This is the value of the @var{class} metaobject's @code{direct-methods} | |
1311 | slot. | |
1312 | @end deffn | |
a0e07ba4 | 1313 | |
62d7cba3 NJ |
1314 | @deffn {primitive procedure} class-precedence-list class |
1315 | Return the class precedence list for class @var{class} (@pxref{Class | |
1316 | Precedence List}). | |
1317 | This is the value of the @var{class} metaobject's @code{cpl} slot. | |
1318 | @end deffn | |
a0e07ba4 | 1319 | |
62d7cba3 NJ |
1320 | @deffn {primitive procedure} class-slots class |
1321 | Return a list containing the slot definitions for all @var{class}'s slots, | |
1322 | including any slots that are inherited from superclasses. | |
1323 | This is the value of the @var{class} metaobject's @code{slots} slot. | |
a0e07ba4 NJ |
1324 | @end deffn |
1325 | ||
62d7cba3 NJ |
1326 | @deffn {primitive procedure} class-environment class |
1327 | Return the value of @var{class}'s @code{environment} slot. | |
1328 | [ *fixme* I don't know what this value is used for. ] | |
1329 | @end deffn | |
a0e07ba4 | 1330 | |
62d7cba3 NJ |
1331 | @deffn procedure class-subclasses class |
1332 | Return a list of all subclasses of @var{class}. | |
a0e07ba4 NJ |
1333 | @end deffn |
1334 | ||
62d7cba3 NJ |
1335 | @deffn procedure class-methods class |
1336 | Return a list of all methods that use @var{class} or a subclass of | |
1337 | @var{class} as one of its formal parameter specializers. | |
1338 | @end deffn | |
a0e07ba4 | 1339 | |
62d7cba3 NJ |
1340 | @node Slots |
1341 | @subsection Slots | |
a0e07ba4 | 1342 | |
62d7cba3 NJ |
1343 | @deffn procedure class-slot-definition class slot-name |
1344 | Return the slot definition for the slot named @var{slot-name} in class | |
1345 | @var{class}. @var{slot-name} should be a symbol. | |
a0e07ba4 NJ |
1346 | @end deffn |
1347 | ||
62d7cba3 NJ |
1348 | @deffn procedure slot-definition-name slot-def |
1349 | Extract and return the slot name from @var{slot-def}. | |
a0e07ba4 NJ |
1350 | @end deffn |
1351 | ||
62d7cba3 NJ |
1352 | @deffn procedure slot-definition-options slot-def |
1353 | Extract and return the slot options from @var{slot-def}. | |
1354 | @end deffn | |
a0e07ba4 | 1355 | |
62d7cba3 NJ |
1356 | @deffn procedure slot-definition-allocation slot-def |
1357 | Extract and return the slot allocation option from @var{slot-def}. This | |
1358 | is the value of the @code{#:allocation} keyword (@pxref{Slot Options,, | |
1359 | allocation}), or @code{#:instance} if the @code{#:allocation} keyword is | |
1360 | absent. | |
1361 | @end deffn | |
a0e07ba4 | 1362 | |
62d7cba3 NJ |
1363 | @deffn procedure slot-definition-getter slot-def |
1364 | Extract and return the slot getter option from @var{slot-def}. This is | |
1365 | the value of the @code{#:getter} keyword (@pxref{Slot Options,, | |
1366 | getter}), or @code{#f} if the @code{#:getter} keyword is absent. | |
a0e07ba4 NJ |
1367 | @end deffn |
1368 | ||
62d7cba3 NJ |
1369 | @deffn procedure slot-definition-setter slot-def |
1370 | Extract and return the slot setter option from @var{slot-def}. This is | |
1371 | the value of the @code{#:setter} keyword (@pxref{Slot Options,, | |
1372 | setter}), or @code{#f} if the @code{#:setter} keyword is absent. | |
1373 | @end deffn | |
a0e07ba4 | 1374 | |
62d7cba3 NJ |
1375 | @deffn procedure slot-definition-accessor slot-def |
1376 | Extract and return the slot accessor option from @var{slot-def}. This | |
1377 | is the value of the @code{#:accessor} keyword (@pxref{Slot Options,, | |
1378 | accessor}), or @code{#f} if the @code{#:accessor} keyword is absent. | |
a0e07ba4 NJ |
1379 | @end deffn |
1380 | ||
62d7cba3 NJ |
1381 | @deffn procedure slot-definition-init-value slot-def |
1382 | Extract and return the slot init-value option from @var{slot-def}. This | |
1383 | is the value of the @code{#:init-value} keyword (@pxref{Slot Options,, | |
1384 | init-value}), or the unbound value if the @code{#:init-value} keyword is | |
1385 | absent. | |
1386 | @end deffn | |
a0e07ba4 | 1387 | |
62d7cba3 NJ |
1388 | @deffn procedure slot-definition-init-form slot-def |
1389 | Extract and return the slot init-form option from @var{slot-def}. This | |
1390 | is the value of the @code{#:init-form} keyword (@pxref{Slot Options,, | |
1391 | init-form}), or the unbound value if the @code{#:init-form} keyword is | |
1392 | absent. | |
1393 | @end deffn | |
a0e07ba4 | 1394 | |
62d7cba3 NJ |
1395 | @deffn procedure slot-definition-init-thunk slot-def |
1396 | Extract and return the slot init-thunk option from @var{slot-def}. This | |
1397 | is the value of the @code{#:init-thunk} keyword (@pxref{Slot Options,, | |
1398 | init-thunk}), or @code{#f} if the @code{#:init-thunk} keyword is absent. | |
1399 | @end deffn | |
a0e07ba4 | 1400 | |
62d7cba3 NJ |
1401 | @deffn procedure slot-definition-init-keyword slot-def |
1402 | Extract and return the slot init-keyword option from @var{slot-def}. | |
1403 | This is the value of the @code{#:init-keyword} keyword (@pxref{Slot | |
1404 | Options,, init-keyword}), or @code{#f} if the @code{#:init-keyword} | |
1405 | keyword is absent. | |
a0e07ba4 NJ |
1406 | @end deffn |
1407 | ||
62d7cba3 NJ |
1408 | @deffn procedure slot-init-function class slot-name |
1409 | Return the initialization function for the slot named @var{slot-name} in | |
1410 | class @var{class}. @var{slot-name} should be a symbol. | |
a0e07ba4 | 1411 | |
62d7cba3 NJ |
1412 | The returned initialization function incorporates the effects of the |
1413 | standard @code{#:init-thunk}, @code{#:init-form} and @code{#:init-value} | |
1414 | slot options. These initializations can be overridden by the | |
1415 | @code{#:init-keyword} slot option or by a specialized @code{initialize} | |
1416 | method, so, in general, the function returned by | |
1417 | @code{slot-init-function} may be irrelevant. For a fuller discussion, | |
1418 | see @ref{Slot Options,, init-value}. | |
a0e07ba4 NJ |
1419 | @end deffn |
1420 | ||
62d7cba3 NJ |
1421 | @node Instances |
1422 | @subsection Instances | |
1423 | ||
1424 | @deffn {primitive procedure} class-of value | |
1425 | Return the GOOPS class of any Scheme @var{value}. | |
1426 | @end deffn | |
1427 | ||
1428 | @deffn {primitive procedure} instance? object | |
1429 | Return @code{#t} if @var{object} is any GOOPS instance, otherwise | |
1430 | @code{#f}. | |
1431 | @end deffn | |
1432 | ||
1433 | @deffn procedure is-a? object class | |
1434 | Return @code{#t} if @var{object} is an instance of @var{class} or one of | |
1435 | its subclasses. | |
1436 | @end deffn | |
1437 | ||
1438 | Implementation notes: @code{is-a?} uses @code{class-of} and | |
1439 | @code{class-precedence-list} to obtain the class precedence list for | |
1440 | @var{object}. | |
1441 | ||
1442 | @node Built-in classes | |
1443 | @subsection Built-in classes | |
1444 | ||
1445 | There are built-in classes like @code{<string>}, @code{<list>} and | |
1446 | @code{<number>} corresponding to all the Guile Scheme types. You can | |
1447 | use the @code{is-a?} predicate to ask whether any given value belongs to | |
1448 | a given class, or @code{class-of} to discover the class of a given | |
1449 | value. | |
1450 | ||
1451 | @lisp | |
1452 | (is-a? 2.3 <number>) @result{} #t | |
1453 | (is-a? 2.3 <real>) @result{} #t | |
1454 | (is-a? 2.3 <string>) @result{} #f | |
1455 | (is-a? '("a" "b") <string>) @result{} #f | |
1456 | (is-a? '("a" "b") <list>) @result{} #t | |
1457 | (is-a? (car '("a" "b")) <string>) @result{} #t | |
1458 | (is-a? <string> <class>) @result{} #t | |
1459 | (is-a? <class> <string>) @result{} #f | |
1460 | ||
1461 | (class-of 2.3) @result{} #<<class> <real> 908c708> | |
1462 | (class-of #(1 2 3)) @result{} #<<class> <vector> 908cd20> | |
1463 | (class-of <string>) @result{} #<<class> <class> 8bd3e10> | |
1464 | (class-of <class>) @result{} #<<class> <class> 8bd3e10> | |
1465 | @end lisp | |
1466 | ||
1467 | ||
1468 | @node Generic Functions | |
1469 | @subsection Generic Functions | |
1470 | ||
1471 | @deffn {primitive procedure} generic-function-name gf | |
1472 | Return the name of generic function @var{gf}. | |
1473 | @end deffn | |
1474 | ||
1475 | @deffn {primitive procedure} generic-function-methods gf | |
1476 | Return a list of the methods of generic function @var{gf}. | |
1477 | This is the value of the @var{gf} metaobject's @code{methods} slot. | |
1478 | @end deffn | |
1479 | ||
1480 | @node Generic Function Methods | |
1481 | @subsection Generic Function Methods | |
1482 | ||
1483 | @deffn {primitive procedure} method-generic-function method | |
1484 | Return the generic function that @var{method} belongs to. | |
1485 | This is the value of the @var{method} metaobject's | |
1486 | @code{generic-function} slot. | |
1487 | @end deffn | |
1488 | ||
1489 | @deffn {primitive procedure} method-specializers method | |
1490 | Return a list of @var{method}'s formal parameter specializers . | |
1491 | This is the value of the @var{method} metaobject's | |
1492 | @code{specializers} slot. | |
1493 | @end deffn | |
1494 | ||
1495 | @deffn {primitive procedure} method-procedure method | |
1496 | Return the procedure that implements @var{method}. | |
1497 | This is the value of the @var{method} metaobject's | |
1498 | @code{procedure} slot. | |
1499 | @end deffn | |
1500 | ||
1501 | @deffn generic method-source | |
1502 | @deffnx method method-source (m <method>) | |
1503 | Return an expression that prints to show the definition of method | |
1504 | @var{m}. | |
1505 | ||
1506 | @example | |
1507 | (define-generic cube) | |
1508 | ||
1509 | (define-method (cube (n <number>)) | |
1510 | (* n n n)) | |
1511 | ||
1512 | (map method-source (generic-function-methods cube)) | |
1513 | @result{} | |
1514 | ((method ((n <number>)) (* n n n))) | |
1515 | @end example | |
1516 | @end deffn | |
1517 | ||
1518 | ||
1519 | @node Class Options | |
1520 | @section Class Options | |
1521 | ||
1522 | @deffn {class option} #:metaclass metaclass | |
1523 | The @code{#:metaclass} class option specifies the metaclass of the class | |
1524 | being defined. @var{metaclass} must be a class that inherits from | |
1525 | @code{<class>}. For the use of metaclasses, see @ref{Metaobjects and | |
1526 | the Metaobject Protocol} and @ref{Terminology}. | |
1527 | ||
1528 | If the @code{#:metaclass} option is absent, GOOPS reuses or constructs a | |
1529 | metaclass for the new class by calling @code{ensure-metaclass} | |
1530 | (@pxref{Class Definition Internals,, ensure-metaclass}). | |
1531 | @end deffn | |
1532 | ||
1533 | @deffn {class option} #:name name | |
1534 | The @code{#:name} class option specifies the new class's name. This | |
1535 | name is used to identify the class whenever related objects - the class | |
1536 | itself, its instances and its subclasses - are printed. | |
1537 | ||
1538 | If the @code{#:name} option is absent, GOOPS uses the first argument to | |
1539 | @code{define-class} as the class name. | |
1540 | @end deffn | |
1541 | ||
1542 | @node Accessing Slots | |
1543 | @section Accessing Slots | |
1544 | ||
1545 | @menu | |
1546 | * Instance Slots:: | |
1547 | * Class Slots:: | |
1548 | * Handling Slot Access Errors:: | |
1549 | @end menu | |
1550 | ||
1551 | @node Instance Slots | |
1552 | @subsection Instance Slots | |
1553 | ||
1554 | Any slot, regardless of its allocation, can be queried, referenced and | |
1555 | set using the following four primitive procedures. | |
1556 | ||
1557 | @deffn {primitive procedure} slot-exists? obj slot-name | |
1558 | Return @code{#t} if @var{obj} has a slot with name @var{slot-name}, | |
1559 | otherwise @code{#f}. | |
1560 | @end deffn | |
1561 | ||
1562 | @deffn {primitive procedure} slot-bound? obj slot-name | |
1563 | Return @code{#t} if the slot named @var{slot-name} in @var{obj} has a | |
1564 | value, otherwise @code{#f}. | |
1565 | ||
1566 | @code{slot-bound?} calls the generic function @code{slot-missing} if | |
1567 | @var{obj} does not have a slot called @var{slot-name} (@pxref{Handling | |
1568 | Slot Access Errors, slot-missing}). | |
1569 | @end deffn | |
1570 | ||
1571 | @deffn {primitive procedure} slot-ref obj slot-name | |
1572 | Return the value of the slot named @var{slot-name} in @var{obj}. | |
1573 | ||
1574 | @code{slot-ref} calls the generic function @code{slot-missing} if | |
1575 | @var{obj} does not have a slot called @var{slot-name} (@pxref{Handling | |
1576 | Slot Access Errors, slot-missing}). | |
1577 | ||
1578 | @code{slot-ref} calls the generic function @code{slot-unbound} if the | |
1579 | named slot in @var{obj} does not have a value (@pxref{Handling Slot | |
1580 | Access Errors, slot-unbound}). | |
1581 | @end deffn | |
1582 | ||
1583 | @deffn {primitive procedure} slot-set! obj slot-name value | |
1584 | Set the value of the slot named @var{slot-name} in @var{obj} to @var{value}. | |
1585 | ||
1586 | @code{slot-set!} calls the generic function @code{slot-missing} if | |
1587 | @var{obj} does not have a slot called @var{slot-name} (@pxref{Handling | |
1588 | Slot Access Errors, slot-missing}). | |
1589 | @end deffn | |
1590 | ||
1591 | GOOPS stores information about slots in classes. Internally, | |
1592 | all of these procedures work by looking up the slot definition for the | |
1593 | slot named @var{slot-name} in the class @code{(class-of | |
1594 | @var{obj})}, and then using the slot definition's ``getter'' and | |
1595 | ``setter'' closures to get and set the slot value. | |
1596 | ||
1597 | The next four procedures differ from the previous ones in that they take | |
1598 | the class as an explicit argument, rather than assuming | |
1599 | @code{(class-of @var{obj})}. Therefore they allow you to apply the | |
1600 | ``getter'' and ``setter'' closures of a slot definition in one class to | |
1601 | an instance of a different class. | |
1602 | ||
1603 | @deffn {primitive procedure} slot-exists-using-class? class obj slot-name | |
1604 | Return @code{#t} if @var{class} has a slot definition for a slot with | |
1605 | name @var{slot-name}, otherwise @code{#f}. | |
1606 | @end deffn | |
1607 | ||
1608 | @deffn {primitive procedure} slot-bound-using-class? class obj slot-name | |
1609 | Return @code{#t} if applying @code{slot-ref-using-class} to the same | |
1610 | arguments would call the generic function @code{slot-unbound}, otherwise | |
1611 | @code{#f}. | |
1612 | ||
1613 | @code{slot-bound-using-class?} calls the generic function | |
1614 | @code{slot-missing} if @var{class} does not have a slot definition for a | |
1615 | slot called @var{slot-name} (@pxref{Handling Slot Access Errors, | |
1616 | slot-missing}). | |
1617 | @end deffn | |
1618 | ||
1619 | @deffn {primitive procedure} slot-ref-using-class class obj slot-name | |
1620 | Apply the ``getter'' closure for the slot named @var{slot-name} in | |
1621 | @var{class} to @var{obj}, and return its result. | |
1622 | ||
1623 | @code{slot-ref-using-class} calls the generic function | |
1624 | @code{slot-missing} if @var{class} does not have a slot definition for a | |
1625 | slot called @var{slot-name} (@pxref{Handling Slot Access Errors, | |
1626 | slot-missing}). | |
1627 | ||
1628 | @code{slot-ref-using-class} calls the generic function | |
1629 | @code{slot-unbound} if the application of the ``getter'' closure to | |
1630 | @var{obj} returns an unbound value (@pxref{Handling Slot Access Errors, | |
1631 | slot-unbound}). | |
1632 | @end deffn | |
1633 | ||
1634 | @deffn {primitive procedure} slot-set-using-class! class obj slot-name value | |
1635 | Apply the ``setter'' closure for the slot named @var{slot-name} in | |
1636 | @var{class} to @var{obj} and @var{value}. | |
1637 | ||
1638 | @code{slot-set-using-class!} calls the generic function | |
1639 | @code{slot-missing} if @var{class} does not have a slot definition for a | |
1640 | slot called @var{slot-name} (@pxref{Handling Slot Access Errors, | |
1641 | slot-missing}). | |
1642 | @end deffn | |
1643 | ||
1644 | @node Class Slots | |
1645 | @subsection Class Slots | |
1646 | ||
1647 | Slots whose allocation is per-class rather than per-instance can be | |
1648 | referenced and set without needing to specify any particular instance. | |
1649 | ||
1650 | @deffn procedure class-slot-ref class slot-name | |
1651 | Return the value of the slot named @var{slot-name} in class @var{class}. | |
1652 | The named slot must have @code{#:class} or @code{#:each-subclass} | |
1653 | allocation (@pxref{Slot Options,, allocation}). | |
1654 | ||
1655 | If there is no such slot with @code{#:class} or @code{#:each-subclass} | |
1656 | allocation, @code{class-slot-ref} calls the @code{slot-missing} generic | |
1657 | function with arguments @var{class} and @var{slot-name}. Otherwise, if | |
1658 | the slot value is unbound, @code{class-slot-ref} calls the | |
1659 | @code{slot-unbound} generic function, with the same arguments. | |
1660 | @end deffn | |
1661 | ||
1662 | @deffn procedure class-slot-set! class slot-name value | |
1663 | Set the value of the slot named @var{slot-name} in class @var{class} to | |
1664 | @var{value}. The named slot must have @code{#:class} or | |
1665 | @code{#:each-subclass} allocation (@pxref{Slot Options,, allocation}). | |
1666 | ||
1667 | If there is no such slot with @code{#:class} or @code{#:each-subclass} | |
1668 | allocation, @code{class-slot-ref} calls the @code{slot-missing} generic | |
1669 | function with arguments @var{class} and @var{slot-name}. | |
1670 | @end deffn | |
1671 | ||
1672 | @node Handling Slot Access Errors | |
1673 | @subsection Handling Slot Access Errors | |
1674 | ||
1675 | GOOPS calls one of the following generic functions when a ``slot-ref'' | |
1676 | or ``slot-set!'' call specifies a non-existent slot name, or tries to | |
1677 | reference a slot whose value is unbound. | |
a0e07ba4 NJ |
1678 | |
1679 | @deffn generic slot-missing | |
1680 | @deffnx method slot-missing (class <class>) slot-name | |
1681 | @deffnx method slot-missing (class <class>) (object <object>) slot-name | |
1682 | @deffnx method slot-missing (class <class>) (object <object>) slot-name value | |
1683 | When an application attempts to reference or set a class or instance | |
1684 | slot by name, and the slot name is invalid for the specified @var{class} | |
1685 | or @var{object}, GOOPS calls the @code{slot-missing} generic function. | |
1686 | ||
1687 | The default methods all call @code{goops-error} with an appropriate | |
1688 | message. | |
1689 | @end deffn | |
1690 | ||
1691 | @deffn generic slot-unbound | |
1692 | @deffnx method slot-unbound (object <object>) | |
1693 | @deffnx method slot-unbound (class <class>) slot-name | |
1694 | @deffnx method slot-unbound (class <class>) (object <object>) slot-name | |
1695 | When an application attempts to reference a class or instance slot, and | |
1696 | the slot's value is unbound, GOOPS calls the @code{slot-unbound} generic | |
1697 | function. | |
1698 | ||
1699 | The default methods all call @code{goops-error} with an appropriate | |
1700 | message. | |
1701 | @end deffn | |
1702 | ||
17285a7c NJ |
1703 | @node Generic Functions and Accessors |
1704 | @section Generic Functions and Accessors | |
a0e07ba4 NJ |
1705 | |
1706 | A generic function is a collection of methods, with rules for | |
1707 | determining which of the methods should be applied for any given | |
17285a7c NJ |
1708 | invocation of the generic function. GOOPS represents generic functions |
1709 | as metaobjects of the class @code{<generic>} (or one of its subclasses). | |
a0e07ba4 | 1710 | |
a0e07ba4 NJ |
1711 | @menu |
1712 | * Determining Which Methods to Apply:: | |
a0e07ba4 NJ |
1713 | @end menu |
1714 | ||
1715 | @node Determining Which Methods to Apply | |
c34d74ff | 1716 | @subsection Determining Which Methods to Apply |
a0e07ba4 NJ |
1717 | |
1718 | [ *fixme* Sorry - this is the area of GOOPS that I understand least of | |
1719 | all, so I'm afraid I have to pass on this section. Would some other | |
1720 | kind person consider filling it in? ] | |
1721 | ||
1722 | @deffn generic apply-generic | |
1723 | @deffnx method apply-generic (gf <generic>) args | |
1724 | @end deffn | |
1725 | ||
1726 | @deffn generic compute-applicable-methods | |
1727 | @deffnx method compute-applicable-methods (gf <generic>) args | |
1728 | @end deffn | |
1729 | ||
1730 | @deffn generic sort-applicable-methods | |
1731 | @deffnx method sort-applicable-methods (gf <generic>) methods args | |
1732 | @end deffn | |
1733 | ||
1734 | @deffn generic method-more-specific? | |
1735 | @deffnx method method-more-specific? (m1 <method>) (m2 <method>) args | |
1736 | @end deffn | |
1737 | ||
1738 | @deffn generic apply-method | |
1739 | @deffnx method apply-method (gf <generic>) methods build-next args | |
1740 | @end deffn | |
1741 | ||
1742 | @deffn generic apply-methods | |
1743 | @deffnx method apply-methods (gf <generic>) (l <list>) args | |
1744 | @end deffn | |
1745 | ||
a0e07ba4 | 1746 | @node Redefining a Class |
c34d74ff | 1747 | @section Redefining a Class |
a0e07ba4 NJ |
1748 | |
1749 | Suppose that a class @code{<my-class>} is defined using @code{define-class} | |
f60a8353 | 1750 | (@pxref{Class Definition,, define-class}), with slots that have |
a0e07ba4 | 1751 | accessor functions, and that an application has created several instances |
f60a8353 | 1752 | of @code{<my-class>} using @code{make} (@pxref{Instance Creation,, |
a0e07ba4 NJ |
1753 | make}). What then happens if @code{<my-class>} is redefined by calling |
1754 | @code{define-class} again? | |
1755 | ||
1756 | @menu | |
1757 | * Default Class Redefinition Behaviour:: | |
1758 | * Customizing Class Redefinition:: | |
1759 | @end menu | |
1760 | ||
1761 | @node Default Class Redefinition Behaviour | |
c34d74ff | 1762 | @subsection Default Class Redefinition Behaviour |
a0e07ba4 NJ |
1763 | |
1764 | GOOPS' default answer to this question is as follows. | |
1765 | ||
1766 | @itemize @bullet | |
1767 | @item | |
1768 | All existing direct instances of @code{<my-class>} are converted to be | |
1769 | instances of the new class. This is achieved by preserving the values | |
f60a8353 NJ |
1770 | of slots that exist in both the old and new definitions, and |
1771 | initializing the values of new slots in the usual way (@pxref{Instance | |
1772 | Creation,, make}). | |
a0e07ba4 NJ |
1773 | |
1774 | @item | |
1775 | All existing subclasses of @code{<my-class>} are redefined, as though | |
1776 | the @code{define-class} expressions that defined them were re-evaluated | |
1777 | following the redefinition of @code{<my-class>}, and the class | |
1778 | redefinition process described here is applied recursively to the | |
1779 | redefined subclasses. | |
1780 | ||
1781 | @item | |
1782 | Once all of its instances and subclasses have been updated, the class | |
1783 | metaobject previously bound to the variable @code{<my-class>} is no | |
1784 | longer needed and so can be allowed to be garbage collected. | |
1785 | @end itemize | |
1786 | ||
1787 | To keep things tidy, GOOPS also needs to do a little housekeeping on | |
1788 | methods that are associated with the redefined class. | |
1789 | ||
1790 | @itemize @bullet | |
1791 | @item | |
1792 | Slot accessor methods for slots in the old definition should be removed | |
1793 | from their generic functions. They will be replaced by accessor methods | |
1794 | for the slots of the new class definition. | |
1795 | ||
1796 | @item | |
1797 | Any generic function method that uses the old @code{<my-class>} metaobject | |
1798 | as one of its formal parameter specializers must be updated to refer to | |
1799 | the new @code{<my-class>} metaobject. (Whenever a new generic function | |
1800 | method is defined, @code{define-method} adds the method to a list stored | |
1801 | in the class metaobject for each class used as a formal parameter | |
1802 | specializer, so it is easy to identify all the methods that must be | |
1803 | updated when a class is redefined.) | |
1804 | @end itemize | |
1805 | ||
1806 | If this class redefinition strategy strikes you as rather counter-intuitive, | |
1807 | bear in mind that it is derived from similar behaviour in other object | |
1808 | systems such as CLOS, and that experience in those systems has shown it to be | |
1809 | very useful in practice. | |
1810 | ||
1811 | Also bear in mind that, like most of GOOPS' default behaviour, it can | |
1812 | be customized@dots{} | |
1813 | ||
1814 | @node Customizing Class Redefinition | |
c34d74ff | 1815 | @subsection Customizing Class Redefinition |
a0e07ba4 NJ |
1816 | |
1817 | When @code{define-class} notices that a class is being redefined, | |
1818 | it constructs the new class metaobject as usual, and then invokes the | |
1819 | @code{class-redefinition} generic function with the old and new classes | |
1820 | as arguments. Therefore, if the old or new classes have metaclasses | |
1821 | other than the default @code{<class>}, class redefinition behaviour can | |
1822 | be customized by defining a @code{class-redefinition} method that is | |
1823 | specialized for the relevant metaclasses. | |
1824 | ||
1825 | @deffn generic class-redefinition | |
1826 | Handle the class redefinition from @var{old-class} to @var{new-class}, | |
1827 | and return the new class metaobject that should be bound to the | |
1828 | variable specified by @code{define-class}'s first argument. | |
1829 | @end deffn | |
1830 | ||
1831 | @deffn method class-redefinition (old-class <class>) (new-class <class>) | |
1832 | Implements GOOPS' default class redefinition behaviour, as described in | |
1833 | @ref{Default Class Redefinition Behaviour}. Returns the metaobject | |
1834 | for the new class definition. | |
1835 | @end deffn | |
1836 | ||
1837 | An alternative class redefinition strategy could be to leave all | |
1838 | existing instances as instances of the old class, but accepting that the | |
1839 | old class is now ``nameless'', since its name has been taken over by the | |
1840 | new definition. In this strategy, any existing subclasses could also | |
1841 | be left as they are, on the understanding that they inherit from a nameless | |
1842 | superclass. | |
1843 | ||
1844 | This strategy is easily implemented in GOOPS, by defining a new metaclass, | |
1845 | that will be used as the metaclass for all classes to which the strategy | |
1846 | should apply, and then defining a @code{class-redefinition} method that | |
1847 | is specialized for this metaclass: | |
1848 | ||
1849 | @example | |
1850 | (define-class <can-be-nameless> (<class>)) | |
1851 | ||
45867c2a NJ |
1852 | (define-method (class-redefinition (old <can-be-nameless>) |
1853 | (new <class>)) | |
a0e07ba4 NJ |
1854 | new) |
1855 | @end example | |
1856 | ||
1857 | When customization can be as easy as this, aren't you glad that GOOPS | |
1858 | implements the far more difficult strategy as its default! | |
1859 | ||
1860 | Finally, note that, if @code{class-redefinition} itself is not customized, | |
1861 | the default @code{class-redefinition} method invokes three further | |
1862 | generic functions that could be individually customized: | |
1863 | ||
1864 | @itemize @bullet | |
1865 | @item | |
1866 | (remove-class-accessors! @var{old-class}) | |
1867 | ||
1868 | @item | |
1869 | (update-direct-method! @var{method} @var{old-class} @var{new-class}) | |
1870 | ||
1871 | @item | |
1872 | (update-direct-subclass! @var{subclass} @var{old-class} @var{new-class}) | |
1873 | @end itemize | |
1874 | ||
1875 | and the default methods for these generic functions invoke further | |
1876 | generic functions, and so on@dots{} The detailed protocol for all of these | |
1877 | is described in @ref{MOP Specification}. | |
1878 | ||
1879 | @node Changing the Class of an Instance | |
c34d74ff | 1880 | @section Changing the Class of an Instance |
a0e07ba4 NJ |
1881 | |
1882 | You can change the class of an existing instance by invoking the | |
1883 | generic function @code{change-class} with two arguments: the instance | |
1884 | and the new class. | |
1885 | ||
1886 | @deffn generic change-class | |
1887 | @end deffn | |
1888 | ||
1889 | The default method for @code{change-class} decides how to implement the | |
1890 | change of class by looking at the slot definitions for the instance's | |
1891 | existing class and for the new class. If the new class has slots with | |
1892 | the same name as slots in the existing class, the values for those slots | |
1893 | are preserved. Slots that are present only in the existing class are | |
1894 | discarded. Slots that are present only in the new class are initialized | |
1895 | using the corresponding slot definition's init function (@pxref{Classes,, | |
1896 | slot-init-function}). | |
1897 | ||
1898 | @deffn {method} change-class (obj <object>) (new <class>) | |
1899 | Modify instance @var{obj} to make it an instance of class @var{new}. | |
1900 | ||
1901 | The value of each of @var{obj}'s slots is preserved only if a similarly named | |
1902 | slot exists in @var{new}; any other slot values are discarded. | |
1903 | ||
1904 | The slots in @var{new} that do not correspond to any of @var{obj}'s | |
1905 | pre-existing slots are initialized according to @var{new}'s slot definitions' | |
1906 | init functions. | |
1907 | @end deffn | |
1908 | ||
1909 | Customized change of class behaviour can be implemented by defining | |
1910 | @code{change-class} methods that are specialized either by the class | |
1911 | of the instances to be modified or by the metaclass of the new class. | |
1912 | ||
1913 | When a class is redefined (@pxref{Redefining a Class}), and the default | |
1914 | class redefinition behaviour is not overridden, GOOPS (eventually) | |
1915 | invokes the @code{change-class} generic function for each existing | |
1916 | instance of the redefined class. | |
1917 | ||
eb12b401 | 1918 | @node GOOPS Error Handling |
1905db2b | 1919 | @section Error Handling |
a0e07ba4 NJ |
1920 | |
1921 | The procedure @code{goops-error} is called to raise an appropriate error | |
1922 | by the default methods of the following generic functions: | |
1923 | ||
1924 | @itemize @bullet | |
1925 | @item | |
1926 | @code{slot-missing} (@pxref{Handling Slot Access Errors,, slot-missing}) | |
1927 | ||
1928 | @item | |
1929 | @code{slot-unbound} (@pxref{Handling Slot Access Errors,, slot-unbound}) | |
1930 | ||
1931 | @item | |
1932 | @code{no-method} (@pxref{Handling Invocation Errors,, no-method}) | |
1933 | ||
1934 | @item | |
1935 | @code{no-applicable-method} (@pxref{Handling Invocation Errors,, | |
1936 | no-applicable-method}) | |
1937 | ||
1938 | @item | |
1939 | @code{no-next-method} (@pxref{Handling Invocation Errors,, | |
1940 | no-next-method}) | |
1941 | @end itemize | |
1942 | ||
1943 | If you customize these functions for particular classes or metaclasses, | |
1944 | you may still want to use @code{goops-error} to signal any error | |
1945 | conditions that you detect. | |
1946 | ||
1947 | @deffn procedure goops-error format-string . args | |
1948 | Raise an error with key @code{goops-error} and error message constructed | |
1949 | from @var{format-string} and @var{args}. Error message formatting is | |
1950 | as done by @code{scm-error}. | |
1951 | @end deffn | |
1952 | ||
1953 | @node Object Comparisons | |
1905db2b | 1954 | @section Object Comparisons |
a0e07ba4 | 1955 | |
b3a9e3d5 MD |
1956 | @deffn generic eqv? |
1957 | @deffnx method eqv? ((x <top>) (y <top>)) | |
1958 | @deffnx generic equal? | |
1959 | @deffnx method equal? ((x <top>) (y <top>)) | |
1960 | @deffnx generic = | |
1961 | @deffnx method = ((x <number>) (y <number>)) | |
a0e07ba4 NJ |
1962 | Generic functions and default (unspecialized) methods for comparing two |
1963 | GOOPS objects. | |
1964 | ||
b3a9e3d5 MD |
1965 | The default method for @code{eqv?} returns @code{#t} for all values |
1966 | that are equal in the sense defined by R5RS and the Guile reference | |
1967 | manual, otherwise @code{#f}. The default method for @code{equal?} | |
1968 | returns @code{#t} or @code{#f} in the sense defined by R5RS and the | |
1969 | Guile reference manual. If no such comparison is defined, | |
1970 | @code{equal?} returns the result of a call to @code{eqv?}. The | |
1971 | default method for = returns @code{#t} if @var{x} and @var{y} are | |
1972 | numerically equal, otherwise @code{#f}. | |
1973 | ||
1974 | Application class authors may wish to define specialized methods for | |
1975 | @code{eqv?}, @code{equal?} and @code{=} that compare instances of the | |
1976 | same class for equality in whatever sense is useful to the | |
1977 | application. Such methods will only be called if the arguments have | |
1978 | the same class and the result of the comparison isn't defined by R5RS | |
1979 | and the Guile reference manual. | |
a0e07ba4 NJ |
1980 | @end deffn |
1981 | ||
1982 | @node Cloning Objects | |
1905db2b | 1983 | @section Cloning Objects |
a0e07ba4 NJ |
1984 | |
1985 | @deffn generic shallow-clone | |
1986 | @deffnx method shallow-clone (self <object>) | |
1987 | Return a ``shallow'' clone of @var{self}. The default method makes a | |
1988 | shallow clone by allocating a new instance and copying slot values from | |
1989 | self to the new instance. Each slot value is copied either as an | |
1990 | immediate value or by reference. | |
1991 | @end deffn | |
1992 | ||
1993 | @deffn generic deep-clone | |
1994 | @deffnx method deep-clone (self <object>) | |
1995 | Return a ``deep'' clone of @var{self}. The default method makes a deep | |
1996 | clone by allocating a new instance and copying or cloning slot values | |
1997 | from self to the new instance. If a slot value is an instance | |
1998 | (satisfies @code{instance?}), it is cloned by calling @code{deep-clone} | |
1999 | on that value. Other slot values are copied either as immediate values | |
2000 | or by reference. | |
2001 | @end deffn | |
2002 | ||
2003 | @node Write and Display | |
1905db2b | 2004 | @section Write and Display |
a0e07ba4 NJ |
2005 | |
2006 | @deffn {primitive generic} write object port | |
2007 | @deffnx {primitive generic} display object port | |
2008 | When GOOPS is loaded, @code{write} and @code{display} become generic | |
2009 | functions with special methods for printing | |
2010 | ||
2011 | @itemize @bullet | |
2012 | @item | |
2013 | objects - instances of the class @code{<object>} | |
2014 | ||
2015 | @item | |
2016 | foreign objects - instances of the class @code{<foreign-object>} | |
2017 | ||
2018 | @item | |
2019 | classes - instances of the class @code{<class>} | |
2020 | ||
2021 | @item | |
2022 | generic functions - instances of the class @code{<generic>} | |
2023 | ||
2024 | @item | |
2025 | methods - instances of the class @code{<method>}. | |
2026 | @end itemize | |
2027 | ||
2028 | @code{write} and @code{display} print non-GOOPS values in the same way | |
2029 | as the Guile primitive @code{write} and @code{display} functions. | |
2030 | @end deffn | |
2031 | ||
a9bf12c2 NJ |
2032 | @node The Metaobject Protocol |
2033 | @section The Metaobject Protocol | |
a0e07ba4 | 2034 | |
5aaf0709 NJ |
2035 | GOOPS is based on a ``metaobject protocol'' (aka ``MOP'') derived from |
2036 | the ones used in CLOS (the Common Lisp Object System), tiny-clos (a | |
2037 | small Scheme implementation of a subset of CLOS functionality) and | |
2038 | STKlos. | |
a0e07ba4 | 2039 | |
a9bf12c2 | 2040 | GOOPS can be used by application authors at a basic level without any |
5aaf0709 NJ |
2041 | need to understand what the MOP is and how it works. On the other hand, |
2042 | the MOP underlies even very simple customizations --- such as defining | |
2043 | an @code{initialize} method to customize the initialization of instances | |
2044 | of an application-defined class --- and an understanding of the MOP | |
2045 | makes it much easier to explain such customizations in a precise way. | |
2046 | And in the long run, understanding the MOP is the key both to | |
a9bf12c2 NJ |
2047 | understanding GOOPS at a deeper level and to taking full advantage of |
2048 | GOOPS' power, by customizing the behaviour of GOOPS itself. | |
a0e07ba4 | 2049 | |
a9bf12c2 NJ |
2050 | @menu |
2051 | * Metaobjects and the Metaobject Protocol:: | |
2052 | * Terminology:: | |
2053 | * MOP Specification:: | |
58ad1de7 NJ |
2054 | * Class Definition Internals:: |
2055 | * Customizing Class Definition:: | |
9e57815d | 2056 | * Customizing Instance Creation:: |
a9bf12c2 NJ |
2057 | * Class Redefinition:: |
2058 | * Method Definition:: | |
de6b3a5c | 2059 | * Method Definition Internals:: |
eed4cc7b | 2060 | * Generic Function Internals:: |
a9bf12c2 NJ |
2061 | * Generic Function Invocation:: |
2062 | @end menu | |
2063 | ||
2064 | @node Metaobjects and the Metaobject Protocol | |
2065 | @subsection Metaobjects and the Metaobject Protocol | |
2066 | ||
5aaf0709 NJ |
2067 | The building blocks of GOOPS are classes, slot definitions, instances, |
2068 | generic functions and methods. A class is a grouping of inheritance | |
2069 | relations and slot definitions. An instance is an object with slots | |
2070 | that are allocated following the rules implied by its class's | |
a9bf12c2 NJ |
2071 | superclasses and slot definitions. A generic function is a collection |
2072 | of methods and rules for determining which of those methods to apply | |
2073 | when the generic function is invoked. A method is a procedure and a set | |
2074 | of specializers that specify the type of arguments to which the | |
2075 | procedure is applicable. | |
2076 | ||
2077 | Of these entities, GOOPS represents classes, generic functions and | |
2078 | methods as ``metaobjects''. In other words, the values in a GOOPS | |
2079 | program that describe classes, generic functions and methods, are | |
2080 | themselves instances (or ``objects'') of special GOOPS classes that | |
2081 | encapsulate the behaviour, respectively, of classes, generic functions, | |
2082 | and methods. | |
2083 | ||
2084 | (The other two entities are slot definitions and instances. Slot | |
2085 | definitions are not strictly instances, but every slot definition is | |
2086 | associated with a GOOPS class that specifies the behaviour of the slot | |
2087 | as regards accessibility and protection from garbage collection. | |
2088 | Instances are of course objects in the usual sense, and there is no | |
2089 | benefit from thinking of them as metaobjects.) | |
2090 | ||
2091 | The ``metaobject protocol'' (aka ``MOP'') is the specification of the | |
2092 | generic functions which determine the behaviour of these metaobjects and | |
2093 | the circumstances in which these generic functions are invoked. | |
2094 | ||
2095 | For a concrete example of what this means, consider how GOOPS calculates | |
2096 | the set of slots for a class that is being defined using | |
2097 | @code{define-class}. The desired set of slots is the union of the new | |
2098 | class's direct slots and the slots of all its superclasses. But | |
2099 | @code{define-class} itself does not perform this calculation. Instead, | |
2100 | there is a method of the @code{initialize} generic function that is | |
2101 | specialized for instances of type @code{<class>}, and it is this method | |
2102 | that performs the slot calculation. | |
2103 | ||
2104 | @code{initialize} is a generic function which GOOPS calls whenever a new | |
2105 | instance is created, immediately after allocating memory for a new | |
2106 | instance, in order to initialize the new instance's slots. The sequence | |
2107 | of steps is as follows. | |
2108 | ||
2109 | @itemize @bullet | |
2110 | @item | |
2111 | @code{define-class} uses @code{make} to make a new instance of the | |
5aaf0709 NJ |
2112 | @code{<class>} class, passing as initialization arguments the |
2113 | superclasses, slot definitions and class options that were specified in | |
2114 | the @code{define-class} form. | |
a9bf12c2 NJ |
2115 | |
2116 | @item | |
2117 | @code{make} allocates memory for the new instance, and then invokes the | |
2118 | @code{initialize} generic function to initialize the new instance's | |
2119 | slots. | |
2120 | ||
2121 | @item | |
2122 | The @code{initialize} generic function applies the method that is | |
2123 | specialized for instances of type @code{<class>}, and this method | |
2124 | performs the slot calculation. | |
2125 | @end itemize | |
2126 | ||
2127 | In other words, rather than being hardcoded in @code{define-class}, the | |
2128 | behaviour of class definition is encapsulated by generic function | |
2129 | methods that are specialized for the class @code{<class>}. | |
2130 | ||
2131 | It is possible to create a new class that inherits from @code{<class>}, | |
2132 | which is called a ``metaclass'', and to write a new @code{initialize} | |
2133 | method that is specialized for instances of the new metaclass. Then, if | |
2134 | the @code{define-class} form includes a @code{#:metaclass} class option | |
2135 | whose value is the new metaclass, the class that is defined by the | |
2136 | @code{define-class} form will be an instance of the new metaclass rather | |
2137 | than of the default @code{<class>}, and will be defined in accordance | |
2138 | with the new @code{initialize} method. Thus the default slot | |
2139 | calculation, as well as any other aspect of the new class's relationship | |
2140 | with its superclasses, can be modified or overridden. | |
2141 | ||
2142 | In a similar way, the behaviour of generic functions can be modified or | |
2143 | overridden by creating a new class that inherits from the standard | |
2144 | generic function class @code{<generic>}, writing appropriate methods | |
2145 | that are specialized to the new class, and creating new generic | |
2146 | functions that are instances of the new class. | |
2147 | ||
2148 | The same is true for method metaobjects. And the same basic mechanism | |
2149 | allows the application class author to write an @code{initialize} method | |
2150 | that is specialized to their application class, to initialize instances | |
2151 | of that class. | |
2152 | ||
2153 | Such is the power of the MOP. Note that @code{initialize} is just one | |
2154 | of a large number of generic functions that can be customized to modify | |
2155 | the behaviour of application objects and classes and of GOOPS itself. | |
5aaf0709 NJ |
2156 | Each following section covers a particular area of GOOPS functionality, |
2157 | and describes the generic functions that are relevant for customization | |
2158 | of that area. | |
2159 | ||
a9bf12c2 NJ |
2160 | @node Terminology |
2161 | @subsection Terminology | |
2162 | ||
2163 | It is assumed that the reader is already familiar with standard object | |
2164 | orientation concepts such as classes, objects/instances, | |
2165 | inheritance/subclassing, generic functions and methods, encapsulation | |
2166 | and polymorphism. | |
2167 | ||
2168 | This section explains some of the less well known concepts and | |
2169 | terminology that GOOPS uses, which are assumed by the following sections | |
2170 | of the reference manual. | |
2171 | ||
2172 | @subsubheading Metaclass | |
2173 | ||
2174 | A @dfn{metaclass} is the class of an object which represents a GOOPS | |
2175 | class. Put more succinctly, a metaclass is a class's class. | |
2176 | ||
2177 | Most GOOPS classes have the metaclass @code{<class>} and, by default, | |
2178 | any new class that is created using @code{define-class} has the | |
2179 | metaclass @code{<class>}. | |
2180 | ||
2181 | But what does this really mean? To find out, let's look in more detail | |
2182 | at what happens when a new class is created using @code{define-class}: | |
2183 | ||
2184 | @example | |
2185 | (define-class <my-class> (<object>) . slots) | |
2186 | @end example | |
2187 | ||
2188 | GOOPS actually expands the @code{define-class} form to something like | |
2189 | this | |
2190 | ||
2191 | @example | |
2192 | (define <my-class> (class (<object>) . slots)) | |
2193 | @end example | |
2194 | ||
2195 | and thence to | |
2196 | ||
2197 | @example | |
2198 | (define <my-class> | |
2199 | (make <class> #:supers (list <object>) #:slots slots)) | |
2200 | @end example | |
2201 | ||
2202 | In other words, the value of @code{<my-class>} is in fact an instance of | |
2203 | the class @code{<class>} with slot values specifying the superclasses | |
2204 | and slot definitions for the class @code{<my-class>}. (@code{#:supers} | |
2205 | and @code{#:slots} are initialization keywords for the @code{dsupers} | |
2206 | and @code{dslots} slots of the @code{<class>} class.) | |
2207 | ||
2208 | In order to take advantage of the full power of the GOOPS metaobject | |
2209 | protocol (@pxref{MOP Specification}), it is sometimes desirable to | |
2210 | create a new class with a metaclass other than the default | |
2211 | @code{<class>}. This is done by writing: | |
2212 | ||
2213 | @example | |
2214 | (define-class <my-class2> (<object>) | |
2215 | slot @dots{} | |
2216 | #:metaclass <my-metaclass>) | |
2217 | @end example | |
2218 | ||
2219 | GOOPS expands this to something like: | |
2220 | ||
2221 | @example | |
2222 | (define <my-class2> | |
2223 | (make <my-metaclass> #:supers (list <object>) #:slots slots)) | |
2224 | @end example | |
2225 | ||
2226 | In this case, the value of @code{<my-class2>} is an instance of the more | |
2227 | specialized class @code{<my-metaclass>}. Note that | |
2228 | @code{<my-metaclass>} itself must previously have been defined as a | |
2229 | subclass of @code{<class>}. For a full discussion of when and how it is | |
2230 | useful to define new metaclasses, see @ref{MOP Specification}. | |
2231 | ||
2232 | Now let's make an instance of @code{<my-class2>}: | |
2233 | ||
2234 | @example | |
2235 | (define my-object (make <my-class2> ...)) | |
2236 | @end example | |
2237 | ||
2238 | All of the following statements are correct expressions of the | |
2239 | relationships between @code{my-object}, @code{<my-class2>}, | |
2240 | @code{<my-metaclass>} and @code{<class>}. | |
2241 | ||
2242 | @itemize @bullet | |
2243 | @item | |
2244 | @code{my-object} is an instance of the class @code{<my-class2>}. | |
2245 | ||
2246 | @item | |
2247 | @code{<my-class2>} is an instance of the class @code{<my-metaclass>}. | |
2248 | ||
2249 | @item | |
2250 | @code{<my-metaclass>} is an instance of the class @code{<class>}. | |
2251 | ||
2252 | @item | |
2253 | The class of @code{my-object} is @code{<my-class2>}. | |
2254 | ||
2255 | @item | |
2256 | The metaclass of @code{my-object} is @code{<my-metaclass>}. | |
2257 | ||
2258 | @item | |
2259 | The class of @code{<my-class2>} is @code{<my-metaclass>}. | |
2260 | ||
2261 | @item | |
2262 | The metaclass of @code{<my-class2>} is @code{<class>}. | |
2263 | ||
2264 | @item | |
2265 | The class of @code{<my-metaclass>} is @code{<class>}. | |
2266 | ||
2267 | @item | |
2268 | The metaclass of @code{<my-metaclass>} is @code{<class>}. | |
2269 | ||
2270 | @item | |
2271 | @code{<my-class2>} is not a metaclass, since it is does not inherit from | |
2272 | @code{<class>}. | |
2273 | ||
2274 | @item | |
2275 | @code{<my-metaclass>} is a metaclass, since it inherits from | |
2276 | @code{<class>}. | |
2277 | @end itemize | |
2278 | ||
2279 | @subsubheading Class Precedence List | |
2280 | ||
2281 | The @dfn{class precedence list} of a class is the list of all direct and | |
2282 | indirect superclasses of that class, including the class itself. | |
2283 | ||
2284 | In the absence of multiple inheritance, the class precedence list is | |
2285 | ordered straightforwardly, beginning with the class itself and ending | |
2286 | with @code{<top>}. | |
2287 | ||
2288 | For example, given this inheritance hierarchy: | |
2289 | ||
2290 | @example | |
2291 | (define-class <invertebrate> (<object>) @dots{}) | |
2292 | (define-class <echinoderm> (<invertebrate>) @dots{}) | |
2293 | (define-class <starfish> (<echinoderm>) @dots{}) | |
2294 | @end example | |
2295 | ||
2296 | the class precedence list of <starfish> would be | |
2297 | ||
2298 | @example | |
2299 | (<starfish> <echinoderm> <invertebrate> <object> <top>) | |
2300 | @end example | |
2301 | ||
2302 | With multiple inheritance, the algorithm is a little more complicated. | |
2303 | A full description is provided by the GOOPS Tutorial: see @ref{Class | |
68f4fee1 | 2304 | Precedence List}. |
a9bf12c2 NJ |
2305 | |
2306 | ``Class precedence list'' is often abbreviated, in documentation and | |
2307 | Scheme variable names, to @dfn{cpl}. | |
2308 | ||
2309 | @subsubheading Accessor | |
2310 | ||
2311 | An @dfn{accessor} is a generic function with both reference and setter | |
2312 | methods. | |
2313 | ||
2314 | @example | |
2315 | (define-accessor perimeter) | |
2316 | @end example | |
2317 | ||
2318 | Reference methods for an accessor are defined in the same way as generic | |
2319 | function methods. | |
2320 | ||
2321 | @example | |
2322 | (define-method (perimeter (s <square>)) | |
2323 | (* 4 (side-length s))) | |
2324 | @end example | |
2325 | ||
2326 | Setter methods for an accessor are defined by specifying ``(setter | |
2327 | <accessor-name>)'' as the first parameter of the @code{define-method} | |
2328 | call. | |
2329 | ||
2330 | @example | |
2331 | (define-method ((setter perimeter) (s <square>) (n <number>)) | |
2332 | (set! (side-length s) (/ n 4))) | |
2333 | @end example | |
2334 | ||
2335 | Once an appropriate setter method has been defined in this way, it can | |
2336 | be invoked using the generalized @code{set!} syntax, as in: | |
2337 | ||
2338 | @example | |
2339 | (set! (perimeter s1) 18.3) | |
2340 | @end example | |
2341 | ||
2342 | @node MOP Specification | |
2343 | @subsection MOP Specification | |
2344 | ||
2345 | The aim of the MOP specification in this chapter is to specify all the | |
2346 | customizable generic function invocations that can be made by the standard | |
2347 | GOOPS syntax, procedures and methods, and to explain the protocol for | |
2348 | customizing such invocations. | |
2349 | ||
2350 | A generic function invocation is customizable if the types of the arguments | |
2351 | to which it is applied are not all determined by the lexical context in | |
2352 | which the invocation appears. For example, | |
2353 | ||
2354 | @itemize @bullet | |
2355 | @item | |
2356 | the @code{(initialize @var{instance} @var{initargs})} invocation in the | |
2357 | default @code{make-instance} method is customizable, because the type of the | |
2358 | @code{@var{instance}} argument is determined by the class that was passed to | |
2359 | @code{make-instance}. | |
a0e07ba4 NJ |
2360 | |
2361 | @item | |
2362 | the @code{(make <generic> #:name ',name)} invocation in @code{define-generic} | |
2363 | is not customizable, because all of its arguments have lexically determined | |
2364 | types. | |
2365 | @end itemize | |
2366 | ||
2367 | When using this rule to decide whether a given generic function invocation | |
2368 | is customizable, we ignore arguments that are expected to be handled in | |
2369 | method definitions as a single ``rest'' list argument. | |
2370 | ||
2371 | For each customizable generic function invocation, the @dfn{invocation | |
2372 | protocol} is explained by specifying | |
2373 | ||
2374 | @itemize @bullet | |
2375 | @item | |
2376 | what, conceptually, the applied method is intended to do | |
2377 | ||
2378 | @item | |
2379 | what assumptions, if any, the caller makes about the applied method's side | |
2380 | effects | |
2381 | ||
2382 | @item | |
2383 | what the caller expects to get as the applied method's return value. | |
2384 | @end itemize | |
2385 | ||
f60a8353 NJ |
2386 | @node Class Definition Internals |
2387 | @subsection Class Definition Internals | |
a0e07ba4 NJ |
2388 | |
2389 | @code{define-class} (syntax) | |
2390 | ||
2391 | @itemize @bullet | |
2392 | @item | |
2393 | @code{class} (syntax) | |
2394 | ||
2395 | @itemize @bullet | |
2396 | @item | |
2397 | @code{make-class} (procedure) | |
2398 | ||
2399 | @itemize @bullet | |
2400 | @item | |
2401 | @code{make @var{metaclass} @dots{}} (generic) | |
2402 | ||
2403 | @var{metaclass} is the metaclass of the class being defined, either | |
2404 | taken from the @code{#:metaclass} class option or computed by | |
2405 | @code{ensure-metaclass}. The applied method must create and return the | |
2406 | fully initialized class metaobject for the new class definition. | |
2407 | @end itemize | |
2408 | ||
2409 | @end itemize | |
2410 | ||
2411 | @item | |
2412 | @code{class-redefinition @var{old-class} @var{new-class}} (generic) | |
2413 | ||
2414 | @code{define-class} calls @code{class-redefinition} if the variable | |
2415 | specified by its first argument already held a GOOPS class definition. | |
2416 | @var{old-class} and @var{new-class} are the old and new class metaobjects. | |
2417 | The applied method should perform whatever is necessary to handle the | |
2418 | redefinition, and should return the class metaobject that is to be bound | |
2419 | to @code{define-class}'s variable. The default class redefinition | |
2420 | protocol is described in @ref{Class Redefinition}. | |
2421 | @end itemize | |
2422 | ||
2423 | The @code{(make @var{metaclass} @dots{})} invocation above will create | |
2424 | an class metaobject with metaclass @var{metaclass}. By default, this | |
2425 | metaobject will be initialized by the @code{initialize} method that is | |
2426 | specialized for instances of type @code{<class>}. | |
2427 | ||
2428 | @code{initialize <class> @var{initargs}} (method) | |
2429 | ||
2430 | @itemize @bullet | |
2431 | @item | |
2432 | @code{compute-cpl @var{class}} (generic) | |
2433 | ||
2434 | The applied method should compute and return the class precedence list | |
2435 | for @var{class} as a list of class metaobjects. When @code{compute-cpl} | |
2436 | is called, the following @var{class} metaobject slots have all been | |
2437 | initialized: @code{name}, @code{direct-supers}, @code{direct-slots}, | |
2438 | @code{direct-subclasses} (empty), @code{direct-methods}. The value | |
2439 | returned by @code{compute-cpl} will be stored in the @code{cpl} slot. | |
2440 | ||
2441 | @item | |
2442 | @code{compute-slots @var{class}} (generic) | |
2443 | ||
2444 | The applied method should compute and return the slots (union of direct | |
2445 | and inherited) for @var{class} as a list of slot definitions. When | |
2446 | @code{compute-slots} is called, all the @var{class} metaobject slots | |
2447 | mentioned for @code{compute-cpl} have been initialized, plus the | |
2448 | following: @code{cpl}, @code{redefined} (@code{#f}), @code{environment}. | |
2449 | The value returned by @code{compute-slots} will be stored in the | |
2450 | @code{slots} slot. | |
2451 | ||
2452 | @item | |
2453 | @code{compute-get-n-set @var{class} @var{slot-def}} (generic) | |
2454 | ||
2455 | @code{initialize} calls @code{compute-get-n-set} for each slot computed | |
2456 | by @code{compute-slots}. The applied method should compute and return a | |
2457 | pair of closures that, respectively, get and set the value of the specified | |
2458 | slot. The get closure should have arity 1 and expect a single argument | |
2459 | that is the instance whose slot value is to be retrieved. The set closure | |
2460 | should have arity 2 and expect two arguments, where the first argument is | |
2461 | the instance whose slot value is to be set and the second argument is the | |
2462 | new value for that slot. The closures should be returned in a two element | |
2463 | list: @code{(list @var{get} @var{set})}. | |
2464 | ||
2465 | The closures returned by @code{compute-get-n-set} are stored as part of | |
2466 | the value of the @var{class} metaobject's @code{getters-n-setters} slot. | |
2467 | Specifically, the value of this slot is a list with the same number of | |
2468 | elements as there are slots in the class, and each element looks either like | |
2469 | ||
2470 | @example | |
2471 | @code{(@var{slot-name-symbol} @var{init-function} . @var{index})} | |
2472 | @end example | |
2473 | ||
2474 | or like | |
2475 | ||
2476 | @example | |
2477 | @code{(@var{slot-name-symbol} @var{init-function} @var{get} @var{set})} | |
2478 | @end example | |
2479 | ||
2480 | Where the get and set closures are replaced by @var{index}, the slot is | |
2481 | an instance slot and @var{index} is the slot's index in the underlying | |
2482 | structure: GOOPS knows how to get and set the value of such slots and so | |
2483 | does not need specially constructed get and set closures. Otherwise, | |
2484 | @var{get} and @var{set} are the closures returned by @code{compute-get-n-set}. | |
2485 | ||
2486 | The structure of the @code{getters-n-setters} slot value is important when | |
2487 | understanding the next customizable generic functions that @code{initialize} | |
2488 | calls@dots{} | |
2489 | ||
2490 | @item | |
2491 | @code{compute-getter-method @var{class} @var{gns}} (generic) | |
2492 | ||
2493 | @code{initialize} calls @code{compute-getter-method} for each of the class's | |
2494 | slots (as determined by @code{compute-slots}) that includes a | |
2495 | @code{#:getter} or @code{#:accessor} slot option. @var{gns} is the | |
2496 | element of the @var{class} metaobject's @code{getters-n-setters} slot that | |
2497 | specifies how the slot in question is referenced and set, as described | |
2498 | above under @code{compute-get-n-set}. The applied method should create | |
2499 | and return a method that is specialized for instances of type @var{class} | |
2500 | and uses the get closure to retrieve the slot's value. [ *fixme Need | |
2501 | to insert something here about checking that the value is not unbound. ] | |
2502 | @code{initialize} uses @code{add-method!} to add the returned method to | |
2503 | the generic function named by the slot definition's @code{#:getter} or | |
2504 | @code{#:accessor} option. | |
2505 | ||
2506 | @item | |
2507 | @code{compute-setter-method @var{class} @var{gns}} (generic) | |
2508 | ||
2509 | @code{compute-setter-method} is invoked with the same arguments as | |
2510 | @code{compute-getter-method}, for each of the class's slots that includes | |
2511 | a @code{#:setter} or @code{#:accessor} slot option. The applied method | |
2512 | should create and return a method that is specialized for instances of | |
2513 | type @var{class} and uses the set closure to set the slot's value. | |
2514 | @code{initialize} then uses @code{add-method!} to add the returned method | |
2515 | to the generic function named by the slot definition's @code{#:setter} | |
2516 | or @code{#:accessor} option. | |
2517 | @end itemize | |
2518 | ||
58ad1de7 NJ |
2519 | @code{define-class} expands to an expression which |
2520 | ||
2521 | @itemize @bullet | |
2522 | @item | |
2523 | checks that it is being evaluated only at top level | |
2524 | ||
2525 | @item | |
2526 | defines any accessors that are implied by the @var{slot-definition}s | |
2527 | ||
2528 | @item | |
2529 | uses @code{class} to create the new class (@pxref{Class Definition | |
2530 | Internals,, class}) | |
2531 | ||
2532 | @item | |
2533 | checks for a previous class definition for @var{name} and, if found, | |
2534 | handles the redefinition by invoking @code{class-redefinition} | |
2535 | (@pxref{Redefining a Class}). | |
2536 | @end itemize | |
2537 | ||
2538 | @deffn syntax class name (super @dots{}) slot-definition @dots{} . options | |
2539 | Return a newly created class that inherits from @var{super}s, with | |
2540 | direct slots defined by @var{slot-definition}s and class options | |
2541 | @var{options}. For the format of @var{slot-definition}s and | |
f60a8353 | 2542 | @var{options}, see @ref{Class Definition,, define-class}. |
58ad1de7 NJ |
2543 | @end deffn |
2544 | ||
2545 | @noindent @code{class} expands to an expression which | |
2546 | ||
2547 | @itemize @bullet | |
2548 | @item | |
2549 | processes the class and slot definition options to check that they are | |
2550 | well-formed, to convert the @code{#:init-form} option to an | |
2551 | @code{#:init-thunk} option, to supply a default environment parameter | |
2552 | (the current top-level environment) and to evaluate all the bits that | |
2553 | need to be evaluated | |
2554 | ||
2555 | @item | |
2556 | calls @code{make-class} to create the class with the processed and | |
2557 | evaluated parameters. | |
2558 | @end itemize | |
2559 | ||
2560 | @deffn procedure make-class supers slots . options | |
2561 | Return a newly created class that inherits from @var{supers}, with | |
2562 | direct slots defined by @var{slots} and class options @var{options}. | |
f60a8353 NJ |
2563 | For the format of @var{slots} and @var{options}, see @ref{Class |
2564 | Definition,, define-class}, except note that for @code{make-class}, | |
58ad1de7 NJ |
2565 | @var{slots} and @var{options} are separate list parameters: @var{slots} |
2566 | here is a list of slot definitions. | |
2567 | @end deffn | |
2568 | ||
2569 | @noindent @code{make-class} | |
2570 | ||
2571 | @itemize @bullet | |
2572 | @item | |
2573 | adds @code{<object>} to the @var{supers} list if @var{supers} is empty | |
2574 | or if none of the classes in @var{supers} have @code{<object>} in their | |
2575 | class precedence list | |
2576 | ||
2577 | @item | |
2578 | defaults the @code{#:environment}, @code{#:name} and @code{#:metaclass} | |
2579 | options, if they are not specified by @var{options}, to the current | |
2580 | top-level environment, the unbound value, and @code{(ensure-metaclass | |
2581 | @var{supers})} respectively (@pxref{Class Definition Internals,, | |
2582 | ensure-metaclass}) | |
2583 | ||
2584 | @item | |
2585 | checks for duplicate classes in @var{supers} and duplicate slot names in | |
2586 | @var{slots}, and signals an error if there are any duplicates | |
2587 | ||
2588 | @item | |
2589 | calls @code{make}, passing the metaclass as the first parameter and all | |
2590 | other parameters as option keywords with values. | |
2591 | @end itemize | |
2592 | ||
2593 | @deffn procedure ensure-metaclass supers env | |
2594 | Return a metaclass suitable for a class that inherits from the list of | |
2595 | classes in @var{supers}. The returned metaclass is the union by | |
2596 | inheritance of the metaclasses of the classes in @var{supers}. | |
2597 | ||
2598 | In the simplest case, where all the @var{supers} are straightforward | |
2599 | classes with metaclass @code{<class>}, the returned metaclass is just | |
2600 | @code{<class>}. | |
2601 | ||
2602 | For a more complex example, suppose that @var{supers} contained one | |
2603 | class with metaclass @code{<operator-class>} and one with metaclass | |
2604 | @code{<foreign-object-class>}. Then the returned metaclass would be a | |
2605 | class that inherits from both @code{<operator-class>} and | |
2606 | @code{<foreign-object-class>}. | |
2607 | ||
2608 | If @var{supers} is the empty list, @code{ensure-metaclass} returns the | |
2609 | default GOOPS metaclass @code{<class>}. | |
2610 | ||
2611 | GOOPS keeps a list of the metaclasses created by | |
2612 | @code{ensure-metaclass}, so that each required type of metaclass only | |
2613 | has to be created once. | |
2614 | ||
2615 | The @code{env} parameter is ignored. | |
2616 | @end deffn | |
2617 | ||
2618 | @deffn procedure ensure-metaclass-with-supers meta-supers | |
2619 | @code{ensure-metaclass-with-supers} is an internal procedure used by | |
2620 | @code{ensure-metaclass} (@pxref{Class Definition Internals,, | |
2621 | ensure-metaclass}). It returns a metaclass that is the union by | |
2622 | inheritance of the metaclasses in @var{meta-supers}. | |
2623 | @end deffn | |
2624 | ||
2625 | The internals of @code{make}, which is ultimately used to create the new | |
2626 | class object, are described in @ref{Customizing Instance Creation}, | |
2627 | which covers the creation and initialization of instances in general. | |
2628 | ||
2629 | @node Customizing Class Definition | |
2630 | @subsection Customizing Class Definition | |
2631 | ||
2632 | During the initialization of a new class, GOOPS calls a number of generic | |
2633 | functions with the newly allocated class instance as the first | |
2634 | argument. Specifically, GOOPS calls the generic function | |
2635 | ||
2636 | @itemize @bullet | |
2637 | @item | |
2638 | (initialize @var{class} @dots{}) | |
2639 | @end itemize | |
2640 | ||
2641 | where @var{class} is the newly allocated class instance, and the default | |
2642 | @code{initialize} method for arguments of type @code{<class>} calls the | |
2643 | generic functions | |
2644 | ||
2645 | @itemize @bullet | |
2646 | @item | |
2647 | (compute-cpl @var{class}) | |
2648 | ||
2649 | @item | |
2650 | (compute-slots @var{class}) | |
2651 | ||
2652 | @item | |
2653 | (compute-get-n-set @var{class} @var{slot-def}), for each of the slot | |
2654 | definitions returned by @code{compute-slots} | |
2655 | ||
2656 | @item | |
2657 | (compute-getter-method @var{class} @var{slot-def}), for each of the | |
2658 | slot definitions returned by @code{compute-slots} that includes a | |
2659 | @code{#:getter} or @code{#:accessor} slot option | |
2660 | ||
2661 | @item | |
2662 | (compute-setter-method @var{class} @var{slot-def}), for each of the | |
2663 | slot definitions returned by @code{compute-slots} that includes a | |
2664 | @code{#:setter} or @code{#:accessor} slot option. | |
2665 | @end itemize | |
2666 | ||
2667 | If the metaclass of the new class is something more specialized than the | |
2668 | default @code{<class>}, then the type of @var{class} in the calls above | |
2669 | is more specialized than @code{<class>}, and hence it becomes possible | |
2670 | to define generic function methods, specialized for the new class's | |
2671 | metaclass, that can modify or override the default behaviour of | |
2672 | @code{initialize}, @code{compute-cpl} or @code{compute-get-n-set}. | |
2673 | ||
2674 | @code{compute-cpl} computes the class precedence list (``CPL'') for the | |
68f4fee1 | 2675 | new class (@pxref{Class Precedence List}), and returns it as a list of |
58ad1de7 NJ |
2676 | class objects. The CPL is important because it defines a superclass |
2677 | ordering that is used, when a generic function is invoked upon an | |
2678 | instance of the class, to decide which of the available generic function | |
2679 | methods is the most specific. Hence @code{compute-cpl} could be | |
2680 | customized in order to modify the CPL ordering algorithm for all classes | |
2681 | with a special metaclass. | |
2682 | ||
2683 | The default CPL algorithm is encapsulated by the @code{compute-std-cpl} | |
2684 | procedure, which is in turn called by the default @code{compute-cpl} | |
2685 | method. | |
2686 | ||
2687 | @deffn procedure compute-std-cpl class | |
2688 | Compute and return the class precedence list for @var{class} according | |
68f4fee1 | 2689 | to the algorithm described in @ref{Class Precedence List}. |
58ad1de7 NJ |
2690 | @end deffn |
2691 | ||
2692 | @code{compute-slots} computes and returns a list of all slot definitions | |
2693 | for the new class. By default, this list includes the direct slot | |
2694 | definitions from the @code{define-class} form, plus the slot definitions | |
2695 | that are inherited from the new class's superclasses. The default | |
2696 | @code{compute-slots} method uses the CPL computed by @code{compute-cpl} | |
2697 | to calculate this union of slot definitions, with the rule that slots | |
2698 | inherited from superclasses are shadowed by direct slots with the same | |
2699 | name. One possible reason for customizing @code{compute-slots} would be | |
2700 | to implement an alternative resolution strategy for slot name conflicts. | |
2701 | ||
2702 | @code{compute-get-n-set} computes the low-level closures that will be | |
2703 | used to get and set the value of a particular slot, and returns them in | |
2704 | a list with two elements. | |
2705 | ||
2706 | The closures returned depend on how storage for that slot is allocated. | |
2707 | The standard @code{compute-get-n-set} method, specialized for classes of | |
2708 | type @code{<class>}, handles the standard GOOPS values for the | |
2709 | @code{#:allocation} slot option (@pxref{Slot Options,, allocation}). By | |
2710 | defining a new @code{compute-get-n-set} method for a more specialized | |
2711 | metaclass, it is possible to support new types of slot allocation. | |
2712 | ||
2713 | Suppose you wanted to create a large number of instances of some class | |
2714 | with a slot that should be shared between some but not all instances of | |
2715 | that class - say every 10 instances should share the same slot storage. | |
2716 | The following example shows how to implement and use a new type of slot | |
2717 | allocation to do this. | |
2718 | ||
2719 | @example | |
2720 | (define-class <batched-allocation-metaclass> (<class>)) | |
2721 | ||
2722 | (let ((batch-allocation-count 0) | |
2723 | (batch-get-n-set #f)) | |
2724 | (define-method (compute-get-n-set | |
2725 | (class <batched-allocation-metaclass>) s) | |
2726 | (case (slot-definition-allocation s) | |
2727 | ((#:batched) | |
2728 | ;; If we've already used the same slot storage for 10 instances, | |
2729 | ;; reset variables. | |
2730 | (if (= batch-allocation-count 10) | |
2731 | (begin | |
2732 | (set! batch-allocation-count 0) | |
2733 | (set! batch-get-n-set #f))) | |
2734 | ;; If we don't have a current pair of get and set closures, | |
2735 | ;; create one. make-closure-variable returns a pair of closures | |
2736 | ;; around a single Scheme variable - see goops.scm for details. | |
2737 | (or batch-get-n-set | |
2738 | (set! batch-get-n-set (make-closure-variable))) | |
2739 | ;; Increment the batch allocation count. | |
2740 | (set! batch-allocation-count (+ batch-allocation-count 1)) | |
2741 | batch-get-n-set) | |
2742 | ||
2743 | ;; Call next-method to handle standard allocation types. | |
2744 | (else (next-method))))) | |
2745 | ||
2746 | (define-class <class-using-batched-slot> () | |
2747 | ... | |
2748 | (c #:allocation #:batched) | |
2749 | ... | |
2750 | #:metaclass <batched-allocation-metaclass>) | |
2751 | @end example | |
2752 | ||
2753 | The usage of @code{compute-getter-method} and @code{compute-setter-method} | |
2754 | is described in @ref{MOP Specification}. | |
2755 | ||
2756 | @code{compute-cpl} and @code{compute-get-n-set} are called by the | |
2757 | standard @code{initialize} method for classes whose metaclass is | |
2758 | @code{<class>}. But @code{initialize} itself can also be modified, by | |
2759 | defining an @code{initialize} method specialized to the new class's | |
2760 | metaclass. Such a method could complete override the standard | |
2761 | behaviour, by not calling @code{(next-method)} at all, but more | |
2762 | typically it would perform additional class initialization steps before | |
2763 | and/or after calling @code{(next-method)} for the standard behaviour. | |
2764 | ||
f60a8353 NJ |
2765 | @node Customizing Instance Creation |
2766 | @subsection Customizing Instance Creation | |
a0e07ba4 NJ |
2767 | |
2768 | @code{make <class> . @var{initargs}} (method) | |
2769 | ||
2770 | @itemize @bullet | |
2771 | @item | |
2772 | @code{allocate-instance @var{class} @var{initargs}} (generic) | |
2773 | ||
2774 | The applied @code{allocate-instance} method should allocate storage for | |
2775 | a new instance of class @var{class} and return the uninitialized instance. | |
2776 | ||
2777 | @item | |
2778 | @code{initialize @var{instance} @var{initargs}} (generic) | |
2779 | ||
2780 | @var{instance} is the uninitialized instance returned by | |
2781 | @code{allocate-instance}. The applied method should initialize the new | |
2782 | instance in whatever sense is appropriate for its class. The method's | |
2783 | return value is ignored. | |
2784 | @end itemize | |
2785 | ||
9e57815d NJ |
2786 | @code{make} itself is a generic function. Hence the @code{make} |
2787 | invocation itself can be customized in the case where the new instance's | |
2788 | metaclass is more specialized than the default @code{<class>}, by | |
2789 | defining a @code{make} method that is specialized to that metaclass. | |
2790 | ||
2791 | Normally, however, the method for classes with metaclass @code{<class>} | |
2792 | will be applied. This method calls two generic functions: | |
2793 | ||
2794 | @itemize @bullet | |
2795 | @item | |
2796 | (allocate-instance @var{class} . @var{initargs}) | |
2797 | ||
2798 | @item | |
2799 | (initialize @var{instance} . @var{initargs}) | |
2800 | @end itemize | |
2801 | ||
2802 | @code{allocate-instance} allocates storage for and returns the new | |
2803 | instance, uninitialized. You might customize @code{allocate-instance}, | |
2804 | for example, if you wanted to provide a GOOPS wrapper around some other | |
2805 | object programming system. | |
2806 | ||
2807 | To do this, you would create a specialized metaclass, which would act as | |
2808 | the metaclass for all classes and instances from the other system. Then | |
2809 | define an @code{allocate-instance} method, specialized to that | |
2810 | metaclass, which calls a Guile primitive C function, which in turn | |
2811 | allocates the new instance using the interface of the other object | |
2812 | system. | |
2813 | ||
2814 | In this case, for a complete system, you would also need to customize a | |
2815 | number of other generic functions like @code{make} and | |
2816 | @code{initialize}, so that GOOPS knows how to make classes from the | |
2817 | other system, access instance slots, and so on. | |
2818 | ||
2819 | @code{initialize} initializes the instance that is returned by | |
2820 | @code{allocate-instance}. The standard GOOPS methods perform | |
2821 | initializations appropriate to the instance class. | |
2822 | ||
2823 | @itemize @bullet | |
2824 | @item | |
2825 | At the least specialized level, the method for instances of type | |
2826 | @code{<object>} performs internal GOOPS instance initialization, and | |
2827 | initializes the instance's slots according to the slot definitions and | |
2828 | any slot initialization keywords that appear in @var{initargs}. | |
2829 | ||
2830 | @item | |
2831 | The method for instances of type @code{<class>} calls | |
2832 | @code{(next-method)}, then performs the class initializations described | |
2833 | in @ref{Customizing Class Definition}. | |
2834 | ||
2835 | @item | |
2836 | and so on for generic functions, method, operator classes @dots{} | |
2837 | @end itemize | |
2838 | ||
2839 | Similarly, you can customize the initialization of instances of any | |
2840 | application-defined class by defining an @code{initialize} method | |
2841 | specialized to that class. | |
2842 | ||
2843 | Imagine a class whose instances' slots need to be initialized at | |
2844 | instance creation time by querying a database. Although it might be | |
2845 | possible to achieve this a combination of @code{#:init-thunk} keywords | |
2846 | and closures in the slot definitions, it is neater to write an | |
2847 | @code{initialize} method for the class that queries the database once | |
2848 | and initializes all the dependent slot values according to the results. | |
2849 | ||
a0e07ba4 | 2850 | @node Class Redefinition |
eb12b401 | 2851 | @subsection Class Redefinition |
a0e07ba4 NJ |
2852 | |
2853 | The default @code{class-redefinition} method, specialized for classes | |
2854 | with the default metaclass @code{<class>}, has the following internal | |
2855 | protocol. | |
2856 | ||
eb12b401 | 2857 | @code{class-redefinition (@var{old <class>}) (@var{new <class>})} |
a0e07ba4 NJ |
2858 | (method) |
2859 | ||
2860 | @itemize @bullet | |
2861 | @item | |
2862 | @code{remove-class-accessors! @var{old}} (generic) | |
2863 | ||
2864 | @item | |
2865 | @code{update-direct-method! @var{method} @var{old} @var{new}} (generic) | |
2866 | ||
2867 | @item | |
2868 | @code{update-direct-subclass! @var{subclass} @var{old} @var{new}} (generic) | |
2869 | @end itemize | |
2870 | ||
da901526 MD |
2871 | This protocol cleans up things that the definition of the old class |
2872 | once changed and modifies things to work with the new class. | |
2873 | ||
2874 | The default @code{remove-class-accessors!} method removes the | |
2875 | accessor methods of the old class from all classes which they | |
2876 | specialize. | |
2877 | ||
2878 | The default @code{update-direct-method!} method substitutes the new | |
2879 | class for the old in all methods specialized to the old class. | |
2880 | ||
a0e07ba4 | 2881 | The default @code{update-direct-subclass!} method invokes |
da901526 MD |
2882 | @code{class-redefinition} recursively to handle the redefinition of |
2883 | subclasses. | |
a0e07ba4 NJ |
2884 | |
2885 | When a class is redefined, any existing instance of the redefined class | |
2886 | will be modified for the new class definition before the next time that | |
2887 | any of the instance's slot is referenced or set. GOOPS modifies each | |
da901526 | 2888 | instance by calling the generic function @code{change-class}. |
a0e07ba4 NJ |
2889 | |
2890 | The default @code{change-class} method copies slot values from the old | |
ddee39a1 | 2891 | to the modified instance, and initializes new slots, as described in |
a0e07ba4 NJ |
2892 | @ref{Changing the Class of an Instance}. After doing so, it makes a |
2893 | generic function invocation that can be used to customize the instance | |
2894 | update algorithm. | |
2895 | ||
eb12b401 | 2896 | @code{change-class (@var{old-instance <object>}) (@var{new <class>})} (method) |
a0e07ba4 NJ |
2897 | |
2898 | @itemize @bullet | |
2899 | @item | |
2900 | @code{update-instance-for-different-class @var{old-instance} @var{new-instance}} (generic) | |
2901 | ||
2902 | @code{change-class} invokes @code{update-instance-for-different-class} | |
2903 | as the last thing that it does before returning. The applied method can | |
2904 | make any further adjustments to @var{new-instance} that are required to | |
2905 | complete or modify the change of class. The return value from the | |
2906 | applied method is ignored. | |
2907 | ||
2908 | The default @code{update-instance-for-different-class} method does | |
2909 | nothing. | |
2910 | @end itemize | |
2911 | ||
2912 | @node Method Definition | |
eb12b401 | 2913 | @subsection Method Definition |
a0e07ba4 NJ |
2914 | |
2915 | @code{define-method} (syntax) | |
2916 | ||
2917 | @itemize @bullet | |
2918 | @item | |
2919 | @code{add-method! @var{target} @var{method}} (generic) | |
2920 | ||
2921 | @code{define-method} invokes the @code{add-method!} generic function to | |
2922 | handle adding the new method to a variety of possible targets. GOOPS | |
2923 | includes methods to handle @var{target} as | |
2924 | ||
2925 | @itemize @bullet | |
2926 | @item | |
2927 | a generic function (the most common case) | |
2928 | ||
2929 | @item | |
2930 | a procedure | |
2931 | ||
2932 | @item | |
eed4cc7b | 2933 | a primitive generic (@pxref{Extending Primitives}) |
a0e07ba4 NJ |
2934 | @end itemize |
2935 | ||
2936 | By defining further methods for @code{add-method!}, you can | |
2937 | theoretically handle adding methods to further types of target. | |
2938 | @end itemize | |
2939 | ||
de6b3a5c NJ |
2940 | @node Method Definition Internals |
2941 | @subsection Method Definition Internals | |
2942 | ||
2943 | @code{define-method} | |
2944 | ||
2945 | @itemize @bullet | |
2946 | @item | |
2947 | checks the form of the first parameter, and applies the following steps | |
2948 | to the accessor's setter if it has the @code{(setter @dots{})} form | |
2949 | ||
2950 | @item | |
2951 | interpolates a call to @code{define-generic} or @code{define-accessor} | |
2952 | if a generic function is not already defined with the supplied name | |
2953 | ||
2954 | @item | |
2955 | calls @code{method} with the @var{parameter}s and @var{body}, to make a | |
2956 | new method instance | |
2957 | ||
2958 | @item | |
2959 | calls @code{add-method!} to add this method to the relevant generic | |
2960 | function. | |
2961 | @end itemize | |
2962 | ||
2963 | @deffn syntax method (parameter @dots{}) . body | |
2964 | Make a method whose specializers are defined by the classes in | |
2965 | @var{parameter}s and whose procedure definition is constructed from the | |
2966 | @var{parameter} symbols and @var{body} forms. | |
2967 | ||
2968 | The @var{parameter} and @var{body} parameters should be as for | |
68f4fee1 | 2969 | @code{define-method} (@pxref{Methods and Generic Functions,, |
de6b3a5c NJ |
2970 | define-method}). |
2971 | @end deffn | |
2972 | ||
2973 | @code{method} | |
2974 | ||
2975 | @itemize @bullet | |
2976 | @item | |
2977 | extracts formals and specializing classes from the @var{parameter}s, | |
2978 | defaulting the class for unspecialized parameters to @code{<top>} | |
2979 | ||
2980 | @item | |
2981 | creates a closure using the formals and the @var{body} forms | |
2982 | ||
2983 | @item | |
2984 | calls @code{make} with metaclass @code{<method>} and the specializers | |
2985 | and closure using the @code{#:specializers} and @code{#:procedure} | |
2986 | keywords. | |
2987 | @end itemize | |
2988 | ||
2989 | @deffn procedure make-method specializers procedure | |
2990 | Make a method using @var{specializers} and @var{procedure}. | |
2991 | ||
2992 | @var{specializers} should be a list of classes that specifies the | |
2993 | parameter combinations to which this method will be applicable. | |
2994 | ||
2995 | @var{procedure} should be the closure that will applied to the generic | |
2996 | function parameters when this method is invoked. | |
2997 | @end deffn | |
2998 | ||
2999 | @code{make-method} is a simple wrapper around @code{make} with metaclass | |
3000 | @code{<method>}. | |
3001 | ||
3002 | @deffn generic add-method! target method | |
3003 | Generic function for adding method @var{method} to @var{target}. | |
3004 | @end deffn | |
3005 | ||
3006 | @deffn method add-method! (generic <generic>) (method <method>) | |
3007 | Add method @var{method} to the generic function @var{generic}. | |
3008 | @end deffn | |
3009 | ||
3010 | @deffn method add-method! (proc <procedure>) (method <method>) | |
3011 | If @var{proc} is a procedure with generic capability (@pxref{Extending | |
3012 | Primitives,, generic-capability?}), upgrade it to a primitive generic | |
3013 | and add @var{method} to its generic function definition. | |
3014 | @end deffn | |
3015 | ||
3016 | @deffn method add-method! (pg <primitive-generic>) (method <method>) | |
3017 | Add method @var{method} to the generic function definition of @var{pg}. | |
3018 | ||
3019 | Implementation: @code{(add-method! (primitive-generic-generic pg) method)}. | |
3020 | @end deffn | |
3021 | ||
3022 | @deffn method add-method! (whatever <top>) (method <method>) | |
3023 | Raise an error indicating that @var{whatever} is not a valid generic | |
3024 | function. | |
3025 | @end deffn | |
3026 | ||
eed4cc7b NJ |
3027 | @node Generic Function Internals |
3028 | @subsection Generic Function Internals | |
3029 | ||
3030 | @code{define-generic} calls @code{ensure-generic} to upgrade a | |
3031 | pre-existing procedure value, or @code{make} with metaclass | |
3032 | @code{<generic>} to create a new generic function. | |
3033 | ||
3034 | @code{define-accessor} calls @code{ensure-accessor} to upgrade a | |
3035 | pre-existing procedure value, or @code{make-accessor} to create a new | |
3036 | accessor. | |
3037 | ||
3038 | @deffn procedure ensure-generic old-definition [name] | |
3039 | Return a generic function with name @var{name}, if possible by using or | |
3040 | upgrading @var{old-definition}. If unspecified, @var{name} defaults to | |
3041 | @code{#f}. | |
3042 | ||
3043 | If @var{old-definition} is already a generic function, it is returned | |
3044 | unchanged. | |
3045 | ||
3046 | If @var{old-definition} is a Scheme procedure or procedure-with-setter, | |
3047 | @code{ensure-generic} returns a new generic function that uses | |
3048 | @var{old-definition} for its default procedure and setter. | |
3049 | ||
3050 | Otherwise @code{ensure-generic} returns a new generic function with no | |
3051 | defaults and no methods. | |
3052 | @end deffn | |
3053 | ||
3054 | @deffn procedure make-generic [name] | |
3055 | Return a new generic function with name @code{(car @var{name})}. If | |
3056 | unspecified, @var{name} defaults to @code{#f}. | |
3057 | @end deffn | |
3058 | ||
3059 | @code{ensure-generic} calls @code{make} with metaclasses | |
3060 | @code{<generic>} and @code{<generic-with-setter>}, depending on the | |
3061 | previous value of the variable that it is trying to upgrade. | |
3062 | ||
3063 | @code{make-generic} is a simple wrapper for @code{make} with metaclass | |
3064 | @code{<generic>}. | |
3065 | ||
3066 | @deffn procedure ensure-accessor proc [name] | |
3067 | Return an accessor with name @var{name}, if possible by using or | |
3068 | upgrading @var{proc}. If unspecified, @var{name} defaults to @code{#f}. | |
3069 | ||
3070 | If @var{proc} is already an accessor, it is returned unchanged. | |
3071 | ||
3072 | If @var{proc} is a Scheme procedure, procedure-with-setter or generic | |
3073 | function, @code{ensure-accessor} returns an accessor that reuses the | |
3074 | reusable elements of @var{proc}. | |
3075 | ||
3076 | Otherwise @code{ensure-accessor} returns a new accessor with no defaults | |
3077 | and no methods. | |
3078 | @end deffn | |
3079 | ||
3080 | @deffn procedure make-accessor [name] | |
3081 | Return a new accessor with name @code{(car @var{name})}. If | |
3082 | unspecified, @var{name} defaults to @code{#f}. | |
3083 | @end deffn | |
3084 | ||
3085 | @code{ensure-accessor} calls @code{make} with | |
3086 | metaclass @code{<generic-with-setter>}, as well as calls to | |
3087 | @code{ensure-generic}, @code{make-accessor} and (tail recursively) | |
3088 | @code{ensure-accessor}. | |
3089 | ||
3090 | @code{make-accessor} calls @code{make} twice, first | |
3091 | with metaclass @code{<generic>} to create a generic function for the | |
3092 | setter, then with metaclass @code{<generic-with-setter>} to create the | |
3093 | accessor, passing the setter generic function as the value of the | |
3094 | @code{#:setter} keyword. | |
3095 | ||
a0e07ba4 | 3096 | @node Generic Function Invocation |
eb12b401 | 3097 | @subsection Generic Function Invocation |
a0e07ba4 NJ |
3098 | |
3099 | [ *fixme* Description required here. ] | |
3100 | ||
3101 | @code{apply-generic} | |
3102 | ||
3103 | @itemize @bullet | |
3104 | @item | |
3105 | @code{no-method} | |
3106 | ||
3107 | @item | |
3108 | @code{compute-applicable-methods} | |
3109 | ||
3110 | @item | |
3111 | @code{sort-applicable-methods} | |
3112 | ||
3113 | @item | |
3114 | @code{apply-methods} | |
3115 | ||
3116 | @item | |
3117 | @code{no-applicable-method} | |
3118 | @end itemize | |
3119 | ||
3120 | @code{sort-applicable-methods} | |
3121 | ||
3122 | @itemize @bullet | |
3123 | @item | |
3124 | @code{method-more-specific?} | |
3125 | @end itemize | |
3126 | ||
3127 | @code{apply-methods} | |
3128 | ||
3129 | @itemize @bullet | |
3130 | @item | |
3131 | @code{apply-method} | |
3132 | @end itemize | |
3133 | ||
3134 | @code{next-method} | |
3135 | ||
3136 | @itemize @bullet | |
3137 | @item | |
3138 | @code{no-next-method} | |
3139 | @end itemize |