Archive for the ‘macros’ Category

“The first rule of macro club is: Don’t write macros”

I wrote this originally as an answer to a StackOverflow question. But the question got closed by some trigger-happy mods before I clicked post. How unfriendly!

Anyway, in case it is useful to people wondering when they should and shouldn’t use macros, I thought I would post it here instead….


I discovered an interesting trick today which I thought worth sharing – you can add a side effect to the end of a sequence in Clojure which will only get called after the sequence is fully consumed for the first time.

(defmacro on-consumed [seq code]
  `(lazy-cat ~seq (do ~code nil)))

(def coll
     (on-consumed [1 2 3] (println "DONE")))

(take 2 coll)   ;; not fully consumed
=> (1 2)

(take 3 coll)   ;; not fully consumed (not gone past third item)
=> (1 2 3)

(take 4 coll)   ;; fully consumed past end of sequence
=> (1 2 3)
DONE            ;; printed to *out*

(take 4 coll)   ;; fully consumed for second time, no side effect
=> (1 2 3)

So how does this work?