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 with darcs (this is the recommended way):
darcs get http://common-lisp.net/project/iterate/darcs/iterate
-
You can get it by asdf-install, if you have
that installed, via:
CL-USER> (asdf-install:install :iterate)
Several lines of compiler output will come up; you'll be asked if you want to accept my GPG key, if you have gnupg installed, and after that, you have iterate installed.
-
If you don't have ASDF-INSTALL in your lisp, but you have ASDF, you
can just grab the latest tarball at
http://common-lisp.net/project/iterate/releases/iterate-current.tar.gz and unpack
it into a directory, say
/home/you/iterate-1.0.4. Make a symbolic link callediterate.asdfrom yourasdf:*central-repository*directory to the file/home/you/iterate-1.0.4/iterate.asd, and you're ready to use iterate.
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, 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 generators:
(iterate (generate i from 0 to 6) (for (key . value) in '((a . 2) (zero . 10) (one . 20) (d . 5))) (when (>= value 10) (collect (cons key (next i))))) ;; gives: ((ZERO . 0) (ONE . 1))Generators are like lazy counters - they remain at one value every time through the loop, until you request the next value. This can be pretty handy in some situations.
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.Development
There is a darcs repository for iterate on common-lisp.net. You can browse the repository or get the tree with the following command line:
darcs get *YOUR-USER*@common-lisp.net:/project/iterate/darcs/iterate
Bugs, feature suggestions and requests
Send those to the Iterate development mailing list at < iterate-devel@common-lisp.net>
The current 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 with darcs (this is the recommended way):