缓存方案中过程的先前返回值

发布于 2024-08-27 08:32:46 字数 451 浏览 4 评论 0原文

在《老练的策划者》第16章中,作者定义了一个递归过程“深度”,它返回'嵌套在n个列表中的披萨,例如(深度3)是(((披萨)))。然后他们将其改进为“深度M”,它使用 set! 缓存其返回值。在列表 Ns 和 Rs 中,它们一起形成一个查找表,因此如果达到以前见过的返回值,则不必一直向下递归。例如,如果我已经计算了(深度M 8),当我稍后计算(深度M 9)时,我只需查找(深度M 8)的返回值并将其cons为null,而不是一直递归到(深度M 0) 。

但随后他们将 N 和 R 移动到过程中,并使用“let”将它们初始化为 null。为什么这没有完全破坏缓存返回值的意义呢?从一些实验来看,每次调用“深度M”时,Ns 和 Rs 都会被重新初始化。

我是否误解了他们的观点?

我想我的问题实际上是这样的:Scheme 中有没有一种方法可以让词法范围的变量在调用过程之间保留它们的值,就像在 Perl 5.10 中使用“状态”变量所做的那样?

In Chapter 16 of "The Seasoned Schemer", the authors define a recursive procedure "depth", which returns 'pizza nested in n lists, e.g (depth 3) is (((pizza))). They then improve it as "depthM", which caches its return values using set! in the lists Ns and Rs, which together form a lookup-table, so you don't have to recurse all the way down if you reach a return value you've seen before. E.g. If I've already computed (depthM 8), when I later compute (depthM 9), I just lookup the return value of (depthM 8) and cons it onto null, instead of recursing all the way down to (depthM 0).

But then they move the Ns and Rs inside the procedure, and initialize them to null with "let". Why doesn't this completely defeat the point of caching the return values? From a bit of experimentation, it appears that the Ns and Rs are being reinitialized on every call to "depthM".

Am I misunderstanding their point?

I guess my question is really this: Is there a way in Scheme to have lexically-scoped variables preserve their values in between calls to a procedure, like you can do in Perl 5.10 with "state" variables?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

洛阳烟雨空心柳 2024-09-03 08:32:46

呃。没有读过《经验丰富的策划者》,我无法评论记忆问题,除非您在这里提供一些源代码。然而,关于是否有一种方法可以让词法范围的变量在函数调用之间保持其状态的问题......这是Scheme 语言的一个称为“闭包”的功能。考虑以下示例:

(define counter 
  (let ((number 0))
    (lambda () 
      (let ((result number))
        (set! number (+ number 1))
        result)))

这段代码定义了一个名为 counter 的函数,它使用词法变量 (number) 来跟踪其状态。每次调用该函数时,您都会得到不同的数字作为返回:

> (counter)
0
> (counter)
1

依此类推。这里重要的一点是,执行 lambda 表达式生成的函数“封闭”封闭范围中的所有词法可见变量(在本例中只有 number)。这意味着,这些变量仍然是读取值或写入新值的有效位置。

Duh. Not having read the Seasoned Schemer, I cannot comment on the memoization issue, unless you give some source code here. However, regarding the question of whether there is a way to have lexically scoped variables keep their state between function calls... This is a feature of the Scheme language called "closures". Consider the following example:

(define counter 
  (let ((number 0))
    (lambda () 
      (let ((result number))
        (set! number (+ number 1))
        result)))

This piece of code defines a function called counter, which uses a lexical variable (number) to keep track of its state. Each time you call the function, you will get a different number in return:

> (counter)
0
> (counter)
1

and so on. The important point here is, that the function generated by the execution of the lambda expression "closes over" all lexically visible variables from enclosing scopes (in this case only number.) This means, that those variables remain valid places to read values from or write new values to.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文