繰り返し(iteration)とは、プログラムの一部を繰り返し実行することを意味します。たとえばリストの各要素、または0からnの整数にたいして、繰り返し一度ずつ何らかの計算を行いたいとしましょう。Emacs
Lispではスペシャルフォームwhile
でこれを行なうことができます:
while
は最初にconditionを評価する。結果が非nil
ならformsをテキスト順に評価する。その後にconditionを再評価して結果が非nil
なら、再度formsを評価する。この処理はconditionがnil
に評価されるまで繰り返される。
繰り返し回数に制限はない。このループはconditionがnil
に評価されるか、エラーになるか、またはthrow
で抜け出す(非ローカル脱出を参照)まで継続される。
while
フォームの値は常にnil
である。
(setq num 0) ⇒ 0
(while (< num 4) (princ (format "Iteration %d." num)) (setq num (1+ num))) -| Iteration 0. -| Iteration 1. -| Iteration 2. -| Iteration 3. ⇒ nil
各繰り返しごとに何かを実行して、その後も終了テストを行なうrepeat-untilループを記述するには、以下のようにwhile
の1番目の引数としてbodyの後に終了テストを記述して、それをprogn
の中に配置する:
(while (progn (forward-line 1) (not (looking-at "^$"))))
これは1行前方に移動して、空行に達するまで行単位の移動を継続する。独特な点はwhile
がbodyをもたず、終了テスト(これはポイント移動という実処理も行なう)だけを行うことである。
マクロdolist
およびdotimes
は、2つの一般的な種類のループを記述する、便利な方法を提供します。
この構文はlistの各要素に一度bodyを実行して、カレント要素をローカルに保持するように、変数varにバインドする。その後にresultを評価した値、resultが省略された場合はnil
をリターンする。たとえば以下はreverse
関数を定義するためにdolist
を使用する方法の例である:
(defun reverse (list) (let (value) (dolist (elt list value) (setq value (cons elt value)))))
この構文は0以上count未満の各整数にたいして、一度bodyを実行してから、繰り返しのカレント回数となる整数を変数varにバインドする。その後にresultの値、resultが省略された場合はnil
をリターンする。resultの使用は推奨しない。以下はdotimes
を使用して、何らかの処理を100回行なう例:
(dotimes (i 100) (insert "I will not obey absurd orders\n"))