Topic: [tuple] extracting tuples out of a tuple
Author: Oliver Kowalke <oliver.kowalke@gmail.com>
Date: Fri, 12 Feb 2016 08:34:36 +0100
Raw View
--089e011762d120f0f8052b8db453
Content-Type: text/plain; charset=UTF-8
In one project I've had the need for extracting tuples from the head/tail
of a given tuple.
Looking at cppreference.com it seams such functions are not part of the
standard yet.
Does a proposal exist that deals with this topic?
I would suggest something like:
std::tuple< int, std::string, std::string, double > tpl{ -1, "abc", "xyz",
..5 };
std::tuple< int, std::string, std::string > tpl1;
std::tuple< std::string, double > tpl2;
head( tpl1) = tpl;
tail( tpl2) = tpl;
split( tpl1, tpl2) = tpl;
Oliver
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-proposals/.
--089e011762d120f0f8052b8db453
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><div><div>In one project I've had the need for extract=
ing <span tabindex=3D"-1" id=3D":1tt.12" style=3D"" class=3D"">tuples</span=
> from the head/tail of a given <span tabindex=3D"-1" id=3D":1tt.13" style=
=3D"" class=3D"">tuple</span>.<br></div><div>Looking at <span tabindex=3D"-=
1" id=3D":1tt.14" style=3D"" class=3D"">cppreference</span>.com it seams su=
ch functions are not part of the standard yet.<br></div><div>Does a proposa=
l exist that deals with this topic?<br></div><div><br></div>I would suggest=
something like:<br></div><div><br>std::<span tabindex=3D"-1" id=3D":1tt.15=
" style=3D"" class=3D"">tuple</span>< int, std::string, std::string, dou=
ble > <span tabindex=3D"-1" id=3D":1tt.16" style=3D"" class=3D"">tpl</sp=
an>{ -1, "<span tabindex=3D"-1" id=3D":1tt.17" style=3D"" class=3D"">a=
bc</span>", "<span tabindex=3D"-1" id=3D":1tt.18" style=3D"" clas=
s=3D"">xyz</span>", .5 };<br>std::<span tabindex=3D"-1" id=3D":1tt.19"=
style=3D"" class=3D"">tuple</span>< int, std::string, std::string > =
tpl1;<br>std::<span tabindex=3D"-1" id=3D":1tt.20" style=3D"" class=3D"">tu=
ple</span>< std::string, double > tpl2;<br><br>head( tpl1) =3D <span =
tabindex=3D"-1" id=3D":1tt.21" style=3D"" class=3D"">tpl</span>;<br>tail( t=
pl2) =3D <span tabindex=3D"-1" id=3D":1tt.22" style=3D"" class=3D"">tpl</sp=
an>;<br></div><div>split( tpl1, tpl2) =3D tpl;<br></div><div><br></div>Oliv=
er<br><div><br></div></div>
<p></p>
-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
Visit this group at <a href=3D"https://groups.google.com/a/isocpp.org/group=
/std-proposals/">https://groups.google.com/a/isocpp.org/group/std-proposals=
/</a>.<br />
--089e011762d120f0f8052b8db453--
.
Author: Matthew Woehlke <mwoehlke.floss@gmail.com>
Date: Fri, 12 Feb 2016 10:06:20 -0500
Raw View
On 2016-02-12 02:34, Oliver Kowalke wrote:
> In one project I've had the need for extracting tuples from the head/tail
> of a given tuple.
> Looking at cppreference.com it seams such functions are not part of the
> standard yet.
> Does a proposal exist that deals with this topic?
>
> I would suggest something like:
>
> std::tuple< int, std::string, std::string, double > tpl{ -1, "abc", "xyz",
> .5 };
> std::tuple< int, std::string, std::string > tpl1;
> std::tuple< std::string, double > tpl2;
>
> head( tpl1) = tpl;
> tail( tpl2) = tpl;
> split( tpl1, tpl2) = tpl;
Here's what *I'd* like:
auto tpl1 = std::make_tuple([:3]tpl...);
auto tpl2 = std::make_tuple([3:]tpl...);
For bonus points, this works on any tuple-*like*, not just std::tuple (I
guess that would be possible with a library solution, but it would make
the implementation rather more complicated, whereas the above requires
no new library features at all).
(Given your prior declarations of `tpl1` and `tpl2`, it may be possible
to do the assignment like `tpl1 = {[:3]tpl...}`.)
I'm not a fan of using magical references to do indirect assignment,
i.e. any of your proposals, but especially `split`. All of these seem
backwards, i.e. should be `tpl1 = head<3>(tpl);` instead.
--
Matthew
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-proposals/.
.
Author: Oliver Kowalke <oliver.kowalke@gmail.com>
Date: Fri, 12 Feb 2016 17:30:59 +0100
Raw View
--089e011602f864ab29052b9532ce
Content-Type: text/plain; charset=UTF-8
2016-02-12 16:06 GMT+01:00 Matthew Woehlke <mwoehlke.floss@gmail.com>:
>
> I'm not a fan of using magical references to do indirect assignment,
> i.e. any of your proposals, but especially `split`. All of these seem
> backwards, i.e. should be `tpl1 = head<3>(tpl);` instead.
>
I've had std::tie() in mind,
int i...;
X x...;
std::tie( i, x) = get_tuple();
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-proposals/.
--089e011602f864ab29052b9532ce
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><div class=3D"gmail_extra"><div class=3D"gmail_quote">2016=
-02-12 16:06 GMT+01:00 Matthew Woehlke <span dir=3D"ltr"><<a href=3D"mai=
lto:mwoehlke.floss@gmail.com" target=3D"_blank">mwoehlke.floss@gmail.com</a=
>></span>:<br><blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8=
ex;border-left:1px #ccc solid;padding-left:1ex"><br>
I'm not a fan of using magical references to do indirect assignment,<br=
>
i.e. any of your proposals, but especially `split`. All of these seem<br>
backwards, i.e. should be `tpl1 =3D head<3>(tpl);` instead.<br></bloc=
kquote></div><br></div><div class=3D"gmail_extra">I've had std::tie() i=
n mind,<br><br></div><div class=3D"gmail_extra">int i...;<br>X x...;<br></d=
iv><div class=3D"gmail_extra">std::tie( i, x) =3D get_tuple();<br></div></d=
iv>
<p></p>
-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
Visit this group at <a href=3D"https://groups.google.com/a/isocpp.org/group=
/std-proposals/">https://groups.google.com/a/isocpp.org/group/std-proposals=
/</a>.<br />
--089e011602f864ab29052b9532ce--
.
Author: Matthew Woehlke <mwoehlke.floss@gmail.com>
Date: Fri, 12 Feb 2016 12:11:24 -0500
Raw View
On 2016-02-12 11:30, Oliver Kowalke wrote:
> 2016-02-12 16:06 GMT+01:00 Matthew Woehlke <mwoehlke.floss@gmail.com>:
>> I'm not a fan of using magical references to do indirect assignment,
>> i.e. any of your proposals, but especially `split`. All of these seem
>> backwards, i.e. should be `tpl1 = head<3>(tpl);` instead.
>
> I've had std::tie() in mind,
>
> int i...;
> X x...;
> std::tie( i, x) = get_tuple();
That's also a horribly ugly interface that we shouldn't be perpetuating;
http://wg21.link/p0144 solves that exact example ever so much better...
At any rate, 'tie' is a much better name for a magic assignment
helper... mainly, because the verb matches the actual action that is
occurring (I could live with 'splice' more than 'split').
--
Matthew
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-proposals/.
.
Author: Arthur O'Dwyer <arthur.j.odwyer@gmail.com>
Date: Fri, 12 Feb 2016 16:28:12 -0800 (PST)
Raw View
------=_Part_1234_442185814.1455323292521
Content-Type: multipart/alternative;
boundary="----=_Part_1235_1903403071.1455323292523"
------=_Part_1235_1903403071.1455323292523
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
On Friday, February 12, 2016 at 9:11:35 AM UTC-8, Matthew Woehlke wrote:
>
> On 2016-02-12 11:30, Oliver Kowalke wrote:=20
> > 2016-02-12 16:06 GMT+01:00 Matthew Woehlke <mwoehlk...@gmail.com=20
> <javascript:>>:=20
> >> I'm not a fan of using magical references to do indirect assignment,=
=20
> >> i.e. any of your proposals, but especially `split`. All of these seem=
=20
> >> backwards, i.e. should be `tpl1 =3D head<3>(tpl);` instead.=20
> >=20
> > I've had std::tie() in mind,=20
> >=20
> > int i...;=20
> > X x...;=20
> > std::tie( i, x) =3D get_tuple();=20
>
> That's also a horribly ugly interface that we shouldn't be perpetuating;=
=20
> http://wg21.link/p0144 solves that exact example ever so much better...=
=20
>
I think maybe Oliver was trying to say that
tuple<int, string, string, double> tpl { -1, "abc", "xyz", .5 };
tuple<string, string, double> tpl1;
tpl1 =3D tail(tpl); // Python: tpl1 =3D tpl[1:]
tail(tpl) =3D tpl1; // Python: tpl[1:] =3D tpl1
should both work, because tail() should return a tuple of references=20
instead of a tuple of values. I definitely support=20
not-making-unnecessary-copies in general, and particularly in this case if=
=20
it lets tail() work like tie(). But it does seem a little bit=20
non-orthogonal. (Also, I'm assuming that Oliver made some typos in his=20
original post =E2=80=94 notice I've flipped the "tpl" and "tpl1" in the sec=
ond line=20
above.)
Also, of course, head(x) should logically return get<0>(x), not some weird=
=20
synonym for reverse(tail(reverse(x))). But that's just poor naming. The=20
underlying operation here is either "splice" (extract a contiguous range of=
=20
indices from the input tuple, as in the Python above) or "select" (extract=
=20
a noncontiguous set of indices from the input tuple and compress them, as=
=20
in various vector instruction sets).
I agree that
std::tuple< int, std::string, std::string, double > tpl{ -1, "abc",=20
"xyz", .5 };
std::tuple< int, std::string, std::string > tpl1;
std::tuple< std::string, double > tpl2;
split( tpl1, tpl2) =3D tpl;
is just nonsense, as written.
However, under the "unpacking with postfix tilde" not-a-proposal, a similar=
=20
operation could be written like this:
tuple<int, string, string, double> tpl { -1, "abc", "xyz", .5 };
tuple<int, string> tpl1;
tuple<string, double> tpl2;
std::tie(tpl1~..., tpl2~...) =3D tpl;
assert(std::get<0>(tpl1) =3D=3D std::get<0>(tpl));
assert(std::get<1>(tpl1) =3D=3D std::get<1>(tpl));
assert(std::get<0>(tpl2) =3D=3D std::get<2>(tpl));
assert(std::get<1>(tpl2) =3D=3D std::get<3>(tpl));
In general, I think that the C++ standard library is woefully lacking in=20
tuple manipulators... but rather than proposing new tuple manipulators (of=
=20
which there could be a million: zip, fold, map, car, cdr, reverse,...), we=
=20
should be trying to give people the ability to express those manipulators=
=20
natively in the language, via something like Matthew's [:] notation or my=
=20
~... notation.
my $.02,
=E2=80=93Arthur
--=20
---=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-propos=
als/.
------=_Part_1235_1903403071.1455323292523
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">On Friday, February 12, 2016 at 9:11:35 AM UTC-8, Matthew =
Woehlke wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-l=
eft: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">On 2016-02-12 11=
:30, Oliver Kowalke wrote:
<br>> 2016-02-12 16:06 GMT+01:00 Matthew Woehlke <<a href=3D"javascri=
pt:" target=3D"_blank" gdf-obfuscated-mailto=3D"ceVKogYTHwAJ" rel=3D"nofoll=
ow" onmousedown=3D"this.href=3D'javascript:';return true;" onclick=
=3D"this.href=3D'javascript:';return true;">mwoehlk...@gmail.com</a=
>>:
<br>>> I'm not a fan of using magical references to do indirect a=
ssignment,
<br>>> i.e. any of your proposals, but especially `split`. All of the=
se seem
<br>>> backwards, i.e. should be `tpl1 =3D head<3>(tpl);` inste=
ad.
<br>>=20
<br>> I've had std::tie() in mind,
<br>>=20
<br>> int i...;
<br>> X x...;
<br>> std::tie( i, x) =3D get_tuple();
<br>
<br>That's also a horribly ugly interface that we shouldn't be perp=
etuating;
<br><a href=3D"http://wg21.link/p0144" target=3D"_blank" rel=3D"nofollow" o=
nmousedown=3D"this.href=3D'http://www.google.com/url?q\75http%3A%2F%2Fw=
g21.link%2Fp0144\46sa\75D\46sntz\0751\46usg\75AFQjCNHRLy3vqbt_AWP1QLZDa6ye8=
6dhPQ';return true;" onclick=3D"this.href=3D'http://www.google.com/=
url?q\75http%3A%2F%2Fwg21.link%2Fp0144\46sa\75D\46sntz\0751\46usg\75AFQjCNH=
RLy3vqbt_AWP1QLZDa6ye86dhPQ';return true;">http://wg21.link/p0144</a> s=
olves that exact example ever so much better...
<br></blockquote><div><br></div><div>I think maybe Oliver was trying to say=
that</div><div><br></div><div class=3D"prettyprint" style=3D"background-co=
lor: rgb(250, 250, 250); border: 1px solid rgb(187, 187, 187); word-wrap: b=
reak-word;"><code class=3D"prettyprint"><div class=3D"subprettyprint"><span=
style=3D"color: #000;" class=3D"styled-by-prettify">=C2=A0 =C2=A0 tuple</s=
pan><span style=3D"color: #660;" class=3D"styled-by-prettify"><</span><s=
pan style=3D"color: #008;" class=3D"styled-by-prettify">int</span><span sty=
le=3D"color: #660;" class=3D"styled-by-prettify">,</span><span style=3D"col=
or: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #008;=
" class=3D"styled-by-prettify">string</span><span style=3D"color: #660;" cl=
ass=3D"styled-by-prettify">,</span><span style=3D"color: #000;" class=3D"st=
yled-by-prettify"> </span><span style=3D"color: #008;" class=3D"styled-by-p=
rettify">string</span><span style=3D"color: #660;" class=3D"styled-by-prett=
ify">,</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </s=
pan><span style=3D"color: #008;" class=3D"styled-by-prettify">double</span>=
<span style=3D"color: #660;" class=3D"styled-by-prettify">></span><span =
style=3D"color: #000;" class=3D"styled-by-prettify"> tpl </span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">{</span><span style=3D"color=
: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #660;" =
class=3D"styled-by-prettify">-</span><span style=3D"color: #066;" class=3D"=
styled-by-prettify">1</span><span style=3D"color: #660;" class=3D"styled-by=
-prettify">,</span><span style=3D"color: #000;" class=3D"styled-by-prettify=
"> </span><span style=3D"color: #080;" class=3D"styled-by-prettify">"a=
bc"</span><span style=3D"color: #660;" class=3D"styled-by-prettify">,<=
/span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><sp=
an style=3D"color: #080;" class=3D"styled-by-prettify">"xyz"</spa=
n><span style=3D"color: #660;" class=3D"styled-by-prettify">,</span><span s=
tyle=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"c=
olor: #660;" class=3D"styled-by-prettify">.</span><span style=3D"color: #06=
6;" class=3D"styled-by-prettify">5</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"> </span><span style=3D"color: #660;" class=3D"style=
d-by-prettify">};</span><span style=3D"color: #000;" class=3D"styled-by-pre=
ttify"><br>=C2=A0 =C2=A0 tuple</span><span style=3D"color: #660;" class=3D"=
styled-by-prettify"><</span><span style=3D"color: #008;" class=3D"styled=
-by-prettify">string</span><span style=3D"color: #660;" class=3D"styled-by-=
prettify">,</span><span style=3D"color: #000;" class=3D"styled-by-prettify"=
> </span><span style=3D"color: #008;" class=3D"styled-by-prettify">string</=
span><span style=3D"color: #660;" class=3D"styled-by-prettify">,</span><spa=
n style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=
=3D"color: #008;" class=3D"styled-by-prettify">double</span><span style=3D"=
color: #660;" class=3D"styled-by-prettify">></span><span style=3D"color:=
#000;" class=3D"styled-by-prettify"> tpl1</span><span style=3D"color: #660=
;" class=3D"styled-by-prettify">;</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"><br>=C2=A0 =C2=A0 tpl1 </span><span style=3D"color:=
#660;" class=3D"styled-by-prettify">=3D</span><span style=3D"color: #000;"=
class=3D"styled-by-prettify"> tail</span><span style=3D"color: #660;" clas=
s=3D"styled-by-prettify">(</span><span style=3D"color: #000;" class=3D"styl=
ed-by-prettify">tpl</span><span style=3D"color: #660;" class=3D"styled-by-p=
rettify">);</span><span style=3D"color: #000;" class=3D"styled-by-prettify"=
> =C2=A0 =C2=A0</span><span style=3D"color: #800;" class=3D"styled-by-prett=
ify">// Python: tpl1 =3D tpl[1:]</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"><br>=C2=A0 =C2=A0 tail</span><span style=3D"color: =
#660;" class=3D"styled-by-prettify">(</span><span style=3D"color: #000;" cl=
ass=3D"styled-by-prettify">tpl</span><span style=3D"color: #660;" class=3D"=
styled-by-prettify">)</span><span style=3D"color: #000;" class=3D"styled-by=
-prettify"> </span><span style=3D"color: #660;" class=3D"styled-by-prettify=
">=3D</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> tpl1=
</span><span style=3D"color: #660;" class=3D"styled-by-prettify">;</span><s=
pan style=3D"color: #000;" class=3D"styled-by-prettify"> =C2=A0 =C2=A0</spa=
n><span style=3D"color: #800;" class=3D"styled-by-prettify">// Python: tpl[=
1:] =3D tpl1</span></div></code></div><div><br></div><div><br></div><div>sh=
ould both work, because tail() should return a tuple of references instead =
of a tuple of values. I definitely support not-making-unnecessary-copies in=
general, and particularly in this case if it lets tail() work like tie(). =
But it does seem a little bit non-orthogonal. =C2=A0(Also, I'm assuming=
that Oliver made some typos in his original post =E2=80=94 notice I've=
flipped the "tpl" and "tpl1" in the second line above.=
)</div><div><br></div><div>Also, of course, head(x) should logically return=
get<0>(x), not some weird synonym for reverse(tail(reverse(x))). But=
that's just poor naming. The underlying operation here is either "=
;splice" (extract a contiguous range of indices from the input tuple, =
as in the Python above) or "select" (extract a noncontiguous set =
of indices from the input tuple and compress them, as in various vector ins=
truction sets).</div><div><br></div><div>I agree that</div><div><br></div><=
div class=3D"prettyprint" style=3D"background-color: rgb(250, 250, 250); bo=
rder: 1px solid rgb(187, 187, 187); word-wrap: break-word;"><code class=3D"=
prettyprint"><div class=3D"subprettyprint"><span style=3D"color: #000;" cla=
ss=3D"styled-by-prettify">=C2=A0 =C2=A0 std</span><span style=3D"color: #66=
0;" class=3D"styled-by-prettify">::</span><span style=3D"color: #000;" clas=
s=3D"styled-by-prettify">tuple</span><span style=3D"color: #660;" class=3D"=
styled-by-prettify"><</span><span style=3D"color: #000;" class=3D"styled=
-by-prettify"> </span><span style=3D"color: #008;" class=3D"styled-by-prett=
ify">int</span><span style=3D"color: #660;" class=3D"styled-by-prettify">,<=
/span><span style=3D"color: #000;" class=3D"styled-by-prettify"> std</span>=
<span style=3D"color: #660;" class=3D"styled-by-prettify">::</span><span st=
yle=3D"color: #008;" class=3D"styled-by-prettify">string</span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">,</span><span style=3D"color=
: #000;" class=3D"styled-by-prettify"> std</span><span style=3D"color: #660=
;" class=3D"styled-by-prettify">::</span><span style=3D"color: #008;" class=
=3D"styled-by-prettify">string</span><span style=3D"color: #660;" class=3D"=
styled-by-prettify">,</span><span style=3D"color: #000;" class=3D"styled-by=
-prettify"> </span><span style=3D"color: #008;" class=3D"styled-by-prettify=
">double</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> <=
/span><span style=3D"color: #660;" class=3D"styled-by-prettify">></span>=
<span style=3D"color: #000;" class=3D"styled-by-prettify"> tpl</span><span =
style=3D"color: #660;" class=3D"styled-by-prettify">{</span><span style=3D"=
color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #6=
60;" class=3D"styled-by-prettify">-</span><span style=3D"color: #066;" clas=
s=3D"styled-by-prettify">1</span><span style=3D"color: #660;" class=3D"styl=
ed-by-prettify">,</span><span style=3D"color: #000;" class=3D"styled-by-pre=
ttify"> </span><span style=3D"color: #080;" class=3D"styled-by-prettify">&q=
uot;abc"</span><span style=3D"color: #660;" class=3D"styled-by-prettif=
y">,</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </spa=
n><span style=3D"color: #080;" class=3D"styled-by-prettify">"xyz"=
</span><span style=3D"color: #660;" class=3D"styled-by-prettify">,</span><s=
pan style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">.</span><span style=3D"color=
: #066;" class=3D"styled-by-prettify">5</span><span style=3D"color: #000;" =
class=3D"styled-by-prettify"> </span><span style=3D"color: #660;" class=3D"=
styled-by-prettify">};</span><span style=3D"color: #000;" class=3D"styled-b=
y-prettify"><br>=C2=A0 =C2=A0 std</span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">::</span><span style=3D"color: #000;" class=3D"styl=
ed-by-prettify">tuple</span><span style=3D"color: #660;" class=3D"styled-by=
-prettify"><</span><span style=3D"color: #000;" class=3D"styled-by-prett=
ify"> </span><span style=3D"color: #008;" class=3D"styled-by-prettify">int<=
/span><span style=3D"color: #660;" class=3D"styled-by-prettify">,</span><sp=
an style=3D"color: #000;" class=3D"styled-by-prettify"> std</span><span sty=
le=3D"color: #660;" class=3D"styled-by-prettify">::</span><span style=3D"co=
lor: #008;" class=3D"styled-by-prettify">string</span><span style=3D"color:=
#660;" class=3D"styled-by-prettify">,</span><span style=3D"color: #000;" c=
lass=3D"styled-by-prettify"> std</span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">::</span><span style=3D"color: #008;" class=3D"styl=
ed-by-prettify">string</span><span style=3D"color: #000;" class=3D"styled-b=
y-prettify"> </span><span style=3D"color: #660;" class=3D"styled-by-prettif=
y">></span><span style=3D"color: #000;" class=3D"styled-by-prettify"> tp=
l1</span><span style=3D"color: #660;" class=3D"styled-by-prettify">;</span>=
<span style=3D"color: #000;" class=3D"styled-by-prettify"><br>=C2=A0 =C2=A0=
std</span><span style=3D"color: #660;" class=3D"styled-by-prettify">::</sp=
an><span style=3D"color: #000;" class=3D"styled-by-prettify">tuple</span><s=
pan style=3D"color: #660;" class=3D"styled-by-prettify"><</span><span st=
yle=3D"color: #000;" class=3D"styled-by-prettify"> std</span><span style=3D=
"color: #660;" class=3D"styled-by-prettify">::</span><span style=3D"color: =
#008;" class=3D"styled-by-prettify">string</span><span style=3D"color: #660=
;" class=3D"styled-by-prettify">,</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"> </span><span style=3D"color: #008;" class=3D"style=
d-by-prettify">double</span><span style=3D"color: #000;" class=3D"styled-by=
-prettify"> </span><span style=3D"color: #660;" class=3D"styled-by-prettify=
">></span><span style=3D"color: #000;" class=3D"styled-by-prettify"> tpl=
2</span><span style=3D"color: #660;" class=3D"styled-by-prettify">;</span><=
span style=3D"color: #000;" class=3D"styled-by-prettify"><br>=C2=A0 =C2=A0 =
split</span><span style=3D"color: #660;" class=3D"styled-by-prettify">(</sp=
an><span style=3D"color: #000;" class=3D"styled-by-prettify"> tpl1</span><s=
pan style=3D"color: #660;" class=3D"styled-by-prettify">,</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"> tpl2</span><span style=3D"c=
olor: #660;" class=3D"styled-by-prettify">)</span><span style=3D"color: #00=
0;" class=3D"styled-by-prettify"> </span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">=3D</span><span style=3D"color: #000;" class=3D"sty=
led-by-prettify"> tpl</span><span style=3D"color: #660;" class=3D"styled-by=
-prettify">;</span></div></code></div><div><br></div><div>is just nonsense,=
as written.</div><div>However, under the "unpacking with postfix tild=
e" not-a-proposal, a similar operation could be written like this:</di=
v><div><br></div><div class=3D"prettyprint" style=3D"background-color: rgb(=
250, 250, 250); border: 1px solid rgb(187, 187, 187); word-wrap: break-word=
;"><code class=3D"prettyprint"><div class=3D"subprettyprint"><span style=3D=
"color: #000;" class=3D"styled-by-prettify">=C2=A0 =C2=A0 tuple</span><span=
style=3D"color: #660;" class=3D"styled-by-prettify"><</span><span style=
=3D"color: #008;" class=3D"styled-by-prettify">int</span><span style=3D"col=
or: #660;" class=3D"styled-by-prettify">,</span><span style=3D"color: #000;=
" class=3D"styled-by-prettify"> </span><span style=3D"color: #008;" class=
=3D"styled-by-prettify">string</span><span style=3D"color: #660;" class=3D"=
styled-by-prettify">,</span><span style=3D"color: #000;" class=3D"styled-by=
-prettify"> </span><span style=3D"color: #008;" class=3D"styled-by-prettify=
">string</span><span style=3D"color: #660;" class=3D"styled-by-prettify">,<=
/span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><sp=
an style=3D"color: #008;" class=3D"styled-by-prettify">double</span><span s=
tyle=3D"color: #660;" class=3D"styled-by-prettify">></span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"> tpl </span><span style=3D"c=
olor: #660;" class=3D"styled-by-prettify">{</span><span style=3D"color: #00=
0;" class=3D"styled-by-prettify"> </span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">-</span><span style=3D"color: #066;" class=3D"style=
d-by-prettify">1</span><span style=3D"color: #660;" class=3D"styled-by-pret=
tify">,</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </=
span><span style=3D"color: #080;" class=3D"styled-by-prettify">"abc&qu=
ot;</span><span style=3D"color: #660;" class=3D"styled-by-prettify">,</span=
><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span st=
yle=3D"color: #080;" class=3D"styled-by-prettify">"xyz"</span><sp=
an style=3D"color: #660;" class=3D"styled-by-prettify">,</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color=
: #660;" class=3D"styled-by-prettify">.</span><span style=3D"color: #066;" =
class=3D"styled-by-prettify">5</span><span style=3D"color: #000;" class=3D"=
styled-by-prettify"> </span><span style=3D"color: #660;" class=3D"styled-by=
-prettify">};</span><span style=3D"color: #000;" class=3D"styled-by-prettif=
y"><br>=C2=A0 =C2=A0 tuple</span><span style=3D"color: #660;" class=3D"styl=
ed-by-prettify"><</span><span style=3D"color: #008;" class=3D"styled-by-=
prettify">int</span><span style=3D"color: #660;" class=3D"styled-by-prettif=
y">,</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </spa=
n><span style=3D"color: #008;" class=3D"styled-by-prettify">string</span><s=
pan style=3D"color: #660;" class=3D"styled-by-prettify">></span><span st=
yle=3D"color: #000;" class=3D"styled-by-prettify"> tpl1</span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">;</span><span style=3D"color=
: #000;" class=3D"styled-by-prettify"><br>=C2=A0 =C2=A0 tuple</span><span s=
tyle=3D"color: #660;" class=3D"styled-by-prettify"><</span><span style=
=3D"color: #008;" class=3D"styled-by-prettify">string</span><span style=3D"=
color: #660;" class=3D"styled-by-prettify">,</span><span style=3D"color: #0=
00;" class=3D"styled-by-prettify"> </span><span style=3D"color: #008;" clas=
s=3D"styled-by-prettify">double</span><span style=3D"color: #660;" class=3D=
"styled-by-prettify">></span><span style=3D"color: #000;" class=3D"style=
d-by-prettify"> tpl2</span><span style=3D"color: #660;" class=3D"styled-by-=
prettify">;</span><span style=3D"color: #000;" class=3D"styled-by-prettify"=
><br><br>=C2=A0 =C2=A0 std</span><span style=3D"color: #660;" class=3D"styl=
ed-by-prettify">::</span><span style=3D"color: #000;" class=3D"styled-by-pr=
ettify">tie</span><span style=3D"color: #660;" class=3D"styled-by-prettify"=
>(</span><span style=3D"color: #000;" class=3D"styled-by-prettify">tpl1</sp=
an><span style=3D"color: #660;" class=3D"styled-by-prettify">~...,</span><s=
pan style=3D"color: #000;" class=3D"styled-by-prettify"> tpl2</span><span s=
tyle=3D"color: #660;" class=3D"styled-by-prettify">~...)</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color=
: #660;" class=3D"styled-by-prettify">=3D</span><span style=3D"color: #000;=
" class=3D"styled-by-prettify"> tpl</span><span style=3D"color: #660;" clas=
s=3D"styled-by-prettify">;</span><span style=3D"color: #000;" class=3D"styl=
ed-by-prettify"><br><br>=C2=A0 =C2=A0 </span><span style=3D"color: #008;" c=
lass=3D"styled-by-prettify">assert</span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">(</span><span style=3D"color: #000;" class=3D"style=
d-by-prettify">std</span><span style=3D"color: #660;" class=3D"styled-by-pr=
ettify">::</span><span style=3D"color: #008;" class=3D"styled-by-prettify">=
get</span><span style=3D"color: #660;" class=3D"styled-by-prettify"><</s=
pan><span style=3D"color: #066;" class=3D"styled-by-prettify">0</span><span=
style=3D"color: #660;" class=3D"styled-by-prettify">>(</span><span styl=
e=3D"color: #000;" class=3D"styled-by-prettify">tpl1</span><span style=3D"c=
olor: #660;" class=3D"styled-by-prettify">)</span><span style=3D"color: #00=
0;" class=3D"styled-by-prettify"> </span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">=3D=3D</span><span style=3D"color: #000;" class=3D"=
styled-by-prettify"> std</span><span style=3D"color: #660;" class=3D"styled=
-by-prettify">::</span><span style=3D"color: #008;" class=3D"styled-by-pret=
tify">get</span><span style=3D"color: #660;" class=3D"styled-by-prettify">&=
lt;</span><span style=3D"color: #066;" class=3D"styled-by-prettify">0</span=
><span style=3D"color: #660;" class=3D"styled-by-prettify">>(</span><spa=
n style=3D"color: #000;" class=3D"styled-by-prettify">tpl</span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">));</span><span style=3D"col=
or: #000;" class=3D"styled-by-prettify"><br>=C2=A0 =C2=A0 </span><span styl=
e=3D"color: #008;" class=3D"styled-by-prettify">assert</span><span style=3D=
"color: #660;" class=3D"styled-by-prettify">(</span><span style=3D"color: #=
000;" class=3D"styled-by-prettify">std</span><span style=3D"color: #660;" c=
lass=3D"styled-by-prettify">::</span><span style=3D"color: #008;" class=3D"=
styled-by-prettify">get</span><span style=3D"color: #660;" class=3D"styled-=
by-prettify"><</span><span style=3D"color: #066;" class=3D"styled-by-pre=
ttify">1</span><span style=3D"color: #660;" class=3D"styled-by-prettify">&g=
t;(</span><span style=3D"color: #000;" class=3D"styled-by-prettify">tpl1</s=
pan><span style=3D"color: #660;" class=3D"styled-by-prettify">)</span><span=
style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D=
"color: #660;" class=3D"styled-by-prettify">=3D=3D</span><span style=3D"col=
or: #000;" class=3D"styled-by-prettify"> std</span><span style=3D"color: #6=
60;" class=3D"styled-by-prettify">::</span><span style=3D"color: #008;" cla=
ss=3D"styled-by-prettify">get</span><span style=3D"color: #660;" class=3D"s=
tyled-by-prettify"><</span><span style=3D"color: #066;" class=3D"styled-=
by-prettify">1</span><span style=3D"color: #660;" class=3D"styled-by-pretti=
fy">>(</span><span style=3D"color: #000;" class=3D"styled-by-prettify">t=
pl</span><span style=3D"color: #660;" class=3D"styled-by-prettify">));</spa=
n><span style=3D"color: #000;" class=3D"styled-by-prettify"><br>=C2=A0 =C2=
=A0 </span><span style=3D"color: #008;" class=3D"styled-by-prettify">assert=
</span><span style=3D"color: #660;" class=3D"styled-by-prettify">(</span><s=
pan style=3D"color: #000;" class=3D"styled-by-prettify">std</span><span sty=
le=3D"color: #660;" class=3D"styled-by-prettify">::</span><span style=3D"co=
lor: #008;" class=3D"styled-by-prettify">get</span><span style=3D"color: #6=
60;" class=3D"styled-by-prettify"><</span><span style=3D"color: #066;" c=
lass=3D"styled-by-prettify">0</span><span style=3D"color: #660;" class=3D"s=
tyled-by-prettify">>(</span><span style=3D"color: #000;" class=3D"styled=
-by-prettify">tpl2</span><span style=3D"color: #660;" class=3D"styled-by-pr=
ettify">)</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> =
</span><span style=3D"color: #660;" class=3D"styled-by-prettify">=3D=3D</sp=
an><span style=3D"color: #000;" class=3D"styled-by-prettify"> std</span><sp=
an style=3D"color: #660;" class=3D"styled-by-prettify">::</span><span style=
=3D"color: #008;" class=3D"styled-by-prettify">get</span><span style=3D"col=
or: #660;" class=3D"styled-by-prettify"><</span><span style=3D"color: #0=
66;" class=3D"styled-by-prettify">2</span><span style=3D"color: #660;" clas=
s=3D"styled-by-prettify">>(</span><span style=3D"color: #000;" class=3D"=
styled-by-prettify">tpl</span><span style=3D"color: #660;" class=3D"styled-=
by-prettify">));</span><span style=3D"color: #000;" class=3D"styled-by-pret=
tify"><br>=C2=A0 =C2=A0 </span><span style=3D"color: #008;" class=3D"styled=
-by-prettify">assert</span><span style=3D"color: #660;" class=3D"styled-by-=
prettify">(</span><span style=3D"color: #000;" class=3D"styled-by-prettify"=
>std</span><span style=3D"color: #660;" class=3D"styled-by-prettify">::</sp=
an><span style=3D"color: #008;" class=3D"styled-by-prettify">get</span><spa=
n style=3D"color: #660;" class=3D"styled-by-prettify"><</span><span styl=
e=3D"color: #066;" class=3D"styled-by-prettify">1</span><span style=3D"colo=
r: #660;" class=3D"styled-by-prettify">>(</span><span style=3D"color: #0=
00;" class=3D"styled-by-prettify">tpl2</span><span style=3D"color: #660;" c=
lass=3D"styled-by-prettify">)</span><span style=3D"color: #000;" class=3D"s=
tyled-by-prettify"> </span><span style=3D"color: #660;" class=3D"styled-by-=
prettify">=3D=3D</span><span style=3D"color: #000;" class=3D"styled-by-pret=
tify"> std</span><span style=3D"color: #660;" class=3D"styled-by-prettify">=
::</span><span style=3D"color: #008;" class=3D"styled-by-prettify">get</spa=
n><span style=3D"color: #660;" class=3D"styled-by-prettify"><</span><spa=
n style=3D"color: #066;" class=3D"styled-by-prettify">3</span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">>(</span><span style=3D"c=
olor: #000;" class=3D"styled-by-prettify">tpl</span><span style=3D"color: #=
660;" class=3D"styled-by-prettify">));</span></div></code></div><div><div><=
br></div></div><div>In general, I think that the C++ standard library is wo=
efully lacking in tuple manipulators... but rather than proposing new tuple=
manipulators (of which there could be a million: zip, fold, map, car, cdr,=
reverse,...), we should be trying to give people the ability to express th=
ose manipulators natively in the language, via something like Matthew's=
[:] notation or my ~... notation.</div><div><br></div><div>my $.02,</div><=
div>=E2=80=93Arthur</div></div>
<p></p>
-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
Visit this group at <a href=3D"https://groups.google.com/a/isocpp.org/group=
/std-proposals/">https://groups.google.com/a/isocpp.org/group/std-proposals=
/</a>.<br />
------=_Part_1235_1903403071.1455323292523--
------=_Part_1234_442185814.1455323292521--
.
Author: Oliver Kowalke <oliver.kowalke@gmail.com>
Date: Sat, 13 Feb 2016 09:44:57 +0100
Raw View
--089e013a089692b6ea052ba2cd89
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
016-02-13 1:28 GMT+01:00 Arthur O'Dwyer <arthur.j.odwyer@gmail.com>:
> (Also, I'm assuming that Oliver made some typos in his original post =E2=
=80=94
> notice I've flipped the "tpl" and "tpl1" in the second line above.)
>
correct
> Also, of course, head(x) should logically return get<0>(x), not some weir=
d
> synonym for reverse(tail(reverse(x))).
>
head(x) should return the part from the source tuple's head that fits into
tuple x, same applies to tail(x)
> But that's just poor naming. The underlying operation here is either
> "splice"
>
I'm only interested in the functionality, not in the naming. One of my
project requires such functionality and I was wondering that neither the
standard
provides such manipulators nor could I find a proposal.
tuple ~... and tuple [:] require a language modification - but I need a
solution now; so I've written head()/tail() (even if the naming is not
perfect).
--=20
---=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-propos=
als/.
--089e013a089692b6ea052ba2cd89
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><div class=3D"gmail_extra"><div class=3D"gmail_quote">016-=
02-13 1:28 GMT+01:00 Arthur O'Dwyer <span dir=3D"ltr"><<a href=3D"ma=
ilto:arthur.j.odwyer@gmail.com" target=3D"_blank">arthur.j.odwyer@gmail.com=
</a>></span>:<br><blockquote class=3D"gmail_quote" style=3D"margin:0px 0=
px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div =
dir=3D"ltr"><span class=3D""></span> (Also, I'm assuming that Oliver ma=
de some typos in his original post =E2=80=94 notice I've flipped the &q=
uot;tpl" and "tpl1" in the second line above.)</div></blockq=
uote><div><br></div><div>correct<br></div><div>=C2=A0</div><blockquote clas=
s=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;border-left:1px solid r=
gb(204,204,204);padding-left:1ex"><div dir=3D"ltr"><div></div><div>Also, of=
course, head(x) should logically return get<0>(x), not some weird sy=
nonym for reverse(tail(reverse(x))). </div></div></blockquote><div><br></di=
v><div>head(x) should return the part from the source tuple's head that=
fits into tuple x, same applies to tail(x)<br></div><div>=C2=A0</div><bloc=
kquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;border-left:=
1px solid rgb(204,204,204);padding-left:1ex"><div dir=3D"ltr"><div>But that=
's just poor naming. The underlying operation here is either "spli=
ce"<br></div></div></blockquote></div><br></div><div class=3D"gmail_ex=
tra">I'm only interested in the functionality, not in the naming. One o=
f my project requires such functionality and I was wondering that neither t=
he standard<br></div><div class=3D"gmail_extra">provides such manipulators =
nor could I find a proposal.<br><span style=3D"font-family:arial,helvetica,=
sans-serif"><br></span></div><div class=3D"gmail_extra"><span style=3D"font=
-family:arial,helvetica,sans-serif">tuple ~... and tu</span><code><span sty=
le=3D"font-family:arial,helvetica,sans-serif">ple [:] require a language mo=
dification - but I need a solution now; so I've written head()/tail() (=
even if the naming is not perfect).</span><span style=3D"color:rgb(136,0,0)=
"></span></code></div></div>
<p></p>
-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
Visit this group at <a href=3D"https://groups.google.com/a/isocpp.org/group=
/std-proposals/">https://groups.google.com/a/isocpp.org/group/std-proposals=
/</a>.<br />
--089e013a089692b6ea052ba2cd89--
.
Author: "Vicente J. Botet Escriba" <vicente.botet@wanadoo.fr>
Date: Sat, 13 Feb 2016 10:06:46 +0100
Raw View
This is a multi-part message in MIME format.
--------------090706040204090900080905
Content-Type: text/plain; charset=UTF-8; format=flowed
Content-Transfer-Encoding: quoted-printable
Le 13/02/2016 01:28, Arthur O'Dwyer a =C3=A9crit :
> On Friday, February 12, 2016 at 9:11:35 AM UTC-8, Matthew Woehlke wrote:
>
> On 2016-02-12 11:30, Oliver Kowalke wrote:
> > 2016-02-12 16:06 GMT+01:00 Matthew Woehlke <mwoehlk...@gmail.com
> <javascript:>>:
> >> I'm not a fan of using magical references to do indirect
> assignment,
> >> i.e. any of your proposals, but especially `split`. All of
> these seem
> >> backwards, i.e. should be `tpl1 =3D head<3>(tpl);` instead.
> >
> > I've had std::tie() in mind,
> >
> > int i...;
> > X x...;
> > std::tie( i, x) =3D get_tuple();
>
> That's also a horribly ugly interface that we shouldn't be
> perpetuating;
> http://wg21.link/p0144 solves that exact example ever so much
> better...
>
>
> I think maybe Oliver was trying to say that
>
> |
> tuple<int,string,string,double>tpl {-1,"abc","xyz",.5};
> tuple<string,string,double>tpl1;
> tpl1 =3Dtail(tpl);// Python: tpl1 =3D tpl[1:]
> tail(tpl)=3Dtpl1;// Python: tpl[1:] =3D tpl1
> |
>
>
> should both work, because tail() should return a tuple of references=20
> instead of a tuple of values. I definitely support=20
> not-making-unnecessary-copies in general, and particularly in this=20
> case if it lets tail() work like tie(). But it does seem a little bit=20
> non-orthogonal. (Also, I'm assuming that Oliver made some typos in=20
> his original post =E2=80=94 notice I've flipped the "tpl" and "tpl1" in t=
he=20
> second line above.)
>
I don't think Oliver made some typos, but it is up to him to confirm.=20
Anyway the name was not good.
std::tuple< int, std::string, std::string, double > tpl{ -1, "abc",=20
"xyz", .5 };
std::tuple< int, std::string, std::string > tpl1;
std::tuple< std::string, double > tpl2;
head( tpl1) =3D tpl;
tail( tpl2) =3D tpl;
split( tpl1, tpl2) =3D tpl;
head(tpl1) returns a reference to tuple that accepts assignment form=20
tuples having the same types from the front and
tail(tpl2) do the opposite, returns a reference to tuple that accepts=20
assignments form tuples having the same types from the back.
head->tie_tuple_at_front
tail->tie_tuple_at_back
It could also be a tie_tuple_at_middle that accepts assignment form=20
tuples having the same types from a unspecified position.
My names are not good neither.
I believe that his split pretended to be a equivalent to his
head( tpl1) =3D tpl;
tail( tpl2) =3D tpl;
but I don't see the added value.
Whether it is worth having this in the standard and looking for a good=20
names is another question.
> Also, of course, head(x) should logically return get<0>(x), not some=20
> weird synonym for reverse(tail(reverse(x))). But that's just poor=20
> naming. The underlying operation here is either "splice" (extract a=20
> contiguous range of indices from the input tuple, as in the Python=20
> above) or "select" (extract a noncontiguous set of indices from the=20
> input tuple and compress them, as in various vector instruction sets).
I'm not saying that a splice function on tuples is not useful, but IMHO=20
Oliver idea was to determine the splice to do depending on the target=20
tuple not on the source tuple.
>
> I agree that
>
> |
> std::tuple<int,std::string,std::string,double>tpl{-1,"abc","xyz",.5};
> std::tuple<int,std::string,std::string>tpl1;
> std::tuple<std::string,double>tpl2;
> split(tpl1,tpl2)=3Dtpl;
> |
>
> is just nonsense, as written.
See above.
> However, under the "unpacking with postfix tilde" not-a-proposal, a=20
> similar operation could be written like this:
>
> |
> tuple<int,string,string,double>tpl {-1,"abc","xyz",.5};
> tuple<int,string>tpl1;
> tuple<string,double>tpl2;
>
> std::tie(tpl1~...,tpl2~...)=3Dtpl;
>
> assert(std::get<0>(tpl1)=3D=3Dstd::get<0>(tpl));
> assert(std::get<1>(tpl1)=3D=3Dstd::get<1>(tpl));
> assert(std::get<0>(tpl2)=3D=3Dstd::get<2>(tpl));
> assert(std::get<1>(tpl2)=3D=3Dstd::get<3>(tpl));
> |
>
> In general, I think that the C++ standard library is woefully lacking=20
> in tuple manipulators... but rather than proposing new tuple=20
> manipulators (of which there could be a million: zip, fold, map, car,=20
> cdr, reverse,...), we should be trying to give people the ability to=20
> express those manipulators natively in the language, via something=20
> like Matthew's [:] notation or my ~... notation.
>
>
Just wondering how could help the no-yet-proposed operators [:], ~,=20
and ... to implement what I interpreted.
Vicente
--=20
---=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-propos=
als/.
--------------090706040204090900080905
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<html>
<head>
<meta content=3D"text/html; charset=3Dutf-8" http-equiv=3D"Content-Type=
">
</head>
<body bgcolor=3D"#FFFFFF" text=3D"#000000">
<div class=3D"moz-cite-prefix">Le 13/02/2016 01:28, Arthur O'Dwyer a
=C3=A9crit=C2=A0:<br>
</div>
<blockquote
cite=3D"mid:7e08b6c5-853c-471e-b248-a9df7e8e27be@isocpp.org"
type=3D"cite">
<div dir=3D"ltr">On Friday, February 12, 2016 at 9:11:35 AM UTC-8,
Matthew Woehlke wrote:
<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left:
0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">On
2016-02-12 11:30, Oliver Kowalke wrote:
<br>
> 2016-02-12 16:06 GMT+01:00 Matthew Woehlke <<a
moz-do-not-send=3D"true" href=3D"javascript:" target=3D"_blank"
gdf-obfuscated-mailto=3D"ceVKogYTHwAJ" rel=3D"nofollow"
onmousedown=3D"this.href=3D'javascript:';return true;"
onclick=3D"this.href=3D'javascript:';return true;"><a class=3D"=
moz-txt-link-abbreviated" href=3D"mailto:mwoehlk...@gmail.com">mwoehlk...@g=
mail.com</a></a>>:
<br>
>> I'm not a fan of using magical references to do
indirect assignment,
<br>
>> i.e. any of your proposals, but especially `split`.
All of these seem
<br>
>> backwards, i.e. should be `tpl1 =3D
head<3>(tpl);` instead.
<br>
> <br>
> I've had std::tie() in mind,
<br>
> <br>
> int i...;
<br>
> X x...;
<br>
> std::tie( i, x) =3D get_tuple();
<br>
<br>
That's also a horribly ugly interface that we shouldn't be
perpetuating;
<br>
<a moz-do-not-send=3D"true" href=3D"http://wg21.link/p0144"
target=3D"_blank" rel=3D"nofollow"
onmousedown=3D"this.href=3D'http://www.google.com/url?q\75http%=
3A%2F%2Fwg21.link%2Fp0144\46sa\75D\46sntz\0751\46usg\75AFQjCNHRLy3vqbt_AWP1=
QLZDa6ye86dhPQ';return
true;"
onclick=3D"this.href=3D'http://www.google.com/url?q\75http%3A%2=
F%2Fwg21.link%2Fp0144\46sa\75D\46sntz\0751\46usg\75AFQjCNHRLy3vqbt_AWP1QLZD=
a6ye86dhPQ';return
true;">http://wg21.link/p0144</a> solves that exact example
ever so much better...
<br>
</blockquote>
<div><br>
</div>
<div>I think maybe Oliver was trying to say that</div>
<div><br>
</div>
<div class=3D"prettyprint" style=3D"background-color: rgb(250, 250,
250); border: 1px solid rgb(187, 187, 187); word-wrap:
break-word;"><code class=3D"prettyprint">
<div class=3D"subprettyprint"><span style=3D"color: #000;"
class=3D"styled-by-prettify">=C2=A0 =C2=A0 tuple</span><spa=
n
style=3D"color: #660;" class=3D"styled-by-prettify"><</s=
pan><span
style=3D"color: #008;" class=3D"styled-by-prettify">int</sp=
an><span
style=3D"color: #660;" class=3D"styled-by-prettify">,</span=
><span
style=3D"color: #000;" class=3D"styled-by-prettify"> </span=
><span
style=3D"color: #008;" class=3D"styled-by-prettify">string<=
/span><span
style=3D"color: #660;" class=3D"styled-by-prettify">,</span=
><span
style=3D"color: #000;" class=3D"styled-by-prettify"> </span=
><span
style=3D"color: #008;" class=3D"styled-by-prettify">string<=
/span><span
style=3D"color: #660;" class=3D"styled-by-prettify">,</span=
><span
style=3D"color: #000;" class=3D"styled-by-prettify"> </span=
><span
style=3D"color: #008;" class=3D"styled-by-prettify">double<=
/span><span
style=3D"color: #660;" class=3D"styled-by-prettify">></s=
pan><span
style=3D"color: #000;" class=3D"styled-by-prettify"> tpl </=
span><span
style=3D"color: #660;" class=3D"styled-by-prettify">{</span=
><span
style=3D"color: #000;" class=3D"styled-by-prettify"> </span=
><span
style=3D"color: #660;" class=3D"styled-by-prettify">-</span=
><span
style=3D"color: #066;" class=3D"styled-by-prettify">1</span=
><span
style=3D"color: #660;" class=3D"styled-by-prettify">,</span=
><span
style=3D"color: #000;" class=3D"styled-by-prettify"> </span=
><span
style=3D"color: #080;" class=3D"styled-by-prettify">"abc"</=
span><span
style=3D"color: #660;" class=3D"styled-by-prettify">,</span=
><span
style=3D"color: #000;" class=3D"styled-by-prettify"> </span=
><span
style=3D"color: #080;" class=3D"styled-by-prettify">"xyz"</=
span><span
style=3D"color: #660;" class=3D"styled-by-prettify">,</span=
><span
style=3D"color: #000;" class=3D"styled-by-prettify"> </span=
><span
style=3D"color: #660;" class=3D"styled-by-prettify">.</span=
><span
style=3D"color: #066;" class=3D"styled-by-prettify">5</span=
><span
style=3D"color: #000;" class=3D"styled-by-prettify"> </span=
><span
style=3D"color: #660;" class=3D"styled-by-prettify">};</spa=
n><span
style=3D"color: #000;" class=3D"styled-by-prettify"><br>
=C2=A0 =C2=A0 tuple</span><span style=3D"color: #660;"
class=3D"styled-by-prettify"><</span><span
style=3D"color: #008;" class=3D"styled-by-prettify">string<=
/span><span
style=3D"color: #660;" class=3D"styled-by-prettify">,</span=
><span
style=3D"color: #000;" class=3D"styled-by-prettify"> </span=
><span
style=3D"color: #008;" class=3D"styled-by-prettify">string<=
/span><span
style=3D"color: #660;" class=3D"styled-by-prettify">,</span=
><span
style=3D"color: #000;" class=3D"styled-by-prettify"> </span=
><span
style=3D"color: #008;" class=3D"styled-by-prettify">double<=
/span><span
style=3D"color: #660;" class=3D"styled-by-prettify">></s=
pan><span
style=3D"color: #000;" class=3D"styled-by-prettify"> tpl1</=
span><span
style=3D"color: #660;" class=3D"styled-by-prettify">;</span=
><span
style=3D"color: #000;" class=3D"styled-by-prettify"><br>
=C2=A0 =C2=A0 tpl1 </span><span style=3D"color: #660;"
class=3D"styled-by-prettify">=3D</span><span style=3D"color=
:
#000;" class=3D"styled-by-prettify"> tail</span><span
style=3D"color: #660;" class=3D"styled-by-prettify">(</span=
><span
style=3D"color: #000;" class=3D"styled-by-prettify">tpl</sp=
an><span
style=3D"color: #660;" class=3D"styled-by-prettify">);</spa=
n><span
style=3D"color: #000;" class=3D"styled-by-prettify"> =C2=A0=
=C2=A0</span><span
style=3D"color: #800;" class=3D"styled-by-prettify">//
Python: tpl1 =3D tpl[1:]</span><span style=3D"color: #000;"
class=3D"styled-by-prettify"><br>
=C2=A0 =C2=A0 tail</span><span style=3D"color: #660;"
class=3D"styled-by-prettify">(</span><span style=3D"color:
#000;" class=3D"styled-by-prettify">tpl</span><span
style=3D"color: #660;" class=3D"styled-by-prettify">)</span=
><span
style=3D"color: #000;" class=3D"styled-by-prettify"> </span=
><span
style=3D"color: #660;" class=3D"styled-by-prettify">=3D</sp=
an><span
style=3D"color: #000;" class=3D"styled-by-prettify"> tpl1</=
span><span
style=3D"color: #660;" class=3D"styled-by-prettify">;</span=
><span
style=3D"color: #000;" class=3D"styled-by-prettify"> =C2=A0=
=C2=A0</span><span
style=3D"color: #800;" class=3D"styled-by-prettify">//
Python: tpl[1:] =3D tpl1</span></div>
</code></div>
<div><br>
</div>
<div><br>
</div>
<div>should both work, because tail() should return a tuple of
references instead of a tuple of values. I definitely support
not-making-unnecessary-copies in general, and particularly in
this case if it lets tail() work like tie(). But it does seem
a little bit non-orthogonal. =C2=A0(Also, I'm assuming that Olive=
r
made some typos in his original post =E2=80=94 notice I've flippe=
d the
"tpl" and "tpl1" in the second line above.)</div>
<div><br>
</div>
</div>
</blockquote>
I don't think Oliver made some typos, but it is up to him to
confirm. Anyway the name was not good.<br>
<br>
std::<span tabindex=3D"-1" id=3D":1tt.15" style=3D"" class=3D"">tuple</=
span><
int, std::string, std::string, double > <span tabindex=3D"-1"
id=3D":1tt.16" style=3D"" class=3D"">tpl</span>{ -1, "<span
tabindex=3D"-1" id=3D":1tt.17" style=3D"" class=3D"">abc</span>", "<s=
pan
tabindex=3D"-1" id=3D":1tt.18" style=3D"" class=3D"">xyz</span>", .5 =
};<br>
std::<span tabindex=3D"-1" id=3D":1tt.19" style=3D"" class=3D"">tuple</=
span><
int, std::string, std::string > tpl1;<br>
std::<span tabindex=3D"-1" id=3D":1tt.20" style=3D"" class=3D"">tuple</=
span><
std::string, double > tpl2;<br>
<br>
head( tpl1) =3D <span tabindex=3D"-1" id=3D":1tt.21" style=3D"" class=
=3D"">tpl</span>;<br>
tail( tpl2) =3D <span tabindex=3D"-1" id=3D":1tt.22" style=3D"" class=
=3D"">tpl</span>;<br>
split( tpl1, tpl2) =3D tpl;<br>
<br>
head(tpl1) returns a reference to tuple that accepts assignment form
tuples having the same types from the front and <br>
tail(tpl2) do the opposite, returns a reference to tuple that
accepts assignments form tuples having the same types from the back.<br=
>
<br>
head->tie_tuple_at_front<br>
tail->tie_tuple_at_back<br>
<br>
It could also be a tie_tuple_at_middle that accepts assignment form
tuples having the same types from a unspecified position.<br>
<br>
My names are not good neither.<br>
<br>
I believe that his split pretended to be a equivalent to his<br>
<br>
head( tpl1) =3D <span tabindex=3D"-1" id=3D":1tt.21" style=3D"" class=
=3D"">tpl</span>;<br>
tail( tpl2) =3D <span tabindex=3D"-1" id=3D":1tt.22" style=3D"" class=
=3D"">tpl</span>;<br>
<br>
but I don't see the added value. <br>
<br>
Whether it is worth having this in the standard and looking for a
good names is another question.<br>
<br>
<br>
<br>
<blockquote
cite=3D"mid:7e08b6c5-853c-471e-b248-a9df7e8e27be@isocpp.org"
type=3D"cite">
<div dir=3D"ltr">
<div>Also, of course, head(x) should logically return
get<0>(x), not some weird synonym for
reverse(tail(reverse(x))). But that's just poor naming. The
underlying operation here is either "splice" (extract a
contiguous range of indices from the input tuple, as in the
Python above) or "select" (extract a noncontiguous set of
indices from the input tuple and compress them, as in various
vector instruction sets).</div>
</div>
</blockquote>
I'm not saying that a splice function on tuples is not useful, but
IMHO Oliver idea was to determine the splice to do depending on the
target tuple not on the source tuple.<br>
<br>
<blockquote
cite=3D"mid:7e08b6c5-853c-471e-b248-a9df7e8e27be@isocpp.org"
type=3D"cite">
<div dir=3D"ltr">
<div><br>
</div>
<div>I agree that</div>
<div><br>
</div>
<div class=3D"prettyprint" style=3D"background-color: rgb(250, 250,
250); border: 1px solid rgb(187, 187, 187); word-wrap:
break-word;"><code class=3D"prettyprint">
<div class=3D"subprettyprint"><span style=3D"color: #000;"
class=3D"styled-by-prettify">=C2=A0 =C2=A0 std</span><span
style=3D"color: #660;" class=3D"styled-by-prettify">::</spa=
n><span
style=3D"color: #000;" class=3D"styled-by-prettify">tuple</=
span><span
style=3D"color: #660;" class=3D"styled-by-prettify"><</s=
pan><span
style=3D"color: #000;" class=3D"styled-by-prettify"> </span=
><span
style=3D"color: #008;" class=3D"styled-by-prettify">int</sp=
an><span
style=3D"color: #660;" class=3D"styled-by-prettify">,</span=
><span
style=3D"color: #000;" class=3D"styled-by-prettify"> std</s=
pan><span
style=3D"color: #660;" class=3D"styled-by-prettify">::</spa=
n><span
style=3D"color: #008;" class=3D"styled-by-prettify">string<=
/span><span
style=3D"color: #660;" class=3D"styled-by-prettify">,</span=
><span
style=3D"color: #000;" class=3D"styled-by-prettify"> std</s=
pan><span
style=3D"color: #660;" class=3D"styled-by-prettify">::</spa=
n><span
style=3D"color: #008;" class=3D"styled-by-prettify">string<=
/span><span
style=3D"color: #660;" class=3D"styled-by-prettify">,</span=
><span
style=3D"color: #000;" class=3D"styled-by-prettify"> </span=
><span
style=3D"color: #008;" class=3D"styled-by-prettify">double<=
/span><span
style=3D"color: #000;" class=3D"styled-by-prettify"> </span=
><span
style=3D"color: #660;" class=3D"styled-by-prettify">></s=
pan><span
style=3D"color: #000;" class=3D"styled-by-prettify"> tpl</s=
pan><span
style=3D"color: #660;" class=3D"styled-by-prettify">{</span=
><span
style=3D"color: #000;" class=3D"styled-by-prettify"> </span=
><span
style=3D"color: #660;" class=3D"styled-by-prettify">-</span=
><span
style=3D"color: #066;" class=3D"styled-by-prettify">1</span=
><span
style=3D"color: #660;" class=3D"styled-by-prettify">,</span=
><span
style=3D"color: #000;" class=3D"styled-by-prettify"> </span=
><span
style=3D"color: #080;" class=3D"styled-by-prettify">"abc"</=
span><span
style=3D"color: #660;" class=3D"styled-by-prettify">,</span=
><span
style=3D"color: #000;" class=3D"styled-by-prettify"> </span=
><span
style=3D"color: #080;" class=3D"styled-by-prettify">"xyz"</=
span><span
style=3D"color: #660;" class=3D"styled-by-prettify">,</span=
><span
style=3D"color: #000;" class=3D"styled-by-prettify"> </span=
><span
style=3D"color: #660;" class=3D"styled-by-prettify">.</span=
><span
style=3D"color: #066;" class=3D"styled-by-prettify">5</span=
><span
style=3D"color: #000;" class=3D"styled-by-prettify"> </span=
><span
style=3D"color: #660;" class=3D"styled-by-prettify">};</spa=
n><span
style=3D"color: #000;" class=3D"styled-by-prettify"><br>
=C2=A0 =C2=A0 std</span><span style=3D"color: #660;"
class=3D"styled-by-prettify">::</span><span style=3D"color:
#000;" class=3D"styled-by-prettify">tuple</span><span
style=3D"color: #660;" class=3D"styled-by-prettify"><</s=
pan><span
style=3D"color: #000;" class=3D"styled-by-prettify"> </span=
><span
style=3D"color: #008;" class=3D"styled-by-prettify">int</sp=
an><span
style=3D"color: #660;" class=3D"styled-by-prettify">,</span=
><span
style=3D"color: #000;" class=3D"styled-by-prettify"> std</s=
pan><span
style=3D"color: #660;" class=3D"styled-by-prettify">::</spa=
n><span
style=3D"color: #008;" class=3D"styled-by-prettify">string<=
/span><span
style=3D"color: #660;" class=3D"styled-by-prettify">,</span=
><span
style=3D"color: #000;" class=3D"styled-by-prettify"> std</s=
pan><span
style=3D"color: #660;" class=3D"styled-by-prettify">::</spa=
n><span
style=3D"color: #008;" class=3D"styled-by-prettify">string<=
/span><span
style=3D"color: #000;" class=3D"styled-by-prettify"> </span=
><span
style=3D"color: #660;" class=3D"styled-by-prettify">></s=
pan><span
style=3D"color: #000;" class=3D"styled-by-prettify"> tpl1</=
span><span
style=3D"color: #660;" class=3D"styled-by-prettify">;</span=
><span
style=3D"color: #000;" class=3D"styled-by-prettify"><br>
=C2=A0 =C2=A0 std</span><span style=3D"color: #660;"
class=3D"styled-by-prettify">::</span><span style=3D"color:
#000;" class=3D"styled-by-prettify">tuple</span><span
style=3D"color: #660;" class=3D"styled-by-prettify"><</s=
pan><span
style=3D"color: #000;" class=3D"styled-by-prettify"> std</s=
pan><span
style=3D"color: #660;" class=3D"styled-by-prettify">::</spa=
n><span
style=3D"color: #008;" class=3D"styled-by-prettify">string<=
/span><span
style=3D"color: #660;" class=3D"styled-by-prettify">,</span=
><span
style=3D"color: #000;" class=3D"styled-by-prettify"> </span=
><span
style=3D"color: #008;" class=3D"styled-by-prettify">double<=
/span><span
style=3D"color: #000;" class=3D"styled-by-prettify"> </span=
><span
style=3D"color: #660;" class=3D"styled-by-prettify">></s=
pan><span
style=3D"color: #000;" class=3D"styled-by-prettify"> tpl2</=
span><span
style=3D"color: #660;" class=3D"styled-by-prettify">;</span=
><span
style=3D"color: #000;" class=3D"styled-by-prettify"><br>
=C2=A0 =C2=A0 split</span><span style=3D"color: #660;"
class=3D"styled-by-prettify">(</span><span style=3D"color:
#000;" class=3D"styled-by-prettify"> tpl1</span><span
style=3D"color: #660;" class=3D"styled-by-prettify">,</span=
><span
style=3D"color: #000;" class=3D"styled-by-prettify"> tpl2</=
span><span
style=3D"color: #660;" class=3D"styled-by-prettify">)</span=
><span
style=3D"color: #000;" class=3D"styled-by-prettify"> </span=
><span
style=3D"color: #660;" class=3D"styled-by-prettify">=3D</sp=
an><span
style=3D"color: #000;" class=3D"styled-by-prettify"> tpl</s=
pan><span
style=3D"color: #660;" class=3D"styled-by-prettify">;</span=
></div>
</code></div>
<div><br>
</div>
<div>is just nonsense, as written.</div>
</div>
</blockquote>
See above.<br>
<blockquote
cite=3D"mid:7e08b6c5-853c-471e-b248-a9df7e8e27be@isocpp.org"
type=3D"cite">
<div dir=3D"ltr">
<div>However, under the "unpacking with postfix tilde"
not-a-proposal, a similar operation could be written like
this:</div>
<div><br>
</div>
<div class=3D"prettyprint" style=3D"background-color: rgb(250, 250,
250); border: 1px solid rgb(187, 187, 187); word-wrap:
break-word;"><code class=3D"prettyprint">
<div class=3D"subprettyprint"><span style=3D"color: #000;"
class=3D"styled-by-prettify">=C2=A0 =C2=A0 tuple</span><spa=
n
style=3D"color: #660;" class=3D"styled-by-prettify"><</s=
pan><span
style=3D"color: #008;" class=3D"styled-by-prettify">int</sp=
an><span
style=3D"color: #660;" class=3D"styled-by-prettify">,</span=
><span
style=3D"color: #000;" class=3D"styled-by-prettify"> </span=
><span
style=3D"color: #008;" class=3D"styled-by-prettify">string<=
/span><span
style=3D"color: #660;" class=3D"styled-by-prettify">,</span=
><span
style=3D"color: #000;" class=3D"styled-by-prettify"> </span=
><span
style=3D"color: #008;" class=3D"styled-by-prettify">string<=
/span><span
style=3D"color: #660;" class=3D"styled-by-prettify">,</span=
><span
style=3D"color: #000;" class=3D"styled-by-prettify"> </span=
><span
style=3D"color: #008;" class=3D"styled-by-prettify">double<=
/span><span
style=3D"color: #660;" class=3D"styled-by-prettify">></s=
pan><span
style=3D"color: #000;" class=3D"styled-by-prettify"> tpl </=
span><span
style=3D"color: #660;" class=3D"styled-by-prettify">{</span=
><span
style=3D"color: #000;" class=3D"styled-by-prettify"> </span=
><span
style=3D"color: #660;" class=3D"styled-by-prettify">-</span=
><span
style=3D"color: #066;" class=3D"styled-by-prettify">1</span=
><span
style=3D"color: #660;" class=3D"styled-by-prettify">,</span=
><span
style=3D"color: #000;" class=3D"styled-by-prettify"> </span=
><span
style=3D"color: #080;" class=3D"styled-by-prettify">"abc"</=
span><span
style=3D"color: #660;" class=3D"styled-by-prettify">,</span=
><span
style=3D"color: #000;" class=3D"styled-by-prettify"> </span=
><span
style=3D"color: #080;" class=3D"styled-by-prettify">"xyz"</=
span><span
style=3D"color: #660;" class=3D"styled-by-prettify">,</span=
><span
style=3D"color: #000;" class=3D"styled-by-prettify"> </span=
><span
style=3D"color: #660;" class=3D"styled-by-prettify">.</span=
><span
style=3D"color: #066;" class=3D"styled-by-prettify">5</span=
><span
style=3D"color: #000;" class=3D"styled-by-prettify"> </span=
><span
style=3D"color: #660;" class=3D"styled-by-prettify">};</spa=
n><span
style=3D"color: #000;" class=3D"styled-by-prettify"><br>
=C2=A0 =C2=A0 tuple</span><span style=3D"color: #660;"
class=3D"styled-by-prettify"><</span><span
style=3D"color: #008;" class=3D"styled-by-prettify">int</sp=
an><span
style=3D"color: #660;" class=3D"styled-by-prettify">,</span=
><span
style=3D"color: #000;" class=3D"styled-by-prettify"> </span=
><span
style=3D"color: #008;" class=3D"styled-by-prettify">string<=
/span><span
style=3D"color: #660;" class=3D"styled-by-prettify">></s=
pan><span
style=3D"color: #000;" class=3D"styled-by-prettify"> tpl1</=
span><span
style=3D"color: #660;" class=3D"styled-by-prettify">;</span=
><span
style=3D"color: #000;" class=3D"styled-by-prettify"><br>
=C2=A0 =C2=A0 tuple</span><span style=3D"color: #660;"
class=3D"styled-by-prettify"><</span><span
style=3D"color: #008;" class=3D"styled-by-prettify">string<=
/span><span
style=3D"color: #660;" class=3D"styled-by-prettify">,</span=
><span
style=3D"color: #000;" class=3D"styled-by-prettify"> </span=
><span
style=3D"color: #008;" class=3D"styled-by-prettify">double<=
/span><span
style=3D"color: #660;" class=3D"styled-by-prettify">></s=
pan><span
style=3D"color: #000;" class=3D"styled-by-prettify"> tpl2</=
span><span
style=3D"color: #660;" class=3D"styled-by-prettify">;</span=
><span
style=3D"color: #000;" class=3D"styled-by-prettify"><br>
<br>
=C2=A0 =C2=A0 std</span><span style=3D"color: #660;"
class=3D"styled-by-prettify">::</span><span style=3D"color:
#000;" class=3D"styled-by-prettify">tie</span><span
style=3D"color: #660;" class=3D"styled-by-prettify">(</span=
><span
style=3D"color: #000;" class=3D"styled-by-prettify">tpl1</s=
pan><span
style=3D"color: #660;" class=3D"styled-by-prettify">~...,</=
span><span
style=3D"color: #000;" class=3D"styled-by-prettify"> tpl2</=
span><span
style=3D"color: #660;" class=3D"styled-by-prettify">~...)</=
span><span
style=3D"color: #000;" class=3D"styled-by-prettify"> </span=
><span
style=3D"color: #660;" class=3D"styled-by-prettify">=3D</sp=
an><span
style=3D"color: #000;" class=3D"styled-by-prettify"> tpl</s=
pan><span
style=3D"color: #660;" class=3D"styled-by-prettify">;</span=
><span
style=3D"color: #000;" class=3D"styled-by-prettify"><br>
<br>
=C2=A0 =C2=A0 </span><span style=3D"color: #008;"
class=3D"styled-by-prettify">assert</span><span
style=3D"color: #660;" class=3D"styled-by-prettify">(</span=
><span
style=3D"color: #000;" class=3D"styled-by-prettify">std</sp=
an><span
style=3D"color: #660;" class=3D"styled-by-prettify">::</spa=
n><span
style=3D"color: #008;" class=3D"styled-by-prettify">get</sp=
an><span
style=3D"color: #660;" class=3D"styled-by-prettify"><</s=
pan><span
style=3D"color: #066;" class=3D"styled-by-prettify">0</span=
><span
style=3D"color: #660;" class=3D"styled-by-prettify">>(</=
span><span
style=3D"color: #000;" class=3D"styled-by-prettify">tpl1</s=
pan><span
style=3D"color: #660;" class=3D"styled-by-prettify">)</span=
><span
style=3D"color: #000;" class=3D"styled-by-prettify"> </span=
><span
style=3D"color: #660;" class=3D"styled-by-prettify">=3D=3D<=
/span><span
style=3D"color: #000;" class=3D"styled-by-prettify"> std</s=
pan><span
style=3D"color: #660;" class=3D"styled-by-prettify">::</spa=
n><span
style=3D"color: #008;" class=3D"styled-by-prettify">get</sp=
an><span
style=3D"color: #660;" class=3D"styled-by-prettify"><</s=
pan><span
style=3D"color: #066;" class=3D"styled-by-prettify">0</span=
><span
style=3D"color: #660;" class=3D"styled-by-prettify">>(</=
span><span
style=3D"color: #000;" class=3D"styled-by-prettify">tpl</sp=
an><span
style=3D"color: #660;" class=3D"styled-by-prettify">));</sp=
an><span
style=3D"color: #000;" class=3D"styled-by-prettify"><br>
=C2=A0 =C2=A0 </span><span style=3D"color: #008;"
class=3D"styled-by-prettify">assert</span><span
style=3D"color: #660;" class=3D"styled-by-prettify">(</span=
><span
style=3D"color: #000;" class=3D"styled-by-prettify">std</sp=
an><span
style=3D"color: #660;" class=3D"styled-by-prettify">::</spa=
n><span
style=3D"color: #008;" class=3D"styled-by-prettify">get</sp=
an><span
style=3D"color: #660;" class=3D"styled-by-prettify"><</s=
pan><span
style=3D"color: #066;" class=3D"styled-by-prettify">1</span=
><span
style=3D"color: #660;" class=3D"styled-by-prettify">>(</=
span><span
style=3D"color: #000;" class=3D"styled-by-prettify">tpl1</s=
pan><span
style=3D"color: #660;" class=3D"styled-by-prettify">)</span=
><span
style=3D"color: #000;" class=3D"styled-by-prettify"> </span=
><span
style=3D"color: #660;" class=3D"styled-by-prettify">=3D=3D<=
/span><span
style=3D"color: #000;" class=3D"styled-by-prettify"> std</s=
pan><span
style=3D"color: #660;" class=3D"styled-by-prettify">::</spa=
n><span
style=3D"color: #008;" class=3D"styled-by-prettify">get</sp=
an><span
style=3D"color: #660;" class=3D"styled-by-prettify"><</s=
pan><span
style=3D"color: #066;" class=3D"styled-by-prettify">1</span=
><span
style=3D"color: #660;" class=3D"styled-by-prettify">>(</=
span><span
style=3D"color: #000;" class=3D"styled-by-prettify">tpl</sp=
an><span
style=3D"color: #660;" class=3D"styled-by-prettify">));</sp=
an><span
style=3D"color: #000;" class=3D"styled-by-prettify"><br>
=C2=A0 =C2=A0 </span><span style=3D"color: #008;"
class=3D"styled-by-prettify">assert</span><span
style=3D"color: #660;" class=3D"styled-by-prettify">(</span=
><span
style=3D"color: #000;" class=3D"styled-by-prettify">std</sp=
an><span
style=3D"color: #660;" class=3D"styled-by-prettify">::</spa=
n><span
style=3D"color: #008;" class=3D"styled-by-prettify">get</sp=
an><span
style=3D"color: #660;" class=3D"styled-by-prettify"><</s=
pan><span
style=3D"color: #066;" class=3D"styled-by-prettify">0</span=
><span
style=3D"color: #660;" class=3D"styled-by-prettify">>(</=
span><span
style=3D"color: #000;" class=3D"styled-by-prettify">tpl2</s=
pan><span
style=3D"color: #660;" class=3D"styled-by-prettify">)</span=
><span
style=3D"color: #000;" class=3D"styled-by-prettify"> </span=
><span
style=3D"color: #660;" class=3D"styled-by-prettify">=3D=3D<=
/span><span
style=3D"color: #000;" class=3D"styled-by-prettify"> std</s=
pan><span
style=3D"color: #660;" class=3D"styled-by-prettify">::</spa=
n><span
style=3D"color: #008;" class=3D"styled-by-prettify">get</sp=
an><span
style=3D"color: #660;" class=3D"styled-by-prettify"><</s=
pan><span
style=3D"color: #066;" class=3D"styled-by-prettify">2</span=
><span
style=3D"color: #660;" class=3D"styled-by-prettify">>(</=
span><span
style=3D"color: #000;" class=3D"styled-by-prettify">tpl</sp=
an><span
style=3D"color: #660;" class=3D"styled-by-prettify">));</sp=
an><span
style=3D"color: #000;" class=3D"styled-by-prettify"><br>
=C2=A0 =C2=A0 </span><span style=3D"color: #008;"
class=3D"styled-by-prettify">assert</span><span
style=3D"color: #660;" class=3D"styled-by-prettify">(</span=
><span
style=3D"color: #000;" class=3D"styled-by-prettify">std</sp=
an><span
style=3D"color: #660;" class=3D"styled-by-prettify">::</spa=
n><span
style=3D"color: #008;" class=3D"styled-by-prettify">get</sp=
an><span
style=3D"color: #660;" class=3D"styled-by-prettify"><</s=
pan><span
style=3D"color: #066;" class=3D"styled-by-prettify">1</span=
><span
style=3D"color: #660;" class=3D"styled-by-prettify">>(</=
span><span
style=3D"color: #000;" class=3D"styled-by-prettify">tpl2</s=
pan><span
style=3D"color: #660;" class=3D"styled-by-prettify">)</span=
><span
style=3D"color: #000;" class=3D"styled-by-prettify"> </span=
><span
style=3D"color: #660;" class=3D"styled-by-prettify">=3D=3D<=
/span><span
style=3D"color: #000;" class=3D"styled-by-prettify"> std</s=
pan><span
style=3D"color: #660;" class=3D"styled-by-prettify">::</spa=
n><span
style=3D"color: #008;" class=3D"styled-by-prettify">get</sp=
an><span
style=3D"color: #660;" class=3D"styled-by-prettify"><</s=
pan><span
style=3D"color: #066;" class=3D"styled-by-prettify">3</span=
><span
style=3D"color: #660;" class=3D"styled-by-prettify">>(</=
span><span
style=3D"color: #000;" class=3D"styled-by-prettify">tpl</sp=
an><span
style=3D"color: #660;" class=3D"styled-by-prettify">));</sp=
an></div>
</code></div>
<div>
<div><br>
</div>
</div>
<div>In general, I think that the C++ standard library is
woefully lacking in tuple manipulators... but rather than
proposing new tuple manipulators (of which there could be a
million: zip, fold, map, car, cdr, reverse,...), we should be
trying to give people the ability to express those
manipulators natively in the language, via something like
Matthew's [:] notation or my ~... notation.</div>
<div><br>
</div>
<br>
</div>
</blockquote>
Just wondering how could help the no-yet-proposed operators=C2=A0 [:], =
~,
and=C2=A0 ... to implement what I interpreted.<br>
<br>
Vicente<br>
</body>
</html>
<p></p>
-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
Visit this group at <a href=3D"https://groups.google.com/a/isocpp.org/group=
/std-proposals/">https://groups.google.com/a/isocpp.org/group/std-proposals=
/</a>.<br />
--------------090706040204090900080905--
.
Author: "Vicente J. Botet Escriba" <vicente.botet@wanadoo.fr>
Date: Sat, 13 Feb 2016 10:18:23 +0100
Raw View
This is a multi-part message in MIME format.
--------------040705010301040704070701
Content-Type: text/plain; charset=UTF-8; format=flowed
Content-Transfer-Encoding: quoted-printable
Le 13/02/2016 09:44, Oliver Kowalke a =C3=A9crit :
> 016-02-13 1:28 GMT+01:00 Arthur O'Dwyer <arthur.j.odwyer@gmail.com=20
> <mailto:arthur.j.odwyer@gmail.com>>:
>
> (Also, I'm assuming that Oliver made some typos in his original
> post =E2=80=94 notice I've flipped the "tpl" and "tpl1" in the second=
line
> above.)
>
>
> correct
I'm confused. Arthur's was not doing an extraction but an insertion in=20
this case
| tail(tpl)=3Dtpl1;// Python: tpl[1:] =3D tpl1|
I believed you were talking of extraction.
>
> Also, of course, head(x) should logically return get<0>(x), not
> some weird synonym for reverse(tail(reverse(x))).
>
>
> head(x) should return the part from the source tuple's head that fits=20
> into tuple x, same applies to tail(x)
>
> But that's just poor naming. The underlying operation here is
> either "splice"
>
>
> I'm only interested in the functionality, not in the naming. One of my=20
> project requires such functionality and I was wondering that neither=20
> the standard
> provides such manipulators nor could I find a proposal.
>
> tuple ~... and tu|ple [:] require a language modification - but I need=20
> a solution now; so I've written head()/tail() (even if the naming is=20
> not perfect).|
>
I agree that we should first think in terms of the desired functionality=20
and if it is worth having it in the standard. If some additional=20
language features make this easier great.
I believe that you would need to describe more precisely what you want=20
these functions to do.
Vicente
--=20
---=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-propos=
als/.
--------------040705010301040704070701
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<html>
<head>
<meta content=3D"text/html; charset=3Dutf-8" http-equiv=3D"Content-Type=
">
</head>
<body bgcolor=3D"#FFFFFF" text=3D"#000000">
<div class=3D"moz-cite-prefix">Le 13/02/2016 09:44, Oliver Kowalke a
=C3=A9crit=C2=A0:<br>
</div>
<blockquote
cite=3D"mid:CA+wfc1-NGb8G1ocpbuzC42aLhAF3KOggRev9rzBNXbL8wd5V6A@mail.gmail.=
com"
type=3D"cite">
<div dir=3D"ltr">
<div class=3D"gmail_extra">
<div class=3D"gmail_quote">016-02-13 1:28 GMT+01:00 Arthur
O'Dwyer <span dir=3D"ltr"><<a moz-do-not-send=3D"true"
href=3D"mailto:arthur.j.odwyer@gmail.com" target=3D"_blank"=
>arthur.j.odwyer@gmail.com</a>></span>:<br>
<blockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px
0.8ex;border-left:1px solid
rgb(204,204,204);padding-left:1ex">
<div dir=3D"ltr"><span class=3D""></span> (Also, I'm assuming
that Oliver made some typos in his original post =E2=80=94
notice I've flipped the "tpl" and "tpl1" in the second
line above.)</div>
</blockquote>
<div><br>
</div>
<div>correct<br>
</div>
</div>
</div>
</div>
</blockquote>
I'm confused. Arthur's was not doing an extraction but an insertion
in this case<br>
<br>
<code class=3D"prettyprint"><span style=3D"color: #000;"
class=3D"styled-by-prettify">=C2=A0 =C2=A0 tail</span><span style=
=3D"color:
#660;" class=3D"styled-by-prettify">(</span><span style=3D"color:
#000;" class=3D"styled-by-prettify">tpl</span><span style=3D"color:
#660;" class=3D"styled-by-prettify">)</span><span style=3D"color:
#000;" class=3D"styled-by-prettify"> </span><span style=3D"color:
#660;" class=3D"styled-by-prettify">=3D</span><span style=3D"color:
#000;" class=3D"styled-by-prettify"> tpl1</span><span
style=3D"color: #660;" class=3D"styled-by-prettify">;</span><span
style=3D"color: #000;" class=3D"styled-by-prettify"> =C2=A0 =C2=A0<=
/span><span
style=3D"color: #800;" class=3D"styled-by-prettify">// Python:
tpl[1:] =3D tpl1</span></code><br>
<br>
I believed you were talking of extraction.<br>
<blockquote
cite=3D"mid:CA+wfc1-NGb8G1ocpbuzC42aLhAF3KOggRev9rzBNXbL8wd5V6A@mail.gmail.=
com"
type=3D"cite">
<div dir=3D"ltr">
<div class=3D"gmail_extra">
<div class=3D"gmail_quote">
<div>=C2=A0</div>
<blockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px
0.8ex;border-left:1px solid
rgb(204,204,204);padding-left:1ex">
<div dir=3D"ltr">
<div>Also, of course, head(x) should logically return
get<0>(x), not some weird synonym for
reverse(tail(reverse(x))). </div>
</div>
</blockquote>
<div><br>
</div>
<div>head(x) should return the part from the source tuple's
head that fits into tuple x, same applies to tail(x)<br>
</div>
<div>=C2=A0</div>
<blockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px
0.8ex;border-left:1px solid
rgb(204,204,204);padding-left:1ex">
<div dir=3D"ltr">
<div>But that's just poor naming. The underlying
operation here is either "splice"<br>
</div>
</div>
</blockquote>
</div>
<br>
</div>
<div class=3D"gmail_extra">I'm only interested in the
functionality, not in the naming. One of my project requires
such functionality and I was wondering that neither the
standard<br>
</div>
<div class=3D"gmail_extra">provides such manipulators nor could I
find a proposal.<br>
<span style=3D"font-family:arial,helvetica,sans-serif"><br>
</span></div>
<div class=3D"gmail_extra"><span
style=3D"font-family:arial,helvetica,sans-serif">tuple ~...
and tu</span><code><span
style=3D"font-family:arial,helvetica,sans-serif">ple [:]
require a language modification - but I need a solution
now; so I've written head()/tail() (even if the naming is
not perfect).</span><span style=3D"color:rgb(136,0,0)"></span=
></code></div>
</div>
<br>
</blockquote>
I agree that we should first think in terms of the desired
functionality and if it is worth having it in the standard. If some
additional language features make this easier great.<br>
I believe that you would need to describe more precisely what you
want these functions to do.<br>
<br>
Vicente<br>
</body>
</html>
<p></p>
-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
Visit this group at <a href=3D"https://groups.google.com/a/isocpp.org/group=
/std-proposals/">https://groups.google.com/a/isocpp.org/group/std-proposals=
/</a>.<br />
--------------040705010301040704070701--
.
Author: Oliver Kowalke <oliver.kowalke@gmail.com>
Date: Sat, 13 Feb 2016 10:43:20 +0100
Raw View
--001a113ced6e52aeb8052ba39e62
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
2016-02-13 10:18 GMT+01:00 Vicente J. Botet Escriba <
vicente.botet@wanadoo.fr>:
> Le 13/02/2016 09:44, Oliver Kowalke a =C3=A9crit :
>
> 016-02-13 1:28 GMT+01:00 Arthur O'Dwyer <arthur.j.odwyer@gmail.com>:
>
>> (Also, I'm assuming that Oliver made some typos in his original post =E2=
=80=94
>> notice I've flipped the "tpl" and "tpl1" in the second line above.)
>>
>
> correct
>
> I'm confused. Arthur's was not doing an extraction but an insertion in
> this case
>
sorry - I was confused
>
> tail(tpl) =3D tpl1; // Python: tpl[1:] =3D tpl1
>
> I believed you were talking of extraction.
>
extraction - I'm not familiar with python
>
>
>> Also, of course, head(x) should logically return get<0>(x), not some
>> weird synonym for reverse(tail(reverse(x))).
>>
>
> head(x) should return the part from the source tuple's head that fits int=
o
> tuple x, same applies to tail(x)
>
>
>> But that's just poor naming. The underlying operation here is either
>> "splice"
>>
>
> I'm only interested in the functionality, not in the naming. One of my
> project requires such functionality and I was wondering that neither the
> standard
> provides such manipulators nor could I find a proposal.
>
> tuple ~... and tuple [:] require a language modification - but I need a
> solution now; so I've written head()/tail() (even if the naming is not
> perfect).
>
> I agree that we should first think in terms of the desired functionality
> and if it is worth having it in the standard. If some additional language
> features make this easier great.
> I believe that you would need to describe more precisely what you want
> these functions to do.
>
the code required something like:
....
auto args =3D std::move( std::get< 1 >( * tpl) );
auto result =3D apply( args);
detail::tail( args) =3D result;
....
output of this code:
std::tuple< int, std::string, std::string, double > tpl{ -1, "abc",
"xyz", .5 };
std::tuple< int, std::string, std::string > tpl1;
std::tuple< std::string, double > tpl2;
head( tpl1) =3D tpl;
tail( tpl2) =3D tpl;
std::cout << " tpl: " << tpl << "\n";
std::cout << " tpl1: " << tpl1 << "\n";
std::cout << " tpl2: " << tpl2 << "\n";
should be:
tpl: (-1, abc, xyz, 0.5)
tpl1: (-1, abc, xyz)
tpl2: (xyz, 0.5)
--=20
---=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-propos=
als/.
--001a113ced6e52aeb8052ba39e62
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><div class=3D"gmail_extra"><div class=3D"gmail_quote">2016=
-02-13 10:18 GMT+01:00 Vicente J. Botet Escriba <span dir=3D"ltr"><<a hr=
ef=3D"mailto:vicente.botet@wanadoo.fr" target=3D"_blank">vicente.botet@wana=
doo.fr</a>></span>:<br><blockquote class=3D"gmail_quote" style=3D"margin=
:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"=
>
=20
=20
=20
<div bgcolor=3D"#FFFFFF" text=3D"#000000"><span class=3D"">
<div>Le 13/02/2016 09:44, Oliver Kowalke a
=C3=A9crit=C2=A0:<br>
</div>
<blockquote type=3D"cite">
<div dir=3D"ltr">
<div class=3D"gmail_extra">
<div class=3D"gmail_quote">016-02-13 1:28 GMT+01:00 Arthur
O'Dwyer <span dir=3D"ltr"><<a href=3D"mailto:arthur.j.od=
wyer@gmail.com" target=3D"_blank">arthur.j.odwyer@gmail.com</a>></span>:=
<br>
<blockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0=
..8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
<div dir=3D"ltr"><span></span> (Also, I'm assuming
that Oliver made some typos in his original post =E2=80=94
notice I've flipped the "tpl" and "tpl1&=
quot; in the second
line above.)</div>
</blockquote>
<div><br>
</div>
<div>correct<br>
</div>
</div>
</div>
</div>
</blockquote></span>
I'm confused. Arthur's was not doing an extraction but an inser=
tion
in this case<span class=3D""><br></span></div></blockquote><div><br></d=
iv><div>sorry - I was confused<br></div><div>=C2=A0</div><blockquote class=
=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;border-left:1px solid rg=
b(204,204,204);padding-left:1ex"><div bgcolor=3D"#FFFFFF" text=3D"#000000">=
<span class=3D"">
<br>
<code><span style=3D"color:rgb(0,0,0)">=C2=A0 =C2=A0 tail</span><span s=
tyle=3D"color:rgb(102,102,0)">(</span><span style=3D"color:rgb(0,0,0)">tpl<=
/span><span style=3D"color:rgb(102,102,0)">)</span><span style=3D"color:rgb=
(0,0,0)"> </span><span style=3D"color:rgb(102,102,0)">=3D</span><span style=
=3D"color:rgb(0,0,0)"> tpl1</span><span style=3D"color:rgb(102,102,0)">;</s=
pan><span style=3D"color:rgb(0,0,0)"> =C2=A0 =C2=A0</span><span style=3D"co=
lor:rgb(136,0,0)">// Python:
tpl[1:] =3D tpl1</span></code><br>
<br></span>
I believed you were talking of extraction.<span class=3D""><br></span><=
/div></blockquote><div><br></div><div>extraction - I'm not familiar wit=
h python<br></div><div>=C2=A0</div><blockquote class=3D"gmail_quote" style=
=3D"margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding=
-left:1ex"><div bgcolor=3D"#FFFFFF" text=3D"#000000"><span class=3D"">
<blockquote type=3D"cite">
<div dir=3D"ltr">
<div class=3D"gmail_extra">
<div class=3D"gmail_quote">
<div>=C2=A0</div>
<blockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0=
..8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
<div dir=3D"ltr">
<div>Also, of course, head(x) should logically return
get<0>(x), not some weird synonym for
reverse(tail(reverse(x))). </div>
</div>
</blockquote>
<div><br>
</div>
<div>head(x) should return the part from the source tuple's
head that fits into tuple x, same applies to tail(x)<br>
</div>
<div>=C2=A0</div>
<blockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0=
..8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
<div dir=3D"ltr">
<div>But that's just poor naming. The underlying
operation here is either "splice"<br>
</div>
</div>
</blockquote>
</div>
<br>
</div>
<div class=3D"gmail_extra">I'm only interested in the
functionality, not in the naming. One of my project requires
such functionality and I was wondering that neither the
standard<br>
</div>
<div class=3D"gmail_extra">provides such manipulators nor could I
find a proposal.<br>
<span style=3D"font-family:arial,helvetica,sans-serif"><br>
</span></div>
<div class=3D"gmail_extra"><span style=3D"font-family:arial,helveti=
ca,sans-serif">tuple ~...
and tu</span><code><span style=3D"font-family:arial,helvetica,s=
ans-serif">ple [:]
require a language modification - but I need a solution
now; so I've written head()/tail() (even if the naming is
not perfect).</span><span style=3D"color:rgb(136,0,0)"></span=
></code></div>
</div>
<br>
</blockquote></span>
I agree that we should first think in terms of the desired
functionality and if it is worth having it in the standard. If some
additional language features make this easier great.<br>
I believe that you would need to describe more precisely what you
want these functions to do.<span class=3D""></span><br></div></blockquo=
te></div><br></div><div class=3D"gmail_extra">the code required something l=
ike:<br></div><div class=3D"gmail_extra">...<br>auto args =3D std::move( st=
d::get< 1 >( * tpl) );<br>auto result =3D apply( args);<br></div><div=
class=3D"gmail_extra">detail::tail( args) =3D result;<br>...<br><br>output=
of this code:<br><br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 std::tuple=
< int, std::string, std::string, double > tpl{ -1, "abc", &=
quot;xyz", .5 };<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 std::tu=
ple< int, std::string, std::string > tpl1;<br>=C2=A0=C2=A0=C2=A0=C2=
=A0=C2=A0=C2=A0=C2=A0 std::tuple< std::string, double > tpl2;<br>=C2=
=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 head( tpl1) =3D tpl;<br>=C2=A0=C2=
=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 tail( tpl2) =3D tpl;<br>=C2=A0=C2=A0=C2=
=A0=C2=A0=C2=A0=C2=A0=C2=A0 std::cout << " tpl: " << =
tpl << "\n";<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 =
std::cout << " tpl1: " << tpl1 << "\n"=
;;<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 std::cout << " =
tpl2: " << tpl2 << "\n";<br><br></div><div class=
=3D"gmail_extra">should be:<br><br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 tpl=
: (-1, abc, xyz, 0.5)<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 tpl1: (-1, ab=
c, xyz)<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 tpl2: (xyz, 0.5)<br><br></d=
iv></div>
<p></p>
-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
Visit this group at <a href=3D"https://groups.google.com/a/isocpp.org/group=
/std-proposals/">https://groups.google.com/a/isocpp.org/group/std-proposals=
/</a>.<br />
--001a113ced6e52aeb8052ba39e62--
.
Author: Oliver Kowalke <oliver.kowalke@gmail.com>
Date: Sat, 13 Feb 2016 10:46:42 +0100
Raw View
--94eb2c09532e5fadd3052ba3aa17
Content-Type: text/plain; charset=UTF-8
2016-02-13 10:43 GMT+01:00 Oliver Kowalke <oliver.kowalke@gmail.com>:
> auto result = apply( args);
>
sorry - I removed too much from the code, I mean 'auto result = apply( fn,
args);' were fn is a callable and result is a tuple returned by the callable
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-proposals/.
--94eb2c09532e5fadd3052ba3aa17
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><div class=3D"gmail_extra"><div class=3D"gmail_quote">2016=
-02-13 10:43 GMT+01:00 Oliver Kowalke <span dir=3D"ltr"><<a href=3D"mail=
to:oliver.kowalke@gmail.com" target=3D"_blank">oliver.kowalke@gmail.com</a>=
></span>:<br><blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8e=
x;border-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><div class=
=3D"gmail_extra">auto result =3D apply( args);<br></div></div></blockquote>=
<div><br></div><div>sorry - I removed too much from the code, I mean 'a=
uto result =3D apply( fn, args);' were fn is a callable and result is a=
tuple returned by the callable<br>=C2=A0<br></div></div><br></div></div>
<p></p>
-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
Visit this group at <a href=3D"https://groups.google.com/a/isocpp.org/group=
/std-proposals/">https://groups.google.com/a/isocpp.org/group/std-proposals=
/</a>.<br />
--94eb2c09532e5fadd3052ba3aa17--
.
Author: David Krauss <potswa@gmail.com>
Date: Sat, 13 Feb 2016 18:03:26 +0800
Raw View
--Apple-Mail=_6A8ED708-663E-4191-8621-BBFEA03F8D91
Content-Transfer-Encoding: quoted-printable
Content-Type: text/plain; charset=UTF-8
> On 2016=E2=80=9302=E2=80=9313, at 12:30 AM, Oliver Kowalke <oliver.kowalk=
e@gmail.com> wrote:
>=20
> I've had std::tie() in mind,
The special feature of tie is generating references. That seems orthogonal =
to slicing a sequence. Reference semantics should be used sparingly in gene=
ral.
How about a function to get a pack of references from a tuple,
template< typename ... t >
std::tuple< t & ... > tuple_ref( std::tuple< t ... > & );
and a generic slice function,
template< std::size_t first, std::size_t last, typename tuple_like >
std::tuple< std::tuple_element_t< tuple_like, N > ... > // N goes from firs=
t to last.
tuple_slice( tuple_like const & );
Then the example looks like,
std::tuple< int, std::string, std::string, double > tpl{ -1, "abc", "xyz", =
..5 };
std::tuple< int, std::string, std::string > tpl1;
std::tuple< std::string, double > tpl2;
tpl1 =3D tuple_slice< 0, 3 >( tpl );
tpl2 =3D tuple_slice< 2, 2 >( tpl );
std::tuple_cat( tuple_ref( tpl1 ), tuple_ref( tpl2 ) ) =3D tpl;
The bounds of the slice are explicit, but that looks more like a feature th=
an a bug.
--=20
---=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-propos=
als/.
--Apple-Mail=_6A8ED708-663E-4191-8621-BBFEA03F8D91
Content-Transfer-Encoding: quoted-printable
Content-Type: text/html; charset=UTF-8
<html><head><meta http-equiv=3D"Content-Type" content=3D"text/html charset=
=3Dutf-8"></head><body style=3D"word-wrap: break-word; -webkit-nbsp-mode: s=
pace; -webkit-line-break: after-white-space;" class=3D""><br class=3D""><di=
v><blockquote type=3D"cite" class=3D""><div class=3D"">On 2016=E2=80=9302=
=E2=80=9313, at 12:30 AM, Oliver Kowalke <<a href=3D"mailto:oliver.kowal=
ke@gmail.com" class=3D"">oliver.kowalke@gmail.com</a>> wrote:</div><br c=
lass=3D"Apple-interchange-newline"><div class=3D""><span style=3D"font-fami=
ly: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; f=
ont-weight: normal; letter-spacing: normal; orphans: auto; text-align: star=
t; text-indent: 0px; text-transform: none; white-space: normal; widows: aut=
o; word-spacing: 0px; -webkit-text-stroke-width: 0px; float: none; display:=
inline !important;" class=3D"">I've had std::tie() in mind,</span><br styl=
e=3D"font-family: Helvetica; font-size: 12px; font-style: normal; font-vari=
ant: normal; font-weight: normal; letter-spacing: normal; orphans: auto; te=
xt-align: start; text-indent: 0px; text-transform: none; white-space: norma=
l; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=
=3D""></div></blockquote></div><br class=3D""><div class=3D"">The special f=
eature of <font face=3D"Courier" class=3D"">tie</font> is generating refere=
nces. That seems orthogonal to slicing a sequence. Reference semantics shou=
ld be used sparingly in general.</div><div class=3D""><br class=3D""></div>=
<div class=3D"">How about a function to get a pack of references from a tup=
le,</div><div class=3D""><br class=3D""></div><div class=3D""><font face=3D=
"Courier" class=3D"">template< typename ... t ></font></div><div clas=
s=3D""><font face=3D"Courier" class=3D"">std::tuple< t & ... > tu=
ple_ref( std::tuple< t ... > & );</font></div><div class=3D""><br=
class=3D""></div><div class=3D"">and a generic slice function,</div><div c=
lass=3D""><br class=3D""></div><div class=3D""><font face=3D"Courier" class=
=3D"">template< std::size_t first, std::size_t last, typename tuple=
_like ></font></div><div class=3D""><div class=3D""><span style=3D"=
font-family: Courier;" class=3D"">std::tuple< std::tuple_element_t< t=
uple_like, N > ... > // N goes from first to last.</span></div><div c=
lass=3D""><font face=3D"Courier" class=3D"">tuple_slice( tuple_like const &=
amp; );</font></div></div><div class=3D""><font face=3D"Courier" class=3D""=
><br class=3D""></font></div><div class=3D"">Then the example looks like,</=
div><div class=3D""><br class=3D""></div><div class=3D""><div class=3D""><f=
ont face=3D"Courier" class=3D"">std::<span tabindex=3D"-1" id=3D":1tt.15" c=
lass=3D"">tuple</span>< int, std::string, std::string, double > =
<span tabindex=3D"-1" id=3D":1tt.16" class=3D"">tpl</span>{ -1, "<span tabi=
ndex=3D"-1" id=3D":1tt.17" class=3D"">abc</span>", "<span tabindex=3D"-1" i=
d=3D":1tt.18" class=3D"">xyz</span>", .5 };<br class=3D"">std::<span tabind=
ex=3D"-1" id=3D":1tt.19" class=3D"">tuple</span>< int, std::string, std:=
:string > tpl1;<br class=3D"">std::<span tabindex=3D"-1" id=3D":1tt.20" =
class=3D"">tuple</span>< std::string, double > tpl2;<br class=3D""><b=
r class=3D"">tpl1 =3D tuple_slice< 0, 3 >( <span tabindex=
=3D"-1" id=3D":1tt.21" class=3D"">tpl )</span>;<br class=3D"">tpl2 =3D =
;tuple_slice< 2, 2 >( <span tabindex=3D"-1" id=3D":1tt.22" class=
=3D"">tpl )</span>;<br class=3D""></font></div><div class=3D""><font face=
=3D"Courier" class=3D"">std::tuple_cat( tuple_ref( tpl1 ), tuple_ref( tpl2 =
) ) =3D tpl;<br class=3D""></font></div></div><div class=3D""><br class=3D"=
"></div><div class=3D"">The bounds of the slice are explicit, but that look=
s more like a feature than a bug.</div><div class=3D""><br class=3D""></div=
></body></html>
<p></p>
-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
Visit this group at <a href=3D"https://groups.google.com/a/isocpp.org/group=
/std-proposals/">https://groups.google.com/a/isocpp.org/group/std-proposals=
/</a>.<br />
--Apple-Mail=_6A8ED708-663E-4191-8621-BBFEA03F8D91--
.
Author: Matthew Woehlke <mwoehlke.floss@gmail.com>
Date: Mon, 15 Feb 2016 10:21:10 -0500
Raw View
On 2016-02-13 05:03, David Krauss wrote:
>> On 2016=E2=80=9302=E2=80=9313, at 12:30 AM, Oliver Kowalke wrote:
>>
>> I've had std::tie() in mind,
>=20
> How about a function to get a pack of references from a tuple,
Please, no; we already *have* std::tie, we don't need others (including
split/splice):
// David's tuple_ref
std::tie([:]t...);
// same as proposed std::split
std::tie([:]tpl1..., [:]tpl2...) =3D std::make_tuple([:]tpl...);
The RHS (second example) can of course be replaced with just `tpl` if
`tpl` is already a std::tuple. Otherwise, this works for any
*tuple-likes*, not just actual std::tuple's, provided that the LHS
get<N>(T&) returns a reference (as it does for e.g. std::tuple, and
presumably would for aggregates when using the implicitly generated
version a la P0197).
> and a generic slice function,
> [snip declaration]
>=20
> tpl1 =3D tuple_slice< 0, 3 >( tpl );
> tpl2 =3D tuple_slice< 2, 2 >( tpl );
> std::tuple_cat( tuple_ref( tpl1 ), tuple_ref( tpl2 ) ) =3D tpl;
I like that you're thinking along the lines of not creating a magical
assignment operator (which is what the proposed head/tail would be; they
necessarily would create a "magical" helper class with a templated
assignment operator which consumes an *arbitrary* tuple of at least N
elements and assigns the first N elements to the N elements of the LHS).
I like less that you're still looking at a library solution that only
handles std::tuple. Language unpacking/slicing handles *any tuple-like*
(on the RHS, and any whose get<N> returns a reference on the LHS).
--=20
Matthew
--=20
---=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-propos=
als/.
.
Author: Matthew Woehlke <mwoehlke.floss@gmail.com>
Date: Mon, 15 Feb 2016 10:54:50 -0500
Raw View
On 2016-02-12 19:28, Arthur O'Dwyer wrote:
> I think maybe Oliver was trying to say that
>
> tuple<int, string, string, double> tpl { -1, "abc", "xyz", .5 };
> tuple<string, string, double> tpl1;
> tpl1 = tail(tpl); // Python: tpl1 = tpl[1:]
> tail(tpl) = tpl1; // Python: tpl[1:] = tpl1
>
> should both work, because tail() should return a tuple of references
> instead of a tuple of values.
No, that's definitely *not* how I understood it. See Vicente's reply.
Actually, thinking about it, `splice` *might* be useful enough to keep
as a function in its own right:
template <typename... Tuples>
splice(Tuples&... tuples)
{
return std::tie(([:]tuples...)...);
}
(Bonus points: would the above syntax actually work? What syntax *would*
work? The goal is: `get<0>(a), ... get<A>(a), get<0>(b), ... get<B>(b),
....`.)
The others (head, tail) don't work this way at all (again, see Vicente's
explanation). Using one of these on the RHS of an expression would be an
error. Neither of your examples above are correct. Rather:
tail(tpl1) = tpl; // Python: tpl1 = tpl[len(tpl) - len(tpl1):]
> In general, I think that the C++ standard library is woefully lacking in
> tuple manipulators... but rather than proposing new tuple manipulators (of
> which there could be a million: zip, fold, map, car, cdr, reverse,...), we
> should be trying to give people the ability to express those manipulators
> natively in the language, via something like Matthew's [:] notation or my
> ~... notation.
....and this thread is a great example of the superiority of `[:]` ;-).
(Because it's not *just* `[:]`, it's `[A:B]` where both of `A` and `B`
are optional. That's harder to do with `~`... I suppose you could write
something like `tpl~{0:2}`, but that's getting a little ugly.)
--
Matthew
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-proposals/.
.
Author: Matthew Woehlke <mwoehlke.floss@gmail.com>
Date: Mon, 15 Feb 2016 10:54:41 -0500
Raw View
On 2016-02-13 03:44, Oliver Kowalke wrote:
> 016-02-13 1:28 GMT+01:00 Arthur O'Dwyer:
>> Also, of course, head(x) should logically return get<0>(x), not some weird
>> synonym for reverse(tail(reverse(x))).
>
> head(x) should return the part from the source tuple's head that fits into
> tuple x, same applies to tail(x)
Where source == tpl and x == tpl1, correct?
The problem is, the implementation for that has to look something like:
template <typename... types>
head_helper head(tuple<types...>& dst) { return {dst}; }
template <typename... types>
class head_helper
{
head_heler(tuple<types...> dst) : dst{dst} {}
template <typename... extra>
tuple<types...>& operator=(tuple<types..., extra...> const& src);
// implementation details elided
tuple<types...>& dst;
};
....and similar for `tail`.
> tuple ~... and tuple [:] require a language modification - but I need a
> solution now; so I've written head()/tail() (even if the naming is not
> perfect).
Then proposing a standard library modification is not going to help you
either; in both cases, you'll need to implement a work-around until at
least C++20. General splicing (i.e. `[:]`) can do the same tasks as your
proposed library features, but it does them *better* (not limited to
std::tuple), and it does *a whole lot more*.
--
Matthew
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-proposals/.
.
Author: Oliver Kowalke <oliver.kowalke@gmail.com>
Date: Mon, 15 Feb 2016 20:12:25 +0100
Raw View
--001a11c182ae373722052bd3cd68
Content-Type: text/plain; charset=UTF-8
2016-02-15 16:54 GMT+01:00 Matthew Woehlke <mwoehlke.floss@gmail.com>:
>
> Then proposing a standard library modification is not going to help you
> either; in both cases, you'll need to implement a work-around until at
> least C++20.
actually I was asking for an existing proposal - but I couldn't found one
> General splicing (i.e. `[:]`) can do the same tasks as your
> proposed library features, but it does them *better* (not limited to
> std::tuple), and it does *a whole lot more*.
>
the '[:] ' - syntax looks ugly for me - I would prefer a library solution
(which could support
std::array too).
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-proposals/.
--001a11c182ae373722052bd3cd68
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><div class=3D"gmail_extra"><div class=3D"gmail_quote">2016=
-02-15 16:54 GMT+01:00 Matthew Woehlke <span dir=3D"ltr"><<a href=3D"mai=
lto:mwoehlke.floss@gmail.com" target=3D"_blank">mwoehlke.floss@gmail.com</a=
>></span>:<br><blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8=
ex;border-left:1px #ccc solid;padding-left:1ex"><span class=3D""><br>
</span>Then proposing a standard library modification is not going to help =
you<br>
either; in both cases, you'll need to implement a work-around until at<=
br>
least C++20.</blockquote><div><br></div><div>actually I was asking for an e=
xisting proposal - but I couldn't found one<br></div><div>=C2=A0</div><=
blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1px=
#ccc solid;padding-left:1ex">General splicing (i.e. `[:]`) can do the same=
tasks as your<br>
proposed library features, but it does them *better* (not limited to<br>
std::tuple), and it does *a whole lot more*.<br></blockquote></div><br></di=
v><div class=3D"gmail_extra">the '[:] ' - syntax looks ugly for me =
- I would prefer a library solution (which could support<br></div><div clas=
s=3D"gmail_extra">std::array too).<br></div></div>
<p></p>
-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
Visit this group at <a href=3D"https://groups.google.com/a/isocpp.org/group=
/std-proposals/">https://groups.google.com/a/isocpp.org/group/std-proposals=
/</a>.<br />
--001a11c182ae373722052bd3cd68--
.
Author: "Arthur O'Dwyer" <arthur.j.odwyer@gmail.com>
Date: Mon, 15 Feb 2016 12:54:58 -0800
Raw View
--001a1147476cce59d5052bd53af8
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
On Mon, Feb 15, 2016 at 7:54 AM, Matthew Woehlke <mwoehlke.floss@gmail.com>
wrote:
> On 2016-02-12 19:28, Arthur O'Dwyer wrote:
>> I think maybe Oliver was trying to say that
>>
>> tuple<int, string, string, double> tpl { -1, "abc", "xyz", .5 };
>> tuple<string, string, double> tpl1;
>> tpl1 =3D tail(tpl); // Python: tpl1 =3D tpl[1:]
>> tail(tpl) =3D tpl1; // Python: tpl[1:] =3D tpl1
>>
>> should both work, because tail() should return a tuple of references
>> instead of a tuple of values.
>
> No, that's definitely *not* how I understood it. See Vicente's reply.
Yep, I was definitely wrong in my interpretation of what Oliver meant. My
standard for "no way, he couldn't possibly mean..." was set too high. ;)
> Actually, thinking about it, `splice` *might* be useful enough to keep
> as a function in its own right:
>
> template <typename... Tuples>
> splice(Tuples&... tuples)
> {
> return std::tie(([:]tuples...)...);
> }
Isn't this (concatenation of a list of tuples) just tuple_cat?
http://en.cppreference.com/w/cpp/utility/tuple/tuple_cat
The missing "primitive" IMHO would be "take a tuple-like and apply
std::ref() to each argument, creating a tuple of references"; which could
be spelled either
std::tie(x~...)
or
std::make_tuple(std::ref(x~)...)
> (Bonus points: would the above syntax actually work? What syntax *would*
> work? The goal is: `get<0>(a), ... get<A>(a), get<0>(b), ... get<B>(b),
> ...`.)
Yes, I think the syntax above would work (modulo my continued objection
that [:], being a prefix operator, logically should not bind tighter than
the postfix operator ...; and modulo the trivial missing auto). However,
oh god, let's not encourage such brain-twisting code.
Assuming I'm understanding correctly, the weirdness here is that
packness "nests" or "stacks", and therefore pattern expressions in the new
regime have to be evaluated "on a stack", kind of like type definitions.
std::tie((tuples~...)...)
tuples is the name of a pack, and therefore it is also a pattern of
"packness" 1.
The ~ operator "adds packness" to the expression. Therefore,
tuples~ is a pattern of packness 2.
tuples~... DOES NOT expand the pattern tuples~ into tuple0~, tuple1~,
tuple2~, because patterns of packness >1 are never expanded right away.
Instead, ... "subtracts packness" from the expression, so that tuples~...
is itself a pattern of packness 1. Expanding it would yield tuple0~...,
tuple1~..., tuple2~....
Finally, (tuples~...)... applies ... to a pattern of packness 1,
yielding tuple0~...,
tuple1~..., tuple2~.... Each of these expressions consists of ... applied
to a pattern of packness 1, so they're all expanded, to yield the result we
want.
I think this concept of "packness >1" would be completely new to C++.
There's currently a place in the grammar where ...... is legal, but it's
not inside expressions; it's a dumb interaction between packs and C-style
variadic functions.
http://stackoverflow.com/questions/27594731/what-are-the-6-dots-in-template=
-parameter-packs
I've been trying to figure out whether "column-major" catting
(basically tuple_cat(tuple_zip(tuple0,
tuple1, tuple2)~...)) can be expressed compactly in tilde-notation /
[:]-notation.
I'm pretty sure it can't, but it's *really* hard to wrap my head around.
Note that you may assume tuple0, tuple1, and tuple2 all have the same size.
>> In general, I think that the C++ standard library is woefully lacking in
>> tuple manipulators... but rather than proposing new tuple manipulators
(of
>> which there could be a million: zip, fold, map, car, cdr, reverse,...),
we
>> should be trying to give people the ability to express those manipulator=
s
>> natively in the language, via something like Matthew's [:] notation or m=
y
>> ~... notation.
>
> ...and this thread is a great example of the superiority of `[:]` ;-).
> (Because it's not *just* `[:]`, it's `[A:B]` where both of `A` and `B`
> are optional. That's harder to do with `~`... I suppose you could write
> something like `tpl~{0:2}`, but that's getting a little ugly.)
Personally I'd just do it with
std::tuple_slice<0,2>(tpl)~
:) Keep in mind that I don't see "slicing" as a primitive operation; I
think slicing can be done efficiently with a library solution (which is to
say, it doesn't add any new expressiveness to the language).
Tuple-unpacking-into-packs, OTOH, definitely adds expressiveness.
(I'm assuming that in the new regime, all the tuple helpers, such as
tuple_cat and tuple_slice and tuple_zip and whatnot, would perfectly
forward all their arguments through to the result, just like
std::forward_as_tuple. This is not currently the case for C++14's
std::tuple_cat. I don't understand why not. The proposal for std::tuple_cat
was
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2299.html
which doesn't mention perfect forwarding as a concern; possibly the
proposal predated the spread of perfect forwarding as a common pattern.)
=E2=80=93Arthur
--=20
---=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-propos=
als/.
--001a1147476cce59d5052bd53af8
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">On Mon, Feb 15, 2016 at 7:54 AM, Matthew Woehlke <<a hr=
ef=3D"mailto:mwoehlke.floss@gmail.com">mwoehlke.floss@gmail.com</a>> wro=
te:<br>> On 2016-02-12 19:28, Arthur O'Dwyer wrote:<br>>> I th=
ink maybe Oliver was trying to say that<br>>><br>>> =C2=A0 =C2=
=A0 tuple<int, string, string, double> tpl { -1, "abc", &qu=
ot;xyz", .5 };<br>>> =C2=A0 =C2=A0 tuple<string, string, doub=
le> tpl1;<br>>> =C2=A0 =C2=A0 tpl1 =3D tail(tpl); =C2=A0 =C2=A0// =
Python: tpl1 =3D tpl[1:]<br>>> =C2=A0 =C2=A0 tail(tpl) =3D tpl1; =C2=
=A0 =C2=A0// Python: tpl[1:] =3D tpl1<br>>><br>>> should both w=
ork, because tail() should return a tuple of references<br>>> instead=
of a tuple of values.<br>><br>> No, that's definitely *not* how =
I understood it. See Vicente's reply.<br><br>Yep, I was definitely wron=
g in my interpretation of what Oliver meant. My standard for "no way, =
he couldn't possibly mean..." was set too high. ;)<br><br>> Act=
ually, thinking about it, `splice` *might* be useful enough to keep<br>>=
as a function in its own right:<br>><br>> =C2=A0 template <typena=
me... Tuples><br>> =C2=A0 splice(Tuples&... tuples)<br>> =C2=
=A0 {<br>> =C2=A0 =C2=A0 return std::tie(([:]tuples...)...);<br>> =C2=
=A0 }<br><br>Isn't this (concatenation of a list of tuples) just tuple_=
cat?<br><a href=3D"http://en.cppreference.com/w/cpp/utility/tuple/tuple_cat=
">http://en.cppreference.com/w/cpp/utility/tuple/tuple_cat<br></a><br>The m=
issing "primitive" IMHO would be "take a tuple-like and appl=
y std::ref() to each argument, creating a tuple of references"; which =
could be spelled either<div><font face=3D"monospace, monospace">=C2=A0 =C2=
=A0 std::tie(x~...)</font></div><div>or</div><div><font face=3D"monospace, =
monospace">=C2=A0 =C2=A0 std::make_tuple(std::ref(x~)...)</font></div><div>=
<br></div><div>> (Bonus points: would the above syntax actually work? Wh=
at syntax *would*<br>> work? The goal is: `get<0>(a), ... get<A=
>(a), get<0>(b), ... get<B>(b),<br>> ...`.)</div><div><br=
></div><div>Yes, I think the syntax above would work (modulo my continued o=
bjection that <font face=3D"monospace, monospace">[:]</font>, being a prefi=
x operator, logically should not bind tighter than the postfix operator <fo=
nt face=3D"monospace, monospace">...</font>; and modulo the trivial missing=
<font face=3D"monospace, monospace">auto</font>).=C2=A0 However, oh god, l=
et's not encourage such brain-twisting code.</div><div><br></div><div>A=
ssuming I'm understanding correctly, the weirdness here is that packnes=
s=C2=A0"nests" or "stacks", and therefore pattern expre=
ssions in the new regime have to be evaluated "on a stack", kind =
of like type definitions.</div><div><br></div><div><font face=3D"monospace,=
monospace">=C2=A0 =C2=A0 std::tie((tuples~...)...)</font></div><div><br></=
div><div><font face=3D"monospace, monospace">tuples</font> is the name of a=
pack, and therefore it is also a pattern of "packness" 1.</div><=
div>The <font face=3D"monospace, monospace">~</font> operator "adds pa=
ckness" to the expression. Therefore,</div><div><font face=3D"monospac=
e, monospace">tuples~</font> is a pattern of packness 2.</div><div><font fa=
ce=3D"monospace, monospace">tuples~...</font> DOES NOT expand the pattern <=
font face=3D"monospace, monospace">tuples~</font> into <font face=3D"monosp=
ace, monospace">tuple0~, tuple1~, tuple2~</font>, because patterns of packn=
ess >1 are never expanded right away. Instead, ... "subtracts packn=
ess" from the expression, so that <font face=3D"monospace, monospace">=
tuples~...</font> is itself a pattern of packness 1. Expanding it would yie=
ld <font face=3D"monospace, monospace">tuple0~..., tuple1~..., tuple2~...</=
font>.<br></div><div>Finally, <font face=3D"monospace, monospace">(tuples~.=
...)...</font> applies <font face=3D"monospace, monospace">...</font> to a p=
attern of packness 1, yielding <font face=3D"monospace, monospace">tuple0~.=
..., tuple1~..., tuple2~...</font>. Each of these expressions consists of <f=
ont face=3D"monospace, monospace">...</font> applied to a pattern of packne=
ss 1, so they're all expanded, to yield the result we want.</div><div><=
br></div><div>I think this concept of "packness >1" would be c=
ompletely new to C++. There's currently a place in the grammar where <f=
ont face=3D"monospace, monospace">......</font> is legal, but it's not =
inside expressions; it's a dumb interaction between packs and C-style v=
ariadic functions.</div><div><a href=3D"http://stackoverflow.com/questions/=
27594731/what-are-the-6-dots-in-template-parameter-packs">http://stackoverf=
low.com/questions/27594731/what-are-the-6-dots-in-template-parameter-packs<=
br></a></div><div><br></div><div>I've been trying to figure out whether=
"column-major" catting (basically <font face=3D"monospace, monos=
pace">tuple_cat(tuple_zip(tuple0, tuple1, tuple2)~...)</font>) can be expre=
ssed compactly in tilde-notation / <font face=3D"monospace, monospace">[:]<=
/font>-notation. I'm pretty sure it can't, but it's <i>really</=
i> hard to wrap my head around. Note that you may assume <font face=3D"mono=
space, monospace">tuple0</font>, <font face=3D"monospace, monospace">tuple1=
</font>, and <font face=3D"monospace, monospace">tuple2</font> all have the=
same size.</div><div><br></div><div><br></div><div>>> In general, I =
think that the C++ standard library is woefully lacking in<br>>> tupl=
e manipulators... but rather than proposing new tuple manipulators (of<br>&=
gt;> which there could be a million: zip, fold, map, car, cdr, reverse,.=
...), we<br>>> should be trying to give people the ability to express =
those manipulators<br>>> natively in the language, via something like=
Matthew's [:] notation or my<br>>> ~... notation.<br>><br>>=
; ...and this thread is a great example of the superiority of `[:]` ;-).<br=
>> (Because it's not *just* `[:]`, it's `[A:B]` where both of `A=
` and `B`<br>> are optional. That's harder to do with `~`... I suppo=
se you could write<br>> something like `tpl~{0:2}`, but that's getti=
ng a little ugly.)<br><br></div><div>Personally I'd just do it with</di=
v><div><br></div><div><font face=3D"monospace, monospace">=C2=A0 =C2=A0 std=
::tuple_slice<0,2>(tpl)~</font></div><div><br></div><div>:) =C2=A0Kee=
p in mind that I don't see "slicing" as a primitive operation=
; I think slicing can be done efficiently with a library solution (which is=
to say, it doesn't add any new expressiveness to the language). Tuple-=
unpacking-into-packs, OTOH, definitely adds expressiveness.</div><div><br><=
/div><div>(I'm assuming that in the new regime, all the tuple helpers, =
such as tuple_cat and tuple_slice and tuple_zip and whatnot, would perfectl=
y forward all their arguments through to the result, just like <font face=
=3D"monospace, monospace">std::forward_as_tuple</font>. This is not current=
ly the case for C++14's <font face=3D"monospace, monospace">std::tuple_=
cat</font>. I don't understand why not. The proposal for std::tuple_cat=
was</div><div><a href=3D"http://www.open-std.org/jtc1/sc22/wg21/docs/paper=
s/2007/n2299.html">http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/=
n2299.html</a></div><div>which doesn't mention perfect forwarding as a =
concern; possibly the proposal predated the spread of perfect forwarding as=
a common pattern.)</div><div><br></div><div>=E2=80=93Arthur</div></div>
<p></p>
-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
Visit this group at <a href=3D"https://groups.google.com/a/isocpp.org/group=
/std-proposals/">https://groups.google.com/a/isocpp.org/group/std-proposals=
/</a>.<br />
--001a1147476cce59d5052bd53af8--
.
Author: Matthew Woehlke <mwoehlke.floss@gmail.com>
Date: Mon, 15 Feb 2016 16:40:34 -0500
Raw View
On 2016-02-15 15:54, Arthur O'Dwyer wrote:
> On Mon, Feb 15, 2016 at 7:54 AM, Matthew Woehlke wrote:
>> On 2016-02-12 19:28, Arthur O'Dwyer wrote:
>>> I think maybe Oliver was trying to say that
>>>
>>> tuple<int, string, string, double> tpl { -1, "abc", "xyz", .5 };
>>> tuple<string, string, double> tpl1;
>>> tpl1 = tail(tpl); // Python: tpl1 = tpl[1:]
>>> tail(tpl) = tpl1; // Python: tpl[1:] = tpl1
>>>
>>> should both work, because tail() should return a tuple of references
>>> instead of a tuple of values.
>>
>> No, that's definitely *not* how I understood it. See Vicente's reply.
>
> Yep, I was definitely wrong in my interpretation of what Oliver meant. My
> standard for "no way, he couldn't possibly mean..." was set too high. ;)
:-D
>> Actually, thinking about it, `splice` *might* be useful enough to keep
>> as a function in its own right:
>>
>> template <typename... Tuples>
>> splice(Tuples&... tuples)
>> {
>> return std::tie(([:]tuples...)...);
>> }
>
> Isn't this (concatenation of a list of tuples) just tuple_cat?
> http://en.cppreference.com/w/cpp/utility/tuple/tuple_cat
If that is extended to take *tuple-likes*, then sure :-). (It isn't
clear from the link, but I assume currently it only takes `std::tuple`s.
I don't see why extending it would be a problem.)
>> (Bonus points: would the above syntax actually work? What syntax *would*
>> work? The goal is: `get<0>(a), ... get<A>(a), get<0>(b), ... get<B>(b),
>> ...`.)
>
> Yes, I think the syntax above would work (modulo [...] the trivial
> missing auto).
Oops :-).
> However, oh god, let's not encourage such brain-twisting code.
Well, it would be in the standard library, at least :-) (i.e. as opposed
to user code).
> Assuming I'm understanding correctly, the weirdness here is that
> packness "nests" or "stacks", and therefore pattern expressions in the new
> regime have to be evaluated "on a stack", kind of like type definitions.
>
> [snip detailed explanation]
Yes, exactly.
>> ...and this thread is a great example of the superiority of `[:]` ;-).
>> (Because it's not *just* `[:]`, it's `[A:B]` where both of `A` and `B`
>> are optional. That's harder to do with `~`... I suppose you could write
>> something like `tpl~{0:2}`, but that's getting a little ugly.)
>
> Personally I'd just do it with
>
> std::tuple_slice<0,2>(tpl)~
>
> :) Keep in mind that I don't see "slicing" as a primitive operation; I
> think slicing can be done efficiently with a library solution (which is to
> say, it doesn't add any new expressiveness to the language).
What happens when you want to do this?
auto {x, y} = some_3d_point; // don't care about z
With tuple_slice:
auto {x, y} = tuple_slice<0,2>(make_tuple(some_3d_point~...));
With my `[:]`:
auto {x, y} = {[:2]some_3d_point...};
(Possibly the `{}`s and `...` could be optional in the above.)
That involves a temporary. (Now, obviously there are totally different
ways to accomplish the same thing that may be better, but I feel like
`[:2]` is the most terse. Also, it means we don't need to bother with
assignment-unpacking syntax for that case.)
Oh! Another reason why we might want slicing:
template <typename Arg> auto sum(Arg arg) { return arg; }
template <typename... Args> auto sum(Args... args)
{
return sum([0]{args...}) + sum([1:]{args...}...);
}
(Ignore that a fold expression would do this better. The point is that
this allows writing recursive variadic-template functions without the
ugly 'Head head, Tail... tail' style parameter lists.)
For bonus points, if we allow `[:]` to directly slice parameter packs,
we can simplify:
return sum([0]args) + sum(([1:]args)...);
// Notes:
[0]args; // single value, not a parameter pack
sizeof...([0]args); // illegal; not a parameter pack
[:]args; // same as 'args'
[:1]args; // still a parameter pack
[0:1]args; // also still a parameter pack
([0:1]args...); // same as '[0]args' (or error if sizeof...(args)==0)
sizeof...([:1]args); // == max(0, sizeof...(args) - 1)
--
Matthew
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-proposals/.
.
Author: Louis Dionne <ldionne.2@gmail.com>
Date: Mon, 15 Feb 2016 15:22:24 -0800 (PST)
Raw View
------=_Part_1342_1859172242.1455578544313
Content-Type: multipart/alternative;
boundary="----=_Part_1343_1172000991.1455578544314"
------=_Part_1343_1172000991.1455578544314
Content-Type: text/plain; charset=UTF-8
Hi,
I'd like to quickly chime in to drop a link to Boost.Hana [1] (which I'm
the
author of, for full disclosure). There seems to be quite a bit of
discussion
about adding language features to manipulate packs and tuples, when a lot
of
this could be done in a library. Hana's purpose is specifically to
manipulate
tuples (and more generally heterogeneous containers) by providing std-like
algorithms to operate on them.
Reading the comments here, I just don't see the need for a new language
feature for manipulating parameter packs. Instead, I think we need proper
standard library features to manipulate tuples with a high level of
abstraction. If properly designed, that could be much more flexible than
a language feature in the long term, when we realize that we're missing
something else. Just to give you a glimpse: how would you reverse a
parameter
pack? How would you sort a parameter pack based on a compile-time
predicate?
I don't see how these slicing proposals are of any help, yet this is a very
real use case for metaprogramming.
Instead, I think we need to carefully design a STL for metaprogramming
(with
customization points where it makes sense), and then let users build on top
of that. And if you're worried about compile-times being too long with a
library-based approach, this can be tackled with a few well-chosen compiler
intrinsics (see this article [2]).
Regards,
Louis Dionne
[1]: https://github.com/boostorg/hana
[2]: http://ldionne.com/2015/11/29/efficient-parameter-pack-indexing/
On Monday, 15 February 2016 16:40:53 UTC-5, Matthew Woehlke wrote:
>
> On 2016-02-15 15:54, Arthur O'Dwyer wrote:
> > On Mon, Feb 15, 2016 at 7:54 AM, Matthew Woehlke wrote:
> >> On 2016-02-12 19:28, Arthur O'Dwyer wrote:
> >>> I think maybe Oliver was trying to say that
> >>>
> >>> tuple<int, string, string, double> tpl { -1, "abc", "xyz", .5 };
> >>> tuple<string, string, double> tpl1;
> >>> tpl1 = tail(tpl); // Python: tpl1 = tpl[1:]
> >>> tail(tpl) = tpl1; // Python: tpl[1:] = tpl1
> >>>
> >>> should both work, because tail() should return a tuple of references
> >>> instead of a tuple of values.
> >>
> >> No, that's definitely *not* how I understood it. See Vicente's reply.
> >
> > Yep, I was definitely wrong in my interpretation of what Oliver meant.
> My
> > standard for "no way, he couldn't possibly mean..." was set too high. ;)
>
> :-D
>
> >> Actually, thinking about it, `splice` *might* be useful enough to keep
> >> as a function in its own right:
> >>
> >> template <typename... Tuples>
> >> splice(Tuples&... tuples)
> >> {
> >> return std::tie(([:]tuples...)...);
> >> }
> >
> > Isn't this (concatenation of a list of tuples) just tuple_cat?
> > http://en.cppreference.com/w/cpp/utility/tuple/tuple_cat
>
> If that is extended to take *tuple-likes*, then sure :-). (It isn't
> clear from the link, but I assume currently it only takes `std::tuple`s.
> I don't see why extending it would be a problem.)
>
> >> (Bonus points: would the above syntax actually work? What syntax
> *would*
> >> work? The goal is: `get<0>(a), ... get<A>(a), get<0>(b), ... get<B>(b),
> >> ...`.)
> >
> > Yes, I think the syntax above would work (modulo [...] the trivial
> > missing auto).
>
> Oops :-).
>
> > However, oh god, let's not encourage such brain-twisting code.
>
> Well, it would be in the standard library, at least :-) (i.e. as opposed
> to user code).
>
> > Assuming I'm understanding correctly, the weirdness here is that
> > packness "nests" or "stacks", and therefore pattern expressions in the
> new
> > regime have to be evaluated "on a stack", kind of like type definitions.
> >
> > [snip detailed explanation]
>
> Yes, exactly.
>
> >> ...and this thread is a great example of the superiority of `[:]` ;-).
> >> (Because it's not *just* `[:]`, it's `[A:B]` where both of `A` and `B`
> >> are optional. That's harder to do with `~`... I suppose you could write
> >> something like `tpl~{0:2}`, but that's getting a little ugly.)
> >
> > Personally I'd just do it with
> >
> > std::tuple_slice<0,2>(tpl)~
> >
> > :) Keep in mind that I don't see "slicing" as a primitive operation; I
> > think slicing can be done efficiently with a library solution (which is
> to
> > say, it doesn't add any new expressiveness to the language).
>
> What happens when you want to do this?
>
> auto {x, y} = some_3d_point; // don't care about z
>
> With tuple_slice:
>
> auto {x, y} = tuple_slice<0,2>(make_tuple(some_3d_point~...));
>
> With my `[:]`:
>
> auto {x, y} = {[:2]some_3d_point...};
>
> (Possibly the `{}`s and `...` could be optional in the above.)
>
> That involves a temporary. (Now, obviously there are totally different
> ways to accomplish the same thing that may be better, but I feel like
> `[:2]` is the most terse. Also, it means we don't need to bother with
> assignment-unpacking syntax for that case.)
>
>
> Oh! Another reason why we might want slicing:
>
> template <typename Arg> auto sum(Arg arg) { return arg; }
> template <typename... Args> auto sum(Args... args)
> {
> return sum([0]{args...}) + sum([1:]{args...}...);
> }
>
> (Ignore that a fold expression would do this better. The point is that
> this allows writing recursive variadic-template functions without the
> ugly 'Head head, Tail... tail' style parameter lists.)
>
> For bonus points, if we allow `[:]` to directly slice parameter packs,
> we can simplify:
>
> return sum([0]args) + sum(([1:]args)...);
>
> // Notes:
> [0]args; // single value, not a parameter pack
> sizeof...([0]args); // illegal; not a parameter pack
>
> [:]args; // same as 'args'
> [:1]args; // still a parameter pack
> [0:1]args; // also still a parameter pack
> ([0:1]args...); // same as '[0]args' (or error if sizeof...(args)==0)
> sizeof...([:1]args); // == max(0, sizeof...(args) - 1)
>
> --
> Matthew
>
>
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-proposals/.
------=_Part_1343_1172000991.1455578544314
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><div><div>Hi,</div><div><br></div><div>I'd like to qui=
ckly chime in to drop a link to Boost.Hana [1] (which I'm the=C2=A0</di=
v><div>author of, for full disclosure). There seems to be quite a bit of di=
scussion=C2=A0</div><div>about adding language features to manipulate packs=
and tuples, when a lot of=C2=A0</div><div>this could be done in a library.=
Hana's purpose is specifically to manipulate=C2=A0</div><div>tuples (a=
nd more generally heterogeneous containers) by providing std-like=C2=A0</di=
v><div>algorithms to operate on them.=C2=A0</div><div><br></div><div>Readin=
g the comments here, I just don't see the need for a new language=C2=A0=
</div><div>feature for manipulating parameter packs. Instead, I think we ne=
ed proper=C2=A0</div><div>standard library features to manipulate tuples wi=
th a high level of=C2=A0</div><div>abstraction. If properly designed, that =
could be much more flexible than=C2=A0</div><div>a language feature in the =
long term, when we realize that we're missing=C2=A0</div><div>something=
else. Just to give you a glimpse: how would you reverse a parameter=C2=A0<=
/div><div>pack? How would you sort a parameter pack based on a compile-time=
predicate?=C2=A0</div><div>I don't see how these slicing proposals are=
of any help, yet this is a very=C2=A0</div><div>real use case for metaprog=
ramming.=C2=A0</div><div><br></div><div>Instead, I think we need to careful=
ly design a STL for metaprogramming (with=C2=A0</div><div>customization poi=
nts where it makes sense), and then let users build on top=C2=A0</div><div>=
of that. And if you're worried about compile-times being too long with =
a=C2=A0</div><div>library-based approach, this can be tackled with a few we=
ll-chosen compiler=C2=A0</div><div>intrinsics (see this article [2]).</div>=
<div><br></div><div>Regards,</div><div>Louis Dionne</div><div><br></div><di=
v>[1]: https://github.com/boostorg/hana</div><div>[2]: http://ldionne.com/2=
015/11/29/efficient-parameter-pack-indexing/</div></div><div><br></div><br>=
On Monday, 15 February 2016 16:40:53 UTC-5, Matthew Woehlke wrote:<blockqu=
ote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-left=
: 1px #ccc solid;padding-left: 1ex;">On 2016-02-15 15:54, Arthur O'Dwye=
r wrote:
<br>> On Mon, Feb 15, 2016 at 7:54 AM, Matthew Woehlke wrote:
<br>>> On 2016-02-12 19:28, Arthur O'Dwyer wrote:
<br>>>> I think maybe Oliver was trying to say that
<br>>>>
<br>>>> =C2=A0 =C2=A0 tuple<int, string, string, double> tpl=
{ -1, "abc", "xyz", .5 };
<br>>>> =C2=A0 =C2=A0 tuple<string, string, double> tpl1;
<br>>>> =C2=A0 =C2=A0 tpl1 =3D tail(tpl); =C2=A0 =C2=A0// Python: =
tpl1 =3D tpl[1:]
<br>>>> =C2=A0 =C2=A0 tail(tpl) =3D tpl1; =C2=A0 =C2=A0// Python: =
tpl[1:] =3D tpl1
<br>>>>
<br>>>> should both work, because tail() should return a tuple of =
references
<br>>>> instead of a tuple of values.
<br>>>
<br>>> No, that's definitely *not* how I understood it. See Vicen=
te's reply.
<br>>=20
<br>> Yep, I was definitely wrong in my interpretation of what Oliver me=
ant. My
<br>> standard for "no way, he couldn't possibly mean..." =
was set too high. ;)
<br>
<br>:-D
<br>
<br>>> Actually, thinking about it, `splice` *might* be useful enough=
to keep
<br>>> as a function in its own right:
<br>>>
<br>>> =C2=A0 template <typename... Tuples>
<br>>> =C2=A0 splice(Tuples&... tuples)
<br>>> =C2=A0 {
<br>>> =C2=A0 =C2=A0 return std::tie(([:]tuples...)...);
<br>>> =C2=A0 }
<br>>=20
<br>> Isn't this (concatenation of a list of tuples) just tuple_cat?
<br>> <a href=3D"http://en.cppreference.com/w/cpp/utility/tuple/tuple_ca=
t" target=3D"_blank" rel=3D"nofollow" onmousedown=3D"this.href=3D'http:=
//www.google.com/url?q\75http%3A%2F%2Fen.cppreference.com%2Fw%2Fcpp%2Futili=
ty%2Ftuple%2Ftuple_cat\46sa\75D\46sntz\0751\46usg\75AFQjCNHovt3grlm5dc6yUOF=
4RcjFOi1p3g';return true;" onclick=3D"this.href=3D'http://www.googl=
e.com/url?q\75http%3A%2F%2Fen.cppreference.com%2Fw%2Fcpp%2Futility%2Ftuple%=
2Ftuple_cat\46sa\75D\46sntz\0751\46usg\75AFQjCNHovt3grlm5dc6yUOF4RcjFOi1p3g=
';return true;">http://en.cppreference.com/w/<wbr>cpp/utility/tuple/tup=
le_cat</a>
<br>
<br>If that is extended to take *tuple-likes*, then sure :-). (It isn't
<br>clear from the link, but I assume currently it only takes `std::tuple`s=
..
<br>I don't see why extending it would be a problem.)
<br>
<br>>> (Bonus points: would the above syntax actually work? What synt=
ax *would*
<br>>> work? The goal is: `get<0>(a), ... get<A>(a), get&=
lt;0>(b), ... get<B>(b),
<br>>> ...`.)
<br>>=20
<br>> Yes, I think the syntax above would work (modulo [...] the trivial
<br>> missing auto).
<br>
<br>Oops :-).
<br>
<br>> However, oh god, let's not encourage such brain-twisting code.
<br>
<br>Well, it would be in the standard library, at least :-) (i.e. as oppose=
d
<br>to user code).
<br>
<br>> Assuming I'm understanding correctly, the weirdness here is th=
at
<br>> packness "nests" or "stacks", and therefore pa=
ttern expressions in the new
<br>> regime have to be evaluated "on a stack", kind of like t=
ype definitions.
<br>>=20
<br>> [snip detailed explanation]
<br>
<br>Yes, exactly.
<br>
<br>>> ...and this thread is a great example of the superiority of `[=
:]` ;-).
<br>>> (Because it's not *just* `[:]`, it's `[A:B]` where bot=
h of `A` and `B`
<br>>> are optional. That's harder to do with `~`... I suppose yo=
u could write
<br>>> something like `tpl~{0:2}`, but that's getting a little ug=
ly.)
<br>>=20
<br>> Personally I'd just do it with
<br>>=20
<br>> =C2=A0 =C2=A0 std::tuple_slice<0,2>(tpl)~
<br>>=20
<br>> :) =C2=A0Keep in mind that I don't see "slicing" as =
a primitive operation; I
<br>> think slicing can be done efficiently with a library solution (whi=
ch is to
<br>> say, it doesn't add any new expressiveness to the language).
<br>
<br>What happens when you want to do this?
<br>
<br>=C2=A0 auto {x, y} =3D some_3d_point; // don't care about z
<br>
<br>With tuple_slice:
<br>
<br>=C2=A0 auto {x, y} =3D tuple_slice<0,2>(make_tuple(<wbr>some_3d_p=
oint~...));
<br>
<br>With my `[:]`:
<br>
<br>=C2=A0 auto {x, y} =3D {[:2]some_3d_point...};
<br>
<br>(Possibly the `{}`s and `...` could be optional in the above.)
<br>
<br>That involves a temporary. (Now, obviously there are totally different
<br>ways to accomplish the same thing that may be better, but I feel like
<br>`[:2]` is the most terse. Also, it means we don't need to bother wi=
th
<br>assignment-unpacking syntax for that case.)
<br>
<br>
<br>Oh! Another reason why we might want slicing:
<br>
<br>=C2=A0 template <typename Arg> auto sum(Arg arg) { return arg; }
<br>=C2=A0 template <typename... Args> auto sum(Args... args)
<br>=C2=A0 {
<br>=C2=A0 =C2=A0 return sum([0]{args...}) + sum([1:]{args...}...);
<br>=C2=A0 }
<br>
<br>(Ignore that a fold expression would do this better. The point is that
<br>this allows writing recursive variadic-template functions without the
<br>ugly 'Head head, Tail... tail' style parameter lists.)
<br>
<br>For bonus points, if we allow `[:]` to directly slice parameter packs,
<br>we can simplify:
<br>
<br>=C2=A0 return sum([0]args) + sum(([1:]args)...);
<br>
<br>=C2=A0 // Notes:
<br>=C2=A0 [0]args; // single value, not a parameter pack
<br>=C2=A0 sizeof...([0]args); // illegal; not a parameter pack
<br>
<br>=C2=A0 [:]args; // same as 'args'
<br>=C2=A0 [:1]args; // still a parameter pack
<br>=C2=A0 [0:1]args; // also still a parameter pack
<br>=C2=A0 ([0:1]args...); // same as '[0]args' (or error if sizeof=
....(args)=3D=3D0)
<br>=C2=A0 sizeof...([:1]args); // =3D=3D max(0, sizeof...(args) - 1)
<br>
<br>--=20
<br>Matthew
<br>
<br></blockquote></div>
<p></p>
-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
Visit this group at <a href=3D"https://groups.google.com/a/isocpp.org/group=
/std-proposals/">https://groups.google.com/a/isocpp.org/group/std-proposals=
/</a>.<br />
------=_Part_1343_1172000991.1455578544314--
------=_Part_1342_1859172242.1455578544313--
.
Author: Nicol Bolas <jmckesson@gmail.com>
Date: Mon, 15 Feb 2016 18:10:51 -0800 (PST)
Raw View
------=_Part_6261_2015470513.1455588651748
Content-Type: multipart/alternative;
boundary="----=_Part_6262_334406376.1455588651749"
------=_Part_6262_334406376.1455588651749
Content-Type: text/plain; charset=UTF-8
On Monday, February 15, 2016 at 6:22:24 PM UTC-5, Louis Dionne wrote:
>
> Hi,
>
> I'd like to quickly chime in to drop a link to Boost.Hana [1] (which I'm
> the
> author of, for full disclosure). There seems to be quite a bit of
> discussion
> about adding language features to manipulate packs and tuples, when a lot
> of
> this could be done in a library. Hana's purpose is specifically to
> manipulate
> tuples (and more generally heterogeneous containers) by providing std-like
> algorithms to operate on them.
>
> Reading the comments here, I just don't see the need for a new language
> feature for manipulating parameter packs. Instead, I think we need proper
> standard library features to manipulate tuples with a high level of
> abstraction.
>
That's like saying, "Why do we need lambdas in the language? We have
Boost.Lambda!"
Indeed, I seem to recall Boost.Lambda being one of the impetuses for
getting language-based lambdas. BLL was basically *proof* that you couldn't
do lambdas as a library. It said, "Look, this is the best the language can
do as is: here's what you get, here's what you have to do to implement it,
here's how ugly user-code looks, and here are all of the places where it
breaks down".
In that regard, libraries like Fusion and Hana are perfect examples of why
tuple unpacking needs to be a *language* feature.
Show me the Hana code for this:
outer(inner([:]tpl)...)
This calls `inner` on each element of the tuple, then pipes the result into
the call to `outer`. It works exactly like parameter packs too, so if `tpl`
were a pack, you just drop the `[:]` syntax and it works.
Show me the Hana code for this:
auto x = inner([:]tpl) + ...;
This simply calls a function on each element of the tuple and takes the sum
of the results. Again, it works like parameter packs, so it reuses existing
knowledge.
Oh, and show me the Hana code for this:
struct Data
{
int i;
float f;
double d;
};
Data d = ...;
outer(inner([:]d)...);
It's the same as the first example, only using an aggregate.
It should also be noted that having compiler support for unpacking tuples
does not mean you can't also have additional library functions for help in
other cases. Sorting, reversing, etc could be library stuff, while the most
common cases are handled by the direct language feature.
> If properly designed, that could be much more flexible than
> a language feature in the long term, when we realize that we're missing
> something else. Just to give you a glimpse: how would you reverse a
> parameter
> pack? How would you sort a parameter pack based on a compile-time
> predicate?
> I don't see how these slicing proposals are of any help, yet this is a
> very
> real use case for metaprogramming.
>
> Instead, I think we need to carefully design a STL for metaprogramming
> (with
> customization points where it makes sense), and then let users build on
> top
> of that. And if you're worried about compile-times being too long with a
> library-based approach, this can be tackled with a few well-chosen
> compiler
> intrinsics (see this article [2]).
>
So instead of having language support for unpacking tuples, you want
language support for... some low-level stuff that can be used to build a
library?
No thanks; I'll take the simple and easy-to-use feature over the huge and
complex STL-like thing.
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-proposals/.
------=_Part_6262_334406376.1455588651749
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">On Monday, February 15, 2016 at 6:22:24 PM UTC-5, Louis Di=
onne wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left=
: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr"><d=
iv><div>Hi,</div><div><br></div><div>I'd like to quickly chime in to dr=
op a link to Boost.Hana [1] (which I'm the=C2=A0</div><div>author of, f=
or full disclosure). There seems to be quite a bit of discussion=C2=A0</div=
><div>about adding language features to manipulate packs and tuples, when a=
lot of=C2=A0</div><div>this could be done in a library. Hana's purpose=
is specifically to manipulate=C2=A0</div><div>tuples (and more generally h=
eterogeneous containers) by providing std-like=C2=A0</div><div>algorithms t=
o operate on them.=C2=A0</div><div><br></div><div>Reading the comments here=
, I just don't see the need for a new language=C2=A0</div><div>feature =
for manipulating parameter packs. Instead, I think we need proper=C2=A0</di=
v><div>standard library features to manipulate tuples with a high level of=
=C2=A0</div><div>abstraction.</div></div></div></blockquote><div><br>That&#=
39;s like saying, "Why do we need lambdas in the language? We have Boo=
st.Lambda!"<br><br>Indeed, I seem to recall Boost.Lambda being one of =
the impetuses for getting language-based lambdas. BLL was basically <i>proo=
f</i> that you couldn't do lambdas as a library. It said, "Look, t=
his is the best the language can do as is: here's what you get, here=
9;s what you have to do to implement it, here's how ugly user-code look=
s, and here are all of the places where it breaks down".<br><br>In tha=
t regard, libraries like Fusion and Hana are perfect examples of why tuple =
unpacking needs to be a <i>language</i> feature.<br><br>Show me the Hana co=
de for this:<br><br><div class=3D"prettyprint" style=3D"background-color: r=
gb(250, 250, 250); border-color: rgb(187, 187, 187); border-style: solid; b=
order-width: 1px; word-wrap: break-word;"><code class=3D"prettyprint"><div =
class=3D"subprettyprint"><span style=3D"color: #000;" class=3D"styled-by-pr=
ettify">outer</span><span style=3D"color: #660;" class=3D"styled-by-prettif=
y">(</span><span style=3D"color: #000;" class=3D"styled-by-prettify">inner<=
/span><span style=3D"color: #660;" class=3D"styled-by-prettify">([:]</span>=
<span style=3D"color: #000;" class=3D"styled-by-prettify">tpl</span><span s=
tyle=3D"color: #660;" class=3D"styled-by-prettify">)...)</span></div></code=
></div><br>This calls `inner` on each element of the tuple, then pipes the =
result into the call to `outer`. It works exactly like parameter packs too,=
so if `tpl` were a pack, you just drop the `[:]` syntax and it works.<br><=
br>Show me the Hana code for this:<br><br><div class=3D"prettyprint" style=
=3D"background-color: rgb(250, 250, 250); border-color: rgb(187, 187, 187);=
border-style: solid; border-width: 1px; word-wrap: break-word;"><code clas=
s=3D"prettyprint"><div class=3D"subprettyprint"><span style=3D"color: #008;=
" class=3D"styled-by-prettify">auto</span><span style=3D"color: #000;" clas=
s=3D"styled-by-prettify"> x </span><span style=3D"color: #660;" class=3D"st=
yled-by-prettify">=3D</span><span style=3D"color: #000;" class=3D"styled-by=
-prettify"> inner</span><span style=3D"color: #660;" class=3D"styled-by-pre=
ttify">([:]</span><span style=3D"color: #000;" class=3D"styled-by-prettify"=
>tpl</span><span style=3D"color: #660;" class=3D"styled-by-prettify">)</spa=
n><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span s=
tyle=3D"color: #660;" class=3D"styled-by-prettify">+</span><span style=3D"c=
olor: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #66=
0;" class=3D"styled-by-prettify">...;</span></div></code></div><br>This sim=
ply calls a function on each element of the tuple and takes the sum of the =
results. Again, it works like parameter packs, so it reuses existing knowle=
dge.<br><br>Oh, and show me the Hana code for this:<br><br><div class=3D"pr=
ettyprint" style=3D"background-color: rgb(250, 250, 250); border-color: rgb=
(187, 187, 187); border-style: solid; border-width: 1px; word-wrap: break-w=
ord;"><code class=3D"prettyprint"><div class=3D"subprettyprint"><span style=
=3D"color: #008;" class=3D"styled-by-prettify">struct</span><span style=3D"=
color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #6=
06;" class=3D"styled-by-prettify">Data</span><span style=3D"color: #000;" c=
lass=3D"styled-by-prettify"><br></span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">{</span><span style=3D"color: #000;" class=3D"style=
d-by-prettify"><br>=C2=A0 </span><span style=3D"color: #008;" class=3D"styl=
ed-by-prettify">int</span><span style=3D"color: #000;" class=3D"styled-by-p=
rettify"> i</span><span style=3D"color: #660;" class=3D"styled-by-prettify"=
>;</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br>=C2=
=A0 </span><span style=3D"color: #008;" class=3D"styled-by-prettify">float<=
/span><span style=3D"color: #000;" class=3D"styled-by-prettify"> f</span><s=
pan style=3D"color: #660;" class=3D"styled-by-prettify">;</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"><br>=C2=A0 </span><span styl=
e=3D"color: #008;" class=3D"styled-by-prettify">double</span><span style=3D=
"color: #000;" class=3D"styled-by-prettify"> d</span><span style=3D"color: =
#660;" class=3D"styled-by-prettify">;</span><span style=3D"color: #000;" cl=
ass=3D"styled-by-prettify"><br></span><span style=3D"color: #660;" class=3D=
"styled-by-prettify">};</span><span style=3D"color: #000;" class=3D"styled-=
by-prettify"><br><br></span><span style=3D"color: #606;" class=3D"styled-by=
-prettify">Data</span><span style=3D"color: #000;" class=3D"styled-by-prett=
ify"> d </span><span style=3D"color: #660;" class=3D"styled-by-prettify">=
=3D</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span=
><span style=3D"color: #660;" class=3D"styled-by-prettify">...;</span><span=
style=3D"color: #000;" class=3D"styled-by-prettify"><br>outer</span><span =
style=3D"color: #660;" class=3D"styled-by-prettify">(</span><span style=3D"=
color: #000;" class=3D"styled-by-prettify">inner</span><span style=3D"color=
: #660;" class=3D"styled-by-prettify">([:]</span><span style=3D"color: #000=
;" class=3D"styled-by-prettify">d</span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">)...);</span></div></code></div><br>It's the sa=
me as the first example, only using an aggregate.<br><br>It should also be =
noted that having compiler support for unpacking tuples does not mean you c=
an't also have additional library functions for help in other cases. So=
rting, reversing, etc could be library stuff, while the most common cases a=
re handled by the direct language feature.<br>=C2=A0</div><blockquote class=
=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #cc=
c solid;padding-left: 1ex;"><div dir=3D"ltr"><div><div>If properly designed=
, that could be much more flexible than=C2=A0</div><div>a language feature =
in the long term, when we realize that we're missing=C2=A0</div><div>so=
mething else. Just to give you a glimpse: how would you reverse a parameter=
=C2=A0</div><div>pack? How would you sort a parameter pack based on a compi=
le-time predicate?=C2=A0</div><div>I don't see how these slicing propos=
als are of any help, yet this is a very=C2=A0</div><div>real use case for m=
etaprogramming.=C2=A0</div><div><br></div><div>Instead, I think we need to =
carefully design a STL for metaprogramming (with=C2=A0</div><div>customizat=
ion points where it makes sense), and then let users build on top=C2=A0</di=
v><div>of that. And if you're worried about compile-times being too lon=
g with a=C2=A0</div><div>library-based approach, this can be tackled with a=
few well-chosen compiler=C2=A0</div><div>intrinsics (see this article [2])=
..</div></div></div></blockquote><div><br>So instead of having language supp=
ort for unpacking tuples, you want language support for... some low-level s=
tuff that can be used to build a library?<br><br>No thanks; I'll take t=
he simple and easy-to-use feature over the huge and complex STL-like thing.=
<br></div></div>
<p></p>
-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
Visit this group at <a href=3D"https://groups.google.com/a/isocpp.org/group=
/std-proposals/">https://groups.google.com/a/isocpp.org/group/std-proposals=
/</a>.<br />
------=_Part_6262_334406376.1455588651749--
------=_Part_6261_2015470513.1455588651748--
.
Author: Matthew Woehlke <mwoehlke.floss@gmail.com>
Date: Tue, 16 Feb 2016 11:07:10 -0500
Raw View
On 2016-02-15 21:10, Nicol Bolas wrote:
> On Monday, February 15, 2016 at 6:22:24 PM UTC-5, Louis Dionne wrote:
>> Reading the comments here, I just don't see the need for a new language
>> feature for manipulating parameter packs. Instead, I think we need proper
>> standard library features to manipulate tuples with a high level of
>> abstraction.
>
> That's like saying, "Why do we need lambdas in the language? We have
> Boost.Lambda!"
> [...]
>
> Show me the Hana code for [many examples]:
Wow... thanks, Nicol! Exactly what I would have said, only better :-).
>> If properly designed, that could be much more flexible than
>> a language feature in the long term, when we realize that we're missing
>> something else. Just to give you a glimpse: how would you reverse a
>> parameter pack? How would you sort a parameter pack based on a compile-time
>> predicate?
*Simple* unpacking solves a basic problem that is hard to solve as a
library solution (see previous discussion at
https://groups.google.com/a/isocpp.org/d/msg/std-proposals/PghsmqN1cAw/0Q1V-22lFAAJ):
foo([:]tl1..., [:]tl2...);
If we have simple unpacking (at least with `[:]`), it's trivial to add
slicing. Why not? It solves real problems and is much cleaner than a
library solution.
No, it doesn't solve reversing or sorting, but I rather doubt those are
nearly as common. Keep in mind all this is modeled heavily after Python,
so there is precedent for what operations are made trivial and which are
left relegated to more complex library solutions.
That all being said, I'm not seeing why these aren't orthogonal. We want
unpacking (see Nicol's reply). If we use `[:]` for unpacking, we can
trivially add slicing to that. If we have sliced unpacking, we can
trivially declare slicing to also work on parameter packs.
Do we also need other ways to manipulate parameter packs? Maybe. What I
don't see is why that should preclude unpacking.
>> I don't see how these slicing proposals are of any help, yet this
>> is a very real use case for metaprogramming.
That's... nice. Many of the example uses for unpacking and even slicing
*do not* involve metaprogramming. Do you have such examples for
reversing and sorting?
--
Matthew
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-proposals/.
.
Author: Louis Dionne <ldionne.2@gmail.com>
Date: Tue, 16 Feb 2016 12:21:28 -0800 (PST)
Raw View
------=_Part_842_437578892.1455654088926
Content-Type: multipart/alternative;
boundary="----=_Part_843_1212118557.1455654088927"
------=_Part_843_1212118557.1455654088927
Content-Type: text/plain; charset=UTF-8
On Monday, 15 February 2016 21:10:52 UTC-5, Nicol Bolas wrote:
> On Monday, February 15, 2016 at 6:22:24 PM UTC-5, Louis Dionne wrote:
> > Hi,
> >
> > I'd like to quickly chime in to drop a link to Boost.Hana [1] (which
I'm the
> > author of, for full disclosure). There seems to be quite a bit of
discussion
> > about adding language features to manipulate packs and tuples, when a
lot of
> > this could be done in a library. Hana's purpose is specifically to
manipulate
> > tuples (and more generally heterogeneous containers) by providing
std-like
> > algorithms to operate on them.
> >
> > Reading the comments here, I just don't see the need for a new language
> > feature for manipulating parameter packs. Instead, I think we need
proper
> > standard library features to manipulate tuples with a high level of
> > abstraction.
>
> That's like saying, "Why do we need lambdas in the language?
> We have Boost.Lambda!"
>
> Indeed, I seem to recall Boost.Lambda being one of the impetuses for
getting
> language-based lambdas. BLL was basically proof that you couldn't do
lambdas
> as a library. It said, "Look, this is the best the language can do as is:
> here's what you get, here's what you have to do to implement it, here's
how
> ugly user-code looks, and here are all of the places where it breaks
down".
It's significantly different in the level of cumbersomeness of using
Boost.Lambda vs language lambdas, and using Boost.Hana vs what you're
proposing. Language-level lambdas are an obvious relief because using
Boost.Lambda is a PITA. As you'll hopefully see below, the status quo
is workable if you use a proper library.
> In that regard, libraries like Fusion and Hana are perfect examples of why
> tuple unpacking needs to be a language feature.
>
> Show me the Hana code for this:
>
> outer(inner([:]tpl)...)
>
> This calls `inner` on each element of the tuple, then pipes the result
into
> the call to `outer`. It works exactly like parameter packs too, so if
`tpl`
> were a pack, you just drop the `[:]` syntax and it works.
With Hana, you'd write
hana::unpack(tpl, hana::on(inner, outer));
or you could also write
hana::unpack(tpl, [](auto ...x) { return outer(inner(x)...); });
Basically, `unpack` is just `std::apply` but with the arguments reversed.
> Show me the Hana code for this:
>
> auto x = inner([:]tpl) + ...;
>
> This simply calls a function on each element of the tuple and takes the
sum
> of the results. Again, it works like parameter packs, so it reuses
existing
> knowledge.
You could write
auto x = hana::fold_left(hana::transform(tpl, inner), std::plus<>{});
or equivalently
auto x = hana::fold_left(tpl, [](auto a, auto b) {
return a + inner(b);
});
`hana::fold_left` is just like `std::accumulate`, and `hana::transform` is
just like `std::transform`. To me, the fact that we're using algorithms that
we already know from runtime programming is a good thing, whereas your
proposed notation requires yet another special thing to learn. Of course,
your proposed syntax wins here because it was designed precisely for these
use cases, but I hope you'll agree that a library-based solution is nowhere
near the ugliness of good old Boost.Lambda expressions.
> Oh, and show me the Hana code for this:
>
> struct Data
> {
> int i;
> float f;
> double d;
> };
>
> Data d = ...;
> outer(inner([:]d)...);
>
> It's the same as the first example, only using an aggregate.
Ah! That's a good one! Here's how you would write it:
BOOST_HANA_DEFINE_STRUCT(Data,
(int, i),
(float, f),
(double, d)
);
Data d = ...;
hana::unpack(hana::members(d), hana::on(inner, outer));
Really, the only cumbersome thing here is the definition of the struct.
And I do agree that we need a proper way of introspecting user defined
types,
and __this is certainly not the job for a library__. However, if we designed
a proper way of introspecting user-defined types, it would then be very easy
to plug this into the customization point of a library. The challenge of
bringing compile-time introspection to C++ is obviously something that needs
to be done, but I think that's out of the scope of the current discussion.
> [...]
>
> > If properly designed, that could be much more flexible than
> > a language feature in the long term, when we realize that we're missing
> > something else. Just to give you a glimpse: how would you reverse a
parameter
> > pack? How would you sort a parameter pack based on a compile-time
predicate?
> > I don't see how these slicing proposals are of any help, yet this is a
very
> > real use case for metaprogramming.
> >
> > Instead, I think we need to carefully design a STL for metaprogramming
(with
> > customization points where it makes sense), and then let users build on
top
> > of that. And if you're worried about compile-times being too long with a
> > library-based approach, this can be tackled with a few well-chosen
compiler
> > intrinsics (see this article [2]).
>
> So instead of having language support for unpacking tuples, you want
> language support for... some low-level stuff that can be used to build
> a library?
>
> No thanks; I'll take the simple and easy-to-use feature over the huge and
> complex STL-like thing.
The problem I see is that to get rid of a more general library solution that
you deem too complex, you propose adding a language feature that will only
tackle a subproblem. You're basically offloading complexity onto the
language
itself, which I think is harmful.
On Tuesday, 16 February 2016 11:07:30 UTC-5, Matthew Woehlke wrote:
> On 2016-02-15 21:10, Nicol Bolas wrote:
> > On Monday, February 15, 2016 at 6:22:24 PM UTC-5, Louis Dionne wrote:
> >> Reading the comments here, I just don't see the need for a new language
> >> feature for manipulating parameter packs. Instead, I think we need
proper
> >> standard library features to manipulate tuples with a high level of
> >> abstraction.
> >
> > That's like saying, "Why do we need lambdas in the language? We have
> > Boost.Lambda!"
> > [...]
> >
> > Show me the Hana code for [many examples]:
>
> Wow... thanks, Nicol! Exactly what I would have said, only better :-).
>
> >> If properly designed, that could be much more flexible than
> >> a language feature in the long term, when we realize that we're missing
> >> something else. Just to give you a glimpse: how would you reverse a
> >> parameter pack? How would you sort a parameter pack based on a
compile-time
> >> predicate?
>
> *Simple* unpacking solves a basic problem that is hard to solve as a
> library solution (see previous discussion at
>
https://groups.google.com/a/isocpp.org/d/msg/std-proposals/PghsmqN1cAw/0Q1V-22lFAAJ):
>
> foo([:]tl1..., [:]tl2...);
You could write
hana::unpack(hana::concat(tl1, tl2), foo);
Sure, it suffers some limitations explored in your link above, but frankly
I would call out these limitations as being academic for the most part.
Definitely not something that justifies a language feature on itself, IMHO.
> [...]
> >> I don't see how these slicing proposals are of any help, yet this
> >> is a very real use case for metaprogramming.
>
> That's... nice. Many of the example uses for unpacking and even slicing
> *do not* involve metaprogramming. Do you have such examples for
> reversing and sorting?
I guess that's just a misunderstanding on what exactly is to be considered
metaprogramming. As for use cases, sorting can be useful if you e.g. have
computations with compile-time dependencies and want to run them in the
right
order. You sort them at compile-time and then execute the computations. Or
it could also be sorting types by alignment as a runtime optimization.
Sorting is arguably more useful than reversing in my experience, but others
like `find_if` are even more important yet we don't have any good way of
doing it.
Let it be clear that I understand that the problems you're talking about for
unpacking are real, and we need a solution (language or library-based). My
discomfort lies in the fact that I'd like to see a carefully designed system
that tackles more than just unpacking and slicing tuples, but that has a
wider
scope and unifying vision. And if unpacking/slicing ends up needing a
language
feature in this __designed__ system, then I'll be all for it. However, what
I
think we need to avoid is to introduce yet another short sighted feature
that
will quickly reach its limitations, and that we'll then need to patch with
another short sighted feature later on.
Regards,
Louis Dionne
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-proposals/.
------=_Part_843_1212118557.1455654088927
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><div><br></div><div><br></div><div>On Monday, 15 February =
2016 21:10:52 UTC-5, Nicol Bolas wrote:</div><div>> On Monday, February =
15, 2016 at 6:22:24 PM UTC-5, Louis Dionne wrote:</div><div>> > Hi,</=
div><div>> ></div><div>> > I'd like to quickly chime in to =
drop a link to Boost.Hana [1] (which I'm the</div><div>> > author=
of, for full disclosure). There seems to be quite a bit of discussion</div=
><div>> > about adding language features to manipulate packs and tupl=
es, when a lot of</div><div>> > this could be done in a library. Hana=
's purpose is specifically to manipulate</div><div>> > tuples (an=
d more generally heterogeneous containers) by providing std-like</div><div>=
> > algorithms to operate on them.</div><div>> ></div><div>>=
> Reading the comments here, I just don't see the need for a new la=
nguage</div><div>> > feature for manipulating parameter packs. Instea=
d, I think we need proper</div><div>> > standard library features to =
manipulate tuples with a high level of</div><div>> > abstraction.</di=
v><div>></div><div>> That's like saying, "Why do we need lam=
bdas in the language?</div><div>> We have Boost.Lambda!"</div><div>=
></div><div>> Indeed, I seem to recall Boost.Lambda being one of the =
impetuses for getting</div><div>> language-based lambdas. BLL was basica=
lly proof that you couldn't do lambdas</div><div>> as a library. It =
said, "Look, this is the best the language can do as is:</div><div>>=
; here's what you get, here's what you have to do to implement it, =
here's how</div><div>> ugly user-code looks, and here are all of the=
places where it breaks down".</div><div><br></div><div>It's signi=
ficantly different in the level of cumbersomeness of using</div><div>Boost.=
Lambda vs language lambdas, and using Boost.Hana vs what you're</div><d=
iv>proposing. Language-level lambdas are an obvious relief because using</d=
iv><div>Boost.Lambda is a PITA. As you'll hopefully see below, the stat=
us quo</div><div>is workable if you use a proper library.</div><div><br></d=
iv><div><br></div><div>> In that regard, libraries like Fusion and Hana =
are perfect examples of why</div><div>> tuple unpacking needs to be a la=
nguage feature.</div><div>></div><div>> Show me the Hana code for thi=
s:</div><div>></div><div>> outer(inner([:]tpl)...)</div><div>></di=
v><div>> This calls `inner` on each element of the tuple, then pipes the=
result into</div><div>> the call to `outer`. It works exactly like para=
meter packs too, so if `tpl`</div><div>> were a pack, you just drop the =
`[:]` syntax and it works.</div><div><br></div><div>With Hana, you'd wr=
ite</div><div><br></div><div>=C2=A0 =C2=A0 hana::unpack(tpl, hana::on(inner=
, outer));</div><div><br></div><div>or you could also write</div><div><br><=
/div><div>=C2=A0 =C2=A0 hana::unpack(tpl, [](auto ...x) { return outer(inne=
r(x)...); });</div><div><br></div><div>Basically, `unpack` is just `std::ap=
ply` but with the arguments reversed.</div><div><br></div><div><br></div><d=
iv>> Show me the Hana code for this:</div><div>></div><div>> auto =
x =3D inner([:]tpl) + ...;</div><div>></div><div>> This simply calls =
a function on each element of the tuple and takes the sum</div><div>> of=
the results. Again, it works like parameter packs, so it reuses existing</=
div><div>> knowledge.</div><div><br></div><div>You could write</div><div=
><br></div><div>=C2=A0 =C2=A0 auto x =3D hana::fold_left(hana::transform(tp=
l, inner), std::plus<>{});</div><div><br></div><div>or equivalently</=
div><div><br></div><div>=C2=A0 =C2=A0 auto x =3D hana::fold_left(tpl, [](au=
to a, auto b) {</div><div>=C2=A0 =C2=A0 =C2=A0 =C2=A0 return a + inner(b);<=
/div><div>=C2=A0 =C2=A0 });</div><div><br></div><div>`hana::fold_left` is j=
ust like `std::accumulate`, and `hana::transform` is</div><div>just like `s=
td::transform`. To me, the fact that we're using algorithms that</div><=
div>we already know from runtime programming is a good thing, whereas your<=
/div><div>proposed notation requires yet another special thing to learn. Of=
course,</div><div>your proposed syntax wins here because it was designed p=
recisely for these</div><div>use cases, but I hope you'll agree that a =
library-based solution is nowhere</div><div>near the ugliness of good old B=
oost.Lambda expressions.</div><div><br></div><div><br></div><div>> Oh, a=
nd show me the Hana code for this:</div><div>></div><div>> struct Dat=
a</div><div>> {</div><div>> =C2=A0 int i;</div><div>> =C2=A0 float=
f;</div><div>> =C2=A0 double d;</div><div>> };</div><div>></div><=
div>> Data d =3D ...;</div><div>> outer(inner([:]d)...);</div><div>&g=
t;</div><div>> It's the same as the first example, only using an agg=
regate.</div><div><br></div><div>Ah! That's a good one! Here's how =
you would write it:</div><div><br></div><div>=C2=A0 =C2=A0 BOOST_HANA_DEFIN=
E_STRUCT(Data,</div><div>=C2=A0 =C2=A0 =C2=A0 =C2=A0 (int, i),</div><div>=
=C2=A0 =C2=A0 =C2=A0 =C2=A0 (float, f),</div><div>=C2=A0 =C2=A0 =C2=A0 =C2=
=A0 (double, d)</div><div>=C2=A0 =C2=A0 );</div><div><br></div><div>=C2=A0 =
=C2=A0 Data d =3D ...;</div><div>=C2=A0 =C2=A0 hana::unpack(hana::members(d=
), hana::on(inner, outer));</div><div><br></div><div>Really, the only cumbe=
rsome thing here is the definition of the struct.</div><div>And I do agree =
that we need a proper way of introspecting user defined types,</div><div>an=
d __this is certainly not the job for a library__. However, if we designed<=
/div><div>a proper way of introspecting user-defined types, it would then b=
e very easy</div><div>to plug this into the customization point of a librar=
y. The challenge of</div><div>bringing compile-time introspection to C++ is=
obviously something that needs</div><div>to be done, but I think that'=
s out of the scope of the current discussion.</div><div><br></div><div><br>=
</div><div>> [...]</div><div>></div><div>> > If properly design=
ed, that could be much more flexible than</div><div>> > a language fe=
ature in the long term, when we realize that we're missing</div><div>&g=
t; > something else. Just to give you a glimpse: how would you reverse a=
parameter</div><div>> > pack? How would you sort a parameter pack ba=
sed on a compile-time predicate?</div><div>> > I don't see how th=
ese slicing proposals are of any help, yet this is a very</div><div>> &g=
t; real use case for metaprogramming.</div><div>> ></div><div>> &g=
t; Instead, I think we need to carefully design a STL for metaprogramming (=
with</div><div>> > customization points where it makes sense), and th=
en let users build on top</div><div>> > of that. And if you're wo=
rried about compile-times being too long with a</div><div>> > library=
-based approach, this can be tackled with a few well-chosen compiler</div><=
div>> > intrinsics (see this article [2]).</div><div>></div><div>&=
gt; So instead of having language support for unpacking tuples, you want</d=
iv><div>> language support for... some low-level stuff that can be used =
to build</div><div>> a library?</div><div>></div><div>> No thanks;=
I'll take the simple and easy-to-use feature over the huge and</div><d=
iv>> complex STL-like thing.</div><div><br></div><div>The problem I see =
is that to get rid of a more general library solution that</div><div>you de=
em too complex, you propose adding a language feature that will only</div><=
div>tackle a subproblem. You're basically offloading complexity onto th=
e language</div><div>itself, which I think is harmful.</div><div><br></div>=
<div><br></div><div><br></div><div>On Tuesday, 16 February 2016 11:07:30 UT=
C-5, Matthew Woehlke wrote:</div><div>> On 2016-02-15 21:10, Nicol Bolas=
wrote:</div><div>> > On Monday, February 15, 2016 at 6:22:24 PM UTC-=
5, Louis Dionne wrote:</div><div>> >> Reading the comments here, I=
just don't see the need for a new language</div><div>> >> fea=
ture for manipulating parameter packs. Instead, I think we need proper</div=
><div>> >> standard library features to manipulate tuples with a h=
igh level of</div><div>> >> abstraction.</div><div>> ></div>=
<div>> > That's like saying, "Why do we need lambdas in the =
language? We have</div><div>> > Boost.Lambda!"</div><div>> &g=
t; [...]</div><div>> ></div><div>> > Show me the Hana code for =
[many examples]:</div><div>></div><div>> Wow... thanks, Nicol! Exactl=
y what I would have said, only better :-).</div><div>></div><div>> &g=
t;> If properly designed, that could be much more flexible than</div><di=
v>> >> a language feature in the long term, when we realize that w=
e're missing</div><div>> >> something else. Just to give you a=
glimpse: how would you reverse a</div><div>> >> parameter pack? H=
ow would you sort a parameter pack based on a compile-time</div><div>> &=
gt;> predicate?</div><div>></div><div>> *Simple* unpacking solves =
a basic problem that is hard to solve as a</div><div>> library solution =
(see previous discussion at</div><div>> https://groups.google.com/a/isoc=
pp.org/d/msg/std-proposals/PghsmqN1cAw/0Q1V-22lFAAJ):</div><div>></div><=
div>> =C2=A0 foo([:]tl1..., [:]tl2...);</div><div><br></div><div>You cou=
ld write</div><div><br></div><div>=C2=A0 =C2=A0 hana::unpack(hana::concat(t=
l1, tl2), foo);</div><div><br></div><div>Sure, it suffers some limitations =
explored in your link above, but frankly</div><div>I would call out these l=
imitations as being academic for the most part.</div><div>Definitely not so=
mething that justifies a language feature on itself, IMHO.</div><div><br></=
div><div><br></div><div>> [...]</div><div>> >> I don't see =
how these slicing proposals are of any help, yet this</div><div>> >&g=
t; is a very real use case for metaprogramming.</div><div>></div><div>&g=
t; That's... nice. Many of the example uses for unpacking and even slic=
ing</div><div>> *do not* involve metaprogramming. Do you have such examp=
les for</div><div>> reversing and sorting?</div><div><br></div><div>I gu=
ess that's just a misunderstanding on what exactly is to be considered<=
/div><div>metaprogramming. As for use cases, sorting can be useful if you e=
..g. have</div><div>computations with compile-time dependencies and want to =
run them in the right</div><div>order. You sort them at compile-time and th=
en execute the computations. Or</div><div>it could also be sorting types by=
alignment as a runtime optimization.</div><div>Sorting is arguably more us=
eful than reversing in my experience, but others</div><div>like `find_if` a=
re even more important yet we don't have any good way of</div><div>doin=
g it.</div><div><br></div><div><br></div><div>Let it be clear that I unders=
tand that the problems you're talking about for</div><div>unpacking are=
real, and we need a solution (language or library-based). My</div><div>dis=
comfort lies in the fact that I'd like to see a carefully designed syst=
em</div><div>that tackles more than just unpacking and slicing tuples, but =
that has a wider</div><div>scope and unifying vision. And if unpacking/slic=
ing ends up needing a language</div><div>feature in this __designed__ syste=
m, then I'll be all for it. However, what I</div><div>think we need to =
avoid is to introduce yet another short sighted feature that</div><div>will=
quickly reach its limitations, and that we'll then need to patch with<=
/div><div>another short sighted feature later on.</div><div><br></div><div>=
Regards,</div><div>Louis Dionne</div><div><br></div></div>
<p></p>
-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
Visit this group at <a href=3D"https://groups.google.com/a/isocpp.org/group=
/std-proposals/">https://groups.google.com/a/isocpp.org/group/std-proposals=
/</a>.<br />
------=_Part_843_1212118557.1455654088927--
------=_Part_842_437578892.1455654088926--
.
Author: Matthew Woehlke <mwoehlke.floss@gmail.com>
Date: Tue, 16 Feb 2016 16:11:18 -0500
Raw View
(FYI, whatever you used to post your last message just butchered the
quoting. And the line wrapping on your own text isn't much better.)
On 2016-02-16 15:21, Louis Dionne wrote:
> On Monday, 15 February 2016 21:10:52 UTC-5, Nicol Bolas wrote:
>> Oh, and show me the Hana code for this:
>>
>> struct Data
>> {
>> int i;
>> float f;
>> double d;
>> };
>>
>> Data d = ...;
>> outer(inner([:]d)...);
>
> Ah! That's a good one! Here's how you would write it:
>
> BOOST_HANA_DEFINE_STRUCT(Data,
Oops. That right there is a no-go. Redefining the type is right out, as
most likely the type is not something that can be directly controlled.
(Even if it was, uglifying the API like this? No, thanks...)
This is where I think we're having a communication issue. The syntax
you're objecting to is mostly related to fold expressions... which *are
already part of the language*.
Please, by all means, submit proposals to make fold expressions /
dealing with parameter packs better :-).
The "meat" of the general unpacking proposal is turning a tuple-like
into a parameter pack. The above suggests that hana doesn't solve that
problem.
> On Tuesday, 16 February 2016 11:07:30 UTC-5, Matthew Woehlke wrote:
>> On Monday, February 15, 2016 at 6:22:24 PM UTC-5, Louis Dionne wrote:
>>> I don't see how these slicing proposals are of any help, yet this
>>> is a very real use case for metaprogramming.
>>
>> That's... nice. Many of the example uses for unpacking and even slicing
>> *do not* involve metaprogramming. Do you have such examples for
>> reversing and sorting?
>
> I guess that's just a misunderstanding on what exactly is to be
> considered metaprogramming. As for use cases, sorting can be useful
> if you e.g. have computations with compile-time dependencies and
> want to run them in the right order. You sort them at compile-time
> and then execute the computations. Or it could also be sorting types
> by alignment as a runtime optimization. Sorting is arguably more
> useful than reversing in my experience, but otherslike `find_if` are
> even more important yet we don't have any good way of doing it.
Again, all of that sounds a) very obscure, and b) like code that gets
written once, buried in a library, and never looked at again.
Unpacking is something that would be useful to me *all the time*.
> Let it be clear that I understand that the problems you're talking
> about for unpacking are real, and we need a solution (language or
> library-based). My discomfort lies in the fact that I'd like to see
> a carefully designed system that tackles more than just unpacking and
> slicing tuples, but that has a wider scope and unifying vision. And
> if unpacking/slicing ends up needing a language feature in this
> __designed__ system, then I'll be all for it. However, what I think
> we need to avoid is to introduce yet another short sighted feature
> that will quickly reach its limitations, and that we'll then need to
> patch with another short sighted feature later on.
Perfect is the enemy of good. My... "concern with your concern", if you
will, is that in trying to build this grand cathedral, we either end up
with no solution at all, or something that makes simple tasks
impractically obtuse.
I tend to think the analogy to lambdas is apt... a language solution may
not be *necessary* in the strict sense, but it's sufficiently *useful*
as to be worthwhile. (Same with P0144, BTW...)
And again, the basic unpacking case (no slicing, just turn a tuple-like
into a parameter pack) allows us to, with a very simple and straight
forward language trick, combine the problem domains of parameter packs
and contained value sequences (i.e. "tuple-likes") so that the same
tools can be applied to both. (I'm certainly willing to entertain that
*those* tools could benefit from a well designed system for working with
parameter packs. But we already *have* parameter packs, so unless you
manage to throw those out entirely, the *worst* I see happening is that
you make `[:]` superfluous. If the slicing form is extended to directly
work on parameter packs, at worst we have a language tool for something
that could be done with a library tool.)
Addition of two integers could be done using a library function rather
than a built-in operator, also... but it's something that happens often
enough that having a language feature (built-in addition operator) is
worthwhile for the improved readability.
At any rate... write a paper. Because this grand cathedral you envision
isn't going to build itself. If you're convinced that there is a better
solution, *show us* that better solution :-).
--
Matthew
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-proposals/.
.
Author: Louis Dionne <ldionne.2@gmail.com>
Date: Tue, 16 Feb 2016 15:13:16 -0800 (PST)
Raw View
------=_Part_5545_942494620.1455664397060
Content-Type: multipart/alternative;
boundary="----=_Part_5546_1684573597.1455664397061"
------=_Part_5546_1684573597.1455664397061
Content-Type: text/plain; charset=UTF-8
On Tuesday, 16 February 2016 16:11:36 UTC-5, Matthew Woehlke wrote:
>
> (FYI, whatever you used to post your last message just butchered the
> quoting. And the line wrapping on your own text isn't much better.)
>
I posted my reply from the Google Groups web page, and both the quoting
and the line wrapping look fine there. I'm not sure what you're referring
to.
>
> On 2016-02-16 15:21, Louis Dionne wrote:
> > On Monday, 15 February 2016 21:10:52 UTC-5, Nicol Bolas wrote:
> >> Oh, and show me the Hana code for this:
> >>
> >> struct Data
> >> {
> >> int i;
> >> float f;
> >> double d;
> >> };
> >>
> >> Data d = ...;
> >> outer(inner([:]d)...);
> >
> > Ah! That's a good one! Here's how you would write it:
> >
> > BOOST_HANA_DEFINE_STRUCT(Data,
>
> Oops. That right there is a no-go. Redefining the type is right out, as
> most likely the type is not something that can be directly controlled.
> (Even if it was, uglifying the API like this? No, thanks...)
>
You don't need to redefine the type, since the above macro actually
defines the type itself. If you don't have control over the type, you can
also use BOOST_HANA_ADAPT_STRUCT to adapt an existing struct.
But all of this is completely irrelevant, since I myself said that these
macros
were nothing but workarounds for the lack of proper introspection
facilities,
which need to be built into the language. This is obviously neither where
we disagree nor the subject of this discussion.
>
> This is where I think we're having a communication issue. The syntax
> you're objecting to is mostly related to fold expressions... which *are
> already part of the language*.
>
> Please, by all means, submit proposals to make fold expressions /
> dealing with parameter packs better :-).
>
> The "meat" of the general unpacking proposal is turning a tuple-like
> into a parameter pack. The above suggests that hana doesn't solve that
> problem.
>
Did you read my code examples? The above shows that it can be done
with reasonable ease using hana::unpack.
> On Tuesday, 16 February 2016 11:07:30 UTC-5, Matthew Woehlke wrote:
> >> On Monday, February 15, 2016 at 6:22:24 PM UTC-5, Louis Dionne wrote:
> >>> I don't see how these slicing proposals are of any help, yet this
> >>> is a very real use case for metaprogramming.
> >>
> >> That's... nice. Many of the example uses for unpacking and even slicing
> >> *do not* involve metaprogramming. Do you have such examples for
> >> reversing and sorting?
> >
> > I guess that's just a misunderstanding on what exactly is to be
> > considered metaprogramming. As for use cases, sorting can be useful
> > if you e.g. have computations with compile-time dependencies and
> > want to run them in the right order. You sort them at compile-time
> > and then execute the computations. Or it could also be sorting types
> > by alignment as a runtime optimization. Sorting is arguably more
> > useful than reversing in my experience, but otherslike `find_if` are
> > even more important yet we don't have any good way of doing it.
>
> Again, all of that sounds a) very obscure, and b) like code that gets
> written once, buried in a library, and never looked at again.
>
> Unpacking is something that would be useful to me *all the time*.
> > Let it be clear that I understand that the problems you're talking
> > about for unpacking are real, and we need a solution (language or
> > library-based). My discomfort lies in the fact that I'd like to see
> > a carefully designed system that tackles more than just unpacking and
> > slicing tuples, but that has a wider scope and unifying vision. And
> > if unpacking/slicing ends up needing a language feature in this
> > __designed__ system, then I'll be all for it. However, what I think
> > we need to avoid is to introduce yet another short sighted feature
> > that will quickly reach its limitations, and that we'll then need to
> > patch with another short sighted feature later on.
>
> Perfect is the enemy of good. My... "concern with your concern", if you
> will, is that in trying to build this grand cathedral, we either end up
> with no solution at all, or something that makes simple tasks
> impractically obtuse.
>
> I tend to think the analogy to lambdas is apt... a language solution may
> not be *necessary* in the strict sense, but it's sufficiently *useful*
> as to be worthwhile. (Same with P0144, BTW...)
>
> And again, the basic unpacking case (no slicing, just turn a tuple-like
> into a parameter pack) allows us to, with a very simple and straight
> forward language trick, combine the problem domains of parameter packs
> and contained value sequences (i.e. "tuple-likes") so that the same
> tools can be applied to both. (I'm certainly willing to entertain that
> *those* tools could benefit from a well designed system for working with
> parameter packs. But we already *have* parameter packs, so unless you
> manage to throw those out entirely, the *worst* I see happening is that
> you make `[:]` superfluous. If the slicing form is extended to directly
> work on parameter packs, at worst we have a language tool for something
> that could be done with a library tool.)
>
> Addition of two integers could be done using a library function rather
> than a built-in operator, also... but it's something that happens often
> enough that having a language feature (built-in addition operator) is
> worthwhile for the improved readability.
>
> At any rate... write a paper. Because this grand cathedral you envision
> isn't going to build itself. If you're convinced that there is a better
> solution, *show us* that better solution :-).
>
Well, I just showed you a prototype for such a "grand cathedral"; Hana.
It's not like I'm shovelling abstract nonsense around. I'm not trying to
standardize Hana, but I think more awareness about what can be done
is important if you're going to change the language, which is why I
shared my experience with you.
To make it back to the proposal, here's what I would find much more
useful than simple unpacking and slicing, and that could actually be
used to build more complex tuple algorithms. If we could take a tuple
and unpack the elements at arbitrary indices, that would be useful.
For example, disregarding the notation,
auto tuple = std::make_tuple('0', '1', '2', '3', '4', '5');
f(tuple[1, 0, 3, 3]); //equivalent to f('1', '0', '3', '3')
Or, equivalently, if we could slice a tuple with an arbitrary
`std::index_sequence`,
that would be neat. The reason is that getting not-necessarily-adjacent
elements
in a tuple is a very basic operation required to implement many other more
complex algorithms, like `remove_if`, `reverse`, and even `sort`. Indeed,
the
idea to implement these algorithms is that we take the input tuple, then
compute
the indices that we want in the resulting tuple at compile-time (using
constexpr
computations or normal template metaprogramming), and then generate an
index_sequence holding those indices. Finally, we extract the subsequence of
elements at those indices to create a new tuple. That gives us a runtime
complexity
of O(1), and most computations can be carried in constexpr-world, which can
be
faster than template metaprogramming. In my experience, being able to
extract
an arbitrary subsequence of a tuple is far more useful than being able to
extract
only consecutive elements. Do you see a way your proposal could accommodate
this?
Regards,
Louis Dionne
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-proposals/.
------=_Part_5546_1684573597.1455664397061
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><br><br>On Tuesday, 16 February 2016 16:11:36 UTC-5, Matth=
ew Woehlke wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;marg=
in-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">(FYI, whatev=
er you used to post your last message just butchered the
<br>quoting. And the line wrapping on your own text isn't much better.)
<br></blockquote><div><br></div><div>I posted my reply from the Google Grou=
ps web page, and both the quoting</div><div>and the line wrapping look fine=
there. I'm not sure what you're referring to.</div><div>=C2=A0</di=
v><blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;b=
order-left: 1px #ccc solid;padding-left: 1ex;">
<br>On 2016-02-16 15:21, Louis Dionne wrote:
<br>> On Monday, 15 February 2016 21:10:52 UTC-5, Nicol Bolas wrote:
<br>>> Oh, and show me the Hana code for this:
<br>>>
<br>>> struct Data
<br>>> {
<br>>> =C2=A0 int i;
<br>>> =C2=A0 float f;
<br>>> =C2=A0 double d;
<br>>> };
<br>>>
<br>>> Data d =3D ...;
<br>>> outer(inner([:]d)...);
<br>>=20
<br>> Ah! That's a good one! Here's how you would write it:
<br>>=20
<br>> =C2=A0 =C2=A0 BOOST_HANA_DEFINE_STRUCT(Data,
<br>
<br>Oops. That right there is a no-go. Redefining the type is right out, as
<br>most likely the type is not something that can be directly controlled.
<br>(Even if it was, uglifying the API like this? No, thanks...)
<br></blockquote><div><br></div><div>You don't need to redefine the typ=
e, since the above macro actually</div><div>defines the type itself. If you=
don't have control over the type, you can</div><div>also use BOOST_HAN=
A_ADAPT_STRUCT to adapt an existing struct.</div><div>But all of this is co=
mpletely irrelevant, since I myself said that these macros</div><div>were n=
othing but workarounds for the lack of proper introspection facilities,</di=
v><div>which need to be built into the language. This is obviously neither =
where</div><div>we disagree nor the subject of this discussion.</div><div>=
=C2=A0</div><blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-lef=
t: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">
<br>This is where I think we're having a communication issue. The synta=
x
<br>you're objecting to is mostly related to fold expressions... which =
*are
<br>already part of the language*.
<br>
<br>Please, by all means, submit proposals to make fold expressions /
<br>dealing with parameter packs better :-).
<br>
<br>The "meat" of the general unpacking proposal is turning a tup=
le-like
<br>into a parameter pack. The above suggests that hana doesn't solve t=
hat
<br>problem.
<br></blockquote><div><br></div><div>Did you read my code examples? The abo=
ve shows that it can be done</div><div>with reasonable ease using hana::unp=
ack.</div><div>=C2=A0</div><div><br></div><blockquote class=3D"gmail_quote"=
style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-=
left: 1ex;">> On Tuesday, 16 February 2016 11:07:30 UTC-5, Matthew Woehl=
ke wrote:
<br>>> On Monday, February 15, 2016 at 6:22:24 PM UTC-5, Louis Dionne=
wrote:
<br>>>> I don't see how these slicing proposals are of any hel=
p, yet this
<br>>>> is a very real use case for metaprogramming.
<br>>>
<br>>> That's... nice. Many of the example uses for unpacking and=
even slicing
<br>>> *do not* involve metaprogramming. Do you have such examples fo=
r
<br>>> reversing and sorting?
<br>>=20
<br>> I guess that's just a misunderstanding on what exactly is to b=
e=20
<br>> considered metaprogramming. As for use cases, sorting can be usefu=
l=20
<br>> if you e.g. have computations with compile-time dependencies and
<br>> want to run them in the right order. You sort them at compile-time
<br>> and then execute the computations. Or it could also be sorting typ=
es
<br>> by alignment as a runtime optimization. Sorting is arguably more
<br>> useful than reversing in my experience, but otherslike `find_if` a=
re
<br>> even more important yet we don't have any good way of doing it=
..
<br>
<br>Again, all of that sounds a) very obscure, and b) like code that gets
<br>written once, buried in a library, and never looked at again.
<br>
<br>Unpacking is something that would be useful to me *all the time*.=C2=A0=
</blockquote><blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-le=
ft: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">
<br>> Let it be clear that I understand that the problems you're tal=
king
<br>> about for unpacking are real, and we need a solution (language or=
=20
<br>> library-based). My discomfort lies in the fact that I'd like t=
o see
<br>> a carefully designed system that tackles more than just unpacking =
and
<br>> slicing tuples, but that has a wider scope and unifying vision. An=
d
<br>> if unpacking/slicing ends up needing a language feature in this
<br>> __designed__ system, then I'll be all for it. However, what I =
think
<br>> we need to avoid is to introduce yet another short sighted feature
<br>> that will quickly reach its limitations, and that we'll then n=
eed to
<br>> patch with another short sighted feature later on.
<br>
<br>Perfect is the enemy of good. My... "concern with your concern&quo=
t;, if you
<br>will, is that in trying to build this grand cathedral, we either end up
<br>with no solution at all, or something that makes simple tasks
<br>impractically obtuse.
<br>
<br>I tend to think the analogy to lambdas is apt... a language solution ma=
y
<br>not be *necessary* in the strict sense, but it's sufficiently *usef=
ul*
<br>as to be worthwhile. (Same with P0144, BTW...)
<br>
<br>And again, the basic unpacking case (no slicing, just turn a tuple-like
<br>into a parameter pack) allows us to, with a very simple and straight
<br>forward language trick, combine the problem domains of parameter packs
<br>and contained value sequences (i.e. "tuple-likes") so that th=
e same
<br>tools can be applied to both. (I'm certainly willing to entertain t=
hat
<br>*those* tools could benefit from a well designed system for working wit=
h
<br>parameter packs. But we already *have* parameter packs, so unless you
<br>manage to throw those out entirely, the *worst* I see happening is that
<br>you make `[:]` superfluous. If the slicing form is extended to directly
<br>work on parameter packs, at worst we have a language tool for something
<br>that could be done with a library tool.)
<br>
<br>Addition of two integers could be done using a library function rather
<br>than a built-in operator, also... but it's something that happens o=
ften
<br>enough that having a language feature (built-in addition operator) is
<br>worthwhile for the improved readability.
<br>
<br>At any rate... write a paper. Because this grand cathedral you envision
<br>isn't going to build itself. If you're convinced that there is =
a better
<br>solution, *show us* that better solution :-).
<br></blockquote><div><br></div><div>Well, I just showed you a prototype fo=
r such a "grand cathedral"; Hana.</div><div>It's not like I&#=
39;m shovelling abstract nonsense around. I'm not trying to</div><div>s=
tandardize Hana, but I think more awareness about what can be done</div><di=
v>is important if you're going to change the language, which is why I</=
div><div>shared my experience with you.</div><div><br></div><div>To make it=
back to the proposal, here's what I would find much more</div><div>use=
ful than simple unpacking and slicing, and that could actually be</div><div=
>used to build more complex tuple algorithms. If we could take a tuple</div=
><div>and unpack the elements at arbitrary indices, that would be useful.</=
div><div>For example, disregarding the notation,</div><div><br></div><div><=
div class=3D"prettyprint" style=3D"background-color: rgb(250, 250, 250); bo=
rder: 1px solid rgb(187, 187, 187); word-wrap: break-word;"><code class=3D"=
prettyprint"><div class=3D"subprettyprint"><span style=3D"color: #008;" cla=
ss=3D"styled-by-prettify">auto</span><span style=3D"color: #000;" class=3D"=
styled-by-prettify"> tuple </span><span style=3D"color: #660;" class=3D"sty=
led-by-prettify">=3D</span><span style=3D"color: #000;" class=3D"styled-by-=
prettify"> std</span><span style=3D"color: #660;" class=3D"styled-by-pretti=
fy">::</span><span style=3D"color: #000;" class=3D"styled-by-prettify">make=
_tuple</span><span style=3D"color: #660;" class=3D"styled-by-prettify">(</s=
pan><span style=3D"color: #080;" class=3D"styled-by-prettify">'0'</=
span><span style=3D"color: #660;" class=3D"styled-by-prettify">,</span><spa=
n style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=
=3D"color: #080;" class=3D"styled-by-prettify">'1'</span><span styl=
e=3D"color: #660;" class=3D"styled-by-prettify">,</span><span style=3D"colo=
r: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #080;"=
class=3D"styled-by-prettify">'2'</span><span style=3D"color: #660;=
" class=3D"styled-by-prettify">,</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"> </span><span style=3D"color: #080;" class=3D"style=
d-by-prettify">'3'</span><span style=3D"color: #660;" class=3D"styl=
ed-by-prettify">,</span><span style=3D"color: #000;" class=3D"styled-by-pre=
ttify"> </span><span style=3D"color: #080;" class=3D"styled-by-prettify">&#=
39;4'</span><span style=3D"color: #660;" class=3D"styled-by-prettify">,=
</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><s=
pan style=3D"color: #080;" class=3D"styled-by-prettify">'5'</span><=
span style=3D"color: #660;" class=3D"styled-by-prettify">);</span><span sty=
le=3D"color: #000;" class=3D"styled-by-prettify"><br>f</span><span style=3D=
"color: #660;" class=3D"styled-by-prettify">(</span><span style=3D"color: #=
000;" class=3D"styled-by-prettify">tuple</span><span style=3D"color: #660;"=
class=3D"styled-by-prettify">[</span><span style=3D"color: #066;" class=3D=
"styled-by-prettify">1</span><span style=3D"color: #660;" class=3D"styled-b=
y-prettify">,</span><span style=3D"color: #000;" class=3D"styled-by-prettif=
y"> </span><span style=3D"color: #066;" class=3D"styled-by-prettify">0</spa=
n><font color=3D"#666600" face=3D"Arial, Helvetica, sans-serif"><span style=
=3D"color: #660;" class=3D"styled-by-prettify">,</span><span style=3D"color=
: #000;" class=3D"styled-by-prettify"> </span></font><span style=3D"color: =
#066;" class=3D"styled-by-prettify">3</span><font color=3D"#666600" face=3D=
"Arial, Helvetica, sans-serif"><span style=3D"color: #660;" class=3D"styled=
-by-prettify">,</span><span style=3D"color: #000;" class=3D"styled-by-prett=
ify"> </span></font><span style=3D"color: #066;" class=3D"styled-by-prettif=
y">3</span><span style=3D"color: #660;" class=3D"styled-by-prettify">]</spa=
n><span style=3D"color: rgb(102, 102, 0); font-family: Arial, Helvetica, sa=
ns-serif;"><span style=3D"color: #660;" class=3D"styled-by-prettify">);</sp=
an><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span =
style=3D"color: #800;" class=3D"styled-by-prettify">//equivalent to f('=
1', '0', '3', '3')</span></span></div></code></=
div><div><br></div>Or, equivalently, if we could slice a tuple with an arbi=
trary `std::index_sequence`,</div><div>that would be neat. The reason is th=
at getting not-necessarily-adjacent elements</div><div>in a tuple is a very=
basic operation required to implement many other more</div><div>complex al=
gorithms, like `remove_if`, `reverse`, and even `sort`. Indeed, the</div><d=
iv>idea to implement these algorithms is that we take the input tuple, then=
compute</div><div>the indices that we want in the resulting tuple at compi=
le-time (using constexpr</div><div>computations or normal template metaprog=
ramming), and then generate an</div><div>index_sequence holding those indic=
es. Finally, we extract the subsequence of</div><div>elements at those indi=
ces to create a new tuple. That gives us a runtime complexity</div><div>of =
O(1), and most computations can be carried in constexpr-world, which can be=
</div><div>faster than template metaprogramming. In my experience, being ab=
le to extract</div><div>an arbitrary subsequence of a tuple is far more use=
ful than being able to extract</div><div>only consecutive elements. Do you =
see a way your proposal could accommodate this?</div><div><br></div><div>Re=
gards,</div><div>Louis Dionne</div><div><br></div></div>
<p></p>
-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
Visit this group at <a href=3D"https://groups.google.com/a/isocpp.org/group=
/std-proposals/">https://groups.google.com/a/isocpp.org/group/std-proposals=
/</a>.<br />
------=_Part_5546_1684573597.1455664397061--
------=_Part_5545_942494620.1455664397060--
.
Author: Nicol Bolas <jmckesson@gmail.com>
Date: Tue, 16 Feb 2016 15:18:59 -0800 (PST)
Raw View
------=_Part_923_1293943875.1455664739617
Content-Type: multipart/alternative;
boundary="----=_Part_924_1041711452.1455664739618"
------=_Part_924_1041711452.1455664739618
Content-Type: text/plain; charset=UTF-8
On Tuesday, February 16, 2016 at 3:21:29 PM UTC-5, Louis Dionne wrote:
>
> On Monday, 15 February 2016 21:10:52 UTC-5, Nicol Bolas wrote:
> > On Monday, February 15, 2016 at 6:22:24 PM UTC-5, Louis Dionne wrote:
> > > Hi,
> > >
> > > I'd like to quickly chime in to drop a link to Boost.Hana [1] (which
> I'm the
> > > author of, for full disclosure). There seems to be quite a bit of
> discussion
> > > about adding language features to manipulate packs and tuples, when a
> lot of
> > > this could be done in a library. Hana's purpose is specifically to
> manipulate
> > > tuples (and more generally heterogeneous containers) by providing
> std-like
> > > algorithms to operate on them.
> > >
> > > Reading the comments here, I just don't see the need for a new language
> > > feature for manipulating parameter packs. Instead, I think we need
> proper
> > > standard library features to manipulate tuples with a high level of
> > > abstraction.
> >
> > That's like saying, "Why do we need lambdas in the language?
> > We have Boost.Lambda!"
> >
> > Indeed, I seem to recall Boost.Lambda being one of the impetuses for
> getting
> > language-based lambdas. BLL was basically proof that you couldn't do
> lambdas
> > as a library. It said, "Look, this is the best the language can do as is:
> > here's what you get, here's what you have to do to implement it, here's
> how
> > ugly user-code looks, and here are all of the places where it breaks
> down".
>
> It's significantly different in the level of cumbersomeness of using
> Boost.Lambda vs language lambdas, and using Boost.Hana vs what you're
> proposing. Language-level lambdas are an obvious relief because using
> Boost.Lambda is a PITA. As you'll hopefully see below, the status quo
> is workable if you use a proper library.
>
Boost.Lambda is workable too... for some definition of "workable".
My point is not that you *cannot do it*. My point is what your code looks
like afterwards.
Hana code only looks reasonable to people experienced in Hana (and
preferably with some functional background). The tuple unpacking code looks
reasonable to C++ programmers experienced in C++ (variadic templates).
I'll break down your examples to show you.
> In that regard, libraries like Fusion and Hana are perfect examples of why
> > tuple unpacking needs to be a language feature.
> >
> > Show me the Hana code for this:
> >
> > outer(inner([:]tpl)...)
> >
> > This calls `inner` on each element of the tuple, then pipes the result
> into
> > the call to `outer`. It works exactly like parameter packs too, so if
> `tpl`
> > were a pack, you just drop the `[:]` syntax and it works.
>
> With Hana, you'd write
>
> hana::unpack(tpl, hana::on(inner, outer));
>
I have no idea what that means. I can guess at what `unpack` does, but "on"
is *completely opaque* to me. I'd have to look that up in documentation to
figure out what it's doing.
Any C++11 programmer who has reasonable experience with variadic templates
can at least take a guess at what `outer(inner([:]tpl)...)` is doing.
I know what a function call looks like. I know what nested function calls
look like. `hana::on(inner, outer)` doesn't look anything like that.
Also, I never said that `inner` or `outer` were each a single functions.
What happens if they're *overloaded*? Indeed, given the circumstances
(calling `inner` on each type), I imagine that it would be impossible for
`inner` to *not* be overloaded or a template function. Either way, this
breaks. Do we need to have lifting syntax for overloads (which to be fair,
is a thing we need in general)?
What if `inner` or `outer` is a member function? Does the user now have to
whip out `std::bind`?
Also, there are performance questions. Will the indirect call through
`hana::on` prevent useful things like inlining?
or you could also write
>
> hana::unpack(tpl, [](auto ...x) { return outer(inner(x)...); });
>
Whenever your library equivalent to a 1-liner language feature includes
"introduce a Lambda", you have *lost* in terms of code comprehensibility.
On the other hand, it does fix (most) of the functionality problems
outlined above.
But here's the #1 reason why the library solution is the wrong solution:
you *wrote it wrong*. You forgot to `std::forward` your arguments. And you
forgot to use `decltype(auto)` for the return value. Both of which are
needed to be exactly equivalent to the above code. Without the
`decltype(auto)`, if `outer` returned a reference of some kind, it could
provoke an unwanted copy.
So it really needed to be:
hana::unpack(tpl, [](auto ...x) -> decltype(auto) { return outer(inner(std::
forward<decltype(auto)>(x)...)); });
I fail to see how this could be considered anywhere nearly as easy to
understand.
Basically, `unpack` is just `std::apply` but with the arguments reversed.
>
>
> > Show me the Hana code for this:
> >
> > auto x = inner([:]tpl) + ...;
> >
> > This simply calls a function on each element of the tuple and takes the
> sum
> > of the results. Again, it works like parameter packs, so it reuses
> existing
> > knowledge.
>
> You could write
>
> auto x = hana::fold_left(hana::transform(tpl, inner), std::plus<>{});
>
And for people who natively read right to left, this would probably be
decent. But that's not how the rest of C++ works.
or equivalently
>
> auto x = hana::fold_left(tpl, [](auto a, auto b) {
> return a + inner(b);
> });
>
Again you forgot to forward the arguments and return values properly. Not
to mention, you turn a simple one-liner into a multi-line statement.
> `hana::fold_left` is just like `std::accumulate`, and `hana::transform` is
> just like `std::transform`. To me, the fact that we're using algorithms
> that
> we already know from runtime programming is a good thing, whereas your
> proposed notation requires yet another special thing to learn.
>
No, it requires learning exactly one special thing: the syntax to turn a
tuple into a parameter pack. After that, you're just using existing
parameter pack features. Which you need to know anyway, since that's a
feature that we're getting one way or another.
Also, if `fold_left` is "just like `std::accumulate`"... why is it called
`fold_left`?
Of course,
> your proposed syntax wins here because it was designed precisely for these
> use cases, but I hope you'll agree that a library-based solution is nowhere
> near the ugliness of good old Boost.Lambda expressions.
>
Actually no. I'd argue that Boost.Lambda is more comprehensible by
comparison. While it is certainly extremely bizarre and has a number of
pitfalls, once you get used to the idea of a value effectively transforming
an expression into a function, it's not so bad for simple cases.
Hana by comparison requires *massive* effort for the simplest of cases.
While I'm sure that it's great for complex metaprogramming, doing something
as simple as the cases we've outlined requires a *lot* of domain knowledge.
That's why I say that Hana would make a good *supplement* to the language
feature. Let the language handle 80+% of all cases; the library can handle
the rest.
> > Oh, and show me the Hana code for this:
> >
> > struct Data
> > {
> > int i;
> > float f;
> > double d;
> > };
> >
> > Data d = ...;
> > outer(inner([:]d)...);
> >
> > It's the same as the first example, only using an aggregate.
>
> Ah! That's a good one! Here's how you would write it:
>
> BOOST_HANA_DEFINE_STRUCT(Data,
> (int, i),
> (float, f),
> (double, d)
> );
>
So... how do I put member functions in `Data`?
Data d = ...;
> hana::unpack(hana::members(d), hana::on(inner, outer));
>
> Really, the only cumbersome thing here is the definition of the struct.
>
Then we have very different definitions of "cumbersome".
> And I do agree that we need a proper way of introspecting user defined
> types,
> and __this is certainly not the job for a library__. However, if we
> designed
> a proper way of introspecting user-defined types, it would then be very
> easy
> to plug this into the customization point of a library. The challenge of
> bringing compile-time introspection to C++ is obviously something that
> needs
> to be done, but I think that's out of the scope of the current discussion.
>
>
> > [...]
> >
> > > If properly designed, that could be much more flexible than
> > > a language feature in the long term, when we realize that we're missing
> > > something else. Just to give you a glimpse: how would you reverse a
> parameter
> > > pack? How would you sort a parameter pack based on a compile-time
> predicate?
> > > I don't see how these slicing proposals are of any help, yet this is a
> very
> > > real use case for metaprogramming.
> > >
> > > Instead, I think we need to carefully design a STL for metaprogramming
> (with
> > > customization points where it makes sense), and then let users build
> on top
> > > of that. And if you're worried about compile-times being too long with
> a
> > > library-based approach, this can be tackled with a few well-chosen
> compiler
> > > intrinsics (see this article [2]).
> >
> > So instead of having language support for unpacking tuples, you want
> > language support for... some low-level stuff that can be used to build
> > a library?
> >
> > No thanks; I'll take the simple and easy-to-use feature over the huge and
> > complex STL-like thing.
>
> The problem I see is that to get rid of a more general library solution
> that
> you deem too complex, you propose adding a language feature that will only
> tackle a subproblem. You're basically offloading complexity onto the
> language
> itself, which I think is harmful.
>
I'm not saying that we shouldn't have (something like) Hana. What I'm
saying is that, for most use cases, Hana is far more painful to use than
having the ability to turn a tuple into a parameter pack. Library
facilities for doing complex tuple operations are good.
But basic "for each element of a tuple" operations deserve to be a
first-class language feature. They simplify uses of tuples in 80% of cases.
For the other 20%, the library solution is available.
You don't use a machete to do surgery. But you don't go into the jungle
with just a scalpel either.
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-proposals/.
------=_Part_924_1041711452.1455664739618
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">On Tuesday, February 16, 2016 at 3:21:29 PM UTC-5, Louis D=
ionne wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-lef=
t: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr"><=
div></div><div>On Monday, 15 February 2016 21:10:52 UTC-5, Nicol Bolas wrot=
e:</div><div>> On Monday, February 15, 2016 at 6:22:24 PM UTC-5, Louis D=
ionne wrote:</div><div>> > Hi,</div><div>> ></div><div>> >=
; I'd like to quickly chime in to drop a link to Boost.Hana [1] (which =
I'm the</div><div>> > author of, for full disclosure). There seem=
s to be quite a bit of discussion</div><div>> > about adding language=
features to manipulate packs and tuples, when a lot of</div><div>> >=
this could be done in a library. Hana's purpose is specifically to man=
ipulate</div><div>> > tuples (and more generally heterogeneous contai=
ners) by providing std-like</div><div>> > algorithms to operate on th=
em.</div><div>> ></div><div>> > Reading the comments here, I ju=
st don't see the need for a new language</div><div>> > feature fo=
r manipulating parameter packs. Instead, I think we need proper</div><div>&=
gt; > standard library features to manipulate tuples with a high level o=
f</div><div>> > abstraction.</div><div>></div><div>> That's=
like saying, "Why do we need lambdas in the language?</div><div>> =
We have Boost.Lambda!"</div><div>></div><div>> Indeed, I seem to=
recall Boost.Lambda being one of the impetuses for getting</div><div>> =
language-based lambdas. BLL was basically proof that you couldn't do la=
mbdas</div><div>> as a library. It said, "Look, this is the best th=
e language can do as is:</div><div>> here's what you get, here's=
what you have to do to implement it, here's how</div><div>> ugly us=
er-code looks, and here are all of the places where it breaks down".</=
div><div><br></div><div>It's significantly different in the level of cu=
mbersomeness of using</div><div>Boost.Lambda vs language lambdas, and using=
Boost.Hana vs what you're</div><div>proposing. Language-level lambdas =
are an obvious relief because using</div><div>Boost.Lambda is a PITA. As yo=
u'll hopefully see below, the status quo</div><div>is workable if you u=
se a proper library.</div></div></blockquote><div><br>Boost.Lambda is worka=
ble too... for some definition of "workable".<br><br>My point is =
not that you <i>cannot do it</i>. My point is what your code looks like aft=
erwards.<br><br>Hana
code only looks reasonable to people experienced in Hana (and preferably w=
ith some functional background). The tuple=20
unpacking code looks reasonable to C++ programmers experienced in C++=20
(variadic templates).<br><br>I'll break down your examples to show you.=
<br><br></div><blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-l=
eft: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr"=
><div></div><div>> In that regard, libraries like Fusion and Hana are pe=
rfect examples of why</div><div>> tuple unpacking needs to be a language=
feature.</div><div>></div><div>> Show me the Hana code for this:</di=
v><div>></div><div>> outer(inner([:]tpl)...)</div><div>></div><div=
>> This calls `inner` on each element of the tuple, then pipes the resul=
t into</div><div>> the call to `outer`. It works exactly like parameter =
packs too, so if `tpl`</div><div>> were a pack, you just drop the `[:]` =
syntax and it works.</div><div><br></div><div>With Hana, you'd write</d=
iv><div><br></div><div>=C2=A0 =C2=A0 hana::unpack(tpl, hana::on(inner, oute=
r));</div></div></blockquote><div><br>I have no idea what that means. I can=
guess at what `unpack` does, but "on" is <i>completely opaque</i=
> to me. I'd have to look that up in documentation to figure out what i=
t's doing.<br><br>Any C++11 programmer who has reasonable experience wi=
th variadic templates can at least take a guess at what `outer(inner([:]tpl=
)...)` is doing.<br><br>I know what a function call looks like. I know what=
nested function calls look like. `hana::on(inner, outer)` doesn't look=
anything like that.<br><br>Also, I never said that `inner` or `outer` were=
each a single functions. What happens if they're <i>overloaded</i>? In=
deed, given the circumstances (calling `inner` on each type), I imagine tha=
t it would be impossible for `inner` to <i>not</i> be overloaded or a templ=
ate function. Either way, this breaks. Do we need to have lifting syntax fo=
r overloads (which to be fair, is a thing we need in general)?<br><br>What =
if `inner` or `outer` is a member function? Does the user now have to whip =
out `std::bind`?<br><br>Also, there are performance questions. Will the ind=
irect call through `hana::on` prevent useful things like inlining?<br><br><=
/div><blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8e=
x;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr"><div></d=
iv><div>or you could also write</div><div><br></div><div>=C2=A0 =C2=A0 hana=
::unpack(tpl, [](auto ...x) { return outer(inner(x)...); });</div></div></b=
lockquote><div><br>Whenever your library equivalent to a 1-liner language f=
eature includes "introduce a Lambda", you have <i>lost</i> in ter=
ms of code comprehensibility. On the other hand, it does fix (most) of the =
functionality problems outlined above.<br><br>But here's the #1 reason =
why the library solution is the wrong solution: you <i>wrote it wrong</i>. =
You forgot to `std::forward` your arguments. And you forgot to use `decltyp=
e(auto)` for the return value. Both of which are needed to be exactly equiv=
alent to the above code. Without the `decltype(auto)`, if `outer` returned =
a reference of some kind, it could provoke an unwanted copy.<br><br>So it r=
eally needed to be:<br><br><div class=3D"prettyprint" style=3D"background-c=
olor: rgb(250, 250, 250); border-color: rgb(187, 187, 187); border-style: s=
olid; border-width: 1px; word-wrap: break-word;"><code class=3D"prettyprint=
"><div class=3D"subprettyprint"><span style=3D"color: #000;" class=3D"style=
d-by-prettify">hana</span><span style=3D"color: #660;" class=3D"styled-by-p=
rettify">::</span><span style=3D"color: #000;" class=3D"styled-by-prettify"=
>unpack</span><span style=3D"color: #660;" class=3D"styled-by-prettify">(</=
span><span style=3D"color: #000;" class=3D"styled-by-prettify">tpl</span><s=
pan style=3D"color: #660;" class=3D"styled-by-prettify">,</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color=
: #660;" class=3D"styled-by-prettify">[](</span><span style=3D"color: #008;=
" class=3D"styled-by-prettify">auto</span><span style=3D"color: #000;" clas=
s=3D"styled-by-prettify"> </span><span style=3D"color: #660;" class=3D"styl=
ed-by-prettify">...</span><span style=3D"color: #000;" class=3D"styled-by-p=
rettify">x</span><span style=3D"color: #660;" class=3D"styled-by-prettify">=
)</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><=
span style=3D"color: #660;" class=3D"styled-by-prettify">-></span><span =
style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"=
color: #008;" class=3D"styled-by-prettify">decltype</span><span style=3D"co=
lor: #660;" class=3D"styled-by-prettify">(</span><span style=3D"color: #008=
;" class=3D"styled-by-prettify">auto</span><span style=3D"color: #660;" cla=
ss=3D"styled-by-prettify">)</span><span style=3D"color: #000;" class=3D"sty=
led-by-prettify"> </span><span style=3D"color: #660;" class=3D"styled-by-pr=
ettify">{</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> =
</span><span style=3D"color: #008;" class=3D"styled-by-prettify">return</sp=
an><span style=3D"color: #000;" class=3D"styled-by-prettify"> outer</span><=
span style=3D"color: #660;" class=3D"styled-by-prettify">(</span><span styl=
e=3D"color: #000;" class=3D"styled-by-prettify">inner</span><span style=3D"=
color: #660;" class=3D"styled-by-prettify">(</span><span style=3D"color: #0=
00;" class=3D"styled-by-prettify">std</span><span style=3D"color: #660;" cl=
ass=3D"styled-by-prettify">::</span><span style=3D"color: #000;" class=3D"s=
tyled-by-prettify">forward</span><span style=3D"color: #660;" class=3D"styl=
ed-by-prettify"><</span><span style=3D"color: #008;" class=3D"styled-by-=
prettify">decltype</span><span style=3D"color: #660;" class=3D"styled-by-pr=
ettify">(</span><span style=3D"color: #008;" class=3D"styled-by-prettify">a=
uto</span><span style=3D"color: #660;" class=3D"styled-by-prettify">)>(<=
/span><span style=3D"color: #000;" class=3D"styled-by-prettify">x</span><sp=
an style=3D"color: #660;" class=3D"styled-by-prettify">)...));</span><span =
style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"=
color: #660;" class=3D"styled-by-prettify">});</span></div></code></div><br=
>I fail to see how this could be considered anywhere nearly as easy to unde=
rstand.<br><br></div><blockquote class=3D"gmail_quote" style=3D"margin: 0;m=
argin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=
=3D"ltr"><div></div><div>Basically, `unpack` is just `std::apply` but with =
the arguments reversed.</div><div><br></div><div><br></div><div>> Show m=
e the Hana code for this:</div><div>></div><div>> auto x =3D inner([:=
]tpl) + ...;</div><div>></div><div>> This simply calls a function on =
each element of the tuple and takes the sum</div><div>> of the results. =
Again, it works like parameter packs, so it reuses existing</div><div>> =
knowledge.</div><div><br></div><div>You could write</div><div><br></div><di=
v>=C2=A0 =C2=A0 auto x =3D hana::fold_left(hana::<wbr>transform(tpl, inner)=
, std::plus<>{});</div></div></blockquote><div><br>And for people who=
natively read right to left, this would probably be decent. But that's=
not how the rest of C++ works.<br><br></div><blockquote class=3D"gmail_quo=
te" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;paddi=
ng-left: 1ex;"><div dir=3D"ltr"><div></div><div>or equivalently</div><div><=
br></div><div>=C2=A0 =C2=A0 auto x =3D hana::fold_left(tpl, [](auto a, auto=
b) {</div><div>=C2=A0 =C2=A0 =C2=A0 =C2=A0 return a + inner(b);</div><div>=
=C2=A0 =C2=A0 });</div></div></blockquote><div><br>Again you forgot to forw=
ard the arguments and return values properly. Not to mention, you turn a si=
mple one-liner into a multi-line statement.<br>=C2=A0</div><blockquote clas=
s=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #c=
cc solid;padding-left: 1ex;"><div dir=3D"ltr"><div></div><div>`hana::fold_l=
eft` is just like `std::accumulate`, and `hana::transform` is</div><div>jus=
t like `std::transform`. To me, the fact that we're using algorithms th=
at</div><div>we already know from runtime programming is a good thing, wher=
eas your</div><div>proposed notation requires yet another special thing to =
learn.<br></div></div></blockquote><div><br>No, it requires learning exactl=
y one special thing: the syntax to turn a tuple into a parameter pack. Afte=
r that, you're just using existing parameter pack features. Which you n=
eed to know anyway, since that's a feature that we're getting one w=
ay or another.<br><br>Also, if `fold_left` is "just like `std::accumul=
ate`"... why is it called `fold_left`?<br><br></div><blockquote class=
=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #cc=
c solid;padding-left: 1ex;"><div dir=3D"ltr"><div> Of course,</div><div>you=
r proposed syntax wins here because it was designed precisely for these</di=
v><div>use cases, but I hope you'll agree that a library-based solution=
is nowhere</div><div>near the ugliness of good old Boost.Lambda expression=
s.</div></div></blockquote><div><br>Actually no. I'd argue that Boost.L=
ambda is more comprehensible by comparison. While it is certainly extremely=
bizarre and has a number of pitfalls, once you get used to the idea of a v=
alue effectively transforming an expression into a function, it's not s=
o bad for simple cases.<br><br>Hana by comparison requires <i>massive</i> e=
ffort for the simplest of cases. While I'm sure that it's great for=
complex metaprogramming, doing something as simple as the cases we've =
outlined requires a <i>lot</i> of domain knowledge.<br><br>That's why I=
say that Hana would make a good <i>supplement</i> to the language feature.=
Let the language handle 80+% of all cases; the library can handle the rest=
..<br>=C2=A0</div><blockquote class=3D"gmail_quote" style=3D"margin: 0;margi=
n-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"l=
tr"><div></div><div>> Oh, and show me the Hana code for this:</div><div>=
></div><div>> struct Data</div><div>> {</div><div>> =C2=A0 int =
i;</div><div>> =C2=A0 float f;</div><div>> =C2=A0 double d;</div><div=
>> };</div><div>></div><div>> Data d =3D ...;</div><div>> outer=
(inner([:]d)...);</div><div>></div><div>> It's the same as the fi=
rst example, only using an aggregate.</div><div><br></div><div>Ah! That'=
;s a good one! Here's how you would write it:</div><div><br></div><div>=
=C2=A0 =C2=A0 BOOST_HANA_DEFINE_STRUCT(Data,</div><div>=C2=A0 =C2=A0 =C2=A0=
=C2=A0 (int, i),</div><div>=C2=A0 =C2=A0 =C2=A0 =C2=A0 (float, f),</div><d=
iv>=C2=A0 =C2=A0 =C2=A0 =C2=A0 (double, d)</div><div>=C2=A0 =C2=A0 );</div>=
</div></blockquote><div><br>So... how do I put member functions in `Data`?<=
br><br></div><blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-le=
ft: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr">=
<div></div><div>=C2=A0 =C2=A0 Data d =3D ...;</div><div>=C2=A0 =C2=A0 hana:=
:unpack(hana::members(d), hana::on(inner, outer));</div><div><br></div><div=
>Really, the only cumbersome thing here is the definition of the struct.</d=
iv></div></blockquote><div><br>Then we have very different definitions of &=
quot;cumbersome".<br>=C2=A0</div><blockquote class=3D"gmail_quote" sty=
le=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left=
: 1ex;"><div dir=3D"ltr"><div>And I do agree that we need a proper way of i=
ntrospecting user defined types,</div><div>and __this is certainly not the =
job for a library__. However, if we designed</div><div>a proper way of intr=
ospecting user-defined types, it would then be very easy</div><div>to plug =
this into the customization point of a library. The challenge of</div><div>=
bringing compile-time introspection to C++ is obviously something that need=
s</div><div>to be done, but I think that's out of the scope of the curr=
ent discussion.</div><div><br></div><div><br></div><div>> [...]</div><di=
v>></div><div>> > If properly designed, that could be much more fl=
exible than</div><div>> > a language feature in the long term, when w=
e realize that we're missing</div><div>> > something else. Just t=
o give you a glimpse: how would you reverse a parameter</div><div>> >=
pack? How would you sort a parameter pack based on a compile-time predicat=
e?</div><div>> > I don't see how these slicing proposals are of a=
ny help, yet this is a very</div><div>> > real use case for metaprogr=
amming.</div><div>> ></div><div>> > Instead, I think we need to=
carefully design a STL for metaprogramming (with</div><div>> > custo=
mization points where it makes sense), and then let users build on top</div=
><div>> > of that. And if you're worried about compile-times bein=
g too long with a</div><div>> > library-based approach, this can be t=
ackled with a few well-chosen compiler</div><div>> > intrinsics (see =
this article [2]).</div><div>></div><div>> So instead of having langu=
age support for unpacking tuples, you want</div><div>> language support =
for... some low-level stuff that can be used to build</div><div>> a libr=
ary?</div><div>></div><div>> No thanks; I'll take the simple and =
easy-to-use feature over the huge and</div><div>> complex STL-like thing=
..</div><div><br></div><div>The problem I see is that to get rid of a more g=
eneral library solution that</div><div>you deem too complex, you propose ad=
ding a language feature that will only</div><div>tackle a subproblem. You&#=
39;re basically offloading complexity onto the language</div><div>itself, w=
hich I think is harmful.</div></div></blockquote><div><br>I'm not sayin=
g that we shouldn't have (something like) Hana. What I'm saying is =
that, for most use cases, Hana is far more painful to use than having the a=
bility to turn a tuple into a parameter pack. Library facilities for doing =
complex tuple operations are good.<br><br>But basic "for each element =
of a tuple" operations deserve to be a first-class language feature. T=
hey simplify uses of tuples in 80% of cases. For the other 20%, the library=
solution is available.<br><br>You don't use a machete to do surgery. B=
ut you don't go into the jungle with just a scalpel either.</div></div>
<p></p>
-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
Visit this group at <a href=3D"https://groups.google.com/a/isocpp.org/group=
/std-proposals/">https://groups.google.com/a/isocpp.org/group/std-proposals=
/</a>.<br />
------=_Part_924_1041711452.1455664739618--
------=_Part_923_1293943875.1455664739617--
.
Author: Nicol Bolas <jmckesson@gmail.com>
Date: Tue, 16 Feb 2016 15:29:53 -0800 (PST)
Raw View
------=_Part_7521_1502835729.1455665393663
Content-Type: multipart/alternative;
boundary="----=_Part_7522_1361472110.1455665393664"
------=_Part_7522_1361472110.1455665393664
Content-Type: text/plain; charset=UTF-8
On Tuesday, February 16, 2016 at 6:13:17 PM UTC-5, Louis Dionne wrote:
>
> On Tuesday, 16 February 2016 16:11:36 UTC-5, Matthew Woehlke wrote:
>
>> This is where I think we're having a communication issue. The syntax
>> you're objecting to is mostly related to fold expressions... which *are
>> already part of the language*.
>>
>> Please, by all means, submit proposals to make fold expressions /
>> dealing with parameter packs better :-).
>>
>> The "meat" of the general unpacking proposal is turning a tuple-like
>> into a parameter pack. The above suggests that hana doesn't solve that
>> problem.
>>
>
> Did you read my code examples? The above shows that it can be done
> with reasonable ease using hana::unpack.
>
We have very different ideas about what constitutes "reasonable". Your code
is functional, but it is not something I'd like to write *or* to code
review. Reasoning about your code requires in-depth knowledge of what all
those functions mean, are, and do.
Reasoning about `...` based code can be complex too; don't get me wrong.
But it's only complex in *complex* cases. In simple cases, it's simple.
Hana is *always* complicated.
> Let it be clear that I understand that the problems you're talking
>> > about for unpacking are real, and we need a solution (language or
>> > library-based). My discomfort lies in the fact that I'd like to see
>> > a carefully designed system that tackles more than just unpacking and
>> > slicing tuples, but that has a wider scope and unifying vision. And
>> > if unpacking/slicing ends up needing a language feature in this
>> > __designed__ system, then I'll be all for it. However, what I think
>> > we need to avoid is to introduce yet another short sighted feature
>> > that will quickly reach its limitations, and that we'll then need to
>> > patch with another short sighted feature later on.
>>
>> Perfect is the enemy of good. My... "concern with your concern", if you
>> will, is that in trying to build this grand cathedral, we either end up
>> with no solution at all, or something that makes simple tasks
>> impractically obtuse.
>>
>> I tend to think the analogy to lambdas is apt... a language solution may
>> not be *necessary* in the strict sense, but it's sufficiently *useful*
>> as to be worthwhile. (Same with P0144, BTW...)
>>
>> And again, the basic unpacking case (no slicing, just turn a tuple-like
>> into a parameter pack) allows us to, with a very simple and straight
>> forward language trick, combine the problem domains of parameter packs
>> and contained value sequences (i.e. "tuple-likes") so that the same
>> tools can be applied to both. (I'm certainly willing to entertain that
>> *those* tools could benefit from a well designed system for working with
>> parameter packs. But we already *have* parameter packs, so unless you
>> manage to throw those out entirely, the *worst* I see happening is that
>> you make `[:]` superfluous. If the slicing form is extended to directly
>> work on parameter packs, at worst we have a language tool for something
>> that could be done with a library tool.)
>>
>> Addition of two integers could be done using a library function rather
>> than a built-in operator, also... but it's something that happens often
>> enough that having a language feature (built-in addition operator) is
>> worthwhile for the improved readability.
>>
>> At any rate... write a paper. Because this grand cathedral you envision
>> isn't going to build itself. If you're convinced that there is a better
>> solution, *show us* that better solution :-).
>>
>
> Well, I just showed you a prototype for such a "grand cathedral"; Hana.
> It's not like I'm shovelling abstract nonsense around. I'm not trying to
> standardize Hana, but I think more awareness about what can be done
> is important if you're going to change the language, which is why I
> shared my experience with you.
>
> To make it back to the proposal, here's what I would find much more
> useful than simple unpacking and slicing, and that could actually be
> used to build more complex tuple algorithms. If we could take a tuple
> and unpack the elements at arbitrary indices, that would be useful.
> For example, disregarding the notation,
>
> auto tuple = std::make_tuple('0', '1', '2', '3', '4', '5');
> f(tuple[1, 0, 3, 3]); //equivalent to f('1', '0', '3', '3')
>
> Or, equivalently, if we could slice a tuple with an arbitrary
> `std::index_sequence`,
> that would be neat. The reason is that getting not-necessarily-adjacent
> elements
>
in a tuple is a very basic operation required to implement many other more
> complex algorithms, like `remove_if`, `reverse`, and even `sort`. Indeed,
> the
> idea to implement these algorithms is that we take the input tuple, then
> compute
> the indices that we want in the resulting tuple at compile-time (using
> constexpr
> computations or normal template metaprogramming), and then generate an
> index_sequence holding those indices. Finally, we extract the subsequence
> of
> elements at those indices to create a new tuple. That gives us a runtime
> complexity
> of O(1), and most computations can be carried in constexpr-world, which
> can be
> faster than template metaprogramming. In my experience, being able to
> extract
> an arbitrary subsequence of a tuple is far more useful than being able to
> extract
> only consecutive elements. Do you see a way your proposal could
> accommodate this?
>
*Behold the power of the elipsis!*
make_tuple(get<[:]index_sequence<1, 0, 3, 3>()>(tpl)...)
All this requires is a `constexpr` version of `get<N>(index_sequence)`. And
of course an `index_sequence` that is a literal type.
Is that good enough for you?
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-proposals/.
------=_Part_7522_1361472110.1455665393664
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">On Tuesday, February 16, 2016 at 6:13:17 PM UTC-5, Louis D=
ionne wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-lef=
t: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr">O=
n Tuesday, 16 February 2016 16:11:36 UTC-5, Matthew Woehlke wrote: <br><bl=
ockquote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-l=
eft:1px #ccc solid;padding-left:1ex">
This is where I think we're having a communication issue. The syntax
<br>you're objecting to is mostly related to fold expressions... which =
*are
<br>already part of the language*.
<br>
<br>Please, by all means, submit proposals to make fold expressions /
<br>dealing with parameter packs better :-).
<br>
<br>The "meat" of the general unpacking proposal is turning a tup=
le-like
<br>into a parameter pack. The above suggests that hana doesn't solve t=
hat
<br>problem.
<br></blockquote><div><br></div><div>Did you read my code examples? The abo=
ve shows that it can be done</div><div>with reasonable ease using hana::unp=
ack.</div></div></blockquote><div><br>We have very different ideas about wh=
at constitutes "reasonable". Your code is functional, but it is n=
ot something I'd like to write <i>or</i> to code review. Reasoning abou=
t your code requires in-depth knowledge of what all those functions mean, a=
re, and do.<br><br>Reasoning about `...` based code can be complex too; don=
't get me wrong. But it's only complex in <i>complex</i> cases. In =
simple cases, it's simple.<br><br>Hana is <i>always</i> complicated.<br=
><br></div><blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left=
: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr"><d=
iv></div><blockquote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.=
8ex;border-left:1px #ccc solid;padding-left:1ex">> Let it be clear that =
I understand that the problems you're talking
<br>> about for unpacking are real, and we need a solution (language or=
=20
<br>> library-based). My discomfort lies in the fact that I'd like t=
o see
<br>> a carefully designed system that tackles more than just unpacking =
and
<br>> slicing tuples, but that has a wider scope and unifying vision. An=
d
<br>> if unpacking/slicing ends up needing a language feature in this
<br>> __designed__ system, then I'll be all for it. However, what I =
think
<br>> we need to avoid is to introduce yet another short sighted feature
<br>> that will quickly reach its limitations, and that we'll then n=
eed to
<br>> patch with another short sighted feature later on.
<br>
<br>Perfect is the enemy of good. My... "concern with your concern&quo=
t;, if you
<br>will, is that in trying to build this grand cathedral, we either end up
<br>with no solution at all, or something that makes simple tasks
<br>impractically obtuse.
<br>
<br>I tend to think the analogy to lambdas is apt... a language solution ma=
y
<br>not be *necessary* in the strict sense, but it's sufficiently *usef=
ul*
<br>as to be worthwhile. (Same with P0144, BTW...)
<br>
<br>And again, the basic unpacking case (no slicing, just turn a tuple-like
<br>into a parameter pack) allows us to, with a very simple and straight
<br>forward language trick, combine the problem domains of parameter packs
<br>and contained value sequences (i.e. "tuple-likes") so that th=
e same
<br>tools can be applied to both. (I'm certainly willing to entertain t=
hat
<br>*those* tools could benefit from a well designed system for working wit=
h
<br>parameter packs. But we already *have* parameter packs, so unless you
<br>manage to throw those out entirely, the *worst* I see happening is that
<br>you make `[:]` superfluous. If the slicing form is extended to directly
<br>work on parameter packs, at worst we have a language tool for something
<br>that could be done with a library tool.)
<br>
<br>Addition of two integers could be done using a library function rather
<br>than a built-in operator, also... but it's something that happens o=
ften
<br>enough that having a language feature (built-in addition operator) is
<br>worthwhile for the improved readability.
<br>
<br>At any rate... write a paper. Because this grand cathedral you envision
<br>isn't going to build itself. If you're convinced that there is =
a better
<br>solution, *show us* that better solution :-).
<br></blockquote><div><br></div><div>Well, I just showed you a prototype fo=
r such a "grand cathedral"; Hana.</div><div>It's not like I&#=
39;m shovelling abstract nonsense around. I'm not trying to</div><div>s=
tandardize Hana, but I think more awareness about what can be done</div><di=
v>is important if you're going to change the language, which is why I</=
div><div>shared my experience with you.</div><div><br></div><div>To make it=
back to the proposal, here's what I would find much more</div><div>use=
ful than simple unpacking and slicing, and that could actually be</div><div=
>used to build more complex tuple algorithms. If we could take a tuple</div=
><div>and unpack the elements at arbitrary indices, that would be useful.</=
div><div>For example, disregarding the notation,</div><div><br></div><div><=
div style=3D"background-color:rgb(250,250,250);border:1px solid rgb(187,187=
,187);word-wrap:break-word"><code><div><span style=3D"color:#008">auto</spa=
n><span style=3D"color:#000"> tuple </span><span style=3D"color:#660">=3D</=
span><span style=3D"color:#000"> std</span><span style=3D"color:#660">::</s=
pan><span style=3D"color:#000">make_tuple</span><span style=3D"color:#660">=
(</span><span style=3D"color:#080">'0'</span><span style=3D"color:#=
660">,</span><span style=3D"color:#000"> </span><span style=3D"color:#080">=
'1'</span><span style=3D"color:#660">,</span><span style=3D"color:#=
000"> </span><span style=3D"color:#080">'2'</span><span style=3D"co=
lor:#660">,</span><span style=3D"color:#000"> </span><span style=3D"color:#=
080">'3'</span><span style=3D"color:#660">,</span><span style=3D"co=
lor:#000"> </span><span style=3D"color:#080">'4'</span><span style=
=3D"color:#660">,</span><span style=3D"color:#000"> </span><span style=3D"c=
olor:#080">'5'</span><span style=3D"color:#660">);</span><span styl=
e=3D"color:#000"><br>f</span><span style=3D"color:#660">(</span><span style=
=3D"color:#000">tuple</span><span style=3D"color:#660">[</span><span style=
=3D"color:#066">1</span><span style=3D"color:#660">,</span><span style=3D"c=
olor:#000"> </span><span style=3D"color:#066">0</span><font face=3D"Arial, =
Helvetica, sans-serif" color=3D"#666600"><span style=3D"color:#660">,</span=
><span style=3D"color:#000"> </span></font><span style=3D"color:#066">3</sp=
an><font face=3D"Arial, Helvetica, sans-serif" color=3D"#666600"><span styl=
e=3D"color:#660">,</span><span style=3D"color:#000"> </span></font><span st=
yle=3D"color:#066">3</span><span style=3D"color:#660">]</span><span style=
=3D"color:rgb(102,102,0);font-family:Arial,Helvetica,sans-serif"><span styl=
e=3D"color:#660">);</span><span style=3D"color:#000"> </span><span style=3D=
"color:#800">//equivalent to f('1', '0', '3', '=
3')</span></span></div></code></div><div><br></div>Or, equivalently, if=
we could slice a tuple with an arbitrary `std::index_sequence`,</div><div>=
that would be neat. The reason is that getting not-necessarily-adjacent ele=
ments</div></div></blockquote><blockquote class=3D"gmail_quote" style=3D"ma=
rgin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">=
<div dir=3D"ltr"><div>in a tuple is a very basic operation required to impl=
ement many other more</div><div>complex algorithms, like `remove_if`, `reve=
rse`, and even `sort`. Indeed, the</div><div>idea to implement these algori=
thms is that we take the input tuple, then compute</div><div>the indices th=
at we want in the resulting tuple at compile-time (using constexpr</div><di=
v>computations or normal template metaprogramming), and then generate an</d=
iv><div>index_sequence holding those indices. Finally, we extract the subse=
quence of</div><div>elements at those indices to create a new tuple. That g=
ives us a runtime complexity</div><div>of O(1), and most computations can b=
e carried in constexpr-world, which can be</div><div>faster than template m=
etaprogramming. In my experience, being able to extract</div><div>an arbitr=
ary subsequence of a tuple is far more useful than being able to extract</d=
iv><div>only consecutive elements. Do you see a way your proposal could acc=
ommodate this?</div></div></blockquote><div><br><i>Behold the power of the =
elipsis!</i><br><br><div class=3D"prettyprint" style=3D"background-color: r=
gb(250, 250, 250); border-color: rgb(187, 187, 187); border-style: solid; b=
order-width: 1px; word-wrap: break-word;"><code class=3D"prettyprint"><div =
class=3D"subprettyprint"><span style=3D"color: #000;" class=3D"styled-by-pr=
ettify">make_tuple</span><span style=3D"color: #660;" class=3D"styled-by-pr=
ettify">(</span><span style=3D"color: #008;" class=3D"styled-by-prettify">g=
et</span><span style=3D"color: #660;" class=3D"styled-by-prettify"><[:]<=
/span><span style=3D"color: #000;" class=3D"styled-by-prettify">index_seque=
nce</span><span style=3D"color: #660;" class=3D"styled-by-prettify"><</s=
pan><span style=3D"color: #066;" class=3D"styled-by-prettify">1</span><span=
style=3D"color: #660;" class=3D"styled-by-prettify">,</span><span style=3D=
"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #=
066;" class=3D"styled-by-prettify">0</span><span style=3D"color: #660;" cla=
ss=3D"styled-by-prettify">,</span><span style=3D"color: #000;" class=3D"sty=
led-by-prettify"> </span><span style=3D"color: #066;" class=3D"styled-by-pr=
ettify">3</span><span style=3D"color: #660;" class=3D"styled-by-prettify">,=
</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><s=
pan style=3D"color: #066;" class=3D"styled-by-prettify">3</span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">>()>(</span><span styl=
e=3D"color: #000;" class=3D"styled-by-prettify">tpl</span><span style=3D"co=
lor: #660;" class=3D"styled-by-prettify">)...)</span></div></code></div><br=
>All
this requires is a `constexpr` version of=20
`get<N>(index_sequence)`. And of course an `index_sequence` that=20
is a literal type.</div><br>Is that good enough for you?<br></div>
<p></p>
-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
Visit this group at <a href=3D"https://groups.google.com/a/isocpp.org/group=
/std-proposals/">https://groups.google.com/a/isocpp.org/group/std-proposals=
/</a>.<br />
------=_Part_7522_1361472110.1455665393664--
------=_Part_7521_1502835729.1455665393663--
.
Author: Louis Dionne <ldionne.2@gmail.com>
Date: Tue, 16 Feb 2016 15:57:58 -0800 (PST)
Raw View
------=_Part_5563_1688387714.1455667078995
Content-Type: multipart/alternative;
boundary="----=_Part_5564_1272298591.1455667078996"
------=_Part_5564_1272298591.1455667078996
Content-Type: text/plain; charset=UTF-8
On Tuesday, 16 February 2016 18:19:00 UTC-5, Nicol Bolas wrote:
>
> On Tuesday, February 16, 2016 at 3:21:29 PM UTC-5, Louis Dionne wrote:
>>
>> On Monday, 15 February 2016 21:10:52 UTC-5, Nicol Bolas wrote:
>> > On Monday, February 15, 2016 at 6:22:24 PM UTC-5, Louis Dionne wrote:
>> > > Hi,
>> > >
>> > > I'd like to quickly chime in to drop a link to Boost.Hana [1] (which
>> I'm the
>> > > author of, for full disclosure). There seems to be quite a bit of
>> discussion
>> > > about adding language features to manipulate packs and tuples, when a
>> lot of
>> > > this could be done in a library. Hana's purpose is specifically to
>> manipulate
>> > > tuples (and more generally heterogeneous containers) by providing
>> std-like
>> > > algorithms to operate on them.
>> > >
>> > > Reading the comments here, I just don't see the need for a new
>> language
>> > > feature for manipulating parameter packs. Instead, I think we need
>> proper
>> > > standard library features to manipulate tuples with a high level of
>> > > abstraction.
>> >
>> > That's like saying, "Why do we need lambdas in the language?
>> > We have Boost.Lambda!"
>> >
>> > Indeed, I seem to recall Boost.Lambda being one of the impetuses for
>> getting
>> > language-based lambdas. BLL was basically proof that you couldn't do
>> lambdas
>> > as a library. It said, "Look, this is the best the language can do as
>> is:
>> > here's what you get, here's what you have to do to implement it, here's
>> how
>> > ugly user-code looks, and here are all of the places where it breaks
>> down".
>>
>> It's significantly different in the level of cumbersomeness of using
>> Boost.Lambda vs language lambdas, and using Boost.Hana vs what you're
>> proposing. Language-level lambdas are an obvious relief because using
>> Boost.Lambda is a PITA. As you'll hopefully see below, the status quo
>> is workable if you use a proper library.
>>
>
> Boost.Lambda is workable too... for some definition of "workable".
>
> My point is not that you *cannot do it*. My point is what your code looks
> like afterwards.
>
> Hana code only looks reasonable to people experienced in Hana (and
> preferably with some functional background). The tuple unpacking code looks
> reasonable to C++ programmers experienced in C++ (variadic templates).
>
> I'll break down your examples to show you.
>
> > In that regard, libraries like Fusion and Hana are perfect examples of
>> why
>> > tuple unpacking needs to be a language feature.
>> >
>> > Show me the Hana code for this:
>> >
>> > outer(inner([:]tpl)...)
>> >
>> > This calls `inner` on each element of the tuple, then pipes the result
>> into
>> > the call to `outer`. It works exactly like parameter packs too, so if
>> `tpl`
>> > were a pack, you just drop the `[:]` syntax and it works.
>>
>> With Hana, you'd write
>>
>> hana::unpack(tpl, hana::on(inner, outer));
>>
>
> I have no idea what that means. I can guess at what `unpack` does, but
> "on" is *completely opaque* to me. I'd have to look that up in
> documentation to figure out what it's doing.
>
> Any C++11 programmer who has reasonable experience with variadic templates
> can at least take a guess at what `outer(inner([:]tpl)...)` is doing.
>
I disagree, for I wouldn't have figured it out myself. There's no point in
arguing over this.
> I know what a function call looks like. I know what nested function calls
> look like. `hana::on(inner, outer)` doesn't look anything like that.
>
> Also, I never said that `inner` or `outer` were each a single functions.
> What happens if they're *overloaded*? Indeed, given the circumstances
> (calling `inner` on each type), I imagine that it would be impossible for
> `inner` to *not* be overloaded or a template function. Either way, this
> breaks. Do we need to have lifting syntax for overloads (which to be fair,
> is a thing we need in general)?
>
A lifting syntax would be nice, but otherwise you can use the other
approach I suggested.
> What if `inner` or `outer` is a member function? Does the user now have to
> whip out `std::bind`?
>
> Also, there are performance questions. Will the indirect call through
> `hana::on` prevent useful things like inlining?
>
Any decent optimizer will get rid of this. If you trust your optimizer
enough to optimize away lambdas
in higher-order std algorithms, then you don't have a problem. However, the
idea of wildly unpacking
tuples into functions does bring a potential issue. What happens when a
function is called with a large
number of arguments performance-wise? If performance is important, it might
be better to pass the
actual tuple instead of its unpacked representation, but that would call
for a benchmark.
> or you could also write
>>
>> hana::unpack(tpl, [](auto ...x) { return outer(inner(x)...); });
>>
>
> Whenever your library equivalent to a 1-liner language feature includes
> "introduce a Lambda", you have *lost* in terms of code comprehensibility.
> On the other hand, it does fix (most) of the functionality problems
> outlined above.
>
You're drawing an arbitrary line without any argument for this. Actually,
I tend to prefer writing things more explicitly like above than using
nested ... expansions when things get complex, for I think the different
rules for ... expansion can be confusing.
>
> But here's the #1 reason why the library solution is the wrong solution:
> you *wrote it wrong*. You forgot to `std::forward` your arguments. And
> you forgot to use `decltype(auto)` for the return value. Both of which are
> needed to be exactly equivalent to the above code. Without the
> `decltype(auto)`, if `outer` returned a reference of some kind, it could
> provoke an unwanted copy.
>
> So it really needed to be:
>
> hana::unpack(tpl, [](auto ...x) -> decltype(auto) { return outer(inner(std
> ::forward<decltype(auto)>(x)...)); });
>
> I fail to see how this could be considered anywhere nearly as easy to
> understand.
>
Fair enough. But if we're going to be pedantic, let's be pedantic for real.
What you wanted
to write is
hana::unpack(tpl, [](auto&& ...x) -> decltype(auto) { return outer(inner(std
::forward<decltype(x)>(x))...); });
With this out of the way, I will argue that you actually don't need to
write the above, except
in rare cases where the tuple is potentially a rvalue. Instead, in most
cases, you'd just
have to write
hana::unpack(tpl, [](auto& ...x) -> decltype(auto) { return outer(inner(x
)...); });
which is slightly less verbose.
> Basically, `unpack` is just `std::apply` but with the arguments reversed.
>>
>>
>> > Show me the Hana code for this:
>> >
>> > auto x = inner([:]tpl) + ...;
>> >
>> > This simply calls a function on each element of the tuple and takes the
>> sum
>> > of the results. Again, it works like parameter packs, so it reuses
>> existing
>> > knowledge.
>>
>> You could write
>>
>> auto x = hana::fold_left(hana::transform(tpl, inner), std::plus<>{});
>>
>
> And for people who natively read right to left, this would probably be
> decent. But that's not how the rest of C++ works.
>
Wtf? How is this different from writing
auto x = ranges::accumulate(ranges::transformed(...), std::plus<>{});
> or equivalently
>>
>> auto x = hana::fold_left(tpl, [](auto a, auto b) {
>> return a + inner(b);
>> });
>>
>
> Again you forgot to forward the arguments and return values properly. Not
> to mention, you turn a simple one-liner into a multi-line statement.
>
Same argument as above. And the fact that I broke the statements into
multiple
lines to make it more readable is a feature. Honestly, I think this (and
especially
the transform/fold_left variant) is more readable than the variant with ...
expansions.
Of course, your version is more terse, but too terse is not good either.
Let's stop arguing over petty details. You want to hear it? Of course your
solution
is better for those use cases, because it was designed with those in mind!
But it is also much more limited, and the point I'm trying to make is that
from
the point of view of a metaprogramming library writer, this proposal, in its
current form, misses the goal just like fold expressions did.
`hana::fold_left` is just like `std::accumulate`, and `hana::transform` is
>> just like `std::transform`. To me, the fact that we're using algorithms
>> that
>> we already know from runtime programming is a good thing, whereas your
>> proposed notation requires yet another special thing to learn.
>>
>
> No, it requires learning exactly one special thing: the syntax to turn a
> tuple into a parameter pack. After that, you're just using existing
> parameter pack features. Which you need to know anyway, since that's a
> feature that we're getting one way or another.
>
> Also, if `fold_left` is "just like `std::accumulate`"... why is it called
> `fold_left`?
>
This naming is consistent with other choices made in the library.
>
> Of course,
>> your proposed syntax wins here because it was designed precisely for these
>> use cases, but I hope you'll agree that a library-based solution is
>> nowhere
>> near the ugliness of good old Boost.Lambda expressions.
>>
>
> Actually no. I'd argue that Boost.Lambda is more comprehensible by
> comparison. While it is certainly extremely bizarre and has a number of
> pitfalls, once you get used to the idea of a value effectively transforming
> an expression into a function, it's not so bad for simple cases.
>
> Hana by comparison requires *massive* effort for the simplest of cases.
> While I'm sure that it's great for complex metaprogramming, doing something
> as simple as the cases we've outlined requires a *lot* of domain
> knowledge.
>
Have you tried using it? Have you tried writing equivalent code yourself?
That's why I say that Hana would make a good *supplement* to the language
> feature. Let the language handle 80+% of all cases; the library can handle
> the rest.
>
>
>> > Oh, and show me the Hana code for this:
>> >
>> > struct Data
>> > {
>> > int i;
>> > float f;
>> > double d;
>> > };
>> >
>> > Data d = ...;
>> > outer(inner([:]d)...);
>> >
>> > It's the same as the first example, only using an aggregate.
>>
>> Ah! That's a good one! Here's how you would write it:
>>
>> BOOST_HANA_DEFINE_STRUCT(Data,
>> (int, i),
>> (float, f),
>> (double, d)
>> );
>>
>
> So... how do I put member functions in `Data`?
>
I actually wrote this wrong. The correct way would have been
struct Data {
BOOST_HANA_DEFINE_STRUCT(Data,
(int, i),
(float, f),
(double, d)
);
// You can put whatever you want here
};
But again, this is largely irrelevant to the ongoing discussion and I would
be more
than happy to have a proper language feature that would allow me to remove
these
crufty macros.
>
> Data d = ...;
>> hana::unpack(hana::members(d), hana::on(inner, outer));
>>
>> Really, the only cumbersome thing here is the definition of the struct.
>>
>
> Then we have very different definitions of "cumbersome".
>
>
>> And I do agree that we need a proper way of introspecting user defined
>> types,
>> and __this is certainly not the job for a library__. However, if we
>> designed
>> a proper way of introspecting user-defined types, it would then be very
>> easy
>> to plug this into the customization point of a library. The challenge of
>> bringing compile-time introspection to C++ is obviously something that
>> needs
>> to be done, but I think that's out of the scope of the current discussion.
>>
>>
>> > [...]
>> >
>> > > If properly designed, that could be much more flexible than
>> > > a language feature in the long term, when we realize that we're
>> missing
>> > > something else. Just to give you a glimpse: how would you reverse a
>> parameter
>> > > pack? How would you sort a parameter pack based on a compile-time
>> predicate?
>> > > I don't see how these slicing proposals are of any help, yet this is
>> a very
>> > > real use case for metaprogramming.
>> > >
>> > > Instead, I think we need to carefully design a STL for
>> metaprogramming (with
>> > > customization points where it makes sense), and then let users build
>> on top
>> > > of that. And if you're worried about compile-times being too long
>> with a
>> > > library-based approach, this can be tackled with a few well-chosen
>> compiler
>> > > intrinsics (see this article [2]).
>> >
>> > So instead of having language support for unpacking tuples, you want
>> > language support for... some low-level stuff that can be used to build
>> > a library?
>> >
>> > No thanks; I'll take the simple and easy-to-use feature over the huge
>> and
>> > complex STL-like thing.
>>
>> The problem I see is that to get rid of a more general library solution
>> that
>> you deem too complex, you propose adding a language feature that will only
>> tackle a subproblem. You're basically offloading complexity onto the
>> language
>> itself, which I think is harmful.
>>
>
> I'm not saying that we shouldn't have (something like) Hana. What I'm
> saying is that, for most use cases, Hana is far more painful to use than
> having the ability to turn a tuple into a parameter pack. Library
> facilities for doing complex tuple operations are good.
>
> But basic "for each element of a tuple" operations deserve to be a
> first-class language feature. They simplify uses of tuples in 80% of cases.
> For the other 20%, the library solution is available.
>
> You don't use a machete to do surgery. But you don't go into the jungle
> with just a scalpel either.
>
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-proposals/.
------=_Part_5564_1272298591.1455667078996
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><br><br>On Tuesday, 16 February 2016 18:19:00 UTC-5, Nicol=
Bolas wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-l=
eft: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr"=
>On Tuesday, February 16, 2016 at 3:21:29 PM UTC-5, Louis Dionne wrote:<blo=
ckquote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-le=
ft:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><div></div><div>On Mon=
day, 15 February 2016 21:10:52 UTC-5, Nicol Bolas wrote:</div><div>> On =
Monday, February 15, 2016 at 6:22:24 PM UTC-5, Louis Dionne wrote:</div><di=
v>> > Hi,</div><div>> ></div><div>> > I'd like to qui=
ckly chime in to drop a link to Boost.Hana [1] (which I'm the</div><div=
>> > author of, for full disclosure). There seems to be quite a bit o=
f discussion</div><div>> > about adding language features to manipula=
te packs and tuples, when a lot of</div><div>> > this could be done i=
n a library. Hana's purpose is specifically to manipulate</div><div>>=
; > tuples (and more generally heterogeneous containers) by providing st=
d-like</div><div>> > algorithms to operate on them.</div><div>> &g=
t;</div><div>> > Reading the comments here, I just don't see the =
need for a new language</div><div>> > feature for manipulating parame=
ter packs. Instead, I think we need proper</div><div>> > standard lib=
rary features to manipulate tuples with a high level of</div><div>> >=
abstraction.</div><div>></div><div>> That's like saying, "W=
hy do we need lambdas in the language?</div><div>> We have Boost.Lambda!=
"</div><div>></div><div>> Indeed, I seem to recall Boost.Lambda =
being one of the impetuses for getting</div><div>> language-based lambda=
s. BLL was basically proof that you couldn't do lambdas</div><div>> =
as a library. It said, "Look, this is the best the language can do as =
is:</div><div>> here's what you get, here's what you have to do =
to implement it, here's how</div><div>> ugly user-code looks, and he=
re are all of the places where it breaks down".</div><div><br></div><d=
iv>It's significantly different in the level of cumbersomeness of using=
</div><div>Boost.Lambda vs language lambdas, and using Boost.Hana vs what y=
ou're</div><div>proposing. Language-level lambdas are an obvious relief=
because using</div><div>Boost.Lambda is a PITA. As you'll hopefully se=
e below, the status quo</div><div>is workable if you use a proper library.<=
/div></div></blockquote><div><br>Boost.Lambda is workable too... for some d=
efinition of "workable".<br><br>My point is not that you <i>canno=
t do it</i>. My point is what your code looks like afterwards.<br><br>Hana
code only looks reasonable to people experienced in Hana (and preferably w=
ith some functional background). The tuple=20
unpacking code looks reasonable to C++ programmers experienced in C++=20
(variadic templates).<br><br>I'll break down your examples to show you.=
<br><br></div><blockquote class=3D"gmail_quote" style=3D"margin:0;margin-le=
ft:0.8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><div=
></div><div>> In that regard, libraries like Fusion and Hana are perfect=
examples of why</div><div>> tuple unpacking needs to be a language feat=
ure.</div><div>></div><div>> Show me the Hana code for this:</div><di=
v>></div><div>> outer(inner([:]tpl)...)</div><div>></div><div>>=
This calls `inner` on each element of the tuple, then pipes the result int=
o</div><div>> the call to `outer`. It works exactly like parameter packs=
too, so if `tpl`</div><div>> were a pack, you just drop the `[:]` synta=
x and it works.</div><div><br></div><div>With Hana, you'd write</div><d=
iv><br></div><div>=C2=A0 =C2=A0 hana::unpack(tpl, hana::on(inner, outer));<=
/div></div></blockquote><div><br>I have no idea what that means. I can gues=
s at what `unpack` does, but "on" is <i>completely opaque</i> to =
me. I'd have to look that up in documentation to figure out what it'=
;s doing.<br><br>Any C++11 programmer who has reasonable experience with va=
riadic templates can at least take a guess at what `outer(inner([:]tpl)...)=
` is doing.<br></div></div></blockquote><div><br></div><div>I disagree, for=
I wouldn't have figured it out myself. There's no point in arguing=
over this.</div><div><br></div><div>=C2=A0</div><blockquote class=3D"gmail=
_quote" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;p=
adding-left: 1ex;"><div dir=3D"ltr"><div>I know what a function call looks =
like. I know what nested function calls look like. `hana::on(inner, outer)`=
doesn't look anything like that.<br><br>Also, I never said that `inner=
` or `outer` were each a single functions. What happens if they're <i>o=
verloaded</i>? Indeed, given the circumstances (calling `inner` on each typ=
e), I imagine that it would be impossible for `inner` to <i>not</i> be over=
loaded or a template function. Either way, this breaks. Do we need to have =
lifting syntax for overloads (which to be fair, is a thing we need in gener=
al)?<br></div></div></blockquote><div><br></div><div>A lifting syntax would=
be nice, but otherwise you can use the other approach I suggested.</div><d=
iv><br></div><div>=C2=A0</div><blockquote class=3D"gmail_quote" style=3D"ma=
rgin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">=
<div dir=3D"ltr"><div>What if `inner` or `outer` is a member function? Does=
the user now have to whip out `std::bind`?<br><br>Also, there are performa=
nce questions. Will the indirect call through `hana::on` prevent useful thi=
ngs like inlining?<br></div></div></blockquote><div><br></div><div>Any dece=
nt optimizer will get rid of this. If you trust your optimizer enough to op=
timize away lambdas</div><div>in higher-order std algorithms, then you don&=
#39;t have a problem. However, the idea of wildly unpacking</div><div>tuple=
s into functions does bring a potential issue. What happens when a function=
is called with a large</div><div>number of arguments performance-wise? If =
performance is important, it might be better to pass the</div><div>actual t=
uple instead of its unpacked representation, but that would call for a benc=
hmark.</div><div>=C2=A0</div><blockquote class=3D"gmail_quote" style=3D"mar=
gin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><=
div dir=3D"ltr"><blockquote class=3D"gmail_quote" style=3D"margin:0;margin-=
left:0.8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><d=
iv></div><div>or you could also write</div><div><br></div><div>=C2=A0 =C2=
=A0 hana::unpack(tpl, [](auto ...x) { return outer(inner(x)...); });</div><=
/div></blockquote><div><br>Whenever your library equivalent to a 1-liner la=
nguage feature includes "introduce a Lambda", you have <i>lost</i=
> in terms of code comprehensibility. On the other hand, it does fix (most)=
of the functionality problems outlined above.<br></div></div></blockquote>=
<div><br></div><div>You're drawing an arbitrary line without any argume=
nt for this. Actually,</div><div>I tend to prefer writing things more expli=
citly like above than using</div><div>nested ... expansions when things get=
complex, for I think the different</div><div>rules for ... expansion can b=
e confusing.</div><div>=C2=A0</div><blockquote class=3D"gmail_quote" style=
=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: =
1ex;"><div dir=3D"ltr"><div><br>But here's the #1 reason why the librar=
y solution is the wrong solution: you <i>wrote it wrong</i>. You forgot to =
`std::forward` your arguments. And you forgot to use `decltype(auto)` for t=
he return value. Both of which are needed to be exactly equivalent to the a=
bove code. Without the `decltype(auto)`, if `outer` returned a reference of=
some kind, it could provoke an unwanted copy.<br><br>So it really needed t=
o be:<br><br><div style=3D"background-color:rgb(250,250,250);border-color:r=
gb(187,187,187);border-style:solid;border-width:1px;word-wrap:break-word"><=
code><div><span style=3D"color:#000">hana</span><span style=3D"color:#660">=
::</span><span style=3D"color:#000">unpack</span><span style=3D"color:#660"=
>(</span><span style=3D"color:#000">tpl</span><span style=3D"color:#660">,<=
/span><span style=3D"color:#000"> </span><span style=3D"color:#660">[](</sp=
an><span style=3D"color:#008">auto</span><span style=3D"color:#000"> </span=
><span style=3D"color:#660">...</span><span style=3D"color:#000">x</span><s=
pan style=3D"color:#660">)</span><span style=3D"color:#000"> </span><span s=
tyle=3D"color:#660">-></span><span style=3D"color:#000"> </span><span st=
yle=3D"color:#008">decltype</span><span style=3D"color:#660">(</span><span =
style=3D"color:#008">auto</span><span style=3D"color:#660">)</span><span st=
yle=3D"color:#000"> </span><span style=3D"color:#660">{</span><span style=
=3D"color:#000"> </span><span style=3D"color:#008">return</span><span style=
=3D"color:#000"> outer</span><span style=3D"color:#660">(</span><span style=
=3D"color:#000">inner</span><span style=3D"color:#660">(</span><span style=
=3D"color:#000">std</span><span style=3D"color:#660">::</span><span style=
=3D"color:#000">forward</span><span style=3D"color:#660"><</span><span s=
tyle=3D"color:#008">declt<wbr>ype</span><span style=3D"color:#660">(</span>=
<span style=3D"color:#008">auto</span><span style=3D"color:#660">)>(</sp=
an><span style=3D"color:#000">x</span><span style=3D"color:#660">)...));</s=
pan><span style=3D"color:#000"> </span><span style=3D"color:#660">});</span=
></div></code></div><br>I fail to see how this could be considered anywhere=
nearly as easy to understand.<br></div></div></blockquote><div><br></div><=
div>Fair enough. But if we're going to be pedantic, let's be pedant=
ic for real. What you wanted</div><div>to write is</div><div><div class=3D"=
prettyprint" style=3D"background-color: rgb(250, 250, 250); border: 1px sol=
id rgb(187, 187, 187); word-wrap: break-word;"><code class=3D"prettyprint">=
<div class=3D"subprettyprint"><span style=3D"color: #000;" class=3D"styled-=
by-prettify">hana</span><span style=3D"color: #660;" class=3D"styled-by-pre=
ttify">::</span><span style=3D"color: #000;" class=3D"styled-by-prettify">u=
npack</span><span style=3D"color: #660;" class=3D"styled-by-prettify">(</sp=
an><span style=3D"color: #000;" class=3D"styled-by-prettify">tpl</span><spa=
n style=3D"color: #660;" class=3D"styled-by-prettify">,</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color=
: #660;" class=3D"styled-by-prettify">[](</span><span style=3D"color: #008;=
" class=3D"styled-by-prettify">auto</span><span style=3D"color: #660;" clas=
s=3D"styled-by-prettify">&&</span><span style=3D"color: #000;" clas=
s=3D"styled-by-prettify"> </span><span style=3D"color: #660;" class=3D"styl=
ed-by-prettify">...</span><span style=3D"color: #000;" class=3D"styled-by-p=
rettify">x</span><span style=3D"color: #660;" class=3D"styled-by-prettify">=
)</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><=
font color=3D"#666600"><span style=3D"color: #660;" class=3D"styled-by-pret=
tify">-></span><span style=3D"color: #000;" class=3D"styled-by-prettify"=
> </span><span style=3D"color: #008;" class=3D"styled-by-prettify">decltype=
</span><span style=3D"color: #660;" class=3D"styled-by-prettify">(</span><s=
pan style=3D"color: #008;" class=3D"styled-by-prettify">auto</span><span st=
yle=3D"color: #660;" class=3D"styled-by-prettify">)</span><span style=3D"co=
lor: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #660=
;" class=3D"styled-by-prettify">{</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"> </span><span style=3D"color: #008;" class=3D"style=
d-by-prettify">return</span><span style=3D"color: #000;" class=3D"styled-by=
-prettify"> outer</span><span style=3D"color: #660;" class=3D"styled-by-pre=
ttify">(</span><span style=3D"color: #000;" class=3D"styled-by-prettify">in=
ner</span><span style=3D"color: #660;" class=3D"styled-by-prettify">(</span=
><span style=3D"color: #000;" class=3D"styled-by-prettify">std</span><span =
style=3D"color: #660;" class=3D"styled-by-prettify">::</span><span style=3D=
"color: #000;" class=3D"styled-by-prettify">forward</span><span style=3D"co=
lor: #660;" class=3D"styled-by-prettify"><</span><span style=3D"color: #=
008;" class=3D"styled-by-prettify">decltype</span><span style=3D"color: #66=
0;" class=3D"styled-by-prettify">(</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify">x</span><span style=3D"color: #660;" class=3D"style=
d-by-prettify">)>(</span><span style=3D"color: #000;" class=3D"styled-by=
-prettify">x</span><span style=3D"color: #660;" class=3D"styled-by-prettify=
">))...);</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> =
</span><span style=3D"color: #660;" class=3D"styled-by-prettify">});</span>=
</font></div></code></div><div><br></div><div>With this out of the way, I w=
ill argue that you actually don't need to write the above, except</div>=
<div>in rare cases where the tuple is potentially a rvalue. Instead, in mos=
t cases, you'd just</div><div>have to write</div><div><br></div><div><d=
iv class=3D"prettyprint" style=3D"background-color: rgb(250, 250, 250); bor=
der: 1px solid rgb(187, 187, 187); word-wrap: break-word;"><code class=3D"p=
rettyprint"><div class=3D"subprettyprint"><font color=3D"#660066"><span sty=
le=3D"color: #000;" class=3D"styled-by-prettify">hana</span><span style=3D"=
color: #660;" class=3D"styled-by-prettify">::</span><span style=3D"color: #=
000;" class=3D"styled-by-prettify">unpack</span><span style=3D"color: #660;=
" class=3D"styled-by-prettify">(</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify">tpl</span><span style=3D"color: #660;" class=3D"sty=
led-by-prettify">,</span><span style=3D"color: #000;" class=3D"styled-by-pr=
ettify"> </span><span style=3D"color: #660;" class=3D"styled-by-prettify">[=
](</span><span style=3D"color: #008;" class=3D"styled-by-prettify">auto</sp=
an><span style=3D"color: #660;" class=3D"styled-by-prettify">&</span><s=
pan style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">...</span><span style=3D"col=
or: #000;" class=3D"styled-by-prettify">x</span><span style=3D"color: #660;=
" class=3D"styled-by-prettify">)</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"> </span><span style=3D"color: #660;" class=3D"style=
d-by-prettify">-></span><span style=3D"color: #000;" class=3D"styled-by-=
prettify"> </span><span style=3D"color: #008;" class=3D"styled-by-prettify"=
>decltype</span><span style=3D"color: #660;" class=3D"styled-by-prettify">(=
</span><span style=3D"color: #008;" class=3D"styled-by-prettify">auto</span=
><span style=3D"color: #660;" class=3D"styled-by-prettify">)</span><span st=
yle=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"co=
lor: #660;" class=3D"styled-by-prettify">{</span><span style=3D"color: #000=
;" class=3D"styled-by-prettify"> </span><span style=3D"color: #008;" class=
=3D"styled-by-prettify">return</span><span style=3D"color: #000;" class=3D"=
styled-by-prettify"> outer</span><span style=3D"color: #660;" class=3D"styl=
ed-by-prettify">(</span><span style=3D"color: #000;" class=3D"styled-by-pre=
ttify">inner</span><span style=3D"color: #660;" class=3D"styled-by-prettify=
">(</span><span style=3D"color: #000;" class=3D"styled-by-prettify">x</span=
><span style=3D"color: #660;" class=3D"styled-by-prettify">)...);</span><sp=
an style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">});</span></font></div></cod=
e></div><div><br></div>which is slightly less verbose.</div><div><br></div>=
</div><blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8=
ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr"><div><b=
r></div><blockquote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8=
ex;border-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><div></div=
><div>Basically, `unpack` is just `std::apply` but with the arguments rever=
sed.</div><div><br></div><div><br></div><div>> Show me the Hana code for=
this:</div><div>></div><div>> auto x =3D inner([:]tpl) + ...;</div><=
div>></div><div>> This simply calls a function on each element of the=
tuple and takes the sum</div><div>> of the results. Again, it works lik=
e parameter packs, so it reuses existing</div><div>> knowledge.</div><di=
v><br></div><div>You could write</div><div><br></div><div>=C2=A0 =C2=A0 aut=
o x =3D hana::fold_left(hana::<wbr>transform(tpl, inner), std::plus<>=
{});</div></div></blockquote><div><br>And for people who natively read righ=
t to left, this would probably be decent. But that's not how the rest o=
f C++ works.<br></div></div></blockquote><div><br></div><div>Wtf? How is th=
is different from writing=C2=A0</div><div><br></div><div><div class=3D"pret=
typrint" style=3D"background-color: rgb(250, 250, 250); border: 1px solid r=
gb(187, 187, 187); word-wrap: break-word;"><code class=3D"prettyprint"><div=
class=3D"subprettyprint"><font color=3D"#000000"><span style=3D"color: #00=
8;" class=3D"styled-by-prettify">auto</span><span style=3D"color: #000;" cl=
ass=3D"styled-by-prettify"> x </span><span style=3D"color: #660;" class=3D"=
styled-by-prettify">=3D</span><span style=3D"color: #000;" class=3D"styled-=
by-prettify"> ranges</span><span style=3D"color: #660;" class=3D"styled-by-=
prettify">::</span><span style=3D"color: #000;" class=3D"styled-by-prettify=
">accumulate</span><span style=3D"color: #660;" class=3D"styled-by-prettify=
">(</span></font><span style=3D"color: #000;" class=3D"styled-by-prettify">=
ranges</span><span style=3D"color: #660;" class=3D"styled-by-prettify">::</=
span><font color=3D"#000000"><span style=3D"color: #000;" class=3D"styled-b=
y-prettify">transformed</span><span style=3D"color: #660;" class=3D"styled-=
by-prettify">(...)</span></font><font color=3D"#000000"><span style=3D"colo=
r: #660;" class=3D"styled-by-prettify">,</span><span style=3D"color: #000;"=
class=3D"styled-by-prettify"> std</span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">::</span><span style=3D"color: #000;" class=3D"styl=
ed-by-prettify">plus</span><span style=3D"color: #660;" class=3D"styled-by-=
prettify"><>{});</span></font></div></code></div><div><br></div><div>=
<br></div></div><blockquote class=3D"gmail_quote" style=3D"margin: 0;margin=
-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"lt=
r"><div><br></div><blockquote class=3D"gmail_quote" style=3D"margin:0;margi=
n-left:0.8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr">=
<div></div><div>or equivalently</div><div><br></div><div>=C2=A0 =C2=A0 auto=
x =3D hana::fold_left(tpl, [](auto a, auto b) {</div><div>=C2=A0 =C2=A0 =
=C2=A0 =C2=A0 return a + inner(b);</div><div>=C2=A0 =C2=A0 });</div></div><=
/blockquote><div><br>Again you forgot to forward the arguments and return v=
alues properly. Not to mention, you turn a simple one-liner into a multi-li=
ne statement.<br></div></div></blockquote><div><br></div><div>Same argument=
as above. And the fact that I broke the statements into multiple</div><div=
>lines to make it more readable is a feature. Honestly, I think this (and e=
specially</div><div>the transform/fold_left variant) is more readable than =
the variant with ... expansions.</div><div>Of course, your version is more =
terse, but too terse is not good either.</div><div><br></div><div>Let's=
stop arguing over petty details. You want to hear it? Of course your solut=
ion</div><div>is better for those use cases, because it was designed with t=
hose in mind!</div><div>But it is also much more limited, and the point I&#=
39;m trying to make is that from</div><div>the point of view of a metaprogr=
amming library writer, this proposal, in its</div><div>current form, misses=
the goal just like fold expressions did.</div><div><br></div><div><br></di=
v><blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;b=
order-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr"><blockquote=
class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1px =
#ccc solid;padding-left:1ex"><div dir=3D"ltr"><div></div><div>`hana::fold_l=
eft` is just like `std::accumulate`, and `hana::transform` is</div><div>jus=
t like `std::transform`. To me, the fact that we're using algorithms th=
at</div><div>we already know from runtime programming is a good thing, wher=
eas your</div><div>proposed notation requires yet another special thing to =
learn.<br></div></div></blockquote><div><br>No, it requires learning exactl=
y one special thing: the syntax to turn a tuple into a parameter pack. Afte=
r that, you're just using existing parameter pack features. Which you n=
eed to know anyway, since that's a feature that we're getting one w=
ay or another.<br><br>Also, if `fold_left` is "just like `std::accumul=
ate`"... why is it called `fold_left`?<br></div></div></blockquote><di=
v><br></div><div>This naming is consistent with other choices made in the l=
ibrary.</div><div>=C2=A0</div><blockquote class=3D"gmail_quote" style=3D"ma=
rgin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">=
<div dir=3D"ltr"><div><br></div><blockquote class=3D"gmail_quote" style=3D"=
margin:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-left:1ex"><di=
v dir=3D"ltr"><div> Of course,</div><div>your proposed syntax wins here bec=
ause it was designed precisely for these</div><div>use cases, but I hope yo=
u'll agree that a library-based solution is nowhere</div><div>near the =
ugliness of good old Boost.Lambda expressions.</div></div></blockquote><div=
><br>Actually no. I'd argue that Boost.Lambda is more comprehensible by=
comparison. While it is certainly extremely bizarre and has a number of pi=
tfalls, once you get used to the idea of a value effectively transforming a=
n expression into a function, it's not so bad for simple cases.<br><br>=
Hana by comparison requires <i>massive</i> effort for the simplest of cases=
.. While I'm sure that it's great for complex metaprogramming, doing=
something as simple as the cases we've outlined requires a <i>lot</i> =
of domain knowledge.<br></div></div></blockquote><div><br></div><div>Have y=
ou tried using it? Have you tried writing equivalent code yourself?</div><d=
iv>=C2=A0</div><div><br></div><blockquote class=3D"gmail_quote" style=3D"ma=
rgin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">=
<div dir=3D"ltr"><div>That's why I say that Hana would make a good <i>s=
upplement</i> to the language feature. Let the language handle 80+% of all =
cases; the library can handle the rest.<br>=C2=A0</div><blockquote class=3D=
"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc soli=
d;padding-left:1ex"><div dir=3D"ltr"><div></div><div>> Oh, and show me t=
he Hana code for this:</div><div>></div><div>> struct Data</div><div>=
> {</div><div>> =C2=A0 int i;</div><div>> =C2=A0 float f;</div><di=
v>> =C2=A0 double d;</div><div>> };</div><div>></div><div>> Dat=
a d =3D ...;</div><div>> outer(inner([:]d)...);</div><div>></div><div=
>> It's the same as the first example, only using an aggregate.</div=
><div><br></div><div>Ah! That's a good one! Here's how you would wr=
ite it:</div><div><br></div><div>=C2=A0 =C2=A0 BOOST_HANA_DEFINE_STRUCT(Dat=
a,</div><div>=C2=A0 =C2=A0 =C2=A0 =C2=A0 (int, i),</div><div>=C2=A0 =C2=A0 =
=C2=A0 =C2=A0 (float, f),</div><div>=C2=A0 =C2=A0 =C2=A0 =C2=A0 (double, d)=
</div><div>=C2=A0 =C2=A0 );</div></div></blockquote><div><br>So... how do I=
put member functions in `Data`?<br></div></div></blockquote><div><br></div=
><div>I actually wrote this wrong. The correct way would have been</div><di=
v><br></div><div><div class=3D"prettyprint" style=3D"background-color: rgb(=
250, 250, 250); border: 1px solid rgb(187, 187, 187); word-wrap: break-word=
;"><code class=3D"prettyprint"><div class=3D"subprettyprint"><div class=3D"=
subprettyprint">struct Data {</div><div class=3D"subprettyprint">=C2=A0 =C2=
=A0 BOOST_HANA_DEFINE_STRUCT(Data,</div><div class=3D"subprettyprint">=C2=
=A0 =C2=A0 =C2=A0 =C2=A0 (int, i),</div><div class=3D"subprettyprint">=C2=
=A0 =C2=A0 =C2=A0 =C2=A0 (float, f),<br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 (double=
, d)</div><div class=3D"subprettyprint">=C2=A0 =C2=A0 );<br><br>=C2=A0 =C2=
=A0 // You can put whatever you want here</div><div class=3D"subprettyprint=
">};</div></div></code></div><br>But again, this is largely irrelevant to t=
he ongoing discussion and I would be more</div><div>than happy to have a pr=
oper language feature that would allow me to remove these</div><div>crufty =
macros.</div><div><br></div><div>=C2=A0</div><blockquote class=3D"gmail_quo=
te" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;paddi=
ng-left: 1ex;"><div dir=3D"ltr"><div><br></div><blockquote class=3D"gmail_q=
uote" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;paddin=
g-left:1ex"><div dir=3D"ltr"><div></div><div>=C2=A0 =C2=A0 Data d =3D ...;<=
/div><div>=C2=A0 =C2=A0 hana::unpack(hana::members(d), hana::on(inner, oute=
r));</div><div><br></div><div>Really, the only cumbersome thing here is the=
definition of the struct.</div></div></blockquote><div><br>Then we have ve=
ry different definitions of "cumbersome".<br>=C2=A0</div><blockqu=
ote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1=
px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><div>And I do agree that w=
e need a proper way of introspecting user defined types,</div><div>and __th=
is is certainly not the job for a library__. However, if we designed</div><=
div>a proper way of introspecting user-defined types, it would then be very=
easy</div><div>to plug this into the customization point of a library. The=
challenge of</div><div>bringing compile-time introspection to C++ is obvio=
usly something that needs</div><div>to be done, but I think that's out =
of the scope of the current discussion.</div><div><br></div><div><br></div>=
<div>> [...]</div><div>></div><div>> > If properly designed, th=
at could be much more flexible than</div><div>> > a language feature =
in the long term, when we realize that we're missing</div><div>> >=
; something else. Just to give you a glimpse: how would you reverse a param=
eter</div><div>> > pack? How would you sort a parameter pack based on=
a compile-time predicate?</div><div>> > I don't see how these sl=
icing proposals are of any help, yet this is a very</div><div>> > rea=
l use case for metaprogramming.</div><div>> ></div><div>> > Ins=
tead, I think we need to carefully design a STL for metaprogramming (with</=
div><div>> > customization points where it makes sense), and then let=
users build on top</div><div>> > of that. And if you're worried =
about compile-times being too long with a</div><div>> > library-based=
approach, this can be tackled with a few well-chosen compiler</div><div>&g=
t; > intrinsics (see this article [2]).</div><div>></div><div>> So=
instead of having language support for unpacking tuples, you want</div><di=
v>> language support for... some low-level stuff that can be used to bui=
ld</div><div>> a library?</div><div>></div><div>> No thanks; I'=
;ll take the simple and easy-to-use feature over the huge and</div><div>>=
; complex STL-like thing.</div><div><br></div><div>The problem I see is tha=
t to get rid of a more general library solution that</div><div>you deem too=
complex, you propose adding a language feature that will only</div><div>ta=
ckle a subproblem. You're basically offloading complexity onto the lang=
uage</div><div>itself, which I think is harmful.</div></div></blockquote><d=
iv><br>I'm not saying that we shouldn't have (something like) Hana.=
What I'm saying is that, for most use cases, Hana is far more painful =
to use than having the ability to turn a tuple into a parameter pack. Libra=
ry facilities for doing complex tuple operations are good.<br><br>But basic=
"for each element of a tuple" operations deserve to be a first-c=
lass language feature. They simplify uses of tuples in 80% of cases. For th=
e other 20%, the library solution is available.<br><br>You don't use a =
machete to do surgery. But you don't go into the jungle with just a sca=
lpel either.</div></div></blockquote></div>
<p></p>
-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
Visit this group at <a href=3D"https://groups.google.com/a/isocpp.org/group=
/std-proposals/">https://groups.google.com/a/isocpp.org/group/std-proposals=
/</a>.<br />
------=_Part_5564_1272298591.1455667078996--
------=_Part_5563_1688387714.1455667078995--
.
Author: Louis Dionne <ldionne.2@gmail.com>
Date: Tue, 16 Feb 2016 16:07:30 -0800 (PST)
Raw View
------=_Part_5740_352118127.1455667650118
Content-Type: multipart/alternative;
boundary="----=_Part_5741_1479236709.1455667650119"
------=_Part_5741_1479236709.1455667650119
Content-Type: text/plain; charset=UTF-8
On Tuesday, 16 February 2016 18:29:54 UTC-5, Nicol Bolas wrote:
>
> On Tuesday, February 16, 2016 at 6:13:17 PM UTC-5, Louis Dionne wrote:
>>
>> On Tuesday, 16 February 2016 16:11:36 UTC-5, Matthew Woehlke wrote:
>>
>>> This is where I think we're having a communication issue. The syntax
>>> you're objecting to is mostly related to fold expressions... which *are
>>> already part of the language*.
>>>
>>> Please, by all means, submit proposals to make fold expressions /
>>> dealing with parameter packs better :-).
>>>
>>> The "meat" of the general unpacking proposal is turning a tuple-like
>>> into a parameter pack. The above suggests that hana doesn't solve that
>>> problem.
>>>
>>
>> Did you read my code examples? The above shows that it can be done
>> with reasonable ease using hana::unpack.
>>
>
> We have very different ideas about what constitutes "reasonable". Your
> code is functional, but it is not something I'd like to write *or* to
> code review. Reasoning about your code requires in-depth knowledge of what
> all those functions mean, are, and do.
>
> Reasoning about `...` based code can be complex too; don't get me wrong.
> But it's only complex in *complex* cases. In simple cases, it's simple.
>
> Hana is *always* complicated.
>
I doubt you're speaking out of experience here. I can't really defend
myself against this since I wrote the library, but I think it's plain BS.
> Let it be clear that I understand that the problems you're talking
>>> > about for unpacking are real, and we need a solution (language or
>>> > library-based). My discomfort lies in the fact that I'd like to see
>>> > a carefully designed system that tackles more than just unpacking and
>>> > slicing tuples, but that has a wider scope and unifying vision. And
>>> > if unpacking/slicing ends up needing a language feature in this
>>> > __designed__ system, then I'll be all for it. However, what I think
>>> > we need to avoid is to introduce yet another short sighted feature
>>> > that will quickly reach its limitations, and that we'll then need to
>>> > patch with another short sighted feature later on.
>>>
>>> Perfect is the enemy of good. My... "concern with your concern", if you
>>> will, is that in trying to build this grand cathedral, we either end up
>>> with no solution at all, or something that makes simple tasks
>>> impractically obtuse.
>>>
>>> I tend to think the analogy to lambdas is apt... a language solution may
>>> not be *necessary* in the strict sense, but it's sufficiently *useful*
>>> as to be worthwhile. (Same with P0144, BTW...)
>>>
>>> And again, the basic unpacking case (no slicing, just turn a tuple-like
>>> into a parameter pack) allows us to, with a very simple and straight
>>> forward language trick, combine the problem domains of parameter packs
>>> and contained value sequences (i.e. "tuple-likes") so that the same
>>> tools can be applied to both. (I'm certainly willing to entertain that
>>> *those* tools could benefit from a well designed system for working with
>>> parameter packs. But we already *have* parameter packs, so unless you
>>> manage to throw those out entirely, the *worst* I see happening is that
>>> you make `[:]` superfluous. If the slicing form is extended to directly
>>> work on parameter packs, at worst we have a language tool for something
>>> that could be done with a library tool.)
>>>
>>> Addition of two integers could be done using a library function rather
>>> than a built-in operator, also... but it's something that happens often
>>> enough that having a language feature (built-in addition operator) is
>>> worthwhile for the improved readability.
>>>
>>> At any rate... write a paper. Because this grand cathedral you envision
>>> isn't going to build itself. If you're convinced that there is a better
>>> solution, *show us* that better solution :-).
>>>
>>
>> Well, I just showed you a prototype for such a "grand cathedral"; Hana.
>> It's not like I'm shovelling abstract nonsense around. I'm not trying to
>> standardize Hana, but I think more awareness about what can be done
>> is important if you're going to change the language, which is why I
>> shared my experience with you.
>>
>> To make it back to the proposal, here's what I would find much more
>> useful than simple unpacking and slicing, and that could actually be
>> used to build more complex tuple algorithms. If we could take a tuple
>> and unpack the elements at arbitrary indices, that would be useful.
>> For example, disregarding the notation,
>>
>> auto tuple = std::make_tuple('0', '1', '2', '3', '4', '5');
>> f(tuple[1, 0, 3, 3]); //equivalent to f('1', '0', '3', '3')
>>
>> Or, equivalently, if we could slice a tuple with an arbitrary
>> `std::index_sequence`,
>> that would be neat. The reason is that getting not-necessarily-adjacent
>> elements
>>
> in a tuple is a very basic operation required to implement many other more
>> complex algorithms, like `remove_if`, `reverse`, and even `sort`. Indeed,
>> the
>> idea to implement these algorithms is that we take the input tuple, then
>> compute
>> the indices that we want in the resulting tuple at compile-time (using
>> constexpr
>> computations or normal template metaprogramming), and then generate an
>> index_sequence holding those indices. Finally, we extract the subsequence
>> of
>> elements at those indices to create a new tuple. That gives us a runtime
>> complexity
>> of O(1), and most computations can be carried in constexpr-world, which
>> can be
>> faster than template metaprogramming. In my experience, being able to
>> extract
>> an arbitrary subsequence of a tuple is far more useful than being able to
>> extract
>> only consecutive elements. Do you see a way your proposal could
>> accommodate this?
>>
>
> *Behold the power of the elipsis!*
>
> make_tuple(get<[:]index_sequence<1, 0, 3, 3>()>(tpl)...)
>
> All this requires is a `constexpr` version of `get<N>(index_sequence)`.
> And of course an `index_sequence` that is a literal type.
>
> Is that good enough for you?
>
No, unfortunately it's not. The one thing that's really interesting with
having a language
feature to slice a tuple is that the compiler might implement this more
efficiently than
doing a dumb syntactic translation and then instantiating the `get<>`
functions for real.
With what you outline above, the compiler has to instantiate the `get<>`
function for
the index_sequence, and then for the tuple. This is a problem for
compile-times.
Basically, what I need is simple. I need a very fast (at compile-time) way
to get the
elements at arbitrary indices inside a tuple. If your proposal does not
give me this,
it's of no use to me (as a metaprogramming library writer, that is).
Otherwise, then
you just solved one of my long standing problems.
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-proposals/.
------=_Part_5741_1479236709.1455667650119
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><br><br>On Tuesday, 16 February 2016 18:29:54 UTC-5, Nicol=
Bolas wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-l=
eft: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr"=
>On Tuesday, February 16, 2016 at 6:13:17 PM UTC-5, Louis Dionne wrote:<blo=
ckquote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-le=
ft:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr">On Tuesday, 16 Februar=
y 2016 16:11:36 UTC-5, Matthew Woehlke wrote: <br><blockquote class=3D"gma=
il_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;pa=
dding-left:1ex">
This is where I think we're having a communication issue. The syntax
<br>you're objecting to is mostly related to fold expressions... which =
*are
<br>already part of the language*.
<br>
<br>Please, by all means, submit proposals to make fold expressions /
<br>dealing with parameter packs better :-).
<br>
<br>The "meat" of the general unpacking proposal is turning a tup=
le-like
<br>into a parameter pack. The above suggests that hana doesn't solve t=
hat
<br>problem.
<br></blockquote><div><br></div><div>Did you read my code examples? The abo=
ve shows that it can be done</div><div>with reasonable ease using hana::unp=
ack.</div></div></blockquote><div><br>We have very different ideas about wh=
at constitutes "reasonable". Your code is functional, but it is n=
ot something I'd like to write <i>or</i> to code review. Reasoning abou=
t your code requires in-depth knowledge of what all those functions mean, a=
re, and do.<br><br>Reasoning about `...` based code can be complex too; don=
't get me wrong. But it's only complex in <i>complex</i> cases. In =
simple cases, it's simple.<br><br>Hana is <i>always</i> complicated.<br=
></div></div></blockquote><div><br></div><div>I doubt you're speaking o=
ut of experience here. I can't really defend</div><div>myself against t=
his since I wrote the library, but I think it's plain BS.</div><div>=C2=
=A0</div><div><br></div><blockquote class=3D"gmail_quote" style=3D"margin: =
0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div d=
ir=3D"ltr"><blockquote class=3D"gmail_quote" style=3D"margin:0;margin-left:=
0.8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><div></=
div><blockquote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;b=
order-left:1px #ccc solid;padding-left:1ex">> Let it be clear that I und=
erstand that the problems you're talking
<br>> about for unpacking are real, and we need a solution (language or=
=20
<br>> library-based). My discomfort lies in the fact that I'd like t=
o see
<br>> a carefully designed system that tackles more than just unpacking =
and
<br>> slicing tuples, but that has a wider scope and unifying vision. An=
d
<br>> if unpacking/slicing ends up needing a language feature in this
<br>> __designed__ system, then I'll be all for it. However, what I =
think
<br>> we need to avoid is to introduce yet another short sighted feature
<br>> that will quickly reach its limitations, and that we'll then n=
eed to
<br>> patch with another short sighted feature later on.
<br>
<br>Perfect is the enemy of good. My... "concern with your concern&quo=
t;, if you
<br>will, is that in trying to build this grand cathedral, we either end up
<br>with no solution at all, or something that makes simple tasks
<br>impractically obtuse.
<br>
<br>I tend to think the analogy to lambdas is apt... a language solution ma=
y
<br>not be *necessary* in the strict sense, but it's sufficiently *usef=
ul*
<br>as to be worthwhile. (Same with P0144, BTW...)
<br>
<br>And again, the basic unpacking case (no slicing, just turn a tuple-like
<br>into a parameter pack) allows us to, with a very simple and straight
<br>forward language trick, combine the problem domains of parameter packs
<br>and contained value sequences (i.e. "tuple-likes") so that th=
e same
<br>tools can be applied to both. (I'm certainly willing to entertain t=
hat
<br>*those* tools could benefit from a well designed system for working wit=
h
<br>parameter packs. But we already *have* parameter packs, so unless you
<br>manage to throw those out entirely, the *worst* I see happening is that
<br>you make `[:]` superfluous. If the slicing form is extended to directly
<br>work on parameter packs, at worst we have a language tool for something
<br>that could be done with a library tool.)
<br>
<br>Addition of two integers could be done using a library function rather
<br>than a built-in operator, also... but it's something that happens o=
ften
<br>enough that having a language feature (built-in addition operator) is
<br>worthwhile for the improved readability.
<br>
<br>At any rate... write a paper. Because this grand cathedral you envision
<br>isn't going to build itself. If you're convinced that there is =
a better
<br>solution, *show us* that better solution :-).
<br></blockquote><div><br></div><div>Well, I just showed you a prototype fo=
r such a "grand cathedral"; Hana.</div><div>It's not like I&#=
39;m shovelling abstract nonsense around. I'm not trying to</div><div>s=
tandardize Hana, but I think more awareness about what can be done</div><di=
v>is important if you're going to change the language, which is why I</=
div><div>shared my experience with you.</div><div><br></div><div>To make it=
back to the proposal, here's what I would find much more</div><div>use=
ful than simple unpacking and slicing, and that could actually be</div><div=
>used to build more complex tuple algorithms. If we could take a tuple</div=
><div>and unpack the elements at arbitrary indices, that would be useful.</=
div><div>For example, disregarding the notation,</div><div><br></div><div><=
div style=3D"background-color:rgb(250,250,250);border:1px solid rgb(187,187=
,187);word-wrap:break-word"><code><div><span style=3D"color:#008">auto</spa=
n><span style=3D"color:#000"> tuple </span><span style=3D"color:#660">=3D</=
span><span style=3D"color:#000"> std</span><span style=3D"color:#660">::</s=
pan><span style=3D"color:#000">make_tuple</span><span style=3D"color:#660">=
(</span><span style=3D"color:#080">'0'</span><span style=3D"color:#=
660">,</span><span style=3D"color:#000"> </span><span style=3D"color:#080">=
'1'</span><span style=3D"color:#660">,</span><span style=3D"color:#=
000"> </span><span style=3D"color:#080">'2'</span><span style=3D"co=
lor:#660">,</span><span style=3D"color:#000"> </span><span style=3D"color:#=
080">'3'</span><span style=3D"color:#660">,</span><span style=3D"co=
lor:#000"> </span><span style=3D"color:#080">'4'</span><span style=
=3D"color:#660">,</span><span style=3D"color:#000"> </span><span style=3D"c=
olor:#080">'5'</span><span style=3D"color:#660">);</span><span styl=
e=3D"color:#000"><br>f</span><span style=3D"color:#660">(</span><span style=
=3D"color:#000">tuple</span><span style=3D"color:#660">[</span><span style=
=3D"color:#066">1</span><span style=3D"color:#660">,</span><span style=3D"c=
olor:#000"> </span><span style=3D"color:#066">0</span><font face=3D"Arial, =
Helvetica, sans-serif" color=3D"#666600"><span style=3D"color:#660">,</span=
><span style=3D"color:#000"> </span></font><span style=3D"color:#066">3</sp=
an><font face=3D"Arial, Helvetica, sans-serif" color=3D"#666600"><span styl=
e=3D"color:#660">,</span><span style=3D"color:#000"> </span></font><span st=
yle=3D"color:#066">3</span><span style=3D"color:#660">]</span><span style=
=3D"color:rgb(102,102,0);font-family:Arial,Helvetica,sans-serif"><span styl=
e=3D"color:#660">);</span><span style=3D"color:#000"> </span><span style=3D=
"color:#800">//equivalent to f('1', '0', '3', '=
3')</span></span></div></code></div><div><br></div>Or, equivalently, if=
we could slice a tuple with an arbitrary `std::index_sequence`,</div><div>=
that would be neat. The reason is that getting not-necessarily-adjacent ele=
ments</div></div></blockquote><blockquote class=3D"gmail_quote" style=3D"ma=
rgin:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-left:1ex"><div =
dir=3D"ltr"><div>in a tuple is a very basic operation required to implement=
many other more</div><div>complex algorithms, like `remove_if`, `reverse`,=
and even `sort`. Indeed, the</div><div>idea to implement these algorithms =
is that we take the input tuple, then compute</div><div>the indices that we=
want in the resulting tuple at compile-time (using constexpr</div><div>com=
putations or normal template metaprogramming), and then generate an</div><d=
iv>index_sequence holding those indices. Finally, we extract the subsequenc=
e of</div><div>elements at those indices to create a new tuple. That gives =
us a runtime complexity</div><div>of O(1), and most computations can be car=
ried in constexpr-world, which can be</div><div>faster than template metapr=
ogramming. In my experience, being able to extract</div><div>an arbitrary s=
ubsequence of a tuple is far more useful than being able to extract</div><d=
iv>only consecutive elements. Do you see a way your proposal could accommod=
ate this?</div></div></blockquote><div><br><i>Behold the power of the elips=
is!</i><br><br><div style=3D"background-color:rgb(250,250,250);border-color=
:rgb(187,187,187);border-style:solid;border-width:1px;word-wrap:break-word"=
><code><div><span style=3D"color:#000">make_tuple</span><span style=3D"colo=
r:#660">(</span><span style=3D"color:#008">get</span><span style=3D"color:#=
660"><[:]</span><span style=3D"color:#000">index_<wbr>sequence</span><sp=
an style=3D"color:#660"><</span><span style=3D"color:#066">1</span><span=
style=3D"color:#660">,</span><span style=3D"color:#000"> </span><span styl=
e=3D"color:#066">0</span><span style=3D"color:#660">,</span><span style=3D"=
color:#000"> </span><span style=3D"color:#066">3</span><span style=3D"color=
:#660">,</span><span style=3D"color:#000"> </span><span style=3D"color:#066=
">3</span><span style=3D"color:#660">>()>(</span><span style=3D"color=
:#000">tpl</span><span style=3D"color:#660">)...)</span></div></code></div>=
<br>All
this requires is a `constexpr` version of=20
`get<N>(index_sequence)`. And of course an `index_sequence` that=20
is a literal type.</div><br>Is that good enough for you?<br></div></blockqu=
ote><div><br></div><div>No, unfortunately it's not. The one thing that&=
#39;s really interesting with having a language</div><div>feature to slice =
a tuple is that the compiler might implement this more efficiently than</di=
v><div>doing a dumb syntactic translation and then instantiating the `get&l=
t;>` functions for real.</div><div>With what you outline above, the comp=
iler has to instantiate the `get<>` function for</div><div>the index_=
sequence, and then for the tuple. This is a problem for compile-times.</div=
><div><br></div><div>Basically, what I need is simple. I need a very fast (=
at compile-time) way to get the</div><div>elements at arbitrary indices ins=
ide a tuple. If your proposal does not give me this,</div><div>it's of =
no use to me (as a metaprogramming library writer, that is). Otherwise, the=
n</div><div>you just solved one of my long standing problems.</div><div><br=
></div></div>
<p></p>
-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
Visit this group at <a href=3D"https://groups.google.com/a/isocpp.org/group=
/std-proposals/">https://groups.google.com/a/isocpp.org/group/std-proposals=
/</a>.<br />
------=_Part_5741_1479236709.1455667650119--
------=_Part_5740_352118127.1455667650118--
.
Author: "Arthur O'Dwyer" <arthur.j.odwyer@gmail.com>
Date: Tue, 16 Feb 2016 17:42:29 -0800
Raw View
--047d7b33dc50e5fdce052bed5c06
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
On Tue, Feb 16, 2016 at 3:13 PM, Louis Dionne <ldionne.2@gmail.com> wrote:
> On Tuesday, 16 February 2016 16:11:36 UTC-5, Matthew Woehlke wrote:
>> On 2016-02-16 15:21, Louis Dionne wrote:
>> > On Monday, 15 February 2016 21:10:52 UTC-5, Nicol Bolas wrote:
>> >> Oh, and show me the Hana code for this:
>> >>
>> >> struct Data
>> >> {
>> >> int i;
>> >> float f;
>> >> double d;
>> >> };
>> >>
>> >> Data d =3D ...;
>> >> outer(inner([:]d)...);
>> >
>> > Ah! That's a good one! Here's how you would write it:
>> >
>> > BOOST_HANA_DEFINE_STRUCT(Data,
>>
>> Oops. That right there is a no-go. [...]
>
> [...] If you don't have control over the type, you can
> also use BOOST_HANA_ADAPT_STRUCT to adapt an existing struct.
> But all of this is completely irrelevant, since I myself said that
these macros
> were nothing but workarounds for the lack of proper
introspection facilities,
> which need to be built into the language. This is obviously neither where
> we disagree nor the subject of this discussion.
Right. The idea that a POD struct should be tuple-like was never part of
this discussion before, and I don't see how it'd be possible without a lot
of unproposed language support for introspection/reflection, *and*
personally I currently think it would be a bad idea. Certainly it's a
distraction from the point of the discussion.
FWIW, guys, I'm pretty sure Louis has *at least* twice the real-world
metaprogramming experience of all three of us put together. IMO you
shouldn't be quick to dismiss anything he has to say on the subject.
(Carefully considered dismissal is still okay. ;))
>> > On Tuesday, 16 February 2016 11:07:30 UTC-5, Matthew Woehlke wrote:
>> >> On Monday, February 15, 2016 at 6:22:24 PM UTC-5, Louis Dionne wrote:
>> >>> I don't see how these slicing proposals are of any help, yet this
>> >>> is a very real use case for metaprogramming.
>> >>
>> >> That's... nice. Many of the example uses for unpacking and even
slicing
>> >> *do not* involve metaprogramming. Do you have such examples for
>> >> reversing and sorting?
>> >
>> > I guess that's just a misunderstanding on what exactly is to be
>> > considered metaprogramming. As for use cases, sorting can be useful
>> > if you e.g. have computations with compile-time dependencies and
>> > want to run them in the right order. You sort them at compile-time
>> > and then execute the computations. Or it could also be sorting types
>> > by alignment as a runtime optimization. Sorting is arguably more
>> > useful than reversing in my experience, but otherslike `find_if` are
>> > even more important yet we don't have any good way of doing it.
Matthew's Python-inspired [:] notation would support reversal and strided
access easily enough (just as Python does). My tilde-notation would not.
Sorting, filtering, etc would still be the domain of libraries like Hana,
no matter what, because they're intrinsically operations on the data items
(e.g. the types in a typelist), rather than on the indices. So we can't get
away from the need for libraries; the question Louis is raising, IMHO, is
whether given the need for a library, we could get away with using that
library even for the "simple" stuff. My kneejerk reaction is "no,
pack-expansions are much much better than Hana for the simple stuff"; but
I'm not 100% sure, never having played with Hana.
>> > Let it be clear that I understand that the problems you're talking
>> > about for unpacking are real, and we need a solution (language or
>> > library-based). My discomfort lies in the fact that I'd like to see
>> > a carefully designed system that tackles more than just unpacking and
>> > slicing tuples, but that has a wider scope and unifying vision. And
>> > if unpacking/slicing ends up needing a language feature in this
>> > __designed__ system, then I'll be all for it. However, what I think
>> > we need to avoid is to introduce yet another short sighted feature
>> > that will quickly reach its limitations, and that we'll then need to
>> > patch with another short sighted feature later on.
Hear, hear. (I said a similar thing earlier, not about the need for a
language feature at all, but about the need for the language feature to
hook directly into the names std::get and std::tuple_element_t. Just
because *I* don't know how to do it right doesn't mean *nobody* knows.)
[...]
> To make it back to the proposal, here's what I would find much more
> useful than simple unpacking and slicing, and that could actually be
> used to build more complex tuple algorithms. If we could take a tuple
> and unpack the elements at arbitrary indices, that would be useful.
[...]
> faster than template metaprogramming. In my experience, being able
to extract
> an arbitrary subsequence of a tuple is far more useful than being able
to extract
> only consecutive elements. Do you see a way your proposal could
accommodate
> this?
Nicol has shown how to do it with tuple-unpacking, assuming that
index_sequence is tuple-like:
tie(get<index_sequence<1, 0, 3, 3>()~>(tpl)...)
In fact, this shorter refinement would also work (out of the box), because
make_tuple is constexpr:
tie(get<make_tuple(1, 0, 3, 3)~>(tpl)...)
If we assume that our constexpr tuple of indices is named "indices", then:
return forward_as_tuple(get<indices~>(tpl)...);
would do the trick perfectly, I think. (I won't bet money on it though. :))
(Thanks, Nicol, for that neat trick =E2=80=94 I wouldn't have thought of it=
myself!)
=E2=80=93Arthur
--=20
---=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-propos=
als/.
--047d7b33dc50e5fdce052bed5c06
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">On Tue, Feb 16, 2016 at 3:13 PM, Louis Dionne <<a href=
=3D"mailto:ldionne.2@gmail.com">ldionne.2@gmail.com</a>> wrote:<br>> =
On Tuesday, 16 February 2016 16:11:36 UTC-5, Matthew Woehlke wrote:<br>>=
> On 2016-02-16 15:21, Louis Dionne wrote:<br>>> > On Monday, 1=
5 February 2016 21:10:52 UTC-5, Nicol Bolas wrote:<br>>> >> Oh,=
and show me the Hana code for this:<br>>> >><br>>> >&=
gt; struct Data<br>>> >> {<br>>> >> =C2=A0 int i;<b=
r>>> >> =C2=A0 float f;<br>>> >> =C2=A0 double d;<b=
r>>> >> };<br>>> >><br>>> >> Data d =3D=
...;<br>>> >> outer(inner([:]d)...);<br>>> ><br>>&=
gt; > Ah! That's a good one! Here's how you would write it:<br>&=
gt;> ><br>>> > =C2=A0 =C2=A0 BOOST_HANA_DEFINE_STRUCT(Data,<=
br>>><br>>> Oops. That right there is a no-go. [...]<br>><br=
>> [...]=C2=A0If you don't have control over the type, you can<br>&g=
t; also use BOOST_HANA_ADAPT_STRUCT to adapt an existing struct.<br>> Bu=
t all of this is completely irrelevant, since I myself said that these=C2=
=A0macros<br>> were nothing but workarounds for the lack of proper intro=
spection=C2=A0facilities,<br>> which need to be built into the language.=
This is obviously neither where<br>> we disagree nor the subject of thi=
s discussion.<div><br></div><div>Right. The idea that a POD struct should b=
e tuple-like was never part of this discussion before, and I don't see =
how it'd be possible without a lot of unproposed language support for i=
ntrospection/reflection, *and* personally I currently think it would be a b=
ad idea. Certainly it's a distraction from the point of the discussion.=
</div><div><br></div><div>FWIW, guys, I'm pretty sure Louis has <i>at l=
east</i> twice the real-world metaprogramming experience of all three of us=
put together. IMO you shouldn't be quick to dismiss anything he has to=
say on the subject. =C2=A0(Carefully considered dismissal is still okay. ;=
))</div><div><br><br></div><div>>> > On Tuesday, 16 February 2016 =
11:07:30 UTC-5, Matthew Woehlke wrote:<br>>> >> On Monday, Febr=
uary 15, 2016 at 6:22:24 PM UTC-5, Louis Dionne wrote:<br>>> >>=
> I don't see how these slicing proposals are of any help, yet this<=
br>>> >>> is a very real use case for metaprogramming.<br>&g=
t;> >><br>>> >> That's... nice. Many of the exampl=
e uses for unpacking and even slicing<br>>> >> *do not* involve=
metaprogramming. Do you have such examples for<br>>> >> revers=
ing and sorting?<br>>> ><br>>> > I guess that's just =
a misunderstanding on what exactly is to be<br>>> > considered met=
aprogramming. As for use cases, sorting can be useful<br>>> > if y=
ou e.g. have computations with compile-time dependencies and<br>>> &g=
t; want to run them in the right order. You sort them at compile-time<br>&g=
t;> > and then execute the computations. Or it could also be sorting =
types<br>>> > by alignment as a runtime optimization. Sorting is a=
rguably more<br>>> > useful than reversing in my experience, but o=
therslike `find_if` are<br>>> > even more important yet we don'=
;t have any good way of doing it.</div><div><br></div><div>Matthew's Py=
thon-inspired [:] notation would support reversal and strided access easily=
enough (just as Python does). My tilde-notation would not.</div><div><br><=
/div><div>Sorting, filtering, etc would still be the domain of libraries li=
ke Hana, no matter what, because they're intrinsically operations on th=
e data items (e.g. the types in a typelist), rather than on the indices. So=
we can't get away from the need for libraries; the question Louis is r=
aising, IMHO, is whether given the need for a library, we could get away wi=
th using that library even for the "simple" stuff. My kneejerk re=
action is "no, pack-expansions are much much better than Hana for the =
simple stuff"; but I'm not 100% sure, never having played with Han=
a.</div><div><br></div><div><br></div><div>>> > Let it be clear th=
at I understand that the problems you're talking<br></div><div>>>=
> about for unpacking are real, and we need a solution (language or<br>=
>> > library-based). My discomfort lies in the fact that I'd l=
ike to see<br>>> > a carefully designed system that tackles more t=
han just unpacking and<br>>> > slicing tuples, but that has a wide=
r scope and unifying vision. And<br>>> > if unpacking/slicing ends=
up needing a language feature in this<br>>> > __designed__ system=
, then I'll be all for it. However, what I think<br>>> > we ne=
ed to avoid is to introduce yet another short sighted feature<br>>> &=
gt; that will quickly reach its limitations, and that we'll then need t=
o<br>>> > patch with another short sighted feature later on.</div>=
<div><br></div><div>Hear, hear. (I said a similar thing earlier, not about =
the need for a language feature at all, but about the need for the language=
feature to hook directly into the names std::get and std::tuple_element_t.=
Just because <i>I</i> don't know how to do it right doesn't mean <=
i>nobody</i> knows.)</div><div><br>[...]</div><div>> To make it back to =
the proposal, here's what I would find much more<br>> useful than si=
mple unpacking and slicing, and that could actually be<br>> used to buil=
d more complex tuple algorithms. If we could take a tuple<br>> and unpac=
k the elements at arbitrary indices, that would be useful.</div><div>[...]<=
br>> faster than template metaprogramming. In my experience, being able =
to=C2=A0extract<br>> an arbitrary subsequence of a tuple is far more use=
ful than being able to=C2=A0extract<br>> only consecutive elements. Do y=
ou see a way your proposal could accommodate<br>> this?</div><div><br></=
div><div>Nicol has shown how to do it with tuple-unpacking, assuming that <=
font face=3D"monospace, monospace">index_sequence</font> is tuple-like:</di=
v><font face=3D"monospace, monospace">=C2=A0 =C2=A0 tie(get<index_sequen=
ce<1, 0, 3, 3>()~>(tpl)...)</font><div>In fact, this shorter refin=
ement would also work (out of the box), because <font face=3D"monospace, mo=
nospace">make_tuple</font> is constexpr:</div><div><font face=3D"monospace,=
monospace">=C2=A0 =C2=A0 tie(get<make_tuple(1, 0, 3, 3)~>(tpl)...)</=
font><br></div><div><font face=3D"monospace, monospace"><br></font></div><d=
iv>If we assume that our constexpr tuple of indices is named "indices&=
quot;, then:</div><div><br></div><div><font face=3D"monospace, monospace">=
=C2=A0 =C2=A0 return forward_as_tuple(get<indices~>(tpl)...);</font><=
/div><div><br></div><div>would do the trick perfectly, I think. (I won'=
t bet money on it though. :))</div><div>(Thanks, Nicol, for that neat trick=
=E2=80=94 I wouldn't have thought of it myself!)</div><div><br></div><=
div>=E2=80=93Arthur</div></div>
<p></p>
-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
Visit this group at <a href=3D"https://groups.google.com/a/isocpp.org/group=
/std-proposals/">https://groups.google.com/a/isocpp.org/group/std-proposals=
/</a>.<br />
--047d7b33dc50e5fdce052bed5c06--
.
Author: Nicol Bolas <jmckesson@gmail.com>
Date: Tue, 16 Feb 2016 19:28:32 -0800 (PST)
Raw View
------=_Part_7760_750743506.1455679712664
Content-Type: multipart/alternative;
boundary="----=_Part_7761_1482735312.1455679712665"
------=_Part_7761_1482735312.1455679712665
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
On Tuesday, February 16, 2016 at 6:57:59 PM UTC-5, Louis Dionne wrote:
>
> On Tuesday, 16 February 2016 18:19:00 UTC-5, Nicol Bolas wrote:
>>
>> On Tuesday, February 16, 2016 at 3:21:29 PM UTC-5, Louis Dionne wrote:
>>>
>>> or you could also write
>>>
>>> hana::unpack(tpl, [](auto ...x) { return outer(inner(x)...); });
>>>
>>
>> Whenever your library equivalent to a 1-liner language feature includes=
=20
>> "introduce a Lambda", you have *lost* in terms of code=20
>> comprehensibility. On the other hand, it does fix (most) of the=20
>> functionality problems outlined above.
>>
>
> You're drawing an arbitrary line without any argument for this.
>
.... yes. Code quality is always arbitrary. Some people claim that this is a=
=20
good, easy-to-understand piece of code:
char * strcpy(char *strDest, const char *strSrc)
{
assert(strDest!=3DNULL && strSrc!=3DNULL);
char *temp =3D strDest;
while(*strDest++ =3D *strSrc++);
return temp;
}
Everyone has their own tastes. But... Concepts TS has 3 different and=20
increasingly brief syntaxes for declaring a constrained template for a=20
reason. In N3701, Stroustrup et. al. defended this by saying:
> Do not confuse the familiar with the simple. The proposed syntax is=20
readable and parsable. We considered =E2=80=9Clouder=E2=80=9D, more verbose=
notations, but=20
did not find them consistently better than what is described here.
Brevity has value.
Actually,
> I tend to prefer writing things more explicitly like above than using
> nested ... expansions when things get complex, for I think the different
> rules for ... expansion can be confusing.
>
Welcome to the point of the whole idea.
In this example, what we're trying to do is to call `inner` for each=20
element of the tuple, then pass the results as parameters to `outer`. To=20
you, this is something that "gets complex".
The purpose of the language feature is so that it *isn't complex* anymore.=
=20
By making it a language feature, we take something that was "complex" and=
=20
make it simple. That's the point.
Your library solution is much like `std::enable_if`. Yes, it gives you a=20
consistent tool for invoking SFINAE. But I *bet* you'd rather be using=20
Concepts.
`enable_if` makes SFINAE doable, but it requires that you express your=20
condition in an unnatural way. Concepts makes SFINAE *trivial*. Same here:=
=20
Hana makes tuple manipulation doable, but requires that you write your code=
=20
in unnatural ways.
The principle difference is that there's nothing `enable_if` can do that=20
concepts can't. Whereas there's a lot that Hana can do which tuple=20
expansion can't. But that alone doesn't mean that it isn't worth being a=20
language feature.
Lambdas were supposed to obsolete std::bind too. Yet there are still some=
=20
valid uses for it.
But here's the #1 reason why the library solution is the wrong solution:=20
>> you *wrote it wrong*. You forgot to `std::forward` your arguments. And=
=20
>> you forgot to use `decltype(auto)` for the return value. Both of which a=
re=20
>> needed to be exactly equivalent to the above code. Without the=20
>> `decltype(auto)`, if `outer` returned a reference of some kind, it could=
=20
>> provoke an unwanted copy.
>>
>> So it really needed to be:
>>
>> hana::unpack(tpl, [](auto ...x) -> decltype(auto) { return outer(inner(
>> std::forward<decltype(auto)>(x)...)); });
>>
>> I fail to see how this could be considered anywhere nearly as easy to=20
>> understand.
>>
>
> Fair enough. But if we're going to be pedantic, let's be pedantic for=20
> real. What you wanted
> to write is
> hana::unpack(tpl, [](auto&& ...x) -> decltype(auto) { return outer(inner(
> std::forward<decltype(x)>(x))...); });
>
> With this out of the way, I will argue that you actually don't need to=20
> write the above, except
> in rare cases where the tuple is potentially a rvalue. Instead, in most=
=20
> cases, you'd just
> have to write
>
> hana::unpack(tpl, [](auto& ...x) -> decltype(auto) { return outer(inner(x
> )...); });
>
> which is slightly less verbose.
>
My point was not just that it was verbose. My point is that it is both=20
verbose *and* easy to get wrong, which we both demonstrated (though at=20
least my error would have shown up in the compiler ;) ).
Basically, `unpack` is just `std::apply` but with the arguments reversed.
>>>
>>>
>>> > Show me the Hana code for this:
>>> >
>>> > auto x =3D inner([:]tpl) + ...;
>>> >
>>> > This simply calls a function on each element of the tuple and takes=
=20
>>> the sum
>>> > of the results. Again, it works like parameter packs, so it reuses=20
>>> existing
>>> > knowledge.
>>>
>>> You could write
>>>
>>> auto x =3D hana::fold_left(hana::transform(tpl, inner), std::plus<>=
{});
>>>
>>
>> And for people who natively read right to left, this would probably be=
=20
>> decent. But that's not how the rest of C++ works.
>>
>
> Wtf? How is this different from writing=20
>
> auto x =3D ranges::accumulate(ranges::transformed(...), std::plus<>{});
>
>
You will never catch me writing *that* either.
or equivalently
>>>
>>> auto x =3D hana::fold_left(tpl, [](auto a, auto b) {
>>> return a + inner(b);
>>> });
>>>
>>
>> Again you forgot to forward the arguments and return values properly. No=
t=20
>> to mention, you turn a simple one-liner into a multi-line statement.
>>
>
> Same argument as above. And the fact that I broke the statements into=20
> multiple
> lines to make it more readable is a feature. Honestly, I think this (and=
=20
> especially
> the transform/fold_left variant) is more readable than the variant with=
=20
> ... expansions.
> Of course, your version is more terse, but too terse is not good either.
>
It's not really that it's terse; that's not what attracts me to tuple=20
expansion. What matters most to me is that the code looks as much like=20
normal code ought to look.
This is also what repels me from your ranges example.
Most programmers know what `outer(inner(value))` does. They can understand=
=20
that by inspection, and its meaning is clear. Most programmers understand=
=20
what `inner(value) + inner(value2)` means.
Hana code is not obvious, not to someone who isn't familiar with template=
=20
metaprogramming and such techniques.
While an unsuspecting programmer may not understand exactly what the `...`=
=20
and `[:]` parts mean, they can still look at `outer(inner([:]value)...)`=20
and see that `inner` will be called, followed by `outer`. It carries the=20
same physical structure and code layout of the simple and obvious case. It=
=20
may be more complex under the hood, but the user is not exposed to it.
When looking at `hana::on(inner, outer)`, they have absolutely no idea what=
=20
that means. Not without looking up the docs. There is no intuitive grasp of=
=20
what's going on.
So the value is more than "just" terseness. The value is that the code's=20
structure remains intact. You're not exchanging a call to `+` with=20
`std::plus<>`. You're not altering the overall order and nature of the code=
..
Let's stop arguing over petty details. You want to hear it? Of course your=
=20
> solution
> is better for those use cases, because it was designed with those in mind=
!
> But it is also much more limited, and the point I'm trying to make is tha=
t=20
> from
> the point of view of a metaprogramming library writer, this proposal, in=
=20
> its
> current form, misses the goal just like fold expressions did.
>
And my overall point is that what you want was *never* the goal to begin=20
with. You are denigrating a proposal for not solving a problem that it was=
=20
never intended to solve. The problem it is solving is making tuples work=20
like parameter pack expansion, so as to be able to more effectively access=
=20
data out of tuples in useful ways.
Arbitrary tuple transformations was never the goal. That's a legitimate and=
=20
useful problem domain. But that's not what this is intended to handle. The=
=20
fact that this syntax can indeed handle some of that via clever usage of=20
the syntax is merely a fortunate coincidence.
C++11 already has a construct that is tuple-like in its nature: parameter=
=20
packs. We're just expanding it to work with actual tuples.
--=20
---=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-propos=
als/.
------=_Part_7761_1482735312.1455679712665
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">On Tuesday, February 16, 2016 at 6:57:59 PM UTC-5, Louis D=
ionne wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-lef=
t: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr">O=
n Tuesday, 16 February 2016 18:19:00 UTC-5, Nicol Bolas wrote:<blockquote =
class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1px #=
ccc solid;padding-left:1ex"><div dir=3D"ltr">On Tuesday, February 16, 2016 =
at 3:21:29 PM UTC-5, Louis Dionne wrote:<blockquote class=3D"gmail_quote" s=
tyle=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-left:=
1ex"><div></div></blockquote></div></blockquote></div></blockquote><blockqu=
ote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-left=
: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr"><div></div><blockquot=
e class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1px=
#ccc solid;padding-left:1ex"><div dir=3D"ltr"><blockquote class=3D"gmail_q=
uote" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;paddin=
g-left:1ex"><div dir=3D"ltr"><div>or you could also write</div><div><br></d=
iv><div>=C2=A0 =C2=A0 hana::unpack(tpl, [](auto ...x) { return outer(inner(=
x)...); });</div></div></blockquote><div><br>Whenever your library equivale=
nt to a 1-liner language feature includes "introduce a Lambda", y=
ou have <i>lost</i> in terms of code comprehensibility. On the other hand, =
it does fix (most) of the functionality problems outlined above.<br></div><=
/div></blockquote><div><br></div><div>You're drawing an arbitrary line =
without any argument for this.</div></div></blockquote><div><br>... yes. Co=
de quality is always arbitrary. Some people claim that this is a good, easy=
-to-understand piece of code:<br><br><div class=3D"prettyprint" style=3D"ba=
ckground-color: rgb(250, 250, 250); border-color: rgb(187, 187, 187); borde=
r-style: solid; border-width: 1px; word-wrap: break-word;"><code class=3D"p=
rettyprint"><div class=3D"subprettyprint"><span style=3D"color: #008;" clas=
s=3D"styled-by-prettify">char</span><span style=3D"color: #000;" class=3D"s=
tyled-by-prettify"> </span><span style=3D"color: #660;" class=3D"styled-by-=
prettify">*</span><span style=3D"color: #000;" class=3D"styled-by-prettify"=
> strcpy</span><span style=3D"color: #660;" class=3D"styled-by-prettify">(<=
/span><span style=3D"color: #008;" class=3D"styled-by-prettify">char</span>=
<span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span sty=
le=3D"color: #660;" class=3D"styled-by-prettify">*</span><span style=3D"col=
or: #000;" class=3D"styled-by-prettify">strDest</span><span style=3D"color:=
#660;" class=3D"styled-by-prettify">,</span><span style=3D"color: #000;" c=
lass=3D"styled-by-prettify"> </span><span style=3D"color: #008;" class=3D"s=
tyled-by-prettify">const</span><span style=3D"color: #000;" class=3D"styled=
-by-prettify"> </span><span style=3D"color: #008;" class=3D"styled-by-prett=
ify">char</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> =
</span><span style=3D"color: #660;" class=3D"styled-by-prettify">*</span><s=
pan style=3D"color: #000;" class=3D"styled-by-prettify">strSrc</span><span =
style=3D"color: #660;" class=3D"styled-by-prettify">)</span><span style=3D"=
color: #000;" class=3D"styled-by-prettify"><br></span><span style=3D"color:=
#660;" class=3D"styled-by-prettify">{</span><span style=3D"color: #000;" c=
lass=3D"styled-by-prettify"><br>=C2=A0 =C2=A0 </span><span style=3D"color: =
#008;" class=3D"styled-by-prettify">assert</span><span style=3D"color: #660=
;" class=3D"styled-by-prettify">(</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify">strDest</span><span style=3D"color: #660;" class=3D=
"styled-by-prettify">!=3D</span><span style=3D"color: #000;" class=3D"style=
d-by-prettify">NULL </span><span style=3D"color: #660;" class=3D"styled-by-=
prettify">&&</span><span style=3D"color: #000;" class=3D"styled-by-=
prettify"> strSrc</span><span style=3D"color: #660;" class=3D"styled-by-pre=
ttify">!=3D</span><span style=3D"color: #000;" class=3D"styled-by-prettify"=
>NULL</span><span style=3D"color: #660;" class=3D"styled-by-prettify">);</s=
pan><span style=3D"color: #000;" class=3D"styled-by-prettify"><br>=C2=A0 =
=C2=A0 </span><span style=3D"color: #008;" class=3D"styled-by-prettify">cha=
r</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><=
span style=3D"color: #660;" class=3D"styled-by-prettify">*</span><span styl=
e=3D"color: #000;" class=3D"styled-by-prettify">temp </span><span style=3D"=
color: #660;" class=3D"styled-by-prettify">=3D</span><span style=3D"color: =
#000;" class=3D"styled-by-prettify"> strDest</span><span style=3D"color: #6=
60;" class=3D"styled-by-prettify">;</span><span style=3D"color: #000;" clas=
s=3D"styled-by-prettify"><br>=C2=A0 =C2=A0 </span><span style=3D"color: #00=
8;" class=3D"styled-by-prettify">while</span><span style=3D"color: #660;" c=
lass=3D"styled-by-prettify">(*</span><span style=3D"color: #000;" class=3D"=
styled-by-prettify">strDest</span><span style=3D"color: #660;" class=3D"sty=
led-by-prettify">++</span><span style=3D"color: #000;" class=3D"styled-by-p=
rettify"> </span><span style=3D"color: #660;" class=3D"styled-by-prettify">=
=3D</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span=
><span style=3D"color: #660;" class=3D"styled-by-prettify">*</span><span st=
yle=3D"color: #000;" class=3D"styled-by-prettify">strSrc</span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">++);</span><span style=3D"co=
lor: #000;" class=3D"styled-by-prettify"><br>=C2=A0 =C2=A0 </span><span sty=
le=3D"color: #008;" class=3D"styled-by-prettify">return</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"> temp</span><span style=3D"c=
olor: #660;" class=3D"styled-by-prettify">;</span><span style=3D"color: #00=
0;" class=3D"styled-by-prettify"><br></span><span style=3D"color: #660;" cl=
ass=3D"styled-by-prettify">}</span><span style=3D"color: #000;" class=3D"st=
yled-by-prettify"><br></span></div></code></div><br>Everyone has their own =
tastes. But... Concepts TS has 3 different and increasingly brief syntaxes =
for declaring a constrained template for a reason. In N3701, Stroustrup et.=
al. defended this by saying:<br><br>> Do not confuse the familiar with =
the simple. The proposed syntax is readable and parsable. We considered =E2=
=80=9Clouder=E2=80=9D, more verbose notations, but did not find them consis=
tently better than what is described here.<br><br>Brevity has value.<br><br=
></div><blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.=
8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr"><div>A=
ctually,</div><div>I tend to prefer writing things more explicitly like abo=
ve than using</div><div>nested ... expansions when things get complex, for =
I think the different</div><div>rules for ... expansion can be confusing.</=
div></div></blockquote><div><br>Welcome to the point of the whole idea.<br>=
<br>In this example, what we're trying to do is to call `inner` for eac=
h element of the tuple, then pass the results as parameters to `outer`. To =
you, this is something that "gets complex".<br><br>The purpose of=
the language feature is so that it <i>isn't complex</i> anymore. By ma=
king it a language feature, we take something that was "complex" =
and make it simple. That's the point.<br><br>Your library solution is m=
uch like `std::enable_if`. Yes, it gives you a consistent tool for invoking=
SFINAE. But I <i>bet</i> you'd rather be using Concepts.<br><br>`enabl=
e_if` makes SFINAE doable, but it requires that you express your condition =
in an unnatural way. Concepts makes SFINAE <i>trivial</i>. Same here: Hana =
makes tuple manipulation doable, but requires that you write your code in u=
nnatural ways.<br><br>The principle difference is that there's nothing =
`enable_if` can do that concepts can't. Whereas there's a lot that =
Hana can do which tuple expansion can't. But that alone doesn't mea=
n that it isn't worth being a language feature.<br><br>Lambdas were sup=
posed to obsolete std::bind too. Yet there are still some valid uses for it=
..<br><br></div><blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-=
left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr=
"><blockquote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;bor=
der-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><div>But here=
9;s the #1 reason why the library solution is the wrong solution: you <i>wr=
ote it wrong</i>. You forgot to `std::forward` your arguments. And you forg=
ot to use `decltype(auto)` for the return value. Both of which are needed t=
o be exactly equivalent to the above code. Without the `decltype(auto)`, if=
`outer` returned a reference of some kind, it could provoke an unwanted co=
py.<br><br>So it really needed to be:<br><br><div style=3D"background-color=
:rgb(250,250,250);border-color:rgb(187,187,187);border-style:solid;border-w=
idth:1px;word-wrap:break-word"><code><div><span style=3D"color:#000">hana</=
span><span style=3D"color:#660">::</span><span style=3D"color:#000">unpack<=
/span><span style=3D"color:#660">(</span><span style=3D"color:#000">tpl</sp=
an><span style=3D"color:#660">,</span><span style=3D"color:#000"> </span><s=
pan style=3D"color:#660">[](</span><span style=3D"color:#008">auto</span><s=
pan style=3D"color:#000"> </span><span style=3D"color:#660">...</span><span=
style=3D"color:#000">x</span><span style=3D"color:#660">)</span><span styl=
e=3D"color:#000"> </span><span style=3D"color:#660">-></span><span style=
=3D"color:#000"> </span><span style=3D"color:#008">decltype</span><span sty=
le=3D"color:#660">(</span><span style=3D"color:#008">auto</span><span style=
=3D"color:#660">)</span><span style=3D"color:#000"> </span><span style=3D"c=
olor:#660">{</span><span style=3D"color:#000"> </span><span style=3D"color:=
#008">return</span><span style=3D"color:#000"> outer</span><span style=3D"c=
olor:#660">(</span><span style=3D"color:#000">inner</span><span style=3D"co=
lor:#660">(</span><span style=3D"color:#000">std</span><span style=3D"color=
:#660">::</span><span style=3D"color:#000">forward</span><span style=3D"col=
or:#660"><</span><span style=3D"color:#008">declt<wbr>ype</span><span st=
yle=3D"color:#660">(</span><span style=3D"color:#008">auto</span><span styl=
e=3D"color:#660">)>(</span><span style=3D"color:#000">x</span><span styl=
e=3D"color:#660">)...));</span><span style=3D"color:#000"> </span><span sty=
le=3D"color:#660">});</span></div></code></div><br>I fail to see how this c=
ould be considered anywhere nearly as easy to understand.<br></div></div></=
blockquote><div><br></div><div>Fair enough. But if we're going to be pe=
dantic, let's be pedantic for real. What you wanted</div><div>to write =
is</div><div><div style=3D"background-color:rgb(250,250,250);border:1px sol=
id rgb(187,187,187);word-wrap:break-word"><code><div><span style=3D"color:#=
000">hana</span><span style=3D"color:#660">::</span><span style=3D"color:#0=
00">unpack</span><span style=3D"color:#660">(</span><span style=3D"color:#0=
00">tpl</span><span style=3D"color:#660">,</span><span style=3D"color:#000"=
> </span><span style=3D"color:#660">[](</span><span style=3D"color:#008">au=
to</span><span style=3D"color:#660">&&</span><span style=3D"color:#=
000"> </span><span style=3D"color:#660">...</span><span style=3D"color:#000=
">x</span><span style=3D"color:#660">)</span><span style=3D"color:#000"> </=
span><font color=3D"#666600"><span style=3D"color:#660">-></span><span s=
tyle=3D"color:#000"> </span><span style=3D"color:#008">decltype</span><span=
style=3D"color:#660">(</span><span style=3D"color:#008">auto</span><span s=
tyle=3D"color:#660">)</span><span style=3D"color:#000"> </span><span style=
=3D"color:#660">{</span><span style=3D"color:#000"> </span><span style=3D"c=
olor:#008">return</span><span style=3D"color:#000"> outer</span><span style=
=3D"color:#660">(</span><span style=3D"color:#000">inner</span><span style=
=3D"color:#660">(</span><span style=3D"color:#000">std</span><span style=3D=
"color:#660">::</span><span style=3D"color:#000">forward</span><span style=
=3D"color:#660"><</span><span style=3D"color:#008">declt<wbr>ype</span><=
span style=3D"color:#660">(</span><span style=3D"color:#000">x</span><span =
style=3D"color:#660">)>(</span><span style=3D"color:#000">x</span><span =
style=3D"color:#660">))...);</span><span style=3D"color:#000"> </span><span=
style=3D"color:#660">});</span></font></div></code></div><div><br></div><d=
iv>With this out of the way, I will argue that you actually don't need =
to write the above, except</div><div>in rare cases where the tuple is poten=
tially a rvalue. Instead, in most cases, you'd just</div><div>have to w=
rite</div><div><br></div><div><div style=3D"background-color:rgb(250,250,25=
0);border:1px solid rgb(187,187,187);word-wrap:break-word"><code><div><font=
color=3D"#660066"><span style=3D"color:#000">hana</span><span style=3D"col=
or:#660">::</span><span style=3D"color:#000">unpack</span><span style=3D"co=
lor:#660">(</span><span style=3D"color:#000">tpl</span><span style=3D"color=
:#660">,</span><span style=3D"color:#000"> </span><span style=3D"color:#660=
">[](</span><span style=3D"color:#008">auto</span><span style=3D"color:#660=
">&</span><span style=3D"color:#000"> </span><span style=3D"color:#660"=
>...</span><span style=3D"color:#000">x</span><span style=3D"color:#660">)<=
/span><span style=3D"color:#000"> </span><span style=3D"color:#660">-></=
span><span style=3D"color:#000"> </span><span style=3D"color:#008">decltype=
</span><span style=3D"color:#660">(</span><span style=3D"color:#008">auto</=
span><span style=3D"color:#660">)</span><span style=3D"color:#000"> </span>=
<span style=3D"color:#660">{</span><span style=3D"color:#000"> </span><span=
style=3D"color:#008">return</span><span style=3D"color:#000"> outer</span>=
<span style=3D"color:#660">(</span><span style=3D"color:#000">inner</span><=
span style=3D"color:#660">(</span><span style=3D"color:#000">x</span><span =
style=3D"color:#660">)...);</span><span style=3D"color:#000"> </span><span =
style=3D"color:#660">});</span></font></div></code></div><div><br></div>whi=
ch is slightly less verbose.</div></div></div></blockquote><div><br>My poin=
t was not just that it was verbose. My point is that it is both verbose <i>=
and</i> easy to get wrong, which we both demonstrated (though at least my e=
rror would have shown up in the compiler ;) ).<br><br></div><blockquote cla=
ss=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #=
ccc solid;padding-left: 1ex;"><div dir=3D"ltr"><div><div></div></div><block=
quote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-left=
:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><div></div><blockquote c=
lass=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1px #c=
cc solid;padding-left:1ex"><div dir=3D"ltr"><div></div><div>Basically, `unp=
ack` is just `std::apply` but with the arguments reversed.</div><div><br></=
div><div><br></div><div>> Show me the Hana code for this:</div><div>>=
</div><div>> auto x =3D inner([:]tpl) + ...;</div><div>></div><div>&g=
t; This simply calls a function on each element of the tuple and takes the =
sum</div><div>> of the results. Again, it works like parameter packs, so=
it reuses existing</div><div>> knowledge.</div><div><br></div><div>You =
could write</div><div><br></div><div>=C2=A0 =C2=A0 auto x =3D hana::fold_le=
ft(hana::<wbr>transform(tpl, inner), std::plus<>{});</div></div></blo=
ckquote><div><br>And for people who natively read right to left, this would=
probably be decent. But that's not how the rest of C++ works.<br></div=
></div></blockquote><div><br></div><div>Wtf? How is this different from wri=
ting=C2=A0</div><div><br></div><div><div style=3D"background-color:rgb(250,=
250,250);border:1px solid rgb(187,187,187);word-wrap:break-word"><code><div=
><font color=3D"#000000"><span style=3D"color:#008">auto</span><span style=
=3D"color:#000"> x </span><span style=3D"color:#660">=3D</span><span style=
=3D"color:#000"> ranges</span><span style=3D"color:#660">::</span><span sty=
le=3D"color:#000">accumulate</span><span style=3D"color:#660">(</span></fon=
t><span style=3D"color:#000">ranges</span><span style=3D"color:#660">::</sp=
an><font color=3D"#000000"><span style=3D"color:#000">tra<wbr>nsformed</spa=
n><span style=3D"color:#660">(...)</span></font><font color=3D"#000000"><sp=
an style=3D"color:#660">,</span><span style=3D"color:#000"> std</span><span=
style=3D"color:#660">::</span><span style=3D"color:#000">plus</span><span =
style=3D"color:#660"><>{});</span></font></div></code></div><div><br>=
</div></div></div></blockquote><div><br>You will never catch me writing <i>=
that</i> either.<br><br></div><blockquote class=3D"gmail_quote" style=3D"ma=
rgin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">=
<div dir=3D"ltr"><div><div></div><div></div></div><blockquote class=3D"gmai=
l_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;pad=
ding-left:1ex"><div dir=3D"ltr"><div></div><blockquote class=3D"gmail_quote=
" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-le=
ft:1ex"><div dir=3D"ltr"><div></div><div>or equivalently</div><div><br></di=
v><div>=C2=A0 =C2=A0 auto x =3D hana::fold_left(tpl, [](auto a, auto b) {</=
div><div>=C2=A0 =C2=A0 =C2=A0 =C2=A0 return a + inner(b);</div><div>=C2=A0 =
=C2=A0 });</div></div></blockquote><div><br>Again you forgot to forward the=
arguments and return values properly. Not to mention, you turn a simple on=
e-liner into a multi-line statement.<br></div></div></blockquote><div><br><=
/div><div>Same argument as above. And the fact that I broke the statements =
into multiple</div><div>lines to make it more readable is a feature. Honest=
ly, I think this (and especially</div><div>the transform/fold_left variant)=
is more readable than the variant with ... expansions.</div><div>Of course=
, your version is more terse, but too terse is not good either.</div></div>=
</blockquote><div><br>It's not really that it's terse; that's n=
ot what attracts me to tuple expansion. What matters most to me is that the=
code looks as much like normal code ought to look.<br><br>This is also wha=
t repels me from your ranges example.<br><br>Most programmers know what `ou=
ter(inner(value))` does. They can understand that by inspection, and its me=
aning is clear. Most programmers understand what `inner(value) + inner(valu=
e2)` means.<br><br>Hana code is not obvious, not to someone who isn't f=
amiliar with template metaprogramming and such techniques.<br><br>While an =
unsuspecting programmer may not understand exactly what the `...` and `[:]`=
parts mean, they can still look at `outer(inner([:]value)...)` and see tha=
t `inner` will be called, followed by `outer`. It carries the same physical=
structure and code layout of the simple and obvious case. It may be more c=
omplex under the hood, but the user is not exposed to it.<br><br>When looki=
ng at `hana::on(inner, outer)`, they have absolutely no idea what that mean=
s. Not without looking up the docs. There is no intuitive grasp of what'=
;s going on.<br><br>So the value is more than "just" terseness. T=
he value is that the code's structure remains intact. You're not ex=
changing a call to `+` with `std::plus<>`. You're not altering th=
e overall order and nature of the code.<br><br></div><blockquote class=3D"g=
mail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc sol=
id;padding-left: 1ex;"><div dir=3D"ltr"><div></div><div>Let's stop argu=
ing over petty details. You want to hear it? Of course your solution</div><=
div>is better for those use cases, because it was designed with those in mi=
nd!</div><div>But it is also much more limited, and the point I'm tryin=
g to make is that from</div><div>the point of view of a metaprogramming lib=
rary writer, this proposal, in its</div><div>current form, misses the goal =
just like fold expressions did.</div></div></blockquote><div><br>And my ove=
rall point is that what you want was <i>never</i> the goal to begin with. Y=
ou are denigrating a proposal for not solving a problem that it was never i=
ntended to solve. The problem it is solving is making tuples work like para=
meter pack expansion, so as to be able to more effectively access data out =
of tuples in useful ways.<br><br>Arbitrary tuple transformations was never =
the goal. That's a legitimate and useful problem domain. But that's=
not what this is intended to handle. The fact that this syntax can indeed =
handle some of that via clever usage of the syntax is merely a fortunate co=
incidence.<br><br>C++11 already has a construct that is tuple-like in its n=
ature: parameter packs. We're just expanding it to work with actual tup=
les.<br></div></div>
<p></p>
-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
Visit this group at <a href=3D"https://groups.google.com/a/isocpp.org/group=
/std-proposals/">https://groups.google.com/a/isocpp.org/group/std-proposals=
/</a>.<br />
------=_Part_7761_1482735312.1455679712665--
------=_Part_7760_750743506.1455679712664--
.
Author: "Vicente J. Botet Escriba" <vicente.botet@wanadoo.fr>
Date: Wed, 17 Feb 2016 07:36:49 +0100
Raw View
This is a multi-part message in MIME format.
--------------070400040709060101000005
Content-Type: text/plain; charset=UTF-8; format=flowed
Content-Transfer-Encoding: quoted-printable
Le 17/02/2016 00:13, Louis Dionne a =C3=A9crit :
>
>
> On Tuesday, 16 February 2016 16:11:36 UTC-5, Matthew Woehlke wrote:
>
> (FYI, whatever you used to post your last message just butchered the
> quoting. And the line wrapping on your own text isn't much better.)
>
>
> I posted my reply from the Google Groups web page, and both the quoting
> and the line wrapping look fine there. I'm not sure what you're=20
> referring to.
>
>
> On 2016-02-16 15:21, Louis Dionne wrote:
> > On Monday, 15 February 2016 21:10:52 UTC-5, Nicol Bolas wrote:
> >> Oh, and show me the Hana code for this:
> >>
> >> struct Data
> >> {
> >> int i;
> >> float f;
> >> double d;
> >> };
> >>
> >> Data d =3D ...;
> >> outer(inner([:]d)...);
> >
> > Ah! That's a good one! Here's how you would write it:
> >
> > BOOST_HANA_DEFINE_STRUCT(Data,
>
> Oops. That right there is a no-go. Redefining the type is right
> out, as
> most likely the type is not something that can be directly
> controlled.
> (Even if it was, uglifying the API like this? No, thanks...)
>
>
> You don't need to redefine the type, since the above macro actually
> defines the type itself. If you don't have control over the type, you can
> also use BOOST_HANA_ADAPT_STRUCT to adapt an existing struct.
> But all of this is completely irrelevant, since I myself said that=20
> these macros
> were nothing but workarounds for the lack of proper introspection=20
> facilities,
> which need to be built into the language. This is obviously neither where
> we disagree nor the subject of this discussion.
>
>
Hi,
I agree here with Louis, this is orthogonal. There is a proposal for=20
defaulting tuple-like access [1] that should help here.
Vicente
[1]=20
https://github.com/viboes/std-make/blob/master/doc/proposal/reflection/P019=
7R0.md
--=20
---=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-propos=
als/.
--------------070400040709060101000005
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<html>
<head>
<meta content=3D"text/html; charset=3Dutf-8" http-equiv=3D"Content-Type=
">
</head>
<body bgcolor=3D"#FFFFFF" text=3D"#000000">
<div class=3D"moz-cite-prefix">Le 17/02/2016 00:13, Louis Dionne a
=C3=A9crit=C2=A0:<br>
</div>
<blockquote
cite=3D"mid:47d71f75-7fb7-4589-863c-f5329bc41952@isocpp.org"
type=3D"cite">
<div dir=3D"ltr"><br>
<br>
On Tuesday, 16 February 2016 16:11:36 UTC-5, Matthew Woehlke
wrote:
<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left:
0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">(FYI,
whatever you used to post your last message just butchered the
<br>
quoting. And the line wrapping on your own text isn't much
better.)
<br>
</blockquote>
<div><br>
</div>
<div>I posted my reply from the Google Groups web page, and both
the quoting</div>
<div>and the line wrapping look fine there. I'm not sure what
you're referring to.</div>
<div>=C2=A0</div>
<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left:
0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">
<br>
On 2016-02-16 15:21, Louis Dionne wrote:
<br>
> On Monday, 15 February 2016 21:10:52 UTC-5, Nicol Bolas
wrote:
<br>
>> Oh, and show me the Hana code for this:
<br>
>>
<br>
>> struct Data
<br>
>> {
<br>
>> =C2=A0 int i;
<br>
>> =C2=A0 float f;
<br>
>> =C2=A0 double d;
<br>
>> };
<br>
>>
<br>
>> Data d =3D ...;
<br>
>> outer(inner([:]d)...);
<br>
> <br>
> Ah! That's a good one! Here's how you would write it:
<br>
> <br>
> =C2=A0 =C2=A0 BOOST_HANA_DEFINE_STRUCT(Data,
<br>
<br>
Oops. That right there is a no-go. Redefining the type is
right out, as
<br>
most likely the type is not something that can be directly
controlled.
<br>
(Even if it was, uglifying the API like this? No, thanks...)
<br>
</blockquote>
<div><br>
</div>
<div>You don't need to redefine the type, since the above macro
actually</div>
<div>defines the type itself. If you don't have control over the
type, you can</div>
<div>also use BOOST_HANA_ADAPT_STRUCT to adapt an existing
struct.</div>
<div>But all of this is completely irrelevant, since I myself
said that these macros</div>
<div>were nothing but workarounds for the lack of proper
introspection facilities,</div>
<div>which need to be built into the language. This is obviously
neither where</div>
<div>we disagree nor the subject of this discussion.</div>
<div>=C2=A0</div>
<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left:
0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">
<br>
</blockquote>
</div>
</blockquote>
Hi, <br>
<br>
I agree here with Louis, this is orthogonal. There is a proposal for
defaulting tuple-like access [1] that should help here.<br>
<br>
Vicente<br>
<br>
<a class=3D"moz-txt-link-freetext"
href=3D"https://github.com/viboes/std-make/blob/master/doc/proposal/reflect=
ion/P0198R0.md">[1]
https://github.com/viboes/std-make/blob/master/doc/proposal/reflection/P019=
7R0.md</a><br>
<br>
</body>
</html>
<p></p>
-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
Visit this group at <a href=3D"https://groups.google.com/a/isocpp.org/group=
/std-proposals/">https://groups.google.com/a/isocpp.org/group/std-proposals=
/</a>.<br />
--------------070400040709060101000005--
.
Author: Sam Kellett <samkellett@gmail.com>
Date: Wed, 17 Feb 2016 09:40:24 +0000
Raw View
--001a114020d813f364052bf40a9b
Content-Type: text/plain; charset=UTF-8
On 17 February 2016 at 03:28, Nicol Bolas <jmckesson@gmail.com> wrote:
> [snip]
>
> It's not really that it's terse; that's not what attracts me to tuple
> expansion. What matters most to me is that the code looks as much like
> normal code ought to look.
>
> This is also what repels me from your ranges example.
>
> Most programmers know what `outer(inner(value))` does. They can understand
> that by inspection, and its meaning is clear. Most programmers understand
> what `inner(value) + inner(value2)` means.
>
> Hana code is not obvious, not to someone who isn't familiar with template
> metaprogramming and such techniques.
>
> While an unsuspecting programmer may not understand exactly what the `...`
> and `[:]` parts mean, they can still look at `outer(inner([:]value)...)`
> and see that `inner` will be called, followed by `outer`. It carries the
> same physical structure and code layout of the simple and obvious case. It
> may be more complex under the hood, but the user is not exposed to it.
>
with all due respect you seem to be taking your own opinion on this and
applying it to all. while that could be ok on it's own it's clashes with
the fact that you also take louis' opinion on this and applying it to just
him.
do you have a study / survey that confirms this? my personal opinion is
that hana's is much much much more obvious (the lambda version of the
example specifically), in no short reason because it's interface is based
on the existing standard library. why do we need two syntax's in one
language when we can do it all with one?
> When looking at `hana::on(inner, outer)`, they have absolutely no idea
> what that means. Not without looking up the docs. There is no intuitive
> grasp of what's going on.
>
again you kinda need proof that this isn't also true for your example. have
you shown it to people blind (without knowledge of the problem domain) and
have they been able to deduce what it means?
also yours appears to be inherently ungoogle-able. assuming i don't
understand either syntax, for louis' i type into google 'c++ hana::unpack',
what do i type to find the reference pages for yours?
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-proposals/.
--001a114020d813f364052bf40a9b
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><div class=3D"gmail_extra"><div class=3D"gmail_quote">On 1=
7 February 2016 at 03:28, Nicol Bolas <span dir=3D"ltr"><<a href=3D"mail=
to:jmckesson@gmail.com" target=3D"_blank">jmckesson@gmail.com</a>></span=
> wrote:<br><blockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0=
..8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">=C2=A0[snip]<=
br><div><div dir=3D"ltr"><span class=3D""></span><span class=3D""></span><s=
pan class=3D""></span> <br></div></div></blockquote><blockquote class=3D"gm=
ail_quote" style=3D"margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,=
204,204);padding-left:1ex"><div><div dir=3D"ltr"><div>It's not really t=
hat it's terse; that's not what attracts me to tuple expansion. Wha=
t matters most to me is that the code looks as much like normal code ought =
to look.<br><br>This is also what repels me from your ranges example.<br><b=
r>Most programmers know what `outer(inner(value))` does. They can understan=
d that by inspection, and its meaning is clear. Most programmers understand=
what `inner(value) + inner(value2)` means.<br><br>Hana code is not obvious=
, not to someone who isn't familiar with template metaprogramming and s=
uch techniques.<br><br>While an unsuspecting programmer may not understand =
exactly what the `...` and `[:]` parts mean, they can still look at `outer(=
inner([:]value)...)` and see that `inner` will be called, followed by `oute=
r`. It carries the same physical structure and code layout of the simple an=
d obvious case. It may be more complex under the hood, but the user is not =
exposed to it.<br></div></div></div></blockquote><div><br></div><div>with a=
ll due respect you seem to be taking your own opinion on this and applying =
it to all. while that could be ok on it's own it's clashes with the=
fact that you also take louis' opinion on this and applying it to just=
him.<br><br></div><div>do you have a study / survey that confirms this? my=
personal opinion is that hana's is much much much more obvious (the la=
mbda version of the example specifically), in no short reason because it=
9;s interface is based on the existing standard library. why do we need two=
syntax's in one language when we can do it all with one? <br>=C2=A0</d=
iv><blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left=
:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><div>When looking at `ha=
na::on(inner, outer)`, they have absolutely no idea what that means. Not wi=
thout looking up the docs. There is no intuitive grasp of what's going =
on.<br></div></div></blockquote><div><br></div><div>again you kinda need pr=
oof that this isn't also true for your example. have you shown it to pe=
ople blind (without knowledge of the problem domain) and have they been abl=
e to deduce what it means?<br><br></div><div>also yours appears to be inher=
ently ungoogle-able. assuming i don't understand either syntax, for lou=
is' i type into google 'c++ hana::unpack', what do i type to fi=
nd the reference pages for yours?<br></div></div></div></div>
<p></p>
-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
Visit this group at <a href=3D"https://groups.google.com/a/isocpp.org/group=
/std-proposals/">https://groups.google.com/a/isocpp.org/group/std-proposals=
/</a>.<br />
--001a114020d813f364052bf40a9b--
.
Author: Louis Dionne <ldionne.2@gmail.com>
Date: Wed, 17 Feb 2016 08:16:15 -0800 (PST)
Raw View
------=_Part_274_527237065.1455725775759
Content-Type: multipart/alternative;
boundary="----=_Part_275_487542790.1455725775761"
------=_Part_275_487542790.1455725775761
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
On Tuesday, 16 February 2016 22:28:33 UTC-5, Nicol Bolas wrote:
>
> On Tuesday, February 16, 2016 at 6:57:59 PM UTC-5, Louis Dionne wrote:
>>
>> On Tuesday, 16 February 2016 18:19:00 UTC-5, Nicol Bolas wrote:
>>>
>>> On Tuesday, February 16, 2016 at 3:21:29 PM UTC-5, Louis Dionne wrote:
>>>>
>>>> or you could also write
>>>>
>>>> hana::unpack(tpl, [](auto ...x) { return outer(inner(x)...); });
>>>>
>>>
>>> Whenever your library equivalent to a 1-liner language feature includes=
=20
>>> "introduce a Lambda", you have *lost* in terms of code=20
>>> comprehensibility. On the other hand, it does fix (most) of the=20
>>> functionality problems outlined above.
>>>
>>
>> You're drawing an arbitrary line without any argument for this.
>>
>
> ... yes. Code quality is always arbitrary. Some people claim that this is=
=20
> a good, easy-to-understand piece of code:
>
> char * strcpy(char *strDest, const char *strSrc)
> {
> assert(strDest!=3DNULL && strSrc!=3DNULL);
> char *temp =3D strDest;
> while(*strDest++ =3D *strSrc++);
> return temp;
> }
>
> Everyone has their own tastes. But... Concepts TS has 3 different and=20
> increasingly brief syntaxes for declaring a constrained template for a=20
> reason. In N3701, Stroustrup et. al. defended this by saying:
>
> > Do not confuse the familiar with the simple. The proposed syntax is=20
> readable and parsable. We considered =E2=80=9Clouder=E2=80=9D, more verbo=
se notations, but=20
> did not find them consistently better than what is described here.
>
> Brevity has value.
>
> Actually,
>> I tend to prefer writing things more explicitly like above than using
>> nested ... expansions when things get complex, for I think the different
>> rules for ... expansion can be confusing.
>>
>
> Welcome to the point of the whole idea.
>
> In this example, what we're trying to do is to call `inner` for each=20
> element of the tuple, then pass the results as parameters to `outer`. To=
=20
> you, this is something that "gets complex".
>
> The purpose of the language feature is so that it *isn't complex*=20
> anymore. By making it a language feature, we take something that was=20
> "complex" and make it simple. That's the point.
>
> Your library solution is much like `std::enable_if`. Yes, it gives you a=
=20
> consistent tool for invoking SFINAE. But I *bet* you'd rather be using=20
> Concepts.
>
> `enable_if` makes SFINAE doable, but it requires that you express your=20
> condition in an unnatural way. Concepts makes SFINAE *trivial*. Same=20
> here: Hana makes tuple manipulation doable, but requires that you write=
=20
> your code in unnatural ways.
>
> The principle difference is that there's nothing `enable_if` can do that=
=20
> concepts can't. Whereas there's a lot that Hana can do which tuple=20
> expansion can't. But that alone doesn't mean that it isn't worth being a=
=20
> language feature.
>
> Lambdas were supposed to obsolete std::bind too. Yet there are still some=
=20
> valid uses for it.
>
> But here's the #1 reason why the library solution is the wrong solution:=
=20
>>> you *wrote it wrong*. You forgot to `std::forward` your arguments. And=
=20
>>> you forgot to use `decltype(auto)` for the return value. Both of which =
are=20
>>> needed to be exactly equivalent to the above code. Without the=20
>>> `decltype(auto)`, if `outer` returned a reference of some kind, it coul=
d=20
>>> provoke an unwanted copy.
>>>
>>> So it really needed to be:
>>>
>>> hana::unpack(tpl, [](auto ...x) -> decltype(auto) { return outer(inner(
>>> std::forward<decltype(auto)>(x)...)); });
>>>
>>> I fail to see how this could be considered anywhere nearly as easy to=
=20
>>> understand.
>>>
>>
>> Fair enough. But if we're going to be pedantic, let's be pedantic for=20
>> real. What you wanted
>> to write is
>> hana::unpack(tpl, [](auto&& ...x) -> decltype(auto) { return outer(inner=
(
>> std::forward<decltype(x)>(x))...); });
>>
>> With this out of the way, I will argue that you actually don't need to=
=20
>> write the above, except
>> in rare cases where the tuple is potentially a rvalue. Instead, in most=
=20
>> cases, you'd just
>> have to write
>>
>> hana::unpack(tpl, [](auto& ...x) -> decltype(auto) { return outer(inner(=
x
>> )...); });
>>
>> which is slightly less verbose.
>>
>
> My point was not just that it was verbose. My point is that it is both=20
> verbose *and* easy to get wrong, which we both demonstrated (though at=20
> least my error would have shown up in the compiler ;) ).
>
> Basically, `unpack` is just `std::apply` but with the arguments reversed.
>>>>
>>>>
>>>> > Show me the Hana code for this:
>>>> >
>>>> > auto x =3D inner([:]tpl) + ...;
>>>> >
>>>> > This simply calls a function on each element of the tuple and takes=
=20
>>>> the sum
>>>> > of the results. Again, it works like parameter packs, so it reuses=
=20
>>>> existing
>>>> > knowledge.
>>>>
>>>> You could write
>>>>
>>>> auto x =3D hana::fold_left(hana::transform(tpl, inner),=20
>>>> std::plus<>{});
>>>>
>>>
>>> And for people who natively read right to left, this would probably be=
=20
>>> decent. But that's not how the rest of C++ works.
>>>
>>
>> Wtf? How is this different from writing=20
>>
>> auto x =3D ranges::accumulate(ranges::transformed(...), std::plus<>{});
>>
>>
> You will never catch me writing *that* either.
>
> or equivalently
>>>>
>>>> auto x =3D hana::fold_left(tpl, [](auto a, auto b) {
>>>> return a + inner(b);
>>>> });
>>>>
>>>
>>> Again you forgot to forward the arguments and return values properly.=
=20
>>> Not to mention, you turn a simple one-liner into a multi-line statement=
..
>>>
>>
>> Same argument as above. And the fact that I broke the statements into=20
>> multiple
>> lines to make it more readable is a feature. Honestly, I think this (and=
=20
>> especially
>> the transform/fold_left variant) is more readable than the variant with=
=20
>> ... expansions.
>> Of course, your version is more terse, but too terse is not good either.
>>
>
> It's not really that it's terse; that's not what attracts me to tuple=20
> expansion. What matters most to me is that the code looks as much like=20
> normal code ought to look.
>
> This is also what repels me from your ranges example.
>
> Most programmers know what `outer(inner(value))` does. They can understan=
d=20
> that by inspection, and its meaning is clear. Most programmers understand=
=20
> what `inner(value) + inner(value2)` means.
>
> Hana code is not obvious, not to someone who isn't familiar with template=
=20
> metaprogramming and such techniques.
>
> While an unsuspecting programmer may not understand exactly what the `...=
`=20
> and `[:]` parts mean, they can still look at `outer(inner([:]value)...)`=
=20
> and see that `inner` will be called, followed by `outer`. It carries the=
=20
> same physical structure and code layout of the simple and obvious case. I=
t=20
> may be more complex under the hood, but the user is not exposed to it.
>
> When looking at `hana::on(inner, outer)`, they have absolutely no idea=20
> what that means. Not without looking up the docs. There is no intuitive=
=20
> grasp of what's going on.
>
> So the value is more than "just" terseness. The value is that the code's=
=20
> structure remains intact. You're not exchanging a call to `+` with=20
> `std::plus<>`. You're not altering the overall order and nature of the=20
> code.=20
>
> Let's stop arguing over petty details. You want to hear it? Of course you=
r=20
>> solution
>> is better for those use cases, because it was designed with those in min=
d!
>> But it is also much more limited, and the point I'm trying to make is=20
>> that from
>> the point of view of a metaprogramming library writer, this proposal, in=
=20
>> its
>> current form, misses the goal just like fold expressions did.
>>
>
> And my overall point is that what you want was *never* the goal to begin=
=20
> with. You are denigrating a proposal for not solving a problem that it wa=
s=20
> never intended to solve.=20
>
I'm sorry if you perceived my comments as denigration, for that was never=
=20
my goal. I know the power
of getting a different perspective, especially one that has been thought=20
out, and that is what I wanted
to share with you. We're all trying to achieve the same thing here; a=20
language that allows us to express
ourselves more easily. We're disagreeing on the way to get there, and you=
=20
seem to be impermeable to
my ideas. It's fine, but my work here is done for I don't feel like=20
something good can come out of more
discussion like what we've been having.
The problem it is solving is making tuples work like parameter pack=20
> expansion, so as to be able to more effectively access data out of tuples=
=20
> in useful ways.
>
When you say "useful ways", I gather that you're saying "ways that are=20
useful for myself". Indeed, I'm
precisely saying that accessing tuples in the way you propose isn't useful=
=20
to me, but you say that this
isn't the goal. I hope you hit the needs of the standard committee members=
=20
right on the spot, otherwise
they might find it difficult to modify _the freaking language_ for your use=
=20
case.
Regards,
Louis Dionne
Arbitrary tuple transformations was never the goal. That's a legitimate and=
=20
> useful problem domain. But that's not what this is intended to handle. Th=
e=20
> fact that this syntax can indeed handle some of that via clever usage of=
=20
> the syntax is merely a fortunate coincidence.
>
> C++11 already has a construct that is tuple-like in its nature: parameter=
=20
> packs. We're just expanding it to work with actual tuples.
>
--=20
---=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-propos=
als/.
------=_Part_275_487542790.1455725775761
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><br><br>On Tuesday, 16 February 2016 22:28:33 UTC-5, Nicol=
Bolas wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-l=
eft: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr"=
>On Tuesday, February 16, 2016 at 6:57:59 PM UTC-5, Louis Dionne wrote:<blo=
ckquote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-le=
ft:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr">On Tuesday, 16 Februar=
y 2016 18:19:00 UTC-5, Nicol Bolas wrote:<blockquote class=3D"gmail_quote"=
style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-lef=
t:1ex"><div dir=3D"ltr">On Tuesday, February 16, 2016 at 3:21:29 PM UTC-5, =
Louis Dionne wrote:<blockquote class=3D"gmail_quote" style=3D"margin:0;marg=
in-left:0.8ex;border-left:1px #ccc solid;padding-left:1ex"><div></div></blo=
ckquote></div></blockquote></div></blockquote><blockquote class=3D"gmail_qu=
ote" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;padding=
-left:1ex"><div dir=3D"ltr"><div></div><blockquote class=3D"gmail_quote" st=
yle=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-left:1=
ex"><div dir=3D"ltr"><blockquote class=3D"gmail_quote" style=3D"margin:0;ma=
rgin-left:0.8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir=3D"lt=
r"><div>or you could also write</div><div><br></div><div>=C2=A0 =C2=A0 hana=
::unpack(tpl, [](auto ...x) { return outer(inner(x)...); });</div></div></b=
lockquote><div><br>Whenever your library equivalent to a 1-liner language f=
eature includes "introduce a Lambda", you have <i>lost</i> in ter=
ms of code comprehensibility. On the other hand, it does fix (most) of the =
functionality problems outlined above.<br></div></div></blockquote><div><br=
></div><div>You're drawing an arbitrary line without any argument for t=
his.</div></div></blockquote><div><br>... yes. Code quality is always arbit=
rary. Some people claim that this is a good, easy-to-understand piece of co=
de:<br><br><div style=3D"background-color:rgb(250,250,250);border-color:rgb=
(187,187,187);border-style:solid;border-width:1px;word-wrap:break-word"><co=
de><div><span style=3D"color:#008">char</span><span style=3D"color:#000"> <=
/span><span style=3D"color:#660">*</span><span style=3D"color:#000"> strcpy=
</span><span style=3D"color:#660">(</span><span style=3D"color:#008">char</=
span><span style=3D"color:#000"> </span><span style=3D"color:#660">*</span>=
<span style=3D"color:#000">strDest</span><span style=3D"color:#660">,</span=
><span style=3D"color:#000"> </span><span style=3D"color:#008">const</span>=
<span style=3D"color:#000"> </span><span style=3D"color:#008">char</span><s=
pan style=3D"color:#000"> </span><span style=3D"color:#660">*</span><span s=
tyle=3D"color:#000">strSrc</span><span style=3D"color:#660">)</span><span s=
tyle=3D"color:#000"><br></span><span style=3D"color:#660">{</span><span sty=
le=3D"color:#000"><br>=C2=A0 =C2=A0 </span><span style=3D"color:#008">asser=
t</span><span style=3D"color:#660">(</span><span style=3D"color:#000">strDe=
st</span><span style=3D"color:#660">!=3D</span><span style=3D"color:#000">N=
ULL </span><span style=3D"color:#660">&&</span><span style=3D"color=
:#000"> strSrc</span><span style=3D"color:#660">!=3D</span><span style=3D"c=
olor:#000">NULL</span><span style=3D"color:#660">);</span><span style=3D"co=
lor:#000"><br>=C2=A0 =C2=A0 </span><span style=3D"color:#008">char</span><s=
pan style=3D"color:#000"> </span><span style=3D"color:#660">*</span><span s=
tyle=3D"color:#000">temp </span><span style=3D"color:#660">=3D</span><span =
style=3D"color:#000"> strDest</span><span style=3D"color:#660">;</span><spa=
n style=3D"color:#000"><br>=C2=A0 =C2=A0 </span><span style=3D"color:#008">=
while</span><span style=3D"color:#660">(*</span><span style=3D"color:#000">=
strDest</span><span style=3D"color:#660">++</span><span style=3D"color:#000=
"> </span><span style=3D"color:#660">=3D</span><span style=3D"color:#000"> =
</span><span style=3D"color:#660">*</span><span style=3D"color:#000">strSrc=
</span><span style=3D"color:#660">++);</span><span style=3D"color:#000"><br=
>=C2=A0 =C2=A0 </span><span style=3D"color:#008">return</span><span style=
=3D"color:#000"> temp</span><span style=3D"color:#660">;</span><span style=
=3D"color:#000"><br></span><span style=3D"color:#660">}</span><span style=
=3D"color:#000"><br></span></div></code></div><br>Everyone has their own ta=
stes. But... Concepts TS has 3 different and increasingly brief syntaxes fo=
r declaring a constrained template for a reason. In N3701, Stroustrup et. a=
l. defended this by saying:<br><br>> Do not confuse the familiar with th=
e simple. The proposed syntax is readable and parsable. We considered =E2=
=80=9Clouder=E2=80=9D, more verbose notations, but did not find them consis=
tently better than what is described here.<br><br>Brevity has value.<br><br=
></div><blockquote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8e=
x;border-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><div>Actual=
ly,</div><div>I tend to prefer writing things more explicitly like above th=
an using</div><div>nested ... expansions when things get complex, for I thi=
nk the different</div><div>rules for ... expansion can be confusing.</div><=
/div></blockquote><div><br>Welcome to the point of the whole idea.<br><br>I=
n this example, what we're trying to do is to call `inner` for each ele=
ment of the tuple, then pass the results as parameters to `outer`. To you, =
this is something that "gets complex".<br><br>The purpose of the =
language feature is so that it <i>isn't complex</i> anymore. By making =
it a language feature, we take something that was "complex" and m=
ake it simple. That's the point.<br><br>Your library solution is much l=
ike `std::enable_if`. Yes, it gives you a consistent tool for invoking SFIN=
AE. But I <i>bet</i> you'd rather be using Concepts.<br><br>`enable_if`=
makes SFINAE doable, but it requires that you express your condition in an=
unnatural way. Concepts makes SFINAE <i>trivial</i>. Same here: Hana makes=
tuple manipulation doable, but requires that you write your code in unnatu=
ral ways.<br><br>The principle difference is that there's nothing `enab=
le_if` can do that concepts can't. Whereas there's a lot that Hana =
can do which tuple expansion can't. But that alone doesn't mean tha=
t it isn't worth being a language feature.<br><br>Lambdas were supposed=
to obsolete std::bind too. Yet there are still some valid uses for it.<br>=
<br></div><blockquote class=3D"gmail_quote" style=3D"margin:0;margin-left:0=
..8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><blockqu=
ote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1=
px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><div>But here's the #1=
reason why the library solution is the wrong solution: you <i>wrote it wro=
ng</i>. You forgot to `std::forward` your arguments. And you forgot to use =
`decltype(auto)` for the return value. Both of which are needed to be exact=
ly equivalent to the above code. Without the `decltype(auto)`, if `outer` r=
eturned a reference of some kind, it could provoke an unwanted copy.<br><br=
>So it really needed to be:<br><br><div style=3D"background-color:rgb(250,2=
50,250);border-color:rgb(187,187,187);border-style:solid;border-width:1px;w=
ord-wrap:break-word"><code><div><span style=3D"color:#000">hana</span><span=
style=3D"color:#660">::</span><span style=3D"color:#000">unpack</span><spa=
n style=3D"color:#660">(</span><span style=3D"color:#000">tpl</span><span s=
tyle=3D"color:#660">,</span><span style=3D"color:#000"> </span><span style=
=3D"color:#660">[](</span><span style=3D"color:#008">auto</span><span style=
=3D"color:#000"> </span><span style=3D"color:#660">...</span><span style=3D=
"color:#000">x</span><span style=3D"color:#660">)</span><span style=3D"colo=
r:#000"> </span><span style=3D"color:#660">-></span><span style=3D"color=
:#000"> </span><span style=3D"color:#008">decltype</span><span style=3D"col=
or:#660">(</span><span style=3D"color:#008">auto</span><span style=3D"color=
:#660">)</span><span style=3D"color:#000"> </span><span style=3D"color:#660=
">{</span><span style=3D"color:#000"> </span><span style=3D"color:#008">ret=
urn</span><span style=3D"color:#000"> outer</span><span style=3D"color:#660=
">(</span><span style=3D"color:#000">inner</span><span style=3D"color:#660"=
>(</span><span style=3D"color:#000">std</span><span style=3D"color:#660">::=
</span><span style=3D"color:#000">forward</span><span style=3D"color:#660">=
<</span><span style=3D"color:#008">declt<wbr>ype</span><span style=3D"co=
lor:#660">(</span><span style=3D"color:#008">auto</span><span style=3D"colo=
r:#660">)>(</span><span style=3D"color:#000">x</span><span style=3D"colo=
r:#660">)...));</span><span style=3D"color:#000"> </span><span style=3D"col=
or:#660">});</span></div></code></div><br>I fail to see how this could be c=
onsidered anywhere nearly as easy to understand.<br></div></div></blockquot=
e><div><br></div><div>Fair enough. But if we're going to be pedantic, l=
et's be pedantic for real. What you wanted</div><div>to write is</div><=
div><div style=3D"background-color:rgb(250,250,250);border:1px solid rgb(18=
7,187,187);word-wrap:break-word"><code><div><span style=3D"color:#000">hana=
</span><span style=3D"color:#660">::</span><span style=3D"color:#000">unpac=
k</span><span style=3D"color:#660">(</span><span style=3D"color:#000">tpl</=
span><span style=3D"color:#660">,</span><span style=3D"color:#000"> </span>=
<span style=3D"color:#660">[](</span><span style=3D"color:#008">auto</span>=
<span style=3D"color:#660">&&</span><span style=3D"color:#000"> </s=
pan><span style=3D"color:#660">...</span><span style=3D"color:#000">x</span=
><span style=3D"color:#660">)</span><span style=3D"color:#000"> </span><fon=
t color=3D"#666600"><span style=3D"color:#660">-></span><span style=3D"c=
olor:#000"> </span><span style=3D"color:#008">decltype</span><span style=3D=
"color:#660">(</span><span style=3D"color:#008">auto</span><span style=3D"c=
olor:#660">)</span><span style=3D"color:#000"> </span><span style=3D"color:=
#660">{</span><span style=3D"color:#000"> </span><span style=3D"color:#008"=
>return</span><span style=3D"color:#000"> outer</span><span style=3D"color:=
#660">(</span><span style=3D"color:#000">inner</span><span style=3D"color:#=
660">(</span><span style=3D"color:#000">std</span><span style=3D"color:#660=
">::</span><span style=3D"color:#000">forward</span><span style=3D"color:#6=
60"><</span><span style=3D"color:#008">declt<wbr>ype</span><span style=
=3D"color:#660">(</span><span style=3D"color:#000">x</span><span style=3D"c=
olor:#660">)>(</span><span style=3D"color:#000">x</span><span style=3D"c=
olor:#660">))...);</span><span style=3D"color:#000"> </span><span style=3D"=
color:#660">});</span></font></div></code></div><div><br></div><div>With th=
is out of the way, I will argue that you actually don't need to write t=
he above, except</div><div>in rare cases where the tuple is potentially a r=
value. Instead, in most cases, you'd just</div><div>have to write</div>=
<div><br></div><div><div style=3D"background-color:rgb(250,250,250);border:=
1px solid rgb(187,187,187);word-wrap:break-word"><code><div><font color=3D"=
#660066"><span style=3D"color:#000">hana</span><span style=3D"color:#660">:=
:</span><span style=3D"color:#000">unpack</span><span style=3D"color:#660">=
(</span><span style=3D"color:#000">tpl</span><span style=3D"color:#660">,</=
span><span style=3D"color:#000"> </span><span style=3D"color:#660">[](</spa=
n><span style=3D"color:#008">auto</span><span style=3D"color:#660">&</s=
pan><span style=3D"color:#000"> </span><span style=3D"color:#660">...</span=
><span style=3D"color:#000">x</span><span style=3D"color:#660">)</span><spa=
n style=3D"color:#000"> </span><span style=3D"color:#660">-></span><span=
style=3D"color:#000"> </span><span style=3D"color:#008">decltype</span><sp=
an style=3D"color:#660">(</span><span style=3D"color:#008">auto</span><span=
style=3D"color:#660">)</span><span style=3D"color:#000"> </span><span styl=
e=3D"color:#660">{</span><span style=3D"color:#000"> </span><span style=3D"=
color:#008">return</span><span style=3D"color:#000"> outer</span><span styl=
e=3D"color:#660">(</span><span style=3D"color:#000">inner</span><span style=
=3D"color:#660">(</span><span style=3D"color:#000">x</span><span style=3D"c=
olor:#660">)...);</span><span style=3D"color:#000"> </span><span style=3D"c=
olor:#660">});</span></font></div></code></div><div><br></div>which is slig=
htly less verbose.</div></div></div></blockquote><div><br>My point was not =
just that it was verbose. My point is that it is both verbose <i>and</i> ea=
sy to get wrong, which we both demonstrated (though at least my error would=
have shown up in the compiler ;) ).<br><br></div><blockquote class=3D"gmai=
l_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;pad=
ding-left:1ex"><div dir=3D"ltr"><div><div></div></div><blockquote class=3D"=
gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid=
;padding-left:1ex"><div dir=3D"ltr"><div></div><blockquote class=3D"gmail_q=
uote" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;paddin=
g-left:1ex"><div dir=3D"ltr"><div></div><div>Basically, `unpack` is just `s=
td::apply` but with the arguments reversed.</div><div><br></div><div><br></=
div><div>> Show me the Hana code for this:</div><div>></div><div>>=
auto x =3D inner([:]tpl) + ...;</div><div>></div><div>> This simply =
calls a function on each element of the tuple and takes the sum</div><div>&=
gt; of the results. Again, it works like parameter packs, so it reuses exis=
ting</div><div>> knowledge.</div><div><br></div><div>You could write</di=
v><div><br></div><div>=C2=A0 =C2=A0 auto x =3D hana::fold_left(hana::<wbr>t=
ransform(tpl, inner), std::plus<>{});</div></div></blockquote><div><b=
r>And for people who natively read right to left, this would probably be de=
cent. But that's not how the rest of C++ works.<br></div></div></blockq=
uote><div><br></div><div>Wtf? How is this different from writing=C2=A0</div=
><div><br></div><div><div style=3D"background-color:rgb(250,250,250);border=
:1px solid rgb(187,187,187);word-wrap:break-word"><code><div><font color=3D=
"#000000"><span style=3D"color:#008">auto</span><span style=3D"color:#000">=
x </span><span style=3D"color:#660">=3D</span><span style=3D"color:#000"> =
ranges</span><span style=3D"color:#660">::</span><span style=3D"color:#000"=
>accumulate</span><span style=3D"color:#660">(</span></font><span style=3D"=
color:#000">ranges</span><span style=3D"color:#660">::</span><font color=3D=
"#000000"><span style=3D"color:#000">tra<wbr>nsformed</span><span style=3D"=
color:#660">(...)</span></font><font color=3D"#000000"><span style=3D"color=
:#660">,</span><span style=3D"color:#000"> std</span><span style=3D"color:#=
660">::</span><span style=3D"color:#000">plus</span><span style=3D"color:#6=
60"><>{});</span></font></div></code></div><div><br></div></div></div=
></blockquote><div><br>You will never catch me writing <i>that</i> either.<=
br><br></div><blockquote class=3D"gmail_quote" style=3D"margin:0;margin-lef=
t:0.8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><div>=
<div></div><div></div></div><blockquote class=3D"gmail_quote" style=3D"marg=
in:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-left:1ex"><div di=
r=3D"ltr"><div></div><blockquote class=3D"gmail_quote" style=3D"margin:0;ma=
rgin-left:0.8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir=3D"lt=
r"><div></div><div>or equivalently</div><div><br></div><div>=C2=A0 =C2=A0 a=
uto x =3D hana::fold_left(tpl, [](auto a, auto b) {</div><div>=C2=A0 =C2=A0=
=C2=A0 =C2=A0 return a + inner(b);</div><div>=C2=A0 =C2=A0 });</div></div>=
</blockquote><div><br>Again you forgot to forward the arguments and return =
values properly. Not to mention, you turn a simple one-liner into a multi-l=
ine statement.<br></div></div></blockquote><div><br></div><div>Same argumen=
t as above. And the fact that I broke the statements into multiple</div><di=
v>lines to make it more readable is a feature. Honestly, I think this (and =
especially</div><div>the transform/fold_left variant) is more readable than=
the variant with ... expansions.</div><div>Of course, your version is more=
terse, but too terse is not good either.</div></div></blockquote><div><br>=
It's not really that it's terse; that's not what attracts me to=
tuple expansion. What matters most to me is that the code looks as much li=
ke normal code ought to look.<br><br>This is also what repels me from your =
ranges example.<br><br>Most programmers know what `outer(inner(value))` doe=
s. They can understand that by inspection, and its meaning is clear. Most p=
rogrammers understand what `inner(value) + inner(value2)` means.<br><br>Han=
a code is not obvious, not to someone who isn't familiar with template =
metaprogramming and such techniques.<br><br>While an unsuspecting programme=
r may not understand exactly what the `...` and `[:]` parts mean, they can =
still look at `outer(inner([:]value)...)` and see that `inner` will be call=
ed, followed by `outer`. It carries the same physical structure and code la=
yout of the simple and obvious case. It may be more complex under the hood,=
but the user is not exposed to it.<br><br>When looking at `hana::on(inner,=
outer)`, they have absolutely no idea what that means. Not without looking=
up the docs. There is no intuitive grasp of what's going on.<br><br>So=
the value is more than "just" terseness. The value is that the c=
ode's structure remains intact. You're not exchanging a call to `+`=
with `std::plus<>`. You're not altering the overall order and na=
ture of the code.=C2=A0</div></div></blockquote><blockquote class=3D"gmail_=
quote" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;pa=
dding-left: 1ex;"><div dir=3D"ltr"><div><br></div><blockquote class=3D"gmai=
l_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;pad=
ding-left:1ex"><div dir=3D"ltr"><div></div><div>Let's stop arguing over=
petty details. You want to hear it? Of course your solution</div><div>is b=
etter for those use cases, because it was designed with those in mind!</div=
><div>But it is also much more limited, and the point I'm trying to mak=
e is that from</div><div>the point of view of a metaprogramming library wri=
ter, this proposal, in its</div><div>current form, misses the goal just lik=
e fold expressions did.</div></div></blockquote><div><br>And my overall poi=
nt is that what you want was <i>never</i> the goal to begin with. You are d=
enigrating a proposal for not solving a problem that it was never intended =
to solve. </div></div></blockquote><div><br></div><div><div>I'm sorry i=
f you perceived my comments as denigration, for that was never my goal. I k=
now the power</div><div>of getting a different perspective, especially one =
that has been thought out, and that is what I wanted</div><div>to share wit=
h you. We're all trying to achieve the same thing here; a language that=
allows us to express</div><div>ourselves more easily. We're disagreein=
g on the way to get there, and you seem to be impermeable to</div><div>my i=
deas. It's fine, but my work here is done for I don't feel like som=
ething good can come out of more</div></div><div>discussion like what we=
9;ve been having.</div><div><br></div><div><br></div><blockquote class=3D"g=
mail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc sol=
id;padding-left: 1ex;"><div dir=3D"ltr"><div>The problem it is solving is m=
aking tuples work like parameter pack expansion, so as to be able to more e=
ffectively access data out of tuples in useful ways.<br></div></div></block=
quote><div><br></div><div>When you say "useful ways", I gather th=
at you're saying "ways that are useful for myself". Indeed, I=
'm</div><div>precisely saying that accessing tuples in the way you prop=
ose isn't useful to me, but you say that this</div><div>isn't the g=
oal. I hope you hit the needs of the standard committee members right on th=
e spot, otherwise</div><div>they might find it difficult to modify _the fre=
aking language_ for your use case.</div><div><br></div><div>Regards,</div><=
div>Louis Dionne</div><div><br></div><div><br></div><blockquote class=3D"gm=
ail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc soli=
d;padding-left: 1ex;"><div dir=3D"ltr"><div>Arbitrary tuple transformations=
was never the goal. That's a legitimate and useful problem domain. But=
that's not what this is intended to handle. The fact that this syntax =
can indeed handle some of that via clever usage of the syntax is merely a f=
ortunate coincidence.<br><br>C++11 already has a construct that is tuple-li=
ke in its nature: parameter packs. We're just expanding it to work with=
actual tuples.<br></div></div></blockquote></div>
<p></p>
-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
Visit this group at <a href=3D"https://groups.google.com/a/isocpp.org/group=
/std-proposals/">https://groups.google.com/a/isocpp.org/group/std-proposals=
/</a>.<br />
------=_Part_275_487542790.1455725775761--
------=_Part_274_527237065.1455725775759--
.
Author: Matthew Woehlke <mwoehlke.floss@gmail.com>
Date: Wed, 17 Feb 2016 12:05:26 -0500
Raw View
On 2016-02-16 19:07, Louis Dionne wrote:
> On Tuesday, 16 February 2016 18:29:54 UTC-5, Nicol Bolas wrote:
>> *Behold the power of the elipsis!*
>>
>> make_tuple(get<[:]index_sequence<1, 0, 3, 3>()>(tpl)...)
>>
>> All this requires is a `constexpr` version of `get<N>(index_sequence)`.
>> And of course an `index_sequence` that is a literal type.
>>
>> Is that good enough for you?
>
> No, unfortunately it's not. The one thing that's really interesting
> with having a language feature to slice a tuple is that the compiler
> might implement this more efficiently than doing a dumb syntactic
> translation and then instantiating the `get<>` functions for real.
Uh... no... not really. The definition of "tuple-like" is "can be
accessed via get<N>". The only time you'll see this happen more
efficiently is if `get<N>` is implicitly provided (a la P0197). In which
case, it should be at least as efficient as your "ideal".
> With what you outline above, the compiler has to instantiate the
> `get<>` function for the index_sequence, and then for the tuple.
Except it *has* to do that. Otherwise, it doesn't know how to access the
elements of the tuple(-like)!
> Basically, what I need is simple. I need a very fast (at
> compile-time) way to get the elements at arbitrary indices inside a
> tuple.
Then you're SOL. You'll only get this - *maybe* - if you use an
aggregate instead of a std::tuple or any old tuple-like. (If you want to
propose somehow guaranteeing that get<N>(std::tuple) is fast, that'd be
fine too, but is orthogonal.)
....or just complain to your compiler vendor; I see no reason this can be
done with an intrinsic as a QoI matter. (Oh, and likewise for
std::index_range while you're at it.)
--
Matthew
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-proposals/.
.
Author: Matthew Woehlke <mwoehlke.floss@gmail.com>
Date: Wed, 17 Feb 2016 12:20:01 -0500
Raw View
On 2016-02-16 18:13, Louis Dionne wrote:
> On Tuesday, 16 February 2016 16:11:36 UTC-5, Matthew Woehlke wrote:
>> On 2016-02-16 15:21, Louis Dionne wrote:
>>> BOOST_HANA_DEFINE_STRUCT(Data,
>>
>> Oops. That right there is a no-go. Redefining the type is right out, as
>> most likely the type is not something that can be directly controlled.
>> (Even if it was, uglifying the API like this? No, thanks...)
>
> You don't need to redefine the type, since the above macro actually
> defines the type itself. If you don't have control over the type, you can
> also use BOOST_HANA_ADAPT_STRUCT to adapt an existing struct.
What about something that satisfies "tuple-like" but does NOT have
public members? That's critical for many, if not most, of my use cases.
I think you're missing the question here. Hana may work on std::tuple
and aggregates (with some additional gymnastics, or if we get
reflection). Will it (or can it be made to) work on *any type with get<N>*?
> To make it back to the proposal, here's what I would find much more
> useful than simple unpacking and slicing, and that could actually be
> used to build more complex tuple algorithms. If we could take a tuple
> and unpack the elements at arbitrary indices, that would be useful.
> For example, disregarding the notation,
>
> auto tuple = std::make_tuple('0', '1', '2', '3', '4', '5');
> f(tuple[1, 0, 3, 3]); //equivalent to f('1', '0', '3', '3')
Although I haven't been noting it recently (and in fact, have
reconsidered whether it should be allowed), my original idea for slicing
does in fact allow this:
f([1,0,3,3]tuple...);
More crudely, even with simplified slicing, you can definitely write:
f([1]tuple, [0]tuple, [3]tuple, [3]tuple);
(Of course, you can also do that today; the single item case is just
short-hand for `get<1>(tuple), ...`.)
> Or, equivalently, if we could slice a tuple with an arbitrary
> `std::index_sequence`,
In *theory*, integer literals can be replaced with any constexpr integer
expression. (For obvious reasons, the compiler has to know the actual
indices at compile time.) This could probably be extended to
index_sequence as well. Trouble comes due to possible confusion with
lambda syntax, however, especially if the tuple-like is an inline
initializer list.
If we made '@' part of the language, this could be easily addressed:
[@expr]tuple; // 'expr' is any constexpr integer or integer sequence
....or perhaps there is some other syntax that is not overly clunky but
avoids ambiguity with existing constructs. (Slicing with literals
doesn't have this problem, as literals are not valid captures and so are
not ambiguous with lambdas.)
Alternatively, do it as Nicol showed :-).
> Do you see a way your proposal could accommodate this?
Sure; see above.
--
Matthew
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-proposals/.
.
Author: Matthew Woehlke <mwoehlke.floss@gmail.com>
Date: Wed, 17 Feb 2016 12:43:46 -0500
Raw View
On 2016-02-16 18:57, Louis Dionne wrote:
> What happens when a function is called with a large number of
> arguments performance-wise? If performance is important, it might be
> better to pass the actual tuple instead of its unpacked
> representation, but that would call for a benchmark.
I see a couple cases here:
1. For whatever reason, you have arguments to a non-template function in
a tuple-like, and want to use them to invoke a function. (Might happen
with RPC's. *Definitely* happens when dealing with linear algebra
vectors, when the function takes N floats/doubles, but you have a
vector-type of some sort.)
2. You need to pass a tuple-like to a function that could take a tuple.
3. You need to pass a bunch of values to a template function that will
do something with each value.
For #1, it's not really relevant; the reason you're unpacking in the
first place is almost certainly because you can't change the API being
called to take the struct in the first place, or because there is no
reason to do so. Performance is probably not an issue, and you likely
aren't dealing with "many" values anyway.
For #2, passing a tuple instead of a bunch of values may require
constructing a tuple from a tuple-like. That may indeed be worthwhile,
but you may need unpacking to construct the tuple in the first place.
For #3, you may need unpacking to make use of the tuple that was
received. You almost certainly will if the function takes an arbitrary
tuple-like.
I definitely agree with your point here. I just don't see it as a good
argument why unpacking isn't needed (although it may affect *where*
unpacking is used).
> On Tuesday, 16 February 2016 18:19:00 UTC-5, Nicol Bolas wrote:
>> On Tuesday, February 16, 2016 at 3:21:29 PM UTC-5, Louis Dionne wrote:
>>> You could write
>>>
>>> auto x = hana::fold_left(hana::transform(tpl, inner), std::plus<>{});
>>
>> And for people who natively read right to left, this would probably be
>> decent. But that's not how the rest of C++ works.
>
> Wtf? How is this different from writing
>
> auto x = ranges::accumulate(ranges::transformed(...), std::plus<>{});
You missed the point. It's different from:
auto x = inner([:]tpl) + ...;
....which is MUCH more terse, and (to me, anyway) very easy to read and
understand.
> the point I'm trying to make is that from the point of view of a
> metaprogramming library writer, this proposal, in its current form,
> misses the goal just like fold expressions did.
As Nicol also pointed out, improved metaprogramming was never an
explicit goal.
The first, most important goal is to be able to write:
foo([:]tpl...);
Secondary goals are being able to slice in unpacking assignments, and
being able to use a tuple-like in parameter pack based fold expressions,
especially `expr << ... << [:]tpl;`.
If it also helps metaprogramming, that's an added bonus. That's not 90+%
of C++ users, though.
--
Matthew
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-proposals/.
.
Author: Matthew Woehlke <mwoehlke.floss@gmail.com>
Date: Wed, 17 Feb 2016 13:06:53 -0500
Raw View
On 2016-02-17 04:40, Sam Kellett wrote:
> my personal opinion is that hana's is much much much more obvious
> (the lambda version of the example specifically), in no short reason
> because it's interface is based on the existing standard library. why
> do we need two syntax's in one language when we can do it all with
> one?
....because parameter packs "don't exist" in a sense. Accordingly, it is
*necessary* that there exists a language syntax to instruct the compiler
how to turn them into real code.
As I stated elsewhere, a lot of the ranting and railing I see here is
directed not at unpacking, but at *fold expressions*. That's borderline
off topic, and I'm not necessarily opposed to improving fold
expressions. (Though I also agree with Nicol that fold expressions are
at least as understandable, and in some cases more so, than hana.)
The point about familiarity here is apt. The hana syntax is obtuse to
anyone not familiar with it. Fold expressions... do have their own
problems, but IMHO are easier to grasp for someone who is a total novice
with both.
> also yours appears to be inherently ungoogle-able. assuming i don't
> understand either syntax, for louis' i type into google 'c++ hana::unpack',
> what do i type to find the reference pages for yours?
https://www.google.com/search?q=c%2B%2B+fold+expressions
--
Matthew
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-proposals/.
.
Author: Miro Knejp <miro.knejp@gmail.com>
Date: Wed, 17 Feb 2016 13:30:28 -0800 (PST)
Raw View
------=_Part_901_1882132413.1455744628399
Content-Type: multipart/alternative;
boundary="----=_Part_902_332764873.1455744628400"
------=_Part_902_332764873.1455744628400
Content-Type: text/plain; charset=UTF-8
I somehow can't shed the feeling that what we really need here is support
for multiple return values.
Just imagine for a moment that the following is valid:
int, float, double foo();
void bar(int, float, double);
bar(foo());
auto {a, b, c} = foo(); // borrowed from P0144R1
having this ability makes writing tuple unpacking trivial
auto tpl = make_tuple(1, 2.f, 3.0);
bar(unpack(tpl));
bar(unpack<2, 1, 0>(tpl));
template<class... Ts>
auto... unpack(tuple<Ts...> x)
{
return unpack_impl<0>(x, index_sequence_for<Ts...>());
}
template<size_t... Is, class... Ts>
auto... unpack(tuple<Ts...> x)
{
return unpack_impl<0>(x, make_index_sequence<Is...>());
}
template<size_t From, size_t To, class... Ts>
auto... unpack_range(tuple<Ts...> x)
{
return unpack_impl<From>(x, make_index_sequence<To - From>);
}
template<size_t Offset, class... Ts, size_t... Is>
auto... unpack_impl(tuple<Ts...> x, index_sequence<Is...>())
{
return get<Is + Offset>(x)...;
}
(and yes, I did omit stuff like rvalue-refs, forward() etc. as they are
only distracting and I am sure everyone here can fill in the details
themselves)
I feel like this opens up the doors to many more possibilities than just
the unpacking syntax alone as discussed in this thread. The syntax may not
be as terse, but to me "unpack(x)" feels easier to understand and teach
than "[:]x". One might consider changing "unpack_range<a, b>(x)" into
"unpack<range<a, b>>(x)", making "unpack" even more potent as a commonly
understood tool (and allows things like unpack<range<0, 2>, 4>(x) getting
the indices 0, 1, 4).
Other examples:
template<class Ts...>
auto tail(tpl<Ts...> x)
{
return make_tuple(unpack_range<1, sizeof...(Ts)>(x));
}
template<size_t Index, class Ts...>
auto... split(tpl<Ts...> x)
{
return make_tuple(unpack<range<0, Index>>(x)),
make_tuple(unpack<range<Index, sizeof...(Ts)>>(x));
}
Given the proper handling of lvalue-refs, rvalue-refs, reference_wrapper
etc, this should also make the example tail(ref(tpl1)) = tpl2 work.
I know multiple return values come with their own set of problems and since
this thread isn't about multiple return values I am not going to address
them here. I guess it comes down to which of the two is more general
purpose and/or has the lesser impact on the language. I just felt like
mentioning this and maybe get more support for multiple return values if
people are interested as the rest emerges naturally from it and the topic
of multiple return values resurfaces regularly.
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-proposals/.
------=_Part_902_332764873.1455744628400
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">I somehow can't shed the feeling that what we really n=
eed here is support for multiple return values.<div><br></div><div>Just ima=
gine for a moment that the following is valid:</div><div><div class=3D"pret=
typrint" style=3D"border: 1px solid rgb(187, 187, 187); word-wrap: break-wo=
rd; background-color: rgb(250, 250, 250);"><code class=3D"prettyprint"><div=
class=3D"subprettyprint"><div class=3D"subprettyprint">int, float, double =
foo();</div><div class=3D"subprettyprint">void bar(int, float, double);</di=
v><div class=3D"subprettyprint">bar(foo());</div><div class=3D"subprettypri=
nt">auto {a, b, c} =3D foo(); // borrowed from P0144R1</div></div></code></=
div><br>having this ability makes writing tuple unpacking trivial</div><div=
><div class=3D"prettyprint" style=3D"border: 1px solid rgb(187, 187, 187); =
word-wrap: break-word; background-color: rgb(250, 250, 250);"><code class=
=3D"prettyprint"><div class=3D"subprettyprint"><div class=3D"subprettyprint=
"><font color=3D"#660066">auto tpl =3D make_tuple(1, 2.f, 3.0);</font></div=
><div class=3D"subprettyprint"><font color=3D"#660066">bar(unpack(tpl));</f=
ont></div><div class=3D"subprettyprint"><font color=3D"#660066">bar(unpack&=
lt;2, 1, 0>(tpl));</font></div><div class=3D"subprettyprint"><font color=
=3D"#660066"><br></font></div><div class=3D"subprettyprint"><div class=3D"s=
ubprettyprint">template<class... Ts></div><div class=3D"subprettyprin=
t">auto... unpack(tuple<Ts...> x)</div><div class=3D"subprettyprint">=
{</div><div class=3D"subprettyprint"><span class=3D"Apple-tab-span" style=
=3D"white-space:pre"> </span>return unpack_impl<0>(x, index_sequence_=
for<Ts...>());</div><div class=3D"subprettyprint">}</div><div class=
=3D"subprettyprint">template<size_t... Is, class... Ts></div><div cla=
ss=3D"subprettyprint">auto... unpack(tuple<Ts...> x)</div><div class=
=3D"subprettyprint">{</div><div class=3D"subprettyprint"><span class=3D"App=
le-tab-span" style=3D"white-space:pre"> </span>return unpack_impl<0>(=
x, make_index_sequence<Is...>());</div><div class=3D"subprettyprint">=
}</div><div class=3D"subprettyprint">template<size_t From, size_t To, cl=
ass... Ts></div><div class=3D"subprettyprint">auto... unpack_range(tuple=
<Ts...> x)</div><div class=3D"subprettyprint">{</div><div class=3D"su=
bprettyprint"><span class=3D"Apple-tab-span" style=3D"white-space:pre"> </s=
pan>return unpack_impl<From>(x, make_index_sequence<To - From>)=
;</div><div class=3D"subprettyprint">}</div><div class=3D"subprettyprint">t=
emplate<size_t Offset, class... Ts, size_t... Is></div><div class=3D"=
subprettyprint">auto... unpack_impl(tuple<Ts...> x, index_sequence<=
;Is...>())</div><div class=3D"subprettyprint">{</div><div class=3D"subpr=
ettyprint"><span class=3D"Apple-tab-span" style=3D"white-space:pre"> </span=
>return get<Is + Offset>(x)...;</div><div class=3D"subprettyprint">}<=
/div></div></div></code></div>(and yes, I did omit stuff like rvalue-refs, =
forward() etc. as they are only distracting and I am sure everyone here can=
fill in the details themselves)<br><br></div><div>I feel like this opens u=
p the doors to many more possibilities than just the unpacking syntax alone=
as discussed in this thread. The syntax may not be as terse, but to me &qu=
ot;unpack(x)" feels easier to understand and teach than "[:]x&quo=
t;. One might consider changing "unpack_range<a, b>(x)" int=
o "unpack<range<a, b>>(x)", making "unpack"=
even more potent as a commonly understood tool (and allows things like unp=
ack<range<0, 2>, 4>(x) getting the indices 0, 1, 4).</div><div>=
<br></div><div>Other examples:</div><div><div class=3D"prettyprint" style=
=3D"border: 1px solid rgb(187, 187, 187); word-wrap: break-word; background=
-color: rgb(250, 250, 250);"><code class=3D"prettyprint"><div class=3D"subp=
rettyprint"><div class=3D"subprettyprint">template<class Ts...></div>=
<div class=3D"subprettyprint">auto tail(tpl<Ts...> x)</div><div class=
=3D"subprettyprint">{</div><div class=3D"subprettyprint"><span class=3D"App=
le-tab-span" style=3D"white-space:pre"> </span>return make_tuple(unpack_ran=
ge<1, sizeof...(Ts)>(x));</div><div class=3D"subprettyprint">}</div><=
div class=3D"subprettyprint">template<size_t Index, class Ts...></div=
><div class=3D"subprettyprint">auto... split(tpl<Ts...> x)</div><div =
class=3D"subprettyprint">{</div><div class=3D"subprettyprint"><span class=
=3D"Apple-tab-span" style=3D"white-space:pre"> </span>return make_tuple(unp=
ack<range<0, Index>>(x)), make_tuple(unpack<range<Index, =
sizeof...(Ts)>>(x));</div><div class=3D"subprettyprint">}</div></div>=
</code></div><div>Given the proper handling of lvalue-refs, rvalue-refs, re=
ference_wrapper etc, this should also make the example tail(ref(tpl1)) =3D =
tpl2 work.<br></div><div><br></div>I know multiple return values come with =
their own set of problems and since this thread isn't about multiple re=
turn values I am not going to address them here. I guess it comes down to w=
hich of the two is more general purpose and/or has the lesser impact on the=
language. I just felt like mentioning this and maybe get more support for =
multiple return values if people are interested as the rest emerges natural=
ly from it and the topic of multiple return values resurfaces regularly.</d=
iv></div>
<p></p>
-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
Visit this group at <a href=3D"https://groups.google.com/a/isocpp.org/group=
/std-proposals/">https://groups.google.com/a/isocpp.org/group/std-proposals=
/</a>.<br />
------=_Part_902_332764873.1455744628400--
------=_Part_901_1882132413.1455744628399--
.
Author: Matthew Woehlke <mwoehlke.floss@gmail.com>
Date: Wed, 17 Feb 2016 17:22:33 -0500
Raw View
On 2016-02-17 16:30, Miro Knejp wrote:
> I somehow can't shed the feeling that what we really need here is support=
=20
> for multiple return values.
I won't say we *don't* need MRV's. However...
> having this ability makes writing tuple unpacking trivial:
>=20
> template<class... Ts> auto... unpack(tuple<Ts...> x);
First off, you meant:
template <typename T> auto... unpack(T);
You mentioned issues with MRV's, so I won't go there except to
acknowledge the point. Although I will note that one of those issues is
creation of something that *looks* like a single value that is actually
multiple values, in a way that's non-obvious (more so than parameter
packs, since the expansion is automatic). In fact, I might venture so
far as to wonder if all the objections against my original proposal
wouldn't come into play? (Do you support fold expressions with MRV's,
for instance?)
TBH, as much as I argued this previously, I have to say that at this
point I'm inclined to see U2PP=C2=B9, and possibly P0222, as the best
solution to MRV's. I can't think offhand of any problems this *doesn't*
solve, and it a) retains the ability to pass around MRV's as single
objects, because they still *are* single objects, and b) adds the power
of fold expressions to all tuple-likes.
(=C2=B9 Unpacking <to> Parameter Packs)
> I feel like this opens up the doors to many more possibilities than just=
=20
> the unpacking syntax alone as discussed in this thread. The syntax may no=
t=20
> be as terse, but to me "unpack(x)" feels easier to understand and teach=
=20
> than "[:]x". One might consider changing "unpack_range<a, b>(x)" into=20
> "unpack<range<a, b>>(x)", making "unpack" even more potent as a commonly=
=20
> understood tool (and allows things like unpack<range<0, 2>, 4>(x) getting=
=20
> the indices 0, 1, 4).
....but as Nicol already showed, you can do this with `[:]` also:
get<[:]{[:]range<a, b>..., 4}>(x)...
....so I am not convinced that this "opens up the doors to many more
possibilities". Rather, it seems like just a different way to achieve
the same possibilities. (Granted, my version is not quite as pretty as
`unpack<range<a, b>>(x)`, but `[:]` trades brevity of more common cases
for verbosity of less common cases.)
Do you have an example of something MRV's could achieve that U2PP can't?
> Given the proper handling of lvalue-refs, rvalue-refs, reference_wrapper=
=20
> etc, this should also make the example tail(ref(tpl1)) =3D tpl2 work.
How would this be different from / better than:
std::tie([1:]tpl1...) =3D tpl2;
....?
--=20
Matthew
--=20
---=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-propos=
als/.
.
Author: Miro Knejp <miro.knejp@gmail.com>
Date: Thu, 18 Feb 2016 00:38:53 +0100
Raw View
Am 17.02.2016 um 23:22 schrieb Matthew Woehlke:
> On 2016-02-17 16:30, Miro Knejp wrote:
>> I somehow can't shed the feeling that what we really need here is suppor=
t
>> for multiple return values.
> I won't say we *don't* need MRV's. However...
>
>> having this ability makes writing tuple unpacking trivial:
>>
>> template<class... Ts> auto... unpack(tuple<Ts...> x);
> First off, you meant:
>
> template <typename T> auto... unpack(T);
No, I didn't. The example I provided was for std::tuple explicitly to=20
demonstrate how MRVs come into the picture. People can obviously=20
customize unpack() in addition to get<>() using ADL as necessary.
>
> You mentioned issues with MRV's, so I won't go there except to
> acknowledge the point. Although I will note that one of those issues is
> creation of something that *looks* like a single value that is actually
> multiple values, in a way that's non-obvious (more so than parameter
> packs, since the expansion is automatic). In fact, I might venture so
> far as to wonder if all the objections against my original proposal
> wouldn't come into play? (Do you support fold expressions with MRV's,
> for instance?)
>
> TBH, as much as I argued this previously, I have to say that at this
> point I'm inclined to see U2PP=C2=B9, and possibly P0222, as the best
> solution to MRV's. I can't think offhand of any problems this *doesn't*
> solve, and it a) retains the ability to pass around MRV's as single
> objects, because they still *are* single objects, and b) adds the power
> of fold expressions to all tuple-likes.
auto t =3D make_tuple(foo()).
There is your "ability to pass around MRV's as single objects".=20
make_tuple() and unpack() become symmetric operations (so maybe a pack()=20
is in order...). (do you have a link to P0222? I couldn't find anything=20
with that number)
In my head MRVs are a transient construct only existent as the type of a=20
call expression. If you need to capture it assign the values to=20
varaiables (like in P0144R1) or forward as parameters to another call=20
expression (like make_tuple). Under this assumption, that MRVs are their=20
own kind of entity, folding becomes possible as (0 + ... + foo()) if=20
their special nature is considered. Therefore folding a tuple becomes (0=20
+ ... + unpack(tpl)).
>
> (=C2=B9 Unpacking <to> Parameter Packs)
>
>> I feel like this opens up the doors to many more possibilities than just
>> the unpacking syntax alone as discussed in this thread. The syntax may n=
ot
>> be as terse, but to me "unpack(x)" feels easier to understand and teach
>> than "[:]x". One might consider changing "unpack_range<a, b>(x)" into
>> "unpack<range<a, b>>(x)", making "unpack" even more potent as a commonly
>> understood tool (and allows things like unpack<range<0, 2>, 4>(x) gettin=
g
>> the indices 0, 1, 4).
> ...but as Nicol already showed, you can do this with `[:]` also:
>
> get<[:]{[:]range<a, b>..., 4}>(x)...
That was not the point. I didn't say the syntax proposed in this thread=20
can't do it. But I'd rather see unpack<range<a, b>>(x) than a line with=20
*8 consecutive punctuation characters*. Some people are already=20
challenged by []{} :)
>
> ...so I am not convinced that this "opens up the doors to many more
> possibilities". Rather, it seems like just a different way to achieve
> the same possibilities.
If all you see is tuples then MRVs don't add anything, that is true. The=20
syntax from here is dedicated to tuple-like things *only*. Whereas MRVs=20
are useful outside the scope of tuple-like things but can be used to=20
implement all the problems (as far as I can tell) presented in this=20
discussion as a library extension. I can't judge how much more/less of=20
an impact specifying the unpacking syntax is compared to MRVs to be able=20
to tell which had a lower barrier of acceptance in the committee, since=20
in the context of this thread alone MRVs don't add anything new.
> (Granted, my version is not quite as pretty as
> `unpack<range<a, b>>(x)`, but `[:]` trades brevity of more common cases
> for verbosity of less common cases.)
>
> Do you have an example of something MRV's could achieve that U2PP can't?
Again, no, since "U2PP" is only useful in the context of tuples whereas=20
MRVs are not constrained to the tuple use case only. People have=20
repeatedly asked for the ability to return multiple values for all kinds=20
of use cases.
>
>> Given the proper handling of lvalue-refs, rvalue-refs, reference_wrapper
>> etc, this should also make the example tail(ref(tpl1)) =3D tpl2 work.
> How would this be different from / better than:
>
> std::tie([1:]tpl1...) =3D tpl2;
>
> ...?
It uses words that actually describe what it does.
Without MRVs you cannot hide "[1:]tpl1..." effortlessly behind a named=20
function. *Every single time* someone needs to unpack the tail of a=20
tuple they have to write out the same sequence of punctuation. DRY=20
anyone? Even languages with this kind of syntax come shipped with=20
utility functions like tail() because they're more descriptive. In order=20
to hide it inside a function you have to return a tuple (maybe=20
containing references) and then use the awkward inversion of "apply(f,=20
something(x))" when using the result. The benefits of the unpacking=20
syntax are completely lost to the user at that point. Compare that to=20
"f(something(x))" and tell me which one you'd prefer to write and read.
If you're asking whether it performs better then nobody can tell unless=20
you have a hacked compiler to measure compile times and look at the=20
disassembly.
--=20
---=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-propos=
als/.
.
Author: Sam Kellett <samkellett@gmail.com>
Date: Thu, 18 Feb 2016 08:56:50 +0000
Raw View
--001a113fcdae173c30052c078cd2
Content-Type: text/plain; charset=UTF-8
On 17 February 2016 at 18:06, Matthew Woehlke <mwoehlke.floss@gmail.com>
wrote:
> On 2016-02-17 04:40, Sam Kellett wrote:
> > my personal opinion is that hana's is much much much more obvious
> > (the lambda version of the example specifically), in no short reason
> > because it's interface is based on the existing standard library. why
> > do we need two syntax's in one language when we can do it all with
> > one?
>
> ...because parameter packs "don't exist" in a sense. Accordingly, it is
> *necessary* that there exists a language syntax to instruct the compiler
> how to turn them into real code.
>
> As I stated elsewhere, a lot of the ranting and railing I see here is
> directed not at unpacking, but at *fold expressions*. That's borderline
> off topic, and I'm not necessarily opposed to improving fold
> expressions. (Though I also agree with Nicol that fold expressions are
> at least as understandable, and in some cases more so, than hana.)
>
> The point about familiarity here is apt. The hana syntax is obtuse to
> anyone not familiar with it. Fold expressions... do have their own
> problems, but IMHO are easier to grasp for someone who is a total novice
> with both.
>
> > also yours appears to be inherently ungoogle-able. assuming i don't
> > understand either syntax, for louis' i type into google 'c++
> hana::unpack',
> > what do i type to find the reference pages for yours?
>
> https://www.google.com/search?q=c%2B%2B+fold+expressions
so assuming that you *don't* understand the code you are looking at. how on
earth did you deduce what they are called?
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-proposals/.
--001a113fcdae173c30052c078cd2
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><div class=3D"gmail_extra"><div class=3D"gmail_quote">On 1=
7 February 2016 at 18:06, Matthew Woehlke <span dir=3D"ltr"><<a href=3D"=
mailto:mwoehlke.floss@gmail.com" target=3D"_blank">mwoehlke.floss@gmail.com=
</a>></span> wrote:<br><blockquote class=3D"gmail_quote" style=3D"margin=
:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><span class=3D"">O=
n 2016-02-17 04:40, Sam Kellett wrote:<br>
> my personal opinion is that hana's is much much much more obvious<=
br>
> (the lambda version of the example specifically), in no short reason<b=
r>
> because it's interface is based on the existing standard library. =
why<br>
> do we need two syntax's in one language when we can do it all with=
<br>
> one?<br>
<br>
</span>...because parameter packs "don't exist" in a sense. A=
ccordingly, it is<br>
*necessary* that there exists a language syntax to instruct the compiler<br=
>
how to turn them into real code.<br>
<br>
As I stated elsewhere, a lot of the ranting and railing I see here is<br>
directed not at unpacking, but at *fold expressions*. That's borderline=
<br>
off topic, and I'm not necessarily opposed to improving fold<br>
expressions. (Though I also agree with Nicol that fold expressions are<br>
at least as understandable, and in some cases more so, than hana.)<br>
<br>
The point about familiarity here is apt. The hana syntax is obtuse to<br>
anyone not familiar with it. Fold expressions... do have their own<br>
problems, but IMHO are easier to grasp for someone who is a total novice<br=
>
with both.<br></blockquote><blockquote class=3D"gmail_quote" style=3D"margi=
n:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<span class=3D""><br>
> also yours appears to be inherently ungoogle-able. assuming i don'=
t<br>
> understand either syntax, for louis' i type into google 'c++ h=
ana::unpack',<br>
> what do i type to find the reference pages for yours?<br>
<br>
</span><a href=3D"https://www.google.com/search?q=3Dc%2B%2B+fold+expression=
s" rel=3D"noreferrer" target=3D"_blank">https://www.google.com/search?q=3Dc=
%2B%2B+fold+expressions</a></blockquote><div><br></div><div>so assuming tha=
t you *don't* understand the code you are looking at. how on earth did =
you deduce what they are called?<br></div></div></div></div>
<p></p>
-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
Visit this group at <a href=3D"https://groups.google.com/a/isocpp.org/group=
/std-proposals/">https://groups.google.com/a/isocpp.org/group/std-proposals=
/</a>.<br />
--001a113fcdae173c30052c078cd2--
.
Author: "Vicente J. Botet Escriba" <vicente.botet@wanadoo.fr>
Date: Thu, 18 Feb 2016 10:40:38 +0100
Raw View
This is a multi-part message in MIME format.
--------------090002050501030908020602
Content-Type: text/plain; charset=UTF-8; format=flowed
Content-Transfer-Encoding: quoted-printable
Le 17/02/2016 22:30, Miro Knejp a =C3=A9crit :
> I somehow can't shed the feeling that what we really need here is=20
> support for multiple return values.
>
I don't know if mandatory for the subject on this thread, but yes, I=20
believe we need MRV, but I don't know exactly what this would mean yet.
> Just imagine for a moment that the following is valid:
> |
> int, float, double foo();
> void bar(int, float, double);
> bar(foo());
> auto {a, b, c} =3D foo(); // borrowed from P0144R1
> |
>
Could you show how would you define foo() to return MRV?
return 0, 1.0, 2.0;
or
| return 0 1.0 2.0;
|
Or?
IIUC, the single things you can do with a MRV is to use it in a call=20
expression and in this case each one of the values is associated to an=20
argument, and
structure binding. However structure binding is associated to a=20
tuple-like interface. Does it means that a MRV thing would have a=20
tuple-like access interface (get<I>(mrv))?
If foo() in the context of bar(foo()) is expanded to bar(a1,a2,a3) for=20
some a1,a2,a3
it should also be expanded in the context of
|
auto {a, b, c} =3D foo();
and so we will need that
|auto {a, b, c} =3D a1, a2, a3;
But |||P0144R1 doesn't support it, neither P0222R0. |
Or would the user need to pack it before?
||auto {a, b, c} =3D make_tuple(foo());
|
IMO a MRV, or whatever we call the result of a MRV function, either
* is always unpacked and needs some sort of pack function (make-tuple)=20
in some cases or
* is packed and we needs some sort of unpack function. I will not be=20
against the use of an operator to unpack a MRV
|
bar(*foo());
|
|
> having this ability makes writing tuple unpacking trivial
> |
> auto tpl =3D make_tuple(1, 2.f, 3.0);
> bar(unpack(tpl));
> bar(unpack<2, 1, 0>(tpl));
>
> template<class... Ts>
> auto... unpack(tuple<Ts...> x)
> {
> return unpack_impl<0>(x, index_sequence_for<Ts...>());
> }
> template<size_t... Is, class... Ts>
> auto... unpack(tuple<Ts...> x)
> {
> return unpack_impl<0>(x, make_index_sequence<Is...>());
> }
> template<size_t From, size_t To, class... Ts>
> auto... unpack_range(tuple<Ts...> x)
> {
> return unpack_impl<From>(x, make_index_sequence<To - From>);
> }
> template<size_t Offset, class... Ts, size_t... Is>
> auto... unpack_impl(tuple<Ts...> x, index_sequence<Is...>())
> {
> return get<Is + Offset>(x)...;
> }
> |
> (and yes, I did omit stuff like rvalue-refs, forward() etc. as they=20
> are only distracting and I am sure everyone here can fill in the=20
> details themselves)
>
Here you introduce something additional. auto... as a deduced MRV.
I suspect to be inline with the way we return here (there is no use of=20
',' to separate the arguments, the foo() function should return as
| return 0 1.0 2.0;|
> I feel like this opens up the doors to many more possibilities than=20
> just the unpacking syntax alone as discussed in this thread. The=20
> syntax may not be as terse, but to me "unpack(x)" feels easier to=20
> understand and teach than "[:]x". One might consider changing=20
> "unpack_range<a, b>(x)" into "unpack<range<a, b>>(x)", making "unpack"=20
> even more potent as a commonly understood tool (and allows things like=20
> unpack<range<0, 2>, 4>(x) getting the indices 0, 1, 4).
>
> Other examples:
> |
> template<class Ts...>
> auto tail(tpl<Ts...> x)
> {
> return make_tuple(unpack_range<1, sizeof...(Ts)>(x));
> }
> template<size_t Index, class Ts...>
> auto... split(tpl<Ts...> x)
> {
> return make_tuple(unpack<range<0, Index>>(x)),=20
> make_tuple(unpack<range<Index, sizeof...(Ts)>>(x));
> }
> |
> Given the proper handling of lvalue-refs, rvalue-refs,=20
> reference_wrapper etc, this should also make the example=20
> tail(ref(tpl1)) =3D tpl2 work.
>
> I know multiple return values come with their own set of problems and=20
> since this thread isn't about multiple return values I am not going to=20
> address them here.
Well, as there is not yet a proposal for MRV we need to consider yours=20
here, to see if is something that could be acceptable. What I mean is=20
that we can not compare two solutions to a specific problem until we=20
have concrete solutions and we can see the advantages and liabilities=20
for both solutions. Maybe you prefer to start a new thread.
> I guess it comes down to which of the two is more general purpose=20
> and/or has the lesser impact on the language. I just felt like=20
> mentioning this and maybe get more support for multiple return values=20
> if people are interested as the rest emerges naturally from it and the=20
> topic of multiple return values resurfaces regularly.
>
I'm not yet for or against any solution, we need concrete proposals=20
containing more details.
Vicente
--=20
---=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-propos=
als/.
--------------090002050501030908020602
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<html>
<head>
<meta content=3D"text/html; charset=3Dutf-8" http-equiv=3D"Content-Type=
">
</head>
<body bgcolor=3D"#FFFFFF" text=3D"#000000">
<div class=3D"moz-cite-prefix">Le 17/02/2016 22:30, Miro Knejp a
=C3=A9crit=C2=A0:<br>
</div>
<blockquote
cite=3D"mid:6e35f24a-f728-4ac2-b329-1894206f59cc@isocpp.org"
type=3D"cite">
<div dir=3D"ltr">I somehow can't shed the feeling that what we
really need here is support for multiple return values.
<div><br>
</div>
</div>
</blockquote>
I don't know if mandatory for the subject on this thread, but yes, I
believe we need MRV, but I don't know exactly what this would mean
yet.<br>
<blockquote
cite=3D"mid:6e35f24a-f728-4ac2-b329-1894206f59cc@isocpp.org"
type=3D"cite">
<div dir=3D"ltr">
<div>Just imagine for a moment that the following is valid:</div>
<div>
<div class=3D"prettyprint" style=3D"border: 1px solid rgb(187,
187, 187); word-wrap: break-word; background-color: rgb(250,
250, 250);"><code class=3D"prettyprint">
<div class=3D"subprettyprint">
<div class=3D"subprettyprint">int, float, double foo();</di=
v>
<div class=3D"subprettyprint">void bar(int, float,
double);</div>
<div class=3D"subprettyprint">bar(foo());</div>
<div class=3D"subprettyprint">auto {a, b, c} =3D foo(); //
borrowed from P0144R1</div>
</div>
</code></div>
<br>
</div>
</div>
</blockquote>
Could you show how would you define foo() to return MRV?<br>
=C2=A0=C2=A0=C2=A0 return 0, 1.0, 2.0;<br>
<br>
or <br>
<br>
<code class=3D"prettyprint">=C2=A0=C2=A0=C2=A0 return 0 1.0 2.0;<br>
</code><br>
Or?<br>
<br>
IIUC, the single things you can do with a MRV is to use it in a call
expression and in this case each one of the values is associated to
an argument, and<br>
structure binding. However structure binding is associated to a
tuple-like interface. Does it means that a MRV thing would have a
tuple-like access interface (get<I>(mrv))?<br>
<br>
If foo() in the context of bar(foo()) is expanded to bar(a1,a2,a3)
for some a1,a2,a3 <br>
<br>
it should also be expanded in the context of<br>
<code class=3D"prettyprint">
<div class=3D"subprettyprint">auto {a, b, c} =3D foo(); <br>
<br>
and so we will need that<br>
<br>
<code class=3D"prettyprint">auto {a, b, c} =3D a1, a2, a3; <br>
<br>
But </code><code class=3D"prettyprint"><code
class=3D"prettyprint">P0144R1 doesn't support it, neither
P0222R0.=C2=A0 </code><br>
<br>
Or would the user need to pack it before?<br>
<br>
</code><code class=3D"prettyprint">auto {a, b, c} =3D
make_tuple(foo()); <br>
</code><br>
<br>
IMO a MRV, or whatever we call the result of a MRV function,
either <br>
* is always unpacked and needs some sort of pack function
(make-tuple) in some cases or <br>
* is packed and we needs some sort of unpack function. I will
not be against the use of an operator to unpack a MRV<br>
<br>
<code class=3D"prettyprint">
<div class=3D"subprettyprint">bar(*foo());</div>
</code><br>
</div>
</code><br>
<br>
<blockquote
cite=3D"mid:6e35f24a-f728-4ac2-b329-1894206f59cc@isocpp.org"
type=3D"cite">
<div dir=3D"ltr">
<div>having this ability makes writing tuple unpacking trivial</div=
>
<div>
<div class=3D"prettyprint" style=3D"border: 1px solid rgb(187,
187, 187); word-wrap: break-word; background-color: rgb(250,
250, 250);"><code class=3D"prettyprint">
<div class=3D"subprettyprint">
<div class=3D"subprettyprint"><font color=3D"#660066">auto
tpl =3D make_tuple(1, 2.f, 3.0);</font></div>
<div class=3D"subprettyprint"><font color=3D"#660066">bar(u=
npack(tpl));</font></div>
<div class=3D"subprettyprint"><font color=3D"#660066">bar(u=
npack<2,
1, 0>(tpl));</font></div>
<div class=3D"subprettyprint"><font color=3D"#660066"><br>
</font></div>
<div class=3D"subprettyprint">
<div class=3D"subprettyprint">template<class...
Ts></div>
<div class=3D"subprettyprint">auto...
unpack(tuple<Ts...> x)</div>
<div class=3D"subprettyprint">{</div>
<div class=3D"subprettyprint"><span class=3D"Apple-tab-sp=
an" style=3D"white-space:pre"> </span>return
unpack_impl<0>(x,
index_sequence_for<Ts...>());</div>
<div class=3D"subprettyprint">}</div>
<div class=3D"subprettyprint">template<size_t... Is,
class... Ts></div>
<div class=3D"subprettyprint">auto...
unpack(tuple<Ts...> x)</div>
<div class=3D"subprettyprint">{</div>
<div class=3D"subprettyprint"><span class=3D"Apple-tab-sp=
an" style=3D"white-space:pre"> </span>return
unpack_impl<0>(x,
make_index_sequence<Is...>());</div>
<div class=3D"subprettyprint">}</div>
<div class=3D"subprettyprint">template<size_t From,
size_t To, class... Ts></div>
<div class=3D"subprettyprint">auto...
unpack_range(tuple<Ts...> x)</div>
<div class=3D"subprettyprint">{</div>
<div class=3D"subprettyprint"><span class=3D"Apple-tab-sp=
an" style=3D"white-space:pre"> </span>return
unpack_impl<From>(x, make_index_sequence<To
- From>);</div>
<div class=3D"subprettyprint">}</div>
<div class=3D"subprettyprint">template<size_t Offset,
class... Ts, size_t... Is></div>
<div class=3D"subprettyprint">auto...
unpack_impl(tuple<Ts...> x,
index_sequence<Is...>())</div>
<div class=3D"subprettyprint">{</div>
<div class=3D"subprettyprint"><span class=3D"Apple-tab-sp=
an" style=3D"white-space:pre"> </span>return
get<Is + Offset>(x)...;</div>
<div class=3D"subprettyprint">}</div>
</div>
</div>
</code></div>
(and yes, I did omit stuff like rvalue-refs, forward() etc. as
they are only distracting and I am sure everyone here can fill
in the details themselves)<br>
<br>
</div>
</div>
</blockquote>
Here you introduce something additional. auto... as a deduced MRV. <br>
<br>
I suspect to be inline with the way we return here=C2=A0 (there is no u=
se
of ',' to separate the arguments, the foo() function should return
as<br>
<br>
<code class=3D"prettyprint">=C2=A0=C2=A0=C2=A0 return 0 1.0 2.0;</code>=
<br>
<blockquote
cite=3D"mid:6e35f24a-f728-4ac2-b329-1894206f59cc@isocpp.org"
type=3D"cite">
<div dir=3D"ltr">
<div>I feel like this opens up the doors to many more
possibilities than just the unpacking syntax alone as
discussed in this thread. The syntax may not be as terse, but
to me "unpack(x)" feels easier to understand and teach than
"[:]x". One might consider changing "unpack_range<a,
b>(x)" into "unpack<range<a, b>>(x)", making
"unpack" even more potent as a commonly understood tool (and
allows things like unpack<range<0, 2>, 4>(x)
getting the indices 0, 1, 4).</div>
<div><br>
</div>
<div>Other examples:</div>
<div>
<div class=3D"prettyprint" style=3D"border: 1px solid rgb(187,
187, 187); word-wrap: break-word; background-color: rgb(250,
250, 250);"><code class=3D"prettyprint">
<div class=3D"subprettyprint">
<div class=3D"subprettyprint">template<class Ts...></=
div>
<div class=3D"subprettyprint">auto tail(tpl<Ts...>
x)</div>
<div class=3D"subprettyprint">{</div>
<div class=3D"subprettyprint"><span class=3D"Apple-tab-span=
" style=3D"white-space:pre"> </span>return
make_tuple(unpack_range<1, sizeof...(Ts)>(x));</div=
>
<div class=3D"subprettyprint">}</div>
<div class=3D"subprettyprint">template<size_t Index,
class Ts...></div>
<div class=3D"subprettyprint">auto...
split(tpl<Ts...> x)</div>
<div class=3D"subprettyprint">{</div>
<div class=3D"subprettyprint"><span class=3D"Apple-tab-span=
" style=3D"white-space:pre"> </span>return
make_tuple(unpack<range<0, Index>>(x)),
make_tuple(unpack<range<Index,
sizeof...(Ts)>>(x));</div>
<div class=3D"subprettyprint">}</div>
</div>
</code></div>
<div>Given the proper handling of lvalue-refs, rvalue-refs,
reference_wrapper etc, this should also make the example
tail(ref(tpl1)) =3D tpl2 work.<br>
</div>
<div><br>
</div>
I know multiple return values come with their own set of
problems and since this thread isn't about multiple return
values I am not going to address them here. </div>
</div>
</blockquote>
Well, as there is not yet a proposal for MRV we need to consider
yours here, to see if is something that could be acceptable. What I
mean is that we can not compare two solutions to a specific problem
until we have concrete solutions and we can see the advantages and
liabilities for both solutions. Maybe you prefer to start a new
thread.<br>
<blockquote
cite=3D"mid:6e35f24a-f728-4ac2-b329-1894206f59cc@isocpp.org"
type=3D"cite">
<div dir=3D"ltr">
<div>I guess it comes down to which of the two is more general
purpose and/or has the lesser impact on the language. I just
felt like mentioning this and maybe get more support for
multiple return values if people are interested as the rest
emerges naturally from it and the topic of multiple return
values resurfaces regularly.</div>
</div>
<br>
</blockquote>
I'm not yet for or against any solution, we need concrete proposals
containing more details.<br>
<br>
Vicente<br>
</body>
</html>
<p></p>
-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
Visit this group at <a href=3D"https://groups.google.com/a/isocpp.org/group=
/std-proposals/">https://groups.google.com/a/isocpp.org/group/std-proposals=
/</a>.<br />
--------------090002050501030908020602--
.
Author: Miro Knejp <miro.knejp@gmail.com>
Date: Thu, 18 Feb 2016 16:39:08 +0100
Raw View
This is a multi-part message in MIME format.
--------------040908020202070905000100
Content-Type: text/plain; charset=UTF-8; format=flowed
Content-Transfer-Encoding: quoted-printable
Am 18.02.2016 um 10:40 schrieb Vicente J. Botet Escriba:
> Le 17/02/2016 22:30, Miro Knejp a =C3=A9crit :
>> I somehow can't shed the feeling that what we really need here is=20
>> support for multiple return values.
>>
> I don't know if mandatory for the subject on this thread, but yes, I=20
> believe we need MRV, but I don't know exactly what this would mean yet.
>> Just imagine for a moment that the following is valid:
>> |
>> int, float, double foo();
>> void bar(int, float, double);
>> bar(foo());
>> auto {a, b, c} =3D foo(); // borrowed from P0144R1
>> |
>>
> Could you show how would you define foo() to return MRV?
> return 0, 1.0, 2.0;
>
> or
>
> | return 0 1.0 2.0;
> |
> Or?
There are examples further down in my post. Besides any syntax presented=20
here is just a strawman so don't get lost in the details too much.
>
> IIUC, the single things you can do with a MRV is to use it in a call=20
> expression and in this case each one of the values is associated to an=20
> argument, and
> structure binding. However structure binding is associated to a=20
> tuple-like interface. Does it means that a MRV thing would have a=20
> tuple-like access interface (get<I>(mrv))?
No. If you want to return multiple values in something with a tupe-like=20
interface, well then use tuple and P0144 binding. There's also a=20
proposal in SG14 to synthesize get<>() for public fields, making any old=20
struct compatible with P0144. It is important to keep the multiple=20
return values separate in a special entity to allow for the compiler=20
magic that unpacks it effortlessly into a list of parameters.
> If foo() in the context of bar(foo()) is expanded to bar(a1,a2,a3) for=20
> some a1,a2,a3
>
> it should also be expanded in the context of
> |
> auto {a, b, c} =3D foo();
>
> and so we will need that
>
> |auto {a, b, c} =3D a1, a2, a3;
> |
> |
|No, since "a1, a2, a3" is a comma-expression and the binding only=20
applies to the result of the expression "a3". If P0144 doesn't consider=20
this special case then it will become impossible to add it later.=20
Functions returning multiple values return a special kind of entity that=20
is transparent to the user and allows unpacking into arguments and can=20
only exist as a temporary. You cannot reference it directly, you cannot=20
decltype() it (same as with parameter packs) and you cannot spell its=20
type. It is not a different syntax for a comma-expression for which we=20
don't need anythign new. What we need is special treatment for "this=20
function returns multiple values and I can pass them as separate=20
arguments to call expressions". We already have a solution if it's not a=20
function result but parameters: parameter packs.|
> |
> |
> But |||P0144R1 doesn't support it, neither P0222R0. |
> |
> |
|Where is this P0222R0 and why is Google unable to find it? :(|
> |
> |
> Or would the user need to pack it before?
>
> ||auto {a, b, c} =3D make_tuple(foo());
> |
>
> IMO a MRV, or whatever we call the result of a MRV function, either
> * is always unpacked and needs some sort of pack function (make-tuple)=20
> in some cases or
> * is packed and we needs some sort of unpack function. I will not be=20
> against the use of an operator to unpack a MRV
>
> |
> bar(*foo());
> |
> |
|My concept treats multiple return values as unpacked, since we already=20
have solutions for packed values: tuple and other classes. MRVs can only=20
be used to
(1) be unpacked as parameters to a call expression
(2) be a direct subexpression in a return statement
(3) be unpacked in a fold expression
(4) be captured into variables by the syntax in P0144
I know (4) is redundant because of (1) but I feel like "auto {a, b, c} =3D=
=20
foo()" is simply too convenient to not have it supported compared to=20
"auto {a, b, c} =3D std::make_tuple(foo())" (which also needs an include).=
=20
With this basic functionality we can implement everything else mentioned=20
in this thread as a library extension using make_tuple() and unpack().=20
But since unpack() doesn't depend on implementation-defined magical=20
compiler intrinsics anyone can write their own special snowflake if they=20
so desire.
Unpacking may require the unpack operator to allow the difference=20
between outer(inner(unpack(x)...)) and outer(inner(unpack(x))...) as=20
mentioned earlier. That is a detail that needs to be discussed.
|
> |
> ||
> |
>
>> having this ability makes writing tuple unpacking trivial
>> |
>> auto tpl =3D make_tuple(1, 2.f, 3.0);
>> bar(unpack(tpl));
>> bar(unpack<2, 1, 0>(tpl));
>>
>> template<class... Ts>
>> auto... unpack(tuple<Ts...> x)
>> {
>> return unpack_impl<0>(x, index_sequence_for<Ts...>());
>> }
>> template<size_t... Is, class... Ts>
>> auto... unpack(tuple<Ts...> x)
>> {
>> return unpack_impl<0>(x, make_index_sequence<Is...>());
>> }
>> template<size_t From, size_t To, class... Ts>
>> auto... unpack_range(tuple<Ts...> x)
>> {
>> return unpack_impl<From>(x, make_index_sequence<To - From>);
>> }
>> template<size_t Offset, class... Ts, size_t... Is>
>> auto... unpack_impl(tuple<Ts...> x, index_sequence<Is...>())
>> {
>> return get<Is + Offset>(x)...;
>> }
>> |
>> (and yes, I did omit stuff like rvalue-refs, forward() etc. as they=20
>> are only distracting and I am sure everyone here can fill in the=20
>> details themselves)
>>
> Here you introduce something additional. auto... as a deduced MRV.
> I suspect to be inline with the way we return here (there is no use=20
> of ',' to separate the arguments, the foo() function should return as
>
> | return 0 1.0 2.0;|
Remember this is strawman syntax, but here goes anyway: "auto..." is to=20
tell the compiler that "return a, b, c;" (as is the result of a=20
parameter pack expansion) does not use the comma operator but actually=20
returns multiple values. If the compiler expects only a single value=20
then "return a, b, c;" only returns the result of evaluating "c" (or=20
whatever crazy person overloaded the comma operator with). This is only=20
needed in deduced return types and "auto..." is arbitrarily chosen=20
because it is currently ill-formed. If you spell out all return types=20
akin to something like "int, int, int foo()" then "return a, b, c;" is=20
unambiguous. Both are means to not break existing code.
>> I feel like this opens up the doors to many more possibilities than=20
>> just the unpacking syntax alone as discussed in this thread. The=20
>> syntax may not be as terse, but to me "unpack(x)" feels easier to=20
>> understand and teach than "[:]x". One might consider changing=20
>> "unpack_range<a, b>(x)" into "unpack<range<a, b>>(x)", making=20
>> "unpack" even more potent as a commonly understood tool (and allows=20
>> things like unpack<range<0, 2>, 4>(x) getting the indices 0, 1, 4).
>>
>> Other examples:
>> |
>> template<class Ts...>
>> auto tail(tpl<Ts...> x)
>> {
>> return make_tuple(unpack_range<1, sizeof...(Ts)>(x));
>> }
>> template<size_t Index, class Ts...>
>> auto... split(tpl<Ts...> x)
>> {
>> return make_tuple(unpack<range<0, Index>>(x)),=20
>> make_tuple(unpack<range<Index, sizeof...(Ts)>>(x));
>> }
>> |
>> Given the proper handling of lvalue-refs, rvalue-refs,=20
>> reference_wrapper etc, this should also make the example=20
>> tail(ref(tpl1)) =3D tpl2 work.
>>
>> I know multiple return values come with their own set of problems and=20
>> since this thread isn't about multiple return values I am not going=20
>> to address them here.
> Well, as there is not yet a proposal for MRV we need to consider yours=20
> here, to see if is something that could be acceptable. What I mean is=20
> that we can not compare two solutions to a specific problem until we=20
> have concrete solutions and we can see the advantages and liabilities=20
> for both solutions. Maybe you prefer to start a new thread.
I haven't given the standard wording any thought yet so whether MRVs are=20
their own thing or parameter packs or whatever is entirely open for=20
debate (in a different thread if there is enough interest).
>> I guess it comes down to which of the two is more general purpose=20
>> and/or has the lesser impact on the language. I just felt like=20
>> mentioning this and maybe get more support for multiple return values=20
>> if people are interested as the rest emerges naturally from it and=20
>> the topic of multiple return values resurfaces regularly.
>>
> I'm not yet for or against any solution, we need concrete proposals=20
> containing more details.
>
> Vicente
> --=20
>
> ---
> You received this message because you are subscribed to the Google=20
> Groups "ISO C++ Standard - Future Proposals" group.
> To unsubscribe from this group and stop receiving emails from it, send=20
> an email to std-proposals+unsubscribe@isocpp.org=20
> <mailto:std-proposals+unsubscribe@isocpp.org>.
> To post to this group, send email to std-proposals@isocpp.org=20
> <mailto:std-proposals@isocpp.org>.
> Visit this group at=20
> https://groups.google.com/a/isocpp.org/group/std-proposals/.
--=20
---=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-propos=
als/.
--------------040908020202070905000100
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<html>
<head>
<meta content=3D"text/html; charset=3Dutf-8" http-equiv=3D"Content-Type=
">
</head>
<body bgcolor=3D"#FFFFFF" text=3D"#000000">
<br>
<br>
<div class=3D"moz-cite-prefix">Am 18.02.2016 um 10:40 schrieb Vicente
J. Botet Escriba:<br>
</div>
<blockquote cite=3D"mid:56C59196.5020401@wanadoo.fr" type=3D"cite">
<meta content=3D"text/html; charset=3Dutf-8" http-equiv=3D"Content-Ty=
pe">
<div class=3D"moz-cite-prefix">Le 17/02/2016 22:30, Miro Knejp a
=C3=A9crit=C2=A0:<br>
</div>
<blockquote
cite=3D"mid:6e35f24a-f728-4ac2-b329-1894206f59cc@isocpp.org"
type=3D"cite">
<div dir=3D"ltr">I somehow can't shed the feeling that what we
really need here is support for multiple return values.
<div><br>
</div>
</div>
</blockquote>
I don't know if mandatory for the subject on this thread, but yes,
I believe we need MRV, but I don't know exactly what this would
mean yet.<br>
<blockquote
cite=3D"mid:6e35f24a-f728-4ac2-b329-1894206f59cc@isocpp.org"
type=3D"cite">
<div dir=3D"ltr">
<div>Just imagine for a moment that the following is valid:</div>
<div>
<div class=3D"prettyprint" style=3D"border: 1px solid rgb(187,
187, 187); word-wrap: break-word; background-color:
rgb(250, 250, 250);"><code class=3D"prettyprint">
<div class=3D"subprettyprint">
<div class=3D"subprettyprint">int, float, double foo();</=
div>
<div class=3D"subprettyprint">void bar(int, float,
double);</div>
<div class=3D"subprettyprint">bar(foo());</div>
<div class=3D"subprettyprint">auto {a, b, c} =3D foo(); /=
/
borrowed from P0144R1</div>
</div>
</code></div>
<br>
</div>
</div>
</blockquote>
Could you show how would you define foo() to return MRV?<br>
=C2=A0=C2=A0=C2=A0 return 0, 1.0, 2.0;<br>
<br>
or <br>
<br>
<code class=3D"prettyprint">=C2=A0=C2=A0=C2=A0 return 0 1.0 2.0;<br>
</code><br>
Or?<br>
</blockquote>
There are examples further down in my post. Besides any syntax
presented here is just a strawman so don't get lost in the details
too much.<br>
<blockquote cite=3D"mid:56C59196.5020401@wanadoo.fr" type=3D"cite"> <br=
>
IIUC, the single things you can do with a MRV is to use it in a
call expression and in this case each one of the values is
associated to an argument, and<br>
structure binding. However structure binding is associated to a
tuple-like interface. Does it means that a MRV thing would have a
tuple-like access interface (get<I>(mrv))?<br>
</blockquote>
No. If you want to return multiple values in something with a
tupe-like interface, well then use tuple and P0144 binding. There's
also a proposal in SG14 to synthesize get<>() for public
fields, making any old struct compatible with P0144. It is important
to keep the multiple return values separate in a special entity to
allow for the compiler magic that unpacks it effortlessly into a
list of parameters.
<blockquote cite=3D"mid:56C59196.5020401@wanadoo.fr" type=3D"cite">If
foo() in the context of bar(foo()) is expanded to bar(a1,a2,a3)
for some a1,a2,a3 <br>
<br>
it should also be expanded in the context of<br>
<code class=3D"prettyprint">
<div class=3D"subprettyprint">auto {a, b, c} =3D foo(); <br>
<br>
and so we will need that<br>
<br>
<code class=3D"prettyprint">auto {a, b, c} =3D a1, a2, a3; <br>
</code></div>
</code></blockquote>
<code>No, since "a1, a2, a3" is a comma-expression and the binding
only applies to the result of the expression "a3". If P0144
doesn't consider this special case then it will become impossible
to add it later. Functions returning multiple values return a
special kind of entity that is transparent to the user and allows
unpacking into arguments and can only exist as a temporary. You
cannot reference it directly, you cannot decltype() it (same as
with parameter packs) and you cannot spell its type. It is not a
different syntax for a comma-expression for which we don't need
anythign new. What we need is special treatment for "this function
returns multiple values and I can pass them as separate arguments
to call expressions". We already have a solution if it's not a
function result but parameters: parameter packs.</code><br>
<blockquote cite=3D"mid:56C59196.5020401@wanadoo.fr" type=3D"cite"><cod=
e
class=3D"prettyprint">
<div class=3D"subprettyprint"><code class=3D"prettyprint"> <br>
But </code><code class=3D"prettyprint"><code
class=3D"prettyprint">P0144R1 doesn't support it, neither
P0222R0.=C2=A0 </code><br>
</code></div>
</code></blockquote>
<code>Where is this P0222R0 and why is Google unable to find it? :(</co=
de><br>
<blockquote cite=3D"mid:56C59196.5020401@wanadoo.fr" type=3D"cite"><cod=
e
class=3D"prettyprint">
<div class=3D"subprettyprint"><code class=3D"prettyprint"> <br>
Or would the user need to pack it before?<br>
<br>
</code><code class=3D"prettyprint">auto {a, b, c} =3D
make_tuple(foo()); <br>
</code><br>
<br>
IMO a MRV, or whatever we call the result of a MRV function,
either <br>
* is always unpacked and needs some sort of pack function
(make-tuple) in some cases or <br>
* is packed and we needs some sort of unpack function. I will
not be against the use of an operator to unpack a MRV<br>
<br>
<code class=3D"prettyprint">
<div class=3D"subprettyprint">bar(*foo());</div>
</code></div>
</code></blockquote>
<code>My concept treats multiple return values as unpacked, since we
already have solutions for packed values: tuple and other classes.
MRVs can only be used to<br>
(1) be unpacked as parameters to a call expression<br>
(2) be a direct subexpression in a return statement<br>
(3) be unpacked in a fold expression<br>
(4) be captured into variables by the syntax in P0144<br>
<br>
I know (4) is redundant because of (1) but I feel like "auto {a,
b, c} =3D foo()" is simply too convenient to not have it supported
compared to "auto {a, b, c} =3D std::make_tuple(foo())" (which also
needs an include). With this basic functionality we can implement
everything else mentioned in this thread as a library extension
using make_tuple() and unpack(). But since unpack() doesn't depend
on implementation-defined magical compiler intrinsics anyone can
write their own special snowflake if they so desire.<br>
<br>
Unpacking may require the unpack operator to allow the difference
between outer(inner(unpack(x)...)) and outer(inner(unpack(x))...)
as mentioned earlier. That is a detail that needs to be discussed.<br=
>
</code>
<blockquote cite=3D"mid:56C59196.5020401@wanadoo.fr" type=3D"cite"><cod=
e
class=3D"prettyprint">
<div class=3D"subprettyprint"><code class=3D"prettyprint"> </code><=
br>
</div>
</code><br>
<br>
<blockquote
cite=3D"mid:6e35f24a-f728-4ac2-b329-1894206f59cc@isocpp.org"
type=3D"cite">
<div dir=3D"ltr">
<div>having this ability makes writing tuple unpacking trivial</d=
iv>
<div>
<div class=3D"prettyprint" style=3D"border: 1px solid rgb(187,
187, 187); word-wrap: break-word; background-color:
rgb(250, 250, 250);"><code class=3D"prettyprint">
<div class=3D"subprettyprint">
<div class=3D"subprettyprint"><font color=3D"#660066">aut=
o
tpl =3D make_tuple(1, 2.f, 3.0);</font></div>
<div class=3D"subprettyprint"><font color=3D"#660066">bar=
(unpack(tpl));</font></div>
<div class=3D"subprettyprint"><font color=3D"#660066">bar=
(unpack<2,
1, 0>(tpl));</font></div>
<div class=3D"subprettyprint"><font color=3D"#660066"><br=
>
</font></div>
<div class=3D"subprettyprint">
<div class=3D"subprettyprint">template<class...
Ts></div>
<div class=3D"subprettyprint">auto...
unpack(tuple<Ts...> x)</div>
<div class=3D"subprettyprint">{</div>
<div class=3D"subprettyprint"><span class=3D"Apple-tab-=
span" style=3D"white-space:pre"> </span>return
unpack_impl<0>(x,
index_sequence_for<Ts...>());</div>
<div class=3D"subprettyprint">}</div>
<div class=3D"subprettyprint">template<size_t...
Is, class... Ts></div>
<div class=3D"subprettyprint">auto...
unpack(tuple<Ts...> x)</div>
<div class=3D"subprettyprint">{</div>
<div class=3D"subprettyprint"><span class=3D"Apple-tab-=
span" style=3D"white-space:pre"> </span>return
unpack_impl<0>(x,
make_index_sequence<Is...>());</div>
<div class=3D"subprettyprint">}</div>
<div class=3D"subprettyprint">template<size_t From,
size_t To, class... Ts></div>
<div class=3D"subprettyprint">auto...
unpack_range(tuple<Ts...> x)</div>
<div class=3D"subprettyprint">{</div>
<div class=3D"subprettyprint"><span class=3D"Apple-tab-=
span" style=3D"white-space:pre"> </span>return
unpack_impl<From>(x,
make_index_sequence<To - From>);</div>
<div class=3D"subprettyprint">}</div>
<div class=3D"subprettyprint">template<size_t
Offset, class... Ts, size_t... Is></div>
<div class=3D"subprettyprint">auto...
unpack_impl(tuple<Ts...> x,
index_sequence<Is...>())</div>
<div class=3D"subprettyprint">{</div>
<div class=3D"subprettyprint"><span class=3D"Apple-tab-=
span" style=3D"white-space:pre"> </span>return
get<Is + Offset>(x)...;</div>
<div class=3D"subprettyprint">}</div>
</div>
</div>
</code></div>
(and yes, I did omit stuff like rvalue-refs, forward() etc.
as they are only distracting and I am sure everyone here can
fill in the details themselves)<br>
<br>
</div>
</div>
</blockquote>
Here you introduce something additional. auto... as a deduced MRV.
<br>
</blockquote>
<blockquote cite=3D"mid:56C59196.5020401@wanadoo.fr" type=3D"cite"> I
suspect to be inline with the way we return here=C2=A0 (there is no u=
se
of ',' to separate the arguments, the foo() function should return
as<br>
<br>
<code class=3D"prettyprint">=C2=A0=C2=A0=C2=A0 return 0 1.0 2.0;</cod=
e><br>
</blockquote>
Remember this is strawman syntax, but here goes anyway: "auto..." is
to tell the compiler that "return a, b, c;" (as is the result of a
parameter pack expansion) does not use the comma operator but
actually returns multiple values. If the compiler expects only a
single value then "return a, b, c;" only returns the result of
evaluating "c" (or whatever crazy person overloaded the comma
operator with). This is only needed in deduced return types and
"auto..." is arbitrarily chosen because it is currently ill-formed.
If you spell out all return types akin to something like "int, int,
int foo()" then "return a, b, c;" is unambiguous. Both are means to
not break existing code.<br>
<blockquote cite=3D"mid:56C59196.5020401@wanadoo.fr" type=3D"cite">
<blockquote
cite=3D"mid:6e35f24a-f728-4ac2-b329-1894206f59cc@isocpp.org"
type=3D"cite">
<div dir=3D"ltr">
<div>I feel like this opens up the doors to many more
possibilities than just the unpacking syntax alone as
discussed in this thread. The syntax may not be as terse,
but to me "unpack(x)" feels easier to understand and teach
than "[:]x". One might consider changing "unpack_range<a,
b>(x)" into "unpack<range<a, b>>(x)", making
"unpack" even more potent as a commonly understood tool (and
allows things like unpack<range<0, 2>, 4>(x)
getting the indices 0, 1, 4).</div>
<div><br>
</div>
<div>Other examples:</div>
<div>
<div class=3D"prettyprint" style=3D"border: 1px solid rgb(187,
187, 187); word-wrap: break-word; background-color:
rgb(250, 250, 250);"><code class=3D"prettyprint">
<div class=3D"subprettyprint">
<div class=3D"subprettyprint">template<class
Ts...></div>
<div class=3D"subprettyprint">auto tail(tpl<Ts...>
x)</div>
<div class=3D"subprettyprint">{</div>
<div class=3D"subprettyprint"><span class=3D"Apple-tab-sp=
an" style=3D"white-space:pre"> </span>return
make_tuple(unpack_range<1, sizeof...(Ts)>(x));</d=
iv>
<div class=3D"subprettyprint">}</div>
<div class=3D"subprettyprint">template<size_t Index,
class Ts...></div>
<div class=3D"subprettyprint">auto...
split(tpl<Ts...> x)</div>
<div class=3D"subprettyprint">{</div>
<div class=3D"subprettyprint"><span class=3D"Apple-tab-sp=
an" style=3D"white-space:pre"> </span>return
make_tuple(unpack<range<0, Index>>(x)),
make_tuple(unpack<range<Index,
sizeof...(Ts)>>(x));</div>
<div class=3D"subprettyprint">}</div>
</div>
</code></div>
<div>Given the proper handling of lvalue-refs, rvalue-refs,
reference_wrapper etc, this should also make the example
tail(ref(tpl1)) =3D tpl2 work.<br>
</div>
<div><br>
</div>
I know multiple return values come with their own set of
problems and since this thread isn't about multiple return
values I am not going to address them here. </div>
</div>
</blockquote>
Well, as there is not yet a proposal for MRV we need to consider
yours here, to see if is something that could be acceptable. What
I mean is that we can not compare two solutions to a specific
problem until we have concrete solutions and we can see the
advantages and liabilities for both solutions. Maybe you prefer to
start a new thread.<br>
</blockquote>
I haven't given the standard wording any thought yet so whether MRVs
are their own thing or parameter packs or whatever is entirely open
for debate (in a different thread if there is enough interest).
<blockquote cite=3D"mid:56C59196.5020401@wanadoo.fr" type=3D"cite">
<blockquote
cite=3D"mid:6e35f24a-f728-4ac2-b329-1894206f59cc@isocpp.org"
type=3D"cite">
<div dir=3D"ltr">
<div>I guess it comes down to which of the two is more general
purpose and/or has the lesser impact on the language. I just
felt like mentioning this and maybe get more support for
multiple return values if people are interested as the rest
emerges naturally from it and the topic of multiple return
values resurfaces regularly.</div>
</div>
<br>
</blockquote>
I'm not yet for or against any solution, we need concrete
proposals containing more details.<br>
<br>
Vicente<br>
-- <br>
<br>
--- <br>
You received this message because you are subscribed to the Google
Groups "ISO C++ Standard - Future Proposals" group.<br>
To unsubscribe from this group and stop receiving emails from it,
send an email to <a moz-do-not-send=3D"true"
href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposals+=
unsubscribe@isocpp.org</a>.<br>
To post to this group, send email to <a moz-do-not-send=3D"true"
href=3D"mailto:std-proposals@isocpp.org">std-proposals@isocpp.org</=
a>.<br>
Visit this group at <a moz-do-not-send=3D"true"
href=3D"https://groups.google.com/a/isocpp.org/group/std-proposals/=
">https://groups.google.com/a/isocpp.org/group/std-proposals/</a>.<br>
</blockquote>
<br>
</body>
</html>
<p></p>
-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
Visit this group at <a href=3D"https://groups.google.com/a/isocpp.org/group=
/std-proposals/">https://groups.google.com/a/isocpp.org/group/std-proposals=
/</a>.<br />
--------------040908020202070905000100--
.
Author: Matthew Woehlke <mwoehlke.floss@gmail.com>
Date: Thu, 18 Feb 2016 11:18:53 -0500
Raw View
On 2016-02-17 18:38, Miro Knejp wrote:
> Am 17.02.2016 um 23:22 schrieb Matthew Woehlke:
>> On 2016-02-17 16:30, Miro Knejp wrote:
>>> I somehow can't shed the feeling that what we really need here is
>>> support for multiple return values.
>>>=20
>>> having this ability makes writing tuple unpacking trivial:
>>>
>>> template<class... Ts> auto... unpack(tuple<Ts...> x);
>>
>> First off, you meant:
>>
>> template <typename T> auto... unpack(T);
>
> No, I didn't. The example I provided was for std::tuple explicitly to
> demonstrate how MRVs come into the picture. People can obviously
> customize unpack() in addition to get<>() using ADL as necessary.
Does assignment unpacking use std::unpack, then? If so, then you've just
changed the customization point. (If not, I object to requiring
different customization points for such similar operations.)
That said, I'm not convinced that std::get isn't the superior
customization point. (Keep in mind I also objected to having to
specialize std::tuple_size, always.)
>> TBH, as much as I argued this previously, I have to say that at this
>> point I'm inclined to see U2PP=C2=B9, and possibly P0222, as the best
>> solution to MRV's.
>
> (do you have a link to P0222? I couldn't find anything with that number)
It hasn't been published yet AFAICT, but should be in the Feb 2016
mailing whenever that does get published.
Meanwhile:
https://github.com/mwoehlke/cpp-proposals/blob/master/p0222r0-anonymous-str=
uct-return.rst
(be aware that github strips the markup for standardese edits; check the
raw reST for these, though in this case the edit may be obvious).
> In my head MRVs are a transient construct only existent as the type of a
> call expression. If you need to capture it assign the values to
> varaiables (like in P0144R1) or forward as parameters to another call
> expression (like make_tuple). Under this assumption, that MRVs are their
> own kind of entity, folding becomes possible as (0 + ... + foo()) if
> their special nature is considered. Therefore folding a tuple becomes (0
> + ... + unpack(tpl)).
So... basically, an MRV *is* a parameter pack? In that case, I don't see
much difference between "true MRV's" and U2PP.
>>> Given the proper handling of lvalue-refs, rvalue-refs, reference_wrappe=
r
>>> etc, this should also make the example tail(ref(tpl1)) =3D tpl2 work.
>>
>> How would this be different from / better than:
>>
>> std::tie([1:]tpl1...) =3D tpl2;
>>
>> ...?
>
> It uses words that actually describe what it does.
>=20
> Without MRVs you cannot hide "[1:]tpl1..." effortlessly behind a named
> function.
You can't?
auto tail(auto tuple) { return make_tuple([1:]tuple...); }
(Simplified for illustrative purposes; usual caveats about proper
reference handling, forwarding, etc.)
> *Every single time* someone needs to unpack the tail of a
> tuple they have to write out the same sequence of punctuation. DRY
> anyone?
That's like saying "every time someone needs to add two numbers they
have to write '+'". Yes, every time you do something you have to write
something. DRY is when you are writing the same *non-trivial* code
repeatedly. Seven characters (`[1:]...`) is not non-trivial, especially
as your example uses a minimum of six (`tail()`, assuming that you are
`using namespace std;`, which not everyone wants to do!).
> Even languages with this kind of syntax come shipped with
> utility functions like tail() because they're more descriptive.
I could argue that. If I'm not familiar with it, I need to check the
documentation to know if 'tail' means `[1:]` or `[-1]`, because it could
mean either one. With U2PP slicing, there is no such ambiguity. (And
anyway, as shown above, there is nothing stopping us having a
`std::tail()` with U2PP.)
> In order to hide it inside a function you have to return a tuple
> (maybe containing references) and then use the awkward inversion of
> "apply(f, something(x))" when using the result.
Ah... no? Why? Huh?
U2PP makes std::apply superfluous.
> Compare that to "f(something(x))" and tell me which one you'd prefer
> to write and read.
I'm not thrilled that I can't tell there that `something(x)` is a
parameter pack. In that sense, I prefer the clarity of
`f([:]something(x)...)`. (Note that this is also how e.g. Python works.
Despite often being used as the poster child for MRV's, Python actually
has no such thing... just lots of syntax sugar a la P0144 and U2PP that
makes it seem as if it does.)
Oh! Here's a fun point... if we *did* have true MRV's, how long until
people start writing unary operator* as a synonym for unpack? Would that
be a good thing?
--=20
Matthew
--=20
---=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-propos=
als/.
.
Author: Matthew Woehlke <mwoehlke.floss@gmail.com>
Date: Thu, 18 Feb 2016 11:28:19 -0500
Raw View
On 2016-02-18 11:18, Matthew Woehlke wrote:
> On 2016-02-17 18:38, Miro Knejp wrote:
>> (do you have a link to P0222? I couldn't find anything with that number)
>
> It hasn't been published yet AFAICT, but should be in the Feb 2016
> mailing whenever that does get published.
My bad: http://wg21.link/p0222 (I think this went live within the last
24 hours...)
--
Matthew
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-proposals/.
.
Author: Matthew Woehlke <mwoehlke.floss@gmail.com>
Date: Thu, 18 Feb 2016 11:54:39 -0500
Raw View
On 2016-02-18 04:40, Vicente J. Botet Escriba wrote:
> If foo() in the context of bar(foo()) is expanded to bar(a1,a2,a3) for
> some a1,a2,a3
>
> it should also be expanded in the context of
> |
> auto {a, b, c} = foo();
>
> and so we will need that
>
> |auto {a, b, c} = a1, a2, a3;
>
> But |||P0144R1 doesn't support it, neither P0222R0. |
If `foo()` returns a parameter pack (which I think Miro and I agree that
it should), then what we need is:
// 'pack' is any expression which expands to a parameter pack
auto {a, b, c} = {pack...};
auto {a, b, c} = pack; // same as previous line
I would like to see this enhancement regardless; it's almost necessary
if we gain "true MRV's" (TMRV's), and it's an obvious and significant
improvement if we gain sliced U2PP. It's also potentially useful with
neither, in variadic templates. (Unfortunately, P0144R1 doesn't support
either. There is a weak argument against the first given in P0144R1. I
think if we gain either TMRV's (and/)or U2PP, there would be a much
stronger motivation to support braced lists (and parameter packs) in
assignment unpacking.
@Miro, I don't think anything needs to be considered now; if TMRV's are
parameter packs, then there should be no problem adding special handling
of parameter packs to assignment unpacking at some later time. (Worst
case, you'd need to add {}'s, and we're in the braced list special case.)
(I don't think P0222 is relevant here ;-).)
> I suspect to be inline with the way we return here (there is no use of
> ',' to separate the arguments, the foo() function should return as
>
> | return 0 1.0 2.0;|
char*, char* foo() { return "houston" "we" "have" "a" "problem"; }
We need commas :-). (Anyway, not a fruitful discussion, as Miro notes.)
--
Matthew
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-proposals/.
.
Author: inkwizytoryankes@gmail.com
Date: Thu, 18 Feb 2016 08:55:01 -0800 (PST)
Raw View
------=_Part_1371_434979499.1455814501822
Content-Type: multipart/alternative;
boundary="----=_Part_1372_1041153098.1455814501822"
------=_Part_1372_1041153098.1455814501822
Content-Type: text/plain; charset=UTF-8
On Wednesday, February 17, 2016 at 7:07:05 PM UTC+1, Matthew Woehlke wrote:
>
> On 2016-02-17 04:40, Sam Kellett wrote:
> > my personal opinion is that hana's is much much much more obvious
> > (the lambda version of the example specifically), in no short reason
> > because it's interface is based on the existing standard library. why
> > do we need two syntax's in one language when we can do it all with
> > one?
>
> ...because parameter packs "don't exist" in a sense. Accordingly, it is
> *necessary* that there exists a language syntax to instruct the compiler
> how to turn them into real code.
>
> As I stated elsewhere, a lot of the ranting and railing I see here is
> directed not at unpacking, but at *fold expressions*. That's borderline
> off topic, and I'm not necessarily opposed to improving fold
> expressions. (Though I also agree with Nicol that fold expressions are
> at least as understandable, and in some cases more so, than hana.)
>
> The point about familiarity here is apt. The hana syntax is obtuse to
> anyone not familiar with it. Fold expressions... do have their own
> problems, but IMHO are easier to grasp for someone who is a total novice
> with both.
>
> > also yours appears to be inherently ungoogle-able. assuming i don't
> > understand either syntax, for louis' i type into google 'c++
> hana::unpack',
> > what do i type to find the reference pages for yours?
>
> https://www.google.com/search?q=c%2B%2B+fold+expressions
>
> --
> Matthew
>
> When you only have symbols "[:]" and "..."? Try use google on that.
When you know name then you know it and don't need google it to get info
what it is.
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-proposals/.
------=_Part_1372_1041153098.1455814501822
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><br><br>On Wednesday, February 17, 2016 at 7:07:05 PM UTC+=
1, Matthew Woehlke wrote:<blockquote class=3D"gmail_quote" style=3D"margin:=
0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">On 20=
16-02-17 04:40, Sam Kellett wrote:
<br>> my personal opinion is that hana's is much much much more obvi=
ous
<br>> (the lambda version of the example specifically), in no short reas=
on
<br>> because it's interface is based on the existing standard libra=
ry. why
<br>> do we need two syntax's in one language when we can do it all =
with
<br>> one?
<br>
<br>...because parameter packs "don't exist" in a sense. Acco=
rdingly, it is
<br>*necessary* that there exists a language syntax to instruct the compile=
r
<br>how to turn them into real code.
<br>
<br>As I stated elsewhere, a lot of the ranting and railing I see here is
<br>directed not at unpacking, but at *fold expressions*. That's border=
line
<br>off topic, and I'm not necessarily opposed to improving fold
<br>expressions. (Though I also agree with Nicol that fold expressions are
<br>at least as understandable, and in some cases more so, than hana.)
<br>
<br>The point about familiarity here is apt. The hana syntax is obtuse to
<br>anyone not familiar with it. Fold expressions... do have their own
<br>problems, but IMHO are easier to grasp for someone who is a total novic=
e
<br>with both.
<br>
<br>> also yours appears to be inherently ungoogle-able. assuming i don&=
#39;t
<br>> understand either syntax, for louis' i type into google 'c=
++ hana::unpack',
<br>> what do i type to find the reference pages for yours?
<br>
<br><a href=3D"https://www.google.com/search?q=3Dc%2B%2B+fold+expressions" =
target=3D"_blank" rel=3D"nofollow" onmousedown=3D"this.href=3D'https://=
www.google.com/search?q\75c%2B%2B+fold+expressions';return true;" oncli=
ck=3D"this.href=3D'https://www.google.com/search?q\75c%2B%2B+fold+expre=
ssions';return true;">https://www.google.com/search?<wbr>q=3Dc%2B%2B+fo=
ld+expressions</a>
<br>
<br>--=20
<br>Matthew
<br>
<br></blockquote><div>When you only have symbols "[:]" and "=
...."? Try use google on that.<br>When you know name then you know it a=
nd don't need google it to get info what it is.<br></div></div>
<p></p>
-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
Visit this group at <a href=3D"https://groups.google.com/a/isocpp.org/group=
/std-proposals/">https://groups.google.com/a/isocpp.org/group/std-proposals=
/</a>.<br />
------=_Part_1372_1041153098.1455814501822--
------=_Part_1371_434979499.1455814501822--
.
Author: Matthew Woehlke <mwoehlke.floss@gmail.com>
Date: Thu, 18 Feb 2016 12:03:06 -0500
Raw View
On 2016-02-18 10:39, Miro Knejp wrote:
> There's also a proposal in SG14 to synthesize get<>() for public
> fields, making any old struct compatible with P0144.
Are you talking about http://wg21.link/p0197? Or is there another
proposal we missed?
> Where is this P0222R0 and why is Google unable to find it? :(
It's probably too new for Google to have indexed it yet. (And apparently
I didn't use the document number in any of the threads here to be able
to find those via the number. Sorry... When in doubt, try wg21.link, but
it's possible that only started working since your last message.)
> But since unpack() doesn't depend on implementation-defined magical
> compiler intrinsics anyone can write their own special snowflake if they
> so desire.
Tuple-like via get<> doesn't depend on magical compiler intrinsics any
more or less than TMRV's + unpack(). In both cases, you either provide
your own, or rely on a compiler provided version of either `get<N>` or
`unpack`.
> Unpacking may require the unpack operator to allow the difference
> between outer(inner(unpack(x)...)) and outer(inner(unpack(x))...) as
> mentioned earlier. That is a detail that needs to be discussed.
IMO it should... Above point notwithstanding, I think it would be just
too confusing if TMRV's are... parameter packs with an exception. (Plus
I still tend to think that there should be some indication that you have
multiple values.)
--
Matthew
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-proposals/.
.
Author: "Vicente J. Botet Escriba" <vicente.botet@wanadoo.fr>
Date: Thu, 18 Feb 2016 18:06:10 +0100
Raw View
This is a multi-part message in MIME format.
--------------050807080102050607060808
Content-Type: text/plain; charset=UTF-8; format=flowed
Content-Transfer-Encoding: quoted-printable
Le 18/02/2016 16:39, Miro Knejp a =C3=A9crit :
>
>
> Am 18.02.2016 um 10:40 schrieb Vicente J. Botet Escriba:
>> Le 17/02/2016 22:30, Miro Knejp a =C3=A9crit :
>>> I somehow can't shed the feeling that what we really need here is=20
>>> support for multiple return values.
>>>
>> I don't know if mandatory for the subject on this thread, but yes, I=20
>> believe we need MRV, but I don't know exactly what this would mean yet.
>>> Just imagine for a moment that the following is valid:
>>> |
>>> int, float, double foo();
>>> void bar(int, float, double);
>>> bar(foo());
>>> auto {a, b, c} =3D foo(); // borrowed from P0144R1
>>> |
>>>
>> Could you show how would you define foo() to return MRV?
>> return 0, 1.0, 2.0;
>>
>> or
>>
>> | return 0 1.0 2.0;
>> |
>> Or?
> There are examples further down in my post. Besides any syntax=20
> presented here is just a strawman so don't get lost in the details too=20
> much.
As you describe below, these details are important.
>>
>> IIUC, the single things you can do with a MRV is to use it in a call=20
>> expression and in this case each one of the values is associated to=20
>> an argument, and
>> structure binding. However structure binding is associated to a=20
>> tuple-like interface. Does it means that a MRV thing would have a=20
>> tuple-like access interface (get<I>(mrv))?
> No. If you want to return multiple values in something with a=20
> tupe-like interface, well then use tuple and P0144 binding. There's=20
> also a proposal in SG14 to synthesize get<>() for public fields,=20
> making any old struct compatible with P0144.=20
Could you give me a reference, because I'm the author of P0197 - Default=20
tuple-like access and I'm really concerned ?
> It is important to keep the multiple return values separate in a=20
> special entity to allow for the compiler magic that unpacks it=20
> effortlessly into a list of parameters.
>> If foo() in the context of bar(foo()) is expanded to bar(a1,a2,a3)=20
>> for some a1,a2,a3
>>
>> it should also be expanded in the context of
>> |
>> auto {a, b, c} =3D foo();
>>
>> and so we will need that
>>
>> |auto {a, b, c} =3D a1, a2, a3;
>> |
>> |
> |No, since "a1, a2, a3" is a comma-expression and the binding only=20
> applies to the result of the expression "a3". If P0144 doesn't=20
> consider this special case then it will become impossible to add it=20
> later. |
P0144 can not take in account the MRV you are describing here ;-)
You your proposal, if you write one, should describe how this could=20
work. IN the absence, I believe that the user would need
||||
auto {a, b, c} =3D make_tuple(foo()); ||
> |Functions returning multiple values return a special kind of entity=20
> that is transparent to the user and allows unpacking into arguments=20
> and can only exist as a temporary. You cannot reference it directly,=20
> you cannot decltype() it (same as with parameter packs) and you cannot=20
> spell its type. It is not a different syntax for a comma-expression=20
> for which we don't need anythign new. What we need is special=20
> treatment for "this function returns multiple values and I can pass=20
> them as separate arguments to call expressions". We already have a=20
> solution if it's not a function result but parameters: parameter packs.|
|We need however to know how to return them.|
>> |
>> |
>> But |||P0144R1 doesn't support it, neither P0222R0. |
>> |
>> |
> |Where is this P0222R0 and why is Google unable to find it? :(|
|Really sorry it was P0217=20
https://isocpp.org/blog/2016/02/p0144r1-and-p0217r0|
>> |
>> |
>> Or would the user need to pack it before?
>>
>> ||auto {a, b, c} =3D make_tuple(foo());
>> |
>>
>> IMO a MRV, or whatever we call the result of a MRV function, either
>> * is always unpacked and needs some sort of pack function=20
>> (make-tuple) in some cases or
>> * is packed and we needs some sort of unpack function. I will not be=20
>> against the use of an operator to unpack a MRV
>>
>> |
>> bar(*foo());
>> |
>> |
> |My concept treats multiple return values as unpacked, since we=20
> already have solutions for packed values: tuple and other classes.=20
> MRVs can only be used to
> (1) be unpacked as parameters to a call expression
> (2) be a direct subexpression in a return statement
> (3) be unpacked in a fold expression
> (4) be captured into variables by the syntax in P0144
>
> |
|I'm missing how to build one from N values, bu I see that you describe=20
it below.|
> |I know (4) is redundant because of (1) but I feel like "auto {a, b,=20
> c} =3D foo()" is simply too convenient to not have it supported compared=
=20
> to "auto {a, b, c} =3D std::make_tuple(foo())" (which also needs an=20
> include).|
|I will no|t say redundant. If MRV don't provide a syntax to retrieve=20
the multiple returned values, I would say that there is something missing.
> |With this basic functionality we can implement everything else=20
> mentioned in this thread as a library extension using make_tuple() and=20
> unpack(). But since unpack() doesn't depend on implementation-defined=20
> magical compiler intrinsics anyone can write their own special=20
> snowflake if they so desire.
>
> Unpacking may require the unpack operator to allow the difference=20
> between outer(inner(unpack(x)...)) and outer(inner(unpack(x))...) as=20
> mentioned earlier. That is a detail that needs to be discussed.
> |
>> |
>> ||
>> |
>>
>>> having this ability makes writing tuple unpacking trivial
>>> |
>>> auto tpl =3D make_tuple(1, 2.f, 3.0);
>>> bar(unpack(tpl));
>>> bar(unpack<2, 1, 0>(tpl));
>>>
>>> template<class... Ts>
>>> auto... unpack(tuple<Ts...> x)
>>> {
>>> return unpack_impl<0>(x, index_sequence_for<Ts...>());
>>> }
>>> template<size_t... Is, class... Ts>
>>> auto... unpack(tuple<Ts...> x)
>>> {
>>> return unpack_impl<0>(x, make_index_sequence<Is...>());
>>> }
>>> template<size_t From, size_t To, class... Ts>
>>> auto... unpack_range(tuple<Ts...> x)
>>> {
>>> return unpack_impl<From>(x, make_index_sequence<To - From>);
>>> }
>>> template<size_t Offset, class... Ts, size_t... Is>
>>> auto... unpack_impl(tuple<Ts...> x, index_sequence<Is...>())
>>> {
>>> return get<Is + Offset>(x)...;
>>> }
>>> |
>>> (and yes, I did omit stuff like rvalue-refs, forward() etc. as they=20
>>> are only distracting and I am sure everyone here can fill in the=20
>>> details themselves)
>>>
>> Here you introduce something additional. auto... as a deduced MRV.
>> I suspect to be inline with the way we return here (there is no use=20
>> of ',' to separate the arguments, the foo() function should return as
>>
>> | return 0 1.0 2.0;|
> Remember this is strawman syntax, but here goes anyway: "auto..." is=20
> to tell the compiler that "return a, b, c;" (as is the result of a=20
> parameter pack expansion) does not use the comma operator but actually=20
> returns multiple values. If the compiler expects only a single value=20
> then "return a, b, c;" only returns the result of evaluating "c" (or=20
> whatever crazy person overloaded the comma operator with). This is=20
> only needed in deduced return types and "auto..." is arbitrarily=20
> chosen because it is currently ill-formed. If you spell out all return=20
> types akin to something like "int, int, int foo()" then "return a, b,=20
> c;" is unambiguous. Both are means to not break existing code.
I believe that this will be conflicting.
>>>
>>>
>>> I know multiple return values come with their own set of problems=20
>>> and since this thread isn't about multiple return values I am not=20
>>> going to address them here.
>> Well, as there is not yet a proposal for MRV we need to consider=20
>> yours here, to see if is something that could be acceptable. What I=20
>> mean is that we can not compare two solutions to a specific problem=20
>> until we have concrete solutions and we can see the advantages and=20
>> liabilities for both solutions. Maybe you prefer to start a new thread.
> I haven't given the standard wording any thought yet so whether MRVs=20
> are their own thing or parameter packs or whatever is entirely open=20
> for debate (in a different thread if there is enough interest).=20
I'm not talking yet of wording, but of how to use the feature.
Vicente
--=20
---=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-propos=
als/.
--------------050807080102050607060808
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<html>
<head>
<meta content=3D"text/html; charset=3Dutf-8" http-equiv=3D"Content-Type=
">
</head>
<body bgcolor=3D"#FFFFFF" text=3D"#000000">
<div class=3D"moz-cite-prefix">Le 18/02/2016 16:39, Miro Knejp a
=C3=A9crit=C2=A0:<br>
</div>
<blockquote cite=3D"mid:56C5E59C.6040007@gmail.com" type=3D"cite">
<meta content=3D"text/html; charset=3Dutf-8" http-equiv=3D"Content-Ty=
pe">
<br>
<br>
<div class=3D"moz-cite-prefix">Am 18.02.2016 um 10:40 schrieb
Vicente J. Botet Escriba:<br>
</div>
<blockquote cite=3D"mid:56C59196.5020401@wanadoo.fr" type=3D"cite">
<meta content=3D"text/html; charset=3Dutf-8"
http-equiv=3D"Content-Type">
<div class=3D"moz-cite-prefix">Le 17/02/2016 22:30, Miro Knejp a
=C3=A9crit=C2=A0:<br>
</div>
<blockquote
cite=3D"mid:6e35f24a-f728-4ac2-b329-1894206f59cc@isocpp.org"
type=3D"cite">
<div dir=3D"ltr">I somehow can't shed the feeling that what we
really need here is support for multiple return values.
<div><br>
</div>
</div>
</blockquote>
I don't know if mandatory for the subject on this thread, but
yes, I believe we need MRV, but I don't know exactly what this
would mean yet.<br>
<blockquote
cite=3D"mid:6e35f24a-f728-4ac2-b329-1894206f59cc@isocpp.org"
type=3D"cite">
<div dir=3D"ltr">
<div>Just imagine for a moment that the following is valid:</di=
v>
<div>
<div class=3D"prettyprint" style=3D"border: 1px solid rgb(187=
,
187, 187); word-wrap: break-word; background-color:
rgb(250, 250, 250);"><code class=3D"prettyprint">
<div class=3D"subprettyprint">
<div class=3D"subprettyprint">int, float, double
foo();</div>
<div class=3D"subprettyprint">void bar(int, float,
double);</div>
<div class=3D"subprettyprint">bar(foo());</div>
<div class=3D"subprettyprint">auto {a, b, c} =3D foo();
// borrowed from P0144R1</div>
</div>
</code></div>
<br>
</div>
</div>
</blockquote>
Could you show how would you define foo() to return MRV?<br>
=C2=A0=C2=A0=C2=A0 return 0, 1.0, 2.0;<br>
<br>
or <br>
<br>
<code class=3D"prettyprint">=C2=A0=C2=A0=C2=A0 return 0 1.0 2.0;<br=
>
</code><br>
Or?<br>
</blockquote>
There are examples further down in my post. Besides any syntax
presented here is just a strawman so don't get lost in the details
too much.<br>
</blockquote>
<br>
As you describe below, these details are important.<br>
<blockquote cite=3D"mid:56C5E59C.6040007@gmail.com" type=3D"cite">
<blockquote cite=3D"mid:56C59196.5020401@wanadoo.fr" type=3D"cite"> <=
br>
IIUC, the single things you can do with a MRV is to use it in a
call expression and in this case each one of the values is
associated to an argument, and<br>
structure binding. However structure binding is associated to a
tuple-like interface. Does it means that a MRV thing would have
a tuple-like access interface (get<I>(mrv))?<br>
</blockquote>
No. If you want to return multiple values in something with a
tupe-like interface, well then use tuple and P0144 binding.
There's also a proposal in SG14 to synthesize get<>() for
public fields, making any old struct compatible with P0144. </blockqu=
ote>
Could you give me a reference, because I'm the author of P0197 -
Default tuple-like access and I'm really concerned ?<br>
<blockquote cite=3D"mid:56C5E59C.6040007@gmail.com" type=3D"cite">It is
important to keep the multiple return values separate in a special
entity to allow for the compiler magic that unpacks it
effortlessly into a list of parameters.
<blockquote cite=3D"mid:56C59196.5020401@wanadoo.fr" type=3D"cite">If
foo() in the context of bar(foo()) is expanded to bar(a1,a2,a3)
for some a1,a2,a3 <br>
<br>
it should also be expanded in the context of<br>
<code class=3D"prettyprint">
<div class=3D"subprettyprint">auto {a, b, c} =3D foo(); <br>
<br>
and so we will need that<br>
<br>
<code class=3D"prettyprint">auto {a, b, c} =3D a1, a2, a3; <br>
</code></div>
</code></blockquote>
<code>No, since "a1, a2, a3" is a comma-expression and the binding
only applies to the result of the expression "a3". If P0144
doesn't consider this special case then it will become
impossible to add it later. </code></blockquote>
P0144 can not take in account the MRV you are describing here ;-)<br>
You your proposal, if you write one, should describe how this could
work. IN the absence, I believe that the user would need<br>
<code class=3D"prettyprint"><code class=3D"prettyprint"></code><code
class=3D"prettyprint"><br>
auto {a, b, c} =3D make_tuple(foo()); </code></code><br>
<blockquote cite=3D"mid:56C5E59C.6040007@gmail.com" type=3D"cite"><code=
>Functions
returning multiple values return a special kind of entity that
is transparent to the user and allows unpacking into arguments
and can only exist as a temporary. You cannot reference it
directly, you cannot decltype() it (same as with parameter
packs) and you cannot spell its type. It is not a different
syntax for a comma-expression for which we don't need anythign
new. What we need is special treatment for "this function
returns multiple values and I can pass them as separate
arguments to call expressions". We already have a solution if
it's not a function result but parameters: parameter packs.</code><=
br>
</blockquote>
<code>We need however to know how to return them.</code><br>
<blockquote cite=3D"mid:56C5E59C.6040007@gmail.com" type=3D"cite">
<blockquote cite=3D"mid:56C59196.5020401@wanadoo.fr" type=3D"cite"><c=
ode
class=3D"prettyprint">
<div class=3D"subprettyprint"><code class=3D"prettyprint"> <br>
But </code><code class=3D"prettyprint"><code
class=3D"prettyprint">P0144R1 doesn't support it, neither
P0222R0.=C2=A0 </code><br>
</code></div>
</code></blockquote>
<code>Where is this P0222R0 and why is Google unable to find it?
:(</code><br>
</blockquote>
<code>Really sorry it was P0217
<a class=3D"moz-txt-link-freetext" href=3D"https://isocpp.org/blog/20=
16/02/p0144r1-and-p0217r0">https://isocpp.org/blog/2016/02/p0144r1-and-p021=
7r0</a></code><br>
<blockquote cite=3D"mid:56C5E59C.6040007@gmail.com" type=3D"cite">
<blockquote cite=3D"mid:56C59196.5020401@wanadoo.fr" type=3D"cite"><c=
ode
class=3D"prettyprint">
<div class=3D"subprettyprint"><code class=3D"prettyprint"> <br>
Or would the user need to pack it before?<br>
<br>
</code><code class=3D"prettyprint">auto {a, b, c} =3D
make_tuple(foo()); <br>
</code><br>
<br>
IMO a MRV, or whatever we call the result of a MRV function,
either <br>
* is always unpacked and needs some sort of pack function
(make-tuple) in some cases or <br>
* is packed and we needs some sort of unpack function. I
will not be against the use of an operator to unpack a MRV<br>
<br>
<code class=3D"prettyprint">
<div class=3D"subprettyprint">bar(*foo());</div>
</code></div>
</code></blockquote>
<code>My concept treats multiple return values as unpacked, since
we already have solutions for packed values: tuple and other
classes. MRVs can only be used to<br>
(1) be unpacked as parameters to a call expression<br>
(2) be a direct subexpression in a return statement<br>
(3) be unpacked in a fold expression<br>
(4) be captured into variables by the syntax in P0144<br>
<br>
</code></blockquote>
<code>I'm missing how to build one from N values, bu I see that you
describe it below.</code><br>
<blockquote cite=3D"mid:56C5E59C.6040007@gmail.com" type=3D"cite"><code=
>
I know (4) is redundant because of (1) but I feel like "auto {a,
b, c} =3D foo()" is simply too convenient to not have it supported
compared to "auto {a, b, c} =3D std::make_tuple(foo())" (which
also needs an include).</code></blockquote>
<code>I will no</code>t say redundant. If MRV don't provide a syntax
to retrieve the multiple returned values, I would say that there is
something missing.<br>
<blockquote cite=3D"mid:56C5E59C.6040007@gmail.com" type=3D"cite"><code=
>
With this basic functionality we can implement everything else
mentioned in this thread as a library extension using
make_tuple() and unpack(). But since unpack() doesn't depend on
implementation-defined magical compiler intrinsics anyone can
write their own special snowflake if they so desire.<br>
<br>
Unpacking may require the unpack operator to allow the
difference between outer(inner(unpack(x)...)) and
outer(inner(unpack(x))...) as mentioned earlier. That is a
detail that needs to be discussed.<br>
</code>
<blockquote cite=3D"mid:56C59196.5020401@wanadoo.fr" type=3D"cite"><c=
ode
class=3D"prettyprint">
<div class=3D"subprettyprint"><code class=3D"prettyprint"> </code=
><br>
</div>
</code><br>
<br>
<blockquote
cite=3D"mid:6e35f24a-f728-4ac2-b329-1894206f59cc@isocpp.org"
type=3D"cite">
<div dir=3D"ltr">
<div>having this ability makes writing tuple unpacking
trivial</div>
<div>
<div class=3D"prettyprint" style=3D"border: 1px solid rgb(187=
,
187, 187); word-wrap: break-word; background-color:
rgb(250, 250, 250);"><code class=3D"prettyprint">
<div class=3D"subprettyprint">
<div class=3D"subprettyprint"><font color=3D"#660066">a=
uto
tpl =3D make_tuple(1, 2.f, 3.0);</font></div>
<div class=3D"subprettyprint"><font color=3D"#660066">b=
ar(unpack(tpl));</font></div>
<div class=3D"subprettyprint"><font color=3D"#660066">b=
ar(unpack<2,
1, 0>(tpl));</font></div>
<div class=3D"subprettyprint"><font color=3D"#660066"><=
br>
</font></div>
<div class=3D"subprettyprint">
<div class=3D"subprettyprint">template<class...
Ts></div>
<div class=3D"subprettyprint">auto...
unpack(tuple<Ts...> x)</div>
<div class=3D"subprettyprint">{</div>
<div class=3D"subprettyprint"><span class=3D"Apple-ta=
b-span" style=3D"white-space:pre"> </span>return
unpack_impl<0>(x,
index_sequence_for<Ts...>());</div>
<div class=3D"subprettyprint">}</div>
<div class=3D"subprettyprint">template<size_t...
Is, class... Ts></div>
<div class=3D"subprettyprint">auto...
unpack(tuple<Ts...> x)</div>
<div class=3D"subprettyprint">{</div>
<div class=3D"subprettyprint"><span class=3D"Apple-ta=
b-span" style=3D"white-space:pre"> </span>return
unpack_impl<0>(x,
make_index_sequence<Is...>());</div>
<div class=3D"subprettyprint">}</div>
<div class=3D"subprettyprint">template<size_t
From, size_t To, class... Ts></div>
<div class=3D"subprettyprint">auto...
unpack_range(tuple<Ts...> x)</div>
<div class=3D"subprettyprint">{</div>
<div class=3D"subprettyprint"><span class=3D"Apple-ta=
b-span" style=3D"white-space:pre"> </span>return
unpack_impl<From>(x,
make_index_sequence<To - From>);</div>
<div class=3D"subprettyprint">}</div>
<div class=3D"subprettyprint">template<size_t
Offset, class... Ts, size_t... Is></div>
<div class=3D"subprettyprint">auto...
unpack_impl(tuple<Ts...> x,
index_sequence<Is...>())</div>
<div class=3D"subprettyprint">{</div>
<div class=3D"subprettyprint"><span class=3D"Apple-ta=
b-span" style=3D"white-space:pre"> </span>return
get<Is + Offset>(x)...;</div>
<div class=3D"subprettyprint">}</div>
</div>
</div>
</code></div>
(and yes, I did omit stuff like rvalue-refs, forward()
etc. as they are only distracting and I am sure everyone
here can fill in the details themselves)<br>
<br>
</div>
</div>
</blockquote>
Here you introduce something additional. auto... as a deduced
MRV. <br>
</blockquote>
<blockquote cite=3D"mid:56C59196.5020401@wanadoo.fr" type=3D"cite"> I
suspect to be inline with the way we return here=C2=A0 (there is no
use of ',' to separate the arguments, the foo() function should
return as<br>
<br>
<code class=3D"prettyprint">=C2=A0=C2=A0=C2=A0 return 0 1.0 2.0;</c=
ode><br>
</blockquote>
Remember this is strawman syntax, but here goes anyway: "auto..."
is to tell the compiler that "return a, b, c;" (as is the result
of a parameter pack expansion) does not use the comma operator but
actually returns multiple values. If the compiler expects only a
single value then "return a, b, c;" only returns the result of
evaluating "c" (or whatever crazy person overloaded the comma
operator with). This is only needed in deduced return types and
"auto..." is arbitrarily chosen because it is currently
ill-formed. If you spell out all return types akin to something
like "int, int, int foo()" then "return a, b, c;" is unambiguous.
Both are means to not break existing code.<br>
</blockquote>
I believe that this will be conflicting.<br>
<blockquote cite=3D"mid:56C5E59C.6040007@gmail.com" type=3D"cite">
<blockquote cite=3D"mid:56C59196.5020401@wanadoo.fr" type=3D"cite">
<blockquote
cite=3D"mid:6e35f24a-f728-4ac2-b329-1894206f59cc@isocpp.org"
type=3D"cite">
<div dir=3D"ltr">
<div><br>
<div><br>
</div>
I know multiple return values come with their own set of
problems and since this thread isn't about multiple return
values I am not going to address them here. </div>
</div>
</blockquote>
Well, as there is not yet a proposal for MRV we need to consider
yours here, to see if is something that could be acceptable.
What I mean is that we can not compare two solutions to a
specific problem until we have concrete solutions and we can see
the advantages and liabilities for both solutions. Maybe you
prefer to start a new thread.<br>
</blockquote>
I haven't given the standard wording any thought yet so whether
MRVs are their own thing or parameter packs or whatever is
entirely open for debate (in a different thread if there is enough
interest). </blockquote>
I'm not talking yet of wording, but of how to use the feature.<br>
<br>
Vicente<br>
<br>
</body>
</html>
<p></p>
-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
Visit this group at <a href=3D"https://groups.google.com/a/isocpp.org/group=
/std-proposals/">https://groups.google.com/a/isocpp.org/group/std-proposals=
/</a>.<br />
--------------050807080102050607060808--
.
Author: Miro Knejp <miro.knejp@gmail.com>
Date: Thu, 18 Feb 2016 18:46:21 +0100
Raw View
Am 18.02.2016 um 17:18 schrieb Matthew Woehlke:
> On 2016-02-17 18:38, Miro Knejp wrote:
>> Am 17.02.2016 um 23:22 schrieb Matthew Woehlke:
>>> On 2016-02-17 16:30, Miro Knejp wrote:
>>>> I somehow can't shed the feeling that what we really need here is
>>>> support for multiple return values.
>>>>
>>>> having this ability makes writing tuple unpacking trivial:
>>>>
>>>> template<class... Ts> auto... unpack(tuple<Ts...> x);
>>> First off, you meant:
>>>
>>> template <typename T> auto... unpack(T);
>> No, I didn't. The example I provided was for std::tuple explicitly to
>> demonstrate how MRVs come into the picture. People can obviously
>> customize unpack() in addition to get<>() using ADL as necessary.
> Does assignment unpacking use std::unpack, then? If so, then you've just
> changed the customization point. (If not, I object to requiring
> different customization points for such similar operations.)
>
> That said, I'm not convinced that std::get isn't the superior
> customization point. (Keep in mind I also objected to having to
> specialize std::tuple_size, always.)
If `get()` is the superior customization point you obviously don't need=20
to customize `unpack()`. However that is a library issue and there is no=20
point in arguing over the library interface while the necessary language=20
feature is still undecided.
>
>>> TBH, as much as I argued this previously, I have to say that at this
>>> point I'm inclined to see U2PP=C2=B9, and possibly P0222, as the best
>>> solution to MRV's.
>> (do you have a link to P0222? I couldn't find anything with that number)
> It hasn't been published yet AFAICT, but should be in the Feb 2016
> mailing whenever that does get published.
>
> Meanwhile:
> https://github.com/mwoehlke/cpp-proposals/blob/master/p0222r0-anonymous-s=
truct-return.rst
> (be aware that github strips the markup for standardese edits; check the
> raw reST for these, though in this case the edit may be obvious).
Thanks
>
>> In my head MRVs are a transient construct only existent as the type of a
>> call expression. If you need to capture it assign the values to
>> varaiables (like in P0144R1) or forward as parameters to another call
>> expression (like make_tuple). Under this assumption, that MRVs are their
>> own kind of entity, folding becomes possible as (0 + ... + foo()) if
>> their special nature is considered. Therefore folding a tuple becomes (0
>> + ... + unpack(tpl)).
> So... basically, an MRV *is* a parameter pack? In that case, I don't see
> much difference between "true MRV's" and U2PP.
Call it whatever you want, I don't care. At this stage I'm interested in=20
the functionality not bikeshedding of syntax or classification.
>
>>>> Given the proper handling of lvalue-refs, rvalue-refs, reference_wrapp=
er
>>>> etc, this should also make the example tail(ref(tpl1)) =3D tpl2 work.
>>> How would this be different from / better than:
>>>
>>> std::tie([1:]tpl1...) =3D tpl2;
>>>
>>> ...?
>> It uses words that actually describe what it does.
>>
>> Without MRVs you cannot hide "[1:]tpl1..." effortlessly behind a named
>> function.
> You can't?
>
> auto tail(auto tuple) { return make_tuple([1:]tuple...); }
>
> (Simplified for illustrative purposes; usual caveats about proper
> reference handling, forwarding, etc.)
Yes, that is how I would implement `tail()` even with MRVs because=20
`tail()` has the signature `(a_0, a_1, ..., a_n) -> (a_1, ..., a_n)`. A=20
better name for the example would have been `unpack_tail(tpl)` or=20
similar, my bad. Basically it needs the signature `(a_0, a_1, ..., a_n)=20
-> a_1, ..., a_n`.
But yet, those two are not equivalent. I cannot substitute the=20
expression `[1:]tpl...` with the expression `unpack_tail(tpl)` using=20
only the tools given in this thread and get the same semantics. Or am I=20
wrong? That's what I mean with you can't `hide` it. A full substitution=20
is `[:]unpack_tail(tpl)...` but that is a leaky abstraction because in=20
order to get the same semantics you have to apply additional operators.
>
>> *Every single time* someone needs to unpack the tail of a
>> tuple they have to write out the same sequence of punctuation. DRY
>> anyone?
> That's like saying "every time someone needs to add two numbers they
> have to write '+'". Yes, every time you do something you have to write
> something. DRY is when you are writing the same *non-trivial* code
> repeatedly. Seven characters (`[1:]...`) is not non-trivial, especially
> as your example uses a minimum of six (`tail()`, assuming that you are
> `using namespace std;`, which not everyone wants to do!).
Calling a function is not a violation of DRY. It's not about writing=20
"something" or "counting characters", it's about not repeating the same=20
implementation but give the repeatedly used abstraction or operation a=20
meaningful name. The triviality doesn't matter. `tail()` is obviously a=20
very trivial example, but even there I'd prefer a descriptive name=20
instead of wading through a forest of consecutive punctuation characters=20
(eight(!) in the previous example) over and over again.
So instead I'd like to hide `[1,5:a,y*3:photon_torpedo()~~^3]tpl...`=20
behind `federation_unpack(tpl)` which should have the signature `(a_0,=20
a_1, ..., a_n) -> x, y, z`. It doesn't return a `tuple<x, y, z>` because=20
it's called "unpack" and the expression I want to substitute with it is=20
not of type `tuple<x, y, z>` but of `x, y, z`. But an implementation=20
without MRVs is forced to the signature `(a_0, a_1, ..., a_n) -> (x, z,=20
y)` which I then have to additionally apply the actual unpacking to.=20
That's not really abstracting the "unpacking" part, is it? It's as if we=20
had to dereference references...
>
>> Even languages with this kind of syntax come shipped with
>> utility functions like tail() because they're more descriptive.
> I could argue that. If I'm not familiar with it, I need to check the
> documentation to know if 'tail' means `[1:]` or `[-1]`, because it could
> mean either one. With U2PP slicing, there is no such ambiguity. (And
> anyway, as shown above, there is nothing stopping us having a
> `std::tail()` with U2PP.)
`tail()` is a ubiquitous operation in basically every language that has=20
some form of builtin list or tuple type. How it is implemented doesn't=20
usually matter. What does matter is that I don't have to copy the=20
implementation around, may it be as trivial as it is in the case of=20
`tail()`. If the C++ committe manages to make `tail()` do something=20
tremendously different then congratulations on confusing everybody!
>
>> In order to hide it inside a function you have to return a tuple
>> (maybe containing references) and then use the awkward inversion of
>> "apply(f, something(x))" when using the result.
> Ah... no? Why? Huh?
> U2PP makes std::apply superfluous.
Well OK, either `apply(f, [:]something(x)...)` or=20
`f([:]something(x)...)` are equivalent, and both are leaking the fact=20
that I actually wanted a list of values but got a tuple instead.
>
>> Compare that to "f(something(x))" and tell me which one you'd prefer
>> to write and read.
> I'm not thrilled that I can't tell there that `something(x)` is a
> parameter pack. In that sense, I prefer the clarity of
> `f([:]something(x)...)`. (Note that this is also how e.g. Python works.
> Despite often being used as the poster child for MRV's, Python actually
> has no such thing... just lots of syntax sugar a la P0144 and U2PP that
> makes it seem as if it does.)
I call that paranoia, as is the case with every new language feature.=20
Soon we won't be able to tell whether `void foo(X x)` is the definition=20
of a function template or not. Are you also not going to avoid that? For=20
how long? But as noted in a previous response to Vicente, the unpack=20
operator *may* be necessary if we want to allow the different nesting=20
levels known from parameter pack expansions. I don't like it as it=20
suffers from the same problems as I described above, and I still hope it=20
can be omitted for the most common case of immedate unpacking. That may=20
be wishful thinking though.
>
> Oh! Here's a fun point... if we *did* have true MRV's, how long until
> people start writing unary operator* as a synonym for unpack? Would that
> be a good thing?
>
People define their own operators for DSLs or convenience all the time.=20
If it gets established as common practice then there's no point in=20
trying to stop it. But you know how it goes: new language features are=20
always heavily abused until people shoot themselves in the foot enough=20
times and figure out what the "good" versus the "bad" abuses are :)
--=20
---=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-propos=
als/.
.
Author: Miro Knejp <miro.knejp@gmail.com>
Date: Thu, 18 Feb 2016 19:10:08 +0100
Raw View
This is a multi-part message in MIME format.
--------------070204060709010704060709
Content-Type: text/plain; charset=UTF-8; format=flowed
Content-Transfer-Encoding: quoted-printable
Am 18.02.2016 um 18:06 schrieb Vicente J. Botet Escriba:
> Le 18/02/2016 16:39, Miro Knejp a =C3=A9crit :
>>
>>
>> Am 18.02.2016 um 10:40 schrieb Vicente J. Botet Escriba:
>>> Le 17/02/2016 22:30, Miro Knejp a =C3=A9crit :
>>>> I somehow can't shed the feeling that what we really need here is=20
>>>> support for multiple return values.
>>>>
>>> I don't know if mandatory for the subject on this thread, but yes, I=20
>>> believe we need MRV, but I don't know exactly what this would mean yet.
>>>> Just imagine for a moment that the following is valid:
>>>> |
>>>> int, float, double foo();
>>>> void bar(int, float, double);
>>>> bar(foo());
>>>> auto {a, b, c} =3D foo(); // borrowed from P0144R1
>>>> |
>>>>
>>> Could you show how would you define foo() to return MRV?
>>> return 0, 1.0, 2.0;
>>>
>>> or
>>>
>>> | return 0 1.0 2.0;
>>> |
>>> Or?
>> There are examples further down in my post. Besides any syntax=20
>> presented here is just a strawman so don't get lost in the details=20
>> too much.
>
> As you describe below, these details are important.
>>>
>>> IIUC, the single things you can do with a MRV is to use it in a call=20
>>> expression and in this case each one of the values is associated to=20
>>> an argument, and
>>> structure binding. However structure binding is associated to a=20
>>> tuple-like interface. Does it means that a MRV thing would have a=20
>>> tuple-like access interface (get<I>(mrv))?
>> No. If you want to return multiple values in something with a=20
>> tupe-like interface, well then use tuple and P0144 binding. There's=20
>> also a proposal in SG14 to synthesize get<>() for public fields,=20
>> making any old struct compatible with P0144.=20
> Could you give me a reference, because I'm the author of P0197 -=20
> Default tuple-like access and I'm really concerned ?
No need to be concerned, it is yours. I just didn't make the connection=20
when writing my reply and confused it with something else.
>> It is important to keep the multiple return values separate in a=20
>> special entity to allow for the compiler magic that unpacks it=20
>> effortlessly into a list of parameters.
>>> If foo() in the context of bar(foo()) is expanded to bar(a1,a2,a3)=20
>>> for some a1,a2,a3
>>>
>>> it should also be expanded in the context of
>>> |
>>> auto {a, b, c} =3D foo();
>>>
>>> and so we will need that
>>>
>>> |auto {a, b, c} =3D a1, a2, a3;
>>> |
>>> |
>> |No, since "a1, a2, a3" is a comma-expression and the binding only=20
>> applies to the result of the expression "a3". If P0144 doesn't=20
>> consider this special case then it will become impossible to add it=20
>> later. |
> P0144 can not take in account the MRV you are describing here ;-)
Of course it can't because MRVs don't exist yet and it doesn't cover=20
parameter packs, which expand either to a comma-expression or a list of=20
values, depending on the context. But since parameter packs are a=20
distinct entity an excepation can be made for them in this context to=20
not expand into a comma-expression.
> You your proposal, if you write one, should describe how this could=20
> work. IN the absence, I believe that the user would need
> ||||
> auto {a, b, c} =3D make_tuple(foo()); ||
>> |Functions returning multiple values return a special kind of entity=20
>> that is transparent to the user and allows unpacking into arguments=20
>> and can only exist as a temporary. You cannot reference it directly,=20
>> you cannot decltype() it (same as with parameter packs) and you=20
>> cannot spell its type. It is not a different syntax for a=20
>> comma-expression for which we don't need anythign new. What we need=20
>> is special treatment for "this function returns multiple values and I=20
>> can pass them as separate arguments to call expressions". We already=20
>> have a solution if it's not a function result but parameters:=20
>> parameter packs.|
> |We need however to know how to return them.|
>>> |
>>> |
>>> But |||P0144R1 doesn't support it, neither P0222R0. |
>>> |
>>> |
>> |Where is this P0222R0 and why is Google unable to find it? :(|
> |Really sorry it was P0217=20
> https://isocpp.org/blog/2016/02/p0144r1-and-p0217r0|
>>> |
>>> |
>>> Or would the user need to pack it before?
>>>
>>> ||auto {a, b, c} =3D make_tuple(foo());
>>> |
>>>
>>> IMO a MRV, or whatever we call the result of a MRV function, either
>>> * is always unpacked and needs some sort of pack function=20
>>> (make-tuple) in some cases or
>>> * is packed and we needs some sort of unpack function. I will not be=20
>>> against the use of an operator to unpack a MRV
>>>
>>> |
>>> bar(*foo());
>>> |
>>> |
>> |My concept treats multiple return values as unpacked, since we=20
>> already have solutions for packed values: tuple and other classes.=20
>> MRVs can only be used to
>> (1) be unpacked as parameters to a call expression
>> (2) be a direct subexpression in a return statement
>> (3) be unpacked in a fold expression
>> (4) be captured into variables by the syntax in P0144
>>
>> |
> |I'm missing how to build one from N values, bu I see that you=20
> describe it below.|
>> |I know (4) is redundant because of (1) but I feel like "auto {a, b,=20
>> c} =3D foo()" is simply too convenient to not have it supported=20
>> compared to "auto {a, b, c} =3D std::make_tuple(foo())" (which also=20
>> needs an include).|
> |I will no|t say redundant. If MRV don't provide a syntax to retrieve=20
> the multiple returned values, I would say that there is something missing=
..
>> |With this basic functionality we can implement everything else=20
>> mentioned in this thread as a library extension using make_tuple()=20
>> and unpack(). But since unpack() doesn't depend on=20
>> implementation-defined magical compiler intrinsics anyone can write=20
>> their own special snowflake if they so desire.
>>
>> Unpacking may require the unpack operator to allow the difference=20
>> between outer(inner(unpack(x)...)) and outer(inner(unpack(x))...) as=20
>> mentioned earlier. That is a detail that needs to be discussed.
>> |
>>> |
>>> ||
>>> |
>>>
>>>> having this ability makes writing tuple unpacking trivial
>>>> |
>>>> auto tpl =3D make_tuple(1, 2.f, 3.0);
>>>> bar(unpack(tpl));
>>>> bar(unpack<2, 1, 0>(tpl));
>>>>
>>>> template<class... Ts>
>>>> auto... unpack(tuple<Ts...> x)
>>>> {
>>>> return unpack_impl<0>(x, index_sequence_for<Ts...>());
>>>> }
>>>> template<size_t... Is, class... Ts>
>>>> auto... unpack(tuple<Ts...> x)
>>>> {
>>>> return unpack_impl<0>(x, make_index_sequence<Is...>());
>>>> }
>>>> template<size_t From, size_t To, class... Ts>
>>>> auto... unpack_range(tuple<Ts...> x)
>>>> {
>>>> return unpack_impl<From>(x, make_index_sequence<To - From>);
>>>> }
>>>> template<size_t Offset, class... Ts, size_t... Is>
>>>> auto... unpack_impl(tuple<Ts...> x, index_sequence<Is...>())
>>>> {
>>>> return get<Is + Offset>(x)...;
>>>> }
>>>> |
>>>> (and yes, I did omit stuff like rvalue-refs, forward() etc. as they=20
>>>> are only distracting and I am sure everyone here can fill in the=20
>>>> details themselves)
>>>>
>>> Here you introduce something additional. auto... as a deduced MRV.
>>> I suspect to be inline with the way we return here (there is no use=20
>>> of ',' to separate the arguments, the foo() function should return as
>>>
>>> | return 0 1.0 2.0;|
>> Remember this is strawman syntax, but here goes anyway: "auto..." is=20
>> to tell the compiler that "return a, b, c;" (as is the result of a=20
>> parameter pack expansion) does not use the comma operator but=20
>> actually returns multiple values. If the compiler expects only a=20
>> single value then "return a, b, c;" only returns the result of=20
>> evaluating "c" (or whatever crazy person overloaded the comma=20
>> operator with). This is only needed in deduced return types and=20
>> "auto..." is arbitrarily chosen because it is currently ill-formed.=20
>> If you spell out all return types akin to something like "int, int,=20
>> int foo()" then "return a, b, c;" is unambiguous. Both are means to=20
>> not break existing code.
> I believe that this will be conflicting.
That's why it's called strawman syntax. It's only meant for=20
demonstration. You could also call it pseudo code if you like. Criticize=20
the idea first, syntax last.
>>>>
>>>>
>>>> I know multiple return values come with their own set of problems=20
>>>> and since this thread isn't about multiple return values I am not=20
>>>> going to address them here.
>>> Well, as there is not yet a proposal for MRV we need to consider=20
>>> yours here, to see if is something that could be acceptable. What I=20
>>> mean is that we can not compare two solutions to a specific problem=20
>>> until we have concrete solutions and we can see the advantages and=20
>>> liabilities for both solutions. Maybe you prefer to start a new thread.
>> I haven't given the standard wording any thought yet so whether MRVs=20
>> are their own thing or parameter packs or whatever is entirely open=20
>> for debate (in a different thread if there is enough interest).=20
> I'm not talking yet of wording, but of how to use the feature.
I provided examples of how to use it. Did I miss an important use case?
--=20
---=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-propos=
als/.
--------------070204060709010704060709
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<html>
<head>
<meta content=3D"text/html; charset=3Dutf-8" http-equiv=3D"Content-Type=
">
</head>
<body bgcolor=3D"#FFFFFF" text=3D"#000000">
Am 18.02.2016 um 18:06 schrieb Vicente J. Botet Escriba:<br>
<blockquote cite=3D"mid:56C5FA02.7020700@wanadoo.fr" type=3D"cite">
<meta content=3D"text/html; charset=3Dutf-8" http-equiv=3D"Content-Ty=
pe">
<div class=3D"moz-cite-prefix">Le 18/02/2016 16:39, Miro Knejp a
=C3=A9crit=C2=A0:<br>
</div>
<blockquote cite=3D"mid:56C5E59C.6040007@gmail.com" type=3D"cite">
<meta content=3D"text/html; charset=3Dutf-8"
http-equiv=3D"Content-Type">
<br>
<br>
<div class=3D"moz-cite-prefix">Am 18.02.2016 um 10:40 schrieb
Vicente J. Botet Escriba:<br>
</div>
<blockquote cite=3D"mid:56C59196.5020401@wanadoo.fr" type=3D"cite">
<meta content=3D"text/html; charset=3Dutf-8"
http-equiv=3D"Content-Type">
<div class=3D"moz-cite-prefix">Le 17/02/2016 22:30, Miro Knejp a
=C3=A9crit=C2=A0:<br>
</div>
<blockquote
cite=3D"mid:6e35f24a-f728-4ac2-b329-1894206f59cc@isocpp.org"
type=3D"cite">
<div dir=3D"ltr">I somehow can't shed the feeling that what we
really need here is support for multiple return values.
<div><br>
</div>
</div>
</blockquote>
I don't know if mandatory for the subject on this thread, but
yes, I believe we need MRV, but I don't know exactly what this
would mean yet.<br>
<blockquote
cite=3D"mid:6e35f24a-f728-4ac2-b329-1894206f59cc@isocpp.org"
type=3D"cite">
<div dir=3D"ltr">
<div>Just imagine for a moment that the following is
valid:</div>
<div>
<div class=3D"prettyprint" style=3D"border: 1px solid
rgb(187, 187, 187); word-wrap: break-word;
background-color: rgb(250, 250, 250);"><code
class=3D"prettyprint">
<div class=3D"subprettyprint">
<div class=3D"subprettyprint">int, float, double
foo();</div>
<div class=3D"subprettyprint">void bar(int, float,
double);</div>
<div class=3D"subprettyprint">bar(foo());</div>
<div class=3D"subprettyprint">auto {a, b, c} =3D
foo(); // borrowed from P0144R1</div>
</div>
</code></div>
<br>
</div>
</div>
</blockquote>
Could you show how would you define foo() to return MRV?<br>
=C2=A0=C2=A0=C2=A0 return 0, 1.0, 2.0;<br>
<br>
or <br>
<br>
<code class=3D"prettyprint">=C2=A0=C2=A0=C2=A0 return 0 1.0 2.0;<=
br>
</code><br>
Or?<br>
</blockquote>
There are examples further down in my post. Besides any syntax
presented here is just a strawman so don't get lost in the
details too much.<br>
</blockquote>
<br>
As you describe below, these details are important.<br>
<blockquote cite=3D"mid:56C5E59C.6040007@gmail.com" type=3D"cite">
<blockquote cite=3D"mid:56C59196.5020401@wanadoo.fr" type=3D"cite">
<br>
IIUC, the single things you can do with a MRV is to use it in
a call expression and in this case each one of the values is
associated to an argument, and<br>
structure binding. However structure binding is associated to
a tuple-like interface. Does it means that a MRV thing would
have a tuple-like access interface (get<I>(mrv))?<br>
</blockquote>
No. If you want to return multiple values in something with a
tupe-like interface, well then use tuple and P0144 binding.
There's also a proposal in SG14 to synthesize get<>() for
public fields, making any old struct compatible with P0144. </block=
quote>
Could you give me a reference, because I'm the author of P0197 -
Default tuple-like access and I'm really concerned ?<br>
</blockquote>
No need to be concerned, it is yours. I just didn't make the
connection when writing my reply and confused it with something
else.<br>
<blockquote cite=3D"mid:56C5FA02.7020700@wanadoo.fr" type=3D"cite">
<blockquote cite=3D"mid:56C5E59C.6040007@gmail.com" type=3D"cite">It
is important to keep the multiple return values separate in a
special entity to allow for the compiler magic that unpacks it
effortlessly into a list of parameters.
<blockquote cite=3D"mid:56C59196.5020401@wanadoo.fr" type=3D"cite">=
If
foo() in the context of bar(foo()) is expanded to
bar(a1,a2,a3) for some a1,a2,a3 <br>
<br>
it should also be expanded in the context of<br>
<code class=3D"prettyprint">
<div class=3D"subprettyprint">auto {a, b, c} =3D foo(); <br>
<br>
and so we will need that<br>
<br>
<code class=3D"prettyprint">auto {a, b, c} =3D a1, a2, a3; <b=
r>
</code></div>
</code></blockquote>
<code>No, since "a1, a2, a3" is a comma-expression and the
binding only applies to the result of the expression "a3". If
P0144 doesn't consider this special case then it will become
impossible to add it later. </code></blockquote>
P0144 can not take in account the MRV you are describing here ;-)<br>
</blockquote>
Of course it can't because MRVs don't exist yet and it doesn't cover
parameter packs, which expand either to a comma-expression or a list
of values, depending on the context. But since parameter packs are a
distinct entity an excepation can be made for them in this context
to not expand into a comma-expression.<br>
<blockquote cite=3D"mid:56C5FA02.7020700@wanadoo.fr" type=3D"cite"> You
your proposal, if you write one, should describe how this could
work. IN the absence, I believe that the user would need<br>
<code class=3D"prettyprint"><code class=3D"prettyprint"></code><code
class=3D"prettyprint"><br>
auto {a, b, c} =3D make_tuple(foo()); </code></code><br>
<blockquote cite=3D"mid:56C5E59C.6040007@gmail.com" type=3D"cite"><co=
de>Functions
returning multiple values return a special kind of entity that
is transparent to the user and allows unpacking into arguments
and can only exist as a temporary. You cannot reference it
directly, you cannot decltype() it (same as with parameter
packs) and you cannot spell its type. It is not a different
syntax for a comma-expression for which we don't need anythign
new. What we need is special treatment for "this function
returns multiple values and I can pass them as separate
arguments to call expressions". We already have a solution if
it's not a function result but parameters: parameter packs.</code=
><br>
</blockquote>
<code>We need however to know how to return them.</code><br>
<blockquote cite=3D"mid:56C5E59C.6040007@gmail.com" type=3D"cite">
<blockquote cite=3D"mid:56C59196.5020401@wanadoo.fr" type=3D"cite">=
<code
class=3D"prettyprint">
<div class=3D"subprettyprint"><code class=3D"prettyprint"> <br>
But </code><code class=3D"prettyprint"><code
class=3D"prettyprint">P0144R1 doesn't support it,
neither P0222R0.=C2=A0 </code><br>
</code></div>
</code></blockquote>
<code>Where is this P0222R0 and why is Google unable to find it?
:(</code><br>
</blockquote>
<code>Really sorry it was P0217 <a moz-do-not-send=3D"true"
class=3D"moz-txt-link-freetext"
href=3D"https://isocpp.org/blog/2016/02/p0144r1-and-p0217r0">http=
s://isocpp.org/blog/2016/02/p0144r1-and-p0217r0</a></code><br>
<blockquote cite=3D"mid:56C5E59C.6040007@gmail.com" type=3D"cite">
<blockquote cite=3D"mid:56C59196.5020401@wanadoo.fr" type=3D"cite">=
<code
class=3D"prettyprint">
<div class=3D"subprettyprint"><code class=3D"prettyprint"> <br>
Or would the user need to pack it before?<br>
<br>
</code><code class=3D"prettyprint">auto {a, b, c} =3D
make_tuple(foo()); <br>
</code><br>
<br>
IMO a MRV, or whatever we call the result of a MRV
function, either <br>
* is always unpacked and needs some sort of pack function
(make-tuple) in some cases or <br>
* is packed and we needs some sort of unpack function. I
will not be against the use of an operator to unpack a MRV<br=
>
<br>
<code class=3D"prettyprint">
<div class=3D"subprettyprint">bar(*foo());</div>
</code></div>
</code></blockquote>
<code>My concept treats multiple return values as unpacked,
since we already have solutions for packed values: tuple and
other classes. MRVs can only be used to<br>
(1) be unpacked as parameters to a call expression<br>
(2) be a direct subexpression in a return statement<br>
(3) be unpacked in a fold expression<br>
(4) be captured into variables by the syntax in P0144<br>
<br>
</code></blockquote>
<code>I'm missing how to build one from N values, bu I see that
you describe it below.</code><br>
<blockquote cite=3D"mid:56C5E59C.6040007@gmail.com" type=3D"cite"><co=
de>
I know (4) is redundant because of (1) but I feel like "auto
{a, b, c} =3D foo()" is simply too convenient to not have it
supported compared to "auto {a, b, c} =3D
std::make_tuple(foo())" (which also needs an include).</code></bl=
ockquote>
<code>I will no</code>t say redundant. If MRV don't provide a
syntax to retrieve the multiple returned values, I would say that
there is something missing.<br>
<blockquote cite=3D"mid:56C5E59C.6040007@gmail.com" type=3D"cite"><co=
de>
With this basic functionality we can implement everything else
mentioned in this thread as a library extension using
make_tuple() and unpack(). But since unpack() doesn't depend
on implementation-defined magical compiler intrinsics anyone
can write their own special snowflake if they so desire.<br>
<br>
Unpacking may require the unpack operator to allow the
difference between outer(inner(unpack(x)...)) and
outer(inner(unpack(x))...) as mentioned earlier. That is a
detail that needs to be discussed.<br>
</code>
<blockquote cite=3D"mid:56C59196.5020401@wanadoo.fr" type=3D"cite">=
<code
class=3D"prettyprint">
<div class=3D"subprettyprint"><code class=3D"prettyprint"> </co=
de><br>
</div>
</code><br>
<br>
<blockquote
cite=3D"mid:6e35f24a-f728-4ac2-b329-1894206f59cc@isocpp.org"
type=3D"cite">
<div dir=3D"ltr">
<div>having this ability makes writing tuple unpacking
trivial</div>
<div>
<div class=3D"prettyprint" style=3D"border: 1px solid
rgb(187, 187, 187); word-wrap: break-word;
background-color: rgb(250, 250, 250);"><code
class=3D"prettyprint">
<div class=3D"subprettyprint">
<div class=3D"subprettyprint"><font color=3D"#660066"=
>auto
tpl =3D make_tuple(1, 2.f, 3.0);</font></div>
<div class=3D"subprettyprint"><font color=3D"#660066"=
>bar(unpack(tpl));</font></div>
<div class=3D"subprettyprint"><font color=3D"#660066"=
>bar(unpack<2,
1, 0>(tpl));</font></div>
<div class=3D"subprettyprint"><font color=3D"#660066"=
><br>
</font></div>
<div class=3D"subprettyprint">
<div class=3D"subprettyprint">template<class...
Ts></div>
<div class=3D"subprettyprint">auto...
unpack(tuple<Ts...> x)</div>
<div class=3D"subprettyprint">{</div>
<div class=3D"subprettyprint"><span class=3D"Apple-=
tab-span" style=3D"white-space:pre"> </span>return
unpack_impl<0>(x,
index_sequence_for<Ts...>());</div>
<div class=3D"subprettyprint">}</div>
<div class=3D"subprettyprint">template<size_t...
Is, class... Ts></div>
<div class=3D"subprettyprint">auto...
unpack(tuple<Ts...> x)</div>
<div class=3D"subprettyprint">{</div>
<div class=3D"subprettyprint"><span class=3D"Apple-=
tab-span" style=3D"white-space:pre"> </span>return
unpack_impl<0>(x,
make_index_sequence<Is...>());</div>
<div class=3D"subprettyprint">}</div>
<div class=3D"subprettyprint">template<size_t
From, size_t To, class... Ts></div>
<div class=3D"subprettyprint">auto...
unpack_range(tuple<Ts...> x)</div>
<div class=3D"subprettyprint">{</div>
<div class=3D"subprettyprint"><span class=3D"Apple-=
tab-span" style=3D"white-space:pre"> </span>return
unpack_impl<From>(x,
make_index_sequence<To - From>);</div>
<div class=3D"subprettyprint">}</div>
<div class=3D"subprettyprint">template<size_t
Offset, class... Ts, size_t... Is></div>
<div class=3D"subprettyprint">auto...
unpack_impl(tuple<Ts...> x,
index_sequence<Is...>())</div>
<div class=3D"subprettyprint">{</div>
<div class=3D"subprettyprint"><span class=3D"Apple-=
tab-span" style=3D"white-space:pre"> </span>return
get<Is + Offset>(x)...;</div>
<div class=3D"subprettyprint">}</div>
</div>
</div>
</code></div>
(and yes, I did omit stuff like rvalue-refs, forward()
etc. as they are only distracting and I am sure everyone
here can fill in the details themselves)<br>
<br>
</div>
</div>
</blockquote>
Here you introduce something additional. auto... as a deduced
MRV. <br>
</blockquote>
<blockquote cite=3D"mid:56C59196.5020401@wanadoo.fr" type=3D"cite">
I suspect to be inline with the way we return here=C2=A0 (there i=
s
no use of ',' to separate the arguments, the foo() function
should return as<br>
<br>
<code class=3D"prettyprint">=C2=A0=C2=A0=C2=A0 return 0 1.0 2.0;<=
/code><br>
</blockquote>
Remember this is strawman syntax, but here goes anyway:
"auto..." is to tell the compiler that "return a, b, c;" (as is
the result of a parameter pack expansion) does not use the comma
operator but actually returns multiple values. If the compiler
expects only a single value then "return a, b, c;" only returns
the result of evaluating "c" (or whatever crazy person
overloaded the comma operator with). This is only needed in
deduced return types and "auto..." is arbitrarily chosen because
it is currently ill-formed. If you spell out all return types
akin to something like "int, int, int foo()" then "return a, b,
c;" is unambiguous. Both are means to not break existing code.<br>
</blockquote>
I believe that this will be conflicting.<br>
</blockquote>
That's why it's called strawman syntax. It's only meant for
demonstration. You could also call it pseudo code if you like.
Criticize the idea first, syntax last.<br>
<blockquote cite=3D"mid:56C5FA02.7020700@wanadoo.fr" type=3D"cite">
<blockquote cite=3D"mid:56C5E59C.6040007@gmail.com" type=3D"cite">
<blockquote cite=3D"mid:56C59196.5020401@wanadoo.fr" type=3D"cite">
<blockquote
cite=3D"mid:6e35f24a-f728-4ac2-b329-1894206f59cc@isocpp.org"
type=3D"cite">
<div dir=3D"ltr">
<div><br>
<div><br>
</div>
I know multiple return values come with their own set of
problems and since this thread isn't about multiple
return values I am not going to address them here. </div>
</div>
</blockquote>
Well, as there is not yet a proposal for MRV we need to
consider yours here, to see if is something that could be
acceptable. What I mean is that we can not compare two
solutions to a specific problem until we have concrete
solutions and we can see the advantages and liabilities for
both solutions. Maybe you prefer to start a new thread.<br>
</blockquote>
I haven't given the standard wording any thought yet so whether
MRVs are their own thing or parameter packs or whatever is
entirely open for debate (in a different thread if there is
enough interest). </blockquote>
I'm not talking yet of wording, but of how to use the feature.<br>
</blockquote>
I provided examples of how to use it. Did I miss an important use
case?<br>
<br>
</body>
</html>
<p></p>
-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
Visit this group at <a href=3D"https://groups.google.com/a/isocpp.org/group=
/std-proposals/">https://groups.google.com/a/isocpp.org/group/std-proposals=
/</a>.<br />
--------------070204060709010704060709--
.
Author: Matthew Woehlke <mwoehlke.floss@gmail.com>
Date: Thu, 18 Feb 2016 13:14:21 -0500
Raw View
On 2016-02-18 12:46, Miro Knejp wrote:
> Am 18.02.2016 um 17:18 schrieb Matthew Woehlke:
>> So... basically, an MRV *is* a parameter pack? In that case, I don't see
>> much difference between "true MRV's" and U2PP.
>
> Call it whatever you want, I don't care. At this stage I'm interested in
> the functionality not bikeshedding of syntax or classification.
That's not a bikeshedding question. A parameter pack is an existing
entity with known functionality. If TMRV's are also parameter packs (and
my impression is that we generally agree the should be), that gives
specific, detailed information about how they function and what they can do.
>> On 2016-02-17 18:38, Miro Knejp wrote:
>>> Without MRVs you cannot hide "[1:]tpl1..." effortlessly behind a named
>>> function.
>>
>> You can't?
>>
>> auto tail(auto tuple) { return make_tuple([1:]tuple...); }
>
> Yes, that is how I would implement `tail()` even with MRVs because
> `tail()` has the signature `(a_0, a_1, ..., a_n) -> (a_1, ..., a_n)`. A
> better name for the example would have been `unpack_tail(tpl)` or
> similar, my bad. Basically it needs the signature `(a_0, a_1, ..., a_n)
> -> a_1, ..., a_n`.
>
> But yet, those two are not equivalent. I cannot substitute the
> expression `[1:]tpl...` with the expression `unpack_tail(tpl)` using
> only the tools given in this thread and get the same semantics. Or am I
> wrong? That's what I mean with you can't `hide` it. A full substitution
> is `[:]unpack_tail(tpl)...` but that is a leaky abstraction because in
> order to get the same semantics you have to apply additional operators.
Well... yes, except a more accurate comparison would be:
unpack_tail(tpl)
// vs.
[:]tail(tpl)
....because the non-MRV version isn't unpacked. (If you actually *want* a
tuple, it's also more efficient, but that's bordering on a strawman
argument...)
It's not exactly a leaky abstraction; more of an inexact equivalence.
That is, you can't exactly implement `unpack_tail` with U2PP. What you
*can* implement is something that returns a tuple that can be unpacked
to obtain the same parameter pack. Is that a problem? Well... maybe. I'm
not sure.
> `tail()` is a ubiquitous operation in basically every language that has
> some form of builtin list or tuple type.
It's also the accessor of the last item in a queue or linked list. :-)
>> I'm not thrilled that I can't tell there that `something(x)` is a
>> parameter pack. In that sense, I prefer the clarity of
>> `f([:]something(x)...)`. (Note that this is also how e.g. Python works.
>> Despite often being used as the poster child for MRV's, Python actually
>> has no such thing... just lots of syntax sugar a la P0144 and U2PP that
>> makes it seem as if it does.)
>
> I call that paranoia, as is the case with every new language feature.
> Soon we won't be able to tell whether `void foo(X x)` is the definition
> of a function template or not. Are you also not going to avoid that?
Well... yeah, I'm not crazy about that either :-).
>> Oh! Here's a fun point... if we *did* have true MRV's, how long until
>> people start writing unary operator* as a synonym for unpack? Would that
>> be a good thing?
>
> People define their own operators for DSLs or convenience all the time.
> If it gets established as common practice then there's no point in
> trying to stop it. But you know how it goes: new language features are
> always heavily abused until people shoot themselves in the foot enough
> times and figure out what the "good" versus the "bad" abuses are :)
I should clarify that the above was *not* meant as a rhetorical question
:-). One possibly "good" think about TMRV's as you propose, including
omission of `...`, is that I can write:
void dot(double, double, double);
vector_3d p = ...;
dot(*p);
....just as in Python. I suspect some people will love this while others
will be passionately opposed to it...
--
Matthew
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-proposals/.
.
Author: Matthew Woehlke <mwoehlke.floss@gmail.com>
Date: Thu, 18 Feb 2016 13:20:25 -0500
Raw View
On 2016-02-18 13:10, Miro Knejp wrote:
> Am 18.02.2016 um 18:06 schrieb Vicente J. Botet Escriba:
>> Le 18/02/2016 16:39, Miro Knejp a =C3=A9crit :
>>> If you want to return multiple values in something with a
>>> tupe-like interface, well then use tuple and P0144 binding. There's
>>> also a proposal in SG14 to synthesize get<>() for public fields,
>>> making any old struct compatible with P0144.=20
>>
>> Could you give me a reference, because I'm the author of P0197 -
>> Default tuple-like access and I'm really concerned ?
>
> No need to be concerned, it is yours. I just didn't make the connection
> when writing my reply and confused it with something else.
Okay... thanks. (Whew, the presenter of P0197=C2=B9 was also worried there
for a moment :-).)
(=C2=B9 That'd be me, if it wasn't obvious...)
>> P0144 can not take in account the MRV you are describing here ;-)
>
> Of course it can't because MRVs don't exist yet and it doesn't cover
> parameter packs, which expand either to a comma-expression or a list of
> values, depending on the context. But since parameter packs are a
> distinct entity an excepation can be made for them in this context to
> not expand into a comma-expression.
Right. As mentioned in my other post, I don't think there is a "problem"
here. (We'd certainly want to broaden assignment unpacking to handle
parameter packs, but that shouldn't be troublesome, just a change to be
made.)
--=20
Matthew
--=20
---=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-propos=
als/.
.