@genekim That's great to hear! You're welcome! For me, dorun
has been the most baffling. I'm sure there is a great use case for it out there, but I still haven't found it useful in production code.
One little laziness 'corner case' (maybe) that I've stumbled over once or twice is that using something lazy in a recur
can lead to a StackOverflow for a sufficiently large number of recursions. For example, if you (recur (map inc coll))
, that can SO, but throwing a doall
in there (or using mapv if you can work with a vector) eliminates it
this is 100% speculation, but looking at core.clj, doall
is defined in terms of dorun
, so the impression that I get is that dorun
can process the whole seq, even if the whole seq doesn't fit in memory, while doall
is basically "dorun and then return the realized seq" (which of course means the whole realization needs to fit in memory). and apparently run!
was introduced in 1.7, so perhaps dorun
was more directly useful before its introduction
@highpressurecarsalesm Are you by any chance using concat in that function? If so, then that is probably the culprit, not recur.
nope... here's a trivial repro (it's obviously not useful code):
(loop [a [10000]]
(if (zero? (first a))
a
(recur (map dec a))))
Ah, yeah. That stacks thunks and will SO.