Live data from Hacker News

A final proposal for Rust await syntax

boats.gitlab.io

221–230 of 265 posts

Re: A final proposal for Rust await syntax

#221

Earlier quoted context omitted.

Counter to your counterpoint: APL did take usability into account. Dr Iverson got annoyed with how inconsistent and hard to read normal math notation was, and how many problems that caused in its usability, and invented Iverson notation to fix that - a tool to be usable by people writing on blackboards to show other people mathematical ideas. Years later, it was used at IBM to describe what the IBM 360 computer would…

> APL did take usability into account. Perhaps usability for a certain, very specific, subset of people (namely those who are writing code on a whiteboard?) But math notaion is not programming, they have different needs. > UX is important! Note that concise and powerful also apply to perl. Concise, in programming does not equal good UX. Often they're antithetical. (This also doesn't mean that verbose is "good UX" eit…

Programming language design, like programming, is about finding the right abstractions and providing them. ref: "Python did take usability into account"

Which APL tries to do with neat and composable functions.

Sum a list of "values": APL: +/values Python: sum(values).

Product of a list: APL: ×/values Python: import operator, functools, then reduce with a lambda function, or write a loop.

Add constant to a list: APL: 1+values Python: [1+x for x in values]

Reverse a list: APL: ⌽values Python: list(reversed(values)) but you have to care if you want an iterator or a list.

Add two lists elementwise: APL: values1+values2 Python: [x+y for x,y in zip(values1, values2)]

Take five from the front: APL: 5↑values Python: values[:5]

In APL this syntax generalises to multidimensional arrays. In Python none of these wildly different syntaxes do, nor do the magic sum/max/min functions.

In APL these are simple instructions to the user, and can be implemented fast by the runtime. In Python these are more complex patterns to learn and run slower, if you want them to work fast you have to switch again to NumPy.

I am not all-in on APL, but this is so much more powerful, concise, consistent and composable than Python - the shining example of a beginner-friendly language - for basic data munging, it's like seeing Python after using Java and wondering why Java has to be so wordy and verbose to get anything done. Why does Python have to be so wordy and verbose and limited to get basic things done? Why is this large mess of inconsistent symbols and calling conventions and library functions and magic functions and sigils considered clean and usable compared to APL's very simple repeatable patterns and careful attentive use of composable symbols?

Re: A final proposal for Rust await syntax

#222

Earlier quoted context omitted.

> APL did take usability into account. Perhaps usability for a certain, very specific, subset of people (namely those who are writing code on a whiteboard?) But math notaion is not programming, they have different needs. > UX is important! Note that concise and powerful also apply to perl. Concise, in programming does not equal good UX. Often they're antithetical. (This also doesn't mean that verbose is "good UX" eit…

Programming language design, like programming, is about finding the right abstractions and providing them. ref: " Python did take usability into account " Which APL tries to do with neat and composable functions. Sum a list of "values": APL: +/values Python: sum(values). Product of a list: APL: ×/values Python: import operator, functools, then reduce with a lambda function, or write a loop. Add constant to a list: AP…

You examples with (and some without) numpy arrays:

values.sum(), values.prod(), 1 + values, values[::-1], values1 + values2, values[:5]

Yes, comparing the "array programming language" with a general purpose programming language when all your examples are array operations is going to make the general purpose language look funny. But I don't want a DSL for array operations I want a programming language. And when you aren't doing array-math, APL isn't so great.

Show me how you present those arrays as a graph in APL. In "wordy, verbose" python it's

    import matplotlib.pyplot as plt
    plt.plot(array)
    array.show(array)
Is visualizing the data you're manipulating so basic?

