懒惰的评价问题

时间:2010-07-15 15:03:20

标签: clojure

我有这样的代码。我可以在repl中运行它但不能从命令行运行。 我想我是一个懒惰的评估问题。


; 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

问候。

2 个答案:

答案 0 :(得分:4)

知道了!

solution

Clojure没有动力在map中运行init-items函数,因为没有返回结果。我将其包装成doall以强制执行,然后执行。

答案 1 :(得分:4)

一些替代方案:

如果您只想将一堆项目添加到Ref中保存的集合中,则每个项目启动一个事务并单独conj它们会有点浪费。相反,你可以做到

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

如果你确实有一些理由以一步一步的方式进行,我认为目前使用doseq的最惯用和最方便的方法是:

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

(或者你可以将整个doseq包裹在dosync中,而不是在dosync的正文中使用doseq。)