出現順にフォームを評価することは、あるフォームから別のフォームへ制御が移る最も一般的な方法です。関数本体などの一部のコンテキストでは、これは自動的に行われます。それ以外の場合は、これを実現するために制御構造の構文である
progn(Lispで最も単純な制御構文)を使用する必要があります。
progn 特殊形式は次のようになります。
(progn a b c ...)
また、フォーム a、b、c などをその順に実行するように記述されています。これらのフォームは、progn フォームのボディと呼ばれます。ボディ内の最後のフォームの値が、progn
全体の値となります。(progn) は nil
を返します。
Lispの黎明期には、2つ以上のフォームを連続して実行し、そのうち最後のフォームの値を利用する唯一の方法がprognであった。しかしプログラマは、(当時)1つのフォームしか許可されていなかった関数本体の中で、しばしばprognを用いる必要があることに気づいた。そこで、関数本体は暗黙的なprognとなり、実際のprognの本体と同様に、複数のフォームが許可されるようになった。他の多くの制御構造も同様に、暗黙的なprognを備えている。その結果、prognは何年も前ほどは使われなくなった。現在では、主にunwind-protect、and、orの内部、あるいはifのthen部分で必要とされる。
この特殊形式は、すべての forms をテキスト順に評価し、最終的な形式の結果を返します。
(progn (print "The first form")
(print "The second form")
(print "The third form"))
⊣ "The first form"
⊣ "The second form"
⊣ "The third form"
⇒ "The third form"
他の2つのコンストラクトも同様に一連のフォームを評価しますが、異なる値を返します:
この特殊形式は、form1 とすべての forms をテキスト順に評価し、form1 の結果を返します。
(prog1 (print "The first form")
(print "The second form")
(print "The third form"))
⊣ "The first form"
⊣ "The second form"
⊣ "The third form"
⇒ "The first form"
変数 x 内のリストから最初の要素を削除し、その元の要素の値を返す方法を以下に示します。
(prog1 (car x) (setq x (cdr x)))
この特殊形式は、form1、form2、および以下のすべてのformsをテキスト順に評価し、form2の結果を返します。
(prog2 (print "The first form")
(print "The second form")
(print "The third form"))
⊣ "The first form"
⊣ "The second form"
⊣ "The third form"
⇒ "The second form"