Why doesn't `coroutineScope {}` have a `CoroutineC...
# coroutines
c
Why doesn't
coroutineScope {}
have a
CoroutineContext
parameter? This seems legitimate to me:
Copy code
coroutineScope(<http://Dispatchers.IO|Dispatchers.IO>) {
    // …
}
AFAIK, the current way to do this is to surround everything with a
withContext
call
k
My understanding is that because
coroutineScope
isn't created with the intent to switch contexts but to create many children of the current context. If it had a context parameter there would be no functional difference between this an
withContext
e
yeah effectively
coroutineScope {}
=
withContext(EmptyCoroutineContext) {}
☝️ 2
today i learned 1
k
And notably, I wouldn't be surprised if
withContext
is a less efficient function than
coroutineScope
simply because it's expected to do more things.
e
well it is a more complex function for sure. but I think it's only significantly more expensive if it has to change dispatchers; otherwise, maybe it results in some extra allocations but I don't think it should be much different
k
Yup. Looking at the code now. The body of the
coroutineScope
function is essentially copy-pasted into one of the fast paths of
withContext
.
I'd be interested to see one of the maintainers chime in here, but I also suspect it's much nicer to have a function specifically tell you that
coroutineScope
is for the concurrent decomposition of work whereas
withContext
has a much broader remit. For example, it's not immediately obvious to people what
withContext(EmptyCoroutineContext)
would even be doing.
o
it looks like
withContext
does some extra synchronization, doesn't it? https://www.baeldung.com/kotlin/withcontext-vs-async-await
e
that is the same as every other suspend function, including
coroutineScope
👌 1
o
but if the blocks are executed in different system threads (due to dispatchers), then in some cases sequential execution may not be required and the blocks could be executed in parallel. Regular suspend functions of the same job are executed in the same system thread in most cases (UI for example). Whereas withContext blocks could be comleted in any random order, hypothetically, but it isn't. well, async/await does
k
Copy code
suspend fun foo() {
  withContext(Dispatchers.Default) {
    println("first")
  }
  withContext(Dispatchers.Default) {
    println("second")
  }
}
Just because withContext is called twice doesn't mean that it will automatically run them concurrently
A call to withContext will suspend until its body has completed, just like
coroutineScope
💯 1
o
yes, Kevin's third answer is perfect. But it's just for fun 😂
j
The point of
coroutineScope
is to give you access to the methods on
CoroutineScope
, like
launch
. If you just want to switch contexts, use
withContext
.