News for hackers. Stuff that matters.
Re:A final proposal for Rust await syntax by foota on Monday May 06, 2019 @12:17PM (#19840804)
It seems they've settled on using a postfix approach. I can't help but feel this is a mistake. Rust is already a weird language to come to from the likes of python, Java, or Javascript, and it feels to me like this relatively unknown approach of putting the operator at the end is a mistake that will add another confusing aspect of the language.

I feel like the committee has worried about the wrong things when considering postfix vs prefix. Their main concern seemed to have been the extra syntax required to make prefix work with . And ? (i.e., (await foo).bar() ), but while avoiding this makes for a more optimized language I'm concerned they've missed the impact this will have on new people.

Or maybe I'm just a Luddite :)

Re:A final proposal for Rust await syntax by wtetzner on Monday May 06, 2019 @12:22PM (#19840864)
> Rust is already a weird language to come to from the likes of python, Java, or Javascript

I think that's a great reason to evaluate new syntax/features on how they will be used, as opposed to how they will attract (or not) new users. New users are already going to be expecting things to be different, and so making this one thing more familiar probably won't make much difference. On the other hand, code lives for a very long time once it's been written, so making the right choice in terms of readability/maintainability seems like the right move.

Re:A final proposal for Rust await syntax by foota on Monday May 06, 2019 @12:29PM (#19840961)
While that's true on an individual basis you can't use that continually to introduce differences, because at some point if someone comes to rust and sees a heap of weirdness they're going to be less likely to adopt the language. I'm mostly a bystander since I've written some rust but not very much, but I think rust is neat and I don't want it to become an esoteric language.
Re:A final proposal for Rust await syntax by ljm on Monday May 06, 2019 @12:49PM (#19841195)
If it's an effective solution it will only seem weird until it's proven to be more useful than the status quo approach.

I read this post and thought 'async as a prefix is intuitive!', but that's only because I saw it first in C#.

Rust already has an immense learning curve despite its ergonomics, I say it should continue to experiment. Same way Haskell does.

I do wonder if `.await` could have a sigil equivalent the same way `try!` did with `?`. `…` could work if it's not already used as spread args.

Re:A final proposal for Rust await syntax by childintime on Monday May 06, 2019 @02:26PM (#19842297)
> 'async as a prefix is intuitive!', but that's only because I saw it first in C#

The analogy made in the post, with the possibility of “expression-oriented” keywords like .match, suggests that `match expr {..}` is equivalent to `expr.match {..}`. So by analogy `await expr` and `expr.await` are also similar.

So why was the "prefix await" syntax dismissed right out of the gate? It is the option that needs the best argumentation, because 1) it is familiar and 2) match is currently a prefix (keyword), so await could probably also be.

Edit: only the await prefix clearly signals a break in control flow, only the prefix variant emphasizes this. In contrast the dot await syntax hides this.

Re:A final proposal for Rust await syntax by ajross on Monday May 06, 2019 @01:04PM (#19841405)
> If it's an effective solution it will only seem weird until it's proven to be more useful than the status quo approach.

Perl was a very effective solution. Still lost. And I say that as a long time perl5 nut.

Rust is, indeed, just syntactically insane to a new learner (honestly, worse than perl ever was). And it's getting rapidly worse.

Re:A final proposal for Rust await syntax by simias on Monday May 06, 2019 @02:08PM (#19842096)
I've used perl5 for a long time (although these days I've replaced it with python in my toolchain, although I have my fair share of complaints about python as well) and I think your comparison is unfair.

Rust's sometimes complicated syntax is made necessary by the very concept of the language. You need to be able to express lifetimes, you need to be able to express generics, you need to be able to strongly type lambdas etc... Of course the syntax is going to be a bit more complicated than, say, Common Lisp where everything is dynamic and garbage collected and you can let the runtime figure things out.

Perl 5 was syntactically insane because that's how the authors decided to do it. Effectively it didn't let you express things that were impossible in Lisp, Python, Ruby or JS. It's just a design choice to lean heavily on sigils and magic variables to favor short code even if it can be cryptic to people not intimately familiar with the language. I doubt anybody who hasn't used perl before will be able to figure out exactly what this does (and I'd argue that it's a fairly simple and idiomatic script, not some heinously cryptic code golf):

    while (<>) { chomp(); s/f.o/bar/; print; }
Rust is noisy because it has to represent concepts that simply don't exist in other programming languages.

I'd go even further: Rust does a better job than most languages at letting you only explicitly mention things that need to be explicitly mentioned. Thanks to the very powerful type inference you can write very tidy code, IMO much more so than in C where I have to explicitly type every intermediary variable that I would use for instance.

Re:A final proposal for Rust await syntax by ajross on Monday May 06, 2019 @03:28PM (#19842871)
> Rust is noisy because it has to represent concepts that simply don't exist in other programming languages.

In a few cases having to do with lifetime management and the borrow checker, that's certainly true.

But the example at hand is fundamentally just cloning ideas from Javascript.

Re:A final proposal for Rust await syntax by majewsky on Monday May 06, 2019 @05:03PM (#19843855)
The point is not that particular feature. It's how this new feature interacts with a bunch of existing language features.
Re:A final proposal for Rust await syntax by dbrgn on Monday May 06, 2019 @07:09PM (#19844853)
Actually JS just cloned those ideas from C# and Python.
Re:A final proposal for Rust await syntax by steveklabnik on Tuesday May 07, 2019 @02:07AM (#19846998)
... and when you get down into the details, there are significant differences in what Rust is doing as opposed to these languages, even if the high level idea is roughly the same.
Re:A final proposal for Rust await syntax by pcwalton on Monday May 06, 2019 @01:28PM (#19841702)
> Rust is, indeed, just syntactically insane to a new learner (honestly, worse than perl ever was).

Can you elaborate?

Re:A final proposal for Rust await syntax by foota on Monday May 06, 2019 @02:06PM (#19842075)
I'll bite. For context, I'm very much a rust beginner with probably a couple dozen hours at most. I find that anything having to do with lifetime parameters is hard. I think this is even worse than C++ templating in some sense since it behaves differently than type templating.

Otherwise, I think the syntax is fairly reasonable.

Re:A final proposal for Rust await syntax by pcwalton on Monday May 06, 2019 @02:49PM (#19842518)
That's legitimate; lifetime parameters are a new concept that aren't found in any other language. They naturally require a learning curve. Lifetime elision—making it so that you don't have to see lifetimes in most cases—is the main way we tried to make them easier.
Re:A final proposal for Rust await syntax by estebank on Monday May 06, 2019 @02:21PM (#19842237)
My advice would be to completely forego lifetimes handling until much later in time. It is a difficult part of the language to master but it gets much easier once you get more practice. Get well acquainted with the rest of the language and you'll pick them up with less trouble.
Re:A final proposal for Rust await syntax by ajross on Monday May 06, 2019 @02:01PM (#19842026)
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 function call and not a struct? Why is "127.0.0.1" not a String? Why do parametrized enumerants look in rvalues like C++ constructor arguments, which you promised earlier Rust didn't have?

Don't tell me the answers to those questions. I know the answers. Just recognize that those are questions that every new reader to that very early page in your docs is going to have. And... did they even need to be questions in the first place?

Re:A final proposal for Rust await syntax by pcwalton on Monday May 06, 2019 @02:24PM (#19842270)
> Why does a parametrized enumerant look like a function call and not a struct?

Because tuples are considered good things to have in a modern language. Structs and enum variants are just named versions of tuples (denoted with parentheses) or records (denoted with braces—unnamed records don't exist in Rust). To follow languages like Python, they're written "(1, 2, 3)". (It would be weird if tuples were written "{1, 2, 3}", right?) Therefore, a tuple named Foo is written "Foo(1, 2, 3)".

Removing tuples from the language was actually considered at one point, but the community (including me) really wanted them to stay, so they stayed.

> Why is "127.0.0.1" not a String?

Because it's a str, and there is a difference between str and String. Not having a string-view type would be a big mistake in a systems language like Rust. Note that "127.0.0.1" is not a std::string in C++ either (though there is an implicit constructor that can make it one).

In fact, the reason why we have both "str" and "String" is precisely to address your criticism: if we named "str" "string_view" or something, then people would be really surprised that a literal like "127.0.0.1" isn't a string.

> Why do parametrized enumerants look in rvalues like C++ constructor arguments, which you promised earlier Rust didn't have?

Because saying Rust has C++ constructors would just make things more confusing, because then people would expect them to behave like C++ constructors. It's less confusing to say that Rust doesn't have constructors like C++ does.

> And... did they even need to be questions in the first place?

I don't see any alternatives to the above that would make the language better instead of worse.

Re:A final proposal for Rust await syntax by yxhuvud on Monday May 06, 2019 @03:07PM (#19842655)
> (It would be weird if tuples were written "{1, 2, 3}", right?)

That is the case in Crystal. Doesn't feel weird - if anything it is consistent in that ()s always denote something to do with execution. Both ()s and {}s have multiple different other syntactic usages though, so it is not as if either is optimal.

Re:A final proposal for Rust await syntax by int_19h on Tuesday May 07, 2019 @04:48AM (#19847604)
Most languages that offer tuples, either use (), or just treat commas as "tuple operator" anywhere they don't have another meaning already. And this goes a long time back.

Function calls can then be treated as functions from a single tuple argument, as is idiomatic in SML.

Re:A final proposal for Rust await syntax by ajross on Monday May 06, 2019 @03:27PM (#19842852)
Like I said the first time, I know all that stuff. I'm trying to express problems a new user is going to have with this syntax, and "but our reasons are really good!" does nothing for them.

It's not inconsistent to hold the simultaneous beliefs that "trying to fix Rust's syntax would make it worse" AND "Rust's syntax is insane".

And given those beliefs, maybe adding a postfix operator to express what everyone else does with a function call was a poor call.

Re:A final proposal for Rust await syntax by pcwalton on Monday May 06, 2019 @04:42PM (#19843626)
It is inconsistent to hold those beliefs. Because "insane" implies that the Rust team made wrong decisions with the syntax, in fact so obviously wrong that no "sane" person would make them. If you acknowledge that the syntax decisions make sense, then they aren't "insane".
Re:A final proposal for Rust await syntax by ajross on Monday May 06, 2019 @05:02PM (#19843849)
Meh. That's just playing semantic games. I'm using "insane" in IMHO the more common colloquial sense of "inscrutable; hard to understand; inconsistent with existing paradigms". I'm absolutely not questioning your mental health.

Nothing about the soundness of your design means that Rust isn't hard to learn, is all I'm saying. And per the freakshow all around us, it's getting harder, not easier.

Re:A final proposal for Rust await syntax by pohl on Monday May 06, 2019 @05:55PM (#19844312)
I've never understood the use of the word "semantic" in the dismissive sense. Meaning is everything when parties are trying to communicate. This thread finally got to the heart of the miscommunication, and instead of celebrating you say "meh." I don't get it.
Re:A final proposal for Rust await syntax by simias on Monday May 06, 2019 @02:20PM (#19842219)
You need to tell us which other language you compare it to then. AFAIK most mainstream languages (the ones these hypothetical new readers are most likely to come from) don't have anything like Rust's enums. C++ does have the difference between C-style "const char " and "std::string" which is a bit* similar to &str and String, although &str is obviously massively safer and more ergonomic.

If they come from Scala or Haskell then yeah, sure but I'd argue that most programmers these days are likely to come from JS, Python or Java/C#/C++ and copying Scala or Haskell syntax would look even more foreign to them. Rust instead preferred to go for a syntax inspired by C++

>Don't tell me the answers to those questions. [...] And... did they even need to be questions in the first place?

So you know the answers but you still think it shouldn't be done that way?

Having things like &str instead of forcing everything into a dynamic String is Rust's killer feature. It means that you can write safe code while not being forced into adding any overhead. You pay for what you use, to quote the C++ motto. That means that as Rust matures it becomes a good competitor for replacing C and C++.

Re:A final proposal for Rust await syntax by pingucrimson on Monday May 06, 2019 @03:07PM (#19842662)
That is exactly the same way Haskell does "parametrized enumerants", and in C terms, str is like any pointer to a string, while String is like a heap-allocated string. What's "new" about any of this? C++ has the same thing going on with string and string_view.

If anything, Rust's managed to be a whole lot simpler than other languages. Python, JavaScript and C++ have some of the worst string encoding stories I've ever seen. And most popular languages don't even have sum types, so it's like they have an "and" and no "or".

Re:A final proposal for Rust await syntax by saghm on Monday May 06, 2019 @02:23PM (#19842256)
> Why does a parametrized enumerant look like a function call and not a struct?

I don't think this is an "invented new syntax"; plenty of languages with built-in support for sum types do it this way. Of course, most mainstream languages don't have built-in support for sum types, but that's an entirely unrelated point to Rust's syntax for them.

Re:A final proposal for Rust await syntax by wtetzner on Tuesday May 07, 2019 @11:38AM (#19850510)
> 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 by zzzcpan on Monday May 06, 2019 @02:08PM (#19842097)
Perl was designed to be familiar to C programmers.
Re:A final proposal for Rust await syntax by teddyh on Monday May 06, 2019 @04:21PM (#19843400)
No, Perl was designed to be familiar with Unix shell script (with its various variants), sed, and AWK programmers.
Re:A final proposal for Rust await syntax by username223 on Monday May 06, 2019 @01:19PM (#19841589)
> Perl was a very effective solution. Still lost.

For some version of "lost." It lost to $LANGUAGE_OF_THE_MOMENT for web development, but Perl is still a great text-munging and glue language, and I'll bet I'm not the only one using it for that. It didn't take over the world, but I'll bet that most people interact with a bit of Perl every day.

I agree that Rust is syntactically insane. Worse, while a Shell-and-C programmer would have some intuition about Perl syntax, a C++ programmer will almost start from scratch in Rust.

Re:A final proposal for Rust await syntax by vedantroy on Monday May 06, 2019 @04:20PM (#19843391)
I feel like unusual language syntax isn't an issue, as long as the syntax is understandable/readable once the programmer learns the syntax.

It doesn't take too long to pick up and become comfortable with a new syntax in a programming language.

Imo, the reason some esoteric languages fail are not purely because their syntax is obscure but because even once you learn the syntax, it is still hard to understand the code (example: Brainfuck).

With Rust, once you learn the new syntax, you can understand Rust code with relatively little effort.

Re:A final proposal for Rust await syntax by dragonwriter on Monday May 06, 2019 @04:26PM (#19843465)
> Imo, the reason perl failed was not because the syntax was obscure but because even once you learned the syntax, it was still hard to read perl code.

IMO, the reason Perl failed is that Perl 6 (which is a fairly awesome language in its own right) sucked up all the energy in moving Perl forward for too long and delivered too late, while competing languages kept providing usable progress (and avoided, as a consequence, looking dead, which may be as important as the actual usable progress itself.)

Re:A final proposal for Rust await syntax by jononor on Monday May 06, 2019 @12:56PM (#19841295)
New users expect things to be a bit different by assuming there are good reasons for change of convention.

EDIT: this might very well be the case here though, especially future extension for similar operators and chain-ability.

Re:A final proposal for Rust await syntax by wtetzner on Wednesday May 08, 2019 @08:47AM (#19858303)
Right, which is why I mentioned that focusing on readability/maintainability is the right move in this case. I think we're in agreement.
Re:A final proposal for Rust await syntax by holy_city on Monday May 06, 2019 @12:38PM (#19841071)
> Rust is already a weird language

Some folks came up with the idea of a "weirdness" budget - arguing that Rust had come close to using it all up.

>I feel like the committee has worried about the wrong things

There is no "committee" really, and all the worries have been expressed and weighed. The debate over this syntax has been going on for months and had huge community involvement.

It's all been summed up in this document:

https://paper.dropbox.com/doc/Await-Syntax-Write-Up--AcIbhZ1...

I was definitely in the prefix camp before I read that document.

Re:A final proposal for Rust await syntax by foota on Monday May 06, 2019 @01:09PM (#19841455)
Thanks, I'd read the intro but missed that.

I don't really see how they refute this argument though? Clearly they state arguments both in favor of postfix and prefix but it feels like some framework for weighing the arguments is missing, otherwise it just comes down to how individuals weigh the arguments.

Re:A final proposal for Rust await syntax by holy_city on Monday May 06, 2019 @01:29PM (#19841705)
That document isn't about arguing one way or the other, it lists all the different options and pros/cons. The post thread is the current stance of the lang team and letting everyone know they're going to make the final decision later this month.

Boats' keynote at rust-latam goes into some more detail as well.

https://www.youtube.com/watch?v=skos4B5x7qE

I'm just a casual observer here, but it seems like just about every argument and position on the subject has been iterated across Github, internals.rust-lang.org, the IRC/Discourse/Zulip chats, Reddit, and now HN.

This post by boats is just the next stepping stone alerting the community to the direction the team is leading and that it's going to be over soon.

Re:A final proposal for Rust await syntax by agency on Monday May 06, 2019 @01:59PM (#19842013)
Thanks for the link. As an outsider I also thought it seemed weird given so many other languages use prefix, but it makes sense with this framing that the main concern is the interaction with the ? operator.
Re:A final proposal for Rust await syntax by jwr on Monday May 06, 2019 @12:41PM (#19841103)
> Rust is already a weird language to come to from the likes of python, Java, or Javascript

Every time I see a statement like this, I remember a (paraphrased) statement from Rich Hickey: "[musical] instruments are made for people who can play them!".

I think unless you are specifically designing a beginner language (like Scratch), you should not take into consideration "ease of use" or "familiarity" arguments.

Re:A final proposal for Rust await syntax by joshuamorton on Monday May 06, 2019 @12:46PM (#19841167)
Counterpoint: APL and perl vs. python. Python did take usability into account and familiarity. UX is important. Developers are users. As a language (or in general tool) designer you have a responsibility to make that tool easy to use, and difficult to misuse.

Familiarity is a big part of that, although ease of use is bigger (which is probably why python got the traction it did despite being unfamiliar to people who came from braces-land).

Re:A final proposal for Rust await syntax by diggan on Monday May 06, 2019 @01:18PM (#19841587)
Different languages for different purposes. AFAIK, python is made for being easy to use and write, Clojure (Rich Hickey) is a pragmatic language for getting things done. Different languages will focus on different things and I think that's a good thing.

If I got to choose between the Clojure I know today VS a Clojure designed for ease of use and being familiar, I'm pretty sure I would chose the first.

Just like APL is much better for some tasks compared to Python, and vice versa.

Re:A final proposal for Rust await syntax by joshuamorton on Monday May 06, 2019 @02:29PM (#19842320)
> is a pragmatic language for getting things done

What does this mean though? Empirically speaking, a lot more "gets done" today using python than clojure. So, perhaps being easy to use is more pragmatic than whatever Rich means.

Re:A final proposal for Rust await syntax by kazinator on Tuesday May 07, 2019 @12:04AM (#19846455)
> Clojure designed for ease of use and being familiar

I.e. Lisp, basically.

Re:A final proposal for Rust await syntax by jodrellblank on Monday May 06, 2019 @07:36PM (#19845016)
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 do. After that, it got turned into APL\360 around 1962 (i.e there weren't all that many programming languages to be familiar with, then). The book "APL\360 An Interactive Guide" by L. Gilman, 1970, has a foreword which says:

APL is clearly gaining acceptance at this time as a computer programming language. This acceptance is not hard to understand. APL is one of the most concise, consistent, and powerful programming languages ever devised. (UX is important!)

and

From a pedagogical standpoint APL has a number of advantages. The material can be taught and used in small pieces. A student can be trying his hand on simple operations after five minutes of instruction. What he doesn't know won't hurt him (a statement that cannot be made about most other languages). If he tries something illegal such as division by zero or adding a number and a letter, he gets an understandable error message and is free to try something else. Nothing the user can do will cause the system to crash. (Usability!)

and

It is indubitably true that a "clever" programmer can use these advanced operators in such a way as to produce an "opaque" program, that is, one so compact and concise as to be nearly impossible for anyone else to understand. Whatever else may be said about such programs, which are questionable in many contexts anyway, they should not be used in demonstrations of APL. Experienced programmers who have seen APL demonstrated in terms of the fantastic cleverness angle sometimes criticize the language as being hard to understand, when their criticism more properly should have been directed at the demonstrator. Such misplaced cleverness is not to be found in this book. All operators are thoroughly covered, but there is no attempt to show off the ingenuity of the authors in writing ingeniously condensed programs.

Re:A final proposal for Rust await syntax by joshuamorton on Monday May 06, 2019 @08:12PM (#19845219)
> 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" either. Programming language design, like programming, is about finding the right abstractions and providing them.)

Compare to ABC (a language python was heavily inspired by) using `:` to declare a function (ie. `def my_f():`) despite it being unnecessary, the language was parsable without it. But they did user studies, and those found that the colon helper readers understand the blocks better.

> Usability

Granted this may have been an improvement in usability. APL, being a higher level language, avoids many of the problems that C and co had, and I've never used basic/fortran any of the other early languages that were popular at the same time.

That said, I have to strongly disagree with the last paragraph. A good tool discourages misuse. Inscrutable programs are misuse, "Readability counts". A language that encourages, or doesn't discourage, inscrutable programs isn't as good a language as one that does (at least if you consider inscrutable programs to be misuse, and it appears that you, I, and the APL author all agree on that).

Re:A final proposal for Rust await syntax by jodrellblank on Monday May 06, 2019 @08:59PM (#19845469)
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 by joshuamorton on Monday May 06, 2019 @09:56PM (#19845739)
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 by jodrellblank on Tuesday May 07, 2019 @08:47AM (#19848857)
Extensibility and composability is a better abstraction.

Say that our modern day programmer is comfortable with + × > < and can learn in a few moments that max 3⌈5 and min 3⌊5 and reverse ⌽values have their own symbols. By learning the three patterns of / as replicate, reduce and n-wise reduce, they get a large amount of composable patterns to play with, covering sum(), min(), max(), reverse(), [::-1], functools.reduce(), functools.filter(), Numpy overloads of +, Numpy .sum() and .prod(), and more.

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 < ⍳10
    0 0 0 0 0 1 1 1 1 1 
Visually patterned half and half. Or this:

        ¯3 ⌽ 3 < ⍳9
    1 1 1 0 0 0 1 1 1 
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<brightness)/pixels will get you the pixels brighter than 50. Try that in Python and you get something like [p for i,p in enumerate(pixels) if i in [i for i,b in enumerate(brightness) if b > 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 by joshuamorton on Tuesday May 07, 2019 @12:30PM (#19850997)
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 by jodrellblank on Tuesday May 07, 2019 @03:39PM (#19852732)
> 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.

All of that to cover ~ten symbols. Is it unfair to Python to point out that this is a huge difference in complexity that someone needs to learn to be able to do those things from scratch?

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

Which is fine. It's just that the few operations of array manipulation DSL go so much farther than I expected they would. I do know that APL is not going to be the language to implement WireShark or Halo vNext.

The big catch in paragraph two is "if my objects support that"; yes you would have to do something more complex in APL. But not /much/ more complex. In Python you'd need to understand classes and magic methods and overloading before you could write that overloaded addition - and understand CPython internals, C and NumPy to add it to NumPy objects, I imagine. I doubt you can do that all in APL, but then again if I'm correctly reading what l2 norm addition is, Pythagorean square-root-of-sum-of-squares including complex numbers, it's not a lot of code to write that anyway:

    values ← 4J3 ¯2J8 10 20
    abs ← |values
    squared ← abs * 2
    sum ← +/squared
    sqrt ← squared * 0.5
or without the temporary variables which don't add much clarity:

    ( +/ (|values) * 2 ) * 0.5
⍨ is a cool operator which lets you swap arguments around, so instead of having to read from inside nested parens out, you can remove parens and read serial code left/right instead:

    0.5 *⍨ +/ 2*⍨ |values
Name that with a lambda/anonymous function/dfn:

    l2NormAdd ← {0.5 *⍨ +/ 2*⍨ | ⍵}
    l2NormAdd values
Which .. isn't so bad that you'd wish for overloading, if the cost of writing the overloading was so much higher, is it?

> That's still just pixels[brightness >50] with numpy.

That is cool, I didn't know you could do it. But it is completely separate from the normal Python list comprehension style, apparently a different use of > (?), won't compose with the normal Python sort(key=) to sort the pixels by brightness. At what point does learning one-off skills for every task start to get annoying? (From my personal experience, it never does get annoying, and that seems weird to me now).

----

But then a tiny amount more APL and here's a depth first recursive tree traversal with accumulator function, projecting a tree structure onto a nested array:

    ⊃∇⍨/⌽(⊂⍺ ⍺⍺ ⍵),⍺ ⍵⍵ ⍵
     │└┬┘  └─┬──┘  └─┬──┘
     │ │     │       └──── (possibly empty) vector of sub-trees.
     │ │     └──────────── new value of accumulator.
     │ └────────────────── left-to-right reduction →foldl←
     └──────────────────── recursive call on (⍺⍺ trav ⍵⍵).

 - https://dfns.dyalog.com/n_trav.htm
I sure could bash out a depth-first tree traversal in Python, with dictionaries or a dedicated tree-node class, and it would take me way less time than understanding this will take me. Yes this may be 20 characters, but it seems a shame to make "few characters" the main focus of why this is interesting. Each of these primitives in the line is almost trivial to learn on its own, none of them are complex magic not even omega-omega. But an expert combining them together carefully makes them do something way more than the sum of their parts, and way more than the shortness suggests they will do. (Here's John Scholes, founder of Dyalog APL, building on this to solve the N-Queens problem: https://www.youtube.com/watch?v=DsZdfnlh_d0 the commonly linked Conway's Game of Life in APL is more approachable, but this is more amazing because of what it's doing to treat arrays as trees, but way harder to follow and more "magic")
Re:A final proposal for Rust await syntax by joshuamorton on Tuesday May 07, 2019 @04:50PM (#19853320)
> I sure could bash out a depth-first tree traversal in Python, with dictionaries or a dedicated tree-node class, and it would take me way less time than understanding this will take me.

That's my point. APL is interesting, but its enforced structure doesn't fit things intuitively (perhaps there's an implied "for most people" here). Yes, omega combinators or whatever it is that's doing is neat and perhaps pedagogically useful. But

> That is cool, I didn't know you could do it. But it is completely separate from the normal Python list comprehension style

That's because you're not using list comprehensions, you're using ndarrays, which do poweful things to python's already powerful slice notation, and as a result get all of the nice broadcasting things that you get in APL. Its why a + b and a * b just do what you expect in numpy-land.

Slice notation in python is already powerful: a[:], a[5:], a[:5], a[::2], and a[::-1] are things I'd expect someone relatively new to understand intuitively (those are copy, head(5), tail(5), every_other, and reversed).

Adding the ability to customize it: `a[:,:,::-1,:]` for example inverts the 3rd axis of a 4d array, similarly you can pull out a subarray, strided subarray, etc. very declaratively. And numpy further extends that by allowing the argument to be a mask (which is what I showed you in the last comment), so a array[boolean_mask] does the kind of thing you'd expect.

>At what point does learning one-off skills for every task start to get annoying?

When the one-off skills are better abstractions for the task than the "consistent" thing, never, as it seems you're realizing.

Re:A final proposal for Rust await syntax by dancek on Tuesday May 07, 2019 @11:47AM (#19850579)
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 by michaelmior on Monday May 06, 2019 @12:55PM (#19841278)
I see "ease of use" and "familiarity" as two different concerns. I think I would agree with you on familiarity, but even if I'm advanced user of the language, I want it to be easy to use wherever that doesn't conflict with other more important goals. (And I think some things are less important than ease of use.).
Re:A final proposal for Rust await syntax by blub on Monday May 06, 2019 @02:38PM (#19842410)
That statement from Rich Hickey makes no sense at all, because we aren't born knowing how to play instruments. And if your brand new instrument is weird, then not many people are going to bother learning how to play it.

Thinking that "ease of use" should not be considered because [favourite reasons] is probably the number one misunderstanding software engineers have about humans. :) Please read Norman's "The design of everyday things", before accidentally making the life of someone miserable through software.

Re:A final proposal for Rust await syntax by wtetzner on Tuesday May 07, 2019 @04:20PM (#19853081)
> And if your brand new instrument is weird, then not many people are going to bother learning how to play it.

Which musical instruments are _not_ weird?

Re:A final proposal for Rust await syntax by pron on Monday May 06, 2019 @04:22PM (#19843414)
> [musical] instruments are made for people who can play them!

And yet, for the most part, trumpets have the same valve configurations, pianos are in the same key, and violins have the same string arrangement.

Unlike different musical instruments, all programming languages make the same sound (more or less). The goal of using a programming language is not to use that programming language, but to program a computer.

> you should not take into consideration "ease of use" or "familiarity" arguments.

Especially if you really don't want it to be wildly successful.

Re:A final proposal for Rust await syntax by 13415 on Monday May 06, 2019 @02:09PM (#19842104)
I wouldn't use a programming language whose designer had this attitude.
Re:A final proposal for Rust await syntax by fnordsensei on Monday May 06, 2019 @02:53PM (#19842557)
This has been debated endlessly with regards to Clojure, sometimes with what seems like deliberate misunderstandings stemming from categorical thinking or entrenched positions.

It's not a binary choice for the most part.

- Ease of use will not be promoted over long term growth or power (I.e., the instrument should be designed such that it can ideally facilitate indefinite growth of skill. It shouldn't be a toy that only works up to a certain point.)

- Very often, ease of use can be optimised in such a way that it does not conflict with the first point, rendering the entire discussion moot.

- Familiarity is a non-goal unless the familiar design has the same properties as the optimal design, with regards to the first point.

This is not to say that easier, beginner friendly designs that _does_ sacrifice the long term power or growth aren't valuable. It's a different design goal, though.

Re:A final proposal for Rust await syntax by Retra on Monday May 06, 2019 @06:00PM (#19844356)
And I wouldn't use a programming language whose designer didn't have this attitude.

I also wouldn't use a programming language that is optimized for increasing the number of users at the expense of performance, clarity, stability, consistency, or power. I don't want a language that appeals to most people, I want one that disproportionately appeals to careful and competent people.

Re:A final proposal for Rust await syntax by jwr on Monday May 06, 2019 @02:21PM (#19842226)
Would you also refuse to play a musical instrument, because the designers had this attitude? Pretty much all musical instruments are "hard to play" and you have to learn them, sometimes for many years.
Re:A final proposal for Rust await syntax by kazinator on Tuesday May 07, 2019 @12:06AM (#19846461)
Professional grade, expensive instruments are highly playable compared to the junk.
Re:A final proposal for Rust await syntax by jodrellblank on Monday May 06, 2019 @07:43PM (#19845056)
Erik Naggum, Comp.Lang.Lisp, 1997:

"what makes _me_ sad is the focus on "most folks" and "Joe Sixpack".

why are we even _thinking_ about home computer equipment when we wish to attract professional programmers?

in _every_ field I know, the difference between the professional and the mass market is so large that Joe Blow wouldn't believe the two could coexist. more often than not, you can't even get the professional quality unless you sign a major agreement with the vendor -- such is the investment on both sides of the table. the commitment for over-the-counter sales to some anonymous customer is _negligible_. consumers are protected by laws because of this, while professionals are protected by signed agreements they are expected to understand. the software industry should surely be no different. (except, of course, that software consumers are denied every consumer right they have had recognized in any other field.)

Microsoft and its ilk has done a marvelous job at marketing their software in the mass market so that non-professional programmers pick them up and non-programmers who decide where the money should be wasted will get a warm fuzzy feeling from certain brand names. I mean, they _must_ recognize that nothing else they buy for their company is advertised in the newspapers that morning and they aren't swayed by consumer ads when they buy office or plant equipment, are they? so _why_ do they swallow this nonsense from the mass-marketing guys hook, line, and sinker?

they don't make poles long enough for me want to touch Microsoft products, and I don't want any mass-marketed game-playing device or Windows appliance _near_ my desk or on my network. this is my _workbench_, dammit, it's not a pretty box to impress people with graphics and sounds. when I work at this system up to 12 hours a day, I'm profoundly uninterested in what user interface a novice user would prefer.

I'm reminded of the response to how people of little or no imagination were complaining about science fiction and incredibly expensive space programs: "the meek can _have_ the earth -- we have other plans".

no, this is not elitist, like some would like to believe in order to avoid thinking about the issues. this is just calling attention to the line between amateurs and professionals, between consumers and producers, that is already there in _every_ field. I want people to wake up to this difference and _reject_ the consumer ads when they look for professional tools. if it's marketed to tens of millions of people, it is _not_ for the professional programmer, and not for you. if its main selling point is novice-friendliness, ignore it unless you _are_ a novice. (and if you are a novice trying to sell your services in a professional market, get the hell out of the way.)

https://groups.google.com/forum/#!topic/comp.lang.lisp/HCMKe...

Re:A final proposal for Rust await syntax by atoav on Monday May 06, 2019 @01:08PM (#19841447)
Rust has some existing postifx syntax (shouldn’t it be called suffix?). And to be honest it didn’t threw me of in the slightest when I started with Rust. Using a questionmark at the end to let an error bubble up seems quite intuitive.

The most scary thing that threw me off the most were lifetimes (which for beginners sake are gladly not needed all that often).

I have trust in the Rust developers and the community that they will choose something very well thought out, because for now the whole language feels incredibly well considered.

Re:A final proposal for Rust await syntax by Twisol on Monday May 06, 2019 @12:26PM (#19840920)
For what it's worth, it seems that Rust isn't alone here. C# 8.0 introduced postfix `switch` expressions (https://devblogs.microsoft.com/dotnet/do-more-with-patterns-...), which are along the same lines of what's suggested for `match` in Rust further along in the OP.

I agree that it looks strange at first. But I think I'll get used to it.

Re:A final proposal for Rust await syntax by albru123 on Monday May 06, 2019 @12:37PM (#19841053)
Thanks for pointing this out, I had no idea they implemented this for C# 8.0

Also is it just me or the switch pattern really is inspired by Rust match?

Re:A final proposal for Rust await syntax by nixpulvis on Monday May 06, 2019 @12:39PM (#19841082)
Pattern matching syntax across many languages is very similar, most notably inspired by ML I'd say.
Re:A final proposal for Rust await syntax by anp on Monday May 06, 2019 @12:41PM (#19841104)
Pattern matching as is in Rust has many notable precedents that IIRC the C# folks considered as prior art, not least of which being F#.
Re:A final proposal for Rust await syntax by giornogiovanna on Monday May 06, 2019 @12:30PM (#19840979)
Literally everyone else uses prefix await, so this will be a problem. But,

- this is a lot easier to chain, which is very useful, and

- the "future expansion" might bring a prefix await anyway (although introducing two syntaxes for the same thing might be even worse).

I'd prefer "f await" to "f.await" because it feels a lot less magical and lets me stick to my intuition that "." is just for stuff implemented by the library, but maybe that's just me.

Re:A final proposal for Rust await syntax by hexane360 on Monday May 06, 2019 @01:00PM (#19841349)
My personal preference is for a happy medium between "f await" and "f.await", which is some other character that indicates "special postfix". Sort of like how func() is clearly different from macro!(), we can have "expr->keyword" or "expr.keyword!" to differentiate from "expr.property"
Re:A final proposal for Rust await syntax by 62747478182 on Monday May 06, 2019 @07:14PM (#19844887)
> Literally everyone else uses prefix await, so this will be a problem.

Kotlin uses `.await()`.

Re:A final proposal for Rust await syntax by empath75 on Monday May 06, 2019 @08:34PM (#19845340)
If you’re able to figure out how to write working rust code, you can learn how to google where ‘await’ goes.
Re:A final proposal for Rust await syntax by axaxs on Monday May 06, 2019 @03:14PM (#19842723)
I tend to agree with you. I love what Rust is doing, but can't force myself to use it because it's, to me, not easy to read. As I've grown, I much prefer simpler languages. Go, Python, and to a lesser extent C(while it can be simple, people abuse it in weird ways) all fit the bill. I wonder how many other folks have this simple aversion...