2010-06-12 3 views
12

Ich habe einige Probleme zu verstehen, wie das delay Makro in Clojure funktioniert. Es scheint nicht zu tun, was es erwartet (das heißt: Verzögerung der Evaluierung). Wie Sie in diesem Codebeispiel:Verzögerte Auswertung in 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))) 

jedoch current-time Aufruf in der REPL den Ausdruck sofort auswerten erscheint, auch ohne das force Makro genutzt haben:

user=> current-time 
#<[email protected]: 1276376485859> 
user=> (force current-time) 
1276376485859 

Warum war die Bewertung von get-timestamp nicht verzögert bis zum ersten force Anruf?

+1

kleiner Kommentar: Es ist besser, direkt (System/currentTimeMillis) zu verwenden, anstatt ein Datum zu erstellen - sie verwenden die gleiche zugrunde liegende Millisekunde-Quelle, aber erstere vermeidet eine unnötige Objektzuordnung. – mikera

Antwort

13

Die gedruckte Darstellung verschiedener Objekte, die an der REPL angezeigt wird, ist das Produkt einer Multimethode namens print-method. Es befindet sich in der Datei core_print.clj in Clojures Quellen, die einen Teil dessen bildet, was in den Namespace clojure.core geht.

Das Problem dabei ist, dass für Objekte clojure.lang.IDeref Implementierung - die Java-Schnittstelle für Dinge deref/@ arbeiten kann auf - print-method den Wert hinter dem Objekt in der gedruckten Darstellung umfasst. Zu diesem Zweck muss es deref das Objekt, und obwohl spezielle Bestimmungen für den Druck gescheiterten Agenten und ausstehende Futures gemacht werden, sind Verzögerungen immer gezwungen.

Eigentlich neige ich dazu, dies als einen Fehler zu betrachten, oder im besten Fall eine Situation, die einer Verbesserung bedarf. Als Workaround sollten Sie besonders darauf achten, keine unnötigen Verzögerungen zu drucken.

+0

Ich werde natürlich versuchen, die Verbesserung zu erreichen. Es sollte ziemlich einfach sein. –

+4

Ich denke, das Heisenberg-Prinzip gilt auch für clojure: Sie können die Verzögerung nicht beobachten, ohne sie zu verändern. :-) – Greg

+0

@Greg: Ich denke du meinst den Beobachter Effekt. :) https://en.wikipedia.org/wiki/Observer_effect_(physics)#Quantum_mechanics – Peeja