Sure, it is "childish and ad-hominem", it is also efficient and usually works. Also, non-async/await solutions for concurrency and asynchrony result in a more verbose, complex and bloated syntax, having to invent fancy terms like "structured concurrency" for use cases which in C# are simply expressed by awaiting the task at the point of its consumption and not declaration (no special methods required) or in Rust via simple, albeit for a different scenario, join!().
var user = try alloc.create(@Frame(service.GetUser));
user.* = async service.GetUser(id);
defer alloc.destroy(user);
var promos = try alloc.create(@Frame(service.GetPromotions));
promos.* = async service.GetPromotions(category);
defer alloc.destroy(promos);
var eligible = GetEligibility(await user.*, await promos.*);
but the claimed difference is not present in this code. It is that GetUser and GetPromotions do not themselves know whether they are async. The author of service is able to just take some readers and writers or some types or objects implementing some protocols and use them, then service's methods inherit the async-ness of its dependencies.
async/await and structured concurrency are two different things, Swift has an async/await syntax but is still structured concurrency.
The point of async/await is that it converts your function into a reentrant state machine (in a different way than compiling a sync function already turned it into a state machine.) The problem with the usual design is that it uses futures, which are bad because they have dynamic lifetimes.