mapv a bit shorter :)
Luc P. > > I've generally liked Clojure's pervasive laziness. It's cute and it sometimes > permits lovely, elegant approaches to particular programming problems. And > although I've long known that it can get you into trouble in a few unusual > cases -- I think I recall seeing a nice blog post on issues related to > "binding" and laziness by Chas Emerick several years ago -- it has generally > seemed safe enough for most purposes. I figured that while it may not always > provide benefits it should at least be mostly harmless. > > However, after spending a couple of days tracking down a particularly > confusing bug, and finding once again (this has happened to me at least a few > times) that the bug was due to laziness that I never really wanted in the > first place, I'm reconsidering. > > I don't have a pared-down version of the bug that I was just dealing with > (see below for a pointer to the non-pared-down version), but it goes away > when I wring out all of the laziness. In this particular case I do so by > calling vec or doall on the results of all of my calls to map and other > functions function that produce lazy sequences (none of which I actually want > to be lazy in this application). I was getting StackOverflowErrors and I have > a half-baked half-theory that it was due to some bad interaction between > laziness and garbage collection, with the JVM not realizing that it could > reclaim lazy things that weren't yet fully evaluated. That doesn't make > complete sense to me, and maybe that kind of bad interaction is not even > possible -- I don't know. But I do know that all is well when I wring out all > of the laziness. > > One possible lesson from this experience (which was particularly frustrating, > BTW, because the stack backtraces were particularly uninformative [1]) is > that I should just be careful to surround any call to any function that > produces a lazy sequence with something like vec that ensures that the > laziness will be eliminated as soon as it is created -- except in those > relatively rare cases where I really want the laziness. But this would be a > pain, and ugly. I rely heavily on Clojure's sequence processing functions and > I would hate to clutter up every call to every one of them or to have to > reimplement my own non-lazy versions of everything. > > Is there a more elegant way? Maybe somebody has already made non-lazy clones > of all of the core functions that normally produce lazy sequences? And if so, > maybe there's some clean way to cause my code to use the non-lazy versions > unless specifically directed to use the lazy versions? > > I realize that this is fighting with a core feature of Clojure, and that the > idea will probably rub lots of folks the wrong way. But I've now been down > this road a couple of times and I'm beginning to think that I'd spend less > time tracking down mysterious bugs if I could avoid laziness more easily. > > In case anybody is motivated to look into the specific bug that I was just > dealing with, I've put the project at > http://hampshire.edu/lspector/temp/world2D.zip. If you do "lein run" in its > present state it will run fine, making little balls bounce around. (This is a > very early version of some code that I plan to use both for teaching an AI > class and for some ALife experiments...) But if you edit > src/world2D/vec2D.clj, commenting out the definitions of *v, +v, and -v, and > uncommenting the alternatives (which are the same except that they lack the > calls to vec) then after running for a few seconds or a minute or so you'll > get the stack overflow. > > Thanks for any suggestions, > > -Lee > > > [1] The stack traces I was getting provide no information about where/what > the offending lazy sequences are, since they don't show locals etc. I see no > references to any of my own code, just a repeating sequence that starts: > > StackOverflowError > clojure.core/seq (core.clj:133) > clojure.core/map/fn--4211 (core.clj:2490) > clojure.lang.LazySeq.sval (LazySeq.java:42) > clojure.lang.LazySeq.seq (LazySeq.java:60) > clojure.lang.RT.seq (RT.java:484) > clojure.core/seq (core.clj:133) > clojure.core/map/fn--4211 (core.clj:2490) > clojure.lang.LazySeq.sval (LazySeq.java:42) > clojure.lang.LazySeq.seq (LazySeq.java:60) > clojure.lang.RT.seq (RT.java:484) > [etc] > > -- > 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. > -- Softaddicts<lprefonta...@softaddicts.ca> sent by ibisMail from my ipad! -- 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.