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