forked from filonenko-mikhail/cltl2-doc
-
Notifications
You must be signed in to change notification settings - Fork 1
/
loop.tex
2139 lines (1794 loc) · 75.7 KB
/
loop.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
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
%%%Chapter of Common Lisp Manual. Copyright 1989 Guy L. Steele Jr.
%%% Based on ANSI X3J13 document X3J13/89-004 which in turn is
%%% based on documentation by Lucid, Inc.
\clearpage\def\pagestatus{FINAL PROOF}
\chapter{Loop}
\label{LOOP}
Author: Jon L White
\begin{new}
X3J13 voted in January 1989
\issue{LOOP-FACILITY}
to adopt an extended definition of the \cdf{loop} macro
as a part of the forthcoming draft Common Lisp standard.
This chapter presents the bulk of the Common Lisp
Loop Facility proposal, written by Jon L White. I have
edited it only very lightly
to conform to the overall style of this book and have inserted a small
number of bracketed remarks, identified by the initials GLS.
(See the Acknowledgments to this second edition for
acknowledgments to others who contributed to the Loop Facility proposal.)
\noindent\hbox to \textwidth{\hss---Guy L. Steele Jr.}
\vskip 8pt plus 3pt minus 2pt
\section{Introduction}
A {\it loop\/} is a series of expressions that are executed one or more times,
a process known as {\it iteration}.
The {\it Loop Facility\/} defines a
variety of useful methods, indicated by
{\it loop keywords}, to iterate and to
accumulate values in a loop.
Loop keywords are not true Common Lisp keywords; they are symbols that
are recognized by the Loop Facility and that provide such capabilities
as controlling the direction of iteration, accumulating values inside
the body of a loop, and evaluating expressions that precede or follow
the loop body. If you do not use any loop keywords, the Loop Facility
simply executes the loop body repeatedly.
\section{How the Loop Facility Works}
The driving element of the Loop Facility is the \cdf{loop} macro.
When Lisp encounters a \cdf{loop} macro call
form, it invokes the Loop Facility and passes to it the loop clauses
as a list of unevaluated forms, as with any macro.
The loop clauses contain Common Lisp forms and loop keywords. The
loop keywords are recognized by their symbol name, regardless of the
packages that contain them. The \cdf{loop} macro translates the
given form into Common Lisp code and returns the expanded form.
The expanded loop form is
one or more lambda-expressions for the local binding of loop variables
and a block and a tagbody that express a looping control structure.
The variables established in the loop construct are bound as
if by using \cdf{let} or \cdf{lambda}. Implementations can interleave the
setting of initial values with the bindings. However, the assignment
of the initial values is always calculated in the order specified by
the user. A variable is thus sometimes bound to a harmless value of the
correct data type, and then later in the prologue it is set to the true
initial value by using \cdf{setq}.
The expanded form consists of three basic parts in the tagbody:
\begin{itemize}
\item
The {\it loop prologue\/} contains forms that are executed before iteration begins,
such as initial settings of loop variables and possibly an initial
termination test.
\item
The {\it loop body\/} contains those forms that are executed during iteration,
including application-specific calculations, termination tests,
and variable stepping. {\it Stepping\/} is the process of assigning a
variable the next item in a series of items.
\item
The {\it loop epilogue} contains forms that are executed after iteration
terminates,
such as code to return values from the loop.
\end{itemize}
Expansion of the \cdf{loop} macro produces an implicit block
(named \cdf{nil}).
Thus, the Common Lisp macro \cdf{return} and the special form
\cdf{return-from} can be
used to return values from a loop or to exit a loop.
Within the executable parts of loop clauses and around the entire
loop form, you can still bind variables by using the Common Lisp
special form \cdf{let}.
\section{Parsing Loop Clauses}
The syntactic parts of a loop construct are called {\it clauses}; the scope
of each clause is determined by the top-level parsing of that clause's
keyword. The following example shows a loop construct with six
clauses:
\begin{lisp}
(loop for i from 1 to (compute-top-value)~~~~~~~~~;{\rm First clause} \\*
~~~~~~while (not (unacceptable i))~~~~~~~~~~~~~~~~;{\rm Second clause} \\*
~~~~~~collect (square i)~~~~~~~~~~~~~~~~~~~~~~~~~~;{\rm Third clause} \\*
~~~~~~do (format t "Working on {\Xtilde}D now" i)~~~~~~~~~;{\rm Fourth clause} \\*
~~~~~~when (evenp i)~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~;{\rm Fifth clause} \\*
~~~~~~~~do (format t "{\Xtilde}D is a non-odd number" i) \\*
~~~~~~finally (format t "About to exit!"))~~~~~~~~;{\rm Sixth clause}
\end{lisp}
Each loop keyword introduces either a compound loop clause or a simple
loop clause that can consist of a loop keyword followed by a
single Lisp form. The number of
forms in a clause is determined by the loop keyword that begins the
clause and by the auxiliary keywords in the clause. The keywords
\cdf{do}, \cdf{initially}, and \cdf{finally} are the only loop
keywords that can take any number of Lisp forms and group them as if
in a single \cdf{progn} form.
Loop clauses can contain auxiliary keywords, which are sometimes
called {\it prepositions}. For example, the first clause in the preceding code
includes the prepositions \cdf{from} and \cdf{to}, which mark
the value from which stepping begins and the value at which stepping
ends.
\subsection{Order of Execution}
With the exceptions listed below, clauses are executed in the loop body
in the order in which they appear in the source. Execution is repeated
until a clause
terminates the loop or until a Common Lisp \cdf{return},
\cdf{go}, or \cdf{throw} form is encountered. The following actions are
exceptions to the linear order of execution:
\begin{itemize}
\item
All variables are initialized first, regardless of where the establishing
clauses appear in the source. The order of initialization follows the
order of these clauses.
\item
The code for any \cdf{initially} clauses is collected
into one \cdf{progn} in the order in which the clauses appear in
the source. The collected code is executed once in the loop prologue
after any implicit variable initializations.
\item
The code for any \cdf{finally} clauses is collected
into one \cdf{progn} in the order in which the clauses appear in
the source. The collected code is executed once in the loop epilogue
before any implicit values from the accumulation clauses are returned.
Explicit returns anywhere in the source, however, will exit the loop
without executing the epilogue code.
\item
A \cdf{with} clause introduces a variable binding and an optional
initial value. The initial values are calculated in the order in
which the \cdf{with} clauses occur.
\item
Iteration control clauses implicitly perform the following actions:
\begin{itemize}
\item
initializing variables
\item
stepping variables, generally between each execution of the loop body
\item
performing termination tests, generally just before the execution of the
loop body
\end{itemize}
\end{itemize}
\subsection{Kinds of Loop Clauses}
\label{LOOP-KINDS-SECTION}
Loop clauses fall into one of the following categories:
\begin{itemize}
\item
variable initialization and stepping
\begin{itemize}
\item
The \cdf{for} and \cdf{as} constructs provide iteration control clauses
that establish a variable to be initialized.
You can combine \cdf{for} and \cdf{as} clauses with the loop
keyword \cdf{and} to get parallel initialization and stepping.
\item
The \cdf{with} construct is similar to a single \cdf{let} clause.
You can combine \cdf{with} clauses using
\cdf{and} to get parallel initialization.
\item
The \cdf{repeat} construct causes iteration to terminate after a specified
number of times. It uses an internal variable to keep track of the
number of iterations.
\end{itemize}
You can specify data types for loop variables (see
section~\ref{LOOP-TYPES-SECTION}).
It is an error to bind the same variable twice in any variable-binding
clause of a single loop expression. Such variables include
local variables, iteration control variables, and variables found by
destructuring.
\item value accumulation
\begin{itemize}
\item The \cdf{collect} construct takes one form in its clause
and adds the value of that form to the end of a list of values. By
default, the list of values is returned when the loop finishes.
\item
The \cdf{append} construct takes one form in its clause
and appends the value of that form to the end of a list of values. By
default, the list of values is returned when the loop finishes.
\item The \cdf{nconc} construct is similar to \cdf{append}, but
its list values are concatenated as if by the Common Lisp function
\cdf{nconc}. By
default, the list of values is returned when the loop finishes.
\item The \cdf{sum} construct takes one form in its clause that
must evaluate to a number and adds that number into a running total.
By default, the cumulative sum is returned when the loop finishes.
\item
The \cdf{count} construct takes one form in its clause and counts the
number of times that the form evaluates to a non-\cdf{nil} value. By
default, the count is returned when the loop finishes.
\item
The \cdf{minimize} construct takes one form in its clause and determines
the minimum value obtained by evaluating that form. By default, the
minimum value is returned when the loop finishes.
\item
The \cdf{maximize} construct takes one form in its clause and
determines the maximum value obtained by evaluating that form. By
default, the maximum value is returned when the loop finishes.
\end{itemize}
\item
termination conditions
\begin{itemize}
\item
The \cdf{loop-finish} Lisp macro terminates iteration and returns any
accumulated result. If specified, any \cdf{finally} clauses are evaluated.
\item
The \cdf{for} and \cdf{as} constructs provide a termination test
that is determined by the iteration control clause.
\item
The \cdf{repeat} construct causes termination after a specified
number of iterations.
\item
The \cdf{while} construct takes one form, a condition, and terminates
the iteration if
the condition evaluates to \cdf{nil}. A \cdf{while} clause is
equivalent to the expression \cd{(if~(not~{\it condition}) (loop-finish))}.
\item
The \cdf{until} construct is the inverse of \cdf{while};
it terminates the iteration if the condition evaluates to any non-\cdf{nil}
value. An \cdf{until} clause is equivalent to the expression
\cd{(if~{\it condition} (loop-finish))}.
\item
The \cdf{always} construct takes one form and terminates the loop
if the form ever evaluates to \cdf{nil}; in this case, it returns
\cdf{nil}. Otherwise, it provides a default return value of \cdf{t}.
\item
The \cdf{never} construct takes one form and terminates the loop
if the form ever evaluates to non-\cdf{nil}; in this case, it returns
\cdf{nil}. Otherwise, it provides a default return value of \cdf{t}.
\item
The \cdf{thereis} construct takes one form and terminates the loop
if the form ever evaluates to non-\cdf{nil}; in this case, it returns
that value.
\end{itemize}
\item unconditional execution
\begin{itemize}
\item
The \cdf{do} construct simply evaluates all forms in its clause.
\item
The \cdf{return} construct takes one form and returns its value. It is
equivalent to the clause \cd{do (return {\it value})}.
\end{itemize}
\item conditional execution
\begin{itemize}
\item
The \cdf{if} construct takes one form as a predicate and a clause that
is executed when the predicate is true. The clause can be a value
accumulation, unconditional, or another conditional clause; it can also
be any combination of such clauses connected by the loop keyword \cdf{and}.
\item
The \cdf{when} construct is a synonym for \cdf{if}.
\item
The \cdf{unless} construct is similar to \cdf{when} except that it complements
the predicate; it executes the following clause if the predicate is false.
\item
The \cdf{else} construct provides an optional component of \cdf{if},
\cdf{when}, and \cdf{unless} clauses that is executed when the
predicate is false. The component is one of the clauses described under
\cdf{if}.
\item
The \cdf{end} construct provides an optional component to mark the
end of a conditional clause.
\end{itemize}
\item miscellaneous operations
\begin{itemize}
\item The \cdf{named} construct assigns a name to a loop construct.
\item The \cdf{initially} construct causes its forms to be evaluated
in the loop prologue, which precedes all loop code except for initial
settings specified by the constructs \cdf{with}, \cdf{for}, or \cdf{as}.
\item The \cdf{finally} construct causes its forms to be evaluated
in the loop epilogue after normal iteration terminates. An unconditional
clause can also follow the loop keyword \cdf{finally}.
\end{itemize}
\end{itemize}
\subsection{Loop Syntax}
The following syntax description provides an overview of the syntax
for loop clauses. Detailed syntax descriptions of individual clauses
appear in sections~\ref{LOOP-ITERATION-SECTION} through~\ref{LOOP-MISC-SECTION}.
A loop consists of the
following types of clauses:
\begin{tabbing}
{\it initial-final\/} ::= {\it initially\/} {\Mor} {\it finally\/} \\*
{\it variables\/} ::= {\it with\/} {\Mor} {\it initial-final\/} {\Mor} {\it for-as\/} {\Mor} {\it repeat} \\*
{\it main\/} ::= {\it unconditional\/} {\Mor} {\it accumulation\/} {\Mor} {\it conditional\/}
{\Mor} {\it termination\/} {\Mor} {\it initial-final\/} \\*
{\it loop\/} ::= \cd{(loop \Mopt{\cd{named {\it name\/}}} \Mstar{\it variables\/} \Mstar{\it main\/})}
\end{tabbing}
Note that a loop must have at least one clause; however, for
backward compatibility, the following format is also supported:
\begin{lisp}
(loop \Mstar{{\it tag} {\Mor} {\it expr}})
\end{lisp}
where {\it expr} is any Common Lisp expression that can be evaluated, and
{\it tag} is any symbol not identifiable as a loop keyword. Such a format
is roughly equivalent to the following one:
\begin{lisp}
(loop do \Mstar{{\it tag} {\Mor} {\it expr}})
\end{lisp}
A loop prologue consists of any automatic variable initializations prescribed
by the {\it variable\/} clauses, along with any {\it initially\/} clauses
in the order they appear in the source.
A loop epilogue consists of {\it finally\/} clauses, if any, along
with any implicit return value from an {\it accumulation\/} clause or
an {\it end-test\/} clause.
\section{User Extensibility}
There is currently no specified portable method for users to add
extensions to the Loop Facility. The names \cdf{defloop} and
\cdf{define-loop-method} have been suggested as candidates for such a method.
\section{Loop Constructs}
The remaining sections of this chapter describe the constructs that the Loop Facility
provides. The descriptions are organized according to the functionality
of the constructs. Each section begins with a general discussion of
a particular operation; it then presents the constructs that perform the
operation.
\begin{itemize}
\item Section~\ref{LOOP-ITERATION-SECTION},
``Iteration Control,'' describes iteration
control clauses that allow directed loop iteration.
\item Section~\ref{LOOP-TEST-SECTION}, ``End-Test Control,''
describes clauses that stop iteration by providing a conditional expression
that can be tested after each execution of the loop body.
\item Section~\ref{LOOP-ACCUM-SECTION},
``Value Accumulation,'' describes constructs
that accumulate values during iteration and return them from a loop. This section also
discusses ways in which accumulation clauses can be combined within the
Loop Facility.
\item Section~\ref{LOOP-VAR-SECTION},
``Variable Initializations,'' describes the \cdf{with}
construct, which provides local variables for use within the loop
body, and other constructs that provide local variables.
\item Section~\ref{LOOP-COND-SECTION},
``Conditional Execution,'' describes how to execute loop
clauses conditionally.
\item Section~\ref{LOOP-UNCOND-SECTION},
``Unconditional Execution,'' describes the \cdf{do}
and \cdf{return} constructs. It also describes constructs that are
used in the loop prologue and loop epilogue.
\item Section~\ref{LOOP-MISC-SECTION},
``Miscellaneous Features,'' discusses loop data types
and destructuring. It also presents constructs for naming a loop and
for specifying initial and final actions.
\end{itemize}
\section{Iteration Control}
\label{LOOP-ITERATION-SECTION}
Iteration control clauses allow you to direct loop iteration. The
loop keywords \cdf{as}, \cdf{for}, and \cdf{repeat} designate iteration control clauses.
Iteration control clauses differ with respect to the specification of
termination conditions and the initialization and stepping
of loop variables. Iteration clauses by themselves
do not cause the Loop Facility to return values, but they
can be used in conjunction with value-accumulation clauses to
return values (see section~\ref{LOOP-ACCUM-SECTION}).
All variables are initialized in the loop prologue. The scope of
the variable binding is {\it lexical} unless it is proclaimed
special; thus, the variable can be
accessed only by expressions that lie textually within the loop.
Stepping assignments are made in the loop body before any other expressions
are evaluated in the body.
The variable argument in iteration control clauses can be a
{\it destructuring list}. A destructuring list
is a tree whose non-null atoms are symbols that
can be assigned a value (see section~\ref{LOOP-DESTRUCTURING-SECTION}).
The iteration control clauses \cdf{for}, \cdf{as}, and \cdf{repeat}
must precede any other loop clauses except
\cdf{initially}, \cdf{with}, and \cdf{named},
since they establish variable bindings. When iteration control clauses are
used in a loop, termination tests in the loop body are evaluated
before any other loop body code is executed.
If you use multiple iteration clauses to control iteration, variable
initialization and stepping occur sequentially by default.
You can use the \cdf{and} construct to connect two or more
iteration clauses when sequential binding and stepping are not necessary.
The iteration behavior of clauses joined by \cdf{and}
is analogous to the behavior of the Common Lisp macro \cdf{do}
relative to \cdf{do*}.
[X3J13 voted in March 1989 \issue{LOOP-AND-DISCREPANCY} to correct a minor
inconsistency in the original syntactic specification for \cdf{loop}. Only \cdf{for}
and \cdf{as} clauses (not \cdf{repeat} clauses) may be joined by the \cdf{and} construct. The
precise syntax is as follows.
%% \begin{tabbing}
%% {\it for-as\/} ::= \Mgroup{\cdf{for} {\Mor} \cdf{as}} {\it for-as-subclause\/} \Mstar{\cdf{and} {\it for-as-subclause\/}} \\*
%% \pushtabs{\it for-as-subclause\/} ::= \={\it for-as-arithmetic\/} {\Mor} {\it for-as-in-list\/} \\*
%% \>\hbox to 0pt{\hss\Mor~}{\it for-as-on-list\/} {\Mor} {\it for-as-equals-then\/} \\*
%% \>\hbox to 0pt{\hss\Mor~}{\it for-as-across\/} {\Mor} {\it for-as-hash\/} {\Mor} {\it for-as-package\/} \poptabs \\
%% \pushtabs{\it for-as-arithmetic\/} ::= \={\it var\/} \Mopt{type-spec} \Mopt{\Mgroup{\cdf{from} {\Mor} \cdf{downfrom} {\Mor} \cdf{upfrom}} expr1} \\*
%% \>\Mopt{\Mgroup{\cdf{to} {\Mor} \cdf{downto} {\Mor} \cdf{upto} {\Mor} \cdf{below} {\Mor} \cdf{above}} expr2} \\*
%% \>\Mopt{\cdf{by} expr3} \poptabs \\
%% {\it for-as-in-list\/} ::= {\it var\/} \Mopt{type-spec} \cdf{in} {\it expr1\/} \Mopt{\cdf{by} step-fun} \\
%% {\it for-as-on-list\/} ::= {\it var\/} \Mopt{type-spec} \cdf{on} {\it expr1\/} \Mopt{\cdf{by} step-fun} \\
%% {\it for-as-equals-then\/} ::= {\it var\/} \Mopt{type-spec} \cdf{=} {\it expr1\/} \Mopt{\cdf{then} step-fun} \\
%% {\it for-as-across\/} ::= {\it var\/} \Mopt{type-spec} \cdf{across} {\it vector\/} \\
%% \pushtabs{\it for-as-hash\/} ::= \={\it var\/} \Mopt{type-spec} \cdf{being} \Mgroup{\cdf{each} {\Mor} \cdf{the}} \\*
%% \>\Mgroup{\cdf{hash-key} {\Mor} \cdf{hash-keys} {\Mor} \cdf{hash-value} {\Mor} \cdf{hash-values}} \\*
%% \>\Mgroup{\cdf{in} {\Mor} \cdf{of}} {\it hash-table\/} \\*
%% \>\Mopt{\cdf{using} \cdf{(}\Mgroup{\cdf{hash-value} {\Mor} \cdf{hash-key}} other-var\/\cdf{)}} \poptabs \\
%% \pushtabs{\it for-as-package\/} ::= \={\it var\/} \Mopt{type-spec} \cdf{being} \Mgroup{\cdf{each} {\Mor} \cdf{the}} \\*
%% \>{\it for-as-package-keyword\/} \\*
%% \>\Mgroup{\cdf{in} {\Mor} \cdf{of}} {\it package\/} \poptabs \\
%% \pushtabs{\it for-as-package-keyword\/} ::= \=\cdf{symbol} {\Mor} \cdf{present-symbol} {\Mor} \cdf{external-symbol} \\*
%% \>\hbox to 0pt{\hss\Mor~}\cdf{symbols} {\Mor} \cdf{present-symbols} {\Mor} \cdf{external-symbols} \poptabs
%% \end{tabbing}
This correction made \cdf{for} and \cdf{as} clauses syntactically
similar to \cdf{with} clauses. I have changed all examples in this
chapter to reflect the corrected syntax.---GLS]
In the following example, the variable \cdf{x} is stepped
before \cdf{y} is stepped; thus, the value of \cdf{y}
reflects the updated value of \cdf{x}:
\begin{lisp}
(loop for x from 1 to 9 \\*
~~~~~~for y = nil then x \\*
~~~~~~collect (list x y)) \\*
~~~\EV~((1 NIL) (2 2) (3 3) (4 4) (5 5) (6 6) (7 7) (8 8) (9 9))
\end{lisp}
In the following example, \cdf{x} and \cdf{y} are stepped in parallel:
\begin{lisp}
(loop for x from 1 to 9 \\*
~~~~~~and y = nil then x \\*
~~~~~~collect (list x y)) \\*
~~~\EV~((1 NIL) (2 1) (3 2) (4 3) (5 4) (6 5) (7 6) (8 7) (9 8))
\end{lisp}
The \cdf{for} and \cdf{as} clauses iterate by using one or more local
loop variables that are initialized to some value and that
can be modified or stepped after each iteration.
For these clauses, iteration terminates when a local
variable reaches some specified value or when some other loop clause
terminates iteration. At each iteration, variables can be stepped by an
increment or a decrement or can be assigned a new value by
the evaluation of
an expression. Destructuring can be used to assign initial values to
variables during iteration.
The \cdf{for} and \cdf{as} keywords are synonyms and may be used
interchangeably. There are
seven syntactic representations for these constructs.
In each syntactic description, the data type of
{\it var\/} can be specified by the optional {\it type-spec\/}
argument. If {\it var\/} is a destructuring list, the data type
specified by the {\it type-spec\/} argument must appropriately match
the elements of the list (see sections~\ref{LOOP-TYPES-SECTION}
and~\ref{LOOP-DESTRUCTURING-SECTION}).
\begin{defloop}
for var [type-spec] [{\!from! | \!downfrom! | \!upfrom!} expr1]
[{\!to! | \!downto! | \!upto! | \!below! | \!above!} expr2]
[\!by! expr3] \\
as var [type-spec] [{\!from! | \!downfrom! | \!upfrom!} expr1]
[{\!to! | \!downto! | \!upto! | \!below! | \!above!} expr2]
[\!by! expr3]
[This is the first of seven \cdf{for}/\cdf{as} syntaxes.---GLS]
The \cdf{for} or \cdf{as} construct iterates from the value specified by
{\it expr1\/} to the value specified by {\it expr2\/} in increments or
decrements denoted by {\it expr3}. Each
expression is evaluated only once and must evaluate to a number.
The variable {\it var\/} is bound to the value of
{\it expr1\/} in the first iteration and is stepped
by the value of {\it expr3\/} in each succeeding iteration,
or by 1 if {\it expr3\/} is not provided.
The following loop keywords serve as valid prepositions within this
syntax.
\begin{flushdesc}
\item[\cdf{from}]
The loop keyword \cdf{from} marks the value from which
stepping begins, as specified by {\it expr1}.
Stepping is incremental by default. For
decremental stepping, use \cdf{above}
or \cdf{downto} with {\it expr2}. For incremental
stepping, the default \cdf{from} value is \cdf{0}.
\item[\cdf{downfrom}, \cdf{upfrom}]
The loop keyword \cdf{downfrom}
indicates that the variable {\it var\/} is decreased in decrements
specified by {\it expr3}; the loop keyword \cdf{upfrom} indicates that
{\it var\/} is increased in increments specified by {\it expr3}.
\item[\cdf{to}]
The loop keyword \cdf{to} marks the end value for stepping specified in
{\it expr2}. Stepping is incremental by default. For
decremental stepping, use \cdf{downto},
\cdf{downfrom}, or \cdf{above} with {\it expr2}.
\item[\cdf{downto}, \cdf{upto}]
The loop keyword \cdf{downto} allows iteration to proceed
from a larger number to a smaller number by the decrement
{\it expr3}. The loop keyword \cdf{upto} allows iteration to proceed
from a smaller number to a larger number by the increment {\it expr3}.
Since there is no default for {\it expr1\/} in decremental stepping,
you must supply a value with \cdf{downto}.
\item[\cdf{below}, \cdf{above}]
The loop keywords \cdf{below} and \cdf{above} are analogous to
\cdf{upto} and \cdf{downto}, respectively. These keywords stop
iteration just before the value of the variable {\it var} reaches the value
specified by {\it expr2\/}; the end value of {\it expr2\/} is not included.
Since there is no default for {\it expr1\/} in decremental stepping,
you must supply a value with \cdf{above}.
\item[\cdf{by}]
The loop keyword \cdf{by} marks the increment or decrement specified by
{\it expr3}. The value of {\it expr3\/} can be any positive number.
The default value is \cdf{1}.
\end{flushdesc}
At least one of these prepositions must be used with this syntax.
In an iteration control clause, the \cdf{for} or \cdf{as} construct
causes termination when the specified limit is reached. That is,
iteration continues until the value {\it var\/} is stepped to the
exclusive or inclusive limit specified by {\it expr2\/}. The range is
{\it exclusive\/} if {\it expr3\/} increases or decreases {\it var\/}
to the value of {\it expr2\/} without reaching that value; the loop
keywords \cdf{below} and \cdf{above} provide exclusive limits. An
{\it inclusive\/} limit allows {\it var\/} to attain the value of
{\it expr2}; \cdf{to}, \cdf{downto}, and \cdf{upto} provide inclusive
limits.
A common convention is to use \cdf{for} to introduce new iterations and \cdf{as}
to introduce iterations that depend on a previous iteration specification.
[However, \cdf{loop} does not enforce this convention, and some of the examples
below violate it. {\it De gustibus non disputandum est.}---GLS]
Examples:
\begin{lisp}
;;; Print some numbers. \\[3pt]
(loop as i from 1 to 5 \\*
~~~~~~do (print i)) \`;{\rm Prints 5 lines} \\
1 \\*
2 \\*
3 \\*
4 \\*
5 \\*
~~~\EV~NIL \\
\\
;;; Print every third number. \\[3pt]
(loop for i from 10 downto 1 by 3 \\*
~~~~~~do (print i)) \`;{\rm Prints 4 lines}\\
10 \\*
7 \\*
4 \\*
1 \\*
~~~\EV~NIL
\end{lisp}
\begin{lisp}
;;; Step incrementally from the default starting value. \\[3pt]
(loop as i below 5 \\*
~~~~~~do (print i)) \`;{\rm Prints 5 lines} \\
0 \\*
1 \\*
2 \\*
3 \\*
4 \\*
~~~\EV~NIL
\end{lisp}
\end{defloop}
\begin{defloop}
for var [type-spec] \!in! expr1 [\!by! step-fun] \\
as var [type-spec] \!in! expr1 [\!by! step-fun]
[This is the second of seven \cdf{for}/\cdf{as} syntaxes.---GLS]
This construct iterates over the contents of a list. It checks for
the end of the list as if using the Common Lisp function \cdf{endp}.
The variable {\it var\/} is bound to the successive elements of
the list {\it expr1\/} before each
iteration. At the end of each iteration, the function {\it step-fun\/}
is called on the list and is expected to produce a successor list;
the default value for {\it step-fun\/} is the \cdf{cdr} function.
The \cdf{for} or \cdf{as} construct causes termination when the
end of the list is reached.
The loop keywords \cdf{in} and \cdf{by} serve as valid prepositions in
this syntax.
Examples:
\begin{lisp}
;;; Print every item in a list. \\[3pt]
(loop for item in '(1 2 3 4 5) do (print item)) \`;{\rm Prints 5 lines} \\
1 \\*
2 \\*
3 \\*
4 \\*
5 \\*
~~~\EV~NIL \\
\\
;;; Print every other item in a list. \\[3pt]
(loop for item in '(1 2 3 4 5) by \#'cddr \\*
~~~~~~do (print item)) \`;{\rm Prints 3 lines} \\
1 \\*
3 \\*
5 \\*
~~~\EV~NIL
\end{lisp}
\begin{lisp}
;;; Destructure items of a list, and sum the x values \\*
;;; using fixnum arithmetic. \\*
(loop for (item . x) (t . fixnum) \\*
~~~~~~~~~~in '((A . 1) (B . 2) (C . 3)) \\*
~~~~~~unless (eq item 'B) sum x) \\*
~~~\EV~4
\end{lisp}
\end{defloop}
\begin{defloop}
for var [type-spec] \!on! expr1 [\!by! step-fun] \\
as var [type-spec] \!on! expr1 [\!by! step-fun]
[This is the third of seven \cdf{for}/\cdf{as} syntaxes.---GLS]
This construct iterates over the contents of a list. It checks for the
end of the list as if using the Common Lisp function
\cdf{endp}.
The variable {\it var\/} is bound to the successive tails of the list
{\it expr1}. At the end of each iteration, the function {\it step-fun\/}
is called on the list and is expected to produce a successor list;
the default value for {\it step-fun\/} is the \cdf{cdr} function.
The loop keywords \cdf{on} and \cdf{by} serve as valid
prepositions in this syntax.
The \cdf{for} or \cdf{as} construct causes termination when the
end of the list is reached.
Examples:
\begin{lisp}
;;; Collect successive tails of a list. \\*
(loop for sublist on '(a b c d) \\*
~~~~~~collect sublist) \\*
~~~\EV~((A B C D) (B C D) (C D) (D)) \\
\\
;;; Print a list by using destructuring with the loop keyword ON. \\*
(loop for (item) on '(1 2 3) \\*
~~~~~~do (print item)) \`;{\rm Prints 3 lines}\\
1 \\*
2 \\*
3 \\*
~~~\EV~NIL \\
\\
;;; Print items in a list without using destructuring. \\*
(loop for item in '(1 2 3) \\*
~~~~~~do (print item)) \`;{\rm Prints 3 lines}\\
1 \\*
2 \\*
3 \\*
~~~\EV~NIL
\end{lisp}
\end{defloop}
\begin{defloop}
for var [type-spec] \!\Xequal! expr1 [\!then! expr2] \\
as var [type-spec] \!\Xequal! expr1 [\!then! expr2]
[This is the fourth of seven \cdf{for}/\cdf{as} syntaxes.---GLS]
This construct initializes the variable {\it var\/} by setting it to the
result of evaluating {\it expr1\/} on the first iteration, then setting
it to the result of evaluating {\it expr2\/} on the second and
subsequent iterations. If {\it expr2\/} is omitted, the construct
uses {\it expr1\/} on the second and
subsequent iterations. When {\it expr2\/} is omitted, the expanded
code shows the following optimization:
\begin{lisp}
;;; Sample original code: \\*
(loop for x = {\it expr1\/} then {\it expr2\/} do (print x))
\end{lisp}
\begin{lisp}
;;; The usual expansion: \\*
(tagbody \\*
~~~~~~(setq x {\it expr1\/}) \\*
~~tag (print x) \\*
~~~~~~(setq x {\it expr2\/}) \\*
~~~~~~(go tag))
\end{lisp}
\begin{lisp}
;;; The optimized expansion: \\*
(tagbody \\*
~~tag (setq x {\it expr1\/}) \\*
~~~~~~(print x) \\*
~~~~~~(go tag))
\end{lisp}
The loop keywords \cdf{=} and \cdf{then} serve as valid prepositions
in this syntax.
This construct does not provide any termination conditions.
Example:
\begin{lisp}
;;; Collect some numbers. \\*
(loop for item = 1 then (+ item 10) \\*
~~~~~~repeat 5 \\*
~~~~~~collect item) \\*
~~~\EV~(1 11 21 31 41)
\end{lisp}
\end{defloop}
\begin{defloop}
for var [type-spec] \!across! vector \\
as var [type-spec] \!across! vector
[This is the fifth of seven \cdf{for}/\cdf{as} syntaxes.---GLS]
This construct binds the variable {\it var\/} to
the value of each element in the array {\it vector}.
The loop keyword \cdf{across} marks the array {\it vector}; \cdf{across}
is used as a preposition in this syntax.
Iteration stops when there are no more elements in the specified
array that can be referenced.
Some implementations might use a [user-supplied---GLS] \cdf{the} special form
in the {\it vector} form to produce more efficient code.
Example:
\begin{lisp}
(loop for char across (the simple-string (find-message port)) \\*
~~~~~~do (write-char char stream))
\end{lisp}
\end{defloop}
\begin{defloop}
for var [type-spec] \!being! {\!each! | \!the!}
{\!hash-key! | \!hash-keys! | \!hash-value! | \!hash-values!}
{\!in! | \!of!} hash-table [\!using! ({\!hash-value! | \!hash-key!} other-var)] \\
as var [type-spec] \!being! {\!each! | \!the!}
{\!hash-key! | \!hash-keys! | \!hash-value! | \!hash-values!}
{\!in! | \!of!} hash-table [\!using! ({\!hash-value! | \!hash-key!} other-var)]
[This is the sixth of seven \cdf{for}/\cdf{as} syntaxes.---GLS]
This construct iterates over the elements, keys, and values of a hash
table. The variable {\it var\/} takes on the value of each hash key
or hash value in the specified hash table.
The following loop keywords serve as valid prepositions within this syntax.
\begin{flushdesc}
\item[\cdf{being}]
The keyword \cdf{being} marks the loop method to be used, either
\cdf{hash-key} or \cdf{hash-value}.
\item[\cdf{each}, \cdf{the}]
For purposes of readability, the loop keyword \cdf{each}
should follow the loop keyword \cdf{being} when \cdf{hash-key} or
\cdf{hash-value} is used. The loop keyword \cdf{the} is used with
\cdf{hash-keys} and \cdf{hash-values}.
\item[\cdf{hash-key}, \cdf{hash-keys}]
These loop keywords access each key entry of the hash table. If
the name \cdf{hash-value} is specified in a \cdf{using} construct with one
of these loop methods, the iteration can optionally access the keyed
value. The order in which the keys are accessed is undefined; empty
slots in the hash table are ignored.
\item[\cdf{hash-value}, \cdf{hash-values}]
These loop keywords access each value entry of a hash table. If
the name \cdf{hash-key} is specified in a \cdf{using} construct with one of
these loop methods, the iteration can optionally access the key that
corresponds to the value. The order in which the keys are accessed is
undefined; empty slots in the hash table are ignored.
\item[\cdf{using}]
The loop keyword \cdf{using} marks the optional key or the keyed value to
be accessed. It allows you to access the hash key if
iterating over the hash values, and the hash value if
iterating over the hash keys.
\item[\cdf{in}, \cdf{of}]
These loop prepositions mark the hash table {\it hash-table}.
\end{flushdesc}
Iteration stops when there are no more hash keys or hash values to be
referenced in the specified hash table.
\end{defloop}
\begin{defloop}
for var [type-spec] \!being! {\!each! | \!the!}
{\!symbol! | \!present-symbol! | \!external-symbol! |
\!symbols! | \!present-symbols! | \!external-symbols!}
{\!in! | \!of!} package \\
as var [type-spec] \!being! {\!each! | \!the!}
{\!symbol! | \!present-symbol! | \!external-symbol! |
\!symbols! | \!present-symbols! | \!external-symbols!}
{\!in! | \!of!} package
[This is the last of seven \cdf{for}/\cdf{as} syntaxes.---GLS]
This construct iterates over the symbols in a package.
The variable {\it var\/} takes on the value of each symbol
in the specified package.
The following loop keywords serve as valid prepositions within this syntax.
\begin{flushdesc}
\item[\cdf{being}]
The keyword \cdf{being} marks the loop method to be used:
\cdf{symbol}, \cd{present-\discretionary{}{}{}symbol}, or \cdf{external-symbol}.
\item[\cdf{each}, \cdf{the}]
For purposes of readability, the loop keyword \cdf{each}
should follow the loop keyword \cdf{being} when \cdf{symbol},
\cdf{present-symbol}, or \cdf{external-symbol} is used. The loop keyword
\cdf{the} is used with \cdf{symbols}, \cdf{present-symbols}, and
\cdf{external-symbols}.
\item[\cdf{present-symbol}, \cdf{present-symbols}]
These loop methods iterate over the symbols that are present but not
external in a package.
The package to be iterated over is
specified in the same way that package arguments to the Common Lisp function
\cdf{find-package} are specified. If you do not specify the package
for the iteration, the current package is used. If you specify a
package that does not exist, an error is signaled.
\item[\cdf{symbol}, \cdf{symbols}]
These loop methods iterate over symbols that are
accessible from a given package. The package to be iterated over is specified
in the same way that package arguments to the Common Lisp function
\cdf{find-package} are specified. If you do not specify the package
for the iteration, the current package is used. If you specify a
package that does not exist, an error is signaled.
\item[\cdf{external-symbol}, \cdf{external-symbols}]
These loop methods iterate over the external symbols of a package.
The package to be iterated over is specified in
the same way that package arguments to the Common Lisp function
\cdf{find-package} are specified. If you do not specify the package
for the iteration, the current package is used. If you specify a
package that does not exist, an error is signaled.
\item[\cdf{in}, \cdf{of}]
These loop prepositions mark the package {\it package}.
\end{flushdesc}
Iteration stops when there are no more symbols to be referenced in the
specified package.
Example:
\begin{lisp}
(loop for x being each present-symbol of "COMMON-LISP-USER" \\*
~~~~~~do (print x)) \`;{\rm Prints 7 lines in this example}\\*
COMMON-LISP-USER::IN \\*
COMMON-LISP-USER::X \\
COMMON-LISP-USER::ALWAYS \\
COMMON-LISP-USER::FOO \\
COMMON-LISP-USER::Y \\
COMMON-LISP-USER::FOR \\*
COMMON-LISP-USER::LUCID \\*
~~~\EV~NIL
\end{lisp}
\end{defloop}
\begin{defloop}
repeat expr
The \cdf{repeat} construct causes iteration to terminate after a
specified number of times.
The loop body is executed {\it n} times, where {\it n} is the value
of the expression {\it expr}. The {\it expr} argument is evaluated one time
in the loop prologue. If the expression evaluates to zero or
to a negative number, the loop body is not evaluated.
The clause \cdf{repeat} {\it n} is roughly equivalent to a clause
such as
\begin{lisp}
for {\it internal-variable} downfrom (- {\it n} 1) to 0
\end{lisp}
but, in some implementations, the \cdf{repeat} construct might
be more efficient.
Examples:
\begin{lisp}