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