我創建了創建一個名爲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