Live data from Hacker News

Async-await on stable Rust

blog.rust-lang.org

61–70 of 392 posts

Re: Async-await on stable Rust

#61

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. Async/await lets you write non-blocking, single-threaded but highly interweaved firmware/apps in allocation-free, single-threaded environments (bare-metal programming wi…

Keep in mind that the current release only brings an MVP of the async/await feature to the table. The two things I've missed are both no_std support and async trait methods, but there are reasons these haven't been completed yet. That doesn't mean they won't be available in the future, just that the team has prioritized to release a significant part of the feature that many will already find useful.

Re: Async-await on stable Rust

#62
This is a major milestone for Rust usability and developer productivity.

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.

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.

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.

Re: Async-await on stable Rust

#63

Earlier quoted context omitted.

The point is that Rust's borrow checker can't reason about lifetimes very well over function boundaries. It can reason about coarse things that are expressable in the type language, but everything more nuanced than that, such as reasoning about how control flow affects the lifetimes is limited to inside function bodies. The difference between synchronous code and async code implemented as libraries is that async code…

> The point is that Rust's borrow checker can't reason about lifetimes very well over function boundaries. It can reason about coarse things that are expressable in the type language, but everything more nuanced than that, such as reasoning about how control flow affects the lifetimes is limited to inside function bodies. BTW this is a big pain point for me (unrelated to async). Code like this: let ref = &mut self.fi…

Couldn't you just pass in the (other) borrowed field as an argument for the function? If you need it to work without adding the argument when called outside of the class, you could overload it with a version that borrows the field and passes it to the version that takes the field as an argument, right?

I'm newish to Rust, so this is just an intuitive guess. Please let me know if I'm wrong.

Re: Async-await on stable Rust

#64

Earlier quoted context omitted.

Are you sure? How would the JavaScript functions execute simultaneously on a single thread? Async is about interleaving computations on a single thread.

Async doesn't have to be single-threaded generally. JavaScript is limited to a single-threaded model, but in other languages (like clojure), futures are tasks run on some other thread. I don't use rust and this article doesn't make any mention of threads so I'm not really sure what's going on here.

> futures are tasks run on some other thread.

This is usually false, in Rust and elsewhere. Futures are tasks that run on whatever thread is scheduling them. They are an even lighter-weight version of green threads/fibers/M:N.

Re: Async-await on stable Rust

#65
post #30

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? 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 the…

JavaScript automatically starts the tasks and this is bad design IMHO. One loses referential transparency and the ability to run the workflow with different schedulers. It looks like Rust has done a better job.

JavaScript does not automatically start the tasks. It executes the function if you...execute the function. If you just want to pass around something with deferred execution, you can just pass the function around, or wrap it in a closure.

Re: Async-await on stable Rust

#66

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. Async/await lets you write non-blocking, single-threaded but highly interweaved firmware/apps in allocation-free, single-threaded environments (bare-metal programming wi…

Which executor do you use? Tokio is a bit heavy, no?

Not the parent, but I've been keeping my eye on https://github.com/Nemo157/embrio-rs

Re: Async-await on stable Rust

#67

Earlier quoted context omitted.

"At the same time"? How does that happen on a single thread?

It just interleaves execution. This really seems more similar to python's generator/yield semantics.

That's how it is implemented under the covers, it uses the nightly only generators feature which builds a state machine of the entire future.

Re: Async-await on stable Rust

#69

Earlier quoted context omitted.

ML-inspired languages have all these features too; is the advantage of Rust over those just that it’s more mainstream, the ecosystem is bigger, etc.?

That, and that it has better support for imperative features than most ML languages. You can combine your fancy combinators with mutable variables and for-loops when just want to get something done quickly. In general, Rust just has all the little details right. It's hard to describe that in concrete terms, but it makes using it a very smooth and satisfying process. I get a similar feeling when using postgres: there'…

Thanks! I actually do use Rust as my main professional language (since my company’s product is based on timely-dataflow and differential-dataflow, so it was the only natural choice).

But I’m always curious about how it stacks up against other languages I’m less familiar with that share similar ideas.

Re: Async-await on stable Rust

#70
post #64

Earlier quoted context omitted.

Async doesn't have to be single-threaded generally. JavaScript is limited to a single-threaded model, but in other languages (like clojure), futures are tasks run on some other thread. I don't use rust and this article doesn't make any mention of threads so I'm not really sure what's going on here.

> futures are tasks run on some other thread. This is usually false, in Rust and elsewhere. Futures are tasks that run on whatever thread is scheduling them. They are an even lighter-weight version of green threads/fibers/M:N.

But only if you await them in that thread. If you `spawn` them, they can be executed in another free thread; although you'll miss the return value in this case.

So for people new to async/await in rust, how a web server usually works:

Request/response future is spawned to the runtime, and a thread decides to take the future for execution if the runtime uses multithreading.

Inside of this request/response future whatever futures are .awaited will continue the execution in the same thread when ready.

Users can also spawn futures inside the request/response future, which might go to another thread. The result of this future is not available for the spawning thread.

Some executors have special functions, such as `blocking` that will execute the block in another thread, giving the result back to the awaiting thread when finished.

Post reply on HN