On Thu, Feb 27, 2020 at 5:19 AM Михаил Найденов via Std-Proposals <std-proposals@lists.isocpp.org> wrote:
Hello, I am aware of the multiple failed attempts at "abbreviated lambda", summarized here recently. Nevertheless, this feature seems to be too important to abandon and I wanted to share some thoughts I have on the subject.

Ultimately, as far as "terseness" (alone) goes, it is the function argument that are the biggest culprit
[](const auto& a, const auto& b) { return a < b; }

As you can see, if we aim to improve verbosity alone, we should look no further then the params 

With that in mind, I believe we can split the "abbreviated lambda" goal in two tasks - one  for the params and one for the body, assuming the one, regarding the body will be harder because more issues must be solved.

Okay, I buy that. At least I don't find it unbelievable. Divide and conquer: to shorten the whole lambda, first shorten the parameter list, and also, orthogonally, shorten the function body.
However, in your message you showed only the first part (shortening the parameter list). Your proposal can't be "We need to do two things; here's how to do one of them; the other one is harder so I didn't solve it." You need to present a complete solution. Otherwise, we get halfway down the road you selected and we discover that it's a dead end.
 
The only issue, outlined in the blog regarding params is the double parsing - the fact the compiler has to parse until => (if any) to know, if it deals with abbr. params .  
[](a) => ;   //< arg
[](a){};     //< no arg, just void(a) signature

The other problem is, what is the type of `a`?  Should it be considered the same as `auto a`? Same as `auto&& a`?
There are good reasons to dismiss `auto a` for non-trivially-copyable types and therefore pick `auto&& a`.
 
Proposal

Allow lambda arguments to be declared without parentheses.
A single item introduces an argument with that name.

[]a,b { return a < b; }

This way the parser will immediately know with type of param list it deals with.

It will be possible to add a type as well

[]a, auto b { return a < b; } 

The argument list is bound b/w [] and { or mutable or ->

[]{ ... } 
[]a, b { ... } 
[]a, b -> R { ... } 
[=]a, b mutable { ... } 

Or `constexpr` or `noexcept` or any of the other things that can go in the post-parameter-list spot, right?

Think about how this syntax will interact with C++20's explicit template parameters, i.e. how would you express []<class T>(T::type a){} in terse notation?  "You can't use the terse notation for that" is an acceptable answer, but you should be explicit about it.

Think about how this syntax interacts with contextual keywords and similar silliness, and whether you care. (You probably don't.) For example, []final{} becomes a valid expression, as does []mutable{} — the former is a lambda of one argument, and the latter is a lambda of zero arguments.

    template<class T> void foo();
    template<class T> void bar() { foo(T{}); foo([]T{}); }  // both are valid


I see two big reasons to reject this proposal:
(1) It's incomplete. By itself it doesn't solve the problem, and you haven't shown that going down this road will lead us to the other half of the solution.
(2) It shuts doors we are already interested in. Specifically, the syntax []foo is frequently mentioned as a way of "lifting" an overload set into a lambda — that is, []foo should mean roughly [](auto&&... as) noexcept(noexcept(foo(FWD(as)...))) -> decltype(foo(FWD(as)...)) { return foo(FWD(as)...) }.

    std::transform(first, last, []std::toupper);  // OK

If you want to take the syntax []foo {}, you'd better be grabbing it for something that will be better than lifting.  I don't think you are.

–Arthur