Title
p

pniederw

02/09/2017, 3:44 AM
@elizarov If you go forward with renaming
defer
to
async
, will you also rename
future
back to
async
?
e

elizarov

02/09/2017, 5:54 AM
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

pniederw

02/09/2017, 5:55 AM
or perhaps neither, to avoid any confusion. that was my point.
e

elizarov

02/09/2017, 5:59 AM
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

pniederw

02/09/2017, 6:05 AM
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

elizarov

02/09/2017, 6:19 AM
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

pniederw

02/09/2017, 6:33 AM
perhaps not in the most general sense, but I’ve found that all I need is a few functions such as:
suspend fun <S, T> Iterable<S>.runConcurrently(action: suspend S.() -> T): Collection<T>
neither usage nor implementation uses
async
e

elizarov

02/09/2017, 6:34 AM
Good point. Something like this can be provided in
kotlinx.coroutines
, too
p

pniederw

02/09/2017, 6:35 AM
so far I’ve just needed two such functions, the other one being:
suspend fun <S, T> (suspend () -> S).runConcurrentlyWith(action: suspend () -> T): Pair<S, T>
used as follows:
suspendingFunction { … }.runConcurrentlyWith { … }
slightly awkward that I need to use
suspendingFunction
to make the type system understand that the lambda is a suspending lambda.
suspend fun <T> suspendingFunction(f: suspend () -> T): suspend () -> T = f
e

elizarov

02/09/2017, 6:45 AM
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:
coroutine { one() } pairWith coroutine { two() } // result is Pair<A,B>
or
collection.map { coroutine { process(it) } }.all() // result is `List<T>`
p

pniederw

02/09/2017, 6:53 AM
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

elizarov

02/09/2017, 7:21 AM
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.