gpt4 book ai didi

stream - 方案:使用 `delay`表达式时的显示问题

转载 作者:行者123 更新时间:2023-12-04 10:29:41 24 4
gpt4 key购买 nike

这是SICP中ex3.51相关的问题,这里是代码

(define (cons-stream x y)
(cons x (delay y)))
(define (stream-car stream) (car stream))
(define (stream-cdr stream) (force (cdr stream)))
(define (stream-map proc s)
(if (stream-null? s)
the-empty-stream
(cons-stream
(proc (stream-car s))
(stream-map proc (stream-cdr s)))))
(define (stream-enumerate-interval low high)
(if (> low high)
the-empty-stream
(cons-stream
low
(stream-enumerate-interval (+ low 1) high))))
(define (stream-ref s n)
(if (= n 0)
(stream-car s)
(stream-ref (stream-cdr s) (- n 1))))
(define (show x)
(display x)
x)
;test
(stream-map show (stream-enumerate-interval 0 10))

输出是 012345678910(0 . #<promise>)

但我认为 cons-stream 中的延迟表达式延迟了评估,如果我在 stream-map 中使用不同的处理函数,如 lambda (x) (+ x 1) 输出 (1 . #<promise>) 更合理,那么为什么 display 打印所有数字?

最佳答案

问题在于这个定义:

(define (cons-stream x y)
(cons x (delay y)))

它定义了 cons-stream作为一个函数,因为它使用 define .

Scheme 的求值是急切的:在输入函数体之前对参数求值。因此 y传递给 delay 时已经完全计算.

相反, cons-stream应该定义为一个宏,比如
(define-syntax cons-stream
(syntax-rules ()
((_ a b) (cons a (delay b)))))

或者我们可以调用 delay明确地,手动地,例如
(define (stream-map proc s)
(if (stream-null? s)
the-empty-stream
(cons
(proc (stream-car s))
(delay
(stream-map proc (stream-cdr s))))))

那么就不会有人调用 cons-stream在我们的代码中,只有 (cons A (delay B))来电。和 delay是一个宏(或特殊形式,无论如何),它不会在工作之前评估其参数,而是直接操作参数表达式。

我们甚至可以放弃对 delay 的调用, 并替换 (cons A (delay B))(cons A (lambda () B)) .这也需要重新实现 force (它是内置的,与内置的 delay 一起使用)简单地 (define (force x) (x))或直接调用 (x)在适当的地方手动强制流的尾部。

你可以看到这样的 lambda接近 this answer 末尾的基于流的代码, 或 ideone entry (对于 this RosettaCode entry )没有使用显式 lambda 的任何宏。但是,这种方法可以改变代码的性能,如 delay正在内存,但 lambda基于流的流不是。如果我们尝试多次访问流的元素,就会看到差异。

另见 this answer对于流实现的另一种看法,通过手术将列表的最后一个 cons 单元格修改为内存 force .

关于stream - 方案:使用 `delay`表达式时的显示问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60471837/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com