You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: proposals/context-parameters.md
+45-11Lines changed: 45 additions & 11 deletions
Original file line number
Diff line number
Diff line change
@@ -13,7 +13,7 @@ This is an updated proposal for [KEEP-259](https://github.com/Kotlin/KEEP/issues
13
13
14
14
1. Introduction of named context parameters,
15
15
2. Context receivers are dropped,
16
-
3. Removal of `this@Type` syntax, introduction of `implicit<A>()`,
16
+
3. Removal of `this@Type` syntax, introduction of `contextOf<A>()`,
17
17
4. Contexts are not allowed in constructors,
18
18
5. Callable references resolve their context arguments eagerly,
19
19
6. Context-in-classes are dropped.
@@ -107,7 +107,7 @@ context(logger: Logger) fun User.doAction() {
107
107
* The type and order of context parameters must coincide.
108
108
* It is allowed (yet discouraged) to change the name of a context parameter.
109
109
110
-
It is a conflict to declare overloads which only differ in the order of the context parameters.
110
+
It is a conflict to declare overloads which only differ in the number of context parameters. It is allowed to declare one overload with _no_context parameters and one with _some_ of them (this is aligned with §7.8).
111
111
112
112
**§1.6***(naming ambiguity)*: We use the term **context** with two meanings:
113
113
@@ -134,6 +134,34 @@ Logger.(User) -> Int
134
134
(Logger, User) ->Int
135
135
```
136
136
137
+
As a result of these equivalences, it is possible invoke a value with a function type with context parameters by giving them as regular value parameters.
It is not allowed to pass context arguments explicitly inside a value argument list when callee is a regular function (not a value of a function type).
151
+
152
+
```kotlin
153
+
context(_:String, _:Double) fun Int.x(z:Long): Unit { }
154
+
155
+
funfoo(y:Int) {
156
+
context("", 1.0) {
157
+
y.x(1L) // regular way to call it
158
+
}
159
+
160
+
y.x("", 1.0, 1L) // NO
161
+
x("", 1.0, y, 1L) // NO
162
+
}
163
+
```
164
+
137
165
**§1.8***(lambdas)*: If a lambda is assigned a function type with context parameters, those behave as if declared with `_` as its name.
138
166
139
167
* They participate in context resolution but are only accessible through the `implicit` function (defined below).
@@ -162,13 +190,13 @@ fun <A, B, R> context(a: A, b: B, block: context(A, B) () -> R): R = block(a, b)
162
190
fun <A, B, C, R> context(a:A, b:B, c:C, block: context(A, B, C) () ->R): R= block(a, b, c)
163
191
```
164
192
165
-
**§2.2***(`implicit` function)*: We also provide a generic way to obtain a value by type from the context. It allows access to context parameters even when declared using `_`, or within the body of a lambda.
193
+
**§2.2***(`contextOf` function)*: We also provide a generic way to obtain a value by type from the context. It allows access to context parameters even when declared using `_`, or within the body of a lambda.
166
194
167
195
* Implementations are encouraged, but not required, to mark this function as `inline`.
168
196
* If possible, type inference for type variable `A` should be restricted (for example, using `@NoInfer`). Developers are expected to use the function with explicit type arguments.
169
197
170
198
```kotlin
171
-
context(ctx:A) fun <A> implicit(): A= ctx
199
+
context(ctx:A) fun <A> contextOf(): A= ctx
172
200
```
173
201
174
202
_Note:_ This function replaces the uses of `this@Type` in the previous iteration of the design.
**Recommended style:** annotations, context parameters, then other modifiers as per the [usual style guide](https://kotlinlang.org/docs/coding-conventions.html#modifiers-order).
478
512
479
513
**§7.2***(disambiguating `context`)*: We do not enforce `context` as a hard keyword, leading to potential ambiguities in the body of declarations. In particular, `context(` may be both the beginning of:
@@ -538,13 +572,13 @@ context(ctx: Any) fun foo() {
538
572
context(s:String) funbar() { }
539
573
```
540
574
541
-
**§7.7***(applicability, `DslMarker`)*: During context resolution, if at a certain scope there is a potential contextual value in scope (either coming from a context parameter or from an implicit receiver) marked with an annotation `@X` which is itself annotated with [`@DslMarker`](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-dsl-marker/) then:
575
+
**§7.7***(applicability, `DslMarker`)*: we say that a value is `X`-DSL-marked if the type of that value is annotated with `@X`, and `X` is itself annotated with [`@DslMarker`](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-dsl-marker/).
576
+
577
+
If at a certain scope there is a potential contextual `X`-DSL-marked value in scope (either coming from a context parameter or from an implicit receiver) and context resolution chooses a contextual `X`-DSL-marked value in an outer scope, it is a compilation _error_.
542
578
543
-
- It is an _error_ for two such values to be available in the same scope.
544
-
- If context resolution chooses a contextual value with the same annotation, but in an outer scope, it is a compilation _error_.
545
-
- If a call binds to a receiver with the same annotation, it is a compilation _error_.
579
+
This is in addition to the _old rule_, stating: if at a certain scope there is an implicit `X`-DSL-marked receiver in scope and resolution chooses a `X`-DSL-marked implicit receiver in an outer scope, it is a compilation error. Note that context parameters do _not_ conflict with implicit receivers when the latter are used as receivers.
546
580
547
-
These rules extend the usual behavior of `@DslMarker` to cover both receivers and context parameters uniformly.
581
+
These rules extend the [usual behavior of `@DslMarker`](https://kotlinlang.org/docs/type-safe-builders.html#scope-control-dslmarker) to cover both receivers and context parameters uniformly.
0 commit comments