-
Notifications
You must be signed in to change notification settings - Fork 0
/
chap-5.texi
6807 lines (4934 loc) · 200 KB
/
chap-5.texi
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
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
@node Data and Control Flow
@chapter Data and Control Flow
@menu
* Generalized Reference::
* Transfer of Control to an Exit Point::
* Data and Control Flow Dictionary::
@end menu
@node Generalized Reference
@section Generalized Reference
@menu
* Overview of Places and Generalized Reference::
* Kinds of Places::
* Treatment of Other Macros Based on SETF::
@end menu
@node Overview of Places and Generalized Reference
@subsection Overview of Places and Generalized Reference
A @newterm{generalized reference} is the use of a @term{form},
sometimes called a @newterm{place},
as if it were a @term{variable} that could be read and written.
The @term{value} of a @term{place} is
the @term{object} to which the @term{place} @term{form} evaluates.
The @term{value} of a @term{place} can be changed by using @symbolref{setf, SYM}.
The concept of binding a @term{place} is not defined in @clisp{},
but an @term{implementation} is permitted to extend the language by defining this concept.
@Thenextfigure{}@spc{}contains examples of the use of @symbolref{setf, SYM}.
Note that the values returned by evaluating the @term{forms} in column two
are not necessarily the same as those obtained by evaluating the
@term{forms} in column three.
In general, the exact @term{macro expansion} of a @symbolref{setf, SYM} @term{form} is not guaranteed
and can even be @term{implementation-dependent};
all that is guaranteed is
that the expansion is an update form that works
for that particular @term{implementation},
that the left-to-right evaluation of @term{subforms} is preserved,
and
that the ultimate result of evaluating @symbolref{setf, SYM} is the value
or values being stored.
@float Figure,fig5.1
@cartouche
@multitable{@f{(symbol-value x)}}{@f{(rplaca x datum)}}{@f{(setf (symbol-value x) datum)}}
@headitem Access function @tab Update Function @tab Update using @symbolref{setf, SYM}
@item @f{x} @tab @f{(setq x datum)} @tab @f{(setf x datum)}
@item @f{(car x)} @tab @f{(rplaca x datum)} @tab @f{(setf (car x) datum)}
@item @f{(symbol-value x)} @tab @f{(set x datum)} @tab @f{(setf (symbol-value x) datum)}
@end multitable
@end cartouche
@caption{Examples of setf}
@end float
@Thenextfigure{}@spc{}shows @term{operators} relating to
@term{places} and @term{generalized reference}.
@float Figure,fig5.2
@cartouche
@multitable{define-setf-expander}{get-setf-expansion}{rotatef}
@item assert @tab defsetf @tab push
@item ccase @tab get-setf-expansion @tab remf
@item ctypecase @tab getf @tab rotatef
@item decf @tab incf @tab setf
@item define-modify-macro @tab pop @tab shiftf
@item define-setf-expander @tab psetf @tab
@end multitable
@end cartouche
@caption{Operators relating to places and generalized reference.}
@end float
Some of the @term{operators} above manipulate @term{places}
and some manipulate @term{setf expanders}.
A @term{setf expansion} can be derived from any @term{place}.
New @term{setf expanders} can be defined by using @symbolref{defsetf, SYM}
and @symbolref{define-setf-expander, SYM}.
@node Evaluation of Subforms to Places
@subsubsection Evaluation of Subforms to Places
The following rules apply to the @term{evaluation} of @term{subforms} in a
@term{place}:
@enumerate 1
@item
The evaluation ordering of @term{subforms} within a @term{place}
is determined by the order specified by the second value returned by
@symbolref{get-setf-expansion, SYM}.
For all @term{places} defined by this specification
(@eg{} @symbolref{getf, SYM}, @symbolref{ldb, SYM}, @mat{@ldots{}}),
this order of evaluation is left-to-right.
@cindex order of evaluation
@cindex evaluation order
When a @term{place} is derived from a macro expansion,
this rule is applied after the macro is expanded to find the appropriate @term{place}.
@term{Places} defined by using @symbolref{defmacro, SYM} or
@symbolref{define-setf-expander, SYM}
use the evaluation order defined by those definitions.
For example, consider the following:
@lisp
(defmacro wrong-order (x y) `(getf ,y ,x))
@end lisp
This following @term{form} evaluates @f{place2} first and
then @f{place1} because that is the order they are evaluated in
the macro expansion:
@lisp
(push value (wrong-order place1 place2))
@end lisp
@item
For the @term{macros} that manipulate @term{places}
(@symbolref{push, SYM},
@symbolref{pushnew, SYM},
@symbolref{remf, SYM},
@symbolref{incf, SYM},
@symbolref{decf, SYM},
@symbolref{shiftf, SYM},
@symbolref{rotatef, SYM},
@symbolref{psetf, SYM},
@symbolref{setf, SYM},
@symbolref{pop, SYM}, and those defined by @symbolref{define-modify-macro, SYM})
the @term{subforms} of the macro call are evaluated exactly once
in left-to-right order, with the @term{subforms} of the @term{places}
evaluated in the order specified in (1).
@symbolref{push, SYM}, @symbolref{pushnew, SYM}, @symbolref{remf, SYM},
@symbolref{incf, SYM}, @symbolref{decf, SYM}, @symbolref{shiftf, SYM}, @symbolref{rotatef, SYM},
@symbolref{psetf, SYM}, @symbolref{pop, SYM} evaluate all @term{subforms} before modifying
any of the @term{place} locations.
@symbolref{setf, SYM} (in the case when @symbolref{setf, SYM} has more than two arguments)
performs its operation on each pair in sequence. For example, in
@lisp
(setf place1 value1 place2 value2 ...)
@end lisp
the @term{subforms} of @f{place1} and @f{value1} are evaluated, the location
specified by
@f{place1} is modified to contain the value returned by
@f{value1}, and
then the rest of the @symbolref{setf, SYM} form is processed in a like manner.
@item
For @symbolref{check-type, SYM}, @symbolref{ctypecase, SYM}, and @symbolref{ccase, SYM},
@term{subforms} of the @term{place} are evaluated once as in (1),
but might be evaluated again if the
type check fails in the case of @symbolref{check-type, SYM}
or none of the cases hold in
@symbolref{ctypecase, SYM} and @symbolref{ccase, SYM}.
@item
For @symbolref{assert, SYM}, the order of evaluation of the generalized
references is not specified.
@cindex order of evaluation
@cindex evaluation order
@end enumerate
Rules 2, 3 and 4 cover all @term{standardized} @term{macros} that manipulate @term{places}.
@node Examples of Evaluation of Subforms to Places
@subsubsection Examples of Evaluation of Subforms to Places
@lisp
(let ((ref2 (list '())))
(push (progn (princ "1") 'ref-1)
(car (progn (princ "2") ref2))))
@OUT{} 12
@EV{} (REF1)
(let (x)
(push (setq x (list 'a))
(car (setq x (list 'b))))
x)
@EV{} (((A) . B))
@end lisp
@symbolref{push, SYM} first evaluates @tt{(setq x (list 'a)) @EV{}@spc{}(a)},
then evaluates @tt{(setq x (list 'b)) @EV{}@spc{}(b)},
then modifies the @term{car} of this latest value to be @tt{((a) . b)}.
@node Setf Expansions
@subsubsection Setf Expansions
Sometimes it is possible to avoid evaluating @term{subforms} of a
@term{place} multiple times or in the wrong order. A
@term{setf expansion}
for a given access form can be expressed as an ordered collection of five @term{objects}:
@table @asis
@item @id{@b{List of temporary variables}}
a list of symbols naming temporary variables to be bound
sequentially, as if by @symbolref{let*, SYM}, to @term{values}
resulting from value forms.
@item @id{@b{List of value forms}}
a list of forms (typically, @term{subforms} of the
@term{place}) which when evaluated
yield the values to which the corresponding temporary
variables should be bound.
@item @id{@b{List of store variables}}
a list of symbols naming temporary store variables which are
to hold the new values that will be assigned to the
@term{place}.
@item @id{@b{Storing form}}
a form which can reference both the temporary and the store variables,
and which changes the @term{value} of the @term{place}
and guarantees to return as its values the values of the store variables,
which are the correct values for @symbolref{setf, SYM} to return.
@item @id{@b{Accessing form}}
a @term{form} which can reference the temporary variables,
and which returns the @term{value} of the @term{place}.
@end table
The value returned by the accessing form is
affected by execution of the storing form, but either of these
forms might be evaluated any number of times.
It is possible
to do more than one @symbolref{setf, SYM} in parallel via
@symbolref{psetf, SYM}, @symbolref{shiftf, SYM}, and @symbolref{rotatef, SYM}.
Because of this, the
@term{setf expander}
must produce new temporary
and store variable names every time. For examples of how to do this,
see @symbolref{gensym, SYM}.
For each @term{standardized} accessor function @param{F},
unless it is explicitly documented otherwise,
it is @term{implementation-dependent} whether the ability to
use an @param{F} @term{form} as a @symbolref{setf, SYM} @term{place}
is implemented by a @term{setf expander} or a @term{setf function}.
Also, it follows from this that it is @term{implementation-dependent}
whether the name @f{(setf @param{F})} is @term{fbound}.
@node Examples of Setf Expansions
@subsubsection Examples of Setf Expansions
Examples of the contents of the constituents of @term{setf expansions}
follow.
For a variable @param{x}:
@float Figure,fig5.3
@cartouche
@multitable{@f{(setq @param{x} g0001)}}{;list of temporary variables}
@item @f{()} @tab ;list of temporary variables
@item @f{()} @tab ;list of value forms
@item @f{(g0001)} @tab ;list of store variables
@item @f{(setq @param{x} g0001)} @tab ;storing form
@item @param{x} @tab ;accessing form
@end multitable
@end cartouche
@caption{Sample Setf Expansion of a Variable}
@end float
For @tt{(car @param{exp})}:
@float Figure,fig5.4
@cartouche
@multitable{@f{(progn (rplaca g0002 g0003) g0003)}}{;list of temporary variables}
@item @f{(g0002)} @tab ;list of temporary variables
@item @f{(@param{exp})} @tab ;list of value forms
@item @f{(g0003)} @tab ;list of store variables
@item @f{(progn (rplaca g0002 g0003) g0003)} @tab ;storing form
@item @f{(car g0002)} @tab ;accessing form
@end multitable
@end cartouche
@caption{Sample Setf Expansion of a CAR Form}
@end float
For @f{(subseq @param{seq} @param{s} @param{e})}:
@float Figure,fig5.5
@cartouche
@multitable{xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx}{xxxxxxxxxxxxxxxxxxxxxxxxxxxx}
@item @f{(g0004 g0005 g0006)} @tab ;list of temporary variables
@item @f{(@param{seq} @param{s} @param{e})} @tab ;list of value forms
@item @f{(g0007)} @tab ;list of store variables
@item @f{(progn (replace g0004 g0007 :start1 g0005 :end1 g0006) g0007)} @span{} @tab
@item @tab ;storing form
@item @f{(subseq g0004 g0005 g0006)} @tab ; accessing form
@end multitable
@end cartouche
@caption{Sample Setf Expansion of a SUBSEQ Form}
@end float
In some cases, if a @term{subform} of a @term{place} is itself
a @term{place}, it is necessary to expand the @term{subform}
in order to compute some of the values in the expansion of the outer
@term{place}. For @f{(ldb @param{bs} (car @param{exp}))}:
@float Figure,fig5.6
@cartouche
@multitable{xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx}{xxxxxxxxxxxxxxxxxxxxxxxxxxxx}
@item @f{(g0001 g0002)} @tab ;list of temporary variables
@item @f{(@param{bs} @param{exp})} @tab ;list of value forms
@item @f{(g0003)} @tab ;list of store variables
@item @f{(progn (rplaca g0002 (dpb g0003 g0001 (car g0002))) g0003)} @span{} @tab
@item @tab ;storing form
@item @f{(ldb g0001 (car g0002))} @tab ; accessing form
@end multitable
@end cartouche
@caption{Sample Setf Expansion of a LDB Form}
@end float
@node Kinds of Places
@subsection Kinds of Places
Several kinds of @term{places} are defined by @clisp{};
this section enumerates them.
This set can be extended by @term{implementations} and by @term{programmer code}.
@node Variable Names as Places
@subsubsection Variable Names as Places
The name of a @term{lexical variable} or @term{dynamic variable}
can be used as a @term{place}.
@node Function Call Forms as Places
@subsubsection Function Call Forms as Places
A @term{function form} can be used as a @term{place} if it falls
into one of the following categories:
@itemize @bullet{}
@item
A function call form whose first element is the name of
any one of the functions in @thenextfigure{}.
@editornote{KMP: Note that what are in some places still called `condition accessors'
are deliberately omitted from this table, and are not labeled as
accessors in their entries. I have not yet had time to do a full
search for these items and eliminate stray references to them as `accessors',
which they are not, but I will do that at some point.}
@float Figure,fig5.7
@cartouche
@multitable{caaaar}{compiler-macro-function}{logical-pathname-translations}
@item aref @tab cdadr @tab get
@item bit @tab cdar @tab gethash
@item caaaar @tab cddaar @tab logical-pathname-translations
@item caaadr @tab cddadr @tab macro-function
@item caaar @tab cddar @tab ninth
@item caadar @tab cdddar @tab nth
@item caaddr @tab cddddr @tab readtable-case
@item caadr @tab cdddr @tab rest
@item caar @tab cddr @tab row-major-aref
@item cadaar @tab cdr @tab sbit
@item cadadr @tab char @tab schar
@item cadar @tab class-name @tab second
@item caddar @tab compiler-macro-function @tab seventh
@item cadddr @tab documentation @tab sixth
@item caddr @tab eighth @tab slot-value
@item cadr @tab elt @tab subseq
@item car @tab fdefinition @tab svref
@item cdaaar @tab fifth @tab symbol-function
@item cdaadr @tab fill-pointer @tab symbol-plist
@item cdaar @tab find-class @tab symbol-value
@item cdadar @tab first @tab tenth
@item cdaddr @tab fourth @tab third
@end multitable
@end cartouche
@caption{Functions that setf can be used with---1}
@end float
In the case of @symbolref{subseq, SYM}, the replacement value must be a @term{sequence}
whose elements might be contained by the sequence argument to @symbolref{subseq, SYM},
but does not have to be a @term{sequence} of the same @term{type}
as the @term{sequence} of which the subsequence is specified.
If the length of the replacement value does not equal the length of
the subsequence to be replaced, then the shorter length determines
the number of elements to be stored, as for @symbolref{replace, SYM}.
@item
A function call form whose first element is the name of
a selector function constructed by @symbolref{defstruct, SYM}.
The function name must refer to the global function definition,
rather than a locally defined @term{function}.
@item
A function call form whose first element is the name of
any one of the functions in @thenextfigure{},
provided that the supplied argument
to that function is in turn a @term{place} form;
in this case the new @term{place} has stored back into it the
result of applying the supplied ``update'' function.
@float Figure,fig5.8
@cartouche
@multitable{@symbolref{mask-field, SYM}}{Argument that is a @param{place}}{@term{implementation-dependent}}
@headitem Function name @tab Argument that is a @param{place} @tab Update function used
@item @symbolref{ldb, SYM} @tab second @tab @symbolref{dpb, SYM}
@item @symbolref{mask-field, SYM} @tab second @tab @symbolref{deposit-field, SYM}
@item @symbolref{getf, SYM} @tab first @tab @term{implementation-dependent}
@end multitable
@end cartouche
@caption{Functions that setf can be used with---2}
@end float
During the @symbolref{setf, SYM} expansion of these @term{forms}, it is necessary to call
@symbolref{get-setf-expansion, SYM}
in order to figure out how the inner, nested generalized variable must be treated.
The information from
@symbolref{get-setf-expansion, SYM}
is used as follows.
@table @asis
@item @id{@symbolref{ldb, SYM}}
In a form such as:
@tt{(setf (ldb @param{byte-spec} @param{place-form}) @param{value-form})}
the place referred to by the @param{place-form} must always be both @term{read}
and @i{written}; note that the update is to the generalized variable
specified by @param{place-form}, not to any object @oftype{integer}.
Thus this @symbolref{setf, SYM} should generate code to do the following:
@enumerate 1
@item Evaluate @param{byte-spec} (and bind it into a temporary variable).
@item Bind the temporary variables for @param{place-form}.
@item Evaluate @param{value-form} (and bind
its value or values into the store variable).
@item Do the @term{read} from @param{place-form}.
@item Do the @term{write} into @param{place-form} with
the given bits of the @term{integer}
fetched in step 4 replaced with the value from step 3.
@end enumerate
If the evaluation of @param{value-form}
in step 3 alters what is found in @param{place-form},
such as setting different bits of @term{integer},
then the change of the bits denoted by
@param{byte-spec} is to that
altered @term{integer},
because step 4 is done after the @param{value-form}
evaluation. Nevertheless, the
evaluations required for @term{binding}
the temporary variables are done in steps 1 and
2, and thus the expected left-to-right evaluation order is seen.
For example:
@lisp
(setq integer #x69) @EV{} #x69
(rotatef (ldb (byte 4 4) integer)
(ldb (byte 4 0) integer))
integer @EV{} #x96
;;; This example is trying to swap two independent bit fields
;;; in an integer. Note that the generalized variable of
;;; interest here is just the (possibly local) program variable
;;; integer.
@end lisp
@item @id{@symbolref{mask-field, SYM}}
This case is the same as @symbolref{ldb, SYM} in all essential aspects.
@item @id{@symbolref{getf, SYM}}
In a form such as:
@f{(setf (getf @param{place-form} @param{ind-form}) @param{value-form})}
the place referred to by @param{place-form} must always be both @term{read}
and @i{written}; note that the update is to the generalized variable
specified by @param{place-form}, not necessarily to the particular
@term{list}
that is the property list in question.
Thus this @symbolref{setf, SYM} should generate code to do the following:
@enumerate 1
@item
Bind the temporary variables for @param{place-form}.
@item
Evaluate @param{ind-form} (and bind it into a temporary variable).
@item
Evaluate @param{value-form} (and bind
its value or values into the store variable).
@item
Do the @term{read} from @param{place-form}.
@item
Do the @term{write} into @param{place-form} with a possibly-new property list
obtained by combining the values from steps 2, 3, and 4.
(Note that the phrase ``possibly-new property list'' can mean that
the former property list is somehow destructively re-used, or it can
mean partial or full copying of it.
Since either copying or destructive re-use can occur,
the treatment of the resultant value for the
possibly-new property list must proceed as if it were a different copy
needing to be stored back into the generalized variable.)
@end enumerate
If the evaluation of @param{value-form}
in step 3 alters what is found in
@param{place-form}, such as setting a different named property in the list,
then the change of the property denoted by @param{ind-form}
is to that
altered list, because step 4 is done after the
@param{value-form}
evaluation. Nevertheless, the
evaluations required for @term{binding}
the temporary variables are done in steps 1 and
2, and thus the expected left-to-right evaluation order is seen.
For example:
@lisp
(setq s (setq r (list (list 'a 1 'b 2 'c 3)))) @EV{} ((a 1 b 2 c 3))
(setf (getf (car r) 'b)
(progn (setq r nil) 6)) @EV{} 6
r @EV{} NIL
s @EV{} ((A 1 B 6 C 3))
;;; Note that the (setq r nil) does not affect the actions of
;;; the SETF because the value of R had already been saved in
;;; a temporary variable as part of the step 1. Only the CAR
;;; of this value will be retrieved, and subsequently modified
;;; after the value computation.
@end lisp
@end table
@end itemize
@node VALUES Forms as Places
@subsubsection VALUES Forms as Places
A @symbolref{values, A} @term{form} can be used as a @term{place},
provided that each of its @term{subforms} is also a @term{place} form.
A form such as
@tt{(setf (values @param{place-1} @dots{} @param{place-n}) @param{values-form})}
does the following:
@enumerate 1
@item The @term{subforms} of each nested @param{place} are evaluated
in left-to-right order.
@item The @param{values-form} is evaluated, and the first store
variable from each @param{place} is bound to its return values as if by
@symbolref{multiple-value-bind, SYM}.
@item If the @term{setf expansion} for any @param{place}
involves more than one store variable, then the additional
store variables are bound to @nil{}.
@item The storing forms for each @param{place} are evaluated in
left-to-right order.
@end enumerate
The storing form in the @term{setf expansion} of @symbolref{values, A}
returns as @term{multiple values}@sub{2} the values of the store
variables in step 2. That is, the number of values returned is the
same as the number of @term{place} forms. This may be more or fewer
values than are produced by the @param{values-form}.
@node THE Forms as Places
@subsubsection THE Forms as Places
A @symbolref{the, SYM} @term{form} can be used as a @term{place},
in which case the declaration is transferred to the @param{newvalue} form,
and the resulting @symbolref{setf, SYM} is analyzed. For example,
@lisp
(setf (the integer (cadr x)) (+ y 3))
@end lisp
is processed as if it were
@lisp
(setf (cadr x) (the integer (+ y 3)))
@end lisp
@node APPLY Forms as Places
@subsubsection APPLY Forms as Places
The following situations involving @symbolref{setf, SYM} of @symbolref{apply, SYM} must be supported:
@itemize @bullet{}
@item @f{(setf (apply #'aref @param{array}
@starparam{subscript}
@param{more-subscripts})
@param{new-element})}
@item @f{(setf (apply #'bit @param{array}
@starparam{subscript}
@param{more-subscripts})
@param{new-element})}
@item @f{(setf (apply #'sbit @param{array}
@starparam{subscript}
@param{more-subscripts})
@param{new-element})}
@end itemize
In all three cases, the @term{element} of @param{array} designated
by the concatenation of @param{subscripts} and @param{more-subscripts}
(@ie{} the same @term{element} which would be @term{read} by the call to
@term{apply} if it were not part of a @symbolref{setf, SYM} @term{form})
is changed to have the @term{value} given by @param{new-element}.
For these usages, the function name (@symbolref{aref, SYM}, @symbolref{bit, A}, or @symbolref{sbit, SYM})
must refer to the global function definition, rather than a locally defined
@term{function}.
No other @term{standardized} @term{function} is required to be supported,
but an @term{implementation} may define such support.
An @term{implementation} may also define support
for @term{implementation-defined} @term{operators}.
If a user-defined @term{function} is used in this context,
the following equivalence is true, except that care is taken
to preserve proper left-to-right evaluation of argument @term{subforms}:
@lisp
(setf (apply #'@param{name} @starparam{arg}) @param{val})
@EQ{} (apply #'(setf @param{name}) @param{val} @starparam{arg})
@end lisp
@node Setf Expansions and Places
@subsubsection Setf Expansions and Places
Any @term{compound form} for which the @term{operator} has a
@term{setf expander}
defined can be used as a @term{place}.
The
@term{operator}
must refer to the global function definition,
rather than a locally defined @term{function} or @term{macro}.
@node Macro Forms as Places
@subsubsection Macro Forms as Places
A @term{macro form} can be used as a @term{place},
in which case @clisp{}@spc{}expands the @term{macro form}
as if by @symbolref{macroexpand-1, SYM}
and then uses the @term{macro expansion} in place of the original @term{place}.
Such @term{macro expansion} is attempted only after exhausting all other possibilities
other than expanding into a call to a function named @f{(setf @param{reader})}.
@node Symbol Macros as Places
@subsubsection Symbol Macros as Places
A reference to a @term{symbol} that has been @term{established} as a @term{symbol macro}
can be used as a @term{place}. In this case,
@symbolref{setf, SYM} expands the reference and then analyzes the resulting @term{form}.
@node Other Compound Forms as Places
@subsubsection Other Compound Forms as Places
For any other @term{compound form} for which the @term{operator} is a
@term{symbol} @param{f},
the @symbolref{setf, SYM} @term{form} expands into a call
to the @term{function} named @f{(setf @param{f})}.
The first @term{argument} in the newly constructed @term{function form}
is @param{newvalue} and the
remaining @term{arguments} are the remaining @term{elements} of
@param{place}.
This expansion occurs regardless of whether @param{f} or @f{(setf @param{f})}
is defined as a @term{function} locally, globally, or not at all.
For example,
@f{(setf (@param{f} @param{arg1} @param{arg2} ...) @param{new-value})}
expands into a form with the same effect and value as
@lisp
(let ((#:temp-1 arg1) ;force correct order of evaluation
(#:temp-2 arg2)
...
(#:temp-0 @param{new-value}))
(funcall (function (setf @param{f})) #:temp-0 #:temp-1 #:temp-2...))
@end lisp
A @term{function} named @f{(setf @param{f})} must return its first argument
as its only value in order to preserve the semantics of @symbolref{setf, SYM}.
@node Treatment of Other Macros Based on SETF
@subsection Treatment of Other Macros Based on SETF
For each of the ``read-modify-write'' @term{operators} in @thenextfigure{},
and for any additional @term{macros}
defined by the @term{programmer} using @symbolref{define-modify-macro, SYM},
an exception is made to the normal rule of left-to-right evaluation of arguments.
Evaluation of @term{argument} @term{forms} occurs in left-to-right order,
with the exception that for the @param{place} @term{argument}, the actual
@term{read} of the ``old value'' from that @param{place} happens
after all of the @term{argument} @term{form} @term{evaluations},
and just before a ``new value'' is computed and @i{written} back into the @param{place}.
Specifically, each of these @term{operators} can be viewed as involving a
@term{form} with the following general syntax:
@lisp
(@term{operator} @starparam{preceding-form} @param{place} @starparam{following-form})
@end lisp
The evaluation of each such @term{form} proceeds like this:
@enumerate 1
@item @term{Evaluate} each of the @param{preceding-forms}, in left-to-right order.
@item @term{Evaluate} the @term{subforms} of the @param{place},
in the order specified by the second value of the @term{setf expansion}
for that @param{place}.
@item @term{Evaluate} each of the @param{following-forms}, in left-to-right order.
@item @term{Read} the old value from @param{place}.
@item Compute the new value.
@item Store the new value into @param{place}.
@end enumerate
@float Figure,fig5.9
@cartouche
@multitable{decf}{push}{pushnew}
@item decf @tab pop @tab pushnew
@item incf @tab push @tab remf
@end multitable
@end cartouche
@caption{Read-Modify-Write Macros}
@end float
@node Transfer of Control to an Exit Point
@section Transfer of Control to an Exit Point
When a transfer of control is initiated by @symbolref{go, SYM},
@symbolref{return-from, SYM}, or @symbolref{throw, SYM}
the following events occur in order to accomplish the transfer of control.
Note that for @symbolref{go, SYM},
the @term{exit point} is the @term{form} within the @symbolref{tagbody, SYM}
that is being executed at the time the @symbolref{go, SYM} is performed;
for @symbolref{return-from, SYM},
the @term{exit point} is the corresponding
@symbolref{block, SYM} @term{form};
and for @symbolref{throw, SYM},
the @term{exit point} is the corresponding
@symbolref{catch, SYM} @term{form}.
@enumerate 1
@item
Intervening @term{exit points} are ``abandoned''
(@ie{} their @term{extent} ends
and it is no longer valid to attempt to transfer control through them).
@item
The cleanup clauses of any intervening @symbolref{unwind-protect, SYM} clauses
are evaluated.
@item
Intervening dynamic @term{bindings} of @symbolref{special, SYM} variables,
@term{catch tags}, @term{condition handlers}, and @term{restarts}
are undone.
@item
The @term{extent} of the @term{exit point} being invoked ends,
and control is passed to the target.
@end enumerate
The extent of an exit being ``abandoned'' because it is being passed over
ends as soon as the transfer of control is initiated. That is,
event 1 occurs at the beginning of the initiation of the transfer of
control.
The consequences are undefined if an attempt is made to transfer control
to an @term{exit point} whose @term{dynamic extent} has ended.
Events 2 and 3 are actually performed interleaved, in the order
corresponding to the reverse order in which they were established.
The effect of this is that the cleanup clauses of an @symbolref{unwind-protect, SYM}
see the same dynamic @term{bindings}
of variables and @term{catch tags} as were
visible when the @symbolref{unwind-protect, SYM} was entered.
Event 4 occurs at the end of the transfer of control.
@node Data and Control Flow Dictionary
@section Data and Control Flow Dictionary
@menu
* apply::
* defun::
* fdefinition::
* fboundp::
* fmakunbound::
* flet; labels; macrolet::
* funcall::
* function (Special Operator)::
* function-lambda-expression::
* functionp::
* compiled-function-p::
* call-arguments-limit::
* lambda-list-keywords::
* lambda-parameters-limit::
* defconstant::
* defparameter; defvar::
* destructuring-bind::
* let; let*::
* progv::
* setq::
* psetq::
* block::
* catch::
* go::
* return-from::
* return::
* tagbody::
* throw::
* unwind-protect::
* nil (Constant Variable)::
* not (Function)::
* t (Constant Variable)::
* eq::
* eql (Function)::
* equal::
* equalp::
* identity::
* complement::
* constantly::
* every; some; notevery; notany::
* and (Macro)::
* cond::
* if::
* or (Macro)::
* when; unless::
* case; ccase; ecase::
* typecase; ctypecase; etypecase::
* multiple-value-bind::
* multiple-value-call::
* multiple-value-list::
* multiple-value-prog1::
* multiple-value-setq::
* values (Accessor)::
* values-list::
* multiple-values-limit::
* nth-value::
* prog; prog*::
* prog1; prog2::
* progn::
* define-modify-macro::
* defsetf::
* define-setf-expander::
* get-setf-expansion::
* setf; psetf::
* shiftf::
* rotatef::
* control-error::
* program-error::
* undefined-function::
@end menu
@node apply
@syindexanchor{apply, SYM}
@subsection apply (Function)
@cindex apply
@subsubheading Syntax:
@DefunWithValues{apply, function @rest{} @plus{args}, @starparam{result}}
@subsubheading Arguments and Values:
@param{function}---a @term{function designator}.
@param{args}---a @term{spreadable argument list designator}.
@param{results}---the @term{values} returned by @param{function}.
@subsubheading Description:
@term{Applies} the @param{function} to the @param{args}.
When the @param{function} receives its arguments via @keyref{rest}, it is
permissible (but not required) for the @term{implementation} to @term{bind}
the @term{rest parameter}
to an @term{object} that shares structure with the last argument to @symbolref{apply, SYM}.
Because a @term{function} can neither detect whether it was called via @symbolref{apply, SYM}
nor whether (if so) the last argument to @symbolref{apply, SYM} was a @term{constant},
@term{conforming programs} must neither rely on the @term{list} structure
of a @term{rest list} to be freshly consed, nor modify that @term{list} structure.
@symbolref{setf, SYM} can be used with @symbolref{apply, SYM} in certain circumstances;
see @ref{APPLY Forms as Places}.
@subsubheading Examples:
@lisp
(setq f '+) @EV{} +
(apply f '(1 2)) @EV{} 3
(setq f #'-) @EV{} #<FUNCTION ->
(apply f '(1 2)) @EV{} -1
(apply #'max 3 5 '(2 7 3)) @EV{} 7
(apply 'cons '((+ 2 3) 4)) @EV{} ((+ 2 3) . 4)
(apply #'+ '()) @EV{} 0
(defparameter *some-list* '(a b c))
(defun strange-test (&rest x) (eq x *some-list*))
(apply #'strange-test *some-list*) @EV{} @term{implementation-dependent}
(defun bad-boy (&rest x) (rplacd x 'y))
(bad-boy 'a 'b 'c) has undefined consequences.
(apply #'bad-boy *some-list*) has undefined consequences.
@end lisp
@lisp
(defun foo (size &rest keys &key double &allow-other-keys)
(let ((v (apply #'make-array size :allow-other-keys t keys)))
(if double (concatenate (type-of v) v v) v)))
(foo 4 :initial-contents '(a b c d) :double t)
@EV{} #(A B C D A B C D)