Is there any way to make the compiler make everyth...
# coroutines
s
Is there any way to make the compiler make everything suspending? I have great respect for what's been done, but
suspend
is a mess, and makes for extremely difficult to maintain code. At this point I'm considering it a best practice to mark ALL functions as suspending, because failing to do so means that at some future point, when we have to make a function suspending, we have a mess of cascading changes. Has anyone else been dealing with this?
🤔 1
💡 1
👎 4
😅 1
👍 1
👎🏾 1
There was great care with exceptions to not require putting
throws
clauses, but we end up with the same thing. If we define an interface, we HAVE to make it suspending because we don't know what implementation might exist that would require it.
This then leads to requiring us to not use properties in many places for the same reasons.
The main reason this has come up, is that I'm switching to use the new AWS Kotlin SDK, which is really nice. But as soon as I did, I needed to change virtually every function in the entire codebase to use suspend, because at any given point there's almost always a chance the code will be making a suspending call.
And what's even better is changing all of my properties to functions that can be suspended. I know the arguments for not having suspend on properties, but the whole thing completely breaks encapsulation.
j
This is a good perspective on the Kotlin suspend function design decision.
This was also written even before the concept of structured concurrency was introduced to the coroutines design, which solidified the need for explicit suspend functions called within a coroutine launched within an explicitly defined scope.
s
I think those are solid arguments but I can't help but feel like what we're headed for is just defining all the functions as suspend. Code changes. Adding suspend is a breaking change, so it just seems to make sense to add it up front, even if I'm not sure I'm going to ever use it. But even if you believe in the modifier, having an easy way to apply it globally or at the class level would be ideal for productivity.
j
I do think there is a use case for being able to define a function and its lambda argument as being able to be called from either a non-suspend or suspend context and have it retain that context depending on the code that calls it. I've run into this need on occasion. The question is posed in the comments and Roman acknowledges it can be resolved with an
inline
function. But it would be nice if there was a language feature that supported this context inference.
v
I've avoided the AWS Kotlin SDK for this very reason. And I use the sdk in short-lived lambda functions - he mental overhead of coroutines and suspend just isn't with it for me, for tasks which are likely to do one thing then get shut down. So I totally share your concerns.
j
Unless you are calling a suspend function there's no need for your function to suspend or to prevent non suspend functions from calling it, which is what the suspend keyword does. What's the big problem here? It's just a keyword that you add on a need to have basis. The compiler will tell you when it's needed even. Is the underlying issue perhaps that you have some legacy blocking code surrounding your non blocking code? Things get a lot easier if you just go all in on non blocking.
d
Hi! We had a discussion exactly like this some time ago: https://kotlinlang.slack.com/archives/C1CFAFJSK/p1705997174121329 In the end, I think it's fair to say that we decided that
suspend
functions don't pollute the whole codebase. @steamstreet, if you have examples of the contrary that weren't discussed in that thread, please share them so that we can better support your usage patterns.
👍 1
k
This is a loosely related read that’s very worth your 20 minutes. https://vorpus.org/blog/notes-on-structured-concurrency-or-go-statement-considered-harmful/