問題4.18 – SICP(計算機プログラムの構造と解釈)その190
2009年05月29日
問題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*
のために上手く動かないということらしい。
計算機プログラムの構造と解釈
posted with amazlet at 08.11.07
ジェラルド・ジェイ サスマン ジュリー サスマン ハロルド エイブルソン
ピアソンエデュケーション
売り上げランキング: 6542
ピアソンエデュケーション
売り上げランキング: 6542