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.