应该偷懒评价定!事实上严格吗?

Should lazy evaluation of set! be in fact strict?

SICP 书描述了如何在 Scheme 中实现 Scheme 解释器。几个月来我一直在断断续续地玩这个,我的代码已经从书中发展了。我现在已经到了实现 strict-eval 过程的阶段,我正在尝试实现一个 lazy-eval 对应物,它总是 returns 一个 'thunk' (一些对象封装了一个表达式和环境和记忆信息)。我有一个 force-thunk 程序,它通过记忆评估 thunk。我的快速而肮脏的实现目前 returns 一个围绕 set! 表达式的 thunk 包装器,当然这会导致奇怪的语义(在强制 thunk 之前不会发生副作用)。我很想改变这一点,并让我的 lazy-eval 过程严格遵守 set! 表达式。实际上,更准确地说,我正在考虑延迟对正在分配的表达式的评估(因此从中创建一个 thunk),但不延迟绑定的更改(即立即将符号分配给环境中的新 thunk)。我有什么理由应该选择延迟副作用吗?

set! 改变了一个绑定,并将 interpeter 从引用透明更改为必须处理不断变化的世界。我想我同意你的描述,即绑定应该与新的 thunk 而不是旧的关联,因此绑定没有设置为惰性,但它的值仍然是惰性的。

(define x expression) ; ==> x is a thunk
(set! x (+ x x)       ; ==> x is a new thunk that references the old `x`
(display x)           ; display would force the evaluation of the nested thunks referenced by `x`

如果你延迟实际的绑定阶段,那么上面的代码将永远不会强制从 set! 表达式返回值,因为它从未被使用过,因此 x 将是旧的 thunk被迫 display?