I am trying to wrap an implementation and dynamically generate the reify clause for all the interfaces the wrapped object implements.
For example:
I want to generate:
(reify
BaseInterface
(fee [_] (custom-operation wrapped))
(foo [_] (.foo wrapped)))
or
(reify
BaseInterface
(fee [_] (custom-operation wrapped))
(foo [_] (.foo wrapped))
AnotherInterface
(bar [_] (.bar wrapped)))
depending on whether wrapped
implements only BaseInterface
or both BaseInterface
and AnotherInterface
.
I tried something like the following, but it fails as the macro is evaluated at compile time and my second argument (the cond->
expression) doesn't have its runtime value:
(defmacro add-interface-implementations
"Adds additional interface implementations to a reify expression.
This is useful to create a reify expression dynamically without introducing if-else branching."
[reify-expr interface->methods]
(reduce
(fn [expr# entry#]
(println "expr#" expr#)
(println "entry#" entry#)
(let [[interface# body#] entry#]
(cons
(first expr#)
(cons interface#
(reduce
(fn [e# m#]
(cons m# e#))
(rest expr#)
body#)))))
reify-expr
interface->methods))
(add-interface-implementations
(reify
BaseInterface
(fee [_] (custom-operation wrapped))
(foo [_] (.foo wrapped)))
(cond-> {}
(instance? AnotherInterface foo)
(assoc AnotherInterface [(bar [_] (.bar wrapped))])))
Any suggestions on how to achieve what I'm trying. I want avoid the if-else branching as it leads to combinatorial explosion as soon as I have more interfaces.