SICP 読み (135) 3.5.2 無限ストリーム

ちょっとヤッツケ状態になってしまっているので一旦停止。

memo-proc について

未だにオチていないのはとりあえず以下の手続き群。

(define-syntax cons-stream
 (syntax-rules ()
   ((_ a b) (cons a (delay b)))))

(define-syntax delay
 (syntax-rules ()
   ((_ p) (memo-proc (lambda () p)))))

(define (force delayed-object) (delayed-object))
(define (memo-proc p)
 (let ((already-run? #f) (result #f))
   (lambda ()
     (if (not already-run?)
         (begin (set! result (p))
                (set! already-run? #t)
                result)
         result))))
(define (stream-car s) (car s))
(define (stream-cdr s) (force (cdr s)))

オチてない点は何か、と自問自答してみるに memo-proc だな。あ、分かったぞ。どうやって_識別_してるか、だ。例えば問題 3.27 のケイスではインスタンスとしては一つなんですが、このケイスはどうなるんだろうか。明確にイメージできていません。だからだな。
何て言えば良いのだろうか。memo-proc のインスタンスがどっかで束縛 (保持) されていないと 1 回目も 2 回目もないだろ、と言えば良いのかなぁ。

分かった??

あ、分かった気がする。result だ。成程ね。
# ってここに到達するまで相当時間が (以下略

例えば以下のストリーム

gosh> (define s (stream-enumerate-interval 1 5))
s
gosh> s
(1 . #<closure (memo-proc memo-proc)>)
gosh>

s にストリームを束縛した段階では cdr にある closure の already-run は #f ですが、(stream-cdr s) した時点で #t になる。
で、その時に (2 . #) が cdr にある closure の result に束縛されるのか。あとは数珠繋ぎな訳ですね。これはこれは。