SlideShare a Scribd company logo
Scala runtime Meta-Programming
About Me
Meir Maor
Chief Architect @ SparkBeyond
At SparkBeyond we leverage the collective
human knowledge to solve the world's toughest
problems
This Talk
Showcase Scala reflection, and compiler toolbox
Use a real guiding example to see how these are
used to solve a real problem
SparkBeyond
SparkBeyond generates code to solve machine
learning problems, leveraging world knowledge
Allows crafting deeply embedded pipelines to
explicitly transform your data
Guiding Example
● We would like to build a deeply embedded
framework to transform data.
● Multiple classes define actions
● Can be stacked together
● Embed user generated Scala code
● Auto generate a UI to input parameters for
actions.
● Allow annotating fields to guide UI generation
case class AddColumn(columnName: String,codeExpression: String) extends Action
{...}
case class SpecialParam(a: Int,b : Int => Int)
object SpecialAction {
val myMap = Map("mul2" -> SpecialParam(1,_ * 2),
"add1" -> SpecialParam(2,_ + 1),
"ident" -> SpecialParam(3, identity)
)
}
case class SpecialAction(@PossibleValuesMap(SpecialAction.myMap) foo:
SpecialParam) extends Action
Intro to Scala Meta Programming
Creating and using mirror
import reflect.runtime.universe._
val cm =
runtimeMirror(getClass.getClassLoader)
Know the players
● Type
● Symbol
● Tree
documentation reference: http://docs.scala-lang.org/overviews/reflection/symbols-trees-types.html
Type
val t=typeOf[List[Int]]
t: reflect.runtime.universe.Type =
scala.List[Int]
Compare with =:= or <:< or weak_<:<
Key methods: declarations, baseClasses,
BaseType, typeSymbol
Symbol
● If it has a name it has a Symbol
– Types, Members, parameters
Not a type, even TypeSymbol is less than a Type
val ts=t.typeSymbol
ts: reflect.runtime.universe.Symbol =
class List
Tree
● An Abstract Syntax Tree
val tree = Apply(Select(Ident(TermName("x")),
TermName("$plus")), List(Literal(Constant(2))))
tree: scala.reflect.runtime.universe.Apply = x.$plus(2)
val expr = reify { class Flower { def name = "Rose" } }
expr: scala.reflect.runtime.universe.Expr[Unit] = …
expr.tree
Get param list from primary ctr
scala> val typ = typeOf[AddColumn]
typ: reflect.runtime.universe.Type = AddColumn
val primary=typ.typeSymbol.asClass.primaryConstructor
primary: reflect.runtime.universe.Symbol = constructor AddColumn
//recall a method can have multiple param lists, hence flaten
val paramList = primary.asMethod.paramLists.flatten
paramList: List[reflect.runtime.universe.Symbol] = List(value
columnName, value codeExpression)
Code Generation
● Cglib – byte code generation library
● Compiling externally and loading with a fresh
classloader
● The unsafe way - mutate the existing
classloader
● Scala Compiler toolbox
UrlClassLoader
def getClassInstanceFromJar[T](jarFile: File, className:
String): T = {
val classLoader = new
scala.reflect.internal.util.ScalaClassLoader.URLClassLoader(Seq(ja
rFile.toURI.toURL), this.getClass.getClassLoader)
val mirror =
scala.reflect.runtime.universe.runtimeMirror(classLoader)
val classSymbol = mirror.staticClass(className)
val ctorSymbol = classSymbol.primaryConstructor.asMethod
val ctor =
mirror.reflectClass(classSymbol).reflectConstructor(ctorSymbol)
ctor.apply().asInstanceOf[T]
}
Mutate existing ClassLoader
public static void addURL(URL u) throws IOException {
URLClassLoader sysloader = (URLClassLoader)
ClassLoader.getSystemClassLoader();
Class sysclass = URLClassLoader.class;
try {
Method method = sysclass.getDeclaredMethod("addURL", parameters);
method.setAccessible(true);
method.invoke(sysloader, new Object[]{u});
} catch (Throwable t) {
t.printStackTrace();
throw new IOException("Error, could not add URL to system
classloader");
}//end try catch
}//end method
Compiler ToolBox
● Experimental (even more so than the rest of the reflection api)
import scala.tools.reflect.ToolBox
val tb = cm.mkToolBox()
● Parse, typecheck, eval
def run(code: String) = {
synchronized {
val tree = tb parse s"import scala._nimport Predef._n $code"
tb eval tree
}
}
Using the ToolBox
● Get User code fragment
● Add boilerplate function definition, useful
variables
● Parse and eval
● Apply function on new data
Annotations
● In Java you can easily read annotations reflectively at
runtime
● Annotations can only hold specific types:
– primitive
– String
– Class
– an Enum
– another Annotation
– an array of any of the above
Scala annotations
● Scala annotations are not Java annotations
● You can put anything in a Scala annotation
● But How do you read it?
Documentation: http://docs.scala-lang.org/overviews/reflection/annotations-names-scopes.html
Defining Scala Annotation
Extend StaticAnnotation to make it available at
Runtime
case class ValuesMap(vals: Map[String, Any]) extends
StaticAnnotation
Get annotations from a symbol
● Many things can be annotated
– A type, A Method, A parameter, a val/var
● Recall our example:
case class SpecialAction(@ValuesMap(SpecialAction.myMap) foo:
SpecialParam) extends Action
Get annotations from a symbol
val param: Symbol = longestParmList.head
param: reflect.runtime.universe.Symbol = value foo
val annotations = param.annotations
scala> annotations: List[reflect.runtime.universe.Annotation] =
List(com.sparkbeyond.runtime.util.misc.ValuesMap(SpecialAction.m
yMap)
Recreate Annotation Instance
scala> val tree=annotations.head.tree
tree: reflect.runtime.universe.Tree = new
com.sparkbeyond.runtime.util.misc.ValuesMap(SpecialAction.myMap)
scala> tb.eval(tb.untypecheck(tree))
res15: Any = ValuesMap(Map(mul2 -> SpecialParam(1,<function1>), add1 ->
SpecialParam(2,<function1>), ident -> SpecialParam(3,<function1>)))
Overcoming Erasure - RTTI
● Java Generics for better or worse get erased in
runtime
● We would like to be able to tell the Type of an
instance including Type Parameters
● In most cases this is possible in a meaningful
way.
What is my type?
case class OneIntSeq(a: Int) extends Seq[Int] {...}
case class MyCaseClass[T,U](e: T,o: Seq[U])
val v = MyCaseClass("foo",OneIntSeq(1))
We want a method, given v to produce:
MyCaseClass[String,Int]
val topType=cm.reflect(v).symbol.toTypeConstructor
topType: reflect.runtime.universe.Type = MyCaseClass
//As Before
val primaryParams = topType.typeSymbol.asClass.primaryConstructor...
primaryParams: List[reflect.runtime.universe.Symbol] = List(value elem,
value other)
primaryParams.map(_.typeSignature)
res29: List[reflect.runtime.universe.Type] = List(T, scala.Seq[U])
Inspecting the Type
topType.decls.foreach{case s => println(s.toString + "t" + s.typeSignature) }
value elem => T
value elem T
value other => scala.Seq[U]
value other scala.Seq[U]
constructor MyCaseClass (elem: T, other: scala.Seq[U])MyCaseClass[T,U]
method copy [T, U](elem: T, other: scala.Seq[U])MyCaseClass[T,U]
method copy$default$1 [T, U]=> T @scala.annotation.unchecked.uncheckedVariance
method copy$default$2 [T, U]=> scala.Seq[U] @scala.annotation.unchecked.uncheckedVariance
method productPrefix => java.lang.String
method productArity => scala.Int
method productElement (x$1: scala.Int)scala.Any
method productIterator => Iterator[scala.Any]
method canEqual (x$1: scala.Any)scala.Boolean
method hashCode ()scala.Int
method toString ()java.lang.String
method equals (x$1: scala.Any)scala.Boolean
val instanceMirror = cm.reflect(v)
instanceMirror: reflect.runtime.universe.InstanceMirror = instance
mirror for MyCaseClass(foo,(1))
val elemField=topType.decls.filterNot(x => x.isMethod).head
elemField: reflect.runtime.universe.Symbol = value elem
val elemValue=instanceMirror.reflectField(elemField.asTerm).get
elemValue: Any = foo
val elemTyp=cm.reflect(elemValue).symbol.toTypeConstructor
elemTyp: reflect.runtime.universe.Type = java.lang.String
Similarly for second param other: Seq[U]
val otherTyp= cm.reflect(otherValue).symbol.toTypeConstructor
otherTyp: reflect.runtime.universe.Type = OneIntSeq
val asBase=otherTyp.baseType(otherField.typeSignature.typeSymbol)
asBase: reflect.runtime.universe.Type = Seq[scala.Int]
val uType = asBase.typeArgs.head
uType: reflect.runtime.universe.Type = scala.Int
Combining Things together
val finalType=appliedType(topType,List(elemTyp,uType))
finalType: reflect.runtime.universe.Type =
MyCaseClass[java.lang.String,scala.Int]
Q.E.D
Final Thoughts
Questions?
Like pushing Scala to it’s limits? Thrive on
scalable computing with machine learning on
top?
Join us!

More Related Content

What's hot (18)

PDF
Stepping Up : A Brief Intro to Scala
Derek Chen-Becker
 
PDF
Scala
Sven Efftinge
 
PDF
Scala @ TechMeetup Edinburgh
Stuart Roebuck
 
PPTX
Scala Intro
Alexey (Mr_Mig) Migutsky
 
PDF
Workshop Scala
Bert Van Vreckem
 
PPTX
Scala fundamentals
Alfonso Ruzafa
 
ODP
A Tour Of Scala
fanf42
 
PDF
scala
Pranav E K
 
ODP
Functional Objects & Function and Closures
Sandip Kumar
 
PDF
camel-scala.pdf
Hiroshi Ono
 
PPT
Scala - brief intro
Razvan Cojocaru
 
PDF
Starting with Scala : Frontier Developer's Meetup December 2010
Derek Chen-Becker
 
PPT
Core java concepts
Ram132
 
PPTX
Scala on Android
Jakub Kahovec
 
PDF
Scaladroids: Developing Android Apps with Scala
Ostap Andrusiv
 
PPTX
Java 8 Lambda and Streams
Venkata Naga Ravi
 
PDF
Scala - core features
Łukasz Wójcik
 
PDF
Scala at HUJI PL Seminar 2008
Yardena Meymann
 
Stepping Up : A Brief Intro to Scala
Derek Chen-Becker
 
Scala @ TechMeetup Edinburgh
Stuart Roebuck
 
Workshop Scala
Bert Van Vreckem
 
Scala fundamentals
Alfonso Ruzafa
 
A Tour Of Scala
fanf42
 
scala
Pranav E K
 
Functional Objects & Function and Closures
Sandip Kumar
 
camel-scala.pdf
Hiroshi Ono
 
Scala - brief intro
Razvan Cojocaru
 
Starting with Scala : Frontier Developer's Meetup December 2010
Derek Chen-Becker
 
Core java concepts
Ram132
 
Scala on Android
Jakub Kahovec
 
Scaladroids: Developing Android Apps with Scala
Ostap Andrusiv
 
Java 8 Lambda and Streams
Venkata Naga Ravi
 
Scala - core features
Łukasz Wójcik
 
Scala at HUJI PL Seminar 2008
Yardena Meymann
 

Viewers also liked (12)

PDF
Scala reflection
David Pichsenmeister
 
PPTX
Practical type mining in Scala
Rose Toomey
 
PDF
Scaladoc for reflection
Vlad Ureche
 
PDF
Tools for Meta-Programming
elliando dias
 
PPTX
The Art of Metaprogramming in Java
Abdelmonaim Remani
 
PDF
Spark Summit EU talk by Stavros kontopoulos and Justin Pihony
Spark Summit
 
PPT
Annotations
Knoldus Inc.
 
PDF
Spark Summit EU talk by Luca Canali
Spark Summit
 
PDF
Akka Cluster and Auto-scaling
Ikuo Matsumura
 
PPTX
7 key recipes for data engineering
univalence
 
PDF
Apache Sparkにおけるメモリ - アプリケーションを落とさないメモリ設計手法 -
Yoshiyasu SAEKI
 
PPTX
Optimizing Apache Spark SQL Joins
Databricks
 
Scala reflection
David Pichsenmeister
 
Practical type mining in Scala
Rose Toomey
 
Scaladoc for reflection
Vlad Ureche
 
Tools for Meta-Programming
elliando dias
 
The Art of Metaprogramming in Java
Abdelmonaim Remani
 
Spark Summit EU talk by Stavros kontopoulos and Justin Pihony
Spark Summit
 
Annotations
Knoldus Inc.
 
Spark Summit EU talk by Luca Canali
Spark Summit
 
Akka Cluster and Auto-scaling
Ikuo Matsumura
 
7 key recipes for data engineering
univalence
 
Apache Sparkにおけるメモリ - アプリケーションを落とさないメモリ設計手法 -
Yoshiyasu SAEKI
 
Optimizing Apache Spark SQL Joins
Databricks
 
Ad

Similar to Scala Reflection & Runtime MetaProgramming (20)

PDF
scala.reflect, Eugene Burmako
Vasil Remeniuk
 
PDF
Евгений Бурмако «scala.reflect»
e-Legion
 
PDF
Scala fun part: Reflection(runtime)
vito jeng
 
PDF
Discover Tasty Query: The library for Scala program analysis
James Thompson
 
PPTX
Deep dive into the Scala Native internals.pptx
VirtusLab
 
PDF
Introduction to meta-programming in scala
Alessandro Marrella
 
PDF
So various polymorphism in Scala
b0ris_1
 
PDF
Reflection in Scala Whats, Whys and Hows - Walter Cazzola (Dipartimento di In...
Scala Italy
 
PDF
An excuse to Try, Either, folding, and Future. sequence
Germán Ferrari
 
PDF
The Great Scala Makeover
Garth Gilmour
 
PDF
Eugene Burmako
Volha Banadyseva
 
PPT
An introduction to scala
Mohsen Zainalpour
 
PDF
Scala Paradigms
Tom Flaherty
 
PDF
Scala for Java Developers
Martin Ockajak
 
PDF
Scala cheatsheet
Arduino Aficionado
 
PDF
Metaprograms and metadata (as part of the the PTT lecture)
Ralf Laemmel
 
PDF
Custom Annotations in Java with Project Lombok
Yann-Gaël Guéhéneuc
 
PPTX
Scala Style by Adform Research (Saulius Valatka)
Vasil Remeniuk
 
PDF
Scalapeno18 - Thinking Less with Scala
Daniel Sebban
 
PDF
Basics of reflection in java
kim.mens
 
scala.reflect, Eugene Burmako
Vasil Remeniuk
 
Евгений Бурмако «scala.reflect»
e-Legion
 
Scala fun part: Reflection(runtime)
vito jeng
 
Discover Tasty Query: The library for Scala program analysis
James Thompson
 
Deep dive into the Scala Native internals.pptx
VirtusLab
 
Introduction to meta-programming in scala
Alessandro Marrella
 
So various polymorphism in Scala
b0ris_1
 
Reflection in Scala Whats, Whys and Hows - Walter Cazzola (Dipartimento di In...
Scala Italy
 
An excuse to Try, Either, folding, and Future. sequence
Germán Ferrari
 
The Great Scala Makeover
Garth Gilmour
 
Eugene Burmako
Volha Banadyseva
 
An introduction to scala
Mohsen Zainalpour
 
Scala Paradigms
Tom Flaherty
 
Scala for Java Developers
Martin Ockajak
 
Scala cheatsheet
Arduino Aficionado
 
Metaprograms and metadata (as part of the the PTT lecture)
Ralf Laemmel
 
Custom Annotations in Java with Project Lombok
Yann-Gaël Guéhéneuc
 
Scala Style by Adform Research (Saulius Valatka)
Vasil Remeniuk
 
Scalapeno18 - Thinking Less with Scala
Daniel Sebban
 
Basics of reflection in java
kim.mens
 
Ad

Recently uploaded (20)

PDF
Module - 4 Machine Learning -22ISE62.pdf
Dr. Shivashankar
 
PPTX
Numerical-Solutions-of-Ordinary-Differential-Equations.pptx
SAMUKTHAARM
 
PPTX
MODULE 03 - CLOUD COMPUTING AND SECURITY.pptx
Alvas Institute of Engineering and technology, Moodabidri
 
PDF
Digital water marking system project report
Kamal Acharya
 
PDF
3rd International Conference on Machine Learning and IoT (MLIoT 2025)
ClaraZara1
 
PPTX
Water Resources Engineering (CVE 728)--Slide 4.pptx
mohammedado3
 
PPTX
Alan Turing - life and importance for all of us now
Pedro Concejero
 
PDF
A Brief Introduction About Robert Paul Hardee
Robert Paul Hardee
 
PPT
Footbinding.pptmnmkjkjkknmnnjkkkkkkkkkkkkkk
mamadoundiaye42742
 
PDF
WD2(I)-RFQ-GW-1415_ Shifting and Filling of Sand in the Pond at the WD5 Area_...
ShahadathHossain23
 
PPTX
Knowledge Representation : Semantic Networks
Amity University, Patna
 
PDF
William Stallings - Foundations of Modern Networking_ SDN, NFV, QoE, IoT, and...
lavanya896395
 
PPTX
template.pptxr4t5y67yrttttttttttttttttttttttttttttttttttt
SithamparanaathanPir
 
PDF
Submit Your Papers-International Journal on Cybernetics & Informatics ( IJCI)
IJCI JOURNAL
 
PDF
this idjfk sgfdhgdhgdbhgbgrbdrwhrgbbhtgdt
WaleedAziz7
 
PDF
Bachelor of information technology syll
SudarsanAssistantPro
 
PDF
methodology-driven-mbse-murphy-july-hsv-huntsville6680038572db67488e78ff00003...
henriqueltorres1
 
PPTX
Seminar Description: YOLO v1 (You Only Look Once).pptx
abhijithpramod20002
 
PDF
Water Industry Process Automation & Control Monthly July 2025
Water Industry Process Automation & Control
 
PDF
Data structures notes for unit 2 in computer science.pdf
sshubhamsingh265
 
Module - 4 Machine Learning -22ISE62.pdf
Dr. Shivashankar
 
Numerical-Solutions-of-Ordinary-Differential-Equations.pptx
SAMUKTHAARM
 
MODULE 03 - CLOUD COMPUTING AND SECURITY.pptx
Alvas Institute of Engineering and technology, Moodabidri
 
Digital water marking system project report
Kamal Acharya
 
3rd International Conference on Machine Learning and IoT (MLIoT 2025)
ClaraZara1
 
Water Resources Engineering (CVE 728)--Slide 4.pptx
mohammedado3
 
Alan Turing - life and importance for all of us now
Pedro Concejero
 
A Brief Introduction About Robert Paul Hardee
Robert Paul Hardee
 
Footbinding.pptmnmkjkjkknmnnjkkkkkkkkkkkkkk
mamadoundiaye42742
 
WD2(I)-RFQ-GW-1415_ Shifting and Filling of Sand in the Pond at the WD5 Area_...
ShahadathHossain23
 
Knowledge Representation : Semantic Networks
Amity University, Patna
 
William Stallings - Foundations of Modern Networking_ SDN, NFV, QoE, IoT, and...
lavanya896395
 
template.pptxr4t5y67yrttttttttttttttttttttttttttttttttttt
SithamparanaathanPir
 
Submit Your Papers-International Journal on Cybernetics & Informatics ( IJCI)
IJCI JOURNAL
 
this idjfk sgfdhgdhgdbhgbgrbdrwhrgbbhtgdt
WaleedAziz7
 
Bachelor of information technology syll
SudarsanAssistantPro
 
methodology-driven-mbse-murphy-july-hsv-huntsville6680038572db67488e78ff00003...
henriqueltorres1
 
Seminar Description: YOLO v1 (You Only Look Once).pptx
abhijithpramod20002
 
Water Industry Process Automation & Control Monthly July 2025
Water Industry Process Automation & Control
 
Data structures notes for unit 2 in computer science.pdf
sshubhamsingh265
 

Scala Reflection & Runtime MetaProgramming

  • 2. About Me Meir Maor Chief Architect @ SparkBeyond At SparkBeyond we leverage the collective human knowledge to solve the world's toughest problems
  • 3. This Talk Showcase Scala reflection, and compiler toolbox Use a real guiding example to see how these are used to solve a real problem
  • 4. SparkBeyond SparkBeyond generates code to solve machine learning problems, leveraging world knowledge Allows crafting deeply embedded pipelines to explicitly transform your data
  • 5. Guiding Example ● We would like to build a deeply embedded framework to transform data. ● Multiple classes define actions ● Can be stacked together ● Embed user generated Scala code ● Auto generate a UI to input parameters for actions. ● Allow annotating fields to guide UI generation
  • 6. case class AddColumn(columnName: String,codeExpression: String) extends Action {...} case class SpecialParam(a: Int,b : Int => Int) object SpecialAction { val myMap = Map("mul2" -> SpecialParam(1,_ * 2), "add1" -> SpecialParam(2,_ + 1), "ident" -> SpecialParam(3, identity) ) } case class SpecialAction(@PossibleValuesMap(SpecialAction.myMap) foo: SpecialParam) extends Action
  • 7. Intro to Scala Meta Programming Creating and using mirror import reflect.runtime.universe._ val cm = runtimeMirror(getClass.getClassLoader)
  • 8. Know the players ● Type ● Symbol ● Tree documentation reference: http://docs.scala-lang.org/overviews/reflection/symbols-trees-types.html
  • 9. Type val t=typeOf[List[Int]] t: reflect.runtime.universe.Type = scala.List[Int] Compare with =:= or <:< or weak_<:< Key methods: declarations, baseClasses, BaseType, typeSymbol
  • 10. Symbol ● If it has a name it has a Symbol – Types, Members, parameters Not a type, even TypeSymbol is less than a Type val ts=t.typeSymbol ts: reflect.runtime.universe.Symbol = class List
  • 11. Tree ● An Abstract Syntax Tree val tree = Apply(Select(Ident(TermName("x")), TermName("$plus")), List(Literal(Constant(2)))) tree: scala.reflect.runtime.universe.Apply = x.$plus(2) val expr = reify { class Flower { def name = "Rose" } } expr: scala.reflect.runtime.universe.Expr[Unit] = … expr.tree
  • 12. Get param list from primary ctr scala> val typ = typeOf[AddColumn] typ: reflect.runtime.universe.Type = AddColumn val primary=typ.typeSymbol.asClass.primaryConstructor primary: reflect.runtime.universe.Symbol = constructor AddColumn //recall a method can have multiple param lists, hence flaten val paramList = primary.asMethod.paramLists.flatten paramList: List[reflect.runtime.universe.Symbol] = List(value columnName, value codeExpression)
  • 13. Code Generation ● Cglib – byte code generation library ● Compiling externally and loading with a fresh classloader ● The unsafe way - mutate the existing classloader ● Scala Compiler toolbox
  • 14. UrlClassLoader def getClassInstanceFromJar[T](jarFile: File, className: String): T = { val classLoader = new scala.reflect.internal.util.ScalaClassLoader.URLClassLoader(Seq(ja rFile.toURI.toURL), this.getClass.getClassLoader) val mirror = scala.reflect.runtime.universe.runtimeMirror(classLoader) val classSymbol = mirror.staticClass(className) val ctorSymbol = classSymbol.primaryConstructor.asMethod val ctor = mirror.reflectClass(classSymbol).reflectConstructor(ctorSymbol) ctor.apply().asInstanceOf[T] }
  • 15. Mutate existing ClassLoader public static void addURL(URL u) throws IOException { URLClassLoader sysloader = (URLClassLoader) ClassLoader.getSystemClassLoader(); Class sysclass = URLClassLoader.class; try { Method method = sysclass.getDeclaredMethod("addURL", parameters); method.setAccessible(true); method.invoke(sysloader, new Object[]{u}); } catch (Throwable t) { t.printStackTrace(); throw new IOException("Error, could not add URL to system classloader"); }//end try catch }//end method
  • 16. Compiler ToolBox ● Experimental (even more so than the rest of the reflection api) import scala.tools.reflect.ToolBox val tb = cm.mkToolBox() ● Parse, typecheck, eval def run(code: String) = { synchronized { val tree = tb parse s"import scala._nimport Predef._n $code" tb eval tree } }
  • 17. Using the ToolBox ● Get User code fragment ● Add boilerplate function definition, useful variables ● Parse and eval ● Apply function on new data
  • 18. Annotations ● In Java you can easily read annotations reflectively at runtime ● Annotations can only hold specific types: – primitive – String – Class – an Enum – another Annotation – an array of any of the above
  • 19. Scala annotations ● Scala annotations are not Java annotations ● You can put anything in a Scala annotation ● But How do you read it? Documentation: http://docs.scala-lang.org/overviews/reflection/annotations-names-scopes.html
  • 20. Defining Scala Annotation Extend StaticAnnotation to make it available at Runtime case class ValuesMap(vals: Map[String, Any]) extends StaticAnnotation
  • 21. Get annotations from a symbol ● Many things can be annotated – A type, A Method, A parameter, a val/var ● Recall our example: case class SpecialAction(@ValuesMap(SpecialAction.myMap) foo: SpecialParam) extends Action
  • 22. Get annotations from a symbol val param: Symbol = longestParmList.head param: reflect.runtime.universe.Symbol = value foo val annotations = param.annotations scala> annotations: List[reflect.runtime.universe.Annotation] = List(com.sparkbeyond.runtime.util.misc.ValuesMap(SpecialAction.m yMap)
  • 23. Recreate Annotation Instance scala> val tree=annotations.head.tree tree: reflect.runtime.universe.Tree = new com.sparkbeyond.runtime.util.misc.ValuesMap(SpecialAction.myMap) scala> tb.eval(tb.untypecheck(tree)) res15: Any = ValuesMap(Map(mul2 -> SpecialParam(1,<function1>), add1 -> SpecialParam(2,<function1>), ident -> SpecialParam(3,<function1>)))
  • 24. Overcoming Erasure - RTTI ● Java Generics for better or worse get erased in runtime ● We would like to be able to tell the Type of an instance including Type Parameters ● In most cases this is possible in a meaningful way.
  • 25. What is my type? case class OneIntSeq(a: Int) extends Seq[Int] {...} case class MyCaseClass[T,U](e: T,o: Seq[U]) val v = MyCaseClass("foo",OneIntSeq(1)) We want a method, given v to produce: MyCaseClass[String,Int]
  • 26. val topType=cm.reflect(v).symbol.toTypeConstructor topType: reflect.runtime.universe.Type = MyCaseClass //As Before val primaryParams = topType.typeSymbol.asClass.primaryConstructor... primaryParams: List[reflect.runtime.universe.Symbol] = List(value elem, value other) primaryParams.map(_.typeSignature) res29: List[reflect.runtime.universe.Type] = List(T, scala.Seq[U])
  • 27. Inspecting the Type topType.decls.foreach{case s => println(s.toString + "t" + s.typeSignature) } value elem => T value elem T value other => scala.Seq[U] value other scala.Seq[U] constructor MyCaseClass (elem: T, other: scala.Seq[U])MyCaseClass[T,U] method copy [T, U](elem: T, other: scala.Seq[U])MyCaseClass[T,U] method copy$default$1 [T, U]=> T @scala.annotation.unchecked.uncheckedVariance method copy$default$2 [T, U]=> scala.Seq[U] @scala.annotation.unchecked.uncheckedVariance method productPrefix => java.lang.String method productArity => scala.Int method productElement (x$1: scala.Int)scala.Any method productIterator => Iterator[scala.Any] method canEqual (x$1: scala.Any)scala.Boolean method hashCode ()scala.Int method toString ()java.lang.String method equals (x$1: scala.Any)scala.Boolean
  • 28. val instanceMirror = cm.reflect(v) instanceMirror: reflect.runtime.universe.InstanceMirror = instance mirror for MyCaseClass(foo,(1)) val elemField=topType.decls.filterNot(x => x.isMethod).head elemField: reflect.runtime.universe.Symbol = value elem val elemValue=instanceMirror.reflectField(elemField.asTerm).get elemValue: Any = foo val elemTyp=cm.reflect(elemValue).symbol.toTypeConstructor elemTyp: reflect.runtime.universe.Type = java.lang.String
  • 29. Similarly for second param other: Seq[U] val otherTyp= cm.reflect(otherValue).symbol.toTypeConstructor otherTyp: reflect.runtime.universe.Type = OneIntSeq val asBase=otherTyp.baseType(otherField.typeSignature.typeSymbol) asBase: reflect.runtime.universe.Type = Seq[scala.Int] val uType = asBase.typeArgs.head uType: reflect.runtime.universe.Type = scala.Int
  • 30. Combining Things together val finalType=appliedType(topType,List(elemTyp,uType)) finalType: reflect.runtime.universe.Type = MyCaseClass[java.lang.String,scala.Int] Q.E.D
  • 31. Final Thoughts Questions? Like pushing Scala to it’s limits? Thrive on scalable computing with machine learning on top? Join us!