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)))
© Colin Allen & Maneesh Dhagat