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

Kyo - Functional Scala 2023

Flavio Brasil
November 30, 2023

Kyo - Functional Scala 2023

Kyo is a next-generation effect system that introduces an approach based on algebraic effects to deliver straightforward APIs in the pure Functional Programming paradigm. Unlike similar solutions, Kyo achieves this without inundating developers with esoteric concepts from Category Theory or using cryptic symbolic operators. This results in a development experience that is both intuitive and robust.

Kyo generalizes the innovative effect rotation mechanism introduced by ZIO. While ZIO restricts effects to two channels, namely dependency injection and short-circuiting, Kyo allows for an arbitrary number of effectful channels. This enhancement offers developers greater flexibility in effect management and simplifies Kyo's internal codebase through more principled design patterns.

In addition to this novel approach to effect handling, Kyo provides seamless direct syntax inspired by Monadless and a comprehensive set of built-in effects like Aborts for short-circuiting, Envs for dependency injection, and Fibers for green threads with fine-grained uncooperative preemption.

After over two years in development, the first public release of the project will be made during Functional Scala 2023. Attendees will also be treated to benchmark results that showcase Kyo's unparalleled performance.

Flavio Brasil

November 30, 2023
Tweet

Other Decks in Programming

Transcript

  1. Releasing Kyo:
    When Performance Meets Elegance In Scala
    Flavio Brasil
    Functional Scala 2023

    View full-size slide

  2. How can I build
    solutions that are

    View full-size slide

  3. ●Simple
    ●Safe
    ●Fast
    How can I build
    solutions that are
    ?

    View full-size slide

  4. Activate
    My first open
    source project

    https://github.com/fwbrasil/activate

    View full-size slide

  5. Bond
    Type-level
    validation
    https://github.com/fwbrasil/bond

    View full-size slide

  6. Clump: Batching

    https://github.com/getclump/clump

    Future: High-perf futures
    https://github.com/traneio/future
    Arrows: Monadic staging

    https://github.com/traneio/arrows
    NDBC: Async DB drivers
    https://github.com/traneio/ndbc

    View full-size slide

  7. Quill
    Compile-time
    Language
    Integrated Queries
    https://github.com/zio/zio-quill

    View full-size slide

  8. Monadless
    Syntactic sugar
    for monads
    https://github.com/monadless/monadless

    View full-size slide

  9. When your hobby
    becomes your
    worry …
    It’s time for a break!

    View full-size slide

  10. A decade working on
    large-scale systems
    ● SoundCloud, Twitter, Nubank
    ● Delivered major performance
    optimizations for Finagle, Twitter
    Future, Stitch, Graal, Clojure
    ● Saw hundreds of crashes
    Scala — Graal

    ScalaMatsuri 2019
    https://youtu.be/a6dK3eXhO7k?si=T775S1sKFu5B4wSf

    View full-size slide

  11. Functional
    Programming is
    great

    View full-size slide

  12. Functional
    Programming is
    great (but terrible)

    View full-size slide

  13. Interpretation
    overhead
    User-level interpreted language
    Highly dynamic execution
    High allocation rate

    View full-size slide

  14. Code complexity

    View full-size slide

  15. Innovation
    begins with
    broken rules

    View full-size slide

  16. ZIO[R, E, A]

    View full-size slide

  17. ZIO[R, E, A]
    type IO[+E, +A] = ZIO[Any, E, A]


    type Task[+A] = ZIO[Any, Throwable, A]


    type RIO[-R, +A] = ZIO[R, Throwable, A]


    type UIO[+A] = ZIO[Any, Nothing, A]


    type URIO[-R, +A] = ZIO[R, Nothing, A]


    View full-size slide

  18. ZIO[R, E, A]
    Do we really need a fixed arity?
    Why assume the computation uses IO and Async?
    Why only dependency injection and short-circuiting?
    What if we could express an unbounded number of effects?

    View full-size slide

  19. Let’s break
    the rules
    again :)

    View full-size slide

  20. ZIO[R, E, A]

    View full-size slide

  21. A > (Envs[R] & Aborts[E])

    View full-size slide

  22. A > Aborts[E]

    View full-size slide

  23. A > Any
    A pure value 😱

    View full-size slide

  24. A > (Envs[Database] & Aborts[DBException])

    View full-size slide

  25. A > (Envs[Database] & Aborts[DBException] & IOs)

    View full-size slide

  26. type Databases = Envs[Database] & Aborts[DBException] & IOs
    A > Databases

    View full-size slide

  27. type Caches = Envs[Cache] & IOs
    type Databases = Envs[Database] & Aborts[DBException] & IOs
    A > (Databases & Caches)

    View full-size slide

  28. type Caches = Envs[Cache] & IOs
    type Databases = Envs[Database] & Aborts[DBException] & Caches
    A > Databases

    View full-size slide

  29. Leveraging
    Scala’s advanced
    type system

    View full-size slide

  30. A > (Envs[Database] & Aborts[DBException] & IOs)

    View full-size slide

  31. A > (Aborts[DBException] & Envs[Database] & IOs)

    View full-size slide

  32. A > (Aborts[DBException] & IOs & Envs[Database])
    Unordered Pending Effects

    View full-size slide

  33. opaque type >[+T, -S]
    Original Design

    View full-size slide

  34. opaque type >[+T, -S] = T | Kyo[_, _, _, T, S]
    Original Design

    View full-size slide

  35. opaque type >[+T, -S] = T | Kyo[_, _, _, T, S]
    Original Design
    Implicit conversions


    from/to T > Any and T

    View full-size slide

  36. opaque type >[+T, -S] = T | Kyo[_, _, _, T, S]
    After Scala 2 support

    View full-size slide

  37. type >[+T, -S] >: T
    After Scala 2 support

    View full-size slide

  38. type >[+T, -S] >: T
    After Scala 2 support
    Any type T is a subclass of T > Any


    View full-size slide

  39. type >[+T, -S] >: T
    After Scala 2 support
    Any type T is a subclass of T > Any


    val a: Int > Any = 1


    val b: Int = a.pure

    View full-size slide

  40. Effect Widening
    val a: Int > Any = 1


    View full-size slide

  41. Effect Widening
    val a: Int > Any = 1



    val b: Int > Options = a

    View full-size slide

  42. Effect Widening
    val a: Int > Any = 1



    val b: Int > Options = a


    val c: Int > (Options & Tries) = b


    View full-size slide

  43. Effect Widening
    val a: Int > Any = 1



    val b: Int > Options = a


    val c: Int > (Options & Tries) = b


    val d: Int > (Options & Tries) = 42

    View full-size slide

  44. def example1(v: Int > (Options & Tries)) =


    v.map(_ + 1)


    Fluent APIs

    View full-size slide

  45. def example1(v: Int > (Options & Tries)) =


    v.map(_ + 1)


    def example2(v: Int > Tries) =


    example1(v)

    Fluent APIs

    View full-size slide

  46. Fluent APIs
    def example1(v: Int > (Options & Tries)) =


    v.map(_ + 1)


    def example2(v: Int > Tries) =


    example1(v)


    def example3 = example1(42)

    View full-size slide

  47. There is no
    flatMap 

    (or map depending
    on how you see it)

    View full-size slide

  48. def example(


    a: Int > Options,


    b: Int > Tries


    ): Int > (Options & Tries) =


    a.flatMap(v => b.map(_ + v))

    View full-size slide

  49. def example(


    a: Int > Options,


    b: Int > Tries


    ): Int > (Options & Tries) =


    a.map(v => b.map(_ + v))

    View full-size slide

  50. Direct
    syntax
    support

    View full-size slide

  51. Quick
    effects
    rundown

    View full-size slide

  52. Envs: Dependency Injection

    View full-size slide

  53. Envs: Dependency Injection

    View full-size slide

  54. Aborts: Short Circuiting

    View full-size slide

  55. Aborts: Short Circuiting

    View full-size slide

  56. Resources: Resource Safety


    View full-size slide

  57. Lists: Exploratory Branching


    View full-size slide

  58. Lists: Exploratory Branching


    View full-size slide

  59. Fibers: Green Threads


    View full-size slide

  60. Fibers: Green Threads


    View full-size slide

  61. Requests: HTTP Client via Sttp


    View full-size slide

  62. Requests: HTTP Client via Sttp


    View full-size slide

  63. Locals Scoped Values
    Aspects Aspect-Oriented Programming
    Options Optional Values
    Tries Exception Handling
    Consoles Console Interaction
    Clocks Time Management
    Randoms Random Values
    Loggers Logging
    Stats Observability
    Queues Concurrent Queuing
    Channels Backpressured Communication
    Hubs Broadcasting with Backpressure
    Meters Computational Limits
    Timers Scheduled Execution
    Latches Fiber Coordination
    Atomics Concurrent State
    Adders Concurrent Accumulation
    Caches Memoized Functions via Caffeine

    View full-size slide

  64. Unparalleled
    performance

    View full-size slide

  65. https://tinyurl.com/kyo-benchs

    View full-size slide

  66. Targets
    Kyo, Cats-effect, ZIO, Ox
    Data
    Throughput, Allocation, Profiling
    Environment
    Github Large Runner
    8 cores, 32 GB
    Ubuntu 22.04
    Source code 

    https://github.com/getkyo/kyo/tree/main/kyo-bench/src/main/scala/kyo/bench
    https://tinyurl.com/kyo-benchs

    View full-size slide

  67. Kyo’s
    throughput is
    249% higher
    than the best contender
    (average across benchmarks)

    View full-size slide

  68. Overhead-free abstraction

    View full-size slide

  69. Overhead-free abstraction

    View full-size slide

  70. Overhead-free abstraction

    View full-size slide

  71. High-performance
    asynchronous
    primitives

    View full-size slide

  72. High-performance
    asynchronous
    primitives

    View full-size slide

  73. High-performance
    asynchronous
    primitives

    View full-size slide

  74. Low-overhead
    Fibers
    (only 32B
    each!)

    View full-size slide

  75. Low-overhead
    Fibers
    (only 32B
    each!)

    View full-size slide

  76. Low-overhead
    Fibers
    (only 32B
    each!)

    View full-size slide

  77. Blazing-fast channels

    View full-size slide

  78. Blazing-fast channels

    View full-size slide

  79. Blazing-fast channels

    View full-size slide

  80. How about
    Caprese?

    View full-size slide

  81. Caprese
    Kyo delivers
    Caprese’s
    key promises

    View full-size slide

  82. Caprese
    Kyo delivers
    Caprese’s
    key promises
    without language
    changes

    View full-size slide

  83. Caprese
    Kyo delivers
    Caprese’s
    key promises
    without language
    changes,
    with a complete set of
    effects

    View full-size slide

  84. Caprese
    Kyo delivers Caprese’s
    key promises
    without language
    changes,
    with a complete set of
    effects
    and next-level
    performance

    View full-size slide

  85. Caprese
    Kyo delivers Caprese’s
    key promises
    without language changes,
    with a complete set of
    effects
    and next-level
    performance
    in Scala 2, 3, and JS

    View full-size slide

  86. Caprese
    Kyo delivers Caprese’s
    key promises
    without language changes,
    with a complete set of
    effects
    and next-level performance
    in Scala 2, 3, and JS
    today

    View full-size slide

  87. CREDITS: This presentation template was created
    by Slidesgo, and includes icons by Flaticon and
    infographics & images by Freepik
    Thanks!
    Any questions?
    https://getkyo.io
    https://dev.to/fwbrasil
    @fbrasisil

    View full-size slide