Live data from Hacker News

Async-await on stable Rust

blog.rust-lang.org

31–40 of 392 posts

Re: Async-await on stable Rust

#31
post #10

How does rust perform in parallel on the same memory? I heard it uses locks? This is not on the same memory right? https://news.ycombinator.com/item?id=21469295 If you want to do joint (on the same memory) parallel HTTP with Java I have a stable solution for you: https://github.com/tinspin/rupy

The same as any language, if you were to write safe code at least. By safe code I mean, if you wrote Go in such a way that race conditions could not happen, you typically would write it in the same way in Rust. Often this involves Mutexes, but there are plenty of libraries that set up foundations for parallel behavior without Mutexes. So it can operate on "the same memory", and there are a whole lot of ways to manage…

this isn't quite right, this feels like what the standard response from a developer with some hubris. Humans are fallible and mushy, and depending on their current state are error prone. So why not just codify some "best practices" that are built in as primitives to a language like Rust?

There are ways to perform parallel work that is "safe", Rust solves this with the borrow/checker implementation, another clear "safe" way would be to make everything immutable as seen on Haskell, Ocaml, F# to where who cares about who gets to what first if the underlying thing will never change.

Mutexes and locks and all the other ways of doing parallel work that is "safe" isn't a primitive thats cooked in with the language.

Re: Async-await on stable Rust

#32

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…

The Fushia team also uses Rust's async/await this way in the implementation of their network stack.

Re: Async-await on stable Rust

#34
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…

Are you sure? How would the JavaScript functions execute simultaneously on a single thread?

Async is about interleaving computations on a single thread.

Re: Async-await on stable Rust

#35
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…

> Awaiting is a completely different concept than invoking, why overload it?

The wording is a bit imprecise; you can't 'await' something to invoke it, exactly. It also won't begin execution until .await is called. What happens is, at some point, you have a future that represents the whole computation, and you pass it to an executor. That's when execution starts.

There's a join macro/function that works the same way as Promise.all, and is what you'd use for parallelism.

Re: Async-await on stable Rust

#36

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…

It's really tricky; there's a tension here between just making your code work, and not making it brittle to further modification.

Re: Async-await on stable Rust

#37
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…

In Rust, you can use a future adapter that does this:

    futures::join!(asyncTaskA(), asyncTaskB()).await
See the join macro of futures[0]. The way it works is, it will create a future that, when polled, will call the underlying poll function of all three futures, saving the eventual result into a tuple.

This will allow making progress on all three futures at the same time.

[0] https://docs.rs/futures/0.3.0/futures/macro.join.html

Re: Async-await on stable Rust

#38
post #31

Earlier quoted context omitted.

The same as any language, if you were to write safe code at least. By safe code I mean, if you wrote Go in such a way that race conditions could not happen, you typically would write it in the same way in Rust. Often this involves Mutexes, but there are plenty of libraries that set up foundations for parallel behavior without Mutexes. So it can operate on "the same memory", and there are a whole lot of ways to manage…

this isn't quite right, this feels like what the standard response from a developer with some hubris. Humans are fallible and mushy, and depending on their current state are error prone. So why not just codify some "best practices" that are built in as primitives to a language like Rust? There are ways to perform parallel work that is "safe", Rust solves this with the borrow/checker implementation, another clear "saf…

Sorry, maybe I misunderstood OP. I was responding to what I thought was a general, vague question about how something safe might work in Rust, compared to other languages (Go in my example).

So while I don't think what I said was incorrect re: Go vs Rust concurrency, perhaps I misunderstood OPs question.

> Mutexes and locks and all the other ways of doing parallel work that is "safe" isn't a primitive thats cooked in with the language.

I didn't understand OPs question as strictly features cooked into the language, so I was not saying that.

With that said, if you're not allowing for Mutexes for "safe things that are cooked into the language" I feel like you won't like Rust. This is an odd metric, though.

edit: words

Re: Async-await on stable Rust

#40
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…

You would use the join method combine the futures (https://docs.rs/futures/0.2.1/futures/trait.FutureExt.html#m...).

Both will execute at the same time and you'll get a tuple of results.

Post reply on HN