Skip to content

Macro based string interpolation #5095

Closed
@allanrenucci

Description

@allanrenucci

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] = ???
}

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions