SICP 問題 4.18
本文中の変形であればうごく.
;; 3章で定義した手続きとマクロ (define (integral integrand initial-value dt) (define int (cons-stream initial-value (add-streams (scale-stream integrand dt) int))) int) (define (stream-map proc . argstreams) (if (stream-null? (car argstreams)) the-empty-stream (cons-stream (apply proc (map stream-car argstreams)) (apply stream-map (cons proc (map stream-cdr argstreams)))))) (define-syntax cons-stream (syntax-rules () ((_ a b) (cons a (delay b))))) (define-syntax delay (syntax-rules () ((_ exp) (memo-proc (lambda () exp)))))
(define (solve f y0 dt) (define y (integral (delay dy) y0 dt)) (define dy (stream-map f y)) y) ;; 問題文の通りに変形すると, (lambda (vars) (let ((y '*unassigned*) (dy '*unassigned*)) (let ((a (integral (delay dy) y0 dt)) (b (stream-map f y))) (set! y a) (set! dy b)) y)) ;; まずはじめのletでyとvは``*unassigned*``に束縛される. ;; 次にaを束縛する.(integral ..)が評価される.dyはまだ*unassigned*だが,initial-valueだけcosされ,のこりの評価は遅れる.(delay dy)となっているのでdyもまだ評価されない. ;; 次にbを束縛する.(stream-map f y)を評価しようとするがこの時yはまだ'*unassigned*なのでエラー. ;; 本文中の変換をすると, (lambda (vars) (let ((y '*unassigned*) (dy '*unassigned*)) (set! y (integral (delay dy) y0 dt)) (set! dy (stream-map f y)) y)) ;; まずはじめに最初の式と同じようにyとdyを束縛する. ;; 次にyに(integral (delay dy) y0 dt)を代入する. ;; (integral ..)が評価される.dyはまだ*unassigned*だが,initial-valueだけcosされ,のこりの評価は遅れる. ;; (delay dy)となっているのでdyもまだ評価されない. ;; 次にdyに(stream-map f y)を代入する.この時点でyの値は(integral (delay dy) y0 dt). ;; stream-mapもはじめに必要なのはyの先頭の要素だけで,それはinitial-valueになっている. ;; その相互に呼び出しあいながらストリームが作られる.