3 ms·
Technically you can get the convenience of not needing to write async/await, with the same runtime implementation decisions underneath as Tokio/futures. Kotlin
by Rusky 9y ago
Technically you can get the convenience of not needing to write async/await, with the same runtime implementation decisions underneath as Tokio/futures. Kotlin is an example of this approach- its coroutines are state machines but with implicit awaits.
This can even be extended to "awaiting across function calls" with effect polymorphism. I haven't seen this done in this context, but it would allow things like passing an async closure, or a generic type with an async trait implementation, to a normal function and having it automatically become an async function instead.
The real choice between explicit and implicit suspension points is thus syntactic, not implementation-driven. The reasoning there is more along the lines of "I like to see where my function might suspend" vs "I don't want to pepper my code with `await`."
- steveklabnik 9y agoI have been meaning to dig into Kotlin's implementation, thanks for that! Is there any good reference documentation to dive into? Most of the stuff I saw was from a user's perspective.
- Rusky 9y agoI used this: https://github.com/Kotlin/kotlin-coroutines/blob/master/kotlin-coroutines-informal.md https://github.com/Kotlin/kotlin-coroutines/blob/master/kotl...
- lmm 9y ago> I haven't seen this done in this context, but it would allow things like passing an async closure, or a generic type with an async trait implementation, to a normal function and having it automatically become an async function instead. I've done that a fair bit in Scala using HKT. E.g. superclass is written in terms of a generic monadic type, one subclass implementation uses Future (actually EitherT with Future), another uses identity, a third uses Writer to track statistics...
- Rusky 9y agoAh, right. I guess I have seen this sort of thing in Haskell then as well. When implemented with HKTs it usually gets really messy with things like monad transformers, so I prefer to think of asynchronicity more in terms of continuations.
- lmm 9y agoI find monad transformers much clearer than continuations; a monad transformer stack tells you exactly how your effects are going to be interleaved, which is necessarily complex, whereas a continuation could be doing anything at all, the way I see it.
- Rusky 9y agoNo, continuations can be controlled similarly through effect polymorphism, which is what I was trying to describe. The difference is not that continuations allow anything at all, but that your effects are commutative rather than layered like a monad transformer stack.
- lmm 9y ago> continuations can be controlled similarly through effect polymorphism, which is what I was trying to describe. Fair enough, but you're effectively talking about a secondary, novel type system, right? One of the things I like about monads is that they can be just plain old values of plain old datatypes. > The difference is not that continuations allow anything at all, but that your effects are commutative rather than layered like a monad transformer stack. Yeah, monad transformers do feel overly cumbersome for the cases where effects do commute. The trouble is that some effects don't commute, and I've yet to see a formalism that had a good solution to distinguishing effects that commute from those that don't. (I read a paper about a tensor product construct once, but couldn't really follow how it was supposed to work in practice)
- Rusky 9y ago