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。宏展开似乎产生了所需结果,所以...我在哪里出了错?

1 个答案

+1

选中
 
最佳回答

binding 影响 运行时。宏通常在读取时展开。当您使用 macroexpand 时,您明确地将宏作为运行时操作的一部分展开(因此 binding 影响它)。

在花费大量时间阅读有关宏的资料后我明白了...我的误解 :)
谢谢!
...