About syntax.. ( Improving signature)

fn ... ( ... )  ->  ... { ... }
                ^^___________ what is that ?

Is it necessary ?

Same questions about closure :

| ... | ... 
^___________ what is that ?

Is first stick necessary ?

If you want a proposal to change Rust syntax, then you are better off posting to IRLO.

1 Like

That said, there is approximately zero chance that such a fundamental thing is considered to be changed. To get the elephant out of the room: it's plainly too late now to add backwards-incompatible changes. Also, there was a lot of thought that went into the basic syntactic design of the language. Things are the way they are because there is usually a good reason behind them. These sort of things have been rehashed many times, and it's highly unlikely that you can single-handedly improve upon them.

To answer your actual questions: yes, the first vertical bar (I'm assuming that is what you are referring to as a stick) is necessary. You have to introduce a closure with something, and a good thing to introduce it with is the delimiter of its parameter list. Meanwhile, the right arrow in a fn item is not technically necessary, but it makes the signature easier to read (it is visually evocative of the return type, since it suggests "goes to").

17 Likes

To be a little more specific, a single stick in Rust is a bitwise OR operator. This program is valid, and does not crash:

fn main() {
    let n = 1 | 4; // binary or 100 with 1 = 101
    assert_eq!(n, 5);
}

More specifically, while getting rid of the arrow in function signatures would probably be doable, you're allowed to name the return type in closure expressions, like this:

fn main() {
    let closure = |a: i32| -> i32 { a | 1 };
    let n = closure(4);
    assert_eq!(n, 5);
}

Getting rid of that arrow is impractical. Because the return type on closures is optional, there needs to be a way to figure out whether the return type is present or absent, preferably without having to use arbitrary lookahead.

It doesn't necessarily need to be an arrow. It could've been a colon, like fn foo(): i32. But, even if you think that's better, it's not better enough to be worth changing every Rust program everywhere.

7 Likes

One thing I'll note here is that "necessary" is basically never the right question to ask.

Even Python, which is well known for being syntax-light, has unnecessary stuff. For example, in

if pi > 2:
    print("The world is sane")

That colon isn't necessary. But it was decided that having it there makes it easier for humans to understand, and thus it's worth having anyway.

One thing that's nice about the leading | for closures is that it allows IDEs to be better. In C# when I type .Select(x the IDE likes to try to auto-complete the x to something that exists, but that's not what I want because I'm trying to type .Select(x => x.bar) -- the x is a new binding. But in Rust, when I type .map(|x , the IDE knows, even though I'm not done yet, that that's going to be a closure, and thus there's no reason to trigger autocomplete for me here. And thus .map(|x| x.bar) comes out nicely without that extra sometimes-hiccup.

TL/DR: Lots of things aren't needed if code appears fully-formed and perfect, and is only ever read by a computer. But for fallible humans like me, a little redundancy is a huge help for readability and for getting better help from the compiler.

15 Likes

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.