# Why Flow default operators does not expose the context?

**URL:** <https://discuss.kotlinlang.org/t/why-flow-default-operators-does-not-expose-the-context/14596>\
**Category:** Language Design\
**Created:** [October 10, 2019, 8:55am UTC](https://discuss.kotlinlang.org/t/why-flow-default-operators-does-not-expose-the-context/14596 "2019-10-10T08:55:00Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![lamba92](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.kotlinlang.org/lamba92/32/5089_2.png) [@lamba92](https://discuss.kotlinlang.org/u/lamba92)\
**Post date:** [October 10, 2019, 8:55am UTC](https://discuss.kotlinlang.org/t/why-flow-default-operators-does-not-expose-the-context/14596/1 "2019-10-10T08:55:00Z")

</div>

Say in one of your `map { }` you need to start suspending calls and in the next `map { }` `await()` for them.

Surely you will need to start them `async { }`! But to do that you need to call `coroutineScope { }` inside the operator and it adds ugliness to the code by adding one more level of indentation to the already big indentation chain that often is any reactive stream (thought Kotlin Flows are very much less verbose, thank you JetBrains and people who helped the repository ❤).

So question is, why did you choose to not expose the coroutine context in operators?

---

<div class="post-metadata">

**Author:** ![nickallendev](https://avatars.discourse-cdn.com/v4/letter/n/cdc98d/32.png) [@nickallendev](https://discuss.kotlinlang.org/u/nickallendev)\
**Post date:** [October 11, 2019, 12:31am UTC](https://discuss.kotlinlang.org/t/why-flow-default-operators-does-not-expose-the-context/14596/2 "2019-10-11T00:31:45Z")

</div>

You always have access to the `CoroutineContext` with the [coroutineContext](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.coroutines/coroutine-context.html) method.

Read [Coroutine Context and Scope](https://medium.com/@elizarov/coroutine-context-and-scope-c8b255d59055) and [Explicit concurrency](https://medium.com/@elizarov/explicit-concurrency-67a8e8fd9b25)for the reasoning behind why you should use the `coroutineScope` method.

Basically, it’s easier to reason about code if suspend methods always finish any launched child jobs before they return.

---

<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:** [October 11, 2019, 4:16am UTC](https://discuss.kotlinlang.org/t/why-flow-default-operators-does-not-expose-the-context/14596/3 "2019-10-11T04:16:38Z")

</div>

> <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:** ![lamba92](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.kotlinlang.org/lamba92/32/5089_2.png) [@lamba92](https://discuss.kotlinlang.org/u/lamba92)\
**Post date:** [October 11, 2019, 1:43pm UTC](https://discuss.kotlinlang.org/t/why-flow-default-operators-does-not-expose-the-context/14596/4 "2019-10-11T13:43:29Z")

</div>

I may have express myself not clearly!

I was looking for a solution to “zip” two suspending calls together the same way you would do with Observable’s `Singles.zip()`. I need to start those functions asynchronously and map their result once both are available!

With suspending calls this is possible by creating `Deferred`s of the calls and then `await()`ing them. To do so you need a `CoroutineScope` that is always available trough `coroutineScope { }` when inside a suspending context.

My question now is, why did the team behind Kotlin Coroutines decided to use regular lambdas instead of extensions lambdas with the context of the transformation? Check the example below:

I was just asking why `map { }` hasn’t this signature:

```kotlin
inline fun <T, R> Flow<T>.scopedMap(crossinline transform: suspend CoroutineScope.(value: T) -> R): Flow<R> = map { 
    coroutineScope { 
        transform(it)
    }
}

```

Of course you can recover the scope whenever you want, but that is another indentation level and it’s ugly! You can as well write down your `scopedMap` and use it.

---

<div class="post-metadata">

**Author:** ![nickallendev](https://avatars.discourse-cdn.com/v4/letter/n/cdc98d/32.png) [@nickallendev](https://discuss.kotlinlang.org/u/nickallendev)\
**Post date:** [October 11, 2019, 7:03pm UTC](https://discuss.kotlinlang.org/t/why-flow-default-operators-does-not-expose-the-context/14596/5 "2019-10-11T19:03:25Z")

</div>

> [@lamba92](#):
>
> My question now is, why did the team behind Kotlin Coroutines decided to use regular lambdas instead of extensions lambdas with the context of the transformation?

Probably because it would be less performant for the sake of a seemingly rare use case that is trivial to implement by users if desired.

---

<div class="post-metadata">

**Author:** ![lamba92](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.kotlinlang.org/lamba92/32/5089_2.png) [@lamba92](https://discuss.kotlinlang.org/u/lamba92)\
**Post date:** [October 11, 2019, 7:41pm UTC](https://discuss.kotlinlang.org/t/why-flow-default-operators-does-not-expose-the-context/14596/6 "2019-10-11T19:41:26Z")

</div>

Well, all of them are inlined so no performance loss at all, but I guess it’s still some added complexity.

---

<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:** [October 11, 2019, 7:46pm UTC](https://discuss.kotlinlang.org/t/why-flow-default-operators-does-not-expose-the-context/14596/7 "2019-10-11T19:46:45Z")

</div>

> [@lamba92](#):
>
> My question now is, why did the team behind Kotlin Coroutines decided to use regular lambdas instead of extensions lambdas with the context of the transformation?

Didn’t Elizarov’s post on Github answer to your question?

> keep simple operators faster, and it is Ok if more complex operators have to use `coroutineScope` occasionally when they need it

---

<div class="post-metadata">

**Author:** ![lamba92](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.kotlinlang.org/lamba92/32/5089_2.png) [@lamba92](https://discuss.kotlinlang.org/u/lamba92)\
**Post date:** [October 11, 2019, 10:24pm UTC](https://discuss.kotlinlang.org/t/why-flow-default-operators-does-not-expose-the-context/14596/8 "2019-10-11T22:24:22Z")

</div>

Oh damn, opening the link through Fasthub from mobile opened the thread from the beginning making me think that I missed the point with my first post! Thank you tho 🙂
