forked from ruricolist/dpans2texi
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathconcept-objects.tex
636 lines (535 loc) · 29.4 KB
/
concept-objects.tex
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
% -*- Mode: TeX -*-
%%2.5 objects
The \term{generic function} \funref{make-instance} creates and returns a new
\term{instance} of a \term{class}. The first argument is a \term{class} or
the \term{name} of a \term{class}, and the remaining arguments form an
\newterm{initialization argument list}.
The initialization of a new \term{instance} consists of several distinct
steps, including the following: combining the explicitly supplied initialization
arguments with default values for the unsupplied initialization arguments,
checking the validity of the initialization arguments, allocating storage
for the \term{instance}, filling \term{slots} with
values, and executing user-supplied \term{methods} that perform additional
initialization. Each step of \funref{make-instance} is implemented by a
\term{generic function} to provide a mechanism for customizing that step.
In addition, \funref{make-instance} is itself a \term{generic function}
and thus also can be customized.
The \OS\ specifies system-supplied primary \term{methods} for each step
and thus specifies a well-defined standard behavior for the entire
initialization process. The standard behavior provides four simple
mechanisms for controlling initialization:
\beginlist
\itemitem{\bull} Declaring a \term{symbol} to be an initialization argument
for a \term{slot}. An initialization argument is declared by using the
\kwd{initarg} slot option to \macref{defclass}. This provides a mechanism
for supplying a value for a \term{slot} in a call to \funref{make-instance}.
\itemitem{\bull} Supplying a default value form for an initialization argument.
Default value forms for initialization arguments are defined by using the
\kwd{default-initargs} class option to \macref{defclass}. If an
initialization argument is not explicitly provided
as an argument to \funref{make-instance}, the default value form is
evaluated in the lexical environment of the \macref{defclass} form that
defined it, and the resulting value is used as the value of the
initialization argument.
\itemitem{\bull} Supplying a default initial value form for a \term{slot}.
A default initial value form for a \term{slot} is defined by using the
\kwd{initform} slot option to \macref{defclass}. If no initialization
argument associated with that \term{slot} is given as an argument to
\funref{make-instance} or is defaulted by \kwd{default-initargs}, this
default initial value form is evaluated in the lexical environment of
the \macref{defclass} form that defined it, and the resulting value is
stored in the \term{slot}. The \kwd{initform} form for a
\term{local slot} may be used when creating an \term{instance}, when
updating an \term{instance} to conform to a redefined \term{class},
or when updating an \term{instance} to conform to the definition of a
different \term{class}. The \kwd{initform} form for a
\term{shared slot} may be used when defining or re-defining the \term{class}.
\itemitem{\bull}
Defining \term{methods} for \funref{initialize-instance} and
\funref{shared-initialize}. The slot-filling behavior described above is
implemented by a system-supplied primary \term{method} for
\funref{initialize-instance} which invokes \funref{shared-initialize}. The
\term{generic function} \funref{shared-initialize} implements the parts of
initialization shared by these four situations: when making an \term{instance},
when re-initializing an \term{instance}, when updating an \term{instance}
to conform to a redefined \term{class}, and when updating an \term{instance}
to conform to the definition of a different \term{class}. The system-supplied
primary \term{method} for \funref{shared-initialize} directly implements the
slot-filling behavior described above, and \funref{initialize-instance}
simply invokes \funref{shared-initialize}.
\endlist
\beginsubsection{Initialization Arguments}
An initialization argument controls \term{object} creation and
initialization. It is often convenient to use keyword \term{symbols}
to name initialization arguments, but the \term{name} of an
initialization argument can be any \term{symbol}, including \nil. An
initialization argument can be used in two ways: to fill a \term{slot}
with a value or to provide an argument for an initialization
\term{method}. A single initialization argument can be used for both
purposes.
\issue{PLIST-DUPLICATES:ALLOW}
An \term{initialization argument list} is a
%list of alternating of
\term{property list} of
initialization argument names and values.
Its structure is identical
to a \term{property list} and also
to the portion of an argument list
processed for \keyref{key} parameters.
As in those lists,
if an initialization
argument name appears more than once in an initialization argument list,
the leftmost occurrence supplies the value and the remaining occurrences
are ignored. The arguments to \funref{make-instance} (after the first
argument) form an \term{initialization argument list}.
\issue{INITIALIZATION-FUNCTION-KEYWORD-CHECKING}
% Error-checking
% of initialization argument names is disabled if the keyword argument
% pair whose keyword is \kwd{allow-other-keys} and whose value is
% \term{non-nil} appears in the \term{initialization argument list}.
\endissue{INITIALIZATION-FUNCTION-KEYWORD-CHECKING}
\endissue{PLIST-DUPLICATES:ALLOW}
An initialization argument can be associated with a \term{slot}. If
the initialization argument has a value in the \term{initialization
argument list}, the value is stored into the \term{slot} of the newly
created \term{object}, overriding any \kwd{initform} form associated
with the \term{slot}. A single initialization argument can initialize
more than one \term{slot}. An initialization argument that initializes
a \term{shared slot} stores its value into the \term{shared slot},
replacing any previous value.
An initialization argument can be associated with a \term{method}. When
an \term{object} is created and a particular initialization argument is
supplied, the \term{generic functions} \funref{initialize-instance},
\funref{shared-initialize}, and \funref{allocate-instance} are called
with that initialization argument's name and value as a keyword argument
pair. If a value for the initialization argument is not supplied in the
\term{initialization argument list}, the \term{method}'s
\term{lambda list} supplies a default value.
Initialization arguments are used in four situations: when making an
\term{instance}, when re-initializing an \term{instance}, when updating
an \term{instance} to conform to a redefined \term{class}, and when
updating an \term{instance} to conform to the definition of a different
\term{class}.
Because initialization arguments are used to control the creation and
initialization of an \term{instance} of some particular \term{class},
we say that an initialization argument is
``an initialization argument for'' that \term{class}.
\endsubsection%{Initialization Arguments}
\beginsubsection{Declaring the Validity of Initialization Arguments}
\DefineSection{DeclaringInitargValidity}
Initialization arguments are checked for validity in each of the four
situations that use them. An initialization argument may be valid in
one situation and not another. For example, the system-supplied
primary \term{method} for \funref{make-instance} defined for
\theclass{standard-class} checks the validity of its initialization arguments
and signals an error if an initialization argument is supplied that is
not declared as valid in that situation.
There are two means for declaring initialization arguments valid.
\beginlist
\itemitem{\bull}
Initialization arguments that fill \term{slots} are declared as valid
by the \kwd{initarg} slot option to \macref{defclass}. The
\kwd{initarg} slot option is inherited from \term{superclasses}. Thus
the set of valid initialization arguments that fill \term{slots} for a
\term{class} is the union of the initialization arguments that fill
\term{slots} declared as valid by that \term{class} and its
\term{superclasses}. Initialization arguments that fill \term{slots}
are valid in all four contexts.
\itemitem{\bull}
Initialization arguments that supply arguments to \term{methods} are
declared as valid by defining those \term{methods}. The keyword name of
each keyword parameter specified in the \term{method}'s
\term{lambda list} becomes an initialization argument for all \term{classes}
for which the \term{method} is applicable.
\issue{INITIALIZATION-FUNCTION-KEYWORD-CHECKING}
The presence of {\allowotherkeys} in the
\term{lambda list} of an applicable method disables validity checking of
initialization arguments.
\endissue{INITIALIZATION-FUNCTION-KEYWORD-CHECKING}
Thus \term{method} inheritance
controls the set of valid initialization arguments that supply arguments
to \term{methods}. The \term{generic functions} for which \term{method}
definitions serve to declare initialization arguments valid are as
follows:
\beginlist
\itemitem{--}
Making an \term{instance} of a \term{class}:
\funref{allocate-instance}, \funref{initialize-instance}, and
\funref{shared-initialize}. Initialization arguments declared as valid
by these \term{methods} are valid when making
an \term{instance} of a \term{class}.
\itemitem{--} Re-initializing an \term{instance}:
\funref{reinitialize-instance} and \funref{shared-initialize}.
Initialization arguments declared as valid by these \term{methods} are
valid when re-initializing an \term{instance}.
\itemitem{--} Updating an \term{instance} to conform to a redefined \term{class}:
\funref{update-instance-for-redefined-class} and \funref{shared-initialize}.
Initialization arguments declared as valid by these \term{methods} are
valid when updating an \term{instance} to conform to a redefined \term{class}.
\itemitem{--} Updating an \term{instance} to conform to the definition of a
different \term{class}:
\funref{update-instance-for-different-class} and \funref{shared-initialize}.
Initialization arguments declared as valid by these \term{methods} are
valid when updating an \term{instance} to conform to the definition
of a different \term{class}.
\endlist
\endlist
The set of valid initialization arguments for a \term{class} is the set of
valid initialization arguments that either fill \term{slots} or supply
arguments to \term{methods}, along with the predefined initialization
argument \kwd{allow-other-keys}. The default value for
\kwd{allow-other-keys} is \nil.
\issue{INITIALIZATION-FUNCTION-KEYWORD-CHECKING}
% The meaning of
% \kwd{allow-other-keys} is the same as when it is passed to an ordinary
% \term{function}.
Validity checking of initialization arguments is disabled if the value of
the initialization argument \kwd{allow-other-keys} is \term{true}.
\endissue{INITIALIZATION-FUNCTION-KEYWORD-CHECKING}
\endsubsection%{Declaring the Validity of Initialization Arguments}
\beginsubsection{Defaulting of Initialization Arguments}
A default value \term{form} can be supplied for an initialization
argument by using the \kwd{default-initargs} \term{class} option. If an
initialization argument is declared valid by some particular \term{class},
its default value form might be specified by a different \term{class}.
In this case \kwd{default-initargs} is used to supply a default value
for an inherited initialization argument.
The \kwd{default-initargs} option is used only to provide default
values for initialization arguments; it does not declare a \term{symbol}
as a valid initialization argument name. Furthermore,
the \kwd{default-initargs} option is used only to provide default values for
initialization arguments when making an \term{instance}.
The argument to the \kwd{default-initargs} class
option is a list of
alternating initialization argument names and \term{forms}.
Each \term{form} is the
default value form for the corresponding initialization
argument. The default value \term{form} of an initialization
argument is used and evaluated only if that initialization argument
does not appear in the arguments to \funref{make-instance} and is not
defaulted by a more specific \term{class}. The default value \term{form} is
evaluated in the lexical environment of the \macref{defclass} form that
supplied it; the resulting value is used as the initialization
argument's value.
The initialization arguments supplied to \funref{make-instance} are combined
with defaulted initialization arguments to produce a
\term{defaulted initialization argument list}. A
\term{defaulted initialization argument list}
is a list of alternating initialization argument names and
values in which unsupplied initialization arguments are defaulted and in
which the explicitly supplied initialization arguments appear earlier in
the list than the defaulted initialization arguments. Defaulted
initialization arguments are ordered according to the order in the
\term{class precedence list} of the \term{classes} that supplied the default values.
There is a distinction between the purposes of the
\kwd{default-initargs} and the \kwd{initform} options with respect to the
initialization of \term{slots}. The \kwd{default-initargs}
class option
provides a mechanism for the user to give a default value \term{form}
for an initialization argument without knowing whether the
initialization argument initializes a \term{slot}
or is passed to a \term{method}.
If that initialization argument is not explicitly supplied in a call
to \funref{make-instance}, the default value \term{form} is used, just
as if it had been supplied in the call. In contrast, the
\kwd{initform} slot option provides a mechanism for the user to give a
default initial value form for a \term{slot}. An \kwd{initform} form is
used to initialize a \term{slot} only if no initialization argument
associated with that \term{slot} is given as an argument to
\funref{make-instance} or is defaulted by \kwd{default-initargs}.
\idxtext{order of evaluation}\idxtext{evaluation order}
The order of evaluation of default value \term{forms} for initialization
arguments and the order of evaluation of \kwd{initform} forms are
undefined. If the order of evaluation is important,
\funref{initialize-instance} or \funref{shared-initialize} \term{methods}
should be used
instead.
\endsubsection%{Defaulting of Initialization Arguments}
\beginsubsection{Rules for Initialization Arguments}
\DefineSection{InitargRules}
The \kwd{initarg} slot option may be specified more than
once for a given \term{slot}.
The following rules specify when initialization arguments may be
multiply defined:
\beginlist
\itemitem{\bull} A given initialization argument can be used to
initialize more than one \term{slot} if the same initialization argument name
appears in more than one \kwd{initarg} slot option.
\itemitem{\bull} A given initialization argument name can appear
in the \term{lambda list} of more than one initialization \term{method}.
\itemitem{\bull} A given initialization argument name can
appear both in an \kwd{initarg} slot option and
in the \term{lambda list}
of an initialization \term{method}.
\endlist
\reviewer{The next three paragraphs could be replaced by ``If two or more
initialization arguments that initialize the same slot appear in the
\term{defaulted initialization argument list}, the leftmost of these supplies
the value, even if they have different names.'' And the rest would follow
from the rules above.}
If two or more initialization arguments that initialize the same
\term{slot} are given in the arguments to \funref{make-instance}, the
leftmost of these initialization arguments in the \term{initialization
argument list} supplies the value, even if the initialization arguments
have different names.
If two or more different initialization arguments that initialize the
same \term{slot} have default values and none is given explicitly in the
arguments to \funref{make-instance}, the initialization argument that
appears in a \kwd{default-initargs} class option in the most specific
of the \term{classes} supplies the value. If a single
\kwd{default-initargs} class option specifies two or more initialization
arguments that initialize the same \term{slot} and none is given
explicitly in the arguments to \funref{make-instance}, the leftmost in
the \kwd{default-initargs} class option supplies the value, and the
values of the remaining default value \term{forms} are ignored.
Initialization arguments given explicitly in the arguments to
\funref{make-instance} appear to the left of defaulted initialization
arguments. Suppose that the classes $C\sub 1$ and $C\sub 2$ supply the
values of defaulted initialization arguments for different \term{slots},
and suppose that $C\sub 1$ is more specific than $C\sub 2$; then the
defaulted initialization argument whose value is supplied by $C\sub 1$
is to the left of the defaulted initialization argument whose value is
supplied by $C\sub 2$ in the \term{defaulted initialization argument
list}. If a single \kwd{default-initargs} class option supplies the
values of initialization arguments for two different \term{slots}, the
initialization argument whose value is specified farther to the left in
the \kwd{default-initargs} class option appears farther to the left in
the \term{defaulted initialization argument list}.
\reviewer{Barmar: End of claim made three paragraphs back.}
If a \term{slot} has both an \kwd{initform} form and an
\kwd{initarg} slot option, and the initialization argument is defaulted
using \kwd{default-initargs} or is supplied to \funref{make-instance},
the captured \kwd{initform} form is neither used nor evaluated.
The following is an example of the above rules:
\code
(defclass q () ((x :initarg a)))
(defclass r (q) ((x :initarg b))
(:default-initargs a 1 b 2))
\endcode
$$\vbox{\halign{\strut#\hfil&\quad\hfil#\hfil&\quad\hfil#\hfil\cr
{}&\bf Defaulted&{}\cr
\bf Form&\bf Initialization Argument List&\bf Contents of Slot X\cr
\noalign{\hrule}
{\tt (make-instance 'r)}&{\tt (a 1 b 2)}&{\tt 1}\cr
{\tt (make-instance 'r 'a 3)}&{\tt (a 3 b 2)}&{\tt 3}\cr
{\tt (make-instance 'r 'b 4)}&{\tt (b 4 a 1)}&{\tt 4}\cr
{\tt (make-instance 'r 'a 1 'a 2)}&{\tt (a 1 a 2 b 2)}&{\tt 1}\cr}}$$
\endsubsection%{Rules for Initialization arguments}
\beginsubsection{Shared-Initialize}
\DefineSection{SharedInitialize}
The \term{generic function} \funref{shared-initialize} is used to fill the
\term{slots}
of an \term{instance}
using initialization arguments and \kwd{initform}
forms when an \term{instance} is created, when an
\term{instance} is re-initialized,
when an \term{instance}
is updated to conform to a redefined \term{class}, and when
an \term{instance} is updated to conform to a different \term{class}.
It uses
standard \term{method} combination. It takes the following arguments: the
\term{instance} to be initialized, a
specification of a set of \term{names} of \term{slots}
\term{accessible} in that \term{instance}, and any number of initialization
arguments. The arguments after the first two must form an
\term{initialization argument list}.
The second argument to \funref{shared-initialize} may be one of the following:
\beginlist
\itemitem{\bull} It can be a (possibly empty) \term{list} of \term{slot} names,
which specifies the set of those \term{slot} names.
% \reviewer{Barmar: This next bullet item is redundant with the previous,
% since NIL -is- a LIST. If there was some confusion, we could say ``(possibly empty)''
% in the previous item.}
%
% \itemitem{\bull} It can be \nil, which specifies the empty set of
% \term{slot} names.
\itemitem{\bull} It can be the symbol \t, which specifies the set of all of the \term{slots}.
\endlist
There is a system-supplied primary \term{method} for \funref{shared-initialize}
whose first \term{parameter specializer} is \theclass{standard-object}.
This \term{method} behaves as follows on each \term{slot},
whether shared or local:
\beginlist
\itemitem{\bull} If an initialization argument in the
\term{initialization argument list} specifies a value for that \term{slot},
that value is stored
into the \term{slot}, even if a value has already been stored in the \term{slot}
before the \term{method} is run.
The affected \term{slots} are independent of which
\term{slots} are indicated by the second argument to \funref{shared-initialize}.
\itemitem{\bull} Any \term{slots}
indicated by the second argument that are still
unbound at this point are initialized according to their
\kwd{initform} forms. For any such \term{slot}
that has an \kwd{initform} form,
that \term{form} is evaluated in the
lexical environment of its defining
\macref{defclass} form and the result is stored into the \term{slot}.
For example,
if a \term{before method} stores a value in the
\term{slot}, the \kwd{initform} form will not be used to supply a value
for the \term{slot}. If
the second argument specifies a \term{name} that does not correspond to any
\term{slots} \term{accessible}
in the \term{instance}, the results are unspecified.
\itemitem{\bull} The rules mentioned in {\secref\InitargRules} are obeyed.
\endlist
The generic function \funref{shared-initialize} is called by the
system-supplied primary \term{methods}
for \funref{reinitialize-instance},
\funref{update-instance-for-different-class},
\funref{update-instance-for-redefined-class}, and
\funref{initialize-instance}. Thus, \term{methods} can be written for
\funref{shared-initialize} to specify actions that should be taken in all of
these contexts.
\endsubsection%{Shared-Initialize}
\beginsubsection{Initialize-Instance}
The \term{generic function} \funref{initialize-instance} is called by
\funref{make-instance} to initialize a newly created \term{instance}.
It uses \term{standard method combination}. \term{Methods} for
\funref{initialize-instance} can be defined in order to perform any
initialization that cannot be achieved
%%This was the only case of a half-glossary-term in the entire spec. -kmp 1-Jan-91
%with the simple \term{slot}-filling mechanisms.
simply by supplying initial values for \term{slots}.
During initialization, \funref{initialize-instance} is invoked
after the following actions have been taken:
\beginlist
\itemitem{\bull} The \term{defaulted initialization argument list}
has been computed by combining the supplied \term{initialization argument list}
with any default initialization arguments for the \term{class}.
\itemitem{\bull} The validity of the \term{defaulted initialization argument list}
has been checked. If any of the initialization arguments has not
been declared as valid, an error is signaled.
\itemitem{\bull} A new \term{instance} whose \term{slots}
are unbound has been created.
\endlist
The generic function \funref{initialize-instance} is called with the
new \term{instance} and the defaulted initialization arguments. There is
a system-supplied primary \term{method} for \funref{initialize-instance}
whose \term{parameter specializer} is \theclass{standard-object}. This
\term{method} calls the generic function
\funref{shared-initialize} to fill in
the \term{slots} according to the initialization arguments and the
\kwd{initform} forms for the \term{slots}; the generic function
\funref{shared-initialize} is called with the following arguments: the \term{instance},
\t, and the defaulted initialization arguments.
Note that \funref{initialize-instance} provides the
\term{defaulted initialization argument list} in its call to \funref{shared-initialize},
so the first step performed by the system-supplied primary \term{method} for
\funref{shared-initialize} takes into account both the initialization
arguments provided in the call to \funref{make-instance} and the
\term{defaulted initialization argument list}.
\term{Methods} for \funref{initialize-instance} can be defined to specify
actions to be taken when an \term{instance} is initialized.
If only \term{after methods} for \funref{initialize-instance} are defined, they will be
run after the system-supplied primary \term{method} for initialization and
therefore will not interfere with the default behavior of
\funref{initialize-instance}.
The \OS\ provides two \term{functions} that are useful in the bodies of
\funref{initialize-instance} methods. \Thefunction{slot-boundp}
returns a \term{generic boolean} value that indicates whether a specified \term{slot} has a
value; this provides a mechanism for writing \term{after methods} for
\funref{initialize-instance} that initialize \term{slots} only if they have
not already been initialized. \Thefunction{slot-makunbound}
causes the \term{slot} to have no value.
\endsubsection%{INITIALIZE-INSTANCE}
\beginsubsection{Definitions of Make-Instance and Initialize-Instance}
The generic function \funref{make-instance} behaves as if it were defined as
follows, except that certain optimizations are permitted:
\code
(defmethod make-instance ((class standard-class) &rest initargs)
...
(let ((instance (apply #'allocate-instance class initargs)))
(apply #'initialize-instance instance initargs)
instance))
(defmethod make-instance ((class-name symbol) &rest initargs)
(apply #'make-instance (find-class class-name) initargs))
\endcode
%This is the code:
%(defmethod make-instance ((class standard-class) &rest initargs)
% (setq initargs (default-initargs class initargs))
% (let* ((proto (class-prototype class))
% (methods
% (append
% (compute-applicable-methods #'allocate-instance `(,class))
% (compute-applicable-methods #'initialize-instance `(,proto))
% (compute-applicable-methods #'shared-initialize `(,proto nil)))))
% (unless
% (subsetp
% (let ((keys '()))
% (do ((plist initargs (cddr plist)))
% ((null plist) keys)
% (push (car plist) keys)))
% (union
% (class-slot-initargs class)
% (reduce #'union (mapcar #'function-keywords methods))))
% (error ...)))
% (let ((instance (apply #'allocate-instance class initargs)))
% (apply #'initialize-instance instance initargs)
% instance))
The elided code in the definition of \funref{make-instance}
%% Per X3J13. -kmp 05-Oct-93
augments the \f{initargs} with any \term{defaulted initialization arguments} and
checks the
%% Per X3J13. -kmp 05-Oct-93
%supplied
resulting
initialization arguments to determine whether an initialization
argument was supplied that neither filled a \term{slot} nor supplied an argument
to an applicable \term{method}.
%This check could be implemented using the generic functions
% ???\funref{class-prototype},??? \funref{compute-applicable-methods},
%\funref{function-keywords}, and ???\funref{class-slot-initargs}. ???
%See Chapter~3 for a
%description of this initialization argument check.
The generic function \funref{initialize-instance} behaves as if it were
defined as follows, except that certain optimizations are permitted:
\code
(defmethod initialize-instance ((instance standard-object) &rest initargs)
(apply #'shared-initialize instance t initargs)))
\endcode
% Barmar complains that "Programmer Interface level" is not defined.
% Presumably it means "this specification".
% Ditto "the meta-object level" is not defined.
% Presumably it should just be omitted as beyond the scope of this standard,
% or else we should define the term somewhere (e.g., the glossary).
% I decided to just trim it down to where glossary words weren't needed. -kmp 6-Jan-91
These procedures can be customized.
% at either the Programmer Interface level,
% the meta-object level, or both.
Customizing at the Programmer Interface level includes using the
\kwd{initform}, \kwd{initarg}, and \kwd{default-initargs} options to
\macref{defclass}, as well as defining \term{methods}
for \funref{make-instance},
%% Per X3J13. -kmp 05-Oct-93
\funref{allocate-instance},
and \funref{initialize-instance}. It is also possible to define
\term{methods} for \funref{shared-initialize}, which would be invoked by the
generic functions \funref{reinitialize-instance},
\funref{update-instance-for-redefined-class},
\funref{update-instance-for-different-class}, and
\funref{initialize-instance}.
The meta-object level supports additional
customization.
%by allowing methods to be defined on \funref{make-instance},
%???\b{default-initargs}???, and \funref{allocate-instance}.
%Chapters~2 and~3 document each of these generic
%functions and the system-supplied primary methods.
Implementations are permitted to make certain optimizations to
\funref{initialize-instance} and \funref{shared-initialize}.
The description of \funref{shared-initialize} in Chapter~7 mentions the
possible optimizations.
%Because of optimization, the check for valid initialization arguments
%might not be implemented using the generic functions
%???\funref{class-prototype},???
%\funref{compute-applicable-methods}, \funref{function-keywords}, and
%???\funref{class-slot-initargs}???. In addition,
%methods for the generic function
%???\funref{default-initargs},??? and the
%system-supplied primary methods for
%???\funref{allocate-instance}???,
%\funref{initialize-instance}, and \funref{shared-initialize} might not be called on
%every call to \funref{make-instance} or might not receive exactly the
%arguments that would be expected.
\endsubsection%{Definitions of MAKE-INSTANCE and Initialize-Instance}