本书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))
在给出这些定义的章节中,计算是使用流完成的。每条小溪都是一对头部和延迟的尾巴。
但是,我没有看到如何在不使用查找表或其他类型的数据结构的情况下实现memoization,这些数据结构会累积先前的调用。
包含这些定义的章节为here。
当我们用各种参数记忆单个过程时,查找表会很有用。然后,我们将参数作为键,将过程的结果作为值。在这种情况下,我们有Nullary程序,因此我们不需要查找表。我们所需要的只是我们迄今为止创建的一组延迟对象。但是,这里使用了闭包。
根据上面memo-proc
的定义,每个延迟对象实际上是一个值为already-run?
和result
的闭包,它们都被初始化为false
。但是,由于调用proc
中的每个延迟对象都有自己的本地already-run?
和result
闭包,因此修改它们不会更改调用树中的其他对象。因此,我觉得再也没有任何其他程序可以读取记忆值。
所以我的问题是,我在想什么是错的,或者对一切如何运作的正确解释是什么?
答案 0 :(得分:4)
每个延迟对象在第一次被强制后存储自己的值;该值存储在result
变量中。它起作用是因为memo-proc
在proc
- promise (一个等待评估的无法工作程序)和result
变量上创建了一个闭包。
第一次强制对象后,将返回存储的result
,并且不会再次重新计算。因此 promise 成为值本身。
我没有看到如何在不使用查找表或其他类型的数据结构的情况下实现memoization,这些数据结构会累积先前的调用。
数据结构是围绕每个promise创建的闭包,它会累积result
变量中第一个调用的值,并为所有后续调用返回它。
因此,我觉得再也没有任何其他程序可以读取记忆值
是的,每次在promise对象上调用force
时都会被读取。