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

Kotlin for the Pragmatic Functionalist

pakoito
November 03, 2017

Kotlin for the Pragmatic Functionalist

Many people are migrating their backends to Kotlin from other JVM languages, lured by the simplicity and expressivity of the language. The Android community embraced it even before release because it healed many longstanding wounds.

So, what can a functional programmer find when migrating to Kotlin? In this talk we'll cover several of the common constructs that are part of any functional stack and how they have already been introduced into the language.

For the people interested in infrastructure, we will also go through some design choices and limitations that JetBrains provided to keep Kotlin within a sane range of pragmatism.

Kategory: http://kategory.io

pakoito

November 03, 2017
Tweet

More Decks by pakoito

Other Decks in Programming

Transcript

  1. @pacoworks
    Paco Estevez
    Kotlin for the
    Pragmatic Functionalist

    View full-size slide

  2. @pacoworks
    Kotlin logo: © 2015-present - JetBrains
    KotlinConf logo: © 2017 - JetBrains
    Kategory logo: © 2017–present - The Kategory maintainers
    ReasonML logo: © 2015–present - Facebook Inc.
    Flow logo: © 2014–present - Facebook Inc.
    2
    Special thanks to Facebook for allowing me to
    work on this on my spare time. Kategory is not
    an internal Facebook project, nor it is an
    incubator. It is an external project of community
    contributors.

    In any case facebookers are bunch of devs
    excited about Kotlin too!

    View full-size slide

  3. @pacoworks
    Kotlin is ready for Functional Programming
    TODAY
    We’re growing
    We’re improving
    We want all of you
    3

    View full-size slide

  4. @pacoworks
    Our community goal
    Use of Kotlin in JS, Native, JVM
    One codebase for mobile, backend, frontend
    Same idioms across languages and ecosystems
    4
    The objective of this talk is to give you a
    peek bleeding edge technologies for
    Kotlin, and what future language
    features will look like.

    View full-size slide

  5. @pacoworks
    Where is Kotlin today
    What are we bringing into the ecosystem
    Where would we like to be
    5

    View full-size slide

  6. @pacoworks
    Kotlin today
    6

    View full-size slide

  7. @pacoworks
    Key cornerstones
    Data classes, sealed classes
    Inliner
    Extension functions
    Type aliases
    Enhanced resolution of generic parameters
    7

    View full-size slide

  8. @pacoworks
    Data & sealed classes
    Plain information
    Stores specifics
    Closed and immutable by
    default
    8
    Pure behavior
    Indicates branching in
    execution
    Checked at compile time
    Data Sealed

    View full-size slide

  9. @pacoworks
    Inliner
    Copies a function in its call site
    Inline functions’ body is copied at compile time
    All call sites with static dispatch are known at
    compile time
    Enables runtime generics
    9
    Reified

    View full-size slide

  10. @pacoworks
    Extension functions
    Converts static functions into object methods
    All call sites with static dispatch are known at
    compile time
    Can extend just for specific generic parameters
    10

    View full-size slide

  11. @pacoworks
    Kotlin today
    with Kategory
    11

    View full-size slide

  12. @pacoworks
    Key features
    Extension Interfaces
    Ad-hoc polymorphism for generic type constructors
    Imperative async code
    Smarter boilerplate removal
    12

    View full-size slide

  13. @pacoworks
    Extension Interfaces
    Implement any interface for already existing types
    Use the extension interface as a parameter
    WIP: automatic extension interface lookup
    13
    Extension protocols

    View full-size slide

  14. @pacoworks
    Extension Interface
    Jsonable
    interface Jsonable {
    fun toJson(T element): String
    fun fromJson(String json): T
    }
    fun jsonable(): Jsonable =
    // lookup code
    14

    View full-size slide

  15. @pacoworks
    Extension Interface
    Jsonable
    object EmployeeJsonable: Jsonable {
    val gson = Gson()
    fun toJson(Employee element): String =
    gson.toJsonString(element)
    fun fromJson(String json): Employee =
    gson.fromJsonString(json)
    }
    15

    View full-size slide

  16. @pacoworks
    Extension Interface
    Jsonable
    fun parser(
    company: Company,
    parser: Jsonable = jsonable()
    ): String =
    parser.toJson(company)
    16
    Note the lookup code
    And if this seems like a lot of work, we
    have a KEEP to integrate a simpler
    version in the language

    View full-size slide

  17. @pacoworks
    KEEP-87
    17
    Introduce Extension Interfaces
    into the language under the name
    “Type Classes”
    Compile time lookup & injection
    Aim for parity with Swift’s
    Extension Protocols

    View full-size slide

  18. @pacoworks
    Ad-hoc polymorphism for
    generic type constructors
    Functions that support any generic type constructor
    Express agnosticity to implementation
    Safe downcast from generic to implementation
    18

    View full-size slide

  19. @pacoworks
    Generic type constructor
    interface Hk
    F is the type of the
    container
    A is the type of the
    content
    19
    We’re going to replace the F

    View full-size slide

  20. @pacoworks
    Generic constructor
    implementations
    sealed class Option: Hk
    data class ListWrap(…): Hk
    sealed class Try : Hk
    F becomes a “tag” type
    A remains as the type of
    the content
    20

    View full-size slide

  21. @pacoworks
    Returning generic type
    constructors
    fun getUserById(
    id: String
    ): Hk =
    ???
    21

    View full-size slide

  22. @pacoworks
    Extension Interface
    Factory
    interface Factory {
    fun create(element: A): Hk
    }
    fun factory(): Factory =
    // lookup code
    22

    View full-size slide

  23. @pacoworks
    Polymorphism for generic
    type constructors
    fun getUserById(
    id: String,
    factory: Factory = factory()
    ): Hk =
    factory.create(getUser(id))
    23
    How do I convert that F back to a real
    value?

    View full-size slide

  24. @pacoworks
    Safely downcasting
    generic containers
    24
    Extension functions can be defined to require just
    some of the generic parameters
    Extension functions are resolved at compile time

    View full-size slide

  25. @pacoworks
    Safely downcasting
    generic containers
    25
    fun Hk.ev() =
    this as Option
    fun Hk.ev() =
    this as Try

    View full-size slide

  26. @pacoworks
    Ad-hoc polymorphism for
    generic constructors
    26
    val a: Option = getUserById(“123”).ev()
    val b: Try = getUserById(“123”).ev()
    Lookup overhead: O(1) after first
    lookup. Ideally it should be 0 because
    the compiler does it for us.

    View full-size slide

  27. @pacoworks
    Ad-hoc polymorphism for
    generic constructors
    27
    object OptionFactory: Factory {
    fun create(element: A): Hk =
    Option.Some(a)
    }
    object TryFactory: Factory {
    fun create(element: A): Hk =
    Try { a }
    }
    <--
    global
    lookup!

    View full-size slide

  28. @pacoworks
    KindedJ
    28
    Initiative to share generic type
    constructors under the name
    “Higher Kinded Types”
    We’re speaking with other FP
    libraries for Java & eta-lang

    View full-size slide

  29. @pacoworks
    Imperative async code
    Express asynchronous sequential and parallel
    execution as if they were synchronous
    For any existing framework and abstraction
    29

    View full-size slide

  30. @pacoworks
    Regular async code
    30
    fun getUserFriends(
    id: String
    ): Observable> =
    getUserById(id).flatMap { user ->
    Observable.merge(
    user.friends.map { friend ->
    getUserById(friend.id)
    }
    ).toList()
    }

    View full-size slide

  31. @pacoworks
    Imperative async code
    31
    fun getUserFriends(
    id: String,
    coroutinable: Coroutinable = coroutinable()
    ): Hk> =
    coroutinable.bindingE {
    val user = getUserById(id).bind()
    val friendProfiles = user.friends.map { getUserById(it.id).bind() }
    yields(friendProfiles)
    }

    View full-size slide

  32. @pacoworks
    Ad-hoc polymorphism for
    imperative async code
    32
    val a: Either> = getUserFriends(“123”).ev()
    val b: Try> = getUserFriends(“123”).ev()
    val c: ObservableKW> = getUserFriends(“123”).ev()
    val d: IO> = getUserFriends(“123”).ev()

    View full-size slide

  33. @pacoworks
    Coroutinable?
    33
    typealias Coroutinable = MonadError

    View full-size slide

  34. @pacoworks
    Effects with MonadError
    Thin Extension Interface that can be implemented by
    any existing framework & abstraction
    With error handling, stack safety, threading &
    cancellation out of the box
    Current integrations: RxJava, kotlin.coroutines, IO
    Potential integrations: CompletableFuture,
    kotlinx.coroutines, AsyncTask, ArchComponents,
    Kovenant…
    34

    View full-size slide

  35. @pacoworks
    Implementations in Kategory
    Error handling: Option, Try, Validated, Either, Ior
    Collections: List, Sequence, Map, Set
    RWS: Reader, Writer, State
    Transformers: ReaderT, WriterT, OptionT, StateT,
    EitherT
    Evaluation: Eval, Trampoline, Free, Function0
    Others: Coproduct, Coreader, Const...
    35
    What if I want my own?

    View full-size slide

  36. @pacoworks
    Smarter boilerplate removal
    36
    Eugenio Marletti’s collaboration
    & mentorship
    Generate boilerplate for all the
    features show using annotations

    View full-size slide

  37. @pacoworks
    Bye bye boring code
    37
    Generic constructors
    @higherkind
    Extension Interfaces
    @derives
    @instance
    Manipulation of immutable data & sealed classes
    kategory-optics by Simon Vergauwen So how did we reach this point?

    View full-size slide

  38. @pacoworks
    Challenges & Pitfalls
    IDE resolution of deeply nested generics
    Scopes with ambiguity for `it` and `this`
    Reified generics are “contagious”
    Unexpected behavior caused by inlining
    Generics and interoperating with Java
    Error recovery in coroutines
    38
    And many more, come talk to us!

    View full-size slide

  39. @pacoworks
    Where would we
    like to be
    39
    2018

    View full-size slide

  40. @pacoworks
    40
    scala_logo.svg
    Swift5
    _0.png
    ELM

    LANG.
    svg
    haskell_lambda
    .png
    rustPro
    mo.png
    EtaLang
    .png
    F-sharp-
    main.png

    View full-size slide

  41. @pacoworks
    Bring your tools in
    Threading
    Databases
    Network
    Error Handling
    Reactive Programming
    41

    View full-size slide

  42. @pacoworks
    Bring your tools in
    Threading
    Databases
    Network
    Error Handling
    Reactive Programming
    42
    Parsers
    Compilers
    Static analyzers
    UI frameworks
    Math & statistics

    View full-size slide

  43. @pacoworks
    Bring your tools in
    Threading
    Databases
    Network
    Error Handling
    Reactive Programming
    43
    Parsers
    Compilers
    Static analyzers
    UI frameworks
    Math & statistics
    Data science
    Machine learning
    Videogames
    Computer vision
    Serialization

    View full-size slide

  44. @pacoworks
    Bring your tools in
    Threading
    Databases
    Network
    Error Handling
    Reactive Programming
    44
    Parsers
    Compilers
    Static analyzers
    UI frameworks
    Math & statistics
    Data science
    Machine learning
    Videogames
    Computer vision
    Serialization
    Category Theory
    Web frameworks
    New Architectures Package management
    Collection libraries
    Stream pipelines

    View full-size slide

  45. @pacoworks
    We’re growing our tools
    We’re improving our ecosystem
    We want all of you to be part of it
    45

    View full-size slide

  46. @pacoworks
    Kategory: kategory.io
    Introduction to Kategory:
    tinyurl.com/KatIntro
    KEEP-87:
    github.com/Kotlin/KEEP/pull/87
    Gitter: gitter.im/kategory
    #kategory in KotlinLang
    #kategory in ASG pacoworks.com
    @pacoworks
    github.com/pakoito
    Slides: tinyurl.com/FunKotlinSF17
    46
    Special thanks to all Kategory
    contributors & supporters!

    View full-size slide