Search code examples
asynchronousclojuremacroslisps-expression

Why doesn't this clojure code using go blocks work?


(defn ff [t]
  (let [ch (chan 5)]
    (map (fn [i]
          (println i)) t)
    (go (>! ch 0))))

(ff [1 2 3 4 5])

The mapping function body isn't being executed. If I remove the go block in the last line, it works as expected.

This function gives the same problem:

(defn ff [t]
  (let [ch (chan 5)]
    (map (fn [i]
          (println i)) t)
    (>!! ch 0)))

Solution

  • map runs lazily.

    When it's not the last form in the let block, the result isn't being evaluated, so the mapping function doesn't get executed.

    This'd happen without the go blocks.

    If you explicitly want to evaluate a sequence for side-effects (like println), use doseq. If you need a lazy sequence to be evaluated eagerly (e.g. it depends on a network connection that will close), wrap it in doall