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)
…