在Clojure中延迟评估

时间:2010-06-12 21:08:55

标签: clojure delay lazy-evaluation

我在理解delay宏在Clojure中的工作原理时遇到了一些麻烦。它似乎没有做到期望它做什么(即:延迟评估)。正如您在此代码示例中所看到的那样:

; returns the current time
(defn get-timestamp [] (System/currentTimeMillis))

; var should contain the current timestamp after calling "force"
(def current-time (delay (get-timestamp)))

然而,即使没有使用current-time宏,在REPL中调用force似乎会立即评估表达式:

user=> current-time
#<Delay@19b5217: 1276376485859>
user=> (force current-time)
1276376485859

为什么get-timestamp的评估在第一次force来电之前没有延迟?

1 个答案:

答案 0 :(得分:13)

REPL上出现的各种对象的打印表示是一种称为print-method的多方法的产物。它驻留在Clojure源代码中的文件core_print.clj中,它构成了clojure.core命名空间中的一部分。

这里的问题是对于实现clojure.lang.IDeref的对象 - deref / @可以操作的Java接口 - print-method包含对象背后的值在印刷表示中。为此,它需要deref对象,尽管为打印失败的代理和未决期货做了特殊规定,但总是强制延迟。

实际上我倾向于认为这是一个错误,或者至多是需要改进的情况。作为现在的解决方法,请特别注意不要打印非受迫延误。