type: special form (fsubr) location: built-in source file: xlcont.c Common LISP compatible: yes supported on: all machines
(do ( [ <binding> ... ] ) ( <done-expr> [ <result> ] ) [ <expr> ... ] ) <binding> - a variable binding which is can take one of the following forms: <symbol> ( <symbol> <init-expr> [<step-expr>] ) <symbol> - a symbol <init-expr> - an initialization expression for <symbol> <step-expr> - an expression that <symbol> symbol is updated at the end of each loop <done-expr> - iteration ends when this returns non-NIL value <result> - an optional expression for the returned result <expr> - expressions comprising the body of the loop which may contain RETURNs, GOs or tags for GO
The DO special form is basically a 'while' looping construct that contains symbols (with optional initializations and updates), a loop test (with an optional return value) and a block of code (expressions) to evaluate. The DO form evaluates its initializations and updates in no specified order (as opposed to DO* which does it in sequential order). The sequence of these events is:
<init-expr> execution while not <done-expr> do loop code execution <step-expr> execution end-while return <result>
The first form after the DO is the 'binding' form. It contains a series of <symbol>'s or <binding>'s. The <binding> is a <symbol> followed by an initialization expression <init-expr> and an optional <step-expr>. If there is no <init-expr>, the <symbol> will be initialized to NIL. There is no specification as to the order of execution of the bindings or the step expressions - except that they happen all together.
The DO form will go through and create and initialize the symbols. This is followed by evaluating the <done-expr>. If <done-expr> returns a non-NIL value, the loop will terminate. If <done-expr> returns a NIL value then the DO will sequentially execute the <expr>'s. After execution of the loop <expr>'s, the <symbol>'s are set to the <step-expr>'s (if the <step-expr>'s exist). Then, the <done-expr> is re-evaluated, and so on.... The value of the <result> expression is evaluated and returned. If no <result> is specified, NIL is returned. When the DO is finished execution, the <symbol>'s that were defined will no longer exist or retain their values.
(do (i) ; DO loop with var I ((eql i 0) "done") ; test and result (print i) (setq i 0) (print i)) ; prints NIL 0 ; returns "done" (do (i) ; DO loop with var I ((eql i 0)) ; test but no result (print i) (setq i 0) (print i)) ; prints NIL 0 ; returns NIL (do ; DO loop ((i 0 (setq i (1+ i))) ; var I=0 increment by 1 (j 10 (setq j (1- j))) ) ; var J=10 decrement by 1 ((eql i j) "met in the middle" ) ; test and result (princ i) (princ " ") ; prints 0 10 (princ j) (terpri)) ; 1 9 ; 2 8 ; 3 7 ; 4 6 ; returns "met in the middle"