24. "Introduction"
.setq loop-chapter chapter-number
.mindex loop
.setq loop-fun page
loop is a Lisp macro which provides a programmable
iteration facility. The same loop module operates compatibly in
Zetalisp, Maclisp (PDP-10 and Multics), and NIL, and a
moderately compatible package is under development for the MDL
programming environment. loop was inspired by the "FOR"
facility of CLISP in InterLisp; however, it is not compatible and
differs in several details.
The general approach is that a form introduced by the word
loop generates a single program loop, into which a large variety
of features can be incorporated. The loop consists of some
initialization (prologue) code, a body which may be executed
several times, and some exit (epilogue) code. Variables may be
declared local to the loop. The features are concerned with loop
variables, deciding when to end the iteration, putting user-written
code into the loop, returning a value from the construct, and
iterating a variable through various real or virtual sets of values.
The loop form consists of a series of clauses, each
introduced by a keyword symbol. Forms appearing in or implied by the
clauses of a loop form are classed as those to be executed as
initialization code, body code, and/or exit code; within each part of
the template that loop fills in, they are executed strictly in
the order implied by the original composition. Thus, just as in
ordinary Lisp code, side-effects may be used, and one piece of code
may depend on following another for its proper operation. This is the
principal philosophy difference from InterLisp's "FOR" facility.
Note that loop forms are intended to look like stylized
English rather than Lisp code. There is a notably low density of
parentheses, and many of the keywords are accepted in several
synonymous forms to allow writing of more euphonious and grammatical
English. Some find this notation verbose and distasteful, while
others find it flexible and convenient. The former are invited to
stick to do.
Here are some examples to illustrate the use of loop.
.group
| .setq print-elements-of-list-example page
(defun print-elements-of-list (list-of-elements)
(loop for element in list-of-elements
do (print element)))
|
The above function prints each element in its argument, which
should be a list. It returns nil.
.end_group
.group
| (defun gather-alist-entries (list-of-pairs)
(loop for pair in list-of-pairs
collect (car pair)))
|
gather-alist-entries takes an association list and
returns a list of the "keys"; that is, (gather-alist-entries
'((foo 1 2) (bar 259) (baz))) returns (foo bar baz).
.end_group
.group
| (defun extract-interesting-numbers (start-value end-value)
(loop for number from start-value to end-value
when (interesting-p number) collect number))
|
The above function takes two arguments, which should be
fixnums, and returns a list of all the numbers in that range
(inclusive) which satisfy the predicate interesting-p.
.end_group
.group
| (defun find-maximum-element (an-array)
(loop for i from 0 below (array-dimension-n 1 an-array)
maximize (aref an-array i)))
|
find-maximum-element returns the maximum of the elements
of its argument, a one-dimensional array. For Maclisp, aref
could be a macro which turns into either funcall or
arraycall depending on what is known about the type of the array.
.end_group
.group
| (defun my-remove (object list)
(loop for element in list
unless (equal object element) collect element))
|
my-remove is like the Lisp function delete, except
that it copies the list rather than destructively splicing out
elements. This is similar, although not identical, to the
Zetalisp function remove.
.end_group
.group
| (defun find-frob (list)
(loop for element in list
when (frobp element) return element
finally (ferror nil "No frob found in the list ~S" list)))
|
This returns the first element of its list argument which
satisfies the predicate frobp. If none is found, an error is
generated.
.end_group
This document was generated
by Brad Parker on June, 13 2006
using texi2html