What's a macro? 
Learning by Examples 
Takako Shimamoto 
BizReach, Inc
What to Talk About 
• What are macros? 
• Good thing about macros 
• Actual use cases of macros 
• Future of macros
Are you using 
macros? 
If “Yes",
The Fab You!
Because 
• Using macros is easy, developing macros is hard
What are macros? 
• Code that generates code 
• Not textual code generation
What are macros? 
• An experimental feature of 2.10+ 
• Compiler invokes functions
Before macros 
• Ad-hoc textual code generation by sbt plugin 
• Compile-time AST operation by compiler plugin
Why macros are necessary? 
• Code is made simple 
• Efficiency improved
Macro is 
on your 
side!
To use macros 
• Need to be enabled explicitly 
• import scala.language.experimental.macros 
• -language:experimental.macros
Notes 
• Macros are separate compilation 
• Macro implementations need to be compiled 
the main compilation
Def Macros
Def Macros 
• Def macros replace well-typed terms with other 
well-typed terms 
• Can contain arbitrary Scala constructs
Practical 
example 
Scala Logging
Where? 
you call 
logger.debug(s"Some $expensive message!") 
replaced by macros 
if (logger.isDebugEnabled) 
logger.debug(s"Some $expensive message!")
M 
• Starts with the conditional keyword 
• F
I 
• Takes several parameter lists
I 
• Takes several parameter lists 
First comes a single 
parameter, of type 
Context
I 
• Takes several parameter lists 
Macro definition 
Next, followed by a list of 
parameters that have the 
same names as the macro 
definition parameters
I 
• The original macro parameter has 
• type T 
• A macro implementation parameter has 
• type c.Expr[T]
Q 
• q"..." string interpolators that build code 
• Unnecessary to directly implement the AST 
• To use the quasiquotes from the macro, just write 
import c.universe._
Q 
• Using the showRaw, it is possible to see the AST
Goodness 
• The hard to comprehend notion of meta 
programming 
• def macros are similar to the concept of a typed 
method call
Practical 
example 
specs2
Where? 
• To use macros to automatically generate matchers 
for any complex typ 
• MatcherMacros trait
Where? 
case class Cat(name: String, age: Int) 
! 
// your test case 
val cat = Cat(name = "Tom", age = 2) 
cat must matchA[Cat].name("Tom") 
you call
Where? 
replaced by macros 
def matchACat( 
name: Matcher[String] = AlwaysMatcher(), 
age: Matcher[Int] = AlwaysMatcher() 
): Matcher[Cat] = 
name ^^ {(cat: Cat) => cat.name} and 
age ^^ {(cat: Cat) => cat.age}
M 
• Generics 
• Has type parameters
I 
• Type tags(actual type arguments) 
along when the macro is expanded
I 
• Type tags(actual type arguments) 
along when the macro is expanded 
Come with 
WeakTypeTag 
context bounds
Goodness 
• DRY approach 
• Usage is fairly simple
Blackbox vs Whitebox 
• From 2.11 
• Not implemented in 2.10 or in macro paradis 
• in 2.12, only include blackbox macros
Blackbox vs Whitebox 
• 2.10 
• scala.reflect.macros.Context 
• 2.11 
• scala.reflect.macros.blackbox.Context 
• scala.reflect.macros.whitebox.Context
Why distinction? 
• Type specification of macro is 
class Foo 
class Bar extends Foo 
Scala 2.10 
! 
object FooExample { 
def foo: Foo = macro foo_impl 
def foo_impl(c: Context): c.Expr[Foo] = 
c.Expr[Foo](c.universe.reify(new Bar).tree) 
}
Why distinction? 
scala> FooExample.foo 
res0: Bar = Bar@4118f8dd 
• Type checking during macro expansion 
• Not affect after expansion
B 
• Type parameters of macro affect the type of after 
macro expansion 
• When blackbox macro is used, 
Implicit Macros will not work
No restrictions 
• Same as 2.10 def macros 
• E 
should be possible in 2.11
Practical 
example 
Spire
Appendix 
• A numeric library for Scala 
• Using features such as macros, type classes 
• Fast and Precise
Where? 
• Using string interpolation and macros, Spire 
provides convenient syntax for number types 
• Evaluated at compile-time
M 
• As usual 
string interpolation
I 
• Syntax check at compile-time
I 
• Syntax check at compile-time 
Occur at compile-time 
if any errors 
encounter
Goodness 
• Static (compile-time) type check 
• Runtime error decrease
But, has 
weak side.
Current state 
• Optimized towards compiler developers, not library 
users 
Complicated
Scala 2.12 (plan) 
• Not introduce new features 
• Bugfixes and stability improvements 
• Mention later why reason
scala.meta 
• A new experimental API for metaprogramming 
• F
scala.meta 
• Implemented in a library shipped separately from 
the official Scala distribution 
• The first milestone release is scheduled for this fall
The goal of scala.meta 
• Metaprogramming easy 
• New API is going to greatly simplify writing 
macros 
• Not require knowledge of compiler internals
Language model 
• All represented with trees 
Types 
Modifiers 
… 
Names 
Trees 
scala.meta 
Terms 
Symbols
Language model 
• Keeps all the information about the program 
• Comments also remain 
• No information is lost anymore
Manner of utilization 
• Code generation 
• Static type checking 
• etc…
Summary 
• Macros are actively used in the OSS library 
• Can be more efficiently and safely programming 
• Scala macros are evolving
Thanks!!

