Comment by thomashabets2
1 day ago
Rust: Well yes. Rust does force you to understand the things, or it won't compile. It does have drawbacks.
Go: goroutines are not async. And you can't understand goroutines without understanding channels. And channels are weirdly implemented in Go, where the semantics of edge cases, while well defined, are like rolling a D20 die if you try to reason from first principles.
Go doesn't force you to understand things. I agree with that. It has pros and cons.
I see what you mean but "cheap threads" is not the same thing as async. More like "current status of massive concurrency". Except that's not right either. tarweb, the subject of the blog post in question, is single threaded and uses io_uring as an event loop. (the idea being to spin up one thread per CPU core, to use full capacity)
So it's current status of… what exactly?
Cheap threads have a benefit over an async loop. The main one being that they're easier to reason about. It also has drawbacks. E.g. each thread may be light weight, but it does need a stack.
> Go: goroutines are not async
Sure they are. The abstraction they provide is a synchronous API, but it's accomplished using an async runtime.
By that definition, pthread is also async. If everything is async, then the word loses all meanings.
Async is really about the surface syntax and ergonomics, not the implementation.
Eh, not really. Async (in this semantic context) is generally about cooperative concurrency and also often about concurrent or multiplexed I/O. Pthreads aren't async by those definitions, though you can run async code within a given pthread as usual.
Goroutines are an unusual case, in that they don't have cooperative concurrency--they're pre-emptive--but the Go runtime does perform I/O using concurrent multiplexers under the hood.
So goroutines are kind of both: computation execution and code semantics look like pthreads, but I/O operations look like NodeJS on the backend.
Now, I'm not sure what "async runtime" means in the GP. If they're referring to I/O multiplexers, then they should say that. If they're referring to something else, then I'm not familiar with other uses of that term that would accurately apply to Golang.
1 reply →
Yeah, in fact I'd argue that any abstraction that doesn't let you treat the work as sync is fundamentally broken.
https://journal.stuffwithstuff.com/2015/02/01/what-color-is-...
I'm trying to understand the context in which the parent commenter uses the term, since it can mean multiple things. They said "async" and then enumerated some wildly different things.
Like, do you need async runtimes to do epoll async in Rust? No. Ok, so that excludes many definitions. Do you need coroutines in C++ to do aio for reading and writing? No.
So like I said, what do they mean by "async"? The blog post refers to a web server that does "async" in Rust without any async runtime, and without the `async` keyword.
In other words, that parent commenter is what's called "not even wrong".