Friday, December 28, 2012

lein-resource 0.2.0 hits clojars

I just deployed lein-resource to clojars. What is lein-resource? A Leiningen plugin that can be used to copy files from mulitiple source directories to a target directory while maintaining the sub-directories. Also, each file will be transformed using stencil. The map that is passed to stencil contains a combination of: The project map The system properties (with .prop added to the name ) Additional values (currently only :timestamp) Values set in the project.clj using :resource :extra-values

Wednesday, December 19, 2012

Hammock driven development pays off with a ClojureScript pipe function - ok not really - See core.async instead

Again, with only using the think method, here is the ClojureScript version of the pipe method
(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
view raw pipe.cljs hosted with ❤ by GitHub

Thanks to Are pipe dreams made of promises? for writing it and Clojure - From Callbacks to Sequences for pointing it out to me. EDIT: While still a good idea, futures and promises are not ClojureScript approved.

Another EDIT:  See core.async for the right way to do this.

Clojure - From Callbacks to Sequences

I have been spending some hammock time on the problem of converting a stream of events into a sequence.  And Lo and Behold, the answer falls in my lap.  I may need to see if I can implement the pipe function in ClojureScript.  Maybe if I spend more time in the hammock, someone will have already done it.

Be sure and read Clojure - From Callbacks to Sequences for a nice explanation and examples.

Here is the function that does the magic:
(defn pipe
"Returns a vector containing a sequence that will read from the
queue, and a function that inserts items into the queue.
Source: http://clj-me.cgrand.net/2010/04/02/pipe-dreams-are-not-necessarily-made-of-promises/"
[]
(let [q (LinkedBlockingQueue.)
EOQ (Object.)
NIL (Object.)
s (fn queue-seq []
(lazy-seq (let [x (.take q)]
(when-not (= EOQ x)
(cons (when-not (= NIL x) x)
(queue-seq))))))]
[(s) (fn queue-put
([] (.put q EOQ))
([x] (.put q (or x NIL))))]))
view raw pipe.clj hosted with ❤ by GitHub