Live data from Hacker News

A final proposal for Rust await syntax

boats.gitlab.io

251–260 of 265 posts

Re: A final proposal for Rust await syntax

#251

Earlier quoted context omitted.

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 ar…

Extensibility and composability is a better abstraction.

Say that our modern day programmer is comfortable with + × > In Python, that is many standalone disconnected patterns which do not compose, In APL the "and more" is because composability means there are lots of ways of putting these operations together. values.prod() is what you have to do without composability, you can't re-use the builtin multiply without making a separate wrapper or overload. The result is visually different to sum(values) and conceptually different because it is a method call on an object, and the resulting prod() does not compose with anything else in the language.

Show me how you present those arrays as a graph in APL. In "wordy, verbose" python it's [three lines, another third party install, an import and rename, a two stage operation and a bizarre array show() call passing itself as a parameter(?)]. Is visualizing the data you're manipulating so basic?

Yes, in Dyalog APL it's:

    ]chart array
And that doesn't just show a bar graph, it also loads a GUI for customizing the look of the chart, and the chart library is SharpPlot for .Net, which ships with it. (This is not in ISO standard APL, like matplotlib is not part of pure CPython. APL is not giving up extensibility, you can write your own functions which hide things behind names, or in different implementations of APL call out to OS/.Net/library features).

when all your examples are array operations is going to make the general purpose language look funny.

Yes, true. But is it not the everyday task of programming to process chunks of data in collections?

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.

Strings are character vectors, like Python lets you treat strings as iterables and slice them, so you can do many array transforms on text. APL's array operations aren't limited to numeric math like +5 or A×B, they also work on something I don't know what to call it - geometric patterns, maybe? Like, indicate where 5 is less than integers to ten:

        5 
Visually patterned half and half. Or this:

        ¯3 ⌽ 3 
Visually, spatially, patterned into thirds. You can feed this into filter() to make combinations of things more complex than "items greater than five", but "items in this pattern", the filter is not a single lambda function which takes an element and decides whether to keep or remove it, the filter-reduce is more powerful and composable than that, and building the patterns from composing the same basic primitives.

And yes you could pull in Numpy and fill an array with values and rotate it, but you wouldn't think to do that to apply it to a string, because it's /so much work/ and so far away and distant from the provided black-box string methods.

That is, APL is so great for things more than array-math. Albeit not everything more than array math. I sure have my own skepticism and questions about how well it scales up to larger programs and where its practical and pragmatic limits are.

But, take some imaginary pixels in one array and brightnesses in another and (50 50]]. The APL is "dense and unreadable" and the Python is "clear and composable". "Oh you wouldn't do that in Python", no indeed you wouldn't, you'd have to put stuff in a tuple or object to work around the fact that Python won't let you keep simple things simple.

Re: A final proposal for Rust await syntax

#252
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.

I think yield would be a candidate for this syntax because yield can return.

Re: A final proposal for Rust await syntax

#253
post #103

Earlier quoted context omitted.

> Rust is, indeed, just syntactically insane to a new learner (honestly, worse than perl ever was). Can you elaborate?

Not even if you paid me to have that fight, no. Edit: OK, one tiny crumb: https://doc.rust-lang.org/book/ch06-01-defining-an-enum.html -- Read through that thinking about how other languages express the same fundamentally simple concepts, and consider how Rust invents new syntax for basically everything, and then sticks it all together by re-using syntax from other areas. Why does a parametrized enumerant look like a…

> Just recognize that those are questions that every new reader to that very early page in your docs is going to have.

I doubt all new readers will have those questions. It depends on their background. For example, plenty of languages use similar syntax for sum types (Scala, Swift, ML, Haskell, etc.).

Re: A final proposal for Rust await syntax

#254

Earlier quoted context omitted.

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 ar…

Extensibility and composability is a better abstraction. Say that our modern day programmer is comfortable with + × > In Python, that is many standalone disconnected patterns which do not compose, In APL the "and more" is because composability means there are lots of ways of putting these operations together. values.prod() is what you have to do without composability, you can't re-use the builtin multiply without mak…

You make very good points, but unfortunately most people won't seriously consider APL as it's not a general-purpose language. It's just too alien to put much effort into.

I do believe in the benefits of powerful notation. I also find some concepts useful outside array-oriented languages, eg. verb rank [0]. My qualms with the APL family is the difficulty of choosing language and implementation. J or K seem strictly better than APL (eg. forks and hooks) except they use line-noise ASCII notation. Implementations tend to be proprietary and require a license.

[0]: https://www.jsoftware.com/help/jforc/loopless_code_i_verbs_h...

Re: A final proposal for Rust await syntax

#255
post #229

Earlier quoted context omitted.

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.

Are you sure about that? I've looked at the library, it doesn't support anything besides epoll and IOCP, i.e. no BSD or OSX support, no AIO on Linux (the kernel one, not POSIX). You probably don't want to consume IOCP API on Windows anymore, Vista introduced higher level and easier to use StartThreadpoolIo and friends. Also on Windows, even with IOCP, you don't want to split async IO from thread pool. The OS kernel m…

