$30 off During Our Annual Pro Sale. View Details »

What's up next for Kotlin?

What's up next for Kotlin?

Our community is officially one year old! What happened in the last years, where we started from, and what we managed to achieve.

We will start from the beginning to see how a simple idea shaped into a meetup for hundred of developers, providing content and opportunities to learn Kotlin together.

Not only our meetup grew a lot: after Google I/O 2017 Kotlin adoption skyrocketed. There's probably never been a better moment for the Kotlin ecosystem, and the language is getting ready to become The "write once, run everywhere" solution.

Let's walk through some of the features of the upcoming Kotlin release (1.3), to see what the Kotlin future might look like.

Nicola Corti

August 08, 2018
Tweet

More Decks by Nicola Corti

Other Decks in Technology

Transcript

  1. What’s up next
    for Kotlin?
    Nicola Corti
    @cortinico

    View Slide

  2. HH

    View Slide

  3. A bit of history

    View Slide

  4. View Slide

  5. Speakers
    • Gesh Markov
    • Christophe Beyls
    • Niklas Baudy
    • Cord Jastram
    • Yahya Bayramoglu
    • Jossi Wolf
    • Jendrik Johannes
    • Ivan Morgillo
    • Jule Lehmann
    • Dmitry Zaytsev
    Lovis Möller - Nicola Corti

    View Slide

  6. View Slide

  7. Stats
    • 7 Meetups organized in the last year
    • ~280 total attendees
    • 333 Meetup Members
    • 128 Twitter Followers
    • Basically always booked out!

    View Slide

  8. View Slide

  9. pusher.com/state-of-kotlin

    View Slide

  10. Kotlin Adoption

    View Slide

  11. Migrating Java to Kotlin

    View Slide

  12. Reasons for
    returning to Java
    Over a quarter of
    respondents who
    migrated Java to Kotlin
    needed to revert.

    View Slide

  13. Favorite Features

    View Slide

  14. Reasons to use
    coroutines (or not)

    View Slide

  15. 1.3

    View Slide

  16. 1.3-M1 EAP

    View Slide

  17. 1.3-M1 EAP
    plugins {
    kotlin("jvm") version "1.2.60"
    }
    repositories {
    mavenCentral()
    }
    dependencies {
    compile(kotlin("stdlib-jdk8", "1.2.60"))
    }

    View Slide

  18. 1.3-M1 EAP
    plugins {
    kotlin("jvm") version "1.2.60"
    }
    repositories {
    mavenCentral()
    maven("http://dl.bintray.com/kotlin/kotlin-eap")
    }
    dependencies {
    compile(kotlin("stdlib-jdk8", "1.2.60"))
    }

    View Slide

  19. 1.3-M1 EAP
    plugins {
    kotlin("jvm") version "1.3-M1"
    }
    repositories {
    mavenCentral()
    maven("http://dl.bintray.com/kotlin/kotlin-eap")
    }
    dependencies {
    compile(kotlin("stdlib-jdk8", "1.3-M1"))
    }

    View Slide

  20. 1.3-M1 EAP
    plugins {
    kotlin("jvm") version "1.3-M1"
    }
    repositories {
    mavenCentral()
    maven("http://dl.bintray.com/kotlin/kotlin-eap")
    }
    dependencies {
    compile(kotlin("stdlib-jdk8", “1.3-M1"))
    compile(“org.jetbrains.kotlinx:kotlinx-coroutines-core:0.24.0")
    }

    View Slide

  21. 1.3-M1 EAP
    plugins {
    kotlin("jvm") version "1.3-M1"
    }
    repositories {
    mavenCentral()
    maven("http://dl.bintray.com/kotlin/kotlin-eap")
    }
    dependencies {
    compile(kotlin("stdlib-jdk8", “1.3-M1"))
    compile(“org.jetbrains.kotlinx:kotlinx-coroutines-core:0.24.0-eap13")
    }

    View Slide

  22. Coroutines

    View Slide

  23. Coroutines
    kotlin {
    experimental.coroutines = Coroutines.ENABLE
    }

    View Slide

  24. Coroutines
    import kotlinx.coroutines.experimental.delay
    import kotlinx.coroutines.experimental.launch
    fun justACoroutine() {
    launch {
    delay(1000)
    println("Hello world!")
    }
    }

    View Slide

  25. Coroutines
    import kotlinx.coroutines.delay
    import kotlinx.coroutines.launch
    fun justACoroutine() {
    launch {
    delay(1000)
    println("Hello world!")
    }
    }

    View Slide

  26. Capturing When

    View Slide

  27. Capturing When
    fun Request.getBody() : ResponseBody {
    val response = executeRequest()
    when (response) {
    is Authenticator.Success -> response.body
    is HttpError -> throw HttpException(response.status)
    }
    }

    View Slide

  28. Capturing When
    fun Request.getBody() : ResponseBody {
    when (val response = executeRequest()) {
    is Authenticator.Success -> response.body
    is HttpError -> throw HttpException(response.status)
    }
    }

    View Slide

  29. Capturing When
    fun Request.getBody() =
    when (val response = executeRequest()) {
    is Authenticator.Success -> response.body
    is HttpError -> throw HttpException(response.status)
    }

    View Slide

  30. Capturing When

    View Slide

  31. Interfaces
    interface MyPublicApi {
    }

    View Slide

  32. Interfaces
    interface MyPublicApi {
    companion object {
    val baseUrl = "http://..."
    fun create(): MyPublicApi = ...
    }
    }

    View Slide

  33. Interfaces
    interface MyPublicApi {
    companion object {
    @JvmField
    val baseUrl = "http://..."
    @JvmStatic
    fun create(): MyPublicApi = ...
    }
    }
    Java 1.8

    View Slide

  34. Annotations
    annotation class MyAnnotation(val value: Int)

    View Slide

  35. Annotations
    annotation class MyAnnotation(val value: Int) {
    annotation class SubAnnotation
    }

    View Slide

  36. Annotations
    annotation class MyAnnotation(val value: Int) {
    annotation class SubAnnotation
    companion object {
    val timestamp = System.currentTimeMillis()
    }
    }

    View Slide

  37. Annotations
    annotation class MyAnnotation(val value: Int) {
    annotation class SubAnnotation
    companion object {
    @JvmField
    val timestamp = System.currentTimeMillis()
    }
    }

    View Slide

  38. KEEP

    View Slide

  39. KEEP

    View Slide

  40. Arity

    View Slide

  41. Arity
    fun arity22Function(lambda : (
    Int, Int, Int, Int, Int, Int, Int, Int, Int, Int,
    Int, Int, Int, Int, Int, Int, Int, Int, Int, Int,
    Int, Int) -> Unit) {
    }

    View Slide

  42. Arity
    fun arity22Function(lambda : (
    Int, Int, Int, Int, Int, Int, Int, Int, Int, Int,
    Int, Int, Int, Int, Int, Int, Int, Int, Int, Int,
    Int, Int) -> Unit) {
    }
    public final void arity22Function(@NotNull Function22 lambda) {
    Intrinsics.checkParameterIsNotNull(lambda, "lambda");
    }

    View Slide

  43. Arity
    package kotlin.jvm.functions
    /** A function that takes 0 arguments. */
    public interface Function0 : Function {
    /** Invokes the function. */
    public operator fun invoke(): R
    }
    /** A function that takes 1 argument. */
    public interface Function1 : Function {
    /** Invokes the function with the specified argument. */
    public operator fun invoke(p1: P1): R
    }
    /** A function that takes 2 arguments. */
    public interface Function2 : Function {
    /** Invokes the function with the specified arguments. */
    public operator fun invoke(p1: P1, p2: P2): R
    }
    /** A function that takes 3 arguments. */
    public interface Function3 : Function {
    /** Invokes the function with the specified arguments. */
    public operator fun invoke(p1: P1, p2: P2, p3: P3): R
    }
    /** A function that takes 4 arguments. */
    public interface Function4 : Function {
    /** Invokes the function with the specified arguments. */
    public operator fun invoke(p1: P1, p2: P2, p3: P3, p4: P4): R
    }
    /** A function that takes 5 arguments. */
    public interface Function5 : Function {
    /** Invokes the function with the specified arguments. */
    public operator fun invoke(p1: P1, p2: P2, p3: P3, p4: P4, p5: P5): R
    }
    /** A function that takes 6 arguments. */
    public interface Function6 : Function {
    /** Invokes the function with the specified arguments. */
    public operator fun invoke(p1: P1, p2: P2, p3: P3, p4: P4, p5: P5, p6: P6): R
    }
    /** A function that takes 7 arguments. */
    public interface Function7 : Function {
    /** Invokes the function with the specified arguments. */
    public operator fun invoke(p1: P1, p2: P2, p3: P3, p4: P4, p5: P5, p6: P6, p7: P7): R
    }
    /** A function that takes 8 arguments. */
    public interface Function8 : Function {
    /** Invokes the function with the specified arguments. */
    public operator fun invoke(p1: P1, p2: P2, p3: P3, p4: P4, p5: P5, p6: P6, p7: P7, p8: P8): R
    }
    /** A function that takes 9 arguments. */
    public interface Function9 : Function {
    /** Invokes the function with the specified arguments. */
    public operator fun invoke(p1: P1, p2: P2, p3: P3, p4: P4, p5: P5, p6: P6, p7: P7, p8: P8, p9: P9): R
    }
    /** A function that takes 10 arguments. */
    public interface Function10 : Function {
    /** Invokes the function with the specified arguments. */
    public operator fun invoke(p1: P1, p2: P2, p3: P3, p4: P4, p5: P5, p6: P6, p7: P7, p8: P8, p9: P9, p10: P10): R
    }
    /** A function that takes 11 arguments. */
    public interface Function11 : Function {

    View Slide

  44. Arity
    /** A function that takes 8 arguments. */
    public interface Function8 : Function {
    /** Invokes the function with the specified arguments. */
    public operator fun invoke(p1: P1, p2: P2, p3: P3, p4: P4, p5: P5, p6: P6, p7: P7, p8: P8): R
    }
    /** A function that takes 9 arguments. */
    public interface Function9 : Function {
    /** Invokes the function with the specified arguments. */
    public operator fun invoke(p1: P1, p2: P2, p3: P3, p4: P4, p5: P5, p6: P6, p7: P7, p8: P8, p9: P9): R
    }
    /** A function that takes 10 arguments. */
    public interface Function10 : Function {
    /** Invokes the function with the specified arguments. */
    public operator fun invoke(p1: P1, p2: P2, p3: P3, p4: P4, p5: P5, p6: P6, p7: P7, p8: P8, p9: P9, p10: P10): R
    }
    /** A function that takes 11 arguments. */
    public interface Function11 : Function {
    /** Invokes the function with the specified arguments. */
    public operator fun invoke(p1: P1, p2: P2, p3: P3, p4: P4, p5: P5, p6: P6, p7: P7, p8: P8, p9: P9, p10: P10, p11: P11): R
    }
    /** A function that takes 12 arguments. */
    public interface Function12 : Function {
    /** Invokes the function with the specified arguments. */
    public operator fun invoke(p1: P1, p2: P2, p3: P3, p4: P4, p5: P5, p6: P6, p7: P7, p8: P8, p9: P9, p10: P10, p11: P11, p12: P12): R
    }
    /** A function that takes 13 arguments. */
    public interface Function13 : Function {
    /** Invokes the function with the specified arguments. */
    public operator fun invoke(p1: P1, p2: P2, p3: P3, p4: P4, p5: P5, p6: P6, p7: P7, p8: P8, p9: P9, p10: P10, p11: P11, p12: P12, p13: P13): R
    }
    /** A function that takes 14 arguments. */
    public interface Function14 : Function {
    /** Invokes the function with the specified arguments. */
    public operator fun invoke(p1: P1, p2: P2, p3: P3, p4: P4, p5: P5, p6: P6, p7: P7, p8: P8, p9: P9, p10: P10, p11: P11, p12: P12, p13: P13, p14: P14): R
    }
    /** A function that takes 15 arguments. */
    public interface Function15 : Function {
    /** Invokes the function with the specified arguments. */
    public operator fun invoke(p1: P1, p2: P2, p3: P3, p4: P4, p5: P5, p6: P6, p7: P7, p8: P8, p9: P9, p10: P10, p11: P11, p12: P12, p13: P13, p14: P14, p15: P15): R
    }
    /** A function that takes 16 arguments. */
    public interface Function16 : Function {
    /** Invokes the function with the specified arguments. */
    public operator fun invoke(p1: P1, p2: P2, p3: P3, p4: P4, p5: P5, p6: P6, p7: P7, p8: P8, p9: P9, p10: P10, p11: P11, p12: P12, p13: P13, p14: P14, p15: P15, p16: P16): R
    }
    /** A function that takes 17 arguments. */
    public interface Function17 : Function {
    /** Invokes the function with the specified arguments. */
    public operator fun invoke(p1: P1, p2: P2, p3: P3, p4: P4, p5: P5, p6: P6, p7: P7, p8: P8, p9: P9, p10: P10, p11: P11, p12: P12, p13: P13, p14: P14, p15: P15, p16: P16, p17: P17): R
    }
    /** A function that takes 18 arguments. */
    public interface Function18 : Function {
    /** Invokes the function with the specified arguments. */
    public operator fun invoke(p1: P1, p2: P2, p3: P3, p4: P4, p5: P5, p6: P6, p7: P7, p8: P8, p9: P9, p10: P10, p11: P11, p12: P12, p13: P13, p14: P14, p15: P15, p16: P16, p17: P17, p18: P18): R
    }
    /** A function that takes 19 arguments. */
    public interface Function19 : Function {
    /** Invokes the function with the specified arguments. */
    public operator fun invoke(p1: P1, p2: P2, p3: P3, p4: P4, p5: P5, p6: P6, p7: P7, p8: P8, p9: P9, p10: P10, p11: P11, p12: P12, p13: P13, p14: P14, p15: P15, p16: P16, p17: P17, p18: P18, p19: P19): R
    }
    /** A function that takes 20 arguments. */
    public interface Function20 : Function {
    /** Invokes the function with the specified arguments. */
    public operator fun invoke(p1: P1, p2: P2, p3: P3, p4: P4, p5: P5, p6: P6, p7: P7, p8: P8, p9: P9, p10: P10, p11: P11, p12: P12, p13: P13, p14: P14, p15: P15, p16: P16, p17: P17, p18: P18, p19: P19, p20: P20): R
    }
    /** A function that takes 21 arguments. */
    public interface Function21 : Function {
    /** Invokes the function with the specified arguments. */
    public operator fun invoke(p1: P1, p2: P2, p3: P3, p4: P4, p5: P5, p6: P6, p7: P7, p8: P8, p9: P9, p10: P10, p11: P11, p12: P12, p13: P13, p14: P14, p15: P15, p16: P16, p17: P17, p18: P18, p19: P19, p20: P20, p21: P21): R
    }
    /** A function that takes 22 arguments. */
    public interface Function22 : Function {
    /** Invokes the function with the specified arguments. */
    public operator fun invoke(p1: P1, p2: P2, p3: P3, p4: P4, p5: P5, p6: P6, p7: P7, p8: P8, p9: P9, p10: P10, p11: P11, p12: P12, p13: P13, p14: P14, p15: P15, p16: P16, p17: P17, p18: P18, p19: P19, p20: P20, p21: P21, p22: P22): R
    }

    View Slide

  45. Arity
    fun arity22Function(lambda : (
    Int, Int, Int, Int, Int, Int, Int, Int, Int, Int,
    Int, Int, Int, Int, Int, Int, Int, Int, Int, Int,
    Int, Int) -> Unit) {
    }

    View Slide

  46. Arity
    fun arity23Function(lambda : (
    Int, Int, Int, Int, Int, Int, Int, Int, Int, Int,
    Int, Int, Int, Int, Int, Int, Int, Int, Int, Int,
    Int, Int, Int) -> Unit) {
    }

    View Slide

  47. Arity
    fun arity23Function(lambda : (
    Int, Int, Int, Int, Int, Int, Int, Int, Int, Int,
    Int, Int, Int, Int, Int, Int, Int, Int, Int, Int,
    Int, Int, Int) -> Unit) {
    }
    public final void arity23Function(@NotNull FunctionN lambda) {
    Intrinsics.checkParameterIsNotNull(lambda, "lambda");
    }

    View Slide

  48. Arity
    fun arity23Function(lambda : (
    Int, Int, Int, Int, Int, Int, Int, Int, Int, Int,
    Int, Int, Int, Int, Int, Int, Int, Int, Int, Int,
    Int, Int, Int) -> Unit) {
    }
    public final void arity23Function(@NotNull FunctionN lambda) {
    Intrinsics.checkParameterIsNotNull(lambda, "lambda");
    }

    View Slide

  49. Arity
    @SinceKotlin("1.3")
    interface FunctionN : Function, FunctionBase {
    /**
    * Invokes the function with the specified arguments.
    *
    * Must **throw exception** if the length of passed [args]
    * is not equal to the parameter count returned by [arity].
    *
    * @param args arguments to the function
    */
    operator fun invoke(vararg args: Any?): R
    /**
    * Returns the number of arguments that must be passed to
    * this function.
    */
    override val arity: Int
    }
    http://bit.ly/keep-bigarity

    View Slide

  50. Experimental features

    View Slide

  51. Inline Classes

    View Slide

  52. Inline Classes
    inline class Username(val value: String)

    View Slide

  53. Inline Classes
    inline class Username(val value: String)
    typealias Username = String

    View Slide

  54. Inline Classes
    inline class Username(val value: String)
    inline class Password(val value: String)

    View Slide

  55. Inline Classes
    inline class Username(val value: String)
    inline class Password(val value: String)
    val myName = Username("nicola")
    val myPassword = Password("p4ssw0rd")

    View Slide

  56. Inline Classes
    inline class Username(val value: String)
    inline class Password(val value: String)
    val myName = Username("nicola")
    val myPassword = Password("p4ssw0rd")
    myName = myPassword

    View Slide

  57. Inline Classes
    inline class Username(val value: String)
    inline class Password(val value: String)
    val myName = Username("nicola")
    val myPassword = Password("p4ssw0rd")
    myName = myPassword
    myPassword = myName

    View Slide

  58. Inline Classes
    inline class Username(val value: String)
    inline class Password(val value: String)
    val myName = Username("nicola")
    val myPassword = Password("p4ssw0rd")
    myName = myPassword
    myPassword = myName
    myName = "MyNewName"
    bit.ly/keep-inlineclasses

    View Slide

  59. Unsigned Types

    View Slide

  60. Unsigned Types
    val anUnsignedInteger : UInt
    val anUnsignedLong : ULong
    val anUnsignedByte : UByte
    val anUnsignedShort : UShort

    View Slide

  61. Unsigned Types
    val anUnsignedInteger : UInt = 0xFFFF_FFFFu
    val anUnsignedLong : ULong = 10uL
    val anUnsignedByte : UByte = 0xFFu
    val anUnsignedShort : UShort = 0xFFFFu

    View Slide

  62. Unsigned Types
    @SinceKotlin("1.3")
    @ExperimentalUnsignedTypes
    public inline class UInt internal constructor(private val data: Int) :
    Comparable {
    bit.ly/keep-utype

    View Slide

  63. Experimental Annotations

    View Slide

  64. Experimental Annotations
    @Experimental(Experimental.Level.WARNING)
    annotation class MyCoolFeatureExperimental

    View Slide

  65. Experimental Annotations
    @Experimental(Experimental.Level.WARNING)
    annotation class MyCoolFeatureExperimental
    @MyCoolFeatureExperimental
    fun myExperimentalFunction() {
    // ...
    }

    View Slide

  66. Experimental Annotations
    @Experimental(Experimental.Level.WARNING)
    annotation class MyCoolFeatureExperimental
    @MyCoolFeatureExperimental
    fun myExperimentalFunction() {
    // ...
    }
    @UseExperimental(MyCoolFeatureExperimental::class)
    fun myClientCode() {
    myExperimentalFunction()
    }

    View Slide

  67. Experimental Annotations
    @Experimental(Experimental.Level.WARNING)
    annotation class MyCoolFeatureExperimental
    @MyCoolFeatureExperimental
    fun myExperimentalFunction() {
    // ...
    }
    @UseExperimental(MyCoolFeatureExperimental::class)
    fun myClientCode() {
    myExperimentalFunction()
    }
    bit.ly/keep-experimental

    View Slide

  68. SuccessOrFailure

    View Slide

  69. SuccessOrFailure
    /**
    * A discriminated union that encapsulates successful outcome
    * with a value of type [T] or a failure with an arbitrary
    * [Throwable] exception.
    */
    inline class SuccessOrFailure internal constructor(
    internal val value: Any? // internal value -- either T or Failure
    ) {
    internal class Failure(val exception: Throwable)
    //...
    }

    View Slide

  70. SuccessOrFailure
    /**
    * A discriminated union that encapsulates successful outcome
    * with a value of type [T] or a failure with an arbitrary
    * [Throwable] exception.
    */
    inline class SuccessOrFailure internal constructor(
    internal val value: Any? // internal value -- either T or Failure
    ) {
    internal class Failure(val exception: Throwable)
    //...
    }

    View Slide

  71. SuccessOrFailure
    /**
    * A discriminated union that encapsulates successful outcome
    * with a value of type [T] or a failure with an arbitrary
    * [Throwable] exception.
    */
    inline class SuccessOrFailure internal constructor(
    internal val value: Any? // internal value -- either T or Failure
    ) {
    internal class Failure(val exception: Throwable)
    //...
    }

    View Slide

  72. SuccessOrFailure
    /**
    * A discriminated union that encapsulates successful outcome
    * with a value of type [T] or a failure with an arbitrary
    * [Throwable] exception.
    */
    inline class SuccessOrFailure internal constructor(
    internal val value: Any? // internal value -- either T or Failure
    ) {
    internal class Failure(val exception: Throwable)
    //...
    }
    inline fun runCatching(block: () -> R): SuccessOrFailure

    View Slide

  73. SuccessOrFailure
    /**
    * A discriminated union that encapsulates successful outcome
    * with a value of type [T] or a failure with an arbitrary
    * [Throwable] exception.
    */
    inline class SuccessOrFailure internal constructor(
    internal val value: Any? // internal value -- either T or Failure
    ) {
    internal class Failure(val exception: Throwable)
    //...
    }
    inline fun runCatching(block: () -> R): SuccessOrFailure

    View Slide

  74. SuccessOrFailure
    inline fun runCatching(block: () -> R): SuccessOrFailure {
    return try {
    SuccessOrFailure.success(block())
    } catch (e: Throwable) {
    SuccessOrFailure.failure(e)
    }
    }

    View Slide

  75. SuccessOrFailure
    fun findUserByName(name: String): ?

    View Slide

  76. SuccessOrFailure
    fun findUserByName(name: String): SuccessOrFailure
    You can do better…

    View Slide

  77. SuccessOrFailure
    fun findUserByName(name: String): User

    View Slide

  78. SuccessOrFailure
    sealed class FindUserResult {
    data class Found(val user: User) : FindUserResult()
    data class NotFound(val name: String) : FindUserResult()
    data class MalformedName(val name: String) : FindUserResult()
    // other cases that need different business-specific handling code
    }
    fun findUserByName(name: String): FindUserResult

    View Slide

  79. SuccessOrFailure
    fun findUserByName(name: String): User

    View Slide

  80. SuccessOrFailure
    fun findUserByName(name: String): User
    val result = runCatching { findUserByName("...") }

    View Slide

  81. SuccessOrFailure
    fun findUserByName(name: String): User
    fun findUserByNameCatching(name: String): SuccessOrFailure
    val result = runCatching { findUserByName("...") }

    View Slide

  82. SuccessOrFailure - Use Cases

    View Slide

  83. SuccessOrFailure - Use Cases
    fun readFilesCatching(files: List): List> =
    files.map {
    }

    View Slide

  84. SuccessOrFailure - Use Cases
    fun readFilesCatching(files: List): List> =
    files.map {
    runCatching {
    readFile(it)
    }
    }

    View Slide

  85. SuccessOrFailure - Use Cases
    fun readFilesCatching(files: List): List> =
    files.map {
    runCatching {
    readFile(it)
    }
    }
    readFilesCatching(listOf("...")).map {
    }

    View Slide

  86. SuccessOrFailure - Use Cases
    fun readFilesCatching(files: List): List> =
    files.map {
    runCatching {
    readFile(it)
    }
    }
    readFilesCatching(listOf("...")).map { result ->
    }

    View Slide

  87. SuccessOrFailure - Use Cases
    fun readFilesCatching(files: List): List> =
    files.map {
    runCatching {
    readFile(it)
    }
    }
    readFilesCatching(listOf("...")).map { result : SuccessOrFailure ->
    }

    View Slide

  88. SuccessOrFailure - Use Cases
    fun readFilesCatching(files: List): List> =
    files.map {
    runCatching {
    readFile(it)
    }
    }
    readFilesCatching(listOf("...")).map { result ->
    result.mapCatching {
    formatFile(it)
    }
    }

    View Slide

  89. SuccessOrFailure - Use Cases
    fun readFilesCatching(files: List): List> =
    files.map {
    runCatching {
    readFile(it)
    }
    }
    readFilesCatching(listOf("...")).map { result ->
    result.mapCatching {
    formatFile(it)
    }
    }

    View Slide

  90. SuccessOrFailure - Use Cases

    View Slide

  91. SuccessOrFailure - Use Cases
    try {
    val data = doSomething()
    processData(data)
    } catch(e: Throwable) {
    showErrorDialog(e)
    }

    View Slide

  92. SuccessOrFailure - Use Cases
    try {
    val data = doSomething()
    processData(data)
    } catch(e: Throwable) {
    showErrorDialog(e)
    }
    runCatching { doSomething() }
    .onFailure { showErrorDialog(it) }
    .onSuccess { processData(it) }

    View Slide

  93. SuccessOrFailure - Use Cases

    View Slide

  94. SuccessOrFailure - Use Cases
    /**
    * Interface representing a continuation after a suspension point that
    * returns value of type `T`.
    */
    @SinceKotlin("1.3")
    public interface Continuation {
    /**
    * Context of the coroutine that corresponds to this continuation.
    */
    public val context: CoroutineContext
    /**
    * Resumes the execution of the corresponding coroutine passing successful or failed
    [result] as the
    * return value of the last suspension point.
    */
    public fun resumeWith(result: SuccessOrFailure)
    }
    bit.ly/keep-successorfailure

    View Slide

  95. To infinity…
    • Collections Literals
    • SAM Conversion
    • Truly Immutability
    val list = listOf("1", "2", "3")
    val list = ["1", "2", "3"]
    val map = mapOf("1" to 1, "2" to 2, "3" to 3)
    val map = ["1" = 1, "2" = 2, "3" = 3]
    interface Function {
    fun run(data: T)
    }
    val myFunction: Function =
    { println ("data $it”) }
    class Foo(var v: Int)
    immutable class Bar(val foo: Foo)
    // This should fail
    bit.ly/kotlin-feature-survey

    View Slide

  96. Thanks!
    Nicola Corti
    @cortinico

    View Slide