Rust provides only OS threads, and supports async/await. Granted.
Why is the actual trend to build async libraries (tokio, actix, etc.) rather than to build libraries of green threads? Is it more performant than green threads?
An inconvenient I see with Async is that it is forces to rewrite all the standard library in an async way, so that we end up with 2 languages : SyncRust and AsyncRust.
Yes, green threads completely changes how code is compiled. You may have heard that Rust does not have a runtime, and one of the things this implies is that Rust can't use green threads.
Green threads basically involves having the compiler insert yield points everywhere so it can pause execution of any thread at any time. Additionally it would require the compiler to embed a library similar to Tokio in all applications so it can execute its green threads efficiently.
The issue is running stuff on those green threads. The green thread library must be able to preempt (i.e. interrupt) the current green thread on an OS thread so it can be replaced by another green thread.
Go doesn't have this problem, not because there's no AsyncGo but actually there's no SyncGo.
In Go, every IO calls are made asynchronous underneath. What it actually do is to hide the await keyword to make it looks more like synchronous code. Cons? We can't put future combinators like join and select on it. Instead in Go we put 2 additional goroutines and combine them with a channel, which is suboptimal.
Unlike Go, Rust can't drop the sync version of code as it defeats the original purpose of the language - to replace libraries written in C.
I mean, I suppose you could in the same sense that you could make a compiler that compiles Java code with one switch and Go code with another. But it wouldn't be comparable to the difference between --debug and --release.
Green threads are not just an optimization. They change behaviour in quite important ways, and Rust would no longer be the same language if you introduced them.
If your project doesn't need async/await, it can use something like the blocking module in reqwest to wrap the async code, but if you need the advantages of async/await, then yes, you need to use async/await.
Thought of the day: nonstandard libraries are not always interoperable: e.g. reqwest will not work with async-std, as it requires tokio. And what if you need some library built on top of async-std, and some other one built on top of tokio?