Live data from Hacker News

Update on await syntax in Rust

boats.gitlab.io

111–120 of 199 posts

Re: Update on await syntax in Rust

#111

Earlier quoted context omitted.

It cannot exist as a macro or function, because it transforms the code in ways they can’t. Macros can transform code, but the final output isn’t something representable in stable Rust, and so it would not compile post-expansion.

Would the macro case be addressed by also supporting a prefix keyword? The post that states macros can't work does not cover this. From what I can tell: `foo.await!()` would just expand to `(await foo())`, and anyone could write their own `my_await!` macro that works similarly.

What's the benefit of this?

Re: Update on await syntax in Rust

#112

Earlier quoted context omitted.

It cannot exist as a macro or function, because it transforms the code in ways they can’t. Macros can transform code, but the final output isn’t something representable in stable Rust, and so it would not compile post-expansion.

Would the macro case be addressed by also supporting a prefix keyword? The post that states macros can't work does not cover this. From what I can tell: `foo.await!()` would just expand to `(await foo())`, and anyone could write their own `my_await!` macro that works similarly.

That needs a postfix macro, which is a completely different feature that does not exist and may not ever exist.

Re: Update on await syntax in Rust

#113

Earlier quoted context omitted.

Would the macro case be addressed by also supporting a prefix keyword? The post that states macros can't work does not cover this. From what I can tell: `foo.await!()` would just expand to `(await foo())`, and anyone could write their own `my_await!` macro that works similarly.

That needs a postfix macro, which is a completely different feature that does not exist and may not ever exist.

Yeah, I was assuming postfix macro + prefix await was accepted, specifically to address the "it can't be a macro" argument in the initial post from boats.

Similarly, postfix keywords are not a thing that exist in rust, and await is the only accepted one.

Re: Update on await syntax in Rust

#114
post #71

Earlier quoted context omitted.

For example, on C#, I sometimes have to do: var value = (await (await startRequest()).GetBody()).Root; While the Rust syntax would make this a little more clear, I do not think it is a dealbreaker.

Please don't do that. I had to look several times to rewrite it as var temp1 = await StartRequest(); var temp2 = await temp1.GetBody(); var value = temp2.Root; which is instantly grokked.

This is to my eyes far more cluttered and confusing than:

    var value = StartRequest().await.GetBody().await.Root;
Or if you prefer multiline:

    var value = StartRequest().await.
                GetBody().await.
                Root;

Re: Update on await syntax in Rust

#115

Earlier quoted context omitted.

Would the macro case be addressed by also supporting a prefix keyword? The post that states macros can't work does not cover this. From what I can tell: `foo.await!()` would just expand to `(await foo())`, and anyone could write their own `my_await!` macro that works similarly.

What's the benefit of this?

Postfix macros are a great feature in general, if accepted later. This would open the door for them, and you'd get things like:

    "{} + {}".format!("foo", "bar")
and other niceties. It would have also solved the try macro's issues, like:

    result.try!()
etc. There are plenty of use cases where postfix macros are awesome.

Macros are already a known control flow mechanism, so a postfix macro should be very easy for both new and old rust users to understand.

It isn't a fake field access, so it's already a step ahead of the competition.

And you get prefix await, which every other language uses, and this addresses the singular argument against macros being used (which is that the macro could not be implemented by users), though I never felt that it was a strong argument anyway.

I don't want to go back and forth discussing it. It isn't happening. I was just curious if the prefix await would have addressed that one argument.

Re: Update on await syntax in Rust

#116

Earlier quoted context omitted.

Would the macro case be addressed by also supporting a prefix keyword? The post that states macros can't work does not cover this. From what I can tell: `foo.await!()` would just expand to `(await foo())`, and anyone could write their own `my_await!` macro that works similarly.

That needs a postfix macro, which is a completely different feature that does not exist and may not ever exist.

The writeup mentioned that (await future)?; is undesirable because it disrupts the logical flow.

Could await be implemented as a prefix, with an additional macro?

awaits!(foo()) that expands to (await foo())

Re: Update on await syntax in Rust

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

I think (but I cannot find a reference to now) one of the proposed syntaxes was that awaits were immediate and implicit in async functions, and that if you didn't want that, you could opt-out and get futures normally. Loosely,

  async fn foo() {
    let result = blocking_req();  // awaiting immediately here.
    async {
      let future = blocking_req();  // not awaited.
      // can do more complex stuff w/ the future
    }
  }
IDK what happened to it, and it is a bit more complex IMO than what the Rust folks went with. However, I don't think it helps your gather case.

For gather, I think the problem w/ your proposed

  return alpha + beta + gamma
is when does that happen? If I do

  let some = alpha + beta;
  // 
  let more = some + gamma;
what happens / when are things evaluated?

At any rate, with the syntax as it is, I think your gather example is essentially¹:

  alpha.join3(beta, gamma).await
or

  Future::join3(alpha, beta, gamma).await
(Perhaps minus the `.await`, depending on when you need/want the result.)

There's no operator overloading, which I'm fine w/, as there is a need to choose between, e.g., select or join.

¹but I'm new w/ the async stuff, so if I'm wrong I'm assuming that Cunningham's Law will kick in and someone will correct me.

Re: Update on await syntax in Rust

#118

Earlier quoted context omitted.

That needs a postfix macro, which is a completely different feature that does not exist and may not ever exist.

The writeup mentioned that (await future)?; is undesirable because it disrupts the logical flow. Could await be implemented as a prefix, with an additional macro? awaits!(foo()) that expands to (await foo())

That ruins the chaining aspect.

Re: Update on await syntax in Rust

#119

Earlier quoted context omitted.

It cannot exist as a macro or function, because it transforms the code in ways they can’t. Macros can transform code, but the final output isn’t something representable in stable Rust, and so it would not compile post-expansion.

Would the macro case be addressed by also supporting a prefix keyword? The post that states macros can't work does not cover this. From what I can tell: `foo.await!()` would just expand to `(await foo())`, and anyone could write their own `my_await!` macro that works similarly.

I as well think there could be promise in someday exploring that space, but for the moment my enthusiasm for hypothetical postfix macros (which have yet to ever be formally proposed) is somewhat dampened by the realization that `foo.bar.qux.qaz.await!()` would need to expand to `await { foo.bar.qux.qaz }`, which makes me consider how uncomfortable such macros would be to parse (the saving grace of "normal" macro calls being the fact that both the reader and the compiler know exactly where the span of a macro begins and ends by looking merely at the balanced delimeters).

IMO, if the goal were ultimate language consistency then that would involve both adding an `await` keyword (with mandatory braces, like `if` and the others) and a postfix macro for the cases where it looks nicer. However, when considered by itself, there's no denying that `foo.await?.bar` appears nicer than `foo.await!()?.bar`, especially if there is no guarantee that postfix macros will ever become a thing.

(Though in honesty I think all these proposals are just trending towards justifying an F#-style pipeline operator.)

Re: Update on await syntax in Rust

#120
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 the lang item. Also, since it's a lang item, you could write your own nostd library that picks a different name for the same lang item and cause even more confusion.
Post reply on HN