https://kotlinlang.org logo
Title
m

molikuner

08/13/2019, 6:36 PM
Hey, I'm just reading the introduction to Channels. Immediately after reading the first example with a function which creates a Chanel, I asked myself why they use an extension function for the CoroutineContext instead of just marking the function a suspend function. Original example:
fun CoroutineScope.produceSquares(): ReceiveChannel<Int> = produce {
    for (x in 1..5) send(x * x)
}
What I would expect:
suspend fun produceSquares(): ReceiveChannel<Int> = produce {
    for (x in 1..5) send(x * x)
}
Later in the document you can find:
All functions that create coroutines are defined as extensions on CoroutineScope, so that we can rely on structured concurrency to make sure that we don't have lingering global coroutines in our application.
But doesn't the
suspend
keyword does exactly that? It makes the current CoroutineContext implicitly available to the called function?
o

octylFractal

08/13/2019, 6:39 PM
CoroutineContext
!=
CoroutineScope
. Scope is generally used to start new coroutines, like with
produce
. It's hard for me to word the exact reason why
suspend
doesn't implicitly have it available, but it has to do with structured concurrency. If you want a CoroutineScope in
suspend
functions, you typically use the
coroutineScope
function
m

molikuner

08/13/2019, 6:47 PM
Okay, thanks.
z

Zach Klippenstein (he/him) [MOD]

08/14/2019, 6:03 PM
It's also because the function doesn't actually suspend, it always returns immediately. Using a scope receiver indicates (and enforces) this. In general, functions that return channels or flows shouldn't suspend, since their return type already expresses asynchrony.
👍 1
m

molikuner

08/14/2019, 6:04 PM
Somehow that makes sense 😂