Live data from Hacker News

Async-await on stable Rust

blog.rust-lang.org

311–320 of 392 posts

Re: Async-await on stable Rust

#311

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'…

ML has always had easy mutables in the form of references, and the closest deployed language to Standard ML (Ocaml and Reason), has always had for-loops and while-loops. Mutable references are used frequently.

Rust is great because it's low level, high-performance, non-garbage collected and it's primary inspiration for higher-level programming is languages like ML and Haskell.

Re: Async-await on stable Rust

#312
post #72

Earlier quoted context omitted.

I also think async (the paradigm) is kind of weird in rust world. I agree with https://journal.stuffwithstuff.com/2015/02/01/what-color-is-... .

The solution suggested by that article is to use M:N threading, which was tried in Rust and turned out to be slower than plain old 1:1 threading. If you don't want to deal with async functions, then you can use threads! That's what they're there for. On Linux they're quite fast. Async is for when you need more performance than what 1:1 or M:N threading can provide.

How hard was it tried?

I imagine there's a reason that languages like Go adopted M:N threading... obviously part of the reason is that it's way more scaleable, but userspace threading is also supposed to be faster, as context switches don't need to switch to kernel space... were the problems tight loops (which AFAIK is also the problem in Go)? or maybe it's just so much easier / more efficient if you also have GC...

Re: Async-await on stable Rust

#313
post #110

Earlier quoted context omitted.

It does automatically start the tasks. JavaScript asyncs are "hot". You can simulate "cold" asyncs using a function, as you describe, but in other languages this is how they work by default.

I’m not sure exactly what hot is here, but if that’s the case then all javascript functions are hot. It’s behaving consistently with any other function. I assume the point here is that Rust in this case changes the way function calls work based on async, which is, well, inconsistent.

An async function immediately returns a Future to the caller, so in that sense it is fully consistent with a sync function that immediately returns a value.

If you want the asynchronously computed value, then the async equivalent to "foo()" is "foo().await", and that is also fully consistent - the function body starts running, and returns the value once it's done.

But there's no sync equivalent of invoking an async function without awaiting it, which is where the hot/cold distinction manifests. Thus, there's no inconsistency, because there's nothing to be consistent with.

Re: Async-await on stable Rust

#314
post #286

Earlier quoted context omitted.

Go is even more different. Rust async has explicit yields with await, but Go does it implicitly at various key locations. This is actually pretty surprising to many folks, it was in the past and maybe still is possible to deadlock Go with a certain incantation of tight looping. Another difference with Rust is that async functions are stackless. Go has to contend with having a non-conventional stack and interoperabili…

> [...] Go does it implicitly at various key locations. This is actually pretty surprising to many folks, it was in the past and maybe still is possible to deadlock Go with a certain incantation of tight looping. This is being worked on here: https://github.com/golang/go/issues/24543

Is there any documentation on the latest status on this, how far along they've come and what technical solutions they're considering / have settled on?

Re: Async-await on stable Rust

#315
post #246
post #234

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? 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 :)

> Is it like coroutines in lua? idk about Lua, but afaik python's async is pretty much implemented on top of coroutines ("generators"). `await` is basically `yield` > 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 :) pretty sure i've heard the same thing said about async io!

I guess the thing that puzzles me is that if they are run threaded (concurrently) they seem just as hard to reason about as threaded IO to me.

And that would leave the motivation to be performance gains by being able to reduce the amount of threads I guess

(And that it is cool of course :)

Re: Async-await on stable Rust

#316

Earlier quoted context omitted.

Probably not using green threads / async at all? That would require a number of stacks as well as a little runtime, which will quickly eat up your 4K.

Just to clarify for those following along, Rust async code does not use green threads and doesn't require a stack per task.

I'm missing some of the technical details here, but from a quick glance of the article it seems like Rust's futures are lazy. I.e. a stack would only be allocated when the future is actually awaited. But in order to execute the relevant code, a call stack per not-finished future is still needed, or am I missing something?

Re: Async-await on stable Rust

#317

Earlier quoted context omitted.

Just to clarify for those following along, Rust async code does not use green threads and doesn't require a stack per task.

I'm missing some of the technical details here, but from a quick glance of the article it seems like Rust's futures are lazy . I.e. a stack would only be allocated when the future is actually awaited. But in order to execute the relevant code, a call stack per not-finished future is still needed, or am I missing something?

Afaik Rust's futures compile to a state machine, which is basically just a struct that contains the current state flag and the variables that need to be kept across yield points. An executor owns a list of such structs/futures and executes them however it sees fit (single-threaded, multi-threaded, ...). So there is no stack per future. The number of stacks depends on how many threads the executor runs in parallel.

Re: Async-await on stable Rust

#318
post #278

Earlier quoted context omitted.

The latter case should be impossible if the method is private?

In Rust, privacy isn't enforced like that. Private just means that things outside the module can't access them. There's no concept of privacy at the instance level.

Yes. So don't make any methods that could potentially be passed incorrect arguments public.

Re: Async-await on stable Rust

#319

Earlier quoted context omitted.

> Programming languages have the power to implement concurrency patterns that offer the same kind of performances, without the hassle. Can you give one that reaches this goal? Go is often cited on that regard but it doesn't really fit your description since it trades performance for convinience (interactions with native libraries are really slow because of that) and still doesn't solve all problems since hot loops ca…

BEAM (Erlang VM) provides pre-emptive scheduling

True for functions written in Erlang/Elixir, but not in NIF functions implemented in C.

Re: Async-await on stable Rust

#320

Earlier quoted context omitted.

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'…

ML has always had easy mutables in the form of references, and the closest deployed language to Standard ML (Ocaml and Reason), has always had for-loops and while-loops. Mutable references are used frequently. Rust is great because it's low level, high-performance, non-garbage collected and it's primary inspiration for higher-level programming is languages like ML and Haskell.

Having used OCaml and Reason i'd say the documentation and compiler messages of Rust are more helpful IMHO
Post reply on HN