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

What's new in Kotlin?

What's new in Kotlin?

Presented at Kotlin Fest Tokyo 2019.

Svetlana Isakova

August 24, 2019
Tweet

More Decks by Svetlana Isakova

Other Decks in Programming

Transcript

  1. Tokyo
    Svetlana Isakova
    @sveta_isakova
    What’s new in Kotlin?

    View Slide

  2. Kotlin developers
    0
    750
    1500
    2250
    3000
    2016 2017 2018
    156K
    700K
    2.2M

    View Slide

  3. Timeline
    … …
    2017 Official on Android
    2010 Project started
    2016 Kotlin 1.0
    2018 Kotlin 1.3

    View Slide

  4. Kotlin evolution
    Kotlin 1.2
    Kotlin 1.0
    Kotlin 1.1
    Kotlin 1.3
    Coroutines (experimental)
    Coroutines get stable!
    Multi-platform projects can target Kotlin/Native (experimental)
    Multi-platform projects (experimental)
    Kotlin/Native (experimental)
    Kotlin gets stable!

    View Slide

  5. Agenda
    • Kotlin evolution
    • “Experimental” features

    View Slide

  6. Agenda: experimental features
    • Inline Classes
    • Contracts
    • Immutable Collections
    • Flows
    • Multiplatform Projects

    View Slide

  7. Principles of Pragmatic Evolution
    Language design is cast in stone,
    but this stone is reasonably soft,
    and with some effort we can reshape
    it later.
    Kotlin Design Team
    * The real sculpture made by José Manuel Castro López

    View Slide

  8. Principles of Pragmatic Evolution
    • keeping the language modern
    • comfortable updates
    • feedback loop

    View Slide

  9. KEEPing the language modern
    https://github.com/Kotlin/KEEP
    KEEP = Kotlin Evolution
    and Enhancement Process
    contains language proposals
    and the corresponding discussions

    View Slide

  10. Comfortable updates
    • Deprecation warnings in advance
    • Automatic migration

    View Slide

  11. Feedback loop with the community
    • Kotlin the community
    • Kotlin team listens to the community
    • The community members influence
    the Kotlin evolution

    View Slide

  12. Contributors from all over the world

    View Slide

  13. Experimental
    features

    View Slide

  14. Experimental features
    The goal: to let new features be tried
    by early adopters as soon as possible

    View Slide

  15. Experimental Language Features
    • you need to explicitly opt in at the call site
    to use experimental features
    compileTestKotlin {

    kotlinOptions {

    freeCompilerArgs += "-Xinline-classes"

    }

    }

    View Slide

  16. Experimental API for Libraries
    • can be publicly released as a part of the library
    • may break at any moment

    View Slide

  17. @ShinyNewAPI
    class Foo {
    ...
    }
    Experimental API
    @Experimental
    annotation class ShinyNewAPI
    You can mark your new class or function as experimental

    View Slide

  18. Using experimental API
    @UseExperimental(ShinyNewAPI::class)
    fun doSomethingImportant() {
    val foo = Foo()
    ...
    }

    View Slide

  19. • feedback loop for new features and API
    Experimental: Summary

    View Slide

  20. Inline classes

    View Slide

  21. Inline classes
    • can wrap values without additional
    overhead
    • currently an experimental feature

    View Slide

  22. Duration API
    • KEEP: Duration and Time Measurement API
    • status: experimental in Kotlin 1.3.50
    • uses inline classes

    View Slide

  23. Refining API: trying primitive args
    fun greetAfterTimeout(millis: Long)
    greetAfterTimeout(2) // meaning 2 seconds?
    Too easy to make a mistake

    View Slide

  24. Refining API: trying overloads
    fun greetAfterTimeoutMillis(millis: Long)

    fun greetAfterTimeoutSeconds(seconds: Long)
    greetAfterTimeoutSeconds(2)
    Too verbose

    View Slide

  25. Refining API: trying class
    fun greetAfterTimeout(duration: Duration)
    greetAfterTimeout(Duration(2))
    Extra object is allocated
    class Duration(val value: Long)

    View Slide

  26. Inline classes to the rescue
    inline class Duration(val value: Double)

    fun greetAfterTimeout(duration: Duration)
    fun greetAfterTimeout_(duration: Double)
    Under the hood:
    No extra object is allocated! ✓

    View Slide

  27. Inline classes constraints
    inline class Duration(val value: Double)

    fun greetAfterTimeout(duration: Duration)
    inline class can define only one val property

    View Slide

  28. Creating Duration
    fun greetAfterTimeout(duration: Duration)
    greetAfterTimeout(2.seconds)

    Explicit units in the code
    val Int.seconds

    get() = toDuration(DurationUnit.SECONDS)

    View Slide

  29. Inline classes: summary
    • KEEP: inline classes
    • help to improve API and avoid extra
    allocations
    • you can go and try it out

    View Slide

  30. Contracts

    View Slide

  31. inline fun run(block: () -> R): R = block()
    inline fun run(block: () -> R): R {
    contract {
    callsInPlace(block, InvocationKind.EXACTLY_ONCE)
    }
    return block()
    }
    Changes in standard library

    View Slide

  32. Changes in standard library
    inline fun run(block: () -> R): R {
    contract {
    callsInPlace(block, InvocationKind.EXACTLY_ONCE)
    }
    return block()
    }
    inline fun run(block: () -> R): R = block()

    View Slide

  33. We know something about run,
    that the compiler doesn’t
    val answer: Int
    run {
    answer = 42
    }
    println(answer)
    Compiler error:
    Captured values initialization is forbidden
    due to possible reassignment

    View Slide

  34. val s: String? = ""
    if (!s.isNullOrEmpty()) {
    s.first()
    } Compiler error:
    Only safe (?.) or non-null asserted (!!.) calls
    are allowed on a nullable receiver of type String?
    We know something about isNullOrEmpty,
    which the compiler doesn’t
    if (s != null && s.isNotEmpty()) {
    s.first()
    }

    View Slide

  35. Kotlin Contracts
    …allow to share extra information
    about code semantics with the compiler

    View Slide

  36. inline fun run(block: () -> R): R {
    contract {
    callsInPlace(block, InvocationKind.EXACTLY_ONCE)
    }
    return block()
    }
    Contract: block lambda
    will be always called once
    val answer: Int
    run {
    answer = 42
    }

    View Slide

  37. fun String?.isNullOrEmpty(): Boolean {
    contract {
    returns(false) implies (this@isNullOrEmpty != null)
    }
    return this == null || this.length == 0
    }
    Contract: if the function returns false,
    the receiver is not-null
    val s: String? = ""
    if (!s.isNullOrEmpty()) {
    s.first()
    }

    View Slide

  38. Contract = explicit statement about function behaviour
    Why can’t compiler just implicitly
    infer such information?
    Because then such implicitly inferred information:
    - can be implicitly changed
    - can accidentally break code depending on it

    View Slide

  39. • handy functions (run, isEmptyOrNull)
    are even more useful
    • contract DSL will change
    • more use-cases in the future
    • you can define contracts for your own
    functions
    Contracts: Summary

    View Slide

  40. Immutable
    Collections

    View Slide

  41. Standard library: Collections
    MutableList
    List
    read-only

    View Slide

  42. Immutable collections
    MutableList
    List
    ImmutableList
    PersistentList
    truly

    immutable
    supports

    modification
    read-only

    View Slide

  43. Persistent collection modifications
    val list = persistentListOf(1, 2, 3)

    val newList = list.add(4)

    println(newList) // [1, 2, 3, 4]
    Modification operation returns new collection:
    Under the hood, newList shares parts of data
    structure with the original list

    View Slide

  44. Persistent collection modifications
    val list = persistentListOf(1, 2, 3)

    val newList = list.builder().apply {

    add(4)

    add(5)

    }.build()

    println(newList) // [1, 2, 3, 4, 5]
    Applying several operations:

    View Slide

  45. • KEEP: Immutable Collections
    • Will be part of the standard library in
    the future (no promised date)
    • You can go and try it out
    Immutable Collections: summary

    View Slide

  46. Flows

    View Slide

  47. Flow
    • suspend-based reactive stream
    flow { emit(value) }

    .map { transform(it) }

    .filter { condition(it) }

    .catch { exception -> log(exception) }

    .collect { process(it) }

    View Slide

  48. Integration with RxJava
    Use extension functions:
    • flow.asPublisher()

    • publisher.asFlow()

    View Slide

  49. Backpressure
    • Backpressure happens automatically
    thanks to suspension mechanism

    View Slide

  50. Flows: summary
    • bring reactive streams to coroutines library
    • currently in an experimental state
    • will get stable soon

    View Slide

  51. Multi-platform
    Projects

    View Slide

  52. expect fun Char.isUpperCase(): Boolean

    public actual fun Char.isUpperCase(): Boolean =

    java.lang.Character.isUpperCase(this)
    Now:
    fun Char.isUpperCase(): Boolean =

    java.lang.Character.isUpperCase(this)
    Before:
    expect / actual in standard library

    View Slide

  53. Multi-platform projects
    Browser
    Kotlin/JS
    Android
    Kotlin/JVM
    iOS
    Kotlin/Native
    Server
    Kotlin/JVM
    common

    code

    View Slide

  54. Sharing common code
    • Sharing business logic
    • Keeping UI platform-dependent
    • The shared part might vary

    View Slide

  55. Common code
    • you define expect declarations in the common
    code and use them
    • you provide different actual implementations
    for different platforms

    View Slide

  56. Time measurement example
    expect fun measureTime(action: () -> Unit): Duration
    Expected platform-specific API:
    Expected API can be used in the common code:
    measureTime {

    // operation

    }

    View Slide

  57. Platform-specific Implementations
    expect fun measureTime(action: () -> Unit): Duration
    actual fun measureTime(action: () -> Unit): Duration {

    // implementation using System.nanoTime()

    }
    actual fun measureTime(action: () -> Unit): Duration {

    // implementation using window.performance.now()

    }
    actual fun measureTime(action: () -> Unit): Duration {

    // implementation using std::chrono::high_resolution_clock

    }
    Kotlin/JVM
    Kotlin/JS
    Kotlin/Native

    View Slide

  58. Common code
    • can use the standard library
    • can define expect declarations and use them
    • can use other multi-platform libraries

    View Slide

  59. Multi-platform libraries
    • Standard library
    • Ktor HTTP client
    • kotlinx.serialization
    • kotlinx.coroutines
    • … and more

    View Slide

  60. Many apps already in production
    Going Native: How I used Kotlin Native to Port 6 years
    of Android Game Code to iOS in 6 months
    Shipping a Mobile Multiplatform Project on iOS &
    Android
    Your Multiplatform Kaptain has Arrived: iOS release is
    powered by Kotlin Multiplatform

    View Slide

  61. Multi-platform projects: summary
    • a modern approach to multi-platform
    development
    • you can easily tune what parts you
    want to be shared
    • you can go and try it out

    View Slide

  62. More about Kotlin

    View Slide

  63. View Slide

  64. Kotlin course at Coursera

    View Slide

  65. Hands-on lab “Intro to coroutines & channels”
    http://kotl.in/hands-on

    View Slide

  66. Have a nice Kotlin!

    View Slide