One of the people behind Kotlin wrote this article called Explicit concurrency, in it, when comparing suspending functions vs CoroutineScope
extensions he says:
As a rule of thumb, you should prefer suspending functions, since concurrency is not a safe default to have. Anyone with a suspending function at hand can explicitly use launch { … } to initiate its concurrent execution.
I don’t understand what is meant by this:
Anyone with a suspending function at hand can explicitly use launch { … } to initiate its concurrent execution.
This is an example of an extension function he uses in the articles:
fun CoroutineScope.launchFooBar() = launch { foo(bar()) }
So the example is wrong? Are we not supposed to call launch from extension functions? I’m confused as to how should I “properly” use CoroutineScope
extensions.
How I understand it
Maybe CoroutineScope
extensions are supposed to “abstract away” the launching of coroutines. Maybe they should even be private functions. Then I can call them with structured concurrency with a regular suspending function.
I tried to come up with an example where you grow vegetables:
enum class Vegetable { TURNIP, ONION, POTATO } private fun CoroutineScope.growVegetableInBackground(vegetable: Vegetable) = launch { // grow the vegetable with different ways depending on what type it is println("Growing $vegetable") delay(1000) println("$vegetable done!") } suspend fun growAll(vegetables: List<Vegetable>) = coroutineScope { println("Growing all vegetables!") vegetables.forEach { growVegetableInBackground(it) } } fun main() = runBlocking { val vegetables = listOf(Vegetable.ONION, Vegetable.POTATO, Vegetable.TURNIP) growAll(vegetables) }
This is what is printed to the console:
Growing all vegetables! Growing ONION Growing POTATO Growing TURNIP ONION done! POTATO done! TURNIP done!
Is this the way?
submitted by /u/cris_null
[link] [comments]