rinse
01/12/2025, 8:00 AMsuspendCoroutine
function.
Given the following code, it prints "Begin End Hello". I believe this behavior is expected because, according to the KEEP, suspendCoroutine
only suspends when the block returns without invoking cont.resumeWith
. However, this behavior seems incompatible with the documentation's description: "Obtain the current continuation instance." to me.
val hello = suspendCoroutine { cont ->
println("Begin")
cont.resume("Hello")
println("End")
}
println(hello)
https://play.kotlinlang.org/embed?short=JJBf260zy
Anyway here is my question: can anyone suggest a way to consistently obtain the current continuation? It is required to go well with kotlinx.coroutines
.
I think we can utilise the intrinsic APIs but I would prefer to explore other options before resorting to it.
It would behave like this:
val hello = ourSuspendCoroutine { cont ->
println("Begin")
cont.resume("Hello")
println("End")
}
println(hello)
// => Begin Hello End
Youssef Shoaib [MOD]
01/12/2025, 9:12 AMresume
to be suspend
very likely. Also, another question arises, which is when do you expect the resume
to be called back? Should it be when the coroutine is completely done, or do you expect it to return when a specific level finishes?
One simple thing you could do is use something like ResourceScope
from Arrow:
resourceScope {
val hello = run {
println("Begin")
onResume { println("End") }
"Hello"
}
println(hello)
}
// => Begin Hello End
rinse
01/12/2025, 11:30 AMsuspend
block as a parameter. Perhaps what I want can be like this: suspend fun callCC(block: suspend (suspend (T) -> Nothing) -> T): T
. And I want it to behave like suspendCoroutine
, while I am not currently sure how it behaves.
Also, thank you for your suggestion, I'll try ResourceScope
and check how ResourceScope
is implemented.Youssef Shoaib [MOD]
01/12/2025, 11:33 AMshift
and reset
which you might be familiar with from other languages (like Racket). It's still a WIP, but I'm fairly confident that it has the correct behaviour.
Your use case would look something like:
newReset {
val hello = shift { k ->
println("Begin")
k("Hello")
println("World")
}
println(hello)
}
Youssef Shoaib [MOD]
01/12/2025, 11:35 AMsuspendCoroutine
is indeed meant as a callCC
-style function, but instead of short circuiting on continuation application, it returns Unit
instead (and, of course, it's single shot)rinse
01/12/2025, 11:49 AMkotlinx.coroutines
, so that I can have shallow-nested effect handlers when context parameters are supported.
Thank you for sharing the information.rinse
01/12/2025, 11:51 AMYoussef Shoaib [MOD]
01/12/2025, 11:59 AMeffekt
tests. It's delightful how expressive all the examples are!
The library provides both deep and shallow effect handlers. The Handler interface I think only provides deep ones, but that's because the examples I'm using haven't needed shallow ones yet (I think it's very trivial to get shallow handlers just by using 2 prompts or something). That's like a one liner though to expose a shallow version of Handler.use
Youssef Shoaib [MOD]
01/12/2025, 12:03 PMrinse
01/12/2025, 12:19 PMrinse
01/12/2025, 12:33 PM