12 Stimmen

Verzögerte Auswertung in Clojure

Ich habe einige Schwierigkeiten zu verstehen, wie die delay Makro funktioniert in Clojure. Es scheint nicht das zu tun, was man von ihm erwartet (nämlich: die Auswertung zu verzögern). Wie Sie in diesem Codebeispiel sehen können:

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

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

Allerdings ist der Aufruf current-time in der REPL scheint den Ausdruck sofort auszuwerten, auch ohne die Verwendung der force Makro:

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

Warum wurde die Bewertung von get-timestamp nicht bis zum ersten Termin der force anrufen?

1 Stimmen

Kleinere Anmerkung: es ist besser, (System/currentTimeMillis) direkt zu verwenden, anstatt ein Datum zu konstruieren - sie verwenden die gleiche zugrunde liegende Millisekundenquelle, aber die erste vermeidet eine unnötige Objektzuweisung.

13voto

Michał Marczyk Punkte 82196

Die gedruckte Darstellung der verschiedenen Objekte, die in der REPL erscheint, ist das Produkt einer Multimethode namens print-method . Sie befindet sich in der Datei core_print.clj in den Clojure-Quellen, die einen Teil dessen ausmachen, was in der clojure.core Namensraum.

Das Problem dabei ist, dass für Objekte, die clojure.lang.IDeref -- die Java-Schnittstelle für Dinge deref / @ können auf -- print-method enthält den Wert hinter dem Objekt in der gedruckten Darstellung. Zu diesem Zweck muss sie deref das Objekt, und obwohl besondere Vorkehrungen für den Druck gescheiterter Agenten und ausstehender Futures getroffen werden, werden Verzögerungen immer erzwungen.

Eigentlich bin ich geneigt, dies als Fehler oder bestenfalls als verbesserungsbedürftige Situation zu betrachten. Als vorläufige Abhilfe sollten Sie besonders darauf achten, keine ungeplanten Verzögerungen zu drucken.

0 Stimmen

Ich werde natürlich versuchen, die Verbesserung zu erreichen. Das sollte ganz einfach sein.

4 Stimmen

Ich denke, das Heisenberg-Prinzip gilt auch für Clojure: Man kann die Verzögerung nicht beobachten, ohne sie zu verändern :-)

0 Stimmen

@Greg: Ich glaube, du meinst den Beobachtereffekt :) de.wikipedia.org/wiki/

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X