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.hallo...@gmail.com> 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.