Live data from Hacker News

Update on await syntax in Rust

boats.gitlab.io

151–160 of 199 posts

Re: Update on await syntax in Rust

#151
post #88

A bit off-topic: Is there any theoretical reason you need async / await syntax at all? (It's certainly desirable for performance and compatibility to avoid making all subroutines into coroutines, so I understand why most languages have done this.) And restricting it to the case where coroutines have a single return... Subroutines are naturally coroutines that don't yield. And it seems like the question of whether it'…

In an abstract sense, no. In rust, it matters a lot. The first reason is that we don’t have a runtime. The second is stuff like http://aturon.github.io/2018/04/24/async-borrowing/

Thanks for the link, I'm definitely interested in how it's done without a runtime. I know in theory a coroutine can compile down to a gory switch statement and some state, but doing anything useful with it gets hairy, I'm sure.

Re: Update on await syntax in Rust

#152
post #81

Excited for the feature. Disappointed we didn't get something like a magic method (e.g., lang item) (which isn't without precedence [1] [2]) so we could have had `Future::await(fut)` or `fut.await()`. [1] - https://manishearth.github.io/blog/2017/01/10/rust-tidbits-b... [2] - https://manishearth.github.io/blog/2017/01/11/rust-tidbits-w...

`fut.await()` looks too magical. There's no hint in that expression that it's anything other than a method call. You could argue the same about `fut.await`, except in this case `await` is a keyword and thus the expression `x.await` is known to be an await expression without knowing anything about `x`, whereas `fut.await()` requires knowing the type of `fut` to understand that the method call `.await()` resolves to th…

If we're gonna have await share syntax with some other language feature, method syntax is IMO better than field syntax- it semantically blocks the function until the callee is complete, it evaluates to a temporary instead of an lvalue, it can unwind the caller (via cancelation, like a panic).

You could implement that syntax and still make `await` a keyword, without doing the usual method lookup and without letting no_std libraries change the term, just like `.await`- that's an orthogonal concern.

Re: Update on await syntax in Rust

#153
post #151

Earlier quoted context omitted.

In an abstract sense, no. In rust, it matters a lot. The first reason is that we don’t have a runtime. The second is stuff like http://aturon.github.io/2018/04/24/async-borrowing/

Thanks for the link, I'm definitely interested in how it's done without a runtime. I know in theory a coroutine can compile down to a gory switch statement and some state, but doing anything useful with it gets hairy, I'm sure.

So, you do need to include some code to drive the futures. The key is that this is a library in Rust, rather than built into the language, and so Rust programs that don't use async do not pay the cost.

And yeah, that's sort of how it works under the covers :)

Re: Update on await syntax in Rust

#154
post #150
post #88

