Somewhat famous article about state of asynchronous programming model of many languages, states that they have a "color" problem, which, in particular, divides the ecosystem into two seperate worlds: async and non-async. Here are properties of such a language:
- Every function has a color, either red or blue (e.g.
async def
) - The way you call a function depends on its color (e.g.
await
) - You can only call red function from within another red function,
SyntaxError: 'await' outside async function
- Red functions are more painful to call (the idea is that if you decide to make a function red, everyone using your API will want to spit in your coffee and/or deposit some even less savory fluids in it)
- Some core library functions are red, so you can't avoid red functions
Kotlin is pretty new language, so I thought I should look into its asynchronous model. However, Kotlin transpiles to JavaScript, so I believe it has color problem more than I believe it doesn't. But its coroutines were a bit hard for me to gross and got confused, so I'm here asking Which of those properties are true for Kotlin? (and how much of color problem it solved).
CodePudding user response:
- Every function has a color, either red or blue (e.g. async def)
Yes.
- The way you call a function depends on its color (e.g. await)
Yes.
- You can only call red function from within another red function
Yes.
- Some core library functions are red
Yes, but they are there to help you with the red function business. You are never forced to use them to get some basic functionality.
- Red functions are more painful to call
Also true, but there's a lot of support to make the pain quite low. You can just use runBlocking { }
anywhere to "ascend into the red world", and you can color the entry point itself red by just writing suspend fun main()
. Another good choice of Kotlin, not seen in many other languages, is that the await
-like behavior is built into the function itself, you don't have to write myFunction().await()
.
In practice, the most painful aspect of Kotlin Coroutines is that they can't remove blocking from the underlying APIs. For example, it's pretty easy to slip into using Java File IO, which is blocking, and freeze the progress of all the other coroutines using the same thread. It is also pretty hard for the compiler to determine when you're doing this, so you find it out the hard way.
CodePudding user response:
I think Kotlin suspend functions are somewhere in between blue and red. They are invoked synchronously and very easy to use, so they're like blue, but they can only be invoked easily from other suspend functions - so red.
Note that red functions are being added to languages not without a reason. This reason is performance. We can do everything with blue-only functions, but it won't be as fast as using reds.
I think Kotlin coroutines or similar solutions in other languages could eventually lead to solving the color problem. Not by going fully-blue, but actually the opposite: fully-red. Or whatever suspend functions really are. If we keep our whole codebase suspendable then we get performance benefits and we write the code as it is just blue.
Unfortunately, I think a lot of time has to pass until we get there. We basically need to break compatibility with all existing libraries that are blue. Which is costly.