Slide 1

Slide 1 text

Kotlin’s Advanced Language Features

Slide 2

Slide 2 text

High Order Function's Extension

Slide 3

Slide 3 text

fun String.blowUp() { boom() } "Nooooo".blowUp()

Slide 4

Slide 4 text

fun buildString( builderAction: (StringBuilder) -> Unit ): String {a }b fun main(args: Array) {c }e

Slide 5

Slide 5 text

fun buildString( builderAction: (StringBuilder) -> Unit ): String {a val sb = StringBuilder() builderAction(sb) return sb.toString() }b fun main(args: Array) {c }e

Slide 6

Slide 6 text

fun buildString( builderAction: (StringBuilder) -> Unit ): String {a val sb = StringBuilder() builderAction(sb) return sb.toString() }b fun main(args: Array) {c val s = buildString({ stringBuilder -> stringBuilder.append("Hello, ") stringBuilder.append("World!") })d }e

Slide 7

Slide 7 text

fun buildString( builderAction: (StringBuilder) -> Unit ): String {a val sb = StringBuilder() builderAction(sb) return sb.toString() }b fun main(args: Array) {c val s = buildString { stringBuilder -> stringBuilder.append("Hello, ") stringBuilder.append("World!") }d }e

Slide 8

Slide 8 text

fun buildString( builderAction: (StringBuilder) -> Unit ): String {a val sb = StringBuilder() builderAction(sb) return sb.toString() }b fun main(args: Array) {c val s = buildString { it.append("Hello, ") it.append("World!") }d }e

Slide 9

Slide 9 text

fun buildString( builderAction: (StringBuilder) -> Unit ): String {a val sb = StringBuilder() builderAction(sb) return sb.toString() }b fun main(args: Array) {c val s = buildString { append("Hello, ") append("World!") }d }e

Slide 10

Slide 10 text

fun buildString( builderAction: StringBuilder.() -> Unit ): String {a val sb = StringBuilder() builderAction(sb) return sb.toString() }b fun main(args: Array) {c val s = buildString { append("Hello, ") append("World!") }d }e

Slide 11

Slide 11 text

fun buildString( builderAction: StringBuilder.() -> Unit ): String {a val sb = StringBuilder() sb.builderAction() return sb.toString() }b fun main(args: Array) {c val s = buildString { append("Hello, ") append("World!") }d }e

Slide 12

Slide 12 text

fun buildString( builderAction: StringBuilder.() -> Unit ): String {a val sb = StringBuilder() sb.builderAction() return sb.toString() }b fun main(args: Array) {c val s = buildString { append("Hello, ") append("World!") }d }e

Slide 13

Slide 13 text

fun buildString( builderAction: StringBuilder.() -> Unit ): String {a val sb = StringBuilder() sb.builderAction() return sb.toString() }b fun main(args: Array) {c val s = buildString { this.append("Hello, ") append("World!") }d }e

Slide 14

Slide 14 text

No content

Slide 15

Slide 15 text

val taco = Taco() with(taco) { println(name) println(tasty) }

Slide 16

Slide 16 text

fun with( receiver: T, block: T.() -> R ): R { return receiver.block() }

Slide 17

Slide 17 text

When do we seal the casting?

Slide 18

Slide 18 text

interface BinaryNumber object Zero : BinaryNumber object One : BinaryNumber

Slide 19

Slide 19 text

interface BinaryNumber object Zero : BinaryNumber object One : BinaryNumber fun BinaryNumber.toInt():Int {a return when (this) {b is One -> 1 is Zero -> 0 else -> throw IllegalStateException() }c }d

Slide 20

Slide 20 text

interface BinaryNumber object Zero : BinaryNumber object One : BinaryNumber fun BinaryNumber.toInt():Int {a return when (this) {b is One -> 1 is Zero -> 0 }c }d

Slide 21

Slide 21 text

interface BinaryNumber object Zero : BinaryNumber object One : BinaryNumber fun BinaryNumber.toInt():Int {a return when (this) {b is One -> 1 is Zero -> 0 else -> throw IllegalStateException() }c }d

Slide 22

Slide 22 text

