# Why coroutineScope { ...} function is not implicit inside suspend functions?

**URL:** <https://discuss.kotlinlang.org/t/why-coroutinescope-function-is-not-implicit-inside-suspend-functions/15833>\
**Category:** Language Design\
**Created:** [January 11, 2020, 9:40pm UTC](https://discuss.kotlinlang.org/t/why-coroutinescope-function-is-not-implicit-inside-suspend-functions/15833 "2020-01-11T21:40:24Z")\
**Posts on this page:** 10\
**Page:** 1

<div class="post-metadata">

**Author:** ![circusmagnus](https://avatars.discourse-cdn.com/v4/letter/c/278dde/32.png) [@circusmagnus](https://discuss.kotlinlang.org/u/circusmagnus)\
**Post date:** [January 11, 2020, 9:40pm UTC](https://discuss.kotlinlang.org/t/why-coroutinescope-function-is-not-implicit-inside-suspend-functions/15833/1 "2020-01-11T21:40:24Z")

</div>

I am just wondering what would be the downsides of having an implicit coroutineScope inside suspend functions. I mean, instead of:

```auto
suspend fun scoped() = coroutineScope { coroutines launched here }

```

one could just write:

```auto
suspend fun implicitlyScoped() { coroutines launched here }

```

suspend functions have access to coroutineContext anyway. Is it so costly to create new scope (job), even if it is not needed?

This need to wrap a lot of things into coroutineScope { … } is a bit tiring:

```auto
flow { 
   coroutineScope { 
      only here I can use some coroutines to make flow collect from multiple sources in parallel
   }
}

```

---

<div class="post-metadata">

**Author:** ![fabianishere](https://avatars.discourse-cdn.com/v4/letter/f/8dc957/32.png) [@fabianishere](https://discuss.kotlinlang.org/u/fabianishere)\
**Post date:** [January 13, 2020, 8:06pm UTC](https://discuss.kotlinlang.org/t/why-coroutinescope-function-is-not-implicit-inside-suspend-functions/15833/2 "2020-01-13T20:06:03Z")

</div>

The first issue with this proposal is that `CoroutineScope` is part of the `kotlinx-coroutines` library and not in the standard library.

Moreover, to give you an example, I am heavily using coroutines without the `kotlinx-coroutines` library and having to construct an unused `CoroutineScope` for every call is an unacceptable overhead in my opinion.

---

<div class="post-metadata">

**Author:** ![ebrowne72](https://avatars.discourse-cdn.com/v4/letter/e/85f322/32.png) [@ebrowne72](https://discuss.kotlinlang.org/u/ebrowne72)\
**Post date:** [January 13, 2020, 9:50pm UTC](https://discuss.kotlinlang.org/t/why-coroutinescope-function-is-not-implicit-inside-suspend-functions/15833/3 "2020-01-13T21:50:48Z")

</div>

Wrapping code in `coroutineScope()` means you are explicitly saying this function should suspend until all the child coroutines complete. If you don’t want the function to suspend (maybe this is a utility function that will be called from the calling function multiple times to start multiple coroutines) then your suggestion would break things.

---

<div class="post-metadata">

**Author:** ![circusmagnus](https://avatars.discourse-cdn.com/v4/letter/c/278dde/32.png) [@circusmagnus](https://discuss.kotlinlang.org/u/circusmagnus)\
**Post date:** [January 14, 2020, 10:35pm UTC](https://discuss.kotlinlang.org/t/why-coroutinescope-function-is-not-implicit-inside-suspend-functions/15833/4 "2020-01-14T22:35:55Z")

</div>

Since enclosing function is suspending, it is obvious that we are going to suspend here. And if there are coroutines launched inside it is IMHO is also obvious, that I want to suspend until they all finish.

Main problem may be indeed performance. Maybe a new Scope is not needed, because I have no coroutines launched inside. Maybe I want to just switch context. Or establish a supervisor scope instead of an ordinary one.

However main selling point of coroutines seems to be simplicity + correctness. That is why I am looking, how existing syntax could be simplified.

---

<div class="post-metadata">

**Author:** ![ebrowne72](https://avatars.discourse-cdn.com/v4/letter/e/85f322/32.png) [@ebrowne72](https://discuss.kotlinlang.org/u/ebrowne72)\
**Post date:** [January 14, 2020, 11:25pm UTC](https://discuss.kotlinlang.org/t/why-coroutinescope-function-is-not-implicit-inside-suspend-functions/15833/5 "2020-01-14T23:25:36Z")

</div>

> [@circusmagnus](#):
>
> And if there are coroutines launched inside it is IMHO is also obvious, that I want to suspend until they all finish.

It’s not obvious to me that everyone will want this behavior all the time.

```
coroutineScope {
    for (i in 1..10) {
        startSomething(i)
    }
}

suspend fun CoroutineScope.startSomething(i: Int) {
    delay(i)
    launch { ... }
}

```

It’s contrived, but that’s a function that suspends and also launches a new coroutine, but we want the function to return immediately. The outer `coroutineScope()` will wait until all of the child coroutines are finished.

---

<div class="post-metadata">

**Author:** ![circusmagnus](https://avatars.discourse-cdn.com/v4/letter/c/278dde/32.png) [@circusmagnus](https://discuss.kotlinlang.org/u/circusmagnus)\
**Post date:** [January 15, 2020, 7:43am UTC](https://discuss.kotlinlang.org/t/why-coroutinescope-function-is-not-implicit-inside-suspend-functions/15833/6 "2020-01-15T07:43:58Z")

</div>

Making suspend function an extension on CoroutineScope will grant You an IDE warning already, as it is pretty ambiguous. One should decide, whether he/she wants to suspend until everything is finished or return immediately and continue working.

You can always (and IMHO should) place this delay outside second function, so that second function is not suspending.

---

<div class="post-metadata">

**Author:** ![fvasco](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.kotlinlang.org/fvasco/32/1961_2.png) [@fvasco](https://discuss.kotlinlang.org/u/fvasco)\
**Post date:** [January 15, 2020, 9:44am UTC](https://discuss.kotlinlang.org/t/why-coroutinescope-function-is-not-implicit-inside-suspend-functions/15833/7 "2020-01-15T09:44:31Z")

</div>

> [@circusmagnus](#):
>
> Since enclosing function is suspending, it is obvious that we are going to suspend here. And if there are coroutines launched inside it is IMHO is also obvious, that I want to suspend until they all finish.

It isn’t so obvious, I wrote a library without using any con `kotlinx.coroutine` stuff.

> **[Asynk / nio · GitLab](https://gitlab.com/asynk/nio)**
>
> GitLab.com

At the same time, may `kotlinx.coroutine`’s methods don’t require a `CoroutineScope`.  
A coroutine scope is a marker for a fork-join algorithm, using the structured concurrency. You can take a look here:

> <https://github.com/Kotlin/kotlinx.coroutines/issues/410>
>
> \### Background and definitions
> 
> Currently coroutine builders like \`launch { ..…. }\` and \`async { ... }\` start a \*\*global\*\* coroutine by default. By global we mean that this coroutine's lifetime is completely standalone just like a lifetime of a daemon thread and outlives the lifetime of the job that had started it. It is terminated only explicitly or on shutdown of the VM, so the invoker had to make extra steps (like invoking \`join\`/\`await\`/\`cancel\`) to ensure that it does live indefinitely.
> 
> In order to start a \*\*child\*\* coroutine a more explicit and lengthly invocation is needed. Something like \`async(coroutineContext) { ... }\` and \`async(coroutineContext) { ... }\` or \`async(parent=job) { ... }\`, etc. Child coroutine is different from a global coroutine in how its lifetime is scoped. The lifetime of child coroutine is strictly subordinate to the lifetime of its parent job (coroutine). A parent job cannot complete until all its children are complete, thus preventing accidental leaks of running children coroutines outside of parent's scope. 
> 
> \### Problem
> 
> \*\*This seems to be a wrong default\*\*. Global coroutines are error-prone. They are easy to leak and they do not represent a typical use-case where some kind of parallel decomposition of work is needed. It is easy to miss the requirement of adding an explicit \`coroutineContext\` or \`parent=job\` parameter to start a child coroutine, introducing subtle and hard to debug problems in the code. 
> 
> Consider the following code that performs parallel loading of two images and returns a combined result (a typical example of parallel decomposition):
> 
> \`\`\`
> suspend fun loadAndCombineImage(name1: String, name2: String): Image {
> val image1 = async { loadImage(name1) }
> val image2 = async { loadImage(name2) }
> return combineImages(image1.await(), image2.await())
> }
> \`\`\`
> 
> This code has a subtle bug in that if loading of the first image fails, then the loading of the second one still proceeds and is not cancelled. Moreover, any error that would occur in the loading of the second image in this case would be lost. Note, that changing \`async\` to \`async(coroutineContext)\` does not fully solve the problem as it binds async loading of images to the scope of the larger (enclosing) coroutine which is wrong in this case. In this case we want these async operations to be children of \`loadAndCombineImage\` operation.
> 
> For some additional background reading explaining the problem please see \[Notes on structured concurrency, or: Go statement considered harmful\](https://vorpus.org/blog/notes-on-structured-concurrency-or-go-statement-considered-harmful/)
> 
> \### Solution
> 
> The proposed solution is to deprecate top-level \`async\`, \`launch\`, and other coroutine builders and redefine them as extension functions on \`CoroutineScope\` interface instead. A dedicated top-level \`GlobalScope\` instance of \`CoroutineScope\` is going to be defined.
> 
> Starting a global coroutine would become more explicit and lengthly, like \`GlobalScope.async { ... }\` and \`GlobalScope.launch { ... }\`, giving an explicit indication to the reader of the code that a global resource was just created and extra care needs to be taken about its potentially unlimited lifetime. 
> 
> Starting a child coroutine would become less explicit and less verbose. Just using \`async { ... }\` or \`launch { ... }\` when \`CoroutineScope\` is in scope (pun intended) would do it. In particular, it means that the following slide-ware code would not need to use \`join\` anymore:
> 
> \`\`\`
> fun main(args: Array\<String\>) = runBlocking { // this: CoroutineScope 
> val jobs = List(100\_000) { 
> launch {
> delay(1000)
> print(".")
> }
> }
> // no need to join here, as all launched coroutines are children of runBlocking automatically
> }
> \`\`\`
> 
> For the case of parallel decomposition like \`loadAndCombineImage\` we would define a separate builder function to capture and encapsulate the current coroutine scope, so that the following code will work properly in all kind of error condition and will properly cancel the loading of the second image when loading of the first one fails:
> 
> \`\`\`
> suspend fun loadAndCombineImage(name1: String, name2: String): Image = coroutineScope { // this: CoroutineScope 
> val image1 = async { loadImage(name1) }
> val image2 = async { loadImage(name2) }
> combineImages(image1.await(), image2.await())
> }
> \`\`\`
> 
> \### Additional goodies
> 
> Another idea behind this design is that it should be easy to turn any entity with life-cycle into an entity that you could start coroutines from. Consider, for example, some kind of an application-specific activity that is launch some coroutines but all of those coroutines should be cancelled when the activity is destroyed (for example). Now it looks like this:
> 
> \`\`\`
> class MyActivity {
> val job = Job() // create a job as a parent for coroutines
> val backgroundContext = ... // somehow inject some context to launch coroutines
> val ctx = backgroundContext + job // actual context to use with coroutines
> 
> fun doSomethingInBackground() = launch(ctx) { ... }
> fun onDestroy() { job.cancel() }    
> }
> \`\`\`
> 
> The proposal is to simply this pattern, by allowing an easy implementation of \`CoroutineScope\` interface by any business entities like the above activity:
> 
> \`\`\`
> class MyActivity : CoroutineScope {
> val job = Job() // create a job as a parent for coroutines
> val backgroundContext = ... // somehow inject some context to launch coroutines
> override val scopeContext = backgroundContext + job // actual context to use with coroutines
> 
> fun doSomethingInBackground() = launch { ... } // !!! 
> fun onDestroy() { job.cancel() }    
> }
> \`\`\`
> 
> Now we don't need to remember to specify the proper context when using \`launch\` anywhere in the body of \`MyActivity\` class and all launched coroutines will get cancelled when lifecycle of \`MyActivity\` terminates.

---

<div class="post-metadata">

**Author:** ![circusmagnus](https://avatars.discourse-cdn.com/v4/letter/c/278dde/32.png) [@circusmagnus](https://discuss.kotlinlang.org/u/circusmagnus)\
**Post date:** [January 15, 2020, 10:54am UTC](https://discuss.kotlinlang.org/t/why-coroutinescope-function-is-not-implicit-inside-suspend-functions/15833/8 "2020-01-15T10:54:34Z")

</div>

Yes, I know what coroutineScope is for. I just had a thought, that it could be default / implicit behaviour of any suspend function. So that one would have less boilerplate to write those fork-joins and they would feel more natural.

Nevermind, I realize, that it is not such a good idea in quite a few use cases.

---

<div class="post-metadata">

**Author:** ![fvasco](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.kotlinlang.org/fvasco/32/1961_2.png) [@fvasco](https://discuss.kotlinlang.org/u/fvasco)\
**Post date:** [January 15, 2020, 11:17am UTC](https://discuss.kotlinlang.org/t/why-coroutinescope-function-is-not-implicit-inside-suspend-functions/15833/9 "2020-01-15T11:17:35Z")

</div>

Maybe this is the answer that are you looking for

> <https://github.com/Kotlin/kotlinx.coroutines/issues/254#issuecomment-481615279>
>
> All the currently provided channel abstractions in \`kotlinx.coroutines\` are \_hot…\_. The data is being produced regardless of the presence of subscriber. This is good for data sources and applications that are inherently hot, like incoming network and UI-events. 
> 
> However, hot streams are not an ideal solution for cases where data stream is produced on demand. Consider, for example, the following simple code that produces \`ReceiveChannel\<Int\>\`:
> 
> 
> \`\`\`
> produce\<Int\> { 
> while (true) {
> val x = computeNextValue()
> send(x)
> } 
> }
> \`\`\`
> 
> One obvious downside is the \`computeNextValue()\` is invoked before \`send\`, so even when receiver is not ready, the next value gets computed. Of course, it gets suspended in \`send\` if there is no receiver, but it is not as lazy as you get with cold reactive Publisher/Observable/Flowable/Flux/Flow.
> 
> We need the abstraction for cold streams in \`kotlinx.coroutines\` that is going to be just as lazy, computing data in "push" mode versus "pull" mode of hot channels that we have now.
> 
> There are the following related discussions:
> \* https://github.com/reactor/reactor-core/issues/979#issuecomment-351770494 describes preliminary performance test that indicates that "push" mode is much faster for same-thread cases.
> \* https://github.com/Kotlin/kotlinx.coroutines/issues/113 (SPSC channels) seems to get superseded by the support of cold streams.

---

<div class="post-metadata">

**Author:** ![circusmagnus](https://avatars.discourse-cdn.com/v4/letter/c/278dde/32.png) [@circusmagnus](https://discuss.kotlinlang.org/u/circusmagnus)\
**Post date:** [January 15, 2020, 12:33pm UTC](https://discuss.kotlinlang.org/t/why-coroutinescope-function-is-not-implicit-inside-suspend-functions/15833/10 "2020-01-15T12:33:28Z")

</div>

Yes, I had the same thoughts, that jcornaz was mentioning in referenced issue. Thanks!
