Lazy assessment problem

I have such a code. I can run this in repl, but I cannot from the command line. I think I have a lazy rating problem.

; items.clj (def items (ref [])) (defn init-items [] (map #(dosync (alter items conj %)) ["foo" "bar" "baz" ] )) (init-items) (println (first @items)) 
 $ java -jar clojure.jar items.clj $ nil 

Sincerely.

+6
clojure
source share
2 answers

Got!

decision

Clojure is not motivated to execute the map function in init-items , because the result is not returned. I wrapped it in a doall to force execution, and presto.

+4
source share

Some alternatives:

If you just want to add a bunch of elements to the collection contained in Ref, starting one transaction per element and conj them individually is a little wasteful. Instead, you could do

 (defn init-items [] (dosync (alter items into ["foo" "bar" "baz"]))) 

If you have a reason to do this with one element per step, I think the most idiomatic and convenient approach for now would be to use doseq :

 (defn init-items [] (doseq [item ["foo" "bar" "baz"]] (dosync (alter items conj item)))) 

(Or you can move the entire doseq to dosync and not use dosync in the body of doseq .)

+4
source share

All Articles