Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

Macro in Scala

3,557 views

Published on

#渋谷java

Published in: Software
  • Be the first to comment

  • Be the first to like this

Macro in Scala

  1. 1. Macro in Scala Naoki Takezoe @takezoen BizReach, Inc 1 Oct. 2016 #渋谷java 17th
  2. 2. What's Macro?
  3. 3. C Expand special directive in source code before compilation by pre-processor #define square(x) ((x) * (x)) printf("i * i = %dn", i, square(i)); #define DEBUG #ifdef DEBUG printf("debug: i = %dn", i) #endif
  4. 4. Lisp (also Scala or Rust) Generate AST in compile-time (defmacro when (test &body body) `(if ,test (progn ,@body))) (progn (when (= 1 1) (print "Hello,") (print "World!!"))) (progn (if (= 1 1) (progn (print "Hello,") (print "World!!")))) Expand by Macro
  5. 5. Example in Scala def assert(cond: Boolean, msg: String): Unit = macro assertImpl def assertImpl(c: Context) (cond: c.Expr[Boolean], msg: c.Expr[String]) = { import c.universe._ q"if(!$cond){ throw new AssertionError($msg) }" }
  6. 6. Example in Scala assert(i == 1, "i does not 1") if(i == 1){ throw new AssertionError("i does not 1") } Expand by Macro Note: Macro have to be compiled before main compilation
  7. 7. Use cases
  8. 8. Use cases ● Validation ● Type generation ● DSL ● Optimization without runtime overhead
  9. 9. Quill ● Database access library for Scala ● Do in compile-time by macro ○ Translate typesafe DSL to SQL ○ SQL validation against real database val q = quote { query[Person].filter(p => p.age > 18) } // SELECT p.id, p.name, p.age FROM Person p WHERE p.age > 18 http://getquill.io/
  10. 10. Macro in Scala
  11. 11. Macro type ● def macro ○ callable as same as normal function ● Macro annotation ○ triggered by annotation ○ requires Macro Paradise plug-in @main object Test { println("hello world") } object Test { def main(args: Array[String]): Unit = { println("hello world") } } Expand by Macro annotation
  12. 12. How to construct AST? ● AST model ● reify ● Quasiquotes
  13. 13. AST model def compileTimeImpl(c: Context)() = { Literal(Constant(new java.util.Date().toString)) }
  14. 14. reify def assertImpl(c: Context) (cond: c.Expr[Boolean], msg: c.Expr[String]) = { import c.universe._ reify(if(!cond.splice){ throw new AssertionError(msg.splice) }) }
  15. 15. Quasiquotes def assertImpl(c: Context) (cond: c.Expr[Boolean], msg: c.Expr[String]) = { import c.universe._ q"if(!$cond){ throw new AssertionError($msg) }" }
  16. 16. Future: scala.mata ● Metaprogramming toolkit for Scala ● Replace scala.reflect ○ More simple and safe ● Scala Macro will move to scala.meta based ○ Only Macro annotation is available by Macro Paradise plug-in currently
  17. 17. Let's learn Macro!

×