GNU Emacs 32.0.50 (9008bf64c3) のマニュアルを PLaMo 翻訳で機械翻訳したものです。誤訳を含むことがあります。原文: https://www.gnu.org/software/emacs/manual/html_node/elisp/Iteration.html ・ emacs-doc.conao3.com

11.5 イテレーション

反復とは、プログラムの一部を繰り返し実行することを指します。例えば、リストの各要素に対して、あるいは0からnまでの各整数に対して、ある計算を1回ずつ繰り返したい場合があるでしょう。Emacs Lispでは、特殊フォームwhileを用いてこれを行うことができます:

特殊形式: while condition forms…

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 ループを記述するには、ここに示すように、本体に続いて終了判定を記述したものを progn とし、それを while の第1引数として渡します:

(while (progn
         (forward-line 1)
         (not (looking-at "^$"))))

これは1行分進み、空行に到達するまで行単位で移動し続けます。whileに本体がなく、終端判定(これが実際にポイントを移動させる役割も担っています)のみがあるという点で独特です。

dolist と dotimes マクロを使えば、よくある2種類のループを便利に記述できます。

マクロ: dolist (var list [result]) body…

この構文は、list の各要素に対して body を1回ずつ実行し、変数 var をローカルにバインドして現在の要素を保持します。その後、result を評価した値、あるいは result が省略されている場合は nil の値を返します。例えば、dolist を使用して reverse 関数を定義する方法は以下の通りです。

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

この構文は、0(含む)からcount(除く)までの各整数に対してbodyを1回ずつ実行し、現在の反復における整数に変数varをバインドします。その後、resultを評価した値、あるいはresultが省略されている場合はnilを返します。resultの使用は非推奨です。以下に、dotimesを使用して何かを100回行う例を示します。

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