stream - 延迟评估期间的内存

标签 stream scheme memoization sicp delayed-execution

本书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/

相关文章:

c# - 使用 HTTPCLient 下载文件时减少内存占用

node.js - 如何从可写流创建可读流? ( Node .js)

node.js - 我如何在 nodejs 的管道流中发生错误事件后恢复?

javascript - 如何处理 Node.js 加密流中的 block 长度

list - 方案流和循环列表

python - 我可以记住一个 Python 生成器吗?

haskell - GHC 测试套件中的这个简短的内存功能是如何工作的?

scheme - Racket Scheme 是否提供类似 Smalltalk 的基于图像的环境?

scheme - 写出到方案中的文件

python - 为什么记忆化在这段 Python 代码中不起作用?