Next: , Previous: , Up: Control Structures   [Contents][Index]


10.4 繰り返し

繰り返し(iteration)とは、プログラムの一部を繰り返し実行することを意味します。たとえばリストの各要素、または0からnの整数にたいして、繰り返し一度ずつ何らかの計算を行いたいとしましょう。Emacs Lispではスペシャルフォームwhileでこれを行なうことができます:

Special Form: while condition forms…

whileは最初にconditionを評価する。結果が非nilならformsをテキスト順に評価する。その後にconditionを再評価して結果が非nilなら、再度formsを評価する。この処理はconditionnilに評価されるまで繰り返される。

繰り返し回数に制限はない。このループはconditionnilに評価されるか、エラーになるか、またはthrowで抜け出す(Nonlocal Exitsを参照)まで継続される。

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つの一般的な種類のループを記述する、便利な方法を提供します。

Macro: dolist (var list [result]) body…

この構文はlistの各要素に一度bodyを実行して、カレント要素をローカルに保持するように、変数varにバインドする。その後にresultを評価した値、resultが省略された場合はnilをリターンする。たとえば以下はreverse関数を定義するためにdolistを使用する方法の例である:

(defun reverse (list)
  (let (value)
    (dolist (elt list value)
      (setq value (cons elt value)))))
Macro: dotimes (var count [result]) body…

この構文は0以上count未満の各整数にたいして、一度bodyを実行してから、繰り返しのカレント回数となる整数を変数varにバインドする。その後にresultの値、resultが省略された場合はnilをリターンする。以下はdotimesを使用して、何らかの処理を100回行なう例である:

(dotimes (i 100)
  (insert "I will not obey absurd orders\n"))