If you have a lazy-seq with side-effects, you almost certainly don't want to let it out of your sight. You're likely to get very strange behavior unless you're exceedingly careful. Most likely, if you've got a lazy-seq with side-effects you should force it with dorun or doall immediately. Use doall if you care about the values in the produced lazy-seq, otherwise use dorun.
This means that dorun should almost always show up right next to the form producing the lazy-seq, which means doseq is very likely a better choice, as it is more efficient and usually more succinct than dorun combined with a lazy-seq producer.
run! is a convenience function that can take place of (dorun (map ,,,)).
for is in rather a different category, since unlike the others it produces a lazy-seq rather than forcing anything. Use for when it's a more convenient way to express the lazy-seq you want than the equivalent combination of map, filter, take-while, etc.
source: https://groups.google.com/d/msg/clojure/8ebJsllH8UY/FxbiHmwJE2oJ