sicp cons-stream是如何实现的?

zca*_*ate 5 scheme sicp

我正在通过scip的streams部分工作,并坚持如何定义流.

以下是我的代码:

(define (memo-func function)
  (let ((already-run? false)
        (result false))
    (lambda ()
      (if (not already-run?)
          (begin (set! result (function))
                 (set! already-run? true)
                 result)
          result))))


(define (delay exp)
  (memo-func (lambda () exp)))

(define (force function)
  (function))

(define the-empty-stream '())
(define (stream-null? stream) (null? stream))
(define (stream-car stream) (car stream))
(define (stream-cdr stream) (force (cdr stream)))

(define (cons-stream a b) (cons a (memo-func (lambda () b))))
Run Code Online (Sandbox Code Playgroud)

如果我按照书的描述方式定义整数:

(define (integers-starting-from n)
   (cons-stream n (integers-starting-from (+ n 1))))
(define integers (integers-starting-from 1))
Run Code Online (Sandbox Code Playgroud)

我收到一条消息说:正在中止!:超出了最大递归深度.

我猜测延迟功能不起作用,但我不知道如何解决它.我在Mac上运行MIT方案.

更新1

所以现在使用cons-stream作为宏,可以定义整数.

但后来我又出现了另一个错误.

(define (stream-take n s)
  (cond ((or (stream-null? s)
             (= n 0)) the-empty-stream)
        (else (cons-stream (stream-car s)
                           (stream-take (- n 1) (stream-cdr s))))))

(stream-take 10 integers)
;ERROR - Variable reference to a syntactic keyword: cons-stream
Run Code Online (Sandbox Code Playgroud)

更新2

请忽略上面的更新1

Chr*_*ung 5

cons-stream需要是一个宏才能让您的示例代码正常工作.否则,调用cons-stream将热切地评估其所有参数.

试试这个(未经测试):

(define-syntax cons-stream
  (syntax-rules ()
    ((cons-stream a b)
     (cons a (memo-func (lambda () b))))))
Run Code Online (Sandbox Code Playgroud)

PS delay出于类似的原因,你也需要成为一个宏.然后修复后delay,您可以直接cons-stream使用delay.

  • 这是SICP新人或像我这样的周围人的面包屑.以下文章相当于一个关于"延迟"的小型研讨会,没有破坏性更新,显示了它的优点和缺点:https://github.com/VincentToups/emacs-utils/blob/master/delay.md这是第一次这样的讨论我发现了 这似乎就足够了.对于我所知道的一切,我们可能在"延迟"中使用破坏性更新的问题可以在SICP本身中得到很好的解决.它也可以在Stack Overflow或programmers.stackexchange.com上的某处解决. (2认同)