【问题标题】:How does evaluation of a thunk object work?thunk 对象的评估如何工作?
【发布时间】:2013-07-04 20:54:37
【问题描述】:

SICP 中的This 章节说actual-value 用于提取thunk 的实际值的定义是这样的:

(define (actual-value exp env)
  (force-it (eval exp env)))

但是如果exp 本身就是一个重击呢?根据delay-it 的定义,这意味着它是(list 'thunk exp env) 形式的列表对象。然而,eval 函数并没有准备好处理以 'thunk.为什么 eval 由于 cond 表达式不匹配而不会产生错误?

编辑: 我认为评估以下表达式应该会导致错误:

(define (add a) (+ 2 a))
(add 0)

add 是一个复合过程,因此delay-it 在应用之前对其参数执行。 + 是一个原始产生,这意味着 actual-value 将在其参数上被调用。论据是 2 和 a。 a 是一个 thunk 对象,因此 actual-value 在将其传递给 eval 时应该会产生错误,因为 eval 没有处理带有 'thunk 标记的列表的条件情况。

【问题讨论】:

  • 你能提供一个发生这种情况的实际代码示例吗?我有一种预感,它不可能在实践中发生,通过构造
  • @ÓscarLópez:我添加了一个例子。

标签: scheme lazy-evaluation sicp thunk


【解决方案1】:

这里的关键点是,当我们评估 (+ 2 a) 时,a 不是一个 thunk,它只是一个将在环境中查找的符号,其值是一个 thunk。在eval 返回thunk 之后,force-it 将负责强制其值。让我们逐步完成这个过程。

在您的示例中唯一被延迟的参数是​​ 0,在调用 add 时,但即便如此,该值也会被list-of-arg-values 强制最终 - 想想它,在某些时候,所有的过程应用程序都会指向apply-primitive-procedure,这就是我们强制执行thunk 的地方。

如果我们在调用list-of-arg-values 时执行跟踪,则传递给actual-value 的值依次为2a2 只是评估自己,没有问题。让我们看看a 会发生什么;这个sn-p 在actual-value:

(eval exp env)

... 将接收符号 a 作为其 exp(变量),在环境中查找后返回相关联的 thunk(请记住:当我们在 apply 中扩展环境时,我们创建了绑定在变量和 thunk 之间),然后 force-it 将收到一个 thunk 作为调用 eval 的结果:

(force-it (eval exp env)))

... 和force-it 知道(thunk? obj) 的情况下如何评估thunk。就是这样!最后我们得到0,实际值。

【讨论】:

  • 我完全忘记了 actual-value 接收 a 作为符号。谢谢你的精彩解释!
猜你喜欢
  • 2017-01-22
  • 2017-03-24
  • 2021-05-08
  • 2021-02-01
  • 2021-05-20
  • 2016-09-13
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多