2024 Clojure 调查问卷中分享您的想法!

欢迎!请参阅关于页面获取更多关于此网站如何运作的信息。

0

我无法在宏定义中将动态变量替换为binding
我的目标是
使用宏定义一个函数,在定义时“固定”一个动态变量。

(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))))

在提供的代码片段中,我期望调用(demo2)的结果是1。看起来macroexpand生成的结果正是我所需要的,所以我缺失了什么?

1 个答案

+1

 
最佳答案

binding影响运行时。宏通常在读取时展开。当您使用macroexpand时,您是显式地将宏作为运行时操作的组成部分展开的(因此binding会影响它)。

花了很多时间研究宏之后我明白了...我的误解 :)
谢谢!
...