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