Clojure中的延迟评估

Clojure中的延迟评估,clojure,delay,lazy-evaluation,Clojure,Delay,Lazy Evaluation,我在理解Clojure中的delay宏如何工作时遇到了一些问题。它似乎没有达到预期的效果(即:延迟评估)。正如您在这个代码示例中所看到的: ; returns the current time (defn get-timestamp [] (System/currentTimeMillis)) ; var should contain the current timestamp after calling "force" (def current-time (delay (get-timest

我在理解Clojure中的
delay
宏如何工作时遇到了一些问题。它似乎没有达到预期的效果(即:延迟评估)。正如您在这个代码示例中所看到的:

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

; var should contain the current timestamp after calling "force"
(def current-time (delay (get-timestamp)))
但是,在REPL中调用
current time
似乎可以立即计算表达式,即使没有使用
force
宏:

user=> current-time
#<Delay@19b5217: 1276376485859>
user=> (force current-time)
1276376485859
user=>当前时间
#
用户=>(强制当前时间)
1276376485859

为什么对
get timestamp
的评估没有延迟到第一次
force
调用时?

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

这里的问题是,对于实现
clojure.lang.IDeref
的对象,
deref
/
@
的Java接口可以操作--
打印方法
在打印表示中包含对象后面的值。为此,它需要解除对象的责任,尽管对打印失败的代理和待定的期货作出了特殊规定,但延迟总是被迫的


实际上,我倾向于认为这是一个错误,或者充其量是一个需要改进的情况。作为目前的解决办法,请特别注意不要打印非强迫性延迟。

我当然会尝试进行改进。这应该很简单。我想海森堡原理也适用于clojure:你不能不改变它就观察到延迟。:-)@格雷格:我想你指的是观察者效应次要评论:最好直接使用(System/currentTimeMillis),而不是构造日期-它们使用相同的底层毫秒源,但前者避免了不必要的对象分配。