(defn pipe "Returns a pair: a seq (the read end) and a function (the write end). The function can takes either no arguments to close the pipe or one argument which is appended to the seq. Read is blocking."  (let [promises (atom (repeatedly promise)) p (second @promises)] [(lazy-seq @p) (fn ( ;close the pipe (let [[a] (swap! promises #(vector (second %)))] (if a (deliver a nil) (throw (Exception. "Pipe already closed"))))) ([x] ;enqueue x (let [[a b] (swap! promises next)] (if (and a b) (do (deliver a (cons x (lazy-seq @b))) x) (throw (Exception. "Pipe already closed"))))))]))
Beware of not printing the seq while the pipe is still open!
(let [[q f] (pipe)] (future (doseq [x q] (println x)) (println "that's all folks!")) (doseq [x (range 10)] (f x)) (f)) ;close the pipe