6

《计算机程序的结构和解释》一书介绍了如下的记忆过程:

(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>)be (memo-proc (lambda () <exp>))。可以使用以下过程强制延迟对象:

(define (force delayed-object)
  (delayed-object))

在给出这些定义的章节中,计算是使用流完成的。每个流都是一对,有一个头和一个延迟的尾。

但是,如果不使用查找表或某种其他类型的累积先前调用的数据结构,我看不到如何实现记忆化。

包含这些定义的章节在这里

当我们使用各种参数来记忆单个过程时,查找表会很有用。然后,我们将参数作为键,将过程的结果作为值。在这种情况下,我们有空程序,因此我们不需要查找表。我们所需要的只是我们迄今为止创建的一组延迟对象。但是,这里使用了闭包。

根据memo-proc上面的定义,每个延迟对象实际上都是一个带有值的闭包already-run?result,它们都被初始化为false。但是,由于调用中的每个延迟对象proc都有自己的闭包和自己的本地already-run?and result,因此修改它们不会更改调用树中的其他对象。因此,我觉得任何其他程序都不会再读取一个记忆值。

所以我的问题是,我在想什么错误或者对一切如何运作的正确解释是什么?

4

1 回答 1

4

每个延迟对象在第一次被强制后存储自己的值;该值存储在result变量中。它之所以起作用,是因为在两者上memo-proc创建了一个闭包——promise(一个等待评估的无参数过程)和变量。procresult

在第一次强制对象后result返回存储的对象,并且不再重新计算。所以承诺变成了价值本身。

如果不使用查找表或某种其他类型的累积先前调用的数据结构,我看不到如何实现记忆化。

数据结构是围绕每个 Promise 创建的闭包,它在变量中累积第一次调用的值,并将其result返回给所有后续调用。

因此,我觉得任何其他程序都不会再读取一个记忆值

是的,每次force在 promise 对象上调用时都会读取它。

于 2013-04-08T03:17:47.947 回答