Async enables clear contract for a type that represents a delayed result.
Better implementations offer eager execution and allow to easily interleave multiple concurrent futures/tasks, like C#. Green threads on the other hand are a workaround to deal with blocking for the most trivial case of cooperative multi-tasking, offering little beyond that.
> Async enables clear contract for a type that represents a delayed result.
It's not really a type, otherwise it would be something like Future<T> in Java and plenty other languages. It is usually implemented as a transformation to a state machine.
Also, Loom is M:N and calling them green threads doesn't give you the whole picture at all. Not exactly sure what you mean by easily interleave -- functionality wise the two is more or less equivalent. You just get to keep your simpler mental model (and tooling) with virtual threads.
blocking is an implementation detail; both async/await and green threads can be implemented on top of either traditional blocking IO, or callback/non-blocking IO
I'd be even happier to discuss concrete code blocks / examples, that's where the superiority of green threads truly shines