** Format:**
` (do ((<var1> <init1> <update1>)`
` (<var2> <init2> <update2>)`
` .`
` .`
` (<varN> <initN> <updateN>))`
` (<test> <body1>)`
` <body2>)`

** Required arguments:**
2

` ((<var> <init> <update>)...)`: a list of zero or more variable
clauses; ` <var>` is a symbol appropriate as a variable
name; ` <init>`, which is optional, is any LISP
expression; ` <update>`, which is optional, is any LISP
expression.
` (<test> <body1>)`: ` <test>` is any LISP expression;
` <body1>` is a sequence of zero or more LISP
expressions.

** Optional arguments:**
arbitrary

` <body2>`: a sequence of zero or more LISP expressions

The special form do allows the programmer to specify
iteration. The first part of do is a list of variables; if ` <init>`
is provided, the ` <var>`'s are initialised to the result of evaluating
the corresponding ` <init>`. If no ` <init>` is provided, ` <var>` is
initialised to NIL. The optional ` <update>` expression may
specify how the variable is to be modified after every iteration.
After every iteration, ` <var>` is set to result of evaluating
` <update>`.
Initialisation and updating for all variables is performed in
parallel; thus a ` <var>` in one clause may not be used in the `
<init>` or ` <update>` of another clause.

The second part of ``do,'' the ` <test>`, checks for termination. The
` <test>` is evaluated before each pass; if it returns a non-NIL value,
the sequence of expressions in ` <body1>` are evaluated one by one; do
returns the value of the last expression in ` <body1>`. If ` <body1>`
contains no expressions, do returns NIL.

The third part of the
do is the body of the iteration, ` <body2>`. At each pass, the sequence
of expressions in ` <body2>` are evaluated one by one.
If ` <body2>` contains an expression of the form ` (return <expr>)`, where
` <expr>` is any LISP expression, do terminates immediately and returns
the result of evaluating `<expr>`.

** Examples:**

(setq sum (+ sum (first lst)))) 25 > (do ((lst '(a (b (c d)) e (f)) (rest lst)) (len 0 (+ 1 len))) ; determines length of lst ((null lst) len)) ; "do," here, has no body 4 > (defun my-exp (m n) ; raise m to power of n (do ((result 1) (exp n)) ((= exp 0) result) (setq result (* result m)) (setq exp (- exp 1)))) MY-EXP > (my-exp 5 3) 125 > (defun my-exp2 (m n) ; simpler version of my-exp (do ((result 1 (* result m)) (exp n (- exp 1))) ((= exp 0) result)))

November 1999