缓存方案中过程的先前返回值
在《老练的策划者》第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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
呃。没有读过《经验丰富的策划者》,我无法评论记忆问题,除非您在这里提供一些源代码。然而,关于是否有一种方法可以让词法范围的变量在函数调用之间保持其状态的问题......这是Scheme 语言的一个称为“闭包”的功能。考虑以下示例:
这段代码定义了一个名为 counter 的函数,它使用词法变量 (
number
) 来跟踪其状态。每次调用该函数时,您都会得到不同的数字作为返回:依此类推。这里重要的一点是,执行 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:
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: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 onlynumber
.) This means, that those variables remain valid places to read values from or write new values to.