A bit off-topic: Is there any theoretical reason you need async / await syntax at all? (It's certainly desirable for performance and compatibility to avoid making all subroutines into coroutines, so I understand why most languages have done this.) And restricting it to the case where coroutines have a single return... Subroutines are naturally coroutines that don't yield. And it seems like the question of whether it'…

> Is there any theoretical reason you need async / await syntax at all? [...] That makes the most concurrent option easiest, as opposed to the clunky idiom of "gathering" many results. Futures / async-await is an idiom that makes async code easier to reason about, not something that provides any new theoretical foundation or any functionality that wasn't possible before. Like a type system, it's strictly for safety &…

> Futures / async-await is an idiom that makes async code easier to reason about, not something that provides any new theoretical foundation or any functionality that wasn't possible before.

So, this is true in GC'd languages, but if you see my link below, in Rust, async/await does let you write code that was previously impossible. This is because the compiler can't understand lifetimes in the way that the code is written with raw futures.

In theory, someday, if and when generators are stabilized, this will be true again, but instead with the caveat of "async/await doesn't give you any new thing that wasn't possible before, except that it can do it with safe code, rather than unsafe code."

Re: Update on await syntax in Rust

#155

Earlier quoted context omitted.

> I'm interested to know how much of this was a religious battle and how much of it results in meaningful complications for user code down the line. Due to the connotations of "religious battle", it's hard to get a good answer here. Nobody wants to be painted in this light. > Is this syntax for native coroutines? No. > Can it be combined with existing user and stdlib syntax? Yes. > What pathways for syntax developmen…

@steveklabnik My apologies if I appeared to make light of the Rust community’s contributions. My definition of religious war is butting heads about problems that don’t have a clear right answer (tabs/spaces). If there are new things considered by the community that make the discussion worthwhile then it’s absolutely worth having; but if it causes people to burn out on the community down the line then maybe more moder…

> My apologies if I appeared to make light of the Rust community’s contributions.

Not at all!

> My definition of religious war is butting heads about problems that don’t have a clear right answer (tabs/spaces).

So this is where we get into the meat of it. I personally do believe that a lot of the discussion was around things that don't have a clear right answer. But (and the post mentions this a bit), that doesn't mean that it's inherently religious, it means that different people value different aspects of the solution differently. The big difference between this discussion and the tabs/spaces discussion is that each person can make their own call with tabs and spaces, but this syntax affects every user of Rust. That means we can't just say "well this is a religious debate, do whatever" because then the feature does not exist.

> If there are new things considered by the community that make the discussion worthwhile then it’s absolutely worth having; but if it causes people to burn out on the community down the line then maybe more moderation would be helpful.

Yes, it is a fine line. There's a lot to it, but it is something that people are thinking about, for sure.

> I’m not sure whether the debate was taking all that into account

I can assure you that the overall development of the feature took every possible thing into account. Part of the reason that this was so synatx focused is that the team spent multiple years working on the semantics. The syntax was all that was left.

I am not 100% sure what you mean with the blog post link, as I'm not really a Python person, so I can't quite grok what you're talking about, exactly. If you can elaborate a bit I can too!

Re: Update on await syntax in Rust

#156
post #128
post #88

A bit off-topic: Is there any theoretical reason you need async / await syntax at all? (It's certainly desirable for performance and compatibility to avoid making all subroutines into coroutines, so I understand why most languages have done this.) And restricting it to the case where coroutines have a single return... Subroutines are naturally coroutines that don't yield. And it seems like the question of whether it'…

Indeed, I think going forward we will see high-level languages that paper over the distinction between synchronous and asynchronous functions. However for Rust specifically, the performance implications you note are of particular concern, while the remark "it seems like the question of whether it's a subroutine or a coroutine shouldn't be something the programmer needs to worry about" is debatable when considering la…

I should revise that: "programmers aren't very good at deciding whether a function should be a subroutine or coroutine."

Specifically, the problem is that making the decision happen requires refactoring and that can make a small change into a big one. My contention is that for some languages (probably not Rust) it would be beneficial if this didn't impact the code structure heavily.

I've seen smart people simply avoid trying to use asynchronous code in Javascript because it "poisons" the whole stack. Part of this was because it was based on promises, and it meant going through a bunch of logic and refactoring. Arguing against my case, that did result in a slightly nicer structure overall.

Hopefully having proper async / await notation avoids 99% of that mess in Rust by making it a matter of decorating code with the appropriate keywords and being a bit more thoughtful about structure.

And you're obviously right that Rust needs to have sane performance characteristics, let alone being able to export C compatible bindings.

Re: Update on await syntax in Rust

#157

Earlier quoted context omitted.

`fut.await()` looks too magical. There's no hint in that expression that it's anything other than a method call. You could argue the same about `fut.await`, except in this case `await` is a keyword and thus the expression `x.await` is known to be an await expression without knowing anything about `x`, whereas `fut.await()` requires knowing the type of `fut` to understand that the method call `.await()` resolves to th…

> There's no hint in that expression that it's anything other than a method call. Compared with `fut.await`... > There's no hint in that expression that it's anything other than a field access. At least there is precedence for functions to have magical compiler-ness for 'doing stuff', instead of overloading field access which is one of the simplest operations you can have. > ... requires knowing the type of `fut` ...…

If it's a method you should be able to create a vector of futures and `.map(Future::await)` or even `.map(Future::await as FnMut(_) -> _)`. Clearly this would never work, since `await` is implement by transforming the containing function into a state machine, your suggestion would make this impossible.

Re: Update on await syntax in Rust

#158
post #150

Earlier quoted context omitted.

> Is there any theoretical reason you need async / await syntax at all? [...] That makes the most concurrent option easiest, as opposed to the clunky idiom of "gathering" many results. Futures / async-await is an idiom that makes async code easier to reason about, not something that provides any new theoretical foundation or any functionality that wasn't possible before. Like a type system, it's strictly for safety &…

> Futures / async-await is an idiom that makes async code easier to reason about, not something that provides any new theoretical foundation or any functionality that wasn't possible before. So, this is true in GC'd languages, but if you see my link below, in Rust, async/await does let you write code that was previously impossible. This is because the compiler can't understand lifetimes in the way that the code is wr…

I meant my comment a bit more broadly & abstractly than that. You can write code in a new way with await, and it does help you with how to factor & manage the code. But it does not fundamentally let you make parallel requests that you couldn't make before, somehow. The code you needed before await might be ugly and stateful and not idiomatic, but it was still possible to make requests and wait for them, before await arrived.

What we have now with await does change the game, it makes async code appear synchronous, and the advantages of that change should not be underestimated. I think futures & await are huge and positive changes for every language they're showing up in, and they do allow for new kinds of programming, I'm just answering the parent comment's question about whether they're strictly necessary in theory. The answer is that they're not.

Re: Update on await syntax in Rust

#159

Earlier quoted context omitted.

> I'm interested to know how much of this was a religious battle and how much of it results in meaningful complications for user code down the line. Due to the connotations of "religious battle", it's hard to get a good answer here. Nobody wants to be painted in this light. > Is this syntax for native coroutines? No. > Can it be combined with existing user and stdlib syntax? Yes. > What pathways for syntax developmen…

@steveklabnik My apologies if I appeared to make light of the Rust community’s contributions. My definition of religious war is butting heads about problems that don’t have a clear right answer (tabs/spaces). If there are new things considered by the community that make the discussion worthwhile then it’s absolutely worth having; but if it causes people to burn out on the community down the line then maybe more moder…

> My impression of async/await is that it’s one part of making concurrency grokkable, and I’m not sure whether the debate was taking all that into account

That's a different question than "where does the await go" and it was certainly taken into account.

Re: Update on await syntax in Rust

#160
post #133

Earlier quoted context omitted.

I understand that, but how much into consideration? Let's just make up some numbers, if 1% of reading of Rust code takes place in environments without code highlight, then it should have been 1% of the consideration. Is that the case?

I don't think you should weight it like that. If you have multiple proposed syntaxes, and both are equally effective with code highlighting but one is moderately ineffective without highlighting, then it makes sense that you should go for the latter. The weighting controls how much of an effectivity loss in the code highlighting case you would be willing to trade off against effectivity improvements in the other case…

It sounds like you're agreeing with me. If two options are indeed essentially equal on all fronts, then one minor use case can be enough to push it towards a winner.
Post reply on HN