Share your thoughts in the 2021 Clojure Community Survey!

Welcome! Please see the About page for a little more info on how this works.

0 votes
in Macros by

I cannot seem to replace a dynamic var with binding on a macrodefinition.
My goal is to
define a function with a macro which upon definition "fixes" a dynamic var.

(def ^:dynamic *pred?*
  (fn []
    (println "original pred")
    false))

(defmacro macro-pred [fname a b]
  `(defn ~fname []
     (if (~*pred?*)
       ~a
       ~b))
  )

(macro-pred demo 1 2)

(demo)
;; => 2

(defn my-pred []
  (fn []
    (println "my pred")
    true))

(binding [*pred?* my-pred]
  (macro-pred demo2 1 2))

(demo2);; => 2

(binding [*pred?* my-pred]
  (macroexpand '(macro-pred demo2 1 2)))
;; => (def
;;     demo2
;;     (clojure.core/fn
;;      ([] (if (#function[macros.demo/my-pred]) 1 2))))

In the provided snippet, I would expect the result of the (demo2) call to be 1. The macroexpand seems to produce what I need, so.. what am I missing?

1 Answer

+1 vote
by
selected by
 
Best answer

binding affects runtime. Macros are generally expanded at read time. When you use macroexpand, you are explicitly expanding the macro as part of runtime operations (so the binding affects it).

by
After spending plenty of time reading about macros I understood... my misunderstanding :)
Thanks!
...