Share
Embed
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
Transcript
81 slides
-
@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) } -
@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) } -
@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) } -
@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) } -
@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) } -
@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) } -
@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) } -
@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)) } -
class BoringClass { fun washDishes() = "maybe later" } fun
usage() { BoringClass().washDishes() } -
class ExcitingClass { fun washDishes() = "maybe later" } fun
usage() { BoringClass().washDishes() } -
class ExcitingClass { fun washDishes() = "maybe later" } fun
usage() { !" ❌ Unresolved reference: BoringClass BoringClass().washDishes() } -
@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() } -
@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() } -
package first fun topLevelFunction(i: Int) = i fun topLevelFunction(s: String)
= s ----------------------------------- package second import first.topLevelFunction -
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 -
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 -
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 -
fun oppaFunctionalStyle(list: List<String>) = list.map { it.toCharArray().map { if (it.isDigit())
return@map CharArray(0) !" which map? % else it.toUpperCase() } } -
fun oppaFunctionalStyle(list: List<String>) = list.map listMap@ { it.toCharArray().map charMap@ {
if (it.isDigit()) return@listMap CharArray(0) !" that map! & else it.toUpperCase() } } -
fun printEverything(vararg args: String) { println(args) } fun usage(stringArray: Array<String>)
{ printEverything(*stringArray) } -
fun printEverything(vararg args: String) { println(args) } fun usage( singleString:
String, anotherSingleString: String, stringArray: Array<String>, anotherStringArray: Array<String>) { printEverything(*stringArray) } -
fun printEverything(vararg args: String) { println(args) } fun usage( singleString:
String, anotherSingleString: String, stringArray: Array<String>, anotherStringArray: Array<String>) { printEverything( singleString, *stringArray, anotherSingleString, *anotherStringArray) } -
fun veryDescriptiveFun( arg1: String, arg2: Int = arg1.length, arg3: Int
= arg2, arg4: Boolean ) = "cool" -
fun veryDescriptiveFun( arg1: String, arg2: Int = arg1.length, arg3: Int
= arg2, arg4: Boolean = loadEntireDbInMemory()!#isEmpty() !& areYouSure() ) = "oh no" -
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()) } -
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()) } -
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()) } -
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()) } -
void !' Unit “In type theory, a unit type is
a type that allows only one value.” -
Void !' Nothing “In type theory, the bottom type is
the type that has no values.” bottom zero empty -
fun inifinite() { while (true) { !" nap } }
fun naive() { inifinite() !" always believe in yourself!⚠ println("I've achieved all my hopes and dreams!") } -
fun inifinite(): Nothing { while (true) { !" nap }
} fun naive() { inifinite() !" ⚠ Unreachable code println("I've achieved all my hopes and dreams!") } -
fun fiveMoreMinutesPlease(): VeryComplexType = TODO() fun TODO(): Nothing = throw
NotImplementedError() -
data class Person( val name: String, val age: Int, val
likesDataClasses: Boolean) -
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 } -
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) } -
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) } -
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) } -
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() -
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() -
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() -
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) -
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) -
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) -
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) -
Kotlin tools team lead @ JetBrains co-author of “Kotlin in
Action” @intelliyole on Twitter “Dmitry Jemerov” in “real life” yole -
“ ” “ ” Kotlin tools team lead @ JetBrains
co-author of “Kotlin in Action” @intelliyole on Twitter “Dmitry Jemerov” in “real life” yole