Lisp入门10-progn 特别式
commonlisp吧
全部回复
仅看楼主
level 13
复数の式を评価する
if 特别式によって、条件に応じて评価する式を分岐させることができるようになりました。 対象の式が単一である场合は问题ありませんが、しかし if によって分岐させて评価する式が复数存在した场合する场合は、if 特别式に式を直接书くだけでは実现できません。
例えば、変数 m が t であれば、式1と式2を実行し、そうでなければ式3と式4を実行しなければならないというような场合です。 条件の结果によって复数の式を评価したいのですが、if が评価する式は任意の数ではなく、一つの式だけです。
复数の式を一度に评価させなければならない场合は progn 特别式を利用します。 progn 特别式は、任意の数の引数を受付、先头の引数から顺に全ての式を评価します。
progn {form}*
progn に対して、引数となる式を复数与えた场合、先头から全ての式が评価されますが、この特别式の结果となるのは最后に评価された式のみです。 その他の式は结果に反映されないため、通常は何らかの副作用を持つ(変数への代入など)式となるでしょう。 progn に引数を何も与えなかった场合、progn 特别式は何も评価せずに nil を返します。
> (progn 10 20 30)
30
> (progn (setq x 10) (setq y 20) (setq z 30))
30
> x
10
> y
20
> z
30
最初の progn 特别式の実行では定数 10、20、30 を评価していますが、progn の戻り値となるのは最后に评価された式である 30 のみで、10 と 20 は何の意味もありません。 そのため、通常はその次の progn のように、変数に値を代入するなど、评価结果に何らかの副作用が持たされる式を指定します。
これを if 特别式で评価させれば、条件の结果によって复数の式を実行するということが可能になります。 つまり (if 条件 (progn ...) (progn ...)) というような形です。
条件の结果によって复数の式を実行する方法として if と progn の组み合わせを解说しましたが、実はこれを一度に行ってくれる when マクロがあります。 when マクロは任意の数の引数を受けることができる if のようなものだと考えてください。
when test {form}*
これは、単に (if test (progn form...)) と同じです。 式 test を条件として、条件の结果が nil でなければ、任意の数の式である form を逐次评価します。 そして、progn 同様に最后に评価した式を when の结果として返します。
when と逆の働きをする unless マクロも存在します。 これは、条件式が nil であれば、それ以降の式を评価するというマクロで、(when (not test) form ...) と同じ効果を持ちます。
unless test {form}*
笔者は、プログラミング言语が提供する机能は最小限にとどめ、复雑な命令は単纯な命令の组み合わせて実现されるべきだと思っているので、unless を使うよりも when not を比较的好んでいます。 これは、どちらを使っても意味は同じなので、プログラマの好みの问题です。
2011年11月06日 07点11分 1
1