Suppose that you have some typeclass and Scala 3 macros to derive it's instances. Macro code is large and bulky, so you decide to split project into two modules - runtime (typeclass itself) and macro code (which isn't required on runtime).
The problem: to write case class ... derives TypeClass you need to have macros defined in runtime module. Compiler will call TypeClass.derived[T], you can't override that. You need to delegate that derivation somehow, without statically linking to macro module.
Possible solution:
Define (in macro module):
object DerivationMacros { inline def derive[T]: TypeClass[T] = /* impl */ }Define (in runtime module):
object TypeClass { def derived[T]: TypeClass[T] = #{ DerivationMacros.derive[T] } } trait TypeClass[T] { /* impl */ }With
#{ .. }denoting imaginary construct that generates it's contents on runtime.
The problem 2: you can't produce ASTs with statically unknown types. At least I didn't found a method to lookup term/type by name. To make this #{ .. } construct work, you need to statically link runtime module to macro module, defeating whole benefit. You need a way to produce that code using manually crafted AST, so that direct dependencies will be avoided.
The question is: either how to do original code splitting task, or how to lookup terms by names?