I recently came across a situation where I very much wanted to delay
the calculation of some values, but where I also wanted those delays
to use their calculated values for equality determinations. This is
particularly important when comparing vectors or maps that contain
delayed values, where doing something like (= (force some-delay) some-
value) isn't possible.
So, I whipped up a tdelay (transparent delay) macro, an almost
complete ripoff of clojure.core/delay, except that it creates
instances of a subclass of clojure.lang.Delay that defers equality and
hashcode calculations to the delay's value. The results:
user=> (= {:a 5 :b (delay 12)} {:a 5 :b 12})
false
user=> (= {:a 5 :b (tdelay 12)} {:a 5 :b 12})
true
I get nervous when I screw around with equality in relatively sneaky
ways like this, so I thought I'd toss this out on the list and see if
anyone has any comments one way or the other.
- Chas
------
(import '(clojure.lang Delay Util))
(defn make-tdelay
[fn]
(proxy [Delay] [fn]
(equals [other]
(Util/equals (.deref this) (Delay/force other)))
(hashCode []
(Util/hash (.deref this)))))
(defmacro tdelay
[& body]
(list 'make-tdelay (list* `#^{:once true} fn* [] body)))
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups
"Clojure" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to
[email protected]
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
-~----------~----~----~----~------~----~------~--~---