Good day..I'm using vertx and it's very enjoyable but for event bus communication it requires a lot of boilerplate and even worst, if I need change some function name I need change it in 4 or 5 places differents..
just know, I'm using an abstraction for transform the vertx callbacks to channels..like this
;;helper
(defn send [add msg]
(let [ch (chan 1)]
(eb/send add msg #(put! ch %))))
;;I wrap the event bus sender in a function for make a bit cleaner the code
(defn eb-get-cached-view [name id]
(send "render:get-cached-view" [name id])) ;;return chan[response]
(eb-get-cached-view "something" "here");;and finally I use it
;;in other verticle, I write the funcion
(defn get-cached-view [name id]
(...))
;;and enable an event bus listener pointing to that function
;; basically I receive a vector, pass it to my function, which return a channel, then I reply to the message with the response
(eb/on-message "render:get-cache-view" #(go (eb/reply (<! (apply get-cached-view %)))))
as you can see it's a lot of boilerplate and I'm afraid every time than I change the function name I could miss change it in some point and my code fails, the on-message argument I follow the convention of use my namespace follow by ":" and the function name
I was thinking than probably would be good something like this
(defbus blah
[name]
(str "hi! " name))
this macro build the function blah and create a bus listener for messages with the "render" namespace (can I access to the namespace inside a macro? is good approach?)
(eb/on-message "namespace:blah" #(go (eb/reply (<!(apply get-cached-view %))))) ;;apply is necessary because the messages are received inside a vctor
and a macro for send the message
(<eb namespace:blah "john Smith") ;; could be a key like :namespace:blah too
than translate to something like this
(defn namespace:blah [message]
(let [ch (chan 1)]
(eb/send "namespace:blah" message #(put! ch %))))
(namespace:blah "john Smith")
with these macros I would avoid boilerplate,change callbacks for promise or avoid inconsistencies in the function names...
is it a good approach? is possible write these macros or I'm ignoring some point?..I'm a bit newbie with clojure and I don't know if it's possible and why it doesnt exist yet...
I appreciate any help and maybe correction of my code (I wrote the code by heart)
----------EDIT 1----------------------------------------------------------
I wrote this macro (thanks to Arthur)...it's a bit simpler than the final macro only for demo
(defmacro defbus [bus-name args code]
`(let [fun# (fn ~args ~code)]
(println (str *ns* ":" ~bus-name))
(eb/on-message (str *ns* ":" ~bus-name) (fn [arg#] (apply fun# arg#)))))
I think than the macro-expansion is pretty well...but when I try use it I get
(defbus blah [a b] (str "just " a " " b))
java.lang.RuntimeException: Unable to resolve symbol: blah in this context
seems than I can use blah directly but a simbol or string...Am I missing something? (I'm a newbie with macros and all the examples are very different to what I need) thanks!...