https://kotlinlang.org logo
Join the conversationJoin Slack
Channels
100daysofcode
100daysofkotlin
100daysofkotlin-2021
advent-of-code
aem
ai
alexa
algeria
algolialibraries
amsterdam
android
android-architecture
android-databinding
android-studio
androidgithubprojects
androidthings
androidx
androidx-xprocessing
anime
anko
announcements
apollo-kotlin
appintro
arabic
argentina
arkenv
arksemdevteam
armenia
arrow
arrow-contributors
arrow-meta
ass
atlanta
atm17
atrium
austin
australia
austria
awesome-kotlin
ballast
bangladesh
barcelona
bayarea
bazel
beepiz-libraries
belgium
berlin
big-data
books
boston
brazil
brikk
budapest
build
build-tools
bulgaria
bydgoszcz
cambodia
canada
carrat
carrat-dev
carrat-feed
chicago
chile
china
chucker
cincinnati-user-group
cli
clikt
cloudfoundry
cn
cobalt
code-coverage
codeforces
codemash-precompiler
codereview
codingame
codingconventions
coimbatore
collaborations
colombia
colorado
communities
competitive-programming
competitivecoding
compiler
compose
compose-android
compose-desktop
compose-hiring
compose-ios
compose-mp
compose-ui-showcase
compose-wear
compose-web
connect-audit-events
corda
cork
coroutines
couchbase
coursera
croatia
cryptography
cscenter-course-2016
cucumber-bdd
cyprus
czech
dagger
data2viz
databinding
datascience
dckotlin
debugging
decompose
decouple
denmark
deprecated
detekt
detekt-hint
dev-core
dfw
docs-revamped
dokka
domain-driven-design
doodle
dsl
dublin
dutch
eap
eclipse
ecuador
edinburgh
education
effective-kotlin
effectivekotlin
emacs
embedded-kotlin
estatik
event21-community-content
events
exposed
failgood
fb-internal-demo
feed
firebase
flow
fluid-libraries
forkhandles
forum
fosdem
fp-in-kotlin
framework-elide
freenode
french
fritz2
fuchsia
functional
funktionale
gamedev
ge-kotlin
general-advice
georgia
geospatial
german-lang
getting-started
github-workflows-kt
glance
godot-kotlin
google-io
gradle
graphic
graphkool
graphql
graphql-kotlin
graviton-browser
greece
grpc
gsoc
gui
hackathons
hacktoberfest
hamburg
hamkrest
helios
helsinki
hexagon
hibernate
hikari-cp
hire-me
hiring
hongkong
hoplite
http4k
hungary
hyderabad
image-processing
india
indonesia
inkremental
intellij
intellij-plugins
intellij-tricks
internships
introduce-yourself
io
ios
iran
israel
istanbulcoders
italian
jackson-kotlin
jadx
japanese
jasync-sql
java-to-kotlin-refactoring
javadevelopers
javafx
javalin
javascript
jdbi
jhipster-kotlin
jobsworldwide
jpa
jshdq
juul-libraries
jvm-ir-backend-feedback
jxadapter
k2-early-adopters
kaal
kafka
kakao
kalasim
kapt
karachi
karg
karlsruhe
kash_shell
kaskade
kbuild
kdbc
kgen-doc-tools
kgraphql
kinta
klaxon
klock
kloudformation
kmdc
kmm-español
kmongo
knbt
knote
koalaql
koans
kobalt
kobweb
kodein
kodex
kohesive
koin
koin-dev
komapper
kondor-json
kong
kontent
kontributors
korau
korean
korge
korim
korio
korlibs
korte
kotest
kotest-contributors
kotless
kotlick
kotlin-asia
kotlin-beam
kotlin-by-example
kotlin-csv
kotlin-data-storage
kotlin-foundation
kotlin-fuel
kotlin-in-action
kotlin-inject
kotlin-latam
kotlin-logging
kotlin-multiplatform-contest
kotlin-mumbai
kotlin-native
kotlin-pakistan
kotlin-plugin
kotlin-pune
kotlin-roadmap
kotlin-samples
kotlin-sap
kotlin-serbia
kotlin-spark
kotlin-szeged
kotlin-website
kotlinacademy
kotlinbot
kotlinconf
kotlindl
kotlinforbeginners
kotlingforbeginners
kotlinlondon
kotlinmad
kotlinprogrammers
kotlinsu
kotlintest
kotlintest-devs
kotlintlv
kotlinultimatechallenge
kotlinx-datetime
kotlinx-files
kotlinx-html
kotrix
kotson
kovenant
kprompt
kraph
krawler
kroto-plus
ksp
ktcc
ktfmt
ktlint
ktor
ktp
kubed
kug-leads
kug-torino
kvision
kweb
lambdaworld_cadiz
lanark
language-evolution
language-proposals
latvia
leakcanary
leedskotlinusergroup
lets-have-fun
libgdx
libkgd
library-development
linkeddata
lithuania
london
losangeles
lottie
love
lychee
macedonia
machinelearningbawas
madrid
malaysia
mathematics
meetkotlin
memes
meta
metro-detroit
mexico
miami
micronaut
minnesota
minutest
mirror
mockk
moko
moldova
monsterpuzzle
montreal
moonbean
morocco
motionlayout
mpapt
mu
multiplatform
mumbai
munich
mvikotlin
mvrx
myndocs-oauth2-server
naming
navigation-architecture-component
nepal
new-mexico
new-zealand
newname
nigeria
nodejs
norway
npm-publish
nyc
oceania
ohio-kotlin-users
oldenburg
oolong
opensource
orbit-mvi
osgi
otpisani
package-search
pakistan
panamá
pattern-matching
pbandk
pdx
peru
philippines
phoenix
pinoy
pocketgitclient
polish
popkorn
portugal
practical-functional-programming
proguard
prozis-android-backup
pyhsikal
python
python-contributors
quasar
random
re
react
reaktive
realm
realworldkotlin
reductor
reduks
redux
redux-kotlin
refactoring-to-kotlin
reflect
refreshversions
reports
result
rethink
revolver
rhein-main
rocksdb
romania
room
rpi-pico
rsocket
russian
russian_feed
russian-kotlinasfirst
rx
rxjava
san-diego
science
scotland
scrcast
scrimage
script
scripting
seattle
serialization
server
sg-user-group
singapore
skia-wasm-interop-temp
skrape-it
slovak
snake
sofl-user-group
southafrica
spacemacs
spain
spanish
speaking
spek
spin
splitties
spotify-mobius
spring
spring-security
squarelibraries
stackoverflow
stacks
stayhungrystayfoolish
stdlib
stlouis
strife-discord-lib
strikt
students
stuttgart
sudan
swagger-gradle-codegen
swarm
sweden
swing
swiss-user-group
switzerland
talking-kotlin
tallinn
tampa
teamcity
tegal
tempe
tensorflow
terminal
test
testing
testtestest
texas
tgbotapi
thailand
tornadofx
touchlab-tools
training
tricity-kotlin-user-group
trójmiasto
truth
tunisia
turkey
turkiye
twitter-feed
uae
udacityindia
uk
ukrainian
uniflow
unkonf
uruguay
utah
uuid
vancouver
vankotlin
vertx
videos
vienna
vietnam
vim
vkug
vuejs
web-mpp
webassembly
webrtc
wimix_sentry
wwdc
zircon
Powered by Linen
arrow
  • i

    Ifvwm

    07/09/2020, 3:03 AM
    if there is Some(f : (A)->B), how I can make f work on another Some object? since map, ap, and flatMap all takes a function
    p
    • 2
    • 1
  • n

    Nicolas Lattuada

    07/09/2020, 8:34 AM
    hi all 👋 With arrow optics is it possible to modify multiple values in the same instruction? maybe something like :
    fun t(dto: UpgradeTrigger) {
        UpgradeTrigger.run {
            title.modify(dto) { it.toUpperCase() }
            subtitle.modify(dto) { it.toUpperCase() }
        }
    }
    s
    s
    j
    • 4
    • 22
  • a

    AdrianRaFo

    07/09/2020, 2:11 PM
    Does Arrow have the
    tupled
    function for data classes?
    s
    r
    • 3
    • 3
  • d

    dimsuz

    07/10/2020, 11:15 AM
    Hi! I want to ask a non-arrow related question, mainly because I think that arrow core developers have a lot of experience with kotlinc's type inference and maybe you'll be able to help me in finding a workaround/solution.
    s
    • 2
    • 12
  • n

    nicopasso

    07/10/2020, 11:40 AM
    Hi!! I’m playing around with Kleisli but I don’t understand how to use
    map2
    with the two Kleisli instances I’ve created,
    readNameKCO
    and
    readAgeKCO
    . My goal is to create a new Kleisli that generates a
    Person
    instance from a
    Config
    one and then using it with
    personK.run(config)
    . I’m doing something wrong for sure but I don’t quite understand out to build the
    personK
    Kleisli
    j
    j
    • 3
    • 3
  • m

    Michael Marth

    07/14/2020, 8:44 AM
    Probably a very naive question, but I can't find an easy solution for: What's the most concise way of turning a
    List<Option<A>>
    into a
    Option<List<A>>
    ? So if any if the `Option`s in the original List is
    None
    , the whole return type should be
    None
    .
    p
    • 2
    • 2
  • r

    raulraja

    07/14/2020, 10:58 AM
    Learn more about optics today in this talk from @simon.vergauwen https://twitter.com/47deg/status/1281891101151055874?s=19
    👍 9
    a
    s
    +2
    • 5
    • 14
  • n

    Nicolas Lattuada

    07/15/2020, 8:48 AM
    Hello all 👋 I am trying to define a typeclass, I have the following
    data class Bank(val account: ErrorBox<Account>)
        data class Account(val balance: Int, val name: String)
    
        @JsonDeserialize(using = ErrorBoxDeserializer::class)
        class ErrorBox<T>(var failure: Throwable?, var value: T?)
    and in my ErrorBoxDeserializer if the json is valid, I return a value otherwise an error. How would you do in order to give monad super powers to ErrorBox? it would be great if it could behave just like Either
    r
    • 2
    • 6
  • i

    Ian D

    07/19/2020, 2:14 AM
    Does anyone have an example of the new "box" for
    either
    ?
    s
    • 2
    • 5
  • b

    Bora Gonul

    07/20/2020, 6:02 AM
    if I add extensions to Apply, I have 87 fields 🙂
    s
    • 2
    • 1
  • j

    Jakub Pi

    07/21/2020, 1:16 AM
    I saw a new addition a few weeks ago to arrow where you could specify a timeout/retry policy. I'm curious what an FP approach to designing a Circuit Breaker might look like. How might you keep your timeouts synchronized across your async layer without using side effects?
    s
    • 2
    • 5
  • d

    dnowak

    07/21/2020, 1:20 PM
    Hi, I would like to collect a metric (a timer) of IO<Either<E, A>> execution. I can measure the time with bracket and result with flatTap. But what I want to achieve is a timer tagged with the result (success, error, failure). Any ideas on how I can get time & result of IO execution?
    • 1
    • 1
  • s

    Sagar Suri

    07/21/2020, 1:31 PM
    Hey team, How can I flatten List<Either<Exception, Value>> to List<Value>??
    j
    j
    • 3
    • 9
  • j

    julian

    07/22/2020, 7:14 PM
    I'm using
    implementation "io.arrow-kt:arrow-generic:0.10.5
    in the
    build.gradle
    file of an Android project. But this doesn't seem to make
    Coproduct
    available. Is there something else I need to do?
    • 1
    • 1
  • s

    simon.vergauwen

    07/23/2020, 10:51 AM
    API docs of Arrow Fx Coroutines are up here for those interested: https://arrow-kt.io/docs/next/apidocs/arrow-fx-coroutines/index.html Feedback and contributions to docs very welcome!! All methods & data types are documented already.
    🔝 1
    j
    b
    • 3
    • 10
  • m

    marc0der

    07/23/2020, 12:18 PM
    Hi all 👋, I'm currently wading through the treacherous waters of Applicative and Traversable functors in the FP in Kotlin book 😅. I'm having some issues expressing some of the more advanced concepts like product, fusion and composition of types like
    Applicative
    and
    Traverse
    . An example of product would be when translating the following function from Scala:
    def compose[G[_]](G: Applicative[G]): Applicative[({type f[x] = F[G[x]]})#f] = {
      val self = this
      new Applicative[({type f[x] = F[G[x]]})#f] {
       def unit[A](a: => A) = self.unit(G.unit(a))
       override def map2[A,B,C](fga: F[G[A]], fgb: F[G[B]])(f: (A,B) => C) =
        self.map2(fga, fgb)(G.map2(_,_)(f))
      }
     }
    The problem here being how to express that type lambda
    ({type f[x] = F[G[x]]})#f
    . The
    unit
    and
    map2
    functions should return types like
    (F[A], G[A])
    , translated to Kotlin that would be
    Tuple2<Kind<F, A>, Kind<G, A>>
    . From what I can tell, this simply isn't possible in Kotlin, but maybe someone else can see a way of achieving this that I just can't see.
    j
    • 2
    • 8
  • j

    julian

    07/23/2020, 9:46 PM
    Much (most?) of the Arrow code I've looked at conforms to 2 space indentation. I've always used 4. But it seems like the more functional-style code I write, the more I run out of horizontal space. Is that typical? What's the reasoning for the 2 space style chosen for Arrow? Is it a carryover from Scala conventions?
    r
    b
    p
    • 4
    • 5
  • t

    tavish pegram

    07/24/2020, 4:33 PM
    I’m messing around with trying to implemented a
    Constrained<T>
    as a DSL for domain modeling (inspired by this and other similar talks

    https://www.youtube.com/watch?v=PLFl95c-IiU▾

    ). What I would really love is to make it a one liner to create constrained types with private constructors so that it becomes effortless to use in domain modeling. Currently in Kotlin the way to implement something like this is
    data class Natural private constructor(val value: Int) {
        companion object {
            fun fromInt(v: Int): Either<NaturalFromIntFailure, Natural> =
                when (v < 0) {
                    true -> NaturalFromIntFailure.IntMustBeGTEZero.left()
                    false -> Natural(v).right()
                }
        }
    }
    sealed class NaturalFromIntFailure {
        object IntMustBeGTEZero: NaturalFromIntFailure()
    }
    which is fine I guess, but if people want to get in the habit of using constrained domain types for every type in a domain (as is recommended), this starts to become tedious and starts to lead toward cutting corners on these types. From reading about dependent types, it would be awesome to do something like
    typealias Natural = Constrained<Int><{ 
        when (it < 0) {
            true -> NaturalFromIntFailure.IntMustBeGTEZero.left()
            false -> Natural(it).right()
        }
    }>
    val x = Natural(-1) // Doesnt compile
    val y = Natural.new(-1) // Left(NaturalFromIntFailure.IntMustBeGTEZero)
    Alas messing around hasn’t gotten me close to this at all. This is the best I’ve gotten so far which is still a little too verbose , doesn’t have a consistent interface for constrained types, and has some public “private” methods :(
    /*
    ----------------------------------------------------------------------------------------------------
    Generic bits
     */
    data class Constrained<A> private constructor(val a: A) {
        companion object {
            fun <A, E>validateNew(a: A, validator: (A) -> Either<E, A>): Either<E, Constrained<A>> =
                validator(a).fold(
                    { it.left() },
                    { Constrained(a).right() }
                )
        }
    }
    
    /*
    ----------------------------------------------------------------------------------------------------
    Consumer Implementation
     */
    typealias Natural = Constrained<Int>
    sealed class NaturalFromIntFailure {
        object IntMustBeGTEZero: NaturalFromIntFailure()
    }
    
    fun natural(a: Int) = Natural.validateNew<Int, NaturalFromIntFailure>(a) {
        when (it < 0) {
            true -> NaturalFromIntFailure.IntMustBeGTEZero.left()
            false -> it.right()
        }
    }
    /*
    ----------------------------------------------------------------------------------------------------
    Examples
     */
    
    val a = Natural(-1) // Doesn't compile
    val b = natural(1)  // Result: Right(Natural(1))
    val c = natural(-1) // Result: Left(NaturalFromIntFailure.IntMustBeGTEZero)
    Does anyone have any suggestions on if there are any tools available in arrow that could move this closer to the ideal state?
    :thread-please: 1
    r
    • 2
    • 16
  • p

    PhBastiani

    07/25/2020, 12:43 PM
    The new 'suspend' API is very interesting. I started to write some pieces of code ... But, to go further in my investigations, the absence of typeclass disturbs me: how to write a polymorphic program? I missed something between Async/ApplicativeError and suspend datatypes ! I understand: if I want to play with F, ..., i need to build datatypes over fxcoroutine. Is the right way ?
    r
    j
    • 3
    • 59
  • a

    Alexander Schell

    07/29/2020, 5:22 AM
    Hello Sorry for the dumb question but is there a way to transform a SequenceK<Either<Throwable, Iterable<T>>> to a SequenceK<Either<Throwable, T>> while preservering the original potential throwable? I'm tinkering around with this problem but without getting anywhere... =( Thanks!
    p
    p
    • 3
    • 25
  • j

    Jose Antonio Jimenez

    07/29/2020, 3:00 PM
    Hi, i am trying to do something like this:
    val result = Either.right(value).map { suspendFunction(it) }
    s
    s
    • 3
    • 2
  • j

    Jose Antonio Jimenez

    07/29/2020, 3:03 PM
    Then i will use the snapshot
    a
    • 2
    • 1
  • s

    Satyam Agarwal

    07/29/2020, 3:19 PM
    Will 0.10.6 be released or we will see only 0.11.0 ?
    a
    g
    • 3
    • 4
  • b

    Big Chungus

    07/30/2020, 10:18 AM
    What platforms is arrow available on? Couldn't find anything on this in the docs.
    s
    • 2
    • 3
  • s

    Satyam Agarwal

    07/31/2020, 7:35 AM
    @raulraja I am very interested in doing https://kotlinlang.slack.com/archives/C5UPMM0A0/p1585855394139500?thread_ts=1585852655.135300&amp;cid=C5UPMM0A0 on version 0.10.4 (which i am using now). Can I implement
    TaskOf<A>
    somehow myself until it gets available in
    0.11.0
    (i am assuming this) ?
    a
    • 2
    • 5
  • g

    Gopal S Akshintala

    08/02/2020, 1:06 PM
    Hi! I am going through this: https://next.arrow-kt.io/docs/fx/polymorphism/#arrow-fx-vs-tagless-final, and there is a mention about Direct relationship between 
    suspend () -> A
     and 
    Kind<F, A>
    . Is there any ongoing development to replace or eliminate higher kinds? If yes, can someone please help me by pointing to a doc or with a simple example. Thanks!
    j
    • 2
    • 3
  • c

    CLOVIS

    08/02/2020, 2:20 PM
    Hi! Thanks to you, I think I finally understand how typeclasses solve the problem of adding new behavior to domain classes (eg. Convert a domain object to JSON, Serialize a domain object, Compare two objects, Display an object, etc). However, I do not understand how typeclasses can be used to add data to an object. I'm trying to model different ‘providers', which can request information from the net to create a specific domain object, let's call it ‘event'. Most properties of events will be identical, but some providers might have additional properties: for instance, maybe two providers can also create sub-events, but a third one cannot. I'd like to be able to conditionally know if a specific property is available on a specific event or not, for example to display the event (only available properties should be displayed). For the use case of ‘one provider lets you edit the event, the others don't', I see how I can leverage typeclasses to specifically add that behavior. However, I don't know how to add data. I thought of three solutions, that I don't find ‘clean', so I'd like to have your thoughts: 1. Use nullable fields for data that is not present on all events That way, it's easy to test if some data is present or not. The code can be very straightforward, but it's not very beautiful that there are many nullable fields on every object. A slightly better solution could be to have every field be an union of the expected data and an
    Unimplemented
    Singleton, but that still doesn't look so good. 2. Use inheritance Create one interface per optional field, and have each provider have its own event implementation that extends the correct interfaces. This could lead to a bit of repetition, though I guess combined with delegation it could look okay. 3. Use WeakHashMap in a typeclass to store the additional information That doesn't seem very nice as well... What do you think?
    j
    s
    • 3
    • 18
  • s

    Slackbot

    08/02/2020, 4:39 PM
    This message was deleted.
    s
    g
    • 3
    • 2
  • j

    julian

    08/02/2020, 7:11 PM
    How does one convert a
    List
    to an
    arrow.fx
    Stream
    using the
    0.11-snapshot
    ? IDE completion doesn't appear to offer an appropriate extension that might do this.
    s
    • 2
    • 3
  • s

    Satyam Agarwal

    08/03/2020, 11:06 AM
    Hei Hei. So I am trying to make a colleague understand
    IO<A>
    . I thought of starting with this line :
    IO<A>
    is just a another way of writing
    suspend () -> Either<Throwable, A>
    is this true ? I grasped this from the PR Simon worked on to bring features from IO to Either using coroutines so that we don’t have to box our types which apparently is costly. I know IO has its own thread pool, works on fibres and not coroutines, but I was wondering if the above statement could be a layman’s explanation ?
    s
    • 2
    • 10
Powered by Linen
Title
s

Satyam Agarwal

08/03/2020, 11:06 AM
Hei Hei. So I am trying to make a colleague understand
IO<A>
. I thought of starting with this line :
IO<A>
is just a another way of writing
suspend () -> Either<Throwable, A>
is this true ? I grasped this from the PR Simon worked on to bring features from IO to Either using coroutines so that we don’t have to box our types which apparently is costly. I know IO has its own thread pool, works on fibres and not coroutines, but I was wondering if the above statement could be a layman’s explanation ?
s

simon.vergauwen

08/03/2020, 12:05 PM
Hey @Satyam Agarwal, That's almost correct.
IO<A>
~>
suspend () -> A
, since
suspend
encapsulates
Throwable
. If you try to run
suspend () -> A
, you always need to provide a function
(Result<A>) -> Unit
in
startCoroutine
when constructing a
Continiuation<A>
. Similarly to
IO
which exposes a function
unsafeRunAsync
which takes a function
(Either<Throwable, A>) -> Unit
. So it's clear these two are the same. Building
IO
is more expensive than using
suspend
since
IO
is build at runtime, and
suspend
is generated by the compiler at compile time. This costs becomes neglectable in heavy concurrent applications with a lot of IO operations, and it becomes more expensive in loops for example.
s

Satyam Agarwal

08/03/2020, 12:07 PM
Awesome. Thank you so much 🙂
s

simon.vergauwen

08/03/2020, 12:07 PM
The
IO
module exposes a set of utilities like
Fiber
,
Resoure
,
Schedule
, dispatchers. and much more to work with
IO
. In the last year I've been working hard on trying to figure out how we could translate all these same principles and patterns from
IO
to
suspend
without losing any features or capabilities. Which finally landed in the PR you probably saw already. The same readme can be found here: https://github.com/arrow-kt/arrow-fx/tree/master/arrow-fx-coroutines
You're very welcome @Satyam Agarwal! If you have any more questions or feedback I'd love to hear it 🙂
s

Satyam Agarwal

08/03/2020, 12:12 PM
Actually. Its related to general async and non-blocking stuff. In my team we are now heavily using ktor with Arrow, and people coming from javascript are writing code in arrow, which is absolutely amazing. They are able to do it without knowing almost anything about these concepts. Since I’ve been writing webapps in arrow for some time now, I’ve found a pattern that is pretty good, and these colleagues just look for examples around these webapp, and mostly it just comes to copy paste. But time to time, when edge cases come, we dive into theses concepts, and then I find myself in a situation where I know how things work and how to play with them, but it becomes hard for me to put them into words to explain to my colleagues. I will paste one such example and would love to hear what you think about it and get your feedback at how can I be better on it.
s

simon.vergauwen

08/03/2020, 12:14 PM
Please do! I'd be happy to clarify any doubts you have in your teams! It's always helpful to supplement docs, or improve APIs 👍
s

Satyam Agarwal

08/03/2020, 12:15 PM
@simon.vergauwen Here I trying to explain to my colleague why I converted my ktor method
fun Application.myModule() : Unit
to
suspend fun <http://Application.my|Application.my> module() : Unit { ... myUnsafeIOWrapped.suspendedCancellable() }
Also he asked about blocking and non-blocking.
s

simon.vergauwen

08/03/2020, 12:31 PM
Yes, that is absolutely correct. I think the biggest problem is that some of the terms aren't well defined in our field, and they often differ a little bit between libraries etc. For example, if we talk about blocking on the JVM we typically talk about operations such as
Thread.sleep
which actually block a thread. Which is problematic on a pool such as
ComputationPool
,
IO.dispatchers().default()
or
Dispatchers.Default
, since those pools are "work-stealing". Meaning they interleave computational work, which is not possible if an operation is blocking the thread. (TL;DR Blocking doesn't allow interleaving of tasks) So a blocking task should be scheduled on an "IO" pool, which creates a new thread per operation. Hence blocking is not a problem, since no interleaving happens on this pool.
IOPool
,
IO.dispatchers().io()
,
<http://Dispatchers.IO|Dispatchers.IO>
, etc. The part about
IO
and
suspend
could be argued about perhaps, since on a back-end requests are running in parallel there is always asynchrony involved. What makes both
IO
and
suspend
so special is that they can wrap a
callback
which regular code cannot. Being able to wrap a callback allows you to jump to a different scheduler, and back, without having to write any of the orchestration around it like you normally would with callbacks.
val result: Result? = ...

runOnComputation { result ->
   runOnIO(result) { res2 ->
      runOnComputation(res) { res3 ->
          finished, return result (???)
          result = res3
      }
    }
}

use result??
compared to
val res = runOnComputation()
val res2 = runOnIO(res)
val res3 runOnComputation(res2)
Where you can implement
runComputation
with
suspendCoroutine
like you could do with
IO.async
.
Where or how they run can still be completely dictated by the caller, as you mention, this is Ktor in this case. And it can run our functions using
parTraverse
or
parTupled
or run them synchronously depending on the config we passed to Ktor. Similarly you can make functions
uncancellable
by wrapping them in
uncancellable { }
. Even if they contain cancellable code.
s

Satyam Agarwal

08/03/2020, 12:39 PM
Wow. Thank you so much. I can basically copy paste this so that my team can understand these things even more. Thank you 🙂
🙌 1
View count: 5