SICP 4.2.1 Ex. 4.25 Ex. 4.26

  • 投稿日:
  • カテゴリ:

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 の引数に使えてうれしい。