Scala marcos: Getting started

Getting started: Hello world

 1 import scala.language.experimental.macros
 2 import scala.reflect.macros.Context
 3 
 4 object HelloWorld1Macro {
 5   def helloWorld() = macro helloWorld_impl
 6 
 7   def helloWorld_impl(c:Context)() : c.Expr[Unit] = {
 8     import c.universe._
 9 
10     reify {
11       println("Hello world")
12     }
13   }
14 }
1 object HelloWold1 extends App {
2   HelloWorld1Macro.helloWorld()
3 }

How to debug

  • Use -Ymacro-debug-lite option of the scala compiler
  • Use c.echo, c.info … to write your own messages to the compiler log

Idea debug

Splicing expressions

 1 object HelloWorld2Macro {
 2   def helloWorld(str: String): Int = macro helloWorld_impl
 3 
 4   def helloWorld_impl(c: Context)(str: c.Expr[String]): c.Expr[Int] = {
 5     import c.universe._
 6 
 7     c.echo(str.tree.pos, "Do the hello world magic")
 8 
 9     reify {
10       println("Hello " + str.splice)
11       str.splice.length
12     }
13   }
14 }

Somewhat more usefull example

 1 object DebugMacro {
 2   def debug(a: Any) = macro debug_impl
 3 
 4   def debug_impl(c: Context)(a: c.Expr[Any]) = {
 5     import c.universe._
 6 
 7     val dump = show(a.tree)
 8     val dumpExpr = c.literal(dump)
 9 
10     reify {
11       println(dumpExpr.splice + "=" + a.splice.toString)
12     }
13   }
14 }
1 object Debug extends App {
2   var a = 10
3 
4   DebugMacro.debug(a)
5 
6   DebugMacro.debug(2 * a)
7 }
Debug.this.a=10
2.*(Debug.this.a)=20