编写用于生成函数/多重方法的宏

Writing macro for generating functions / multimethods

我目前正在尝试使用 Clojure 宏来提供 DSL。我的库的用户必须能够使用该 DSL 扩展它。该库为开箱即用的某些特定命令提供了多种方法和一些使用 defmethod 的基线实现。比方说,我们有一个多重方法: (defmulti command command-name) 以及图书馆提供的一些命令,例如: (defmethod command "say-hello" [arg] (println "hello" arg)) (defmethod command "say-bye" [arg] (println "bye" arg)) 我的想法是编写一个宏来生成这些 defmethods,因此用户不需要自己编写 defmethods,而是使用我的 DSL。关于这一点,我写了下面的宏: (defmacro add-command [command-name command-impl] `(defmethod command ~command-name '[arg] ~@command-impl))

我得到的是,每当我使用我的宏时,(add-command "new-command" (print "new-command")) 出现以下异常“java.lang.IllegalArgumentException:参数声明应该是一个向量” .

如果我展开宏: (clojure.core/defmethod com.foo/on-error "new-command" [] (println "starting"))

一切看起来都很好,除了参数向量,它在扩展后是空的。

我错过了什么?

如果你想让隐含的arg存在于你需要写的正文中:

(defmacro add-command [command-name command-impl]
   `(defmethod command ~command-name [~'arg] ~@command-impl))

相反。照应宏(引入固定名称的宏,如 arg 此处)在 Clojure 中通常 unusual/frowned。

请注意,对您的示例进行宏扩展后,我得到了与您不同的(和预期的)结果:

(clojure.core/defmethod user/command "new-command" (quote [user/arg]) print "new-command")