Quotes: generate arbitrary trait or class implementations
See original GitHub issueThe problem
Using Scala 2 macros, we have built an RPC framework that can automatically generate implementations of arbitrary traits. These implementations are effectively network proxies that translate every method call into a network request. When the request is received by the RPC server, a reverse translation is performed and a real implementation of this trait is invoked.
A very simplified example of this mechanism:
trait RawRpc {
def invoke(methodName: String, parameters: Map[String, Json]): Future[Json]
}
object RawRpc {
def asReal[RealRpc](rawRpc: RawRpc): RealRpc = macro ...
def asRaw[RealRpc](realRpc: RealRpc): RawRpc = macro ...
}
The asReal
macro needs to do the following:
- enumerate all (abstract) methods of
RealRpc
- for every parameter of every method, find a typeclass instance that would allow it to serialize it into
Json
- for every method’s result type, find a typeclass instance that would allow it to deserialize it from
Json
(assuming that the result type is aFuture
) - generate an implementation of every method that forwards it to
rawRpc
- inspect annotations on methods and parameters in order to treat them in some special way
The asRaw
macro needs similar capabilities in order to perform a reverse translation.
Situation in Scala 3
It’s unclear to me whether something like this is possible with Scala 3. Looking at the Quotes
API, it should in principle be possible if I was able to generate arbitrary trees, starting with ClassDef
. However, it seems that currently ClassDef.apply
is commented out and marked as TODO.
So my questions are:
- First of all, is this a valid use case for Scala 3 metaprogramming?
- If yes, can this be done with
Quotes
API? - Are there any serious obstacles preventing methods like
ClassDef.apply
from being exposed?
(Note: I asked this question briefly on Gitter and it was recommended to me to create an issue.)
Issue Analytics
- State:
- Created 3 years ago
- Reactions:21
- Comments:30 (16 by maintainers)
My company is interested in sponsoring a production-worthy and well-thought out implementation of this feature.
We try to not rush stabilizing APIs since we’re bound by binary compatibility constraints afterwards, but one thing that would help would be to get feedback from users on whether the APIs implemented in https://github.com/lampepfl/dotty/pull/14124 actually solve their problems (see the PR changes for documentation and test cases).
To try it out, just set your scalaVersion to a recent nightly to have access to experimental APIs (scroll to the bottom of https://repo1.maven.org/maven2/org/scala-lang/scala3-compiler_3/ to find the version number), e.g.