the concept underlying metaprogramming in Scala. ▰ I will not provide many tutorial examples to write macros. ▰ I want you to feel the “お気持ち (philosophy)” of Scala metaprogramming system. 4 / 43 主に概念について解説. チュートリアルではない. Scalaメタプロの“お気持ち”.
programs have the ability to treat programs as the data. (from https://en.wikipedia.org/wiki/Metaprogramming) 8 / 43 メタプロとは「プログラムをデータとして扱うプロ グラム」 (wikipedia). “
▰ Different AST definitions can completely capture syntactic structure of identical program, without any information loss. 11 / 43 ASTはプログラムの構文情報を表す木. 異なるAST定義が同等の情報を表せる. Abstract Syntax Tree (AST)
not been any official metaprogramming tools. ▰ However, there were some tricks. ▻ java.lang.reflect ▻ scalap (ScalaSignature) ▻ They provided severely limited functions in runtime reflection. 17 / 43 Scala 2.10が出る前はjava.reflectかscalap. 実行時リフレクションのごく一部.
and compile-time reflection. ▰ Provides a set of API to manipulate internal AST in scalac 19 / 43 2.10からscala.reflectが使える. scalacの内部に 定義されたASTを操作するためのAPI群. Generation 1
scalac of Scala 2.x. ▰ This means that macros written with scala.reflect are not portable to other Scala implementations which define their original AST. 21 / 43 scala.reflectはScala 2.xのscalacの内部で利用 されるASTの定義に依存. “可搬性”がない. Generation 1: Problem
intelliJ ▻ causes a lot of warnings because they can’t find macro- expanded Defns. ▰ Who wants to completely rewrite their macros just for an IDE…? 22 / 43 scalac以外の実装: DottyやIDEでは scala.reflectベースのマクロが動かない. Generation 1: Problem
definition as the “standard AST”. ▰ Before expanding macro, compiler internal AST are converted to standard AST. 24 / 43 scala.metaベースのmacro annotation. コンパイラASTを標準ASTに変換. Generation 2
▰ Implementing AST converters is a hard task. ▻ Converters must support all possible syntactic elements. ▻ Each compiler requires a tailored converter. ▰ Some information will be lost in conversion. ▰ Conversion incurs performance penalty.
AST. ▰ Implemented as “abstract contractors” and “abstract extractors” which let raw compiler AST “act” as standard syntax. ▰ Note: these functions do not convert AST. 32 / 43 標準constractor/extractorでコンパイラASTを 「見かけ上」標準化する. 変換ではない. Generation 3: Standard Syntax
Advantages ▰ Reduce implementation cost. ▻ wrappers are far easier to implement than converters. ▰ Improve performance of macro code. ▻ no AST conversion, no additional cost. ▰ Retain full information in raw compiler AST. ▻ because scala.macros manipulates raw AST “as-is”.
Scala implementation, don’t we? ▰ YES. But the cost is far smaller than converters. ▻ We don’t have to care about meta information attached to raw AST. ▻ Wrappers are not required to cover all syntactic elements. 39 / 43 標準構文wrapperはScala実装ごとに定義する 必要? → そうだが、コストが段違いに低い. Generation 3: FAQ
to 10) foreach { case i if i % 3 == 0 => println(i) case _ => () } else throw new RuntimeException() To invert this if expr... macros.TermIf Generation 3 needs scalac.Term scalac.Term scalac.Term
to 10) foreach { case i if i % 3 == 0 => println(i) case _ => () } else throw new RuntimeException() To invert this if expr... scala.meta.Term.{ If, Apply, Select, Name, ApplyInfix, PartialFunction, Throw, Param } scala.meta.{ Lit.{String, Int, Unit}, Template, Pat.Var.Term, Ctor.Ref.Name } Generation 2 needs
of metaprogramming system in Scala can be seen as a process to pursue “portability without pain” ▰ New scala.macros is expected to be a good solution towards this goal.
a scala.meta-based static code generation tool. ▻ Also it may be the first attempt for an organized code generation tool. ▰ Although this is a private (i.e. not an scalacenter’s official) project, it is worthy of note. 42 / 43 新しい静的コード生成ツール“ScalaGen”にも注 目する価値がある. Appendix: ScalaGen