Add some way to expand macros in Quotes in metaprogramming API #17863
Replies: 0 comments 3 replies
-
I think it should work with a |
Beta Was this translation helpful? Give feedback.
-
Currently is no way to expand macro (event transient inline) programmatically from quotation. Here is a code: package x
import scala.quoted._
def p(x: Int):Int = ???
object Incr:
transparent inline def op(x:Int):Int =
p(x + 1)
object GenX:
inline def transform(inline x:Int, viaMacro: Boolean):Int = ${
transformImpl('x, 'viaMacro)
}
def transformImpl(x:Expr[Int], viaMacro: Expr[Boolean])(using qctx: Quotes):Expr[Int] =
import qctx.reflect._
val r1 = if (viaMacro.valueOrError) then {
'{ Incr.op($x) }.asExprOf[Int]
} else {
'{ p($x+1) }.asExprOf[Int]
}
println(s"r1=${r1.show}")
val noP = new TreeMap() {
override def transformTerm(tree:Term)(owner: Symbol): Term =
tree match
case Apply(Ident("p"),List(y)) =>
'{ val tmp=${y.asExprOf[Int]}; println(s"p:$tmp"); tmp }.asTerm
case _ => super.transformTerm(tree)(owner)
}
val r2 = noP.transformTerm(r1.asTerm)(Symbol.spliceOwner).asExprOf[Int]
println(s"r2=${r2.show}")
r2 and Main.scala: package x
object Main {
def main(args:Array[String]):Unit =
val a = GenX.transform(1, false)
val b = GenX.transform(2, true)
}
when we compile/run this we receive:
I.e. as we see, when we use macro in quotation, it's not expanded. r1 in transformImpl is |
Beta Was this translation helpful? Give feedback.
-
Aga, as I understand the @LPTK comment, the question: should we allow only transient inline macroses here? I.e.:
vs
Technically, any variant is ok (because it will allow passing behavior to macroses). Generic expand macroses is slightly better (as more general), but if we can't run compiler pass on a tree, living with expandTransientInline() only is possible. |
Beta Was this translation helpful? Give feedback.
-
It would be good to have some way to expand macroses from metaprogramming API.
Something like:
Usecase is passing 'configuration depends from type' to macroses. I.e. I have one big macro which accepts some types, and inside these macros different types can have different additional compile-time operations, which I want to interpret inside the scope of 'big macros'.
[More concrete example: memorizing in IO have type IO[IO[T]]; in monix: Task[T], in Future - none (it's memorized by default), so for uniform handling of effect memorization I need or write 'if' in macros for concrete libs (which I want to avoid) or define via implicit search some sort of macro-code for each type, which should be substituted inside my big 'async' macro. With this feature implemented this can be just a macro definition.]
Beta Was this translation helpful? Give feedback.
All reactions