next up previous
Contents Next: documentation (FUNCTION) Up: Appendix: Selected Lisp Previous: defun (MACRO)

do (SPECIAL FORM)

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)))



next up previous
Contents Next: documentation (FUNCTION) Up: Appendix: Selected Lisp Previous: defun (MACRO)



© Colin Allen & Maneesh Dhagat
November 1999