The Kotlin documentation's overview of coroutines says that "Kotlin provides coroutine support at the language level, and delegates most of the functionality to libraries." But does Kotlin actually support coroutines, or are they misusing the word?
In practice what the quote from the docs means is:
- The language provides the
suspendmodifier, and the compiler transforms suspend functions into CPS (continuation-passing style). - The
kotlinx.coroutineslibrary provides machinery for executing the resulting chains of continuations.
I haven't found a good answer for which bit of the above constitutes 'a coroutine' in Kotlin's terminology. My current best understanding is that Kotlin refers to the instance created by launch as a 'coroutine'. That fits with the slogan we see everywhere that "coroutines are light-weight threads" (for example here).
suspend fun myFunction(): Unit = delay(100)
someScope.launch { myFunction() } // this creates a 'coroutine'.
However it doesn't fit with my (admittedly thin) knowledge/experience of coroutines in other languages. Outside of Kotlin, I would describe a coroutine as a function that is like a subroutine, but can suspend and yield control to another arbitrary coroutine at any point. This definition is partly based on my reading of the Wikipedia article on Coroutines.
This is different from the way Kotlin uses the term in two major respects:
- In Kotlin, the coroutine is the rather abstract 'lightweight thread' that executes the function, whereas by my definition, the coroutine would be the function itself.
- Kotlin's suspend functions can only yield control back to the caller, whereas a defining characteristic of a coroutine is that it can pass control to another coroutine.
I think that Kotlin's suspend functions are actually generators or semicoroutines, and that the kotlinx.coroutines library is essentially providing a trampoline.
Is my understanding correct, based on the way the term 'coroutine' is used outside of Kotlin? If so, could the existing language support actually be used to implement something more akin to true coroutines, or is it fundamentally limited to semicoroutines and generators?