<@U2E974ELT> If you go forward with renaming `defe...
# coroutines
p
@elizarov If you go forward with renaming
defer
to
async
, will you also rename
future
back to
async
?
e
pniederw:
async
and
future
return different future classes.
async
result type is
Deferred
, while
future
result type is
CompletableFuture
. They cannot both have the same name. Which one to call
async
then? The one that returns
Deferred
, of course, because it works anywhere (including any Android version), while
CompletableFuture
is only available on JDK8 and latest Androids.
p
or perhaps neither, to avoid any confusion. that was my point.
e
That was one of the original reasons not to call it
async
(different libs might want to use different futures), but we'd rather nudge people into using this particular implementation of futures, since it does not have any blocking operations (better for coroutines -- less error-prone), has clear exception-transparency semantics, supports laziness, and will work with upcoming
select
p
for network services, your network framework/library of choice will dictate which future to use. on the jvm, they either come with their own or use
CompletableFuture
. that’s my perspective on this topic.
within my own code, I just have a few combinators for suspend lambdas, e.g. to wait for all suspend lambdas to complete. no need for futures.
e
The basic need for `async`/`await` is to serve as a learning "bridge" to help people coming from other languages. As they get familiar with concepts of Kotlin coroutines, they'll realize that they don't need to use any kind of futures that much often. You might have noticed, that coroutines guide has only a cursory overview of deferred computations.
👍 1
Yet, combinators is another reason. There is no easy way to "wait for all suspend lambdas to complete" but using
async
.
p
perhaps not in the most general sense, but I’ve found that all I need is a few functions such as:
Copy code
suspend fun <S, T> Iterable<S>.runConcurrently(action: suspend S.() -> T): Collection<T>
neither usage nor implementation uses
async
e
Good point. Something like this can be provided in
kotlinx.coroutines
, too
p
so far I’ve just needed two such functions, the other one being:
Copy code
suspend fun <S, T> (suspend () -> S).runConcurrentlyWith(action: suspend () -> T): Pair<S, T>
used as follows:
Copy code
suspendingFunction { … }.runConcurrentlyWith { … }
slightly awkward that I need to use
suspendingFunction
to make the type system understand that the lambda is a suspending lambda.
Copy code
suspend fun <T> suspendingFunction(f: suspend () -> T): suspend () -> T = f
e
I was thinking at one point on some kind of general wrapper to reify suspendable computation of this kind with some nice, but shorte names. Not make them directly extensions to suspending functions, but a wrapper. Something like:
Copy code
coroutine { one() } pairWith coroutine { two() } // result is Pair<A,B>
or
Copy code
collection.map { coroutine { process(it) } }.all() // result is `List<T>`
p
that’s just a slightly different future api though, right? whereas my approach is more direct and doesn’t require dealing with futures, at the expense of being less flexible.
back when I was using futures everywhere, I had functions such as
fun Iterable<CompletableFuture>.await()
.
extension functions for the win
e
Maybe they should be directly extensions to suspending functions, but that looks like "funKtionale" to me. It is not an idiomatic Kotlin style to have extensions on functional types. I don't know what is the best way to do it yet.