今まで修行(?)のために繰り返し処理も再帰を使って表現していたため、
CommonLispが用意してるループマクロ類の使い方を全然知りませんでした。
というわけでメモ。

(dotimes (var limit result) S式 ...)

(let ((x nil))
  (dotimes (i 16 (nreverse x))
    (setq x (cons i x)) ))

(dolist (var init-form result) S式 ... )

(let ((mylist '(0 1 2 3 4 5 6 7 8 9 10)))
  (dolist (x mylist "finish !") (print (expt 2 x))) )

(do ((var [init-form [step-form]]) ...) (end-test [result]) S式 ... )

(do ( (a 0 (1+ a)) (b) );;bはnil
    ( (= a 10) (nreverse b) );;真で抜ける
  (setq b (cons a b)) )

参考:
http://www.geocities.jp/m_hiroi/xyzzy_lisp/abclisp04.html



[追記]
doの他にdo*というものがあるみたい。
何が違うのかmacroexpandで確かめてみた(xyzzy)↓

(macroexpand
 '(do ((x 1 (1+ x)))
   ((= x 10) x)) )(block nil (let ((x 1)) (lisp::*loop (if (= x 10) (return (progn x))) (tagbody) (psetq x (1+ x)))))


(macroexpand
 '(do* ((x 1 (1+ x)))
   ((= x 10) x)) )(block nil (let* ((x 1)) (lisp::*loop (if (= x 10) (return (progn x))) (tagbody) (setq x (1+ x)))))


予想通りlet*になっていただけでした。