通过未定义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本身非常有用。