Rust's optional leading |
(vertical bar) in patterns was introduced in Rust RFC 1925. As the motivation section of the RFC explains:
This is taking a feature which is nice about F# and allowing it by a straightforward extension of the current rust language. After having used this in F#, it seems limiting to not even support this at the language level.
So, the author of the RFC just thought it was neat syntax. Rust draws a lot from ML languages like F#, Haskell, and OCaml, both in its syntax and semantics. In particular, Rust's enums/match/patterns features are very closely inspired by ML languages.
The motivating example is that a match pattern might have multiple cases A | B | C
. There are some different ways to format this across multiple lines. For example, Rust's normal style:
match value {
A
| B
| C => todo!(),
_ => unimplemented(),
}
But some people think the different alignment of A
and B
is confusing there. Introducing a leading |
helps with alignment, and could make the code more easy to read. This changes |
from a pattern separator to a pattern introduction marker, just like how it is often used in the ML languages:
match value {
| A
| B
| C => todo!(),
| _ => unimplemented(),
}
The discussion for that RFC was far from unanimous, and there was strong opposition to this change. But as Josh Triplet summarized the discussion:
I'm not seeing any objections to the idea of supporting this in the grammar. I do see some comments about what our recommended style should look like, and in particular whether or not this should replace indentation of match arms. The thing that's causing those two to be conflated is that the RFC's samples all assume a particular style when writing, and not everyone is a fan of that style. As far as I can tell, every objection I've seen is objecting to the indentation style as shown in the RFC, which I wouldn't argue with.
Does anyone object to allowing the optional vert at all? If not, I would propose that we move to accept this, and then separately determine how it might affect the default style.
That is, people were mostly hung up about how Rust code should be ideally formatted, but there were little to no fundamental objections against giving authors this option to format their code more clearly.
In general, I think it's good when a programming languages gives authors the opportunity to express their ideas clearly. On the other hand, such flexibility also gives opportunity to obfuscate the code, and increases the complexity of the language as a whole – Eric Lippert once suggestedthe C# language team had a concept that every (C#) language feature starts with minus 100 points, but the Rust RFC process doesn't follow this philosophy.
Here, the Rust grammar facilitates potential confusion between Smalltalk/Ruby-style closures |arg| expr
, patterns | pat1 | pat2
, and bitwise or logical “or” operators (a | b), (a || b)
. The quoted tweet provides a pathological case of this for Rust, but similar obfuscation is a common pastime in other languages with complex and flexible syntax, such as Perl.