Я испытываю некоторые затруднения при понимании как 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
звонить?
Печатное представление различных объектов, которое появляется в REPL, является продуктом мультиметода, называемого print-method
. Он находится в файле core_print.clj
в исходных кодах Clojure, который составляет часть того, что входит в пространство имен clojure.core
.
Проблема здесь в том, что для объектов, реализующих clojure.lang.IDeref
- интерфейс Java для вещей, deref
/ @
может работать с - print-method
включает значение, стоящее за объектом в печатном представлении. Для этого ему необходимо deref
объекта, и хотя для печати неудачных агентов и ожидающих фьючерсов предусмотрены специальные условия, задержки всегда принудительно.
На самом деле я склонен считать это ошибкой или, в лучшем случае, ситуацией, требующей улучшения. В качестве временного решения на данный момент будьте особенно осторожны, чтобы не печатать невынужденные задержки.