我创建了创建一个名为dispatcher
与3同伙功能get-dispatcher
,set-dispatcher
和call-dispatcher
与调度员的工作(他们得到一个调度功能,添加一个或拨打一个宏)。这一切都很好!但是,现在我想自动创建相关的函数名称,因此我将所有这些宏的内部元素放入一个定义了这个简单构造函数的let
中。请注意,在下面的代码中,只有get-
函数的名称由该自动化构造而成。 set-
和call-
这些名字的创造仍然有那种手工的气味。Clojure的 - 在宏一个让行不通
(defmacro create-dispatcher [name]
;creates a set of dispatching functions tagged
`(do
;define dispatcher
(def ~(symbol name) ~(atom {}))
(let
[name-w-prefix (fn [x] (~(symbol (str x "-" name))))]
; -- define getter
(defn (name-w-prefix "get")
"get-dispatcher [tag]: get a dispatcher fn by tag"
(~'[] (println "no tag is provided for '" ~(str name) "' dispatcher"))
(~'[tag]
(do
(println "dispatcher '" ~(str name) "' called with '" ~'tag "' tag")
; return the tagged dispatcher
((keyword ~'tag) @~(symbol name))))
)
; -- define caller
(defn ~(symbol (str "call-" name))
"get-dispatcher [tag & args]: call a dispatcher fn by tag and apply to the args"
~'[tag & args]
(apply (~(symbol (str "get-" name)) ~'tag) ~'args)
)
; -- define setter
(defn ~(symbol (str "set-" name))
~'[tag fn]
"add-dispatcher [tag fn]: add a dispatcher fn associated with the tag"
(swap! ~(symbol name) assoc (keyword ~'tag) ~'fn)
)
)
; -- report
(println "created dispatcher set for '" ~(str name) "' ok!")
))
但是,有一个问题。 let
语句绑定中的name-w-prefix
会导致错误。我该如何解决这个问题?
(也改进所提出的建议是受欢迎的,因为我是一个福利局,这是几乎是我用Clojure写的第一件事)
感谢您的解释!不知道..但是我做了它,现在它抱怨函数定义中的'x'符号。 – noncom 2013-02-27 21:15:40
请参阅编辑。我认为你对语法引用内部和外部的内容有点困惑。 – Alex 2013-02-27 21:37:45
是啊,看起来像!例如,我认为,因为它完全关于AST,所以我可以像函数中的'〜(expr)'那样返回,并且它将替换调用者,就像在这里显式写入一样。但看起来'〜'的工作方式不同......感谢'〜'''>'#'建议!现在我已经修复了所有宏,并且它工作正常! – noncom 2013-02-27 22:37:44