Kotlin gets Reflection

2,748 views
2,451 views

Published on

Presented at JVM Language Summit, 2013

Published in: Technology, Education
0 Comments
1 Like
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total views
2,748
On SlideShare
0
From Embeds
0
Number of Embeds
33
Actions
Shares
0
Downloads
0
Comments
0
Likes
1
Embeds 0
No embeds

No notes for slide

Kotlin gets Reflection

  1. 1. KOTLIN GETS REFLECTION Andrey.Breslav@JetBrains.com
  2. 2. Introspection is examination of one's own conscious thoughts and feelings. Schultz, D. P.; Schultz, S. E. (2012). A history of modern psychology (10th ed.)
  3. 3. LEGAL Takeiteasy
  4. 4. DON’T JUDGE STRICTLY
  5. 5. OUTLINE • Intro • Ways of Introspection • Reflection API • Reflection Literals • Expression Trees • Conclusion
  6. 6. USE CASES Dependency Injection Data binding Convention over configuration Hacks Workarounds Black Magic
  7. 7. INTROSPECTION Instances - what is your class? Classes & Types - what are your members? supertypes? create an instance Methods/Fields - what are your parameters/types/etc? run with these args. Expressions - ???
  8. 8. JAVA.LANG.REFLECT? Top-level functions Default arguments Properties Nullable types Special types (Nothing, (Mutable)List, etc) … + modules (classes in a package)
  9. 9. METADATA *.kt *.class (kotlin) *.jar (kotlin) kotlin symbols kotlin symbols kotlin symbols java symbols kotlinc
  10. 10. HOW TO STORE METADATA? *.class Custom attributes Annotations Annotate each symbol One big annotation
  11. 11. ONE BIG ANNOTATION *.class @KotlinClass(“data”) val/var types defaults … Java definitions erased generic annotations …
  12. 12. RE-USE j.l.Class *.kt *.class AST @KotlinClass Symbols
  13. 13. DISCREPANCY 1 java.lang.annotation.Annotation vs org.jetbrains.kotlin.internal….AnnotationDescriptor
  14. 14. PURE JAVA CLASSES? j.l.Class *.kt *.class AST @KotlinClass Symbols *.java java2k
  15. 15. DISCREPANCY 2 // Java class Foo { @NotNull String getFirstName() { … } String getMiddleName() { … } } // Corresponding Kotlin class Foo { fun getFirstName(): String fun getMiddleName(): String? }
  16. 16. DISCREPANCY 2 j.l.Class *.class Symbols *.java java2k annotations.xml
  17. 17. SUMMARY 1 Kotlin-specific reflection API - works for Java as well Metadata representation - one big annotation - re-use code from the compiler Problems - representing annotations - nullable/mutable types
  18. 18. ENTRY POINTS
  19. 19. SYNTAX (TENTATIVE) Foo::class expr::class List<String>::member org.sample.bar::member expr::member expr::type (maybe)
  20. 20. USE CASES: PASSING CODE AROUND list.filter(Item::isValid) * Why not a lambda? foo {a, b, c -> bar(a, b, c) }
  21. 21. USE CASES: CONSTRUCTORS fun <T: Tag> tag( create: () -> T, init: T.() -> Unit ) { … } tag(::DIV) { // kara.tags::DIV … }
  22. 22. USE CASES: DATA BINDING class Model { var userName: String by observable() } bind(view.textField, model::userName)
  23. 23. GENERICS? fun foo(s: String): Foo ::foo : (String) -> Foo fun <T> foo(t: T): T { … } ::foo : ∀T.(T) -> T
  24. 24. RANK-2 POLYMORPHISM interface Function1<P1, R> { R invoke(P1 p1); } vs interface GenericFunction1_1<P1, R> { <T> R<T> invoke(P1<T> p1); }
  25. 25. ENCODING FOR FUNCTIONS f: (Foo) -> Bar is Function1<Foo, Bar> interface Function1<P1, R> { R invoke(P1 p1); }
  26. 26. GENERIC FUNCTIONS f: <T>(List<T>) -> T • GenericFunction<List<T>, T> ??? • GenericFunction<T, List<T>, T> ??? interface GenericFunction1_1<P1, R> { <T> R<T> invoke(P1<T> p1); } + Kinds
  27. 27. GENERICS class Foo<T> { fun <R> bar(t: T): R { … } } Foo<T’>::bar<R’> : (T’) -> R’
  28. 28. EXPR::TYPE val x: Any = listOf(1, 2, 3) x::class -> java.util.ArrayList x::type -> java.util.ArrayList<Unknown> vs val x = listOf(1, 2, 3) // x: List<Int> x::class -> java.util.ArrayList x::type -> java.util.ArrayList<Int>
  29. 29. DELEGATED PROPERTIES val foos: List<Foo> by Lazy { foos.find(…) } class Lazy<T>(compute: () -> T) { private var value: T? = null fun get(me: Any, p: PropertyMetadata): T { if (value == null) value = compute() return value } }
  30. 30. DELEGATED PROPERTIES val foos: List<Foo> by Lazy { foos.find(…) } ::foos::delegate : Lazy<Foo> ::foos : Property<List<Foo>> or ::foos.delegate : Lazy<Foo> ::foos : DelegatedProperty< List<Foo>, Lazy<Foo> >
  31. 31. SUMMARY 2 Reflection literals - Static name lookup & typing - Generics are hard, as usual
  32. 32. CODE INTROSPECTION I told you!
  33. 33. USE CASES: LINQ db .selectFrom(::User) .where { lastName.startsWith(“A”) } .orderBy { lastName + firstName }
  34. 34. server client server USE CASES: WEB html { body { onLoad { ... } ... } }
  35. 35. EXPRESSION TREES fun onLoad(ast: Expression<() -> Unit>) { ... } onLoad { ... // compiled to factory calls } At run time the tree can be translated to JS
  36. 36. SUMMARY Kotlin’s introspection facilities - Reflection API - Java interop is the hardest issue - Reflection literals - Issues with generics - Expression trees - Compiler as a service

×