я создал макрос, который создает именованный 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!")
))
Однако есть проблемы. Значение name-w-prefix
в привязке оператора let
вызывает ошибки. Как я могу это исправить?
(также любые советы по улучшению приветствуются, так как я Newb и это чуть ли не первое, что я писал в Clojure)
Спасибо за объяснение! Не знал этого .. но я сделал это, и теперь он жалуется на символ 'x' в определении функции. – noncom
См. Edit. Я думаю, вы немного смущены тем, что происходит внутри и вне цитат синтаксиса. – Alex
Да, похоже! Например, я думал, что, поскольку все дело в AST, я мог бы возвратиться как '~ (expr)' от функции, и он заменит вызывающего, как будто он явно написан здесь. Но выглядит так: '' 'работает по-другому ... Спасибо за совет' ~ ''->' # 'также! Теперь я исправил все макросы, и все работает отлично! – noncom