> Green threads aren’t easier than async functions. The function colors don’t go away
Don't they? Using green threads I can happily call a blocking function in a synchronous context in one place, and run it with a goroutine in another place.
With async (particularly Rust's tokio), you need to pass around the "runtime" object in order to call an async function in a synchronous context.
Go functions are coloured as well. context.Context proliferates everywhere IO takes place to handle cancellation / short circuiting because goroutines can’t be sent signals to die like threads. They have to exit themselves.
Not really. A context-less function can call a contextual one by passing in a context.Background(), and a contextual function can call a context-less one by leaving out the context. This is unlike the split between sync/async.
> A context-less function can call a contextual one by passing in a context.Background()
Yeah, but if you're calling passing context.Background() because the caller's caller had a context but you can't access it through the context-less caller, now you've got a "synchronicity leak" (a.k.a. "the program won't gracefully shut down when I press ^C.")
Golang's concurrency is an abstract machine model whose soundness you need to enforce yourself, because the compiler doesn't care about it.
If the compiler actually cared about enforcing the concurrency model, writing code like the you're describing would fail to compile, due to function coloring.
Don't they? Using green threads I can happily call a blocking function in a synchronous context in one place, and run it with a goroutine in another place.
With async (particularly Rust's tokio), you need to pass around the "runtime" object in order to call an async function in a synchronous context.