What's a macro?: Learning by Examples / Scalaのマクロに実用例から触れてみよう!

  • 1.
    What's a macro? Learning by Examples Takako Shimamoto BizReach, Inc
  • 2.
    What to TalkAbout • What are macros? • Good thing about macros • Actual use cases of macros • Future of macros
  • 3.
    Are you using macros? If “Yes",
  • 4.
  • 5.
    Because • Usingmacros is easy, developing macros is hard
  • 6.
    What are macros? • Code that generates code • Not textual code generation
  • 7.
    What are macros? • An experimental feature of 2.10+ • Compiler invokes functions
  • 8.
    Before macros •Ad-hoc textual code generation by sbt plugin • Compile-time AST operation by compiler plugin
  • 9.
    Why macros arenecessary? • Code is made simple • Efficiency improved
  • 10.
    Macro is onyour side!
  • 11.
    To use macros • Need to be enabled explicitly • import scala.language.experimental.macros • -language:experimental.macros
  • 12.
    Notes • Macrosare separate compilation • Macro implementations need to be compiled the main compilation
  • 13.
  • 14.
    Def Macros •Def macros replace well-typed terms with other well-typed terms • Can contain arbitrary Scala constructs
  • 15.
  • 16.
    Where? you call logger.debug(s"Some $expensive message!") replaced by macros if (logger.isDebugEnabled) logger.debug(s"Some $expensive message!")
  • 17.
    M • Startswith the conditional keyword • F
  • 18.
    I • Takesseveral parameter lists
  • 19.
    I • Takesseveral parameter lists First comes a single parameter, of type Context
  • 20.
    I • Takesseveral parameter lists Macro definition Next, followed by a list of parameters that have the same names as the macro definition parameters
  • 21.
    I • Theoriginal macro parameter has • type T • A macro implementation parameter has • type c.Expr[T]
  • 22.
    Q • q"..."string interpolators that build code • Unnecessary to directly implement the AST • To use the quasiquotes from the macro, just write import c.universe._
  • 23.
    Q • Usingthe showRaw, it is possible to see the AST
  • 24.
    Goodness • Thehard to comprehend notion of meta programming • def macros are similar to the concept of a typed method call
  • 25.
  • 26.
    Where? • Touse macros to automatically generate matchers for any complex typ • MatcherMacros trait
  • 27.
    Where? case classCat(name: String, age: Int) ! // your test case val cat = Cat(name = "Tom", age = 2) cat must matchA[Cat].name("Tom") you call
  • 28.
    Where? replaced bymacros def matchACat( name: Matcher[String] = AlwaysMatcher(), age: Matcher[Int] = AlwaysMatcher() ): Matcher[Cat] = name ^^ {(cat: Cat) => cat.name} and age ^^ {(cat: Cat) => cat.age}
  • 29.
    M • Generics • Has type parameters
  • 30.
    I • Typetags(actual type arguments) along when the macro is expanded
  • 31.
    I • Typetags(actual type arguments) along when the macro is expanded Come with WeakTypeTag context bounds
  • 32.
    Goodness • DRYapproach • Usage is fairly simple
  • 33.
    Blackbox vs Whitebox • From 2.11 • Not implemented in 2.10 or in macro paradis • in 2.12, only include blackbox macros
  • 34.
    Blackbox vs Whitebox • 2.10 • scala.reflect.macros.Context • 2.11 • scala.reflect.macros.blackbox.Context • scala.reflect.macros.whitebox.Context
  • 35.
    Why distinction? •Type specification of macro is class Foo class Bar extends Foo Scala 2.10 ! object FooExample { def foo: Foo = macro foo_impl def foo_impl(c: Context): c.Expr[Foo] = c.Expr[Foo](c.universe.reify(new Bar).tree) }
  • 36.
    Why distinction? scala>FooExample.foo res0: Bar = Bar@4118f8dd • Type checking during macro expansion • Not affect after expansion
  • 37.
    B • Typeparameters of macro affect the type of after macro expansion • When blackbox macro is used, Implicit Macros will not work
  • 38.
    No restrictions •Same as 2.10 def macros • E should be possible in 2.11
  • 39.
  • 40.
    Appendix • Anumeric library for Scala • Using features such as macros, type classes • Fast and Precise
  • 41.
    Where? • Usingstring interpolation and macros, Spire provides convenient syntax for number types • Evaluated at compile-time
  • 42.
    M • Asusual string interpolation
  • 43.
    I • Syntaxcheck at compile-time
  • 44.
    I • Syntaxcheck at compile-time Occur at compile-time if any errors encounter
  • 45.
    Goodness • Static(compile-time) type check • Runtime error decrease
  • 46.
  • 47.
    Current state •Optimized towards compiler developers, not library users Complicated
  • 49.
    Scala 2.12 (plan) • Not introduce new features • Bugfixes and stability improvements • Mention later why reason
  • 50.
    scala.meta • Anew experimental API for metaprogramming • F
  • 51.
    scala.meta • Implementedin a library shipped separately from the official Scala distribution • The first milestone release is scheduled for this fall
  • 52.
    The goal ofscala.meta • Metaprogramming easy • New API is going to greatly simplify writing macros • Not require knowledge of compiler internals
  • 53.
    Language model •All represented with trees Types Modifiers … Names Trees scala.meta Terms Symbols
  • 54.
    Language model •Keeps all the information about the program • Comments also remain • No information is lost anymore
  • 56.
    Manner of utilization • Code generation • Static type checking • etc…
  • 57.
    Summary • Macrosare actively used in the OSS library • Can be more efficiently and safely programming • Scala macros are evolving
  • 58.