2013年9月10日火曜日

開発環境

計算機プログラムの構造と解釈(Gerald Jay Sussman(原著)、Julie Sussman(原著)、Harold Abelson(原著)、和田 英一(翻訳)、ピアソンエデュケーション、原書: Structure and Interpretation of Computer Programs (MIT Electrical Engineering and Computer Science)(SICP))の4(超言語的抽象)、4.1(超循環評価器)、4.1.6(内部定義)、問題 4.18を解いてみる。

その他参考書籍

問題 4.18

掃き出しのもう一つの戦略の場合を見ていく。

まず手続きsolveをlambdaを使って書き換える。

(lambda (f y0 dt)
  (let ((y '*unassigned*)
        (dy '*unassigned*))
    (let ((a (integral (delay dy) y0 dt))
          (b (stream-map f y)))
      (set! y a)
      (set! dy b)
      y)))

これは、2つ目のletでaを束縛する時にdyの値を使うことになるけど、dyは'*unassignedaのためエラーになる。bもyの値を使おうとしてエラーになる。

よって、手続きsolveは問題で示したように内部定義を壁出したら動かない。

本文に示されたように掃き出した場合。

(lambda (f y0 dt)
  (let ((y '*unassigned*)
        (dy '*unassigned*))
    (set! y (integral (delay dy) dy0 dt))
    (set! dy (stream-map f y))
    y))
;; (set! y (integral (delay dy) dy0 dt))をみていく。
;; evalで(assignment? exp)がtrueになるから次が評価される
(eval-assignment exp env)

(set-variable-value! (assignment-variable exp)
                     (eval (assignment-value exp) env)
                     env)

(set-variable-value! y 
                    (eval (integral (delay dy) dy0 dt) env)
                    env)

;; (eval (integral (delay dy) dy0 dt) env)についてみていく。
;; integralはevalで(list 'procedure … env)となっている。(手続きではない。)

よって未代入の変数の値を使おうとしてエラーになることはない。

0 コメント:

コメントを投稿