通过未定义clojure宏的命名空间访问clojure宏
我在通过未定义clojure宏的命名空间访问clojure宏,clojure,Clojure,我在func.clj中定义了一个宏: (ns my-library.func) (defmacro my-macro [arg] `(identity ~arg)) (ns my-library.core (:require [my-library.func :as func]) (def my-macro-core func/my-macro) 我想把它绑定到core.clj中的一个变量: (ns my-library.func) (defmacro my-macro [ar
func.clj
中定义了一个宏:
(ns my-library.func)
(defmacro my-macro [arg]
`(identity ~arg))
(ns my-library.core
(:require [my-library.func :as func])
(def my-macro-core func/my-macro)
我想把它绑定到core.clj
中的一个变量:
(ns my-library.func)
(defmacro my-macro [arg]
`(identity ~arg))
(ns my-library.core
(:require [my-library.func :as func])
(def my-macro-core func/my-macro)
这样我就可以做如下事情:
(ns script.core
(:require [my-library.core :as mlc]))
(mlc/my-macro-core :boring-macro) ; -> :boring-macro
但是,我不能这样做,因为宏的计算结果不是一个值。以下工作:
(ns my-library.core
(:require [my-library.func :as func])
(defmacro my-macro-core [arg]
`(func/my-macro ~arg))
但这是多余的,所以我想知道是否有更干净的方法来做到这一点。这有点麻烦,但可以做到:
(ns my-library.func)
(defmacro my-macro [arg]
`(identity ~arg))
(ns my-library.core
(:require [my-library.func :as func]))
(def ^:macro my-macro-core @#'func/my-macro)
(ns script.core
(:require [my-library.core :as mlc]))
(mlc/my-macro-core :boring-macro)
诀窍是将定义的新变量设置为别名宏的原始函数值,同时设置:macro
元数据标志,以便编译器识别并适当调用它。Potemkin支持宏:
(require '[potemkin :refer [import-vars]])
(import-vars [my-library.core my-macro])
看来@是不必要的。例如,
(def^:macro my or#or)
生成一个新的宏my or
,其工作原理与或
完全相同。那是什么?再次感谢你的回答。我发布的方式避免了风险。如果希望在别名中反映对var值的后续更新,则使用var本身非常有用。