Closed
Description
The goal of this issue is to discuss how one could implement a macro based string interpolator similar to densh/joyquote:
Let's consider an hypothetical xml interpolator.
In Scala 2, one can write:
implicit class XmlQuote(val sc: StringContext) {
def xml(args: Any*): Xml = macro QuoteImpl.apply
}
class QuoteImpl(val c: blackbox.Context) {
import c.universe._
def apply(args: Tree*): Tree = ???
}
Let's see how this could translate to Dotty macros. A naive translation would be:
import scala.quoted._
import scala.tasty.Tasty
implicit class XmlQuote(val sc: StringContext) {
rewrite def xml(args: Any*): Xml = ~QuoteImpl.apply('(ctx), '(args))
}
object QuoteImpl {
def apply(ctx: Expr[StringContext], args: Expr[Seq[Any]])(implicit tasty: Tasty): Expr[Xml] = ???
}
The issue with this approach is that the apply
macro doesn't see the tree for ctx
and args
as they are lifted out by the compiler and we only see references to the lifted values. To prevent parameters from being lifted out, one needs to make them by name:
import scala.quoted._
import scala.tasty.Tasty
implicit rewrite def XmlQuote(ctx: => StringContext): XmlQuote = new XmlQuote(ctx)
class XmlQuote(val sc: StringContext) {
rewrite def xml(args: => Any*): Xml = ~QuoteImpl.apply('(ctx), '(args))
}
object QuoteImpl {
def apply(ctx: Expr[StringContext], args: Expr[Seq[Any]])(implicit tasty: Tasty): Expr[Xml] = ???
}