I'm doing some reading on asynchronous programming...
# coroutines
c
I'm doing some reading on asynchronous programming in different languages. I'm adding what I learn into a WIP doc - you check it out here Q: Do you know of good blog posts or articles that explain how async is implemented in languages?
l
Kotlin coroutines KEEP document is quite filled with how suspend functions are implemented IIRC
t
async/await / coroutines generally breakdown into two camps, Stackless and stackful. If you google those, you'll get some more info.
stackless are the easiest to understand (IMO). The compiler is just hiding a callback. It's mostly synatic sugar over callbacks. This is what kotlin, rust, C++, zig, etc do.
If you take a small bit of kotlin code like :
suspend {
println("one")
delay(1000)
println("two")
}
And look at the resulting java code the kotlin compiler outputs it sorta looks like :
void suspendFn(int version) {
switch(version) {
case 1:
println("one");
setDelay(1000);
break;
case 2:
println("two");
break;
}
}
1
when the delay code calls
resume
the compiler turns in into a call to
suspendFn(2)
Go & Loom use stackful coroutines, which are a simluar to threads (but far more light-weight). A stack is given to every
task
. In theory, you can suspend them at any point, just like a thread can, unlike stackless which run until a suspend point is hit.
There are pros and cons for both. Stackless tend to have the colored function problem. Personalty I never considered it much of a problem, but Loom & Go avoid the issue.
generally, if you see decorators on functions (or function calls) like
suspend
and
async
it's stackless.
I think C#/.net is stackless, but I haven't dug around much, so I don't know.
I'm really interested in different async models & implemtations. I did this benchmark a while ago : https://github.com/TwoClocks/coroutine-benchmarks I'd love to see what you come up with.
💜 1
c
My efforts will be mostly reading and understanding how they work. Won't be benchmarking any languages. But your benchmark is amazing. If I come to a point where benchmarking also makes sense I'll probably fork or contribute to your repo
t
maybe more interesting for you, I think the benchmarks are the smallest/simplest implementation of a coroutinein each language.... or at least as small as I could figure out.
c
That is true. Didn't think of them like that. Let's see if I can learn something from your implementation. Gotta say, I've never written zig but I hear many praising it (even you). This should be fun learning it's implementation too
e
In addition to the nice read about coloured functions linked to above (thanks!), I'd like to recommend this talk by mr. Kotlin coroutine himself, Roman Elizarov:

https://youtu.be/_hfBv0a09Jc

While the talk itself is likely too Kotlin specific, the part that starts shortly after 21 minutes is what I find most interesting about coroutines: why is there the
suspend
keyword, but not the
async
and
await
keywords? That's the brilliance of Kotlin coroutines, IMO!
Do note that this talk is from 2017 when the Kotlin coroutine syntax was a little different from the modern state of the language, so there might be syntactic problems with the code as presented in 2017 when run in 2021
BTW, the conclusion of his very important point is reached around 30:30 into the video
t
async != coroutines. You can write coroutines w/out the kotlinx-coroutine library. Asycn (and everything else in the library) is just helpers or to deal with coroutines. You could write the equivalent of everything in the coroutines library your self if you wanted to. There is no magic in there. The thing you can't write your self, and only the compiler can do for you is suspend/resume. Those are keyword implemented by the compiler. Everything is built on top of that.
generateSqeuence
in the stdlib uses coroutines, but has not dependency on kotlinx-coroutines.
@Clament John Zig is "fun" for sure. It's the first languages I've used where the "macro" language is the same as the run-time language, except run at compile-time. (I think maybe old-school lisp has this? not sure). I'm not sure Zig is actually useful in the real world for real projects. TBD for me.