It says that it is also backed by kqueue and supports FreeBSD , NetBSD, and OS X.

I found this issue where they're discussing rewriting the Windows implementation using the library `wepoll`.

https://github.com/tokio-rs/gsoc/issues/3

What would be the advantages of supporting AIO on Linux?

Re: A final proposal for Rust await syntax

#256

Earlier quoted context omitted.

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 ar…

Extensibility and composability is a better abstraction. Say that our modern day programmer is comfortable with + × > In Python, that is many standalone disconnected patterns which do not compose, In APL the "and more" is because composability means there are lots of ways of putting these operations together. values.prod() is what you have to do without composability, you can't re-use the builtin multiply without mak…

That's still just pixels[brightness >50] with numpy. Which brings me back to what I said before: if I want a powerful array manipulation dsl, I still have it, but I'm not limited by it.

To your statement "you can't use the built-in multiply without adding an overload": yes, but that's because apl forces everything to be an array. If I want to work with something with non-array syntax (as an example, where addition uses a l2 norm), if my objects support that, that's just x+y, while in apl you have to do something more complex.

Note also that you're being unfair to Python. List comprehensions, array index notation, and numpy methods cover pretty much everything you've mentioned in apl. And they funny require matching weird syntax to operations.

Re: A final proposal for Rust await syntax

#257
post #255

Earlier quoted context omitted.

Are you sure about that? I've looked at the library, it doesn't support anything besides epoll and IOCP, i.e. no BSD or OSX support, no AIO on Linux (the kernel one, not POSIX). You probably don't want to consume IOCP API on Windows anymore, Vista introduced higher level and easier to use StartThreadpoolIo and friends. Also on Windows, even with IOCP, you don't want to split async IO from thread pool. The OS kernel m…

It says that it is also backed by kqueue and supports FreeBSD , NetBSD, and OS X. I found this issue where they're discussing rewriting the Windows implementation using the library `wepoll`. https://github.com/tokio-rs/gsoc/issues/3 What would be the advantages of supporting AIO on Linux?

> rewriting the Windows implementation using the library `wepoll`.

Interesting idea but I don’t like it too much. While removing the huge complexity of manually managing IOCP and required resources, It’s an undocumented API. New Vista+ threadpool-based IO also removes that complexity, removes complexity of implementing thread pools in the higher level in Tokyo. It’s documented and supported, and Rust has issues with WinXP support anyway.

> What would be the advantages of supporting AIO on Linux?

Faster async disk IO for the apps which are OK with the limitations, i.e. which read/write complete blocks of O_DIRECT files. Databases come to mind.

BTW, io_uring feature coming into Linux kernel removes most limitations of AIO while also improving performance.

Re: A final proposal for Rust await syntax

#258

The syntax feels a bit Ruby-ish, doesn't it? Here's an example from the article of how they could expand the syntax in the future: foo.bar(..).baz(..).match { Variant1 => { ... } Variant2(quux) => { ... } } Compared to some Ruby: 5.times { puts "Hello world!" } Note I'm by no means an expert in Ruby or Rust, this is just what I thought of when I saw the syntax.

A .match "method" just opens the dam to "why stop there?" I prefer Kotlin's general approach of .let and similar: number = foo.bar().baz().let { match it { A => 1 B => 2 } } Now anyone has the general tool for chaining without needing library authors or language designers to create the API for them.

Note that in Rust, `.match` would itself provide the general way:

    let number = foo.bar().baz().match { it =>
        it + 1
    };

Re: A final proposal for Rust await syntax

#259

Earlier quoted context omitted.

Python also chains methods. And having to write (await (await (await foo).bar()).baz()) is annoying.

That doesn't look like well written async code at all... You're not supposed to use await literally everywhere and especially not multiple times in a single line. Javascript already has an answer to this (Hint it was inspired by Monads but it isn't one): await foo.then(f => f.bar()).then(b => b.baz())

What happens if f.bar() throws an exception asynchronously?

Re: A final proposal for Rust await syntax

#260
post #199

Earlier quoted context omitted.

Technically, `?` can work in lambda's if the return value is a `Result` - though it won't work like it's being called as part of a normal loop or whatever. That's largely mitigated by the combinators available on an interator of `Result`s. So I think we'll just need similar tooling for lambdas - perhaps an `async` modifier for them? That (I think) would lift await stuff up to `?` in terms of lambda support.

Yep, and in fact async lambdas are already a thing on nightly. But, while I may just be nitpicking, `.map(async |f| f.await)` wouldn't do anything useful. Applied to an Iterator of Futures, it would be a no-op, kind of like (since you mentioned `?`) `.map(|x| Ok(x?)). Instead you'd probably want some combinator to turn it into whatever "Iterator but async" trait Rust eventually standardizes on – futures-rs has Stream…

Thanks for the nitpick! I hadn't thought it through all the way. I was mostly thinking about doing async stuff with the inner stuff, but you're definitely right. I'm glad you commented because I've had to rethink it.
Post reply on HN