Grammar liberalizations

In an effort to make Rust’s grammar more tolerant of macros and people, I’d like to collect a list of grammatical forms that are currently not allowed.

Note that the forms that may be illegal now but possibly legal in the future are not an indication of a recommended one-true-style by rustfmt. Instead, it is a philosophy in Rust language design to have a flexible grammar that accepts things that people find abhorrent.

Some forms that are illegal now are:

  1. Leading comma
fn main() {
    let arr = [
    , 1
    , 2
    , 3
    ];
}

struct Foo {
  , foo: usize
  , bar: u8
}

fn foo<, T>() {}
  1. Leading plus
fn foo<T: + Copy>() {}

If you can think of any other “strange” forms that are illegal today please make a note of them here.

The end result of this thread will likely be an RFC proposing that some of these forms be legal.

I don’t understand why allowing leading commas would be useful. If you want as many commas as elements/struct fields, then just include a trailing comma after the last one. That is allowed today, and it’s also trivial to achieve in machine-generated code.

2 Likes

Simple... Some people prefer that style.

in that case, the decision should also be equally simple: that’s probably not enough justification for adding them to the language.

2 Likes

I don’t want to litigate this here. Only collect instances where some people think that the grammar is too unforgiving.

Is this true? The liberalizations I've seen (trailing comma in calls, leading vert in arms, trailing + in bounds, ...) all seem to be aiming for a different philosophy: All items in a sequence can be written the same way, if you so wish, with no need to do something different a particular position. Thus foo(a, b,), T: A+ B+, |A |B =>, ...

That serves both the code generators wanting to just do the same transformation for each item as well as the rustfmt principle to prefer formats that result in minimal diffs in source control.

That's very different from supporting different formats because people have different tastes.

10 Likes

I love the Python part of its Zen:

There should be one-- and preferably only one --obvious way to do it.

I add a lovely quotation from John Carmack (https://www.gamasutra.com/view/news/128836/InDepth_Static_Code_Analysis.php ):

This seems to imply that if you have a large enough codebase, any class of error that is syntactically legal probably exists there. In a large project, code quality is every bit as statistical as physical material properties – flaws exist all over the place, you can only hope to minimize the impact they have on your users.

1 Like

Yes, I think it is. However, let's not go to meta and discuss the premise of the thread please.

Describing the current rules as “too unforgiving” is litigating the issue here.

3 Likes

I’m quite interested now though, do you (or anyone else) know of any code in other languages that’s actually written like that?

In Haskell it is common to write like so:

myList =
  [ 1
  , 2
  , 3
  , 4
  ]

if we take this to what I believe is its natural conclusion (the point is to have the comma at the start of the line) you get:

let arr = [
  , 1
  , 2
  , 3
];

I’ve heard multiple experienced Haskell programmers say “this is a thing we do because we can’t use trailing commas”.

3 Likes

That's not my experience, but to each their own. Personally, when I write Haskell, I find it pleasant to have a leading comma for arrays.

I know of that style for Haskell, and you can write it the same way in current Rust. I was specifically wondering about the leading comma on the first item thing, which I’ve never seen before, thus was questioning the “some people prefer that style.”

(Additionally, it gets even weirder when the commas aren’t aligned with the square brackets.)

Somehow this discussion seems to be meandering away from its initial purpose of „macro tolerance". As humans we may prefer not to have list separators/combiners before the first element or after the last element of a list, but macros in Rust are facilitated when the language syntax tolerates them.

Trailing comma on all lines instead of leading comma seems much better since it’s also an acceptable way to write normal prose, and saves a character (the space character after leading comma).

Supporting both styles would result in a mismatch of styles in the wild, which makes reading Rust code less pleasant, and catering to multiple readers seems more important than catering to the single writer’s preferences.

7 Likes

For me, that is certainly how my use of leading comma began. But to be entirely honest, if Haskell were to one day suddenly begin supporting both trailing and leading commas, I would start writing what @centril wrote. Leading punctuation makes structure more obvious, because it lines up.

I'd probably even take leading semicolons if the world wasn't so entrenched in the current standard syntax (and were it not for the whole semicolon-equals-unit-value thing in Rust). It would certainly have eliminated the majority of those dumb edit-recompile cycles where I forgot a semicolon, or put one after a braced item. Thank goodness now for IDEs/RLS...

1 Like

I hate to be the one guy, that hates everyone ideas. but here it goes, I actually disagree with making rust more lenient syntax wise. sure makes certain code generators easier to write. but it comes with a cost and a steep one at that. by making it more lenient, It can lead to what i would call the single char cascade problem. change a single character and the entire program is effectively different. in addition a single char added some where else has absolute no effect or meaning.

I would rather have every single character to serve a purpose beyond simply stylistically pleasantness, or leniency.

It can also lead to bad or misleading error messages because their now more possible corrections. while a stricter language, has the problems effectively reduced.

3 Likes

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.