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
-~----------~----~----~----~------~----~------~--~---

Reply via email to