Consider this code snippet:
(defn foo []
(let [line (apply str (repeat 2 \.))
lines (into [] (repeat 2 line))]
(for [x lines] (println x)) ; this doesn't print
(loop [remaining [[1 2] [3 4]]]
(if (empty? remaining)
(for [y lines] (println y)) ; but this does print
(recur (rest remaining))))))
The output of running foo
is:
..
..
(nil nil)
Thus, the line commented with this doesn't print produces no output. In fact, I can remove that line and get the same output.
The output I expected to get is:
..
..
..
..
(nil nil)
When I remove the whole loop/recur business, the line works as expected:
(defn foo []
(let [line (apply str (repeat 2 \.))
lines (into [] (repeat 2 line))]
(for [x lines] (println x)))) ; now it prints
yields
..
..
(nil nil)
as expected. Why does the loop/recur prevent the for/println from generating output?
for
is lazy. If nothing uses its result, nothing in its body will run.
For the particular case of printing all the lines, you can simply print the whole collection - (println lines)
.
Or, if you want each item to go onto its own line, (run! println lines)
.