DOLIST and DOTIMES

I’ll start with the easy-to-use **DOLIST** and **DOTIMES** macros.

**DOLIST** loops across the items of a list, executing the loop body with a variable holding the successive items of the list.5 This is the basic skeleton (leaving out some of the more esoteric options):

  1. (dolist (var list-form)
  2. body-form*)

When the loop starts, the list-form is evaluated once to produce a list. Then the body of the loop is evaluated once for each item in the list with the variable var holding the value of the item. For instance:

  1. CL-USER> (dolist (x '(1 2 3)) (print x))
  2. 1
  3. 2
  4. 3
  5. NIL

Used this way, the **DOLIST** form as a whole evaluates to **NIL**.

If you want to break out of a **DOLIST** loop before the end of the list, you can use **RETURN**.

  1. CL-USER> (dolist (x '(1 2 3)) (print x) (if (evenp x) (return)))
  2. 1
  3. 2
  4. NIL

**DOTIMES** is the high-level looping construct for counting loops. The basic template is much the same as **DOLIST**‘s.

  1. (dotimes (var count-form)
  2. body-form*)

The count-form must evaluate to an integer. Each time through the loop var holds successive integers from 0 to one less than that number. For instance:

  1. CL-USER> (dotimes (i 4) (print i))
  2. 0
  3. 1
  4. 2
  5. 3
  6. NIL

As with **DOLIST**, you can use **RETURN** to break out of the loop early.

Because the body of both **DOLIST** and **DOTIMES** loops can contain any kind of expressions, you can also nest loops. For example, to print out the times tables from 1 � 1 = 1 to 20 � 20 = 400, you can write this pair of nested **DOTIMES** loops:

  1. (dotimes (x 20)
  2. (dotimes (y 20)
  3. (format t "~3d " (* (1+ x) (1+ y))))
  4. (format t "~%"))