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 会影响它)。

在阅读了大量有关宏的内容后我明白了...我的误解:
谢谢!
...