Я пытаюсь обернуть реализацию и динамически сгенерировать предложение reify для всех интерфейсов, которые реализует обернутый объект.
Например:
Я хочу сгенерировать:
(reify
BaseInterface
(fee [_] (custom-operation wrapped))
(foo [_] (.foo wrapped)))
или
(reify
BaseInterface
(fee [_] (custom-operation wrapped))
(foo [_] (.foo wrapped))
AnotherInterface
(bar [_] (.bar wrapped)))
в зависимости от того, реализует ли wrapped
только BaseInterface
или оба BaseInterface
и AnotherInterface
.
Я попробовал что-то вроде следующего, но это не удалось, так как макрос вычисляется во время компиляции, а мой второй аргумент (выражение cond->
) не имеет значения времени выполнения:
(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))])))
Любые предложения о том, как добиться того, что я пытаюсь. Я хочу избежать разветвления if-else, так как оно приведет к комбинаторному взрыву, как только у меня будет больше интерфейсов.