Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Kotlin’s Mind Blowers

Kotlin’s Mind Blowers

A curated collection of authentic “ohhhhh”, “can’t believe it works”, and “WAIT YOU CAN DO THAT” experiences, evoked by some of the most disruptive properties of the Kotlin language, slowly refined through an artisanal all-natural process. [ gluten free / may contain traces of nuts ]

Presented at Kotlin Night Berlin 2018
https://www.meetup.com/kotlin-berlin/events/247865835/

--> Second part: https://bit.ly/kotlin-mind-blowers2

Fde10bcf0813b2162545477be4e7470b?s=128

Eugenio Marletti

March 15, 2018
Tweet

Transcript

  1. Kotlin’s Mind Blowers Eugenio Marletti @workingkills

  2. None
  3. None
  4. @Deprecated("Just don't.") fun deprecatedFun(age: Int, name: String) { !" nasty

    stuff } data class Name(val name: String) data class Age(val age: Int) fun niceFun(name: Name, age: Age) { !" good stuff } fun usage(myName: String, myAge: Int) { !" ⚠ 'deprecatedFun(Int, String): Unit' is deprecated. Just Don't. deprecatedFun(myAge, myName) }
  5. @Deprecated("Just don't.", level = DeprecationLevel.WARNING) fun deprecatedFun(age: Int, name: String)

    { !" nasty stuff } data class Name(val name: String) data class Age(val age: Int) fun niceFun(name: Name, age: Age) { !" good stuff } fun usage(myName: String, myAge: Int) { !" ⚠ 'deprecatedFun(Int, String): Unit' is deprecated. Just Don't. deprecatedFun(myAge, myName) }
  6. @Deprecated("Just don't.", level = DeprecationLevel.ERROR) fun deprecatedFun(age: Int, name: String)

    { !" nasty stuff } data class Name(val name: String) data class Age(val age: Int) fun niceFun(name: Name, age: Age) { !" good stuff } fun usage(myName: String, myAge: Int) { !" ❌ Using 'deprecatedFun(Int, String): Unit' is an error. Just Don't. deprecatedFun(myAge, myName) }
  7. @Deprecated("Just don't.", level = DeprecationLevel.HIDDEN) fun deprecatedFun(age: Int, name: String)

    { !" nasty stuff } data class Name(val name: String) data class Age(val age: Int) fun niceFun(name: Name, age: Age) { !" good stuff } fun usage(myName: String, myAge: Int) { !" ❌ Unresolved reference: deprecatedFun deprecatedFun(myAge, myName) }
  8. @Deprecated("Just don't.", ReplaceWith("niceFun(Name(name), Age(age))")) fun deprecatedFun(age: Int, name: String) {

    !" nasty stuff } data class Name(val name: String) data class Age(val age: Int) fun niceFun(name: Name, age: Age) { !" good stuff } fun usage(myName: String, myAge: Int) { !" # deprecatedFun(myAge, myName) }
  9. @Deprecated("Just don't.", ReplaceWith("niceFun(Name(name), Age(age))")) fun deprecatedFun(age: Int, name: String) {

    !" nasty stuff } data class Name(val name: String) data class Age(val age: Int) fun niceFun(name: Name, age: Age) { !" good stuff } fun usage(myName: String, myAge: Int) { !" # deprecatedFun(myAge, myName) }
  10. @Deprecated("Just don't.", ReplaceWith("niceFun(Name(name), Age(age))")) fun deprecatedFun(age: Int, name: String) {

    !" nasty stuff } data class Name(val name: String) data class Age(val age: Int) fun niceFun(name: Name, age: Age) { !" good stuff } fun usage(myName: String, myAge: Int) { !" # deprecatedFun(myAge, myName) }
  11. @Deprecated("Just don't.", ReplaceWith("niceFun(Name(name), Age(age))")) fun deprecatedFun(age: Int, name: String) {

    !" nasty stuff } data class Name(val name: String) data class Age(val age: Int) fun niceFun(name: Name, age: Age) { !" good stuff } fun usage(myName: String, myAge: Int) { !" ✅ niceFun(Name(myName), Age(myAge)) }
  12. typealias TotallyNotThatClass = ThatClass

  13. typealias AbsSubject<T> = Subject<T, T>

  14. class BoringClass { fun washDishes() = "maybe later" } fun

    usage() { BoringClass().washDishes() }
  15. class ExcitingClass { fun washDishes() = "maybe later" } fun

    usage() { BoringClass().washDishes() }
  16. class ExcitingClass { fun washDishes() = "maybe later" } fun

    usage() { !" ❌ Unresolved reference: BoringClass BoringClass().washDishes() }
  17. @Deprecated("Stop being boring.") typealias BoringClass = ExcitingClass class ExcitingClass {

    fun washDishes() = "maybe later" } fun usage() { !" ⚠ 'typealias BoringClass = ExcitingClass' is deprecated. !" Stop being boring. BoringClass().washDishes() }
  18. @Deprecated("Stop being boring.", ReplaceWith("ExcitingClass")) typealias BoringClass = ExcitingClass class ExcitingClass

    { fun washDishes() = "maybe later" } fun usage() { !" ⚠ 'typealias BoringClass = ExcitingClass' is deprecated. !" Stop being boring. BoringClass().washDishes() }
  19. package first fun topLevelFunction(i: Int) = i fun topLevelFunction(s: String)

    = s
  20. package first fun topLevelFunction(i: Int) = i fun topLevelFunction(s: String)

    = s ----------------------------------- package second import first.topLevelFunction
  21. package my.package data class ColorInt(val color: Int)

  22. package my.package import android.support.annotation.ColorInt data class ColorInt(@ColorInt val color: Int)

  23. package my.package import android.support.annotation.ColorInt data class ColorInt(@ColorInt val color: Int)

    --------------------------------------------- package not.my.package !" ❌ Conflicting import, imported name 'ColorInt' is ambiguous import android.support.annotation.ColorInt import my.package.ColorInt
  24. package my.package import android.support.annotation.ColorInt data class ColorInt(@ColorInt val color: Int)

    --------------------------------------------- package not.my.package !" ✅ import android.support.annotation.ColorInt as ColorIntAnnotation import my.package.ColorInt
  25. package my.package import android.support.annotation.ColorInt data class ColorInt(@ColorInt val color: Int)

    --------------------------------------------- package not.my.package !" ✅ import android.support.annotation.ColorInt as ColorIntAnnotationDuplicate import android.support.annotation.ColorInt as ColorIntAnnotation import my.package.ColorInt
  26. fun oppaFunctionalStyle(list: List<String>) = list.map { it.toCharArray().map { if (it.isDigit())

    return@map CharArray(0) !" which map? % else it.toUpperCase() } }
  27. fun oppaFunctionalStyle(list: List<String>) = list.map listMap@ { it.toCharArray().map charMap@ {

    if (it.isDigit()) return@listMap CharArray(0) !" that map! & else it.toUpperCase() } }
  28. fun stringLengthOrNull(maybeString: Any?) = if (maybeString is String) maybeString.length else

    null
  29. fun stringLengthOrNull(maybeString: Any?) = (maybeString as? String)!#length

  30. fun printEverything(vararg args: String) { println(args) } fun usage(stringArray: Array<String>)

    { printEverything(*stringArray) }
  31. fun printEverything(vararg args: String) { println(args) } fun usage( singleString:

    String, anotherSingleString: String, stringArray: Array<String>, anotherStringArray: Array<String>) { printEverything(*stringArray) }
  32. fun printEverything(vararg args: String) { println(args) } fun usage( singleString:

    String, anotherSingleString: String, stringArray: Array<String>, anotherStringArray: Array<String>) { printEverything( singleString, *stringArray, anotherSingleString, *anotherStringArray) }
  33. fun veryDescriptiveFun( arg1: String, arg2: Int, arg3: Int, arg4: Boolean

    ) = "meh"
  34. fun veryDescriptiveFun( arg1: String, arg2: Int = arg1.length, arg3: Int

    = arg2, arg4: Boolean ) = "cool"
  35. fun veryDescriptiveFun( arg1: String, arg2: Int = arg1.length, arg3: Int

    = arg2, arg4: Boolean = loadEntireDbInMemory()!#isEmpty() !& areYouSure() ) = "oh no"
  36. fun iterate(iterable: Iterable<String>) { iterable .onEach { println(it) } .map

    { it.length } .forEach { println(it) } } fun sequentiate(sequence: Sequence<String>) { sequence .onEach { println(it) } .map { it.length } .forEach { println(it) } } fun usage() { val strings = listOf("a", "bb", "ccc") iterate(strings.asIterable()) sequentiate(strings.asSequence()) }
  37. fun iterate(iterable: Iterable<String>) { !" iterable !" .onEach { println(it)

    } !" .map { it.length } !" .forEach { println(it) } !" } !" fun sequentiate(sequence: Sequence<String>) { !" sequence !" .onEach { println(it) } !" .map { it.length } !" .forEach { println(it) } !" } !" fun usage() { val strings = listOf("a", "bb", "ccc") iterate(strings.asIterable()) sequentiate(strings.asSequence()) }
  38. fun iterate(iterable: Iterable<String>) { !" a iterable !" bb .onEach

    { println(it) } !" ccc .map { it.length } !" 1 .forEach { println(it) } !" 2 } !" 3 fun sequentiate(sequence: Sequence<String>) { !" sequence !" .onEach { println(it) } !" .map { it.length } !" .forEach { println(it) } !" } !" fun usage() { val strings = listOf("a", "bb", "ccc") iterate(strings.asIterable()) sequentiate(strings.asSequence()) }
  39. fun iterate(iterable: Iterable<String>) { !" a iterable !" bb .onEach

    { println(it) } !" ccc .map { it.length } !" 1 .forEach { println(it) } !" 2 } !" 3 fun sequentiate(sequence: Sequence<String>) { !" a sequence !" 1 .onEach { println(it) } !" bb .map { it.length } !" 2 .forEach { println(it) } !" ccc } !" 3 fun usage() { val strings = listOf("a", "bb", "ccc") iterate(strings.asIterable()) sequentiate(strings.asSequence()) }
  40. void

  41. void !" not a type

  42. void !' Unit

  43. void !' Unit “In type theory, a unit type is

    a type that allows only one value.”
  44. void !' Unit !" single instance

  45. fun unity() { }

  46. fun unity(): Unit { }

  47. fun unity() = Unit

  48. fun unity() = println("sweet")

  49. fun unity() = java.lang.System.out.println("sweet")

  50. Void

  51. Void !" a type that can’t be instantiated

  52. Void !' Nothing

  53. Void !' Nothing “In type theory, the bottom type is

    the type that has no values.” bottom zero empty
  54. Void !' Nothing !" a type that can’t be instantiated

    (same!)
  55. Void !' Nothing?

  56. fun foreverNull(): Nothing? = null

  57. fun inifinite() { while (true) { !" nap } }

    fun naive() { inifinite() !" always believe in yourself!⚠ println("I've achieved all my hopes and dreams!") }
  58. fun inifinite(): Nothing { while (true) { !" nap }

    } fun naive() { inifinite() !" ⚠ Unreachable code println("I've achieved all my hopes and dreams!") }
  59. fun fiveMoreMinutesPlease(): VeryComplexType

  60. fun fiveMoreMinutesPlease(): VeryComplexType = TODO()

  61. fun fiveMoreMinutesPlease(): VeryComplexType = TODO() fun TODO(): Nothing = throw

    NotImplementedError()
  62. data class Person( val name: String, val age: Int, val

    likesDataClasses: Boolean)
  63. data class Person( val name: String, val age: Int, val

    likesDataClasses: Boolean) fun parsePerson(map: Map<Any?, Any?>): Person? { val name = map["name"] if (name is String) { val age = map["age"] if (age is Int) { val likesDataClasses = map["likes-data-classes"] if (likesDataClasses is Boolean) { return Person( name, age, likesDataClasses) } } } return null }
  64. data class Person( val name: String, val age: Int, val

    likesDataClasses: Boolean) fun parsePerson(map: Map<Any?, Any?>): Person? { val name = map["name"] if (name !is String) return null val age = map["age"] if (age !is Int) return null val likesDataClasses = map["likes-data-classes"] if (likesDataClasses !is Boolean) return null return Person( name, age, likesDataClasses) }
  65. data class Person( val name: String, val age: Int, val

    likesDataClasses: Boolean) fun parsePerson(map: Map<Any?, Any?>): Person? { val name = map["name"] as? String !& return null val age = map["age"] as? Int !& return null val likesDataClasses = map["likes-data-classes"] as? Boolean !& return null return Person( name, age, likesDataClasses) }
  66. data class Person( val name: String, val age: Int, val

    likesDataClasses: Boolean) fun parsePerson(map: Map<Any?, Any?>): Person? { return Person( map["name"] as? String !& return null, map["age"] as? Int !& return null, map["likes-data-classes"] as? Boolean !& return null) }
  67. !" Elvis operator !&

  68. !& "hey"

  69. a += b a.plusAssign(b) a -= b a.minusAssign(b) a!* a.inc()

    a!, a.dec() a + b a.plus(b) a - b a.minus(b) a * b a.times(b) a / b a.div(b) a % b a.rem(b) a!-b a.rangeTo(b) +a a.unaryPlus() -a a.unaryMinus() !a a.not()
  70. a[i] a.get(i) a[i_1, !!., i_n] a.get(i_1, !!., i_n) a +=

    b a.plusAssign(b) a -= b a.minusAssign(b) a *= b a.timesAssign(b) a !/ b a.divAssign(b) a %= b a.remAssign(b) a!* a.inc() a!, a.dec() a + b a.plus(b) a - b a.minus(b) a * b a.times(b) a / b a.div(b) a % b a.rem(b) a!-b a.rangeTo(b) +a a.unaryPlus() -a a.unaryMinus() !a a.not()
  71. a > b a.compareTo(b) > 0 a < b a.compareTo(b)

    < 0 a !0 b a.compareTo(b) !0 0 a !1 b a.compareTo(b) !1 0 a[i] a.get(i) a[i_1, !!., i_n] a.get(i_1, !!., i_n) a[i] = b a.set(i, b) a[i_1, !!., i_n] = b a.set(i_1, !!., i_n, b) a += b a.plusAssign(b) a -= b a.minusAssign(b) a *= b a.timesAssign(b) a !/ b a.divAssign(b) a %= b a.remAssign(b) a!* a.inc() a!, a.dec() a + b a.plus(b) a - b a.minus(b) a * b a.times(b) a / b a.div(b) a % b a.rem(b) a!-b a.rangeTo(b) !a a.not()
  72. a() a.invoke() a(i) a.invoke(i) a in b b.contains(a) a !in

    b !b.contains(a) a > b a.compareTo(b) > 0 a < b a.compareTo(b) < 0 a !0 b a.compareTo(b) !0 0 a !1 b a.compareTo(b) !1 0 a[i] a.get(i) a[i_1, !!., i_n] a.get(i_1, !!., i_n) a[i] = b a.set(i, b) a[i_1, !!., i_n] = b a.set(i_1, !!., i_n, b) a += b a.plusAssign(b) a -= b a.minusAssign(b) a *= b a.timesAssign(b) a !/ b a.divAssign(b) a %= b a.remAssign(b) a - b a.minus(b) a * b a.times(b) a / b a.div(b) a % b a.rem(b) a!-b a.rangeTo(b)
  73. a() a.invoke() a(i) a.invoke(i) a(i_1, !!., i_n) a.invoke(i_1, !!., i_n)

    a in b b.contains(a) a !in b !b.contains(a) a > b a.compareTo(b) > 0 a < b a.compareTo(b) < 0 a !0 b a.compareTo(b) !0 0 a !1 b a.compareTo(b) !1 0 a[i] a.get(i) a[i_1, !!., i_n] a.get(i_1, !!., i_n) a[i] = b a.set(i, b) a[i_1, !!., i_n] = b a.set(i_1, !!., i_n, b) a += b a.plusAssign(b) a -= b a.minusAssign(b) a *= b a.timesAssign(b) a !/ b a.divAssign(b) a %= b a.remAssign(b)
  74. a() a.invoke() a(i) a.invoke(i) a(i_1, !!., i_n) a.invoke(i_1, !!., i_n)

    a in b b.contains(a) a !in b !b.contains(a) a > b a.compareTo(b) > 0 a < b a.compareTo(b) < 0 a !0 b a.compareTo(b) !0 0 a !1 b a.compareTo(b) !1 0 a[i] a.get(i) a[i_1, !!., i_n] a.get(i_1, !!., i_n) a[i] = b a.set(i, b) a[i_1, !!., i_n] = b a.set(i_1, !!., i_n, b) a %= b a.remAssign(b)
  75. a() a.invoke() a(i) a.invoke(i) a(i_1, !!., i_n) a.invoke(i_1, !!., i_n)

    a in b b.contains(a) a !in b !b.contains(a) a > b a.compareTo(b) > 0 a < b a.compareTo(b) < 0 a !0 b a.compareTo(b) !0 0 a !1 b a.compareTo(b) !1 0 a[i_1, !!., i_n] a.get(i_1, !!., i_n) a[i] = b a.set(i, b) a[i_1, !!., i_n] = b a.set(i_1, !!., i_n, b)
  76. getValue, setValue, provideDelegate val someValue by lazy { "don't judge

    me" }
  77. None
  78. None
  79. Kotlin tools team lead @ JetBrains co-author of “Kotlin in

    Action” @intelliyole on Twitter “Dmitry Jemerov” in “real life” yole
  80. “ ” “ ” Kotlin tools team lead @ JetBrains

    co-author of “Kotlin in Action” @intelliyole on Twitter “Dmitry Jemerov” in “real life” yole
  81. bit.ly/kotlin-mind-blowers Eugenio Marletti @workingkills