bobko
08/27/2025, 4:49 PMsuspend functions" exploration proposal.
Text
DiscussionYoussef Shoaib [MOD]
08/27/2025, 6:35 PMprovideDelegate right now would be appreciated (this doesn't have the tricky design pitfalls that getValue and setValue have).Youssef Shoaib [MOD]
08/27/2025, 7:14 PM@RestrictsSuspension as well. In some respect, we can view normal suspend functions as ones that have a CoroutineContext context param, and it's as if CoroutineContext was marked with @RestrictsSuspension.
It feels like an alternate history version of Kotlin would've had CoroutineContext context param be needed for normal suspend functions, but that ship has sailed now. It's still an interesting theoretical thing since it makes @RestrictsSuspension somewhat less weird.bobko
08/27/2025, 7:23 PM@RestrictsSuspension effectively disallows non-empty coroutine context https://youtrack.jetbrains.com/issue/KT-80344
2. Right now, we have weirdness around kotlin.context and kotlinx.coroutines.withContext functions. The former replaces the context, but the later appends to the context. And the functions naming is generally just confusing. It'd be great if it was just a single functionYoussef Shoaib [MOD]
08/27/2025, 7:31 PMwithContext and context would effectively do almost the same thing (withContext would have to take the current context and append to it) in that alternate world (minus some unsoundness bugs related to @RestrictsSuspension).
@RestrictsSuspension not allowing a non-empty context is very consistent under this idea (and it has minor performance improvements).
Continuing the line to its logical conclusion, maybe if a @RestrictsSuspension type extends CoroutineContext, then normal suspend functions should be allowed to be called too? I've had cases where I really wanted that. It'd be weird to implement though (we'd form a Continuation in-place with the context and the restricted continuation).
In my use case though, I'd have also needed that new continuation to be intercepted, since I was doing trampolining. I ended up just making a bridge { } function instead that bridges between my restricted type and normal suspension (and it creates such a new continuation with the proper context that was hidden inside my restricted type, and also intercepts it using the interceptor in context).bobko
08/27/2025, 7:39 PM@RestrictsSuspension type A extends @RestrictsSuspension type B, then we could allow calling B-suspend functions from A-suspend functions (or maybe it's already allowed? I didn't check it)
UPD: Ah, it's already possibleYoussef Shoaib [MOD]
08/27/2025, 7:42 PM@RestrictsSuspension implements a fully-featured type-safe resource management system using type parameters as regions (and parameter subtyping for region subtyping) ala the ST monad in Haskell.
In normal English, this means you can allocate resources that can only be used in a specific region of code, and are useless outside of it. The resources are also usable in subregions.
@RestrictsSuspension is surprisingly fully fledged for being such an underused feature. There are also bugs with it of course, and with the regions thing, the syntax ends up being clunky too, but it's crazy that Kotlin can express this at all without it being a `flatMap`ed mess.