About iterate
iterate is an iteration construct for Common Lisp. It is similar to the CL:LOOP macro, with these distinguishing marks:
- it is extensible,
- it helps editors like Emacs indent iterate forms by having a more lisp-like syntax, and
- it isn't part of the ANSI standard for Common Lisp (which is sometimes a bad thing and sometimes good).
Where to get it
- The Iterate Manual in PDF
- The Iterate Manual in browsable HTML
- Iterate itself
Iterate has spent most of its life in the CMU AI archive as a lisp file for pre-ANSI Common Lisps. Some people have adapted it to other implementations, but the most activly maintained version right now is the one you find here.
-
You can get the latest version from gitlab (this is the recommended way):
git clone https://gitlab.common-lisp.net/iterate/iterate.git
- You can also get it with quicklisp.
- Alternatively, you can just grab the latest tarball and unpack it into a directory that is explored by your ASDF configuration.
How to make it available to your code
If you're using ASDF (highly recommended), have :iterate on the :depends-on list to your system, like this:
(defsystem my-example :depends-on (:iterate) :components ((:file "foo")))
If you're not using ASDF (not recommended), use code like this in one of the files that use the iterate construct:
(eval-when (:compile-toplevel :load-toplevel :execute) (require 'iterate))
Some examples
...to highlight the superiority of the iterate construct (-:
Finding the longest list in a list of lists:
(iterate (for elt in list-of-lists) (finding elt maximizing (length elt)))
Whereas with loop (with whose maximizing clause can be used to find the greatest sublist length only), you'd have to use something like:
(loop with max-elt = nil with max-key = 0 for elt in list-of-lists for key = (length elt) do (when (> key max-key) (setq max-elt elt max-key key)) finally (return max-elt))
So, which version is clearer? I know which I prefer. (-:
Here's another example, using named blocks:
(iter outer (for i below (array-dimension ar 0)) (iter (for j below (array-dimension ar 1)) (in outer (collect (aref ar i j)))))
A named block in an iterate form lets you perform operations inside the context of that named form from iterate forms nested inside it. So here, in this example, we collect all elements in a two-dimensional array in a flat list. The loop equivalent isn't very nice.
You can find more documentation on iterate and its features (there are a lot more than I can demonstrate in this document!) in the
doc/
directory in your iterate distribution.Bugs, feature suggestions and requests
You may file an issue in the gitlab page.
There's a mailing list at iterate-devel@common-lisp.net (also note the list info and archives).
An old bugs file can be found at the current iterate bugs page.
We are looking forward to hearing from you!
-
You can get the latest version from gitlab (this is the recommended way):