Bitten by Lazy Sequence of map


While impletenting the live reload feature for Clay a few weeks ago, unfortunately, I was bitten by the laziness of map. It seems quite obvious we all know that its result is a lazy sequence, but I just can't help fall into the "trap".

At that time I was adding a vector to keep track of all beholder instances watching file changes in user specified directories. So then when it's time to stop all the watchers, I used something like to achieve the goal:

(defn stop-watchers
  "Stop all directory watchers."
  []
  (map beholder/stop
    (:watchers @*dir-watchers))
  (reset! *dir-watchers dir-watchers-initial))

But the problem was the callback function got called multiple times, when a file got changed. It did trap me for some time, what made me even confused was that when I eval'ed the map form via cider, it worked perfectly.

After realizing it was due to the laziness, the solution was simple:

(defn stop-watchers
  "Stop all directory watchers."
  []
  (doseq [w (:watchers @*dir-watchers)]
    (beholder/stop w))
  (reset! *dir-watchers dir-watchers-initial))

See also

comments powered by Disqus