This is a major milestone for Rust usability and developer productivity.<p>It was really hard to build asynchronous code until now. You had to clone objects used within futures. You had to chain asynchronous calls together. You had to bend over backwards to support conditional returns. Error messages weren't very explanatory. You had limited access to documentation and tutorials to figure everything out. It was a process of walking over hot coals before becoming productive with asynchronous Rust.<p>Now, the story is different. Further a few heroes of the community are actively writing more educational materials to make it even easier for newcomers to become productive with async programming much faster than it took others.<p>Refactoring legacy asynchronous code to async-await syntax offers improved readability, maintainability, functionality, and performance. It's totally worth the effort. Do your due diligence in advance, though, and ensure that your work is eligible for refactoring. Niko wasn't kidding about this being a minimum viable product.
I’ve been playing with async await in a polar opposite vertical than its typical use case (high tps web backends) and believe this was the missing piece to further unlock great ergonomic and productivity gains for system development: embedded no_std.<p>Async/await lets you write non-blocking, single-threaded but highly interweaved firmware/apps in allocation-free, single-threaded environments (bare-metal programming without an OS). The abstractions around stack snapshots allow seamless coroutines and I believe will make rust pretty much the easiest low-level platform to develop for.
This is a big improvement, however this is still explicit/userland asynchronous programming: If anything down the callstack is synchronous, it blocks everything. This requires every components of a program, including every dependency, to be specifically designed for this kind of concurency.<p>Async I/O gives awesome performance, but further abstractions would make it easier and less risky to use. Designing everything around the fact that a program uses async I/O, including things that have nothing to do with I/O, is crazy.<p>Programming languages have the power to implement concurrency patterns that offer the same kind of performances, without the hassle.
This is big! Turns out that syntactic support for asynchronous programming in Rust isn't just syntactic: it enables the compiler to reason about the lifetimes in asynchronous code in a way that wasn't possible to implement in libraries. The end result of having async/await syntax is that async code reads just like normal Rust, which definitely wasn't the case before. This is a huge improvement in usability.
Isn't it kind of a poor design choice that Rust will not actually begin execution of the function until `.await` is called? If I didn't want to execute the function yet, I wouldn't have invoked it. Awaiting is a completely different concept than invoking, why overload it?<p>If you want to defer execution of a promise until you await it, you can always do that, but this paradigm forces you to do that. The problem is then, how do I do parallel execution of asynchronous tasks?<p>In JavaScript I could do<p><pre><code> const results = await Promise.all([
asyncTaskA(),
asyncTaskB(),
asyncTaskC()
]);
</code></pre>
and those will execute simultaneously and await all results.<p>And that's me deferring execution to the point that I'd like to await it, but in JavaScript you could additionally do<p><pre><code> const results = await Promise.all([
alreadyExecutingPromiseA,
alreadyExecutingPromiseB,
alreadyExecutingPromiseC
]);
</code></pre>
Where I pass in the actual promises which have returned from having called the functions at some point previously.<p>So how is parallel execution handled in Rust?
This is going to open the flood gates. I am sure lot of people were just waiting for this moment for Rust adoption. I for one was definitely in this boat.<p>Also, this has all the goodness: open-source, high quality engineering, design in open, large contributors to a complex piece of software. Truly inspiring!
I've been working with alpha futures, tokio, hyper, etc with async/await support on rust beta (didn't use async std yet) and can attest to them working quite well. There was quite a learning curve for me to know when to use arc, mutex, different stream combinators, and understand raw polling, but after I did, writing the code became a bit easier. I suggest anyone wanting to learn to grab a tcp-level networking project/idea/protocol and grind on it for days, heh.
For JavaScript developers expecting to jump over to Rust and be productive now that async/await is stable:<p>I'm pretty sure the state of affairs for async programming is still a bit "different" in Rust land. Don't you need to spawn async tasks into an executor, etc.?<p>Coming from JavaScript, the built in event-loop handles all of that. In Rust, the "event loop" so to speak is typically a third party library/package, <i>not</i> something provided by the language/standard itself.
The same day as async/await hits stable, the next Prisma alpha is released and is the first alpha that's based on Futures and async/await.<p><a href="https://github.com/prisma/prisma-engine/" rel="nofollow">https://github.com/prisma/prisma-engine/</a><p>Been working with the ecosystem since the first version of futures some years ago, and I must say how things are right now it's definitely much much easier.<p>There are still optimizations to be made, but IO starts to be in a good shape!
Exciting! I know this has been a long time coming, so congrats to everyone for finally landing it in stable.<p>As a rust noob, small question based on the example given: Why does `another_function` have to be defined with `async fn`? Naively, I would expect that because it calls `future.await` on its own async call, that from the "outside" it doesn't seem like an async function at all. Or do you have to tag any function as async if it calls an async function, whether or not it returns a future?
If you're just starting to learn Rust, I suggest waiting a little before using async. It's awesome, BUT libraries, tutorials, etc. will need a while to update from the prototype verion of Futures (AKA v0.1) to the final version (std::future). Changes made during standardization were relatively minor, but there's no point learning two versions of Futures and dealing with temporary chaos while the ecosystem switches to the final one.
This seems very similar to Python's approach, which I've been finding poor to use.<p>I was wondering if a more pleasant approach would be to add a 'defer' keyword to return a future from an async call, and have the default call be to await and return the result (setting up a default scheduler if necessary). Requiring the await keyword to be inserted in the majority of locations seems poor UX, as is requiring callsites to all be updated when you update your synchronous API to async.
This is massive and props to the team! I have a small prototype for interop between 0.1 and 0.3 futures which are also compatible with async/await first order.<p>Excited for where this takes us! Can't wait for tokio 2.0 now.<p><a href="https://github.com/cdbattags/async-actix-web" rel="nofollow">https://github.com/cdbattags/async-actix-web</a>
I have honestly never enjoyed learning a language more than I've been enjoying Rust, the docs and material are so thorough and clear. Very excited to tackle this topic.
I have never used async/await and cant really understand it. Is it like coroutines in lua? It seems very similar. But I guess its not limited to one thread like lua? Whats makes it better then threaded IO? Losing the overhead of threads?<p>I like coroutines but thats mostly because they are not threads, they only switch execution on yield, and that makes them easy to reason about :)
This is great news!<p>I tried out Rust for a typical server-side app over a year ago (JSON API and PostgreSQL backend), and the lack of async-await was the main reason I switched back to Typescript afterwards, even though Diesel is probably the best ORM I've ever worked with. Time to give it a try again.
This is awesome... been waiting on this... looking at a lot at rocket and yew (really new with rust), and had been waiting to see the async stuff shake out before continuing (been holding for a few months now), may take a bit of time over the weekend to start up again.
An interesting presentation on the history of futures in Rust (from RustLatam 2019):<p><a href="https://www.youtube.com/watch?v=skos4B5x7qE" rel="nofollow">https://www.youtube.com/watch?v=skos4B5x7qE</a>
Rust beginner here who writes a lot of async code in Node.js. If I am to start writing async code in Rust, should I directly pick up async-await? Or should I first understand how it is done in the current way?
I would be interested to know if a comparison between async and sync API at level exists. I have this intuitive but probably wrong feeling that async often implies memory overhead.
Thank you Alex Crichton, Niko Matsakis and all other core devs, Rust is by far the most well designed programming language I've ever dealt with. It's a masterpiece of software engineering IMO.
How does rust perform in parallel on the same memory?<p>I heard it uses locks?<p>This is not on the same memory right? <a href="https://news.ycombinator.com/item?id=21469295" rel="nofollow">https://news.ycombinator.com/item?id=21469295</a><p>If you want to do joint (on the same memory) parallel HTTP with Java I have a stable solution for you: <a href="https://github.com/tinspin/rupy" rel="nofollow">https://github.com/tinspin/rupy</a>