SICP問題4.18

3.5.4節のsolve手続き:

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

を問題で示したように内部定義を掃き出した場合に動作するか?本文に示したように掃き出したら動作するか?を述べる。

三章のストリーム関係の手続き動かそうと思ったらdefine-macroとか組み込まないとダメじゃん!ということで脳内シミュレート。

solveを問題で示したように掃き出すと以下のようになる。

(define (solve f y0 dt)
  (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))))

a の束縛を作る際に dy が必要となるが、この時点では '*unassigned* である。
ただし、 delay されているので、この扱いが良く分からない。
b の束縛を作る際に y が必要となるが、この時点では '*unassigned* である。
a の束縛を作る際の dy の扱いは良く分からないが、b の束縛を作る際の y については *unassigned* でエラーとなるため、期待通りに動作しないと思われる。

本文に示したように掃き出すと以下のようになる。

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

y に set! する際に dy が必要となるが、この時点では '*unassigned* である。
ただし、 delay されているので、この扱いが良く分からない。
dy に set! する際は y が必要となる。上記の delay がうまくいっていればエラーとはならない。
よって delay が動作するのであれば、期待通りに動作するし、delay が動作しないのであれば、期待通りに動作しない。

と思うんだけど正解が知りたい…。