Date: Fri, 26 Nov 2021 18:44:10 -0300
I have an idea for relaxing lambda syntax
Please, tell me if it´s a non-starter or if it may be something interesting.
1 - Permit lambdas defined only by the capture, making '{}' optional, so auto
x = [a=10, b=20] becomes a valid lambda, and when there is no {} and no
'()' ( parents are already optional ) the data members become public,
permitting access, and avoiding ABI problems with current lambdas.
2 - Also, all constant captures should be initialized thru initializers, in
the lambda_xx internal class, allowing default construction if all captures
are constants.
TLDR Sample:
x = 10;
auto a = [x,y=20];
std::cout << '(' << a.x << ',' << a.y << ')';
Longer version :
1 "Sort of" named parameters:
Sample:
given:
void rect(int x1, int y1, int x2, int y2) {...}
one can make a wrapper:
void rect( auto r ) { rect(r.x1, r.y1, r.x2, r.y2); }
and call like this :
rect( [x2=30,y1=10,x1=10,y2=30] ); // unordered members passed as a
lambda
or even using concepts
template <class T>
concept rect_top_width = requires(T t) {
{ t.top } -> std::same_as<int>; { t.left } -> std::same_as<int>;
{ t.height } -> std::same_as<int>; { t.width } -> std::same_as<int>;
};
template <class T>
concept rect_4ints = requires(T t) {
{ t.x1 } -> std::same_as<int>; { t.y1 } -> std::same_as<int>;
{ t.x2 } -> std::same_as<int>; { t.y2 } -> std::same_as<int>;
};
template <class T>
concept rect_2points = requires(T t) {
{ t.a.x } -> std::same_as<int>; { t.a.y } -> std::same_as<int>;
{ t.b.x } -> std::same_as<int>; { t.b.y } -> std::same_as<int>;
};
one can make different wrappers
void rect( rect_top_width auto r ) { rect(r.left, r.top, r.left +
r.width, r.top + r.height); }
void rect( rect_4ints auto r ) { rect(r.x1, r.y1, r.x2, r.y2); }
void rect( rect_2points auto r ) { rect(r.a.x, r.a.y, r.b.x, r.b.y); }
rect( [height=220,top=30,left=10,width=304] ); // unordered members
rect( [b=[y=10, x=10], a=[x=80,y=80]] ); // unordered members
widget w; // assuming widget has top/left/width/height members
rect( w ); // the function rect(rect_top_width) will be called
struct point { int x, y; };
point a{10, 20}, b{50, 60};
rect( [a,b] ); // one can mimic a 'rectangle' structure without
defining it
2 "Sort of" less harmless ( i hope ) auto-types in structures.
The possibility of a structure like X was proposed, in n3897
<http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n3897.html>
struct X {
auto i = c; // probably not possible in auto-type
auto s = "10"sv;
auto f = 10.8;
auto foo1 = [] (auto p) { return p * 2; };
};
Allowing public member lambdas, and member const initialization:
const int c = 20;
auto x = [i=c,
s="10"sv,
f=10.8,
foo1 = [](auto v) {
return v * 2;
}];
using X = decltype(x); // X should be default constructible now
I would like to use the syntax decltype( [lambda]... ) but due to
unevaluated context problems it's not possible.
Thanks
BR[]
Please, tell me if it´s a non-starter or if it may be something interesting.
1 - Permit lambdas defined only by the capture, making '{}' optional, so auto
x = [a=10, b=20] becomes a valid lambda, and when there is no {} and no
'()' ( parents are already optional ) the data members become public,
permitting access, and avoiding ABI problems with current lambdas.
2 - Also, all constant captures should be initialized thru initializers, in
the lambda_xx internal class, allowing default construction if all captures
are constants.
TLDR Sample:
x = 10;
auto a = [x,y=20];
std::cout << '(' << a.x << ',' << a.y << ')';
Longer version :
1 "Sort of" named parameters:
Sample:
given:
void rect(int x1, int y1, int x2, int y2) {...}
one can make a wrapper:
void rect( auto r ) { rect(r.x1, r.y1, r.x2, r.y2); }
and call like this :
rect( [x2=30,y1=10,x1=10,y2=30] ); // unordered members passed as a
lambda
or even using concepts
template <class T>
concept rect_top_width = requires(T t) {
{ t.top } -> std::same_as<int>; { t.left } -> std::same_as<int>;
{ t.height } -> std::same_as<int>; { t.width } -> std::same_as<int>;
};
template <class T>
concept rect_4ints = requires(T t) {
{ t.x1 } -> std::same_as<int>; { t.y1 } -> std::same_as<int>;
{ t.x2 } -> std::same_as<int>; { t.y2 } -> std::same_as<int>;
};
template <class T>
concept rect_2points = requires(T t) {
{ t.a.x } -> std::same_as<int>; { t.a.y } -> std::same_as<int>;
{ t.b.x } -> std::same_as<int>; { t.b.y } -> std::same_as<int>;
};
one can make different wrappers
void rect( rect_top_width auto r ) { rect(r.left, r.top, r.left +
r.width, r.top + r.height); }
void rect( rect_4ints auto r ) { rect(r.x1, r.y1, r.x2, r.y2); }
void rect( rect_2points auto r ) { rect(r.a.x, r.a.y, r.b.x, r.b.y); }
rect( [height=220,top=30,left=10,width=304] ); // unordered members
rect( [b=[y=10, x=10], a=[x=80,y=80]] ); // unordered members
widget w; // assuming widget has top/left/width/height members
rect( w ); // the function rect(rect_top_width) will be called
struct point { int x, y; };
point a{10, 20}, b{50, 60};
rect( [a,b] ); // one can mimic a 'rectangle' structure without
defining it
2 "Sort of" less harmless ( i hope ) auto-types in structures.
The possibility of a structure like X was proposed, in n3897
<http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n3897.html>
struct X {
auto i = c; // probably not possible in auto-type
auto s = "10"sv;
auto f = 10.8;
auto foo1 = [] (auto p) { return p * 2; };
};
Allowing public member lambdas, and member const initialization:
const int c = 20;
auto x = [i=c,
s="10"sv,
f=10.8,
foo1 = [](auto v) {
return v * 2;
}];
using X = decltype(x); // X should be default constructible now
I would like to use the syntax decltype( [lambda]... ) but due to
unevaluated context problems it's not possible.
Thanks
BR[]
Received on 2021-11-26 15:44:24