C++ Logo

STD-PROPOSALS

Advanced search

Subject: [std-proposals] Thoughts on fixing the terse lambda issues
From: Михаил Найденов (mihailnajdenov_at_[hidden])
Date: 2020-01-30 06:13:10


Hello, after reading this blog post about the failed abbreviated lambda
attempt https://brevzin.github.io/c++/2020/01/15/abbrev-lambdas/
I wanted to share how I see some possible solutions.

The post cites 3 major issues

   - Differing semantics with regular lambdas
   - Arbitrary lookahead parsing
   - Mismatch between the trailing-return-type and the body

*The first issue *(different return semantics reference vs value) can be
solved by reusing the decltype keyword to mark "return by ref cases"

auto f = [](int const* p) { return *p; } //< Both return by value
auto g = [](int const* p) => *p; //<

auto g = [](int const* p) => decltype *p; //< switch the return type to
const int& (as-if decltype(auto))

Note that in both abbreviated cases, the expression is SFINAE-friendly.
Having decltype is only about return type, not SFINAE tricks

*The second issue* (parsing overhead when types are removed from arguments)
can be solved for lambdas alone relatively easily.

We could introduce arguments *without* parenths.

[] => "Hello"; //< no argument
[] name => "Hello, " + name; //< one argument
[] a, b => a.id() < b.id(); //< two arguments

Should work with body block as well

[] name { auto h = "Hello, "; h += name; return h; };

It will *not* be allowed to have a type-only argument(s), but should be
allowed to have types optionally

[] String greet, name => greet + name; //< OK, type & name and name only
[] String, name => "Hello, " + name; //< FAILS, type only

*The last one*. This issue seems to be only solvable by not "just"
"expanding" the terse
[](auto&& a, auto&& b) => a.id() < b.id();
to a
[](auto&& a, auto&& b) -> decltype((a.id() < b.id())) noexcept(noexcept(a.id()
< b.id())) { return a.id() < b.id(); }

But instead adding explicit wording how the SFINAE would work in
terse-lambda expressions.
In particular, the fact that any identifiers that are not arguments should
be looked up as captures and not as arguments/variables from the enclosing
scope.
In a way this will make SFINAE semantically correct, testing the expression
as in-body, not as arbitrary an expression outside the function/lambda.

Thanks



STD-PROPOSALS list run by std-proposals-owner@lists.isocpp.org

Standard Proposals Archives on Google Groups