Ex. 4.25
作用順序の場合、unless の引数が先に評価される。
(unless false (* 5 (factorial 4)) 1)
なので、5! が返るかと思っていたら、なぜか無限ループしてしまった。
何が悪かったのか見てみると、引数1でfactorial が止まらない。考えてみると
(factorial 1)
は、
(unless true (* 1 (factorial 0)) 1)
となるが、作用順序なので、unless を展開する前に、先に (factorial 0) を実行しようとする。(factorial 0)を実行すると、(factorial -1)が出てきて、それをさらに実行して、、、と全然止まらないのである。
一方、正規順序(遅延評価)の場合、
(factorial 1)
は、
(unless true (* 1 (factorial 0)) 1)
となるが、正規順序なので、(factorial 0)を実行する前に、先に unless が展開される。
(if true 1 (* 1 (factorial 0)))
これを実行すると、 if式は、false節を無視して1を返す。(factorial 0)は何もされず捨てられ る。こうして無事ループは停止する。
Ex. 4.26
unless を導出式にする。eval に unless の節を追加して、そこで
(unless c a b)を
(if c b a)
にするような置き換え行う。...実装は省略。
unless が関数のままで嬉しい場合。→ メタ関数の引数に使える。map の引数に使えてうれしい。