Structural Informatics Group (SIG) logo
Home | Projects | Demos | Downloads | Publications | Local Info | About Us | New site
Go to the first, previous, next, last section, table of contents.



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

Go to the first, previous, next, last section, table of contents.