Thanks  Stu & Lee,

I will be more careful next time I order a cocktail in a bar.

I wasn't aware that pr-str depended on *out*, as it could be implemented as 
a pure function, without this harmful mixing effect. I guess pr-str is used 
to get something in edn-shape without (yet) going to the none-pure 
real-world. But I expect the current implementation is (via with-out-str) 
is the fastest and the most compact implementation.

Lee, thanks for your suggestions on how to tackle the dreadful HeisenBugs.

Regards,
Cees.

On Saturday, September 13, 2014 4:01:53 PM UTC+2, Lee wrote:
>
>
> A man walks into a bar and says "I used lazy evaluation and things were 
> confusing." Bartender says "You might have mixed it with I/O, but then 
> again maybe you're getting tripped up by other some other 
> not-purely-functional aspect of your program or the JVM, like GC or thread 
> transitions."   
>
> Okay, it's not as good a joke that way, but it may be more accurate. 
>
> While the OP's issue was IO-related, I've run into confusing 
> laziness-related bugs, some of which were indeed Heisenbugs, that didn't 
> have anything obvious to do with IO. I think some were related to GC not 
> knowing that it could collect something, while others had to do with 
> something lazy being realized in a different thread than I expected. For 
> some, I've never really figured out what was happening, but I've 
> nonetheless found that the problem went away when I switched map to mapv, 
> or filter to filterv, etc. 
>
> So now one of my first steps when I'm faced with a confusing bug is to 
> stamp out all of the laziness except where I'm really doing things lazily 
> on purpose, for a good reason. I've also come to think that the 
> pervasiveness and defaultness of laziness in Clojure may not really be so 
> wonderful after all. Laziness is beautiful when you want it, and when you 
> do want it it's beautiful that so much of Clojure works with it so 
> effortlessly and transparently, but it can also produce subtle problems 
> when things aren't purely functional (which is a lot of the time, in my 
> experience, sometimes for subtle reasons). 
>
>  -Lee 
>
>
> On Sep 13, 2014, at 9:32 AM, Stuart Halloway <stuart....@gmail.com 
> <javascript:>> wrote: 
>
> > A man walks into a bar and says "I used lazy evaluation and things were 
> confusing." Bartender says "You mixed it with I/O" without bothering to 
> look at the code.  :-) 
> > 
> > Your experiment uses pr-str, which uses a dynamically scoped resource 
> *out* in order to create its result.  Your observation uses println, which 
> uses the same dynamically scoped resource.  Mix in different evaluation 
> strategies, and races can lead to different outcomes. Here is a much 
> smaller example: 
> > 
> > (pr-str [1 2]) 
> > (pr-str (map #(doto % println) [1 2])) 
> > 
> > So this result is expected.  Beware I/O, and in the presence of I/O be 
> very careful in concluding that something is a value.  Your quoted-pr-str 
> is not a pure function, and so it does not make values. 
> > 
> > Regards, 
> > Stu 
> >   
>
>

-- 
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
Note that posts from new members are moderated - please be patient with your 
first post.
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
--- 
You received this message because you are subscribed to the Google Groups 
"Clojure" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to