【问题标题】:Delayed evaluation in ClojureClojure 中的延迟评估
【发布时间】:2011-03-03 02:04:52
【问题描述】:

我无法理解 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)))

但是,在 REPL 中调用 current-time 似乎会立即计算表达式,即使没有使用 force 宏:

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

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

【问题讨论】:

  • 次要评论:最好直接使用 (System/currentTimeMillis) 而不是构造 Date - 它们使用相同的底层毫秒源,但前者避免了不必要的对象分配。

标签: clojure delay lazy-evaluation


【解决方案1】:

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

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

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

【讨论】:

  • 我当然会努力改进。应该很简单。
  • 我猜 Heisenberg 原则也适用于 clojure:如果不更改延迟,您将无法观察到延迟。 :-)
  • @Greg:我认为你的意思是观察者效应。 :) en.wikipedia.org/wiki/…
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-05-17
  • 2016-06-20
  • 1970-01-01
  • 2012-06-15
  • 1970-01-01
  • 1970-01-01
  • 2021-06-21
相关资源
最近更新 更多