Python chooses extensibility (numpy) over domain specificity, and you get the same power (really, the numpy examples aren't any worse than yours, in fact to someone unfamiliar, `sum` and `product` are likely clearer than `+/` and `×/`.

Extensibility and composability is a better abstraction.

Re: A final proposal for Rust await syntax

#223
post #183

Earlier quoted context omitted.

> (2) If we create new such postfix operators in the future we'll have to break yet more source code by reserving yet more field names in all structs in all existing code. This is already the case; all keywords in Rust are reserved keywords, not contextual keywords, so you already can't have a field named, say, `return`, despite the fact that a hypothetical `foo.return` would otherwise be unambiguous. Further, with t…

> This is already the case; all keywords in Rust are reserved keywords, not contextual keywords, so you already can't have a field named, say, `return`, despite the fact that a hypothetical `foo.return` would otherwise be unambiguous. Further, with the Edition system and rustfmt, reserving keywords in this manner shouldn't be disruptive. Well, the keyword could instead be "@await" instead of "await" meaning that no r…

Sure, the Rust developers could implement it such that `@await` worked, but `await` is already a reserved keyword as of the 2018 edition, so in this particular case it no longer makes any difference. For that matter, they could also have made it such that `.await` or `.anyotherkeyword` become legal in Rust 2015 (since keywords don't currently exist in that position, it wouldn't break any code). However this misses the point that the Rust developers have made a conscious philosophical decision to make their keywords reserved and not contextual. Reserving a keyword vs. contextualizing a keyword is a philosophical choice, not a technical one.

Re: A final proposal for Rust await syntax

#224

I figure the reason the proposed syntax looks gross is because other languages have been using a prefixed await for many years. The Rust decision seems well thought out though, enough to make me wonder if perhaps other languages have been doing it wrong. My first experience with futures was in the form of QFuture ( https://doc.qt.io/qt-5/qfuture.html ), and there you call .result() to block and wait for the result. T…

Postfix in itself is fine, although "await" as a verb reads best in a prefix position (cf. "try", "match", "yield", "loop", "return"). The reason the "dot await" notation looks gross is first and foremost because it coopts the field access syntax—familiar from almost every language in the C family—for a purpose entirely orthogonal to field access.

> it coopts the field access syntax [...] for a purpose entirely orthogonal to field access

You mean like C++'s a.this_method_is_a_function_call(...) did? Not to be confused with a.function_pointer_field(...), despite having literally identical syntax.

Personally, I think they should have intoduced a dot-keyword instead of postfix ?; it's too easy to miss, especially for something that hides a implicit return.

Re: A final proposal for Rust await syntax

#225
post #35

Earlier quoted context omitted.

My dislike for the ”dot keyword” syntax has been strong, but if it is selected, hopefully it’s at least generalized to other keywords in the future, so that `.await` doesn’t stay a lone awkward exception to what dot notation means. In particular, I wouldn’t mind if in the future `expr?` could be spelled `expr.try` for consistency (even at the expense of introducing redundancy).

I wonder if I would ever find something like my_iter .foo() .bar() .return more appealing than return my_iter .foo() .bar(); I could see it happening, but I'll definitely need some time to get used to it.

The problem with that is return doesn't evaluate to anything, so there's no (return foo).bar expressions to benefit from that change. Same problem with break, continue, and goto, for that matter.

Re: A final proposal for Rust await syntax

#226
post #223

Earlier quoted context omitted.

> This is already the case; all keywords in Rust are reserved keywords, not contextual keywords, so you already can't have a field named, say, `return`, despite the fact that a hypothetical `foo.return` would otherwise be unambiguous. Further, with the Edition system and rustfmt, reserving keywords in this manner shouldn't be disruptive. Well, the keyword could instead be "@await" instead of "await" meaning that no r…

Sure, the Rust developers could implement it such that `@await` worked, but `await` is already a reserved keyword as of the 2018 edition, so in this particular case it no longer makes any difference. For that matter, they could also have made it such that `.await` or `.anyotherkeyword` become legal in Rust 2015 (since keywords don't currently exist in that position, it wouldn't break any code). However this misses th…

I'm not sure that the idea of contextual vs non-contextual keywords is relevant here unless I've misunderstood you. I assumed that the 'async' keyword was reserved in 2018 edition to ensure that no matter how they chose to implement it (prefix, postfix, whatever) they had the flexibility to pick after the fact. I don't think they closed the door on a new, non-breaking non-contextual operator, although I wasn't a party to any of those conversations.

Releasing 'async' and capturing '@async' would be 2015- and 2018- edition safe change unless there's something I've overlooked. It shouldn't break any 2018-edition code to make the 'async' keyword available, only to capture a new, currently-valid one, and I assume that's part of why they took this approach. I feel like the ball's still on the court until someone writes some valid 2018 edition code utilizing the keyword as defined in this proposal. This would also mark precedent for not reserving additional currently-valid keywords for postfix operations.

I'm proposing releasing 'async' and capturing '@async' as a new non-contexual composite keyword. In the state the language is right now, this change should keep the grammar context-free (except for raw string literals as is the case now afaik).

Re: A final proposal for Rust await syntax

#227
Language syntax and futures is only a half of the problem. IMO actual async IO implementation is harder.

Too many incompatible platform-specific APIs: epoll and AIO on Linux, kqueue on BSD and OSX, IOCP and new thread pool API on Windows. I’m pretty sure I forgot couple others, and each of them have non-trivial amount of quirks, bugs, and performance-ruining edge cases. Also these APIs are not directly compatible to each other.

To be usable, async IO needs to be integrated into the rest of IO. You can’t just place that on top, e.g. Java did that, IMO didn’t work particularly well.

The combination of the above makes creating good cross-platform abstraction for async IO challenging.

Not saying impossible, but it’s very hard to do.

I’ve tried once in C++, for that project I needed epoll and iocp, but I wasn’t able within reasonable time. Ended up swapping relatively large IO-related parts of my app depending on platform.

Re: A final proposal for Rust await syntax

#228
post #217
post #212

Earlier quoted context omitted.

> This proposal does raise another question: why not just green threads, and remove the concept of async functions entirely? Making another reply because this is completely unrelated... Rust already tried that. The problem is that Rust has a hard requirement as a systems language to support , at least, native I/O APIs, and the green threads implementation added a pervasive cost to that support because all standard li…

Couldn't green threads in principle be implemented the same way as your async proposal? The compiler could infer which functions need to be marked async. To support separate compilation it might need to compile two versions of each function, an async one and a normal one. You'd have exactly what you have in your proposal, except you never have to write async fn. You could still have blocking & non-blocking IO. It wou…

Yes, though you probably wouldn't call them green threads anymore at that point. (I mean, Rust async/await is implemented that way modulo syntax and it's not called green threads. But that's beside the point.)

In fact Rust has already thrown out separate compilation with its monomorphization-based generics, so making functions "async polymorphic" in the same way wouldn't be anything new.

And while that's somewhat unlikely from what I can tell, Rust is getting a little bit of that "effect polymorphism" somewhere else- generic `const fn`s can become runtime functions when their type arguments are non-const. So maybe someday we'll be able to re-use generic functions in both sync and async contexts depending on their type arguments.

Re: A final proposal for Rust await syntax

#229

Language syntax and futures is only a half of the problem. IMO actual async IO implementation is harder. Too many incompatible platform-specific APIs: epoll and AIO on Linux, kqueue on BSD and OSX, IOCP and new thread pool API on Windows. I’m pretty sure I forgot couple others, and each of them have non-trivial amount of quirks, bugs, and performance-ruining edge cases. Also these APIs are not directly compatible to…

Most of the work you're talking about has been completed for a long time in the crate "mio". It abstracts out all of the platform dependent async io operations into a single consistent interface.

Re: A final proposal for Rust await syntax

#230

I'm curious as to why the mandatory prefix syntax wasn't chosen (`await {...}`). It's less magic than a magic field and it fits into preexisting syntax better.

I'm not sure why it wasn't chosen, but I can give you some arguments against it. The braces introduce line noise. They introduce a new scope. I believe that rustfmt will currently put a newline after the opening brace. And it has the general problem that it can't be read from left to right.

(P.s. I'm not trying to start a debate, just trying to answer the question.)

Post reply on HN