Difference between doseq and for in Clojure

Clojure

Clojure Problem Overview


What's the difference between doseq and for in Clojure? What are some examples of when you would choose to use one over the other?

Clojure Solutions


Solution 1 - Clojure

The difference is that for builds a lazy sequence and returns it while doseq is for executing side-effects and returns nil.

user=> (for [x [1 2 3]] (+ x 5))
(6 7 8)
user=> (doseq [x [1 2 3]] (+ x 5))
nil
user=> (doseq [x [1 2 3]] (println x))
1
2
3
nil

If you want to build a new sequence based on other sequences, use for. If you want to do side-effects (printing, writing to a database, launching a nuclear warhead, etc) based on elements from some sequences, use doseq.

Solution 2 - Clojure

Note also that doseq is eager while for is lazy. The example missing in Rayne's answer is

(for [x [1 2 3]] (println x))

At the REPL, this will generally do what you want, but that's basically a coincidence: the REPL forces the lazy sequence produced by for, causing the printlns to happen. In a non-interactive environment, nothing will ever be printed. You can see this in action by comparing the results of

user> (def lazy (for [x [1 2 3]] (println 'lazy x)))
#'user/lazy

user> (def eager (doseq [x [1 2 3]] (println 'eager x)))
eager 1
eager 2
eager 3
#'user/eager

Because the def form returns the new var created, and not the value which is bound to it, there's nothing for the REPL to print, and lazy will refer to an unrealized lazy-seq: none of its elements have been computed at all. eager will refer to nil, and all of its printing will have been done.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionJeff the BearView Question on Stackoverflow
Solution 1 - ClojureRayneView Answer on Stackoverflow
Solution 2 - ClojureamalloyView Answer on Stackoverflow