Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

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.



This just then boils down to saying "the await keyword should have required parens after it", which is a different argument than saying "it should be a lang item".


hell, I'd support that. A function/method 'does a thing' while field access 'reads a thing'. Rust doesn't have implicit getters and setters like Python might have. It doesn't LOOK like `fut.await` should/could DO anything, but it can.


Ah, but isn't the whole point of an `async` function that it syntactically erases the notion of blocking on an operation? If you ignore the fact that it blocks the async function (and yields control back to the executor), then `foo.await` isn't really "doing" anything at all, it's just handing you back the future's output.

Having said that, I'd have to assume that `fut.await` does consume the future, which normal field access doesn't do. Personally, I'm ok with the tradeoff that says "this keyword looks like field access but it consumes the receiver, but as a result we don't have these extra parens all over the place on a keyword", especially because going the other way introduces other costs (e.g. it looks like a method call and yet can't be referred to as Future::await).


It doesn't do anything locally but it does (as part of going back to the executor) let arbitrary other code run, which is basically what a method call does.


That's covered under the whole "erasing the notion of blocking on an operation".

And besides, conceptually that's no different than yielding back to the OS thread scheduler.


    impl Future {
        fn await(self: Self) -> Self::Target {
            intrinsic::await(self) # compiler magic
        }
    }

Then you CAN do `fut.await()` or `Future::await(fut)`, etc. Assuming this wouldn't be impossible for some other reason. And it makes it clear that `await` is magic, not something that a new programmer just can't find the definition of or assumes is the result of a macro or something.

> we don't have these extra parens all over the place on a keyword

like `fut.await().await().await()` vs. `fut.await.await.await`? Both look equally stupid and I feel like the existing Future APIs already discourage these kinds of things from happening by providing good APIs. But it's been a while since I played with them.


It's impossible for some other reason.

Namely, await isn't a matter of just inserting some compiler-defined behavior at a specific point. It requires rewriting the control flow of the surrounding function. The await! macro did this by invoking a magical unstable keyword `yield`, but even that still has to be done within the current function (e.g. the implementation of await! must be a macro, not a function).


I mean, that just means the compiler needs to ignore the `Future::await()` function scope and rewrite the context above. It's already being magical. A slight indirection in implementation would be worth the pedagogical clarity, I think.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: