問題4.18 – SICP(計算機プログラムの構造と解釈)その190

問題4.18

どうも解らなかったので以下のサイトを参考にした。
参考:4.1.6 内部定義 – 三十路プログラマ

(define (solve f y0 dt)
  (define y (integral (delay dy) y0 dt))
  (define dy (stream-map f y))
  y)

;; 最初の掃き出し方
(define solve
  (lambda (f y0 dt)
          (let ((y '*unassigned*)
                (dy '*unassigned*))
               (set! y (integral (delay dy) y0 dt))
               (set! dy (stream-map f y))
               y)))

;; 問題4.18 のもう一つの掃き出し方の戦略
(define solve
  (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)))

set!eval-assignment 手続きで実行される。

(define (eval exp env)
  (cond ((self-evaluating? exp) exp)
        ;; 省略
        ((assignment? exp) (eval-assignment exp env))
        ;; 省略
        (else
          (error "Unknown expression type -- EVAL" exp))))

(define (assignment? exp)
  (tagged-list? exp 'set!))

(define (assignment-variable exp) (cadr exp))

(define (assignment-value exp) (caddr exp))

(define (eval-assignment exp env)
  (set-variable-value! (assignment-variable exp)
                       (eval (assignment-value exp) env)
                       env)
  'ok)

最初の掃き出し方の場合、set-variable-value! の時点では (integral (delay dy) y0 dt) はまだ評価されない。

(set! y (integral (delay dy) y0 dt))
; ↓
(eval-assignment '(set! y (integral (delay dy) y0 dt)) env)
; ↓
(set-variable-value! y
                     (eval '(integral (delay dy) y0 dt) env)
                     env)

もう一つの掃き出し方の戦略では、a(integral (delay dy) y0 dt) を束縛する時点で integral が評価されて、dy の値が *unassigned* のために上手く動かないということらしい。

計算機プログラムの構造と解釈
ジェラルド・ジェイ サスマン ジュリー サスマン ハロルド エイブルソン
ピアソンエデュケーション
売り上げランキング: 6542
«
»