Some things that are unique to iterate
:
No rigid order for clauses
loop
requires that all for
clauses appear before the loop body, for example before while
. It's ok for iter
:
(iter (for x in '(1 2 99)
(while (< x 10))
(for y = (print x))
(collect (list x y)))
Accumulating clauses can be nested
collect
, appending
and the like can appear anywhere:
(iter (for x in '(1 2 3))
(case x
(1 (collect :a))
(2 (collect :b))))
finding
;; Finding the longest list in a list of lists:
(iter (for lst in '((a) (b c d) (e f)))
(finding lst maximizing (length lst)))
=> (B C D)
;; The rough equivalent in LOOP:
(loop with max-lst = nil
with max-key = 0
for lst in '((a) (b c d) (e f))
for key = (length lst)
do
(when (> key max-key)
(setf max-lst lst
max-key key))
finally (return max-lst))
=> (B C D)
https://common-lisp.net/project/iterate/ first example
Finding the minimum of x^2 - 4x + 1
in an interval:
(iter (for x from -5 to 5 by 1/100)
(finding x minimizing (1+ (* x (- x 4)))))
2
©Common Lisp Recipes p.198
next-iteration
it is like "continue" and loop doesn't have it.
iter
also has first-iteration-p
and (if-first-time then else)
.
https://web.archive.org/web/20170713081006/https://items.sjbach.com/211/comparing-loop-and-iterate
generators
generate
and next
. A generator is lazy, it goes to the next value when said explicitly.
(iter (for i in '(1 2 3 4 5))
(generate c in-string "black")
(if (oddp i) (next c))
(format t "~a " c))
b b l l a
NIL
https://sites.google.com/site/sabraonthehill/loop-v-iter
previous
(iter (for el in '(a b c d e))
(for prev-el previous el)
(collect (list el prev-el)))
=> ((A NIL) (B A) (C B) (D C) (E D))
although it is doable with loop
's parallel binding and
:
(loop for el in '(a b c d e)
and prev-el = nil then el
collect (list el prev-el))
more clauses
in-string
LOOP offers collecting, nconcing, and appending. ITERATE has these and also adjoining
, unioning
, nunioning
, and accumulating
.
(iter (for el in '(a b c a d b))
(adjoining el))
=> (A B C D)
(adjoin
is a set operation)
LOOP has summing, counting, maximizing, and minimizing. ITERATE also includes multiplying
and reducing
. reducing is the generalized reduction builder:
(iter (with dividend = 100)
(for divisor in '(10 5 2))
(reducing divisor by #'/ initial-value dividend))
=> 1
https://web.archive.org/web/20170713105315/https://items.sjbach.com/280/extending-the-iterate-macro
It is extensible
(defmacro dividing-by (num &keys (initial-value 0))
`(reducing ,num by #'/ initial-value ,initial-value))
(iter (for i in '(10 5 2))
(dividing-by i :initial-value 100))
=> 1
but there is more.
https://common-lisp.net/project/iterate/doc/Rolling-Your-Own.html#Rolling-Your-Own
https://web.archive.org/web/20170713105315/https://items.sjbach.com/280/extending-the-iterate-macro where in the Appendix, we see two examples of loop
extensions. But they are not portable really, the code is full of #+(or allegro clisp-aloop cmu openmcl sbcl scl) (ansi-loop::add-loop-path …
, sb-loop::add-loop-path
etc.
Stuff missing in iterate
No parallel binding like loop's and
, but not needed?.
I'm probably missing here.
But that's not all, there are more differences.