easy metaprogramming for everyone! - scala...
TRANSCRIPT
![Page 1: Easy Metaprogramming For Everyone! - Scala Macrosscalamacros.org/paperstalks/2014-06-17-EasyMetaprogrammingForEveryone.pdf · Metaprogramming is useful Code generation Program veri](https://reader030.vdocuments.site/reader030/viewer/2022040421/5e0fb6bb3953844dcc03f4fc/html5/thumbnails/1.jpg)
Easy Metaprogramming For Everyone!
Eugene Burmako (@xeno by)Denys Shabalin (@den sh)
Ecole Polytechnique Federale de Lausannehttp://scalameta.org/
17 June 2014
Exactly two years later, we are happy to present a status update:scalamacros.org/paperstalks/2016-06-17-Metaprogramming20.pdf
![Page 2: Easy Metaprogramming For Everyone! - Scala Macrosscalamacros.org/paperstalks/2014-06-17-EasyMetaprogrammingForEveryone.pdf · Metaprogramming is useful Code generation Program veri](https://reader030.vdocuments.site/reader030/viewer/2022040421/5e0fb6bb3953844dcc03f4fc/html5/thumbnails/2.jpg)
Metaprogramming is...
Metaprogramming is the writing of computer programs thatwrite or manipulate other programs or themselves as their data.
—Wikipedia
2
![Page 3: Easy Metaprogramming For Everyone! - Scala Macrosscalamacros.org/paperstalks/2014-06-17-EasyMetaprogrammingForEveryone.pdf · Metaprogramming is useful Code generation Program veri](https://reader030.vdocuments.site/reader030/viewer/2022040421/5e0fb6bb3953844dcc03f4fc/html5/thumbnails/3.jpg)
Metaprogramming is useful
▶ Code generation
▶ Program verification
▶ Style checking
▶ Refactoring
▶ Incremental compilation
▶ Documentation generation
▶ ...
3
![Page 4: Easy Metaprogramming For Everyone! - Scala Macrosscalamacros.org/paperstalks/2014-06-17-EasyMetaprogrammingForEveryone.pdf · Metaprogramming is useful Code generation Program veri](https://reader030.vdocuments.site/reader030/viewer/2022040421/5e0fb6bb3953844dcc03f4fc/html5/thumbnails/4.jpg)
Before Scala 2.10
4
![Page 5: Easy Metaprogramming For Everyone! - Scala Macrosscalamacros.org/paperstalks/2014-06-17-EasyMetaprogrammingForEveryone.pdf · Metaprogramming is useful Code generation Program veri](https://reader030.vdocuments.site/reader030/viewer/2022040421/5e0fb6bb3953844dcc03f4fc/html5/thumbnails/5.jpg)
Baby steps of Scala metaprogramming
▶ Text-based introspection with scalap
▶ Unstable and undocumented compiler plugins
▶ Ad-hoc textual code generation
5
![Page 6: Easy Metaprogramming For Everyone! - Scala Macrosscalamacros.org/paperstalks/2014-06-17-EasyMetaprogrammingForEveryone.pdf · Metaprogramming is useful Code generation Program veri](https://reader030.vdocuments.site/reader030/viewer/2022040421/5e0fb6bb3953844dcc03f4fc/html5/thumbnails/6.jpg)
After Scala 2.10
6
![Page 7: Easy Metaprogramming For Everyone! - Scala Macrosscalamacros.org/paperstalks/2014-06-17-EasyMetaprogrammingForEveryone.pdf · Metaprogramming is useful Code generation Program veri](https://reader030.vdocuments.site/reader030/viewer/2022040421/5e0fb6bb3953844dcc03f4fc/html5/thumbnails/7.jpg)
Current state of things
Metaprogramming with scala.reflect:
+ Full-fledged model of Scala available in standard distribution
+ Structured code generation with macros and quasiquotes
– Complicated: optimized towards compiler developers, not library users
– Brittle: a lot of unspecified and hard-to-satisfy invariants
– Locked-in: tightly bound to scalac internals
7
![Page 8: Easy Metaprogramming For Everyone! - Scala Macrosscalamacros.org/paperstalks/2014-06-17-EasyMetaprogrammingForEveryone.pdf · Metaprogramming is useful Code generation Program veri](https://reader030.vdocuments.site/reader030/viewer/2022040421/5e0fb6bb3953844dcc03f4fc/html5/thumbnails/8.jpg)
Current state of things
Metaprogramming with scala.reflect:
+ Full-fledged model of Scala available in standard distribution
+ Structured code generation with macros and quasiquotes
– Complicated: optimized towards compiler developers, not library users
– Brittle: a lot of unspecified and hard-to-satisfy invariants
– Locked-in: tightly bound to scalac internals
8
![Page 9: Easy Metaprogramming For Everyone! - Scala Macrosscalamacros.org/paperstalks/2014-06-17-EasyMetaprogrammingForEveryone.pdf · Metaprogramming is useful Code generation Program veri](https://reader030.vdocuments.site/reader030/viewer/2022040421/5e0fb6bb3953844dcc03f4fc/html5/thumbnails/9.jpg)
Nevertheless scala.reflect has proven to be useful
▶ Enables libraries like async, pickling, scala-blitz, etc
▶ Empowers existing solutions in scalatest, Play!, parboiled, etc
▶ Foundation for high-level abstractions: shapeless, yin-yang, etc
9
![Page 10: Easy Metaprogramming For Everyone! - Scala Macrosscalamacros.org/paperstalks/2014-06-17-EasyMetaprogrammingForEveryone.pdf · Metaprogramming is useful Code generation Program veri](https://reader030.vdocuments.site/reader030/viewer/2022040421/5e0fb6bb3953844dcc03f4fc/html5/thumbnails/10.jpg)
We are building an even better tech
10
![Page 11: Easy Metaprogramming For Everyone! - Scala Macrosscalamacros.org/paperstalks/2014-06-17-EasyMetaprogrammingForEveryone.pdf · Metaprogramming is useful Code generation Program veri](https://reader030.vdocuments.site/reader030/viewer/2022040421/5e0fb6bb3953844dcc03f4fc/html5/thumbnails/11.jpg)
Meet our new metaprogramming platform
▶ Name: scala.meta (formerly known as Project Palladium)
▶ Goal: Build a tool to conveniently work with programs as data
▶ Status: Alpha version, public preview coming this fall
11
![Page 12: Easy Metaprogramming For Everyone! - Scala Macrosscalamacros.org/paperstalks/2014-06-17-EasyMetaprogrammingForEveryone.pdf · Metaprogramming is useful Code generation Program veri](https://reader030.vdocuments.site/reader030/viewer/2022040421/5e0fb6bb3953844dcc03f4fc/html5/thumbnails/12.jpg)
Language model
![Page 13: Easy Metaprogramming For Everyone! - Scala Macrosscalamacros.org/paperstalks/2014-06-17-EasyMetaprogrammingForEveryone.pdf · Metaprogramming is useful Code generation Program veri](https://reader030.vdocuments.site/reader030/viewer/2022040421/5e0fb6bb3953844dcc03f4fc/html5/thumbnails/13.jpg)
Scala language model a la scala.reflect
▶ Trees
▶ TermTrees
▶ TypTrees
▶ DefTrees
▶ ...
▶ Types
▶ Symbols
▶ Scopes
▶ Names
▶ Annotations
▶ Constants
▶ Modifiers
▶ ...
13
![Page 14: Easy Metaprogramming For Everyone! - Scala Macrosscalamacros.org/paperstalks/2014-06-17-EasyMetaprogrammingForEveryone.pdf · Metaprogramming is useful Code generation Program veri](https://reader030.vdocuments.site/reader030/viewer/2022040421/5e0fb6bb3953844dcc03f4fc/html5/thumbnails/14.jpg)
Scala language model a la scala.reflect
▶ Trees
▶ TermTrees
▶ TypTrees
▶ DefTrees
▶ ...
▶ Types
▶ Symbols
▶ Scopes
▶ Names
▶ Annotations
▶ Constants
▶ Modifiers
▶ ...
14
![Page 15: Easy Metaprogramming For Everyone! - Scala Macrosscalamacros.org/paperstalks/2014-06-17-EasyMetaprogrammingForEveryone.pdf · Metaprogramming is useful Code generation Program veri](https://reader030.vdocuments.site/reader030/viewer/2022040421/5e0fb6bb3953844dcc03f4fc/html5/thumbnails/15.jpg)
Scala language model a la scala.reflect
▶ Trees
▶ TermTrees
▶ TypTrees
▶ DefTrees
▶ ...
▶ Types
▶ Symbols
▶ Scopes
▶ Names
▶ Annotations
▶ Constants
▶ Modifiers
▶ ...
15
![Page 16: Easy Metaprogramming For Everyone! - Scala Macrosscalamacros.org/paperstalks/2014-06-17-EasyMetaprogrammingForEveryone.pdf · Metaprogramming is useful Code generation Program veri](https://reader030.vdocuments.site/reader030/viewer/2022040421/5e0fb6bb3953844dcc03f4fc/html5/thumbnails/16.jpg)
Scala language model a la scala.reflect
▶ Trees
▶ TermTrees
▶ TypTrees
▶ DefTrees
▶ ...
▶ Types
▶ Symbols
▶ Scopes
▶ Names
▶ Annotations
▶ Constants
▶ Modifiers
▶ ...
16
![Page 17: Easy Metaprogramming For Everyone! - Scala Macrosscalamacros.org/paperstalks/2014-06-17-EasyMetaprogrammingForEveryone.pdf · Metaprogramming is useful Code generation Program veri](https://reader030.vdocuments.site/reader030/viewer/2022040421/5e0fb6bb3953844dcc03f4fc/html5/thumbnails/17.jpg)
A lot of concepts that interact in inconsistent ways
scala> val list = q"List(1, 2, 3)"
list: universe.Tree = List(1, 2, 3)
scala> toolbox.typecheck(list).tpe
res1: toolbox.u.Type = List[Int]
scala> tq"List[Int]"
res2: universe.Tree = List[Int]
scala> res1 == res2
res3: Boolean = false
scala> toolbox.typecheck(res2, toolbox.TYPEmode).tpe
res4: toolbox.u.Type = List[Int]
scala> res1 == res4
res5: Boolean = true
17
![Page 18: Easy Metaprogramming For Everyone! - Scala Macrosscalamacros.org/paperstalks/2014-06-17-EasyMetaprogrammingForEveryone.pdf · Metaprogramming is useful Code generation Program veri](https://reader030.vdocuments.site/reader030/viewer/2022040421/5e0fb6bb3953844dcc03f4fc/html5/thumbnails/18.jpg)
A lot of concepts that interact in inconsistent ways
scala> val list = q"List(1, 2, 3)"
list: universe.Tree = List(1, 2, 3)
scala> toolbox.typecheck(list).tpe
res1: toolbox.u.Type = List[Int]
scala> tq"List[Int]"
res2: universe.Tree = List[Int]
scala> res1 == res2
res3: Boolean = false
scala> toolbox.typecheck(res2, toolbox.TYPEmode).tpe
res4: toolbox.u.Type = List[Int]
scala> res1 == res4
res5: Boolean = true
18
![Page 19: Easy Metaprogramming For Everyone! - Scala Macrosscalamacros.org/paperstalks/2014-06-17-EasyMetaprogrammingForEveryone.pdf · Metaprogramming is useful Code generation Program veri](https://reader030.vdocuments.site/reader030/viewer/2022040421/5e0fb6bb3953844dcc03f4fc/html5/thumbnails/19.jpg)
A lot of concepts that interact in inconsistent ways
scala> val list = q"List(1, 2, 3)"
list: universe.Tree = List(1, 2, 3)
scala> toolbox.typecheck(list).tpe
res1: toolbox.u.Type = List[Int]
scala> tq"List[Int]"
res2: universe.Tree = List[Int]
scala> res1 == res2
res3: Boolean = false
scala> toolbox.typecheck(res2, toolbox.TYPEmode).tpe
res4: toolbox.u.Type = List[Int]
scala> res1 == res4
res5: Boolean = true
19
![Page 20: Easy Metaprogramming For Everyone! - Scala Macrosscalamacros.org/paperstalks/2014-06-17-EasyMetaprogrammingForEveryone.pdf · Metaprogramming is useful Code generation Program veri](https://reader030.vdocuments.site/reader030/viewer/2022040421/5e0fb6bb3953844dcc03f4fc/html5/thumbnails/20.jpg)
A lot of concepts that interact in inconsistent ways
scala> val list = q"List(1, 2, 3)"
list: universe.Tree = List(1, 2, 3)
scala> toolbox.typecheck(list).tpe
res1: toolbox.u.Type = List[Int]
scala> tq"List[Int]"
res2: universe.Tree = List[Int]
scala> res1 == res2
res3: Boolean = false
scala> toolbox.typecheck(res2, toolbox.TYPEmode).tpe
res4: toolbox.u.Type = List[Int]
scala> res1 == res4
res5: Boolean = true
20
![Page 21: Easy Metaprogramming For Everyone! - Scala Macrosscalamacros.org/paperstalks/2014-06-17-EasyMetaprogrammingForEveryone.pdf · Metaprogramming is useful Code generation Program veri](https://reader030.vdocuments.site/reader030/viewer/2022040421/5e0fb6bb3953844dcc03f4fc/html5/thumbnails/21.jpg)
Scala language model a la scala.meta
Trees
.
▶ In scala.meta, we model everything just with its abstract syntax
▶ Types, members, names, modifiers: all represented with trees
▶ There’s only one data structure, so there’s only one way to do it
21
![Page 22: Easy Metaprogramming For Everyone! - Scala Macrosscalamacros.org/paperstalks/2014-06-17-EasyMetaprogrammingForEveryone.pdf · Metaprogramming is useful Code generation Program veri](https://reader030.vdocuments.site/reader030/viewer/2022040421/5e0fb6bb3953844dcc03f4fc/html5/thumbnails/22.jpg)
Scala language model a la scala.meta
Trees.
▶ In scala.meta, we model everything just with its abstract syntax
▶ Types, members, names, modifiers: all represented with trees
▶ There’s only one data structure, so there’s only one way to do it
22
![Page 23: Easy Metaprogramming For Everyone! - Scala Macrosscalamacros.org/paperstalks/2014-06-17-EasyMetaprogrammingForEveryone.pdf · Metaprogramming is useful Code generation Program veri](https://reader030.vdocuments.site/reader030/viewer/2022040421/5e0fb6bb3953844dcc03f4fc/html5/thumbnails/23.jpg)
Scala language model a la scala.meta
Trees.
▶ In scala.meta, we model everything just with its abstract syntax
▶ Types, members, names, modifiers: all represented with trees
▶ There’s only one data structure, so there’s only one way to do it
23
![Page 24: Easy Metaprogramming For Everyone! - Scala Macrosscalamacros.org/paperstalks/2014-06-17-EasyMetaprogrammingForEveryone.pdf · Metaprogramming is useful Code generation Program veri](https://reader030.vdocuments.site/reader030/viewer/2022040421/5e0fb6bb3953844dcc03f4fc/html5/thumbnails/24.jpg)
Terms are trees
scala> q"List(1, 2, 3)"
res0: meta.Term = List(1, 2, 3)
scala> q"List(1, 2, 3)".tpe
res1: meta.Type = List[Int]
24
![Page 25: Easy Metaprogramming For Everyone! - Scala Macrosscalamacros.org/paperstalks/2014-06-17-EasyMetaprogrammingForEveryone.pdf · Metaprogramming is useful Code generation Program veri](https://reader030.vdocuments.site/reader030/viewer/2022040421/5e0fb6bb3953844dcc03f4fc/html5/thumbnails/25.jpg)
Types are trees
scala> t"List[Int]"
res2: meta.Type = List[Int]
scala> t"List[Int]" == q"List(1, 2, 3)".tpe
res3: Boolean = true
scala> t"List[Int]" <:< t"List[_]"
res4: Boolean = true
scala> t"List[Int]".subtypes
res5: Seq[meta.Type] = List(::[Int], Nil.type)
25
![Page 26: Easy Metaprogramming For Everyone! - Scala Macrosscalamacros.org/paperstalks/2014-06-17-EasyMetaprogrammingForEveryone.pdf · Metaprogramming is useful Code generation Program veri](https://reader030.vdocuments.site/reader030/viewer/2022040421/5e0fb6bb3953844dcc03f4fc/html5/thumbnails/26.jpg)
Symbols are trees
scala> val head1 = t"List[Int]".defs("head")
head1: meta.Def = def head: Int
scala> val head2 = q"List(1, 2, 3).head".defn
head2: meta.Def = def head: Int
scala> head1 == head2
res8: Boolean = true
scala> head1.owner
res9: meta.Scope = class List { ... }
scala> head1.show[Raw]
res10: String = Decl.Def(Nil, Term.Name(head), Nil, Nil, Int)
26
![Page 27: Easy Metaprogramming For Everyone! - Scala Macrosscalamacros.org/paperstalks/2014-06-17-EasyMetaprogrammingForEveryone.pdf · Metaprogramming is useful Code generation Program veri](https://reader030.vdocuments.site/reader030/viewer/2022040421/5e0fb6bb3953844dcc03f4fc/html5/thumbnails/27.jpg)
Something seems fishy
27
![Page 28: Easy Metaprogramming For Everyone! - Scala Macrosscalamacros.org/paperstalks/2014-06-17-EasyMetaprogrammingForEveryone.pdf · Metaprogramming is useful Code generation Program veri](https://reader030.vdocuments.site/reader030/viewer/2022040421/5e0fb6bb3953844dcc03f4fc/html5/thumbnails/28.jpg)
You might be thinking
▶ If there’s just trees and nothing more
▶ How do we know that List in List(1, 2, 3) is scala.List?
28
![Page 29: Easy Metaprogramming For Everyone! - Scala Macrosscalamacros.org/paperstalks/2014-06-17-EasyMetaprogrammingForEveryone.pdf · Metaprogramming is useful Code generation Program veri](https://reader030.vdocuments.site/reader030/viewer/2022040421/5e0fb6bb3953844dcc03f4fc/html5/thumbnails/29.jpg)
In scala.reflectTrees only
scala> val list = q"List(1, 2, 3)"
list: universe.Tree = List(1, 2, 3)
scala> tb.eval(q"val List = 42; $list")
compilation has failed: Int does not take parameters
Trees and symbols
scala> val List = mirror.staticModule("s.c.i.List")
res0: universe.ModuleSymbol = object List
scala> val list = q"$List(1, 2, 3)"
list: universe.Tree = List(1, 2, 3)
scala> tb.eval(q"val List = 42; $list")
res2: Any = List(1, 2, 3)
29
![Page 30: Easy Metaprogramming For Everyone! - Scala Macrosscalamacros.org/paperstalks/2014-06-17-EasyMetaprogrammingForEveryone.pdf · Metaprogramming is useful Code generation Program veri](https://reader030.vdocuments.site/reader030/viewer/2022040421/5e0fb6bb3953844dcc03f4fc/html5/thumbnails/30.jpg)
In scala.reflectTrees only
scala> val list = q"List(1, 2, 3)"
list: universe.Tree = List(1, 2, 3)
scala> tb.eval(q"val List = 42; $list")
compilation has failed: Int does not take parameters
Trees and symbols
scala> val List = mirror.staticModule("s.c.i.List")
res0: universe.ModuleSymbol = object List
scala> val list = q"$List(1, 2, 3)"
list: universe.Tree = List(1, 2, 3)
scala> tb.eval(q"val List = 42; $list")
res2: Any = List(1, 2, 3)
30
![Page 31: Easy Metaprogramming For Everyone! - Scala Macrosscalamacros.org/paperstalks/2014-06-17-EasyMetaprogrammingForEveryone.pdf · Metaprogramming is useful Code generation Program veri](https://reader030.vdocuments.site/reader030/viewer/2022040421/5e0fb6bb3953844dcc03f4fc/html5/thumbnails/31.jpg)
The missing technology
31
![Page 32: Easy Metaprogramming For Everyone! - Scala Macrosscalamacros.org/paperstalks/2014-06-17-EasyMetaprogrammingForEveryone.pdf · Metaprogramming is useful Code generation Program veri](https://reader030.vdocuments.site/reader030/viewer/2022040421/5e0fb6bb3953844dcc03f4fc/html5/thumbnails/32.jpg)
Hygiene in action
In scala.reflect
scala> val list = q"List(1, 2, 3)"
list: universe.Tree = List(1, 2, 3)
scala> tb.eval(q"val List = 42; $list")
compilation has failed: Int does not take parameters
In scala.meta
scala> val list = q"List(1, 2, 3)"
list: meta.Tree = List(1, 2, 3)
scala> q"val List = 42; $list".eval
res1: Any = List(1, 2, 3)
32
![Page 33: Easy Metaprogramming For Everyone! - Scala Macrosscalamacros.org/paperstalks/2014-06-17-EasyMetaprogrammingForEveryone.pdf · Metaprogramming is useful Code generation Program veri](https://reader030.vdocuments.site/reader030/viewer/2022040421/5e0fb6bb3953844dcc03f4fc/html5/thumbnails/33.jpg)
Tree design
![Page 34: Easy Metaprogramming For Everyone! - Scala Macrosscalamacros.org/paperstalks/2014-06-17-EasyMetaprogrammingForEveryone.pdf · Metaprogramming is useful Code generation Program veri](https://reader030.vdocuments.site/reader030/viewer/2022040421/5e0fb6bb3953844dcc03f4fc/html5/thumbnails/34.jpg)
Trees are now comprehensive
In scala.reflect
scala> q"for (i <- List(1, 2, 3)) println(i)"
res0: universe.Tree = List(1, 2, 3).foreach(i => println(i))
In scala.meta
scala> q"for (i <- List(1, 2, 3)) println(i)"
res1: meta.Term = for (i <- List(1, 2, 3)) println(i)
34
![Page 35: Easy Metaprogramming For Everyone! - Scala Macrosscalamacros.org/paperstalks/2014-06-17-EasyMetaprogrammingForEveryone.pdf · Metaprogramming is useful Code generation Program veri](https://reader030.vdocuments.site/reader030/viewer/2022040421/5e0fb6bb3953844dcc03f4fc/html5/thumbnails/35.jpg)
Trees are now comprehensive
In scala.reflect
scala> q"for (i <- List(1, 2, 3)) println(i)"
res0: universe.Tree = List(1, 2, 3).foreach(i => println(i))
In scala.meta
scala> q"for (i <- List(1, 2, 3)) println(i)"
res1: meta.Term = for (i <- List(1, 2, 3)) println(i)
35
![Page 36: Easy Metaprogramming For Everyone! - Scala Macrosscalamacros.org/paperstalks/2014-06-17-EasyMetaprogrammingForEveryone.pdf · Metaprogramming is useful Code generation Program veri](https://reader030.vdocuments.site/reader030/viewer/2022040421/5e0fb6bb3953844dcc03f4fc/html5/thumbnails/36.jpg)
Trees are now comprehensive
▶ In scala.meta, we keep all the information about the program
▶ Nothing is desugared (e.g. for loops or string interpolations)
▶ Nothing is thrown away (e.g. comments or formatting details)
36
![Page 37: Easy Metaprogramming For Everyone! - Scala Macrosscalamacros.org/paperstalks/2014-06-17-EasyMetaprogrammingForEveryone.pdf · Metaprogramming is useful Code generation Program veri](https://reader030.vdocuments.site/reader030/viewer/2022040421/5e0fb6bb3953844dcc03f4fc/html5/thumbnails/37.jpg)
Trees are now strongly-typed
In scala.reflect
case class Apply(fun: Tree, args: List[Tree])
In scala.meta
@ast class Apply(fun: Term, args: Seq[Arg])
37
![Page 38: Easy Metaprogramming For Everyone! - Scala Macrosscalamacros.org/paperstalks/2014-06-17-EasyMetaprogrammingForEveryone.pdf · Metaprogramming is useful Code generation Program veri](https://reader030.vdocuments.site/reader030/viewer/2022040421/5e0fb6bb3953844dcc03f4fc/html5/thumbnails/38.jpg)
In scala.reflect
scala> val List = tq"_root_.scala.List"
List: universe.Select = _root_.scala.List
scala> val list = q"$List(1, 2, 3)"
list: universe.Tree = _root_.scala.List(1, 2, 3)
scala> toolbox.typecheck(list)
s.t.r.ToolBoxError: type scala.List is not a value
at s.t.r.ToolBoxFactory$...apply(ToolBoxFactory.scala:178)
at s.t.r.ToolBoxFactory$...apply(ToolBoxFactory.scala:170)
at s.t.r.ToolBoxFactory$...apply(ToolBoxFactory.scala:148)
...
38
![Page 39: Easy Metaprogramming For Everyone! - Scala Macrosscalamacros.org/paperstalks/2014-06-17-EasyMetaprogrammingForEveryone.pdf · Metaprogramming is useful Code generation Program veri](https://reader030.vdocuments.site/reader030/viewer/2022040421/5e0fb6bb3953844dcc03f4fc/html5/thumbnails/39.jpg)
In scala.meta
scala> val List = t"_root_.scala.List"
List: meta.Type = _root_.scala.List
scala> val list = q"$List(1, 2, 3)"
<console>:27: error: type mismatch;
found : Type
required: Term
val list = q"$List(1, 2, 3)"
^
39
![Page 40: Easy Metaprogramming For Everyone! - Scala Macrosscalamacros.org/paperstalks/2014-06-17-EasyMetaprogrammingForEveryone.pdf · Metaprogramming is useful Code generation Program veri](https://reader030.vdocuments.site/reader030/viewer/2022040421/5e0fb6bb3953844dcc03f4fc/html5/thumbnails/40.jpg)
Boromir has certain doubts about scala.reflect
40
![Page 41: Easy Metaprogramming For Everyone! - Scala Macrosscalamacros.org/paperstalks/2014-06-17-EasyMetaprogrammingForEveryone.pdf · Metaprogramming is useful Code generation Program veri](https://reader030.vdocuments.site/reader030/viewer/2022040421/5e0fb6bb3953844dcc03f4fc/html5/thumbnails/41.jpg)
Trees are now immutable
In scala.reflect
abstract class Tree {
private[this] var rawtpe: Type =
def tpe: Type = rawtpe
def setType(tp: Type): this.type = { rawtpe = tp; this }
...
}
In scala.meta
implicit class SemanticTermOps(val term: Term) extends AnyVal {
@hosted def tpe: Type = ...
}
41
![Page 42: Easy Metaprogramming For Everyone! - Scala Macrosscalamacros.org/paperstalks/2014-06-17-EasyMetaprogrammingForEveryone.pdf · Metaprogramming is useful Code generation Program veri](https://reader030.vdocuments.site/reader030/viewer/2022040421/5e0fb6bb3953844dcc03f4fc/html5/thumbnails/42.jpg)
Trees are now immutable
In scala.reflect
abstract class Tree {
private[this] var rawtpe: Type =
def tpe: Type = rawtpe
def setType(tp: Type): this.type = { rawtpe = tp; this }
...
}
In scala.meta
implicit class SemanticTermOps(val term: Term) extends AnyVal {
@hosted def tpe: Type = ...
}
42
![Page 43: Easy Metaprogramming For Everyone! - Scala Macrosscalamacros.org/paperstalks/2014-06-17-EasyMetaprogrammingForEveryone.pdf · Metaprogramming is useful Code generation Program veri](https://reader030.vdocuments.site/reader030/viewer/2022040421/5e0fb6bb3953844dcc03f4fc/html5/thumbnails/43.jpg)
Anytime metaprogramming
![Page 44: Easy Metaprogramming For Everyone! - Scala Macrosscalamacros.org/paperstalks/2014-06-17-EasyMetaprogrammingForEveryone.pdf · Metaprogramming is useful Code generation Program veri](https://reader030.vdocuments.site/reader030/viewer/2022040421/5e0fb6bb3953844dcc03f4fc/html5/thumbnails/44.jpg)
Flavors of metaprogramming
▶ Compile-time metaprogramming (macros)
▶ Runtime metaprogramming (runtime reflection, toolboxes)
▶ Some-time metaprogramming (IDEs, incremental compilation, linters)
44
![Page 45: Easy Metaprogramming For Everyone! - Scala Macrosscalamacros.org/paperstalks/2014-06-17-EasyMetaprogrammingForEveryone.pdf · Metaprogramming is useful Code generation Program veri](https://reader030.vdocuments.site/reader030/viewer/2022040421/5e0fb6bb3953844dcc03f4fc/html5/thumbnails/45.jpg)
Flavors of environments
▶ Scala compiler (scala-reflect.jar and scala-compiler.jar)
▶ IntelliJ IDEA (a very own implementation of Scala’s typechecker)
▶ Scala IDE (Scala compiler running in a funny mode)
▶ SBT (A tiny compiler plugin + a very own analysis infrastructure)
▶ DIY (Just have some Scala sources and need to find something out)
45
![Page 46: Easy Metaprogramming For Everyone! - Scala Macrosscalamacros.org/paperstalks/2014-06-17-EasyMetaprogrammingForEveryone.pdf · Metaprogramming is useful Code generation Program veri](https://reader030.vdocuments.site/reader030/viewer/2022040421/5e0fb6bb3953844dcc03f4fc/html5/thumbnails/46.jpg)
Too complicated again!
▶ Typechecking and evaluation kind of work at runtime, but not quite
▶ Macros work at compile time, but only in a separate project
▶ Macros seem to work in IntelliJ, but they actually don’t
46
![Page 47: Easy Metaprogramming For Everyone! - Scala Macrosscalamacros.org/paperstalks/2014-06-17-EasyMetaprogrammingForEveryone.pdf · Metaprogramming is useful Code generation Program veri](https://reader030.vdocuments.site/reader030/viewer/2022040421/5e0fb6bb3953844dcc03f4fc/html5/thumbnails/47.jpg)
With scala.meta it’s no longer a problem
Demo!
47
![Page 48: Easy Metaprogramming For Everyone! - Scala Macrosscalamacros.org/paperstalks/2014-06-17-EasyMetaprogrammingForEveryone.pdf · Metaprogramming is useful Code generation Program veri](https://reader030.vdocuments.site/reader030/viewer/2022040421/5e0fb6bb3953844dcc03f4fc/html5/thumbnails/48.jpg)
But how is this supposed to work?!
48
![Page 49: Easy Metaprogramming For Everyone! - Scala Macrosscalamacros.org/paperstalks/2014-06-17-EasyMetaprogrammingForEveryone.pdf · Metaprogramming is useful Code generation Program veri](https://reader030.vdocuments.site/reader030/viewer/2022040421/5e0fb6bb3953844dcc03f4fc/html5/thumbnails/49.jpg)
But how is this supposed to work?!
▶ Macros are known to be just bytecode invoked by reflection
▶ But when macros aren’t compiled yet, there’s no bytecode
▶ Therefore having macros work in the same file would be most unusual
▶ This merits an explanation
49
![Page 50: Easy Metaprogramming For Everyone! - Scala Macrosscalamacros.org/paperstalks/2014-06-17-EasyMetaprogrammingForEveryone.pdf · Metaprogramming is useful Code generation Program veri](https://reader030.vdocuments.site/reader030/viewer/2022040421/5e0fb6bb3953844dcc03f4fc/html5/thumbnails/50.jpg)
Explanation, in a nutshell
▶ With scala.meta, we have principled tools for metaprogramming
▶ This makes it possible to make macros principled
▶ When macros become a proper abstraction, all becomes much better
50
![Page 51: Easy Metaprogramming For Everyone! - Scala Macrosscalamacros.org/paperstalks/2014-06-17-EasyMetaprogrammingForEveryone.pdf · Metaprogramming is useful Code generation Program veri](https://reader030.vdocuments.site/reader030/viewer/2022040421/5e0fb6bb3953844dcc03f4fc/html5/thumbnails/51.jpg)
Explanation, part 1: Clear requirements for all hosts
▶ A standalone, independent metaprogramming interface
▶ Built on simple, strongly-typed and immutable foundation
▶ With clear and concise host API
▶ Prototype implementations for scalac and IntelliJ
51
![Page 52: Easy Metaprogramming For Everyone! - Scala Macrosscalamacros.org/paperstalks/2014-06-17-EasyMetaprogrammingForEveryone.pdf · Metaprogramming is useful Code generation Program veri](https://reader030.vdocuments.site/reader030/viewer/2022040421/5e0fb6bb3953844dcc03f4fc/html5/thumbnails/52.jpg)
Explanation, part 1: Clear requirements for all hosts
52
![Page 53: Easy Metaprogramming For Everyone! - Scala Macrosscalamacros.org/paperstalks/2014-06-17-EasyMetaprogrammingForEveryone.pdf · Metaprogramming is useful Code generation Program veri](https://reader030.vdocuments.site/reader030/viewer/2022040421/5e0fb6bb3953844dcc03f4fc/html5/thumbnails/53.jpg)
Explanation, part 2: Equal opportunities for all hosts
▶ With our plugin enabled, scalac saves all ASTs after typer
▶ This means that full info about any program is available at any time
▶ No information is lost anymore (e.g. signatures of local definitions)
▶ The overhead is actually quite reasonable (e.g. compressed untypedASTs of scala-library.jar are less than 15% of the bytecodes)
53
![Page 54: Easy Metaprogramming For Everyone! - Scala Macrosscalamacros.org/paperstalks/2014-06-17-EasyMetaprogrammingForEveryone.pdf · Metaprogramming is useful Code generation Program veri](https://reader030.vdocuments.site/reader030/viewer/2022040421/5e0fb6bb3953844dcc03f4fc/html5/thumbnails/54.jpg)
Explanation, part 3: Brave new world!
▶ Easy access to all ASTs enables a lot of interesting things
▶ One of them is host-independent AST interpretation
▶ That’s exactly what we’re using to lift the precompilation restriction
54
![Page 55: Easy Metaprogramming For Everyone! - Scala Macrosscalamacros.org/paperstalks/2014-06-17-EasyMetaprogrammingForEveryone.pdf · Metaprogramming is useful Code generation Program veri](https://reader030.vdocuments.site/reader030/viewer/2022040421/5e0fb6bb3953844dcc03f4fc/html5/thumbnails/55.jpg)
Anytime metaprogramming
55
![Page 56: Easy Metaprogramming For Everyone! - Scala Macrosscalamacros.org/paperstalks/2014-06-17-EasyMetaprogrammingForEveryone.pdf · Metaprogramming is useful Code generation Program veri](https://reader030.vdocuments.site/reader030/viewer/2022040421/5e0fb6bb3953844dcc03f4fc/html5/thumbnails/56.jpg)
Automatic code rewriting tool
▶ As of late, there have been talks about deprecating procedure syntax
▶ But it’s so common that warnings are only emitted under -Xfuture
▶ It would be nice to have an automatic migration tool for this!
56
![Page 57: Easy Metaprogramming For Everyone! - Scala Macrosscalamacros.org/paperstalks/2014-06-17-EasyMetaprogrammingForEveryone.pdf · Metaprogramming is useful Code generation Program veri](https://reader030.vdocuments.site/reader030/viewer/2022040421/5e0fb6bb3953844dcc03f4fc/html5/thumbnails/57.jpg)
Automatic code rewriting tool
▶ Unfortunately existing scalac functionality isn’t quite fit for that
▶ Wheels are reinvented in order to do robust parsing and prettyprinting
▶ With scala.meta, this become very simple!
57
![Page 58: Easy Metaprogramming For Everyone! - Scala Macrosscalamacros.org/paperstalks/2014-06-17-EasyMetaprogrammingForEveryone.pdf · Metaprogramming is useful Code generation Program veri](https://reader030.vdocuments.site/reader030/viewer/2022040421/5e0fb6bb3953844dcc03f4fc/html5/thumbnails/58.jpg)
Automatic code rewriting tool
some/project$ sbt meta
[info] Loading project definition...
[info] Starting scala interpreter...
> project
res0: Project = Project(List("scalameta/package.scala",
"scalameta/Trees.scala", "scalameta/semantic/Hosts.scala"..))
> project.rewrite {
| case q"..$mods def $nme[..$tps](...$pss) { ..$body }" =>
| q"..$mods def $nme[..$tps](...$pss): Unit = { ..$body }"
| }.persist
res1: Project = Project(List("scalameta/package.scala",
"scalameta/Trees.scala", "scalameta/semantic/Hosts.scala"..))
58
![Page 59: Easy Metaprogramming For Everyone! - Scala Macrosscalamacros.org/paperstalks/2014-06-17-EasyMetaprogrammingForEveryone.pdf · Metaprogramming is useful Code generation Program veri](https://reader030.vdocuments.site/reader030/viewer/2022040421/5e0fb6bb3953844dcc03f4fc/html5/thumbnails/59.jpg)
Automatic code rewriting tool
some/project$ sbt meta
[info] Loading project definition...
[info] Starting scala interpreter...
> project
res0: Project = Project(List("scalameta/package.scala",
"scalameta/Trees.scala", "scalameta/semantic/Hosts.scala"..))
> project.rewrite {
| case q"..$mods def $nme[..$tps](...$pss) { ..$body }" =>
| q"..$mods def $nme[..$tps](...$pss): Unit = { ..$body }"
| }.persist
res1: Project = Project(List("scalameta/package.scala",
"scalameta/Trees.scala", "scalameta/semantic/Hosts.scala"..))
59
![Page 60: Easy Metaprogramming For Everyone! - Scala Macrosscalamacros.org/paperstalks/2014-06-17-EasyMetaprogrammingForEveryone.pdf · Metaprogramming is useful Code generation Program veri](https://reader030.vdocuments.site/reader030/viewer/2022040421/5e0fb6bb3953844dcc03f4fc/html5/thumbnails/60.jpg)
Automatic code rewriting tool
some/project$ sbt meta
[info] Loading project definition...
[info] Starting scala interpreter...
> project
res0: Project = Project(List("scalameta/package.scala",
"scalameta/Trees.scala", "scalameta/semantic/Hosts.scala"..))
> project.rewrite {
| case q"..$mods def $nme[..$tps](...$pss) { ..$body }" =>
| q"..$mods def $nme[..$tps](...$pss): Unit = { ..$body }"
| }.persist
res1: Project = Project(List("scalameta/package.scala",
"scalameta/Trees.scala", "scalameta/semantic/Hosts.scala"..))
60
![Page 61: Easy Metaprogramming For Everyone! - Scala Macrosscalamacros.org/paperstalks/2014-06-17-EasyMetaprogrammingForEveryone.pdf · Metaprogramming is useful Code generation Program veri](https://reader030.vdocuments.site/reader030/viewer/2022040421/5e0fb6bb3953844dcc03f4fc/html5/thumbnails/61.jpg)
Wrapping up
![Page 62: Easy Metaprogramming For Everyone! - Scala Macrosscalamacros.org/paperstalks/2014-06-17-EasyMetaprogrammingForEveryone.pdf · Metaprogramming is useful Code generation Program veri](https://reader030.vdocuments.site/reader030/viewer/2022040421/5e0fb6bb3953844dcc03f4fc/html5/thumbnails/62.jpg)
Brought to you by the Palladium team
This project is brought to you by the Palladium team.Thank you very much, folks, for making this presentation possible!
▶ Uladzimir Abramchuk
▶ Igor Bogomolov
▶ Eugene Burmako
▶ Mathieu Demarne
▶ Martin Duhem
▶ Adrien Ghosn
▶ Mikhail Mutcianko
▶ Dmitry Naydanov
▶ Artem Nikiforov
▶ Vladimir Nikolaev
▶ Alexander Podkhalyuzin
▶ Jatin Puri
▶ Denys Shabalin
62
![Page 63: Easy Metaprogramming For Everyone! - Scala Macrosscalamacros.org/paperstalks/2014-06-17-EasyMetaprogrammingForEveryone.pdf · Metaprogramming is useful Code generation Program veri](https://reader030.vdocuments.site/reader030/viewer/2022040421/5e0fb6bb3953844dcc03f4fc/html5/thumbnails/63.jpg)
What we’ve seen today
▶ Built on a simple principle that everything is a tree
▶ And designed in strongly-typed and fully immutable style
▶ scala.meta is a clean and portable metaprogramming toolkit
▶ Public preview is coming this fall
▶ But some results are available right now (e.g. sbt improvements)
63