Is it possible scala's macro expansion to generate another macro invocation and get expanded again?

93 views
Skip to first unread message

Shiva Wu

unread,
Apr 15, 2014, 5:28:29 AM4/15/14
to scala-l...@googlegroups.com
In lisp-like macro system, a macro can be expanded into other macro calls and it will keep expanding until there's no macro call.

Is this possible in the current scala's macro system?

Cause in my 2 cents, if this is possible, we can totally resolve the symbols in AST while writing macros by generating another reify call or sth like that.

Also, another question is, why does scala compiler require that the macro definition must be separated from the macro usage into different compiler runs?
Is it a limitation of the current implementation (and I'd like to know the specific details, if possible) or it's intended?

Thanks!

Eugene Burmako

unread,
Apr 15, 2014, 5:33:32 AM4/15/14
to scala-l...@googlegroups.com
1) Yes, it is possible. Macros expand during typechecking, and macro expansions get typechecked immediately after macros return, which means that all macro applications in expansions are going to immediately expand.

2) It's a limitation of the current implementation that's being fixed in Project Palladium. Current macro engine needs macro implementations to be precompiled (hence the different compiler run requirement), because current architecture of scalac makes JIT compilation of macro implementations close to impossible. In Palladium, we're going to lift this restriction by interpreting macro impls.


--
You received this message because you are subscribed to the Google Groups "scala-language" group.
To unsubscribe from this group and stop receiving emails from it, send an email to scala-languag...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Shiva Wu

unread,
Apr 15, 2014, 6:08:13 AM4/15/14
to scala-l...@googlegroups.com
Hi Eugene,

Thanks for your immediate and kind response.

I've tested the macro-expand-to-macro thing, it worked, using 3 compilation passes, macro def 1, macro def 2 (who calls def 1) and macro usage (who uses def 2).
But it seems no way to expand to reify and get reify to be expanded again to an another AST.
For example, when I do this,

object P2Macro {
  def p2macro(format: String) = macro impl
  def impl(c: Context)(format: c.Expr[String]): c.Expr[Any] = {
    c.universe.reify { c.universe.reify { 100 } }
  }
}

I will end up with:

scala> P2Macro.p2macro("100")
<console>:8: error: Macro expansion contains free term variable c defined by impl in P2Macro.scala:7:12. Have you forgotten to use splice when splicing this variable into a reifee? If you have troubles tracking free term variables, consider using -Xlog-free-terms
              P2Macro.p2macro("100")

I assume this is because the reify implementation will look for ASTs in its body and try to splice it. But how am I suppose to achieve this?
Using quasiquotes with fully-resolved symbols is either no luck, but maybe I'm doing it wrong.
For example,

    val m1 = symbolOf[c.universe.type].asClass
    val r1 = m1.info.member(TermName("reify"))
    c.Expr(q"$r1(100)")

Is this because the reify method is a macro method builtin into the complier and it's impossible to nest it in macro expansion?

Also, about Project Palladium, I've read the slides on NE Scala, really cool stuff! Makes macro much more usable. Looking forward to your future updates.

Eugene Burmako

unread,
Apr 15, 2014, 1:38:38 PM4/15/14
to scala-l...@googlegroups.com
Thanks for the kind words!

As for the two attempts to reify(reify) you're bringing up, I can explain why none of them work, but first could you elaborate what you're trying to achieve with nested reification?
Reply all
Reply to author
Forward
0 new messages