This is quite ambiguous since that is also a positive literal integer, not some kind of shorthand lambda. Given my understanding of Rust's preference for unambiguous syntax (cf. turbofish), this won't work as presented and some other syntax will be required. You also have ambiguities with *var for right-hand multiplication (I don't think operator overloads have to abide by commutativity, just precedence orders and they get the default associativity). I suspect this has been discussed before, but I don't have the links myself.
Prelude> :t (+1)
(+1) :: Num a => a -> a
Prelude> :t +1
<interactive>:1:1: error: parse error on input ‘+’
Prelude> :t -1
-1 :: Num a => a
Prelude> :t (-1)
(-1) :: Num a => a
Prelude> :t (- 1)
(- 1) :: Num a => a
It would seem that anything ambiguous is taken to be an integer literal. I don't think that (+1) being a lambda while (-1) is an integer makes me feel happy about it (yes, Haskell has this weird dichotomy, but flip (-) 1 is natural enough there whereas Rust doesn't have anything that concise at hand).
Well, except that the closure is already shorter than that?
flip (-) 1
|x| x - 1
When the closure is short enough for this kind of sugar to be potentially-good, the name for the parameter can also be super-short.
So given that Rust's closure syntax is already quite short, I've never felt that it was worth adding the extra magic for this. It's not like we're old-C# where it was delegate int (int x) { return x - 1; } or old-C++ where it was std::bind2nd(std::minus<int>(), 1) -- both of those languages did add new shorter syntax because the old one was too long.
I quite like Rust's usual preference of explicit vs implicit. |x, y| x + y and |(x, y)| x + y are conveniently explicit. _ + _ is just explicit enough IMO. Anything less than that is too implicit.
I'd really like to see your breakdown of pros and cons of these options. If the only "advantage" of (^) and (1-) is that they save 4 characters then I personally think that is far from sufficient to justify the disadvantages.
I'll note that that could be any of the following:
|x| x + x
|x, y| x + y
|x| |y| x + y
Not to mention that once it's in context it's even less obvious, as one needs to make a rule why foo.map(!_) is foo.map(|x| !x) instead of |x| foo.map(!x).
Now, obviously we could write rules for which one it is, or restrict it to only only one argument, or a variety of other such things. But it's not at all clear to me that the value of omitting the |x| is worth all that complexity.
If you're skeptical of one of those expansions, let me suggest that let squares = (0..n).map(_ * _);looks reasonable.
The big problem with _ + 1 as a shorthand for |x| x + 1 is defining the scope of the closure. What does 1 + _ + 1 act as? Is it 1 + |x| { x + 1 } or |x| { 1 + x + 1 }? What about foo(_)? It could be useful to have that as either |x| { foo(x) } or foo(|x| { x }), and either could be intuited. Consider also bar(1, _).
The consensus the last time this _ closure syntax was discussed is that it's way too (human) ambiguous.
Actually, no, Rust doesn't support + in number literals, nor prefix +. Stable 1.56 gives the unhelpful error
error: expected expression, found `+`
--> src/main.rs:2:13
|
2 | let _ = +1;
| ^ expected expression
but we've improved it in beta 1.57 to the more helpful
error: leading `+` is not supported
--> src/main.rs:2:13
|
2 | let _ = +1;
| ^ unexpected `+`
|
help: try removing the `+`
|
2 - let _ = +1;
2 + let _ = 1;
|
In macros, though, the error is still quite unhelpful
error: no rules expected the token `+`
--> src/main.rs:2:10
|
2 | dbg!(+1);
| ^ no rules expected this token in macro call
and this hints at why this would be a (small, editionable) breaking change: macros can currently match a leading + explicitly just fine, and making it part of the number literal would break such macros.