我如何使用`clojure.tools.macro/name-with-attributes`?

Jef*_*.D. 6 macros clojure

我看到什么有望成为clojure.tools.macro库中任何编写defn类宏的工具:该函数.文档字符串说:name-with-attributes

用于宏定义.处理可选的文档字符串和属性映射,以便在宏参数列表中定义名称.如果第一个宏参数是字符串,则将其作为docstring添加到name并从宏参数列表中删除.如果之后第一个宏参数是一个映射,则将其条目添加到名称的元数据映射中,并从宏参数列表中删除映射.返回值是一个向量,包含带有扩展元数据映射的名称和未处理的宏参数列表.

但我似乎找不到在任何地方使用此功能的示例.

那么,我怎样才能使用这个函数来定义一个defn2宏,它应该是一个clojure.core/defn包含所有相同功能的克隆,包括:

  • 文档字符串
  • 属性图
  • 先决条件
  • 多arities

Jef*_*.D. 6

这是defn2:

(require '[clojure.tools.macro :as ctm])

(defmacro defn2
  "A clone of `defn`."
  [symb & defn-args]
  (let [[symb body] (ctm/name-with-attributes symb defn-args)]
    `(defn ~symb ~@body)))
Run Code Online (Sandbox Code Playgroud)

查看元数据,我们可以看到它被正确附加:

(defn2 ^:private add
       "Docstring"
       ([] :foo)
       ([a b] {:pre [(= 1 1)]} (+ a b)))

(pprint (meta #'add))
Run Code Online (Sandbox Code Playgroud)

...收益率:

{:arglists ([] [a b]),
 :ns #<Namespace user>,
 :name add,
 :column 1,
 :private true,
 :doc "Docstring",
 :line 1,
 :file
 "/private/var/folders/30/v73zyld1359d7jb2xtlc_kjm0000gn/T/form-init8938188655190399857.clj"}
Run Code Online (Sandbox Code Playgroud)

使用defn2上面创建的add函数如下:

(add)     ; => :foo
(add 1 2) ; => 3
Run Code Online (Sandbox Code Playgroud)