Open BenWoodworth opened 2 weeks ago
There may be some fundamental issues with this as well, since it'd be breaking assumptions that Kotlin makes about code.
For example:
suspend fun multiResume() {}
suspend fun x() {
val a: Int
multiResume()
a = 4
a = 5 // ERROR: 'val' cannot be reassigned
}
Here Kotlin is fine with the first assignment since it assumes that the continuation at multiResume()
will be resumed at most once. But, of course, with a multi-shot coroutine like what this issue's proposing, that's not the case.
Testing on JVM I'm finding that the code does run without any issue, replacing the value of 4 with 5. There are some subtle inconsistencies that can arise though:
fun test() {
val a: Int
a = 4
val printCaptured = { println(a) }
@Suppress("VAL_REASSIGNMENT")
a = 5
printCaptured()
println(a)
}
In this example, a is captured in the lambda, and since it's a val and won't change, the constant value 4
is captured, instead of a reference that will change to 5 when a
is updated. So in this code, "4 5" is printed. But, if a
is changed to a var, a reference to a
's value is captured, and the lambda will always print the actual current value of a
, meaning that var a
results in "5 5" being printed.
While this isn't necessarily a problem, and might even be desirable, it might hint towards a bigger issue when abusing coroutines like this.
This is not a planned feature, at least not yet, but this issue tracks how
parameterize
could work if it were implemented as asuspend
block that resumes from eachparameter
instead of re-running the whole blockIt could be implemented as a suspend point when declaring a parameter:
A
parameter
will be constructed only once (instead of every iteration). After that, there will be a suspend point whenprovideDelegate
is called on it, and having the listed/computed arguments locked in. From there,parameterize
'ssuspend
block will resume from there once for each of the arguments as a multi-shot coroutine.Benefits
ParameterizeContinue
up the call stack for internal control flowparameterOf
is no longer a performance concernparameterize
is no longer neededProblems/Blockers
provideDelegate
as suspend is not supported as of Kotlin 2.0Implementation
Multi-shot coroutines should be possible as long as a coroutine continuation can be cloned, that way it can be resumed more than once.
For each platform: