On Apr 9, 2009, at 4:20 PM, Rich Hickey wrote:
> On Apr 9, 2:55 pm, 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. >> > > You shouldn't ignore your nervousness in this case: > > user=> (= {:a 5 :b 12} {:a 5 :b (tdelay 12)}) > false > > The lack of symmetry makes this too fragile IMO. Whoo-hoo! I guess that's what 10 minutes in the REPL gets me. I really should have seen that. :-[ As I heard someone else say once, "you're only as smart as the people you ask for help". On Apr 9, 2009, at 7:07 PM, Jason Wolfe wrote: > 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. That sounds very promising. In fact, I could simply drop LazySeq in as the superclass of the proxy used in the make-tdelay fn, and add in an IDeref impl as well. That would enabling @ syntax, and eliminate the necessity of explicitly specifying the single-element vector going into the lazy seq. Unfortunately, LazySeq is final. Rich, is there a particular reason why that's the case? Or, any reason why Jason's idea (or my idea to mix in IDeref with LazySeq) is trending towards disaster? - Chas --~--~---------~--~----~------------~-------~--~----~ 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 -~----------~----~----~----~------~----~------~--~---