Topic: Core Language featuMultiple assignments from
Author: Matthew Fioravante <fmatthew5876@gmail.com>
Date: Wed, 20 May 2015 18:14:30 -0700 (PDT)
Raw View
------=_Part_1109_25404122.1432170870220
Content-Type: multipart/alternative;
boundary="----=_Part_1110_1765316348.1432170870221"
------=_Part_1110_1765316348.1432170870221
Content-Type: text/plain; charset=UTF-8
So this idea came out of the number parsing thread. Many languages like
python have support for functions returning multiple values.
In C++, one option we have currently is this:
std::tuple<int,float,double> foo();
int x;
double d;
std::tie(x, std::ignore, d) = foo();
This works but it has a lot of problems:
- We have to declare the receiving variables beforehand. This means they
have to be default constructed and then assigned and we cannot use auto.
- Its overly verbose and clumsy to use. First we have to declare the
variables, then we need 8 character std::tie and 11 character std::ignore.
- tuple and tie are not as well known to beginners. A "standard practice"
for capturing multiple values would be better as a core language feature
than a library feature.
So one solution would be to invent a new syntax:
int x;
[x; void; auto d] = foo();
Which is the equivalent of:
int x;
auto _t = foo();
x = std::get<0>(std::move(_t));
auto d = std::get<2>(std::move(_t));
Each element in this "assignment list" corresponds to a element of a tuple
of the right hand side of the expression. Each element can be one of:
- An lvalue expression: the resulting lvalue is assigned with operator=()
to the corresponding tuple element.
- void: the corresponding tuple element is ignored
- A local variable declaration. A local variable is created and constructed
with the corresponding tuple element.
I've chosen to use [] instead of {} because so far braces always introduce
a scope and in this example, d which is created inside the braces actually
lives in the outer scope.
I've chosen to use ; instead of , to avoid confusion with the comma
operator.
We can also allow the user to specify a shorter list, with default values
of void for the trailing elements not mentioned:
[auto x] = foo(); //same as [auto x, void, void] = foo()
What do you think about such a feature?
--
---
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 http://groups.google.com/a/isocpp.org/group/std-proposals/.
------=_Part_1110_1765316348.1432170870221
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">So this idea came out of the number parsing thread. Many l=
anguages like python have support for functions returning multiple values.<=
div><br></div><div>In C++, one option we have currently is this:</div><div>=
<br></div><div><div class=3D"prettyprint" style=3D"border: 1px solid rgb(18=
7, 187, 187); word-wrap: break-word; background-color: rgb(250, 250, 250);"=
><code class=3D"prettyprint"><div class=3D"subprettyprint"><span style=3D"c=
olor: #000;" class=3D"styled-by-prettify">std</span><span style=3D"color: #=
660;" class=3D"styled-by-prettify">::</span><span style=3D"color: #000;" cl=
ass=3D"styled-by-prettify">tuple</span><span style=3D"color: #660;" class=
=3D"styled-by-prettify"><</span><span style=3D"color: #008;" class=3D"st=
yled-by-prettify">int</span><span style=3D"color: #660;" class=3D"styled-by=
-prettify">,</span><span style=3D"color: #008;" class=3D"styled-by-prettify=
">float</span><span style=3D"color: #660;" 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><font=
color=3D"#000000"><span style=3D"color: #000;" class=3D"styled-by-prettify=
"> foo</span><span style=3D"color: #660;" class=3D"styled-by-prettify">();<=
/span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br><br></s=
pan><span style=3D"color: #008;" class=3D"styled-by-prettify">int</span><sp=
an 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"><br></span><span style=3D"color: #008=
;" class=3D"styled-by-prettify">double</span><span style=3D"color: #000;" c=
lass=3D"styled-by-prettify"> d</span><span style=3D"color: #660;" class=3D"=
styled-by-prettify">;</span><span style=3D"color: #000;" class=3D"styled-by=
-prettify"><br>std</span><span style=3D"color: #660;" class=3D"styled-by-pr=
ettify">::</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">x</span><span st=
yle=3D"color: #660;" class=3D"styled-by-prettify">,</span><span style=3D"co=
lor: #000;" class=3D"styled-by-prettify"> std</span><span style=3D"color: #=
660;" class=3D"styled-by-prettify">::</span><span style=3D"color: #000;" cl=
ass=3D"styled-by-prettify">ignore</span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">,</span><span style=3D"color: #000;" class=3D"style=
d-by-prettify"> d</span><span style=3D"color: #660;" class=3D"styled-by-pre=
ttify">)</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"> foo</span><span s=
tyle=3D"color: #660;" class=3D"styled-by-prettify">();</span></font></div><=
/code></div><br>This works but it has a lot of problems:</div><div>- We hav=
e to declare the receiving variables beforehand. This means they have to be=
default constructed and then assigned and we cannot use auto.</div><div>- =
Its overly verbose and clumsy to use. First we have to declare the variable=
s, then we need 8 character std::tie and 11 character std::ignore.</div><di=
v>- tuple and tie are not as well known to beginners. A "standard practice"=
for capturing multiple values would be better as a core language feature t=
han a library feature.</div><div><br></div><div>So one solution would be to=
invent a new syntax:</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"=
><span style=3D"font-family: Arial, Helvetica, sans-serif;"><span style=3D"=
color: #008;" class=3D"styled-by-prettify">int</span><span style=3D"color: =
#000;" class=3D"styled-by-prettify"> x</span><span style=3D"color: #660;" c=
lass=3D"styled-by-prettify">;</span><span style=3D"color: #000;" class=3D"s=
tyled-by-prettify"><br></span><span style=3D"color: #660;" class=3D"styled-=
by-prettify">[</span><span style=3D"color: #000;" class=3D"styled-by-pretti=
fy">x</span><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: #008;" class=3D"styled-by-prettify">void</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">auto</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"> d</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: #660;" class=3D"styled-by-prettify">=
=3D</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> foo</s=
pan><span style=3D"color: #660;" class=3D"styled-by-prettify">();</span></s=
pan><span style=3D"color: #000;" class=3D"styled-by-prettify"><br></span></=
div></code></div><div><br></div><div>Which is the equivalent of:</div><div>=
<div class=3D"prettyprint" style=3D"border: 1px solid rgb(187, 187, 187); w=
ord-wrap: break-word; background-color: rgb(250, 250, 250);"><code class=3D=
"prettyprint"><div class=3D"subprettyprint"><span style=3D"color: #008;" cl=
ass=3D"styled-by-prettify">int</span><span style=3D"color: #000;" class=3D"=
styled-by-prettify"> x</span><span style=3D"color: #660;" class=3D"styled-b=
y-prettify">;</span><span style=3D"color: #000;" class=3D"styled-by-prettif=
y"><br></span><span style=3D"color: #008;" class=3D"styled-by-prettify">aut=
o</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> _t </spa=
n><span style=3D"color: #660;" class=3D"styled-by-prettify">=3D</span><span=
style=3D"color: #000;" class=3D"styled-by-prettify"> foo</span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">();</span><span style=3D"col=
or: #000;" class=3D"styled-by-prettify"><br>x </span><span style=3D"color: =
#660;" class=3D"styled-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-prettify">::</span><span style=3D"color: #008;" class=3D"styl=
ed-by-prettify">get</span><span style=3D"color: #660;" class=3D"styled-by-p=
rettify"><</span><span style=3D"color: #066;" class=3D"styled-by-prettif=
y">0</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 sty=
le=3D"color: #000;" class=3D"styled-by-prettify">move</span><span style=3D"=
color: #660;" class=3D"styled-by-prettify">(</span><span style=3D"color: #0=
00;" class=3D"styled-by-prettify">_t</span><span style=3D"color: #660;" cla=
ss=3D"styled-by-prettify">));</span><span style=3D"color: #000;" class=3D"s=
tyled-by-prettify"><br></span><span style=3D"color: #008;" class=3D"styled-=
by-prettify">auto</span><span style=3D"color: #000;" class=3D"styled-by-pre=
ttify"> d </span><span style=3D"color: #660;" class=3D"styled-by-prettify">=
=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">::</span><spa=
n 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"co=
lor: #066;" class=3D"styled-by-prettify">2</span><span style=3D"color: #660=
;" class=3D"styled-by-prettify">>(</span><span style=3D"color: #000;" cl=
ass=3D"styled-by-prettify">std</span><font color=3D"#008800"><span style=3D=
"color: #660;" class=3D"styled-by-prettify">::</span><span style=3D"color: =
#000;" class=3D"styled-by-prettify">move</span><span style=3D"color: #660;"=
class=3D"styled-by-prettify">(</span></font><span style=3D"color: #000;" c=
lass=3D"styled-by-prettify">_t</span><span style=3D"color: #660;" class=3D"=
styled-by-prettify">));</span></div></code></div><br></div><div>Each elemen=
t in this "assignment list" corresponds to a element of a tuple of the righ=
t hand side of the expression. Each element can be one of:<br></div><div>- =
An lvalue expression: the resulting lvalue is assigned with operator=3D() t=
o the corresponding tuple element.</div><div>- void: the corresponding tupl=
e element is ignored</div><div>- A local variable declaration. A local vari=
able is created and constructed with the corresponding tuple element.</div>=
<div><br></div>I've chosen to use [] instead of {} because so far braces al=
ways introduce a scope and in this example, d which is created inside the b=
races actually lives in the outer scope.</div><div>I've chosen to use ; ins=
tead of , to avoid confusion with the comma operator.</div><div><br></div><=
div>We can also allow the user to specify a shorter list, with default valu=
es of void for the trailing elements not mentioned:</div><div><br></div><di=
v><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"><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;" class=3D"style=
d-by-prettify"> x</span><span style=3D"color: #660;" class=3D"styled-by-pre=
ttify">]</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> <=
/span><span style=3D"color: #660;" class=3D"styled-by-prettify">=3D</span><=
font color=3D"#000000"><span style=3D"color: #000;" class=3D"styled-by-pret=
tify"> foo</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: #800;" class=3D"styled-by-prettify">//same as [auto =
x, void, void] =3D foo()</span><span style=3D"color: #000;" class=3D"styled=
-by-prettify"><br></span></font></div></code></div><br>What do you think ab=
out such a feature?</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"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />
------=_Part_1110_1765316348.1432170870221--
------=_Part_1109_25404122.1432170870220--
.
Author: Morwenn <morwenn29@gmail.com>
Date: Thu, 21 May 2015 00:49:44 -0700 (PDT)
Raw View
------=_Part_2901_839747073.1432194584614
Content-Type: multipart/alternative;
boundary="----=_Part_2902_366527827.1432194584614"
------=_Part_2902_366527827.1432194584614
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
While I don't really like the syntax (it's hard to make something short=20
when you have to declare a type anyway), I want to say that I really much=
=20
like the use of std::get to get the parameters. That means that any type=20
compatible with std::get, such as std::pair or std::array, could be used=20
for multi-valued return types. This is IMO better than forcing users to use=
=20
std::tuple everywhere and make some standard library functions returning=20
std::pair work with the syntax out of the box.
There have already been a number of discussions about such a feature by the=
=20
way. I bet that you can find some in this very mailing list.
Le jeudi 21 mai 2015 03:14:30 UTC+2, Matthew Fioravante a =C3=A9crit :
>
> So this idea came out of the number parsing thread. Many languages like=
=20
> python have support for functions returning multiple values.
>
> In C++, one option we have currently is this:
>
> std::tuple<int,float,double> foo();
>
> int x;
> double d;
> std::tie(x, std::ignore, d) =3D foo();
>
> This works but it has a lot of problems:
> - We have to declare the receiving variables beforehand. This means they=
=20
> have to be default constructed and then assigned and we cannot use auto.
> - Its overly verbose and clumsy to use. First we have to declare the=20
> variables, then we need 8 character std::tie and 11 character std::ignore=
..
> - tuple and tie are not as well known to beginners. A "standard practice"=
=20
> for capturing multiple values would be better as a core language feature=
=20
> than a library feature.
>
> So one solution would be to invent a new syntax:
> int x;
> [x; void; auto d] =3D foo();
>
> Which is the equivalent of:
> int x;
> auto _t =3D foo();
> x =3D std::get<0>(std::move(_t));
> auto d =3D std::get<2>(std::move(_t));
>
> Each element in this "assignment list" corresponds to a element of a tupl=
e=20
> of the right hand side of the expression. Each element can be one of:
> - An lvalue expression: the resulting lvalue is assigned with operator=3D=
()=20
> to the corresponding tuple element.
> - void: the corresponding tuple element is ignored
> - A local variable declaration. A local variable is created and=20
> constructed with the corresponding tuple element.
>
> I've chosen to use [] instead of {} because so far braces always introduc=
e=20
> a scope and in this example, d which is created inside the braces actuall=
y=20
> lives in the outer scope.
> I've chosen to use ; instead of , to avoid confusion with the comma=20
> operator.
>
> We can also allow the user to specify a shorter list, with default values=
=20
> of void for the trailing elements not mentioned:
>
> [auto x] =3D foo(); //same as [auto x, void, void] =3D foo()
>
> What do you think about such a feature?
>
--=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 http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.
------=_Part_2902_366527827.1432194584614
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">While I don't really like the syntax (it's hard to make so=
mething short when you have to declare a type anyway), I want to say that I=
really much like the use of <span style=3D"font-family: courier new,monosp=
ace;">std::get</span> to get the parameters. That means that any type compa=
tible with<span style=3D"font-family: courier new,monospace;"> std::get</sp=
an>, such as <span style=3D"font-family: courier new,monospace;">std::pair<=
/span> or <span style=3D"font-family: courier new,monospace;">std::array</s=
pan>, could be used for multi-valued return types. This is IMO better than =
forcing users to use <span style=3D"font-family: courier new,monospace;">st=
d::tuple</span> everywhere and make some standard library functions returni=
ng <span style=3D"font-family: courier new,monospace;">std::pair</span> wor=
k with the syntax out of the box.<br><br>There have already been a number o=
f discussions about such a feature by the way. I bet that you can find some=
in this very mailing list.<br><br>Le jeudi 21 mai 2015 03:14:30 UTC+2, Mat=
thew Fioravante a =C3=A9crit :<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">So this idea came out of the number parsing thread. =
Many languages like python have support for functions returning multiple va=
lues.<div><br></div><div>In C++, one option we have currently is this:</div=
><div><br></div><div><div style=3D"border:1px solid rgb(187,187,187);word-w=
rap:break-word;background-color:rgb(250,250,250)"><code><div><span style=3D=
"color:#000">std</span><span style=3D"color:#660">::</span><span style=3D"c=
olor:#000">tuple</span><span style=3D"color:#660"><</span><span style=3D=
"color:#008">int</span><span style=3D"color:#660">,</span><span style=3D"co=
lor:#008">float</span><span style=3D"color:#660">,</span><span style=3D"col=
or:#008">double</span><span style=3D"color:#660">></span><font color=3D"=
#000000"><span style=3D"color:#000"> foo</span><span style=3D"color:#660">(=
);</span><span style=3D"color:#000"><br><br></span><span style=3D"color:#00=
8">int</span><span style=3D"color:#000"> x</span><span style=3D"color:#660"=
>;</span><span style=3D"color:#000"><br></span><span style=3D"color:#008">d=
ouble</span><span style=3D"color:#000"> d</span><span style=3D"color:#660">=
;</span><span style=3D"color:#000"><br>std</span><span style=3D"color:#660"=
>::</span><span style=3D"color:#000">tie</span><span style=3D"color:#660">(=
</span><span style=3D"color:#000">x</span><span style=3D"color:#660">,</spa=
n><span style=3D"color:#000"> std</span><span style=3D"color:#660">::</span=
><span style=3D"color:#000">ignore</span><span style=3D"color:#660">,</span=
><span style=3D"color:#000"> d</span><span style=3D"color:#660">)</span><sp=
an style=3D"color:#000"> </span><span style=3D"color:#660">=3D</span><span =
style=3D"color:#000"> foo</span><span style=3D"color:#660">();</span></font=
></div></code></div><br>This works but it has a lot of problems:</div><div>=
- We have to declare the receiving variables beforehand. This means they ha=
ve to be default constructed and then assigned and we cannot use auto.</div=
><div>- Its overly verbose and clumsy to use. First we have to declare the =
variables, then we need 8 character std::tie and 11 character std::ignore.<=
/div><div>- tuple and tie are not as well known to beginners. A "standard p=
ractice" for capturing multiple values would be better as a core language f=
eature than a library feature.</div><div><br></div><div>So one solution wou=
ld be to invent a new syntax:</div><div><div style=3D"border:1px solid rgb(=
187,187,187);word-wrap:break-word;background-color:rgb(250,250,250)"><code>=
<div><span style=3D"font-family:Arial,Helvetica,sans-serif"><span style=3D"=
color:#008">int</span><span style=3D"color:#000"> x</span><span style=3D"co=
lor:#660">;</span><span style=3D"color:#000"><br></span><span style=3D"colo=
r:#660">[</span><span style=3D"color:#000">x</span><span style=3D"color:#66=
0">;</span><span style=3D"color:#000"> </span><span style=3D"color:#008">vo=
id</span><span style=3D"color:#660">;</span><span style=3D"color:#000"> </s=
pan><span style=3D"color:#008">auto</span><span style=3D"color:#000"> d</sp=
an><span style=3D"color:#660">]</span><span style=3D"color:#000"> </span><s=
pan style=3D"color:#660">=3D</span><span style=3D"color:#000"> foo</span><s=
pan style=3D"color:#660">();</span></span><span style=3D"color:#000"><br></=
span></div></code></div><div><br></div><div>Which is the equivalent of:</di=
v><div><div style=3D"border:1px solid rgb(187,187,187);word-wrap:break-word=
;background-color:rgb(250,250,250)"><code><div><span style=3D"color:#008">i=
nt</span><span style=3D"color:#000"> x</span><span style=3D"color:#660">;</=
span><span style=3D"color:#000"><br></span><span style=3D"color:#008">auto<=
/span><span style=3D"color:#000"> _t </span><span style=3D"color:#660">=3D<=
/span><span style=3D"color:#000"> foo</span><span style=3D"color:#660">();<=
/span><span style=3D"color:#000"><br>x </span><span style=3D"color:#660">=
=3D</span><span style=3D"color:#000"> std</span><span style=3D"color:#660">=
::</span><span style=3D"color:#008">get</span><span style=3D"color:#660">&l=
t;</span><span style=3D"color:#066">0</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">move</span><span style=3D"color:#660">(</s=
pan><span style=3D"color:#000">_t</span><span style=3D"color:#660">));</spa=
n><span style=3D"color:#000"><br></span><span style=3D"color:#008">auto</sp=
an><span style=3D"color:#000"> d </span><span style=3D"color:#660">=3D</spa=
n><span style=3D"color:#000"> std</span><span style=3D"color:#660">::</span=
><span style=3D"color:#008">get</span><span style=3D"color:#660"><</span=
><span style=3D"color:#066">2</span><span style=3D"color:#660">>(</span>=
<span style=3D"color:#000">std</span><font color=3D"#008800"><span style=3D=
"color:#660">::</span><span style=3D"color:#000">move</span><span style=3D"=
color:#660">(</span></font><span style=3D"color:#000">_t</span><span style=
=3D"color:#660">));</span></div></code></div><br></div><div>Each element in=
this "assignment list" corresponds to a element of a tuple of the right ha=
nd side of the expression. Each element can be one of:<br></div><div>- An l=
value expression: the resulting lvalue is assigned with operator=3D() to th=
e corresponding tuple element.</div><div>- void: the corresponding tuple el=
ement is ignored</div><div>- A local variable declaration. A local variable=
is created and constructed with the corresponding tuple element.</div><div=
><br></div>I've chosen to use [] instead of {} because so far braces always=
introduce a scope and in this example, d which is created inside the brace=
s actually lives in the outer scope.</div><div>I've chosen to use ; instead=
of , to avoid confusion with the comma operator.</div><div><br></div><div>=
We can also allow the user to specify a shorter list, with default values o=
f void for the trailing elements not mentioned:</div><div><br></div><div><d=
iv style=3D"border:1px solid rgb(187,187,187);word-wrap:break-word;backgrou=
nd-color:rgb(250,250,250)"><code><div><span style=3D"color:#660">[</span><s=
pan style=3D"color:#008">auto</span><span style=3D"color:#000"> x</span><sp=
an style=3D"color:#660">]</span><span style=3D"color:#000"> </span><span st=
yle=3D"color:#660">=3D</span><font color=3D"#000000"><span style=3D"color:#=
000"> foo</span><span style=3D"color:#660">();</span><span style=3D"color:#=
000"> </span><span style=3D"color:#800">//same as [auto x, void, void] =3D =
foo()</span><span style=3D"color:#000"><br></span></font></div></code></div=
><br>What do you think about such a feature?</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"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />
------=_Part_2902_366527827.1432194584614--
------=_Part_2901_839747073.1432194584614--
.
Author: =?UTF-8?Q?P=C3=A9ter?= <mitchnull@gmail.com>
Date: Tue, 26 May 2015 07:47:41 -0700 (PDT)
Raw View
------=_Part_2198_1270251742.1432651661843
Content-Type: multipart/alternative;
boundary="----=_Part_2199_986092967.1432651661843"
------=_Part_2199_986092967.1432651661843
Content-Type: text/plain; charset=UTF-8
I'd also like to see this feature added to c++. I don't really like the
proposed syntax either (the square brackets are out-of-place here, imo).
The best would be to simply use
int x;
(x; void; auto d) = foo();
but I guess that'd introduce parsing issues. How about:
int x;
auto (x; void; auto d) = foo();
But even the proposed square-bracket syntax is better than nothing, so good
luck!
--
---
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 http://groups.google.com/a/isocpp.org/group/std-proposals/.
------=_Part_2199_986092967.1432651661843
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">I'd also like to see this feature added to c++. I do=
n't really like the proposed syntax either (the square brackets are out-of-=
place here, imo). The best would be to simply use <div><br><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"prettypri=
nt"><div class=3D"subprettyprint"><span style=3D"color: #008;" class=3D"sty=
led-by-prettify">int</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"><br></s=
pan><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><span style=3D"color: #=
000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #008;" cla=
ss=3D"styled-by-prettify">void</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=
">auto</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> d</=
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: #660;" class=3D"styled-by-prettify">=3D</span><span style=3D"col=
or: #000;" class=3D"styled-by-prettify"> foo</span><span style=3D"color: #6=
60;" class=3D"styled-by-prettify">();</span><span style=3D"color: #000;" cl=
ass=3D"styled-by-prettify"><br></span></div></code></div><div><br></div><di=
v>but I guess that'd introduce parsing issues. How about:<div><br></d=
iv><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"><span style=3D"color: #008;"=
class=3D"styled-by-prettify">int</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"> x</span><span style=3D"color: #660;" class=3D"styl=
ed-by-prettify">;</span><span style=3D"color: #000;" class=3D"styled-by-pre=
ttify"><br></span><span style=3D"color: #008;" class=3D"styled-by-prettify"=
>auto</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </sp=
an><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><span style=3D"color: #0=
00;" class=3D"styled-by-prettify"> </span><span style=3D"color: #008;" clas=
s=3D"styled-by-prettify">void</span><span style=3D"color: #660;" class=3D"s=
tyled-by-prettify">;</span><span style=3D"color: #000;" class=3D"styled-by-=
prettify"> </span><span style=3D"color: #008;" class=3D"styled-by-prettify"=
>auto</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> d</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</span><span style=3D"color:=
#000;" class=3D"styled-by-prettify"> foo</span><span style=3D"color: #660;=
" class=3D"styled-by-prettify">();</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"><br></span></div></code></div><div><br></div><div>B=
ut even the proposed square-bracket syntax is better than nothing, so good =
luck!</div><div><br></div><div><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"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />
------=_Part_2199_986092967.1432651661843--
------=_Part_2198_1270251742.1432651661843--
.
Author: Matthew Woehlke <mw_triad@users.sourceforge.net>
Date: Tue, 26 May 2015 12:09:14 -0400
Raw View
On 2015-05-20 21:14, Matthew Fioravante wrote:
> I've chosen to use [] instead of {} [...]
Given the syntax comments, I would encourage you to read the previous
thread(s). That said, I have to say I'm actually in favor of the []
syntax; it "feels" least likely to have parsing issues, and [] normally
being indexing operators, it makes sense to me to use them for
unpacking. (It probably also helps that I write the odd bit of Python,
and Python uses [] to write lists :-).)
> I've chosen to use ; instead of , to avoid confusion with the comma
> operator.
I strongly agree with using ';' to separate elements, since multiple
declarations should be permitted, but '[auto x, auto y]' clearly makes
no syntactic sense. That said, is ',' allowed inside the []'s at all? If
yes, what does it mean?
[auto x, y] = bar(); // forces decltype(x) == decltype(y)?
> We can also allow the user to specify a shorter list, with default values
> of void for the trailing elements not mentioned:
>
> [auto x] = foo(); //same as [auto x, void, void] = foo()
I'd be somewhat strongly inclined to follow Python, and not discard any
values. So the last item in the list becomes a tuple of whatever is left
over.
So, to take only the first value, you would write:
[auto x; void] = foo();
I also wonder if it should be an error if the number of arguments don't
match, and require '...' to allow an item to expand to a (partial)
tuple. For example:
// assume foo() -> tuple<int, double, int>
[auto x; void...] = foo(); // like above
[auto x; auto... y] = foo(); // decltype(y) == tuple<double, int>
The down side of course is that this (except the 'void...' case)
requires the compiler to know how many items are in the result. For
tuple this is probably easy. For "generic" types it may be harder, but I
imagine if necessary we could introduce a companion to std::get to
return the largest index that can be used with std::get, if we don't
already have ways to accomplish that.
> What do you think about such a feature?
As you may recall from (at least one of) the time(s) this came up
previously, I am in favor of this :-).
This may be implied anyway, but I'll say it explicitly; let's please
also support this in range-based for:
for ([auto key; auto value] : some_map) { ... }
--
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 http://groups.google.com/a/isocpp.org/group/std-proposals/.
.
Author: Nicol Bolas <jmckesson@gmail.com>
Date: Tue, 26 May 2015 11:10:11 -0700 (PDT)
Raw View
------=_Part_396_1479029013.1432663811455
Content-Type: multipart/alternative;
boundary="----=_Part_397_917407466.1432663811455"
------=_Part_397_917407466.1432663811455
Content-Type: text/plain; charset=UTF-8
If we're going to have special syntax for using multiple return values, I
would much rather we have actual multiple return value syntax, not
something built on `tuple`.
Using the `[]` syntax noted here, you could have matching return and
capture:
[int,float,double] foo()
{
return [5; 23.4f; 10447.023d];
}
double v{};
[auto x, float g, v] = foo();
The reason to want this to be a legitimate language feature is so that we
can have all of the aspects of return values still apply to returning
multiple values. Specifically, there's no reason we shouldn't be able to
have copy/move elision just because you want to have a function return
multiple values.
--
---
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 http://groups.google.com/a/isocpp.org/group/std-proposals/.
------=_Part_397_917407466.1432663811455
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">If we're going to have special syntax for using multiple r=
eturn values, I would much rather we have actual multiple return value synt=
ax, not something built on `tuple`.<br><br>Using the `[]` syntax noted here=
, you could have matching return and capture:<br><br><div class=3D"prettypr=
int" 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 class=3D"prettyprint"><div class=3D"subprettyprint"><span style=3D"co=
lor: #660;" class=3D"styled-by-prettify">[</span><span style=3D"color: #008=
;" class=3D"styled-by-prettify">int</span><span style=3D"color: #660;" clas=
s=3D"styled-by-prettify">,</span><span style=3D"color: #008;" class=3D"styl=
ed-by-prettify">float</span><span style=3D"color: #660;" 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"> foo</span>=
<span style=3D"color: #660;" class=3D"styled-by-prettify">()</span><span st=
yle=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;" class=3D"styled-by-prettify"><br> </span><span style=3D"color: =
#008;" class=3D"styled-by-prettify">return</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"style=
d-by-prettify">5</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: #066;" class=3D"styled-by-prettify">23.4f</span>=
<span style=3D"color: #660;" class=3D"styled-by-prettify">;</span><span sty=
le=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"col=
or: #066;" class=3D"styled-by-prettify">10447.023d</span><span style=3D"col=
or: #660;" class=3D"styled-by-prettify">];</span><span style=3D"color: #000=
;" class=3D"styled-by-prettify"><br></span><span style=3D"color: #660;" cla=
ss=3D"styled-by-prettify">}</span><span style=3D"color: #000;" class=3D"sty=
led-by-prettify"><br><br></span><span style=3D"color: #008;" class=3D"style=
d-by-prettify">double</span><span style=3D"color: #000;" class=3D"styled-by=
-prettify"> v</span><span style=3D"color: #660;" class=3D"styled-by-prettif=
y">{};</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br>=
</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: #000;" class=3D"styled-by-prettify"> x</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: #008;" class=
=3D"styled-by-prettify">float</span><span style=3D"color: #000;" class=3D"s=
tyled-by-prettify"> g</span><span style=3D"color: #660;" class=3D"styled-by=
-prettify">,</span><span style=3D"color: #000;" class=3D"styled-by-prettify=
"> v</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">=3D</span><span style=3D=
"color: #000;" class=3D"styled-by-prettify"> foo</span><span style=3D"color=
: #660;" class=3D"styled-by-prettify">();</span></div></code></div><br>The =
reason to want this to be a legitimate language feature is so that we can h=
ave all of the aspects of return values still apply to returning multiple v=
alues. Specifically, there's no reason we shouldn't be able to have copy/mo=
ve elision just because you want to have a function return multiple values.=
<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"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />
------=_Part_397_917407466.1432663811455--
------=_Part_396_1479029013.1432663811455--
.
Author: Matthew Fioravante <fmatthew5876@gmail.com>
Date: Tue, 26 May 2015 11:11:49 -0700 (PDT)
Raw View
------=_Part_4538_2062887079.1432663909572
Content-Type: multipart/alternative;
boundary="----=_Part_4539_1967139585.1432663909572"
------=_Part_4539_1967139585.1432663909572
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
>
> On Thursday, May 21, 2015 at 3:49:44 AM UTC-4, Morwenn wrote:
> While I don't really like the syntax (it's hard to make something short=
=20
> when you have to declare a type anyway), I want to say that I really much=
=20
> like the use of std::get to get the parameters. That means that any type=
=20
> compatible with std::get, such as std::pair or std::array, could be used=
=20
> for multi-valued return types. This is IMO better than forcing users to u=
se=20
> std::tuple everywhere and make some standard library functions returning=
=20
> std::pair work with the syntax out of the box.
>
This makes sense, but has some pitfalls when combined with Matthew W.'s=20
ideas (see below).
On Tuesday, May 26, 2015 at 10:47:41 AM UTC-4, P=C3=A9ter wrote:
>
> I'd also like to see this feature added to c++. I don't really like the=
=20
> proposed syntax either (the square brackets are out-of-place here, imo).=
=20
> The best would be to simply use=20
>
> int x;
> (x; void; auto d) =3D foo();
>
>
While I agree with you that this syntax seems better, I'm not a C++ parsing=
=20
expert and I don't know if such a syntax would be possible. If it is, I=20
would probably prefer it also over [].=20
=20
> but I guess that'd introduce parsing issues. How about:
>
> int x;
> auto (x; void; auto d) =3D foo();
>
>
Not sure this one is a good idea as it seems like a hijacking of the auto=
=20
keyword. auto is always used to declare a variable (or template parameter=
=20
if some new proposals are accepted). The () expression itself is not a=20
local variable so I don't think auto is appropriate.
This example doesn't create any new variables even though auto is used.
int x;
int y;
auto (x; y; void) =3D foo();
On Tuesday, May 26, 2015 at 12:09:27 PM UTC-4, Matthew Woehlke wrote:
>
> On 2015-05-20 21:14, Matthew Fioravante wrote:=20
> > I've chosen to use [] instead of {} [...]=20
>
> Given the syntax comments, I would encourage you to read the previous=20
> thread(s). That said, I have to say I'm actually in favor of the []=20
> syntax; it "feels" least likely to have parsing issues, and [] normally=
=20
> being indexing operators, it makes sense to me to use them for=20
> unpacking. (It probably also helps that I write the odd bit of Python,=20
> and Python uses [] to write lists :-).)=20
>
But python also uses () to define tuples. The () syntax to me seems more=20
natural but again I don't know it its possible with the current parsing=20
rules.
=20
>
> > I've chosen to use ; instead of , to avoid confusion with the comma=20
> > operator.=20
>
> I strongly agree with using ';' to separate elements, since multiple=20
> declarations should be permitted, but '[auto x, auto y]' clearly makes=20
> no syntactic sense. That said, is ',' allowed inside the []'s at all? If=
=20
> yes, what does it mean?=20
>
> [auto x, y] =3D bar(); // forces decltype(x) =3D=3D decltype(y)?=20
>
It should be equivalent to:
auto t =3D bar();
auto x, y =3D std::get<0>(t);
Which is currently an error because x is not initialized.
However you could do this:
[int x, y;void;void] =3D foo();
Which when decomposed like the last example compiles (but may not give you=
=20
what you want).
You could have some horrible thing like this, which would be allowed:
int& operator,(int& a, int& b) { return a; }
int x;
int y;
[ x,y; void; void] =3D foo(); //assignes std::get<0>(foo()) to x
=20
>
> > We can also allow the user to specify a shorter list, with default=20
> values=20
> > of void for the trailing elements not mentioned:=20
> >=20
> > [auto x] =3D foo(); //same as [auto x, void, void] =3D foo()=20
>
> I'd be somewhat strongly inclined to follow Python, and not discard any=
=20
> values. So the last item in the list becomes a tuple of whatever is left=
=20
> over.=20
>
> So, to take only the first value, you would write:=20
>
> [auto x; void] =3D foo();=20
>
> I also wonder if it should be an error if the number of arguments don't=
=20
> match, and require '...' to allow an item to expand to a (partial)=20
> tuple. For example: =20
>
> // assume foo() -> tuple<int, double, int>=20
> [auto x; void...] =3D foo(); // like above=20
> [auto x; auto... y] =3D foo(); // decltype(y) =3D=3D tuple<double, int>=
=20
>
>
I think this is better as its more explicit and ... is not too verbose. We=
=20
should also support support empty list as I believe this should be useful=
=20
for generic code. You can extract one parameter and pass along the others.
tuple<int,int> foo();
[auto x; auto y; auto... z] =3D foo();
//decltype(z) is tuple<>.
This feature conflicts with allowing this syntax to work with any std::get=
=20
compatible type. What type should auto... z be?
tuple<int,int> a();
array<int,2> b();
pair<int,int> c();
[auto xa; auto xva] =3D a(); //decltype(xva) is tuple<int>?
[auto xb; auto xvb] =3D b(); //decltype(xvb) is array<int,1>?
[auto xc; auto xvc] =3D c(); //What is decltype(xvc)???
Here is another generic code use case which is trickier if we are only=20
based on std::get().
Imagine we want to extract the second parameter, and pass long a=20
concatenated list of the first and the tail.=20
[auto first; auto second; auto... tail] =3D foo();
use(first);
auto params =3D concat({ first }, tail)
bar(params)
Such a thing is possible for tuple and array but not pair.=20
=20
> The down side of course is that this (except the 'void...' case)=20
> requires the compiler to know how many items are in the result. For=20
> tuple this is probably easy. For "generic" types it may be harder, but I=
=20
> imagine if necessary we could introduce a companion to std::get to=20
> return the largest index that can be used with std::get, if we don't=20
> already have ways to accomplish that.=20
>
This language feature is built ontop of std::get<> which itself is designed=
=20
for container types where we can dereference elements by index at compile=
=20
time. Calling std::get with an invalid index is a compiler error and thus=
=20
it should be possible to determine the valid index range at compile time=20
using SFINAE tricks.
> > What do you think about such a feature?=20
>
> As you may recall from (at least one of) the time(s) this came up=20
> previously, I am in favor of this :-).=20
>
> This may be implied anyway, but I'll say it explicitly; let's please=20
> also support this in range-based for:=20
>
> for ([auto key; auto value] : some_map) { ... }=20
>
This is one major use case of such a feature and hopefully it should fall=
=20
out automagically without any special provisions for it.
--=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 http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.
------=_Part_4539_1967139585.1432663909572
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><blockquote style=3D"margin: 0px 0px 0px 0.8ex; border-lef=
t: 1px solid rgb(204, 204, 204); padding-left: 1ex;" class=3D"gmail_quote">=
On Thursday, May 21, 2015 at 3:49:44 AM UTC-4, Morwenn wrote:<br>While
I don't really like the syntax (it's hard to make something short when=20
you have to declare a type anyway), I want to say that I really much=20
like the use of <span style=3D"font-family:courier new,monospace">std::get<=
/span> to get the parameters. That means that any type compatible with<span=
style=3D"font-family:courier new,monospace"> std::get</span>, such as <spa=
n style=3D"font-family:courier new,monospace">std::pair</span> or <span sty=
le=3D"font-family:courier new,monospace">std::array</span>, could be used f=
or multi-valued return types. This is IMO better than forcing users to use =
<span style=3D"font-family:courier new,monospace">std::tuple</span> everywh=
ere and make some standard library functions returning <span style=3D"font-=
family:courier new,monospace">std::pair</span> work with the syntax out of =
the box.<br></blockquote><br>This makes sense, but has some pitfalls when c=
ombined with Matthew W.'s ideas (see below).<br><br>On Tuesday, May 26, 201=
5 at 10:47:41 AM UTC-4, P=C3=A9ter wrote:<blockquote class=3D"gmail_quote" =
style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-l=
eft: 1ex;"><div dir=3D"ltr">I'd
also like to see this feature added to c++. I don't really like the=
=20
proposed syntax either (the square brackets are out-of-place here, imo).
The best would be to simply use <div><br><div style=3D"border:1px sol=
id rgb(187,187,187);word-wrap:break-word;background-color:rgb(250,250,250)"=
><code><div><span style=3D"color:#008">int</span><span style=3D"color:#000"=
> x</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">x</sp=
an><span style=3D"color:#660">;</span><span style=3D"color:#000"> </span><s=
pan style=3D"color:#008">void</span><span style=3D"color:#660">;</span><spa=
n style=3D"color:#000"> </span><span style=3D"color:#008">auto</span><span =
style=3D"color:#000"> d</span><span style=3D"color:#660">)</span><span styl=
e=3D"color:#000"> </span><span style=3D"color:#660">=3D</span><span style=
=3D"color:#000"> foo</span><span style=3D"color:#660">();</span><span style=
=3D"color:#000"><br></span></div></code></div><div><br></div></div></div></=
blockquote><div><br>While I agree with you that this syntax seems better, I=
'm not a C++ parsing expert and I don't know if such a syntax would be poss=
ible. If it is, I would probably prefer it also over []. <br></div><div>&nb=
sp;</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></div><div>but I guess that'd introduce parsing issues. How abo=
ut:<div><br></div><div style=3D"border:1px solid rgb(187,187,187);word-wrap=
:break-word;background-color:rgb(250,250,250)"><code><div><span style=3D"co=
lor:#008">int</span><span style=3D"color:#000"> x</span><span style=3D"colo=
r:#660">;</span><span style=3D"color:#000"><br></span><span style=3D"color:=
#008">auto</span><span style=3D"color:#000"> </span><span style=3D"color:#6=
60">(</span><span style=3D"color:#000">x</span><span style=3D"color:#660">;=
</span><span style=3D"color:#000"> </span><span style=3D"color:#008">void</=
span><span style=3D"color:#660">;</span><span style=3D"color:#000"> </span>=
<span style=3D"color:#008">auto</span><span style=3D"color:#000"> d</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"> foo</span><span =
style=3D"color:#660">();</span><span style=3D"color:#000"><br></span></div>=
</code></div><div><br></div></div></div></div></blockquote><div><br>Not sur=
e this one is a good idea as it seems like a hijacking of the auto keyword.=
auto is always used to declare a variable (or template parameter if some n=
ew proposals are accepted). The () expression itself is not a local variabl=
e so I don't think auto is appropriate.<br><br>This example doesn't create =
any new variables even though auto is used.<br><div class=3D"prettyprint" s=
tyle=3D"background-color: rgb(250, 250, 250); border-color: rgb(187, 187, 1=
87); border-style: solid; border-width: 1px; word-wrap: break-word;"><code =
class=3D"prettyprint"><div class=3D"subprettyprint"><span style=3D"color: #=
008;" class=3D"styled-by-prettify">int</span><span style=3D"color: #000;" c=
lass=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"><br></span><span style=3D"color: #008;" class=3D"styled-by-prett=
ify">int</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> y=
</span><span style=3D"color: #660;" class=3D"styled-by-prettify">;</span><s=
pan style=3D"color: #000;" class=3D"styled-by-prettify"><br></span><span st=
yle=3D"color: #008;" class=3D"styled-by-prettify">auto</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;" cla=
ss=3D"styled-by-prettify">x</span><span style=3D"color: #660;" class=3D"sty=
led-by-prettify">;</span><span style=3D"color: #000;" class=3D"styled-by-pr=
ettify"> y</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">void</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">=3D</span><span style=3D"color: #000;" cla=
ss=3D"styled-by-prettify"> foo</span><span style=3D"color: #660;" class=3D"=
styled-by-prettify">();</span><span style=3D"color: #000;" class=3D"styled-=
by-prettify"><br></span></div></code></div><br></div><br>On Tuesday, May 26=
, 2015 at 12:09:27 PM UTC-4, Matthew Woehlke wrote:<blockquote class=3D"gma=
il_quote" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid=
;padding-left: 1ex;">On 2015-05-20 21:14, Matthew Fioravante wrote:
<br>> I've chosen to use [] instead of {} [...]
<br>
<br>Given the syntax comments, I would encourage you to read the previous
<br>thread(s). That said, I have to say I'm actually in favor of the []
<br>syntax; it "feels" least likely to have parsing issues, and [] normally
<br>being indexing operators, it makes sense to me to use them for
<br>unpacking. (It probably also helps that I write the odd bit of Python,
<br>and Python uses [] to write lists :-).)
<br></blockquote><div><br>But python also uses () to define tuples. The () =
syntax to me seems more natural but again I don't know it its possible with=
the current parsing rules.<br> </div><blockquote class=3D"gmail_quote=
" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding=
-left: 1ex;">
<br>> I've chosen to use ; instead of , to avoid confusion with the comm=
a=20
<br>> operator.
<br>
<br>I strongly agree with using ';' to separate elements, since multiple
<br>declarations should be permitted, but '[auto x, auto y]' clearly makes
<br>no syntactic sense. That said, is ',' allowed inside the []'s at all? I=
f
<br>yes, what does it mean?
<br>
<br> [auto x, y] =3D bar(); // forces decltype(x) =3D=3D decltype(y)?
<br></blockquote><div><br>It should be equivalent to:<br><br><div class=3D"=
prettyprint" 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 class=3D"prettyprint"><div class=3D"subprettyprint"><span sty=
le=3D"color: #008;" class=3D"styled-by-prettify">auto</span><span style=3D"=
color: #000;" class=3D"styled-by-prettify"> t </span><span style=3D"color: =
#660;" class=3D"styled-by-prettify">=3D</span><span style=3D"color: #000;" =
class=3D"styled-by-prettify"> bar</span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">();</span><span style=3D"color: #000;" class=3D"sty=
led-by-prettify"><br></span><span style=3D"color: #008;" class=3D"styled-by=
-prettify">auto</span><span style=3D"color: #000;" class=3D"styled-by-prett=
ify"> x</span><span style=3D"color: #660;" class=3D"styled-by-prettify">,</=
span><span style=3D"color: #000;" class=3D"styled-by-prettify"> y </span><s=
pan style=3D"color: #660;" class=3D"styled-by-prettify">=3D</span><span sty=
le=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">get</span><span style=3D"color: #660;" c=
lass=3D"styled-by-prettify"><</span><span style=3D"color: #066;" class=
=3D"styled-by-prettify">0</span><span style=3D"color: #660;" class=3D"style=
d-by-prettify">>(</span><span style=3D"color: #000;" class=3D"styled-by-=
prettify">t</span><span style=3D"color: #660;" class=3D"styled-by-prettify"=
>);</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br></s=
pan></div></code></div><br>Which is currently an error because x is not ini=
tialized.<br><br>However you could do this:<br><br><div class=3D"prettyprin=
t" style=3D"background-color: rgb(250, 250, 250); border-color: rgb(187, 18=
7, 187); border-style: solid; border-width: 1px; word-wrap: break-word;"><c=
ode class=3D"prettyprint"><div class=3D"subprettyprint"><span style=3D"colo=
r: #660;" class=3D"styled-by-prettify">[</span><span style=3D"color: #008;"=
class=3D"styled-by-prettify">int</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"> x</span><span style=3D"color: #660;" class=3D"styl=
ed-by-prettify">,</span><span style=3D"color: #000;" class=3D"styled-by-pre=
ttify"> y</span><span style=3D"color: #660;" class=3D"styled-by-prettify">;=
</span><span style=3D"color: #008;" class=3D"styled-by-prettify">void</span=
><span style=3D"color: #660;" class=3D"styled-by-prettify">;</span><span st=
yle=3D"color: #008;" class=3D"styled-by-prettify">void</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;" cla=
ss=3D"styled-by-prettify">=3D</span><span style=3D"color: #000;" class=3D"s=
tyled-by-prettify"> foo</span><span style=3D"color: #660;" class=3D"styled-=
by-prettify">();</span><span style=3D"color: #000;" class=3D"styled-by-pret=
tify"><br></span></div></code></div><br>Which when decomposed like the last=
example compiles (but may not give you what you want).<br><br>You could ha=
ve some horrible thing like this, which would be allowed:<br><br><div class=
=3D"prettyprint" style=3D"background-color: rgb(250, 250, 250); border-colo=
r: rgb(187, 187, 187); border-style: solid; border-width: 1px; word-wrap: b=
reak-word;"><code class=3D"prettyprint"><div class=3D"subprettyprint"><span=
style=3D"color: #008;" class=3D"styled-by-prettify">int</span><span style=
=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: #00=
8;" class=3D"styled-by-prettify">operator</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"color: #660;" class=3D"sty=
led-by-prettify">&</span><span style=3D"color: #000;" class=3D"styled-b=
y-prettify"> a</span><span style=3D"color: #660;" class=3D"styled-by-pretti=
fy">,</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </sp=
an><span style=3D"color: #008;" class=3D"styled-by-prettify">int</span><spa=
n style=3D"color: #660;" class=3D"styled-by-prettify">&</span><span sty=
le=3D"color: #000;" class=3D"styled-by-prettify"> b</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: #660;" class=
=3D"styled-by-prettify">{</span><span style=3D"color: #000;" class=3D"style=
d-by-prettify"> </span><span style=3D"color: #008;" class=3D"styled-by-pret=
tify">return</span><span style=3D"color: #000;" class=3D"styled-by-prettify=
"> a</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"><br><br></span><span style=3D"col=
or: #008;" class=3D"styled-by-prettify">int</span><span style=3D"color: #00=
0;" class=3D"styled-by-prettify"> x</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></span><span style=3D"color: #008;" class=3D"styled-by-=
prettify">int</span><span style=3D"color: #000;" class=3D"styled-by-prettif=
y"> y</span><span style=3D"color: #660;" class=3D"styled-by-prettify">;</sp=
an><span style=3D"color: #000;" class=3D"styled-by-prettify"><br></span><sp=
an 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"colo=
r: #660;" class=3D"styled-by-prettify">,</span><span style=3D"color: #000;"=
class=3D"styled-by-prettify">y</span><span style=3D"color: #660;" class=3D=
"styled-by-prettify">;</span><span style=3D"color: #000;" class=3D"styled-b=
y-prettify"> </span><span style=3D"color: #008;" class=3D"styled-by-prettif=
y">void</span><span style=3D"color: #660;" class=3D"styled-by-prettify">;</=
span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><spa=
n style=3D"color: #008;" class=3D"styled-by-prettify">void</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: #660;"=
class=3D"styled-by-prettify">=3D</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"> foo</span><span style=3D"color: #660;" class=3D"st=
yled-by-prettify">();</span><span style=3D"color: #000;" class=3D"styled-by=
-prettify"> </span><span style=3D"color: #800;" class=3D"styled-by-prettify=
">//assignes std::get<0>(foo()) to x</span><span style=3D"color: #000=
;" class=3D"styled-by-prettify"><br></span></div></code></div><br> <br=
></div><blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.=
8ex;border-left: 1px #ccc solid;padding-left: 1ex;">
<br>> We can also allow the user to specify a shorter list, with default=
values=20
<br>> of void for the trailing elements not mentioned:
<br>>=20
<br>> [auto x] =3D foo(); //same as [auto x, void, void] =3D foo()
<br>
<br>I'd be somewhat strongly inclined to follow Python, and not discard any
<br>values. So the last item in the list becomes a tuple of whatever is lef=
t
<br>over.
<br>
<br>So, to take only the first value, you would write:
<br>
<br> [auto x; void] =3D foo();
<br>
<br>I also wonder if it should be an error if the number of arguments don't
<br>match, and require '...' to allow an item to expand to a (partial)
<br>tuple. For example:
<br>
<br> // assume foo() -> tuple<int, double, int>
<br> [auto x; void...] =3D foo(); // like above
<br> [auto x; auto... y] =3D foo(); // decltype(y) =3D=3D tuple<do=
uble, int>
<br>
<br></blockquote><div><br>I think this is better as its more explicit and .=
... is not too verbose. We should also support support empty list as I belie=
ve this should be useful for generic code. You can extract one parameter an=
d pass along the others.<br><br><div class=3D"prettyprint" style=3D"backgro=
und-color: rgb(250, 250, 250); border-color: rgb(187, 187, 187); border-sty=
le: solid; border-width: 1px; word-wrap: break-word;"><code class=3D"pretty=
print"><div class=3D"subprettyprint"><span style=3D"color: #000;" class=3D"=
styled-by-prettify">tuple</span><span style=3D"color: #660;" class=3D"style=
d-by-prettify"><</span><span style=3D"color: #008;" class=3D"styled-by-p=
rettify">int</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><sp=
an style=3D"color: #000;" class=3D"styled-by-prettify"> foo</span><span sty=
le=3D"color: #660;" class=3D"styled-by-prettify">();</span><span style=3D"c=
olor: #000;" class=3D"styled-by-prettify"><br><br></span><span style=3D"col=
or: #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"> x</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: #008;" class=3D"styled-by-prettify">a=
uto</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> y</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: #008;" class=3D"styled-by-prettify">auto</span><span style=3D"color: =
#660;" class=3D"styled-by-prettify">...</span><span style=3D"color: #000;" =
class=3D"styled-by-prettify"> z</span><span style=3D"color: #660;" class=3D=
"styled-by-prettify">]</span><span style=3D"color: #000;" class=3D"styled-b=
y-prettify"> </span><span style=3D"color: #660;" class=3D"styled-by-prettif=
y">=3D</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> foo=
</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: #800;" class=3D"styled-by-prettify">//decltype(z) is tuple&=
lt;>.</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><b=
r></span></div></code></div><br>This feature conflicts with allowing this s=
yntax to work with any std::get compatible type. What type should auto... z=
be?<br><br><div class=3D"prettyprint" style=3D"background-color: rgb(250, =
250, 250); border-color: rgb(187, 187, 187); border-style: solid; border-wi=
dth: 1px; word-wrap: break-word;"><code class=3D"prettyprint"><div class=3D=
"subprettyprint"><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: #008;" class=3D"styled-by-prettify">int</span><=
span style=3D"color: #660;" class=3D"styled-by-prettify">,</span><span styl=
e=3D"color: #008;" class=3D"styled-by-prettify">int</span><span style=3D"co=
lor: #660;" class=3D"styled-by-prettify">></span><span style=3D"color: #=
000;" class=3D"styled-by-prettify"> a</span><span style=3D"color: #660;" cl=
ass=3D"styled-by-prettify">();</span><span style=3D"color: #000;" class=3D"=
styled-by-prettify"><br>array</span><span style=3D"color: #660;" class=3D"s=
tyled-by-prettify"><</span><span style=3D"color: #008;" class=3D"styled-=
by-prettify">int</span><span style=3D"color: #660;" class=3D"styled-by-pret=
tify">,</span><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"> b</span><span sty=
le=3D"color: #660;" class=3D"styled-by-prettify">();</span><span style=3D"c=
olor: #000;" class=3D"styled-by-prettify"><br>pair</span><span style=3D"col=
or: #660;" class=3D"styled-by-prettify"><</span><span style=3D"color: #0=
08;" class=3D"styled-by-prettify">int</span><span style=3D"color: #660;" cl=
ass=3D"styled-by-prettify">,</span><span style=3D"color: #008;" class=3D"st=
yled-by-prettify">int</span><span style=3D"color: #660;" class=3D"styled-by=
-prettify">></span><span style=3D"color: #000;" class=3D"styled-by-prett=
ify"> c</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: #660;" class=3D"styled-by-prettify">[</span><spa=
n style=3D"color: #008;" class=3D"styled-by-prettify">auto</span><span styl=
e=3D"color: #000;" class=3D"styled-by-prettify"> xa</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">auto</span><span style=3D"color: #000;" class=3D"st=
yled-by-prettify"> xva</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: #660;" class=3D"styled-by-prettify">=3D</s=
pan><span style=3D"color: #000;" class=3D"styled-by-prettify"> a</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=
: #800;" class=3D"styled-by-prettify">//decltype(xva) is tuple<int>?<=
/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 sty=
le=3D"color: #008;" class=3D"styled-by-prettify">auto</span><span style=3D"=
color: #000;" class=3D"styled-by-prettify"> xb</span><span style=3D"color: =
#660;" class=3D"styled-by-prettify">;</span><span style=3D"color: #000;" cl=
ass=3D"styled-by-prettify"> </span><span style=3D"color: #008;" class=3D"st=
yled-by-prettify">auto</span><span style=3D"color: #000;" class=3D"styled-b=
y-prettify"> xvb</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: #660;" class=3D"styled-by-prettify">=3D</span><s=
pan style=3D"color: #000;" class=3D"styled-by-prettify"> b</span><span styl=
e=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: #800=
;" class=3D"styled-by-prettify">//decltype(xvb) is array<int,1>?</spa=
n><span style=3D"color: #000;" class=3D"styled-by-prettify"><br></span><spa=
n 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"co=
lor: #000;" class=3D"styled-by-prettify"> xc</span><span style=3D"color: #6=
60;" class=3D"styled-by-prettify">;</span><span style=3D"color: #000;" clas=
s=3D"styled-by-prettify"> </span><span style=3D"color: #008;" class=3D"styl=
ed-by-prettify">auto</span><span style=3D"color: #000;" class=3D"styled-by-=
prettify"> xvc</span><span style=3D"color: #660;" class=3D"styled-by-pretti=
fy">]</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </sp=
an><span style=3D"color: #660;" class=3D"styled-by-prettify">=3D</span><spa=
n style=3D"color: #000;" class=3D"styled-by-prettify"> c</span><span style=
=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: #800;=
" class=3D"styled-by-prettify">//What is decltype(xvc)???</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"><br></span></div></code></di=
v><br>Here is another generic code use case which is trickier if we are onl=
y based on std::get().<br>Imagine we want to extract the second param=
eter, and pass long a concatenated list of the first and the tail. <br><br>=
<div class=3D"prettyprint" style=3D"background-color: rgb(250, 250, 250); b=
order-color: rgb(187, 187, 187); border-style: solid; border-width: 1px; wo=
rd-wrap: break-word;"><code class=3D"prettyprint"><div class=3D"subprettypr=
int"><span style=3D"color: #660;" class=3D"styled-by-prettify">[</span><spa=
n style=3D"color: #008;" class=3D"styled-by-prettify">auto</span><span styl=
e=3D"color: #000;" class=3D"styled-by-prettify"> first</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;" cla=
ss=3D"styled-by-prettify">auto</span><span style=3D"color: #000;" class=3D"=
styled-by-prettify"> second</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: #008;" class=3D"styled-by-prettify">a=
uto</span><span style=3D"color: #660;" class=3D"styled-by-prettify">...</sp=
an><span style=3D"color: #000;" class=3D"styled-by-prettify"> tail</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">=3D</span><span style=3D"color: #000;=
" class=3D"styled-by-prettify"> foo</span><span style=3D"color: #660;" clas=
s=3D"styled-by-prettify">();</span><span style=3D"color: #000;" class=3D"st=
yled-by-prettify"><br></span><span style=3D"color: #008;" class=3D"styled-b=
y-prettify">use</span><span style=3D"color: #660;" class=3D"styled-by-prett=
ify">(</span><span style=3D"color: #000;" class=3D"styled-by-prettify">firs=
t</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: #008;" class=3D"styled-by-prettify">auto</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color=
: #008;" class=3D"styled-by-prettify">params</span><span style=3D"color: #0=
00;" class=3D"styled-by-prettify"> </span><span style=3D"color: #660;" clas=
s=3D"styled-by-prettify">=3D</span><span style=3D"color: #000;" class=3D"st=
yled-by-prettify"> concat</span><span style=3D"color: #660;" class=3D"style=
d-by-prettify">({</span><span style=3D"color: #000;" class=3D"styled-by-pre=
ttify"> first </span><span style=3D"color: #660;" class=3D"styled-by-pretti=
fy">},</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> tai=
l</span><span style=3D"color: #660;" class=3D"styled-by-prettify">)</span><=
span style=3D"color: #000;" class=3D"styled-by-prettify"><br>bar</span><spa=
n style=3D"color: #660;" class=3D"styled-by-prettify">(</span><span style=
=3D"color: #008;" class=3D"styled-by-prettify">params</span><span style=3D"=
color: #660;" class=3D"styled-by-prettify">)</span><span style=3D"color: #0=
00;" class=3D"styled-by-prettify"><br></span></div></code></div><br>Such a =
thing is possible for tuple and array but not pair. <br></div><div> </=
div><blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex=
;border-left: 1px #ccc solid;padding-left: 1ex;">The down side of course is=
that this (except the 'void...' case)
<br>requires the compiler to know how many items are in the result. For
<br>tuple this is probably easy. For "generic" types it may be harder, but =
I
<br>imagine if necessary we could introduce a companion to std::get to
<br>return the largest index that can be used with std::get, if we don't
<br>already have ways to accomplish that.
<br></blockquote><div><br>This language feature is built ontop of std::get&=
lt;> which itself is designed for container types where we can dereferen=
ce elements by index at compile time. Calling std::get with an invalid inde=
x is a compiler error and thus it should be possible to determine the valid=
index range at compile time using SFINAE tricks.<br><br></div><blockquote =
class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1p=
x #ccc solid;padding-left: 1ex;">
<br>> What do you think about such a feature?
<br>
<br>As you may recall from (at least one of) the time(s) this came up
<br>previously, I am in favor of this :-).
<br>
<br>This may be implied anyway, but I'll say it explicitly; let's please
<br>also support this in range-based for:
<br>
<br> for ([auto key; auto value] : some_map) { ... }
<br></blockquote><div><br>This is one major use case of such a feature and =
hopefully it should fall out automagically without any special provisions f=
or it.<br><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"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />
------=_Part_4539_1967139585.1432663909572--
------=_Part_4538_2062887079.1432663909572--
.
Author: Matthew Fioravante <fmatthew5876@gmail.com>
Date: Tue, 26 May 2015 11:21:31 -0700 (PDT)
Raw View
------=_Part_4516_1836884468.1432664491043
Content-Type: multipart/alternative;
boundary="----=_Part_4517_292344404.1432664491043"
------=_Part_4517_292344404.1432664491043
Content-Type: text/plain; charset=UTF-8
On Tuesday, May 26, 2015 at 2:10:11 PM UTC-4, Nicol Bolas wrote:
>
> If we're going to have special syntax for using multiple return values, I
> would much rather we have actual multiple return value syntax, not
> something built on `tuple`.
>
> Using the `[]` syntax noted here, you could have matching return and
> capture:
>
> [int,float,double] foo()
> {
> return [5; 23.4f; 10447.023d];
> }
>
> double v{};
> [auto x, float g, v] = foo();
>
>
I'd probably still use braces in your return statement for initialization.
[int,float,double] foo()
{
return {5, 23.4f, 10447.023d};
}
double v{};
[auto x; float g; v] = foo();
The idea is that [int,float,double] is shorthand for some type (maybe
tuple) and in the return statement you are just initializing it using the
same old initialization rules. If we allow return [x;y;z...] then we have
to define all kinds of rules for how this yet another initialization syntax
works.
> The reason to want this to be a legitimate language feature is so that we
> can have all of the aspects of return values still apply to returning
> multiple values. Specifically, there's no reason we shouldn't be able to
> have copy/move elision just because you want to have a function return
> multiple values.
>
Your proposed type specification syntax could just be syntactic sugar for
tuple. This would automatically give support to any interface that already
returns a tuple and generic code that works with tuples.
Is there any reason why [int,float,double] should be a new type different
than tuple<int,float,double>?
//syntactic sugar for tuple<int,float,double> foo()
[int,float,double] foo();
//Extract the first value, and store the tail in a tuple<float,double>
[auto x; auto... yz] = foo();
//Extract the values of yz later.
[auto y; auto z] = yz;
//Construct a tuple directly using new syntax
//Different from lambda because the [] contains only a list of types, not
variable names
auto xyz = [int,float,double]();
--
---
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 http://groups.google.com/a/isocpp.org/group/std-proposals/.
------=_Part_4517_292344404.1432664491043
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><br><br>On Tuesday, May 26, 2015 at 2:10:11 PM UTC-4, Nico=
l 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"=
>If we're going to have special syntax for using multiple return values, I =
would much rather we have actual multiple return value syntax, not somethin=
g built on `tuple`.<br><br>Using the `[]` syntax noted here, you could have=
matching return and capture:<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:#660">[</span><span =
style=3D"color:#008">int</span><span style=3D"color:#660">,</span><span sty=
le=3D"color:#008">float</span><span style=3D"color:#660">,</span><span styl=
e=3D"color:#008">double</span><span style=3D"color:#660">]</span><span styl=
e=3D"color:#000"> foo</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><span style=3D"color:#008">return</span><=
span style=3D"color:#000"> </span><span style=3D"color:#660">[</span><span =
style=3D"color:#066">5</span><span style=3D"color:#660">;</span><span style=
=3D"color:#000"> </span><span style=3D"color:#066">23.4f</span><span style=
=3D"color:#660">;</span><span style=3D"color:#000"> </span><span style=3D"c=
olor:#066">10447.023d</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><br></span><span style=3D"color:#008">double</span><spa=
n style=3D"color:#000"> v</span><span style=3D"color:#660">{};</span><span =
style=3D"color:#000"><br></span><span style=3D"color:#660">[</span><span st=
yle=3D"color:#008">auto</span><span style=3D"color:#000"> x</span><span sty=
le=3D"color:#660">,</span><span style=3D"color:#000"> </span><span style=3D=
"color:#008">float</span><span style=3D"color:#000"> g</span><span style=3D=
"color:#660">,</span><span style=3D"color:#000"> v</span><span style=3D"col=
or:#660">]</span><span style=3D"color:#000"> </span><span style=3D"color:#6=
60">=3D</span><span style=3D"color:#000"> foo</span><span style=3D"color:#6=
60">();</span></div></code></div><br></div></blockquote><div><br>I'd probab=
ly still use braces in your return statement for initialization.<br><br><di=
v 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:#660">[</span><span style=3D"color:#008">int</span><span sty=
le=3D"color:#660">,</span><span style=3D"color:#008">float</span><span styl=
e=3D"color:#660">,</span><span style=3D"color:#008">double</span><span styl=
e=3D"color:#660">]</span><span style=3D"color:#000"> foo</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><span =
style=3D"color:#008">return</span><span style=3D"color:#000"> </span><span =
style=3D"color:#660">{</span><span style=3D"color:#066">5</span><span style=
=3D"color:#660">,</span><span style=3D"color:#000"> </span><span style=3D"c=
olor:#066">23.4f</span><span style=3D"color:#660">,</span><span style=3D"co=
lor:#000"> </span><span style=3D"color:#066">10447.023d</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><br></span><span sty=
le=3D"color:#008">double</span><span style=3D"color:#000"> v</span><span st=
yle=3D"color:#660">{};</span><span style=3D"color:#000"><br></span><span st=
yle=3D"color:#660">[</span><span style=3D"color:#008">auto</span><span styl=
e=3D"color:#000"> x</span><span style=3D"color:#660">;</span><span style=3D=
"color:#000"> </span><span style=3D"color:#008">float</span><span style=3D"=
color:#000"> g</span><span style=3D"color:#660">;</span><span style=3D"colo=
r:#000"> v</span><span style=3D"color:#660">]</span><span style=3D"color:#0=
00"> </span><span style=3D"color:#660">=3D</span><span style=3D"color:#000"=
> foo</span><span style=3D"color:#660">();</span></div></code></div><br>The=
idea is that [int,float,double] is shorthand for some type (maybe tuple)&n=
bsp; and in the return statement you are just initializing it using the sam=
e old initialization rules. If we allow return [x;y;z...] then we have to d=
efine all kinds of rules for how this yet another initialization syntax wor=
ks.<br> </div><blockquote class=3D"gmail_quote" style=3D"margin: 0;mar=
gin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D=
"ltr">The reason to want this to be a legitimate language feature is so tha=
t we can have all of the aspects of return values still apply to returning =
multiple values. Specifically, there's no reason we shouldn't be able to ha=
ve copy/move elision just because you want to have a function return multip=
le values.<br></div></blockquote><div><br>Your proposed type specification =
syntax could just be syntactic sugar for tuple. This would automatically gi=
ve support to any interface that already returns a tuple and generic code t=
hat works with tuples. <br><br>Is there any reason why [int,float,dou=
ble] should be a new type different than tuple<int,float,double>?<br>=
<br><code></code><div class=3D"prettyprint" style=3D"background-color: rgb(=
250, 250, 250); border-color: rgb(187, 187, 187); border-style: solid; bord=
er-width: 1px; word-wrap: break-word;"><code class=3D"prettyprint"><div cla=
ss=3D"subprettyprint"><span style=3D"color: #800;" class=3D"styled-by-prett=
ify">//syntactic sugar for tuple<int,float,double> foo()</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=
: #008;" class=3D"styled-by-prettify">int</span><span style=3D"color: #660;=
" class=3D"styled-by-prettify">,</span><span style=3D"color: #008;" class=
=3D"styled-by-prettify">float</span><span style=3D"color: #660;" class=3D"s=
tyled-by-prettify">,</span><span style=3D"color: #008;" class=3D"styled-by-=
prettify">double</span><span style=3D"color: #660;" class=3D"styled-by-pret=
tify">]</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> fo=
o</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: #800;" class=3D"styled-by-prettify">//Extract the firs=
t value, and store the tail in a tuple<float,double></span><span styl=
e=3D"color: #000;" class=3D"styled-by-prettify"><br></span><span style=3D"c=
olor: #660;" class=3D"styled-by-prettify">[</span><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"s=
tyled-by-prettify">;</span><span style=3D"color: #000;" 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 style=3D"color: #000;" class=3D"styled-by-prettify"> yz</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">=3D</span><span style=3D"color: #000;=
" class=3D"styled-by-prettify"> foo</span><span style=3D"color: #660;" clas=
s=3D"styled-by-prettify">();</span><span style=3D"color: #000;" class=3D"st=
yled-by-prettify"><br></span><span style=3D"color: #800;" class=3D"styled-b=
y-prettify">//Extract the values of yz later.</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: #008;" class=3D"=
styled-by-prettify">auto</span><span style=3D"color: #000;" class=3D"styled=
-by-prettify"> y</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: #008;" class=3D"styled-by-prettify">auto</span><=
span style=3D"color: #000;" class=3D"styled-by-prettify"> z</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: #660;=
" class=3D"styled-by-prettify">=3D</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"> yz</span><span style=3D"color: #660;" class=3D"sty=
led-by-prettify">;</span><span style=3D"color: #000;" class=3D"styled-by-pr=
ettify"><br><br></span><span style=3D"color: #800;" class=3D"styled-by-pret=
tify">//Construct a tuple directly using new syntax</span><span style=3D"co=
lor: #000;" class=3D"styled-by-prettify"><br></span><span style=3D"color: #=
800;" class=3D"styled-by-prettify">//Different from lambda because the [] c=
ontains only a list of types, not variable names</span><span style=3D"color=
: #000;" class=3D"styled-by-prettify"><br></span><span style=3D"color: #008=
;" class=3D"styled-by-prettify">auto</span><span style=3D"color: #000;" cla=
ss=3D"styled-by-prettify"> xyz </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-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: #008;" class=3D"styled-by-prettify">float</span><span st=
yle=3D"color: #660;" class=3D"styled-by-prettify">,</span><span style=3D"co=
lor: #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"><br><br></span></div></code></div><br><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"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />
------=_Part_4517_292344404.1432664491043--
------=_Part_4516_1836884468.1432664491043--
.
Author: Matthew Woehlke <mw_triad@users.sourceforge.net>
Date: Tue, 26 May 2015 14:23:56 -0400
Raw View
On 2015-05-26 14:10, Nicol Bolas wrote:
> If we're going to have special syntax for using multiple return values, I
> would much rather we have actual multiple return value syntax, not
> something built on `tuple`.
>
> The reason to want this to be a legitimate language feature is so that we
> can have all of the aspects of return values still apply to returning
> multiple values. Specifically, there's no reason we shouldn't be able to
> have copy/move elision just because you want to have a function return
> multiple values.
Is there a reason this is not possible with returning std::tuple? Is
there a reason we should not support unpacking of e.g. std::pair,
std::tuple as return values? (In particular I would like std::pair
unpacking for the sake of API's that already return a std::pair, where
unpacking would make sense. Like std::map::iterator.)
Put differently, is there a reason this needs to be part of the initial
proposal rather than a follow-on proposal? (That said, I *would* be in
favor of a simplified mechanism for returning multiple values;
std::tuple is... aesthetically challenged :-).)
--
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 http://groups.google.com/a/isocpp.org/group/std-proposals/.
.
Author: Matthew Fioravante <fmatthew5876@gmail.com>
Date: Tue, 26 May 2015 11:29:43 -0700 (PDT)
Raw View
------=_Part_4703_191647805.1432664983717
Content-Type: multipart/alternative;
boundary="----=_Part_4704_1946671782.1432664983718"
------=_Part_4704_1946671782.1432664983718
Content-Type: text/plain; charset=UTF-8
On Tuesday, May 26, 2015 at 2:24:22 PM UTC-4, Matthew Woehlke wrote:
>
> On 2015-05-26 14:10, Nicol Bolas wrote:
> > If we're going to have special syntax for using multiple return values,
> I
> > would much rather we have actual multiple return value syntax, not
> > something built on `tuple`.
> >
> > The reason to want this to be a legitimate language feature is so that
> we
> > can have all of the aspects of return values still apply to returning
> > multiple values. Specifically, there's no reason we shouldn't be able to
> > have copy/move elision just because you want to have a function return
> > multiple values.
>
> Is there a reason this is not possible with returning std::tuple? Is
> there a reason we should not support unpacking of e.g. std::pair,
> std::tuple as return values?
std::pair<X,Y> is convertible to std::tuple<X,Y>, so we could allow the
syntax to perform a conversion
std::pair<int,int> foo();
[auto x; auto y] = foo();
//is like
auto p = foo();
std::tuple<int,int> t = std::move(p);
auto x = std::get<0>(t);
auto y = std::get<1>(t);
> (In particular I would like std::pair
> unpacking for the sake of API's that already return a std::pair, where
> unpacking would make sense. Like std::map::iterator.)
>
> Put differently, is there a reason this needs to be part of the initial
> proposal rather than a follow-on proposal? (That said, I *would* be in
> favor of a simplified mechanism for returning multiple values;
> std::tuple is... aesthetically challenged :-).)
>
I agree std::tuple is ugly is somewhat non-obvious for beginners. Having a
syntax for defining multiple return functions and also capturing the values
would probably be the way to go.
--
---
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 http://groups.google.com/a/isocpp.org/group/std-proposals/.
------=_Part_4704_1946671782.1432664983718
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><br><br>On Tuesday, May 26, 2015 at 2:24:22 PM UTC-4, Matt=
hew Woehlke wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;marg=
in-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">On 2015-05-2=
6 14:10, Nicol Bolas wrote:
<br>> If we're going to have special syntax for using multiple return va=
lues, I=20
<br>> would much rather we have actual multiple return value syntax, not=
=20
<br>> something built on `tuple`.
<br>>=20
<br>> The reason to want this to be a legitimate language feature is so =
that we=20
<br>> can have all of the aspects of return values still apply to return=
ing=20
<br>> multiple values. Specifically, there's no reason we shouldn't be a=
ble to=20
<br>> have copy/move elision just because you want to have a function re=
turn=20
<br>> multiple values.
<br>
<br>Is there a reason this is not possible with returning std::tuple? Is
<br>there a reason we should not support unpacking of e.g. std::pair,
<br>std::tuple as return values? </blockquote><div><br>std::pair<X,Y>=
is convertible to std::tuple<X,Y>, so we could allow the syntax to p=
erform a conversion<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">std</span><span style=3D"color: #660;" class=3D"styled-by-pr=
ettify">::</span><span style=3D"color: #000;" class=3D"styled-by-prettify">=
pair</span><span style=3D"color: #660;" class=3D"styled-by-prettify"><</=
span><span style=3D"color: #008;" class=3D"styled-by-prettify">int</span><s=
pan 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: #0=
00;" class=3D"styled-by-prettify"> foo</span><span style=3D"color: #660;" c=
lass=3D"styled-by-prettify">();</span><span style=3D"color: #000;" class=3D=
"styled-by-prettify"><br></span><span style=3D"color: #660;" class=3D"style=
d-by-prettify">[</span><span style=3D"color: #008;" class=3D"styled-by-pret=
tify">auto</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 sty=
le=3D"color: #008;" class=3D"styled-by-prettify">auto</span><span style=3D"=
color: #000;" class=3D"styled-by-prettify"> y</span><span style=3D"color: #=
660;" class=3D"styled-by-prettify">]</span><span style=3D"color: #000;" cla=
ss=3D"styled-by-prettify"> </span><span style=3D"color: #660;" class=3D"sty=
led-by-prettify">=3D</span><span style=3D"color: #000;" class=3D"styled-by-=
prettify"> foo</span><span style=3D"color: #660;" class=3D"styled-by-pretti=
fy">();</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br=
><br></span><span style=3D"color: #800;" class=3D"styled-by-prettify">//is =
like</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br></=
span><span style=3D"color: #008;" class=3D"styled-by-prettify">auto</span><=
span style=3D"color: #000;" class=3D"styled-by-prettify"> p </span><span st=
yle=3D"color: #660;" class=3D"styled-by-prettify">=3D</span><span style=3D"=
color: #000;" class=3D"styled-by-prettify"> foo</span><span style=3D"color:=
#660;" class=3D"styled-by-prettify">();</span><span style=3D"color: #000;"=
class=3D"styled-by-prettify"><br>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">tuple</span><span style=3D"color: #660;" class=3D"styled=
-by-prettify"><</span><span style=3D"color: #008;" class=3D"styled-by-pr=
ettify">int</span><span style=3D"color: #660;" class=3D"styled-by-prettify"=
>,</span><span style=3D"color: #008;" class=3D"styled-by-prettify">int</spa=
n><span style=3D"color: #660;" class=3D"styled-by-prettify">></span><spa=
n style=3D"color: #000;" class=3D"styled-by-prettify"> t </span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">=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: #000;" cla=
ss=3D"styled-by-prettify">move</span><span style=3D"color: #660;" class=3D"=
styled-by-prettify">(</span><span style=3D"color: #000;" class=3D"styled-by=
-prettify">p</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: #008;" class=3D"styled-by-prettify">auto</span><=
span style=3D"color: #000;" class=3D"styled-by-prettify"> x </span><span st=
yle=3D"color: #660;" class=3D"styled-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-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"st=
yled-by-prettify">0</span><span style=3D"color: #660;" class=3D"styled-by-p=
rettify">>(</span><span style=3D"color: #000;" class=3D"styled-by-pretti=
fy">t</span><span style=3D"color: #660;" class=3D"styled-by-prettify">);</s=
pan><span style=3D"color: #000;" class=3D"styled-by-prettify"><br></span><s=
pan style=3D"color: #008;" class=3D"styled-by-prettify">auto</span><span st=
yle=3D"color: #000;" class=3D"styled-by-prettify"> y </span><span style=3D"=
color: #660;" class=3D"styled-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-prettify">::</span><span style=3D"color: #008;" class=
=3D"styled-by-prettify">get</span><span style=3D"color: #660;" class=3D"sty=
led-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">t</=
span><span style=3D"color: #660;" class=3D"styled-by-prettify">);</span><sp=
an style=3D"color: #000;" class=3D"styled-by-prettify"><br><br></span></div=
></code></div><br><br> </div><blockquote class=3D"gmail_quote" style=
=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: =
1ex;">(In particular I would like std::pair
<br>unpacking for the sake of API's that already return a std::pair, where
<br>unpacking would make sense. Like std::map::iterator.)
<br>
<br>Put differently, is there a reason this needs to be part of the initial
<br>proposal rather than a follow-on proposal? (That said, I *would* be in
<br>favor of a simplified mechanism for returning multiple values;
<br>std::tuple is... aesthetically challenged :-).)
<br></blockquote><div><br>I agree std::tuple is ugly is somewhat non-obviou=
s for beginners. Having a syntax for defining multiple return functions and=
also capturing the values would probably be the way to go.<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"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />
------=_Part_4704_1946671782.1432664983718--
------=_Part_4703_191647805.1432664983717--
.
Author: Matthew Woehlke <mw_triad@users.sourceforge.net>
Date: Tue, 26 May 2015 14:50:46 -0400
Raw View
On 2015-05-26 14:11, Matthew Fioravante wrote:
> On Tuesday, May 26, 2015 at 12:09:27 PM UTC-4, Matthew Woehlke wrote:
>> On 2015-05-20 21:14, Matthew Fioravante wrote:
>>> I've chosen to use [] instead of {} [...]
>>
>> Given the syntax comments, I would encourage you to read the previous
>> thread(s). That said, I have to say I'm actually in favor of the []
>> syntax; it "feels" least likely to have parsing issues, and [] normally
>> being indexing operators, it makes sense to me to use them for
>> unpacking. (It probably also helps that I write the odd bit of Python,
>> and Python uses [] to write lists :-).)
>
> But python also uses () to define tuples. The () syntax to me seems more
> natural but again I don't know it its possible with the current parsing
> rules.
True :-). I'm not wedded to []'s (I could see ()'s too), it's more that
they don't *bother* me, the way they seem to bother some folks. Also
that it "feels" like they would be the easiest to parse without
additional typing or syntax ambiguities.
>>> I've chosen to use ; instead of , to avoid confusion with the comma
>>> operator.
>>
>> I strongly agree with using ';' to separate elements, since multiple
>> declarations should be permitted, but '[auto x, auto y]' clearly makes
>> no syntactic sense. That said, is ',' allowed inside the []'s at all? If
>> yes, what does it mean?
>>
>> [auto x, y] = bar(); // forces decltype(x) == decltype(y)?
>
> It should be equivalent to:
>
> auto t = bar();
> auto x, y = std::get<0>(t);
>
> Which is currently an error because x is not initialized.
Riiiight. That seems weird. I was thinking:
auto&& __temp = bar();
auto x = get<0>(__temp), y = get<1>(__temp);
....which anyway I'm not sure if that's legal (at least not for 'auto'),
but seems like a reasonable way to parse the above input. I'd lean
toward either that, or just make ',' (or at least 'a declaration
declaring more than one variable') an error in this context.
> You could have some horrible thing like this, which would be allowed:
>
> int& operator,(int& a, int& b) { return a; }
>
> int x;
> int y;
> [ x,y; void; void] = foo(); //assignes std::get<0>(foo()) to x
Well, yes, but that's just abusing an lvalue expression :-). We'd have
to explicitly forbid that, which doesn't seem worthwhile.
>> I'd be somewhat strongly inclined to follow Python, and not discard any
>> values. So the last item in the list becomes a tuple of whatever is left
>> over.
>
> This feature conflicts with allowing this syntax to work with any std::get
> compatible type. What type should auto... z be?
I'd say 'tuple'. It makes sense for 'tuple', and it makes sense for
weird things (e.g. some struct with std::get to get each member by
index) which otherwise would require the compiler to synthesize a new
type on the spot (which... sounds like a tuple anyway).
If we implemented it as, say, a new std::get<size_t from, size_t to>,
users would be able to provide partial specializations to override that
default behavior (and STL could do so for e.g. std::array). The
"default" would return a tuple of the specified values.
> tuple<int,int> a();
> array<int,2> b();
> pair<int,int> c();
>
> [auto xa; auto xva] = a(); //decltype(xva) is tuple<int>?
> [auto xb; auto xvb] = b(); //decltype(xvb) is array<int,1>?
> [auto xc; auto xvc] = c(); //What is decltype(xvc)???
Hmm... this seems like a good reason to require '...'. Then, only '...'
may consume multiple values (presuming we're going with the 'must
explicitly consume everything' rule), and a '...' *always* has a
multi-valued type, as above, even if there is only a single remaining value.
> Here is another generic code use case which is trickier if we are only
> based on std::get().
> Imagine we want to extract the second parameter, and pass long a
> concatenated list of the first and the tail.
>
> [auto first; auto second; auto... tail] = foo();
> use(first);
> auto params = concat({ first }, tail)
> bar(params)
>
> Such a thing is possible for tuple and array but not pair.
If 'auto...' can be empty, why would this not work? (In fact, why would
it work differently for tuple<T1, T2> than pair<T1, T2>?)
>> The down side of course is that this (except the 'void...' case)
>> requires the compiler to know how many items are in the result. For
>> tuple this is probably easy. For "generic" types it may be harder, but I
>> imagine if necessary we could introduce a companion to std::get to
>> return the largest index that can be used with std::get, if we don't
>> already have ways to accomplish that.
>
> This language feature is built ontop of std::get<> which itself is designed
> for container types where we can dereference elements by index at compile
> time. Calling std::get with an invalid index is a compiler error and thus
> it should be possible to determine the valid index range at compile time
> using SFINAE tricks.
Okay... inelegant, but works :-). Considering that the compiler should
only need to inspect one more index than the number of assignments that
are being emitted, it may even be not inefficient.
>> This may be implied anyway, but I'll say it explicitly; let's please
>> also support this in range-based for:
>>
>> for ([auto key; auto value] : some_map) { ... }
>
> This is one major use case of such a feature and hopefully it should fall
> out automagically without any special provisions for it.
It might :-). It depends on how firm the "as-if" rule is that
range-based for involves an assignment. (Well, that may be more a case
of how compilers implement range-based for, but this feels like
something that could possibly be resolved in a DR if necessary, assuming
the proposal is accepted without explicitly acknowledging this case.
Also, I suspect compilers would tend to implement it even if the
standard didn't technically require it.)
Disclosure: I haven't looked up the standardese for how range-based for
is specified.
--
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 http://groups.google.com/a/isocpp.org/group/std-proposals/.
.
Author: hun.nemethpeter@gmail.com
Date: Tue, 26 May 2015 12:04:14 -0700 (PDT)
Raw View
------=_Part_5426_1266166845.1432667054645
Content-Type: multipart/alternative;
boundary="----=_Part_5427_1050705792.1432667054645"
------=_Part_5427_1050705792.1432667054645
Content-Type: text/plain; charset=UTF-8
I think we need a parameter struct like thing. A struct with a parameter
list syntax, something like:
// return type is a parameter-struct
struct (int a, int b, double) foo() {
return { 1, 2, 3.0 };
}
struct Test : decltype(foo()) // inherit from a parameter-struct
{
};
int main() {
int a = foo().a;
int b = foo().b;
int c = foo().member2; // unnamed member got a member + index name
int ai = foo().get<0>(); // auto generated getter
int bi = foo().get<1>();
double c = foo().get<2>();
foo().set<1>(2).get<1>(); // auto generated setter, returning *this
}
Peter
On Thursday, May 21, 2015 at 3:14:30 AM UTC+2, Matthew Fioravante wrote:
>
> So this idea came out of the number parsing thread. Many languages like
> python have support for functions returning multiple values.
>
> In C++, one option we have currently is this:
>
> std::tuple<int,float,double> foo();
>
> int x;
> double d;
> std::tie(x, std::ignore, d) = foo();
>
> This works but it has a lot of problems:
> - We have to declare the receiving variables beforehand. This means they
> have to be default constructed and then assigned and we cannot use auto.
> - Its overly verbose and clumsy to use. First we have to declare the
> variables, then we need 8 character std::tie and 11 character std::ignore.
> - tuple and tie are not as well known to beginners. A "standard practice"
> for capturing multiple values would be better as a core language feature
> than a library feature.
>
> So one solution would be to invent a new syntax:
> int x;
> [x; void; auto d] = foo();
>
> Which is the equivalent of:
> int x;
> auto _t = foo();
> x = std::get<0>(std::move(_t));
> auto d = std::get<2>(std::move(_t));
>
> Each element in this "assignment list" corresponds to a element of a tuple
> of the right hand side of the expression. Each element can be one of:
> - An lvalue expression: the resulting lvalue is assigned with operator=()
> to the corresponding tuple element.
> - void: the corresponding tuple element is ignored
> - A local variable declaration. A local variable is created and
> constructed with the corresponding tuple element.
>
> I've chosen to use [] instead of {} because so far braces always introduce
> a scope and in this example, d which is created inside the braces actually
> lives in the outer scope.
> I've chosen to use ; instead of , to avoid confusion with the comma
> operator.
>
> We can also allow the user to specify a shorter list, with default values
> of void for the trailing elements not mentioned:
>
> [auto x] = foo(); //same as [auto x, void, void] = foo()
>
> What do you think about such a feature?
>
--
---
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 http://groups.google.com/a/isocpp.org/group/std-proposals/.
------=_Part_5427_1050705792.1432667054645
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">I think we need a parameter struct like thing. A struct wi=
th a parameter list syntax, something like:<br><br><div class=3D"prettyprin=
t" style=3D"background-color: rgb(250, 250, 250); border-color: rgb(187, 18=
7, 187); border-style: solid; border-width: 1px; word-wrap: break-word;"><c=
ode class=3D"prettyprint"><div class=3D"subprettyprint"><span style=3D"colo=
r: #800;" class=3D"styled-by-prettify">// return type is a parameter-struct=
</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br></span=
><span style=3D"color: #008;" class=3D"styled-by-prettify">struct</span><sp=
an 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">int</span><span style=3D"color: #000;=
" class=3D"styled-by-prettify"> a</span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">,</span><span style=3D"color: #000;" class=3D"style=
d-by-prettify"> </span><span style=3D"color: #008;" class=3D"styled-b=
y-prettify">int</span><span style=3D"color: #000;" class=3D"styled-by-prett=
ify"> b</span><span style=3D"color: #660;" class=3D"styled-by-prettify">,</=
span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><spa=
n style=3D"color: #008;" class=3D"styled-by-prettify">double</span><span st=
yle=3D"color: #660;" class=3D"styled-by-prettify">)</span><span style=3D"co=
lor: #000;" class=3D"styled-by-prettify"> foo</span><span style=3D"color: #=
660;" class=3D"styled-by-prettify">()</span><span style=3D"color: #000;" cl=
ass=3D"styled-by-prettify"> </span><span style=3D"color: #660;" class=3D"st=
yled-by-prettify">{</span><span style=3D"color: #000;" class=3D"styled-by-p=
rettify"><br> </span><span style=3D"color: #008;" class=3D"sty=
led-by-prettify">return</span><span style=3D"color: #000;" class=3D"styled-=
by-prettify"> </span><span style=3D"color: #660;" class=3D"styled-by-pretti=
fy">{</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </sp=
an><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: #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"styl=
ed-by-prettify"> </span><span style=3D"color: #066;" class=3D"styled-by-pre=
ttify">3.0</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></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"co=
lor: #008;" class=3D"styled-by-prettify">struct</span><span style=3D"color:=
#000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #606;" c=
lass=3D"styled-by-prettify">Test</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-pret=
tify"> </span><span style=3D"color: #008;" class=3D"styled-by-prettify">dec=
ltype</span><span style=3D"color: #660;" class=3D"styled-by-prettify">(</sp=
an><span style=3D"color: #000;" class=3D"styled-by-prettify">foo</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=
: #800;" class=3D"styled-by-prettify">// inherit from a parameter-struct</s=
pan><span style=3D"color: #000;" class=3D"styled-by-prettify"><br></span><s=
pan 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"co=
lor: #660;" class=3D"styled-by-prettify">};</span><span style=3D"color: #00=
0;" class=3D"styled-by-prettify"><br><br></span><span style=3D"color: #008;=
" class=3D"styled-by-prettify">int</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"> main</span><span style=3D"color: #660;" class=3D"s=
tyled-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"><br>&nb=
sp; </span><span style=3D"color: #008;" class=3D"styled-by-prettify">int</s=
pan><span style=3D"color: #000;" class=3D"styled-by-prettify"> a </span><sp=
an style=3D"color: #660;" class=3D"styled-by-prettify">=3D</span><span styl=
e=3D"color: #000;" class=3D"styled-by-prettify"> foo</span><span style=3D"c=
olor: #660;" class=3D"styled-by-prettify">().</span><span style=3D"color: #=
000;" class=3D"styled-by-prettify">a</span><span style=3D"color: #660;" cla=
ss=3D"styled-by-prettify">;</span><span style=3D"color: #000;" class=3D"sty=
led-by-prettify"><br> </span><span style=3D"color: #008;" class=3D"st=
yled-by-prettify">int</span><span style=3D"color: #000;" class=3D"styled-by=
-prettify"> b </span><span style=3D"color: #660;" class=3D"styled-by-pretti=
fy">=3D</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> fo=
o</span><span style=3D"color: #660;" class=3D"styled-by-prettify">().</span=
><span style=3D"color: #000;" class=3D"styled-by-prettify">b</span><span st=
yle=3D"color: #660;" class=3D"styled-by-prettify">;</span><span style=3D"co=
lor: #000;" class=3D"styled-by-prettify"><br> </span><span style=3D"c=
olor: #008;" class=3D"styled-by-prettify">int</span><span style=3D"color: #=
000;" class=3D"styled-by-prettify"> c </span><span style=3D"color: #660;" c=
lass=3D"styled-by-prettify">=3D</span><span style=3D"color: #000;" class=3D=
"styled-by-prettify"> foo</span><span style=3D"color: #660;" class=3D"style=
d-by-prettify">().</span><span style=3D"color: #000;" class=3D"styled-by-pr=
ettify">member2</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: #800;" class=3D"styled-by-prettify">// unnamed me=
mber got a member + index name</span><span style=3D"color: #000;" class=3D"=
styled-by-prettify"><br> </span><span style=3D"color: #008;" class=3D=
"styled-by-prettify">int</span><span style=3D"color: #000;" class=3D"styled=
-by-prettify"> ai </span><span style=3D"color: #660;" class=3D"styled-by-pr=
ettify">=3D</span><span style=3D"color: #000;" class=3D"styled-by-prettify"=
> foo</span><span style=3D"color: #660;" class=3D"styled-by-prettify">().</=
span><span style=3D"color: #008;" class=3D"styled-by-prettify">get</span><s=
pan style=3D"color: #660;" class=3D"styled-by-prettify"><</span><span st=
yle=3D"color: #066;" class=3D"styled-by-prettify">0</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: #800;" =
class=3D"styled-by-prettify">// auto generated getter</span><span style=3D"=
color: #000;" class=3D"styled-by-prettify"><br> </span><span style=3D=
"color: #008;" class=3D"styled-by-prettify">int</span><span style=3D"color:=
#000;" class=3D"styled-by-prettify"> bi </span><span style=3D"color: #660;=
" class=3D"styled-by-prettify">=3D</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"> foo</span><span style=3D"color: #660;" class=3D"st=
yled-by-prettify">().</span><span style=3D"color: #008;" class=3D"styled-by=
-prettify">get</span><span style=3D"color: #660;" class=3D"styled-by-pretti=
fy"><</span><span style=3D"color: #066;" class=3D"styled-by-prettify">1<=
/span><span style=3D"color: #660;" class=3D"styled-by-prettify">>();</sp=
an><span style=3D"color: #000;" class=3D"styled-by-prettify"><br> </s=
pan><span style=3D"color: #008;" class=3D"styled-by-prettify">double</span>=
<span style=3D"color: #000;" class=3D"styled-by-prettify"> c </span><span s=
tyle=3D"color: #660;" class=3D"styled-by-prettify">=3D</span><span style=3D=
"color: #000;" class=3D"styled-by-prettify"> foo</span><span 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"color: #660;" class=
=3D"styled-by-prettify"><</span><span style=3D"color: #066;" class=3D"st=
yled-by-prettify">2</span><span style=3D"color: #660;" class=3D"styled-by-p=
rettify">>();</span><span style=3D"color: #000;" class=3D"styled-by-pret=
tify"><br> foo</span><span style=3D"color: #660;" class=3D"styled-by-=
prettify">().</span><span style=3D"color: #008;" class=3D"styled-by-prettif=
y">set</span><span style=3D"color: #660;" class=3D"styled-by-prettify"><=
</span><span style=3D"color: #066;" class=3D"styled-by-prettify">1</span><s=
pan style=3D"color: #660;" class=3D"styled-by-prettify">>(</span><span s=
tyle=3D"color: #066;" class=3D"styled-by-prettify">2</span><span style=3D"c=
olor: #660;" class=3D"styled-by-prettify">).</span><span style=3D"color: #0=
08;" class=3D"styled-by-prettify">get</span><span style=3D"color: #660;" cl=
ass=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-p=
rettify"> </span><span style=3D"color: #800;" class=3D"styled-by-prettify">=
// auto generated setter, returning *this</span><span style=3D"color: #000;=
" class=3D"styled-by-prettify"><br></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></span></div></code></div><br><br>Peter<br><br><br>On T=
hursday, May 21, 2015 at 3:14:30 AM UTC+2, Matthew Fioravante wrote:<blockq=
uote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-lef=
t: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr">So this idea came ou=
t of the number parsing thread. Many languages like python have support for=
functions returning multiple values.<div><br></div><div>In C++, one option=
we have currently is this:</div><div><br></div><div><div style=3D"border:1=
px solid rgb(187,187,187);word-wrap:break-word;background-color:rgb(250,250=
,250)"><code><div><span style=3D"color:#000">std</span><span style=3D"color=
:#660">::</span><span style=3D"color:#000">tuple</span><span style=3D"color=
:#660"><</span><span style=3D"color:#008">int</span><span style=3D"color=
:#660">,</span><span style=3D"color:#008">float</span><span style=3D"color:=
#660">,</span><span style=3D"color:#008">double</span><span style=3D"color:=
#660">></span><font color=3D"#000000"><span style=3D"color:#000"> foo</s=
pan><span style=3D"color:#660">();</span><span style=3D"color:#000"><br><br=
></span><span style=3D"color:#008">int</span><span style=3D"color:#000"> x<=
/span><span style=3D"color:#660">;</span><span style=3D"color:#000"><br></s=
pan><span style=3D"color:#008">double</span><span style=3D"color:#000"> d</=
span><span style=3D"color:#660">;</span><span style=3D"color:#000"><br>std<=
/span><span style=3D"color:#660">::</span><span style=3D"color:#000">tie</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"> std</span><sp=
an style=3D"color:#660">::</span><span style=3D"color:#000">ignore</span><s=
pan style=3D"color:#660">,</span><span style=3D"color:#000"> d</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"> foo</span><span style=
=3D"color:#660">();</span></font></div></code></div><br>This works but it h=
as a lot of problems:</div><div>- We have to declare the receiving variable=
s beforehand. This means they have to be default constructed and then assig=
ned and we cannot use auto.</div><div>- Its overly verbose and clumsy to us=
e. First we have to declare the variables, then we need 8 character std::ti=
e and 11 character std::ignore.</div><div>- tuple and tie are not as well k=
nown to beginners. A "standard practice" for capturing multiple values woul=
d be better as a core language feature than a library feature.</div><div><b=
r></div><div>So one solution would be to invent a new syntax:</div><div><di=
v style=3D"border:1px solid rgb(187,187,187);word-wrap:break-word;backgroun=
d-color:rgb(250,250,250)"><code><div><span style=3D"font-family:Arial,Helve=
tica,sans-serif"><span style=3D"color:#008">int</span><span style=3D"color:=
#000"> x</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">=
x</span><span style=3D"color:#660">;</span><span style=3D"color:#000"> </sp=
an><span style=3D"color:#008">void</span><span style=3D"color:#660">;</span=
><span style=3D"color:#000"> </span><span style=3D"color:#008">auto</span><=
span style=3D"color:#000"> d</span><span style=3D"color:#660">]</span><span=
style=3D"color:#000"> </span><span style=3D"color:#660">=3D</span><span st=
yle=3D"color:#000"> foo</span><span style=3D"color:#660">();</span></span><=
span style=3D"color:#000"><br></span></div></code></div><div><br></div><div=
>Which is the equivalent of:</div><div><div style=3D"border:1px solid rgb(1=
87,187,187);word-wrap:break-word;background-color:rgb(250,250,250)"><code><=
div><span style=3D"color:#008">int</span><span style=3D"color:#000"> x</spa=
n><span style=3D"color:#660">;</span><span style=3D"color:#000"><br></span>=
<span style=3D"color:#008">auto</span><span style=3D"color:#000"> _t </span=
><span style=3D"color:#660">=3D</span><span style=3D"color:#000"> foo</span=
><span style=3D"color:#660">();</span><span style=3D"color:#000"><br>x </sp=
an><span style=3D"color:#660">=3D</span><span style=3D"color:#000"> std</sp=
an><span style=3D"color:#660">::</span><span style=3D"color:#008">get</span=
><span style=3D"color:#660"><</span><span style=3D"color:#066">0</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">move</span><=
span style=3D"color:#660">(</span><span style=3D"color:#000">_t</span><span=
style=3D"color:#660">));</span><span style=3D"color:#000"><br></span><span=
style=3D"color:#008">auto</span><span style=3D"color:#000"> d </span><span=
style=3D"color:#660">=3D</span><span style=3D"color:#000"> std</span><span=
style=3D"color:#660">::</span><span style=3D"color:#008">get</span><span s=
tyle=3D"color:#660"><</span><span style=3D"color:#066">2</span><span sty=
le=3D"color:#660">>(</span><span style=3D"color:#000">std</span><font co=
lor=3D"#008800"><span style=3D"color:#660">::</span><span style=3D"color:#0=
00">move</span><span style=3D"color:#660">(</span></font><span style=3D"col=
or:#000">_t</span><span style=3D"color:#660">));</span></div></code></div><=
br></div><div>Each element in this "assignment list" corresponds to a eleme=
nt of a tuple of the right hand side of the expression. Each element can be=
one of:<br></div><div>- An lvalue expression: the resulting lvalue is assi=
gned with operator=3D() to the corresponding tuple element.</div><div>- voi=
d: the corresponding tuple element is ignored</div><div>- A local variable =
declaration. A local variable is created and constructed with the correspon=
ding tuple element.</div><div><br></div>I've chosen to use [] instead of {}=
because so far braces always introduce a scope and in this example, d whic=
h is created inside the braces actually lives in the outer scope.</div><div=
>I've chosen to use ; instead of , to avoid confusion with the comma operat=
or.</div><div><br></div><div>We can also allow the user to specify a shorte=
r list, with default values of void for the trailing elements not mentioned=
:</div><div><br></div><div><div style=3D"border:1px solid rgb(187,187,187);=
word-wrap:break-word;background-color:rgb(250,250,250)"><code><div><span st=
yle=3D"color:#660">[</span><span style=3D"color:#008">auto</span><span styl=
e=3D"color:#000"> x</span><span style=3D"color:#660">]</span><span style=3D=
"color:#000"> </span><span style=3D"color:#660">=3D</span><font color=3D"#0=
00000"><span style=3D"color:#000"> foo</span><span style=3D"color:#660">();=
</span><span style=3D"color:#000"> </span><span style=3D"color:#800">//same=
as [auto x, void, void] =3D foo()</span><span style=3D"color:#000"><br></s=
pan></font></div></code></div><br>What do you think about such a feature?</=
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"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />
------=_Part_5427_1050705792.1432667054645--
------=_Part_5426_1266166845.1432667054645--
.
Author: Matthew Woehlke <mw_triad@users.sourceforge.net>
Date: Tue, 26 May 2015 15:07:15 -0400
Raw View
On 2015-05-26 14:29, Matthew Fioravante wrote:
> On Tuesday, May 26, 2015 at 2:24:22 PM UTC-4, Matthew Woehlke wrote:
>> Is there a reason this is not possible with returning std::tuple? Is
>> there a reason we should not support unpacking of e.g. std::pair,
>> std::tuple as return values?
>
> std::pair<X,Y> is convertible to std::tuple<X,Y> [...]
I think you missed the point :-). Nicol seemed to be implying a
(performance?) benefit to only supporting some new, special built-in
tuple-like type, as opposed to std::tuple (or more generally, classes
that support std::get). I'm not convinced that RVO can't happen with
this and e.g. std::tuple.
>> Put differently, is there a reason this needs to be part of the initial
>> proposal rather than a follow-on proposal? (That said, I *would* be in
>> favor of a simplified mechanism for returning multiple values;
>> std::tuple is... aesthetically challenged :-).)
>
> I agree std::tuple is ugly is somewhat non-obvious for beginners. Having a
> syntax for defining multiple return functions and also capturing the values
> would probably be the way to go.
Sure. But I agree with your comments; it seems to me also that this
should be syntactic sugar for std::tuple. This significantly lessens the
implementation burden (in particular, no new syntax for the return). And
that being the case, it may make sense to do it as a follow-on proposal.
(Hmm... should we allow '[int*3]' -> std::array<int, 3>? Again, though,
this feels like it should be a separate, follow-on proposal.)
--
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 http://groups.google.com/a/isocpp.org/group/std-proposals/.
.
Author: Matthew Fioravante <fmatthew5876@gmail.com>
Date: Tue, 26 May 2015 12:18:36 -0700 (PDT)
Raw View
------=_Part_881_450055081.1432667916489
Content-Type: multipart/alternative;
boundary="----=_Part_882_638341633.1432667916490"
------=_Part_882_638341633.1432667916490
Content-Type: text/plain; charset=UTF-8
On Tuesday, May 26, 2015 at 2:50:59 PM UTC-4, Matthew Woehlke wrote:
>
>
> True :-). I'm not wedded to []'s (I could see ()'s too), it's more that
> they don't *bother* me, the way they seem to bother some folks. Also
> that it "feels" like they would be the easiest to parse without
> additional typing or syntax ambiguities.
>
Honestly I'm ok with either one. The question of () vs [] (assuming both
are possible) can be considered a bikeshed question.
>
> >>> I've chosen to use ; instead of , to avoid confusion with the comma
> >>> operator.
> >>
> >> I strongly agree with using ';' to separate elements, since multiple
> >> declarations should be permitted, but '[auto x, auto y]' clearly makes
> >> no syntactic sense. That said, is ',' allowed inside the []'s at all?
> If
> >> yes, what does it mean?
> >>
> >> [auto x, y] = bar(); // forces decltype(x) == decltype(y)?
> >
> > It should be equivalent to:
> >
> > auto t = bar();
> > auto x, y = std::get<0>(t);
> >
> > Which is currently an error because x is not initialized.
>
> Riiiight. That seems weird. I was thinking:
>
> auto&& __temp = bar();
> auto x = get<0>(__temp), y = get<1>(__temp);
>
> ...which anyway I'm not sure if that's legal (at least not for 'auto'),
> but seems like a reasonable way to parse the above input. I'd lean
> toward either that, or just make ',' (or at least 'a declaration
> declaring more than one variable') an error in this context.
>
I think this would be very confusing because now you can use , or ; to
capture multiple values. I think the easiest way to specify this feature
would be to specify the code that it "as-if" decomposes to, just like C++11
for each.
Since "auto x, y = something" is illegal C++, users already get a compiler
warning when they accidentally try to use, instead of ;.
>
> > You could have some horrible thing like this, which would be allowed:
> >
> > int& operator,(int& a, int& b) { return a; }
> >
> > int x;
> > int y;
> > [ x,y; void; void] = foo(); //assignes std::get<0>(foo()) to x
>
> Well, yes, but that's just abusing an lvalue expression :-). We'd have
> to explicitly forbid that, which doesn't seem worthwhile.
>
I don't think we should explicitly forbid anything. Either you specify a
local variable declaration (which is compiled "as-if"), void, or an
expression whose result is assigned to ("as-if").
>
> >> I'd be somewhat strongly inclined to follow Python, and not discard any
> >> values. So the last item in the list becomes a tuple of whatever is
> left
> >> over.
> >
> > This feature conflicts with allowing this syntax to work with any
> std::get
> > compatible type. What type should auto... z be?
>
> I'd say 'tuple'. It makes sense for 'tuple', and it makes sense for
> weird things (e.g. some struct with std::get to get each member by
> index) which otherwise would require the compiler to synthesize a new
> type on the spot (which... sounds like a tuple anyway).
>
> If we implemented it as, say, a new std::get<size_t from, size_t to>,
> users would be able to provide partial specializations to override that
> default behavior (and STL could do so for e.g. std::array). The
> "default" would return a tuple of the specified values.
>
> > tuple<int,int> a();
> > array<int,2> b();
> > pair<int,int> c();
> >
> > [auto xa; auto xva] = a(); //decltype(xva) is tuple<int>?
> > [auto xb; auto xvb] = b(); //decltype(xvb) is array<int,1>?
> > [auto xc; auto xvc] = c(); //What is decltype(xvc)???
>
> Hmm... this seems like a good reason to require '...'. Then, only '...'
> may consume multiple values (presuming we're going with the 'must
> explicitly consume everything' rule), and a '...' *always* has a
> multi-valued type, as above, even if there is only a single remaining
> value.
>
Sorry, I actually meant to say ... there and made a typo. I agree that ...
should be used to multi-capture, even in the size 1 or 0 case. The question
I was trying to highlight is what the type should be if we are generically
supporting any std::get() compatible type?
If the multi-captured value is to inherit the return type of the original
function, this works fine for tuple and array but not for pair because pair
has to be always size 2. We could add a "hack" for converting pair to
tuple, but then we still have to figure out how to handle std::get
compatible user defined types.
Allowing the syntax to capture from an array and then having the
multi-capture variable be a tuple might be confusing.
array<int,4> foo();
[auto x, auto... yzw] = foo();
//yzw is tuple<int,int,int> but I expected array<int,3>!
> > Here is another generic code use case which is trickier if we are only
> > based on std::get().
> > Imagine we want to extract the second parameter, and pass long a
> > concatenated list of the first and the tail.
> >
> > [auto first; auto second; auto... tail] = foo();
> > use(first);
> > auto params = concat({ first }, tail)
> > bar(params)
> >
> > Such a thing is possible for tuple and array but not pair.
>
> If 'auto...' can be empty, why would this not work? (In fact, why would
> it work differently for tuple<T1, T2> than pair<T1, T2>?)
>
pair is always size 2, you cannot concatenate and chop up pairs like you
can with tuples and arrays.
>
> >> The down side of course is that this (except the 'void...' case)
> >> requires the compiler to know how many items are in the result. For
> >> tuple this is probably easy. For "generic" types it may be harder, but
> I
> >> imagine if necessary we could introduce a companion to std::get to
> >> return the largest index that can be used with std::get, if we don't
> >> already have ways to accomplish that.
> >
> > This language feature is built ontop of std::get<> which itself is
> designed
> > for container types where we can dereference elements by index at
> compile
> > time. Calling std::get with an invalid index is a compiler error and
> thus
> > it should be possible to determine the valid index range at compile time
> > using SFINAE tricks.
>
> Okay... inelegant, but works :-). Considering that the compiler should
> only need to inspect one more index than the number of assignments that
> are being emitted, it may even be not inefficient.
>
> >> This may be implied anyway, but I'll say it explicitly; let's please
> >> also support this in range-based for:
> >>
> >> for ([auto key; auto value] : some_map) { ... }
> >
> > This is one major use case of such a feature and hopefully it should
> fall
> > out automagically without any special provisions for it.
>
> It might :-). It depends on how firm the "as-if" rule is that
> range-based for involves an assignment. (Well, that may be more a case
> of how compilers implement range-based for, but this feels like
> something that could possibly be resolved in a DR if necessary, assuming
> the proposal is accepted without explicitly acknowledging this case.
> Also, I suspect compilers would tend to implement it even if the
> standard didn't technically require it.)
>
> Disclosure: I haven't looked up the standardese for how range-based for
> is specified.
>
I believe range for is specified using "as-if" code substitution, so it
should just be like 2 macro substitutions. The first one to expand the
range for into an optimal iterator loop, and then another to expand the
multi return value extraction syntax.
--
---
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 http://groups.google.com/a/isocpp.org/group/std-proposals/.
------=_Part_882_638341633.1432667916490
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><br><br>On Tuesday, May 26, 2015 at 2:50:59 PM UTC-4, Matt=
hew Woehlke wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;marg=
in-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><br>True :-)=
.. I'm not wedded to []'s (I could see ()'s too), it's more that
<br>they don't *bother* me, the way they seem to bother some folks. Also
<br>that it "feels" like they would be the easiest to parse without
<br>additional typing or syntax ambiguities.
<br></blockquote><div><br>Honestly I'm ok with either one. The question of =
() vs [] (assuming both are possible) can be considered a bikeshed question=
..<br> </div><blockquote class=3D"gmail_quote" style=3D"margin: 0;margi=
n-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">
<br>>>> I've chosen to use ; instead of , to avoid confusion with =
the comma=20
<br>>>> operator.=20
<br>>>
<br>>> I strongly agree with using ';' to separate elements, since mu=
ltiple=20
<br>>> declarations should be permitted, but '[auto x, auto y]' clear=
ly makes=20
<br>>> no syntactic sense. That said, is ',' allowed inside the []'s =
at all? If=20
<br>>> yes, what does it mean?=20
<br>>>
<br>>> [auto x, y] =3D bar(); // forces decltype(x) =3D=3D dec=
ltype(y)?=20
<br>>=20
<br>> It should be equivalent to:
<br>>=20
<br>> auto t =3D bar();
<br>> auto x, y =3D std::get<0>(t);
<br>>=20
<br>> Which is currently an error because x is not initialized.
<br>
<br>Riiiight. That seems weird. I was thinking:
<br>
<br> auto&& __temp =3D bar();
<br> auto x =3D get<0>(__temp), y =3D get<1>(__temp);
<br>
<br>...which anyway I'm not sure if that's legal (at least not for 'auto'),
<br>but seems like a reasonable way to parse the above input. I'd lean
<br>toward either that, or just make ',' (or at least 'a declaration
<br>declaring more than one variable') an error in this context.
<br></blockquote><div><br>I think this would be very confusing because now =
you can use , or ; to capture multiple values. I think the easiest way to s=
pecify this feature would be to specify the code that it "as-if" decomposes=
to, just like C++11 for each.<br><br>Since "auto x, y =3D something" is il=
legal C++, users already get a compiler warning when they accidentally try =
to use, instead of ;. <br> </div><blockquote class=3D"gmail_quote" sty=
le=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left=
: 1ex;">
<br>> You could have some horrible thing like this, which would be allow=
ed:
<br>>=20
<br>> int& operator,(int& a, int& b) { return a; }
<br>>=20
<br>> int x;
<br>> int y;
<br>> [ x,y; void; void] =3D foo(); //assignes std::get<0>(foo()) =
to x
<br>
<br>Well, yes, but that's just abusing an lvalue expression :-). We'd have
<br>to explicitly forbid that, which doesn't seem worthwhile.
<br></blockquote><div><br>I don't think we should explicitly forbid anythin=
g. Either you specify a local variable declaration (which is compiled "as-i=
f"), void, or an expression whose result is assigned to ("as-if").<br> =
;</div><blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.=
8ex;border-left: 1px #ccc solid;padding-left: 1ex;">
<br>>> I'd be somewhat strongly inclined to follow Python, and not di=
scard any=20
<br>>> values. So the last item in the list becomes a tuple of whatev=
er is left=20
<br>>> over.=20
<br>>=20
<br>> This feature conflicts with allowing this syntax to work with any =
std::get=20
<br>> compatible type. What type should auto... z be?
<br>
<br>I'd say 'tuple'. It makes sense for 'tuple', and it makes sense for
<br>weird things (e.g. some struct with std::get to get each member by
<br>index) which otherwise would require the compiler to synthesize a new
<br>type on the spot (which... sounds like a tuple anyway).
<br>
<br>If we implemented it as, say, a new std::get<size_t from, size_t to&=
gt;,
<br>users would be able to provide partial specializations to override that
<br>default behavior (and STL could do so for e.g. std::array). The
<br>"default" would return a tuple of the specified values.
<br>
<br>> tuple<int,int> a();
<br>> array<int,2> b();
<br>> pair<int,int> c();
<br>>=20
<br>> [auto xa; auto xva] =3D a(); //decltype(xva) is tuple<int>?
<br>> [auto xb; auto xvb] =3D b(); //decltype(xvb) is array<int,1>=
?
<br>> [auto xc; auto xvc] =3D c(); //What is decltype(xvc)???
<br>
<br>Hmm... this seems like a good reason to require '...'. Then, only '...'
<br>may consume multiple values (presuming we're going with the 'must
<br>explicitly consume everything' rule), and a '...' *always* has a
<br>multi-valued type, as above, even if there is only a single remaining v=
alue.
<br></blockquote><div><br>Sorry, I actually meant to say ... there and made=
a typo. I agree that ... should be used to multi-capture, even in the size=
1 or 0 case. The question I was trying to highlight is what the type shoul=
d be if we are generically supporting any std::get() compatible type? <br><=
br>If the multi-captured value is to inherit the return type of the origina=
l function, this works fine for tuple and array but not for pair because pa=
ir has to be always size 2. We could add a "hack" for converting pair to tu=
ple, but then we still have to figure out how to handle std::get compatible=
user defined types.<br><br>Allowing the syntax to capture from an array an=
d then having the multi-capture variable be a tuple might be confusing.<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 class=3D"prettyprint"><div class=3D"subpret=
typrint"><span style=3D"color: #000;" class=3D"styled-by-prettify">array</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: #066;" class=3D"styled-by-prettify">4</span><span style=3D"color: #660;=
" class=3D"styled-by-prettify">></span><span style=3D"color: #000;" clas=
s=3D"styled-by-prettify"> foo</span><span style=3D"color: #660;" class=3D"s=
tyled-by-prettify">();</span><span style=3D"color: #000;" class=3D"styled-b=
y-prettify"><br></span><span style=3D"color: #660;" class=3D"styled-by-pret=
tify">[</span><span style=3D"color: #008;" class=3D"styled-by-prettify">aut=
o</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 sty=
le=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"col=
or: #008;" class=3D"styled-by-prettify">auto</span><span style=3D"color: #6=
60;" class=3D"styled-by-prettify">...</span><span style=3D"color: #000;" cl=
ass=3D"styled-by-prettify"> yzw</span><span style=3D"color: #660;" class=3D=
"styled-by-prettify">]</span><span style=3D"color: #000;" class=3D"styled-b=
y-prettify"> </span><span style=3D"color: #660;" class=3D"styled-by-prettif=
y">=3D</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> foo=
</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: #800;" class=3D"styled-by-prettify">//yzw is tuple<int,i=
nt,int> but I expected array<int,3>!</span><span style=3D"color: #=
000;" class=3D"styled-by-prettify"><br></span></div></code></div><br><br><b=
r></div><blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0=
..8ex;border-left: 1px #ccc solid;padding-left: 1ex;">
<br>> Here is another generic code use case which is trickier if we are =
only=20
<br>> based on std::get().
<br>> Imagine we want to extract the second parameter, and pass lo=
ng a=20
<br>> concatenated list of the first and the tail.=20
<br>>=20
<br>> [auto first; auto second; auto... tail] =3D foo();
<br>> use(first);
<br>> auto params =3D concat({ first }, tail)
<br>> bar(params)
<br>>=20
<br>> Such a thing is possible for tuple and array but not pair.
<br>
<br>If 'auto...' can be empty, why would this not work? (In fact, why would
<br>it work differently for tuple<T1, T2> than pair<T1, T2>?)
<br></blockquote><div><br>pair is always size 2, you cannot concatenate and=
chop up pairs like you can with tuples and arrays.<br> <br></div><blo=
ckquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-=
left: 1px #ccc solid;padding-left: 1ex;">
<br>>> The down side of course is that this (except the 'void...' cas=
e)=20
<br>>> requires the compiler to know how many items are in the result=
.. For=20
<br>>> tuple this is probably easy. For "generic" types it may be har=
der, but I=20
<br>>> imagine if necessary we could introduce a companion to std::ge=
t to=20
<br>>> return the largest index that can be used with std::get, if we=
don't=20
<br>>> already have ways to accomplish that.=20
<br>>=20
<br>> This language feature is built ontop of std::get<> which its=
elf is designed=20
<br>> for container types where we can dereference elements by index at =
compile=20
<br>> time. Calling std::get with an invalid index is a compiler error a=
nd thus=20
<br>> it should be possible to determine the valid index range at compil=
e time=20
<br>> using SFINAE tricks.
<br>
<br>Okay... inelegant, but works :-). Considering that the compiler should
<br>only need to inspect one more index than the number of assignments that
<br>are being emitted, it may even be not inefficient.
<br>
<br>>> This may be implied anyway, but I'll say it explicitly; let's =
please=20
<br>>> also support this in range-based for:=20
<br>>>
<br>>> for ([auto key; auto value] : some_map) { ... }=20
<br>>=20
<br>> This is one major use case of such a feature and hopefully it shou=
ld fall=20
<br>> out automagically without any special provisions for it.
<br>
<br>It might :-). It depends on how firm the "as-if" rule is that
<br>range-based for involves an assignment. (Well, that may be more a case
<br>of how compilers implement range-based for, but this feels like
<br>something that could possibly be resolved in a DR if necessary, assumin=
g
<br>the proposal is accepted without explicitly acknowledging this case.
<br>Also, I suspect compilers would tend to implement it even if the
<br>standard didn't technically require it.)
<br>
<br>Disclosure: I haven't looked up the standardese for how range-based for
<br>is specified.
<br></blockquote><div><br>I believe range for is specified using "as-if" co=
de substitution, so it should just be like 2 macro substitutions. The first=
one to expand the range for into an optimal iterator loop, and then anothe=
r to expand the multi return value extraction syntax.<br><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"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />
------=_Part_882_638341633.1432667916490--
------=_Part_881_450055081.1432667916489--
.
Author: Matthew Fioravante <fmatthew5876@gmail.com>
Date: Tue, 26 May 2015 12:34:18 -0700 (PDT)
Raw View
------=_Part_463_375870567.1432668858807
Content-Type: multipart/alternative;
boundary="----=_Part_464_1507213742.1432668858807"
------=_Part_464_1507213742.1432668858807
Content-Type: text/plain; charset=UTF-8
On Tuesday, May 26, 2015 at 3:07:27 PM UTC-4, Matthew Woehlke wrote:
>
> I'm not convinced that RVO can't happen with
> this and e.g. std::tuple.
>
I'm not convinced either.
For example, this should be possible today:
tuple<int,float,double> foo();
//RVO constructs t in place
auto t = foo();
auto x = std::move(get<0>(t));
//use x from here, but never touch t again
There is no reason the compiler can't completely elide the move/copy
construction of x and just keep referencing std::get<0>(t) which itself was
RVO constructed.
>
> >> Put differently, is there a reason this needs to be part of the initial
> >> proposal rather than a follow-on proposal? (That said, I *would* be in
> >> favor of a simplified mechanism for returning multiple values;
> >> std::tuple is... aesthetically challenged :-).)
> >
> > I agree std::tuple is ugly is somewhat non-obvious for beginners. Having
> a
> > syntax for defining multiple return functions and also capturing the
> values
> > would probably be the way to go.
>
> Sure. But I agree with your comments; it seems to me also that this
> should be syntactic sugar for std::tuple. This significantly lessens the
> implementation burden (in particular, no new syntax for the return). And
> that being the case, it may make sense to do it as a follow-on proposal.
>
> (Hmm... should we allow '[int*3]' -> std::array<int, 3>? Again, though,
> this feels like it should be a separate, follow-on proposal.)
>
I was thinking maybe [int,3] but using * might be ok too, but yes there
could be value for supporting arrays also. Arrays have advantages in that
you can do for loops on arrays and pass them on directly to APIs which take
an array_view, pointer pairs, etc.. Arrays also allow you to store and
compute the "number of elements" as a compile time constant / constexpr
expression.
If the extraction syntax works for array, then I think multi value extract
should also be an array.
[int,3] foo();
[auto x, auto yz] = foo();
//yz is array<int,2>
[auto y, auto z] yz;
We could also combine them:
[[int,2],float,[double,3]] x; //tuple<array<int,2>,float,array<double,3>> x;
Also saying std::array<int,3> is verbose and ugly. Its probably one of the
biggest reasons why people still use C arrays even though they really have
no advantages and a lot of disadvantages over std::array.
Finally, one more step gives us the much desired "deduce the size from the
initialization sequence" behavior of C arrays.
[auto,*] x = {1, 2, 3}; //x is array<int,3>
--
---
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 http://groups.google.com/a/isocpp.org/group/std-proposals/.
------=_Part_464_1507213742.1432668858807
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><br><br>On Tuesday, May 26, 2015 at 3:07:27 PM UTC-4, Matt=
hew Woehlke wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;marg=
in-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"> I'm no=
t convinced that RVO can't happen with
<br>this and e.g. std::tuple.
<br></blockquote><div><br>I'm not convinced either.<br><br>For example, thi=
s should be possible today:<br><br><div class=3D"prettyprint" style=3D"back=
ground-color: rgb(250, 250, 250); border-color: rgb(187, 187, 187); border-=
style: solid; border-width: 1px; word-wrap: break-word;"><code class=3D"pre=
ttyprint"><div class=3D"subprettyprint"><span style=3D"color: #000;" class=
=3D"styled-by-prettify">tuple</span><span style=3D"color: #660;" class=3D"s=
tyled-by-prettify"><</span><span style=3D"color: #008;" class=3D"styled-=
by-prettify">int</span><span style=3D"color: #660;" class=3D"styled-by-pret=
tify">,</span><span style=3D"color: #008;" class=3D"styled-by-prettify">flo=
at</span><span style=3D"color: #660;" class=3D"styled-by-prettify">,</span>=
<span style=3D"color: #008;" class=3D"styled-by-prettify">double</span><spa=
n style=3D"color: #660;" class=3D"styled-by-prettify">></span><span styl=
e=3D"color: #000;" class=3D"styled-by-prettify"> foo</span><span style=3D"c=
olor: #660;" class=3D"styled-by-prettify">();</span><span style=3D"color: #=
000;" class=3D"styled-by-prettify"><br><br></span><span style=3D"color: #80=
0;" class=3D"styled-by-prettify">//RVO constructs t in place</span><span st=
yle=3D"color: #000;" class=3D"styled-by-prettify"><br></span><span style=3D=
"color: #008;" class=3D"styled-by-prettify">auto</span><span style=3D"color=
: #000;" class=3D"styled-by-prettify"> t </span><span style=3D"color: #660;=
" class=3D"styled-by-prettify">=3D</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"> foo</span><span style=3D"color: #660;" class=3D"st=
yled-by-prettify">();</span><span style=3D"color: #000;" class=3D"styled-by=
-prettify"><br></span><span style=3D"color: #008;" class=3D"styled-by-prett=
ify">auto</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> =
x </span><span style=3D"color: #660;" class=3D"styled-by-prettify">=3D</spa=
n><span style=3D"color: #000;" class=3D"styled-by-prettify"> std</span><spa=
n style=3D"color: #660;" class=3D"styled-by-prettify">::</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify">move</span><span style=3D"co=
lor: #660;" class=3D"styled-by-prettify">(</span><span style=3D"color: #008=
;" class=3D"styled-by-prettify">get</span><span style=3D"color: #660;" clas=
s=3D"styled-by-prettify"><</span><span style=3D"color: #066;" class=3D"s=
tyled-by-prettify">0</span><span style=3D"color: #660;" class=3D"styled-by-=
prettify">>(</span><span style=3D"color: #000;" class=3D"styled-by-prett=
ify">t</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: #800;" class=3D"styled-by-prettify">//use x from here=
, but never touch t again</span><span style=3D"color: #000;" class=3D"style=
d-by-prettify"><br></span></div></code></div><br>There is no reason the com=
piler can't completely elide the move/copy construction of x and just keep =
referencing std::get<0>(t) which itself was RVO constructed.<br><br>&=
nbsp;</div><blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left=
: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">
<br>>> Put differently, is there a reason this needs to be part of th=
e initial=20
<br>>> proposal rather than a follow-on proposal? (That said, I *woul=
d* be in=20
<br>>> favor of a simplified mechanism for returning multiple values;=
=20
<br>>> std::tuple is... aesthetically challenged :-).)=20
<br>>=20
<br>> I agree std::tuple is ugly is somewhat non-obvious for beginners. =
Having a=20
<br>> syntax for defining multiple return functions and also capturing t=
he values=20
<br>> would probably be the way to go.
<br>
<br>Sure. But I agree with your comments; it seems to me also that this
<br>should be syntactic sugar for std::tuple. This significantly lessens th=
e
<br>implementation burden (in particular, no new syntax for the return). An=
d
<br>that being the case, it may make sense to do it as a follow-on proposal=
..
<br>
<br>(Hmm... should we allow '[int*3]' -> std::array<int, 3>? Again=
, though,
<br>this feels like it should be a separate, follow-on proposal.)
<br></blockquote><div><br>I was thinking maybe [int,3] but using * might be=
ok too, but yes there could be value for supporting arrays also. Arrays ha=
ve advantages in that you can do for loops on arrays and pass them on direc=
tly to APIs which take an array_view, pointer pairs, etc.. Arrays also allo=
w you to store and compute the "number of elements" as a compile time const=
ant / constexpr expression.<br><br>If the extraction syntax works for array=
, then I think multi value extract should also be an array.<br><br><div cla=
ss=3D"prettyprint" style=3D"background-color: rgb(250, 250, 250); border-co=
lor: rgb(187, 187, 187); border-style: solid; border-width: 1px; word-wrap:=
break-word;"><code class=3D"prettyprint"><div class=3D"subprettyprint"><sp=
an 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: #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"style=
d-by-prettify"> foo</span><span style=3D"color: #660;" class=3D"styled-by-p=
rettify">();</span><span style=3D"color: #000;" class=3D"styled-by-prettify=
"><br></span><span style=3D"color: #660;" class=3D"styled-by-prettify">[</s=
pan><span style=3D"color: #008;" class=3D"styled-by-prettify">auto</span><s=
pan style=3D"color: #000;" class=3D"styled-by-prettify"> x</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: #008;"=
class=3D"styled-by-prettify">auto</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"> yz</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">=
=3D</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> foo</s=
pan><span style=3D"color: #660;" class=3D"styled-by-prettify">();</span><sp=
an style=3D"color: #000;" class=3D"styled-by-prettify"><br></span><span sty=
le=3D"color: #800;" class=3D"styled-by-prettify">//yz is array<int,2>=
</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 st=
yle=3D"color: #008;" class=3D"styled-by-prettify">auto</span><span style=3D=
"color: #000;" class=3D"styled-by-prettify"> y</span><span style=3D"color: =
#660;" class=3D"styled-by-prettify">,</span><span style=3D"color: #000;" cl=
ass=3D"styled-by-prettify"> </span><span style=3D"color: #008;" class=3D"st=
yled-by-prettify">auto</span><span style=3D"color: #000;" class=3D"styled-b=
y-prettify"> z</span><span style=3D"color: #660;" class=3D"styled-by-pretti=
fy">]</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> yz</=
span><span style=3D"color: #660;" class=3D"styled-by-prettify">;</span><spa=
n style=3D"color: #000;" class=3D"styled-by-prettify"><br></span></div></co=
de></div><br>We could also combine them:<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=
class=3D"prettyprint"><div class=3D"subprettyprint"><span style=3D"color: =
#660;" class=3D"styled-by-prettify">[[</span><span style=3D"color: #008;" c=
lass=3D"styled-by-prettify">int</span><span style=3D"color: #660;" class=3D=
"styled-by-prettify">,</span><span style=3D"color: #066;" class=3D"styled-b=
y-prettify">2</span><span style=3D"color: #660;" class=3D"styled-by-prettif=
y">],</span><span style=3D"color: #008;" class=3D"styled-by-prettify">float=
</span><span style=3D"color: #660;" 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: #066;" class=3D"styled-by-prettify">3</span><span style=3D"color: #=
660;" class=3D"styled-by-prettify">]]</span><span style=3D"color: #000;" cl=
ass=3D"styled-by-prettify"> x</span><span style=3D"color: #660;" class=3D"s=
tyled-by-prettify">;</span><span style=3D"color: #000;" class=3D"styled-by-=
prettify"> </span><span style=3D"color: #800;" class=3D"styled-by-prettify"=
>//tuple<array<int,2>,float,array<double,3>> x;</span><sp=
an style=3D"color: #000;" class=3D"styled-by-prettify"><br></span></div></c=
ode></div><br>Also saying std::array<int,3> is verbose and ugly. Its =
probably one of the biggest reasons why people still use C arrays even thou=
gh they really have no advantages and a lot of disadvantages over std::arra=
y.<br><br>Finally, one more step gives us the much desired "deduce the size=
from the initialization sequence" behavior of C arrays.<br><br><div class=
=3D"prettyprint" style=3D"background-color: rgb(250, 250, 250); border-colo=
r: rgb(187, 187, 187); border-style: solid; border-width: 1px; word-wrap: b=
reak-word;"><code class=3D"prettyprint"><div class=3D"subprettyprint"><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 style=3D"color: #000;=
" class=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"sty=
led-by-prettify"> </span><span style=3D"color: #660;" class=3D"styled-by-pr=
ettify">{</span><span style=3D"color: #066;" class=3D"styled-by-prettify">1=
</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: #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"> </span><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-prettif=
y"> </span><span style=3D"color: #800;" class=3D"styled-by-prettify">//x is=
array<int,3> </span><span style=3D"color: #000;" class=3D"styled-by-=
prettify"><br></span></div></code></div><br><br> <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"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />
------=_Part_464_1507213742.1432668858807--
------=_Part_463_375870567.1432668858807--
.
Author: hun.nemethpeter@gmail.com
Date: Tue, 26 May 2015 12:36:09 -0700 (PDT)
Raw View
------=_Part_4885_2057269857.1432668969146
Content-Type: multipart/alternative;
boundary="----=_Part_4886_1295765671.1432668969153"
------=_Part_4886_1295765671.1432668969153
Content-Type: text/plain; charset=UTF-8
On Tuesday, May 26, 2015 at 9:04:14 PM UTC+2, hun.nem...@gmail.com wrote:
>
> I think we need a parameter struct like thing. A struct with a parameter
> list syntax, something like:
>
> // return type is a parameter-struct
> struct (int a, int b, double) foo() {
> return { 1, 2, 3.0 };
> }
>
> struct Test : decltype(foo()) // inherit from a parameter-struct
> {
> };
>
> int main() {
> int a = foo().a;
> int b = foo().b;
> int c = foo().member2; // unnamed member got a member + index name
> int ai = foo().get<0>(); // auto generated getter
> int bi = foo().get<1>();
> double c = foo().get<2>();
> foo().set<1>(2).get<1>(); // auto generated setter, returning *this
> }
>
>
> Peter
>
>
>
Maybe with an inline extension
inline struct (int a, int b, double) foo() {
return { 1, 2, 3.0 };
}
int main() {
foo();
std::cout << "Hello inline variables: " << a << b << member2 << std::end;
}
Or using a compile time code generator (not exit now) feature here.
struct (int a, int b, double) foo() {
return { 1, 2, 3.0 };
}
int main() {
#!inlineVariables(foo());
std::cout << "Hello inline variables: " << a << b << member2 << std::end;
}
Peter
--
---
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 http://groups.google.com/a/isocpp.org/group/std-proposals/.
------=_Part_4886_1295765671.1432668969153
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><br><br>On Tuesday, May 26, 2015 at 9:04:14 PM UTC+2, hun.=
nem...@gmail.com wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0=
;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div di=
r=3D"ltr">I think we need a parameter struct like thing. A struct with a pa=
rameter list syntax, something like:<br><br><div style=3D"background-color:=
rgb(250,250,250);border-color:rgb(187,187,187);border-style:solid;border-wi=
dth:1px;word-wrap:break-word"><code><div><span style=3D"color:#800">// retu=
rn type is a parameter-struct</span><span style=3D"color:#000"><br></span><=
span style=3D"color:#008">struct</span><span style=3D"color:#000"> </span><=
span style=3D"color:#660">(</span><span style=3D"color:#008">int</span><spa=
n style=3D"color:#000"> a</span><span style=3D"color:#660">,</span><span st=
yle=3D"color:#000"> </span><span style=3D"color:#008">int</span><span=
style=3D"color:#000"> b</span><span style=3D"color:#660">,</span><span sty=
le=3D"color:#000"> </span><span style=3D"color:#008">double</span><span sty=
le=3D"color:#660">)</span><span style=3D"color:#000"> foo</span><span style=
=3D"color:#660">()</span><span style=3D"color:#000"> </span><span style=3D"=
color:#660">{</span><span style=3D"color:#000"><br> </span><sp=
an style=3D"color:#008">return</span><span style=3D"color:#000"> </span><sp=
an style=3D"color:#660">{</span><span style=3D"color:#000"> </span><span st=
yle=3D"color:#066">1</span><span style=3D"color:#660">,</span><span style=
=3D"color:#000"> </span><span style=3D"color:#066">2</span><span style=3D"c=
olor:#660">,</span><span style=3D"color:#000"> </span><span style=3D"color:=
#066">3.0</span><span style=3D"color:#000"> </span><span style=3D"color:#66=
0">};</span><span style=3D"color:#000"><br></span><span style=3D"color:#660=
">}</span><span style=3D"color:#000"><br><br></span><span style=3D"color:#0=
08">struct</span><span style=3D"color:#000"> </span><span style=3D"color:#6=
06">Test</span><span style=3D"color:#000"> </span><span style=3D"color:#660=
">:</span><span style=3D"color:#000"> </span><span style=3D"color:#008">dec=
ltype</span><span style=3D"color:#660">(</span><span style=3D"color:#000">f=
oo</span><span style=3D"color:#660">())</span><span style=3D"color:#000"> <=
/span><span style=3D"color:#800">// inherit from a parameter-struct</span><=
span style=3D"color:#000"><br></span><span style=3D"color:#660">{</span><sp=
an style=3D"color:#000"><br></span><span style=3D"color:#660">};</span><spa=
n style=3D"color:#000"><br><br></span><span style=3D"color:#008">int</span>=
<span style=3D"color:#000"> main</span><span style=3D"color:#660">()</span>=
<span style=3D"color:#000"> </span><span style=3D"color:#660">{</span><span=
style=3D"color:#000"><br> </span><span style=3D"color:#008">int</spa=
n><span style=3D"color:#000"> a </span><span style=3D"color:#660">=3D</span=
><span style=3D"color:#000"> foo</span><span style=3D"color:#660">().</span=
><span style=3D"color:#000">a</span><span style=3D"color:#660">;</span><spa=
n style=3D"color:#000"><br> </span><span style=3D"color:#008">int</sp=
an><span style=3D"color:#000"> b </span><span style=3D"color:#660">=3D</spa=
n><span style=3D"color:#000"> foo</span><span style=3D"color:#660">().</spa=
n><span style=3D"color:#000">b</span><span style=3D"color:#660">;</span><sp=
an style=3D"color:#000"><br> </span><span style=3D"color:#008">int</s=
pan><span style=3D"color:#000"> c </span><span style=3D"color:#660">=3D</sp=
an><span style=3D"color:#000"> foo</span><span style=3D"color:#660">().</sp=
an><span style=3D"color:#000">member2</span><span style=3D"color:#660">;</s=
pan><span style=3D"color:#000"> </span><span style=3D"color:#800">// unname=
d member got a member + index name</span><span style=3D"color:#000"><br>&nb=
sp; </span><span style=3D"color:#008">int</span><span style=3D"color:#000">=
ai </span><span style=3D"color:#660">=3D</span><span style=3D"color:#000">=
foo</span><span style=3D"color:#660">().</span><span style=3D"color:#008">=
get</span><span style=3D"color:#660"><</span><span style=3D"color:#066">=
0</span><span style=3D"color:#660">>();</span><span style=3D"color:#000"=
> </span><span style=3D"color:#800">// auto generated getter</span><span st=
yle=3D"color:#000"><br> </span><span style=3D"color:#008">int</span><=
span style=3D"color:#000"> bi </span><span style=3D"color:#660">=3D</span><=
span style=3D"color:#000"> foo</span><span style=3D"color:#660">().</span><=
span style=3D"color:#008">get</span><span style=3D"color:#660"><</span><=
span style=3D"color:#066">1</span><span style=3D"color:#660">>();</span>=
<span style=3D"color:#000"><br> </span><span style=3D"color:#008">dou=
ble</span><span style=3D"color:#000"> c </span><span style=3D"color:#660">=
=3D</span><span style=3D"color:#000"> foo</span><span style=3D"color:#660">=
().</span><span style=3D"color:#008">get</span><span style=3D"color:#660">&=
lt;</span><span style=3D"color:#066">2</span><span style=3D"color:#660">>=
;();</span><span style=3D"color:#000"><br> foo</span><span style=3D"c=
olor:#660">().</span><span style=3D"color:#008">set</span><span style=3D"co=
lor:#660"><</span><span style=3D"color:#066">1</span><span style=3D"colo=
r:#660">>(</span><span style=3D"color:#066">2</span><span style=3D"color=
:#660">).</span><span style=3D"color:#008">get</span><span style=3D"color:#=
660"><</span><span style=3D"color:#066">1</span><span style=3D"color:#66=
0">>();</span><span style=3D"color:#000"> </span><span style=3D"color:#8=
00">// auto generated setter, returning *this</span><span style=3D"color:#0=
00"><br></span><span style=3D"color:#660">}</span><span style=3D"color:#000=
"><br></span></div></code></div><br><br>Peter<br><br><br></div></blockquote=
><div><br>Maybe with an inline extension<br><code><span style=3D"color:#008=
">inline struct</span><span style=3D"color:#000"> </span><span style=3D"col=
or:#660">(</span><span style=3D"color:#008">int</span><span style=3D"color:=
#000"> a</span><span style=3D"color:#660">,</span><span style=3D"color:#000=
"> </span><span style=3D"color:#008">int</span><span style=3D"color:#=
000"> b</span><span style=3D"color:#660">,</span><span style=3D"color:#000"=
> </span><span style=3D"color:#008">double</span><span style=3D"color:#660"=
>)</span><span style=3D"color:#000"> foo</span><span style=3D"color:#660">(=
)</span><span style=3D"color:#000"> </span><span style=3D"color:#660">{</sp=
an><span style=3D"color:#000"><br> </span><span style=3D"color=
:#008">return</span><span style=3D"color:#000"> </span><span style=3D"color=
:#660">{</span><span style=3D"color:#000"> </span><span style=3D"color:#066=
">1</span><span style=3D"color:#660">,</span><span style=3D"color:#000"> </=
span><span style=3D"color:#066">2</span><span style=3D"color:#660">,</span>=
<span style=3D"color:#000"> </span><span style=3D"color:#066">3.0</span><sp=
an style=3D"color:#000"> </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></span></code><code><span style=3D"color:#008">int</s=
pan><span style=3D"color:#000"> main</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"><br> </span><span style=3D"color:#000">foo<=
/span><span style=3D"color:#660">()</span><span style=3D"color:#000"></span=
><span style=3D"color:#660">;<br> std::cout << "Hello inline va=
riables: " << a << b << member2 << std::end;<br></s=
pan></code>} <br><br>Or using a compile time code generator (not exit now) =
feature here.<br><br><code><span style=3D"color:#008"><code><span style=3D"=
color:#008">struct</span><span style=3D"color:#000"> </span><span style=3D"=
color:#660">(</span><span style=3D"color:#008">int</span><span style=3D"col=
or:#000"> a</span><span style=3D"color:#660">,</span><span style=3D"color:#=
000"> </span><span style=3D"color:#008">int</span><span style=3D"colo=
r:#000"> b</span><span style=3D"color:#660">,</span><span style=3D"color:#0=
00"> </span><span style=3D"color:#008">double</span><span style=3D"color:#6=
60">)</span><span style=3D"color:#000"> foo</span><span style=3D"color:#660=
">()</span><span style=3D"color:#000"> </span><span style=3D"color:#660">{<=
/span><span style=3D"color:#000"><br> </span><span style=3D"co=
lor:#008">return</span><span style=3D"color:#000"> </span><span style=3D"co=
lor:#660">{</span><span style=3D"color:#000"> </span><span style=3D"color:#=
066">1</span><span style=3D"color:#660">,</span><span style=3D"color:#000">=
</span><span style=3D"color:#066">2</span><span style=3D"color:#660">,</sp=
an><span style=3D"color:#000"> </span><span style=3D"color:#066">3.0</span>=
<span style=3D"color:#000"> </span><span style=3D"color:#660">};</span><spa=
n style=3D"color:#000"><br></span><span style=3D"color:#660">}</span><span =
style=3D"color:#000"><br></span></code><code><span style=3D"color:#008"></s=
pan></code>int</span><span style=3D"color:#000"> main</span><span style=3D"=
color:#660">()</span><span style=3D"color:#000"> </span><span style=3D"colo=
r:#660">{</span><span style=3D"color:#000"><br> </span></code><code><=
span style=3D"color:#000">#!inlineVariables(foo());<br></span><span style=
=3D"color:#660"> std::cout << "Hello inline variables: " <&l=
t; a << b << member2 << std::end;<br></span></code>} <br>=
<br>Peter<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"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />
------=_Part_4886_1295765671.1432668969153--
------=_Part_4885_2057269857.1432668969146--
.
Author: hun.nemethpeter@gmail.com
Date: Tue, 26 May 2015 12:39:56 -0700 (PDT)
Raw View
------=_Part_5070_2047930300.1432669196398
Content-Type: multipart/alternative;
boundary="----=_Part_5071_1844141631.1432669196398"
------=_Part_5071_1844141631.1432669196398
Content-Type: text/plain; charset=UTF-8
On Tuesday, May 26, 2015 at 9:04:14 PM UTC+2, hun.nem...@gmail.com wrote:
>
> I think we need a parameter struct like thing. A struct with a parameter
> list syntax, something like:
>
> // return type is a parameter-struct
> struct (int a, int b, double) foo() {
> return { 1, 2, 3.0 };
> }
>
> struct Test : decltype(foo()) // inherit from a parameter-struct
> {
> };
>
> int main() {
> int a = foo().a;
> int b = foo().b;
> int c = foo().member2; // unnamed member got a member + index name
> int ai = foo().get<0>(); // auto generated getter
> int bi = foo().get<1>();
> double c = foo().get<2>();
> foo().set<1>(2).get<1>(); // auto generated setter, returning *this
> }
>
>
>
Another addition can be a generated constexpr size() method
int bi = foo().size(); // returns 3
static_assert(foo().size() == 3);
--
---
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 http://groups.google.com/a/isocpp.org/group/std-proposals/.
------=_Part_5071_1844141631.1432669196398
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><br><br>On Tuesday, May 26, 2015 at 9:04:14 PM UTC+2, hun.=
nem...@gmail.com wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0=
;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div di=
r=3D"ltr">I think we need a parameter struct like thing. A struct with a pa=
rameter list syntax, something like:<br><br><div style=3D"background-color:=
rgb(250,250,250);border-color:rgb(187,187,187);border-style:solid;border-wi=
dth:1px;word-wrap:break-word"><code><div><span style=3D"color:#800">// retu=
rn type is a parameter-struct</span><span style=3D"color:#000"><br></span><=
span style=3D"color:#008">struct</span><span style=3D"color:#000"> </span><=
span style=3D"color:#660">(</span><span style=3D"color:#008">int</span><spa=
n style=3D"color:#000"> a</span><span style=3D"color:#660">,</span><span st=
yle=3D"color:#000"> </span><span style=3D"color:#008">int</span><span=
style=3D"color:#000"> b</span><span style=3D"color:#660">,</span><span sty=
le=3D"color:#000"> </span><span style=3D"color:#008">double</span><span sty=
le=3D"color:#660">)</span><span style=3D"color:#000"> foo</span><span style=
=3D"color:#660">()</span><span style=3D"color:#000"> </span><span style=3D"=
color:#660">{</span><span style=3D"color:#000"><br> </span><sp=
an style=3D"color:#008">return</span><span style=3D"color:#000"> </span><sp=
an style=3D"color:#660">{</span><span style=3D"color:#000"> </span><span st=
yle=3D"color:#066">1</span><span style=3D"color:#660">,</span><span style=
=3D"color:#000"> </span><span style=3D"color:#066">2</span><span style=3D"c=
olor:#660">,</span><span style=3D"color:#000"> </span><span style=3D"color:=
#066">3.0</span><span style=3D"color:#000"> </span><span style=3D"color:#66=
0">};</span><span style=3D"color:#000"><br></span><span style=3D"color:#660=
">}</span><span style=3D"color:#000"><br><br></span><span style=3D"color:#0=
08">struct</span><span style=3D"color:#000"> </span><span style=3D"color:#6=
06">Test</span><span style=3D"color:#000"> </span><span style=3D"color:#660=
">:</span><span style=3D"color:#000"> </span><span style=3D"color:#008">dec=
ltype</span><span style=3D"color:#660">(</span><span style=3D"color:#000">f=
oo</span><span style=3D"color:#660">())</span><span style=3D"color:#000"> <=
/span><span style=3D"color:#800">// inherit from a parameter-struct</span><=
span style=3D"color:#000"><br></span><span style=3D"color:#660">{</span><sp=
an style=3D"color:#000"><br></span><span style=3D"color:#660">};</span><spa=
n style=3D"color:#000"><br><br></span><span style=3D"color:#008">int</span>=
<span style=3D"color:#000"> main</span><span style=3D"color:#660">()</span>=
<span style=3D"color:#000"> </span><span style=3D"color:#660">{</span><span=
style=3D"color:#000"><br> </span><span style=3D"color:#008">int</spa=
n><span style=3D"color:#000"> a </span><span style=3D"color:#660">=3D</span=
><span style=3D"color:#000"> foo</span><span style=3D"color:#660">().</span=
><span style=3D"color:#000">a</span><span style=3D"color:#660">;</span><spa=
n style=3D"color:#000"><br> </span><span style=3D"color:#008">int</sp=
an><span style=3D"color:#000"> b </span><span style=3D"color:#660">=3D</spa=
n><span style=3D"color:#000"> foo</span><span style=3D"color:#660">().</spa=
n><span style=3D"color:#000">b</span><span style=3D"color:#660">;</span><sp=
an style=3D"color:#000"><br> </span><span style=3D"color:#008">int</s=
pan><span style=3D"color:#000"> c </span><span style=3D"color:#660">=3D</sp=
an><span style=3D"color:#000"> foo</span><span style=3D"color:#660">().</sp=
an><span style=3D"color:#000">member2</span><span style=3D"color:#660">;</s=
pan><span style=3D"color:#000"> </span><span style=3D"color:#800">// unname=
d member got a member + index name</span><span style=3D"color:#000"><br>&nb=
sp; </span><span style=3D"color:#008">int</span><span style=3D"color:#000">=
ai </span><span style=3D"color:#660">=3D</span><span style=3D"color:#000">=
foo</span><span style=3D"color:#660">().</span><span style=3D"color:#008">=
get</span><span style=3D"color:#660"><</span><span style=3D"color:#066">=
0</span><span style=3D"color:#660">>();</span><span style=3D"color:#000"=
> </span><span style=3D"color:#800">// auto generated getter</span><span st=
yle=3D"color:#000"><br> </span><span style=3D"color:#008">int</span><=
span style=3D"color:#000"> bi </span><span style=3D"color:#660">=3D</span><=
span style=3D"color:#000"> foo</span><span style=3D"color:#660">().</span><=
span style=3D"color:#008">get</span><span style=3D"color:#660"><</span><=
span style=3D"color:#066">1</span><span style=3D"color:#660">>();</span>=
<span style=3D"color:#000"><br> </span><span style=3D"color:#008">dou=
ble</span><span style=3D"color:#000"> c </span><span style=3D"color:#660">=
=3D</span><span style=3D"color:#000"> foo</span><span style=3D"color:#660">=
().</span><span style=3D"color:#008">get</span><span style=3D"color:#660">&=
lt;</span><span style=3D"color:#066">2</span><span style=3D"color:#660">>=
;();</span><span style=3D"color:#000"><br> foo</span><span style=3D"c=
olor:#660">().</span><span style=3D"color:#008">set</span><span style=3D"co=
lor:#660"><</span><span style=3D"color:#066">1</span><span style=3D"colo=
r:#660">>(</span><span style=3D"color:#066">2</span><span style=3D"color=
:#660">).</span><span style=3D"color:#008">get</span><span style=3D"color:#=
660"><</span><span style=3D"color:#066">1</span><span style=3D"color:#66=
0">>();</span><span style=3D"color:#000"> </span><span style=3D"color:#8=
00">// auto generated setter, returning *this</span><span style=3D"color:#0=
00"><br></span><span style=3D"color:#660">}</span><span style=3D"color:#000=
"><br></span></div></code></div><br><br></div></blockquote><div><br>Another=
addition can be a generated constexpr size() method<br> <code><span s=
tyle=3D"color:#000"> </span><span style=3D"color:#008">int</span><spa=
n style=3D"color:#000"> bi </span><span style=3D"color:#660">=3D</span><spa=
n style=3D"color:#000"> foo</span><span style=3D"color:#660">().</span><spa=
n style=3D"color:#008">size</span><span style=3D"color:#660">();</span><spa=
n style=3D"color:#000"> // returns 3<br> static_assert(foo().si=
ze() =3D=3D 3);<br></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"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />
------=_Part_5071_1844141631.1432669196398--
------=_Part_5070_2047930300.1432669196398--
.
Author: Matthew Woehlke <mw_triad@users.sourceforge.net>
Date: Tue, 26 May 2015 15:51:04 -0400
Raw View
On 2015-05-26 15:18, Matthew Fioravante wrote:
> On Tuesday, May 26, 2015 at 2:50:59 PM UTC-4, Matthew Woehlke wrote:
>>> tuple<int,int> a();
>>> array<int,2> b();
>>> pair<int,int> c();
>>>
>>> [auto xa; auto xva] = a(); //decltype(xva) is tuple<int>?
>>> [auto xb; auto xvb] = b(); //decltype(xvb) is array<int,1>?
>>> [auto xc; auto xvc] = c(); //What is decltype(xvc)???
>
> Sorry, I actually meant to say ... there and made a typo. [...] The question
> I was trying to highlight is what the type should be if we are generically
> supporting any std::get() compatible type?
I still think the best way to answer that is to use something other than
std::get<size_t> for '...', even if it's std::get<size_t, size_t>. That
way users can specialized, STL can specialize (e.g. for std::array), and
anything that doesn't can fall back on std::tuple.
>>> Here is another generic code use case which is trickier if we are only
>>> based on std::get().
>>> Imagine we want to extract the second parameter, and pass long a
>>> concatenated list of the first and the tail.
>>>
>>> [auto first; auto second; auto... tail] = foo();
>>> use(first);
>>> auto params = concat({ first }, tail)
>>> bar(params)
>>>
>>> Such a thing is possible for tuple and array but not pair.
>>
>> If 'auto...' can be empty, why would this not work? (In fact, why would
>> it work differently for tuple<T1, T2> than pair<T1, T2>?)
>
> pair is always size 2, you cannot concatenate and chop up pairs like you
> can with tuples and arrays.
....but why would you expect the result of the above example to be
different for (e.g.) std::pair<int, int> than for std::tuple<int, int>?
I wouldn't. I would expect them to be the same; decltype(tail) ==
std::tuple<>.
Actually, I think this illustrates *why* tails should normally decompose
to tuples; it's much easier to deal with them if they end up as a known
type.
--
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 http://groups.google.com/a/isocpp.org/group/std-proposals/.
.
Author: Matthew Woehlke <mw_triad@users.sourceforge.net>
Date: Tue, 26 May 2015 15:57:42 -0400
Raw View
On 2015-05-26 15:34, Matthew Fioravante wrote:
> On Tuesday, May 26, 2015 at 3:07:27 PM UTC-4, Matthew Woehlke wrote:
>> (Hmm... should we allow '[int*3]' -> std::array<int, 3>? Again, though,
>> this feels like it should be a separate, follow-on proposal.)
>
> I was thinking maybe [int,3] but using * might be ok too,
It's Pythonic, but on second thought, '[int**3]' would be confusing :-).
Anyway, that's a bikeshed for another time; I still think we should get
unpacking first, and worry about syntax sugars later.
(Your other point is addressed in my other replies.)
> Also saying std::array<int,3> is verbose and ugly. Its probably one of the
> biggest reasons why people still use C arrays even though they really have
> no advantages and a lot of disadvantages over std::array.
This gives me ideas, but they're likely to be contentious (maybe not
between us, but to others). So instead I'll mention again this is one
reason I'd like to worry about unpacking first, and syntax sugar
separately :-).
> [auto,*] x = {1, 2, 3}; //x is array<int,3>
(Er... yes. Ideas along these lines. See previous comment.)
--
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 http://groups.google.com/a/isocpp.org/group/std-proposals/.
.
Author: Matthew Fioravante <fmatthew5876@gmail.com>
Date: Tue, 26 May 2015 13:00:50 -0700 (PDT)
Raw View
------=_Part_889_1718373122.1432670450525
Content-Type: multipart/alternative;
boundary="----=_Part_890_1336976598.1432670450525"
------=_Part_890_1336976598.1432670450525
Content-Type: text/plain; charset=UTF-8
On Tuesday, May 26, 2015 at 3:51:19 PM UTC-4, Matthew Woehlke wrote:
>
> On 2015-05-26 15:18, Matthew Fioravante wrote:
> > On Tuesday, May 26, 2015 at 2:50:59 PM UTC-4, Matthew Woehlke wrote:
> >>> tuple<int,int> a();
> >>> array<int,2> b();
> >>> pair<int,int> c();
> >>>
> >>> [auto xa; auto xva] = a(); //decltype(xva) is tuple<int>?
> >>> [auto xb; auto xvb] = b(); //decltype(xvb) is array<int,1>?
> >>> [auto xc; auto xvc] = c(); //What is decltype(xvc)???
> >
> > Sorry, I actually meant to say ... there and made a typo. [...] The
> question
> > I was trying to highlight is what the type should be if we are
> generically
> > supporting any std::get() compatible type?
>
> I still think the best way to answer that is to use something other than
> std::get<size_t> for '...', even if it's std::get<size_t, size_t>. That
> way users can specialized, STL can specialize (e.g. for std::array), and
> anything that doesn't can fall back on std::tuple.
>
> >>> Here is another generic code use case which is trickier if we are only
> >>> based on std::get().
> >>> Imagine we want to extract the second parameter, and pass long a
> >>> concatenated list of the first and the tail.
> >>>
> >>> [auto first; auto second; auto... tail] = foo();
> >>> use(first);
> >>> auto params = concat({ first }, tail)
> >>> bar(params)
> >>>
> >>> Such a thing is possible for tuple and array but not pair.
> >>
> >> If 'auto...' can be empty, why would this not work? (In fact, why would
> >> it work differently for tuple<T1, T2> than pair<T1, T2>?)
> >
> > pair is always size 2, you cannot concatenate and chop up pairs like you
> > can with tuples and arrays.
>
> ...but why would you expect the result of the above example to be
> different for (e.g.) std::pair<int, int> than for std::tuple<int, int>?
>
> I wouldn't. I would expect them to be the same; decltype(tail) ==
> std::tuple<>.
>
> Actually, I think this illustrates *why* tails should normally decompose
> to tuples; it's much easier to deal with them if they end up as a known
> type.
>
> Converting a pair to a tuple is natural and probably won't result in too
many surprises, converting array to tuple not so much.
If this feature is to support std::array, then I think it would be better
for multi-capture to also construct a (sub) array as arrays have nice
properties that tuples do not have. If multi-capture always constructs a
tuple then it would probably be better to only define this proposal to
operate with tuple, possibly doing conversions from pair and array.
Having all of the "type lists" be the same type will improve readability,
generic code (I can pass the entire type list or a multi-captured sub
type-list to the same function) and reduce surprises.
Is there any real reason to actually support anything other than tuple
(with implicit conversion from pair) and array?
--
---
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 http://groups.google.com/a/isocpp.org/group/std-proposals/.
------=_Part_890_1336976598.1432670450525
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><br><br>On Tuesday, May 26, 2015 at 3:51:19 PM UTC-4, Matt=
hew Woehlke wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;marg=
in-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">On 2015-05-2=
6 15:18, Matthew Fioravante wrote:
<br>> On Tuesday, May 26, 2015 at 2:50:59 PM UTC-4, Matthew Woehlke wrot=
e:
<br>>>> tuple<int,int> a();=20
<br>>>> array<int,2> b();=20
<br>>>> pair<int,int> c();=20
<br>>>>
<br>>>> [auto xa; auto xva] =3D a(); //decltype(xva) is tuple<i=
nt>?=20
<br>>>> [auto xb; auto xvb] =3D b(); //decltype(xvb) is array<i=
nt,1>?=20
<br>>>> [auto xc; auto xvc] =3D c(); //What is decltype(xvc)???=20
<br>>=20
<br>> Sorry, I actually meant to say ... there and made a typo. [...] Th=
e question=20
<br>> I was trying to highlight is what the type should be if we are gen=
erically=20
<br>> supporting any std::get() compatible type?
<br>
<br>I still think the best way to answer that is to use something other tha=
n
<br>std::get<size_t> for '...', even if it's std::get<size_t, size=
_t>. That
<br>way users can specialized, STL can specialize (e.g. for std::array), an=
d
<br>anything that doesn't can fall back on std::tuple.
<br>
<br>>>> Here is another generic code use case which is trickier if=
we are only=20
<br>>>> based on std::get().=20
<br>>>> Imagine we want to extract the second parameter, and=
pass long a=20
<br>>>> concatenated list of the first and the tail.=20
<br>>>>
<br>>>> [auto first; auto second; auto... tail] =3D foo();=20
<br>>>> use(first);=20
<br>>>> auto params =3D concat({ first }, tail)=20
<br>>>> bar(params)=20
<br>>>>
<br>>>> Such a thing is possible for tuple and array but not pair.=
=20
<br>>>
<br>>> If 'auto...' can be empty, why would this not work? (In fact, =
why would=20
<br>>> it work differently for tuple<T1, T2> than pair<T1, T=
2>?)=20
<br>>=20
<br>> pair is always size 2, you cannot concatenate and chop up pairs li=
ke you=20
<br>> can with tuples and arrays.
<br>
<br>...but why would you expect the result of the above example to be
<br>different for (e.g.) std::pair<int, int> than for std::tuple<i=
nt, int>?
<br>
<br>I wouldn't. I would expect them to be the same; decltype(tail) =3D=3D
<br>std::tuple<>.
<br>
<br>Actually, I think this illustrates *why* tails should normally decompos=
e
<br>to tuples; it's much easier to deal with them if they end up as a known
<br>type.
<br>
<br></blockquote><div>Converting a pair to a tuple is natural and probably =
won't result in too many surprises, converting array to tuple not so much. =
<br><br></div><div>If this feature is to support std::array, then I think i=
t would be better for multi-capture to also construct a (sub) array as arra=
ys have nice properties that tuples do not have. If multi-capture always co=
nstructs a tuple then it would probably be better to only define this propo=
sal to operate with tuple, possibly doing conversions from pair and array. =
<br><br>Having all of the "type lists" be the same type will improve readab=
ility, generic code (I can pass the entire type list or a multi-captured su=
b type-list to the same function) and reduce surprises.<br><br>Is there any=
real reason to actually support anything other than tuple (with implicit c=
onversion from pair) and array? <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"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />
------=_Part_890_1336976598.1432670450525--
------=_Part_889_1718373122.1432670450525--
.
Author: Matthew Woehlke <mw_triad@users.sourceforge.net>
Date: Tue, 26 May 2015 16:33:13 -0400
Raw View
On 2015-05-26 16:00, Matthew Fioravante wrote:
> Is there any real reason to actually support anything other than tuple
> (with implicit conversion from pair) and array?
QPair. QSize. Other weird user-defined classes that "look like"
std::tuple, std::pair, or std::array. Existing API's that currently
return a struct because they predate std::tuple or considered it "too
ugly". (I have a range struct, i.e. a "pair" with lower/upper, that
might benefit.)
For that matter, tuple is *still* ugly in failing to name its elements.
I can readily imagine that even with unpacking, some folks will want to
return structs, but would like to be able to unpack them.
In general, yes, I think adds value if unpacking can be extended by the
user to work on new types, i.e. by providing std::get for such types.
> Converting a pair to a tuple is natural and probably won't result in too
> many surprises, converting array to tuple not so much.
This, and the above, is why I keep saying that the tail should use
something *like-but-not-exactly* std::get<size_t>, so that STL and the
user can specialize it if it makes sense for the tail to be something
other than std::tuple. (Note that in saying that, I am implying that STL
*would* specialize so that a tail of std::array is a std::array.)
Plus, if we miss STL edge cases, I'd expect there to be less resistance
in such case to vendors implementing non-conforming specializations in
their STL implementation and getting them standardized via DR's.
--
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 http://groups.google.com/a/isocpp.org/group/std-proposals/.
.
Author: Nicol Bolas <jmckesson@gmail.com>
Date: Tue, 26 May 2015 13:36:23 -0700 (PDT)
Raw View
------=_Part_5_295431885.1432672583228
Content-Type: multipart/alternative;
boundary="----=_Part_6_341499331.1432672583228"
------=_Part_6_341499331.1432672583228
Content-Type: text/plain; charset=UTF-8
On Tuesday, May 26, 2015 at 3:34:18 PM UTC-4, Matthew Fioravante wrote:
>
>
>
> On Tuesday, May 26, 2015 at 3:07:27 PM UTC-4, Matthew Woehlke wrote:
>>
>> I'm not convinced that RVO can't happen with
>> this and e.g. std::tuple.
>>
>
> I'm not convinced either.
>
> For example, this should be possible today:
>
> tuple<int,float,double> foo();
>
> //RVO constructs t in place
> auto t = foo();
> auto x = std::move(get<0>(t));
> //use x from here, but never touch t again
>
> There is no reason the compiler can't completely elide the move/copy
> construction of x and just keep referencing std::get<0>(t) which itself was
> RVO constructed.
>
Yes there is. The Standard for Programming Language C++ *explicitly forbids
it*.
This statement:
auto x = std::move(<<<insert any expression here>>>);
is *required* by the standard to construct `x` via an explicit call to a
copy/move constructor (as appropriate to the type of the expression).
The only reason that this statement:
auto x = FunctionCall(...);
is allowed to elide the copy/move to `x` is because the standard has
explicit language *allowing* the compiler to elide the copy/move. It can
only happen through the return value from a function, *directly*.
What you're suggesting would be some form of generalized elision, which
nobody has suggested or proposed, and would be... well, quite frankly
rather scary to even contemplate.
--
---
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 http://groups.google.com/a/isocpp.org/group/std-proposals/.
------=_Part_6_341499331.1432672583228
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><br><br>On Tuesday, May 26, 2015 at 3:34:18 PM UTC-4, Matt=
hew Fioravante wrote:<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"><br><br>On Tuesday, May 26, 2015 at 3:07:27 PM UTC-4, Matthew Woeh=
lke wrote:<blockquote class=3D"gmail_quote" style=3D"margin:0;margin-left:0=
..8ex;border-left:1px #ccc solid;padding-left:1ex"> I'm not convinced t=
hat RVO can't happen with
<br>this and e.g. std::tuple.
<br></blockquote><div><br>I'm not convinced either.<br><br>For example, thi=
s should be possible today:<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">tuple</span><spa=
n style=3D"color:#660"><</span><span style=3D"color:#008">int</span><spa=
n style=3D"color:#660">,</span><span style=3D"color:#008">float</span><span=
style=3D"color:#660">,</span><span style=3D"color:#008">double</span><span=
style=3D"color:#660">></span><span style=3D"color:#000"> foo</span><spa=
n style=3D"color:#660">();</span><span style=3D"color:#000"><br><br></span>=
<span style=3D"color:#800">//RVO constructs t in place</span><span style=3D=
"color:#000"><br></span><span style=3D"color:#008">auto</span><span style=
=3D"color:#000"> t </span><span style=3D"color:#660">=3D</span><span style=
=3D"color:#000"> foo</span><span style=3D"color:#660">();</span><span style=
=3D"color:#000"><br></span><span style=3D"color:#008">auto</span><span styl=
e=3D"color:#000"> x </span><span style=3D"color:#660">=3D</span><span style=
=3D"color:#000"> std</span><span style=3D"color:#660">::</span><span style=
=3D"color:#000">move</span><span style=3D"color:#660">(</span><span style=
=3D"color:#008">get</span><span style=3D"color:#660"><</span><span style=
=3D"color:#066">0</span><span style=3D"color:#660">>(</span><span style=
=3D"color:#000">t</span><span style=3D"color:#660">));</span><span style=3D=
"color:#000"><br></span><span style=3D"color:#800">//use x from here, but n=
ever touch t again</span><span style=3D"color:#000"><br></span></div></code=
></div><br>There is no reason the compiler can't completely elide the move/=
copy construction of x and just keep referencing std::get<0>(t) which=
itself was RVO constructed.<br></div></div></blockquote><div><br>Yes there=
is. The Standard for Programming Language C++ <i>explicitly forbids it</i>=
..<br><br>This statement:<br><br><div class=3D"prettyprint" style=3D"backgro=
und-color: rgb(250, 250, 250); border-color: rgb(187, 187, 187); border-sty=
le: solid; border-width: 1px; word-wrap: break-word;"><code class=3D"pretty=
print"><div class=3D"subprettyprint"><span style=3D"color: #008;" class=3D"=
styled-by-prettify">auto</span><span style=3D"color: #000;" class=3D"styled=
-by-prettify"> x </span><span style=3D"color: #660;" class=3D"styled-by-pre=
ttify">=3D</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: #000;" class=3D"styled-by-prettify">move</span><sp=
an style=3D"color: #660;" class=3D"styled-by-prettify">(<<<</span>=
<span style=3D"color: #000;" class=3D"styled-by-prettify">insert any expres=
sion here</span><span style=3D"color: #660;" class=3D"styled-by-prettify">&=
gt;>>);</span><span style=3D"color: #000;" class=3D"styled-by-prettif=
y"><br></span></div></code></div><br>is <i>required</i> by the standard to =
construct `x` via an explicit call to a copy/move constructor (as appropria=
te to the type of the expression).<br><br>The only reason that this stateme=
nt:<br><br><div class=3D"prettyprint" style=3D"background-color: rgb(250, 2=
50, 250); border-color: rgb(187, 187, 187); border-style: solid; border-wid=
th: 1px; word-wrap: break-word;"><code class=3D"prettyprint"><div class=3D"=
subprettyprint"><span style=3D"color: #008;" class=3D"styled-by-prettify">a=
uto</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> x </sp=
an><span style=3D"color: #660;" class=3D"styled-by-prettify">=3D</span><spa=
n style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=
=3D"color: #606;" class=3D"styled-by-prettify">FunctionCall</span><span sty=
le=3D"color: #660;" class=3D"styled-by-prettify">(...);</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"><br></span></div></code></di=
v><br>is allowed to elide the copy/move to `x` is because the standard has =
explicit language <i>allowing</i> the compiler to elide the copy/move. It c=
an only happen through the return value from a function, <i>directly</i>.<b=
r><br>What you're suggesting would be some form of generalized elision, whi=
ch nobody has suggested or proposed, and would be... well, quite frankly ra=
ther scary to even contemplate. <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"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />
------=_Part_6_341499331.1432672583228--
------=_Part_5_295431885.1432672583228--
.
Author: Nicol Bolas <jmckesson@gmail.com>
Date: Tue, 26 May 2015 13:40:03 -0700 (PDT)
Raw View
------=_Part_970_1286394368.1432672803252
Content-Type: multipart/alternative;
boundary="----=_Part_971_1712268627.1432672803252"
------=_Part_971_1712268627.1432672803252
Content-Type: text/plain; charset=UTF-8
On Tuesday, May 26, 2015 at 3:07:27 PM UTC-4, Matthew Woehlke wrote:
>
> On 2015-05-26 14:29, Matthew Fioravante wrote:
> > On Tuesday, May 26, 2015 at 2:24:22 PM UTC-4, Matthew Woehlke wrote:
> >> Is there a reason this is not possible with returning std::tuple? Is
> >> there a reason we should not support unpacking of e.g. std::pair,
> >> std::tuple as return values?
> >
> > std::pair<X,Y> is convertible to std::tuple<X,Y> [...]
>
> I think you missed the point :-). Nicol seemed to be implying a
> (performance?) benefit to only supporting some new, special built-in
> tuple-like type, as opposed to std::tuple (or more generally, classes
> that support std::get). I'm not convinced that RVO can't happen with
> this and e.g. std::tuple.
>
You can be convinced of whatever you want; the standard doesn't agree.
Elision can only take place for the initialization of parameters to
functions and the initialization of return values directly from functions.
Therefore, if a function returns a tuple, then the tuple you store it in
can elide the copy/move. However, if you then want to extract a member of
this tuple, whether via `std::tie` or via `std::get<>` or whathaveyou,
that's constructing a new value.
You can get a reference to the value in the tuple. But you can't copy/move
to a new non-reference type without actually copying/moving.
--
---
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 http://groups.google.com/a/isocpp.org/group/std-proposals/.
------=_Part_971_1712268627.1432672803252
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">On Tuesday, May 26, 2015 at 3:07:27 PM UTC-4, Matthew Woeh=
lke wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left:=
0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">On 2015-05-26 14:29,=
Matthew Fioravante wrote:
<br>> On Tuesday, May 26, 2015 at 2:24:22 PM UTC-4, Matthew Woehlke wrot=
e:
<br>>> Is there a reason this is not possible with returning std::tup=
le? Is=20
<br>>> there a reason we should not support unpacking of e.g. std::pa=
ir,=20
<br>>> std::tuple as return values?=20
<br>>=20
<br>> std::pair<X,Y> is convertible to std::tuple<X,Y> [...]
<br>
<br>I think you missed the point :-). Nicol seemed to be implying a
<br>(performance?) benefit to only supporting some new, special built-in
<br>tuple-like type, as opposed to std::tuple (or more generally, classes
<br>that support std::get). I'm not convinced that RVO can't happen with
<br>this and e.g. std::tuple.
<br></blockquote><div><br>You can be convinced of whatever you want; the st=
andard doesn't agree. Elision can only take place for the initialization of=
parameters to functions and the initialization of return values directly f=
rom functions. Therefore, if a function returns a tuple, then the tuple you=
store it in can elide the copy/move. However, if you then want to extract =
a member of this tuple, whether via `std::tie` or via `std::get<>` or=
whathaveyou, that's constructing a new value.<br><br>You can get a referen=
ce to the value in the tuple. But you can't copy/move to a new non-referenc=
e type without actually copying/moving.</div><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"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />
------=_Part_971_1712268627.1432672803252--
------=_Part_970_1286394368.1432672803252--
.
Author: Nicol Bolas <jmckesson@gmail.com>
Date: Tue, 26 May 2015 13:42:29 -0700 (PDT)
Raw View
------=_Part_5333_210050452.1432672949309
Content-Type: multipart/alternative;
boundary="----=_Part_5334_2002314743.1432672949309"
------=_Part_5334_2002314743.1432672949309
Content-Type: text/plain; charset=UTF-8
On Tuesday, May 26, 2015 at 4:40:03 PM UTC-4, Nicol Bolas wrote:
>
> On Tuesday, May 26, 2015 at 3:07:27 PM UTC-4, Matthew Woehlke wrote:
>>
>> On 2015-05-26 14:29, Matthew Fioravante wrote:
>> > On Tuesday, May 26, 2015 at 2:24:22 PM UTC-4, Matthew Woehlke wrote:
>> >> Is there a reason this is not possible with returning std::tuple? Is
>> >> there a reason we should not support unpacking of e.g. std::pair,
>> >> std::tuple as return values?
>> >
>> > std::pair<X,Y> is convertible to std::tuple<X,Y> [...]
>>
>> I think you missed the point :-). Nicol seemed to be implying a
>> (performance?) benefit to only supporting some new, special built-in
>> tuple-like type, as opposed to std::tuple (or more generally, classes
>> that support std::get). I'm not convinced that RVO can't happen with
>> this and e.g. std::tuple.
>>
>
> You can be convinced of whatever you want; the standard doesn't agree.
> Elision can only take place for the initialization of parameters to
> functions and the initialization of return values directly from functions.
> Therefore, if a function returns a tuple, then the tuple you store it in
> can elide the copy/move. However, if you then want to extract a member of
> this tuple, whether via `std::tie` or via `std::get<>` or whathaveyou,
> that's constructing a new value.
>
> You can get a reference to the value in the tuple. But you can't copy/move
> to a new non-reference type without actually copying/moving.
>
>
Also, I should make this clear: I'm not supporting the idea of returning a
"tuple-like type". I'm saying that we should have multiple return values
from functions. Just like functions can have multiple parameters.
You don't stick your parameters in a `tuple` just to call a function, so
why should you pull them from a `tuple` when you return them? It's purely a
language limitation, and one that is decidedly artificial.
--
---
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 http://groups.google.com/a/isocpp.org/group/std-proposals/.
------=_Part_5334_2002314743.1432672949309
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><br><br>On Tuesday, May 26, 2015 at 4:40:03 PM UTC-4, Nico=
l 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, May 26, 2015 at 3:07:27 PM UTC-4, Matthew Woehlke wrote:<block=
quote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-left=
:1px #ccc solid;padding-left:1ex">On 2015-05-26 14:29, Matthew Fioravante w=
rote:
<br>> On Tuesday, May 26, 2015 at 2:24:22 PM UTC-4, Matthew Woehlke wrot=
e:
<br>>> Is there a reason this is not possible with returning std::tup=
le? Is=20
<br>>> there a reason we should not support unpacking of e.g. std::pa=
ir,=20
<br>>> std::tuple as return values?=20
<br>>=20
<br>> std::pair<X,Y> is convertible to std::tuple<X,Y> [...]
<br>
<br>I think you missed the point :-). Nicol seemed to be implying a
<br>(performance?) benefit to only supporting some new, special built-in
<br>tuple-like type, as opposed to std::tuple (or more generally, classes
<br>that support std::get). I'm not convinced that RVO can't happen with
<br>this and e.g. std::tuple.
<br></blockquote><div><br>You can be convinced of whatever you want; the st=
andard doesn't agree. Elision can only take place for the initialization of=
parameters to functions and the initialization of return values directly f=
rom functions. Therefore, if a function returns a tuple, then the tuple you=
store it in can elide the copy/move. However, if you then want to extract =
a member of this tuple, whether via `std::tie` or via `std::get<>` or=
whathaveyou, that's constructing a new value.<br><br>You can get a referen=
ce to the value in the tuple. But you can't copy/move to a new non-referenc=
e type without actually copying/moving.<br></div><br></div></blockquote><di=
v><br>Also, I should make this clear: I'm not supporting the idea of return=
ing a "tuple-like type". I'm saying that we should have multiple return val=
ues from functions. Just like functions can have multiple parameters.<br><b=
r>You don't stick your parameters in a `tuple` just to call a function, so =
why should you pull them from a `tuple` when you return them? It's purely a=
language limitation, and one that is decidedly artificial.<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"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />
------=_Part_5334_2002314743.1432672949309--
------=_Part_5333_210050452.1432672949309--
.
Author: Matthew Fioravante <fmatthew5876@gmail.com>
Date: Tue, 26 May 2015 13:56:54 -0700 (PDT)
Raw View
------=_Part_4683_1097610704.1432673814742
Content-Type: multipart/alternative;
boundary="----=_Part_4684_658574398.1432673814742"
------=_Part_4684_658574398.1432673814742
Content-Type: text/plain; charset=UTF-8
On Tuesday, May 26, 2015 at 4:33:24 PM UTC-4, Matthew Woehlke wrote:
>
> On 2015-05-26 16:00, Matthew Fioravante wrote:
> > Is there any real reason to actually support anything other than tuple
> > (with implicit conversion from pair) and array?
>
> QPair. QSize. Other weird user-defined classes that "look like"
> std::tuple, std::pair, or std::array. Existing API's that currently
> return a struct because they predate std::tuple or considered it "too
> ugly". (I have a range struct, i.e. a "pair" with lower/upper, that
> might benefit.)
>
Another solution for these could be asking user defined types to implement
operator tuple<X,Y,Z>() or operator array<X,N>(); That might require copies
though and be less efficient than std::get(). The thing about std::get() is
that its actually very painful to implement because handling the max index
requires a lot of ugly SFINAE hacks. Implementing a range based std::get
would be even more complicated meta-programming.
>
> For that matter, tuple is *still* ugly in failing to name its elements.
> I can readily imagine that even with unpacking, some folks will want to
> return structs, but would like to be able to unpack them.
>
For unpacking, having names does not matter but I agree sometimes I like to
use structs. Still I'm not sure the two use cases mesh well.
If I'm returning a struct, that probably means I intend the client to use
the struct as a distinct object by itself. If the user can use this
proposals feature to capture the return values directly into nicely named
local variables, that kind of defeats the purpose of returning a struct
just for the named members.
> In general, yes, I think adds value if unpacking can be extended by the
> user to work on new types, i.e. by providing std::get for such types.
>
> > Converting a pair to a tuple is natural and probably won't result in too
> > many surprises, converting array to tuple not so much.
>
> This, and the above, is why I keep saying that the tail should use
> something *like-but-not-exactly* std::get<size_t>, so that STL and the
> user can specialize it if it makes sense for the tail to be something
> other than std::tuple. (Note that in saying that, I am implying that STL
> *would* specialize so that a tail of std::array is a std::array.)
>
We should think more specifically about what such an API would look like
and what it takes for a user to implement one for a simple case such as
struct { float x; float y; float z; }. Not only do we need std::get<int>
but also std::get<int,int> for the mutli-value capture and all of these
need to correctly fail compilation for an invalid index while
simultaneously supporting recursive iteration (SFINAE).
--
---
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 http://groups.google.com/a/isocpp.org/group/std-proposals/.
------=_Part_4684_658574398.1432673814742
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><br><br>On Tuesday, May 26, 2015 at 4:33:24 PM UTC-4, Matt=
hew Woehlke wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;marg=
in-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">On 2015-05-2=
6 16:00, Matthew Fioravante wrote:
<br>> Is there any real reason to actually support anything other than t=
uple=20
<br>> (with implicit conversion from pair) and array?=20
<br>
<br>QPair. QSize. Other weird user-defined classes that "look like"
<br>std::tuple, std::pair, or std::array. Existing API's that currently
<br>return a struct because they predate std::tuple or considered it "too
<br>ugly". (I have a range struct, i.e. a "pair" with lower/upper, that
<br>might benefit.)
<br></blockquote><div><br>Another solution for these could be asking user d=
efined types to implement operator tuple<X,Y,Z>() or operator array&l=
t;X,N>(); That might require copies though and be less efficient than st=
d::get(). The thing about std::get() is that its actually very painful to i=
mplement because handling the max index requires a lot of ugly SFINAE hacks=
.. Implementing a range based std::get would be even more complicated meta-p=
rogramming.<br> </div><blockquote class=3D"gmail_quote" style=3D"margi=
n: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">
<br>For that matter, tuple is *still* ugly in failing to name its elements.
<br>I can readily imagine that even with unpacking, some folks will want to
<br>return structs, but would like to be able to unpack them.
<br></blockquote><div><br>For unpacking, having names does not matter but I=
agree sometimes I like to use structs. Still I'm not sure the two use case=
s mesh well. <br><br>If I'm returning a struct, that probably means I inten=
d the client to use the struct as a distinct object by itself. If the user =
can use this proposals feature to capture the return values directly into n=
icely named local variables, that kind of defeats the purpose of returning =
a struct just for the named members.<br><br></div><blockquote class=3D"gmai=
l_quote" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;=
padding-left: 1ex;">
<br>In general, yes, I think adds value if unpacking can be extended by the
<br>user to work on new types, i.e. by providing std::get for such types.
<br>
<br>> Converting a pair to a tuple is natural and probably won't result =
in too=20
<br>> many surprises, converting array to tuple not so much.
<br>
<br>This, and the above, is why I keep saying that the tail should use
<br>something *like-but-not-exactly* std::get<size_t>, so that STL an=
d the
<br>user can specialize it if it makes sense for the tail to be something
<br>other than std::tuple. (Note that in saying that, I am implying that ST=
L
<br>*would* specialize so that a tail of std::array is a std::array.)
<br></blockquote><div><br>We should think more specifically about what such=
an API would look like and what it takes for a user to implement one for a=
simple case such as struct { float x; float y; float z; }. Not only do we =
need std::get<int> but also std::get<int,int> for the mutli-val=
ue capture and all of these need to correctly fail compilation for an inval=
id index while simultaneously supporting recursive iteration (SFINAE).<br><=
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"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />
------=_Part_4684_658574398.1432673814742--
------=_Part_4683_1097610704.1432673814742--
.
Author: Matthew Fioravante <fmatthew5876@gmail.com>
Date: Tue, 26 May 2015 13:58:36 -0700 (PDT)
Raw View
------=_Part_4736_1966315319.1432673916832
Content-Type: multipart/alternative;
boundary="----=_Part_4737_235722750.1432673916832"
------=_Part_4737_235722750.1432673916832
Content-Type: text/plain; charset=UTF-8
On Tuesday, May 26, 2015 at 4:56:54 PM UTC-4, Matthew Fioravante wrote:
> We should think more specifically about what such an API would look like
> and what it takes for a user to implement one for a simple case such as
> struct { float x; float y; float z; }. Not only do we need std::get<int>
> but also std::get<int,int> for the mutli-value capture and all of these
> need to correctly fail compilation for an invalid index while
> simultaneously supporting recursive iteration (SFINAE).
>
>
Also don't forget about implementing std::get() correctly for lvalue and
rvalues...
http://en.cppreference.com/w/cpp/utility/tuple/get
--
---
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 http://groups.google.com/a/isocpp.org/group/std-proposals/.
------=_Part_4737_235722750.1432673916832
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><br><br>On Tuesday, May 26, 2015 at 4:56:54 PM UTC-4, Matt=
hew Fioravante wrote:<br><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>We should think more specifically about what such an API w=
ould look like and what it takes for a user to implement one for a simple c=
ase such as struct { float x; float y; float z; }. Not only do we need std:=
:get<int> but also std::get<int,int> for the mutli-value captur=
e and all of these need to correctly fail compilation for an invalid index =
while simultaneously supporting recursive iteration (SFINAE).<br><br></div>=
</div></blockquote><div><br>Also don't forget about implementing std::get()=
correctly for lvalue and rvalues...<br><br>http://en.cppreference.com/w/cp=
p/utility/tuple/get<br> <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"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />
------=_Part_4737_235722750.1432673916832--
------=_Part_4736_1966315319.1432673916832--
.
Author: Matthew Woehlke <mw_triad@users.sourceforge.net>
Date: Tue, 26 May 2015 17:04:31 -0400
Raw View
On 2015-05-26 16:36, Nicol Bolas wrote:
> On Tuesday, May 26, 2015 at 3:34:18 PM UTC-4, Matthew Fioravante wrote:
>> For example, this should be possible today:
>>
>> tuple<int,float,double> foo();
>>
>> //RVO constructs t in place
>> auto t = foo();
>> auto x = std::move(get<0>(t));
>> //use x from here, but never touch t again
>>
>> There is no reason the compiler can't completely elide the move/copy
>> construction of x and just keep referencing std::get<0>(t) which itself was
>> RVO constructed.
>
> Yes there is. The Standard for Programming Language C++ *explicitly forbids
> it*.
>
> What you're suggesting would be some form of generalized elision, which
> nobody has suggested or proposed, and would be... well, quite frankly
> rather scary to even contemplate.
Why generalized? Why can we not extend RVO to unpacking? IOW, implement
unpacking "as-if" but with a special allowance for RVO? (Why would that
be worse than what you were proposing?)
--
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 http://groups.google.com/a/isocpp.org/group/std-proposals/.
.
Author: Matthew Fioravante <fmatthew5876@gmail.com>
Date: Tue, 26 May 2015 14:23:20 -0700 (PDT)
Raw View
------=_Part_4916_1177443396.1432675400523
Content-Type: multipart/alternative;
boundary="----=_Part_4917_229349467.1432675400523"
------=_Part_4917_229349467.1432675400523
Content-Type: text/plain; charset=UTF-8
On Tuesday, May 26, 2015 at 4:40:03 PM UTC-4, Nicol Bolas wrote:
>
> You can be convinced of whatever you want; the standard doesn't agree.
> Elision can only take place for the initialization of parameters to
> functions and the initialization of return values directly from functions.
> Therefore, if a function returns a tuple, then the tuple you store it in
> can elide the copy/move. However, if you then want to extract a member of
> this tuple, whether via `std::tie` or via `std::get<>` or whathaveyou,
> that's constructing a new value.
>
>
If that's the case, the standard practice could be to capture by reference.
[const auto& x; auto& y] = foo();
//expands to:
auto t = foo();
const auto& x = std::get<0>(t);
auto& y = std::get<1>(t);
Since the unnamed tuple "t" in this example always has a longer lifetime
than x or y, the references will always be valid. You're still forced to do
a move/copy if you are assigning to a pre-existing variable, but you can't
get RVO in that case anyway.
Capturing by reference also makes sense when you are extracting from a
tuple object directly.
auto t = [int,float]();
[auto& i, auto& f] = t;
On Tuesday, May 26, 2015 at 4:42:29 PM UTC-4, Nicol Bolas wrote:
>
> Also, I should make this clear: I'm not supporting the idea of returning a
> "tuple-like type". I'm saying that we should have multiple return values
> from functions. Just like functions can have multiple parameters.
>
> You don't stick your parameters in a `tuple` just to call a function, so
> why should you pull them from a `tuple` when you return them? It's purely a
> language limitation, and one that is decidedly artificial.
>
Why not? Conceptually, there is little difference between a type list and
list of function parameters. You could think of calling a function as "take
these local variables, arrange them into a type list, and call the function
with that list of parameters". Some languages like python let you expand a
tuple in place to call a function with it as the parameters. Python also
handles multiple return value capture using tuple syntax.
As was stated earlier, doing it this way would be a huge change that likely
would never make it past the committee. Each platform will have to define a
new calling convention for multiple return valued functions. We would never
get support for interfaces which already return pair and tuple and they
could never be changed because it would break old code. Other than
potential performance concerns with RVO that might be alleviated by using
references, what is the real benefit of doing it as a pure language feature
like this?
How would you for example support a range for loop with std::unordered_map?
The iterator dereference already returns a std::pair. There is no way we
could change it return multiple values using the magic syntax and break old
code. We wouldn't even want that as sometimes we want to pass along the
pair, and other times we want to extract the key and value and work with
those.
Using a type like tuple gives the callers the option of capturing all of
the return values together in a container or extracting them out. They also
can use generic tuple processing functions for free if it makes sense to do
that.
--
---
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 http://groups.google.com/a/isocpp.org/group/std-proposals/.
------=_Part_4917_229349467.1432675400523
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><br><br>On Tuesday, May 26, 2015 at 4:40:03 PM UTC-4, Nico=
l 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"=
>You can be convinced of whatever you want; the
standard doesn't agree. Elision can only take place for the=20
initialization of parameters to functions and the initialization of=20
return values directly from functions. Therefore, if a function returns a
tuple, then the tuple you store it in can elide the copy/move. However,
if you then want to extract a member of this tuple, whether via=20
`std::tie` or via `std::get<>` or whathaveyou, that's constructing
a new value.<br><div><br></div></div></blockquote><div><br>If that's the c=
ase, the standard practice could be to capture by reference.<br><br><div cl=
ass=3D"prettyprint" style=3D"background-color: rgb(250, 250, 250); border-c=
olor: rgb(187, 187, 187); border-style: solid; border-width: 1px; word-wrap=
: break-word;"><code class=3D"prettyprint"><div class=3D"subprettyprint"><s=
pan style=3D"color: #660;" class=3D"styled-by-prettify">[</span><span style=
=3D"color: #008;" class=3D"styled-by-prettify">const</span><span style=3D"c=
olor: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #00=
8;" class=3D"styled-by-prettify">auto</span><span style=3D"color: #660;" cl=
ass=3D"styled-by-prettify">&</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"> x</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: #008;" class=3D"styled-by-prettify">au=
to</span><span style=3D"color: #660;" class=3D"styled-by-prettify">&</s=
pan><span style=3D"color: #000;" class=3D"styled-by-prettify"> y</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">=3D</span><span style=3D"color: #000;=
" class=3D"styled-by-prettify"> foo</span><span style=3D"color: #660;" clas=
s=3D"styled-by-prettify">();</span><span style=3D"color: #000;" class=3D"st=
yled-by-prettify"><br><br></span><span style=3D"color: #800;" class=3D"styl=
ed-by-prettify">//expands to:</span><span style=3D"color: #000;" class=3D"s=
tyled-by-prettify"><br></span><span style=3D"color: #008;" class=3D"styled-=
by-prettify">auto</span><span style=3D"color: #000;" class=3D"styled-by-pre=
ttify"> t </span><span style=3D"color: #660;" class=3D"styled-by-prettify">=
=3D</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> foo</s=
pan><span style=3D"color: #660;" class=3D"styled-by-prettify">();</span><sp=
an style=3D"color: #000;" class=3D"styled-by-prettify"><br></span><span sty=
le=3D"color: #008;" class=3D"styled-by-prettify">const</span><span style=3D=
"color: #000;" 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 style=3D"color: #000;" class=
=3D"styled-by-prettify"> x </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: #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-prettify">0</span><span sty=
le=3D"color: #660;" class=3D"styled-by-prettify">>(</span><span style=3D=
"color: #000;" class=3D"styled-by-prettify">t</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: #008;" class=3D=
"styled-by-prettify">auto</span><span style=3D"color: #660;" class=3D"style=
d-by-prettify">&</span><span style=3D"color: #000;" class=3D"styled-by-=
prettify"> y </span><span style=3D"color: #660;" class=3D"styled-by-prettif=
y">=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-prettify">get</span><span st=
yle=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">t</span><span style=3D"color: #660;" class=3D=
"styled-by-prettify">);</span><span style=3D"color: #000;" class=3D"styled-=
by-prettify"><br></span></div></code></div><br>Since the unnamed tuple "t" =
in this example always has a longer lifetime than x or y, the references wi=
ll always be valid. You're still forced to do a move/copy if you are assign=
ing to a pre-existing variable, but you can't get RVO in that case anyway.<=
br><br>Capturing by reference also makes sense when you are extracting from=
a tuple object directly.<br><br><div class=3D"prettyprint" style=3D"backgr=
ound-color: rgb(250, 250, 250); border-color: rgb(187, 187, 187); border-st=
yle: solid; border-width: 1px; word-wrap: break-word;"><code class=3D"prett=
yprint"><div class=3D"subprettyprint"><span style=3D"color: #008;" class=3D=
"styled-by-prettify">auto</span><span style=3D"color: #000;" class=3D"style=
d-by-prettify"> t </span><span style=3D"color: #660;" class=3D"styled-by-pr=
ettify">=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: #008;" class=3D"styled-by-prettify">int</span><span s=
tyle=3D"color: #660;" class=3D"styled-by-prettify">,</span><span style=3D"c=
olor: #008;" class=3D"styled-by-prettify">float</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;" clas=
s=3D"styled-by-prettify">[</span><span style=3D"color: #008;" class=3D"styl=
ed-by-prettify">auto</span><span style=3D"color: #660;" class=3D"styled-by-=
prettify">&</span><span style=3D"color: #000;" class=3D"styled-by-prett=
ify"> i</span><span style=3D"color: #660;" class=3D"styled-by-prettify">,</=
span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><spa=
n style=3D"color: #008;" class=3D"styled-by-prettify">auto</span><span styl=
e=3D"color: #660;" class=3D"styled-by-prettify">&</span><span style=3D"=
color: #000;" class=3D"styled-by-prettify"> f</span><span style=3D"color: #=
660;" class=3D"styled-by-prettify">]</span><span style=3D"color: #000;" cla=
ss=3D"styled-by-prettify"> </span><span style=3D"color: #660;" class=3D"sty=
led-by-prettify">=3D</span><span style=3D"color: #000;" class=3D"styled-by-=
prettify"> t</span><span style=3D"color: #660;" class=3D"styled-by-prettify=
">;</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br></s=
pan></div></code></div><br></div><br>On Tuesday, May 26, 2015 at 4:42:29 PM=
UTC-4, 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">Also, I should make this clear: I'm not supporting the idea of=
returning a "tuple-like type". I'm saying that we should have multiple ret=
urn values from functions. Just like functions can have multiple parameters=
..<br><div><br>You don't stick your parameters in a `tuple` just to call a f=
unction, so why should you pull them from a `tuple` when you return them? I=
t's purely a language limitation, and one that is decidedly artificial.<br>=
</div></div></blockquote><div><br>Why not? Conceptually, there is little di=
fference between a type list and list of function parameters. You could thi=
nk of calling a function as "take these local variables, arrange them into =
a type list, and call the function with that list of parameters". Some lang=
uages like python let you expand a tuple in place to call a function with i=
t as the parameters. Python also handles multiple return value capture usin=
g tuple syntax.<br><br>As was stated earlier, doing it this way would be a =
huge change that likely would never make it past the committee. Each platfo=
rm will have to define a new calling convention for multiple return valued =
functions. We would never get support for interfaces which already return p=
air and tuple and they could never be changed because it would break old co=
de. Other than potential performance concerns with RVO that might be allevi=
ated by using references, what is the real benefit of doing it as a pure la=
nguage feature like this?<br><br>How would you for example support a range =
for loop with std::unordered_map? The iterator dereference already returns =
a std::pair. There is no way we could change it return multiple values usin=
g the magic syntax and break old code. We wouldn't even want that as someti=
mes we want to pass along the pair, and other times we want to extract the =
key and value and work with those.<br><br>Using a type like tuple gives the=
callers the option of capturing all of the return values together in a con=
tainer or extracting them out. They also can use generic tuple processing f=
unctions for free if it makes sense to do that.<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"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />
------=_Part_4917_229349467.1432675400523--
------=_Part_4916_1177443396.1432675400523--
.
Author: Matthew Woehlke <mw_triad@users.sourceforge.net>
Date: Tue, 26 May 2015 17:30:42 -0400
Raw View
On 2015-05-26 16:31, Nicol Bolas wrote:
> On Tuesday, May 26, 2015 at 2:49:38 PM UTC-4, Miro Knejp wrote:
>> The question here is really whether you want
>> 1. a syntax and language support for multiple return values
>> or
>> 2. a destructuring syntax for tuple/pair (or anything compatible with
>> unqualified get<N>(x))
>>
>> These are orthogonal features.
>
> Sort of.
>
> We already have a way to deconstruct tuples/pairs: `std::tie`. So what is
> being suggested is specialized syntax for it.
>
> However, the principle justification for making that a language syntax (as
> stated here in the OP) is for multiple return values. So if you have
> multiple return values as legitimate syntax, you lose about 80% of the
> reason for having tuple unpacking syntax.
If we had multiple return values as a first class language feature, why
should I not expect to be able to write the opposite of std::tie? :-)
--
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 http://groups.google.com/a/isocpp.org/group/std-proposals/.
.
Author: Magnus Fromreide <magfr@lysator.liu.se>
Date: Tue, 26 May 2015 23:47:38 +0200
Raw View
One thing I am asking myself is if these should be composable.
[int, long, double] foo();
bar(int, long, double);
bar(foo()); // Should this be valid?
/MF
--
---
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 http://groups.google.com/a/isocpp.org/group/std-proposals/.
.
Author: Matthew Woehlke <mw_triad@users.sourceforge.net>
Date: Tue, 26 May 2015 17:51:15 -0400
Raw View
On 2015-05-26 16:56, Matthew Fioravante wrote:
> We should think more specifically about what such an API would look like
> and what it takes for a user to implement one for a simple case such as
> struct { float x; float y; float z; }. Not only do we need std::get<int>
> but also std::get<int,int> for the mutli-value capture and all of these
> need to correctly fail compilation for an invalid index while
> simultaneously supporting recursive iteration (SFINAE).
*STL* would need the latter. Users would only need to specialize the
latter if they want something other than a tuple as the result. The
default would use the single-valued std::get to produce a tuple.
--
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 http://groups.google.com/a/isocpp.org/group/std-proposals/.
.
Author: Matthew Fioravante <fmatthew5876@gmail.com>
Date: Tue, 26 May 2015 14:52:43 -0700 (PDT)
Raw View
------=_Part_2630_1734082875.1432677163144
Content-Type: multipart/alternative;
boundary="----=_Part_2631_1230306688.1432677163144"
------=_Part_2631_1230306688.1432677163144
Content-Type: text/plain; charset=UTF-8
On Tuesday, May 26, 2015 at 5:47:42 PM UTC-4, Magnus Fromreide wrote:
>
> One thing I am asking myself is if these should be composable.
>
> [int, long, double] foo();
> bar(int, long, double);
>
> bar(foo()); // Should this be valid?
>
> /MF
>
I would say no. One needs to differentiate between passing the whole
collection of parameters as one object and unpacking the parameters and
passing them separately.
Something like this if desired would probably require yet another unpacking
syntax, similar to how python lets you unpack a tuple into a function call.
[int, long, double] foo();
[int, long, double] x;
void bar(int, long, double);
void car(tuple<int, long, double>);
bar([*]foo());
bar([*]x);
car(foo());
car(x);
--
---
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 http://groups.google.com/a/isocpp.org/group/std-proposals/.
------=_Part_2631_1230306688.1432677163144
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><br><br>On Tuesday, May 26, 2015 at 5:47:42 PM UTC-4, Magn=
us Fromreide wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;mar=
gin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">One thing I=
am asking myself is if these should be composable.
<br>
<br>[int, long, double] foo();
<br>bar(int, long, double);
<br>
<br>bar(foo()); // Should this be valid?
<br>
<br>/MF
<br></blockquote><div><br>I would say no. One needs to differentiate betwee=
n passing the whole collection of parameters as one object and unpacking th=
e parameters and passing them separately. <br><br>Something like this if de=
sired would probably require yet another unpacking syntax, similar to how p=
ython lets you unpack a tuple into a function call.<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: #660;" class=3D"styled-by-prettify">[</span><span style=3D"color=
: #008;" class=3D"styled-by-prettify">int</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">long</span><span style=3D"color: #660;" class=3D"styled-by-p=
rettify">,</span><span style=3D"color: #000;" class=3D"styled-by-prettify">=
</span><span style=3D"color: #008;" class=3D"styled-by-prettify">double</s=
pan><span style=3D"color: #660;" class=3D"styled-by-prettify">]</span><span=
style=3D"color: #000;" class=3D"styled-by-prettify"> foo</span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">();</span><span style=3D"col=
or: #000;" class=3D"styled-by-prettify"><br></span><span style=3D"color: #6=
60;" class=3D"styled-by-prettify">[</span><span style=3D"color: #008;" clas=
s=3D"styled-by-prettify">int</span><span style=3D"color: #660;" class=3D"st=
yled-by-prettify">,</span><span style=3D"color: #000;" class=3D"styled-by-p=
rettify"> </span><span style=3D"color: #008;" class=3D"styled-by-prettify">=
long</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: #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"> x</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: #008;" class=3D"style=
d-by-prettify">void</span><span style=3D"color: #000;" class=3D"styled-by-p=
rettify"> bar</span><span style=3D"color: #660;" class=3D"styled-by-prettif=
y">(</span><span style=3D"color: #008;" class=3D"styled-by-prettify">int</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: #008;" class=3D"styled-by-prettify">long</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"styl=
ed-by-prettify">);</span><span style=3D"color: #000;" class=3D"styled-by-pr=
ettify"><br></span><span style=3D"color: #008;" class=3D"styled-by-prettify=
">void</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> car=
</span><span style=3D"color: #660;" class=3D"styled-by-prettify">(</span><s=
pan style=3D"color: #000;" class=3D"styled-by-prettify">tuple</span><span s=
tyle=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">long</span><span style=3D"color: #660;" class=3D"st=
yled-by-prettify">,</span><span style=3D"color: #000;" class=3D"styled-by-p=
rettify"> </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"><br><br>=
bar</span><span style=3D"color: #660;" class=3D"styled-by-prettify">([*]</s=
pan><span style=3D"color: #000;" class=3D"styled-by-prettify">foo</span><sp=
an style=3D"color: #660;" class=3D"styled-by-prettify">());</span><span sty=
le=3D"color: #000;" class=3D"styled-by-prettify"><br>bar</span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">([*]</span><span style=3D"co=
lor: #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"><br>car</span><span style=3D"color: #660;" class=3D=
"styled-by-prettify">(</span><span style=3D"color: #000;" class=3D"styled-b=
y-prettify">foo</span><span style=3D"color: #660;" class=3D"styled-by-prett=
ify">());</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><=
br>car</span><span style=3D"color: #660;" class=3D"styled-by-prettify">(</s=
pan><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"><br><br></span></div></code>=
</div><br> <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"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />
------=_Part_2631_1230306688.1432677163144--
------=_Part_2630_1734082875.1432677163144--
.
Author: Matthew Woehlke <mw_triad@users.sourceforge.net>
Date: Tue, 26 May 2015 18:45:43 -0400
Raw View
On 2015-05-26 17:47, Magnus Fromreide wrote:
> One thing I am asking myself is if these should be composable.
>
> [int, long, double] foo();
> bar(int, long, double);
>
> bar(foo()); // Should this be valid?
No. Not, anyway, without some additional syntax. Even in Python this is
not legal (you need a '*').
Now, I'd love to see the ability to unpack a std::tuple into multiple
parameters for a function, but that could be orthogonal. (Maybe not
orthogonal, if we decide to go Nicol's route and make arguments packs
some sort of first class entities that *aren't* std::tuple, though for
various reasons already expressed I remain unconvinced that's a good
idea...)
I could live with '[*]tuple' :-).
--
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 http://groups.google.com/a/isocpp.org/group/std-proposals/.
.
Author: Nicol Bolas <jmckesson@gmail.com>
Date: Tue, 26 May 2015 17:14:09 -0700 (PDT)
Raw View
------=_Part_1298_867964733.1432685649602
Content-Type: multipart/alternative;
boundary="----=_Part_1299_26853460.1432685649602"
------=_Part_1299_26853460.1432685649602
Content-Type: text/plain; charset=UTF-8
On Tuesday, May 26, 2015 at 5:31:10 PM UTC-4, Matthew Woehlke wrote:
>
> On 2015-05-26 16:31, Nicol Bolas wrote:
> > On Tuesday, May 26, 2015 at 2:49:38 PM UTC-4, Miro Knejp wrote:
> >> The question here is really whether you want
> >> 1. a syntax and language support for multiple return values
> >> or
> >> 2. a destructuring syntax for tuple/pair (or anything compatible with
> >> unqualified get<N>(x))
> >>
> >> These are orthogonal features.
> >
> > Sort of.
> >
> > We already have a way to deconstruct tuples/pairs: `std::tie`. So what
> is
> > being suggested is specialized syntax for it.
> >
> > However, the principle justification for making that a language syntax
> (as
> > stated here in the OP) is for multiple return values. So if you have
> > multiple return values as legitimate syntax, you lose about 80% of the
> > reason for having tuple unpacking syntax.
>
> If we had multiple return values as a first class language feature, why
> should I not expect to be able to write the opposite of std::tie? :-)
>
.... std::tie takes a tuple and exports the members of that tuple into
variables. The opposite of that would be to take variables and combine them
into a tuple. That's called `make_tuple`
<http://en.cppreference.com/w/cpp/utility/tuple/make_tuple>; you don't need
special syntax for that.
Also, I have no idea what that has to do with multiple return values.
--
---
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 http://groups.google.com/a/isocpp.org/group/std-proposals/.
------=_Part_1299_26853460.1432685649602
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><br><br>On Tuesday, May 26, 2015 at 5:31:10 PM UTC-4, Matt=
hew Woehlke wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;marg=
in-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">On 2015-05-2=
6 16:31, Nicol Bolas wrote:
<br>> On Tuesday, May 26, 2015 at 2:49:38 PM UTC-4, Miro Knejp wrote:
<br>>> The question here is really whether you want=20
<br>>> 1. a syntax and language support for multiple return val=
ues=20
<br>>> or=20
<br>>> 2. a destructuring syntax for tuple/pair (or anything compatib=
le with=20
<br>>> unqualified get<N>(x))=20
<br>>>
<br>>> These are orthogonal features.
<br>>=20
<br>> Sort of.
<br>>=20
<br>> We already have a way to deconstruct tuples/pairs: `std::tie`. So =
what is=20
<br>> being suggested is specialized syntax for it.
<br>>=20
<br>> However, the principle justification for making that a language sy=
ntax (as=20
<br>> stated here in the OP) is for multiple return values. So if you ha=
ve=20
<br>> multiple return values as legitimate syntax, you lose about 80% of=
the=20
<br>> reason for having tuple unpacking syntax.
<br>
<br>If we had multiple return values as a first class language feature, why
<br>should I not expect to be able to write the opposite of std::tie? :-)
<br></blockquote><div><br><br>... std::tie takes a tuple and exports the me=
mbers of that tuple into variables. The opposite of that would be to take v=
ariables and combine them into a tuple. That's called <a href=3D"http://en.=
cppreference.com/w/cpp/utility/tuple/make_tuple">`make_tuple`</a>; you don'=
t need special syntax for that.<br><br>Also, I have no idea what that has t=
o do with multiple return values.<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"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />
------=_Part_1299_26853460.1432685649602--
------=_Part_1298_867964733.1432685649602--
.
Author: Nicol Bolas <jmckesson@gmail.com>
Date: Tue, 26 May 2015 18:23:50 -0700 (PDT)
Raw View
------=_Part_5932_727366721.1432689830792
Content-Type: multipart/alternative;
boundary="----=_Part_5933_1375561123.1432689830792"
------=_Part_5933_1375561123.1432689830792
Content-Type: text/plain; charset=UTF-8
On Tuesday, May 26, 2015 at 5:23:20 PM UTC-4, Matthew Fioravante wrote:
>
>
> On Tuesday, May 26, 2015 at 4:42:29 PM UTC-4, Nicol Bolas wrote:
>>
>> Also, I should make this clear: I'm not supporting the idea of returning
>> a "tuple-like type". I'm saying that we should have multiple return values
>> from functions. Just like functions can have multiple parameters.
>>
>> You don't stick your parameters in a `tuple` just to call a function, so
>> why should you pull them from a `tuple` when you return them? It's purely a
>> language limitation, and one that is decidedly artificial.
>>
>
> Why not?
>
Because it requires needless copy/moving. Because it looks like worse
syntax than function parameters, even with your terse version. Because it
provides absolutely zero descriptive information about what those
parameters mean.
Because it's entirely pointless, and has been since we got variadic
templates. Unless you happen to have a collection of values that are
already in a tuple, there's no reason to pass a tuple to a function as a
set of parameters.
Conceptually, there is little difference between a type list and list of
> function parameters. You could think of calling a function as "take these
> local variables, arrange them into a type list, and call the function with
> that list of parameters". Some languages like python let you expand a tuple
> in place to call a function with it as the parameters. Python also handles
> multiple return value capture using tuple syntax.
>
Yeah, and Python also handles *multiple return values* as a first-class
language feature. It doesn't force you to package your multiple return
values into a tuple, return them, and then unpack them. Nor does it force
you to package parameters into a tuple.
So you're kind of proving my point for me.
It should also be noted that Python:
1) Is not a statically typed language.
2) Is not a strongly typed language.
Because of these, Python doesn't have "tuples" at all. It simply has arrays
(and other data structures), which can contain values by index. It has a
function that can take an array and return that array as though it were a
sequence of values. And so forth. Because Python is dynamically typed, the
distinction between "tuple" and "array" simply doesn't exist.
So Python doesn't have the issues that C++ does.
As was stated earlier, doing it this way would be a huge change that likely
> would never make it past the committee.
>
But it's the right way to do it. And quite frankly, we don't need multiple
return values so badly that we should do it the wrong way just to have
*some* convenient way to do it.
Some people use tuples a lot (some might say to the point of overuse). But
you shouldn't steal potentially useful syntax from those C++ programmers
who don't use them. Syntax is a precious commodity, which once apportioned,
cannot be taken back.
It should also be noted that reflection, with the full ability to
compile-time inspect and generate types with full syntax (including
variable names) makes tuples... a dubious proposition for the future of
C++. With reflection, you can index a struct by number. With reflection,
you can take any typelist and build an honest-to-God struct out of it
(which can be standard layout and such).
In short, it is entirely possible that tuples will become obsolete, thus
also obsoleting this kind of syntax. So let's not have another std::bind
happen here...
> Each platform will have to define a new calling convention for multiple
> return valued functions. We would never get support for interfaces which
> already return pair and tuple and they could never be changed because it
> would break old code. Other than potential performance concerns with RVO
> that might be alleviated by using references, what is the real benefit of
> doing it as a pure language feature like this?
>
Well sure, if you ignore all of the advantages of something, then yes
there's not much point to it.
How would you for example support a range for loop with std::unordered_map?
> The iterator dereference already returns a std::pair.
>
To extend it for multiple return values, all you need is an alternate
iterator type that returns multiple values.
--
---
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 http://groups.google.com/a/isocpp.org/group/std-proposals/.
------=_Part_5933_1375561123.1432689830792
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">On Tuesday, May 26, 2015 at 5:23:20 PM UTC-4, Matthew Fior=
avante wrote:<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><br>On Tuesday, May 26, 2015 at 4:42:29 PM UTC-4, Nicol Bolas wr=
ote:<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">Also, I should=
make this clear: I'm not supporting the idea of returning a "tuple-like ty=
pe". I'm saying that we should have multiple return values from functions. =
Just like functions can have multiple parameters.<br><div><br>You don't sti=
ck your parameters in a `tuple` just to call a function, so why should you =
pull them from a `tuple` when you return them? It's purely a language limit=
ation, and one that is decidedly artificial.<br></div></div></blockquote><d=
iv><br>Why not?</div></div></blockquote><div><br>Because it requires needle=
ss copy/moving. Because it looks like worse syntax than function parameters=
, even with your terse version. Because it provides absolutely zero descrip=
tive information about what those parameters mean.<br><br>Because it's enti=
rely pointless, and has been since we got variadic templates. Unless you ha=
ppen to have a collection of values that are already in a tuple, there's no=
reason to pass a tuple to a function as a set of parameters.<br><br></div>=
<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>Conceptu=
ally, there is little difference between a type list and list of function p=
arameters. You could think of calling a function as "take these local varia=
bles, arrange them into a type list, and call the function with that list o=
f parameters". Some languages like python let you expand a tuple in place t=
o call a function with it as the parameters. Python also handles multiple r=
eturn value capture using tuple syntax.<br></div></div></blockquote><div><b=
r>Yeah, and Python also handles <i>multiple return values</i> as a first-cl=
ass language feature. It doesn't force you to package your multiple return =
values into a tuple, return them, and then unpack them. Nor does it force y=
ou to package parameters into a tuple.<br><br>So you're kind of proving my =
point for me.<br><br>It should also be noted that Python:<br><br>1) Is not =
a statically typed language.<br><br>2) Is not a strongly typed language.<br=
><br>Because of these, Python doesn't have "tuples" at all. It simply has a=
rrays (and other data structures), which can contain values by index. It ha=
s a function that can take an array and return that array as though it were=
a sequence of values. And so forth. Because Python is dynamically typed, t=
he distinction between "tuple" and "array" simply doesn't exist.<br><br>So =
Python doesn't have the issues that C++ does.<br><br></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>As was stated earlier, d=
oing it this way would be a huge change that likely would never make it pas=
t the committee.</div></div></blockquote><div><br>But it's the right way to=
do it. And quite frankly, we don't need multiple return values so badly th=
at we should do it the wrong way just to have <i>some</i> convenient way to=
do it.<br><br>Some people use tuples a lot (some might say to the point of=
overuse). But you shouldn't steal potentially useful syntax from those C++=
programmers who don't use them. Syntax is a precious commodity, which once=
apportioned, cannot be taken back.<br><br>It should also be noted that ref=
lection, with the full ability to=20
compile-time inspect and generate types with full syntax=20
(including variable names) makes tuples... a dubious proposition for the
future of C++. With reflection, you can index a struct by number. With ref=
lection, you can take any typelist and build an honest-to-God=20
struct out of it (which can be standard layout and such).<br><br>In short, =
it is entirely possible that tuples will become obsolete, thus also obsolet=
ing this kind of syntax. So let's not have another std::bind happen here...=
<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"lt=
r"><div>Each platform will have to define a new calling convention for mult=
iple return valued functions. We would never get support for interfaces whi=
ch already return pair and tuple and they could never be changed because it=
would break old code. Other than potential performance concerns with RVO t=
hat might be alleviated by using references, what is the real benefit of do=
ing it as a pure language feature like this?<br></div></div></blockquote><d=
iv><br>Well sure, if you ignore all of the advantages of something, then ye=
s there's not much point to it.<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>How would you for example support a ra=
nge for loop with std::unordered_map? The iterator dereference already retu=
rns a std::pair.</div></div></blockquote><div><br>To extend it for multiple=
return values, all you need is an alternate iterator type that returns mul=
tiple values.<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"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />
------=_Part_5933_1375561123.1432689830792--
------=_Part_5932_727366721.1432689830792--
.
Author: Matthew Fioravante <fmatthew5876@gmail.com>
Date: Tue, 26 May 2015 19:53:04 -0700 (PDT)
Raw View
------=_Part_5350_2126470302.1432695184948
Content-Type: multipart/alternative;
boundary="----=_Part_5351_1163512340.1432695184948"
------=_Part_5351_1163512340.1432695184948
Content-Type: text/plain; charset=UTF-8
On Tuesday, May 26, 2015 at 9:23:50 PM UTC-4, Nicol Bolas wrote:
>
> On Tuesday, May 26, 2015 at 5:23:20 PM UTC-4, Matthew Fioravante wrote:
>>
>>
>> On Tuesday, May 26, 2015 at 4:42:29 PM UTC-4, Nicol Bolas wrote:
>>>
>>> Also, I should make this clear: I'm not supporting the idea of returning
>>> a "tuple-like type". I'm saying that we should have multiple return values
>>> from functions. Just like functions can have multiple parameters.
>>>
>>> You don't stick your parameters in a `tuple` just to call a function, so
>>> why should you pull them from a `tuple` when you return them? It's purely a
>>> language limitation, and one that is decidedly artificial.
>>>
>>
>> Why not?
>>
>
> Because it requires needless copy/moving.
>
I don't see any needless copying happening below.
void foo(int x, const string& s);
tuple<int,string> t;
foo([*]t); //expands to foo(get<0>(t), get<1>(t));
> Because it looks like worse syntax than function parameters, even with
> your terse version. Because it provides absolutely zero descriptive
> information about what those parameters mean.
>
You yourself suggested the following:
[int,float,double] foo() { return {1, 1.0f, 1.0 }; }
All that tells me is that foo() returns an int, float, and double. How is
this more descriptive than a tuple?
>
> Because it's entirely pointless, and has been since we got variadic
> templates. Unless you happen to have a collection of values that are
> already in a tuple, there's no reason to pass a tuple to a function as a
> set of parameters.
>
Magnus just showed a use case for this.. Composing multi-return functions
together. Even if tuple is not used, something just like this would be need
to say "unpack the multi-return values and forward them directly to the
next function".
>
> Conceptually, there is little difference between a type list and list of
>> function parameters. You could think of calling a function as "take these
>> local variables, arrange them into a type list, and call the function with
>> that list of parameters". Some languages like python let you expand a tuple
>> in place to call a function with it as the parameters. Python also handles
>> multiple return value capture using tuple syntax.
>>
>
> Yeah, and Python also handles *multiple return values* as a first-class
> language feature. It doesn't force you to package your multiple return
> values into a tuple, return them, and then unpack them.
>
The multiple return values should be in some kind of container, whether its
a tuple or something else. Sometimes I want to deal with the whole
collection as one object, other times I want to unpack right away into
local variables which could just be references to the original pack.
> Nor does it force you to package parameters into a tuple.
>
But it does, at least at the syntax level
def foo():
return (1, 2, 3);
(x, y, z) = foo();
>
> So you're kind of proving my point for me.
>
> It should also be noted that Python:
>
> 1) Is not a statically typed language.
>
> 2) Is not a strongly typed language.
>
> Because of these, Python doesn't have "tuples" at all. It simply has
> arrays (and other data structures), which can contain values by index. It
> has a function that can take an array and return that array as though it
> were a sequence of values. And so forth. Because Python is dynamically
> typed, the distinction between "tuple" and "array" simply doesn't exist.
>
Which is why we may need a tuple like syntax and an array like syntax.
>
> So Python doesn't have the issues that C++ does.
>
> As was stated earlier, doing it this way would be a huge change that
>> likely would never make it past the committee.
>>
>
> But it's the right way to do it. And quite frankly, we don't need multiple
> return values so badly that we should do it the wrong way just to have
> *some* convenient way to do it.
>
> Some people use tuples a lot (some might say to the point of overuse). But
> you shouldn't steal potentially useful syntax from those C++ programmers
> who don't use them.
>
Programmers who have no interest in tuple itself can just use the syntax to
return multiple values and unpack them at the call site. They don't have to
care that tuple (or something tuple like) is used to accomplish this.
> Syntax is a precious commodity, which once apportioned, cannot be taken
> back.
>
> It should also be noted that reflection, with the full ability to
> compile-time inspect and generate types with full syntax (including
> variable names) makes tuples... a dubious proposition for the future of
> C++. With reflection, you can index a struct by number. With reflection,
> you can take any typelist and build an honest-to-God struct out of it
> (which can be standard layout and such).
>
> In short, it is entirely possible that tuples will become obsolete, thus
> also obsoleting this kind of syntax. So let's not have another std::bind
> happen here...
>
[int,long,double] foo();
auto x = foo();
Ok, if tuple is out then what is decltype(x) in the above example doing
things your way? Another kind of typelist which is standard layout
compatible? Or are we no longer able to capture all of the return values
into one object?
If not using tuple, can you explain in a bit more detail how your proposed
solution would actually work?
>
>
>> Each platform will have to define a new calling convention for multiple
>> return valued functions. We would never get support for interfaces which
>> already return pair and tuple and they could never be changed because it
>> would break old code. Other than potential performance concerns with RVO
>> that might be alleviated by using references, what is the real benefit of
>> doing it as a pure language feature like this?
>>
>
> Well sure, if you ignore all of the advantages of something, then yes
> there's not much point to it.
>
> How would you for example support a range for loop with
>> std::unordered_map? The iterator dereference already returns a std::pair.
>>
>
> To extend it for multiple return values, all you need is an alternate
> iterator type that returns multiple values.
>
So how do I get to use this alternate iterator type? That means I have to
add some range wrapper because the default iterators with begin/end still
use std::pair.
for([auto& k; auto& v] : make_multi_return_range(hashmap)){}
That would be pretty sad if in order to simplify the left side of the loop
I have to add boilerplate to the right. Something like this should work
naturally. Even if tuple is not the answer, I would hope some kind of
automatic compatibility with tuple/pair is provided so we can write simple
code with STL classes without awful legacy wrappers like
make_multi_return_range().
I should be able to do both of these without any unnecessary additional
noise.
for(auto& kv: hashmap);
for([auto& k; auto& v]: hashmap);
--
---
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 http://groups.google.com/a/isocpp.org/group/std-proposals/.
------=_Part_5351_1163512340.1432695184948
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><br><br>On Tuesday, May 26, 2015 at 9:23:50 PM UTC-4, Nico=
l 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, May 26, 2015 at 5:23:20 PM UTC-4, Matthew Fioravante wrote:<bl=
ockquote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-l=
eft:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><div></div><br>On Tue=
sday, May 26, 2015 at 4:42:29 PM UTC-4, Nicol Bolas wrote:<blockquote class=
=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc s=
olid;padding-left:1ex"><div dir=3D"ltr">Also, I should make this clear: I'm=
not supporting the idea of returning a "tuple-like type". I'm saying that =
we should have multiple return values from functions. Just like functions c=
an have multiple parameters.<br><div><br>You don't stick your parameters in=
a `tuple` just to call a function, so why should you pull them from a `tup=
le` when you return them? It's purely a language limitation, and one that i=
s decidedly artificial.<br></div></div></blockquote><div><br>Why not?</div>=
</div></blockquote><div><br>Because it requires needless copy/moving. </div=
></div></blockquote><div><br></div><div>I don't see any needless copying ha=
ppening below.</div><div><br></div><div><div class=3D"prettyprint" style=3D=
"border: 1px solid rgb(187, 187, 187); word-wrap: break-word; background-co=
lor: rgb(250, 250, 250);"><code class=3D"prettyprint"><div class=3D"subpret=
typrint"><span style=3D"color: #008;" class=3D"styled-by-prettify">void</sp=
an><span style=3D"color: #000;" class=3D"styled-by-prettify"> foo</span><sp=
an 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: #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: #008;" class=3D"style=
d-by-prettify">const</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">&am=
p;</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> s</span=
><span style=3D"color: #660;" class=3D"styled-by-prettify">);</span><span s=
tyle=3D"color: #000;" class=3D"styled-by-prettify"><br>tuple</span><span st=
yle=3D"color: #660;" class=3D"styled-by-prettify"><</span><span style=3D=
"color: #008;" class=3D"styled-by-prettify">int</span><span style=3D"color:=
#660;" class=3D"styled-by-prettify">,</span><span style=3D"color: #008;" c=
lass=3D"styled-by-prettify">string</span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">></span><span style=3D"color: #000;" class=3D"st=
yled-by-prettify"> t</span><span style=3D"color: #660;" class=3D"styled-by-=
prettify">;</span><span style=3D"color: #000;" class=3D"styled-by-prettify"=
><br><br>foo</span><span style=3D"color: #660;" class=3D"styled-by-prettify=
">([*]</span><span style=3D"color: #000;" class=3D"styled-by-prettify">t</s=
pan><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: #800;" class=3D"styled-by-prettify">//expands to foo(get<0>=
;(t), get<1>(t));</span><span style=3D"color: #000;" class=3D"styled-=
by-prettify"><br><br></span></div></code></div><div><br></div></div><div>&n=
bsp;</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"><di=
v>Because it looks like worse syntax than function parameters, even with yo=
ur terse version. Because it provides absolutely zero descriptive informati=
on about what those parameters mean.<br></div></div></blockquote><div> =
;</div><div>You yourself suggested the following:</div><div><br></div><div>=
<div class=3D"prettyprint" style=3D"border: 1px solid rgb(187, 187, 187); w=
ord-wrap: break-word; background-color: rgb(250, 250, 250);"><code class=3D=
"prettyprint"><div class=3D"subprettyprint"><span style=3D"color: #660;" cl=
ass=3D"styled-by-prettify">[</span><span style=3D"color: #008;" class=3D"st=
yled-by-prettify">int</span><span style=3D"color: #660;" class=3D"styled-by=
-prettify">,</span><span style=3D"color: #008;" class=3D"styled-by-prettify=
">float</span><span style=3D"color: #660;" 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 st=
yle=3D"color: #000;" class=3D"styled-by-prettify"> foo</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;" 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">return</span><span style=3D"color: #000;" class=3D"styled-by-prett=
ify"> </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">1.0f</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">1.0</span><span style=3D"color: #000;" class=3D"styled-by-pretti=
fy"> </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: #660;" class=3D"styled-by-prettify">}</span></div></code><=
/div><br></div><div>All that tells me is that foo() returns an int, float, =
and double. How is this more descriptive than a tuple?</div><div> </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"><div><br>Be=
cause it's entirely pointless, and has been since we got variadic templates=
.. Unless you happen to have a collection of values that are already in a tu=
ple, there's no reason to pass a tuple to a function as a set of parameters=
..<br></div></div></blockquote><div><br></div><div>Magnus just showed a use =
case for this.. Composing multi-return functions together. Even if tuple is=
not used, something just like this would be need to say "unpack the multi-=
return values and forward them directly to the next function".</div><div>&n=
bsp;</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"><di=
v><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>C=
onceptually, there is little difference between a type list and list of fun=
ction parameters. You could think of calling a function as "take these loca=
l variables, arrange them into a type list, and call the function with that=
list of parameters". Some languages like python let you expand a tuple in =
place to call a function with it as the parameters. Python also handles mul=
tiple return value capture using tuple syntax.<br></div></div></blockquote>=
<div><br>Yeah, and Python also handles <i>multiple return values</i> as a f=
irst-class language feature. It doesn't force you to package your multiple =
return values into a tuple, return them, and then unpack them. </div></div>=
</blockquote><div><br></div><div>The multiple return values should be in so=
me kind of container, whether its a tuple or something else. Sometimes I wa=
nt to deal with the whole collection as one object, other times I want to u=
npack right away into local variables which could just be references to the=
original pack.</div><div> </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>Nor does it force you to package parameters i=
nto a tuple.<br></div></div></blockquote><div><br></div><div>But it does, a=
t least at the syntax level</div><div><br></div><div class=3D"prettyprint" =
style=3D"border: 1px solid rgb(187, 187, 187); word-wrap: break-word; backg=
round-color: rgb(250, 250, 250);"><code class=3D"prettyprint"><div class=3D=
"subprettyprint"><span style=3D"color: #008;" class=3D"styled-by-prettify">=
def</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> foo</s=
pan><span style=3D"color: #660;" class=3D"styled-by-prettify">():</span><sp=
an style=3D"color: #000;" class=3D"styled-by-prettify"><br> </=
span><span style=3D"color: #008;" class=3D"styled-by-prettify">return</span=
><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span st=
yle=3D"color: #660;" class=3D"styled-by-prettify">(</span><span style=3D"co=
lor: #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"style=
d-by-prettify">2</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: #066;" class=3D"styled-by-prettify">3</span><spa=
n 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: #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><span style=3D"color: #000;" class=3D"=
styled-by-prettify"> y</span><span style=3D"color: #660;" class=3D"styled-b=
y-prettify">,</span><span style=3D"color: #000;" class=3D"styled-by-prettif=
y"> z</span><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: #660;" class=3D"styled-by-prettify">=3D</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"> foo</span><span style=3D"co=
lor: #660;" class=3D"styled-by-prettify">();</span></div></code></div><div>=
<br></div><div> </div><blockquote class=3D"gmail_quote" style=3D"margi=
n: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><di=
v dir=3D"ltr"><div><br>So you're kind of proving my point for me.<br><br>It=
should also be noted that Python:<br><br>1) Is not a statically typed lang=
uage.<br><br>2) Is not a strongly typed language.<br><br>Because of these, =
Python doesn't have "tuples" at all. It simply has arrays (and other data s=
tructures), which can contain values by index. It has a function that can t=
ake an array and return that array as though it were a sequence of values. =
And so forth. Because Python is dynamically typed, the distinction between =
"tuple" and "array" simply doesn't exist.<br></div></div></blockquote><div>=
<br></div><div>Which is why we may need a tuple like syntax and an array li=
ke syntax.</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><br>So Python doesn't have the issues that C++ doe=
s.<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>As was stated earlier, doing it this way would be a huge change that lik=
ely would never make it past the committee.</div></div></blockquote><div><b=
r>But it's the right way to do it. And quite frankly, we don't need multipl=
e return values so badly that we should do it the wrong way just to have <i=
>some</i> convenient way to do it.<br><br>Some people use tuples a lot (som=
e might say to the point of overuse). But you shouldn't steal potentially u=
seful syntax from those C++ programmers who don't use them. </div></div></b=
lockquote><div><br></div><div>Programmers who have no interest in tuple its=
elf can just use the syntax to return multiple values and unpack them at th=
e call site. They don't have to care that tuple (or something tuple like) i=
s used to accomplish this.</div><div> </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>Syntax is a precious commodity, wh=
ich once apportioned, cannot be taken back.<br><br>It should also be noted =
that reflection, with the full ability to=20
compile-time inspect and generate types with full syntax=20
(including variable names) makes tuples... a dubious proposition for the
future of C++. With reflection, you can index a struct by number. With ref=
lection, you can take any typelist and build an honest-to-God=20
struct out of it (which can be standard layout and such).<br><br>In short, =
it is entirely possible that tuples will become obsolete, thus also obsolet=
ing this kind of syntax. So let's not have another std::bind happen here...=
<br></div></div></blockquote><div><br></div><div><div class=3D"prettyprint"=
style=3D"border: 1px solid rgb(187, 187, 187); word-wrap: break-word; back=
ground-color: rgb(250, 250, 250);"><code class=3D"prettyprint"><div class=
=3D"subprettyprint"><span style=3D"color: #660;" class=3D"styled-by-prettif=
y">[</span><span style=3D"color: #008;" class=3D"styled-by-prettify">int</s=
pan><span style=3D"color: #660;" class=3D"styled-by-prettify">,</span><span=
style=3D"color: #008;" class=3D"styled-by-prettify">long</span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">,</span><span style=3D"color=
: #008;" class=3D"styled-by-prettify">double</span><span style=3D"color: #6=
60;" class=3D"styled-by-prettify">]</span><span style=3D"color: #000;" clas=
s=3D"styled-by-prettify"> foo</span><span style=3D"color: #660;" class=3D"s=
tyled-by-prettify">();</span><span style=3D"color: #000;" class=3D"styled-b=
y-prettify"><br></span><span style=3D"color: #008;" class=3D"styled-by-pret=
tify">auto</span><span style=3D"color: #000;" class=3D"styled-by-prettify">=
x </span><span style=3D"color: #660;" class=3D"styled-by-prettify">=3D</sp=
an><span style=3D"color: #000;" class=3D"styled-by-prettify"> foo</span><sp=
an style=3D"color: #660;" class=3D"styled-by-prettify">();</span><font colo=
r=3D"#666600"></font></div></code></div><br></div><div>Ok, if tuple is out =
then what is decltype(x) in the above example doing things your way? Anothe=
r kind of typelist which is standard layout compatible? Or are we no longer=
able to capture all of the return values into one object?</div><div><br></=
div><div>If not using tuple, can you explain in a bit more detail how your =
proposed solution would actually work?</div><div> </div><blockquote cl=
ass=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"><div>Each platform will have=
to define a new calling convention for multiple return valued functions. W=
e would never get support for interfaces which already return pair and tupl=
e and they could never be changed because it would break old code. Other th=
an potential performance concerns with RVO that might be alleviated by usin=
g references, what is the real benefit of doing it as a pure language featu=
re like this?<br></div></div></blockquote><div><br>Well sure, if you ignore=
all of the advantages of something, then yes there's not much point to it.=
<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=
>How would you for example support a range for loop with std::unordered_map=
? The iterator dereference already returns a std::pair.</div></div></blockq=
uote><div><br>To extend it for multiple return values, all you need is an a=
lternate iterator type that returns multiple values.<br></div></div></block=
quote><div><br></div><div>So how do I get to use this alternate iterator ty=
pe? That means I have to add some range wrapper because the default iterato=
rs with begin/end still use std::pair.</div><div><br></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"prettypri=
nt"><div class=3D"subprettyprint"><span style=3D"color: #008;" class=3D"sty=
led-by-prettify">for</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 style=3D"color: #000;" class=3D"styled-by-prettify"> k</span>=
<span style=3D"color: #660;" class=3D"styled-by-prettify">;</span><span sty=
le=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"col=
or: #008;" class=3D"styled-by-prettify">auto</span><span style=3D"color: #6=
60;" class=3D"styled-by-prettify">&</span><span style=3D"color: #000;" =
class=3D"styled-by-prettify"> v</span><span style=3D"color: #660;" class=3D=
"styled-by-prettify">]</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><font color=3D"#000000"><span style=3D"color: #000;" class=3D"st=
yled-by-prettify"> make_multi_return_range</span><span style=3D"color: #660=
;" class=3D"styled-by-prettify">(</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify">hashmap</span><span style=3D"color: #660;" class=3D=
"styled-by-prettify">)){}</span></font><font color=3D"#000000"></font></div=
></code></div><br>That would be pretty sad if in order to simplify the left=
side of the loop I have to add boilerplate to the right. Something like th=
is should work naturally. Even if tuple is not the answer, I would hope som=
e kind of automatic compatibility with tuple/pair is provided so we can wri=
te simple code with STL classes without awful legacy wrappers like make_mul=
ti_return_range().</div><div><br></div><div>I should be able to do both of =
these without any unnecessary additional noise.</div><div><br></div><div><d=
iv class=3D"prettyprint" style=3D"border: 1px solid rgb(187, 187, 187); wor=
d-wrap: break-word; background-color: rgb(250, 250, 250);"><code class=3D"p=
rettyprint"><div class=3D"subprettyprint"><span style=3D"color: #008;" clas=
s=3D"styled-by-prettify">for</span><span style=3D"color: #660;" class=3D"st=
yled-by-prettify">(</span><span style=3D"color: #008;" class=3D"styled-by-p=
rettify">auto</span><span style=3D"color: #660;" class=3D"styled-by-prettif=
y">&</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> k=
v</span><span style=3D"color: #660;" class=3D"styled-by-prettify">:</span><=
span style=3D"color: #000;" class=3D"styled-by-prettify"> hashmap</span><sp=
an 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"co=
lor: #008;" class=3D"styled-by-prettify">for</span><span style=3D"color: #6=
60;" class=3D"styled-by-prettify">([</span><span style=3D"color: #008;" cla=
ss=3D"styled-by-prettify">auto</span><span style=3D"color: #660;" class=3D"=
styled-by-prettify">&</span><span style=3D"color: #000;" class=3D"style=
d-by-prettify"> k</span><span style=3D"color: #660;" class=3D"styled-by-pre=
ttify">;</span><span style=3D"color: #000;" 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=
style=3D"color: #000;" class=3D"styled-by-prettify"> v</span><font color=
=3D"#666600"><span style=3D"color: #660;" class=3D"styled-by-prettify">]:</=
span><span style=3D"color: #000;" class=3D"styled-by-prettify"> hashmap</sp=
an><span style=3D"color: #660;" class=3D"styled-by-prettify">);</span></fon=
t></div></code></div><br><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"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />
------=_Part_5351_1163512340.1432695184948--
------=_Part_5350_2126470302.1432695184948--
.
Author: Nicol Bolas <jmckesson@gmail.com>
Date: Wed, 27 May 2015 00:43:10 -0700 (PDT)
Raw View
------=_Part_5552_178908165.1432712590537
Content-Type: multipart/alternative;
boundary="----=_Part_5553_432423355.1432712590537"
------=_Part_5553_432423355.1432712590537
Content-Type: text/plain; charset=UTF-8
On Tuesday, May 26, 2015 at 10:53:05 PM UTC-4, Matthew Fioravante wrote:
>
> On Tuesday, May 26, 2015 at 9:23:50 PM UTC-4, Nicol Bolas wrote:
>>
>> On Tuesday, May 26, 2015 at 5:23:20 PM UTC-4, Matthew Fioravante wrote:
>>>
>>> On Tuesday, May 26, 2015 at 4:42:29 PM UTC-4, Nicol Bolas wrote:
>>>>
>>>> Also, I should make this clear: I'm not supporting the idea of
>>>> returning a "tuple-like type". I'm saying that we should have multiple
>>>> return values from functions. Just like functions can have multiple
>>>> parameters.
>>>>
>>>> You don't stick your parameters in a `tuple` just to call a function,
>>>> so why should you pull them from a `tuple` when you return them? It's
>>>> purely a language limitation, and one that is decidedly artificial.
>>>>
>>>
>>> Why not?
>>>
>>
>> Because it requires needless copy/moving.
>>
>
> I don't see any needless copying happening below.
>
> void foo(int x, const string& s);
> tuple<int,string> t;
>
> foo([*]t); //expands to foo(get<0>(t), get<1>(t));
>
>
>
Please re-read what I said: "You don't stick your parameters in a `tuple`
just to call a function." I was analogizing return-values-as-tuple with
parameters-as-tuple, which would require that `foo` in your example take a
tuple, not a list of parameters. Passing parameters as a tuple would
require copy/moving the parameters into the tuple. Hence the "needless
copying" bit.
>
>> Because it looks like worse syntax than function parameters, even with
>> your terse version. Because it provides absolutely zero descriptive
>> information about what those parameters mean.
>>
>
> You yourself suggested the following:
>
> [int,float,double] foo() { return {1, 1.0f, 1.0 }; }
>
> All that tells me is that foo() returns an int, float, and double. How is
> this more descriptive than a tuple?
>
Ahem: "You don't stick your parameters in a `tuple` just to call a
function." That's the context of that part of the discussion. That's what
"looks like worse syntax than function parameters".
>
>>
>> Because it's entirely pointless, and has been since we got variadic
>> templates. Unless you happen to have a collection of values that are
>> already in a tuple, there's no reason to pass a tuple to a function as a
>> set of parameters.
>>
>
> Magnus just showed a use case for this.. Composing multi-return functions
> together.
>
Since multiple return values are not something that exists, they can be
defined to be whatever we want. So if we want function composition to work
with multiple return values, I see nothing standing in the way of declaring
that it does. And most importantly of all, it would require *zero* syntax
(outside of declaring that the inner function returns multiple values). See
below.
Even if tuple is not used, something just like this would be need to say
> "unpack the multi-return values and forward them directly to the next
> function".
>
You're assuming that multiple return values are in any way "packed".
They're not; they're *multiple return values*. At no time are MRV's a
single value packed into anything.
Scripting languages (or at least, ones that don't make whitespace part of
their grammar. See below) do this all the time; that's how they make
multiple return values work.
>
>
>> Nor does it force you to package parameters into a tuple.
>>
>
> But it does, at least at the syntax level
>
> def foo():
> return (1, 2, 3);
>
> (x, y, z) = foo();
>
>
Sorry, my knowledge of Python is limited; I just assumed it worked more or
less like Lua.
In Lua, you don't need special syntax for returning or capturing multiple
values. And quite frankly, I see no reason why you should:
function foo()
return 1, 2, 3 --Returns a sequence of 3 values.
end
function bar()
return {1, 2, 3} --Returns a single table, containing 3 values
end
local x, y, z = foo() --Declares 3 local variables, initializing them with 3
values from the function.
local w = {foo()} --Stores the sequence of values returned from `foo` in a
table (aka: array)
local a = bar() --Stores the table
local comp = bar(foo()) --The sequence is passed to `bar` as 3 parameters.
local comp2 = bar(bar()) --A single parameter is passed to the outer `bar`.
local comp3 = bar(unpack(bar())) --Unpacks the array into the outer `bar`'s
parameters
I find that much more reasonable and consistent than the Python syntax.
There is a distinction between a sequence of values and a data structure.
`foo` and `bar` may be "conceptually" the same, but functionally they're
different. One returns a sequence of values, the other returns a table. If
you need to convert a table into a sequence of values, you call `unpack`.
If you need to convert a sequence of values into a table, you create a
table with it.
Sequences of values in Lua are ephemeral; if you want to store the sequence
and preserve it as a sequence, you stick it in a table. But if you just
want to compose functions, store values, and the like, you use the sequence
as is.
If C++ is going to pattern its functionality off of something, I'd much
rather Lua's proper MRV syntax than Python's MRVs-as-arrays (I assume the
() syntax is creating an array of some kind).
>
>
>> As was stated earlier, doing it this way would be a huge change that
>>> likely would never make it past the committee.
>>>
>>
>> But it's the right way to do it. And quite frankly, we don't need
>> multiple return values so badly that we should do it the wrong way just to
>> have *some* convenient way to do it.
>>
>> Some people use tuples a lot (some might say to the point of overuse).
>> But you shouldn't steal potentially useful syntax from those C++
>> programmers who don't use them.
>>
>
> Programmers who have no interest in tuple itself can just use the syntax
> to return multiple values and unpack them at the call site. They don't have
> to care that tuple (or something tuple like) is used to accomplish this.
>
Except that they have to pay the cost for it. Consider something simple
like this:
auto single_value()
{
std::string a = ...;
return a;
}
auto multi_value()
{
std::string a = ...;
std::vector b = ...;
return [a; b];
}
`single_value` is subject to copy elision, so you should feel no problem
with using it. Even with a small-string-optimized std::string class, you
will get the maximum possible performance if you're using the result to
initialize an object.
With language-level multiple return values, `multi_value` would be able to
operate under the same principle. `a` and `b` would be considered return
values, and they would each be separately subject to elision.
With your way, that's just not possible. If that syntax creates a `tuple`,
then it must copy or move initialize the elements of that `tuple`. So even
though the `tuple` itself is subject to elision, the creation of it is not.
>
>> Syntax is a precious commodity, which once apportioned, cannot be taken
>> back.
>>
>> It should also be noted that reflection, with the full ability to
>> compile-time inspect and generate types with full syntax (including
>> variable names) makes tuples... a dubious proposition for the future of
>> C++. With reflection, you can index a struct by number. With reflection,
>> you can take any typelist and build an honest-to-God struct out of it
>> (which can be standard layout and such).
>>
>> In short, it is entirely possible that tuples will become obsolete, thus
>> also obsoleting this kind of syntax. So let's not have another std::bind
>> happen here...
>>
>
> [int,long,double] foo();
> auto x = foo();
>
> Ok, if tuple is out then what is decltype(x) in the above example doing
> things your way?
>
There are two defensible answers to this:
1) A compilation error. You called a function that returns 3 things, but
you only captured one. That suggests you weren't paying attention.
2) `int`. The other two types are dropped on the floor.
#2 is probably the way to go. Any sort of aggregate object type is not even
up for discussion.
Multiple return values means *multiple return values*, not "pack multiple
values into some kind of object and unpack them later".
> Another kind of typelist which is standard layout compatible? Or are we no
> longer able to capture all of the return values into one object?
>
If you want to capture them all in an object, you just ask for it:
auto x = make_tuple(foo());
That is neither hard nor particularly verbose. You can even stick them in
an array, if all of the returned values are of the same type:
auto x = make_array(foo());
Or in an arbitrary data structure:
auto x = std::vector<Type>{foo()};
But most people using multiple return values don't capture them in a big
object, so we don't make the syntax optimal for that case.
If not using tuple, can you explain in a bit more detail how your proposed
> solution would actually work?
>
The details of how it works are more or less the way Lua works.
In C++ parlance, the notion of a "sequence of values" would be a construct.
It would *not* necessarily be an "expression", in the same way that a
braced-init-list is not an expression. Since it's a new construct, you can
give it whatever properties you want.
Functions can return sequences of values, with the sequence as a full part
of its return type. Using the sequence initialization syntax, you can
initialize/assign multiple variables to a sequence of values. If a sequence
of values is given to a function argument list, the values are placed in
that list as arguments. If the sequence of values is used in any other kind
of expression, then it resolves down to the first element of that sequence
of values.
Initialization/assignment of variables through a sequence would work
element by element, in order from left to right.
--
---
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 http://groups.google.com/a/isocpp.org/group/std-proposals/.
------=_Part_5553_432423355.1432712590537
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">On Tuesday, May 26, 2015 at 10:53:05 PM UTC-4, Matthew Fio=
ravante 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, May 26, 2015 at 9:23:50 PM UTC-4, Nicol Bolas wrote:<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">On Tuesday, May 26, 2015 at =
5:23:20 PM UTC-4, Matthew Fioravante wrote:<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>On Tuesday, May 26, 2015 at 4:42:29 PM =
UTC-4, 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">Also, I should make this clear: I'm not supporting the idea of ret=
urning a "tuple-like type". I'm saying that we should have multiple return =
values from functions. Just like functions can have multiple parameters.<br=
><div><br>You don't stick your parameters in a `tuple` just to call a funct=
ion, so why should you pull them from a `tuple` when you return them? It's =
purely a language limitation, and one that is decidedly artificial.<br></di=
v></div></blockquote><div><br>Why not?</div></div></blockquote><div><br>Bec=
ause it requires needless copy/moving. </div></div></blockquote><div><br></=
div><div>I don't see any needless copying happening below.</div><div><br></=
div><div><div style=3D"border:1px solid rgb(187,187,187);word-wrap:break-wo=
rd;background-color:rgb(250,250,250)"><code><div><span style=3D"color:#008"=
>void</span><span style=3D"color:#000"> foo</span><span style=3D"color:#660=
">(</span><span style=3D"color:#008">int</span><span style=3D"color:#000"> =
x</span><span style=3D"color:#660">,</span><span style=3D"color:#000"> </sp=
an><span style=3D"color:#008">const</span><span style=3D"color:#000"> </spa=
n><span style=3D"color:#008">string</span><span style=3D"color:#660">&<=
/span><span style=3D"color:#000"> s</span><span style=3D"color:#660">);</sp=
an><span style=3D"color:#000"><br>tuple</span><span style=3D"color:#660">&l=
t;</span><span style=3D"color:#008">int</span><span style=3D"color:#660">,<=
/span><span style=3D"color:#008">string</span><span style=3D"color:#660">&g=
t;</span><span style=3D"color:#000"> t</span><span style=3D"color:#660">;</=
span><span style=3D"color:#000"><br><br>foo</span><span style=3D"color:#660=
">([*]</span><span style=3D"color:#000">t</span><span style=3D"color:#660">=
);</span><span style=3D"color:#000"> </span><span style=3D"color:#800">//ex=
pands to foo(get<0>(t), get<1>(t));</span><span style=3D"color:=
#000"><br><br></span></div></code></div><div><br></div></div></div></blockq=
uote><div><br>Please re-read what I said: "You don't stick your parameters =
in a `tuple` just to call a function." I was analogizing return-values-as-t=
uple with parameters-as-tuple, which would require that `foo` in your examp=
le take a tuple, not a list of parameters. Passing parameters as a tuple wo=
uld require copy/moving the parameters into the tuple. Hence the "needless =
copying" bit.<br><br></div><blockquote class=3D"gmail_quote" style=3D"margi=
n: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><di=
v dir=3D"ltr"><div><div></div></div><div> </div><blockquote class=3D"g=
mail_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;=
padding-left:1ex"><div dir=3D"ltr"><div>Because it looks like worse syntax =
than function parameters, even with your terse version. Because it provides=
absolutely zero descriptive information about what those parameters mean.<=
br></div></div></blockquote><div> </div><div>You yourself suggested th=
e following:</div><div><br></div><div><div style=3D"border:1px solid rgb(18=
7,187,187);word-wrap:break-word;background-color:rgb(250,250,250)"><code><d=
iv><span style=3D"color:#660">[</span><span style=3D"color:#008">int</span>=
<span style=3D"color:#660">,</span><span style=3D"color:#008">float</span><=
span style=3D"color:#660">,</span><span style=3D"color:#008">double</span><=
span style=3D"color:#660">]</span><span style=3D"color:#000"> foo</span><sp=
an 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 style=
=3D"color:#008">return</span><span style=3D"color:#000"> </span><span style=
=3D"color:#660">{</span><span style=3D"color:#066">1</span><span style=3D"c=
olor:#660">,</span><span style=3D"color:#000"> </span><span style=3D"color:=
#066">1.0f</span><span style=3D"color:#660">,</span><span style=3D"color:#0=
00"> </span><span style=3D"color:#066">1.0</span><span style=3D"color:#000"=
> </span><span style=3D"color:#660">};</span><span style=3D"color:#000"> </=
span><span style=3D"color:#660">}</span></div></code></div><br></div><div>A=
ll that tells me is that foo() returns an int, float, and double. How is th=
is more descriptive than a tuple?</div></div></blockquote><div><br>Ahem: "Y=
ou don't stick your parameters in a `tuple` just to call a function." That'=
s the context of that part of the discussion. That's what "looks like worse=
syntax than function parameters".<br><br></div><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> </div><blockquote class=3D"gm=
ail_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;p=
adding-left:1ex"><div dir=3D"ltr"><div><br>Because it's entirely pointless,=
and has been since we got variadic templates. Unless you happen to have a =
collection of values that are already in a tuple, there's no reason to pass=
a tuple to a function as a set of parameters.<br></div></div></blockquote>=
<div><br></div><div>Magnus just showed a use case for this.. Composing mult=
i-return functions together.</div></div></blockquote><div><br>Since multipl=
e return values are not something that exists, they can be defined to be wh=
atever we want. So if we want function composition to work with multiple re=
turn values, I see nothing standing in the way of declaring that it does. A=
nd most importantly of all, it would require <i>zero</i> syntax (outside of=
declaring that the inner function returns multiple values). See below.<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"><di=
v>Even if tuple is not used, something just like this would be need to say =
"unpack the multi-return values and forward them directly to the next funct=
ion".</div></div></blockquote><div><br>You're assuming that multiple return=
values are in any way "packed". They're not; they're <i>multiple return va=
lues</i>. At no time are MRV's a single value packed into anything.<br><br>=
Scripting languages (or at least, ones that don't make whitespace part of t=
heir grammar. See below) do this all the time; that's how they make multipl=
e return values work.<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> </div></div></blockquote><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"><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>Nor does it force y=
ou to package parameters into a tuple.<br></div></div></blockquote><div><br=
></div><div>But it does, at least at the syntax level</div><div><br></div><=
div style=3D"border:1px solid rgb(187,187,187);word-wrap:break-word;backgro=
und-color:rgb(250,250,250)"><code><div><span style=3D"color:#008">def</span=
><span style=3D"color:#000"> foo</span><span style=3D"color:#660">():</span=
><span style=3D"color:#000"><br> </span><span style=3D"color:#=
008">return</span><span style=3D"color:#000"> </span><span 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 style=3D"color:#066">2</sp=
an><span style=3D"color:#660">,</span><span style=3D"color:#000"> </span><s=
pan style=3D"color:#066">3</span><span style=3D"color:#660">);</span><span =
style=3D"color:#000"><br><br></span><span style=3D"color:#660">(</span><spa=
n style=3D"color:#000">x</span><span style=3D"color:#660">,</span><span sty=
le=3D"color:#000"> y</span><span style=3D"color:#660">,</span><span style=
=3D"color:#000"> z</span><span style=3D"color:#660">)</span><span style=3D"=
color:#000"> </span><span style=3D"color:#660">=3D</span><span style=3D"col=
or:#000"> foo</span><span style=3D"color:#660">();</span></div></code></div=
><div><br></div></div></blockquote><div><br>Sorry, my knowledge of Python i=
s limited; I just assumed it worked more or less like Lua.<br><br>In Lua, y=
ou don't need special syntax for returning or capturing multiple values. An=
d quite frankly, I see no reason why you should:<br><br><div class=3D"prett=
yprint" style=3D"background-color: rgb(250, 250, 250); border-color: rgb(18=
7, 187, 187); border-style: solid; border-width: 1px; word-wrap: break-word=
;"><code class=3D"prettyprint"><div class=3D"subprettyprint"><span style=3D=
"color: #008;" class=3D"styled-by-prettify">function</span><span style=3D"c=
olor: #000;" class=3D"styled-by-prettify"> foo</span><span style=3D"color: =
#660;" class=3D"styled-by-prettify">()</span><span style=3D"color: #000;" c=
lass=3D"styled-by-prettify"><br> </span><span style=3D"color: #008;" =
class=3D"styled-by-prettify">return</span><span style=3D"color: #000;" clas=
s=3D"styled-by-prettify"> </span><span style=3D"color: #066;" class=3D"styl=
ed-by-prettify">1</span><span style=3D"color: #660;" class=3D"styled-by-pre=
ttify">,</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> <=
/span><span style=3D"color: #066;" class=3D"styled-by-prettify">2</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=
: #066;" class=3D"styled-by-prettify">3</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: #606;" class=3D"styled-b=
y-prettify">Returns</span><span style=3D"color: #000;" class=3D"styled-by-p=
rettify"> a sequence of </span><span style=3D"color: #066;" class=3D"styled=
-by-prettify">3</span><span style=3D"color: #000;" class=3D"styled-by-prett=
ify"> values</span><span style=3D"color: #660;" class=3D"styled-by-prettify=
">.</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br></s=
pan><span style=3D"color: #008;" class=3D"styled-by-prettify">end</span><sp=
an style=3D"color: #000;" class=3D"styled-by-prettify"><br><br></span><span=
style=3D"color: #008;" class=3D"styled-by-prettify">function</span><span s=
tyle=3D"color: #000;" class=3D"styled-by-prettify"> bar</span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">()</span><span style=3D"colo=
r: #000;" class=3D"styled-by-prettify"><br> </span><span style=3D"col=
or: #008;" class=3D"styled-by-prettify">return</span><span style=3D"color: =
#000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #660;" cl=
ass=3D"styled-by-prettify">{</span><span style=3D"color: #066;" class=3D"st=
yled-by-prettify">1</span><span style=3D"color: #660;" class=3D"styled-by-p=
rettify">,</span><span style=3D"color: #000;" class=3D"styled-by-prettify">=
</span><span style=3D"color: #066;" class=3D"styled-by-prettify">2</span><=
span style=3D"color: #660;" class=3D"styled-by-prettify">,</span><span styl=
e=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"colo=
r: #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"> </span><span style=3D"color: #660;" class=3D"styled-b=
y-prettify">--</span><span style=3D"color: #606;" class=3D"styled-by-pretti=
fy">Returns</span><span style=3D"color: #000;" class=3D"styled-by-prettify"=
> a single table</span><span style=3D"color: #660;" class=3D"styled-by-pret=
tify">,</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> co=
ntaining </span><span style=3D"color: #066;" class=3D"styled-by-prettify">3=
</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> values<br=
></span><span style=3D"color: #008;" class=3D"styled-by-prettify">end</span=
><span style=3D"color: #000;" class=3D"styled-by-prettify"><br><br></span><=
span style=3D"color: #008;" class=3D"styled-by-prettify">local</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"> y</span><span style=3D"color: #660;" cl=
ass=3D"styled-by-prettify">,</span><span style=3D"color: #000;" class=3D"st=
yled-by-prettify"> z </span><span style=3D"color: #660;" class=3D"styled-by=
-prettify">=3D</span><span style=3D"color: #000;" class=3D"styled-by-pretti=
fy"> foo</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: #660;" class=3D"styled-by-prettify">--</span><span styl=
e=3D"color: #606;" class=3D"styled-by-prettify">Declares</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color=
: #066;" class=3D"styled-by-prettify">3</span><span style=3D"color: #000;" =
class=3D"styled-by-prettify"> </span><span style=3D"color: #008;" class=3D"=
styled-by-prettify">local</span><span style=3D"color: #000;" class=3D"style=
d-by-prettify"> variables</span><span style=3D"color: #660;" class=3D"style=
d-by-prettify">,</span><span style=3D"color: #000;" class=3D"styled-by-pret=
tify"> initializing them </span><span style=3D"color: #008;" class=3D"style=
d-by-prettify">with</span><span style=3D"color: #000;" class=3D"styled-by-p=
rettify"> </span><span style=3D"color: #066;" class=3D"styled-by-prettify">=
3</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> values <=
/span><span style=3D"color: #008;" class=3D"styled-by-prettify">from</span>=
<span style=3D"color: #000;" class=3D"styled-by-prettify"> the </span><span=
style=3D"color: #008;" class=3D"styled-by-prettify">function</span><span s=
tyle=3D"color: #660;" class=3D"styled-by-prettify">.</span><span style=3D"c=
olor: #000;" class=3D"styled-by-prettify"><br><br></span><span style=3D"col=
or: #008;" class=3D"styled-by-prettify">local</span><span style=3D"color: #=
000;" class=3D"styled-by-prettify"> w </span><span style=3D"color: #660;" c=
lass=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-b=
y-prettify">{</span><span style=3D"color: #000;" class=3D"styled-by-prettif=
y">foo</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: #660;" class=3D"styled-by-prettify">--</span><span style=
=3D"color: #606;" class=3D"styled-by-prettify">Stores</span><span style=3D"=
color: #000;" class=3D"styled-by-prettify"> the sequence of values returned=
</span><span style=3D"color: #008;" class=3D"styled-by-prettify">from</spa=
n><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span s=
tyle=3D"color: #080;" class=3D"styled-by-prettify">`foo`</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color=
: #008;" class=3D"styled-by-prettify">in</span><span style=3D"color: #000;"=
class=3D"styled-by-prettify"> a table </span><span style=3D"color: #660;" =
class=3D"styled-by-prettify">(</span><span style=3D"color: #000;" class=3D"=
styled-by-prettify">aka</span><span style=3D"color: #660;" class=3D"styled-=
by-prettify">:</span><span style=3D"color: #000;" class=3D"styled-by-pretti=
fy"> array</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: #008;" class=3D"styled-by-prettify">local</span=
><span style=3D"color: #000;" class=3D"styled-by-prettify"> a </span><span =
style=3D"color: #660;" class=3D"styled-by-prettify">=3D</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"> bar</span><span style=3D"co=
lor: #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: #606;" class=3D"styl=
ed-by-prettify">Stores</span><span style=3D"color: #000;" class=3D"styled-b=
y-prettify"> the table<br><br></span><span style=3D"color: #008;" class=3D"=
styled-by-prettify">local</span><span style=3D"color: #000;" class=3D"style=
d-by-prettify"> comp </span><span style=3D"color: #660;" class=3D"styled-by=
-prettify">=3D</span><span style=3D"color: #000;" class=3D"styled-by-pretti=
fy"> bar</span><span style=3D"color: #660;" class=3D"styled-by-prettify">(<=
/span><span style=3D"color: #000;" class=3D"styled-by-prettify">foo</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: #60=
6;" class=3D"styled-by-prettify">The</span><span style=3D"color: #000;" cla=
ss=3D"styled-by-prettify"> sequence </span><span style=3D"color: #008;" cla=
ss=3D"styled-by-prettify">is</span><span style=3D"color: #000;" class=3D"st=
yled-by-prettify"> passed to </span><span style=3D"color: #080;" class=3D"s=
tyled-by-prettify">`bar`</span><span style=3D"color: #000;" class=3D"styled=
-by-prettify"> </span><span style=3D"color: #008;" class=3D"styled-by-prett=
ify">as</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </=
span><span style=3D"color: #066;" class=3D"styled-by-prettify">3</span><spa=
n style=3D"color: #000;" class=3D"styled-by-prettify"> parameters</span><sp=
an 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: #008;" class=3D"styled-by-prettify">local</span><span style=3D"c=
olor: #000;" class=3D"styled-by-prettify"> comp2 </span><span style=3D"colo=
r: #660;" class=3D"styled-by-prettify">=3D</span><span style=3D"color: #000=
;" class=3D"styled-by-prettify"> bar</span><span style=3D"color: #660;" cla=
ss=3D"styled-by-prettify">(</span><span style=3D"color: #000;" class=3D"sty=
led-by-prettify">bar</span><span style=3D"color: #660;" class=3D"styled-by-=
prettify">())</span><span style=3D"color: #000;" class=3D"styled-by-prettif=
y"> </span><span style=3D"color: #660;" class=3D"styled-by-prettify">--</sp=
an><span style=3D"color: #000;" class=3D"styled-by-prettify">A single param=
eter </span><span style=3D"color: #008;" class=3D"styled-by-prettify">is</s=
pan><span style=3D"color: #000;" class=3D"styled-by-prettify"> passed to th=
e outer </span><span style=3D"color: #080;" class=3D"styled-by-prettify">`b=
ar`</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: #008;" class=3D"styled-by-prettify">local</span><span =
style=3D"color: #000;" class=3D"styled-by-prettify"> comp3 </span><span sty=
le=3D"color: #660;" class=3D"styled-by-prettify">=3D</span><span style=3D"c=
olor: #000;" class=3D"styled-by-prettify"> bar</span><span style=3D"color: =
#660;" class=3D"styled-by-prettify">(</span><span style=3D"color: #000;" cl=
ass=3D"styled-by-prettify">unpack</span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">(</span><span style=3D"color: #000;" class=3D"style=
d-by-prettify">bar</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">--</spa=
n><span style=3D"color: #606;" class=3D"styled-by-prettify">Unpacks</span><=
span style=3D"color: #000;" class=3D"styled-by-prettify"> the array </span>=
<span style=3D"color: #008;" class=3D"styled-by-prettify">into</span><span =
style=3D"color: #000;" class=3D"styled-by-prettify"> the outer </span><span=
style=3D"color: #080;" class=3D"styled-by-prettify">`bar`'s parameters<br>=
</span></div></code></div><br>I find that much more reasonable and consiste=
nt than the Python syntax. There is a distinction between a sequence of val=
ues and a data structure. `foo` and `bar` may be "conceptually" the same, b=
ut functionally they're different. One returns a sequence of values, the ot=
her returns a table. If you need to convert a table into a sequence of valu=
es, you call `unpack`. If you need to convert a sequence of values into a t=
able, you create a table with it.<br><br>Sequences of values in Lua are eph=
emeral; if you want to store the sequence and preserve it as a sequence, yo=
u stick it in a table. But if you just want to compose functions, store val=
ues, and the like, you use the sequence as is.<br><br>If C++ is going to pa=
ttern its functionality off of something, I'd much rather Lua's proper MRV =
syntax than Python's MRVs-as-arrays (I assume the () syntax is creating an =
array of some kind).<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></div><div> </div><br><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><br></div><blockquote class=3D"gm=
ail_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;p=
adding-left:1ex"><div dir=3D"ltr"><div>As was stated earlier, doing it this=
way would be a huge change that likely would never make it past the commit=
tee.</div></div></blockquote><div><br>But it's the right way to do it. And =
quite frankly, we don't need multiple return values so badly that we should=
do it the wrong way just to have <i>some</i> convenient way to do it.<br><=
br>Some people use tuples a lot (some might say to the point of overuse). B=
ut you shouldn't steal potentially useful syntax from those C++ programmers=
who don't use them. </div></div></blockquote><div><br></div><div>Programme=
rs who have no interest in tuple itself can just use the syntax to return m=
ultiple values and unpack them at the call site. They don't have to care th=
at tuple (or something tuple like) is used to accomplish this.</div></div><=
/blockquote><div><br>Except that they have to pay the cost for it. Consider=
something simple like this:<br><br><div class=3D"prettyprint" style=3D"bac=
kground-color: rgb(250, 250, 250); border-color: rgb(187, 187, 187); border=
-style: solid; border-width: 1px; word-wrap: break-word;"><code class=3D"pr=
ettyprint"><div class=3D"subprettyprint"><span style=3D"color: #008;" class=
=3D"styled-by-prettify">auto</span><span style=3D"color: #000;" class=3D"st=
yled-by-prettify"> single_value</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-pre=
ttify">{</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><b=
r> 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: #000;" class=3D"styled-by-prettify"> a </span>=
<span style=3D"color: #660;" class=3D"styled-by-prettify">=3D</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: =
#000;" class=3D"styled-by-prettify"><br> </span><span style=3D"color:=
#008;" class=3D"styled-by-prettify">return</span><span style=3D"color: #00=
0;" class=3D"styled-by-prettify"> a</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></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: #008;" class=3D"styled-by-prettify">a=
uto</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> multi_=
value</span><span style=3D"color: #660;" class=3D"styled-by-prettify">()</s=
pan><span style=3D"color: #000;" class=3D"styled-by-prettify"><br></span><s=
pan style=3D"color: #660;" class=3D"styled-by-prettify">{</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"><br> std</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"colo=
r: #000;" class=3D"styled-by-prettify"> a </span><span style=3D"color: #660=
;" class=3D"styled-by-prettify">=3D</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-=
prettify"><br> std</span><span style=3D"color: #660;" class=3D"styled=
-by-prettify">::</span><span style=3D"color: #000;" class=3D"styled-by-pret=
tify">vector b </span><span style=3D"color: #660;" class=3D"styled-by-prett=
ify">=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> </span=
><span style=3D"color: #008;" class=3D"styled-by-prettify">return</span><sp=
an 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">a</span><span style=3D"color: #660;" =
class=3D"styled-by-prettify">;</span><span style=3D"color: #000;" class=3D"=
styled-by-prettify"> b</span><span style=3D"color: #660;" class=3D"styled-b=
y-prettify">];</span><span style=3D"color: #000;" class=3D"styled-by-pretti=
fy"><br></span><span style=3D"color: #660;" class=3D"styled-by-prettify">}<=
/span></div></code></div><br>`single_value` is subject to copy elision, so =
you should feel no problem with using it. Even with a small-string-optimize=
d std::string class, you will get the maximum possible performance if you'r=
e using the result to initialize an object.<br><br>With language-level mult=
iple return values, `multi_value` would be able to operate under the same p=
rinciple. `a` and `b` would be considered return values, and they would eac=
h be separately subject to elision.<br><br>With your way, that's just not p=
ossible. If that syntax creates a `tuple`, then it must copy or move initia=
lize the elements of that `tuple`. So even though the `tuple` itself is sub=
ject to elision, the creation of it is not.<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> </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>Syntax is a precious commo=
dity, which once apportioned, cannot be taken back.<br><br>It should also b=
e noted that reflection, with the full ability to=20
compile-time inspect and generate types with full syntax=20
(including variable names) makes tuples... a dubious proposition for the
future of C++. With reflection, you can index a struct by number. With ref=
lection, you can take any typelist and build an honest-to-God=20
struct out of it (which can be standard layout and such).<br><br>In short, =
it is entirely possible that tuples will become obsolete, thus also obsolet=
ing this kind of syntax. So let's not have another std::bind happen here...=
<br></div></div></blockquote><div><br></div><div><div style=3D"border:1px s=
olid rgb(187,187,187);word-wrap:break-word;background-color:rgb(250,250,250=
)"><code><div><span style=3D"color:#660">[</span><span style=3D"color:#008"=
>int</span><span style=3D"color:#660">,</span><span style=3D"color:#008">lo=
ng</span><span style=3D"color:#660">,</span><span style=3D"color:#008">doub=
le</span><span style=3D"color:#660">]</span><span style=3D"color:#000"> foo=
</span><span style=3D"color:#660">();</span><span style=3D"color:#000"><br>=
</span><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"> foo=
</span><span style=3D"color:#660">();</span><font color=3D"#666600"></font>=
</div></code></div><br></div><div>Ok, if tuple is out then what is decltype=
(x) in the above example doing things your way?</div></div></blockquote><di=
v><br>There are two defensible answers to this:<br><br>1) A compilation err=
or. You called a function that returns 3 things, but you only captured one.=
That suggests you weren't paying attention.<br><br>2) `int`. The other two=
types are dropped on the floor.<br><br>#2 is probably the way to go. Any s=
ort of aggregate object type is not even up for discussion.<br><br>Multiple=
return values means <i>multiple return values</i>, not "pack multiple valu=
es into some kind of object and unpack them later".<br> </div><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> Another kind of=
typelist which is standard layout compatible? Or are we no longer able to =
capture all of the return values into one object?</div></div></blockquote><=
div><br>If you want to capture them all in an object, you just ask for it:<=
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 class=3D"prettyprint"><div class=3D"subp=
rettyprint"><span style=3D"color: #008;" class=3D"styled-by-prettify">auto<=
/span><span style=3D"color: #000;" class=3D"styled-by-prettify"> x </span><=
span style=3D"color: #660;" class=3D"styled-by-prettify">=3D</span><span st=
yle=3D"color: #000;" class=3D"styled-by-prettify"> make_tuple</span><span s=
tyle=3D"color: #660;" class=3D"styled-by-prettify">(</span><span style=3D"c=
olor: #000;" class=3D"styled-by-prettify">foo</span><span style=3D"color: #=
660;" class=3D"styled-by-prettify">());</span></div></code></div><br>That i=
s neither hard nor particularly verbose. You can even stick them in an arra=
y, if all of the returned values are of the same type:<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: brea=
k-word;"><code class=3D"prettyprint"><div class=3D"subprettyprint"><span st=
yle=3D"color: #008;" class=3D"styled-by-prettify">auto</span><span style=3D=
"color: #000;" class=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"> make_array</span><span style=3D"color: #660;=
" class=3D"styled-by-prettify">(</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify">foo</span><span style=3D"color: #660;" class=3D"sty=
led-by-prettify">());</span></div></code></div><br>Or in an arbitrary data =
structure:<br><br><div class=3D"prettyprint" style=3D"background-color: rgb=
(250, 250, 250); border-color: rgb(187, 187, 187); border-style: solid; bor=
der-width: 1px; word-wrap: break-word;"><code class=3D"prettyprint"><div cl=
ass=3D"subprettyprint"><span style=3D"color: #008;" class=3D"styled-by-pret=
tify">auto</span><span style=3D"color: #000;" class=3D"styled-by-prettify">=
x </span><span style=3D"color: #660;" class=3D"styled-by-prettify">=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: #000;" class=3D"styled-by-prettify">vector</span><span style=3D"=
color: #660;" class=3D"styled-by-prettify"><</span><span style=3D"color:=
#606;" class=3D"styled-by-prettify">Type</span><span style=3D"color: #660;=
" class=3D"styled-by-prettify">>{</span><span style=3D"color: #000;" cla=
ss=3D"styled-by-prettify">foo</span><span style=3D"color: #660;" class=3D"s=
tyled-by-prettify">()};</span><span style=3D"color: #000;" class=3D"styled-=
by-prettify"><br></span></div></code></div><br>But most people using multip=
le return values don't capture them in a big object, so we don't make the s=
yntax optimal for that case.<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></div><div>If not using tuple, can you ex=
plain in a bit more detail how your proposed solution would actually work?<=
/div></div></blockquote><div><br>The details of how it works are more or le=
ss the way Lua works.<br><br>In C++ parlance, the notion of a "sequence of =
values" would be a construct. It would <i>not</i> necessarily be an "expres=
sion", in the same way that a braced-init-list is not an expression. Since =
it's a new construct, you can give it whatever properties you want.<br><br>=
Functions can return sequences of values, with the sequence as a full part =
of its return type. Using the sequence initialization syntax, you can initi=
alize/assign multiple variables to a sequence of values. If a sequence of v=
alues is given to a function argument list, the values are placed in that l=
ist as arguments. If the sequence of values is used in any other kind of ex=
pression, then it resolves down to the first element of that sequence of va=
lues.<br><br>Initialization/assignment of variables through a sequence woul=
d work element by element, in order from left to right.<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"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />
------=_Part_5553_432423355.1432712590537--
------=_Part_5552_178908165.1432712590537--
.
Author: Morwenn <morwenn29@gmail.com>
Date: Wed, 27 May 2015 08:18:40 -0700 (PDT)
Raw View
------=_Part_311_1010970216.1432739920022
Content-Type: multipart/alternative;
boundary="----=_Part_312_485805248.1432739920022"
------=_Part_312_485805248.1432739920022
Content-Type: text/plain; charset=UTF-8
Just a thought, but wouldn't it be possible to add a "shortcut" syntax
along with the proposed one:
int [a, b, c] = foo();
Or:
auto&& [x, y, z] = bar();
Which would be equivalent to:
[auto&& x; auto&& y; auto&& z] = bar();
It would allow to to have a shorthand syntax while preserving the proposed
flexibility.
--
---
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 http://groups.google.com/a/isocpp.org/group/std-proposals/.
------=_Part_312_485805248.1432739920022
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">Just a thought, but wouldn't it be possible to add a "shor=
tcut" syntax along with the proposed one:<br><br><span style=3D"font-family=
: courier new,monospace;">int [a, b, c] =3D foo();</span><br><br>Or:<br><br=
><span style=3D"font-family: courier new,monospace;">auto&& [x, y, =
z] =3D bar();</span><br><br>Which would be equivalent to:<br><br><span styl=
e=3D"font-family: courier new,monospace;">[auto&& x; auto&&=
y; auto&& z] =3D bar();</span><br><br>It would allow to to have a =
shorthand syntax while preserving the proposed flexibility.<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"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />
------=_Part_312_485805248.1432739920022--
------=_Part_311_1010970216.1432739920022--
.
Author: Matthew Woehlke <mw_triad@users.sourceforge.net>
Date: Wed, 27 May 2015 11:21:47 -0400
Raw View
On 2015-05-27 03:43, Nicol Bolas wrote:
> On Tuesday, May 26, 2015 at 10:53:05 PM UTC-4, Matthew Fioravante wrote:
>> On Tuesday, May 26, 2015 at 9:23:50 PM UTC-4, Nicol Bolas wrote:
>>> Nor does it force you to package parameters into a tuple.
>>
>> But it does, at least at the syntax level
>>
>> def foo():
>> return (1, 2, 3);
>>
>> (x, y, z) = foo();
Actually it doesn't:
>>> def foo():
>>> return 1, 2
>>> a, b = foo()
....but the return is a 'tuple' nevertheless:
>>> type(foo())
<type 'tuple'>
(Basically, the ()'s are optional, and implied if absent.)
> Sorry, my knowledge of Python is limited; I just assumed it worked more or
> less like Lua.
My knowledge of Lua is limited ("effectively nonexistent" is probably
more accurate). Python, however, only supports single return values. It
just has syntax sugar for returning tuples and unpacking tuples.
The latter, btw, works on any iterable:
>>> a, b = (1, 2)
>>> c, d = "cd"
This has significant advantages:
- Unpacking can be used on lots of things, not just some "multiple
return values" concept that doesn't actually exist in Python. For
example, std::pair returned by existing std::map::iterator. This means
that existing code would benefit from the addition of an unpacking
feature as proposed by Matthew F. Your proposal only helps new code and
requires ugly syntax to work in a range-based for over existing
dictionaries.
- The programmer has the option to unpack immediately, or to capture the
entire return value as a container to unpack later, or to use directly
as a container type. Moreover, container operations are possible (e.g.
concatenating two sets of return values).
- It makes slicing operations on the return value set possible. For
example, consuming one value and passing the others as a set along to
some other function. (With '...' unpacking, it allows metaprogramming
tricks like invoking some function for each return value.)
- It simplifies templates (Miro's point); templates code does not
necessarily need to be specialized depending on whether a function used
in a template returns a single or multiple values.
- It doesn't require massive changes to the standard or creation of a
new ABI.
The second in particular, plus unpacking into parameter lists, makes
something like this possible:
[int, int] foo();
[double, int] bar();
void something_different(int, int, double, int)'
auto&& x = foo();
auto&& y = bar();
something_different([*](concat(x, y));
(Digression: Python actually does strictly enforces that unpacking
matches the element count of the tuple being unpacked; no 'tail tuple'.
Possibly we should think about only providing that mode to start with;
we can always add tail unpacking via '...' later.)
> In Lua, you don't need special syntax for returning or capturing multiple
> values. And quite frankly, I see no reason why you should:
>
> function foo()
> return 1, 2, 3 --Returns a sequence of 3 values.
> end
Like Python, I don't even see a return type specified there, so I'm not
sure what you mean by "don't need special syntax".
In Python, "return x, y" is syntactic sugar for "return (x, y)". I
suppose we could allow similar sugar in C++, possibly with the
requirement that the function was declared with the tuple sugar (as in
the declarations in the above example) in order to avoid changing the
meaning of existing code w.r.t. 'operator,'.
> I find that much more reasonable and consistent than the Python syntax.
> There is a distinction between a sequence of values and a data structure.
I'm not convinced this is really *that* different from the Pythonic
distinction between 'tuple' and 'list'. Moreover, C++ has no concept of
"a sequence of values" existing outside of some containing type such as
std::tuple. I remain unconvinced that the significant effort to add such
a concept is worthwhile.
> auto multi_value()
> {
> std::string a = ...;
> std::vector b = ...;
> return [a; b];
> }
Is there a reason we can't introduce a new type, probably along the
lines of initializer_list, that would allow in-place construction but
would otherwise behave like std::tuple?
I don't think either Matthew F. or myself are wedded to the return type
*actually being* std::tuple, just that it should behave like std::tuple
(i.e. a single 'object' subject to sequence operations, get<N>, etc.).
For that matter, I at least am content not saying *anything* about
multiple return values. I still consider it an orthogonal issue. We just
need to coordinate so that immediate unpacking is allowed to leverage
RVO. (And I still think unpacking - as in Python - should be permitted
on anything that provides get<N>, be that "value sequences", std::tuple,
std::pair, std::array, QSize, my_funky_class, etc.) Multiple return
values might be the most common use case, but it not the *only* use
case. And there is enormous value on unpacking being useful with
existing API's.
>> [int,long,double] foo();
>> auto x = foo();
>>
>> Ok, if tuple is out then what is decltype(x) in the above example doing
>> things your way?
>
> There are two defensible answers to this:
>
> 1) A compilation error. You called a function that returns 3 things, but
> you only captured one. That suggests you weren't paying attention.
>
> 2) `int`. The other two types are dropped on the floor.
>
> #2 is probably the way to go. Any sort of aggregate object type is not even
> up for discussion.
I disagree on both counts. There are advantages to having an aggregate
object, as explained above. And silently dropping return values should
definitely not be allowed.
Maybe you and Matthew F. can write a paper together that presents both
proposals along with a comparison of the advantages and disadvantages of
both?
>> If not using tuple, can you explain in a bit more detail how your proposed
>> solution would actually work?
Nicol, I'd still like to see your equivalent of:
for([auto&& k; auto&& v] : some_map)
--
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 http://groups.google.com/a/isocpp.org/group/std-proposals/.
.
Author: Matthew Woehlke <mw_triad@users.sourceforge.net>
Date: Wed, 27 May 2015 11:25:24 -0400
Raw View
On 2015-05-27 11:11, Nicol Bolas wrote:
> On Wednesday, May 27, 2015 at 4:51:58 AM UTC-4, Miro Knejp wrote:
>> Then there=E2=80=99s the point of what generic code would require to do =
to=20
>> consistently capture the return value(s) of a Callable without knowing i=
f=20
>> there are one or multiple return values.
>>
>> template<class F>
>> void contrived_example2(F f) {
>> ??? x =3D f();
>> ...
>> }
>=20
> That one's easy. Since you're in generic code and could be getting multip=
le=20
> values, the only way to manipulate them is with a tuple. So that's what y=
ou=20
> stick them in:
>=20
> auto x =3D make_tuple(f());
Okay, so composition in the face of generic code, where I also need to
store the return value(s) at some point for whatever reason, *requires*
the ability to unpack a std::tuple into an argument list.
That's true either way... but just sayin'...
--=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 http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.
.
Author: Matthew Woehlke <mw_triad@users.sourceforge.net>
Date: Wed, 27 May 2015 11:45:43 -0400
Raw View
On 2015-05-27 11:33, Thiago Macieira wrote:
> On Wednesday 27 May 2015 11:21:47 Matthew Woehlke wrote:
>> In Python, "return x, y" is syntactic sugar for "return (x, y)". I
>> suppose we could allow similar sugar in C++, possibly with the
>> requirement that the function was declared with the tuple sugar (as in
>> the declarations in the above example) in order to avoid changing the
>> meaning of existing code w.r.t. 'operator,'.
>=20
> Please don't, because operator, can be overloaded. Using it is one of the=
=20
> tricks to handling void returns.
Yes, thank you, that's sort of my point :-).
IMO (and IYIO=C2=B9 apparently) it's dangerous to allow MRV with no more
syntax than 'return a, b'. *At minimum* I would restrict this to
functions that have explicitly declared MRV's (which is what I was
suggesting).
Personally, I'm not convinced (as Nicol is asserting) that we need it at
all. *I* don't have a problem requiring an MRV return to be wrapped in
either {}'s or []'s, and in fact I'd rather prefer that.
(=C2=B9 In Your Informed Opinion, as in, I'm just talking, but you (Thiago)
know what you're talking about :-).)
--=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 http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.
.
Author: Matthew Woehlke <mw_triad@users.sourceforge.net>
Date: Wed, 27 May 2015 12:10:32 -0400
Raw View
On 2015-05-26 20:14, Nicol Bolas wrote:
> On Tuesday, May 26, 2015 at 5:31:10 PM UTC-4, Matthew Woehlke wrote:
>> If we had multiple return values as a first class language feature, why
>> should I not expect to be able to write the opposite of std::tie? :-)
>
> ... std::tie takes a tuple and exports the members of that tuple into
> variables.
Er... okay, I don't use std::tie. Ugh. That looks like a wart that
should die :-); proper unpacking syntax would make it superfluous:
auto t = foo(); // decltype(t) == tuple<int, int, int>
// Old
int x, y, z;
std::tie(x, y, z) = t;
// New (v1)
int x, y, z;
[x; y; z] = t; // Much more concise
// New (v2)
[auto x; auto y; auto z] = t; // Concise, and can declare with 'auto'
What I meant was that MRV by value sequence (your proposal) should make
it possible for me to write 'unpack', as in this example:
int foo(int, int, int);
std::tuple<int, int, int> params = { ... };
foo(unpack(params));
And...
>> On 2015-05-26 16:31, Nicol Bolas wrote:
>>> So while they're not technically orthogonal, it's highly unlikely that we'd
>>> ever get both.
....if we also have a way to unpack MRV's (which I assume we do, since
you object so strongly to anything container-like for MRV's), doesn't
that mean we *do* have the ability to unpack a std::tuple with your
proposal? (Without resorting to the ugly std::tie?)
That's what I was trying to say.
I still don't see why these shouldn't be orthogonal, especially if we
make some new quasi-container a la initializer_list for MRV's. Unpacking
can be something we introduce *now*, which immediately fixes at least
the map iteration problem, and allows MRV's via std::tuple with no other
major changes. Separately/later we can add "proper" MRV support in a way
that's compatible with the existing unpacking mechanism (and can be
stored / has implicit conversion to something container-like for the
reasons mentioned elsewhere). This makes both changes much more modest,
has no major drawbacks that I can see, and lets us tackle the problem in
more bite-sized chunks.
--
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 http://groups.google.com/a/isocpp.org/group/std-proposals/.
.
Author: Matthew Woehlke <mw_triad@users.sourceforge.net>
Date: Wed, 27 May 2015 12:28:38 -0400
Raw View
On 2015-05-27 11:59, Nicol Bolas wrote:
> On Wednesday, May 27, 2015 at 11:11:34 AM UTC-4, Matthew Fioravante wrote:
>> So whats stopping someone from writing a proposal to allow copy/move
>> elision in your multi_value() example?
>
> The fact that C++ can't do that. Remember: your [values...] syntax equates
> to the construction of a `std::tuple` from the given values. [...]
>
> If the standard were changed, it couldn't be changed in anything remotely
> like a generic way. It would have to be based on a basic assumption that
> `[values..,]` syntax doesn't generate a `std::tuple`, but some other
> compiler-generated object type. And this type would be treated specially by
> the language, being allowed to skip constructors.
Great! Let's go with that. And lets make this "CGO" behave like
std::tuple, at least as far as being deterministic (i.e. as far as the
decltype() for a distinct type sequence) and implementing get<N>. Then
it will work with the unpacking proposal, which can be orthogonal.
>> auto... x = bar();
>> foo(x...);
>> foo(x...);
>
> Now that... that sounds like an idea. I've always wanted a way to build a
> template parameter pack.
This can be a third orthogonal proposal, e.g. '[*]' or '...' to accept
an MRV "object" as some sort of special "value sequence". Or if an MRV
"object" is implicitly unpacked as parameters, '[*]' can be written as a
template function.
I'd prefer option 1, '[*]' to convert a "container" to a parameter list.
(More versatile, if nothing else...)
>> Its not uncommon. Every class that has multiple "values" (e.g
>> unordered_map) will be returning them in a pack using its default
>> iterators so that one can write a simple range for loop.
>
> And how often do people iterate through maps? The main purpose of a map is
> to efficiently look up items by a key.
....or to store data that logically follows a "key"/"value" structure for
which there already exists a "key" and "value" type, but not a type that
combines the two. (And/or where sometimes look-up is needed, and
sometimes doing something with all items is needed.)
I run into this often enough that I have helper macros associated with
it, and a helper class to perform key/value iteration over Qt
associative containers (whose iterator's operator* only gives you the
value, such that the key is not accessible to foreach() / range-based
for). I've even proposed the latter for addition to Qt (though I haven't
yet gone back and done anything about submitting it).
> So I'd say it's still relatively uncommon. It's certainly not common enough
> to make a special syntax for tuples.
By itself, maybe not, but it's one use case of many for the same
feature. I think it's common enough that a solution to MRV unpacking
that doesn't also cover these other use cases when they are so clearly
related, is questionable.
--
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 http://groups.google.com/a/isocpp.org/group/std-proposals/.
.
Author: Matthew Woehlke <mw_triad@users.sourceforge.net>
Date: Wed, 27 May 2015 12:44:11 -0400
Raw View
On 2015-05-27 12:06, Thiago Macieira wrote:
> On Wednesday 27 May 2015 11:45:43 Matthew Woehlke wrote:
>> IMO (and IYIO=C2=B9 apparently) it's dangerous to allow MRV with no more
>> syntax than 'return a, b'. *At minimum* I would restrict this to
>> functions that have explicitly declared MRV's (which is what I was
>> suggesting).
>=20
> My point is that
>=20
> return a, b;
>=20
> Already has a meaning.
*Exactly*. You must be misinterpreting something I said, because we are
violently agreeing with each other :-). (Maybe because I said "suppose
we could", which doesn't do a great job conveying "eew... um... do we
really *have* to?".)
This is what happened:
Nicol: I don't want to have to type extra symbols for MRV.
Me: Um... well... I *guess* I could see that, but it seems dangerous.
You: Absolutely it is dangerous!
Me: Yes!
....and then I thanked you for putting my uneasy mutterings into a clear
example of why said mutterings are fully justified.
TL;DR: We both agree that changing the meaning of 'return a, b' is bad
and both of us would rather not do that.
> Imagine (contrived example):
>=20
> template <typename T> auto void do(T &&t)
> {
> return SomeAction(), t();
> }
>=20
> [int, float] void f();
>=20
> Does do<f> return [int, float]? Or does it return [SomeAction, [int, floa=
t]]?
The former; 'do' wasn't explicitly declared to have MRV. (This is even
if we allow MRV without new syntax, which as stated, I'm not comfortable
with, for the same reasons you're objecting to it.)
--=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 http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.
.
Author: Edward Catmur <ed@catmur.co.uk>
Date: Wed, 27 May 2015 10:25:48 -0700 (PDT)
Raw View
------=_Part_3655_793797568.1432747548476
Content-Type: multipart/alternative;
boundary="----=_Part_3656_1187310212.1432747548476"
------=_Part_3656_1187310212.1432747548476
Content-Type: text/plain; charset=UTF-8
On Wednesday, 27 May 2015 16:31:12 UTC+1, Matthew Woehlke wrote:
>
> On 2015-05-27 11:11, Nicol Bolas wrote:
> > That one's easy. Since you're in generic code and could be getting
> multiple
> > values, the only way to manipulate them is with a tuple. So that's what
> you
> > stick them in:
> >
> > auto x = make_tuple(f());
>
> Okay, so composition in the face of generic code, where I also need to
> store the return value(s) at some point for whatever reason, *requires*
> the ability to unpack a std::tuple into an argument list.
>
That's a library addition; we can even do it with Python syntax, since
std::tuple doesn't provide unary operator* yet:
template<class... T> [T...] tuple<T...>::operator*() { return [get<0...
sizeof...(T...)>(*this)...]; }
allowing:
auto x = make_tuple(f());
g(*x);
--
---
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 http://groups.google.com/a/isocpp.org/group/std-proposals/.
------=_Part_3656_1187310212.1432747548476
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">On Wednesday, 27 May 2015 16:31:12 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 2015-05-27 11:11, Ni=
col Bolas wrote:
<br>> That one's easy. Since you're in generic code and could be getting=
multiple=20
<br>> values, the only way to manipulate them is with a tuple. So that's=
what you=20
<br>> stick them in:
<br>>=20
<br>> auto x =3D make_tuple(f());
<br>
<br>Okay, so composition in the face of generic code, where I also need to
<br>store the return value(s) at some point for whatever reason, *requires*
<br>the ability to unpack a std::tuple into an argument list.
<br></blockquote><div><br></div><div>That's a library addition; we can even=
do it with Python syntax, since std::tuple doesn't provide unary <font fac=
e=3D"courier new, monospace">operator*</font> yet:</div><div><br></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"pre=
ttyprint"><div class=3D"subprettyprint"><span style=3D"color: #008;" class=
=3D"styled-by-prettify">template</span><span style=3D"color: #660;" class=
=3D"styled-by-prettify"><</span><span style=3D"color: #008;" class=3D"st=
yled-by-prettify">class</span><span style=3D"color: #660;" class=3D"styled-=
by-prettify">...</span><span style=3D"color: #000;" class=3D"styled-by-pret=
tify"> T</span><span style=3D"color: #660;" class=3D"styled-by-prettify">&g=
t;</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span>=
<span style=3D"color: #660;" class=3D"styled-by-prettify">[</span><span sty=
le=3D"color: #000;" class=3D"styled-by-prettify">T</span><span style=3D"col=
or: #660;" class=3D"styled-by-prettify">...]</span><span style=3D"color: #0=
00;" class=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">T</span><span style=3D"color: #660;" class=3D"style=
d-by-prettify">...>::</span><span style=3D"color: #008;" class=3D"styled=
-by-prettify">operator</span><span style=3D"color: #660;" class=3D"styled-b=
y-prettify">*()</span><span style=3D"color: #000;" class=3D"styled-by-prett=
ify"> </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">return</span><span sty=
le=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"col=
or: #660;" class=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"st=
yled-by-prettify">0.</span><span style=3D"color: #660;" class=3D"styled-by-=
prettify">..</span><span style=3D"color: #008;" class=3D"styled-by-prettify=
">sizeof</span><span style=3D"color: #660;" class=3D"styled-by-prettify">..=
..(</span><span style=3D"color: #000;" class=3D"styled-by-prettify">T</span>=
<span style=3D"color: #660;" class=3D"styled-by-prettify">...)>(*</span>=
<span style=3D"color: #008;" class=3D"styled-by-prettify">this</span><span =
style=3D"color: #660;" class=3D"styled-by-prettify">)...];</span><span styl=
e=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"colo=
r: #660;" class=3D"styled-by-prettify">}</span><span style=3D"color: #000;"=
class=3D"styled-by-prettify"><br></span></div></code></div><div><br>allowi=
ng:</div><div><br></div><div class=3D"prettyprint" style=3D"border: 1px sol=
id rgb(187, 187, 187); word-wrap: break-word; background-color: rgb(250, 25=
0, 250);"><code class=3D"prettyprint"><div class=3D"subprettyprint"><span s=
tyle=3D"color: #008;" class=3D"styled-by-prettify">auto</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"> x </span><span style=3D"col=
or: #660;" class=3D"styled-by-prettify">=3D</span><span style=3D"color: #00=
0;" class=3D"styled-by-prettify"> make_tuple</span><span style=3D"color: #6=
60;" class=3D"styled-by-prettify">(</span><span style=3D"color: #000;" clas=
s=3D"styled-by-prettify">f</span><span style=3D"color: #660;" class=3D"styl=
ed-by-prettify">());</span><span style=3D"color: #000;" class=3D"styled-by-=
prettify"> <br>g</span><span style=3D"color: #660;" class=3D"styled-by-pret=
tify">(*</span><span style=3D"color: #000;" class=3D"styled-by-prettify">x<=
/span><span style=3D"color: #660;" class=3D"styled-by-prettify">);</span><s=
pan style=3D"color: #000;" class=3D"styled-by-prettify"><br></span></div></=
code></div><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"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />
------=_Part_3656_1187310212.1432747548476--
------=_Part_3655_793797568.1432747548476--
.
Author: Matthew Woehlke <mw_triad@users.sourceforge.net>
Date: Wed, 27 May 2015 14:01:18 -0400
Raw View
On 2015-05-27 13:44, Thiago Macieira wrote:
> On Wednesday 27 May 2015 12:44:11 Matthew Woehlke wrote:
>> On 2015-05-27 12:06, Thiago Macieira wrote:
>>> template <typename T> auto void do(T &&t)
>>> {
>>> return SomeAction(), t();
>>> }
>>>
>>> [int, float] void f();
>>>
>>> Does do<f> return [int, float]? Or does it return [SomeAction, [int,
>>> float]]?
>>
>> The former; 'do' wasn't explicitly declared to have MRV. (This is even
>> if we allow MRV without new syntax, which as stated, I'm not comfortable
>> with, for the same reasons you're objecting to it.)
>
> Ok, so
>
> template <typename T> decltype(t()) do(T &&);
>
> Is that an explicit MRV?
I *want* to say "yes"... and... eep, yeah, I think you're right, that
would at best result in a compile error for code that used to work :-).
So, there is no way to allow MRV without some syntax to denote the MRV
list. I wasn't fond of it anyway, but that's the proverbial last nail in
the coffin.
Great analysis. Thanks again!
(That said, if we had MRV, I think your example should compile as-is...
i.e. no additional syntax required to 'pass through' an MRV object as an
MRV. But that's an aside.)
--
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 http://groups.google.com/a/isocpp.org/group/std-proposals/.
.
Author: Matthew Woehlke <mw_triad@users.sourceforge.net>
Date: Wed, 27 May 2015 14:08:52 -0400
Raw View
On 2015-05-27 13:25, Edward Catmur wrote:
> On Wednesday, 27 May 2015 16:31:12 UTC+1, Matthew Woehlke wrote:
>> Okay, so composition in the face of generic code, where I also need to
>> store the return value(s) at some point for whatever reason, *requires*
>> the ability to unpack a std::tuple into an argument list.
>
> That's a library addition; we can even do it with Python syntax, since
> std::tuple doesn't provide unary operator* yet [...] allowing:
>
> auto x = make_tuple(f());
> g(*x);
....that assumes that a std::value_sequence<...> (or whatever) is
implicitly expanded when it appears in an argument list, which is *not*
a library addition. Also, that only works if it is not possible to treat
a value sequence as a single object, to which I (pardon the homograph)
object.
Plus, I'd rather have a unary "operator" '[*]' (or whatever) that
generically unpacks something that supports get<N> into a sequence of
values. This would work with e.g. QMap::iterator which *does* already
have an operator*.
--
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 http://groups.google.com/a/isocpp.org/group/std-proposals/.
.
Author: Cleiton Santoia <cleitonsantoia@gmail.com>
Date: Wed, 27 May 2015 13:16:10 -0700 (PDT)
Raw View
------=_Part_1066_1288319926.1432757770652
Content-Type: multipart/alternative;
boundary="----=_Part_1067_1045411383.1432757770659"
------=_Part_1067_1045411383.1432757770659
Content-Type: text/plain; charset=UTF-8
Let me give my 2 cents :
A "variadic initializer list" or some analogue concept may solve part of
this problem.
template<typename ...T> class initializer_list {}
or even a different class
template<typename ...T> class var_initializer_list {}
This also allow "implicit" construction of tuples and pairs via uniform
initialization.
So instead of
template<typename ...Types>
explicit tuple (const Types&... elems);
We might use
template<typename ...Types>
tuple (const initializer_list<Types...>& elems);
BR
Cleiton
Em quarta-feira, 27 de maio de 2015 14:25:48 UTC-3, Edward Catmur escreveu:
>
> On Wednesday, 27 May 2015 16:31:12 UTC+1, Matthew Woehlke wrote:
>>
>> On 2015-05-27 11:11, Nicol Bolas wrote:
>> > That one's easy. Since you're in generic code and could be getting
>> multiple
>> > values, the only way to manipulate them is with a tuple. So that's what
>> you
>> > stick them in:
>> >
>> > auto x = make_tuple(f());
>>
>> Okay, so composition in the face of generic code, where I also need to
>> store the return value(s) at some point for whatever reason, *requires*
>> the ability to unpack a std::tuple into an argument list.
>>
>
> That's a library addition; we can even do it with Python syntax, since
> std::tuple doesn't provide unary operator* yet:
>
> template<class... T> [T...] tuple<T...>::operator*() { return [get<0...
> sizeof...(T...)>(*this)...]; }
>
> allowing:
>
> auto x = make_tuple(f());
> g(*x);
>
>
--
---
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 http://groups.google.com/a/isocpp.org/group/std-proposals/.
------=_Part_1067_1045411383.1432757770659
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><div><br></div><div>Let me give my 2 cents : </div><d=
iv><br></div><div>A "variadic initializer list" or some analogue concept ma=
y solve part of this problem.<br></div><div><br></div><div><div class=3D"pr=
ettyprint" style=3D"border: 1px solid rgb(187, 187, 187); word-wrap: break-=
word; background-color: rgb(250, 250, 250);"><code class=3D"prettyprint"><d=
iv class=3D"subprettyprint"><span style=3D"color: #008;" class=3D"styled-by=
-prettify">template</span><span style=3D"color: #660;" class=3D"styled-by-p=
rettify"><</span><span style=3D"color: #008;" class=3D"styled-by-prettif=
y">typename</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">T</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=
: #008;" class=3D"styled-by-prettify">class</span><span style=3D"color: #00=
0;" class=3D"styled-by-prettify"> initializer_list</span><font color=3D"#66=
6600"><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><sp=
an style=3D"color: #660;" class=3D"styled-by-prettify">{}</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"><br></span></font></div></co=
de></div><br></div><div>or even a different class </div><div><br></div=
><div><div class=3D"prettyprint" style=3D"border: 1px solid rgb(187, 187, 1=
87); word-wrap: break-word; background-color: rgb(250, 250, 250);"><code cl=
ass=3D"prettyprint"><div class=3D"subprettyprint"><span style=3D"color: #00=
8;" class=3D"styled-by-prettify">template</span><span style=3D"color: #660;=
" class=3D"styled-by-prettify"><</span><span style=3D"color: #008;" clas=
s=3D"styled-by-prettify">typename</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-pr=
ettify">T</span><span style=3D"color: #660;" class=3D"styled-by-prettify">&=
gt;</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span=
><span style=3D"color: #008;" class=3D"styled-by-prettify">class</span><spa=
n style=3D"color: #000;" class=3D"styled-by-prettify"> var_initializer_list=
</span><font color=3D"#666600"><span style=3D"color: #000;" class=3D"styled=
-by-prettify"> </span><span style=3D"color: #660;" class=3D"styled-by-prett=
ify">{}</span></font><span style=3D"color: #000;" class=3D"styled-by-pretti=
fy"><br></span></div></code></div><br>This also allow "implicit" constructi=
on of tuples and pairs via uniform initialization.</div><div><br></div=
><div>So instead of </div><div><div class=3D"prettyprint" style=3D"bor=
der: 1px solid rgb(187, 187, 187); word-wrap: break-word; background-color:=
rgb(250, 250, 250);"><code class=3D"prettyprint"><div class=3D"subprettypr=
int"><pre style=3D"color: rgb(0, 128, 0); font-size: 12px; background-color=
: rgb(242, 255, 242);"><span style=3D"color: #008;" class=3D"styled-by-pret=
tify">template</span><span style=3D"color: #660;" class=3D"styled-by-pretti=
fy"><</span><span style=3D"color: #008;" class=3D"styled-by-prettify">ty=
pename</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </s=
pan><span style=3D"color: #660;" class=3D"styled-by-prettify">...</span><sp=
an style=3D"color: rgb(102, 0, 102); font-family: Arial, Helvetica, sans-se=
rif;"><span style=3D"color: #606;" class=3D"styled-by-prettify">Types</span=
></span><span style=3D"color: #660;" class=3D"styled-by-prettify">></spa=
n><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span></pre><=
pre style=3D"color: rgb(0, 128, 0); font-size: 12px; background-color: rgb(=
242, 255, 242);"><span style=3D"color: #008;" class=3D"styled-by-prettify">=
explicit</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> t=
uple </span><span style=3D"color: #660;" class=3D"styled-by-prettify">(</sp=
an><span style=3D"color: #008;" class=3D"styled-by-prettify">const</span><s=
pan style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=
=3D"color: #606;" class=3D"styled-by-prettify">Types</span><span style=3D"c=
olor: #660;" class=3D"styled-by-prettify">&...</span><span style=3D"col=
or: #000;" class=3D"styled-by-prettify"> elems</span><span style=3D"color: =
#660;" class=3D"styled-by-prettify">);</span></pre></div></code></div><br>W=
e might use </div><div><br></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"><pre style=3D"color: rgb(0, 128, 0); font-size: 12px; backgroun=
d-color: rgb(242, 255, 242);"><span style=3D"color: #008;" class=3D"styled-=
by-prettify">template</span><span style=3D"color: #660;" class=3D"styled-by=
-prettify"><</span><span style=3D"color: #008;" class=3D"styled-by-prett=
ify">typename</span><span style=3D"color: #000;" class=3D"styled-by-prettif=
y"> </span><span style=3D"color: #660;" class=3D"styled-by-prettify">...</s=
pan><span style=3D"color: rgb(102, 0, 102); font-family: Arial, Helvetica, =
sans-serif;"><span style=3D"color: #606;" class=3D"styled-by-prettify">Type=
s</span></span><span style=3D"color: #660;" class=3D"styled-by-prettify">&g=
t;</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span>=
</pre><pre style=3D"color: rgb(0, 128, 0); font-size: 12px; background-colo=
r: rgb(242, 255, 242);"><span style=3D"color: #000;" class=3D"styled-by-pre=
ttify">tuple </span><span style=3D"color: #660;" class=3D"styled-by-prettif=
y">(</span><span style=3D"color: #008;" class=3D"styled-by-prettify">const<=
/span><span style=3D"color: #000;" class=3D"styled-by-prettify"> initialize=
r_list</span><font color=3D"#666600" style=3D"font-size: 13px; white-space:=
normal; background-color: rgb(250, 250, 250);"><span style=3D"color: #660;=
" class=3D"styled-by-prettify"><</span><span style=3D"color: #606;" clas=
s=3D"styled-by-prettify">T</span></font><span style=3D"color: #606;" class=
=3D"styled-by-prettify">ypes</span><span style=3D"color: #660;" class=3D"st=
yled-by-prettify">...>&</span><span style=3D"color: #000;" class=3D"=
styled-by-prettify"> elems</span><span style=3D"color: #660;" class=3D"styl=
ed-by-prettify">);</span></pre></div></code></div><br><br></div><div>BR</di=
v><div>Cleiton</div><br><br>Em quarta-feira, 27 de maio de 2015 14:25:48 UT=
C-3, Edward Catmur escreveu:<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">On Wednesday, 27 May 2015 16:31:12 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 2015-05-27 11:11, Nicol Bo=
las wrote:
<br>> That one's easy. Since you're in generic code and could be getting=
multiple=20
<br>> values, the only way to manipulate them is with a tuple. So that's=
what you=20
<br>> stick them in:
<br>>=20
<br>> auto x =3D make_tuple(f());
<br>
<br>Okay, so composition in the face of generic code, where I also need to
<br>store the return value(s) at some point for whatever reason, *requires*
<br>the ability to unpack a std::tuple into an argument list.
<br></blockquote><div><br></div><div>That's a library addition; we can even=
do it with Python syntax, since std::tuple doesn't provide unary <font fac=
e=3D"courier new, monospace">operator*</font> yet:</div><div><br></div><div=
style=3D"border:1px solid rgb(187,187,187);word-wrap:break-word;background=
-color:rgb(250,250,250)"><code><div><span style=3D"color:#008">template</sp=
an><span style=3D"color:#660"><</span><span style=3D"color:#008">class</=
span><span style=3D"color:#660">...</span><span style=3D"color:#000"> T</sp=
an><span style=3D"color:#660">></span><span style=3D"color:#000"> </span=
><span style=3D"color:#660">[</span><span style=3D"color:#000">T</span><spa=
n style=3D"color:#660">...]</span><span style=3D"color:#000"> tuple</span><=
span style=3D"color:#660"><</span><span style=3D"color:#000">T</span><sp=
an style=3D"color:#660">...>::</span><span style=3D"color:#008">operator=
</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"> </span><=
span style=3D"color:#008">return</span><span style=3D"color:#000"> </span><=
span style=3D"color:#660">[</span><span style=3D"color:#008">get</span><spa=
n style=3D"color:#660"><</span><span style=3D"color:#066">0.</span><span=
style=3D"color:#660">..</span><span style=3D"color:#008">sizeof</span><spa=
n style=3D"color:#660">...(</span><span style=3D"color:#000">T</span><span =
style=3D"color:#660">...)>(*</span><span style=3D"color:#008">thi<wbr>s<=
/span><span style=3D"color:#660">)...];</span><span style=3D"color:#000"> <=
/span><span style=3D"color:#660">}</span><span style=3D"color:#000"><br></s=
pan></div></code></div><div><br>allowing:</div><div><br></div><div style=3D=
"border:1px solid rgb(187,187,187);word-wrap:break-word;background-color:rg=
b(250,250,250)"><code><div><span style=3D"color:#008">auto</span><span styl=
e=3D"color:#000"> x </span><span style=3D"color:#660">=3D</span><span style=
=3D"color:#000"> make_tuple</span><span style=3D"color:#660">(</span><span =
style=3D"color:#000">f</span><span style=3D"color:#660">());</span><span st=
yle=3D"color:#000"> <br>g</span><span style=3D"color:#660">(*</span><span s=
tyle=3D"color:#000">x</span><span style=3D"color:#660">);</span><span style=
=3D"color:#000"><br></span></div></code></div><br></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"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />
------=_Part_1067_1045411383.1432757770659--
------=_Part_1066_1288319926.1432757770652--
.
Author: Matthew Woehlke <mw_triad@users.sourceforge.net>
Date: Wed, 27 May 2015 16:42:11 -0400
Raw View
On 2015-05-27 16:06, Nicol Bolas wrote:
> struct Simple
> {
> std::string str;
> int foo;
> };
>
> std::string in = ...;
>
> return Simple{in, 2};
>
> [...] So... how would "partial constructor elision" work? Would it
> only be restricted to aggregates?
At least restricted to only aggregates, yes. Anything else, as you note,
is... "fun".
You are *also* proposing something almost, if not exactly, equivalent
for your "value sequence" concept. If we define "value sequence" as some
tuple-like-but-not-tuple "object" for which this sort of in-place
construction is allowed, then I don't see why this needs to be tightly
coupled to unpacking.
> The questions you need to answer are [...] Can you actually implement
> it?
Can you actually implement your MRV concept? Seems like it has most of
the same issues...
Aside from determining when to employ elision, at least, but then, if
the return type supports unpacking (which it obviously should), I don't
see why we need to get so worked up about it.
Really, what we need is a) generalized unpacking, and b) a special
tuple-like type that can only be "constructed" in certain ways, which
includes an appropriate form of RVO in-place construction. I don't see
why these need to be conjoined.
--
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 http://groups.google.com/a/isocpp.org/group/std-proposals/.
.
Author: Matthew Woehlke <mw_triad@users.sourceforge.net>
Date: Wed, 27 May 2015 17:05:34 -0400
Raw View
On 2015-05-27 16:13, Thiago Macieira wrote:
> On Wednesday 27 May 2015 12:10:32 Matthew Woehlke wrote:
>> What I meant was that MRV by value sequence (your proposal) should make
>> it possible for me to write 'unpack', as in this example:
>>
>> int foo(int, int, int);
>>
>> std::tuple<int, int, int> params = { ... };
>> foo(unpack(params));
>
> This is unlikely.
Why? If Nicol's "value sequence" idea was accepted, I mean.
My understanding of that idea is that a "value sequence" is NOT a
container, and can be used where multiple values are expected. I.e. this
should work:
[int, int] foo();
void bar(int, int);
bar(foo());
If that works, then I should also be able to write a template 'unpack'
as in the above example.
That said, this notion of a single "entity" that is really multiple
values... bugs me. It would be one thing if we had syntax that said
'hey, this here is multiple values that I would like passed as separate
parameters', but my understanding is that that *isn't* what Nicol is
suggesting. Given that we don't have any similar concept in the language
currently, I'm not particularly fond of introducing it.
This is one reason why I think that MRV's, however they happen under the
hood, should still be "container-like". Which in turn strongly suggests
that unpacking should be explicit and not too tightly coupled to MRV's.
(Which in turn is what I've been saying all along.)
I still think we have three *orthogonal* ideas:
1. Unpacking via assignment/declaration (original proposal).
2. MRV optimization, especially w.r.t. RVO.
3. Unpacking into an argument list (i.e. function calls).
I'm not convinced that *any* of these are dependent on each other, not
even 2 -> 1. Yes, it's obnoxious right now to write 'auto&& a = foo();
auto& x = get<0>(a);', but why shouldn't RVO (given that we have 2) work
for that?
--
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 http://groups.google.com/a/isocpp.org/group/std-proposals/.
.
Author: Nicol Bolas <jmckesson@gmail.com>
Date: Wed, 27 May 2015 15:05:15 -0700 (PDT)
Raw View
------=_Part_1026_984778707.1432764315773
Content-Type: multipart/alternative;
boundary="----=_Part_1027_519261120.1432764315773"
------=_Part_1027_519261120.1432764315773
Content-Type: text/plain; charset=UTF-8
On Wednesday, May 27, 2015 at 4:42:24 PM UTC-4, Matthew Woehlke wrote:
>
> On 2015-05-27 16:06, Nicol Bolas wrote:
> > struct Simple
> > {
> > std::string str;
> > int foo;
> > };
> >
> > std::string in = ...;
> >
> > return Simple{in, 2};
> >
> > [...] So... how would "partial constructor elision" work? Would it
> > only be restricted to aggregates?
>
> At least restricted to only aggregates, yes. Anything else, as you note,
> is... "fun".
>
> You are *also* proposing something almost, if not exactly, equivalent
> for your "value sequence" concept. If we define "value sequence" as some
> tuple-like-but-not-tuple "object" for which this sort of in-place
> construction is allowed, then I don't see why this needs to be tightly
> coupled to unpacking.
>
This is the thing you don't seem to fully understand.
I do not *want* a "value sequence" to be *any* kind of C++ object. It
should not be a type with a value. It should not be memory stored in some
location. Remember: template parameter packs are not objects either. You
can't copy them, move them, reference them, or use them in anything other
than a parameter pack expression. Similarly, braced-init-lists are not
elements of an expression; the construct `{4.3, "foo"}` is not a legal
expression. It is merely a construct which can be used in certain locations
to initialize values in C++.
Value sequences should be like those. Such constructs can be arbitrarily
assigned behavior that we find useful, rather than having to fit into
existing paradigms.
I don't want them to be objects of any sort.
> The questions you need to answer are [...] Can you actually implement
> > it?
>
> Can you actually implement your MRV concept? Seems like it has most of
> the same issues...
>
That's a fair question, but I fail to see the implementation problems.
Certainly, they're nothing like those for defining and implementing elision
out of some type.
Right now, as I understand it, output values at the compiled code level are
returned as either registers (for small objects), or the caller provides a
piece of stack space to store the returned object (for larger objects).
Since the caller knows the function's MRV signature, it knows how much
space to allocate. And you can even still only pass a single "value" for
the return value, knowing exactly how the function will fill in the
multiple objects in the value.
Indeed, that's how elision works. The caller is given the output value as a
pointer to stack memory. Internally, the C++ code says to create some value
and then return it. The compiler sees the opportunity for elision and
simply decides to allocate that value in the return value space, thus
making the return statement a noop. The space the caller provides is simply
the object that the caller is initializing, if the caller is initializing
an object.
If the caller is not initializing the object, then the caller creates some
temporary stack space, does the copy/move into the final location, and then
destroys the temporary. No initialization, no elision.
Oh sure, it would require something of an ABI change. But since it's part
of the return value, you wouldn't even need to mess with name mangling.
You'd just use the list of input types to determine how big of a buffer you
need to pass in.
Aside from determining when to employ elision, at least, but then, if
> the return type supports unpacking (which it obviously should), I don't
> see why we need to get so worked up about it.
>
Because you're asking for general syntax, rather than a library feature or
a contained bit of syntax. And once assigned, that syntax will be
permanently embedded in C++. Forever. It can not be used for anything else
in the language.
Because syntax is rare and precious, it is not cheap. And valuable syntax
should not be created just because it makes the lives of generic
programmers who work with tuples easier. Syntax should be something we can
all, or most all, use.
Uniform initialization, lambda expressions, move semantics, these are all
highly useful elements of basic C++ syntax that can be used by programmers
regardless of discipline. Even terse template syntax has substantial value,
particularly in light of many other changes coming down the pipe. Multiple
return values would be a similarly broad concept, usable by many people.
But doing MRVs as some kind of hack, based on building tuples (or
tuple-like objects) and the like? No.
--
---
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 http://groups.google.com/a/isocpp.org/group/std-proposals/.
------=_Part_1027_519261120.1432764315773
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">On Wednesday, May 27, 2015 at 4:42:24 PM UTC-4, Matthew Wo=
ehlke wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-lef=
t: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">On 2015-05-27 16:0=
6, Nicol Bolas wrote:
<br>> struct Simple
<br>> {
<br>> std::string str;
<br>> int foo;
<br>> };
<br>>=20
<br>> std::string in =3D ...;
<br>>=20
<br>> return Simple{in, 2};
<br>>=20
<br>> [...] So... how would "partial constructor elision" work? Would it
<br>> only be restricted to aggregates?
<br>
<br>At least restricted to only aggregates, yes. Anything else, as you note=
,
<br>is... "fun".
<br>
<br>You are *also* proposing something almost, if not exactly, equivalent
<br>for your "value sequence" concept. If we define "value sequence" as som=
e
<br>tuple-like-but-not-tuple "object" for which this sort of in-place
<br>construction is allowed, then I don't see why this needs to be tightly
<br>coupled to unpacking.<br></blockquote><div><br>This is the thing you do=
n't seem to fully understand.<br><br>I do not <i>want</i> a "value sequence=
" to be <i>any</i> kind of C++ object. It should not be a type with a value=
.. It should not be memory stored in some location. Remember: template param=
eter packs are not objects either. You can't copy them, move them, referenc=
e them, or use them in anything other than a parameter pack expression. Sim=
ilarly, braced-init-lists are not elements of an expression; the construct =
`{4.3, "foo"}` is not a legal expression. It is merely a construct which ca=
n be used in certain locations to initialize values in C++.<br><br>Value se=
quences should be like those. Such constructs can be arbitrarily assigned b=
ehavior that we find useful, rather than having to fit into existing paradi=
gms.<br><br>I don't want them to be objects of any sort.<br><br></div><bloc=
kquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-l=
eft: 1px #ccc solid;padding-left: 1ex;">
> The questions you need to answer are [...] Can you actually implement
<br>> it?
<br>
<br>Can you actually implement your MRV concept? Seems like it has most of
<br>the same issues...<br></blockquote><div><br>That's a fair question, but=
I fail to see the implementation problems. Certainly, they're nothing like=
those for defining and implementing elision out of some type.<br><br>Right=
now, as I understand it, output values at the compiled code level are retu=
rned as either registers (for small objects), or the caller provides a piec=
e of stack space to store the returned object (for larger objects). Since t=
he caller knows the function's MRV signature, it knows how much space to al=
locate. And you can even still only pass a single "value" for the return va=
lue, knowing exactly how the function will fill in the multiple objects in =
the value.<br><br>Indeed, that's how elision works. The caller is given the=
output value as a pointer to stack memory. Internally, the C++ code says t=
o create some value and then return it. The compiler sees the opportunity f=
or elision and simply decides to allocate that value in the return value sp=
ace, thus making the return statement a noop. The space the caller provides=
is simply the object that the caller is initializing, if the caller is ini=
tializing an object.<br><br>If the caller is not initializing the object, t=
hen the caller creates some temporary stack space, does the copy/move into =
the final location, and then destroys the temporary. No initialization, no =
elision.<br><br>Oh sure, it would require something of an ABI change. But s=
ince it's part of the return value, you wouldn't even need to mess with nam=
e mangling. You'd just use the list of input types to determine how big of =
a buffer you need to pass in.<br><br></div><blockquote class=3D"gmail_quote=
" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding=
-left: 1ex;">
Aside from determining when to employ elision, at least, but then, if
<br>the return type supports unpacking (which it obviously should), I don't
<br>see why we need to get so worked up about it.<br></blockquote><div><br>=
Because you're asking for general syntax, rather than a library feature or =
a contained bit of syntax. And once assigned, that syntax will be permanent=
ly embedded in C++. Forever. It can not be used for anything else in the la=
nguage.<br><br>Because syntax is rare and precious, it is not cheap. And va=
luable syntax should not be created just because it makes the lives of gene=
ric programmers who work with tuples easier. Syntax should be something we =
can all, or most all, use.<br><br>Uniform initialization, lambda expression=
s, move semantics, these are all highly useful elements of basic C++ syntax=
that can be used by programmers regardless of discipline. Even terse templ=
ate syntax has substantial value, particularly in light of many other chang=
es coming down the pipe. Multiple return values would be a similarly broad =
concept, usable by many people.<br><br>But doing MRVs as some kind of hack,=
based on building tuples (or tuple-like objects) and the like? No.</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"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />
------=_Part_1027_519261120.1432764315773--
------=_Part_1026_984778707.1432764315773--
.
Author: Nicol Bolas <jmckesson@gmail.com>
Date: Wed, 27 May 2015 15:09:33 -0700 (PDT)
Raw View
------=_Part_2225_531959364.1432764573697
Content-Type: multipart/alternative;
boundary="----=_Part_2226_666608287.1432764573697"
------=_Part_2226_666608287.1432764573697
Content-Type: text/plain; charset=UTF-8
On Wednesday, May 27, 2015 at 5:05:45 PM UTC-4, Matthew Woehlke wrote:
>
> That said, this notion of a single "entity" that is really multiple
> values... bugs me. It would be one thing if we had syntax that said
> 'hey, this here is multiple values that I would like passed as separate
> parameters', but my understanding is that that *isn't* what Nicol is
> suggesting. Given that we don't have any similar concept in the language
> currently, I'm not particularly fond of introducing it.
>
We do have a similar concept: template parameter packs. It is one entity
which represents multiple objects. You can unpack them in arbitrary
expressions, which makes them much more useful than your limited `unpack`
tuple suggestion.
I'm not saying that MRV functions should effectively return TPPs. But my
point is that we already have similar constructs that are based on similar
elements. So there's nothing strange about the idea of such a construct.
--
---
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 http://groups.google.com/a/isocpp.org/group/std-proposals/.
------=_Part_2226_666608287.1432764573697
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><br><br>On Wednesday, May 27, 2015 at 5:05:45 PM UTC-4, Ma=
tthew Woehlke wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;ma=
rgin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">That said,=
this notion of a single "entity" that is really multiple
<br>values... bugs me. It would be one thing if we had syntax that said
<br>'hey, this here is multiple values that I would like passed as separate
<br>parameters', but my understanding is that that *isn't* what Nicol is
<br>suggesting. Given that we don't have any similar concept in the languag=
e
<br>currently, I'm not particularly fond of introducing it.<br></blockquote=
><div><br>We do have a similar concept: template parameter packs. It is one=
entity which represents multiple objects. You can unpack them in arbitrary=
expressions, which makes them much more useful than your limited `unpack` =
tuple suggestion.<br><br>I'm not saying that MRV functions should effective=
ly return TPPs. But my point is that we already have similar constructs tha=
t are based on similar elements. So there's nothing strange about the idea =
of such a construct.<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"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />
------=_Part_2226_666608287.1432764573697--
------=_Part_2225_531959364.1432764573697--
.
Author: Farid Mehrabi <farid.mehrabi@gmail.com>
Date: Thu, 28 May 2015 12:39:08 +0430
Raw View
--001a1135a2e82391c105171fe2e3
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
=E2=80=8B=E2=80=8B
=E2=80=8B=E2=80=8B
2015-05-21 5:44 GMT+04:30 Matthew Fioravante <fmatthew5876@gmail.com>:
> So this idea came out of the number parsing thread. Many languages like
> python have support for functions returning multiple values.
>
> In C++, one option we have currently is this:
> =E2=80=8B=E2=80=8B
>
> std::tuple<int,float,double> foo();
>
> int x;
> double d;
> std::tie(x, std::ignore, d) =3D foo();
>
> This works but it has a lot of problems:
> - We have to declare the receiving variables beforehand. This means they
> have to be default constructed and then assigned and we cannot use auto.
> - Its overly verbose and clumsy to use. First we have to declare the
> variables, then we need 8 character std::tie and 11 character std::ignore=
..
> - tuple and tie are not as well known to beginners. A "standard practice"
> for capturing multiple values would be better as a core language feature
> than a library feature.
>
> So one solution would be to invent a new syntax:
> int x;
> [x; void; auto d] =3D foo();
>
> Which is the equivalent of:
> =E2=80=8B=E2=80=8B
> int x;
> auto _t =3D foo();
> =E2=80=8B=E2=80=8B
> x =3D std::get<0>(std::move(_t));
> auto d =3D std::get<2>(std::move(_t));
>
> Each element in this "assignment list" corresponds to a element of a tupl=
e
> of the right hand side of the expression. Each element can be one of:
> - An lvalue expression: the resulting lvalue is assigned with operator=3D=
()
> to the corresponding tuple element.
> - void: the corresponding tuple element is ignored
> - A local variable declaration. A local variable is created and
> constructed with the corresponding tuple element.
>
> I've chosen to use [] instead of {} because so far braces always introduc=
e
> a scope and in this example, d which is created inside the braces actuall=
y
> lives in the outer scope.
> I've chosen to use ; instead of , to avoid confusion with the comma
> operator.
>
> We can also allow the user to specify a shorter list, with default values
> of void for the trailing elements not mentioned:
>
> [
> =E2=80=8B=E2=80=8B
> auto x] =3D foo(); //same as [auto x, void, void] =3D foo()
>
> What do you think about such a feature?
>
> --
>
=E2=80=8BWhat is wrong with using references?
=E2=80=8B=E2=80=8B=E2=80=8B=E2=80=8B
=E2=80=8B
auto
=E2=80=8B
& bar
=E2=80=8B
=3D foo();
=E2=80=8B
int
=E2=80=8B=E2=80=8B
x =3D std::get<0>(
=E2=80=8B
bar
=E2=80=8B
);
auto
=E2=80=8B=E2=80=8B
=E2=80=8B
=E2=80=8B
d =3D std::get<2>(
=E2=80=8B=E2=80=8B
bar
);
=E2=80=8Bregards,
FM.=E2=80=8B
--=20
how am I supposed to end the twisted road of your hair in such a dark
night??
unless the candle of your face does shed some light upon my way!!!
--=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 http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.
--001a1135a2e82391c105171fe2e3
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"rtl"><div class=3D"gmail_default" style=3D"font-family:'ari=
al narrow',sans-serif;font-size:large"><br></div><div class=3D"gmail_de=
fault" style=3D"font-family:'arial narrow',sans-serif;font-size:lar=
ge">=E2=80=8B=E2=80=8B</div><div class=3D"gmail_default" style=3D"font-fami=
ly:'arial narrow',sans-serif;font-size:large">=E2=80=8B=E2=80=8B</d=
iv><div class=3D"gmail_extra"><br><div class=3D"gmail_quote"><div dir=3D"lt=
r">2015-05-21 5:44 GMT+04:30 Matthew Fioravante <span dir=3D"ltr"><<a hr=
ef=3D"mailto:fmatthew5876@gmail.com" target=3D"_blank">fmatthew5876@gmail.c=
om</a>></span>:</div><blockquote class=3D"gmail_quote" style=3D"margin:0=
px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);b=
order-left-style:solid;padding-left:1ex"><div dir=3D"ltr">So this idea came=
out of the number parsing thread. Many languages like python have support =
for functions returning multiple values.<div><br></div><div>In C++, one opt=
ion we have currently is this:</div><div><div class=3D"gmail_default" style=
=3D"font-family:'arial narrow',sans-serif;font-size:large">=E2=80=
=8B=E2=80=8B</div><br></div><div><div style=3D"border:1px solid rgb(187,187=
,187);word-wrap:break-word;background-color:rgb(250,250,250)"><code><div><s=
pan style=3D"color:rgb(0,0,0)">std</span><span style=3D"color:rgb(102,102,0=
)">::</span><span style=3D"color:rgb(0,0,0)">tuple</span><span style=3D"col=
or:rgb(102,102,0)"><</span><span style=3D"color:rgb(0,0,136)">int</span>=
<span style=3D"color:rgb(102,102,0)">,</span><span style=3D"color:rgb(0,0,1=
36)">float</span><span style=3D"color:rgb(102,102,0)">,</span><span style=
=3D"color:rgb(0,0,136)">double</span><span style=3D"color:rgb(102,102,0)">&=
gt;</span><font color=3D"#000000"><span style=3D"color:rgb(0,0,0)"> foo</sp=
an><span style=3D"color:rgb(102,102,0)">();</span><span style=3D"color:rgb(=
0,0,0)"><br><br></span><span style=3D"color:rgb(0,0,136)">int</span><span s=
tyle=3D"color:rgb(0,0,0)"> x</span><span style=3D"color:rgb(102,102,0)">;</=
span><span style=3D"color:rgb(0,0,0)"><br></span><span style=3D"color:rgb(0=
,0,136)">double</span><span style=3D"color:rgb(0,0,0)"> d</span><span style=
=3D"color:rgb(102,102,0)">;</span><span style=3D"color:rgb(0,0,0)"><br>std<=
/span><span style=3D"color:rgb(102,102,0)">::</span><span style=3D"color:rg=
b(0,0,0)">tie</span><span style=3D"color:rgb(102,102,0)">(</span><span styl=
e=3D"color:rgb(0,0,0)">x</span><span style=3D"color:rgb(102,102,0)">,</span=
><span style=3D"color:rgb(0,0,0)"> std</span><span style=3D"color:rgb(102,1=
02,0)">::</span><span style=3D"color:rgb(0,0,0)">ignore</span><span style=
=3D"color:rgb(102,102,0)">,</span><span style=3D"color:rgb(0,0,0)"> d</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"c=
olor:rgb(0,0,0)"> foo</span><span style=3D"color:rgb(102,102,0)">();</span>=
</font></div></code></div><br>This works but it has a lot of problems:</div=
><div>- We have to declare the receiving variables beforehand. This means t=
hey have to be default constructed and then assigned and we cannot use auto=
..</div><div>- Its overly verbose and clumsy to use. First we have to declar=
e the variables, then we need 8 character std::tie and 11 character std::ig=
nore.</div><div>- tuple and tie are not as well known to beginners. A "=
;standard practice" for capturing multiple values would be better as a=
core language feature than a library feature.</div><div><br></div><div>So =
one solution would be to invent a new syntax:</div><div><div style=3D"borde=
r:1px solid rgb(187,187,187);word-wrap:break-word;background-color:rgb(250,=
250,250)"><code><div><span style=3D"font-family:Arial,Helvetica,sans-serif"=
><span style=3D"color:rgb(0,0,136)">int</span><span style=3D"color:rgb(0,0,=
0)"> x</span><span style=3D"color:rgb(102,102,0)">;</span><span style=3D"co=
lor:rgb(0,0,0)"><br></span><span style=3D"color:rgb(102,102,0)">[</span><sp=
an style=3D"color:rgb(0,0,0)">x</span><span style=3D"color:rgb(102,102,0)">=
;</span><span style=3D"color:rgb(0,0,0)"> </span><span style=3D"color:rgb(0=
,0,136)">void</span><span style=3D"color:rgb(102,102,0)">;</span><span styl=
e=3D"color:rgb(0,0,0)"> </span><span style=3D"color:rgb(0,0,136)">auto</spa=
n><span style=3D"color:rgb(0,0,0)"> d</span><span style=3D"color:rgb(102,10=
2,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)"> foo</span><spa=
n style=3D"color:rgb(102,102,0)">();</span></span><span style=3D"color:rgb(=
0,0,0)"><br></span></div></code></div><div><br></div><div>Which is the equi=
valent of:<div class=3D"gmail_default" style=3D"font-family:'arial narr=
ow',sans-serif;font-size:large;display:inline">=E2=80=8B=E2=80=8B</div>=
</div><div><div style=3D"border:1px solid rgb(187,187,187);word-wrap:break-=
word;background-color:rgb(250,250,250)"><code><div><span style=3D"color:rgb=
(0,0,136)">int</span><span style=3D"color:rgb(0,0,0)"> x</span><span style=
=3D"color:rgb(102,102,0)">;</span><span style=3D"color:rgb(0,0,0)"><br></sp=
an><span style=3D"color:rgb(0,0,136)">auto</span><span style=3D"color:rgb(0=
,0,0)"> _t </span><span style=3D"color:rgb(102,102,0)">=3D</span><span styl=
e=3D"color:rgb(0,0,0)"> foo</span><span style=3D"color:rgb(102,102,0)">();<=
/span><span style=3D"color:rgb(0,0,0)"><br><div class=3D"gmail_default" sty=
le=3D"font-family:'arial narrow',sans-serif;font-size:large;display=
:inline">=E2=80=8B=E2=80=8B</div>x </span><span style=3D"color:rgb(102,102,=
0)">=3D</span><span style=3D"color:rgb(0,0,0)"> std</span><span style=3D"co=
lor:rgb(102,102,0)">::</span><span style=3D"color:rgb(0,0,136)">get</span><=
span style=3D"color:rgb(102,102,0)"><</span><span style=3D"color:rgb(0,1=
02,102)">0</span><span style=3D"color:rgb(102,102,0)">>(</span><span sty=
le=3D"color:rgb(0,0,0)">std</span><span style=3D"color:rgb(102,102,0)">::</=
span><span style=3D"color:rgb(0,0,0)">move</span><span style=3D"color:rgb(1=
02,102,0)">(</span><span style=3D"color:rgb(0,0,0)">_t</span><span style=3D=
"color:rgb(102,102,0)">));</span><span style=3D"color:rgb(0,0,0)"><br></spa=
n><span style=3D"color:rgb(0,0,136)">auto</span><span style=3D"color:rgb(0,=
0,0)"> d </span><span style=3D"color:rgb(102,102,0)">=3D</span><span style=
=3D"color:rgb(0,0,0)"> std</span><span style=3D"color:rgb(102,102,0)">::</s=
pan><span style=3D"color:rgb(0,0,136)">get</span><span style=3D"color:rgb(1=
02,102,0)"><</span><span style=3D"color:rgb(0,102,102)">2</span><span st=
yle=3D"color:rgb(102,102,0)">>(</span><span style=3D"color:rgb(0,0,0)">s=
td</span><font color=3D"#008800"><span style=3D"color:rgb(102,102,0)">::</s=
pan><span style=3D"color:rgb(0,0,0)">move</span><span style=3D"color:rgb(10=
2,102,0)">(</span></font><span style=3D"color:rgb(0,0,0)">_t</span><span st=
yle=3D"color:rgb(102,102,0)">));</span></div></code></div><br></div><div>Ea=
ch element in this "assignment list" corresponds to a element of =
a tuple of the right hand side of the expression. Each element can be one o=
f:<br></div><div>- An lvalue expression: the resulting lvalue is assigned w=
ith operator=3D() to the corresponding tuple element.</div><div>- void: the=
corresponding tuple element is ignored</div><div>- A local variable declar=
ation. A local variable is created and constructed with the corresponding t=
uple element.</div><div><br></div>I've chosen to use [] instead of {} b=
ecause so far braces always introduce a scope and in this example, d which =
is created inside the braces actually lives in the outer scope.</div><div>I=
've chosen to use ; instead of , to avoid confusion with the comma oper=
ator.</div><div><br></div><div>We can also allow the user to specify a shor=
ter list, with default values of void for the trailing elements not mention=
ed:</div><div><br></div><div><div style=3D"border:1px solid rgb(187,187,187=
);word-wrap:break-word;background-color:rgb(250,250,250)"><code><div><span =
style=3D"color:rgb(102,102,0)">[</span><span style=3D"color:rgb(0,0,136)"><=
div class=3D"gmail_default" style=3D"font-family:'arial narrow',san=
s-serif;font-size:large;display:inline">=E2=80=8B=E2=80=8B</div>auto</span>=
<span style=3D"color:rgb(0,0,0)"> x</span><span style=3D"color:rgb(102,102,=
0)">]</span><span style=3D"color:rgb(0,0,0)"> </span><span style=3D"color:r=
gb(102,102,0)">=3D</span><font color=3D"#000000"><span style=3D"color:rgb(0=
,0,0)"> foo</span><span style=3D"color:rgb(102,102,0)">();</span><span styl=
e=3D"color:rgb(0,0,0)"> </span><span style=3D"color:rgb(136,0,0)">//same as=
[auto x, void, void] =3D foo()</span><span style=3D"color:rgb(0,0,0)"><br>=
</span></font></div></code></div><br>What do you think about such a feature=
?</div></div><span class=3D""><font color=3D"#888888">
<p></p>
--=C2=A0<br></font></span></blockquote><div style=3D"direction:ltr"><div cl=
ass=3D"gmail_default" style=3D"font-family:'arial narrow',sans-seri=
f;font-size:large;display:inline">=E2=80=8BWhat is wrong with using referen=
ces?</div></div><div style=3D"direction:ltr"><div class=3D"gmail_default" s=
tyle=3D"font-family:'arial narrow',sans-serif;font-size:large">=E2=
=80=8B=E2=80=8B=E2=80=8B=E2=80=8B</div><div><div style=3D"border:1px solid =
rgb(187,187,187);word-wrap:break-word;background-color:rgb(250,250,250)"><c=
ode><span style=3D"color:rgb(0,0,136)"><div class=3D"gmail_default" style=
=3D"font-family:'arial narrow',sans-serif;font-size:large;display:i=
nline">=E2=80=8B</div></span><span style=3D"color:rgb(0,0,136)">auto</span>=
<span style=3D"color:rgb(0,0,0)">=C2=A0<div class=3D"gmail_default" style=
=3D"font-family:'arial narrow',sans-serif;font-size:large;display:i=
nline">=E2=80=8B</div><div class=3D"gmail_default" style=3D"display:inline"=
><font face=3D"arial, helvetica, sans-serif">& bar</font></div><div cla=
ss=3D"gmail_default" style=3D"font-family:'arial narrow',sans-serif=
;font-size:large;display:inline">=E2=80=8B</div>=C2=A0</span><span style=3D=
"color:rgb(102,102,0)">=3D</span><span style=3D"color:rgb(0,0,0)">=C2=A0foo=
</span><span style=3D"color:rgb(102,102,0)">();</span><span style=3D"color:=
rgb(0,0,0)"><br></span><span style=3D"color:rgb(0,0,136)"><div class=3D"gma=
il_default" style=3D"font-family:'arial narrow',sans-serif;font-siz=
e:large;display:inline">=E2=80=8B</div>int</span><span style=3D"color:rgb(0=
,0,0)">=C2=A0</span><span style=3D"color:rgb(0,0,0)"><div class=3D"gmail_de=
fault" style=3D"font-family:'arial narrow',sans-serif;font-size:lar=
ge;display:inline">=E2=80=8B=E2=80=8B</div>x=C2=A0</span><span style=3D"col=
or:rgb(102,102,0)">=3D</span><span style=3D"color:rgb(0,0,0)">=C2=A0std</sp=
an><span style=3D"color:rgb(102,102,0)">::</span><span style=3D"color:rgb(0=
,0,136)">get</span><span style=3D"color:rgb(102,102,0)"><</span><span st=
yle=3D"color:rgb(0,102,102)">0</span><font color=3D"#666600">>(</font><f=
ont color=3D"#000000"><div class=3D"gmail_default" style=3D"font-family:=
9;arial narrow',sans-serif;font-size:large;display:inline">=E2=80=8B</d=
iv><div class=3D"gmail_default" style=3D"display:inline"><font face=3D"aria=
l, helvetica, sans-serif">bar</font></div><div class=3D"gmail_default" styl=
e=3D"font-family:'arial narrow',sans-serif;font-size:large;display:=
inline">=E2=80=8B</div></font><span style=3D"color:rgb(102,102,0)">);</span=
><span style=3D"color:rgb(0,0,0)"><br></span><span style=3D"color:rgb(0,0,1=
36)">auto<div class=3D"gmail_default" style=3D"font-family:'arial narro=
w',sans-serif;font-size:large;display:inline">=E2=80=8B=E2=80=8B</div><=
/span><span style=3D"color:rgb(0,0,0)">=C2=A0<div class=3D"gmail_default" s=
tyle=3D"font-family:'arial narrow',sans-serif;font-size:large;displ=
ay:inline">=E2=80=8B</div><div class=3D"gmail_default" style=3D"font-family=
:'arial narrow',sans-serif;font-size:large;display:inline">=E2=80=
=8B</div>d=C2=A0</span><span style=3D"color:rgb(102,102,0)">=3D</span><span=
style=3D"color:rgb(0,0,0)">=C2=A0std</span><span style=3D"color:rgb(102,10=
2,0)">::</span><span style=3D"color:rgb(0,0,136)">get</span><span style=3D"=
color:rgb(102,102,0)"><</span><span style=3D"color:rgb(0,102,102)">2</sp=
an><font color=3D"#666600">>(</font><div class=3D"gmail_default" style=
=3D"color:rgb(102,102,0);font-family:'arial narrow',sans-serif;font=
-size:large;display:inline">=E2=80=8B=E2=80=8B</div><div class=3D"gmail_def=
ault" style=3D"display:inline"><font color=3D"#000000" face=3D"arial, helve=
tica, sans-serif">bar</font></div><span style=3D"color:rgb(102,102,0)">);</=
span></code></div></div></div><div><div style=3D"direction:ltr"><br></div><=
/div><div style=3D"font-family:'arial narrow',sans-serif;font-size:=
large" class=3D"gmail_default" dir=3D"ltr">=E2=80=8Bregards,</div><div styl=
e=3D"font-family:'arial narrow',sans-serif;font-size:large" class=
=3D"gmail_default" dir=3D"ltr">FM.=E2=80=8B</div></div><br clear=3D"all"><d=
iv><br></div>-- <br><div class=3D"gmail_signature"><div dir=3D"rtl"><div><d=
iv dir=3D"ltr">how am I supposed to end the twisted road of=C2=A0 your hair=
in such a dark night??<br>unless the candle of your face does shed some li=
ght upon my way!!!<br></div></div></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"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />
--001a1135a2e82391c105171fe2e3--
.
Author: Matthew Woehlke <mw_triad@users.sourceforge.net>
Date: Thu, 28 May 2015 12:13:49 -0400
Raw View
On 2015-05-27 18:05, Nicol Bolas wrote:
> On Wednesday, May 27, 2015 at 4:42:24 PM UTC-4, Matthew Woehlke wrote:
>> If we define "value sequence" as some tuple-like-but-not-tuple
>> "object" for which this sort of in-place construction is allowed,
>> then I don't see why this needs to be tightly coupled to
>> unpacking.
>
> This is the thing you don't seem to fully understand.
>
> I do not *want* a "value sequence" to be *any* kind of C++ object. It
> should not be a type with a value.
I think I do understand. It's just that I strongly disagree.
At some point, there *has* to be an object representing a value
sequence. Even if it's not a "C++ object", the compiler needs some sort
of internal notion that it has so many values and they are stored in
such-and-such manner.
If it has this, I fail to see why there is a problem giving that
construct a C++ name such that one can write get<N> against the object.
Whether or not one can "make copies" is an interesting question, though
again I object to declaring that you can't.
As stated elsewhere, I also object to the notion that there is no
(non-explicit) way to treat a value sequence as a single entity
(regardless of the underlying representation). C++ currently has no
concept at all like this. Python has no such concept. I am utterly
unconvinced that there is any genuine value in creating such a concept,
when the main objections you raised can be addressed by a new container
type.
> Remember: template parameter packs are not objects either. You
> can't copy them, move them, reference them, or use them in anything other
> than a parameter pack expression.
Template parameter packs *also* are not real C++ entities. They are
template meta-programming entities that are much more closely related to
template type names. Substitution occurs at compile time, at instantiation.
This is not the case with return values, multiple or otherwise. For one,
the types are not templated (or it they are, that is an orthogonal process).
I object to the idea of MRV's being unusable except to be unpacked
(which would also imply that unpacking is a concept that can only be
used for MRV's). I fail to see the justification for this approach
compared to a more traditional "MRV's are a real, single type" approach.
> Similarly, braced-init-lists are not
> elements of an expression; the construct `{4.3, "foo"}` is not a legal
> expression.
You're confusing the issue. That's *not* valid without context, no, but
we're not talking about a context-free case. And '{1, 2}' *is* valid; on
its own, it is a std::initializer_list<int>.
MRV's have context. Either the types are known a-priori, or else your
proposal requires that they be deduced. However I see no reason that
deduction can't deduce a std::value_sequence<Types...>.
> Value sequences should be like those.
They won't be. A brace expression such as the above is *always* a brace
expression. You can't get such a thing back from a function, or give it
a name. Again, I object to having functions return something that is
invisibly treated as multiple expressions.
>> Can you actually implement your MRV concept? Seems like it has most of
>> the same issues...
>
> That's a fair question, but I fail to see the implementation problems.
> Certainly, they're nothing like those for defining and implementing elision
> out of some type.
That is *exactly* a problem. In your proposal, you expect this:
std::vector<int> a = {1, 2, 3};
std::string b = "foo";
return [a; b];
....to deduce that the 'a' and 'b' objects should NOT be constructed on
the stack, but rather in some manner that allows RVO.
I fail to see why it should be any more difficult to do this if the MRV
is some new "object type".
> Right now, as I understand it, output values at the compiled code level are
> returned as either registers (for small objects), or the caller provides a
> piece of stack space to store the returned object (for larger objects).
So what's the problem giving std::value_sequence this behavior?
It seems to me that std::value_sequence can be treated as a struct with
members equal to the set of return values *that are not constructed by
the caller*. The caller provides this storage as it would for e.g. a
std::tuple. The callee constructs the "members" of this in place in the
usual manner of RVO. No ABI change is needed.
>> I don't see why we need to get so worked up about it.
>
> Because syntax is rare and precious, it is not cheap. And valuable syntax
> should not be created just because it makes the lives of generic
> programmers who work with tuples easier.
I *don't* work with tuples. The *reason* I don't work with tuples is
because they are a pain, exactly *because* we don't have syntax to make
them easier.
Nor is unpacking limited to tuples. Aside from the range-based for
example (which, btw, I consider as a "critical" use case for any form of
unpacking and/or MRV), unpacking has potential value for any
sequence-like structure. Think about arrays, points, ranges,
dimensions... all could potentially use unpacking.
Python obviously felt that *generalized* unpacking is sufficiently
valuable that it is not only a language feature, but one that uses
almost *no* syntax.
--
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 http://groups.google.com/a/isocpp.org/group/std-proposals/.
.
Author: Arthur O'Dwyer <arthur.j.odwyer@gmail.com>
Date: Thu, 28 May 2015 12:00:20 -0700 (PDT)
Raw View
------=_Part_7506_2119063727.1432839620267
Content-Type: multipart/alternative;
boundary="----=_Part_7507_1254118138.1432839620267"
------=_Part_7507_1254118138.1432839620267
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
On Wednesday, May 27, 2015 at 8:23:16 AM UTC-7, Matthew Woehlke wrote:
>
> On 2015-05-27 03:43, Nicol Bolas wrote:=20
> > On Tuesday, May 26, 2015 at 10:53:05 PM UTC-4, Matthew Fioravante wrote=
:=20
> >> On Tuesday, May 26, 2015 at 9:23:50 PM UTC-4, Nicol Bolas wrote:=20
> >>> Nor does it force you to package parameters into a tuple.=20
> >>=20
> >> But it does, at least at the syntax level=20
> >>=20
> >> def foo():=20
> >> return (1, 2, 3);=20
> >>=20
> >> (x, y, z) =3D foo();=20
>
> Actually it doesn't:=20
>
> >>> def foo():=20
> >>> return 1, 2=20
> >>> a, b =3D foo()=20
>
> ...but the return is a 'tuple' nevertheless:=20
>
> >>> type(foo())=20
> <type 'tuple'>=20
>
> (Basically, the ()'s are optional, and implied if absent.)=20
>
> My knowledge of Lua is limited ("effectively nonexistent" is probably=20
> more accurate). Python, however, only supports single return values. It=
=20
> just has syntax sugar for returning tuples and unpacking tuples.=20
>
> [...]
> In Python, "return x, y" is syntactic sugar for "return (x, y)".
>
I'm glad someone finally pointed that out! This thread has been relatively=
=20
full of misconceptions about non-C++ languages. I even saw somebody=20
claiming that Python doesn't *have* tuples. :P
https://docs.python.org/2/tutorial/datastructures.html#tuples-and-sequences
FWIW, I'm strongly opposed to "filling in" any holes in the lambda syntax=
=20
[x](...){...} with completely unrelated functionality [x]=3D(...).
(And yes, I was initially opposed to the crazy lambda syntax "filling in"=
=20
holes in the array-indexing syntax. This is the line-noise-must-compile=20
philosophy of Perl: "a[i] works, i[a] works, now let's make [a]{i;} do=20
something too!")
However, let's go back to analyzing use-cases. I hear three coming up over=
=20
and over:
(1) Initializing a set of named local variables from a tuple, without using=
=20
std::tie, and ideally defining those variables with 'auto'.
std::tuple<float,float,float> getcoords();
int main() {
auto x, y, z =3D getcoords();
}
This syntax would work out of the box, if you defined "auto list-of-idents=
=20
=3D expression" to be a single syntactic unit that meant "auto&& __e =3D=20
expression, ident0 =3D std::get<0>(__e), ident1 =3D std::get<1>(__e), ...".=
=20
There would be some difficulty in specifying how std::get was looked up;=
=20
but we have already solved that problem for ranged for-loop syntax (which=
=20
relies on std::begin and std::end), so we'd solve it the same way.
Notice that "auto" here is magic; "int x, y, z =3D getcoords();" would rema=
in=20
a compile error (due to tuple<float,float,float>'s not being convertible to=
=20
int in the initializer of z). The reason "auto" works is that "auto x, y, z=
=20
=3D ..." with no initializers for x and y would ordinarily (e.g. in C++14) =
be=20
a compile error.
(2) Passing the "multiple return values" of one function as the "multiple=
=20
arguments" to another. This is solved already in C++17:=20
http://en.cppreference.com/w/cpp/utility/functional/invoke, inherited from=
=20
Boost Fusion=20
http://www.boost.org/doc/libs/1_58_0/libs/fusion/doc/html/fusion/functional=
/invocation/functions/invoke.html
..
(3) Creating a local "parameter pack" variable, suitable for expanding into=
=20
subsequent expressions.
std::tuple<float,float,float> getcoords();
bool enemy_at(float x, float y, float z)
int main() {
auto... xyz =3D std::unpack(getcoords()); // hypothetical magical=
=20
"std::unpack" for turning a tuple into a parameter-pack
if (enemy_at(xyz...)) {
auto sum_of_coords =3D 0 +...+ xyz; // C++17 fold-expression
}
}
This requires more thought (from me, at least). It seems to want some=20
notion of functions "returning" parameter-packs, which doesn't exist at the=
=20
moment.
Anyway, I see no reason to start introducing square brackets and stuff into=
=20
what ideally would be a straightforward and newbie-friendly syntax feature.
=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 http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.
------=_Part_7507_1254118138.1432839620267
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">On Wednesday, May 27, 2015 at 8:23:16 AM UTC-7, Matthew Wo=
ehlke wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-lef=
t: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">On 2015-05-27 03:4=
3, Nicol Bolas wrote:
<br>> On Tuesday, May 26, 2015 at 10:53:05 PM UTC-4, Matthew Fioravante =
wrote:
<br>>> On Tuesday, May 26, 2015 at 9:23:50 PM UTC-4, Nicol Bolas wrot=
e:
<br>>>> Nor does it force you to package parameters into a tuple.
<br>>>
<br>>> But it does, at least at the syntax level
<br>>>
<br>>> def foo():
<br>>> return (1, 2, 3);
<br>>>
<br>>> (x, y, z) =3D foo();
<br>
<br>Actually it doesn't:
<br>
<br> >>> def foo():
<br> >>> return 1, 2
<br> >>> a, b =3D foo()
<br>
<br>...but the return is a 'tuple' nevertheless:
<br>
<br> >>> type(foo())
<br> <type 'tuple'>
<br>
<br>(Basically, the ()'s are optional, and implied if absent.)
<br>
<br>My knowledge of Lua is limited ("effectively nonexistent" is probably
<br>more accurate). Python, however, only supports single return values. It
<br>just has syntax sugar for returning tuples and unpacking tuples.
<br>
<br>[...]<br>In Python, "return x, y" is syntactic sugar for "return (x, y)=
".<br></blockquote><div><br></div><div>I'm glad someone finally pointed tha=
t out! This thread has been relatively full of misconceptions about n=
on-C++ languages. I even saw somebody claiming that Python doesn't <i>have<=
/i> tuples. :P</div><div>https://docs.python.org/2/tutorial/datastructures.=
html#tuples-and-sequences<br></div><div><br></div><div>FWIW, I'm strongly o=
pposed to "filling in" any holes in the lambda syntax [x](...){...} with co=
mpletely unrelated functionality [x]=3D(...).</div><div>(And yes, I was ini=
tially opposed to the crazy lambda syntax "filling in" holes in the array-i=
ndexing syntax. This is the line-noise-must-compile philosophy of Perl: "a[=
i] works, i[a] works, now let's make [a]{i;} do something too!")</div><div>=
<br></div><div>However, let's go back to analyzing use-cases. I hear three =
coming up over and over:</div><div><br></div><div>(1) Initializing a set of=
named local variables from a tuple, without using std::tie, and ideally de=
fining those variables with 'auto'.</div><div><br></div><div> =
std::tuple<float,float,float> getcoords();</div><div> in=
t main() {</div><div> auto x, y, z =3D getcoords=
();</div><div> }</div><div><br></div><div>This syntax would wo=
rk out of the box, if you defined "auto list-of-idents =3D expression" to b=
e a single syntactic unit that meant "auto&& __e =3D expression, id=
ent0 =3D std::get<0>(__e), ident1 =3D std::get<1>(__e), ...". &=
nbsp;There would be some difficulty in specifying how std::get was looked u=
p; but we have already solved that problem for ranged for-loop syntax (whic=
h relies on std::begin and std::end), so we'd solve it the same way.</div><=
div><br></div><div>Notice that "auto" here is magic; "int x, y, z =3D getco=
ords();" would remain a compile error (due to tuple<float,float,float>=
;'s not being convertible to int in the initializer of z). The reason "auto=
" works is that "auto x, y, z =3D ..." with no initializers for x and y wou=
ld ordinarily (e.g. in C++14) be a compile error.</div><div><br></div><div>=
(2) Passing the "multiple return values" of one function as the "multiple a=
rguments" to another. This is solved already in C++17: <a href=3D"http://en=
..cppreference.com/w/cpp/utility/functional/invoke">http://en.cppreference.c=
om/w/cpp/utility/functional/invoke</a>, inherited from Boost Fusion <a href=
=3D"http://www.boost.org/doc/libs/1_58_0/libs/fusion/doc/html/fusion/functi=
onal/invocation/functions/invoke.html">http://www.boost.org/doc/libs/1_58_0=
/libs/fusion/doc/html/fusion/functional/invocation/functions/invoke.html</a=
>.</div><div><br></div><div>(3) Creating a local "parameter pack" variable,=
suitable for expanding into subsequent expressions.</div><div><br></div><d=
iv><div> std::tuple<float,float,float> getcoords();</div=
><div> bool enemy_at(float x, float y, float z)</div><div>&nbs=
p; int main() {</div><div> auto... xyz =
=3D std::unpack(getcoords()); // hypothetical magical "std::unpack" f=
or turning a tuple into a parameter-pack</div><div> &nb=
sp; if (enemy_at(xyz...)) {</div><div> &n=
bsp; auto sum_of_coords =3D 0 +...+ xyz; // C++17 fold-expression</di=
v><div> }</div><div> }<br></div></d=
iv><div><br></div><div>This requires more thought (from me, at least). &nbs=
p;It seems to want some notion of functions "returning" parameter-packs, wh=
ich doesn't exist at the moment.<br></div><div><br></div><div>Anyway, I see=
no reason to start introducing square brackets and stuff into what ideally=
would be a straightforward and newbie-friendly syntax feature.</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"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />
------=_Part_7507_1254118138.1432839620267--
------=_Part_7506_2119063727.1432839620267--
.
Author: Nicol Bolas <jmckesson@gmail.com>
Date: Thu, 28 May 2015 12:11:26 -0700 (PDT)
Raw View
------=_Part_2266_2009098051.1432840287106
Content-Type: multipart/alternative;
boundary="----=_Part_2267_1699274188.1432840287117"
------=_Part_2267_1699274188.1432840287117
Content-Type: text/plain; charset=UTF-8
On Thursday, May 28, 2015 at 12:14:01 PM UTC-4, Matthew Woehlke wrote:
>
> On 2015-05-27 18:05, Nicol Bolas wrote:
> > On Wednesday, May 27, 2015 at 4:42:24 PM UTC-4, Matthew Woehlke wrote:
> >> If we define "value sequence" as some tuple-like-but-not-tuple
> >> "object" for which this sort of in-place construction is allowed,
> >> then I don't see why this needs to be tightly coupled to
> >> unpacking.
> >
> > This is the thing you don't seem to fully understand.
> >
> > I do not *want* a "value sequence" to be *any* kind of C++ object. It
> > should not be a type with a value.
>
> I think I do understand. It's just that I strongly disagree.
>
> At some point, there *has* to be an object representing a value
> sequence. Even if it's not a "C++ object", the compiler needs some sort
> of internal notion that it has so many values and they are stored in
> such-and-such manner.
>
Yes, if the compiler is generating an AST from parsing C++, then it must
have some AST construct that represents a multiple return value return
statement.
So what? If it is not a "C++ object", then it is not an "object" in any way
that matters to the standard. Any such "object" is merely an implementation
detail, *not* something the standard has to deal with. It does not work in
the way that a "C++ object" works.
So there does not "have to be" any object associated with a value sequence.
If it has this, I fail to see why there is a problem giving that
> construct a C++ name such that one can write get<N> against the object.
>
Because then it would have to be an *object*, which would have to work in
accord with the rules for objects. I'm using the term "object" as used in
the standard. Objects have types. Objects have values. Objects have
storage. Objects have all kinds of things.
Template parameter packs are not objects. They do not have a type. They do
not have a value. They do not have memory storage. They do not need any of
these things.
Why does a value sequence *need* a type? If you want to assign them a type,
if you want to make them an object, stick them in a `tuple`; I've already
shown how.
But why does it *by default* need to be shoved into some object?
> > Remember: template parameter packs are not objects either. You
> > can't copy them, move them, reference them, or use them in anything
> other
> > than a parameter pack expression.
>
> Template parameter packs *also* are not real C++ entities. They are
> template meta-programming entities that are much more closely related to
> template type names. Substitution occurs at compile time, at instantiation.
>
Template metaprogramming is C++. Thus, "meta-programming entities" are by
definition C++ entities.
What they are not is C++ objects.
> This is not the case with return values, multiple or otherwise. For one,
> the types are not templated (or it they are, that is an orthogonal
> process).
>
.... what does it matter if it's not in a tempate? The types of the members
of the sequence are all known.
> Similarly, braced-init-lists are not
> > elements of an expression; the construct `{4.3, "foo"}` is not a legal
> > expression.
>
> You're confusing the issue. That's *not* valid without context, no, but
> we're not talking about a context-free case. And '{1, 2}' *is* valid; on
> its own, it is a std::initializer_list<int>.
>
No, it is not. The standard is very clear on this. It only *becomes* a
std::initializer_list in a context in which that transformation is a
possibility. Auto/template type deduction is such a context, as is
initialization via constructor. In aggregate initialization, `{1, 2}` is
not a std::initializer_list of any sort. It is instead a group of
constructs used for aggregate initialization.
After all:
int a[4] = {1, 2, 3, 4};
int b[4];
b = {1, 2, 3, 4};
`a` is legal; `b` is not. If `{1, 2, 3, 4}` genuinely was a value of
`std::initializer_list<int>` type, then the standard would have no room to
say that `a` is legal and `b` is not. Not without a bunch of special case
rules that say, "if the object is not a initializer_list, then do this..."
This is precisely why braced-init-lists are not types or expressions.
> > Value sequences should be like those.
>
> They won't be. A brace expression such as the above is *always* a brace
> expression.
There is no such thing as a "brace expression". The standard is *very clear*
about this: it is not an expression.
Please use the proper terminology for standardized constructs, not the way
you think they work.
>> Can you actually implement your MRV concept? Seems like it has most of
> >> the same issues...
> >
> > That's a fair question, but I fail to see the implementation problems.
> > Certainly, they're nothing like those for defining and implementing
> elision
> > out of some type.
>
> That is *exactly* a problem. In your proposal, you expect this:
>
> std::vector<int> a = {1, 2, 3};
> std::string b = "foo";
> return [a; b];
>
> ...to deduce that the 'a' and 'b' objects should NOT be constructed on
> the stack, but rather in some manner that allows RVO.
>
> I fail to see why it should be any more difficult to do this if the MRV
> is some new "object type".
>
.... OK, I see your point. Assuming that the type's construction is handled
purely in compiler logic, that's reasonable.
> Right now, as I understand it, output values at the compiled code level
> are
> > returned as either registers (for small objects), or the caller provides
> a
> > piece of stack space to store the returned object (for larger objects).
>
> So what's the problem giving std::value_sequence this behavior?
>
> It seems to me that std::value_sequence can be treated as a struct with
> members equal to the set of return values *that are not constructed by
> the caller*. The caller provides this storage as it would for e.g. a
> std::tuple. The callee constructs the "members" of this in place in the
> usual manner of RVO. No ABI change is needed.
>
Well, the ABI now has to include the "std::value_sequence" type, which
again is a "magic type", not a normal type. I admittedly know very little
about ABIs, so I have no idea how any particular "magic type" of this sort
would be handled at the ABI level. But it would depend on how much "magic"
is in this magic type.
That being said, and given that I don't know much about ABIs, I don't
really understand why MRVs would be problematic for ABIs. Or more to the
point, how the solution of returning a "magic value" would differ from the
MRV solution. In both cases, the compiler needs to know how much space to
allocate, which will be based on some aggregation of the types involved. In
both cases, the compiler and it's ABI will have to define that aggregation,
whether it's in the "magic type" (and therefore, the ABI will have to
define the ordering of the items in the type as well as their layout) or
purely internally (with the ABI defining the offsets/alignment for each
type in the returned data).
std::initializer_list poses the same ABI "change", in the sense that the
ABI has to explain what std::initializer_list looks like internally.
Otherwise, one compiler could not compile code that's ABI compatible with
another, if someone tries to pass an `initializer_list` across ABI
boundaries.
>> I don't see why we need to get so worked up about it.
> >
> > Because syntax is rare and precious, it is not cheap. And valuable
> syntax
> > should not be created just because it makes the lives of generic
> > programmers who work with tuples easier.
>
> I *don't* work with tuples. The *reason* I don't work with tuples is
> because they are a pain, exactly *because* we don't have syntax to make
> them easier.
>
And that brings up yet another reason not to regularize tuple usage by
giving them special syntax: tuples are not *good*.
The nice thing about a struct is that its members are named. This means
that every member has some semantic information associated with it.
When you have something like map::insert that returns a pair, you lose any
semantic information. What does the boolean value mean? A nice name like
"did_insert" would be handy to have. But a `pair` can't do that; it'd have
to have returned a proper struct.
Similarly, when using your preferred example of iterating through a `map`,
you have to know that the key comes first. Sure, that's obvious to those
who are used to the type, but if a function were just handed a std::pair,
and had no idea where it came from, how do you know how to use it? By all
rights, std::map should have used a struct type with real members, not a
generic `pair`, since any function that takes it will have to know what the
members mean.
Tuples are not a construct that should see *frequent* use. Not just because
there's no easy syntax for working with them, but because frequent use of
them destroys semantic information.
That's not to say that they aren't useful. But we shouldn't enshrine them
just because dynamically typed languages like the construct.
Nor is unpacking limited to tuples. Aside from the range-based for
> example (which, btw, I consider as a "critical" use case for any form of
> unpacking and/or MRV),
We can't change the past. If C++ had MRVs from day 1, std::map's iterator
would not return a `pair`. For `map`, "pair" would merely be an
implementation detail; anytime we see a "pair" in a return value, that's
nothing more than a syntactic necessity due to lacking MRVs.
We shouldn't make features the wrong way just to support an API that's was
poorly designed for the new paradigm. We should support having a proper API
that works with the new method. So `map` would simply have a `mrv_range`
member functions that returns an MRV-style range.
It should also be noted that your magical type syntax doesn't support this,
while MRV does:
auto x = Typename{FuncThatReturnsMultipleValues()};
This function's return values can be used to initialize a variable who's
type is determined by the caller. A `value_sequence` return type could only
be able to do so if `Typename` *specifically* allowed it.
I would consider this, and indeed any sort of chaining of this kind, to be
a prime use case for MRVs. It would be just as common if not substantially
moreso than iterating through a `std::map`.
I imagine that next, you're going to say that, since `value_sequence` is a
magic type, we can just make this syntax magically work somehow. At which
point, you're basically just taking a sledgehammer to the C++
specification, breaking it wherever you have to in order to make the syntax
work with an object. You're saying that objects mostly work like X, except
when magic objects are used which instead work like Y.
And that is one of the main reasons why braced-init-lists are *not objects*.
Because to make their syntax work where it currently does, yet still
requiring them to follow normal object rules, would require so many special
cases that it'd be basically impossible to specify it in the language.
unpacking has potential value for any
> sequence-like structure. Think about arrays, points, ranges,
> dimensions... all could potentially use unpacking.
>
I cannot recall a single instance where I've had the desire to "unpack"
members of an array, point, or arbitrary ranges into a function call or
anything of the like. And even if I did, I would consider it to be an
outlier case, for which specialized syntax would not be needed.
With MRVs, it could just be a `std::unpack` function, that could work on
anything (either through reflection or through user-defined specialization).
Python obviously felt that *generalized* unpacking is sufficiently
> valuable that it is not only a language feature, but one that uses
> almost *no* syntax.
>
Lua obviously felt that value sequences were sufficiently valuable that
they are not only a language feature, but one that uses almost *no* syntax.
I can play the "some other language does it" game too. That fact alone is
not a justification for C++ to do it. You could try to claim that Python is
better because it's more widely used. I could counter that by claiming that
Lua is better because it's more efficient (value sequences in Lua are just
values on its stack. Thus, they require zero memory allocation, unlike
Python tuple packing/unpacking).
--
---
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 http://groups.google.com/a/isocpp.org/group/std-proposals/.
------=_Part_2267_1699274188.1432840287117
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">On Thursday, May 28, 2015 at 12:14:01 PM UTC-4, Matthew Wo=
ehlke wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-lef=
t: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">On 2015-05-27 18:0=
5, Nicol Bolas wrote:
<br>> On Wednesday, May 27, 2015 at 4:42:24 PM UTC-4, Matthew Woehlke wr=
ote:
<br>>> If we define "value sequence" as some tuple-like-but-not-tuple
<br>>> "object" for which this sort of in-place construction is allow=
ed,
<br>>> then I don't see why this needs to be tightly coupled to
<br>>> unpacking.
<br>>=20
<br>> This is the thing you don't seem to fully understand.
<br>>=20
<br>> I do not *want* a "value sequence" to be *any* kind of C++ object.=
It=20
<br>> should not be a type with a value.
<br>
<br>I think I do understand. It's just that I strongly disagree.
<br>
<br>At some point, there *has* to be an object representing a value
<br>sequence. Even if it's not a "C++ object", the compiler needs some sort
<br>of internal notion that it has so many values and they are stored in
<br>such-and-such manner.
<br></blockquote><div><br>Yes, if the compiler is generating an AST from pa=
rsing C++, then it must have some AST construct that represents a multiple =
return value return statement.<br><br>So what? If it is not a "C++ object",=
then it is not an "object" in any way that matters to the standard. Any su=
ch "object" is merely an implementation detail, <i>not</i> something the st=
andard has to deal with. It does not work in the way that a "C++ object" wo=
rks.<br><br>So there does not "have to be" any object associated with a val=
ue sequence.<br><br></div><blockquote class=3D"gmail_quote" style=3D"margin=
: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">
If it has this, I fail to see why there is a problem giving that
<br>construct a C++ name such that one can write get<N> against the o=
bject.<br></blockquote><div><br>Because then it would have to be an <i>obje=
ct</i>, which would have to work in accord with the rules for objects. I'm =
using the term "object" as used in the standard. Objects have types. Object=
s have values. Objects have storage. Objects have all kinds of things.<br><=
br>Template parameter packs are not objects. They do not have a type. They =
do not have a value. They do not have memory storage. They do not need any =
of these things.<br><br>Why does a value sequence <i>need</i> a type? If yo=
u want to assign them a type, if you want to make them an object, stick the=
m in a `tuple`; I've already shown how.<br><br>But why does it <i>by defaul=
t</i> need to be shoved into some object?<br></div><div> </div><blockq=
uote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-lef=
t: 1px #ccc solid;padding-left: 1ex;">> Remember: template parameter pac=
ks are not objects either. You=20
<br>> can't copy them, move them, reference them, or use them in anythin=
g other=20
<br>> than a parameter pack expression.
<br>
<br>Template parameter packs *also* are not real C++ entities. They are
<br>template meta-programming entities that are much more closely related t=
o
<br>template type names. Substitution occurs at compile time, at instantiat=
ion.<br></blockquote><div><br>Template metaprogramming is C++. Thus, "meta-=
programming entities" are by definition C++ entities.<br><br>What they are =
not is C++ objects.<br> </div><blockquote class=3D"gmail_quote" style=
=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: =
1ex;">
This is not the case with return values, multiple or otherwise. For one,
<br>the types are not templated (or it they are, that is an orthogonal proc=
ess).<br></blockquote><div><br>... what does it matter if it's not in a tem=
pate? The types of the members of the sequence are all known.<br><br></div>=
<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;bor=
der-left: 1px #ccc solid;padding-left: 1ex;">
> Similarly, braced-init-lists are not=20
<br>> elements of an expression; the construct `{4.3, "foo"}` is not a l=
egal=20
<br>> expression.
<br>
<br>You're confusing the issue. That's *not* valid without context, no, but
<br>we're not talking about a context-free case. And '{1, 2}' *is* valid; o=
n
<br>its own, it is a std::initializer_list<int>.
<br></blockquote><div><br>No, it is not. The standard is very clear on this=
.. It only <i>becomes</i> a std::initializer_list in a context in which that=
transformation is a possibility. Auto/template type deduction is such a co=
ntext, as is initialization via constructor. In aggregate initialization, `=
{1, 2}` is not a std::initializer_list of any sort. It is instead a group o=
f constructs used for aggregate initialization.<br><br>After all:<br><br><d=
iv class=3D"prettyprint" style=3D"background-color: rgb(250, 250, 250); bor=
der-color: rgb(187, 187, 187); border-style: solid; border-width: 1px; word=
-wrap: break-word;"><code class=3D"prettyprint"><div class=3D"subprettyprin=
t"><span style=3D"color: #008;" class=3D"styled-by-prettify">int</span><spa=
n style=3D"color: #000;" class=3D"styled-by-prettify"> a</span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">[</span><span style=3D"color=
: #066;" class=3D"styled-by-prettify">4</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-pretti=
fy"> </span><span style=3D"color: #660;" class=3D"styled-by-prettify">{</sp=
an><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: #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"styl=
ed-by-prettify"> </span><span style=3D"color: #066;" class=3D"styled-by-pre=
ttify">3</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: #066;" class=3D"styled-by-prettify">4</span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">};</span><span style=3D"colo=
r: #000;" class=3D"styled-by-prettify"><br></span><span style=3D"color: #00=
8;" class=3D"styled-by-prettify">int</span><span style=3D"color: #000;" cla=
ss=3D"styled-by-prettify"> b</span><span style=3D"color: #660;" class=3D"st=
yled-by-prettify">[</span><span style=3D"color: #066;" class=3D"styled-by-p=
rettify">4</span><span style=3D"color: #660;" class=3D"styled-by-prettify">=
];</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br>b </=
span><span style=3D"color: #660;" class=3D"styled-by-prettify">=3D</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">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">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: #066;" class=3D"styled-by-prettify">3</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: #066=
;" class=3D"styled-by-prettify">4</span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">};</span><span style=3D"color: #000;" class=3D"styl=
ed-by-prettify"><br></span></div></code></div><br>`a` is legal; `b` is not.=
If `{1, 2, 3, 4}` genuinely was a value of `std::initializer_list<int&g=
t;` type, then the standard would have no room to say that `a` is legal and=
`b` is not. Not without a bunch of special case rules that say, "if the ob=
ject is not a initializer_list, then do this..."<br><br>This is precisely w=
hy braced-init-lists are not types or expressions.<br> </div><blockquo=
te class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-left:=
1px #ccc solid;padding-left: 1ex;">
> Value sequences should be like those.
<br>
<br>They won't be. A brace expression such as the above is *always* a brace
<br>expression.</blockquote><div><br>There is no such thing as a "brace exp=
ression". The standard is <i>very clear</i> about this: it is not an expres=
sion.<br><br>Please use the proper terminology for standardized constructs,=
not the way you think they work.<br><br></div><blockquote class=3D"gmail_q=
uote" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;pad=
ding-left: 1ex;">>> Can you actually implement your MRV concept? Seem=
s like it has most of=20
<br>>> the same issues...
<br>>=20
<br>> That's a fair question, but I fail to see the implementation probl=
ems.=20
<br>> Certainly, they're nothing like those for defining and implementin=
g elision=20
<br>> out of some type.
<br>
<br>That is *exactly* a problem. In your proposal, you expect this:
<br>
<br> std::vector<int> a =3D {1, 2, 3};
<br> std::string b =3D "foo";
<br> return [a; b];
<br>
<br>...to deduce that the 'a' and 'b' objects should NOT be constructed on
<br>the stack, but rather in some manner that allows RVO.
<br>
<br>I fail to see why it should be any more difficult to do this if the MRV
<br>is some new "object type".<br></blockquote><div><br>... OK, I see your =
point. Assuming that the type's construction is handled purely in compiler =
logic, that's reasonable.<br><br></div><blockquote class=3D"gmail_quote" st=
yle=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-lef=
t: 1ex;">
> Right now, as I understand it, output values at the compiled code leve=
l are=20
<br>> returned as either registers (for small objects), or the caller pr=
ovides a=20
<br>> piece of stack space to store the returned object (for larger obje=
cts).
<br>
<br>So what's the problem giving std::value_sequence this behavior?
<br>
<br>It seems to me that std::value_sequence can be treated as a struct with
<br>members equal to the set of return values *that are not constructed by
<br>the caller*. The caller provides this storage as it would for e.g. a
<br>std::tuple. The callee constructs the "members" of this in place in the
<br>usual manner of RVO. No ABI change is needed.<br></blockquote><div><br>=
Well, the ABI now has to include the "std::value_sequence" type, which agai=
n is a "magic type", not a normal type. I admittedly know very little about=
ABIs, so I have no idea how any particular "magic type" of this sort would=
be handled at the ABI level. But it would depend on how much "magic" is in=
this magic type.<br><br>That being said, and given that I don't know much =
about ABIs, I don't really understand why MRVs would be problematic for ABI=
s. Or more to the point, how the solution of returning a "magic value" woul=
d differ from the MRV solution. In both cases, the compiler needs to know h=
ow much space to allocate, which will be based on some aggregation of the t=
ypes involved. In both cases, the compiler and it's ABI will have to define=
that aggregation, whether it's in the "magic type" (and therefore, the ABI=
will have to define the ordering of the items in the type as well as their=
layout) or purely internally (with the ABI defining the offsets/alignment =
for each type in the returned data).<br><br>std::initializer_list poses the=
same ABI "change", in the sense that the ABI has to explain what std::init=
ializer_list looks like internally. Otherwise, one compiler could not compi=
le code that's ABI compatible with another, if someone tries to pass an `in=
itializer_list` across ABI boundaries.<br><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;">
>> I don't see why we need to get so worked up about it.
<br>>=20
<br>> Because syntax is rare and precious, it is not cheap. And valuable=
syntax=20
<br>> should not be created just because it makes the lives of generic=
=20
<br>> programmers who work with tuples easier.
<br>
<br>I *don't* work with tuples. The *reason* I don't work with tuples is
<br>because they are a pain, exactly *because* we don't have syntax to make
<br>them easier.<br></blockquote><div><br>And that brings up yet another re=
ason not to regularize tuple usage by giving them special syntax: tuples ar=
e not <i>good</i>.<br><br>The nice thing about a struct is that its members=
are named. This means that every member has some semantic information asso=
ciated with it.<br><br>When you have something like map::insert that return=
s a pair, you lose any semantic information. What does the boolean value me=
an? A nice name like "did_insert" would be handy to have. But a `pair` can'=
t do that; it'd have to have returned a proper struct.<br><br>Similarly, wh=
en using your preferred example of iterating through a `map`, you have to k=
now that the key comes first. Sure, that's obvious to those who are used to=
the type, but if a function were just handed a std::pair, and had no idea =
where it came from, how do you know how to use it? By all rights, std::map =
should have used a struct type with real members, not a generic `pair`, sin=
ce any function that takes it will have to know what the members mean.<br><=
br>Tuples are not a construct that should see <i>frequent</i> use. Not just=
because there's no easy syntax for working with them, but because frequent=
use of them destroys semantic information.<br><br>That's not to say that t=
hey aren't useful. But we shouldn't enshrine them just because dynamically =
typed languages like the construct.<br><br></div><blockquote class=3D"gmail=
_quote" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;p=
adding-left: 1ex;">Nor is unpacking limited to tuples. Aside from the range=
-based for
<br>example (which, btw, I consider as a "critical" use case for any form o=
f
<br>unpacking and/or MRV),</blockquote><div><br>We can't change the past. I=
f C++ had MRVs from day 1, std::map's iterator would not return a `pair`. F=
or `map`, "pair" would merely be an implementation detail; anytime we see a=
"pair" in a return value, that's nothing more than a syntactic necessity d=
ue to lacking MRVs.<br><br>We shouldn't make features the wrong way just to=
support an API that's was poorly designed for the new paradigm. We should =
support having a proper API that works with the new method. So `map` would =
simply have a `mrv_range` member functions that returns an MRV-style range.=
<br><br>It should also be noted that your magical type syntax doesn't suppo=
rt this, while MRV does:<br><br><div class=3D"prettyprint" style=3D"backgro=
und-color: rgb(250, 250, 250); border-color: rgb(187, 187, 187); border-sty=
le: solid; border-width: 1px; word-wrap: break-word;"><code class=3D"pretty=
print"><div class=3D"subprettyprint"><span style=3D"color: #008;" class=3D"=
styled-by-prettify">auto</span><span style=3D"color: #000;" class=3D"styled=
-by-prettify"> x </span><span style=3D"color: #660;" class=3D"styled-by-pre=
ttify">=3D</span><span style=3D"color: #000;" class=3D"styled-by-prettify">=
</span><span style=3D"color: #606;" class=3D"styled-by-prettify">Typename<=
/span><span style=3D"color: #660;" class=3D"styled-by-prettify">{</span><sp=
an style=3D"color: #606;" class=3D"styled-by-prettify">FuncThatReturnsMulti=
pleValues</span><span style=3D"color: #660;" class=3D"styled-by-prettify">(=
)};</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br></s=
pan></div></code></div><br>This function's return values can be used to ini=
tialize a variable who's
type is determined by the caller. A `value_sequence` return type could=20
only be able to do so if `Typename` <i>specifically</i> allowed it.<br><br>=
I would consider this, and indeed any sort of chaining of this kind, to be =
a prime use case for MRVs. It would be just as common if not substantially =
moreso than iterating through a `std::map`.<br><br>I imagine that next, you=
're going to say that, since `value_sequence` is a magic type, we can just =
make this syntax magically work somehow. At which point, you're basically j=
ust taking a sledgehammer to the C++ specification, breaking it wherever yo=
u have to in order to make the syntax work with an object. You're saying th=
at objects mostly work like X, except when magic objects are used which ins=
tead work like Y.<br><br>And that is one of the main reasons why braced-ini=
t-lists are <i>not objects</i>. Because to make their syntax work where it =
currently does, yet still requiring them to follow normal object rules, wou=
ld require so many special cases that it'd be basically impossible to speci=
fy it in the language.<br><br></div><blockquote class=3D"gmail_quote" style=
=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: =
1ex;"> unpacking has potential value for any
<br>sequence-like structure. Think about arrays, points, ranges,
<br>dimensions... all could potentially use unpacking.<br></blockquote><div=
><br>I cannot recall a single instance where I've had the desire to "unpack=
" members of an array, point, or arbitrary ranges into a function call or a=
nything of the like. And even if I did, I would consider it to be an outlie=
r case, for which specialized syntax would not be needed.<br><br>With MRVs,=
it could just be a `std::unpack` function, that could work on anything (ei=
ther through reflection or through user-defined specialization).<br><br></d=
iv><blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;=
border-left: 1px #ccc solid;padding-left: 1ex;">
Python obviously felt that *generalized* unpacking is sufficiently
<br>valuable that it is not only a language feature, but one that uses
<br>almost *no* syntax.<br></blockquote><div><br>Lua obviously felt that va=
lue sequences were sufficiently valuable that they are not only a language =
feature, but one that uses almost *no* syntax.<br><br>I can play the "some =
other language does it" game too. That fact alone is not a justification fo=
r C++ to do it. You could try to claim that Python is better because it's m=
ore widely used. I could counter that by claiming that Lua is better becaus=
e it's more efficient (value sequences in Lua are just values on its stack.=
Thus, they require zero memory allocation, unlike Python tuple packing/unp=
acking).<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"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />
------=_Part_2267_1699274188.1432840287117--
------=_Part_2266_2009098051.1432840287106--
.
Author: Nicol Bolas <jmckesson@gmail.com>
Date: Thu, 28 May 2015 12:23:33 -0700 (PDT)
Raw View
------=_Part_934_1005645895.1432841013537
Content-Type: multipart/alternative;
boundary="----=_Part_935_1194255375.1432841013537"
------=_Part_935_1194255375.1432841013537
Content-Type: text/plain; charset=UTF-8
On Thursday, May 28, 2015 at 3:00:20 PM UTC-4, Arthur O'Dwyer wrote:
>
> On Wednesday, May 27, 2015 at 8:23:16 AM UTC-7, Matthew Woehlke wrote:
>>
>> On 2015-05-27 03:43, Nicol Bolas wrote:
>> > On Tuesday, May 26, 2015 at 10:53:05 PM UTC-4, Matthew Fioravante
>> wrote:
>> >> On Tuesday, May 26, 2015 at 9:23:50 PM UTC-4, Nicol Bolas wrote:
>> >>> Nor does it force you to package parameters into a tuple.
>> >>
>> >> But it does, at least at the syntax level
>> >>
>> >> def foo():
>> >> return (1, 2, 3);
>> >>
>> >> (x, y, z) = foo();
>>
>> Actually it doesn't:
>>
>> >>> def foo():
>> >>> return 1, 2
>> >>> a, b = foo()
>>
>> ...but the return is a 'tuple' nevertheless:
>>
>> >>> type(foo())
>> <type 'tuple'>
>>
>> (Basically, the ()'s are optional, and implied if absent.)
>>
>> My knowledge of Lua is limited ("effectively nonexistent" is probably
>> more accurate). Python, however, only supports single return values. It
>> just has syntax sugar for returning tuples and unpacking tuples.
>>
>> [...]
>> In Python, "return x, y" is syntactic sugar for "return (x, y)".
>>
>
> I'm glad someone finally pointed that out! This thread has been
> relatively full of misconceptions about non-C++ languages. I even saw
> somebody claiming that Python doesn't *have* tuples. :P
> https://docs.python.org/2/tutorial/datastructures.html#tuples-and-sequences
>
> FWIW, I'm strongly opposed to "filling in" any holes in the lambda syntax
> [x](...){...} with completely unrelated functionality [x]=(...).
> (And yes, I was initially opposed to the crazy lambda syntax "filling in"
> holes in the array-indexing syntax. This is the line-noise-must-compile
> philosophy of Perl: "a[i] works, i[a] works, now let's make [a]{i;} do
> something too!")
>
> However, let's go back to analyzing use-cases. I hear three coming up over
> and over:
>
> (1) Initializing a set of named local variables from a tuple, without
> using std::tie, and ideally defining those variables with 'auto'.
>
> std::tuple<float,float,float> getcoords();
> int main() {
> auto x, y, z = getcoords();
> }
>
> This syntax would work out of the box, if you defined "auto list-of-idents
> = expression" to be a single syntactic unit that meant "auto&& __e =
> expression, ident0 = std::get<0>(__e), ident1 = std::get<1>(__e), ...".
> There would be some difficulty in specifying how std::get was looked up;
> but we have already solved that problem for ranged for-loop syntax (which
> relies on std::begin and std::end), so we'd solve it the same way.
>
So... you want to limit this automatic unpacking just to `auto`? That's a
pretty terrible limitation. Not everyone is crazy about using `auto`
everywhere. They shouldn't have to do 10x the syntactic work just to do
that.
It's one thing to make that syntax an *option*; it's quite another to say
that it's the only possible way to automatically unpack a tuple or use MRVs.
> (2) Passing the "multiple return values" of one function as the "multiple
> arguments" to another. This is solved already in C++17:
> http://en.cppreference.com/w/cpp/utility/functional/invoke, inherited
> from Boost Fusion
> http://www.boost.org/doc/libs/1_58_0/libs/fusion/doc/html/fusion/functional/invocation/functions/invoke.html
> .
>
So.. if you have a `tuple`... how do you use `invoke` on it?
`fusion::invoke` takes a FUsion sequence; `std::invoke` just takes
parameters, not a `tuple` or anything else that's remotely sequence-like.
Equally importantly, it's not nearly as simple as real MRVs. Nor is it as
composable:
some_func(func1(), func2());
If `some_func` takes three values, func1 could return 1 value with func2
returning 2. Or vice-versa. That is much more "straightforward and
newbie-friendly syntax" than any form of `invoke`.
Not that even `fusion::invoke` could handle the above.
--
---
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 http://groups.google.com/a/isocpp.org/group/std-proposals/.
------=_Part_935_1194255375.1432841013537
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><br><br>On Thursday, May 28, 2015 at 3:00:20 PM UTC-4, Art=
hur O'Dwyer wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;marg=
in-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"=
ltr">On Wednesday, May 27, 2015 at 8:23:16 AM UTC-7, Matthew Woehlke wrote:=
<blockquote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;borde=
r-left:1px #ccc solid;padding-left:1ex">On 2015-05-27 03:43, Nicol Bolas wr=
ote:
<br>> On Tuesday, May 26, 2015 at 10:53:05 PM UTC-4, Matthew Fioravante =
wrote:
<br>>> On Tuesday, May 26, 2015 at 9:23:50 PM UTC-4, Nicol Bolas wrot=
e:
<br>>>> Nor does it force you to package parameters into a tuple.
<br>>>
<br>>> But it does, at least at the syntax level
<br>>>
<br>>> def foo():
<br>>> return (1, 2, 3);
<br>>>
<br>>> (x, y, z) =3D foo();
<br>
<br>Actually it doesn't:
<br>
<br> >>> def foo():
<br> >>> return 1, 2
<br> >>> a, b =3D foo()
<br>
<br>...but the return is a 'tuple' nevertheless:
<br>
<br> >>> type(foo())
<br> <type 'tuple'>
<br>
<br>(Basically, the ()'s are optional, and implied if absent.)
<br>
<br>My knowledge of Lua is limited ("effectively nonexistent" is probably
<br>more accurate). Python, however, only supports single return values. It
<br>just has syntax sugar for returning tuples and unpacking tuples.
<br>
<br>[...]<br>In Python, "return x, y" is syntactic sugar for "return (x, y)=
".<br></blockquote><div><br></div><div>I'm glad someone finally pointed tha=
t out! This thread has been relatively full of misconceptions about n=
on-C++ languages. I even saw somebody claiming that Python doesn't <i>have<=
/i> tuples. :P</div><div><a href=3D"https://docs.python.org/2/tutorial/data=
structures.html#tuples-and-sequences" target=3D"_blank" rel=3D"nofollow" on=
mousedown=3D"this.href=3D'https://www.google.com/url?q\75https%3A%2F%2Fdocs=
..python.org%2F2%2Ftutorial%2Fdatastructures.html%23tuples-and-sequences\46s=
a\75D\46sntz\0751\46usg\75AFQjCNEhX0NlOYL5VOnZ3Y7Beinn4_Pypw';return true;"=
onclick=3D"this.href=3D'https://www.google.com/url?q\75https%3A%2F%2Fdocs.=
python.org%2F2%2Ftutorial%2Fdatastructures.html%23tuples-and-sequences\46sa=
\75D\46sntz\0751\46usg\75AFQjCNEhX0NlOYL5VOnZ3Y7Beinn4_Pypw';return true;">=
https://docs.python.org/2/<wbr>tutorial/datastructures.html#<wbr>tuples-and=
-sequences</a><br></div><div><br></div><div>FWIW, I'm strongly opposed to "=
filling in" any holes in the lambda syntax [x](...){...} with completely un=
related functionality [x]=3D(...).</div><div>(And yes, I was initially oppo=
sed to the crazy lambda syntax "filling in" holes in the array-indexing syn=
tax. This is the line-noise-must-compile philosophy of Perl: "a[i] works, i=
[a] works, now let's make [a]{i;} do something too!")</div><div><br></div><=
div>However, let's go back to analyzing use-cases. I hear three coming up o=
ver and over:</div><div><br></div><div>(1) Initializing a set of named loca=
l variables from a tuple, without using std::tie, and ideally defining thos=
e variables with 'auto'.</div><div><br></div><div> std::tuple&=
lt;float,float,float> getcoords();</div><div> int main() {<=
/div><div> auto x, y, z =3D getcoords();</div><d=
iv> }</div><div><br></div><div>This syntax would work out of t=
he box, if you defined "auto list-of-idents =3D expression" to be a single =
syntactic unit that meant "auto&& __e =3D expression, ident0 =3D st=
d::get<0>(__e), ident1 =3D std::get<1>(__e), ...". There =
would be some difficulty in specifying how std::get was looked up; but we h=
ave already solved that problem for ranged for-loop syntax (which relies on=
std::begin and std::end), so we'd solve it the same way.</div></div></bloc=
kquote><div><br>So... you want to limit this automatic unpacking just to `a=
uto`? That's a pretty terrible limitation. Not everyone is crazy about usin=
g `auto` everywhere. They shouldn't have to do 10x the syntactic work just =
to do that.<br><br>It's one thing to make that syntax an <i>option</i>; it'=
s quite another to say that it's the only possible way to automatically unp=
ack a tuple or use MRVs.<br> </div><blockquote class=3D"gmail_quote" s=
tyle=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-le=
ft: 1ex;"><div dir=3D"ltr"><div></div><div>(2) Passing the "multiple return=
values" of one function as the "multiple arguments" to another. This is so=
lved already in C++17: <a href=3D"http://en.cppreference.com/w/cpp/utility/=
functional/invoke" target=3D"_blank" rel=3D"nofollow" onmousedown=3D"this.h=
ref=3D'http://www.google.com/url?q\75http%3A%2F%2Fen.cppreference.com%2Fw%2=
Fcpp%2Futility%2Ffunctional%2Finvoke\46sa\75D\46sntz\0751\46usg\75AFQjCNG1V=
ZE_zGVGE-4dTSCHvV95lvBDJg';return true;" onclick=3D"this.href=3D'http://www=
..google.com/url?q\75http%3A%2F%2Fen.cppreference.com%2Fw%2Fcpp%2Futility%2F=
functional%2Finvoke\46sa\75D\46sntz\0751\46usg\75AFQjCNG1VZE_zGVGE-4dTSCHvV=
95lvBDJg';return true;">http://en.cppreference.com/w/<wbr>cpp/utility/funct=
ional/invoke</a>, inherited from Boost Fusion <a href=3D"http://www.boost.o=
rg/doc/libs/1_58_0/libs/fusion/doc/html/fusion/functional/invocation/functi=
ons/invoke.html" target=3D"_blank" rel=3D"nofollow" onmousedown=3D"this.hre=
f=3D'http://www.google.com/url?q\75http%3A%2F%2Fwww.boost.org%2Fdoc%2Flibs%=
2F1_58_0%2Flibs%2Ffusion%2Fdoc%2Fhtml%2Ffusion%2Ffunctional%2Finvocation%2F=
functions%2Finvoke.html\46sa\75D\46sntz\0751\46usg\75AFQjCNGy7GD_sqWr_h5Fm7=
Aydc4yATTp3Q';return true;" onclick=3D"this.href=3D'http://www.google.com/u=
rl?q\75http%3A%2F%2Fwww.boost.org%2Fdoc%2Flibs%2F1_58_0%2Flibs%2Ffusion%2Fd=
oc%2Fhtml%2Ffusion%2Ffunctional%2Finvocation%2Ffunctions%2Finvoke.html\46sa=
\75D\46sntz\0751\46usg\75AFQjCNGy7GD_sqWr_h5Fm7Aydc4yATTp3Q';return true;">=
http://www.boost.org/doc/libs/<wbr>1_58_0/libs/fusion/doc/html/<wbr>fusion/=
functional/invocation/<wbr>functions/invoke.html</a>.</div></div></blockquo=
te><div><br>So.. if you have a `tuple`... how do you use `invoke` on it? `f=
usion::invoke` takes a FUsion sequence; `std::invoke` just takes parameters=
, not a `tuple` or anything else that's remotely sequence-like.<br><br>Equa=
lly importantly, it's not nearly as simple as real MRVs. Nor is it as compo=
sable:<br><br>some_func(func1(), func2());<br><br>If `some_func` takes thre=
e values, func1 could return 1 value with func2 returning 2. Or vice-versa.=
That is much more "straightforward and newbie-friendly syntax" than any fo=
rm of `invoke`.<br><br>Not that even `fusion::invoke` could handle the abov=
e.<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"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />
------=_Part_935_1194255375.1432841013537--
------=_Part_934_1005645895.1432841013537--
.
Author: Matthew Woehlke <mw_triad@users.sourceforge.net>
Date: Thu, 28 May 2015 16:34:20 -0400
Raw View
On 2015-05-28 15:11, Nicol Bolas wrote:
> When you have something like map::insert that returns a pair, you lose any
> semantic information. What does the boolean value mean? A nice name like
> "did_insert" would be handy to have. But a `pair` can't do that; it'd have
> to have returned a proper struct.
(OT)
I still dream about one day having something that is transparently
equivalent to std::pair (meaning, we could change e.g. std::map without
SIC/BIC) but has meaningful names for the members :-).
--
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 http://groups.google.com/a/isocpp.org/group/std-proposals/.
.
Author: Matthew Woehlke <mw_triad@users.sourceforge.net>
Date: Thu, 28 May 2015 17:22:25 -0400
Raw View
(Sigh... I had a reply and TB ate it. Going to try to cover the high
points; sorry if this ends up being a bit terse.)
On 2015-05-28 15:11, Nicol Bolas wrote:
> On Thursday, May 28, 2015 at 12:14:01 PM UTC-4, Matthew Woehlke wrote:
>> On 2015-05-27 18:05, Nicol Bolas wrote:
>>> Similarly, braced-init-lists are not
>>> elements of an expression; the construct `{4.3, "foo"}` is not a legal
>>> expression. Value sequences should be like those.
>>
>> They won't be. A brace expression such as the above is *always* a brace
>> expression.
>
> There is no such thing as a "brace expression". The standard is *very clear*
> about this: it is not an expression.
Please don't language lawyer :-).
What I mean is, the symbols '{a, b}' show me that there are two items.
In no way can I, at present, "pass" those two items in a way that I lose
the immediately obvious fact that there are two items.
What I object to is:
> auto x = Typename{FuncThatReturnsMultipleValues()};
....this. Here, I have to inspect FuncThatReturnsMultipleValues to know
that it returns multiple values. I object to that. I strongly would
prefer to require some syntax to indicate unpacking, e.g. '[*]' or '...'
or whatever.
>> That is *exactly* a problem. In your proposal, you expect this:
>>
>> std::vector<int> a = {1, 2, 3};
>> std::string b = "foo";
>> return [a; b];
>>
>> ...to deduce that the 'a' and 'b' objects should NOT be constructed on
>> the stack, but rather in some manner that allows RVO.
>>
>> I fail to see why it should be any more difficult to do this if the MRV
>> is some new "object type".
>
> ... OK, I see your point. Assuming that the type's construction is handled
> purely in compiler logic, that's reasonable.
Right. (Well, I would say that there "is" no construction, at least at
the call site. Construction would be of the "member items", in-place, in
the callee.)
> Well, the ABI now has to include the "std::value_sequence" type, which
> again is a "magic type", not a normal type. I admittedly know very little
> about ABIs, so I have no idea how any particular "magic type" of this sort
> would be handled at the ABI level. But it would depend on how much "magic"
> is in this magic type.
>
> That being said, and given that I don't know much about ABIs, I don't
> really understand why MRVs would be problematic for ABIs. Or more to the
> point, how the solution of returning a "magic value" would differ from the
> MRV solution.
I don't think there is much magic, and I think we are more or less
wanting the same thing. The only real exception that I am seeing is that
unpacking and MRV's (and expansion) are orthogonal, and that an MRV has
a type.
Note: the more I think about it, the more I'm inclined to say that it is
an unnameable type, like lambdas. That is, 'auto x = mrv_func()' is
legal, but doing anything besides unpacking 'x' is not. (Potentially
even passing it via a template type.)
> In both cases, the compiler needs to know how much space to
> allocate, which will be based on some aggregation of the types involved. In
> both cases, the compiler and it's ABI will have to define that aggregation,
> whether it's in the "magic type" (and therefore, the ABI will have to
> define the ordering of the items in the type as well as their layout) or
> purely internally (with the ABI defining the offsets/alignment for each
> type in the returned data).
Right, though I don't think there is a real difference here.
Particularly if the type is unnameable, the order isn't necessarily
consistent for a given type list, but would depend on the callee. (In
neither case, AFAIK, can it vary at run-time, or by who is the caller.)
> std::initializer_list poses the same ABI "change", in the sense that the
> ABI has to explain what std::initializer_list looks like internally.
> Otherwise, one compiler could not compile code that's ABI compatible with
> another, if someone tries to pass an `initializer_list` across ABI
> boundaries.
Isn't that already the case in general? (Compiler 1's ABI is not
compatible with Compiler 2? Even for different versions of the same
vendor's compiler?)
>>> Because syntax is rare and precious, it is not cheap. And valuable
>>> syntax should not be created just because it makes the lives of
>>> generic programmers who work with tuples easier.
Incidentally, I'm not sure this is a *valid* reason. Depending on the
unpacking syntax, knowing that you are unpacking without a lot of
look-ahead might be difficult. Compiler vendors tend to not like that;
as a result, it may be that your unpacking syntax would not be any more
context sensitive than generic unpacking.
> The nice thing about a struct is that its members are named. This means
> that every member has some semantic information associated with it.
The nice thing about generic unpacking is that I can unpack the MRV's
from a function that returned them as a struct with pretty names :-).
> We shouldn't make features the wrong way just to support an API that's was
> poorly designed for the new paradigm. We should support having a proper API
> that works with the new method. So `map` would simply have a `mrv_range`
> member functions that returns an MRV-style range.
Generic unpacking would make std::map, and any user classes with similar
API, Just Work.
> It should also be noted that your magical type syntax doesn't support this,
> while MRV does:
>
> auto x = Typename{FuncThatReturnsMultipleValues()};
Per above, I object to that :-).
My "magic type" *would* work like:
auto x = Typename{[*]FuncThatReturnsMultipleValues()};
....and so would this:
auto params = make_tuple(5, 12, 42.0);
auto x = Typename{[*]params};
> I would consider this, and indeed any sort of chaining of this kind, to be
> a prime use case for MRVs. It would be just as common if not substantially
> moreso than iterating through a `std::map`.
Agreed, but I also consider parameter expansion an orthogonal problem.
And one that works with value sequences *and more*, if get<N> can be
used on a value sequence.
Oh, and, I'm pretty sure I would at some point write code like:
auto qm = QMatrix4x4{[*]m.elements};
(Yes, that's right, there are some obnoxious matrix classes that take a
list of values, but not an array of values, for initialization. Generic
expansion lets me not have to write out that junk.)
>> unpacking has potential value for any
>> sequence-like structure. Think about arrays, points, ranges,
>> dimensions... all could potentially use unpacking.
>
> I cannot recall a single instance where I've had the desire to "unpack"
> members of an array, point, or arbitrary ranges into a function call or
> anything of the like.
I can. Here's the example (slightly simplified, and with names changed)
that I know of offhand:
inline void foo(point2d const& in, double result[2])
{
// Method 1 (shorter)
[result[0]; result[1]] = foo([*]in);
// Method 2 (more generic)
std::tie([*]result) = std::tie([*](foo[*]in));
// C++98 (not generic)
const point2d p = foo(in.X, in.Y);
result[0] = p.X;
result[1] = p.Y;
}
This is in real, production code, and yes I would write it like that if
I could. (Note: I'm not sure if assignment like that actually works, but
that's only an issue because my 'point2d' is not assignable from a tuple.)
Unpacking objects (usually geometry types) into individual local
variables is not unusual for me.
--
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 http://groups.google.com/a/isocpp.org/group/std-proposals/.
.
Author: Nicol Bolas <jmckesson@gmail.com>
Date: Thu, 28 May 2015 15:51:11 -0700 (PDT)
Raw View
------=_Part_8086_1462317433.1432853471714
Content-Type: multipart/alternative;
boundary="----=_Part_8087_1366240163.1432853471714"
------=_Part_8087_1366240163.1432853471714
Content-Type: text/plain; charset=UTF-8
On Thursday, May 28, 2015 at 5:22:42 PM UTC-4, Matthew Woehlke wrote:
>
> (Sigh... I had a reply and TB ate it. Going to try to cover the high
> points; sorry if this ends up being a bit terse.)
>
> On 2015-05-28 15:11, Nicol Bolas wrote:
> > On Thursday, May 28, 2015 at 12:14:01 PM UTC-4, Matthew Woehlke wrote:
> >> On 2015-05-27 18:05, Nicol Bolas wrote:
> >>> Similarly, braced-init-lists are not
> >>> elements of an expression; the construct `{4.3, "foo"}` is not a legal
> >>> expression. Value sequences should be like those.
> >>
> >> They won't be. A brace expression such as the above is *always* a brace
> >> expression.
> >
> > There is no such thing as a "brace expression". The standard is *very
> clear*
> > about this: it is not an expression.
>
> Please don't language lawyer :-).
>
You want to modify The Standard for Programming Language C++. That requires
a degree of precision about what things are called.
> What I mean is, the symbols '{a, b}' show me that there are two items.
> In no way can I, at present, "pass" those two items in a way that I lose
> the immediately obvious fact that there are two items.
>
> What I object to is:
>
> > auto x = Typename{FuncThatReturnsMultipleValues()};
>
> ...this. Here, I have to inspect FuncThatReturnsMultipleValues to know
> that it returns multiple values. I object to that. I strongly would
> prefer to require some syntax to indicate unpacking, e.g. '[*]' or '...'
> or whatever.
>
On what basis do you object to that? You say that you have to inspect it to
know that it returns multiple values. Well... why do you care? All you care
about is what you need to; namely, that `Typename` has a constructor that
matches the return value(s) of the function you're using. Whether it's one
return value or 20, as long as there's a matching constructor, you're
syntactically fine.
Why should using `FuncThatReturnsOneValue` require less syntax than
`FuncThatReturnsMultipleValues`? Furthermore, what happens if someone
changes the return type; why should it cause this (particular) code to
break? The statement would be no less legal, so long as Typename has a
valid constructor.
I just don't see what the point of the added syntax would be. I understand
why you need template parameter pack unpacking syntax (because you're able
to distribute unpacking across an expression). But what do you gain from
having to unpack the results, rather than having the results not be packed
to begin with?
> > Well, the ABI now has to include the "std::value_sequence" type, which
> > again is a "magic type", not a normal type. I admittedly know very
> little
> > about ABIs, so I have no idea how any particular "magic type" of this
> sort
> > would be handled at the ABI level. But it would depend on how much
> "magic"
> > is in this magic type.
> >
> > That being said, and given that I don't know much about ABIs, I don't
> > really understand why MRVs would be problematic for ABIs. Or more to the
> > point, how the solution of returning a "magic value" would differ from
> the
> > MRV solution.
>
> I don't think there is much magic, and I think we are more or less
> wanting the same thing. The only real exception that I am seeing is that
> unpacking and MRV's (and expansion) are orthogonal, and that an MRV has
> a type.
>
> Note: the more I think about it, the more I'm inclined to say that it is
> an unnameable type, like lambdas. That is, 'auto x = mrv_func()' is
> legal, but doing anything besides unpacking 'x' is not. (Potentially
> even passing it via a template type.)
>
Then what's the point of being able to store it? Why make it an object at
all if the only thing it can do is be unpacked?
>
> > In both cases, the compiler needs to know how much space to
> > allocate, which will be based on some aggregation of the types involved.
> In
> > both cases, the compiler and it's ABI will have to define that
> aggregation,
> > whether it's in the "magic type" (and therefore, the ABI will have to
> > define the ordering of the items in the type as well as their layout) or
> > purely internally (with the ABI defining the offsets/alignment for each
> > type in the returned data).
>
> Right, though I don't think there is a real difference here.
> Particularly if the type is unnameable, the order isn't necessarily
> consistent for a given type list, but would depend on the callee. (In
> neither case, AFAIK, can it vary at run-time, or by who is the caller.)
>
I don't know much about ABIs, but I'm pretty sure that "consistency" is a
*very* important element of them. Otherwise, you can't have different code
that links to each other.
If the caller doesn't know that the first item in the typelist is actually
the first in the data structure, how can the caller access it to unpack it?
The whole point of an ABI is for both the caller and callee to know what's
going on in an interface.
> >>> Because syntax is rare and precious, it is not cheap. And valuable
> >>> syntax should not be created just because it makes the lives of
> >>> generic programmers who work with tuples easier.
>
> Incidentally, I'm not sure this is a *valid* reason. Depending on the
> unpacking syntax, knowing that you are unpacking without a lot of
> look-ahead might be difficult. Compiler vendors tend to not like that;
> as a result, it may be that your unpacking syntax would not be any more
> context sensitive than generic unpacking.
>
Um, I'm not talking about "unpacking syntax." Or rather, more to the point,
I don't *want* "unpacking syntax". Or packing syntax.
I want MRV syntax. Packing and unpacking would not be syntax; they'd just
be function calls.
Agreed, but I also consider parameter expansion an orthogonal problem.
>
That's because you're focused on syntax for packing and unpacking tuples.
If you simply have MRVs as a first-class feature rather than an unpacking
hack, then packing and unpacking is nothing more than a function call.
> >> unpacking has potential value for any
> >> sequence-like structure. Think about arrays, points, ranges,
> >> dimensions... all could potentially use unpacking.
> >
> > I cannot recall a single instance where I've had the desire to "unpack"
> > members of an array, point, or arbitrary ranges into a function call or
> > anything of the like.
>
> I can. Here's the example (slightly simplified, and with names changed)
> that I know of offhand:
>
> inline void foo(point2d const& in, double result[2])
> {
> // Method 1 (shorter)
> [result[0]; result[1]] = foo([*]in);
>
> // Method 2 (more generic)
> std::tie([*]result) = std::tie([*](foo[*]in));
>
> // C++98 (not generic)
> const point2d p = foo(in.X, in.Y);
> result[0] = p.X;
> result[1] = p.Y;
> }
>
> This is in real, production code, and yes I would write it like that if
> I could. (Note: I'm not sure if assignment like that actually works, but
> that's only an issue because my 'point2d' is not assignable from a tuple.)
>
> Unpacking objects (usually geometry types) into individual local
> variables is not unusual for me.
>
So your use case for this syntax is translating values of structs between
different APIs? Isn't that something that should happen at the leaf parts
of your code, with the internals of your code actually handling things in a
consistent way?
In your example above, a user who wants the result as a `double[2]` should
call `foo` like this:
double result[2];
to_double2(foo(data), result);
That way, you don't have to write 20 different variations of `foo`.
--
---
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 http://groups.google.com/a/isocpp.org/group/std-proposals/.
------=_Part_8087_1366240163.1432853471714
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">On Thursday, May 28, 2015 at 5:22:42 PM UTC-4, Matthew Woe=
hlke wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left=
: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">(Sigh... I had a re=
ply and TB ate it. Going to try to cover the high
<br>points; sorry if this ends up being a bit terse.)
<br>
<br>On 2015-05-28 15:11, Nicol Bolas wrote:
<br>> On Thursday, May 28, 2015 at 12:14:01 PM UTC-4, Matthew Woehlke wr=
ote:
<br>>> On 2015-05-27 18:05, Nicol Bolas wrote:=20
<br>>>> Similarly, braced-init-lists are not=20
<br>>>> elements of an expression; the construct `{4.3, "foo"}` is=
not a legal=20
<br>>>> expression. Value sequences should be like those.=20
<br>>>
<br>>> They won't be. A brace expression such as the above is *always=
* a brace=20
<br>>> expression.
<br>>=20
<br>> There is no such thing as a "brace expression". The standard is *v=
ery clear*=20
<br>> about this: it is not an expression.
<br>
<br>Please don't language lawyer :-).<br></blockquote><div><br>You want to =
modify The Standard for Programming Language C++. That requires a degree of=
precision about what things are called.<br> </div><blockquote class=
=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #cc=
c solid;padding-left: 1ex;">
What I mean is, the symbols '{a, b}' show me that there are two items.
<br>In no way can I, at present, "pass" those two items in a way that I los=
e
<br>the immediately obvious fact that there are two items.
<br>
<br>What I object to is:
<br>
<br>> auto x =3D Typename{<wbr>FuncThatReturnsMultipleValues(<wbr>)};
<br>
<br>...this. Here, I have to inspect FuncThatReturnsMultipleValues to know
<br>that it returns multiple values. I object to that. I strongly would
<br>prefer to require some syntax to indicate unpacking, e.g. '[*]' or '...=
'
<br>or whatever.
<br></blockquote><div><br>On what basis do you object to that? You say that=
you have to inspect it to know that it returns multiple values. Well... wh=
y do you care? All you care about is what you need to; namely, that `Typena=
me` has a constructor that matches the return value(s) of the function you'=
re using. Whether it's one return value or 20, as long as there's a matchin=
g constructor, you're syntactically fine.<br><br>Why should using `FuncThat=
ReturnsOneValue` require less syntax than `FuncThatReturnsMultipleValues`? =
Furthermore, what happens if someone changes the return type; why should it=
cause this (particular) code to break? The statement would be no less lega=
l, so long as Typename has a valid constructor.<br><br>I just don't see wha=
t the point of the added syntax would be. I understand why you need templat=
e parameter pack unpacking syntax (because you're able to distribute unpack=
ing across an expression). But what do you gain from having to unpack the r=
esults, rather than having the results not be packed to begin with?<br><br>=
</div><blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8=
ex;border-left: 1px #ccc solid;padding-left: 1ex;">
<br>> Well, the ABI now has to include the "std::value_sequence" type, w=
hich=20
<br>> again is a "magic type", not a normal type. I admittedly know very=
little=20
<br>> about ABIs, so I have no idea how any particular "magic type" of t=
his sort=20
<br>> would be handled at the ABI level. But it would depend on how much=
"magic"=20
<br>> is in this magic type.
<br>>=20
<br>> That being said, and given that I don't know much about ABIs, I do=
n't=20
<br>> really understand why MRVs would be problematic for ABIs. Or more =
to the=20
<br>> point, how the solution of returning a "magic value" would differ =
from the=20
<br>> MRV solution.
<br>
<br>I don't think there is much magic, and I think we are more or less
<br>wanting the same thing. The only real exception that I am seeing is tha=
t
<br>unpacking and MRV's (and expansion) are orthogonal, and that an MRV has
<br>a type.
<br>
<br>Note: the more I think about it, the more I'm inclined to say that it i=
s
<br>an unnameable type, like lambdas. That is, 'auto x =3D mrv_func()' is
<br>legal, but doing anything besides unpacking 'x' is not. (Potentially
<br>even passing it via a template type.)<br></blockquote><div><br>Then wha=
t's the point of being able to store it? Why make it an object at all if th=
e only thing it can do is be unpacked?<br> </div><blockquote class=3D"=
gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc so=
lid;padding-left: 1ex;">
<br>> In both cases, the compiler needs to know how much space to=20
<br>> allocate, which will be based on some aggregation of the types inv=
olved. In=20
<br>> both cases, the compiler and it's ABI will have to define that agg=
regation,=20
<br>> whether it's in the "magic type" (and therefore, the ABI will have=
to=20
<br>> define the ordering of the items in the type as well as their layo=
ut) or=20
<br>> purely internally (with the ABI defining the offsets/alignment for=
each=20
<br>> type in the returned data).
<br>
<br>Right, though I don't think there is a real difference here.
<br>Particularly if the type is unnameable, the order isn't necessarily
<br>consistent for a given type list, but would depend on the callee. (In
<br>neither case, AFAIK, can it vary at run-time, or by who is the caller.)=
<br></blockquote><div><br>I don't know much about ABIs, but I'm pretty sure=
that "consistency" is a <i>very</i> important element of them. Otherwise, =
you can't have different code that links to each other.<br><br>If the calle=
r doesn't know that the first item in the typelist is actually the first in=
the data structure, how can the caller access it to unpack it? The whole p=
oint of an ABI is for both the caller and callee to know what's going on in=
an interface.<br> </div><blockquote class=3D"gmail_quote" style=3D"ma=
rgin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">
>>> Because syntax is rare and precious, it is not cheap. And valu=
able=20
<br>>>> syntax should not be created just because it makes the liv=
es of
<br>>>> generic programmers who work with tuples easier.
<br>
<br>Incidentally, I'm not sure this is a *valid* reason. Depending on the
<br>unpacking syntax, knowing that you are unpacking without a lot of
<br>look-ahead might be difficult. Compiler vendors tend to not like that;
<br>as a result, it may be that your unpacking syntax would not be any more
<br>context sensitive than generic unpacking.
<br></blockquote><div><br>Um, I'm not talking about "unpacking syntax." Or =
rather, more to the point, I don't <i>want</i> "unpacking syntax". Or packi=
ng syntax.<br><br>I want MRV syntax. Packing and unpacking would not be syn=
tax; they'd just be function calls.<br><br></div><blockquote class=3D"gmail=
_quote" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;p=
adding-left: 1ex;">
Agreed, but I also consider parameter expansion an orthogonal problem.<br><=
/blockquote><div><br>That's because you're focused on syntax for packing an=
d unpacking tuples. If you simply have MRVs as a first-class feature rather=
than an unpacking hack, then packing and unpacking is nothing more than a =
function call.<br> </div><blockquote class=3D"gmail_quote" style=3D"ma=
rgin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">
>> unpacking has potential value for any=20
<br>>> sequence-like structure. Think about arrays, points, ranges,=
=20
<br>>> dimensions... all could potentially use unpacking.
<br>>=20
<br>> I cannot recall a single instance where I've had the desire to "un=
pack"=20
<br>> members of an array, point, or arbitrary ranges into a function ca=
ll or=20
<br>> anything of the like.
<br>
<br>I can. Here's the example (slightly simplified, and with names changed)
<br>that I know of offhand:
<br>
<br> inline void foo(point2d const& in, double result[2])
<br> {
<br> // Method 1 (shorter)
<br> [result[0]; result[1]] =3D foo([*]in);
<br>
<br> // Method 2 (more generic)
<br> std::tie([*]result) =3D std::tie([*](foo[*]in));
<br>
<br> // C++98 (not generic)
<br> const point2d p =3D foo(in.X, in.Y);
<br> result[0] =3D p.X;
<br> result[1] =3D p.Y;
<br> }
<br>
<br>This is in real, production code, and yes I would write it like that if
<br>I could. (Note: I'm not sure if assignment like that actually works, bu=
t
<br>that's only an issue because my 'point2d' is not assignable from a tupl=
e.)
<br>
<br>Unpacking objects (usually geometry types) into individual local
<br>variables is not unusual for me.<br></blockquote><div><br>So your use c=
ase for this syntax is translating values of structs between different APIs=
? Isn't that something that should happen at the leaf parts of your code, w=
ith the internals of your code actually handling things in a consistent way=
?<br><br>In your example above, a user who wants the result as a `double[2]=
` should call `foo` like this:<br><br><div class=3D"prettyprint" style=3D"b=
ackground-color: rgb(250, 250, 250); border-color: rgb(187, 187, 187); bord=
er-style: solid; border-width: 1px; word-wrap: break-word;"><code class=3D"=
prettyprint"><div class=3D"subprettyprint"><span style=3D"color: #008;" cla=
ss=3D"styled-by-prettify">double</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"> result</span><span style=3D"color: #660;" class=3D=
"styled-by-prettify">[</span><span style=3D"color: #066;" class=3D"styled-b=
y-prettify">2</span><span style=3D"color: #660;" class=3D"styled-by-prettif=
y">];</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br>t=
o_double2</span><span style=3D"color: #660;" class=3D"styled-by-prettify">(=
</span><span style=3D"color: #000;" class=3D"styled-by-prettify">foo</span>=
<span style=3D"color: #660;" class=3D"styled-by-prettify">(</span><span sty=
le=3D"color: #000;" class=3D"styled-by-prettify">data</span><span style=3D"=
color: #660;" class=3D"styled-by-prettify">),</span><span style=3D"color: #=
000;" class=3D"styled-by-prettify"> result</span><span style=3D"color: #660=
;" class=3D"styled-by-prettify">);</span></div></code></div></div><br>That =
way, you don't have to write 20 different variations of `foo`.<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"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />
------=_Part_8087_1366240163.1432853471714--
------=_Part_8086_1462317433.1432853471714--
.
Author: Matthew Fioravante <fmatthew5876@gmail.com>
Date: Thu, 28 May 2015 19:38:09 -0700 (PDT)
Raw View
------=_Part_139_1451287769.1432867089194
Content-Type: multipart/alternative;
boundary="----=_Part_140_674270957.1432867089194"
------=_Part_140_674270957.1432867089194
Content-Type: text/plain; charset=UTF-8
Even if MRV is implemented by returning a kind of non-type sequence /
parameter pack, I think there still is value in a generalized unpacking
syntax. We will need an unpacking syntax for MRV itself.
//Unpack pair
std::pair<int,int> p;
[const auto& p0, const auto& p1] = p;
//Unpack tuple
std::tuple<int, int, int> t;
int t2;
[const auto& t0; void; t2] = t;
//Unpack C array
int a[2];
[auto a0, auto a1] = a;
//Unpack std::array
std::array<int,4> ax;
[auto ax0; auto ax1, void, void] = ax;
//Unpack string literal
std::string_literal<3> s = "bar";
[auto sb; auto sa; auto sr] = s;
The syntax can support braced initializers
//Braced initialization can be unpacked
[auto i; auto l; auto d] = { 1, 1L, 1.0 };
This syntax would also support unpacking sequences from MRV.
The ... syntax is more verbose and maybe redundant, but it clearly tells us
at usage whether we are dealing with an MRV sequence or an expression.
[int,float,double] foo();
auto... x = foo();
//More verbose, obvious where parameter packs are used
[auto x, auto y, auto z] = { x... }; //implemented using braced initializer
support
[auto x1, void, void] = { foo()... };
It also gives us flexibility in how to chain templates and function calls.
std::max_element({ mrvs... });
std::forward<decltype(mrvs)>(mrvs)...;
This version is more terse.
[int,float,double] foo();
auto... x = foo();
//More terse, possible confusion is x a type or
[auto x, auto y, auto z] = x;
[auto x1, void, void] = foo();
It would seem odd to me that to expand a variadic template parameter pack I
need ... but for an MRV pack I don't. They look too similar that it could
be confusing if the rules are very different.
[int,float,double] foo();
void bar(int, float, double);
template <typename... Args> void run(Args&&... tpp) {
auto... mrvs = foo();
bar(mrvs);
bar(tpp...);
}
Classes can define custom operator[auto&&...] to return MRV packs which can
then use the unpack syntax
//Operator returns an MRV sequence
class udt0 {
public:
constexpr operator[auto&&...]() = default;
//constexpr operator[auto...]() { return {i, f, d}; }
//constexpr operator[auto...]() { return {f, d, i}; }
//constexpr operator[int,float,double]() { return {i,f,d}; };
//constexpr operator[double,float,int]() { return {d, f, i}; };
//constexpr operator[double,auto]() { return {d - i, f + i}; };
private:
int i; float f; double d;
} udt;
[auto di; auto fi] = udt;
POD struct types (maybe can relax constraints) have compiler generated
default operator[auto&&...]
//POD types have compiler generated operator[auto...]
struct kv { string key; vector<int> value; } kv;
--
---
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 http://groups.google.com/a/isocpp.org/group/std-proposals/.
------=_Part_140_674270957.1432867089194
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">Even if MRV is implemented by returning a kind of non-type=
sequence / parameter pack, I think there still is value in a generalized u=
npacking syntax. We will need an unpacking syntax for MRV itself.<div><br><=
/div><div><div class=3D"prettyprint" style=3D"border: 1px solid rgb(187, 18=
7, 187); word-wrap: break-word; background-color: rgb(250, 250, 250);"><cod=
e class=3D"prettyprint"><div class=3D"subprettyprint"><span style=3D"color:=
#800;" class=3D"styled-by-prettify">//Unpack pair</span><span style=3D"col=
or: #000;" class=3D"styled-by-prettify"><br>std</span><span style=3D"color:=
#660;" class=3D"styled-by-prettify">::</span><span style=3D"color: #000;" =
class=3D"styled-by-prettify">pair</span><span style=3D"color: #660;" class=
=3D"styled-by-prettify"><</span><span style=3D"color: #008;" class=3D"st=
yled-by-prettify">int</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"color: #660;" class=3D"styled-by-prettify">><=
/span><span style=3D"color: #000;" class=3D"styled-by-prettify"> p</span><s=
pan 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"co=
lor: #660;" class=3D"styled-by-prettify">[</span><span style=3D"color: #008=
;" class=3D"styled-by-prettify">const</span><span style=3D"color: #000;" cl=
ass=3D"styled-by-prettify"> </span><span style=3D"color: #008;" class=3D"st=
yled-by-prettify">auto</span><span style=3D"color: #660;" class=3D"styled-b=
y-prettify">&</span><span style=3D"color: #000;" class=3D"styled-by-pre=
ttify"> p0</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">const</span><span =
style=3D"color: #000;" 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 style=3D"color: #000=
;" class=3D"styled-by-prettify"> p1</span><font color=3D"#666600"><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: #660;=
" class=3D"styled-by-prettify">=3D</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"> p</span><span style=3D"color: #660;" class=3D"styl=
ed-by-prettify">;</span><span style=3D"color: #000;" class=3D"styled-by-pre=
ttify"><br><br></span></font><span style=3D"color: #800;" class=3D"styled-b=
y-prettify">//Unpack tuple</span><span style=3D"color: #000;" class=3D"styl=
ed-by-prettify"><br>std</span><span style=3D"color: #660;" class=3D"styled-=
by-prettify">::</span><span style=3D"color: #000;" class=3D"styled-by-prett=
ify">tuple</span><span style=3D"color: #660;" class=3D"styled-by-prettify">=
<</span><span style=3D"color: #008;" class=3D"styled-by-prettify">int</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: #008;" class=3D"styled-by-prettify">int</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">int</span><span style=3D"color: #660;" class=3D"styled-b=
y-prettify">></span><span style=3D"color: #000;" class=3D"styled-by-pret=
tify"> t</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: #008;" class=3D"styled-by-prettify">int</span><span s=
tyle=3D"color: #000;" class=3D"styled-by-prettify"> t2</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: #008;" class=3D"=
styled-by-prettify">const</span><span style=3D"color: #000;" class=3D"style=
d-by-prettify"> </span><span style=3D"color: #008;" class=3D"styled-by-pret=
tify">auto</span><span style=3D"color: #660;" class=3D"styled-by-prettify">=
&</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> t0</=
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">void</span><span style=3D"co=
lor: #660;" class=3D"styled-by-prettify">;</span><font color=3D"#008800"><s=
pan style=3D"color: #000;" class=3D"styled-by-prettify"> t2</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: #660;=
" class=3D"styled-by-prettify">=3D</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"> t</span><span style=3D"color: #660;" class=3D"styl=
ed-by-prettify">;</span><span style=3D"color: #000;" class=3D"styled-by-pre=
ttify"><br><br></span></font><span style=3D"color: #800;" class=3D"styled-b=
y-prettify">//Unpack C array</span><span style=3D"color: #000;" class=3D"st=
yled-by-prettify"><br></span><span style=3D"color: #008;" class=3D"styled-b=
y-prettify">int</span><span style=3D"color: #000;" class=3D"styled-by-prett=
ify"> a</span><span style=3D"color: #660;" class=3D"styled-by-prettify">[</=
span><font color=3D"#006666"><span style=3D"color: #066;" class=3D"styled-b=
y-prettify">2</span><span style=3D"color: #660;" class=3D"styled-by-prettif=
y">];</span></font><span style=3D"color: #000;" class=3D"styled-by-prettify=
"><br></span><span style=3D"color: #660;" class=3D"styled-by-prettify">[</s=
pan><span style=3D"color: #008;" class=3D"styled-by-prettify">auto</span><s=
pan style=3D"color: #000;" class=3D"styled-by-prettify"> </span><font color=
=3D"#006666"><span style=3D"color: #000;" class=3D"styled-by-prettify">a0</=
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">auto</span><span style=3D"co=
lor: #000;" class=3D"styled-by-prettify"> a1</span><span style=3D"color: #6=
60;" class=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">=3D</span><span style=3D"color: #000;" class=3D"styled-by-p=
rettify"> a</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></font><span style=3D"color: #800;" class=3D"styled-by-prettify">//U=
npack std::array</span><span style=3D"color: #000;" class=3D"styled-by-pret=
tify"><br>std</span><span style=3D"color: #660;" class=3D"styled-by-prettif=
y">::</span><span style=3D"color: #000;" class=3D"styled-by-prettify">array=
</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"color: #660;" class=3D"styled-by-prettify">,</span><span style=3D"=
color: #066;" class=3D"styled-by-prettify">4</span><span style=3D"color: #6=
60;" class=3D"styled-by-prettify">></span><span style=3D"color: #000;" c=
lass=3D"styled-by-prettify"> ax</span><span style=3D"color: #660;" class=3D=
"styled-by-prettify">;</span><span style=3D"color: #000;" class=3D"styled-b=
y-prettify"><br></span><span style=3D"color: #660;" class=3D"styled-by-pret=
tify">[</span><span style=3D"color: #008;" class=3D"styled-by-prettify">aut=
o</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> ax0</spa=
n><font color=3D"#666600"><span style=3D"color: #660;" class=3D"styled-by-p=
rettify">;</span><span style=3D"color: #000;" class=3D"styled-by-prettify">=
</span><span style=3D"color: #008;" class=3D"styled-by-prettify">auto</spa=
n><span style=3D"color: #000;" class=3D"styled-by-prettify"> ax1</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=
: #008;" class=3D"styled-by-prettify">void</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">void</span><span style=3D"color: #660;" class=3D"styled-by-p=
rettify">]</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"> ax</span><span =
style=3D"color: #660;" class=3D"styled-by-prettify">;</span><span style=3D"=
color: #000;" class=3D"styled-by-prettify"><br></span></font><span style=3D=
"color: #000;" class=3D"styled-by-prettify"><br></span><span style=3D"color=
: #800;" class=3D"styled-by-prettify">//Unpack string literal</span><span s=
tyle=3D"color: #000;" class=3D"styled-by-prettify"><br>std</span><span styl=
e=3D"color: #660;" class=3D"styled-by-prettify">::</span><span style=3D"col=
or: #000;" class=3D"styled-by-prettify">string_literal</span><span style=3D=
"color: #660;" class=3D"styled-by-prettify"><</span><font color=3D"#0066=
66"><span style=3D"color: #066;" class=3D"styled-by-prettify">3</span></fon=
t><span style=3D"color: #660;" class=3D"styled-by-prettify">></span><spa=
n style=3D"color: #000;" class=3D"styled-by-prettify"> s </span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">=3D</span><span style=3D"col=
or: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #080;=
" class=3D"styled-by-prettify">"bar"</span><span style=3D"color: #660;" cla=
ss=3D"styled-by-prettify">;</span><span style=3D"color: #000;" class=3D"sty=
led-by-prettify"><br></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;" class=3D"styled-by-prettify"> sb<=
/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: #008;" class=3D"styled-by-prettify">auto</span><span style=3D"co=
lor: #000;" class=3D"styled-by-prettify"> sa</span><span style=3D"color: #6=
60;" class=3D"styled-by-prettify">;</span><span style=3D"color: #000;" clas=
s=3D"styled-by-prettify"> </span><span style=3D"color: #008;" class=3D"styl=
ed-by-prettify">auto</span><span style=3D"color: #000;" class=3D"styled-by-=
prettify"> sr</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: #660;" class=3D"styled-by-prettify">=3D</span><span=
style=3D"color: #000;" class=3D"styled-by-prettify"> s</span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">;</span><span style=3D"color=
: #000;" class=3D"styled-by-prettify"><br></span></div></code></div><div><b=
r></div><div>The syntax can support braced initializers</div><div><div clas=
s=3D"prettyprint" style=3D"border: 1px solid rgb(187, 187, 187); word-wrap:=
break-word; background-color: rgb(250, 250, 250);"><code class=3D"prettypr=
int"><div class=3D"subprettyprint"><span style=3D"color: #800;" class=3D"st=
yled-by-prettify">//Braced initialization can be unpacked</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"><br></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: #000;" cla=
ss=3D"styled-by-prettify"> i</span><span style=3D"color: #660;" class=3D"st=
yled-by-prettify">;</span><span style=3D"color: #000;" class=3D"styled-by-p=
rettify"> </span><span style=3D"color: #008;" class=3D"styled-by-prettify">=
auto</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> l</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">auto</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;" 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-pretti=
fy"> </span><span style=3D"color: #660;" class=3D"styled-by-prettify">{</sp=
an><font color=3D"#006666"><span style=3D"color: #000;" 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 sty=
le=3D"color: #066;" class=3D"styled-by-prettify">1L</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: #066;" class=
=3D"styled-by-prettify">1.0</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></font></div></code></div><br></div>This syntax would also=
support unpacking sequences from MRV.</div><div>The ... syntax is more ver=
bose and maybe redundant, but it clearly tells us at usage whether we are d=
ealing with an MRV sequence or an expression.<br></div><div><div class=3D"p=
rettyprint" 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"><span style=3D"color: #660;" class=3D"styled-b=
y-prettify">[</span><span style=3D"color: #008;" class=3D"styled-by-prettif=
y">int</span><span style=3D"color: #660;" class=3D"styled-by-prettify">,</s=
pan><span style=3D"color: #008;" class=3D"styled-by-prettify">float</span><=
span style=3D"color: #660;" class=3D"styled-by-prettify">,</span><span styl=
e=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"> foo</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: #008;" class=3D"st=
yled-by-prettify">auto</span><span style=3D"color: #660;" class=3D"styled-b=
y-prettify">...</span><span style=3D"color: #000;" class=3D"styled-by-prett=
ify"> x </span><span style=3D"color: #660;" class=3D"styled-by-prettify">=
=3D</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> foo</s=
pan><span style=3D"color: #660;" class=3D"styled-by-prettify">();</span><sp=
an style=3D"color: #000;" class=3D"styled-by-prettify"><br></span><span sty=
le=3D"color: #800;" class=3D"styled-by-prettify">//More verbose, obvious wh=
ere parameter packs are used</span><span style=3D"color: #000;" class=3D"st=
yled-by-prettify"><br></span><span style=3D"color: #660;" class=3D"styled-b=
y-prettify">[</span><span style=3D"color: #008;" class=3D"styled-by-prettif=
y">auto</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: #008;" class=3D"styled-by-prettify">auto</span><span style=3D"co=
lor: #000;" class=3D"styled-by-prettify"> y</span><span style=3D"color: #66=
0;" 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">auto</span><span style=3D"color: #000;" class=3D"styled-by-p=
rettify"> z</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 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: #00=
0;" class=3D"styled-by-prettify"> x</span><span style=3D"color: #660;" clas=
s=3D"styled-by-prettify">...</span><span style=3D"color: #000;" class=3D"st=
yled-by-prettify"> </span><span style=3D"color: #660;" class=3D"styled-by-p=
rettify">};</span><span style=3D"color: #000;" class=3D"styled-by-prettify"=
> </span><span style=3D"color: #800;" class=3D"styled-by-prettify">//implem=
ented using braced initializer support</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: #008;" class=3D"style=
d-by-prettify">auto</span><span style=3D"color: #000;" class=3D"styled-by-p=
rettify"> x1</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">void</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">void</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-pretti=
fy"> </span><span style=3D"color: #660;" class=3D"styled-by-prettify">{</sp=
an><span style=3D"color: #000;" class=3D"styled-by-prettify"> foo</span><sp=
an 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></div></code></div><div><=
br></div><div>It also gives us flexibility in how to chain templates and fu=
nction calls.</div><div><div class=3D"prettyprint" style=3D"border: 1px sol=
id rgb(187, 187, 187); word-wrap: break-word; background-color: rgb(250, 25=
0, 250);"><code class=3D"prettyprint"><div class=3D"subprettyprint"><span s=
tyle=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">max_element</span><span style=3D"color:=
#660;" class=3D"styled-by-prettify">({</span><span style=3D"color: #000;" =
class=3D"styled-by-prettify"> mrvs</span><span style=3D"color: #660;" class=
=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"=
><br>std</span><span style=3D"color: #660;" class=3D"styled-by-prettify">::=
</span><span style=3D"color: #000;" class=3D"styled-by-prettify">forward</s=
pan><span style=3D"color: #660;" class=3D"styled-by-prettify"><</span><s=
pan style=3D"color: #008;" class=3D"styled-by-prettify">decltype</span><spa=
n style=3D"color: #660;" class=3D"styled-by-prettify">(</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify">mrvs</span><span style=3D"co=
lor: #660;" class=3D"styled-by-prettify">)>(</span><span style=3D"color:=
#000;" class=3D"styled-by-prettify">mrvs</span><span style=3D"color: #660;=
" class=3D"styled-by-prettify">)...;</span></div></code></div><div><br></di=
v>This version is more terse.<br><div class=3D"prettyprint" style=3D"border=
: 1px solid rgb(187, 187, 187); word-wrap: break-word; background-color: rg=
b(250, 250, 250);"><code class=3D"prettyprint"><div class=3D"subprettyprint=
"><span style=3D"color: #660;" class=3D"styled-by-prettify">[</span><span s=
tyle=3D"color: #008;" class=3D"styled-by-prettify">int</span><span style=3D=
"color: #660;" class=3D"styled-by-prettify">,</span><span style=3D"color: #=
008;" class=3D"styled-by-prettify">float</span><span style=3D"color: #660;"=
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"sty=
led-by-prettify">]</span><span style=3D"color: #000;" class=3D"styled-by-pr=
ettify"> foo</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: #008;" class=3D"styled-by-prettify">auto</span>=
<span style=3D"color: #660;" class=3D"styled-by-prettify">...</span><span s=
tyle=3D"color: #000;" class=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"> foo</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: #800;" class=
=3D"styled-by-prettify">//More terse, possible confusion is x a type or</sp=
an><span style=3D"color: #000;" class=3D"styled-by-prettify"><br></span><sp=
an 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"co=
lor: #000;" class=3D"styled-by-prettify"> x</span><span style=3D"color: #66=
0;" 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">auto</span><span style=3D"color: #000;" class=3D"styled-by-p=
rettify"> y</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">auto</span><span =
style=3D"color: #000;" class=3D"styled-by-prettify"> z</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;" cla=
ss=3D"styled-by-prettify">=3D</span><span style=3D"color: #000;" class=3D"s=
tyled-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=
"><br></span><span style=3D"color: #660;" class=3D"styled-by-prettify">[</s=
pan><span style=3D"color: #008;" class=3D"styled-by-prettify">auto</span><s=
pan style=3D"color: #000;" class=3D"styled-by-prettify"> x1</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">void</span><span style=3D"color: #660;" clas=
s=3D"styled-by-prettify">,</span><span style=3D"color: #000;" class=3D"styl=
ed-by-prettify"> </span><span style=3D"color: #008;" class=3D"styled-by-pre=
ttify">void</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 s=
tyle=3D"color: #000;" class=3D"styled-by-prettify"> foo</span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">();</span><span style=3D"col=
or: #000;" class=3D"styled-by-prettify"><br></span></div></code></div></div=
><div><br></div><div>It would seem odd to me that to expand a variadic temp=
late parameter pack I need ... but for an MRV pack I don't. They look too s=
imilar that it could be confusing if the rules are very different.</div><di=
v><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"><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"color: #660;" class=3D"styled=
-by-prettify">,</span><span style=3D"color: #008;" class=3D"styled-by-prett=
ify">float</span><span style=3D"color: #660;" class=3D"styled-by-prettify">=
,</span><span style=3D"color: #008;" class=3D"styled-by-prettify">double</s=
pan><span style=3D"color: #660;" class=3D"styled-by-prettify">]</span><span=
style=3D"color: #000;" class=3D"styled-by-prettify"> foo</span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">();</span><span style=3D"col=
or: #000;" class=3D"styled-by-prettify"><br></span><span style=3D"color: #0=
08;" class=3D"styled-by-prettify">void</span><span style=3D"color: #000;" c=
lass=3D"styled-by-prettify"> bar</span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">(</span><span style=3D"color: #008;" class=3D"style=
d-by-prettify">int</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">float</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: #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"><br></span><span style=3D"color: #008;" class=
=3D"styled-by-prettify">template</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: #008;" class=3D"styled-by-p=
rettify">typename</span><span style=3D"color: #660;" class=3D"styled-by-pre=
ttify">...</span><font color=3D"#000000"><span style=3D"color: #000;" class=
=3D"styled-by-prettify"> </span><span style=3D"color: #606;" class=3D"style=
d-by-prettify">Args</span><span style=3D"color: #660;" class=3D"styled-by-p=
rettify">></span><span style=3D"color: #000;" class=3D"styled-by-prettif=
y"> </span><span style=3D"color: #008;" class=3D"styled-by-prettify">void</=
span><span style=3D"color: #000;" class=3D"styled-by-prettify"> run</span><=
span style=3D"color: #660;" class=3D"styled-by-prettify">(</span><span styl=
e=3D"color: #606;" class=3D"styled-by-prettify">Args</span><span style=3D"c=
olor: #660;" class=3D"styled-by-prettify">&&...</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"> tpp</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: #660;" class=
=3D"styled-by-prettify">{</span><span style=3D"color: #000;" class=3D"style=
d-by-prettify"><br> </span><span style=3D"color: #008;" class=3D"styl=
ed-by-prettify">auto</span><span style=3D"color: #660;" class=3D"styled-by-=
prettify">...</span><span style=3D"color: #000;" class=3D"styled-by-prettif=
y"> mrvs </span><span style=3D"color: #660;" class=3D"styled-by-prettify">=
=3D</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> foo</s=
pan><span style=3D"color: #660;" class=3D"styled-by-prettify">();</span><sp=
an style=3D"color: #000;" class=3D"styled-by-prettify"><br> bar</span=
><span style=3D"color: #660;" class=3D"styled-by-prettify">(</span><span st=
yle=3D"color: #000;" class=3D"styled-by-prettify">mrvs</span><span style=3D=
"color: #660;" class=3D"styled-by-prettify">);</span><span style=3D"color: =
#000;" class=3D"styled-by-prettify"><br> bar</span><span style=3D"col=
or: #660;" class=3D"styled-by-prettify">(</span><span style=3D"color: #000;=
" class=3D"styled-by-prettify">tpp</span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">...);</span><span style=3D"color: #000;" class=3D"s=
tyled-by-prettify"><br></span><span style=3D"color: #660;" class=3D"styled-=
by-prettify">}</span></font></div></code></div></div><br><span class=3D"sty=
led-by-prettify" style=3D"font-family: monospace; color: rgb(0, 0, 0); back=
ground-color: rgb(250, 250, 250);">Classes can define custom operator[auto&=
amp;&...] to return MRV packs which can then use the unpack syntax<br><=
/span><div class=3D"prettyprint" style=3D"border: 1px solid rgb(187, 187, 1=
87); word-wrap: break-word; background-color: rgb(250, 250, 250);"><code cl=
ass=3D"prettyprint"><div class=3D"subprettyprint"><span style=3D"color: #80=
0;" class=3D"styled-by-prettify">//Operator returns an MRV sequence</span><=
span style=3D"color: #000;" class=3D"styled-by-prettify"><br></span><span s=
tyle=3D"color: #008;" class=3D"styled-by-prettify">class</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"> udt0 </span><span style=3D"=
color: #660;" class=3D"styled-by-prettify">{</span><span style=3D"color: #0=
00;" class=3D"styled-by-prettify"><br></span><span style=3D"color: #008;" c=
lass=3D"styled-by-prettify">public</span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">:</span><span style=3D"color: #000;" class=3D"style=
d-by-prettify"><br> </span><span style=3D"color: rgb(136, 0, 0);"><sp=
an style=3D"color: #008;" class=3D"styled-by-prettify">constexpr</span><spa=
n style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=
=3D"color: #008;" class=3D"styled-by-prettify">operator</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 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"> </span><span style=3D"color: #008;" class=3D"style=
d-by-prettify">default</span><span style=3D"color: #660;" class=3D"styled-b=
y-prettify">;</span><span style=3D"color: #000;" class=3D"styled-by-prettif=
y"><br></span></span><span style=3D"color: #000;" class=3D"styled-by-pretti=
fy"> </span><span style=3D"color: #800;" class=3D"styled-by-prettify"=
>//constexpr operator[auto...]() { return {i, f, d}; }</span><span style=3D=
"color: #000;" class=3D"styled-by-prettify"><br></span><span style=3D"color=
: rgb(136, 0, 0);"><span style=3D"color: #000;" class=3D"styled-by-prettify=
"> </span><span style=3D"color: #800;" class=3D"styled-by-prettify">/=
/constexpr operator[auto...]() { return {f, d, i}; }</span></span><span sty=
le=3D"color: #000;" class=3D"styled-by-prettify"><br> </span><span st=
yle=3D"color: #800;" class=3D"styled-by-prettify">//constexpr operator[</sp=
an><font color=3D"#000088"><span style=3D"color: #800;" class=3D"styled-by-=
prettify">int,float,double</span></font><span style=3D"color: #800;" class=
=3D"styled-by-prettify">]() { return {</span><font color=3D"#000000"><span =
style=3D"color: #800;" class=3D"styled-by-prettify">i,f,d</span></font><spa=
n style=3D"color: #800;" class=3D"styled-by-prettify">}; };</span><span sty=
le=3D"color: #000;" class=3D"styled-by-prettify"><br> </span><span st=
yle=3D"color: #800;" class=3D"styled-by-prettify">//constexpr operator[</sp=
an><font color=3D"#000088"><span style=3D"color: #800;" class=3D"styled-by-=
prettify">double,float,int</span></font><span style=3D"color: #800;" class=
=3D"styled-by-prettify">]() { return {</span><font color=3D"#000000"><span =
style=3D"color: #800;" class=3D"styled-by-prettify">d, f, i</span></font><s=
pan style=3D"color: #800;" class=3D"styled-by-prettify">}; };</span><span s=
tyle=3D"color: #000;" class=3D"styled-by-prettify"><br> </span><span =
style=3D"color: #800;" class=3D"styled-by-prettify">//constexpr operator[</=
span><font color=3D"#000088"><span style=3D"color: #800;" class=3D"styled-b=
y-prettify">double,auto</span></font><span style=3D"color: #800;" class=3D"=
styled-by-prettify">]() { return {</span><font color=3D"#000000"><span styl=
e=3D"color: #800;" class=3D"styled-by-prettify">d - i, f + i</span></font><=
span style=3D"color: #800;" class=3D"styled-by-prettify">}; };</span><span =
style=3D"color: #000;" class=3D"styled-by-prettify"><br> <br></span><=
span style=3D"color: #008;" class=3D"styled-by-prettify">private</span><spa=
n style=3D"color: #660;" class=3D"styled-by-prettify">:</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"><br> </span><span styl=
e=3D"color: #008;" class=3D"styled-by-prettify">int</span><span style=3D"co=
lor: #000;" class=3D"styled-by-prettify"> i</span><span style=3D"color: #66=
0;" 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">float</span><span style=3D"color: #000;" class=3D"styled-by-=
prettify"> f</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><sp=
an 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;" class=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"> udt</span><span style=3D"color: #660;" class=3D"st=
yled-by-prettify">;</span><span style=3D"color: #000;" class=3D"styled-by-p=
rettify"><br></span><span style=3D"color: #660;" class=3D"styled-by-prettif=
y">[</span><span style=3D"color: #008;" class=3D"styled-by-prettify">auto</=
span><span style=3D"color: #000;" class=3D"styled-by-prettify"> di</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=
: #008;" class=3D"styled-by-prettify">auto</span><span style=3D"color: #000=
;" class=3D"styled-by-prettify"> </span><span style=3D"color: #008;" class=
=3D"styled-by-prettify">fi</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: #660;" class=3D"styled-by-prettify">=
=3D</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> udt</s=
pan><span style=3D"color: #660;" class=3D"styled-by-prettify">;</span></div=
></code></div><span class=3D"styled-by-prettify" style=3D"font-family: mono=
space; color: rgb(102, 102, 0); background-color: rgb(250, 250, 250);"><br>=
</span><span class=3D"styled-by-prettify" style=3D"font-family: monospace; =
color: rgb(0, 0, 0); background-color: rgb(250, 250, 250);">POD struct type=
s (maybe can relax constraints) have compiler generated default operator[au=
to&&...]<br></span><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"><spa=
n style=3D"color: #800;" class=3D"styled-by-prettify">//POD types have comp=
iler generated operator[auto...]</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"><br></span><span style=3D"color: #008;" class=3D"st=
yled-by-prettify">struct</span><span style=3D"color: #000;" class=3D"styled=
-by-prettify"> kv </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">string</sp=
an><span style=3D"color: #000;" class=3D"styled-by-prettify"> key</span><sp=
an style=3D"color: #660;" class=3D"styled-by-prettify">;</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"> vector</span><span style=3D=
"color: #080;" class=3D"styled-by-prettify"><int></span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"> value</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: #660;" clas=
s=3D"styled-by-prettify">}</span><span style=3D"color: #000;" class=3D"styl=
ed-by-prettify"> kv</span><span style=3D"color: #660;" class=3D"styled-by-p=
rettify">;</span></div></code></div><br><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"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />
------=_Part_140_674270957.1432867089194--
------=_Part_139_1451287769.1432867089194--
.
Author: Matthew Woehlke <mw_triad@users.sourceforge.net>
Date: Fri, 29 May 2015 11:16:44 -0400
Raw View
On 2015-05-28 18:51, Nicol Bolas wrote:
> On Thursday, May 28, 2015 at 5:22:42 PM UTC-4, Matthew Woehlke wrote:
>> What I object to is:
>>
>>> auto x = Typename{FuncThatReturnsMultipleValues()};
>>
>> ...this. Here, I have to inspect FuncThatReturnsMultipleValues to know
>> that it returns multiple values. I object to that. I strongly would
>> prefer to require some syntax to indicate unpacking, e.g. '[*]' or '...'
>> or whatever.
>
> Why should using `FuncThatReturnsOneValue` require less syntax than
> `FuncThatReturnsMultipleValues`?
Because in no existing case can a single 'token' represent multiple
parameters without that being made obvious.
To ask the opposite question, should we allow this?
template <Typename Args...>
void foo(Args... args)
{
bar(args);
}
Also because separating expansion from unpacking from MRV's gives
greater consistency and greater general usefulness, rather than limiting
those concepts to a single tightly-coupled use case.
> Then what's the point of being able to store it? Why make it an object at
> all if the only thing it can do is be unpacked?
auto r = foo();
auto x = get<0>(params);
auto params = get<1,-1>(params)
for (auto i : x)
i->bar([*]params);
Storing allows it to be used more than once, allows accepting the values
and using the values to be separated, ...
One could use a tuple, but this whole discussion started because you
objected (loudly) to the extraneous copies that would incur. In the
above example, I might even hope that the compiler makes no copies
(excluding when calling 'bar', and possibly with some '&'s added). I
would *especially* expect no copies if I wasn't slicing the value
sequence, but merely reusing it.
>> Right, though I don't think there is a real difference here.
>> Particularly if the type is unnameable, the order isn't necessarily
>> consistent for a given type list, but would depend on the callee. (In
>> neither case, AFAIK, can it vary at run-time, or by who is the caller.)
>
> I don't know much about ABIs, but I'm pretty sure that "consistency" is a
> *very* important element of them. Otherwise, you can't have different code
> that links to each other.
Hmm... I was thinking that, depending on the internal implementation of
a function, the compiler might make a different choice how to pass
parameters (e.g. registers or not). But on further consideration, you're
right; I don't see how the compiler would then know how to call that
function. So, yeah, it would have to be consistent for a given type list.
> Um, I'm not talking about "unpacking syntax." Or rather, more to the point,
> I don't *want* "unpacking syntax". Or packing syntax.
>
> I want MRV syntax. Packing and unpacking would not be syntax; they'd just
> be function calls.
What, then, is your equivalent to this?
[auto x; auto y] = some_mrv_function();
(Note that you cannot use std::tie here, as 'x' and 'y' are not declared
yet.)
It seems you are entirely ignoring this case and asserting that "real
MRV's" make it go away. I disagree with that assertion. (And will point
out, again, that I still think Matthew F's proposal and yours are, or
should be, orthogonal. They are complementary, and yours needs to be
implemented in a way to be compatible with unpacking, but otherwise
orthogonal.)
>> Agreed, but I also consider parameter expansion an orthogonal problem.
>
> That's because you're focused on syntax for packing and unpacking tuples.
Right. Because I think it's a problem worth solving (see also previous
comment), and because it was the original proposal.
I think you may be confusing unpacking and expansion. Unpacking, as I am
using it, is the ability to write assignments like the above example.
Expansion is the ability to tell the compiler to... well, do this:
{[*]tuple_like};
foo([*]tuple_like);
// ...becomes
{get<0>(tuple_like), get<1>(tuple_like), ...};
foo(get<0>(tuple_like), get<1>(tuple_like), ...);
They have some conceptual similarities, but are very different operations.
> So your use case for this syntax is translating values of structs between
> different APIs?
That's *a* use case.
Here's another:
[auto x; auto y] = [*]p;
x = sin(2*x) + cos(2*y);
y = sqrt(y);
return {x, y};
Invented and somewhat simplified, but this is another case I run into
with moderate frequency; given a "tuple-like" class (often one that does
not have public data members), I want to "crack" it into local variables
for various reasons; terseness, to avoid multiple invocations of
accessor methods, etc.
There is also, of course, the associative container iteration example.
I'm confident there are others I'm not thinking of offhand.
> In your example above, a user who wants the result as a `double[2]` should
> call `foo` like this:
>
> double result[2];
> to_double2(foo(data), result);
>
> That way, you don't have to write 20 different variations of `foo`.
I find it more convenient to write utility overloads to accept data in a
variety of formats, and I'm not the only API to do so. The difference is
I can write those overloads *once* and use them many times, compared to
having to write call-site conversions many times.
--
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 http://groups.google.com/a/isocpp.org/group/std-proposals/.
.
Author: Matthew Woehlke <mw_triad@users.sourceforge.net>
Date: Fri, 29 May 2015 11:23:30 -0400
Raw View
On 2015-05-28 22:38, Matthew Fioravante wrote:
> //More verbose, obvious where parameter packs are used
> [auto x, auto y, auto z] = { x... }; //implemented using braced initializer
> support
I've been writing std::tie here (make_tuple would be equally
sufficient), but... yeah, I like being able to unpack a literal '{...}'
better :-). (More efficient, for sure...)
What's a little weird, though, is that this can't work under the 'as-if'
rule, since as Nicol pointed out, a general braced list can't be
assigned to a variable. I think that's a useful special case, but it
*is* a special case.
--
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 http://groups.google.com/a/isocpp.org/group/std-proposals/.
.
Author: Matthew Fioravante <fmatthew5876@gmail.com>
Date: Fri, 29 May 2015 08:44:48 -0700 (PDT)
Raw View
------=_Part_777_1279002723.1432914288916
Content-Type: multipart/alternative;
boundary="----=_Part_778_2034942638.1432914288916"
------=_Part_778_2034942638.1432914288916
Content-Type: text/plain; charset=UTF-8
Implicit expansion might be a way to make braced initializers work with
perfect forwarding. This might require the terse syntax.
struct Foo { Foo(int, double); };
struct Bar { Bar(const Foo&, const Foo&); }
auto... x = { 1, 1.0 };
auto f = Foo{x};
auto b = Bar{{x}, {x}}
//Expands to 2 mrv packs which are then forwarded to BAR(const Foo&, const
Foo&)
std::make_unique<Bar>({1, 1.0}, {2, 2.0});
--
---
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 http://groups.google.com/a/isocpp.org/group/std-proposals/.
------=_Part_778_2034942638.1432914288916
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><div>Implicit expansion might be a way to make b=
raced initializers work with perfect forwarding. This might require the ter=
se syntax.</div><div> </div><div><div style=3D"border: 1px solid rgb(1=
87, 187, 187); word-wrap: break-word; background-color: rgb(250, 250, 250);=
" class=3D"prettyprint"><code class=3D"prettyprint"><div class=3D"subpretty=
print"><span style=3D"color: rgb(0, 0, 136);" class=3D"styled-by-prettify">=
struct</span><span style=3D"color: rgb(0, 0, 0);" class=3D"styled-by-pretti=
fy"> </span><span style=3D"color: rgb(102, 0, 102);" class=3D"styled-by-pre=
ttify">Foo</span><span style=3D"color: rgb(0, 0, 0);" class=3D"styled-by-pr=
ettify"> </span><span style=3D"color: rgb(102, 102, 0);" class=3D"styled-by=
-prettify">{</span><span style=3D"color: rgb(0, 0, 0);" class=3D"styled-by-=
prettify"> </span><span style=3D"color: rgb(102, 0, 102);" class=3D"styled-=
by-prettify">Foo</span><span style=3D"color: rgb(102, 102, 0);" class=3D"st=
yled-by-prettify">(</span><span style=3D"color: rgb(0, 0, 136);" class=3D"s=
tyled-by-prettify">int</span><span style=3D"color: rgb(102, 102, 0);" class=
=3D"styled-by-prettify">,</span><span style=3D"color: rgb(0, 0, 0);" class=
=3D"styled-by-prettify"> </span><span style=3D"color: rgb(0, 0, 136);" clas=
s=3D"styled-by-prettify">double</span><span style=3D"color: rgb(102, 102, 0=
);" class=3D"styled-by-prettify">);</span><span style=3D"color: rgb(0, 0, 0=
);" class=3D"styled-by-prettify"> </span><span style=3D"color: rgb(102, 102=
, 0);" class=3D"styled-by-prettify">};</span><span style=3D"color: rgb(0, 0=
, 0);" class=3D"styled-by-prettify"><br></span><span style=3D"color: rgb(0,=
0, 136);" class=3D"styled-by-prettify">struct</span><span style=3D"color: =
rgb(0, 0, 0);" class=3D"styled-by-prettify"> </span><span style=3D"color: r=
gb(102, 0, 102);" class=3D"styled-by-prettify">Bar</span><span style=3D"col=
or: rgb(0, 0, 0);" class=3D"styled-by-prettify"> </span><span style=3D"colo=
r: rgb(102, 102, 0);" class=3D"styled-by-prettify">{</span><span style=3D"c=
olor: rgb(0, 0, 0);" class=3D"styled-by-prettify"> </span><span style=3D"co=
lor: rgb(102, 0, 102);" class=3D"styled-by-prettify">Bar</span><span style=
=3D"color: rgb(102, 102, 0);" class=3D"styled-by-prettify">(</span><span st=
yle=3D"color: rgb(0, 0, 136);" class=3D"styled-by-prettify">const</span><sp=
an style=3D"color: rgb(0, 0, 0);" class=3D"styled-by-prettify"> </span><spa=
n style=3D"color: rgb(102, 0, 102);" class=3D"styled-by-prettify">Foo</span=
><span style=3D"color: rgb(102, 102, 0);" class=3D"styled-by-prettify">&=
;,</span><span style=3D"color: rgb(0, 0, 0);" class=3D"styled-by-prettify">=
</span><span style=3D"color: rgb(0, 0, 136);" class=3D"styled-by-prettify"=
>const</span><span style=3D"color: rgb(0, 0, 0);" class=3D"styled-by-pretti=
fy"> </span><span style=3D"color: rgb(102, 0, 102);" class=3D"styled-by-pre=
ttify">Foo</span><span style=3D"color: rgb(102, 102, 0);" class=3D"styled-b=
y-prettify">&);</span><span style=3D"color: rgb(0, 0, 0);" class=3D"sty=
led-by-prettify"> </span><span style=3D"color: rgb(102, 102, 0);" class=3D"=
styled-by-prettify">}</span><span style=3D"color: rgb(0, 0, 0);" class=3D"s=
tyled-by-prettify"><br></span><span style=3D"color: rgb(0, 0, 136);" class=
=3D"styled-by-prettify">auto</span><span style=3D"color: rgb(102, 102, 0);"=
class=3D"styled-by-prettify">...</span><span style=3D"color: rgb(0, 0, 0);=
" class=3D"styled-by-prettify"> x </span><span style=3D"color: rgb(102, 102=
, 0);" class=3D"styled-by-prettify">=3D</span><span style=3D"color: rgb(0, =
0, 0);" class=3D"styled-by-prettify"> </span><span style=3D"color: rgb(102,=
102, 0);" class=3D"styled-by-prettify">{</span><span style=3D"color: rgb(0=
, 0, 0);" class=3D"styled-by-prettify"> </span><span style=3D"color: rgb(0,=
102, 102);" class=3D"styled-by-prettify">1</span><span style=3D"color: rgb=
(102, 102, 0);" class=3D"styled-by-prettify">,</span><span style=3D"color: =
rgb(0, 0, 0);" class=3D"styled-by-prettify"> </span><span style=3D"color: r=
gb(0, 102, 102);" class=3D"styled-by-prettify">1.0</span><span style=3D"col=
or: rgb(0, 0, 0);" class=3D"styled-by-prettify"> </span><span style=3D"colo=
r: rgb(102, 102, 0);" class=3D"styled-by-prettify">};</span><span style=3D"=
color: rgb(0, 0, 0);" class=3D"styled-by-prettify"><br></span><font color=
=3D"#660066"><span style=3D"color: rgb(0, 0, 136);" class=3D"styled-by-pret=
tify">auto</span><span style=3D"color: rgb(0, 0, 0);" class=3D"styled-by-pr=
ettify"> f </span><span style=3D"color: rgb(102, 102, 0);" class=3D"styled-=
by-prettify">=3D</span><span style=3D"color: rgb(0, 0, 0);" class=3D"styled=
-by-prettify"> </span><span style=3D"color: rgb(102, 0, 102);" class=3D"sty=
led-by-prettify">Foo</span><span style=3D"color: rgb(102, 102, 0);" class=
=3D"styled-by-prettify">{</span><span style=3D"color: rgb(0, 0, 0);" class=
=3D"styled-by-prettify">x</span><span style=3D"color: rgb(102, 102, 0);" cl=
ass=3D"styled-by-prettify">};</span><span style=3D"color: rgb(0, 0, 0);" cl=
ass=3D"styled-by-prettify"><br></span><span style=3D"color: rgb(0, 0, 136);=
" class=3D"styled-by-prettify">auto</span><span style=3D"color: rgb(0, 0, 0=
);" class=3D"styled-by-prettify"> b </span><span style=3D"color: rgb(102, 1=
02, 0);" class=3D"styled-by-prettify">=3D</span><span style=3D"color: rgb(0=
, 0, 0);" class=3D"styled-by-prettify"> </span><span style=3D"color: rgb(10=
2, 0, 102);" class=3D"styled-by-prettify">Bar</span><span style=3D"color: r=
gb(102, 102, 0);" class=3D"styled-by-prettify">{{</span><span style=3D"colo=
r: rgb(0, 0, 0);" class=3D"styled-by-prettify">x</span><span style=3D"color=
: rgb(102, 102, 0);" class=3D"styled-by-prettify">},</span><span style=3D"c=
olor: rgb(0, 0, 0);" class=3D"styled-by-prettify"> </span><span style=3D"co=
lor: rgb(102, 102, 0);" class=3D"styled-by-prettify">{</span><span style=3D=
"color: rgb(0, 0, 0);" class=3D"styled-by-prettify">x</span><span style=3D"=
color: rgb(102, 102, 0);" class=3D"styled-by-prettify">}}</span><span style=
=3D"color: rgb(0, 0, 0);" class=3D"styled-by-prettify"><br><br></span><span=
style=3D"color: rgb(136, 0, 0);" class=3D"styled-by-prettify">//Expands to=
2 mrv packs which are then forwarded to BAR(const Foo&, const Foo&=
)</span><span style=3D"color: rgb(0, 0, 0);" class=3D"styled-by-prettify"><=
br>std</span><span style=3D"color: rgb(102, 102, 0);" class=3D"styled-by-pr=
ettify">::</span><span style=3D"color: rgb(0, 0, 0);" class=3D"styled-by-pr=
ettify">make_unique</span><span style=3D"color: rgb(102, 102, 0);" class=3D=
"styled-by-prettify"><</span><span style=3D"color: rgb(102, 0, 102);" cl=
ass=3D"styled-by-prettify">Bar</span><span style=3D"color: rgb(102, 102, 0)=
;" class=3D"styled-by-prettify">>({</span><span style=3D"color: rgb(0, 1=
02, 102);" class=3D"styled-by-prettify">1</span><span style=3D"color: rgb(1=
02, 102, 0);" class=3D"styled-by-prettify">,</span><span style=3D"color: rg=
b(0, 0, 0);" class=3D"styled-by-prettify"> </span><span style=3D"color: rgb=
(0, 102, 102);" class=3D"styled-by-prettify">1.0</span><span style=3D"color=
: rgb(102, 102, 0);" class=3D"styled-by-prettify">},</span><span style=3D"c=
olor: rgb(0, 0, 0);" class=3D"styled-by-prettify"> </span><span style=3D"co=
lor: rgb(102, 102, 0);" class=3D"styled-by-prettify">{</span><span style=3D=
"color: rgb(0, 102, 102);" class=3D"styled-by-prettify">2</span><span style=
=3D"color: rgb(102, 102, 0);" class=3D"styled-by-prettify">,</span><span st=
yle=3D"color: rgb(0, 0, 0);" class=3D"styled-by-prettify"> </span><span sty=
le=3D"color: rgb(0, 102, 102);" class=3D"styled-by-prettify">2.0</span><spa=
n style=3D"color: rgb(102, 102, 0);" class=3D"styled-by-prettify">});</span=
><span style=3D"color: rgb(0, 0, 0);" class=3D"styled-by-prettify"><br><br>=
</span></font><span style=3D"color: rgb(0, 0, 0);" class=3D"styled-by-prett=
ify"><br></span></div></code></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"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />
------=_Part_778_2034942638.1432914288916--
------=_Part_777_1279002723.1432914288916--
.
Author: Nicol Bolas <jmckesson@gmail.com>
Date: Fri, 29 May 2015 16:57:00 -0700 (PDT)
Raw View
------=_Part_820_842064398.1432943820355
Content-Type: multipart/alternative;
boundary="----=_Part_821_659103456.1432943820355"
------=_Part_821_659103456.1432943820355
Content-Type: text/plain; charset=UTF-8
On Friday, May 29, 2015 at 11:16:56 AM UTC-4, Matthew Woehlke wrote:
>
> On 2015-05-28 18:51, Nicol Bolas wrote:
> > On Thursday, May 28, 2015 at 5:22:42 PM UTC-4, Matthew Woehlke wrote:
> >> What I object to is:
> >>
> >>> auto x = Typename{FuncThatReturnsMultipleValues()};
> >>
> >> ...this. Here, I have to inspect FuncThatReturnsMultipleValues to know
> >> that it returns multiple values. I object to that. I strongly would
> >> prefer to require some syntax to indicate unpacking, e.g. '[*]' or
> '...'
> >> or whatever.
> >
> > Why should using `FuncThatReturnsOneValue` require less syntax than
> > `FuncThatReturnsMultipleValues`?
>
> Because in no existing case can a single 'token' represent multiple
> parameters without that being made obvious.
>
.... what?
`FuncThatReturnsMultipleValues()` is not a "token"; it's *three* tokens.
It's an identifier, followed by an open paren, followed by a close paren.
You can consider this pedantic, but it's very hard to have a discussion
about the standard if you use misuse standard terminology this badly.
If by "token", you meant "expression", then you're correct. The result of
an expression is, without multiple return values, a single value with a
single type. Therefore, in order for MRVs to work, that will have to change.
Obviously.
The standard would have to be changed to allow the evaluation of a function
call expression to be a value sequence, as defined by the function's return
value sequence syntax. Value sequences would only be able to be used in
certain locations, such as in the initialization of a variable(s) or in the
argument list of an enclosing function call expression.
There is no need for special expansion syntax at the site of the use of a
value sequence for this to work.
> To ask the opposite question, should we allow this?
>
> template <Typename Args...>
> void foo(Args... args)
> {
> bar(args);
> }
>
>
I understand why they didn't. It's for two reasons:
1) You already need an explicit unpacking operation on packs, so that you
can do cool expression expansion tricks.
2) Because of #1, it's really important that the user understands what
they're asking for (the difference between `func(args...)` and
`func(args)...`). Otherwise, they might expect `args` to be able to be used
in places or ways it can't be.
Since value sequences are not parameter packs, these don't have to apply.
One could use a tuple, but this whole discussion started because you
> objected (loudly) to the extraneous copies that would incur.
Then you've misunderstood the point.
The primary justification for this feature was having multiple return
values. It's *the title of the thread*. My point was that, by doing it as
proposed (through std::tuple), it interferes with elision. Which it does.
Remember: the elision problem was that the callee had some variable, which
was being packed into a tuple, then unpacked into the caller's variable.
The elision in question was the elision between the callee's variable and
the caller's variable.
Well, if the caller is storing the tuple as a *tuple*, rather than
broadcasting the tuple elements into variables, this argument no longer
applies.
> In the
> above example, I might even hope that the compiler makes no copies
> (excluding when calling 'bar', and possibly with some '&'s added). I
> would *especially* expect no copies if I wasn't slicing the value
> sequence, but merely reusing it.
>
As previously stated, the standard *requires* this statement:
auto x = get<0>(params);
to call a constructor. Elision works *only* in cases where elision is
expressly permitted. And this is in no way one of them.
Not only that, elision in this case breaks all kinds of C++ guarantees. In
your case, if the copy/move was elided, `x` and `params` would be sharing
data. Changing `x` would implicitly change `params`. I'm no authority on
this matter, but I'm pretty sure that violates strict aliasing or some
other C++ guarantee.
> > Um, I'm not talking about "unpacking syntax." Or rather, more to the
> point,
> > I don't *want* "unpacking syntax". Or packing syntax.
> >
> > I want MRV syntax. Packing and unpacking would not be syntax; they'd
> just
> > be function calls.
>
> What, then, is your equivalent to this?
>
> [auto x; auto y] = some_mrv_function();
>
Under MRV rules, that is not "unpacking" or "expansion", because
`some_mrv_function` does not return a "packed" value that needs to be
"unpacked" or "expanded". It returns *multiple values*.
Under MRV, this is merely the syntax for storing multiple values.
> So your use case for this syntax is translating values of structs between
> > different APIs?
>
> That's *a* use case.
>
> Here's another:
>
> [auto x; auto y] = [*]p;
> x = sin(2*x) + cos(2*y);
> y = sqrt(y);
> return {x, y};
>
> Invented and somewhat simplified, but this is another case I run into
> with moderate frequency ; given a "tuple-like" class (often one that does
> not have public data members), I want to "crack" it into local variables
> for various reasons; terseness, to avoid multiple invocations of
> accessor methods, etc.
>
There's a word for that use case:
Perfidy <http://dictionary.reference.com/browse/perfidy?db=*>.
If you violate a class's interface, you are *committing fraud*. You had an
agreement with the class, that you would follow its public interface. And
you are knowingly and deliberately breaking that agreement.
If you don't like a class's interface; that's your right. You can choose
not to use it for that reason; that's also your right. It's not your right
to back-door the class, break in, and do whatever you want with what you
find.
I know that C++ is not supposed to *prevent* perfidy. But we should not
make perfidy literally *three keystrokes away*. What the hell good is
public/private if anyone can bypass it all trivially?
"We should have this because it makes it trivial for me to break
encapsulation" is not a good argument for any feature. That's not to say
that being able to use a feature to break the language makes the feature a
priori wrong. But such uses should be necessary evils, not a prime
motivator for having it.
There is also, of course, the associative container iteration example.
> I'm confident there are others I'm not thinking of offhand.
>
> > In your example above, a user who wants the result as a `double[2]`
> should
> > call `foo` like this:
> >
> > double result[2];
> > to_double2(foo(data), result);
> >
> > That way, you don't have to write 20 different variations of `foo`.
>
> I find it more convenient to write utility overloads to accept data in a
> variety of formats, and I'm not the only API to do so. The difference is
> I can write those overloads *once* and use them many times, compared to
> having to write call-site conversions many times.
>
That's your prerogative. But you should accept the *burden* of wanting to
do so: having to write all of those overloads.
The fact that one possible method of implementing something requires more
effort than you'd like to expend is not a sufficient reason for requesting
a syntactic change.
--
---
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 http://groups.google.com/a/isocpp.org/group/std-proposals/.
------=_Part_821_659103456.1432943820355
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">On Friday, May 29, 2015 at 11:16:56 AM UTC-4, Matthew Woeh=
lke wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left:=
0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">On 2015-05-28 18:51,=
Nicol Bolas wrote:
<br>> On Thursday, May 28, 2015 at 5:22:42 PM UTC-4, Matthew Woehlke wro=
te:
<br>>> What I object to is:=20
<br>>>
<br>>>> auto x =3D Typename{<wbr>FuncThatReturnsMultipleValues(<wb=
r>)};=20
<br>>>
<br>>> ...this. Here, I have to inspect FuncThatReturnsMultipleValues=
to know=20
<br>>> that it returns multiple values. I object to that. I strongly =
would=20
<br>>> prefer to require some syntax to indicate unpacking, e.g. '[*]=
' or '...'=20
<br>>> or whatever.=20
<br>>=20
<br>> Why should using `FuncThatReturnsOneValue` require less syntax tha=
n=20
<br>> `<wbr>FuncThatReturnsMultipleValues`<wbr>?
<br>
<br>Because in no existing case can a single 'token' represent multiple
<br>parameters without that being made obvious.
<br></blockquote><div><br>... what?<br><br>`FuncThatReturnsMultipleValues()=
` is not a "token"; it's <i>three</i> tokens. It's an identifier, followed =
by an open paren, followed by a close paren.<br><br>You can consider this p=
edantic, but it's very hard to have a discussion about the standard if you =
use misuse standard terminology this badly.<br><br>If by "token", you meant=
"expression", then you're correct. The result of an expression is, without=
multiple return values, a single value with a single type. Therefore, in o=
rder for MRVs to work, that will have to change.<br><br>Obviously.<br><br>T=
he standard would have to be changed to allow the evaluation of a function =
call expression to be a value sequence, as defined by the function's return=
value sequence syntax. Value sequences would only be able to be used in ce=
rtain locations, such as in the initialization of a variable(s) or in the a=
rgument list of an enclosing function call expression.<br><br>There is no n=
eed for special expansion syntax at the site of the use of a value sequence=
for this to work.<br> </div><blockquote class=3D"gmail_quote" style=
=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: =
1ex;">
To ask the opposite question, should we allow this?
<br>
<br> template <Typename Args...>
<br> void foo(Args... args)
<br> {
<br> bar(args);
<br> }
<br>
<br></blockquote><div><br>I understand why they didn't. It's for two reason=
s:<br><br>1) You already need an explicit unpacking operation on packs, so =
that you can do cool expression expansion tricks.<br><br>2) Because of #1, =
it's really important that the user understands what they're asking for (th=
e difference between `func(args...)` and `func(args)...`). Otherwise, they =
might expect `args` to be able to be used in places or ways it can't be.<br=
><br>Since value sequences are not parameter packs, these don't have to app=
ly.<br><br></div><blockquote class=3D"gmail_quote" style=3D"margin: 0;margi=
n-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">One could use=
a tuple, but this whole discussion started because you
<br>objected (loudly) to the extraneous copies that would incur.</blockquot=
e><div><br>Then you've misunderstood the point.<br><br>The primary justific=
ation for this feature was having multiple return values. It's <i>the title=
of the thread</i>. My point was that, by doing it as proposed (through std=
::tuple), it interferes with elision. Which it does.<br><br>Remember: the e=
lision problem was that the callee had some variable, which was being packe=
d into a tuple, then unpacked into the caller's variable. The elision in qu=
estion was the elision between the callee's variable and the caller's varia=
ble.<br><br>Well, if the caller is storing the tuple as a <i>tuple</i>, rat=
her than broadcasting the tuple elements into variables, this argument no l=
onger applies.<br> </div><blockquote class=3D"gmail_quote" style=3D"ma=
rgin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">=
In the
<br>above example, I might even hope that the compiler makes no copies
<br>(excluding when calling 'bar', and possibly with some '&'s added). =
I
<br>would *especially* expect no copies if I wasn't slicing the value
<br>sequence, but merely reusing it.<br></blockquote><div><br>As previously=
stated, the standard <i>requires</i> this statement:<br><br><div class=3D"=
prettyprint" 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 class=3D"prettyprint"><div class=3D"subprettyprint"><span sty=
le=3D"color: #008;" class=3D"styled-by-prettify">auto</span><span style=3D"=
color: #000;" class=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"> </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">0</span><span style=3D"color: #660;" class=3D"styled-by-prettify">&g=
t;(</span><span style=3D"color: #008;" class=3D"styled-by-prettify">params<=
/span><span style=3D"color: #660;" class=3D"styled-by-prettify">);</span></=
div></code></div><br>to call a constructor. Elision works <i>only</i> in ca=
ses where elision is expressly permitted. And this is in no way one of them=
..<br><br>Not only that, elision in this case breaks all kinds of C++ guaran=
tees. In your case, if the copy/move was elided, `x` and `params` would be =
sharing data. Changing `x` would implicitly change `params`. I'm no authori=
ty on this matter, but I'm pretty sure that violates strict aliasing or som=
e other C++ guarantee.<br> </div><blockquote class=3D"gmail_quote" sty=
le=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left=
: 1ex;">
> Um, I'm not talking about "unpacking syntax." Or rather, more to the p=
oint,=20
<br>> I don't *want* "unpacking syntax". Or packing syntax.
<br>>=20
<br>> I want MRV syntax. Packing and unpacking would not be syntax; they=
'd just=20
<br>> be function calls.
<br>
<br>What, then, is your equivalent to this?
<br>
<br> [auto x; auto y] =3D some_mrv_function();
<br></blockquote><div><br>Under MRV rules, that is not "unpacking" or "expa=
nsion", because `some_mrv_function` does not return a "packed" value that n=
eeds to be "unpacked" or "expanded". It returns <i>multiple values</i>.<br>=
<br>Under MRV, this is merely the syntax for storing multiple values.<br><b=
r></div><blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0=
..8ex;border-left: 1px #ccc solid;padding-left: 1ex;">
> So your use case for this syntax is translating values of structs betw=
een=20
<br>> different APIs?
<br>
<br>That's *a* use case.
<br>
<br>Here's another:
<br>
<br> [auto x; auto y] =3D [*]p;
<br> x =3D sin(2*x) + cos(2*y);
<br> y =3D sqrt(y);
<br> return {x, y};
<br>
<br>Invented and somewhat simplified, but this is another case I run into
<br>with moderate frequency ; given a "tuple-like" class (often one that do=
es
<br>not have public data members), I want to "crack" it into local variable=
s
<br>for various reasons; terseness, to avoid multiple invocations of
<br>accessor methods, etc.<br></blockquote><div><br>There's a word for that=
use case:<br><br><a href=3D"http://dictionary.reference.com/browse/perfidy=
?db=3D*">Perfidy</a>.<br><br>If you violate a class's interface, you are <i=
>committing fraud</i>. You had an agreement with the class, that you would =
follow its public interface. And you are knowingly and deliberately breakin=
g that agreement.<br><br>If you don't like a class's interface; that's your=
right. You can choose not to use it for that reason; that's also your righ=
t. It's not your right to back-door the class, break in, and do whatever yo=
u want with what you find.<br><br>I know that C++ is not supposed to <i>pre=
vent</i> perfidy. But we should not make perfidy literally <i>three keystro=
kes away</i>. What the hell good is public/private if anyone can bypass it =
all trivially?<br><br>"We should have this because it makes it trivial for =
me to break encapsulation" is not a good argument for any feature. That's n=
ot to say that being able to use a feature to break the language makes the =
feature a priori wrong. But such uses should be necessary evils, not a prim=
e motivator for having it.<br><br></div><blockquote class=3D"gmail_quote" s=
tyle=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-le=
ft: 1ex;">
There is also, of course, the associative container iteration example.
<br>I'm confident there are others I'm not thinking of offhand.
<br>
<br>> In your example above, a user who wants the result as a `double[2]=
` should=20
<br>> call `foo` like this:
<br>>=20
<br>> double result[2];
<br>> to_double2(foo(data), result);
<br>>=20
<br>> That way, you don't have to write 20 different variations of `foo`=
..
<br>
<br>I find it more convenient to write utility overloads to accept data in =
a
<br>variety of formats, and I'm not the only API to do so. The difference i=
s
<br>I can write those overloads *once* and use them many times, compared to
<br>having to write call-site conversions many times.<br></blockquote><div>=
<br>That's your prerogative. But you should accept the <i>burden</i> of wan=
ting to do so: having to write all of those overloads.<br><br>The fact that=
one possible method of implementing something requires more effort than yo=
u'd like to expend is not a sufficient reason for requesting a syntactic ch=
ange.</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"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />
------=_Part_821_659103456.1432943820355--
------=_Part_820_842064398.1432943820355--
.
Author: Matthew Fioravante <fmatthew5876@gmail.com>
Date: Fri, 29 May 2015 19:59:07 -0700 (PDT)
Raw View
------=_Part_1216_1324260534.1432954747658
Content-Type: multipart/alternative;
boundary="----=_Part_1217_326277430.1432954747658"
------=_Part_1217_326277430.1432954747658
Content-Type: text/plain; charset=UTF-8
On Friday, May 29, 2015 at 7:57:00 PM UTC-4, Nicol Bolas wrote:
>
> On Friday, May 29, 2015 at 11:16:56 AM UTC-4, Matthew Woehlke wrote:
>>
>> On 2015-05-28 18:51, Nicol Bolas wrote:
>> > On Thursday, May 28, 2015 at 5:22:42 PM UTC-4, Matthew Woehlke wrote:
>> >> What I object to is:
>> >>
>> >>> auto x = Typename{FuncThatReturnsMultipleValues()};
>> >>
>> >> ...this. Here, I have to inspect FuncThatReturnsMultipleValues to know
>> >> that it returns multiple values. I object to that. I strongly would
>> >> prefer to require some syntax to indicate unpacking, e.g. '[*]' or
>> '...'
>> >> or whatever.
>> >
>> > Why should using `FuncThatReturnsOneValue` require less syntax than
>> > `FuncThatReturnsMultipleValues`?
>>
>> Because in no existing case can a single 'token' represent multiple
>> parameters without that being made obvious.
>>
>
> ... what?
>
> `FuncThatReturnsMultipleValues()` is not a "token"; it's *three* tokens.
> It's an identifier, followed by an open paren, followed by a close paren.
>
> You can consider this pedantic, but it's very hard to have a discussion
> about the standard if you use misuse standard terminology this badly.
>
> If by "token", you meant "expression", then you're correct. The result of
> an expression is, without multiple return values, a single value with a
> single type. Therefore, in order for MRVs to work, that will have to change.
>
> Obviously.
>
> The standard would have to be changed to allow the evaluation of a
> function call expression to be a value sequence, as defined by the
> function's return value sequence syntax. Value sequences would only be able
> to be used in certain locations, such as in the initialization of a
> variable(s) or in the argument list of an enclosing function call
> expression.
>
> There is no need for special expansion syntax at the site of the use of a
> value sequence for this to work.
>
>
>> To ask the opposite question, should we allow this?
>>
>> template <Typename Args...>
>> void foo(Args... args)
>> {
>> bar(args);
>> }
>>
>>
> I understand why they didn't. It's for two reasons:
>
> 1) You already need an explicit unpacking operation on packs, so that you
> can do cool expression expansion tricks.
>
> 2) Because of #1, it's really important that the user understands what
> they're asking for (the difference between `func(args...)` and
> `func(args)...`). Otherwise, they might expect `args` to be able to be used
> in places or ways it can't be.
>
> Since value sequences are not parameter packs, these don't have to apply.
>
But it seems to me that you might actually want to have this flexibility
even with MRV's. I might want to call a function, passing all of the return
values to it, or I might want to call a function separately for each return
value.
[int,int] f();
[int,int] g(int, int);
int h(int);
void i(int, int, int, int);
//Compose f and g and g again
g(g(f()...)...);
//Call h on each of f()'s return values and then forward the resulting
sequence to g().
g(h(f())...);
//f() produces 2 values, call g() on each of them separately to produce 4
values which is then forwarded to i().
i(g(f())...);
> One could use a tuple, but this whole discussion started because you
>> objected (loudly) to the extraneous copies that would incur.
>
>
> Then you've misunderstood the point.
>
> The primary justification for this feature was having multiple return
> values. It's *the title of the thread*. My point was that, by doing it as
> proposed (through std::tuple), it interferes with elision. Which it does.
>
> Remember: the elision problem was that the callee had some variable, which
> was being packed into a tuple, then unpacked into the caller's variable.
> The elision in question was the elision between the callee's variable and
> the caller's variable.
>
> Well, if the caller is storing the tuple as a *tuple*, rather than
> broadcasting the tuple elements into variables, this argument no longer
> applies.
>
>
>> In the
>> above example, I might even hope that the compiler makes no copies
>> (excluding when calling 'bar', and possibly with some '&'s added). I
>> would *especially* expect no copies if I wasn't slicing the value
>> sequence, but merely reusing it.
>>
>
> As previously stated, the standard *requires* this statement:
>
> auto x = get<0>(params);
>
> to call a constructor. Elision works *only* in cases where elision is
> expressly permitted. And this is in no way one of them.
>
> Not only that, elision in this case breaks all kinds of C++ guarantees. In
> your case, if the copy/move was elided, `x` and `params` would be sharing
> data.
>
If you wrote something like this:
[int,float] f();
[auto x; auto y] = f();
The tuple like thing returned by f() is a hidden object never directly
accessible by the programmer. The optimizer therefore should be able to
elide the copies and make x and y effectively aliases to the data members
of the unnamed tuple return object thing on the stack.
If you do this however, all bets are off unless you explicitly use
references
auto xy = f();
[auto x; auto y]=xy;
> Changing `x` would implicitly change `params`. I'm no authority on this
> matter, but I'm pretty sure that violates strict aliasing or some other C++
> guarantee.
>
>
>> > Um, I'm not talking about "unpacking syntax." Or rather, more to the
>> point,
>> > I don't *want* "unpacking syntax". Or packing syntax.
>> >
>> > I want MRV syntax. Packing and unpacking would not be syntax; they'd
>> just
>> > be function calls.
>>
>> What, then, is your equivalent to this?
>>
>> [auto x; auto y] = some_mrv_function();
>>
>
> Under MRV rules, that is not "unpacking" or "expansion", because
> `some_mrv_function` does not return a "packed" value that needs to be
> "unpacked" or "expanded". It returns *multiple values*.
>
> Under MRV, this is merely the syntax for storing multiple values.
>
> > So your use case for this syntax is translating values of structs
>> between
>> > different APIs?
>>
>> That's *a* use case.
>>
>> Here's another:
>>
>> [auto x; auto y] = [*]p;
>> x = sin(2*x) + cos(2*y);
>> y = sqrt(y);
>> return {x, y};
>>
>> Invented and somewhat simplified, but this is another case I run into
>> with moderate frequency ; given a "tuple-like" class (often one that does
>> not have public data members), I want to "crack" it into local variables
>> for various reasons; terseness, to avoid multiple invocations of
>> accessor methods, etc.
>>
>
> There's a word for that use case:
>
> Perfidy <http://dictionary.reference.com/browse/perfidy?db=*>.
>
> If you violate a class's interface, you are *committing fraud*. You had
> an agreement with the class, that you would follow its public interface.
> And you are knowingly and deliberately breaking that agreement.
>
Obviously compiler generated unpacking would only be allowed for standard
layout types with all public data members. If you want to support unpacking
for a class with private data members you'll have to write the operator
yourself.
>
> If you don't like a class's interface; that's your right. You can choose
> not to use it for that reason; that's also your right. It's not your right
> to back-door the class, break in, and do whatever you want with what you
> find.
>
> I know that C++ is not supposed to *prevent* perfidy. But we should not
> make perfidy literally *three keystrokes away*. What the hell good is
> public/private if anyone can bypass it all trivially?
>
> "We should have this because it makes it trivial for me to break
> encapsulation" is not a good argument for any feature. That's not to say
> that being able to use a feature to break the language makes the feature a
> priori wrong. But such uses should be necessary evils, not a prime
> motivator for having it.
>
> There is also, of course, the associative container iteration example.
>> I'm confident there are others I'm not thinking of offhand.
>>
>> > In your example above, a user who wants the result as a `double[2]`
>> should
>> > call `foo` like this:
>> >
>> > double result[2];
>> > to_double2(foo(data), result);
>> >
>> > That way, you don't have to write 20 different variations of `foo`.
>>
>> I find it more convenient to write utility overloads to accept data in a
>> variety of formats, and I'm not the only API to do so. The difference is
>> I can write those overloads *once* and use them many times, compared to
>> having to write call-site conversions many times.
>>
>
> That's your prerogative. But you should accept the *burden* of wanting to
> do so: having to write all of those overloads.
>
> The fact that one possible method of implementing something requires more
> effort than you'd like to expend is not a sufficient reason for requesting
> a syntactic change.
>
--
---
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 http://groups.google.com/a/isocpp.org/group/std-proposals/.
------=_Part_1217_326277430.1432954747658
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><br><br>On Friday, May 29, 2015 at 7:57:00 PM UTC-4, Nicol=
Bolas wrote:<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">=
On Friday, May 29, 2015 at 11:16:56 AM UTC-4, Matthew Woehlke wrote:<blockq=
uote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-left:=
1px #ccc solid;padding-left:1ex">On 2015-05-28 18:51, Nicol Bolas wrote:
<br>> On Thursday, May 28, 2015 at 5:22:42 PM UTC-4, Matthew Woehlke wro=
te:
<br>>> What I object to is:=20
<br>>>
<br>>>> auto x =3D Typename{<wbr>FuncThatReturnsMultipleValues(<wb=
r>)};=20
<br>>>
<br>>> ...this. Here, I have to inspect FuncThatReturnsMultipleValues=
to know=20
<br>>> that it returns multiple values. I object to that. I strongly =
would=20
<br>>> prefer to require some syntax to indicate unpacking, e.g. '[*]=
' or '...'=20
<br>>> or whatever.=20
<br>>=20
<br>> Why should using `FuncThatReturnsOneValue` require less syntax tha=
n=20
<br>> `<wbr>FuncThatReturnsMultipleValues`<wbr>?
<br>
<br>Because in no existing case can a single 'token' represent multiple
<br>parameters without that being made obvious.
<br></blockquote><div><br>... what?<br><br>`<wbr>FuncThatReturnsMultipleVal=
ues(<wbr>)` is not a "token"; it's <i>three</i> tokens. It's an identifier,=
followed by an open paren, followed by a close paren.<br><br>You can consi=
der this pedantic, but it's very hard to have a discussion about the standa=
rd if you use misuse standard terminology this badly.<br><br>If by "token",=
you meant "expression", then you're correct. The result of an expression i=
s, without multiple return values, a single value with a single type. There=
fore, in order for MRVs to work, that will have to change.<br><br>Obviously=
..<br><br>The standard would have to be changed to allow the evaluation of a=
function call expression to be a value sequence, as defined by the functio=
n's return value sequence syntax. Value sequences would only be able to be =
used in certain locations, such as in the initialization of a variable(s) o=
r in the argument list of an enclosing function call expression.<br><br>The=
re is no need for special expansion syntax at the site of the use of a valu=
e sequence for this to work.<br> </div><blockquote class=3D"gmail_quot=
e" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-l=
eft:1ex">
To ask the opposite question, should we allow this?
<br>
<br> template <Typename Args...>
<br> void foo(Args... args)
<br> {
<br> bar(args);
<br> }
<br>
<br></blockquote><div><br>I understand why they didn't. It's for two reason=
s:<br><br>1) You already need an explicit unpacking operation on packs, so =
that you can do cool expression expansion tricks.<br><br>2) Because of #1, =
it's really important that the user understands what they're asking for (th=
e difference between `func(args...)` and `func(args)...`). Otherwise, they =
might expect `args` to be able to be used in places or ways it can't be.<br=
><br>Since value sequences are not parameter packs, these don't have to app=
ly.<br></div></div></blockquote><div><br></div><div>But it seems to me that=
you might actually want to have this flexibility even with MRV's. I might =
want to call a function, passing all of the return values to it, or I might=
want to call a function separately for each return value.</div><div><br></=
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"><span style=3D"color: =
#660;" class=3D"styled-by-prettify">[</span><span style=3D"color: #008;" cl=
ass=3D"styled-by-prettify">int</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"color: #660;" class=3D"styled-by-pretti=
fy">]</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> f</s=
pan><span style=3D"color: #660;" class=3D"styled-by-prettify">();</span><sp=
an style=3D"color: #000;" class=3D"styled-by-prettify"><br></span><span sty=
le=3D"color: #660;" class=3D"styled-by-prettify">[</span><span style=3D"col=
or: #008;" class=3D"styled-by-prettify">int</span><span style=3D"color: #66=
0;" class=3D"styled-by-prettify">,</span><span style=3D"color: #008;" class=
=3D"styled-by-prettify">int</span><span style=3D"color: #660;" class=3D"sty=
led-by-prettify">]</span><span style=3D"color: #000;" class=3D"styled-by-pr=
ettify"> g</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"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: #008;" class=3D"styled-by-prettify">int</span><span style=3D"color: #6=
60;" class=3D"styled-by-prettify">);</span><span style=3D"color: #000;" cla=
ss=3D"styled-by-prettify"><br></span><span style=3D"color: #008;" class=3D"=
styled-by-prettify">int</span><span style=3D"color: #000;" class=3D"styled-=
by-prettify"> h</span><span style=3D"color: #660;" 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><s=
pan style=3D"color: #000;" class=3D"styled-by-prettify"><br></span><span st=
yle=3D"color: #008;" class=3D"styled-by-prettify">void</span><span style=3D=
"color: #000;" class=3D"styled-by-prettify"> i</span><span style=3D"color: =
#660;" class=3D"styled-by-prettify">(</span><span style=3D"color: #008;" cl=
ass=3D"styled-by-prettify">int</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=
">int</span><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: #008;" class=3D"styled-by-prettify">int</span><font color=
=3D"#000000"><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</span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">);</span></font><span style=
=3D"color: #000;" class=3D"styled-by-prettify"><br><br></span><span style=
=3D"color: #800;" class=3D"styled-by-prettify">//Compose f and g and g agai=
n</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br>g</sp=
an><span style=3D"color: #660;" class=3D"styled-by-prettify">(</span><span =
style=3D"color: #000;" class=3D"styled-by-prettify">g</span><span style=3D"=
color: #660;" class=3D"styled-by-prettify">(</span><span style=3D"color: #0=
00;" class=3D"styled-by-prettify">f</span><span style=3D"color: #660;" clas=
s=3D"styled-by-prettify">()...)...);</span><span style=3D"color: #000;" cla=
ss=3D"styled-by-prettify"><br><br></span><span style=3D"color: #800;" class=
=3D"styled-by-prettify">//Call h on each of f()'s return values and then fo=
rward the resulting sequence to g().</span><span style=3D"color: #000;" cla=
ss=3D"styled-by-prettify"><br>g</span><span style=3D"color: #660;" class=3D=
"styled-by-prettify">(</span><span style=3D"color: #000;" class=3D"styled-b=
y-prettify">h</span><span style=3D"color: #660;" class=3D"styled-by-prettif=
y">(</span><span style=3D"color: #000;" class=3D"styled-by-prettify">f</spa=
n><span style=3D"color: #660;" class=3D"styled-by-prettify">())...);</span>=
<span style=3D"color: #000;" class=3D"styled-by-prettify"><br><br></span><s=
pan style=3D"color: #800;" class=3D"styled-by-prettify">//f() produces 2 va=
lues, call g() on each of them separately to produce 4 values which is then=
forwarded to i().</span><span style=3D"color: #000;" class=3D"styled-by-pr=
ettify"><br>i</span><span style=3D"color: #660;" class=3D"styled-by-prettif=
y">(</span><span style=3D"color: #000;" class=3D"styled-by-prettify">g</spa=
n><span style=3D"color: #660;" class=3D"styled-by-prettify">(</span><span s=
tyle=3D"color: #000;" class=3D"styled-by-prettify">f</span><span style=3D"c=
olor: #660;" class=3D"styled-by-prettify">())...);</span><span style=3D"col=
or: #000;" class=3D"styled-by-prettify"><br><br></span></div></code></div><=
div><br></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"><div><br></div><blockquote class=3D"gmail_quote" style=3D"margin=
:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-left:1ex">One could=
use a tuple, but this whole discussion started because you
<br>objected (loudly) to the extraneous copies that would incur.</blockquot=
e><div><br>Then you've misunderstood the point.<br><br>The primary justific=
ation for this feature was having multiple return values. It's <i>the title=
of the thread</i>. My point was that, by doing it as proposed (through std=
::tuple), it interferes with elision. Which it does.<br><br>Remember: the e=
lision problem was that the callee had some variable, which was being packe=
d into a tuple, then unpacked into the caller's variable. The elision in qu=
estion was the elision between the callee's variable and the caller's varia=
ble.<br><br>Well, if the caller is storing the tuple as a <i>tuple</i>, rat=
her than broadcasting the tuple elements into variables, this argument no l=
onger applies.<br> </div><blockquote class=3D"gmail_quote" style=3D"ma=
rgin:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-left:1ex">In th=
e
<br>above example, I might even hope that the compiler makes no copies
<br>(excluding when calling 'bar', and possibly with some '&'s added). =
I
<br>would *especially* expect no copies if I wasn't slicing the value
<br>sequence, but merely reusing it.<br></blockquote><div><br>As previously=
stated, the standard <i>requires</i> this statement:<br><br><div style=3D"=
background-color:rgb(250,250,250);border-color:rgb(187,187,187);border-styl=
e:solid;border-width:1px;word-wrap:break-word"><code><div><span style=3D"co=
lor:#008">auto</span><span style=3D"color:#000"> x </span><span style=3D"co=
lor:#660">=3D</span><span style=3D"color:#000"> </span><span style=3D"color=
:#008">get</span><span style=3D"color:#660"><</span><span style=3D"color=
:#066">0</span><span style=3D"color:#660">>(</span><span style=3D"color:=
#008">params</span><span style=3D"color:#660">);</span></div></code></div><=
br>to call a constructor. Elision works <i>only</i> in cases where elision =
is expressly permitted. And this is in no way one of them.<br><br>Not only =
that, elision in this case breaks all kinds of C++ guarantees. In your case=
, if the copy/move was elided, `x` and `params` would be sharing data. =
;</div></div></blockquote><div><br></div><div>If you wrote something like t=
his:</div><div><br></div><div><div class=3D"prettyprint" style=3D"border: 1=
px solid rgb(187, 187, 187); word-wrap: break-word; background-color: rgb(2=
50, 250, 250);"><code class=3D"prettyprint"><div class=3D"subprettyprint"><=
span style=3D"color: #660;" class=3D"styled-by-prettify">[</span><span styl=
e=3D"color: #008;" class=3D"styled-by-prettify">int</span><span style=3D"co=
lor: #660;" class=3D"styled-by-prettify">,</span><font color=3D"#000000"><s=
pan style=3D"color: #008;" class=3D"styled-by-prettify">float</span><span s=
tyle=3D"color: #660;" class=3D"styled-by-prettify">]</span><span style=3D"c=
olor: #000;" class=3D"styled-by-prettify"> f</span><span style=3D"color: #6=
60;" 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: #008;" class=3D"styled-b=
y-prettify">auto</span><span style=3D"color: #000;" class=3D"styled-by-pret=
tify"> x</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">auto</span><span sty=
le=3D"color: #000;" class=3D"styled-by-prettify"> y</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: #660;" class=
=3D"styled-by-prettify">=3D</span><span style=3D"color: #000;" class=3D"sty=
led-by-prettify"> f</span><span style=3D"color: #660;" class=3D"styled-by-p=
rettify">();</span></font></div></code></div><br>The tuple like thing retur=
ned by f() is a hidden object never directly accessible by the programmer. =
The optimizer therefore should be able to elide the copies and make x and y=
effectively aliases to the data members of the unnamed tuple return object=
thing on the stack.</div><div><br></div><div>If you do this however, all b=
ets are off unless you explicitly use references</div><div><div class=3D"pr=
ettyprint" style=3D"border: 1px solid rgb(187, 187, 187); word-wrap: break-=
word; background-color: rgb(250, 250, 250);"><code class=3D"prettyprint"><d=
iv class=3D"subprettyprint"><font color=3D"#660066"><span style=3D"color: #=
008;" class=3D"styled-by-prettify">auto</span><span style=3D"color: #000;" =
class=3D"styled-by-prettify"> xy </span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">=3D</span><span style=3D"color: #000;" class=3D"sty=
led-by-prettify"> f</span><span style=3D"color: #660;" class=3D"styled-by-p=
rettify">();</span><span style=3D"color: #000;" class=3D"styled-by-prettify=
"><br></span><span style=3D"color: #660;" class=3D"styled-by-prettify">[</s=
pan><span style=3D"color: #008;" class=3D"styled-by-prettify">auto</span><s=
pan style=3D"color: #000;" class=3D"styled-by-prettify"> x</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: #008;"=
class=3D"styled-by-prettify">auto</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"> y</span><span style=3D"color: #660;" class=3D"styl=
ed-by-prettify">]=3D</span><span style=3D"color: #000;" class=3D"styled-by-=
prettify">xy</span><span style=3D"color: #660;" class=3D"styled-by-prettify=
">;</span></font></div></code></div><br><br></div><div> </div><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>Changing `x` wou=
ld implicitly change `params`. I'm no authority on this matter, but I'm pre=
tty sure that violates strict aliasing or some other C++ guarantee.<br>&nbs=
p;</div><blockquote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8=
ex;border-left:1px #ccc solid;padding-left:1ex">
> Um, I'm not talking about "unpacking syntax." Or rather, more to the p=
oint,=20
<br>> I don't *want* "unpacking syntax". Or packing syntax.
<br>>=20
<br>> I want MRV syntax. Packing and unpacking would not be syntax; they=
'd just=20
<br>> be function calls.
<br>
<br>What, then, is your equivalent to this?
<br>
<br> [auto x; auto y] =3D some_mrv_function();
<br></blockquote><div><br>Under MRV rules, that is not "unpacking" or "expa=
nsion", because `some_mrv_function` does not return a "packed" value that n=
eeds to be "unpacked" or "expanded". It returns <i>multiple values</i>.<br>=
<br>Under MRV, this is merely the syntax for storing multiple values.<br><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">
> So your use case for this syntax is translating values of structs betw=
een=20
<br>> different APIs?
<br>
<br>That's *a* use case.
<br>
<br>Here's another:
<br>
<br> [auto x; auto y] =3D [*]p;
<br> x =3D sin(2*x) + cos(2*y);
<br> y =3D sqrt(y);
<br> return {x, y};
<br>
<br>Invented and somewhat simplified, but this is another case I run into
<br>with moderate frequency ; given a "tuple-like" class (often one that do=
es
<br>not have public data members), I want to "crack" it into local variable=
s
<br>for various reasons; terseness, to avoid multiple invocations of
<br>accessor methods, etc.<br></blockquote><div><br>There's a word for that=
use case:<br><br><a href=3D"http://dictionary.reference.com/browse/perfidy=
?db=3D*" target=3D"_blank" rel=3D"nofollow" onmousedown=3D"this.href=3D'htt=
p://www.google.com/url?q\75http%3A%2F%2Fdictionary.reference.com%2Fbrowse%2=
Fperfidy%3Fdb%3D*\46sa\75D\46sntz\0751\46usg\75AFQjCNFgtV1sgAWaHPFDjWUTiuBM=
1gYH9w';return true;" onclick=3D"this.href=3D'http://www.google.com/url?q\7=
5http%3A%2F%2Fdictionary.reference.com%2Fbrowse%2Fperfidy%3Fdb%3D*\46sa\75D=
\46sntz\0751\46usg\75AFQjCNFgtV1sgAWaHPFDjWUTiuBM1gYH9w';return true;">Perf=
idy</a>.<br><br>If you violate a class's interface, you are <i>committing f=
raud</i>. You had an agreement with the class, that you would follow its pu=
blic interface. And you are knowingly and deliberately breaking that agreem=
ent.<br></div></div></blockquote><div><br></div><div>Obviously compiler gen=
erated unpacking would only be allowed for standard layout types with all p=
ublic data members. If you want to support unpacking for a class with priva=
te data members you'll have to write the operator yourself.</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><=
br>If you don't like a class's interface; that's your right. You can choose=
not to use it for that reason; that's also your right. It's not your right=
to back-door the class, break in, and do whatever you want with what you f=
ind.<br><br>I know that C++ is not supposed to <i>prevent</i> perfidy. But =
we should not make perfidy literally <i>three keystrokes away</i>. What the=
hell good is public/private if anyone can bypass it all trivially?<br><br>=
"We should have this because it makes it trivial for me to break encapsulat=
ion" is not a good argument for any feature. That's not to say that being a=
ble to use a feature to break the language makes the feature a priori wrong=
.. But such uses should be necessary evils, not a prime motivator for having=
it.<br><br></div><blockquote class=3D"gmail_quote" style=3D"margin:0;margi=
n-left:0.8ex;border-left:1px #ccc solid;padding-left:1ex">
There is also, of course, the associative container iteration example.
<br>I'm confident there are others I'm not thinking of offhand.
<br>
<br>> In your example above, a user who wants the result as a `double[2]=
` should=20
<br>> call `foo` like this:
<br>>=20
<br>> double result[2];
<br>> to_double2(foo(data), result);
<br>>=20
<br>> That way, you don't have to write 20 different variations of `foo`=
..
<br>
<br>I find it more convenient to write utility overloads to accept data in =
a
<br>variety of formats, and I'm not the only API to do so. The difference i=
s
<br>I can write those overloads *once* and use them many times, compared to
<br>having to write call-site conversions many times.<br></blockquote><div>=
<br>That's your prerogative. But you should accept the <i>burden</i> of wan=
ting to do so: having to write all of those overloads. </div></div></b=
lockquote><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"><di=
v><br>The fact that one possible method of implementing something requires =
more effort than you'd like to expend is not a sufficient reason for reques=
ting a syntactic change.</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"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />
------=_Part_1217_326277430.1432954747658--
------=_Part_1216_1324260534.1432954747658--
.
Author: Matthew Woehlke <mw_triad@users.sourceforge.net>
Date: Sat, 30 May 2015 12:26:11 -0400
Raw View
On 2015-05-29 22:59, Matthew Fioravante wrote:
> On Friday, May 29, 2015 at 7:57:00 PM UTC-4, Nicol Bolas wrote:
>> As previously stated, the standard *requires* this statement:
>>
>> auto x =3D get<0>(params);
>>
>> to call a constructor. Elision works *only* in cases where elision is=20
>> expressly permitted. And this is in no way one of them.
>>
>> Not only that, elision in this case breaks all kinds of C++ guarantees. =
In=20
>> your case, if the copy/move was elided, `x` and `params` would be sharin=
g=20
>> data.=20
>=20
> If you wrote something like this:
>=20
> [int,float] f();
> [auto x; auto y] =3D f();
>=20
> The tuple like thing returned by f() is a hidden object never directly=20
> accessible by the programmer. The optimizer therefore should be able to=
=20
> elide the copies and make x and y effectively aliases to the data members=
=20
> of the unnamed tuple return object thing on the stack.
>=20
> If you do this however, all bets are off unless you explicitly use=20
> references
> auto xy =3D f();
> [auto x; auto y]=3Dxy;
Right:
// Full elision
[auto x; auto y] =3D foo();
// Elision for 'x', copy for 'y'
Bar y;
[auto x; y] =3D foo();
// Elision for 'xy', copy for 'x' and 'y'
auto xy =3D foo();
[auto x; auto y] =3D xy;
>> On Friday, May 29, 2015 at 11:16:56 AM UTC-4, Matthew Woehlke wrote:
>>> Here's another [use case]:=20
>>>
>>> [auto x; auto y] =3D [*]p;=20
>>> x =3D sin(2*x) + cos(2*y);=20
>>> y =3D sqrt(y);=20
>>> return {x, y};=20
>>
>> If you violate a class's interface, you are *committing fraud*. You had=
=20
>> an agreement with the class, that you would follow its public interface.=
=20
>> And you are knowingly and deliberately breaking that agreement.
>=20
> Obviously compiler generated unpacking would only be allowed for standard=
=20
> layout types with all public data members. If you want to support unpacki=
ng=20
> for a class with private data members you'll have to write the operator=
=20
> yourself.
Er... right. Nicol, you're adding scary things to my proposal that *are
not part of it*. Unpacking is not magic. For the above to work requires
that get<N> is implemented (somewhere) for the type (or the type has a
conversion-to-tuple-like operator as has been mentioned a few times).
The mechanism for extracting "values" therefore either *is=C2=B9* part of t=
he
type's public API, or must be written against the type's public API.
(=C2=B9 Unless you implement get<N> with nasty protection-bypassing code, b=
ut
then, that's not unpacking's fault that you did that.)
In particular, this additional code was implied:
int get<0>(QPoint const& p) { return p.x(); }
int get<1>(QPoint const& p) { return p.y(); }
--=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 http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.
.
Author: Matthew Woehlke <mw_triad@users.sourceforge.net>
Date: Sat, 30 May 2015 12:34:54 -0400
Raw View
On 2015-05-29 19:57, Nicol Bolas wrote:
> On Friday, May 29, 2015 at 11:16:56 AM UTC-4, Matthew Woehlke wrote:
>> On 2015-05-28 18:51, Nicol Bolas wrote:=20
>>> Why should using `FuncThatReturnsOneValue` require less syntax than=20
>>> `FuncThatReturnsMultipleValues`?=20
>>
>> Because in no existing case can a single 'token' represent multiple=20
>> parameters without that being made obvious.=20
>=20
> ... what?
>=20
> `FuncThatReturnsMultipleValues()` is not a "token"; it's *three* tokens.=
=20
> It's an identifier, followed by an open paren, followed by a close paren.
(OT: Do you have *any idea* how annoying it is when you do this? I'm
trying to talk in abstract concepts, okay? It's frustratingly difficult
to do that when a) all the terminology that naturally lends itself to
doing so has already been "coopted" to have some specific meaning in
standardese, which b) you must insist on applying.)
s/token/conceptual unit in the mind of the developer/
....is that better?
> If by "token", you meant "expression", then you're correct.
....and last time I used "expression" you complained at me for that too.
/me sighs
> The result of an expression is, without multiple return values, a
> single value with a single type. Therefore, in order for MRVs to
> work, that will have to change.
Yes, it would have to change. That is a big part of my objection.
> There is no need for special expansion syntax at the site of the use of a=
=20
> value sequence for this to work.
From a technical perspective, no. It's the cognative perspective that
bothers me.
>> One could use a tuple, but this whole discussion started because you=20
>> objected (loudly) to the extraneous copies that would incur.
>=20
> Then you've misunderstood the point.
>=20
> The primary justification for this feature was having multiple return=20
> values. It's *the title of the thread*.
Yes, but the *feature* was *multiple assignments*. (That's *also* in the
title of the thread. First, in fact.) AFAICT you are trying to kill, or
needlessly cripple, that.
> My point was that, by doing it as proposed (through std::tuple), it
> interferes with elision. Which it does.
We agree that std::tuple is not optimal for MRV's. Please stop beating
on the point.
The proposal is to do unpacking for *anything that can be unpacked*, for
whatever that means (e.g. get<N>, conversion operator, something
else...). That would include std::tuple, std::pair, std::array, any user
types that provide support for it, and whatever we use as the 'optimal
mechanism for MRV's'.
>> What, then, is your equivalent to this?=20
>>
>> [auto x; auto y] =3D some_mrv_function();=20
>=20
> Under MRV rules, that is not "unpacking" or "expansion", because=20
> `some_mrv_function` does not return a "packed" value that needs to be=20
> "unpacked" or "expanded". It returns *multiple values*.
>=20
> Under MRV, this is merely the syntax for storing multiple values.
So, you are saying you *still* want unpacking syntax=C2=B9, you just only
want it to work for MRV's? Why? What is the benefit to limiting it in
such manner? (As previously explained, I don't buy the "syntax is
precious" argument.)
(=C2=B9 Syntax which performs multiple declarations/assignments from some
conceptual construction of multiple values, e.g. MRV functions.)
--=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 http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.
.
Author: Nicol Bolas <jmckesson@gmail.com>
Date: Mon, 1 Jun 2015 09:01:53 -0700 (PDT)
Raw View
------=_Part_296_706968092.1433174513625
Content-Type: multipart/alternative;
boundary="----=_Part_297_2133187040.1433174513626"
------=_Part_297_2133187040.1433174513626
Content-Type: text/plain; charset=UTF-8
On Saturday, May 30, 2015 at 12:26:23 PM UTC-4, Matthew Woehlke wrote:
>
> On 2015-05-29 22:59, Matthew Fioravante wrote:
> >
> >> On Friday, May 29, 2015 at 11:16:56 AM UTC-4, Matthew Woehlke wrote:
> >>> Here's another [use case]:
> >>>
> >>> [auto x; auto y] = [*]p;
> >>> x = sin(2*x) + cos(2*y);
> >>> y = sqrt(y);
> >>> return {x, y};
> >>
> >> If you violate a class's interface, you are *committing fraud*. You had
> >> an agreement with the class, that you would follow its public
> interface.
> >> And you are knowingly and deliberately breaking that agreement.
> >
> > Obviously compiler generated unpacking would only be allowed for
> standard
> > layout types with all public data members. If you want to support
> unpacking
> > for a class with private data members you'll have to write the operator
> > yourself.
>
> Er... right. Nicol, you're adding scary things to my proposal that *are
> not part of it*.
Matthew's the one wanting to use unpacking to break encapsulationHe was the
one I was responding to. He specifically stated that in his post: "I want
to "crack" it into local variables
for various reasons; terseness,
*to avoid multiple invocations ofaccessor methods*, etc" (emphasis added).
You can't avoid accessor invocations without breaking encapsulation.
--
---
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 http://groups.google.com/a/isocpp.org/group/std-proposals/.
------=_Part_297_2133187040.1433174513626
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><br><br>On Saturday, May 30, 2015 at 12:26:23 PM UTC-4, Ma=
tthew Woehlke wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;ma=
rgin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">On 2015-05=
-29 22:59, Matthew Fioravante wrote:
<br>> <br>>> On Friday, May 29, 2015 at 11:16:56 AM UTC-4, Matthew=
Woehlke wrote:
<br>>>> Here's another [use case]:=20
<br>>>>
<br>>>> [auto x; auto y] =3D [*]p;=20
<br>>>> x =3D sin(2*x) + cos(2*y);=20
<br>>>> y =3D sqrt(y);=20
<br>>>> return {x, y};=20
<br>>>
<br>>> If you violate a class's interface, you are *committing fraud*=
.. You had=20
<br>>> an agreement with the class, that you would follow its public =
interface.=20
<br>>> And you are knowingly and deliberately breaking that agreement=
..
<br>>=20
<br>> Obviously compiler generated unpacking would only be allowed for s=
tandard=20
<br>> layout types with all public data members. If you want to support =
unpacking=20
<br>> for a class with private data members you'll have to write the ope=
rator=20
<br>> yourself.
<br>
<br>Er... right. Nicol, you're adding scary things to my proposal that *are
<br>not part of it*.</blockquote><div><br>Matthew's the one wanting to use =
unpacking to break encapsulationHe was the one I was responding to. He spec=
ifically stated that in his post: "I want to "crack" it into local variable=
s<br>for various reasons; terseness, <b>to avoid multiple invocations of<br=
>accessor methods</b>, etc" (emphasis added). You can't avoid accessor invo=
cations without breaking encapsulation.<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"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />
------=_Part_297_2133187040.1433174513626--
------=_Part_296_706968092.1433174513625--
.
Author: Nicol Bolas <jmckesson@gmail.com>
Date: Mon, 1 Jun 2015 09:15:37 -0700 (PDT)
Raw View
------=_Part_3583_2014196856.1433175337039
Content-Type: multipart/alternative;
boundary="----=_Part_3584_1821831131.1433175337040"
------=_Part_3584_1821831131.1433175337040
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
On Saturday, May 30, 2015 at 12:35:06 PM UTC-4, Matthew Woehlke wrote:
>
> On 2015-05-29 19:57, Nicol Bolas wrote:=20
> > On Friday, May 29, 2015 at 11:16:56 AM UTC-4, Matthew Woehlke wrote:=20
> >> On 2015-05-28 18:51, Nicol Bolas wrote:=20
> >>> Why should using `FuncThatReturnsOneValue` require less syntax than=
=20
> >>> `FuncThatReturnsMultipleValues`?=20
> >>=20
> >> Because in no existing case can a single 'token' represent multiple=20
> >> parameters without that being made obvious.=20
> >=20
> > ... what?=20
> >=20
> > `FuncThatReturnsMultipleValues()` is not a "token"; it's *three* tokens=
..=20
> > It's an identifier, followed by an open paren, followed by a close=20
> paren.=20
>
> (OT: Do you have *any idea* how annoying it is when you do this? I'm=20
> trying to talk in abstract concepts, okay? It's frustratingly difficult=
=20
> to do that when a) all the terminology that naturally lends itself to=20
> doing so has already been "coopted" to have some specific meaning in=20
> standardese, which b) you must insist on applying.)
>
Do you know how annoying it is when people are having a detailed discussion=
=20
of the standard, yet use standardese incorrectly? I can't know what you=20
mean by "token" means if you're using some colloquial definition of the=20
term.
> If by "token", you meant "expression", then you're correct.=20
>
> ...and last time I used "expression" you complained at me for that too.
>
*Because it wasn't an expression!* I never said "never use the word=20
'expression'". I said "braced-init-lists are not an expression."
> > The result of an expression is, without multiple return values, a=20
> > single value with a single type. Therefore, in order for MRVs to=20
> > work, that will have to change.=20
>
> Yes, it would have to change. That is a big part of my objection.
>
.... why?
>> One could use a tuple, but this whole discussion started because you=20
> >> objected (loudly) to the extraneous copies that would incur.=20
> >=20
> > Then you've misunderstood the point.=20
> >=20
> > The primary justification for this feature was having multiple return=
=20
> > values. It's *the title of the thread*.=20
>
> Yes, but the *feature* was *multiple assignments*. (That's *also* in the=
=20
> title of the thread. First, in fact.) AFAICT you are trying to kill, or=
=20
> needlessly cripple, that.
>
No, I'm trying to kill the "via tuple" part. I want "Multiple assignments=
=20
from multiple return values, as a first-class language feature."
>> What, then, is your equivalent to this?=20
> >>=20
> >> [auto x; auto y] =3D some_mrv_function();=20
> >=20
> > Under MRV rules, that is not "unpacking" or "expansion", because=20
> > `some_mrv_function` does not return a "packed" value that needs to be=
=20
> > "unpacked" or "expanded". It returns *multiple values*.=20
> >=20
> > Under MRV, this is merely the syntax for storing multiple values.=20
>
> So, you are saying you *still* want unpacking syntax=C2=B9, you just only=
=20
> want it to work for MRV's? Why? What is the benefit to limiting it in=20
> such manner? (As previously explained, I don't buy the "syntax is=20
> precious" argument.)
>
You can choose not to buy it, but that doesn't make it false.
If the syntax gets thrown away on "unpacking packed objects" (as opposed to=
=20
"storing multiple values"), then there will be no syntax left to have=20
actual MRVs as a first-class language feature. So they're not "orthogonal"=
=20
in any way; the syntactic presence of one precludes the possibility,=20
viability, and utility of the other.
If there can be only one, I want real MRVs, not "unpacking packed objects".=
=20
If we need the latter, we can create a function that returns multiple=20
values, representing the members of the object. Unpacking packed objects is=
=20
not a useful enough to promote to the level of syntax. Just like `tuple` is=
=20
not important enough to make it a language feature rather than just a=20
useful class.
--=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 http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.
------=_Part_3584_1821831131.1433175337040
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">On Saturday, May 30, 2015 at 12:35:06 PM UTC-4, Matthew Wo=
ehlke wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-lef=
t: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">On 2015-05-29 19:5=
7, Nicol Bolas wrote:
<br>> On Friday, May 29, 2015 at 11:16:56 AM UTC-4, Matthew Woehlke wrot=
e:
<br>>> On 2015-05-28 18:51, Nicol Bolas wrote:=20
<br>>>> Why should using `FuncThatReturnsOneValue` require less sy=
ntax than=20
<br>>>> `<wbr>FuncThatReturnsMultipleValues`<wbr>?=20
<br>>>
<br>>> Because in no existing case can a single 'token' represent mul=
tiple=20
<br>>> parameters without that being made obvious.=20
<br>>=20
<br>> ... what?
<br>>=20
<br>> `<wbr>FuncThatReturnsMultipleValues(<wbr>)` is not a "token"; it's=
*three* tokens.=20
<br>> It's an identifier, followed by an open paren, followed by a close=
paren.
<br>
<br>(OT: Do you have *any idea* how annoying it is when you do this? I'm
<br>trying to talk in abstract concepts, okay? It's frustratingly difficult
<br>to do that when a) all the terminology that naturally lends itself to
<br>doing so has already been "coopted" to have some specific meaning in
<br>standardese, which b) you must insist on applying.)<br></blockquote><di=
v><br>Do you know how annoying it is when people are having a detailed disc=
ussion of the standard, yet use standardese incorrectly? I can't know what =
you mean by "token" means if you're using some colloquial definition of the=
term.<br><br></div><blockquote class=3D"gmail_quote" style=3D"margin: 0;ma=
rgin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">> If by=
"token", you meant "expression", then you're correct.
<br>
<br>...and last time I used "expression" you complained at me for that too.=
<br></blockquote><div><br><i>Because it wasn't an expression!</i> I never s=
aid "never use the word 'expression'". I said "braced-init-lists are not an=
expression."<br><br></div><blockquote class=3D"gmail_quote" style=3D"margi=
n: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">
<br>> The result of an expression is, without multiple return values, a
<br>> single value with a single type. Therefore, in order for MRVs to
<br>> work, that will have to change.
<br>
<br>Yes, it would have to change. That is a big part of my objection.<br></=
blockquote><div><br>... why?<br><br></div><blockquote class=3D"gmail_quote"=
style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-=
left: 1ex;">
>> One could use a tuple, but this whole discussion started because y=
ou=20
<br>>> objected (loudly) to the extraneous copies that would incur.
<br>>=20
<br>> Then you've misunderstood the point.
<br>>=20
<br>> The primary justification for this feature was having multiple ret=
urn=20
<br>> values. It's *the title of the thread*.
<br>
<br>Yes, but the *feature* was *multiple assignments*. (That's *also* in th=
e
<br>title of the thread. First, in fact.) AFAICT you are trying to kill, or
<br>needlessly cripple, that.<br></blockquote><div><br>No, I'm trying to ki=
ll the "via tuple" part. I want "Multiple assignments from multiple return =
values, as a first-class language feature."<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;">
>> What, then, is your equivalent to this?=20
<br>>>
<br>>> [auto x; auto y] =3D some_mrv_function();=20
<br>>=20
<br>> Under MRV rules, that is not "unpacking" or "expansion", because=
=20
<br>> `some_mrv_function` does not return a "packed" value that needs to=
be=20
<br>> "unpacked" or "expanded". It returns *multiple values*.
<br>>=20
<br>> Under MRV, this is merely the syntax for storing multiple values.
<br>
<br>So, you are saying you *still* want unpacking syntax=C2=B9, you just on=
ly
<br>want it to work for MRV's? Why? What is the benefit to limiting it in
<br>such manner? (As previously explained, I don't buy the "syntax is
<br>precious" argument.)<br></blockquote><div><br>You can choose not to buy=
it, but that doesn't make it false.<br><br>If the syntax gets thrown away =
on "unpacking packed objects" (as opposed to "storing multiple values"), th=
en there will be no syntax left to have actual MRVs as a first-class langua=
ge feature. So they're not "orthogonal" in any way; the syntactic presence =
of one precludes the possibility, viability, and utility of the other.<br><=
br>If there can be only one, I want real MRVs, not "unpacking packed object=
s". If we need the latter, we can create a function that returns multiple v=
alues, representing the members of the object. Unpacking packed objects is =
not a useful enough to promote to the level of syntax. Just like `tuple` is=
not important enough to make it a language feature rather than just a usef=
ul class.<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"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />
------=_Part_3584_1821831131.1433175337040--
------=_Part_3583_2014196856.1433175337039--
.
Author: Matthew Woehlke <mw_triad@users.sourceforge.net>
Date: Mon, 01 Jun 2015 12:25:55 -0400
Raw View
On 2015-06-01 12:01, Nicol Bolas wrote:
> Matthew's the one wanting to use unpacking to break encapsulation. He was the
> one I was responding to. He specifically stated that in his post:
>
>> I want to "crack" it into local variables for various reasons; terseness,
>> *to avoid multiple invocations ofaccessor methods*, etc.
>
> (Emphasis added.) You can't avoid accessor invocations without breaking encapsulation.
No, you're still misinterpreting. Also, by presuming to tell me what *I*
want, you're deliberately putting words in my mouth. In, I would add,
direct contradiction to my previous post. Stop that.
The key word there *is not* "invocation", it is *"multiple"*.
As in this (eliding the second variable for brevity):
auto x = p.x();
x = x * x - sin(x);
return {x}
....vs. this:
return { p.x() * p.x() - sin(p.x()) };
Please go back and re-read my previous post which explains how my
proposed unpacking is merely shorthand for the above form and does not
in any way violate encapsulation.
--
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 http://groups.google.com/a/isocpp.org/group/std-proposals/.
.
Author: Matthew Woehlke <mw_triad@users.sourceforge.net>
Date: Mon, 01 Jun 2015 12:51:29 -0400
Raw View
On 2015-06-01 12:15, Nicol Bolas wrote:
> On Saturday, May 30, 2015 at 12:35:06 PM UTC-4, Matthew Woehlke wrote:
>> On 2015-05-29 19:57, Nicol Bolas wrote:=20
>>> The result of an expression is, without multiple return values, a=20
>>> single value with a single type. Therefore, in order for MRVs to=20
>>> work, that will have to change.=20
>>
>> Yes, it would have to change. That is a big part of my objection.
>=20
> ... why?
Because 'foo()' "looks like" a single semantic "thing". And right now it
always *means* a single semantic thing. You propose to make it possible
for it to suddenly mean *multiple* semantic things, with no indication
to the reader.
>>> The primary justification for this feature was having multiple return=
=20
>>> values. It's *the title of the thread*.=20
>>
>> Yes, but the *feature* was *multiple assignments*. (That's *also* in the=
=20
>> title of the thread. First, in fact.) AFAICT you are trying to kill, or=
=20
>> needlessly cripple, that.
>=20
> No, I'm trying to kill the "via tuple" part.
Then why do you object to MRV's being tuple-like? Or to generic
unpacking? Neither of these relate to "trying to kill the 'via tuple' part"=
..
I want three things, all of which IMO can, and probably should, be
separate proposals:
1. Generic unpacking, i.e. multiple assignment from a "container".
2. A better (i.e. RVO-friendly) way to return multiple values without
the need to declare a struct for the purpose.
3. The ability to expand a "container" into multiple "values", e.g. as
function call arguments, or within a brace initializer list.
Each of these is made more valuable by the others, but each is also
useful by itself. None has an absolute dependency on another. (Not even
syntactically, I assert; see below.)
>> So, you are saying you *still* want unpacking syntax=C2=B9, you just onl=
y=20
>> want it to work for MRV's? Why? What is the benefit to limiting it in=20
>> such manner? (As previously explained, I don't buy the "syntax is=20
>> precious" argument.)
>=20
> You can choose not to buy it, but that doesn't make it false.
You are asking for this:
auto t =3D make_tuple(...);
[auto x; void; y] =3D foo(); // Legal
[auto a; void; b] =3D t; // Illegal / reserved for future use
Really? Leaving aside the compiler complexity arguments, I'd be inclined
to reject that just on the basis of the confusion it is likely to cause.
Context-sensitive syntax has a high cognitive burden. That is much less
an issue for context-sensitive keywords. (For one, most people will
pretend that they are just keywords, and not use them otherwise.)
As a code writer, I look at the above and want to know why the second
one doesn't work.
> If the syntax gets thrown away on "unpacking packed objects" (as opposed =
to=20
> "storing multiple values"), then there will be no syntax left to have=20
> actual MRVs as a first-class language feature. So they're not "orthogonal=
"=20
> in any way; the syntactic presence of one precludes the possibility,=20
> viability, and utility of the other.
If you said that [expr; ...] is only multiple assignment *if followed by
'=3D'*, and means something else otherwise, I'd be okay with that. And in
particular, 'something else' can be MRV return specification. (In either
case, the restriction 'at the start of a LOC' can and probably should
apply.)
....But that also means there is no reason to limit the RHS of the
assignment to MRV's.
Are we *really* having this conversation because I neglected to mandate
the '=3D'?
(Even more pedantic: the full specification of the syntax in question is
"[" <lvalue-expression or declaration> [ ";" ... ] "]" "=3D". So the
syntax "[" <type specifier> [ ";" ... ] "]" is still available.)
It should be obvious that it was never the intent to coopt the '['
symbol as the first symbol without limitation. At least, there is the
implied restriction that the meaning of "[a]0" - abomination though it
may be :-) - is not changed.
--=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 http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.
.
Author: Nicol Bolas <jmckesson@gmail.com>
Date: Mon, 1 Jun 2015 18:06:01 -0700 (PDT)
Raw View
------=_Part_4447_918554730.1433207162010
Content-Type: multipart/alternative;
boundary="----=_Part_4448_422756189.1433207162010"
------=_Part_4448_422756189.1433207162010
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
On Monday, June 1, 2015 at 12:51:41 PM UTC-4, Matthew Woehlke wrote:
>
> On 2015-06-01 12:15, Nicol Bolas wrote:=20
> > On Saturday, May 30, 2015 at 12:35:06 PM UTC-4, Matthew Woehlke wrote:=
=20
> >> On 2015-05-29 19:57, Nicol Bolas wrote:=20
> >>> The result of an expression is, without multiple return values, a=20
> >>> single value with a single type. Therefore, in order for MRVs to=20
> >>> work, that will have to change.=20
> >>=20
> >> Yes, it would have to change. That is a big part of my objection.=20
> >=20
> > ... why?=20
>
> Because 'foo()' "looks like" a single semantic "thing". And right now it=
=20
> always *means* a single semantic thing. You propose to make it possible=
=20
> for it to suddenly mean *multiple* semantic things, with no indication=20
> to the reader.
>
I've been using Lua for years, and it never bothered me. Indeed, the only=
=20
things that bother me about Lua's MRV syntax are certain places where it's=
=20
not orthogonal (these are complex to explain, and none of them are=20
necessary for C++).
So it seems to me that it's more a matter of what you're used to/expect=20
than a general problem with the concept.
And it should be noted that you're trying to adopt this view as well. You=
=20
want to treat a tuple as semantically indistinguishable from its component=
=20
parts; to you, the tuple is an implementation detail of dealing with value=
=20
sequences. That is the very core of the title of your thread: multiple=20
assignments, multiple *semantic* values, via one *syntactic* value.
All I'm saying is that the implementation detail needs to go away: multiple=
=20
assignments, multiple *syntactic* values.
I want three things, all of which IMO can, and probably should, be=20
> separate proposals:=20
>
> 1. Generic unpacking, i.e. multiple assignment from a "container".=20
> 2. A better (i.e. RVO-friendly) way to return multiple values without=20
> the need to declare a struct for the purpose.=20
>
> 3. The ability to expand a "container" into multiple "values", e.g. as=20
> function call arguments, or within a brace initializer list.=20
>
> Each of these is made more valuable by the others, but each is also=20
> useful by itself. None has an absolute dependency on another. (Not even=
=20
> syntactically, I assert; see below.)=20
Here's the problem with the notion that these are all separate things.
If you *start* with solving #1, you will come up with a different solution=
=20
to #2 than if you started with #2. Instead of introducing value sequences=
=20
as a first-class construct, you'll likely do what was suggested earlier.=20
You make some language hack type that mimics tuple, but has some arbitrary=
=20
rules that allow elision through it. Similarly, for #3, you would introduce=
=20
some syntax that will implicitly use the generic unpacking you used in #1,=
=20
which is probably based directly on `std::get<>`.
However, if you start from #2, then you start from a position of needing=20
the concept of value sequences. So your solution to #1 is based on calling=
=20
an MRV function to do the generic unpacking. And thus, your solution to #3=
=20
will similarly use this same MRV function to do the generic unpacking,=20
coupled with expanding where value sequences can be used.
So these are not terribly orthogonal concepts. Each may have uses on their=
=20
own, but the overall solutions to these problems will be different. If you=
=20
already have #2, the solution to #1 is going to look very different than if=
=20
you don't.
>> So, you are saying you *still* want unpacking syntax=C2=B9, you just onl=
y=20
> >> want it to work for MRV's? Why? What is the benefit to limiting it in=
=20
> >> such manner? (As previously explained, I don't buy the "syntax is=20
> >> precious" argument.)=20
> >=20
> > You can choose not to buy it, but that doesn't make it false.=20
>
> You are asking for this:=20
>
> auto t =3D make_tuple(...);=20
> [auto x; void; y] =3D foo(); // Legal=20
> [auto a; void; b] =3D t; // Illegal / reserved for future use=20
>
> Really? Leaving aside the compiler complexity arguments, I'd be inclined=
=20
> to reject that just on the basis of the confusion it is likely to cause.=
=20
> Context-sensitive syntax has a high cognitive burden. That is much less=
=20
> an issue for context-sensitive keywords. (For one, most people will=20
> pretend that they are just keywords, and not use them otherwise.)=20
>
> As a code writer, I look at the above and want to know why the second=20
> one doesn't work.
>
As a code writer, I would look at the above and realize, "hey, that's a=20
tuple, not a value sequence. I shouldn't expect to be able to transform one=
=20
thing into multiple things without an explicit conversion."
A tuple is a value; a *single* value. It is only a "collection of values"=
=20
*semantically*; syntactically, a tuple is no more multiple values than an=
=20
integer is.
And to be quite frank, from the perspective what "a code writer" thinks=20
ought to happen, the fact that `vector<int>{3}` and `vector<int>{{3}}` do=
=20
the same thing is far more pernicious than the notion that a tuple and a=20
value sequence would not be directly interchangeable.
--=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 http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.
------=_Part_4448_422756189.1433207162010
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">On Monday, June 1, 2015 at 12:51:41 PM UTC-4, Matthew Woeh=
lke wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left:=
0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">On 2015-06-01 12:15,=
Nicol Bolas wrote:
<br>> On Saturday, May 30, 2015 at 12:35:06 PM UTC-4, Matthew Woehlke wr=
ote:
<br>>> On 2015-05-29 19:57, Nicol Bolas wrote:=20
<br>>>> The result of an expression is, without multiple return va=
lues, a=20
<br>>>> single value with a single type. Therefore, in order for M=
RVs to=20
<br>>>> work, that will have to change.=20
<br>>>
<br>>> Yes, it would have to change. That is a big part of my objecti=
on.
<br>>=20
<br>> ... why?
<br>
<br>Because 'foo()' "looks like" a single semantic "thing". And right now i=
t
<br>always *means* a single semantic thing. You propose to make it possible
<br>for it to suddenly mean *multiple* semantic things, with no indication
<br>to the reader.<br></blockquote><div><br>I've been using Lua for years, =
and it never bothered me. Indeed, the only things that bother me about Lua'=
s MRV syntax are certain places where it's not orthogonal (these are comple=
x to explain, and none of them are necessary for C++).<br><br>So it seems t=
o me that it's more a matter of what you're used to/expect than a general p=
roblem with the concept.<br><br>And it should be noted that you're trying t=
o adopt this view as well. You want to treat a tuple as semantically indist=
inguishable from its component parts; to you, the tuple is an implementatio=
n detail of dealing with value sequences. That is the very core of the titl=
e of your thread: multiple assignments, multiple <i>semantic</i> values, vi=
a one <i>syntactic</i> value.<br><br>All I'm saying is that the implementat=
ion detail needs to go away: multiple assignments, multiple <i>syntactic</i=
> values.<br><br></div><blockquote class=3D"gmail_quote" style=3D"margin: 0=
;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">I want =
three things, all of which IMO can, and probably should, be
<br>separate proposals:
<br>
<br>1. Generic unpacking, i.e. multiple assignment from a "container". =
;</blockquote><blockquote style=3D"margin: 0px 0px 0px 0.8ex; border-left: =
1px solid rgb(204, 204, 204); padding-left: 1ex;" class=3D"gmail_quote"><br=
></blockquote><blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-l=
eft: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">2. A better (i.e=
.. RVO-friendly) way to return multiple values without
<br>the need to declare a struct for the purpose.
<br>
<br>3. The ability to expand a "container" into multiple "values", e.g. as
<br>function call arguments, or within a brace initializer list.
<br>
<br>Each of these is made more valuable by the others, but each is also
<br>useful by itself. None has an absolute dependency on another. (Not even
<br>syntactically, I assert; see below.)
</blockquote><div><br>Here's the problem with the notion that these are all=
separate things.<br><br>If you <i>start</i> with solving #1, you will come=
up with a different solution to #2 than if you started with #2. Instead of=
introducing value sequences as a first-class construct, you'll likely do w=
hat was suggested earlier. You make some language hack type that mimics tup=
le, but has some arbitrary rules that allow elision through it. Similarly, =
for #3, you would introduce some syntax that will implicitly use the generi=
c unpacking you used in #1, which is probably based directly on `std::get&l=
t;>`.<br><br>However, if you start from #2, then you start from a positi=
on of needing the concept of value sequences. So your solution to #1 is bas=
ed on calling an MRV function to do the generic unpacking. And thus, your s=
olution to #3 will similarly use this same MRV function to do the generic u=
npacking, coupled with expanding where value sequences can be used.<br><br>=
So these are not terribly orthogonal concepts. Each may have uses on their =
own, but the overall solutions to these problems will be different. If you =
already have #2, the solution to #1 is going to look very different than if=
you don't.<br><br></div><blockquote class=3D"gmail_quote" style=3D"margin:=
0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">>&=
gt; So, you are saying you *still* want unpacking syntax=C2=B9, you just on=
ly=20
<br>>> want it to work for MRV's? Why? What is the benefit to limitin=
g it in=20
<br>>> such manner? (As previously explained, I don't buy the "syntax=
is=20
<br>>> precious" argument.)
<br>>=20
<br>> You can choose not to buy it, but that doesn't make it false.
<br>
<br>You are asking for this:
<br>
<br> auto t =3D make_tuple(...);
<br> [auto x; void; y] =3D foo(); // Legal
<br> [auto a; void; b] =3D t; // Illegal / reserved for future use
<br>
<br>Really? Leaving aside the compiler complexity arguments, I'd be incline=
d
<br>to reject that just on the basis of the confusion it is likely to cause=
..
<br>Context-sensitive syntax has a high cognitive burden. That is much less
<br>an issue for context-sensitive keywords. (For one, most people will
<br>pretend that they are just keywords, and not use them otherwise.)
<br>
<br>As a code writer, I look at the above and want to know why the second
<br>one doesn't work.<br></blockquote><div><br>As a code writer, I would lo=
ok at the above and realize, "hey, that's a tuple, not a value sequence. I =
shouldn't expect to be able to transform one thing into multiple things wit=
hout an explicit conversion."<br><br>A tuple is a value; a <i>single</i> va=
lue. It is only a "collection of values" <i>semantically</i>; syntactically=
, a tuple is no more multiple values than an integer is.<br><br>And to be q=
uite frank, from the perspective what "a code writer" thinks ought to happe=
n, the fact that `vector<int>{3}` and `vector<int>{{3}}` do the=
same thing is far more pernicious than the notion that a tuple and a value=
sequence would not be directly interchangeable.<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"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />
------=_Part_4448_422756189.1433207162010--
------=_Part_4447_918554730.1433207162010--
.
Author: Matthew Woehlke <mw_triad@users.sourceforge.net>
Date: Tue, 02 Jun 2015 10:03:41 -0400
Raw View
On 2015-06-01 21:06, Nicol Bolas wrote:
> On Monday, June 1, 2015 at 12:51:41 PM UTC-4, Matthew Woehlke wrote:
>> 'foo()' "looks like" a single semantic "thing". And right now it
>> always *means* a single semantic thing. You propose to make it
>> possible for it to suddenly mean *multiple* semantic things, with
>> no indication to the reader.
>
> I've been using Lua for years, and it never bothered me. Indeed, the only
> things that bother me about Lua's MRV syntax are certain places where it's
> not orthogonal (these are complex to explain, and none of them are
> necessary for C++).
>
> So it seems to me that it's more a matter of what you're used to/expect
> than a general problem with the concept.
That may be true. C++ coders however are likely used to one "thing"
actually being one "thing".
> And it should be noted that you're trying to adopt this view as well. You
> want to treat a tuple as semantically indistinguishable from its component
> parts; to you, the tuple is an implementation detail of dealing with value
> sequences. That is the very core of the title of your thread: multiple
> assignments, multiple *semantic* values, via one *syntactic* value.
I'm not sure I'd say that (although I'm not exactly sure what you're
saying). Rather, I would like to be able to interchange more freely
between value sequence containers and the contained collection of
values. Regardless of the actual type of the container :-).
> All I'm saying is that the implementation detail needs to go away: multiple
> assignments, multiple *syntactic* values.
....yes? I *think* I am saying that also...
>> I want three things, all of which IMO can, and probably should, be
>> separate proposals:
>>
>> 1. Generic unpacking, i.e. multiple assignment from a "container".
>>
>> 2. A better (i.e. RVO-friendly) way to return multiple values without
>> the need to declare a struct for the purpose.
>>
>> 3. The ability to expand a "container" into multiple "values", e.g. as
>> function call arguments, or within a brace initializer list.
>>
>> Each of these is made more valuable by the others, but each is also
>> useful by itself. None has an absolute dependency on another. (Not even
>> syntactically, I assert; see below.)
>
> Here's the problem with the notion that these are all separate things.
>
> If you *start* with solving #1, you will come up with a different solution
> to #2 than if you started with #2. Instead of introducing value sequences
> as a first-class construct, you'll likely do what was suggested earlier.
> You make some language hack type that mimics tuple, but has some arbitrary
> rules that allow elision through it.
I guess I don't understand what difference this makes. What features
does my implementation lack that yours provides? (Besides implicit
expansion, which as stated above I don't want anyway.)
> Similarly, for #3, you would introduce some syntax that will
> implicitly use the generic unpacking you used in #1, which is
> probably based directly on `std::get<>`.
Yes, but again, what's wrong with that?
> However, if you start from #2, then you start from a position of needing
> the concept of value sequences. So your solution to #1 is based on calling
> an MRV function to do the generic unpacking.
....and why should I have to write additional code to unpack something?
(Moreover, how are you going to provide a non-ugly implementation of
that unpacking function? In particular, can it be written without
recursion? Unpacking generated by the compiler will create the best
possible code, and likely provide better diagnostics when there is an
error.)
> So these are not terribly orthogonal concepts. Each may have uses on their
> own, but the overall solutions to these problems will be different. If you
> already have #2, the solution to #1 is going to look very different than if
> you don't.
Okay, I can see that, but I share your opinion in reverse: I *prefer*
the solution that arises from providing #1 first and dislike the
solution that becomes the only option if #2 is addressed first without
considering #1. Also, I still want to be able to capture the entire MRV
set as a single "entity".
>> You are asking for this:
>>
>> auto t = make_tuple(...);
>> [auto x; void; y] = foo(); // Legal
>> [auto a; void; b] = t; // Illegal / reserved for future use
>
> As a code writer, I would look at the above and realize, "hey, that's a
> tuple, not a value sequence. I shouldn't expect to be able to transform one
> thing into multiple things without an explicit conversion."
Um... which is exactly my point at the start of this thread, in a
slightly different context.
In this context, I would say that unpacking *is* an explicit conversion.
That's sort of how I define unpacking, in fact; taking a single
syntactic "thing" that is multiple semantic "things", splitting it apart
into it's component semantic parts, and assigning (or discarding) the parts.
--
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 http://groups.google.com/a/isocpp.org/group/std-proposals/.
.
Author: Matthew Woehlke <mw_triad@users.sourceforge.net>
Date: Tue, 02 Jun 2015 10:22:41 -0400
Raw View
On 2015-06-02 08:17, Miro Knejp wrote:
> Now imagine we have multiple return values:
>=20
> T, U, V bar(A a, B b)
>=20
> In the best-case scenario RVO is possible for all three return values, tr=
ansforming the function into
>=20
> struct __Result { T t; U u; V v; };
> void bar(__Result* result, A a, B b);
>=20
> This assumes all three types are copyable or at least movable to their fi=
nal destination.
....no? With RVO you are *not* copying/moving, you are constructing in
place. (Well, IIRC the standard requires that they *be* copyable, but
the point is that they won't actually *be* copied.)
IOW, this:
auto answer =3D some_logic();
...
return answer;
....becomes this:
new (sizeof(ResultType), result) ResultType{some_logic()};
...
return;
> In the case where all three return values are used for initialization thi=
s is pretty trivial.
>=20
> T t, U u, V v =3D bar(a, b);
>=20
> transforms into
>=20
> #1
> __Result __result; // not initialized
> bar(&__result, a, b);
> // t, u, v are now aliases to __result.t, __result.u, __result.v
Correct.
> Now what if the initialization is different
>=20
> #2
> T t;
> U u;
> t, u, V v =3D bar(a, b);
>=20
> This must be transformed to=20
>=20
> __Result __result; // not initialized
> bar(&__result, A a, B b);
> // v is now an alias to result.v
> t =3D std::move(__result.t);
> u =3D std::move(__result.u);
> __result.u.~U();
> __result.t.~T();
Also correct (in particular, thanks for noting that the destructors need
to be called immediately!), and...
> This means there is wasted stack space for t and u (due to the fixed=20
> layout of __Result) __result.t and __result.u have to stay until v
> goes out of scope. It could be recycled for other variables, but just
> saying.
....unavoidable AFAICT. Well... the compiler should "know" that the
storage for __result.t and __result.u is now unused and could be reused,
but you are correct that the storage can't be *released* in this case.
(It could if it was at the end of the result list, but I assume you knew
that.)
> [snip lots]
> I guess my whole point here is that there are at least two ways to=20
> implement this that need to be hammered into the ABI and dictate how=20
> much flexibility the caller has and how much call overhead there is
> per return value (1 or n additional pointers pushed). Once there is a
> syntax for this compiler-generated unpacking it can surely be
> extended to user-defined types.
Two questions:
1. Is the overhead of passing more pointers to the called function worth
the benefits? I ask objectively. I think your argument is convincing,
but ultimately a qualified answer to this question is desired before
choosing an implementation. (This may not be a question to be answered
by the standard, either, but by compiler vendors.)
2. Can the second form allow for code such as the following example? Is
there a necessary performance penalty?
auto results =3D foo();
for (;;)
bar(results...);
(Doesn't need to be an infinite loop, so long as the compiler is
prevented from transforming the separate call and assignment into
'bar(foo()...)'.)
> I just don=E2=80=99t think that there is as much elision potential for
> user-defined types.
I think we all agree on that much. I'm not sure there is *any* elision
possible :-).
--=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 http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.
.
Author: Matthew Woehlke <mw_triad@users.sourceforge.net>
Date: Tue, 02 Jun 2015 13:16:44 -0400
Raw View
On 2015-06-02 11:54, Miro Knejp wrote:
>> On 02 Jun 2015, at 16:22 , Matthew Woehlke wrote:
>> 1. Is the overhead of passing more pointers to the called function worth
>> the benefits? I ask objectively. I think your argument is convincing,
>> but ultimately a qualified answer to this question is desired before
>> choosing an implementation. (This may not be a question to be answered
>> by the standard, either, but by compiler vendors.)
>=20
> I do not have any measurements so I don=E2=80=99t know. In the end this i=
s
> for the ABI designers to decide.
Right. If the standardese does not have requirements that preclude one
or the other mechanism, I don't the standard needs to decide this.
>> 2. Can the second form allow for code such as the following example? Is
>> there a necessary performance penalty?
>>
>> auto results =3D foo();
>> for (;;)
>> bar(results...);
>=20
> This is basically equivalent to
>=20
> auto a =3D =E2=80=A6
> auto b =3D =E2=80=A6
> auto c =3D ...
> for(;;)
> bar(a, b, c);
In the above example, yes. A more pertinent question is probably if we
allow for 'results' to be stored/copied/etc. If it has an unnameable
type and is not copyable, we are probably okay, and the compiler can
just magic away the storage details.
Works for me...
Thanks,
--=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 http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.
.
Author: Matthew Woehlke <mw_triad@users.sourceforge.net>
Date: Tue, 02 Jun 2015 15:45:57 -0400
Raw View
On 2015-06-02 14:46, Nicol Bolas wrote:
> On Tuesday, June 2, 2015 at 8:17:53 AM UTC-4, Miro Knejp wrote:
>> __Result __result; // not initialized
>> bar(&__result, A a, B b);
>> // v is now an alias to result.v
>> t = std::move(__result.t);
>> u = std::move(__result.u);
>> __result.u.~U();
>> __result.t.~T();
>>
>> This means there is wasted stack space for t and u (due to the fixed
>> layout of __Result) __result.t and __result.u have to stay until v goes out
>> of scope. It could be recycled for other variables, but just saying.
>
> How is that any different from the single return value case, when you store
> the result into a live object?
I think the difference is that, with the above approach (pass one memory
location, MRV's are stored in fixed order), you introduce the
possibility of stack fragmentation. Because the compiler has to allocate
*contiguous* space for all MRV's, if you declare-assign only the last
one, then the space for the others becomes unused but cannot be
released, because you are retaining the top of the stack for the one
value you kept.
That's what Miro was trying to point out. Otherwise, yes, it's
essentially the same as the single return value case.
(@Miro, d'oh, I missed when writing my previous reply that you'd already
noted the possibility to reuse the space.)
--
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 http://groups.google.com/a/isocpp.org/group/std-proposals/.
.