放射状

勉強のメモ。

SICP二日目~問題1.5

1.4と1.5の間が空いたのは、1.4まではテキストの前のほうを読まなくても解けたからです。教科書の本文を読まずに問題だけ解くのが学生時代からの私の勉強スタイルでしたが、そろそろ改めなければいけない時代が来たようです。
SICPは問題集でもLisp仕様書でもない。正しく計算機プログラミングの構造と解釈に関する教科書であった、とも思い知ったわけです。
楽しようとするよくない。

参照先

今回はこのあたりを読んでからここの問題1.5を考えてみます。

問題 1.5

問題文を眺める。難しい。以下のようにふわっととらえることにする。

  • 正規順序の評価:完全に展開し、簡約する。→ 全部眺めてからいいとこどりする(評価されずに捨てられる部分がある。無駄なことは行わない)
  • 作用的順序の評価:引数を評価し, 作用させる。→ まず引数を評価してから、関数に適用する。

つまり、正規順序でこの式を評価した場合、testの最初の引数x→x=0が先に評価され、第二引数yの評価は省略される。つまり、testの実行結果は「0」となる。
また、作用的順序でこの式を評価した場合(lispですね)はx→x=0が評価される前に第二引数である関数p(要するに無限ループ関数)が評価されるため、testの実行結果は無限ループとなる。
ちなみに実際に実行してみると、scheme(gauche)ではなにも画面に表示されないのですな(ループは続いている)。ついでにCLISPで似たようなもの↓を書いてみると、stack overflowとなります。こっちのほうが親切ですね。

(defun p() (p))
(defun test (x y) (if (= x 0) 0 y))
(test 0 (p))

ここまでやってみて

gaucheで無限ループになっても最初まったく気がつかなかったので(画面に変化がないため)、そろそろlispデバッグって具体的にどうやるのかな…とか気になり始めました。
あとCLISPschemeってけっこう違うんですな! python2とpython3程度の違いかと思っていたら。