Description
Hi!
I would've posted this in discussion if it was available, but I was curious if it had ever been considered to use coroutines instead of exceptions for the binding blocks.
Using exceptions has always seemed slightly error prone to me since all it takes is for someone to catch a generic exception and you now potentially have unexpected behavior. In addition stacktraces can be slightly expensive to produce.
On the flip side, coroutines have their drawbacks as well. For example, the stack traces can sometimes be confusing and there are limitations for where you can actually use bind.
For example I made a proof of concept and tried it out in a repo that made decent usage of binding. The issues are that any function that is not inline or suspend will produce a compilation error because you need to be within the custom coroutine context.
A map function is okay because it's inline, but a sequence function is not
listOf(1, 2, 3).asSequence().map {
provideX().bind()
}
Suspension functions can be called only within coroutine body
The other issue I discovered is when the binding context is put into the receiver of another function it fails as well (this is only an issue when restricting the scope of what suspend functions can be called from your scope).
run {
provideX().bind()
}
doesn't work but
kotlin.run {
provideX().bind()
}
In conclusion, I'm not convinced yet whether one solution is better than the other. I think the coroutine based approach has some benefits over the exception based approach, but it's slightly more restrictive in how you use it. I'm curious to know what you and others think! Thanks for your time.
Here's a link to my POC if you want to try it out. I made both a pure kotlin.coroutines version and a kotlinx.coroutines version.
dronda-t/kotlin-result@master...dronda-t:kotlin-result:dronda/kotlin-coroutines