I'm building a macro that should be called like this:
(myMacro MyController something otherthing
(defn onFoo [this event]
(println "ok"))
(defn onBar [this event]
(println "ok"))
)
After the first three parameters I want to be able to pass a few functions that should be used to build the function definitions in the (definterface
and the (deftype
part of the macro.
The result of the above call should be this:
(definterface IMyController
(^void onFoo [^javafx.event.ActionEvent event])
(^void onBar [^javafx.event.ActionEvent event])
)
(deftype MyController []
IHandler (^{javafx.fxml.FXML {}} onFoo [this event] (println "ok"))
IHandler (^{javafx.fxml.FXML {}} onBar [this event] (println "ok"))
)
Im very new to Clojure but the hand build implementation of the controller for the FXML file is already working, I just want to simplify it with a macro but I wasn't able to find any help on how do this kind of loop inside a macro definition.
UPDATE
The macro is almost done, and is already running successfully.
(defmacro viewHandler [className & fn-defs]
(def interface (symbol (join ["I" className])))
`(do
(definterface ~interface
~@(for [curr-fn fn-defs]
`(~(second curr-fn) [~'event])
))
(deftype ~className []
~interface
~@(for [curr-fn fn-defs]
(rest curr-fn))
))
)
Called by:
(viewHandler Bar
(defn onFoo [this event] (println "ok-1"))
(defn onBar [this event] (println "ok-2"))
)
But I still can't do the type-hints for the java method annotations.
Start off with something simple:
the backquote (backtick?) starts an inline code template. The ~@ turns off the template part and starts live code execution (try substituting ~ instead of ~@ to see the difference - an extra layer of parentheses).
But, the code we want to output is more like
(fun1 [] ...)
, which is literal code we DON'T want to execute. So, that must be wrapped inside of another syntax-quote/template, but we need another ~ to make the "curr-fn" be "live code" again:Result is:
We need the outer (do ...) form since we are outputting both a (definterface ...) and a (deftype ...) forms.
I'll leave it to you to figure out the type-hints, etc.