本书Structure and Interpretation of Computer Programs介绍一个内存过程如下:
(define (memo-proc proc)
(let ((already-run? false) (result false))
(lambda ()
(if (not already-run?)
(begin (set! result (proc))
(set! already-run? true)
result)
result))))
在建议延迟执行的定义时,
(delay <exp>)
是 (memo-proc (lambda () <exp>))
.可以使用以下过程强制延迟对象:(define (force delayed-object)
(delayed-object))
在给出这些定义的章节中,计算是使用流完成的。每个流都是一对,有一个头和一个延迟的尾。
但是,如果不使用查找表或某种其他类型的累积先前调用的数据结构,我看不到如何实现记忆化。
包含这些定义的章节是 here .
当我们使用各种参数来内存单个过程时,查找表会很有用。然后,我们将参数作为键,将过程的结果作为值。在这种情况下,我们有空程序,因此我们不需要查找表。我们所需要的只是我们迄今为止创建的一组延迟对象。但是,这里使用了闭包。
根据
memo-proc
的定义上面,每个延迟对象实际上是一个闭包,其值为 already-run?
和 result
, 它们都初始化为 false
.但是,由于调用 proc
内的每个延迟对象将拥有自己的本地 already-run?
关闭和 result
,修改它们不会改变调用树中的其他的。因此,我觉得任何其他程序都不会再读取一个内存值。所以我的问题是,我在想什么错误或者对一切如何运作的正确解释是什么?
最佳答案
每个延迟对象在第一次被强制后存储自己的值;该值存储在 result
多变的。它之所以有效是因为 memo-proc
在两个 proc
上创建一个闭包- promise (等待评估的无参数过程)和 result
多变的。
第一次后对象被强制存储 result
被返回,并且不再重新计算。所以 promise 变成了值(value)本身。
I don't see how memoization is achieved without using a lookup table, or some other kind of data structure which accumulates the previous calls.
数据结构是围绕每个 promise 创建的闭包,它在
result
中累积第一次调用的值变量,为所有后续调用返回它。Hence, I'm feeling like a memoized value won't ever be read by any other procedures again
是的,每次
force
都会被阅读。在 promise 对象上调用。
关于stream - 延迟评估期间的内存,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15870466/