interface BinaryNumber object Zero : BinaryNumber object One : BinaryNumber class Magic() : BinaryNumber() { fun abracadabra() { // ... } } fun BinaryNumber.toInt():Int {a return when (this) {b is One -> 1 is Zero -> 0 else -> throw IllegalStateException() }c }d

Slide 23

Slide 23 text

interface BinaryNumber object Zero : BinaryNumber object One : BinaryNumber fun BinaryNumber.toInt():Int {a return when (this) {b is One -> 1 is Zero -> 0 else -> throw IllegalStateException() }c }d

Slide 24

Slide 24 text

sealed class BinaryNumber object Zero : BinaryNumber() object One : BinaryNumber() fun BinaryNumber.toInt():Int {a return when (this) {b is One -> 1 is Zero -> 0 else -> throw IllegalStateException() }c }d

Slide 25

Slide 25 text

sealed class BinaryNumber object Zero : BinaryNumber() object One : BinaryNumber() fun BinaryNumber.toInt():Int {a return when (this) {b is One -> 1 is Zero -> 0 }c }d

Slide 26

Slide 26 text

sealed class BinaryNumber object Zero : BinaryNumber() object One : BinaryNumber() class Magic() : BinaryNumber() {z fun abracadabra() {w // ... }t }r fun BinaryNumber.toInt():Int {a return when (this) {b is One -> 1 is Zero -> 0 }c }d

Slide 27

Slide 27 text

sealed class BinaryNumber object Zero : BinaryNumber() object One : BinaryNumber() class Magic() : BinaryNumber() {z fun abracadabra() {w // ... }t }r fun BinaryNumber.toInt():Int {a return when (this) {b is One -> 1 is Zero -> 0 }c }d

Slide 28

Slide 28 text

sealed class BinaryNumber object Zero : BinaryNumber() object One : BinaryNumber() class Magic() : BinaryNumber() {z fun abracadabra() {w // ... }t }r fun BinaryNumber.toInt():Int {a return when (this) {b is One -> 1 is Zero -> 0 is Magic -> this.abracadabra() }c }d

Slide 29

Slide 29 text

sealed class BinaryNumber object Zero : BinaryNumber() object One : BinaryNumber() class Magic() : BinaryNumber() { fun abracadabra() { // ... } } fun BinaryNumber.toInt():Int {a return when (this) {b is One -> 1 is Zero -> 0 is Magic -> this.abracadabra() }c }d

Slide 30

Slide 30 text

No content

Slide 31

Slide 31 text

fun requireNotNull(obj: Any?) {a if (obj == null) throw IllegalArgumentException() }d

Slide 32

Slide 32 text

fun requireNotNull(obj: Any?) {a if (obj == null) throw IllegalArgumentException() }d fun foo(s: String?) {e requireNotNull(s) s.length }f

Slide 33

Slide 33 text

fun requireNotNull(obj: Any?) {a contract { returns() implies (obj != null) }c if (obj == null) throw IllegalArgumentException() }d fun foo(s: String?) {e requireNotNull(s) s.length }f

Slide 34

Slide 34 text

No content

Slide 35

Slide 35 text

Error is Ever the Sequence of Haste

Slide 36

Slide 36 text

people // List

Slide 37

Slide 37 text

people // List .map(People::name) .filter { it.startsWith("J") }

Slide 38

Slide 38 text

people // List .map(People::name) // List .filter { it.startsWith("J") } // List

Slide 39

Slide 39 text

people // List .asSequence() .map(People::name) .filter { it.startsWith("J") }

Slide 40

Slide 40 text

people // List .asSequence() // Sequence .map(People::name) // Sequence .filter { it.startsWith("J") } // Sequence

Slide 41

Slide 41 text

people // List .asSequence() // Sequence .map(People::name) // Sequence .filter { it.startsWith("J") } // Sequence .toList() // List

Slide 42

Slide 42 text

people .map(People::name) .find { it.startsWith("J") }

Slide 43

Slide 43 text

people .map(People::name) .find { it.startsWith("J") } And Car Jes Wil Pir A C J W P A C J

Slide 44

Slide 44 text

people.asSequence() .map(People::name) .find { it.startsWith("J") } And Car Jes Wil Pir A C J A C J

Slide 45

Slide 45 text

No content

Slide 46

Slide 46 text

Generics at runtime

Slide 47

Slide 47 text

fun sumUp(items: Collection<*>) {a if (items is List) {d println(ints.sum()) }b }c val strings: List = listOf("a", "b") sumUp(strings)

Slide 48

Slide 48 text

fun sumUp(items: Collection<*>) {a if (items is List) {d println(ints.sum()) }b }c val strings: List = listOf("a", "b") sumUp(strings)

Slide 49

Slide 49 text

fun sumUp(items: Collection<*>) {a val ints = items as? List ?: return println("We got a list of ints") println(ints.sum()) }c val strings: List = listOf("a", "b") sumUp(strings)

Slide 50

Slide 50 text

fun sumUp(items: Collection<*>) {a val ints = items as? List ?: return println("We got a list of ints") println(ints.sum()) }c val strings: List = listOf("a", "b") sumUp(strings) ----- We got a list of ints Exception in thread "main" java.lang.ClassCastException: java.lang.String cannot be cast to java.lang.Number

Slide 51

Slide 51 text

fun sumUp(items: Collection<*>) {a val ints = items as? List ?: return println("We got a list of ints") println(ints.sum()) }c val strings: List = listOf("a", "b") sumUp(strings)

Slide 52

Slide 52 text

fun sumUp(items: Collection) {a val ints = items as? List ?: return println("We got a list of ints") println(ints.sum()) }c val strings: List = listOf("a", "b") sumUp(strings)

Slide 53

Slide 53 text

No content

Slide 54

Slide 54 text

fun Iterable<*>.filterIsInstance(): List {a val destination = mutableListOf() for (element in this) {c if (element is T) {d destination.add(element) }p }e return destination }f

Slide 55

Slide 55 text

fun Iterable<*>.filterIsInstance(): List {a val destination = mutableListOf() for (element in this) {c if (element is T) {d destination.add(element) }p }e return destination }f listOf("a", 1, 0x0, 2L, 'u') .filterIsInstance()

Slide 56

Slide 56 text

fun Iterable<*>.filterIsInstance(): List {a val destination = mutableListOf() for (element in this) {c if (element is T) {d destination.add(element) }p }e return destination }f listOf("a", 1, 0x0, 2L, 'u') .filterIsInstance()

Slide 57

Slide 57 text

fun Iterable<*>.filterIsInstance(): List {a val destination = mutableListOf() for (element in this) {c if (element is T) {d destination.add(element) }p }e return destination }f listOf("a", 1, 0x0, 2L, 'u') .filterIsInstance()

Slide 58

Slide 58 text

fun Iterable<*>.filterIsInstance(): List {a val destination = mutableListOf() for (element in this) {c if (element is T) {d destination.add(element) }p }e return destination }f

Slide 59

Slide 59 text

No content

Slide 60

Slide 60 text

fun Iterable<*>.filterIsInstance(): List {a val destination = mutableListOf() for (element in this) {c if (element is T) {d destination.add(element) }p }e return destination }f

Slide 61

Slide 61 text

inline fun Iterable<*>.filterIsInstance(): List {a val destination = mutableListOf() for (element in this) {c if (element is T) {d destination.add(element) }p }e return destination }f

Slide 62

Slide 62 text

inline fun Iterable<*>.filterIsInstance(): List val destination = mutableListOf() for (element in this) {c if (element is T) {d destination.add(element) }p }e return destination }f

Slide 63

Slide 63 text

inline fun Iterable<*>.filterIsInstance(): List val destination = mutableListOf() for (element in this) {c if (element is T) {d destination.add(element) }p }e return destination }f

Slide 64

Slide 64 text

inline fun Iterable<*>.filterIsInstance(): List val destination = mutableListOf() for (element in this) {c if (element is T) {d destination.add(element) }p }e return destination }f listOf("a", 1, 0x0, 2L, 'u') .filterIsInstance()

Slide 65

Slide 65 text

No content

Slide 66

Slide 66 text

val moshi = Moshi.Builder().build() moshi.adapter(String::class.java) // JsonAdapter

Slide 67

Slide 67 text

val moshi = Moshi.Builder().build() moshi.adapter(String::class.java)

Slide 68

Slide 68 text

val moshi = Moshi.Builder().build() moshi.adapter()

Slide 69

Slide 69 text

inline fun Moshi.adapter(): JsonAdapter {a return this.adapter(T::class.java) }b val moshi = Moshi.Builder().build() moshi.adapter()

Slide 70

Slide 70 text

No content

Slide 71

Slide 71 text

If you really want to grow as a Klass, you've got to learn to delegate

Slide 72

Slide 72 text

class canTbeextended open class canbeextended

Slide 73

Slide 73 text

class CountingSet( val innerSet: MutableCollection = HashSet() ) : MutableCollection {abcdefgh }t

Slide 74

Slide 74 text

class CountingSet( val innerSet: MutableCollection = HashSet() ) : MutableCollection {abcdefgh var objectsAdded = 0 }t

Slide 75

Slide 75 text

class CountingSet( val innerSet: MutableCollection = HashSet() ) : MutableCollection {abcdefgh var objectsAdded = 0 override fun add(element: T): Boolean {w objectsAdded++ return innerSet.add(element) }p override fun addAll(c: Collection): Boolean {o objectsAdded += c.size return innerSet.addAll(c) }k }t

Slide 76

Slide 76 text

class CountingSet( val innerSet: MutableCollection = HashSet() ) : MutableCollection {abcdefgh var objectsAdded = 0 override fun add(element: T): Boolean {w objectsAdded++ return innerSet.add(element) }p override fun addAll(c: Collection): Boolean {o objectsAdded += c.size return innerSet.addAll(c) }k }t

Slide 77

Slide 77 text

class CountingSet( val innerSet: MutableCollection = HashSet() ) : MutableCollection {abcdefgh var objectsAdded = 0 override fun add(element: T): Boolean {w objectsAdded++ return innerSet.add(element) }p override fun addAll(c: Collection): Boolean {o objectsAdded += c.size return innerSet.addAll(c) }k override val size: Int get() = innerSet.size override fun contains(element: T): Boolean { return innerSet.contains(element) } override fun containsAll(elements: Collection): Boolean { return innerSet.containsAll(elements) } override fun isEmpty(): Boolean { return innerSet.isEmpty() } override fun clear() { innerSet.clear() } override fun iterator(): MutableIterator { return innerSet.iterator() } override fun remove(element: T): Boolean { return innerSet.remove(element) } override fun removeAll(elements: Collection): Boolean { return innerSet.removeAll(elements) } override fun retainAll(elements: Collection): Boolean { return innerSet.retainAll(elements) } }t

Slide 78

Slide 78 text

class CountingSet( val innerSet: MutableCollection = HashSet() ) : MutableCollection {abcdefgh var objectsAdded = 0 override fun add(element: T): Boolean {w objectsAdded++ return innerSet.add(element) }p override fun addAll(c: Collection): Boolean {o objectsAdded += c.size return innerSet.addAll(c) }k }t

Slide 79

Slide 79 text

class CountingSet( val innerSet: MutableCollection = HashSet() ) : MutableCollection by innerSet {abcdefgh var objectsAdded = 0 override fun add(element: T): Boolean {w objectsAdded++ return innerSet.add(element) }p override fun addAll(c: Collection): Boolean {o objectsAdded += c.size return innerSet.addAll(c) }k }t

Slide 80

Slide 80 text

class CountingSet( val innerSet: MutableCollection = HashSet() ) : MutableCollection by innerSet {abcdefgh var objectsAdded = 0 override fun add(element: T): Boolean {w objectsAdded++ return innerSet.add(element) }p override fun addAll(c: Collection): Boolean {o objectsAdded += c.size return innerSet.addAll(c) }k }t

Slide 81

Slide 81 text

No content

Slide 82

Slide 82 text

class Foo { val data: Int by lazy { computeStuff() } } • lazy • observable • vetoable • notNull

Slide 83

Slide 83 text

The Secret of Success of to Triple Your Quotes

Slide 84

Slide 84 text

"""(.+)"(.+)"(.+)""".toRegex() new Regex("(.+)\"(.+)\"(.+)") "C:\\Users\\yole\\kotlin-book" """C:\Users\yole\kotlin-book""" """${'$'}99.9""" "\$99.9" "$99.9" Java Kotlin

Slide 85

Slide 85 text

assertThat(toString(taco)).isEqualTo("" + "package com.squareup.tacos\n" + "\n" + "import kotlin.String\n" + "\n" + "class Taco {\n" + " final override fun toString(): String = \"taco\"\n" + "}\n" + "")c

Slide 86

Slide 86 text

assertThat(toString(taco)).isEqualTo(""" package com.squareup.tacos import kotlin.String class Taco { final override fun toString(): String = "taco" }z """)c

Slide 87

Slide 87 text

assertThat(toString(taco)).isEqualTo(""" package com.squareup.tacos import kotlin.String class Taco { final override fun toString(): String = "taco" }z """)c

Slide 88

Slide 88 text

assertThat(toString(taco)).isEqualTo(""" |package com.squareup.tacos | |import kotlin.String | |class Taco { | final override fun toString(): String = "taco" |}z |""")c

Slide 89

Slide 89 text

assertThat(toString(taco)).isEqualTo(""" |package com.squareup.tacos | |import kotlin.String | |class Taco { | final override fun toString(): String = "taco" |} |""".trimMargin())c

Slide 90

Slide 90 text

No content

Slide 91

Slide 91 text

And if you want these kind of dreams it's Deprecation

Slide 92

Slide 92 text

class SomeList {a fun remove(index: Int) {b }c }f

Slide 93

Slide 93 text

class SomeList {a fun remove(index: Int) {b }c fun removeAt(index: Int) {d }e }f

Slide 94

Slide 94 text

class SomeList {a @Deprecated("Use removeAt(index) instead.")h fun remove(index: Int) {b }c fun removeAt(index: Int) {d }e }f

Slide 95

Slide 95 text

class SomeList {a @Deprecated("Use removeAt(index) instead.", ReplaceWith("removeAt(index)"))h fun remove(index: Int) {b }c fun removeAt(index: Int) {d }e }f

Slide 96

Slide 96 text

class SomeList {a @Deprecated("Use removeAt(index) instead.", ReplaceWith("removeAt(index)"))h fun remove(index: Int) {b }c fun removeAt(index: Int) {d }e }f

Slide 97

Slide 97 text

Live Demo

Slide 98

Slide 98 text

No content