@@ -1436,14 +1436,6 @@ In ~loopy~, iteration commands are named after what they iterate through. For
1436
1436
example, the =array= and =list= commands iterate through the elements of arrays
1437
1437
and lists, respectively.
1438
1438
1439
- #+ATTR_TEXINFO: :tag Note
1440
- #+begin_quote
1441
- In general, iteration variables (such as the ~i~ and ~j~ above) are initialized
1442
- to ~nil~. For efficiency, some commands do not do this. In such cases, the
1443
- initial value of an iteration variable can be set using the =with= special macro
1444
- argument, but this can result in less efficient code.
1445
- #+end_quote
1446
-
1447
1439
Because some iteration commands use their variable to manage state, it is an
1448
1440
error to use the same iteration variable for multiple iteration commands.
1449
1441
@@ -1454,6 +1446,62 @@ error to use the same iteration variable for multiple iteration commands.
1454
1446
(finally-return t))
1455
1447
#+end_src
1456
1448
1449
+ Iteration variables are initialized to ~nil~ and they are updated at the point
1450
+ in the loop body corresponding to the loop command's position in the macro's
1451
+ arguments.
1452
+
1453
+ #+begin_src emacs-lisp
1454
+ ;; `elem' retains its value from the previous
1455
+ ;; iteration until it is updated again:
1456
+ ;;
1457
+ ;; => (((1 . nil) ; before
1458
+ ;; (2 . 1)
1459
+ ;; (3 . 2)
1460
+ ;; (4 . 3))
1461
+ ;; ((1 . 1) ; after
1462
+ ;; (2 . 2)
1463
+ ;; (3 . 3)
1464
+ ;; (4 . 4)))
1465
+ (loopy (numbers nth :from 1)
1466
+ (collect elem-before (cons nth elem))
1467
+ (list elem '(1 2 3 4))
1468
+ (collect elem-after (cons nth elem))
1469
+ (finally-return elem-before
1470
+ elem-after))
1471
+ #+end_src
1472
+
1473
+ Generally, iteration commands with conditions check whether to terminate the
1474
+ loop /before/ the next iteration is run. They do not check their conditions
1475
+ while running the current iteration. In the below example, note that the final
1476
+ value of ~i~ is 2 and not 3, even though the =do= command (similar to
1477
+ ~cl-loop~'s =do= keyword) is placed before the =list= command. Even though ~i~
1478
+ is updated before ~elem~ is updated, the =list= command's condition that decides
1479
+ whether to continue the loop is checked /before/ the code in the =do= command is
1480
+ run.
1481
+
1482
+ #+begin_src emacs-lisp
1483
+ ;; => 2, not 3
1484
+ (let ((i 0))
1485
+ (loopy (do (setq i (1+ i)))
1486
+ (list elem '(0 1)))
1487
+ i)
1488
+ #+end_src
1489
+
1490
+ If you do wish to conditionally leave the loop during an iteration, consider
1491
+ using the =leave= and =leave-from= commands ([[#exiting-the-loop-early]]).
1492
+
1493
+ #+begin_src emacs-lisp
1494
+ ;; => (3 (0 1))
1495
+ (loopy (with (some-list (list 0 1))
1496
+ (i 0))
1497
+ (do (setq i (1+ i)))
1498
+ (when (null some-list)
1499
+ (leave))
1500
+ (collect elems (car some-list))
1501
+ (do (setq some-list (cdr some-list)))
1502
+ (finally-return i elems))
1503
+ #+end_src
1504
+
1457
1505
Unlike ~cl-loop~ and like Common Lisp's ~iterate~, arguments of the iteration
1458
1506
commands are evaluated only once. For example, while iterating through numbers,
1459
1507
you can't suddenly change the direction of the iteration in the middle of the
@@ -1472,12 +1520,15 @@ loop. This restriction allows for producing more efficient code.
1472
1520
#+findex: cycling
1473
1521
#+findex: repeat
1474
1522
#+findex: repeating
1475
- - =(cycle|repeat [VAR] EXPR)= :: Run the loop for =EXPR= iterations. If
1476
- specified, =VAR= starts at 0, and is incremented by 1 at the end of each step
1477
- in the loop. If =EXPR= is 0, then the loop isn't run.
1523
+ - =(cycle|repeat [VAR] EXPR)= :: Run the loop for =EXPR= iterations.
1524
+
1525
+ If given, then during the loop, =VAR= is set to the number of iteration steps
1526
+ that have been run (0 for the first iteration step).
1478
1527
1479
- For efficiency, =VAR= is not initialized to ~nil~. This can be overridden
1480
- using the =with= special macro argument, which can result in slower code.
1528
+ If =EXPR= is 0, then the loop isn't run.
1529
+
1530
+ =(cycle VAR EXPR)= works the same as =(numbers VAR :from 0 :below EXPR)=
1531
+ ([[#numeric-iteration]]).
1481
1532
1482
1533
This command also has the aliases =cycling= and =repeating=.
1483
1534
@@ -1493,6 +1544,14 @@ loop. This restriction allows for producing more efficient code.
1493
1544
(collect i)
1494
1545
(collect j))
1495
1546
1547
+ ;; Same as above:
1548
+ ;;
1549
+ ;; => (10 0 10 1 10 2)
1550
+ (loopy (with (i 10))
1551
+ (numbers j :from 0 :below 3)
1552
+ (collect i)
1553
+ (collect j))
1554
+
1496
1555
;; An argument of 0 stops the loop from running:
1497
1556
;; => nil
1498
1557
(loopy (cycle 0)
@@ -1519,13 +1578,6 @@ loop. This restriction allows for producing more efficient code.
1519
1578
once, =yield-result= is an expression which is substituted into the loop body.
1520
1579
Therefore, =yield-result= can be used to repeatedly call functions.
1521
1580
1522
- For efficiency, when possible, =VAR= is bound to the yielded value before each
1523
- step of the loop, which is used to detect whether the iterator signals that it
1524
- is finished. This is not possible when destructuring. You can override this
1525
- behavior by using the =with= special macro argument, which can result in
1526
- slower code and tells the macro that the initial value of =VAR= is meaningful
1527
- and to update =VAR= during the loop.
1528
-
1529
1581
This command also has the name =iterating=.
1530
1582
1531
1583
#+begin_src emacs-lisp
@@ -1632,11 +1684,6 @@ variants =numbers-up= and =numbers-down=.
1632
1684
=(list i (number-sequence 1 10))=, and =(numbers i 3)= is similar to
1633
1685
=(set i 3 (1+ i))=.
1634
1686
1635
- For efficiency, _=VAR= is initialized to the starting numeric value_, not
1636
- ~nil~, and is updated at the end of each step of the loop. This can be
1637
- overridden using the =with= special macro argument, which can result in slower
1638
- code.
1639
-
1640
1687
In its most basic form, =numbers= iterates from a starting value to an
1641
1688
inclusive ending value using the =:from= and =:to= keywords, respectively.
1642
1689
@@ -1646,6 +1693,34 @@ variants =numbers-up= and =numbers-down=.
1646
1693
(collect i))
1647
1694
#+end_src
1648
1695
1696
+ Unlike ~cl-loop~, =VAR= is not initialized to the starting value given.
1697
+ Instead, =VAR= is updated during the loop, like in other iteration
1698
+ commands. This avoids unexpectedly changing the value of =VAR= after the
1699
+ iteration step, as happens with some implementations of Common Lisp's ~loop~
1700
+ macro (such ~cl-loop~).
1701
+
1702
+ #+begin_src emacs-lisp
1703
+ ;; => (4 (1 2 3 4))
1704
+ (loopy (list elem (list 1 2 3 4))
1705
+ (numbers num :from 1)
1706
+ (collect nums num)
1707
+ (finally-return num nums))
1708
+
1709
+ ;; => (5 (1 2 3 4))
1710
+ (cl-loop for elem in (list 1 2 3 4)
1711
+ for num from 1
1712
+ collect num into nums
1713
+ finally return (list num nums))
1714
+
1715
+ ;; SBCL returns 4, not 5:
1716
+ ;;
1717
+ ;; => (4 (1 2 3 4))
1718
+ (loop for elem in (list 1 2 3 4)
1719
+ for num from 1
1720
+ collect num into nums
1721
+ finally (return (list num nums)))
1722
+ #+end_src
1723
+
1649
1724
If the ending value is not given, then the value is incremented by 1 without
1650
1725
end.
1651
1726
@@ -1929,11 +2004,6 @@ source sequences.
1929
2004
- =(cons|conses VAR EXPR &key by)= :: Loop through the cons cells of =EXPR=.
1930
2005
Optionally, find the cons cells via the function =by= instead of =cdr=.
1931
2006
1932
- For efficiency, when possible, =VAR= is initialized to the value of =EXPR=,
1933
- not ~nil~, and is updated at the end of each step in the loop. This is not
1934
- possible when destructuring. Such initialization can be overridden by using
1935
- the =with= special macro argument, which can result in slower code.
1936
-
1937
2007
This command also has the alias =consing=.
1938
2008
1939
2009
#+BEGIN_SRC emacs-lisp
@@ -2214,11 +2284,6 @@ source sequences.
2214
2284
and are compatible with features from the built-in =seq= library, such as
2215
2285
~seq-elt~ and ~seq-do~.
2216
2286
2217
- For efficiency, when possible, =VAR= is initialized to the value of =EXPR=,
2218
- not ~nil~, and is updated at the end of each step in the loop. This is not
2219
- possible when destructuring. Such initialization can be overridden by using
2220
- the =with= special macro argument, which can result in slower code.
2221
-
2222
2287
Sub-streams can only be destructured using the =&seq= feature of the default
2223
2288
destructuring method ([[#basic-destructuring][Basic Destructuring]]), or by using the =seq= flag
2224
2289
([[#flags][Using Flags]]). Streams are neither lists nor arrays.
@@ -2313,11 +2378,6 @@ iterate.
2313
2378
With =numbers=, one would first need to explicitly calculate the length of the
2314
2379
sequence.
2315
2380
2316
- Similar to =numbers=, for efficiency, =VAR= is initialized to the starting
2317
- index value, not ~nil~, and is updated at the end of each step of the loop.
2318
- This can be overridden using the =with= special macro argument, which can
2319
- result in slower code.
2320
-
2321
2381
#+begin_src emacs-lisp
2322
2382
;; => (97 98 99 100 101 102)
2323
2383
(loopy (with (my-string "abcdef"))
0 commit comments