core.async

Outside go blocks Don't do blocking I/O inside go blocks (it starves the fixed pool); use thread ((a/thread (blocking-call))) or pipeline-blocking. core.async works in ClojureScript too (where it simulates concurrency on the single JS thread).

(require '[clojure.core.async :as a :refer [chan go go-loop >! <! >!! <!! put! take! close! timeout alts! alts!!]])

;; Channels: queues connecting producers and consumers (CSP)
(def c (chan 10))                        ; buffered channel
(>!! c "hello")                          ; blocking put (outside go blocks)
(<!! c)                                  ; "hello": blocking take

;; go blocks: lightweight processes (parked, not blocking threads)
(let [c (chan)]
  (go (>! c (* 6 7)))
  (<!! c))                               ; 42

;; Producer/consumer pipeline
(let [jobs (chan 10)
      results (chan 10)]
  (go-loop [i 0]
    (when (< i 5)
      (>! jobs i)
      (recur (inc i))))
  (dotimes [_ 3]                          ; three workers
    (go-loop []
      (when-some [j (<! jobs)]
        (>! results (* j j))
        (recur))))
  (<!! (a/into [] (a/take 5 results))))  ; [0 1 4 9 16] (order may vary)

;; Timeouts and alts!
(go
  (let [[v ch] (alts! [c (timeout 1000)])]
    (if (= ch c) (println "got" v) (println "timed out"))))

;; Transducers on channels
(def evens (chan 10 (filter even?)))

;; Pub/sub, mult, mix, pipeline
(def in (chan))
(def out (chan))
(a/pipeline 4 out (map inc)
…