Skip to content

Instantly share code, notes, and snippets.

@zilti
Created October 28, 2018 21:19
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save zilti/f008287e05cefda634710361eea8860d to your computer and use it in GitHub Desktop.
Save zilti/f008287e05cefda634710361eea8860d to your computer and use it in GitHub Desktop.
Nested macro vs. macro plus function with eval
;; This approach works as intended:
(defn- connect-fn [instance iface method args & code]
(eval `(proxy [~iface] []
(~(symbol (.getName method)) ~args
~@code))))
(defmacro connect [instance method args & code]
`(let [functional-method# (first (clojure.lang.Reflector/getMethods (class ~instance) 1 ~(str "set" (camelcase (name method))) false))
functional-para# (symbol (.getName (first (.getParameterTypes ^Method functional-method#))))]
(~(symbol (str ".set" (camelcase (name method)))) ~instance
(connect-fn ~instance functional-para# functional-method# '~args ~@code))))
;; This here, however, does not:
(defmacro connect
"This macro is used to make use of functional interfaces."
[instance method args & code]
`(let [functional-method# (first (clojure.lang.Reflector/getMethods (class ~instance) 1 ~(str "set" (camelcase (name method))) false))
functional-para# (symbol (.getName (first (.getParameterTypes ^Method functional-method#))))]
(~(symbol (str ".set" (camelcase (name method)))) ~instance
`(proxy [~functional-para#] []
(~(symbol (.getName functional-method#)) ~'~args
~'~@code)))))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment