producer_kt.kt
# coroutines
s
producer_kt.kt
g
Although CoroutineScope(coroutineContext) works I wouldn’t recommend use this approach and instead pass coroutine scope explictly or use extension function
t
@gildor I didn't know you could get the scope that way. Why is this discouraged?
g
Nothing completely wrong there, but this is way that makes scope handling implicit, you cannot start this suspend function and you don’t know that there is background coroutine that will attach to calling scope
t
Yes, this is true. But using the scope as implicit receiver leads to difficult code, too. We had something like this example in our code base:
Copy code
suspend fun runInScope(body: suspend () -> Unit) {
    coroutineScope {
        body()
    }
}

fun main() {
    runBlocking {
        try {
            runInScope {
                launch {
                    throw RuntimeException("dead")
                }
            }
        } catch (e: Exception) {
            println("caught")
        }
    }
}
And this compiles fine but kills the whole application instead of printing
caught
because somebody forgot to add
CoroutineScope.
receiver to the
body
parameter. Correct code:
Copy code
suspend fun runInScope(body: suspend CoroutineScope.() -> Unit) {
    coroutineScope {
        body()
    }
}

fun main() {
    runBlocking {
        try {
            runInScope {
                launch {
                    throw RuntimeException("dead")
                }
            }
        } catch (e: Exception) {
            println("caught")
        }
    }
}
I think maybe the scope should always be passed explicitly
g
I don't understand from this example why do you need runInScope, you already have scope from runBlocking
Also not sure why do you need runInScope in general, this is just useless wrapper on top of coroutineScope function that doesn't add anything to coroutineScope function
Maybe it's just too synthetic example, because launch is also not needed here
t
Yes of course, this is synthetic. The point is that it's easy to
launch
on the wrong receiver. If you change the signature of
runInScope
, there is no visual change on the calling site but something completely different happens.
g
I see what you mean, good illustration that implicit coroutine scope maybe confusing