Writing a lazy, functional, interactive command line application in Clojure
I'm wondering: what is the best way to write a Clojure program that interacts with a user or another program thorough stdin and stdout?
Clearly it would be possible to write some kind of imperative loop, but I'm hoping to find something more la开发者_JAVA百科zy / functional, a bit inspired by Haskell's "interact" function.
This was the best I could come up with:
(defn interact [f]
(lazy-seq
(cons (do (let [input (read-line)
result (f input)]
(println result)
{:input input :result result}))
(interact f))))
You could use it like this:
(def session
(take-while #(not= (:result %) 0)
(interact count)))
REPL:
user=> (str "Total Length: " (reduce #(+ %1 (:result %2)) 0 session))
foobar
6
stackoverflow
13
0
"Total Length: 19"
user=> session
({:input "foobar", :result 6} {:input "stackoverflow", :result 13})
精彩评论