Hi Chas, Have you considered wrapping the computation in a lazy sequence?
(lazy-seq [(expensive-calculation)]) The, instead of (force ...), you just use (first ...). I think equality and hashing will automatically work like you want them to. Cheers, Jason On Apr 9, 11:55 am, Chas Emerick <cemer...@snowtide.com> wrote: > 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 clojure@googlegroups.com To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~----------~----~----~----~------~----~------~--~---