Clojure手表功能正在执行,但是' map'作为功​​能不执行的一部分

时间:2014-12-02 01:01:52

标签: clojure

(defonce instance
  (atom
    {:id nil
     :canvas nil
     :subscribers #{"test1" "test2"}))

(defn replace-canvas [canvas id]
  (println "replaced" id "'s canvas"))

(defn update-subscribers
  [k r old-state new-state]
  (pprint "this function is being called")
  (pprint "I can execute consecutive forms")
  (map (partial replace-canvas (new-state :canvas))
       (new-state :subscribers)))

(add-watch instance :update-subs update-subscribers)

当实例原子发生变化时,表面上调用了watch函数,因为“正在调用此函数”和“我可以执行连续表单”都被打印,但地图函数似乎永远不会发生。我不知道为什么会这样,而且我在add-watch的文档中找不到任何可以放在watch函数内部的限制。

即使我用更简单的东西替换更新订阅者中的地图,例如

(map println (new-state :subscribers))

地图似乎没有任何效果。

任何帮助将不胜感激,  谢谢!

1 个答案:

答案 0 :(得分:4)

map函数是惰性的,所以只有当调用者实现它产生的序列时它才会起作用(当一个函数被调用作为手表的一部分时,情况并非如此,因为结果基本上被抛弃了)

您要么想要将map电话打包在doall中,要么改为使用doseq(这对于副作用代码更为惯用):

(doseq [subscriber (:subscribers new-state)]
  (replace-canvas (:canvas new-state) subscriber))

另请注意,(:canvas new-state)(new-state :canvas) - 首先是关键字更具惯用性。