It’s about time that I started writing some posts on this blog. I’ll start with something small, by talking about the difference between dorun, doseq and doall and how to easily remember what each one of them does. All of them are supposed to force evaluation of lazy sequences. At least to me it was not obvious from the name of these functions and I had to constantly go back to the docstrings at first.
doall
doall forces the evaluation of the lazy sequence and it retains the head, causing the entire seq to live in memory. Useful when you want to immediately force evaluation of something like map. I use the “all” part of doall to help me remember that it keeps all the items of the seq in memory.
dorun
Use dorun when you just want the side effects of computing the lazy sequence, but you don’t care about the items in the sequence itself. But be careful when you see yourself using (dorun (map ….. )), you should probably use doseq instead. I use the “run” part of dorun to help me remember that it only runs over the seq for side effects, without keeping anything.
doseq
To me doseq has more in common with for than with doall or dorun. Since in Clojure for is used for lazy list-comprehension, doseq fulfills the role of something like “for … in …” or “foreach” from other languages. It takes the same arguments that for does, but it runs immediately and it doesn’t collect the results. I really feel that doseq needs a better name so I don’t have a good way to remember what it does just by looking at its name.
Thank you!
I had a (doseq .. ) that I wanted to execute in parallel. It was trivial to rewrite it as (dorun (map ….. )) and then simply use pmap instead!
Comment by klang — June 22, 2011 @ 5:54 pm