問題4-25〜26

「4.2 Schemeの変形 --- 遅延評価」に入りました。自前評価器を機能拡張していきます。こういうことができると、その機能を低水準言語やハードウェアに実装する前に、その動きを自前評価器を使ってシミュレーションすることができるということが冒頭に述べられています。
「4.2.1 正規順序と作用的順序」を読みながら、第一章で作用的順序について述べられている部分を復習しました。本書のこんな冒頭で、かなり大事なことが説明されていたということを、今頃になって気づくことができました。
問題4-25では、unlessでfactorialを処理しようとした時、作用的順序のSchemeではどのように動くのかということを確認します。結果は無限ループに陥ってしまいました。unlessの三つの実引数全てを、unlessの内部処理を始める前に評価してしまうため、第二引数の(* n (factorial (-n 1)))が、(= n 1)の場合でも評価されてしまい、それ以降、nがデクリメントされながら永遠にfactorialが呼び出されてしまうようです。もし、正規順序で評価されるなら、unlessの内部処理でusual-valueが必要になるまでは、それが評価されることはないので、conditionの評価結果が真になったら、exceptional-valueのみしか評価されないという処理が実現されます。
問題4-26。unlessを特殊形式として実装するのではなく、手続きとして実装するにはどうすればいいのか、ということですが、問われていることがいまいち理解できなかったので、tosutudycsさんのエントリーを参考にしました。自前評価器に、unlessタグがあるかどうかのチェックロジックを追加して、unless式だったらif文に変換してやった上でevalしてやるというアプローチで良さそうです。こうしてやると、unlessを合成手続きの一部として使えるので、例えば、whileループのようなロジックを書く時に、停止判定と通常手続きをラッピングすることができるので、そういうことをやる時に有用なのではないかと思いました。