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

Eugenio Marletti

March 15, 2018
Tweet

More Decks by Eugenio Marletti

Other Decks in Technology

Transcript

  1. @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) }
  2. @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) }
  3. @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) }
  4. @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) }
  5. @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) }
  6. @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) }
  7. @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) }
  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) { !" ✅ niceFun(Name(myName), Age(myAge)) }
  9. class BoringClass { fun washDishes() = "maybe later" } fun

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

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

    usage() { !" ❌ Unresolved reference: BoringClass BoringClass().washDishes() }
  12. @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() }
  13. @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() }
  14. package first fun topLevelFunction(i: Int) = i fun topLevelFunction(s: String)

    = s ----------------------------------- package second import first.topLevelFunction
  15. 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
  16. 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
  17. 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
  18. fun oppaFunctionalStyle(list: List<String>) = list.map { it.toCharArray().map { if (it.isDigit())

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

    if (it.isDigit()) return@listMap CharArray(0) !" that map! & else it.toUpperCase() } }
  20. fun printEverything(vararg args: String) { println(args) } fun usage( singleString:

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

    String, anotherSingleString: String, stringArray: Array<String>, anotherStringArray: Array<String>) { printEverything( singleString, *stringArray, anotherSingleString, *anotherStringArray) }
  22. fun veryDescriptiveFun( arg1: String, arg2: Int = arg1.length, arg3: Int

    = arg2, arg4: Boolean = loadEntireDbInMemory()!#isEmpty() !& areYouSure() ) = "oh no"
  23. 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()) }
  24. 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()) }
  25. 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()) }
  26. 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()) }
  27. void !' Unit “In type theory, a unit type is

    a type that allows only one value.”
  28. Void !' Nothing “In type theory, the bottom type is

    the type that has no values.” bottom zero empty
  29. fun inifinite() { while (true) { !" nap } }

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

    } fun naive() { inifinite() !" ⚠ Unreachable code println("I've achieved all my hopes and dreams!") }
  31. 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 }
  32. 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) }
  33. 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) }
  34. 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) }
  35. 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()
  36. 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()
  37. 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()
  38. 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)
  39. 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)
  40. 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)
  41. 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)
  42. Kotlin tools team lead @ JetBrains co-author of “Kotlin in

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

    co-author of “Kotlin in Action” @intelliyole on Twitter “Dmitry Jemerov” in “real life” yole