方案,SICP,R5RS,为什么延迟不是特殊形式?

Kno*_*tle 8 scheme sicp r5rs

这与SICP的第3.5章有关,其中正在讨论流.这个想法是:

(cons-stream 1 (display 'hey))
Run Code Online (Sandbox Code Playgroud)

不应该评估cons-stream的第二部分,所以它不应该打印"嘿".这确实发生了,我得到以下输出:

嘿(1.#<承诺>)

所以我的结论是延迟不是作为特殊形式实现的?或者我做错了什么?我使用以下实现:

(define (cons-stream a b) 
  (cons a (delay b)))
Run Code Online (Sandbox Code Playgroud)

延迟是默认的R5RS实现.这是实施中的错误,还是我没有做或理解它?

Eli*_*lay 15

确实创建了一个承诺,但承诺是在您的内部创建的cons-stream,这意味着它已经太晚了并且已经评估了表达式.试试这个:

(define (foo x)
  (display "foo: ") (write x) (newline)
  x)

(cons-stream 1 (foo 2))
Run Code Online (Sandbox Code Playgroud)

你会发现它的评估太早了.出于同样的原因,这个:

(define ones (cons-stream 1 ones))
Run Code Online (Sandbox Code Playgroud)

当你cons-stream是一个函数时,任何其他无限列表都不会起作用.所以问题是这delay是一种特殊的形式,但你没有使用它的功能,因为你定义cons-stream为普通函数.你必须定义cons-stream一个宏,如果你想在同一个特殊的方式表现了.例如:

(define-syntax cons-stream
  (syntax-rules ()
    [(cons-stream x y) (cons x (delay y))]))
Run Code Online (Sandbox Code Playgroud)