Skip to content

Instantly share code, notes, and snippets.

@m0smith
Created December 19, 2012 23:36
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save m0smith/4341697 to your computer and use it in GitHub Desktop.
Save m0smith/4341697 to your computer and use it in GitHub Desktop.
A ClojureScript usable version of pipe that will return a seq and a function to add elements to the end of the pipe. I found it here: http://clj-me.cgrand.net/2009/11/18/are-pipe-dreams-made-of-promises/ and just wanted to have a copy I could find
(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
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment