thunk对象的评估如何工作?

时间:2013-07-04 20:54:38

标签: scheme lazy-evaluation sicp thunk

SICP中的

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

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

但是,如果exp本身就是一个笨蛋怎么办?根据{{​​1}}的定义,它意味着它是delay-it形式的列表对象。然而,eval函数无法准备处理以'thunk开头的标记列表。为什么eval不会因为cond表达式无法匹配而产生错误?

修改 我认为评估以下表达式会导致错误:

(list 'thunk exp env)

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

1 个答案:

答案 0 :(得分:3)

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

在您的示例中,唯一的参数是0,在调用add时,但即使这样,该值也会被强制最终 {{ 1}} - 想一想,在某些时候,所有的程序应用程序都会导致list-of-arg-values,这就是我们强迫thunk的重点。

如果我们在调用apply-primitive-procedure时执行跟踪,则传递给list-of-arg-values的值按此顺序为actual-value2a只评估自己,没问题。让我们看看2会发生什么。 a中的这个代码段:

actual-value

...将收到符号(eval exp env) 作为其a(变量),在环境中查找后返回相关的thunk(请记住:当我们在{{1}扩展环境时我们在变量和thunk之间创建了绑定),之后exp会因调用apply而收到thunk:

force-it
eval案例中,

... (force-it (eval exp env))) 知道如何评估thunk。就是这样!最后我们获得force-it,即实际值。