Context Parameter's Capability with Receiver-based APIs
## Why we need this?
Because receivers/extensions came out much ealier, a lot of codes in Kotlin ecosystem is already written in Receiver-based scope APIs.
Migration suggestions are introduced in [KEEP/context-parameters](https://github.com/Kotlin/KEEP/blob/context-parameters/proposals/context-parameters.md#simulating-receivers), but sometimes it takes cost to introduce a new context-parameter-based API without making collisions or breaking changes. (For example: [kotlinx.coroutines](https://github.com/Kotlin/kotlinx.coroutines/issues/4534))
## How it should be?
If there is a receiver in a scope, it should be considered as a context element and allow call functions requiring it as context. For example:
This is a existing kotlinx.coroutines API: [launch](https://kotlinlang.org/api/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines/launch.html).
```kotlin
fun CoroutineScope.launch(
context: CoroutineContext = EmptyCoroutineContext,
start: CoroutineStart = CoroutineStart.DEFAULT,
block: suspend CoroutineScope.() -> Unit
): Job
```
If we have:
```kotlin
fun CoroutineScope.task1() {}
context(_: CoroutineScope)
fun task2() {}
context(_: CoroutineScope)
fun launchMigrated(
block: context(CoroutineScope) suspend () -> Unit
): Job
```
It should be:
```kotlin
GlobalScope.launch {
// now we have CoroutineScope as receiver in this scope
// this is OK, using receiver-based api in receiver-based scope
task1()
// this is not OK for now, but it should be OK to use context-based API in receiver-based scopes
task2()
// this is not OK for now, but it should be OK to use context-based API in receiver-based scopes
launchMigrated {
// now we have CoroutineScope as context in this scope
// when we need to use receiver-based API in context-based scopes, it can be this
contextOf<CoroutineScope>.task1()
// this is OK, using context-based API in context-based scope
}
}
```
## It's OK and not breaking the principles
> Q: Why drop context receivers?
>
> One of the main objections to the previous design was the potential scope pollution:
>
> Having too many functions available in scope without qualification makes it difficult to find the right one;
>
> It becomes much harder to establish where a certain member is coming from.
>
> We think that context parameters provide a better first step in understanding how implicit context resolution fits in Kotlin, without that caveat.
This change will only make receiver in scope regarded as context element, will not make context parameter regarded as availible reveivers. So there will not "having too many functions available in scope without qualification"
This initiation aims at making the migration less and easier for current Kotlin ecosystem from receiver-scope world to context-scope world.
关闭于 2025-09-29 1 条评论