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.
Async-await on stable Rust
51–60 of 392 posts
Re: Async-await on stable Rust
#52Earlier quoted context omitted.
Rust isn't only great because it's low level. Things like sum types (called enums in rust), pattern matching and expression orientation mean that it is often much more expressive than other languages for high level code.
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.?
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's usually a nice way of doing what I want, and I rarely come up against unwelcome surprises.
Re: Async-await on stable Rust
#53Isn'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.
Think of it this way. I have 3 letters I need to send, and I'm expecting replies for each. A single threaded, synchronous language, would basically send the first letter, wait for the reply, send the second letter, wait for the reply, then send the third and wait for the reply. In JS, you're still single threaded, but you just recognize that there is no point in sitting around and waiting before moving onto the next item. So you send the first letter, and when it would be time to wait, you continue executing code, so you immediately send the next letter, and then finally send the 3rd.
How they're scheduled simultaneously on a single thread is exactly what makes JS so fast for IO. Once it starts making an http call, db call, disk read, etc, it will release the thread to begin execution of the next item in the event loop (which is the structure JS uses under the hood to schedule tasks).
So what really happens is when we call
asyncA();
asyncB();
JS will go into `asyncA`, run the code, and at some point it will get to a line that does something like "write this value to the database." This will be an asynchronous behavior, that it knows will be handled with a callback or a Promise, so it will immediately continue execution of the code. So now it pops out of executing `asyncA` and executes `asyncB`, meanwhile the call to the DB has gone out and we don't care if it has finished, we'll await both of these when we need them.Re: Async-await on stable Rust
#54Earlier quoted context omitted.
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/macr…
"At the same time"? How does that happen on a single thread?
Re: Async-await on stable Rust
#55Earlier quoted context omitted.
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/macr…
"At the same time"? How does that happen on a single thread?
Re: Async-await on stable Rust
#56How 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
If you want two threads running in parallel to concurrently access the same memory location you don't need synchronization if you only perform reads, and you need one if there is at least one write. Like in any other language (this comes directly from how CPU works).
The good thing with Rust is that you can't shoot yourself in the foot: if you can't accidentally have an unsynchronize mutable variable accessible from two threads: the compiler will show you an error (unless you explicitely opt out this security by using unsafe primitives, in which case the borrow checker will let you go).
Re: Async-await on stable Rust
#57I’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…
Re: Async-await on stable Rust
#58Isn'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.
* First, it runs the callee synchronously until the first await, which can fire off network requests, etc.
* Second, continuations are pushed onto queues immediately- the microtask queue that runs when the current event handler returns, for example.
Rust does neither of these things:
* Calling an async function constructs its stack frame without running any of its body.
* Continuations are not managed individually; instead an entire stack of async function frames (aka Futures) is scheduled as a unit (aka a "task").
So if you just write async functions and await them, things behave much more like thread APIs- futures start running when you pass a top-level future to a "spawn" API, and futures run concurrently when you combine them with "join"/"select"/etc APIs.
Re: Async-await on stable Rust
#59Re: Async-await on stable Rust
#60Isn'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/macr…
In JS, for example, the `bluebird` library is a third party utility for managing execution of functions. You can do things like
const results = await Promise.map(users, user => saveUserToDBAsync(user), { concurrency: 5});
And I pass in thousands of users, and can specify `concurrency: 5` to know that it will be execute no more than 5 simultaneously.Implementation of this behavior in user space is trivial in JS, is it possible in Rust?