Задержка оценки в Clojure - PullRequest
12 голосов
/ 13 июня 2010

У меня возникли проблемы с пониманием того, как работает макрос 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 Ответ

13 голосов
/ 13 июня 2010

Печатное представление различных объектов, которое появляется в REPL, является продуктом мультиметода, называемого print-method. Он находится в файле core_print.clj в источниках Clojure, который является частью того, что входит в пространство имен clojure.core.

Проблема здесь в том, что для объектов, реализующих clojure.lang.IDeref - интерфейс Java для вещей deref / @ может работать - print-method включает значение за объектом в печатном представлении. Для этого ему необходимо deref объект, и хотя для печати неудачных агентов и ожидающих фьючерсов предусмотрены специальные условия, задержки всегда принудительны.

На самом деле я склонен считать это ошибкой или, в лучшем случае, ситуацией, требующей улучшения. В качестве временного решения, будьте особенно осторожны, чтобы не печатать вынужденные задержки.

...