4 ms·
I have been using "async/await is bad, use {feature name[0]}" as a litmus test for people who are generally bad at programming, especially so at concurrent flav
by neonsunset 3y ago
I have been using "async/await is bad, use {feature name[0]}" as a litmus test for people who are generally bad at programming, especially so at concurrent flavour of such.
Sure, Rust is certainly verbose and very strict how the ownership rules apply in the context of async, but this is a hard constraint of its memory safety model.
We could probably do better while retaining all performance but this is by far one of the best implementations. Another example of nice to use async/await is C# which trades performance/memory (state has to be boxed if it is to live across continuations) for convenience (you just write it naturally without worrying about underlying behavior).
There is a reason Rust toyed with "green threads" at its inception but decided against such. The only popular languages of today that do these are Go and Java (which basically forced to do this because you can't go async without introducing the feature early in the lifecycle of the language, and the authors of project Loom are simply wrong with their excuses why this is superior to async/await).
Async/await is here to stay and is the right abstraction, git good, and it's not even difficult to use anyway.
[0] where feature name is green threads, not doing concurrency at all, doing it manually, etc.
- anonymoushn 3y agoIf someone is foolish enough to implement a websocket library that insists on performing I/O by calling the methods on the language's generic reader and writer interfaces (rather than just operating on buffers the user passes in or whatever), why should they need to implement it a second time to add async? There are plenty of languages in which they do not need to do this, like Python or Lua.
- neonsunset 3y agoHow does that relate to async/await? This is an arbitrary implementation choice. Generic reader/writer in Rust wouldn't matter since it will get optimized away, only leaving cooperative multitasking code if the buffer were to be filled by another thread/producer/source.
- anonymoushn 3y agoIf you write a library that implements websockets on top of the Read trait or on top of sockets, is it *also* an async websocket library, with no additional code and without containing any instances of the async keyword? In many languages the answer is yes. I guess I should specify that this is true even in a single-threaded context and even without any additional buffers or whatever.
- bitblender 3y agoDisliking async/await does not make someone "generally bad at programming". This is a childish ad-hominem mindset that has no place in technical debates. Rust's decision to adopt async/await over green threads was intended to keep the runtime lean, not because it is an inherently better abstraction. Java certainly could have async/await syntactic sugar around its existing futures api, but project loom has greater ambitions by retrofitting asynchronous IO onto the existing thread api. The authors are certainly not "simply wrong" for this decision.
- neonsunset 3y agoSure, 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!().
- astrange 3y agoasync/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.
- anonymoushn 3y ago> Also, non-async/await solutions for concurrency and asynchrony result in a more verbose, complex and bloated syntax I just write the same code that I would write if it were synchronous and it executes asynchronously.
- neonsunset 3y agoHow would your code look like if you wanted to fire off two concurrent requests and then consume their results later on? In C# it is just var user = service.GetUser(id); var promos = service.GetPromotions(category); var eligible = GetEligibility(await user, await promos);
- mike_hearn 3y ago> the authors of project Loom are simply wrong Why?
- grumpyprole 3y ago> Async/await is here to stay and is the right abstraction, git good, and it's not even difficult to use anyway. It's probably the right abstraction for Haskell, or any other language that works well with functional programming, lambdas and monads. Loom is a better fit for Java. Rust also would have probably been better off with something else. Effect handlers might have been a good choice.