Rust's async story is much less ergonomic than go's -- mostly because of lack of garbage collection. That might be a good reason by itself?
Rust's async story is much less ergonomic than go's -- mostly because of lack of garbage collection. That might be a good reason by itself?
Does Go actually have an async story? I know that question risks starting a semantic debate, so let me be more specific.
Go allows creating lightweight threads to the point where it's a good pattern to just spin off goroutines left and right to your heart's content. That's more of a concurrency primitive than async. Sure, you combine it with a channel, and you've created an async future.
The explicit passing of contexts is interesting. I initially thought it would be awkward, but it works well in practice. Except of course when you need to call a blocking API that doesn't take context.
And in environments where you can run a multitasking runtime, that's pretty cool. Rust's async is more ambitious, but has its drawbacks.
Go's concurrency story (I wouldn't call it an async story) is way more yolo, as is the rest of the Go language. And in my experience that Go yolo tends to blow up in more hilarious ways once the system is complex enough.
For one, I am glad I don't have to color my functions like your typical async.
I agree that this is the big problem with Rust's async story.
But like I said, in my opinion this compares with Go not having an async story at all.
Other languages have ill considered shortcomings. Rust has ambitious shortcomings.
Go's async story is great, as there is no function coloring at all. That being said, I don't like Go's syntax very much. The runtime is great though.
To be fair, Go’s async story only works because there’s a prologue compiled into every single function that says “before I execute this function, should another goroutine run instead?” and you pay that cost on every function call. (Granted, that prologue is also used for other features like GC checks and stack size guards, but the point still stands.) Languages that aspire to having zero-cost abstractions can’t make that kind of decision, and so you get function coloring.
I'm not sure this is 100% correct. I haven't researched it but why would they perform such a check at runtime if it is 1)material and 2) can be done at compile time. However, even if it is, Go is only trying to be medium fast / efficient in the same realm as its garbage collected peers (Java and C#).
If you want to look at Rust peer languages though, I do think the direction the Zig team is heading with 0.16 looks like a good direction to me.