I still remember first hearing about Rust and how it was using Green Threads, then out of the blue a year later passes or months, and I'm reading that it doesn't do any of that anymore, it's basically C++ on steroids mixed with functional programming. I never did look up why they gave up on Green threads and other things, I wonder if they faced similar challenges?
Rust has settled into an excellent design niche where the language does not provide any features that require a language runtime.
Rust's async/await is a purely compile-time feature, with no runtime support required.
This is extremely powerful because it means you can do things like easily run async code on embedded devices with no OS.
To run async code in rust, you bring your own executor. The most popular one is tokio (for desktop OSs), but you also have stuff like pollster (for running async code as blocking code) and embassy or RTIC (for embedded).
I might be completely wrong as I only played with rust but the current method seems to couple any async libraries you’d like to write to the executor. Which feels wrong imo.
Would it be feasible to provide async io (file, network) code in std and let the executors execute?
Or even some std traits that abstract the filesystem, network etc so that the executors can bring their own implementations but at least library code could only depend on std?
The feature is less than 1 year old, so a lot of the ecosystem couldn't use the feature because of being written before the feature existed. It does seem silly to have a warning today.
Agreed, as much as there are complaints about usability of async in Rust, many alternatives proposed would fail in resource constrained systems. Green threading would be impossible or very limiting on embedded, where each stack eats away at something like 1-2% of memory and allocation is likely impossible or prohibitively expensive.
I do note that some of the futures are starting to take up a couple KiB of RAM and ROM.
This is a fine approach but it's trivial to ship green threads with no runtime support as well. Various libraries implementing the feature exist for C or Zig etc.
If you can accept cooperative scheduling that runs tasks only on a single core, then yes, lightweight solutions exist. This is more like "event-driven coroutines" than "green threads" though.
If you want "full" green threads with preemptive scheduling and parallel execution across multiple cores, then an active runtime is needed.
>I still remember first hearing about Rust and how it was using Green Threads, [...] I never did look up why they gave up on Green threads
It's because green threads have unavoidable performance costs. I collected various threads that has Rust contributors explaining the costs they didn't want to pay:
https://news.ycombinator.com/item?id=39062953
A language like Go is willing to pay those performance costs because they deliberately sit at a higher level of abstraction than lower-level Rust.
Each chose different tradeoffs for different goals:
- Golang : green threads worth the perf cost to gain higher productivity (goroutines, channels, etc) for the type of programs that Go programmers like to write
- Rust : green threads are not worth the perf cost so as to not sacrifice the best possible performance for the type of programs Rust programmers like to write
You can't have a language+runtime that satisfies both camps 100% perfectly. The language designer must choose the tradeoff. But because this tradeoff decision is not blatantly well-known and disseminated ... it also perpetually confuses Language X proponents on why Language Y didn't do the same thing as Language X.
User level (aka green) threading is difficult. Very few implementations work (Erlang, Golang, <any others>+) and it takes a great deal of time and effort to get to that "fully working" state.
+Perhaps the new Java fiber stuff works but I don't have enough data to be sure yet.