Earlier quoted context omitted.
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 fie…
Update on await syntax in Rust
181–190 of 199 posts
Re: Update on await syntax in Rust
#182Earlier quoted context omitted.
> I think it's totally reasonable to judge a road surface based on how effective it is, in practice, with the kinds of traffic that will be travelling on it. Yes, and if we outlawed the use of cars without traction control on certain roads, then I would be fine with designing with the assumption traction control will be on. But as long as you allow older cars without traction control to still drive on the road, you a…
I'm not sure if you read me as slightly more critical than I had intended or if I'm reading you as slightly more defensive than you'd intended, but I think we more-or-less agree: readability is important both with and without syntax highlighting, and tradeoffs should be considered in that light. A nitpick: > But as long as you allow older cars without traction control to still drive on the road, you are making the ro…
That one. :)
> But if a sufficient fraction of cars have traction control, and we sufficiently improve the performance of traction controlled tires at sufficiently small damage to the performance of other tires
That's a slightly different scenario, where the change is to increase safety. Then it is, as you say, a trade-off. It could just as easily be a trade-off because material is cheaper though, in which case different calculations are important.
Also, it's important to be careful not to exclude important information from the calculation even if it's about a relative safety increase. For example, if you increase the safety for 90% of the people but decrease it for 10%, and that 10% is mostly comprised a population that is unable to switch and benefit (e.g. poor people with little choice in the vehicle they drive, as they drive what's available and cheap), you might not only be forcing that risk on an already captive population, but they might also be a population that is resistant to change that would mitigate this danger (they can't afford new cars and they can't afford better cars). Conversely, shifting risk to the wealthier (more elastic) part of the market might yield more of a net reduction in risk as they are capable and willing to respond to the increased risk (or more likely, increased annoyance).
> I don't think there's a direct mapping back to syntax and highlighting.
There isn't, we're getting into the weeds, but conceptually I think there are some interesting points that apply at least partially. For example, not all changes are felt and valued by the populations they affect similarly. E.g. not relying on syntax highlighting for a language feature does not affect a person that uses syntax highlighting that much one way or another (it will likely still be highlighted in some way), but it can impact those that don't or can't fairly heavily. If I'm stuck trying to review some bug while on vacation through some crappy online git interface that isn't highlighting code well, or maybe even at all, I'm going to curse the heavens if there's a feature that's easily missed or hard to follow in monochromatic output if it's causing me problems in my stressful moment.
Perhaps that's my sysadmin history coming through, but I want stuff to be simple, reproducible, and obvious. Complexity, fragility and obscurity are the enemy, and I fight them wherever I see them. ;)
Re: Update on await syntax in Rust
#183Earlier quoted context omitted.
No problem. :) I was actually in the same camp as you until, in the wake of boats' prior post on await syntax, I sat down and got well into writing an RFC for postfix macros until I stumbled upon the parsing concern and shelved it under the category of "not nearly as trivial as I thought it would be".
https://github.com/rust-lang/rfcs/pull/2442
It would also appear to be deficient for the same parsing reason I mentioned, i.e. that you need some way to tell whether `2 + 2.bar!()` should expand to `2 + bar!(2)` or `bar!(2 + 2)`; the RFC appears to choose the latter, whereas a hypothetical `await!()` would want the former. This problem is called out in the RFC:
"Rather than this minimal approach, we could define a full postfix macro system that allows processing the preceding expression without evaluation. This would require specifying how much of the preceding expression to process unevaluated, including chains of such macros. Furthermore, unlike existing macros, which wrap around the expression whose evaluation they modify, if a postfix macro could arbitrarily control the evaluation of the method chain it postfixed, such a macro could change the interpretation of an arbitrarily long expression that it appears at the end of, which has the potential to create significantly more confusion when reading the code."
Re: Update on await syntax in Rust
#184Earlier quoted context omitted.
https://github.com/rust-lang/rfcs/pull/2442
Thanks, I haven't seen that RFC before, but reading it now it seems it would be insufficient to support this use case without also supporting `let x: impl Future`, since the RFC deliberately chooses to expand to a temporary binding for `self`. It would also appear to be deficient for the same parsing reason I mentioned, i.e. that you need some way to tell whether `2 + 2.bar!()` should expand to `2 + bar!(2)` or `bar!…
2 + {
let _self = 2;
bar!(_self)
}Re: Update on await syntax in Rust
#185Earlier quoted context omitted.
I mean, why couldn't it? let newvec = vec![fut1, fut2, fut3].map(Future::await).collect() would be equivalent to let f1 = fut1.await(); let f2 = fut2.await(); let f3 = fut3.await(); let newvec = vec![f1,f2,f3]; or vec![fut1,fut2,fut3].map(|fut| fut.await).collect()
I think you fundamentally misunderstand async await. `vec[fut1, fut2, fut3].map(|fut| fut.await).collect()` will not do what you might expect, although I haven't bothered to read the RFC whether it will be allowed at all. Await must have compiler support and cannot just be some function you call.
vec![fut1, fut2, fut3].map_async(async|fut| fut.await).collect()
I believe that could be built. Though, now I'm getting myself tripped up. Because I claimed that this is similar to vec![fut1, fut2, fut3].map(Future::await).collect()
But I notice that I expect `await` to be a blocking, non-async function. Which, feels strange in that the lambda in the first block needs to be async but the function itself doesn't.> Await must have compiler support and cannot just be some function you call.
I'm not saying it doesn't need compiler support. I explicitly state that it does - I just want the magic to be a little more explicit. Moreover, I believe that most programmers think of functions as 'encapsulated code', something that does a thing. In this sense, it matches what await does better than syntax that looks like it's accessing a field. Admittedly, in the purest sense of encapsulation, this method 'escapes' that encapsulation, but I don't consider that terribly important.
Re: Update on await syntax in Rust
#186Earlier quoted context omitted.
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 fie…
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.
Re: Update on await syntax in Rust
#187Earlier quoted context omitted.
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 fie…
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…
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).
Re: Update on await syntax in Rust
#188Earlier quoted context omitted.
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 fie…
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.
And besides, conceptually that's no different than yielding back to the OS thread scheduler.
Re: Update on await syntax in Rust
#189Earlier quoted context omitted.
I find the don't-consider-syntax-highlighting-at-all argument odd. It's like arguing traffic lights shouldn't use colors to indicate stop-and-go because some people either cannot perceive the color difference or choose to wear glasses that negate the color difference. (Analogies here suck. Instead, consider that the vast majority of programmers read code that has been syntax highlighted. To completely discount that e…
> It's like arguing traffic lights shouldn't use colors to indicate stop-and-go because some people either cannot perceive the color difference or choose to wear glasses that negate the color difference. There is a reason that we have three separate lights still instead of one (that is, there's more reasons than just inertia), and that's because some people can't tell the color differences. Specifically, my father ca…
And we aren't in the late 70's anymore, where languages had design decisions (keywords always caps) due to printing limitations.
Re: Update on await syntax in Rust
#190Earlier quoted context omitted.
I find the don't-consider-syntax-highlighting-at-all argument odd. It's like arguing traffic lights shouldn't use colors to indicate stop-and-go because some people either cannot perceive the color difference or choose to wear glasses that negate the color difference. (Analogies here suck. Instead, consider that the vast majority of programmers read code that has been syntax highlighted. To completely discount that e…
> It's like arguing traffic lights shouldn't use colors to indicate stop-and-go because some people either cannot perceive the color difference or choose to wear glasses that negate the color difference. There is a reason that we have three separate lights still instead of one (that is, there's more reasons than just inertia), and that's because some people can't tell the color differences. Specifically, my father ca…
Which is exactly what has been done. So I don't understand what you're complaining about. The rest of your comment is a giant straw man. I've never heard of or seen implied that anyone in any decision making position in the Rust project is "assuming everyone has syntax highlighting set up."
When you make ridiculous assumptions about the decision procedures of other people, then it's easy to derive ridiculous conclusions. But reality is always more nuanced than that: https://news.ycombinator.com/item?id=20031706