1

SICP 中的这一章说,actual-value提取 thunk 的真实值的定义是这样的:

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

但是,如果exp它本身是一个 thunk 呢?根据它的定义,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.

4

1 回答 1

4

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

在您的示例中被延迟的唯一参数是0, 在调用时add,但即使这样,该值最终也会被强制list-of-arg-values- 想想看,在某些时候所有过程应用程序都会导致apply-primitive-procedure,这就是我们强制重击。

如果我们在调用 时执行跟踪list-of-arg-values,则传递给的值actual-value2a。只是对自己进行评估,2那里没有问题。让我们看看 ; 会发生什么a。这个片段在actual-value

(eval exp env)

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

(force-it (eval exp env)))

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

于 2013-07-04T22:22:49.700 回答