Topic: Apply std::common_type_t to deduce final return
Author: Thiago Macieira <thiago@macieira.org>
Date: Sat, 23 Jun 2018 13:58:01 -0700
Raw View
On Saturday, 23 June 2018 13:14:31 PDT anonymous.from.applecity@gmail.com
wrote:
> I cannot think of any at the moment. I never encountered a case where
> compilation error inside of lambda would be of any use. I believe this
> shouldn't affect existing code, as std::common_type is conversion rules
> friendly (not 100% sure though).
You're thinking of the fact that you'll only make invalid code valid. In that
case, sure, there's no issue, since your proposal cannot change valid code.
What you're missing is that the rules are like that for a reason. Deduction is
intentional that it requires all return statements to return the same thing,
to prevent one type from being accidentally converted to another or -- worse
-- changing the function's return type when adding or removing a return
statement after refactoring. Your proposal needs to address why the
intentional rule should be changed and how the protection that the rule
afforded can either be re-obtained or is something we can do away with.
--
Thiago Macieira - thiago (AT) macieira.info - thiago (AT) kde.org
Software Architect - Intel Open Source Technology Center
--
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.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/15456583.cP562BaXFI%40tjmaciei-mobl1.
.
Author: anonymous.from.applecity@gmail.com
Date: Sat, 23 Jun 2018 14:10:48 -0700 (PDT)
Raw View
------=_Part_21399_1164160264.1529788248218
Content-Type: multipart/alternative;
boundary="----=_Part_21400_1581853760.1529788248218"
------=_Part_21400_1581853760.1529788248218
Content-Type: text/plain; charset="UTF-8"
On Sunday, June 24, 2018 at 2:58:05 AM UTC+6, Thiago Macieira wrote:
> What you're missing is that the rules are like that for a reason.
> Deduction is
> intentional that it requires all return statements to return the same
> thing,
> to prevent one type from being accidentally converted to another or --
> worse
> -- changing the function's return type when adding or removing a return
> statement after refactoring.
>
I believe that removing a return statement will actually be bug in itself.
For example in case with std::optional, leaving out nullopt won't be an
error and will be correct anyway. In case of leaving out non-empty return,
the value will either implicitly convert or be an error, which should break
the rest of the code (e.g. explode, making error visible). This is only my
case though, so I'll try to search for some more usages of the lambdas in
general, and parse standard to search for edge cases. I can only think of
github to walk around, may be SO. Could you please suggest a place where I
could reach out to people with something like "Will this break your code?"
I'm thinking about implementing the feature and trying to compile and run
some projects off Github. Thank you for feedback.
--
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.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/1e1bbf44-71d9-4818-91e9-c4de174b0248%40isocpp.org.
------=_Part_21400_1581853760.1529788248218
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><div>On Sunday, June 24, 2018 at 2:58:05 AM UTC+6, Thiago =
Macieira wrote:</div><blockquote class=3D"gmail_quote" style=3D"margin: 0;m=
argin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">What you&=
#39;re missing is that the rules are like that for a reason. Deduction is=
=20
<br>intentional that it requires all return statements to return the same t=
hing,=20
<br>to prevent one type from being accidentally converted to another or -- =
worse=20
<br>-- changing the function's return type when adding or removing a re=
turn=20
<br>statement after refactoring. <br></blockquote><div><br></div><div><div>=
<br></div><div>I believe that removing a return statement will=20
actually be bug in itself. For example in case with std::optional,=20
leaving out nullopt won't be an error and will be correct anyway. In=20
case of leaving out non-empty return, the value will either implicitly=20
convert or be an error, which should break the rest of the code (e.g.=20
explode, making error visible). This is only my case though, so I'll tr=
y
to search for some more usages of the lambdas in general, and parse=20
standard to search for edge cases. I can only think of github to walk=20
around, may be SO. Could you please suggest a place where I could reach=20
out to people with something like "Will this break your code?" I&=
#39;m=20
thinking about implementing the feature and trying to compile and run=20
some projects off Github. Thank you for feedback.</div>=C2=A0</div></div>
<p></p>
-- <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 />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/1e1bbf44-71d9-4818-91e9-c4de174b0248%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/1e1bbf44-71d9-4818-91e9-c4de174b0248=
%40isocpp.org</a>.<br />
------=_Part_21400_1581853760.1529788248218--
------=_Part_21399_1164160264.1529788248218--
.
Author: Nicol Bolas <jmckesson@gmail.com>
Date: Sat, 23 Jun 2018 16:00:10 -0700 (PDT)
Raw View
------=_Part_22387_1244627315.1529794810949
Content-Type: multipart/alternative;
boundary="----=_Part_22388_232376494.1529794810950"
------=_Part_22388_232376494.1529794810950
Content-Type: text/plain; charset="UTF-8"
On Saturday, June 23, 2018 at 4:14:31 PM UTC-4, anonymous.fr...@gmail.com
wrote:
>
> Problem*:*
>
> When trying to mix std::optional with lambdas, I run into some rather
> annoying issue. I need to always use trailing return type syntax to get it
> deduced correctly in situations like this (e.g. when return std::nullopt
> comes first):
>
> [](auto args)
> {
> if (!check(args))
> return std::nullopt;
>
> return foo(args); //returns some std::optional<T>
> }
>
> The above will not compile, as std::nullopt_t cannot be converted to
> std::optional<T>.
>
Well, the code could be rewritten as `return check(args) ? foo(args) :
std::nullopt;`. Lambdas that are large and complicated enough that you
can't use ?: for these cases are probably large and complicated enough that
declaring a return type is not an onerous burden. Indeed, it would likely
improve code clarity to do so.
Context*:*
>
> I'm trying to implement try_in_sequence, which basically executes
> functions passed as arguments one by one, until one succeeds (e.g. returns
> non-empty optional). Writing return type on every one of the 4-5 lambdas
> per function call is daunting. I understand that lambda's return type is
> consistent with auto, but it doesn't seem to be practical in this case.
>
While I feel for you, P1012 (allowing fold expressions over the ?:
operator) would be a much more reasonable solution to your problem than
making such a drastic change. But in any case, making such a change for
just this seems to be too narrow of an issue.
>
> Proposal*:*
>
> Use std::common_type<return_stm_types...> as return type. E.g. use auto
> on each return statement *individually*, then deduce common type using
> `std::common_type`. std::common_type<std::nullopt_t, std::optional<int>>
> indeed yields std::optional<int>, as shown in shown in this example
> <https://wandbox.org/permlink/oIhIR7QsmvThbSoM>:
>
>
> #include <type_traits>
> #include <optional>
>
> template <typename>
> struct undefined;
>
> int main()
> {
> using common_t = std::common_type_t<std::nullopt_t, std::optional<int>
> >;
> static_assert(std::is_same_v<std::optional<int>, common_t>);
> //undefined<std::common_type_t<std::nullopt_t, std::optional<int>>>
> foo;
> }
>
> Possible damage:
>
> I cannot think of any at the moment. I never encountered a case where
> compilation error inside of lambda would be of any use. I believe this
> shouldn't affect existing code, as std::common_type is conversion rules
> friendly (not 100% sure though).
>
The question is not one of whether it is possible. Yes, it's possible
without breaking existing code.
It's whether it's a good idea. Doing this makes code potentially more
difficult to read, since you can no longer look at a single return
statement to know what type a function returns.
It also ignores the fact that the current rules actually catch bugs before
they happen. By forcing users to make sure all return types are the same,
you prevent someone from accidentally returning the wrong thing. There is
nothing wrong with making the writer of a function sit down and work out
exactly what it is they want to return in complicated cases. And the more
return statements a function has, the more complicated it is.
--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/c16c3476-1a7c-4ae9-b46a-f096477813d6%40isocpp.org.
------=_Part_22388_232376494.1529794810950
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><br><br>On Saturday, June 23, 2018 at 4:14:31 PM UTC-4, an=
onymous.fr...@gmail.com wrote:<blockquote class=3D"gmail_quote" style=3D"ma=
rgin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">=
<div dir=3D"ltr"><div><font size=3D"4">Problem</font><b>:</b><br></div><div=
><br></div><div>When trying to mix <code><span style=3D"color:rgb(11,83,148=
)"><span style=3D"background-color:rgb(238,238,238)"><span style=3D"font-fa=
mily:courier new,monospace">std::optional</span></span></span> with lambdas=
, I run into some rather annoying issue. I need to always use trailing retu=
rn type syntax to get it deduced correctly in situations like this (e.g. wh=
en </code><code><code><span style=3D"color:rgb(11,83,148)"><span style=3D"b=
ackground-color:rgb(238,238,238)"><span style=3D"font-family:courier new,mo=
nospace">return std::nullopt</span></span></span></code> comes first):</cod=
e></div><div><code><br></code></div><div><code><div style=3D"background-col=
or:rgb(250,250,250);border-color:rgb(187,187,187);border-style:solid;border=
-width:1px"><code><div><span style=3D"color:#660">[](</span><span style=3D"=
color:#008">auto</span><span style=3D"color:#000"> args</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>=C2=A0 =C2=A0 </span=
><span style=3D"color:#008">if</span><span style=3D"color:#000"> </span><sp=
an style=3D"color:#660">(!</span><span style=3D"color:#000">check</span><sp=
an style=3D"color:#660">(</span><span style=3D"color:#000">args</span><span=
style=3D"color:#660">))</span><span style=3D"color:#000"><br>=C2=A0 =C2=A0=
=C2=A0 =C2=A0 </span><span style=3D"color:#008">return</span><span style=
=3D"color:#000"> std</span><span style=3D"color:#660">::</span><span style=
=3D"color:#000">nullopt</span><span style=3D"color:#660">;</span><span styl=
e=3D"color:#000"><br><br>=C2=A0 =C2=A0 </span><span style=3D"color:#008">re=
turn</span><span style=3D"color:#000"> foo</span><span style=3D"color:#660"=
>(</span><span style=3D"color:#000">args</span><span style=3D"color:#660">)=
;</span><span style=3D"color:#000"> </span><span style=3D"color:#800">//ret=
urns some std::optional<T></span><span style=3D"color:#000"><br></spa=
n><span style=3D"color:#660">}</span><span style=3D"color:#000"><br></span>=
</div></code></div><br>The above will not compile, as <span style=3D"color:=
rgb(11,83,148)"><span style=3D"background-color:rgb(238,238,238)"><span sty=
le=3D"font-family:courier new,monospace">std::nullopt_t</span></span></span=
> cannot be converted to <span style=3D"color:rgb(11,83,148)"><span style=
=3D"background-color:rgb(238,238,238)">std::optional<T></span></span>=
..<br></code></div></div></blockquote><div><br></div><div>Well, the code cou=
ld be rewritten as `return check(args) ? foo(args) : std::nullopt;`. Lambda=
s that are large and complicated enough that you can't use ?: for these=
cases are probably large and complicated enough that declaring a return ty=
pe is not an onerous burden. Indeed, it would likely improve code clarity t=
o do so.<br></div><div><br></div><blockquote class=3D"gmail_quote" style=3D=
"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex=
;"><div dir=3D"ltr"><div><code></code></div><div><code></code></div><div><c=
ode><font size=3D"4">Context</font><b>:</b></code></div><div><code><b><br><=
/b></code></div><div><code>I'm trying to implement <span style=3D"color=
:rgb(11,83,148)"><span style=3D"background-color:rgb(238,238,238)"><span st=
yle=3D"font-family:courier new,monospace">try_in_sequence</span></span></sp=
an>, which basically executes functions passed as arguments one by one, unt=
il one succeeds (e.g. returns non-empty optional). Writing return type on e=
very one of the 4-5 lambdas per function call is daunting. I understand tha=
t lambda's return type is consistent with <span style=3D"color:rgb(11,8=
3,148)"><span style=3D"background-color:rgb(238,238,238)"><span style=3D"fo=
nt-family:courier new,monospace">auto</span></span></span>, but it doesn=
9;t seem to be practical in this case.</code></div></div></blockquote><div>=
<br></div><div>While I feel for you, P1012 (allowing fold expressions over =
the ?: operator) would be a much more reasonable solution to your problem t=
han making such a drastic change. But in any case, making such a change for=
just this seems to be too narrow of an issue.<br></div><div>=C2=A0</div><b=
lockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;borde=
r-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr"><div><code><br>=
</code></div><div><code><font size=3D"4">Proposal</font><b>:</b></code></di=
v><div><code><b><br></b></code></div><div><code>Use <span style=3D"color:rg=
b(11,83,148)"><span style=3D"background-color:rgb(238,238,238)"><span style=
=3D"font-family:courier new,monospace">std::common_type<return_stm_<wbr>=
types...></span></span></span> as return type. E.g. use </code><code><co=
de><span style=3D"color:rgb(11,83,148)"><span style=3D"background-color:rgb=
(238,238,238)"><span style=3D"font-family:courier new,monospace">auto</span=
></span></span></code> on each return statement <i>individually</i>, then d=
educe common type using `std::common_type`. </code><code><code><span style=
=3D"color:rgb(11,83,148)"><span style=3D"background-color:rgb(238,238,238)"=
><span style=3D"font-family:courier new,monospace">std::common_type<std:=
:nullopt_<wbr>t, std::optional<int>></span></span></span></code> i=
ndeed yields </code><code><code><span style=3D"color:rgb(11,83,148)"><span =
style=3D"background-color:rgb(238,238,238)">std::optional<int></span>=
</span></code>, as shown in shown in <a href=3D"https://wandbox.org/permlin=
k/oIhIR7QsmvThbSoM" target=3D"_blank" rel=3D"nofollow" onmousedown=3D"this.=
href=3D'https://www.google.com/url?q\x3dhttps%3A%2F%2Fwandbox.org%2Fper=
mlink%2FoIhIR7QsmvThbSoM\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNEZZxBM_zx9=
Q2T2EyWaujaURGlStQ';return true;" onclick=3D"this.href=3D'https://w=
ww.google.com/url?q\x3dhttps%3A%2F%2Fwandbox.org%2Fpermlink%2FoIhIR7QsmvThb=
SoM\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNEZZxBM_zx9Q2T2EyWaujaURGlStQ=
9;;return true;">this example</a>:</code></div><div><code><br></code></div>=
<div style=3D"background-color:rgb(250,250,250);border-color:rgb(187,187,18=
7);border-style:solid;border-width:1px"><code><div><span style=3D"color:#00=
0"><br></span><span style=3D"color:#800">#include</span><span style=3D"colo=
r:#000"> </span><span style=3D"color:#080"><type_traits></span><span =
style=3D"color:#000"><br></span><span style=3D"color:#800">#include</span><=
span style=3D"color:#000"> </span><span style=3D"color:#080"><optional&g=
t;</span><span style=3D"color:#000"><br><br></span><span style=3D"color:#00=
8">template</span><span style=3D"color:#000"> </span><span style=3D"color:#=
080"><typename></span><span style=3D"color:#000"><br></span><span sty=
le=3D"color:#008">struct</span><span style=3D"color:#000"> </span><span sty=
le=3D"color:#008">undefined</span><span style=3D"color:#660">;</span><span =
style=3D"color:#000"><br><br></span><span style=3D"color:#008">int</span><s=
pan style=3D"color:#000"> main</span><span style=3D"color:#660">()</span><s=
pan style=3D"color:#000"><br></span><span style=3D"color:#660">{</span><spa=
n style=3D"color:#000"><br>=C2=A0 =C2=A0 </span><span style=3D"color:#008">=
using</span><span style=3D"color:#000"> common_t </span><span style=3D"colo=
r:#660">=3D</span><span style=3D"color:#000"> std</span><span style=3D"colo=
r:#660">::</span><span style=3D"color:#000">common_type_t</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">nullop<wbr>t_t</span><s=
pan style=3D"color:#660">,</span><span style=3D"color:#000"> std</span><spa=
n style=3D"color:#660">::</span><span style=3D"color:#000">optional</span><=
span style=3D"color:#080"><int></span><span style=3D"color:#660">>=
;</span><span style=3D"color:#000"><br>=C2=A0 =C2=A0 </span><span style=3D"=
color:#008">static_assert</span><span style=3D"color:#660">(</span><span st=
yle=3D"color:#000">std</span><span style=3D"color:#660">::</span><span styl=
e=3D"color:#000">is_same_v</span><span style=3D"color:#660"><</span><spa=
n style=3D"color:#000">s<wbr>td</span><span style=3D"color:#660">::</span><=
span style=3D"color:#000">optional</span><span style=3D"color:#080"><int=
></span><span style=3D"color:#660">,</span><span style=3D"color:#000"> c=
ommon_t</span><span style=3D"color:#660">>);</span><span style=3D"color:=
#000"><br>=C2=A0 =C2=A0 </span><span style=3D"color:#800">//undefined<st=
d::common_type_<wbr>t<std::nullopt_t, std::optional<int>>> f=
oo;</span><span style=3D"color:#000"><br></span><span style=3D"color:#660">=
}</span></div></code></div><div><code><br><font size=3D"4">Possible damage:=
</font></code></div><div><code><b><br></b></code></div><div><code>I cannot =
think of any at the moment. I never encountered a case where compilation er=
ror inside of lambda would be of any use. I believe this shouldn't affe=
ct existing code, as </code><code><code><code><span style=3D"color:rgb(11,8=
3,148)"><span style=3D"background-color:rgb(238,238,238)"><span style=3D"fo=
nt-family:courier new,monospace">std::common_type</span></span></span></cod=
e></code> is conversion rules friendly (not 100% sure though).<br></code></=
div></div></blockquote><div><br></div><div>The question is not one of wheth=
er it is possible. Yes, it's possible without breaking existing code.</=
div><div><br></div><div>It's whether it's a good idea. Doing this m=
akes code potentially more difficult to read, since you can no longer look =
at a single return statement to know what type a function returns.</div><di=
v><br></div><div>It also ignores the fact that the current rules actually c=
atch bugs before they happen. By forcing users to make sure all return type=
s are the same, you prevent someone from accidentally returning the wrong t=
hing. There is nothing wrong with making the writer of a function sit down =
and work out exactly what it is they want to return in complicated cases. A=
nd the more return statements a function has, the more complicated it is.<b=
r></div></div>
<p></p>
-- <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 />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/c16c3476-1a7c-4ae9-b46a-f096477813d6%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/c16c3476-1a7c-4ae9-b46a-f096477813d6=
%40isocpp.org</a>.<br />
------=_Part_22388_232376494.1529794810950--
------=_Part_22387_1244627315.1529794810949--
.
Author: Richard Smith <richard@metafoo.co.uk>
Date: Mon, 25 Jun 2018 10:24:06 -0700
Raw View
--000000000000cdb1ed056f7aa60c
Content-Type: text/plain; charset="UTF-8"
On Sat, 23 Jun 2018, 13:14 , <anonymous.from.applecity@gmail.com> wrote:
> Problem*:*
>
> When trying to mix std::optional with lambdas, I run into some rather
> annoying issue. I need to always use trailing return type syntax to get it
> deduced correctly in situations like this (e.g. when return std::nullopt
> comes first):
>
> [](auto args)
> {
> if (!check(args))
> return std::nullopt;
>
> return foo(args); //returns some std::optional<T>
> }
>
> The above will not compile, as std::nullopt_t cannot be converted to
> std::optional<T>.
>
> Context*:*
>
> I'm trying to implement try_in_sequence, which basically executes
> functions passed as arguments one by one, until one succeeds (e.g. returns
> non-empty optional). Writing return type on every one of the 4-5 lambdas
> per function call is daunting. I understand that lambda's return type is
> consistent with auto, but it doesn't seem to be practical in this case.
>
> Proposal*:*
>
> Use std::common_type<return_stm_types...> as return type. E.g. use auto
> on each return statement *individually*, then deduce common type using
> `std::common_type`. std::common_type<std::nullopt_t, std::optional<int>>
> indeed yields std::optional<int>, as shown in shown in this example
> <https://wandbox.org/permlink/oIhIR7QsmvThbSoM>:
>
>
> #include <type_traits>
> #include <optional>
>
> template <typename>
> struct undefined;
>
> int main()
> {
> using common_t = std::common_type_t<std::nullopt_t, std::optional<int>
> >;
> static_assert(std::is_same_v<std::optional<int>, common_t>);
> //undefined<std::common_type_t<std::nullopt_t, std::optional<int>>>
> foo;
> }
>
> Possible damage:
>
> I cannot think of any at the moment. I never encountered a case where
> compilation error inside of lambda would be of any use. I believe this
> shouldn't affect existing code, as std::common_type is conversion rules
> friendly (not 100% sure though).
>
The current rules permit a function to call itself recursively after its
first return statement. How would you handle that?
common_type decays its arguments. How would you handle a return type of
auto& or decltype(auto)?
This adds coupling between the language and library. What should happen if
a declaration of common_type has not been included prior to the definition
of a function with deduced return type?
> --
> 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.
> To view this discussion on the web visit
> https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/7772686a-7e80-4c28-a87b-c5dc11450cc6%40isocpp.org
> <https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/7772686a-7e80-4c28-a87b-c5dc11450cc6%40isocpp.org?utm_medium=email&utm_source=footer>
> .
>
--
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.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CAOfiQqkzrG-PaTDHdq8Yk8m212%2Birb4hfFOefDmdUjH6vNON4A%40mail.gmail.com.
--000000000000cdb1ed056f7aa60c
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable
<div dir=3D"auto"><div><div class=3D"gmail_quote"><div dir=3D"ltr">On Sat, =
23 Jun 2018, 13:14 , <<a href=3D"mailto:anonymous.from.applecity@gmail.c=
om">anonymous.from.applecity@gmail.com</a>> wrote:<br></div><blockquote =
class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid=
;padding-left:1ex"><div dir=3D"ltr"><div><font size=3D"4">Problem</font><b>=
:</b><br></div><div><br></div><div>When trying to mix <code><span style=3D"=
color:rgb(11,83,148)"><span style=3D"background-color:rgb(238,238,238)"><sp=
an style=3D"font-family:courier new,monospace">std::optional</span></span><=
/span> with lambdas, I run into some rather annoying issue. I need to alway=
s use trailing return type syntax to get it deduced correctly in situations=
like this (e.g. when </code><code><code><span style=3D"color:rgb(11,83,148=
)"><span style=3D"background-color:rgb(238,238,238)"><span style=3D"font-fa=
mily:courier new,monospace">return std::nullopt</span></span></span></code>=
comes first):</code></div><div><code><br></code></div><div><code><div styl=
e=3D"background-color:rgb(250,250,250);border-color:rgb(187,187,187);border=
-style:solid;border-width:1px" class=3D"m_6119929370070058788prettyprint"><=
code class=3D"m_6119929370070058788prettyprint"><div class=3D"m_61199293700=
70058788subprettyprint"><span style=3D"color:#660" class=3D"m_6119929370070=
058788styled-by-prettify">[](</span><span style=3D"color:#008" class=3D"m_6=
119929370070058788styled-by-prettify">auto</span><span style=3D"color:#000"=
class=3D"m_6119929370070058788styled-by-prettify"> args</span><span style=
=3D"color:#660" class=3D"m_6119929370070058788styled-by-prettify">)</span><=
span style=3D"color:#000" class=3D"m_6119929370070058788styled-by-prettify"=
> <br></span><span style=3D"color:#660" class=3D"m_6119929370070058788style=
d-by-prettify">{</span><span style=3D"color:#000" class=3D"m_61199293700700=
58788styled-by-prettify"><br>=C2=A0 =C2=A0 </span><span style=3D"color:#008=
" class=3D"m_6119929370070058788styled-by-prettify">if</span><span style=3D=
"color:#000" class=3D"m_6119929370070058788styled-by-prettify"> </span><spa=
n style=3D"color:#660" class=3D"m_6119929370070058788styled-by-prettify">(!=
</span><span style=3D"color:#000" class=3D"m_6119929370070058788styled-by-p=
rettify">check</span><span style=3D"color:#660" class=3D"m_6119929370070058=
788styled-by-prettify">(</span><span style=3D"color:#000" class=3D"m_611992=
9370070058788styled-by-prettify">args</span><span style=3D"color:#660" clas=
s=3D"m_6119929370070058788styled-by-prettify">))</span><span style=3D"color=
:#000" class=3D"m_6119929370070058788styled-by-prettify"><br>=C2=A0 =C2=A0 =
=C2=A0 =C2=A0 </span><span style=3D"color:#008" class=3D"m_6119929370070058=
788styled-by-prettify">return</span><span style=3D"color:#000" class=3D"m_6=
119929370070058788styled-by-prettify"> std</span><span style=3D"color:#660"=
class=3D"m_6119929370070058788styled-by-prettify">::</span><span style=3D"=
color:#000" class=3D"m_6119929370070058788styled-by-prettify">nullopt</span=
><span style=3D"color:#660" class=3D"m_6119929370070058788styled-by-prettif=
y">;</span><span style=3D"color:#000" class=3D"m_6119929370070058788styled-=
by-prettify"><br><br>=C2=A0 =C2=A0 </span><span style=3D"color:#008" class=
=3D"m_6119929370070058788styled-by-prettify">return</span><span style=3D"co=
lor:#000" class=3D"m_6119929370070058788styled-by-prettify"> foo</span><spa=
n style=3D"color:#660" class=3D"m_6119929370070058788styled-by-prettify">(<=
/span><span style=3D"color:#000" class=3D"m_6119929370070058788styled-by-pr=
ettify">args</span><span style=3D"color:#660" class=3D"m_611992937007005878=
8styled-by-prettify">);</span><span style=3D"color:#000" class=3D"m_6119929=
370070058788styled-by-prettify"> </span><span style=3D"color:#800" class=3D=
"m_6119929370070058788styled-by-prettify">//returns some std::optional<T=
></span><span style=3D"color:#000" class=3D"m_6119929370070058788styled-=
by-prettify"><br></span><span style=3D"color:#660" class=3D"m_6119929370070=
058788styled-by-prettify">}</span><span style=3D"color:#000" class=3D"m_611=
9929370070058788styled-by-prettify"><br></span></div></code></div><br>The a=
bove will not compile, as <span style=3D"color:rgb(11,83,148)"><span style=
=3D"background-color:rgb(238,238,238)"><span style=3D"font-family:courier n=
ew,monospace">std::nullopt_t</span></span></span> cannot be converted to <s=
pan style=3D"color:rgb(11,83,148)"><span style=3D"background-color:rgb(238,=
238,238)">std::optional<T></span></span>. <br></code></div><div><code=
><br></code></div><div><code><font size=3D"4">Context</font><b>:</b></code>=
</div><div><code><b><br></b></code></div><div><code>I'm trying to imple=
ment <span style=3D"color:rgb(11,83,148)"><span style=3D"background-color:r=
gb(238,238,238)"><span style=3D"font-family:courier new,monospace">try_in_s=
equence</span></span></span>, which basically executes functions passed as =
arguments one by one, until one succeeds (e.g. returns non-empty optional).=
Writing return type on every one of the 4-5 lambdas per function call is d=
aunting. I understand that lambda's return type is consistent with <spa=
n style=3D"color:rgb(11,83,148)"><span style=3D"background-color:rgb(238,23=
8,238)"><span style=3D"font-family:courier new,monospace">auto</span></span=
></span>, but it doesn't seem to be practical in this case.</code></div=
><div><code><br></code></div><div><code><font size=3D"4">Proposal</font><b>=
:</b></code></div><div><code><b><br></b></code></div><div><code>Use <span s=
tyle=3D"color:rgb(11,83,148)"><span style=3D"background-color:rgb(238,238,2=
38)"><span style=3D"font-family:courier new,monospace">std::common_type<=
return_stm_types...></span></span></span> as return type. E.g. use </cod=
e><code><code><span style=3D"color:rgb(11,83,148)"><span style=3D"backgroun=
d-color:rgb(238,238,238)"><span style=3D"font-family:courier new,monospace"=
>auto</span></span></span></code> on each return statement <i>individually<=
/i>, then deduce common type using `std::common_type`. </code><code><code><=
span style=3D"color:rgb(11,83,148)"><span style=3D"background-color:rgb(238=
,238,238)"><span style=3D"font-family:courier new,monospace">std::common_ty=
pe<std::nullopt_t, std::optional<int>></span></span></span></co=
de> indeed yields </code><code><code><span style=3D"color:rgb(11,83,148)"><=
span style=3D"background-color:rgb(238,238,238)">std::optional<int></=
span></span></code>, as shown in shown in <a href=3D"https://wandbox.org/pe=
rmlink/oIhIR7QsmvThbSoM" target=3D"_blank" rel=3D"noreferrer">this example<=
/a>:</code></div><div><code><br></code></div><div style=3D"background-color=
:rgb(250,250,250);border-color:rgb(187,187,187);border-style:solid;border-w=
idth:1px" class=3D"m_6119929370070058788prettyprint"><code class=3D"m_61199=
29370070058788prettyprint"><div class=3D"m_6119929370070058788subprettyprin=
t"><span style=3D"color:#000" class=3D"m_6119929370070058788styled-by-prett=
ify"><br></span><span style=3D"color:#800" class=3D"m_6119929370070058788st=
yled-by-prettify">#include</span><span style=3D"color:#000" class=3D"m_6119=
929370070058788styled-by-prettify"> </span><span style=3D"color:#080" class=
=3D"m_6119929370070058788styled-by-prettify"><type_traits></span><spa=
n style=3D"color:#000" class=3D"m_6119929370070058788styled-by-prettify"><b=
r></span><span style=3D"color:#800" class=3D"m_6119929370070058788styled-by=
-prettify">#include</span><span style=3D"color:#000" class=3D"m_61199293700=
70058788styled-by-prettify"> </span><span style=3D"color:#080" class=3D"m_6=
119929370070058788styled-by-prettify"><optional></span><span style=3D=
"color:#000" class=3D"m_6119929370070058788styled-by-prettify"><br><br></sp=
an><span style=3D"color:#008" class=3D"m_6119929370070058788styled-by-prett=
ify">template</span><span style=3D"color:#000" class=3D"m_61199293700700587=
88styled-by-prettify"> </span><span style=3D"color:#080" class=3D"m_6119929=
370070058788styled-by-prettify"><typename></span><span style=3D"color=
:#000" class=3D"m_6119929370070058788styled-by-prettify"><br></span><span s=
tyle=3D"color:#008" class=3D"m_6119929370070058788styled-by-prettify">struc=
t</span><span style=3D"color:#000" class=3D"m_6119929370070058788styled-by-=
prettify"> </span><span style=3D"color:#008" class=3D"m_6119929370070058788=
styled-by-prettify">undefined</span><span style=3D"color:#660" class=3D"m_6=
119929370070058788styled-by-prettify">;</span><span style=3D"color:#000" cl=
ass=3D"m_6119929370070058788styled-by-prettify"><br><br></span><span style=
=3D"color:#008" class=3D"m_6119929370070058788styled-by-prettify">int</span=
><span style=3D"color:#000" class=3D"m_6119929370070058788styled-by-prettif=
y"> main</span><span style=3D"color:#660" class=3D"m_6119929370070058788sty=
led-by-prettify">()</span><span style=3D"color:#000" class=3D"m_61199293700=
70058788styled-by-prettify"><br></span><span style=3D"color:#660" class=3D"=
m_6119929370070058788styled-by-prettify">{</span><span style=3D"color:#000"=
class=3D"m_6119929370070058788styled-by-prettify"><br>=C2=A0 =C2=A0 </span=
><span style=3D"color:#008" class=3D"m_6119929370070058788styled-by-prettif=
y">using</span><span style=3D"color:#000" class=3D"m_6119929370070058788sty=
led-by-prettify"> common_t </span><span style=3D"color:#660" class=3D"m_611=
9929370070058788styled-by-prettify">=3D</span><span style=3D"color:#000" cl=
ass=3D"m_6119929370070058788styled-by-prettify"> std</span><span style=3D"c=
olor:#660" class=3D"m_6119929370070058788styled-by-prettify">::</span><span=
style=3D"color:#000" class=3D"m_6119929370070058788styled-by-prettify">com=
mon_type_t</span><span style=3D"color:#660" class=3D"m_6119929370070058788s=
tyled-by-prettify"><</span><span style=3D"color:#000" class=3D"m_6119929=
370070058788styled-by-prettify">std</span><span style=3D"color:#660" class=
=3D"m_6119929370070058788styled-by-prettify">::</span><span style=3D"color:=
#000" class=3D"m_6119929370070058788styled-by-prettify">nullopt_t</span><sp=
an style=3D"color:#660" class=3D"m_6119929370070058788styled-by-prettify">,=
</span><span style=3D"color:#000" class=3D"m_6119929370070058788styled-by-p=
rettify"> std</span><span style=3D"color:#660" class=3D"m_61199293700700587=
88styled-by-prettify">::</span><span style=3D"color:#000" class=3D"m_611992=
9370070058788styled-by-prettify">optional</span><span style=3D"color:#080" =
class=3D"m_6119929370070058788styled-by-prettify"><int></span><span s=
tyle=3D"color:#660" class=3D"m_6119929370070058788styled-by-prettify">>;=
</span><span style=3D"color:#000" class=3D"m_6119929370070058788styled-by-p=
rettify"><br>=C2=A0 =C2=A0 </span><span style=3D"color:#008" class=3D"m_611=
9929370070058788styled-by-prettify">static_assert</span><span style=3D"colo=
r:#660" class=3D"m_6119929370070058788styled-by-prettify">(</span><span sty=
le=3D"color:#000" class=3D"m_6119929370070058788styled-by-prettify">std</sp=
an><span style=3D"color:#660" class=3D"m_6119929370070058788styled-by-prett=
ify">::</span><span style=3D"color:#000" class=3D"m_6119929370070058788styl=
ed-by-prettify">is_same_v</span><span style=3D"color:#660" class=3D"m_61199=
29370070058788styled-by-prettify"><</span><span style=3D"color:#000" cla=
ss=3D"m_6119929370070058788styled-by-prettify">std</span><span style=3D"col=
or:#660" class=3D"m_6119929370070058788styled-by-prettify">::</span><span s=
tyle=3D"color:#000" class=3D"m_6119929370070058788styled-by-prettify">optio=
nal</span><span style=3D"color:#080" class=3D"m_6119929370070058788styled-b=
y-prettify"><int></span><span style=3D"color:#660" class=3D"m_6119929=
370070058788styled-by-prettify">,</span><span style=3D"color:#000" class=3D=
"m_6119929370070058788styled-by-prettify"> common_t</span><span style=3D"co=
lor:#660" class=3D"m_6119929370070058788styled-by-prettify">>);</span><s=
pan style=3D"color:#000" class=3D"m_6119929370070058788styled-by-prettify">=
<br>=C2=A0 =C2=A0 </span><span style=3D"color:#800" class=3D"m_611992937007=
0058788styled-by-prettify">//undefined<std::common_type_t<std::nullop=
t_t, std::optional<int>>> foo;</span><span style=3D"color:#000"=
class=3D"m_6119929370070058788styled-by-prettify"><br></span><span style=
=3D"color:#660" class=3D"m_6119929370070058788styled-by-prettify">}</span><=
/div></code></div><div><code><br><font size=3D"4">Possible damage:</font></=
code></div><div><code><b><br></b></code></div><div><code>I cannot think of =
any at the moment. I never encountered a case where compilation error insid=
e of lambda would be of any use. I believe this shouldn't affect existi=
ng code, as </code><code><code><code><span style=3D"color:rgb(11,83,148)"><=
span style=3D"background-color:rgb(238,238,238)"><span style=3D"font-family=
:courier new,monospace">std::common_type</span></span></span></code></code>=
is conversion rules friendly (not 100% sure though).</code></div></div></b=
lockquote></div></div><div dir=3D"auto"><br></div><div dir=3D"auto">The cur=
rent rules permit a function to call itself recursively after its first ret=
urn statement. How would you handle that?</div><div dir=3D"auto"><br></div>=
<div dir=3D"auto">common_type decays its arguments. How would you handle a =
return type of auto& or decltype(auto)?</div><div dir=3D"auto"><br></di=
v><div dir=3D"auto">This adds coupling between the language and library. Wh=
at should happen if a declaration of common_type has not been included prio=
r to the definition of a function with deduced return type?</div><div dir=
=3D"auto"><div class=3D"gmail_quote"><blockquote class=3D"gmail_quote" styl=
e=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<p></p>
-- <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" target=3D"_=
blank" rel=3D"noreferrer">std-proposals+unsubscribe@isocpp.org</a>.<br>
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org" target=3D"_blank" rel=3D"noreferrer">std-proposals@isocpp.org</a>.<br=
>
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/7772686a-7e80-4c28-a87b-c5dc11450cc6%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter" target=3D"_blank" =
rel=3D"noreferrer">https://groups.google.com/a/isocpp.org/d/msgid/std-propo=
sals/7772686a-7e80-4c28-a87b-c5dc11450cc6%40isocpp.org</a>.<br>
</blockquote></div></div></div>
<p></p>
-- <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 />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/CAOfiQqkzrG-PaTDHdq8Yk8m212%2Birb4hfF=
OefDmdUjH6vNON4A%40mail.gmail.com?utm_medium=3Demail&utm_source=3Dfooter">h=
ttps://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CAOfiQqkzrG-PaT=
DHdq8Yk8m212%2Birb4hfFOefDmdUjH6vNON4A%40mail.gmail.com</a>.<br />
--000000000000cdb1ed056f7aa60c--
.
Author: Tony V E <tvaneerd@gmail.com>
Date: Mon, 25 Jun 2018 14:39:48 -0400
Raw View
<html><head></head><body lang=3D"en-US" style=3D"background-color: rgb(255,=
255, 255); line-height: initial;"> =
<div style=3D"width: 100%; fo=
nt-size: initial; font-family: Calibri, 'Slate Pro', sans-serif, sans-serif=
; color: rgb(31, 73, 125); text-align: initial; background-color: rgb(255, =
255, 255);">We could at least avoid common_type by instead talking about as=
if by ?:</div> =
<d=
iv style=3D"width: 100%; font-size: initial; font-family: Calibri, 'Slate P=
ro', sans-serif, sans-serif; color: rgb(31, 73, 125); text-align: initial; =
background-color: rgb(255, 255, 255);"><br style=3D"display:initial"></div>=
=
=
<div style=3D"font-size: initi=
al; font-family: Calibri, 'Slate Pro', sans-serif, sans-serif; color: rgb(3=
1, 73, 125); text-align: initial; background-color: rgb(255, 255, 255);">Se=
nt from my BlackBerry portable Babbage Device=
</div> =
=
<table width=3D"100%" style=3D"background=
-color:white;border-spacing:0px;"> <tbody><tr><td colspan=3D"2" style=3D"fo=
nt-size: initial; text-align: initial; background-color: rgb(255, 255, 255)=
;"> <div style=3D"border-style: solid none none; =
border-top-color: rgb(181, 196, 223); border-top-width: 1pt; padding: 3pt 0=
in 0in; font-family: Tahoma, 'BB Alpha Sans', 'Slate Pro'; font-size: 10pt;=
"> <div><b>From: </b>Richard Smith</div><div><b>Sent: </b>Monday, June 25,=
2018 1:24 PM</div><div><b>To: </b>std-proposals@isocpp.org</div><div><b>Re=
ply To: </b>std-proposals@isocpp.org</div><div><b>Subject: </b>Re: [std-pro=
posals] Apply std::common_type_t to deduce final return type in lambda retu=
rn type deduction</div></div></td></tr></tbody></table><div style=3D"border=
-style: solid none none; border-top-color: rgb(186, 188, 209); border-top-w=
idth: 1pt; font-size: initial; text-align: initial; background-color: rgb(2=
55, 255, 255);"></div><br><div id=3D"_originalContent" style=3D""><div dir=
=3D"auto"><div><div class=3D"gmail_quote"><div dir=3D"ltr">On Sat, 23 Jun 2=
018, 13:14 , <<a href=3D"mailto:anonymous.from.applecity@gmail.com">anon=
ymous.from.applecity@gmail.com</a>> wrote:<br></div><blockquote class=3D=
"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padding=
-left:1ex"><div dir=3D"ltr"><div><font size=3D"4">Problem</font><b>:</b><br=
></div><div><br></div><div>When trying to mix <code><span style=3D"color:rg=
b(11,83,148)"><span style=3D"background-color:rgb(238,238,238)"><span style=
=3D"font-family:courier new,monospace">std::optional</span></span></span> w=
ith lambdas, I run into some rather annoying issue. I need to always use tr=
ailing return type syntax to get it deduced correctly in situations like th=
is (e.g. when </code><code><code><span style=3D"color:rgb(11,83,148)"><span=
style=3D"background-color:rgb(238,238,238)"><span style=3D"font-family:cou=
rier new,monospace">return std::nullopt</span></span></span></code> comes f=
irst):</code></div><div><code><br></code></div><div><code><div style=3D"bac=
kground-color:rgb(250,250,250);border-color:rgb(187,187,187);border-style:s=
olid;border-width:1px" class=3D"m_6119929370070058788prettyprint"><code cla=
ss=3D"m_6119929370070058788prettyprint"><div class=3D"m_6119929370070058788=
subprettyprint"><span style=3D"color:#660" class=3D"m_6119929370070058788st=
yled-by-prettify">[](</span><span style=3D"color:#008" class=3D"m_611992937=
0070058788styled-by-prettify">auto</span><span style=3D"color:#000" class=
=3D"m_6119929370070058788styled-by-prettify"> args</span><span style=3D"col=
or:#660" class=3D"m_6119929370070058788styled-by-prettify">)</span><span st=
yle=3D"color:#000" class=3D"m_6119929370070058788styled-by-prettify"> <br><=
/span><span style=3D"color:#660" class=3D"m_6119929370070058788styled-by-pr=
ettify">{</span><span style=3D"color:#000" class=3D"m_6119929370070058788st=
yled-by-prettify"><br> </span><span style=3D"color:#008" class=
=3D"m_6119929370070058788styled-by-prettify">if</span><span style=3D"color:=
#000" class=3D"m_6119929370070058788styled-by-prettify"> </span><span style=
=3D"color:#660" class=3D"m_6119929370070058788styled-by-prettify">(!</span>=
<span style=3D"color:#000" class=3D"m_6119929370070058788styled-by-prettify=
">check</span><span style=3D"color:#660" class=3D"m_6119929370070058788styl=
ed-by-prettify">(</span><span style=3D"color:#000" class=3D"m_6119929370070=
058788styled-by-prettify">args</span><span style=3D"color:#660" class=3D"m_=
6119929370070058788styled-by-prettify">))</span><span style=3D"color:#000" =
class=3D"m_6119929370070058788styled-by-prettify"><br> =
</span><span style=3D"color:#008" class=3D"m_6119929370070058788styl=
ed-by-prettify">return</span><span style=3D"color:#000" class=3D"m_61199293=
70070058788styled-by-prettify"> std</span><span style=3D"color:#660" class=
=3D"m_6119929370070058788styled-by-prettify">::</span><span style=3D"color:=
#000" class=3D"m_6119929370070058788styled-by-prettify">nullopt</span><span=
style=3D"color:#660" class=3D"m_6119929370070058788styled-by-prettify">;</=
span><span style=3D"color:#000" class=3D"m_6119929370070058788styled-by-pre=
ttify"><br><br> </span><span style=3D"color:#008" class=3D"m_6=
119929370070058788styled-by-prettify">return</span><span style=3D"color:#00=
0" class=3D"m_6119929370070058788styled-by-prettify"> foo</span><span style=
=3D"color:#660" class=3D"m_6119929370070058788styled-by-prettify">(</span><=
span style=3D"color:#000" class=3D"m_6119929370070058788styled-by-prettify"=
>args</span><span style=3D"color:#660" class=3D"m_6119929370070058788styled=
-by-prettify">);</span><span style=3D"color:#000" class=3D"m_61199293700700=
58788styled-by-prettify"> </span><span style=3D"color:#800" class=3D"m_6119=
929370070058788styled-by-prettify">//returns some std::optional<T></s=
pan><span style=3D"color:#000" class=3D"m_6119929370070058788styled-by-pret=
tify"><br></span><span style=3D"color:#660" class=3D"m_6119929370070058788s=
tyled-by-prettify">}</span><span style=3D"color:#000" class=3D"m_6119929370=
070058788styled-by-prettify"><br></span></div></code></div><br>The above wi=
ll not compile, as <span style=3D"color:rgb(11,83,148)"><span style=3D"back=
ground-color:rgb(238,238,238)"><span style=3D"font-family:courier new,monos=
pace">std::nullopt_t</span></span></span> cannot be converted to <span styl=
e=3D"color:rgb(11,83,148)"><span style=3D"background-color:rgb(238,238,238)=
">std::optional<T></span></span>. <br></code></div><div><code><br></c=
ode></div><div><code><font size=3D"4">Context</font><b>:</b></code></div><d=
iv><code><b><br></b></code></div><div><code>I'm trying to implement <span s=
tyle=3D"color:rgb(11,83,148)"><span style=3D"background-color:rgb(238,238,2=
38)"><span style=3D"font-family:courier new,monospace">try_in_sequence</spa=
n></span></span>, which basically executes functions passed as arguments on=
e by one, until one succeeds (e.g. returns non-empty optional). Writing ret=
urn type on every one of the 4-5 lambdas per function call is daunting. I u=
nderstand that lambda's return type is consistent with <span style=3D"color=
:rgb(11,83,148)"><span style=3D"background-color:rgb(238,238,238)"><span st=
yle=3D"font-family:courier new,monospace">auto</span></span></span>, but it=
doesn't seem to be practical in this case.</code></div><div><code><br></co=
de></div><div><code><font size=3D"4">Proposal</font><b>:</b></code></div><d=
iv><code><b><br></b></code></div><div><code>Use <span style=3D"color:rgb(11=
,83,148)"><span style=3D"background-color:rgb(238,238,238)"><span style=3D"=
font-family:courier new,monospace">std::common_type<return_stm_types...&=
gt;</span></span></span> as return type. E.g. use </code><code><code><span =
style=3D"color:rgb(11,83,148)"><span style=3D"background-color:rgb(238,238,=
238)"><span style=3D"font-family:courier new,monospace">auto</span></span><=
/span></code> on each return statement <i>individually</i>, then deduce com=
mon type using `std::common_type`. </code><code><code><span style=3D"color:=
rgb(11,83,148)"><span style=3D"background-color:rgb(238,238,238)"><span sty=
le=3D"font-family:courier new,monospace">std::common_type<std::nullopt_t=
, std::optional<int>></span></span></span></code> indeed yields </=
code><code><code><span style=3D"color:rgb(11,83,148)"><span style=3D"backgr=
ound-color:rgb(238,238,238)">std::optional<int></span></span></code>,=
as shown in shown in <a href=3D"https://wandbox.org/permlink/oIhIR7QsmvThb=
SoM" target=3D"_blank" rel=3D"noreferrer">this example</a>:</code></div><di=
v><code><br></code></div><div style=3D"background-color:rgb(250,250,250);bo=
rder-color:rgb(187,187,187);border-style:solid;border-width:1px" class=3D"m=
_6119929370070058788prettyprint"><code class=3D"m_6119929370070058788pretty=
print"><div class=3D"m_6119929370070058788subprettyprint"><span style=3D"co=
lor:#000" class=3D"m_6119929370070058788styled-by-prettify"><br></span><spa=
n style=3D"color:#800" class=3D"m_6119929370070058788styled-by-prettify">#i=
nclude</span><span style=3D"color:#000" class=3D"m_6119929370070058788style=
d-by-prettify"> </span><span style=3D"color:#080" class=3D"m_61199293700700=
58788styled-by-prettify"><type_traits></span><span style=3D"color:#00=
0" class=3D"m_6119929370070058788styled-by-prettify"><br></span><span style=
=3D"color:#800" class=3D"m_6119929370070058788styled-by-prettify">#include<=
/span><span style=3D"color:#000" class=3D"m_6119929370070058788styled-by-pr=
ettify"> </span><span style=3D"color:#080" class=3D"m_6119929370070058788st=
yled-by-prettify"><optional></span><span style=3D"color:#000" class=
=3D"m_6119929370070058788styled-by-prettify"><br><br></span><span style=3D"=
color:#008" class=3D"m_6119929370070058788styled-by-prettify">template</spa=
n><span style=3D"color:#000" class=3D"m_6119929370070058788styled-by-pretti=
fy"> </span><span style=3D"color:#080" class=3D"m_6119929370070058788styled=
-by-prettify"><typename></span><span style=3D"color:#000" class=3D"m_=
6119929370070058788styled-by-prettify"><br></span><span style=3D"color:#008=
" class=3D"m_6119929370070058788styled-by-prettify">struct</span><span styl=
e=3D"color:#000" class=3D"m_6119929370070058788styled-by-prettify"> </span>=
<span style=3D"color:#008" class=3D"m_6119929370070058788styled-by-prettify=
">undefined</span><span style=3D"color:#660" class=3D"m_6119929370070058788=
styled-by-prettify">;</span><span style=3D"color:#000" class=3D"m_611992937=
0070058788styled-by-prettify"><br><br></span><span style=3D"color:#008" cla=
ss=3D"m_6119929370070058788styled-by-prettify">int</span><span style=3D"col=
or:#000" class=3D"m_6119929370070058788styled-by-prettify"> main</span><spa=
n style=3D"color:#660" class=3D"m_6119929370070058788styled-by-prettify">()=
</span><span style=3D"color:#000" class=3D"m_6119929370070058788styled-by-p=
rettify"><br></span><span style=3D"color:#660" class=3D"m_61199293700700587=
88styled-by-prettify">{</span><span style=3D"color:#000" class=3D"m_6119929=
370070058788styled-by-prettify"><br> </span><span style=3D"col=
or:#008" class=3D"m_6119929370070058788styled-by-prettify">using</span><spa=
n style=3D"color:#000" class=3D"m_6119929370070058788styled-by-prettify"> c=
ommon_t </span><span style=3D"color:#660" class=3D"m_6119929370070058788sty=
led-by-prettify">=3D</span><span style=3D"color:#000" class=3D"m_6119929370=
070058788styled-by-prettify"> std</span><span style=3D"color:#660" class=3D=
"m_6119929370070058788styled-by-prettify">::</span><span style=3D"color:#00=
0" class=3D"m_6119929370070058788styled-by-prettify">common_type_t</span><s=
pan style=3D"color:#660" class=3D"m_6119929370070058788styled-by-prettify">=
<</span><span style=3D"color:#000" class=3D"m_6119929370070058788styled-=
by-prettify">std</span><span style=3D"color:#660" class=3D"m_61199293700700=
58788styled-by-prettify">::</span><span style=3D"color:#000" class=3D"m_611=
9929370070058788styled-by-prettify">nullopt_t</span><span style=3D"color:#6=
60" class=3D"m_6119929370070058788styled-by-prettify">,</span><span style=
=3D"color:#000" class=3D"m_6119929370070058788styled-by-prettify"> std</spa=
n><span style=3D"color:#660" class=3D"m_6119929370070058788styled-by-pretti=
fy">::</span><span style=3D"color:#000" class=3D"m_6119929370070058788style=
d-by-prettify">optional</span><span style=3D"color:#080" class=3D"m_6119929=
370070058788styled-by-prettify"><int></span><span style=3D"color:#660=
" class=3D"m_6119929370070058788styled-by-prettify">>;</span><span style=
=3D"color:#000" class=3D"m_6119929370070058788styled-by-prettify"><br> =
; </span><span style=3D"color:#008" class=3D"m_6119929370070058788st=
yled-by-prettify">static_assert</span><span style=3D"color:#660" class=3D"m=
_6119929370070058788styled-by-prettify">(</span><span style=3D"color:#000" =
class=3D"m_6119929370070058788styled-by-prettify">std</span><span style=3D"=
color:#660" class=3D"m_6119929370070058788styled-by-prettify">::</span><spa=
n style=3D"color:#000" class=3D"m_6119929370070058788styled-by-prettify">is=
_same_v</span><span style=3D"color:#660" class=3D"m_6119929370070058788styl=
ed-by-prettify"><</span><span style=3D"color:#000" class=3D"m_6119929370=
070058788styled-by-prettify">std</span><span style=3D"color:#660" class=3D"=
m_6119929370070058788styled-by-prettify">::</span><span style=3D"color:#000=
" class=3D"m_6119929370070058788styled-by-prettify">optional</span><span st=
yle=3D"color:#080" class=3D"m_6119929370070058788styled-by-prettify"><in=
t></span><span style=3D"color:#660" class=3D"m_6119929370070058788styled=
-by-prettify">,</span><span style=3D"color:#000" class=3D"m_611992937007005=
8788styled-by-prettify"> common_t</span><span style=3D"color:#660" class=3D=
"m_6119929370070058788styled-by-prettify">>);</span><span style=3D"color=
:#000" class=3D"m_6119929370070058788styled-by-prettify"><br> =
</span><span style=3D"color:#800" class=3D"m_6119929370070058788styled-by-p=
rettify">//undefined<std::common_type_t<std::nullopt_t, std::optional=
<int>>> foo;</span><span style=3D"color:#000" class=3D"m_611992=
9370070058788styled-by-prettify"><br></span><span style=3D"color:#660" clas=
s=3D"m_6119929370070058788styled-by-prettify">}</span></div></code></div><d=
iv><code><br><font size=3D"4">Possible damage:</font></code></div><div><cod=
e><b><br></b></code></div><div><code>I cannot think of any at the moment. I=
never encountered a case where compilation error inside of lambda would be=
of any use. I believe this shouldn't affect existing code, as </code><code=
><code><code><span style=3D"color:rgb(11,83,148)"><span style=3D"background=
-color:rgb(238,238,238)"><span style=3D"font-family:courier new,monospace">=
std::common_type</span></span></span></code></code> is conversion rules fri=
endly (not 100% sure though).</code></div></div></blockquote></div></div><d=
iv dir=3D"auto"><br></div><div dir=3D"auto">The current rules permit a func=
tion to call itself recursively after its first return statement. How would=
you handle that?</div><div dir=3D"auto"><br></div><div dir=3D"auto">common=
_type decays its arguments. How would you handle a return type of auto&=
or decltype(auto)?</div><div dir=3D"auto"><br></div><div dir=3D"auto">This=
adds coupling between the language and library. What should happen if a de=
claration of common_type has not been included prior to the definition of a=
function with deduced return type?</div><div dir=3D"auto"><div class=3D"gm=
ail_quote"><blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;bor=
der-left:1px #ccc solid;padding-left:1ex">
<p></p>
-- <br>
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.<br>
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org" target=3D"_=
blank" rel=3D"noreferrer">std-proposals+unsubscribe@isocpp.org</a>.<br>
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org" target=3D"_blank" rel=3D"noreferrer">std-proposals@isocpp.org</a>.<br=
>
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/7772686a-7e80-4c28-a87b-c5dc11450cc6%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter" target=3D"_blank" =
rel=3D"noreferrer">https://groups.google.com/a/isocpp.org/d/msgid/std-propo=
sals/7772686a-7e80-4c28-a87b-c5dc11450cc6%40isocpp.org</a>.<br>
</blockquote></div></div></div>
<p></p>
-- <br>
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.<br>
To unsubscribe from this group and stop receiving emails from it, send an 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>
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/CAOfiQqkzrG-PaTDHdq8Yk8m212%2Birb4hfF=
OefDmdUjH6vNON4A%40mail.gmail.com?utm_medium=3Demail&utm_source=3Dfoote=
r">https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CAOfiQqkzrG=
-PaTDHdq8Yk8m212%2Birb4hfFOefDmdUjH6vNON4A%40mail.gmail.com</a>.<br>
<br><!--end of _originalContent --></div></body></html>
<p></p>
-- <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 />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/20180625183948.5193804.45505.56022%40=
gmail.com?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.com=
/a/isocpp.org/d/msgid/std-proposals/20180625183948.5193804.45505.56022%40gm=
ail.com</a>.<br />
.
Author: Richard Smith <richard@metafoo.co.uk>
Date: Mon, 25 Jun 2018 12:28:44 -0700
Raw View
--0000000000000143be056f7c65fe
Content-Type: text/plain; charset="UTF-8"
On 25 June 2018 at 11:39, Tony V E <tvaneerd@gmail.com> wrote:
> We could at least avoid common_type by instead talking about as if by ?:
>
Yes; I wish the language rule had originally been defined that way. The
self-recursive function case doesn't seem sufficiently compelling to me to
take priority over supporting multiple returns with different types.
(Note that this would not permit common_type to be used as a customization
point for return type deduction, but that seems OK to me... ?: doesn't
support that either, and it doesn't seem to be a big deal in practice -- if
we want to make that work, adding a way to overload operator?: enough to
guide its type deduction -- rather than specializing common_type -- seems
like a reasonable way forward:
template<typename R1, typename P1, typename R2, typename P2>
operator?:(chrono::duration<R1, P1>, chrono::duration<R2, P2>) ->
chrono::duration<common_type_t<R1, R2>, gcd<P1, P2>>;
.... but I'm not suggesting we pursue that at this time.)
I suppose we could say that return type deduction happens at the end of the
function or at the first recursive call, whichever comes first, and that
the program is ill-formed if there's a recursive call and the return type
that would be deduced at the end of the function differs from the return
type deduced at the recursive call.
> Sent from my BlackBerry portable Babbage Device
> *From: *Richard Smith
> *Sent: *Monday, June 25, 2018 1:24 PM
> *To: *std-proposals@isocpp.org
> *Reply To: *std-proposals@isocpp.org
> *Subject: *Re: [std-proposals] Apply std::common_type_t to deduce final
> return type in lambda return type deduction
>
> On Sat, 23 Jun 2018, 13:14 , <anonymous.from.applecity@gmail.com> wrote:
>
>> Problem*:*
>>
>> When trying to mix std::optional with lambdas, I run into some rather
>> annoying issue. I need to always use trailing return type syntax to get it
>> deduced correctly in situations like this (e.g. when return std::nullopt
>> comes first):
>>
>> [](auto args)
>> {
>> if (!check(args))
>> return std::nullopt;
>>
>> return foo(args); //returns some std::optional<T>
>> }
>>
>> The above will not compile, as std::nullopt_t cannot be converted to
>> std::optional<T>.
>>
>> Context*:*
>>
>> I'm trying to implement try_in_sequence, which basically executes
>> functions passed as arguments one by one, until one succeeds (e.g. returns
>> non-empty optional). Writing return type on every one of the 4-5 lambdas
>> per function call is daunting. I understand that lambda's return type is
>> consistent with auto, but it doesn't seem to be practical in this case.
>>
>> Proposal*:*
>>
>> Use std::common_type<return_stm_types...> as return type. E.g. use auto
>> on each return statement *individually*, then deduce common type using
>> `std::common_type`. std::common_type<std::nullopt_t, std::optional<int>>
>> indeed yields std::optional<int>, as shown in shown in this example
>> <https://wandbox.org/permlink/oIhIR7QsmvThbSoM>:
>>
>>
>> #include <type_traits>
>> #include <optional>
>>
>> template <typename>
>> struct undefined;
>>
>> int main()
>> {
>> using common_t = std::common_type_t<std::nullopt_t, std::optional
>> <int>>;
>> static_assert(std::is_same_v<std::optional<int>, common_t>);
>> //undefined<std::common_type_t<std::nullopt_t, std::optional<int>>>
>> foo;
>> }
>>
>> Possible damage:
>>
>> I cannot think of any at the moment. I never encountered a case where
>> compilation error inside of lambda would be of any use. I believe this
>> shouldn't affect existing code, as std::common_type is conversion rules
>> friendly (not 100% sure though).
>>
>
> The current rules permit a function to call itself recursively after its
> first return statement. How would you handle that?
>
> common_type decays its arguments. How would you handle a return type of
> auto& or decltype(auto)?
>
> This adds coupling between the language and library. What should happen if
> a declaration of common_type has not been included prior to the definition
> of a function with deduced return type?
>
>> --
>> 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.
>> To view this discussion on the web visit https://groups.google.com/a/
>> isocpp.org/d/msgid/std-proposals/7772686a-7e80-4c28-
>> a87b-c5dc11450cc6%40isocpp.org
>> <https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/7772686a-7e80-4c28-a87b-c5dc11450cc6%40isocpp.org?utm_medium=email&utm_source=footer>
>> .
>>
> --
> 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.
> To view this discussion on the web visit https://groups.google.com/a/
> isocpp.org/d/msgid/std-proposals/CAOfiQqkzrG-PaTDHdq8Yk8m212%
> 2Birb4hfFOefDmdUjH6vNON4A%40mail.gmail.com
> <https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CAOfiQqkzrG-PaTDHdq8Yk8m212%2Birb4hfFOefDmdUjH6vNON4A%40mail.gmail.com?utm_medium=email&utm_source=footer>
> .
>
> --
> 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.
> To view this discussion on the web visit https://groups.google.com/a/
> isocpp.org/d/msgid/std-proposals/20180625183948.
> 5193804.45505.56022%40gmail.com
> <https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/20180625183948.5193804.45505.56022%40gmail.com?utm_medium=email&utm_source=footer>
> .
>
--
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.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CAOfiQqnZxpq2v8xHx_%3DscJOMGXydDzr9RReV81vyn276O%3DM%3DoA%40mail.gmail.com.
--0000000000000143be056f7c65fe
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><div class=3D"gmail_extra"><div class=3D"gmail_quote">On 2=
5 June 2018 at 11:39, Tony V E <span dir=3D"ltr"><<a href=3D"mailto:tvan=
eerd@gmail.com" target=3D"_blank">tvaneerd@gmail.com</a>></span> wrote:<=
br><blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left=
:1px #ccc solid;padding-left:1ex"><div lang=3D"en-US" style=3D"background-c=
olor:rgb(255,255,255);line-height:initial"> =
<div style=3D"width:1=
00%;font-size:initial;font-family:Calibri,'Slate Pro',sans-serif,sa=
ns-serif;color:rgb(31,73,125);text-align:initial;background-color:rgb(255,2=
55,255)">We could at least avoid common_type by instead talking about as if=
by ?:</div></div></blockquote><div><br></div><div>Yes; I wish the language=
rule had originally been defined that way. The self-recursive function cas=
e doesn't seem sufficiently compelling to me to take priority over supp=
orting multiple returns with different types.</div><div><br></div><div>(Not=
e that this would not permit common_type to be used as a customization poin=
t for return type deduction, but that seems OK to me... ?: doesn't supp=
ort that either, and it doesn't seem to be a big deal in practice -- if=
we want to make that work, adding a way to overload operator?: enough to g=
uide its type deduction -- rather than specializing common_type -- seems li=
ke a reasonable way forward:</div><div><br></div><div>template<typename =
R1, typename P1, typename R2, typename P2></div><div>=C2=A0 operator?:(c=
hrono::duration<R1, P1>, chrono::duration<R2, P2>) -> chrono=
::duration<common_type_t<R1, R2>, gcd<P1, P2>>;</div><div=
><br></div><div>... but I'm not suggesting we pursue that at this time.=
)</div><div><br></div><div>I suppose we could say that return type deductio=
n happens at the end of the function or at the first recursive call, whiche=
ver comes first, and that the program is ill-formed if there's a recurs=
ive call and the return type that would be deduced at the end of the functi=
on differs from the return type deduced at the recursive call.</div><div>=
=C2=A0</div><blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;bo=
rder-left:1px #ccc solid;padding-left:1ex"><div lang=3D"en-US" style=3D"bac=
kground-color:rgb(255,255,255);line-height:initial"> =
=
=
<div style=3D"font-size:initial;font-family:Calibri,&=
#39;Slate Pro',sans-serif,sans-serif;color:rgb(31,73,125);text-align:in=
itial;background-color:rgb(255,255,255)">Sent=C2=A0from=C2=A0my=C2=A0BlackB=
erry=C2=A0<wbr>portable=C2=A0Babbage=C2=A0Device</div> =
=
=
<table width=3D"100%" style=3D"background-color:white;border-spacing=
:0px"> <tbody><tr><td colspan=3D"2" style=3D"font-size:initial;text-align:i=
nitial;background-color:rgb(255,255,255)"> <div s=
tyle=3D"border-style:solid none none;border-top-color:rgb(181,196,223);bord=
er-top-width:1pt;padding:3pt 0in 0in;font-family:Tahoma,'BB Alpha Sans&=
#39;,'Slate Pro';font-size:10pt"> <div><b>From: </b>Richard Smith<=
/div><div><b>Sent: </b>Monday, June 25, 2018 1:24 PM</div><div><b>To: </b><=
a href=3D"mailto:std-proposals@isocpp.org" target=3D"_blank">std-proposals@=
isocpp.org</a></div><div><b>Reply To: </b><a href=3D"mailto:std-proposals@i=
socpp.org" target=3D"_blank">std-proposals@isocpp.org</a></div><div><b>Subj=
ect: </b>Re: [std-proposals] Apply std::common_type_t to deduce final retur=
n type in lambda return type deduction</div></div></td></tr></tbody></table=
><div style=3D"border-style:solid none none;border-top-color:rgb(186,188,20=
9);border-top-width:1pt;font-size:initial;text-align:initial;background-col=
or:rgb(255,255,255)"></div><br><div id=3D"m_5029138139341741775_originalCon=
tent"><div><div class=3D"h5"><div dir=3D"auto"><div><div class=3D"gmail_quo=
te"><div dir=3D"ltr">On Sat, 23 Jun 2018, 13:14 , <<a href=3D"mailto:ano=
nymous.from.applecity@gmail.com" target=3D"_blank">anonymous.from.applecity=
@<wbr>gmail.com</a>> wrote:<br></div><blockquote class=3D"gmail_quote" s=
tyle=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div=
dir=3D"ltr"><div><font size=3D"4">Problem</font><b>:</b><br></div><div><br=
></div><div>When trying to mix <code><span style=3D"color:rgb(11,83,148)"><=
span style=3D"background-color:rgb(238,238,238)"><span style=3D"font-family=
:courier new,monospace">std::optional</span></span></span> with lambdas, I =
run into some rather annoying issue. I need to always use trailing return t=
ype syntax to get it deduced correctly in situations like this (e.g. when <=
/code><code><code><span style=3D"color:rgb(11,83,148)"><span style=3D"backg=
round-color:rgb(238,238,238)"><span style=3D"font-family:courier new,monosp=
ace">return std::nullopt</span></span></span></code> comes first):</code></=
div><div><code><br></code></div><div><code><div style=3D"background-color:r=
gb(250,250,250);border-color:rgb(187,187,187);border-style:solid;border-wid=
th:1px" class=3D"m_5029138139341741775m_6119929370070058788prettyprint"><co=
de class=3D"m_5029138139341741775m_6119929370070058788prettyprint"><div cla=
ss=3D"m_5029138139341741775m_6119929370070058788subprettyprint"><span style=
=3D"color:#660" class=3D"m_5029138139341741775m_6119929370070058788styled-b=
y-prettify">[](</span><span style=3D"color:#008" class=3D"m_502913813934174=
1775m_6119929370070058788styled-by-prettify">auto</span><span style=3D"colo=
r:#000" class=3D"m_5029138139341741775m_6119929370070058788styled-by-pretti=
fy"> args</span><span style=3D"color:#660" class=3D"m_5029138139341741775m_=
6119929370070058788styled-by-prettify">)</span><span style=3D"color:#000" c=
lass=3D"m_5029138139341741775m_6119929370070058788styled-by-prettify"> <br>=
</span><span style=3D"color:#660" class=3D"m_5029138139341741775m_611992937=
0070058788styled-by-prettify">{</span><span style=3D"color:#000" class=3D"m=
_5029138139341741775m_6119929370070058788styled-by-prettify"><br>=C2=A0 =C2=
=A0 </span><span style=3D"color:#008" class=3D"m_5029138139341741775m_61199=
29370070058788styled-by-prettify">if</span><span style=3D"color:#000" class=
=3D"m_5029138139341741775m_6119929370070058788styled-by-prettify"> </span><=
span style=3D"color:#660" class=3D"m_5029138139341741775m_61199293700700587=
88styled-by-prettify">(!</span><span style=3D"color:#000" class=3D"m_502913=
8139341741775m_6119929370070058788styled-by-prettify">check</span><span sty=
le=3D"color:#660" class=3D"m_5029138139341741775m_6119929370070058788styled=
-by-prettify">(</span><span style=3D"color:#000" class=3D"m_502913813934174=
1775m_6119929370070058788styled-by-prettify">args</span><span style=3D"colo=
r:#660" class=3D"m_5029138139341741775m_6119929370070058788styled-by-pretti=
fy">))</span><span style=3D"color:#000" class=3D"m_5029138139341741775m_611=
9929370070058788styled-by-prettify"><br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 </span>=
<span style=3D"color:#008" class=3D"m_5029138139341741775m_6119929370070058=
788styled-by-prettify">return</span><span style=3D"color:#000" class=3D"m_5=
029138139341741775m_6119929370070058788styled-by-prettify"> std</span><span=
style=3D"color:#660" class=3D"m_5029138139341741775m_6119929370070058788st=
yled-by-prettify">::</span><span style=3D"color:#000" class=3D"m_5029138139=
341741775m_6119929370070058788styled-by-prettify">nullopt</span><span style=
=3D"color:#660" class=3D"m_5029138139341741775m_6119929370070058788styled-b=
y-prettify">;</span><span style=3D"color:#000" class=3D"m_50291381393417417=
75m_6119929370070058788styled-by-prettify"><br><br>=C2=A0 =C2=A0 </span><sp=
an style=3D"color:#008" class=3D"m_5029138139341741775m_6119929370070058788=
styled-by-prettify">return</span><span style=3D"color:#000" class=3D"m_5029=
138139341741775m_6119929370070058788styled-by-prettify"> foo</span><span st=
yle=3D"color:#660" class=3D"m_5029138139341741775m_6119929370070058788style=
d-by-prettify">(</span><span style=3D"color:#000" class=3D"m_50291381393417=
41775m_6119929370070058788styled-by-prettify">args</span><span style=3D"col=
or:#660" class=3D"m_5029138139341741775m_6119929370070058788styled-by-prett=
ify">);</span><span style=3D"color:#000" class=3D"m_5029138139341741775m_61=
19929370070058788styled-by-prettify"> </span><span style=3D"color:#800" cla=
ss=3D"m_5029138139341741775m_6119929370070058788styled-by-prettify">//retur=
ns some std::optional<T></span><span style=3D"color:#000" class=3D"m_=
5029138139341741775m_6119929370070058788styled-by-prettify"><br></span><spa=
n style=3D"color:#660" class=3D"m_5029138139341741775m_6119929370070058788s=
tyled-by-prettify">}</span><span style=3D"color:#000" class=3D"m_5029138139=
341741775m_6119929370070058788styled-by-prettify"><br></span></div></code><=
/div><br>The above will not compile, as <span style=3D"color:rgb(11,83,148)=
"><span style=3D"background-color:rgb(238,238,238)"><span style=3D"font-fam=
ily:courier new,monospace">std::nullopt_t</span></span></span> cannot be co=
nverted to <span style=3D"color:rgb(11,83,148)"><span style=3D"background-c=
olor:rgb(238,238,238)">std::optional<T></span></span>. <br></code></d=
iv><div><code><br></code></div><div><code><font size=3D"4">Context</font><b=
>:</b></code></div><div><code><b><br></b></code></div><div><code>I'm tr=
ying to implement <span style=3D"color:rgb(11,83,148)"><span style=3D"backg=
round-color:rgb(238,238,238)"><span style=3D"font-family:courier new,monosp=
ace">try_in_sequence</span></span></span>, which basically executes functio=
ns passed as arguments one by one, until one succeeds (e.g. returns non-emp=
ty optional). Writing return type on every one of the 4-5 lambdas per funct=
ion call is daunting. I understand that lambda's return type is consist=
ent with <span style=3D"color:rgb(11,83,148)"><span style=3D"background-col=
or:rgb(238,238,238)"><span style=3D"font-family:courier new,monospace">auto=
</span></span></span>, but it doesn't seem to be practical in this case=
..</code></div><div><code><br></code></div><div><code><font size=3D"4">Propo=
sal</font><b>:</b></code></div><div><code><b><br></b></code></div><div><cod=
e>Use <span style=3D"color:rgb(11,83,148)"><span style=3D"background-color:=
rgb(238,238,238)"><span style=3D"font-family:courier new,monospace">std::co=
mmon_type<return_stm_<wbr>types...></span></span></span> as return ty=
pe. E.g. use </code><code><code><span style=3D"color:rgb(11,83,148)"><span =
style=3D"background-color:rgb(238,238,238)"><span style=3D"font-family:cour=
ier new,monospace">auto</span></span></span></code> on each return statemen=
t <i>individually</i>, then deduce common type using `std::common_type`. </=
code><code><code><span style=3D"color:rgb(11,83,148)"><span style=3D"backgr=
ound-color:rgb(238,238,238)"><span style=3D"font-family:courier new,monospa=
ce">std::common_type<std::nullopt_<wbr>t, std::optional<int>></=
span></span></span></code> indeed yields </code><code><code><span style=3D"=
color:rgb(11,83,148)"><span style=3D"background-color:rgb(238,238,238)">std=
::optional<int></span></span></code>, as shown in shown in <a href=3D=
"https://wandbox.org/permlink/oIhIR7QsmvThbSoM" rel=3D"noreferrer" target=
=3D"_blank">this example</a>:</code></div><div><code><br></code></div><div =
style=3D"background-color:rgb(250,250,250);border-color:rgb(187,187,187);bo=
rder-style:solid;border-width:1px" class=3D"m_5029138139341741775m_61199293=
70070058788prettyprint"><code class=3D"m_5029138139341741775m_6119929370070=
058788prettyprint"><div class=3D"m_5029138139341741775m_6119929370070058788=
subprettyprint"><span style=3D"color:#000" class=3D"m_5029138139341741775m_=
6119929370070058788styled-by-prettify"><br></span><span style=3D"color:#800=
" class=3D"m_5029138139341741775m_6119929370070058788styled-by-prettify">#i=
nclude</span><span style=3D"color:#000" class=3D"m_5029138139341741775m_611=
9929370070058788styled-by-prettify"> </span><span style=3D"color:#080" clas=
s=3D"m_5029138139341741775m_6119929370070058788styled-by-prettify"><type=
_traits></span><span style=3D"color:#000" class=3D"m_5029138139341741775=
m_6119929370070058788styled-by-prettify"><br></span><span style=3D"color:#8=
00" class=3D"m_5029138139341741775m_6119929370070058788styled-by-prettify">=
#include</span><span style=3D"color:#000" class=3D"m_5029138139341741775m_6=
119929370070058788styled-by-prettify"> </span><span style=3D"color:#080" cl=
ass=3D"m_5029138139341741775m_6119929370070058788styled-by-prettify"><op=
tional></span><span style=3D"color:#000" class=3D"m_5029138139341741775m=
_6119929370070058788styled-by-prettify"><br><br></span><span style=3D"color=
:#008" class=3D"m_5029138139341741775m_6119929370070058788styled-by-prettif=
y">template</span><span style=3D"color:#000" class=3D"m_5029138139341741775=
m_6119929370070058788styled-by-prettify"> </span><span style=3D"color:#080"=
class=3D"m_5029138139341741775m_6119929370070058788styled-by-prettify"><=
;typename></span><span style=3D"color:#000" class=3D"m_50291381393417417=
75m_6119929370070058788styled-by-prettify"><br></span><span style=3D"color:=
#008" class=3D"m_5029138139341741775m_6119929370070058788styled-by-prettify=
">struct</span><span style=3D"color:#000" class=3D"m_5029138139341741775m_6=
119929370070058788styled-by-prettify"> </span><span style=3D"color:#008" cl=
ass=3D"m_5029138139341741775m_6119929370070058788styled-by-prettify">undefi=
ned</span><span style=3D"color:#660" class=3D"m_5029138139341741775m_611992=
9370070058788styled-by-prettify">;</span><span style=3D"color:#000" class=
=3D"m_5029138139341741775m_6119929370070058788styled-by-prettify"><br><br><=
/span><span style=3D"color:#008" class=3D"m_5029138139341741775m_6119929370=
070058788styled-by-prettify">int</span><span style=3D"color:#000" class=3D"=
m_5029138139341741775m_6119929370070058788styled-by-prettify"> main</span><=
span style=3D"color:#660" class=3D"m_5029138139341741775m_61199293700700587=
88styled-by-prettify">()</span><span style=3D"color:#000" class=3D"m_502913=
8139341741775m_6119929370070058788styled-by-prettify"><br></span><span styl=
e=3D"color:#660" class=3D"m_5029138139341741775m_6119929370070058788styled-=
by-prettify">{</span><span style=3D"color:#000" class=3D"m_5029138139341741=
775m_6119929370070058788styled-by-prettify"><br>=C2=A0 =C2=A0 </span><span =
style=3D"color:#008" class=3D"m_5029138139341741775m_6119929370070058788sty=
led-by-prettify">using</span><span style=3D"color:#000" class=3D"m_50291381=
39341741775m_6119929370070058788styled-by-prettify"> common_t </span><span =
style=3D"color:#660" class=3D"m_5029138139341741775m_6119929370070058788sty=
led-by-prettify">=3D</span><span style=3D"color:#000" class=3D"m_5029138139=
341741775m_6119929370070058788styled-by-prettify"> std</span><span style=3D=
"color:#660" class=3D"m_5029138139341741775m_6119929370070058788styled-by-p=
rettify">::</span><span style=3D"color:#000" class=3D"m_5029138139341741775=
m_6119929370070058788styled-by-prettify">common_type_t</span><span style=3D=
"color:#660" class=3D"m_5029138139341741775m_6119929370070058788styled-by-p=
rettify"><</span><span style=3D"color:#000" class=3D"m_50291381393417417=
75m_6119929370070058788styled-by-prettify">std</span><span style=3D"color:#=
660" class=3D"m_5029138139341741775m_6119929370070058788styled-by-prettify"=
>::</span><span style=3D"color:#000" class=3D"m_5029138139341741775m_611992=
9370070058788styled-by-prettify">nullop<wbr>t_t</span><span style=3D"color:=
#660" class=3D"m_5029138139341741775m_6119929370070058788styled-by-prettify=
">,</span><span style=3D"color:#000" class=3D"m_5029138139341741775m_611992=
9370070058788styled-by-prettify"> std</span><span style=3D"color:#660" clas=
s=3D"m_5029138139341741775m_6119929370070058788styled-by-prettify">::</span=
><span style=3D"color:#000" class=3D"m_5029138139341741775m_611992937007005=
8788styled-by-prettify">optional</span><span style=3D"color:#080" class=3D"=
m_5029138139341741775m_6119929370070058788styled-by-prettify"><int></=
span><span style=3D"color:#660" class=3D"m_5029138139341741775m_61199293700=
70058788styled-by-prettify">>;</span><span style=3D"color:#000" class=3D=
"m_5029138139341741775m_6119929370070058788styled-by-prettify"><br>=C2=A0 =
=C2=A0 </span><span style=3D"color:#008" class=3D"m_5029138139341741775m_61=
19929370070058788styled-by-prettify">static_assert</span><span style=3D"col=
or:#660" class=3D"m_5029138139341741775m_6119929370070058788styled-by-prett=
ify">(</span><span style=3D"color:#000" class=3D"m_5029138139341741775m_611=
9929370070058788styled-by-prettify">std</span><span style=3D"color:#660" cl=
ass=3D"m_5029138139341741775m_6119929370070058788styled-by-prettify">::</sp=
an><span style=3D"color:#000" class=3D"m_5029138139341741775m_6119929370070=
058788styled-by-prettify">is_same_v</span><span style=3D"color:#660" class=
=3D"m_5029138139341741775m_6119929370070058788styled-by-prettify"><</spa=
n><span style=3D"color:#000" class=3D"m_5029138139341741775m_61199293700700=
58788styled-by-prettify">s<wbr>td</span><span style=3D"color:#660" class=3D=
"m_5029138139341741775m_6119929370070058788styled-by-prettify">::</span><sp=
an style=3D"color:#000" class=3D"m_5029138139341741775m_6119929370070058788=
styled-by-prettify">optional</span><span style=3D"color:#080" class=3D"m_50=
29138139341741775m_6119929370070058788styled-by-prettify"><int></span=
><span style=3D"color:#660" class=3D"m_5029138139341741775m_611992937007005=
8788styled-by-prettify">,</span><span style=3D"color:#000" class=3D"m_50291=
38139341741775m_6119929370070058788styled-by-prettify"> common_t</span><spa=
n style=3D"color:#660" class=3D"m_5029138139341741775m_6119929370070058788s=
tyled-by-prettify">>);</span><span style=3D"color:#000" class=3D"m_50291=
38139341741775m_6119929370070058788styled-by-prettify"><br>=C2=A0 =C2=A0 </=
span><span style=3D"color:#800" class=3D"m_5029138139341741775m_61199293700=
70058788styled-by-prettify">//undefined<std::common_type_<wbr>t<std::=
nullopt_t, std::optional<int>>> foo;</span><span style=3D"color=
:#000" class=3D"m_5029138139341741775m_6119929370070058788styled-by-prettif=
y"><br></span><span style=3D"color:#660" class=3D"m_5029138139341741775m_61=
19929370070058788styled-by-prettify">}</span></div></code></div><div><code>=
<br><font size=3D"4">Possible damage:</font></code></div><div><code><b><br>=
</b></code></div><div><code>I cannot think of any at the moment. I never en=
countered a case where compilation error inside of lambda would be of any u=
se. I believe this shouldn't affect existing code, as </code><code><cod=
e><code><span style=3D"color:rgb(11,83,148)"><span style=3D"background-colo=
r:rgb(238,238,238)"><span style=3D"font-family:courier new,monospace">std::=
common_type</span></span></span></code></code> is conversion rules friendly=
(not 100% sure though).</code></div></div></blockquote></div></div><div di=
r=3D"auto"><br></div><div dir=3D"auto">The current rules permit a function =
to call itself recursively after its first return statement. How would you =
handle that?</div><div dir=3D"auto"><br></div><div dir=3D"auto">common_type=
decays its arguments. How would you handle a return type of auto& or d=
ecltype(auto)?</div><div dir=3D"auto"><br></div><div dir=3D"auto">This adds=
coupling between the language and library. What should happen if a declara=
tion of common_type has not been included prior to the definition of a func=
tion with deduced return type?</div><div dir=3D"auto"><div class=3D"gmail_q=
uote"><blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-l=
eft:1px #ccc solid;padding-left:1ex">
<p></p>
-- <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" rel=3D"nore=
ferrer" target=3D"_blank">std-proposals+unsubscribe@<wbr>isocpp.org</a>.<br=
>
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org" rel=3D"noreferrer" target=3D"_blank">std-proposals@isocpp.org</a>.<br=
>
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/7772686a-7e80-4c28-a87b-c5dc11450cc6%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter" rel=3D"noreferrer"=
target=3D"_blank">https://groups.google.com/a/<wbr>isocpp.org/d/msgid/std-=
<wbr>proposals/7772686a-7e80-4c28-<wbr>a87b-c5dc11450cc6%40isocpp.org</a><w=
br>.<br>
</blockquote></div></div></div>
<p></p>
-- <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" target=3D"_=
blank">std-proposals+unsubscribe@<wbr>isocpp.org</a>.<br>
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org" target=3D"_blank">std-proposals@isocpp.org</a>.<br></div></div>
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/CAOfiQqkzrG-PaTDHdq8Yk8m212%2Birb4hfF=
OefDmdUjH6vNON4A%40mail.gmail.com?utm_medium=3Demail&utm_source=3Dfoote=
r" target=3D"_blank">https://groups.google.com/a/<wbr>isocpp.org/d/msgid/st=
d-<wbr>proposals/CAOfiQqkzrG-<wbr>PaTDHdq8Yk8m212%<wbr>2Birb4hfFOefDmdUjH6v=
NON4A%<wbr>40mail.gmail.com</a>.<br>
<br></div></div><span class=3D"">
<p></p>
-- <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" target=3D"_=
blank">std-proposals+unsubscribe@<wbr>isocpp.org</a>.<br>
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org" target=3D"_blank">std-proposals@isocpp.org</a>.<br></span>
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/20180625183948.5193804.45505.56022%40=
gmail.com?utm_medium=3Demail&utm_source=3Dfooter" target=3D"_blank">htt=
ps://groups.google.com/a/<wbr>isocpp.org/d/msgid/std-<wbr>proposals/2018062=
5183948.<wbr>5193804.45505.56022%40gmail.<wbr>com</a>.<br>
</blockquote></div><br></div></div>
<p></p>
-- <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 />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/CAOfiQqnZxpq2v8xHx_%3DscJOMGXydDzr9RR=
eV81vyn276O%3DM%3DoA%40mail.gmail.com?utm_medium=3Demail&utm_source=3Dfoote=
r">https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CAOfiQqnZxp=
q2v8xHx_%3DscJOMGXydDzr9RReV81vyn276O%3DM%3DoA%40mail.gmail.com</a>.<br />
--0000000000000143be056f7c65fe--
.
Author: Nicol Bolas <jmckesson@gmail.com>
Date: Mon, 25 Jun 2018 13:26:55 -0700 (PDT)
Raw View
------=_Part_37506_1193642979.1529958415858
Content-Type: multipart/alternative;
boundary="----=_Part_37507_1070270909.1529958415858"
------=_Part_37507_1070270909.1529958415858
Content-Type: text/plain; charset="UTF-8"
On Monday, June 25, 2018 at 3:29:11 PM UTC-4, Richard Smith wrote:
>
> On 25 June 2018 at 11:39, Tony V E <tvan...@gmail.com <javascript:>>
> wrote:
>
>> We could at least avoid common_type by instead talking about as if by ?:
>>
>
> Yes; I wish the language rule had originally been defined that way.
>
.... it *is* defined that way. `std::common_type` is defined in terms of the
rules for `?:`, not the other way around.
The self-recursive function case doesn't seem sufficiently compelling to me
> to take priority over supporting multiple returns with different types.
>
But do we really want to support that? Or more to the point, do we really
need to avoid writing a type name this badly?
Return type deduction is not free. You're taking an important piece of
information which is well-specified in a specific location and obscuring
it. Being able to inspect what a function does quickly is a good thing, and
having to peer through its code to figure out what's going on is a bad
thing.
So for me, in order for the gains of return type deduction to outweigh the
drawbacks, one of the following must be true:
1. The return type is obvious based on the function's name and its
parameters. A function named `add` that takes two parameters naturally
returns whatever type is the sum of those parameters. So telling us what we
can work out for ourselves is pointless redundancy.
2. The function is very short, 5 statements or less. Telling us what we can
see from within the function quite easily is pointless redundancy.
3. The return type is difficult to type (large metaprogramming thing based
on the types of parameters) or impossible to type (lambdas). Writing a big,
long thing at the beginning (or end) of our function makes it difficult to
read or understand.
If none of these are true, I would say that return type deduction makes
code harder to deal with rather than easier. A function with multiple
return statements almost certainly fails #2. #3 can still happen, but not
in the case the OP outlined when dealing with a clear case of
`optional<int>`.
So what we're left with is something that only rarely makes code easier to
read. While simultaneously not catching mistakes where you happen to
accidentally change the function's return type.
Overall, I just think that this is way too much of a corner case to put it
into the standard. I hate to use principles as bludgeons for features I
don't like, but Bjarne's "Remember the Vasa" post <http://wg21.link/P0977>
would seem to speak to this. It's not making the language easier to use;
it's making the language more expert-friendly, at the detriment to ease of
use.
To know what the return value of a function is, you have to look up the
rules of ?:'s common typing. Is that something we need to do? Or rather, is
the gain from this really worth the cost?
--
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.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/9cc60e12-5874-4e6e-a14f-2cfe5463755c%40isocpp.org.
------=_Part_37507_1070270909.1529958415858
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">On Monday, June 25, 2018 at 3:29:11 PM UTC-4, Richard Smit=
h 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"><div>=
<div class=3D"gmail_quote">On 25 June 2018 at 11:39, Tony V E <span dir=3D"=
ltr"><<a href=3D"javascript:" target=3D"_blank" gdf-obfuscated-mailto=3D=
"SM69lkzfAwAJ" rel=3D"nofollow" onmousedown=3D"this.href=3D'javascript:=
';return true;" onclick=3D"this.href=3D'javascript:';return tru=
e;">tvan...@gmail.com</a>></span> wrote:<br><blockquote class=3D"gmail_q=
uote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1e=
x"><div style=3D"background-color:rgb(255,255,255);line-height:initial" lan=
g=3D"en-US"> =
<div style=3D"width:100%;font-size:initial;font-fami=
ly:Calibri,'Slate Pro',sans-serif,sans-serif;color:rgb(31,73,125);t=
ext-align:initial;background-color:rgb(255,255,255)">We could at least avoi=
d common_type by instead talking about as if by ?:</div></div></blockquote>=
<div><br></div><div>Yes; I wish the language rule had originally been defin=
ed that way.</div></div></div></div></blockquote><div><br></div><div>... it=
<i>is</i> defined that way. `std::common_type` is defined in terms of the =
rules for `?:`, not the other way around.</div><div><br></div><blockquote c=
lass=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 class=3D"gmail_q=
uote"><div>The self-recursive function case doesn't seem sufficiently c=
ompelling to me to take priority over supporting multiple returns with diff=
erent types.</div></div></div></div></blockquote><div><br></div><div>But do=
we really want to support that? Or more to the point, do we really need to=
avoid writing a type name this badly?</div><div><br></div><div>Return type=
deduction is not free. You're taking an important piece of information=
which is well-specified in a specific location and obscuring it. Being abl=
e to inspect what a function does quickly is a good thing, and having to pe=
er through its code to figure out what's going on is a bad thing.<br></=
div><div><br></div><div>So for me, in order for the gains of return type de=
duction to outweigh the drawbacks, one of the following must be true:</div>=
<div><br></div><div>1. The return type is obvious based on the function'=
;s name and its parameters. A function named `add` that takes two parameter=
s naturally returns whatever type is the sum of those parameters. So tellin=
g us what we can work out for ourselves is pointless redundancy.<br></div><=
div><br></div><div>2. The function is very short, 5 statements or less. Tel=
ling us what we can see from within the function quite easily is pointless =
redundancy.<br></div><div><br></div><div>3. The return type is difficult to=
type (large metaprogramming thing based on the types of parameters) or imp=
ossible to type (lambdas). Writing a big, long thing at the beginning (or e=
nd) of our function makes it difficult to read or understand.<br></div><div=
><br></div><div>If none of these are true, I would say that return type ded=
uction makes code harder to deal with rather than easier. A function with m=
ultiple return statements almost certainly fails #2. #3 can still happen, b=
ut not in the case the OP outlined when dealing with a clear case of `optio=
nal<int>`.</div><div><br></div><div>So what we're left with is so=
mething that only rarely makes code easier to read. While simultaneously no=
t catching mistakes where you happen to accidentally change the function=
9;s return type.</div><div><br></div><div>Overall, I just think that this i=
s way too much of a corner case to put it into the standard. I hate to use =
principles as bludgeons for features I don't like, but <a href=3D"http:=
//wg21.link/P0977">Bjarne's "Remember the Vasa" post</a> woul=
d seem to speak to this. It's not making the language easier to use; it=
's making the language more expert-friendly, at the detriment to ease o=
f use.</div><div><br></div><div>To know what the return value of a function=
is, you have to look up the rules of ?:'s common typing. Is that somet=
hing we need to do? Or rather, is the gain from this really worth the cost?=
<br></div></div>
<p></p>
-- <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 />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/9cc60e12-5874-4e6e-a14f-2cfe5463755c%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/9cc60e12-5874-4e6e-a14f-2cfe5463755c=
%40isocpp.org</a>.<br />
------=_Part_37507_1070270909.1529958415858--
------=_Part_37506_1193642979.1529958415858--
.
Author: anonymous.from.applecity@gmail.com
Date: Mon, 25 Jun 2018 14:39:27 -0700 (PDT)
Raw View
------=_Part_37620_1778524570.1529962767132
Content-Type: multipart/alternative;
boundary="----=_Part_37621_78305733.1529962767133"
------=_Part_37621_78305733.1529962767133
Content-Type: text/plain; charset="UTF-8"
On Tuesday, June 26, 2018 at 2:26:56 AM UTC+6, Nicol Bolas wrote:
> To know what the return value of a function is, you have to look up the
> rules of ?:'s common typing. Is that something we need to do? Or rather, is
> the gain from this really worth the cost?
I just thought that it would be easier than introducing some other
construct. What I'd like is basically an equivalent to the matcher macro
below:
#include <optional>
#define matcher [&]()->std::optional
#include <iostream>
template <typename T>
std::ostream& operator<<(std::ostream& os, const std::optional<T>& val)
{
if (val.has_value())
os << *val;
else
os << "*null*";
return os;
}
int main() {
int target = 0;
auto zero_matcher = matcher<int>{
if (target == 0)
return target;
else
return std::nullopt;
};
std::cout << zero_matcher() << '\n';
target = 3;
std::cout << zero_matcher() << '\n';
}
The problem I have with the solution is of course it being a macro. I
thought if metaclasses can solve the problem, but after reading it through
I couldn't confidently say yes or no. I believe the solution above, if had
language support, would satisfy most of your points about clarify of code
and not removing any existing bug-catcher functionality. I've never written
ISO proposal in my life, so writing something completely new would be
pretty hard for me.
--
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.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/88bcc681-812b-4472-853e-2f917a16e9a2%40isocpp.org.
------=_Part_37621_78305733.1529962767133
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><div>On Tuesday, June 26, 2018 at 2:26:56 AM UTC+6, Nicol =
Bolas wrote:<br><blockquote class=3D"gmail_quote" style=3D"margin: 0px 0px =
0px 0.8ex; border-left: 1px solid rgb(204, 204, 204); padding-left: 1ex;">T=
o
know what the return value of a function is, you have to look up the=20
rules of ?:'s common typing. Is that something we need to do? Or rather=
,
is the gain from this really worth the cost?</blockquote></div><div><br></=
div><div>I just thought that it would be easier than introducing some other=
construct. What I'd like is basically an equivalent to the matcher mac=
ro below:</div><div><br></div><div><div style=3D"background-color: rgb(250,=
250, 250); border-color: rgb(187, 187, 187); border-style: solid; border-w=
idth: 1px; overflow-wrap: break-word;" class=3D"prettyprint"><code class=3D=
"prettyprint"><div class=3D"subprettyprint"><div style=3D"color: #000000;ba=
ckground-color: #fffffe;font-family: Consolas, "><div><span style=3D"color:=
#0000ff;"><span style=3D"color: #800;" class=3D"styled-by-prettify">#inclu=
de</span></span><span style=3D"color: #000000;"><span style=3D"color: #000;=
" class=3D"styled-by-prettify"> </span><span style=3D"color: #080;" class=
=3D"styled-by-prettify"><optional></span></span></div><div><span styl=
e=3D"color: #0000ff;"><span style=3D"color: #800;" class=3D"styled-by-prett=
ify">#define</span></span><span style=3D"color: #000000;"><span style=3D"co=
lor: #000;" class=3D"styled-by-prettify"> matcher </span><span style=3D"col=
or: #660;" class=3D"styled-by-prettify">[&]()-></span><span style=3D=
"color: #000;" class=3D"styled-by-prettify">std</span><span style=3D"color:=
#660;" class=3D"styled-by-prettify">::</span><span style=3D"color: #000;" =
class=3D"styled-by-prettify">optional</span></span></div><span style=3D"col=
or: #000;" class=3D"styled-by-prettify"><br></span><div><span style=3D"colo=
r: #0000ff;"><span style=3D"color: #800;" class=3D"styled-by-prettify">#inc=
lude</span></span><span style=3D"color: #000000;"><span style=3D"color: #00=
0;" class=3D"styled-by-prettify"> </span><span style=3D"color: #080;" class=
=3D"styled-by-prettify"><iostream></span></span></div><div><span styl=
e=3D"color: #0000ff;"><span style=3D"color: #008;" class=3D"styled-by-prett=
ify">template</span></span><span style=3D"color: #000000;"><span style=3D"c=
olor: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #66=
0;" class=3D"styled-by-prettify"><</span></span><span style=3D"color: #0=
000ff;"><span style=3D"color: #008;" class=3D"styled-by-prettify">typename<=
/span></span><span style=3D"color: #000000;"><span style=3D"color: #000;" c=
lass=3D"styled-by-prettify"> T</span><span style=3D"color: #660;" class=3D"=
styled-by-prettify">></span></span></div><div><span style=3D"color: #000=
000;"><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">ostream</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><span style=3D"col=
or: #0000ff;"><span style=3D"color: #008;" class=3D"styled-by-prettify">ope=
rator</span></span><span style=3D"color: #000000;"><span style=3D"color: #6=
60;" class=3D"styled-by-prettify"><<(</span><span style=3D"color: #00=
0;" class=3D"styled-by-prettify">std</span><span style=3D"color: #660;" cla=
ss=3D"styled-by-prettify">::</span><span style=3D"color: #000;" class=3D"st=
yled-by-prettify">ostream</span><span style=3D"color: #660;" class=3D"style=
d-by-prettify">&</span><span style=3D"color: #000;" class=3D"styled-by-=
prettify"> os</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><span style=3D"color: #0000ff;"><span style=3D"color: #008;" class=
=3D"styled-by-prettify">const</span></span><span style=3D"color: #000000;">=
<span style=3D"color: #000;" class=3D"styled-by-prettify"> std</span><span =
style=3D"color: #660;" class=3D"styled-by-prettify">::</span><span style=3D=
"color: #000;" class=3D"styled-by-prettify">optional</span><span style=3D"c=
olor: #660;" class=3D"styled-by-prettify"><</span><span style=3D"color: =
#000;" class=3D"styled-by-prettify">T</span><span style=3D"color: #660;" cl=
ass=3D"styled-by-prettify">>&</span><span style=3D"color: #000;" cla=
ss=3D"styled-by-prettify"> val</span><span style=3D"color: #660;" class=3D"=
styled-by-prettify">)</span></span></div><div><span style=3D"color: #000000=
;"><span style=3D"color: #660;" class=3D"styled-by-prettify">{</span></span=
></div><div><span style=3D"color: #000000;"><span style=3D"color: #000;" cl=
ass=3D"styled-by-prettify"> =C2=A0 =C2=A0</span></span><span style=3D"color=
: #0000ff;"><span style=3D"color: #008;" class=3D"styled-by-prettify">if</s=
pan></span><span style=3D"color: #000000;"><span style=3D"color: #000;" cla=
ss=3D"styled-by-prettify"> </span><span style=3D"color: #660;" class=3D"sty=
led-by-prettify">(</span><span style=3D"color: #000;" class=3D"styled-by-pr=
ettify">val</span><span style=3D"color: #660;" class=3D"styled-by-prettify"=
>.</span><span style=3D"color: #000;" class=3D"styled-by-prettify">has_valu=
e</span><span style=3D"color: #660;" class=3D"styled-by-prettify">())</span=
></span></div><div><span style=3D"color: #000000;"><span style=3D"color: #0=
00;" class=3D"styled-by-prettify"> =C2=A0 =C2=A0 =C2=A0 =C2=A0os </span><sp=
an style=3D"color: #660;" class=3D"styled-by-prettify"><<</span><span=
style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D=
"color: #660;" class=3D"styled-by-prettify">*</span><span style=3D"color: #=
000;" class=3D"styled-by-prettify">val</span><span style=3D"color: #660;" c=
lass=3D"styled-by-prettify">;</span></span></div><div><span style=3D"color:=
#000000;"><span style=3D"color: #000;" class=3D"styled-by-prettify"> =C2=
=A0 =C2=A0</span></span><span style=3D"color: #0000ff;"><span style=3D"colo=
r: #008;" class=3D"styled-by-prettify">else</span></span></div><div><span s=
tyle=3D"color: #000000;"><span style=3D"color: #000;" class=3D"styled-by-pr=
ettify"> =C2=A0 =C2=A0 =C2=A0 =C2=A0os </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><span style=3D"color: #a31515;"><=
span style=3D"color: #080;" class=3D"styled-by-prettify">"*null*"=
</span></span><span style=3D"color: #000000;"><span style=3D"color: #660;" =
class=3D"styled-by-prettify">;</span></span></div><div><span style=3D"color=
: #000000;"><span style=3D"color: #000;" class=3D"styled-by-prettify"> =C2=
=A0 =C2=A0</span></span><span style=3D"color: #0000ff;"><span style=3D"colo=
r: #008;" class=3D"styled-by-prettify">return</span></span><span style=3D"c=
olor: #000000;"><span style=3D"color: #000;" class=3D"styled-by-prettify"> =
os</span><span style=3D"color: #660;" class=3D"styled-by-prettify">;</span>=
</span></div><div><span style=3D"color: #000000;"><span style=3D"color: #66=
0;" class=3D"styled-by-prettify">}</span></span></div><span style=3D"color:=
#000;" class=3D"styled-by-prettify"><br></span><div><span style=3D"color: =
#0000ff;"><span style=3D"color: #008;" class=3D"styled-by-prettify">int</sp=
an></span><span style=3D"color: #000000;"><span style=3D"color: #000;" clas=
s=3D"styled-by-prettify"> main</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></span></div><div><span style=3D"color: #000000;"><span style=3D=
"color: #000;" class=3D"styled-by-prettify"> =C2=A0 =C2=A0</span></span><sp=
an style=3D"color: #0000ff;"><span style=3D"color: #008;" class=3D"styled-b=
y-prettify">int</span></span><span style=3D"color: #000000;"><span style=3D=
"color: #000;" class=3D"styled-by-prettify"> target </span><span style=3D"c=
olor: #660;" class=3D"styled-by-prettify">=3D</span><span style=3D"color: #=
000;" class=3D"styled-by-prettify"> </span></span><span style=3D"color: #09=
885a;"><span style=3D"color: #066;" class=3D"styled-by-prettify">0</span></=
span><span style=3D"color: #000000;"><span style=3D"color: #660;" class=3D"=
styled-by-prettify">;</span></span></div><div><span style=3D"color: #000000=
;"><span style=3D"color: #000;" class=3D"styled-by-prettify"> =C2=A0 =C2=A0=
</span></span><span style=3D"color: #0000ff;"><span style=3D"color: #008;" =
class=3D"styled-by-prettify">auto</span></span><span style=3D"color: #00000=
0;"><span style=3D"color: #000;" class=3D"styled-by-prettify"> zero_matcher=
</span><span style=3D"color: #660;" class=3D"styled-by-prettify">=3D</span=
><span style=3D"color: #000;" class=3D"styled-by-prettify"> matcher</span><=
span style=3D"color: #080;" class=3D"styled-by-prettify"><</span></span>=
<span style=3D"color: #0000ff;"><span style=3D"color: #080;" class=3D"style=
d-by-prettify">int</span></span><span style=3D"color: #000000;"><span style=
=3D"color: #080;" class=3D"styled-by-prettify">></span><span style=3D"co=
lor: #660;" class=3D"styled-by-prettify">{</span></span></div><div><span st=
yle=3D"color: #000000;"><span style=3D"color: #000;" class=3D"styled-by-pre=
ttify"> =C2=A0 =C2=A0 =C2=A0 =C2=A0</span></span><span style=3D"color: #000=
0ff;"><span style=3D"color: #008;" class=3D"styled-by-prettify">if</span></=
span><span style=3D"color: #000000;"><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=
">target </span><span style=3D"color: #660;" class=3D"styled-by-prettify">=
=3D=3D</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </s=
pan></span><span style=3D"color: #09885a;"><span style=3D"color: #066;" cla=
ss=3D"styled-by-prettify">0</span></span><span style=3D"color: #000000;"><s=
pan style=3D"color: #660;" class=3D"styled-by-prettify">)</span></span></di=
v><div><span style=3D"color: #000000;"><span style=3D"color: #000;" class=
=3D"styled-by-prettify"> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0</span></=
span><span style=3D"color: #0000ff;"><span style=3D"color: #008;" class=3D"=
styled-by-prettify">return</span></span><span style=3D"color: #000000;"><sp=
an style=3D"color: #000;" class=3D"styled-by-prettify"> target</span><span =
style=3D"color: #660;" class=3D"styled-by-prettify">;</span></span></div><d=
iv><span style=3D"color: #000000;"><span style=3D"color: #000;" class=3D"st=
yled-by-prettify"> =C2=A0 =C2=A0 =C2=A0 =C2=A0</span></span><span style=3D"=
color: #0000ff;"><span style=3D"color: #008;" class=3D"styled-by-prettify">=
else</span></span></div><div><span style=3D"color: #000000;"><span style=3D=
"color: #000;" class=3D"styled-by-prettify"> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =
=C2=A0 =C2=A0</span></span><span style=3D"color: #0000ff;"><span style=3D"c=
olor: #008;" class=3D"styled-by-prettify">return</span></span><span style=
=3D"color: #000000;"><span style=3D"color: #000;" class=3D"styled-by-pretti=
fy"> std</span><span style=3D"color: #660;" class=3D"styled-by-prettify">::=
</span><span style=3D"color: #000;" class=3D"styled-by-prettify">nullopt</s=
pan><span style=3D"color: #660;" class=3D"styled-by-prettify">;</span></spa=
n></div><div><span style=3D"color: #000000;"><span style=3D"color: #000;" c=
lass=3D"styled-by-prettify"> =C2=A0 =C2=A0</span><span style=3D"color: #660=
;" class=3D"styled-by-prettify">};</span></span></div><div><span style=3D"c=
olor: #000000;"><span style=3D"color: #000;" class=3D"styled-by-prettify"> =
=C2=A0 =C2=A0</span></span></div><div><span style=3D"color: #000000;"><span=
style=3D"color: #000;" class=3D"styled-by-prettify"> =C2=A0 =C2=A0std</spa=
n><span style=3D"color: #660;" class=3D"styled-by-prettify">::</span><span =
style=3D"color: #000;" class=3D"styled-by-prettify">cout </span><span style=
=3D"color: #660;" class=3D"styled-by-prettify"><<</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"> zero_matcher</span><span st=
yle=3D"color: #660;" class=3D"styled-by-prettify">()</span><span style=3D"c=
olor: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #66=
0;" class=3D"styled-by-prettify"><<</span><span style=3D"color: #000;=
" class=3D"styled-by-prettify"> </span></span><span style=3D"color: #a31515=
;"><span style=3D"color: #080;" class=3D"styled-by-prettify">'\n'</=
span></span><span style=3D"color: #000000;"><span style=3D"color: #660;" cl=
ass=3D"styled-by-prettify">;</span></span></div><div><span style=3D"color: =
#000000;"><span style=3D"color: #000;" class=3D"styled-by-prettify"> =C2=A0=
=C2=A0target </span><span style=3D"color: #660;" class=3D"styled-by-pretti=
fy">=3D</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </=
span></span><span style=3D"color: #09885a;"><span style=3D"color: #066;" cl=
ass=3D"styled-by-prettify">3</span></span><span style=3D"color: #000000;"><=
span style=3D"color: #660;" class=3D"styled-by-prettify">;</span></span></d=
iv><div><span style=3D"color: #000000;"><span style=3D"color: #000;" class=
=3D"styled-by-prettify"> =C2=A0 =C2=A0std</span><span style=3D"color: #660;=
" class=3D"styled-by-prettify">::</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify">cout </span><span style=3D"color: #660;" class=3D"s=
tyled-by-prettify"><<</span><span style=3D"color: #000;" class=3D"sty=
led-by-prettify"> zero_matcher</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><span style=3D"color: #000;" class=3D"styled-by-prettify"=
> </span></span><span style=3D"color: #a31515;"><span style=3D"color: #080;=
" class=3D"styled-by-prettify">'\n'</span></span><span style=3D"col=
or: #000000;"><span style=3D"color: #660;" class=3D"styled-by-prettify">;</=
span></span></div><div><span style=3D"color: #000000;"><span style=3D"color=
: #660;" class=3D"styled-by-prettify">}</span></span></div></div></div></co=
de></div></div><div><br></div><div>The problem I have with the solution is =
of course it being a macro. I thought if metaclasses can solve the problem,=
but after reading it through I couldn't confidently say yes or no. I b=
elieve the solution above, if had language support, would satisfy most of y=
our points about clarify of code and not removing any existing bug-catcher =
functionality. I've never written ISO proposal in my life, so writing s=
omething completely new would be pretty hard for me.<br></div></div>
<p></p>
-- <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 />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/88bcc681-812b-4472-853e-2f917a16e9a2%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/88bcc681-812b-4472-853e-2f917a16e9a2=
%40isocpp.org</a>.<br />
------=_Part_37621_78305733.1529962767133--
------=_Part_37620_1778524570.1529962767132--
.
Author: anonymous.from.applecity@gmail.com
Date: Mon, 25 Jun 2018 15:04:06 -0700 (PDT)
Raw View
------=_Part_37764_1292908921.1529964246519
Content-Type: multipart/alternative;
boundary="----=_Part_37765_1444832780.1529964246520"
------=_Part_37765_1444832780.1529964246520
Content-Type: text/plain; charset="UTF-8"
When I think of it now, it seems like some clojure-esque solution would be
easier to introduce. The language supported alternative to matcher perhaps
would be a better idea:
#include <optional>
#define matcher [&]()->std::optional
#include <iostream>
template <typename T>
std::ostream& operator<<(std::ostream& os, const std::optional<T>& val)
{
if (val.has_value())
os << *val;
else
os << "*null*";
return os;
}
int main() {
int target = 0;
auto zero_matcher = matcher<int>{
if (target == 0)
return target;
else
return std::nullopt;
};
std::cout << zero_matcher() << '\n';
target = 3;
std::cout << zero_matcher() << '\n';
}
Now, the declaration probably should be like a template declaration,
otherwise the only implementation would be virtual call style. Also, if it
indeed looks like a template, it could integrate well with concepts and
have already existing functionality to apply type erasure on them, like
std::function and clojure shown <https://youtu.be/JRkoWiDA3KA> on
MeetingC++.
--
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.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/bb1d402c-7647-4d29-97b7-0832d9375f18%40isocpp.org.
------=_Part_37765_1444832780.1529964246520
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><div><code>When I think of it now, it seems like some cloj=
ure-esque solution would be easier to introduce. The language supported alt=
ernative to matcher perhaps would be a better idea:<br></code></div><div><c=
ode><div style=3D"background-color: rgb(250, 250, 250); border-color: rgb(1=
87, 187, 187); border-style: solid; border-width: 1px; overflow-wrap: break=
-word;" class=3D"prettyprint"><code class=3D"prettyprint"><div class=3D"sub=
prettyprint"><span style=3D"color: #800;" class=3D"styled-by-prettify">#inc=
lude</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </spa=
n><span style=3D"color: #080;" class=3D"styled-by-prettify"><optional>=
;</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br></spa=
n><span style=3D"color: #800;" class=3D"styled-by-prettify">#define</span><=
span style=3D"color: #000;" class=3D"styled-by-prettify"> matcher </span><s=
pan style=3D"color: #660;" class=3D"styled-by-prettify">[&]()-></spa=
n><span style=3D"color: #000;" class=3D"styled-by-prettify">std</span><span=
style=3D"color: #660;" class=3D"styled-by-prettify">::</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify">optional<br><br></span><span=
style=3D"color: #800;" class=3D"styled-by-prettify">#include</span><span s=
tyle=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"c=
olor: #080;" class=3D"styled-by-prettify"><iostream></span><span styl=
e=3D"color: #000;" class=3D"styled-by-prettify"><br></span><span style=3D"c=
olor: #008;" class=3D"styled-by-prettify">template</span><span style=3D"col=
or: #000;" class=3D"styled-by-prettify"> </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"> T</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-pre=
ttify">::</span><span style=3D"color: #000;" class=3D"styled-by-prettify">o=
stream</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">operator</span><sp=
an style=3D"color: #660;" class=3D"styled-by-prettify"><<(</span><spa=
n 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"colo=
r: #000;" class=3D"styled-by-prettify">ostream</span><span style=3D"color: =
#660;" class=3D"styled-by-prettify">&</span><span style=3D"color: #000;=
" class=3D"styled-by-prettify"> os</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">const</span><span style=3D"color: #000;" class=3D"styled-by-prettify"=
> std</span><span style=3D"color: #660;" class=3D"styled-by-prettify">::</s=
pan><span style=3D"color: #000;" class=3D"styled-by-prettify">optional</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">>&</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"> val</span><span style=3D"co=
lor: #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>=C2=A0 =C2=A0 </span><span style=3D"color: #008;" clas=
s=3D"styled-by-prettify">if</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">v=
al</span><span style=3D"color: #660;" class=3D"styled-by-prettify">.</span>=
<span style=3D"color: #000;" class=3D"styled-by-prettify">has_value</span><=
span style=3D"color: #660;" class=3D"styled-by-prettify">())</span><span st=
yle=3D"color: #000;" class=3D"styled-by-prettify"><br>=C2=A0 =C2=A0 =C2=A0 =
=C2=A0 os </span><span style=3D"color: #660;" class=3D"styled-by-prettify">=
<<</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> <=
/span><span style=3D"color: #660;" class=3D"styled-by-prettify">*</span><sp=
an style=3D"color: #000;" class=3D"styled-by-prettify">val</span><span styl=
e=3D"color: #660;" class=3D"styled-by-prettify">;</span><span style=3D"colo=
r: #000;" class=3D"styled-by-prettify"><br>=C2=A0 =C2=A0 </span><span style=
=3D"color: #008;" class=3D"styled-by-prettify">else</span><span style=3D"co=
lor: #000;" class=3D"styled-by-prettify"><br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 os=
</span><span style=3D"color: #660;" class=3D"styled-by-prettify"><<<=
/span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><sp=
an style=3D"color: #080;" class=3D"styled-by-prettify">"*null*"</=
span><span style=3D"color: #660;" class=3D"styled-by-prettify">;</span><spa=
n style=3D"color: #000;" class=3D"styled-by-prettify"><br>=C2=A0 =C2=A0 </s=
pan><span style=3D"color: #008;" class=3D"styled-by-prettify">return</span>=
<span style=3D"color: #000;" class=3D"styled-by-prettify"> os</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></span><span style=3D"color: =
#660;" class=3D"styled-by-prettify">}</span><span style=3D"color: #000;" cl=
ass=3D"styled-by-prettify"><br><br></span><span style=3D"color: #008;" clas=
s=3D"styled-by-prettify">int</span><span style=3D"color: #000;" class=3D"st=
yled-by-prettify"> main</span><span style=3D"color: #660;" class=3D"styled-=
by-prettify">()</span><span style=3D"color: #000;" class=3D"styled-by-prett=
ify"> </span><span style=3D"color: #660;" class=3D"styled-by-prettify">{</s=
pan><span style=3D"color: #000;" class=3D"styled-by-prettify"><br>=C2=A0 =
=C2=A0 </span><span style=3D"color: #008;" class=3D"styled-by-prettify">int=
</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> target </=
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: #066;" class=3D"styled-by-prettify">0</span><span style=3D"color=
: #660;" class=3D"styled-by-prettify">;</span><span style=3D"color: #000;" =
class=3D"styled-by-prettify"><br>=C2=A0 =C2=A0 </span><span style=3D"color:=
#008;" class=3D"styled-by-prettify">auto</span><span style=3D"color: #000;=
" class=3D"styled-by-prettify"> zero_matcher </span><span style=3D"color: #=
660;" class=3D"styled-by-prettify">=3D</span><span style=3D"color: #000;" c=
lass=3D"styled-by-prettify"> matcher</span><span style=3D"color: #080;" cla=
ss=3D"styled-by-prettify"><int></span><span style=3D"color: #660;" cl=
ass=3D"styled-by-prettify">{</span><span style=3D"color: #000;" class=3D"st=
yled-by-prettify"><br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 </span><span style=3D"col=
or: #008;" class=3D"styled-by-prettify">if</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">target </span><span style=3D"color: #660;" class=3D"styled-b=
y-prettify">=3D=3D</span><span style=3D"color: #000;" class=3D"styled-by-pr=
ettify"> </span><span style=3D"color: #066;" class=3D"styled-by-prettify">0=
</span><span style=3D"color: #660;" class=3D"styled-by-prettify">)</span><s=
pan style=3D"color: #000;" class=3D"styled-by-prettify"><br>=C2=A0 =C2=A0 =
=C2=A0 =C2=A0 =C2=A0 =C2=A0 </span><span style=3D"color: #008;" class=3D"st=
yled-by-prettify">return</span><span style=3D"color: #000;" class=3D"styled=
-by-prettify"> target</span><span style=3D"color: #660;" class=3D"styled-by=
-prettify">;</span><span style=3D"color: #000;" class=3D"styled-by-prettify=
"><br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 </span><span style=3D"color: #008;" class=
=3D"styled-by-prettify">else</span><span style=3D"color: #000;" class=3D"st=
yled-by-prettify"><br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 </span><spa=
n style=3D"color: #008;" class=3D"styled-by-prettify">return</span><span st=
yle=3D"color: #000;" class=3D"styled-by-prettify"> std</span><span style=3D=
"color: #660;" class=3D"styled-by-prettify">::</span><span style=3D"color: =
#000;" class=3D"styled-by-prettify">nullopt</span><span style=3D"color: #66=
0;" class=3D"styled-by-prettify">;</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"><br>=C2=A0 =C2=A0 </span><span style=3D"color: #660=
;" class=3D"styled-by-prettify">};</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"><br>=C2=A0 =C2=A0 <br>=C2=A0 =C2=A0 std</span><span=
style=3D"color: #660;" class=3D"styled-by-prettify">::</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify">cout </span><span style=3D"c=
olor: #660;" class=3D"styled-by-prettify"><<</span><span style=3D"col=
or: #000;" class=3D"styled-by-prettify"> zero_matcher</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"><<</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"> </span><span style=3D"color: #080;" class=3D"style=
d-by-prettify">'\n'</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>=C2=A0 =C2=A0 target </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: #066;" class=3D"styled-by-pr=
ettify">3</span><span style=3D"color: #660;" class=3D"styled-by-prettify">;=
</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br>=C2=A0=
=C2=A0 std</span><span style=3D"color: #660;" class=3D"styled-by-prettify"=
>::</span><span style=3D"color: #000;" class=3D"styled-by-prettify">cout </=
span><span style=3D"color: #660;" class=3D"styled-by-prettify"><<</sp=
an><span style=3D"color: #000;" class=3D"styled-by-prettify"> zero_matcher<=
/span><span style=3D"color: #660;" class=3D"styled-by-prettify">()</span><s=
pan style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=
=3D"color: #660;" class=3D"styled-by-prettify"><<</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color=
: #080;" class=3D"styled-by-prettify">'\n'</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;" clas=
s=3D"styled-by-prettify">}</span></div></code></div><br>Now, the declaratio=
n probably should be like a template declaration, otherwise the only implem=
entation would be virtual call style. Also, if it indeed looks like a templ=
ate, it could integrate well with concepts and have already existing functi=
onality to apply type erasure on them, like std::function and clojure <a hr=
ef=3D"https://youtu.be/JRkoWiDA3KA">shown</a> on MeetingC++.<br></code></di=
v></div>
<p></p>
-- <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 />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/bb1d402c-7647-4d29-97b7-0832d9375f18%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/bb1d402c-7647-4d29-97b7-0832d9375f18=
%40isocpp.org</a>.<br />
------=_Part_37765_1444832780.1529964246520--
------=_Part_37764_1292908921.1529964246519--
.
Author: Richard Smith <richard@metafoo.co.uk>
Date: Mon, 25 Jun 2018 15:12:30 -0700
Raw View
--000000000000b61ba3056f7eaed7
Content-Type: text/plain; charset="UTF-8"
On 25 June 2018 at 13:26, Nicol Bolas <jmckesson@gmail.com> wrote:
> On Monday, June 25, 2018 at 3:29:11 PM UTC-4, Richard Smith wrote:
>>
>> On 25 June 2018 at 11:39, Tony V E <tvan...@gmail.com> wrote:
>>
>>> We could at least avoid common_type by instead talking about as if by ?:
>>>
>>
>> Yes; I wish the language rule had originally been defined that way.
>>
>
> ... it *is* defined that way. `std::common_type` is defined in terms of
> the rules for `?:`, not the other way around.
>
Sorry, we have miscommunicated: "the language rule" I'm talking about is
return type deduction, and how it handles the case of multiple types (not
common_type). It (return type deduction) is not defined as using ?: to
compute a common type, as you are no doubt aware.
The self-recursive function case doesn't seem sufficiently compelling to me
>> to take priority over supporting multiple returns with different types.
>>
>
> But do we really want to support that? Or more to the point, do we really
> need to avoid writing a type name this badly?
>
> Return type deduction is not free. You're taking an important piece of
> information which is well-specified in a specific location and obscuring
> it. Being able to inspect what a function does quickly is a good thing, and
> having to peer through its code to figure out what's going on is a bad
> thing.
>
> So for me, in order for the gains of return type deduction to outweigh the
> drawbacks, one of the following must be true:
>
> 1. The return type is obvious based on the function's name and its
> parameters. A function named `add` that takes two parameters naturally
> returns whatever type is the sum of those parameters. So telling us what we
> can work out for ourselves is pointless redundancy.
>
> 2. The function is very short, 5 statements or less. Telling us what we
> can see from within the function quite easily is pointless redundancy.
>
> 3. The return type is difficult to type (large metaprogramming thing based
> on the types of parameters) or impossible to type (lambdas). Writing a big,
> long thing at the beginning (or end) of our function makes it difficult to
> read or understand.
>
> If none of these are true, I would say that return type deduction makes
> code harder to deal with rather than easier. A function with multiple
> return statements almost certainly fails #2. #3 can still happen, but not
> in the case the OP outlined when dealing with a clear case of
> `optional<int>`.
>
> So what we're left with is something that only rarely makes code easier to
> read. While simultaneously not catching mistakes where you happen to
> accidentally change the function's return type.
>
> Overall, I just think that this is way too much of a corner case to put it
> into the standard. I hate to use principles as bludgeons for features I
> don't like, but Bjarne's "Remember the Vasa" post <http://wg21.link/P0977>
> would seem to speak to this. It's not making the language easier to use;
> it's making the language more expert-friendly, at the detriment to ease of
> use.
>
> To know what the return value of a function is, you have to look up the
> rules of ?:'s common typing. Is that something we need to do? Or rather, is
> the gain from this really worth the cost?
>
I think there are examples when it is worth the cost (particularly, the
cases where the function has a primary return statement and some bailouts
that return nullptr or nullopt or similar). Conversely, I'm not convinced
that supporting return type deduction for (directly) recursive functions is
worth the cost -- that seems like the expert-only feature in this context.
Conversely, having a single general type unification algorithm that is used
in all contexts where it makes sense makes the language simpler and more
beginner-friendly (I seem to recall a good blog post on this subject --
perhaps from Eric Lippert -- a few years back, about how the C# language
was simplified by using the same rules for ?: type unification and for type
unification in return type deduction, but I can't find it right now...). A
beginner expects to be able to use nullptr where they would have used a
value of a pointer type, and saying you can't do that in a return statement
in a function with a deduced return type is an unnecessary complication.
("Why can't the compiler just work it out for itself? The intended return
type is obvious.")
--
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.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CAOfiQq%3D_ey_QRj3mYvqX5XVwz_MGANv3e7Ec9ioaCx%3DBuE8r6Q%40mail.gmail.com.
--000000000000b61ba3056f7eaed7
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><div class=3D"gmail_extra"><div class=3D"gmail_quote">On 2=
5 June 2018 at 13:26, Nicol Bolas <span dir=3D"ltr"><<a href=3D"mailto:j=
mckesson@gmail.com" target=3D"_blank">jmckesson@gmail.com</a>></span> wr=
ote:<br><blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border=
-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr">On Monday, June 25,=
2018 at 3:29:11 PM UTC-4, Richard Smith wrote:<span class=3D""><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 class=3D"gmail_quot=
e">On 25 June 2018 at 11:39, Tony V E <span dir=3D"ltr"><<a rel=3D"nofol=
low">tvan...@gmail.com</a>></span> wrote:<br><blockquote class=3D"gmail_=
quote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1=
ex"><div style=3D"background-color:rgb(255,255,255);line-height:initial" la=
ng=3D"en-US"> =
<div style=3D"width:100%;font-size:initial;font-fam=
ily:Calibri,'Slate Pro',sans-serif,sans-serif;color:rgb(31,73,125);=
text-align:initial;background-color:rgb(255,255,255)">We could at least avo=
id common_type by instead talking about as if by ?:</div></div></blockquote=
><div><br></div><div>Yes; I wish the language rule had originally been defi=
ned that way.</div></div></div></div></blockquote><div><br></div></span><di=
v>... it <i>is</i> defined that way. `std::common_type` is defined in terms=
of the rules for `?:`, not the other way around.</div></div></blockquote><=
div><br></div><div>Sorry, we have miscommunicated: "the language rule&=
quot; I'm talking about is return type deduction, and how it handles th=
e case of multiple types (not common_type). It (return type deduction) is n=
ot defined as using ?: to compute a common type, as you are no doubt aware.=
</div><div><br></div><blockquote class=3D"gmail_quote" style=3D"margin:0 0 =
0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><span =
class=3D""><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><d=
iv class=3D"gmail_quote"><div>The self-recursive function case doesn't =
seem sufficiently compelling to me to take priority over supporting multipl=
e returns with different types.</div></div></div></div></blockquote><div><b=
r></div></span><div>But do we really want to support that? Or more to the p=
oint, do we really need to avoid writing a type name this badly?</div><div>=
<br></div><div>Return type deduction is not free. You're taking an impo=
rtant piece of information which is well-specified in a specific location a=
nd obscuring it. Being able to inspect what a function does quickly is a go=
od thing, and having to peer through its code to figure out what's goin=
g on is a bad thing.<br></div><div><br></div><div>So for me, in order for t=
he gains of return type deduction to outweigh the drawbacks, one of the fol=
lowing must be true:</div><div><br></div><div>1. The return type is obvious=
based on the function's name and its parameters. A function named `add=
` that takes two parameters naturally returns whatever type is the sum of t=
hose parameters. So telling us what we can work out for ourselves is pointl=
ess redundancy.<br></div><div><br></div><div>2. The function is very short,=
5 statements or less. Telling us what we can see from within the function =
quite easily is pointless redundancy.<br></div><div><br></div><div>3. The r=
eturn type is difficult to type (large metaprogramming thing based on the t=
ypes of parameters) or impossible to type (lambdas). Writing a big, long th=
ing at the beginning (or end) of our function makes it difficult to read or=
understand.<br></div><div><br></div><div>If none of these are true, I woul=
d say that return type deduction makes code harder to deal with rather than=
easier. A function with multiple return statements almost certainly fails =
#2. #3 can still happen, but not in the case the OP outlined when dealing w=
ith a clear case of `optional<int>`.</div><div><br></div><div>So what=
we're left with is something that only rarely makes code easier to rea=
d. While simultaneously not catching mistakes where you happen to accidenta=
lly change the function's return type.</div><div><br></div><div>Overall=
, I just think that this is way too much of a corner case to put it into th=
e standard. I hate to use principles as bludgeons for features I don't =
like, but <a href=3D"http://wg21.link/P0977" target=3D"_blank">Bjarne's=
"Remember the Vasa" post</a> would seem to speak to this. It'=
;s not making the language easier to use; it's making the language more=
expert-friendly, at the detriment to ease of use.</div><div><br></div><div=
>To know what the return value of a function is, you have to look up the ru=
les of ?:'s common typing. Is that something we need to do? Or rather, =
is the gain from this really worth the cost?</div></div></blockquote><div><=
br></div><div>I think there are examples when it is worth the cost (particu=
larly, the cases where the function has a primary return statement and some=
bailouts that return nullptr or nullopt or similar). Conversely, I'm n=
ot convinced that supporting return type deduction for (directly) recursive=
functions is worth the cost -- that seems like the expert-only feature in =
this context. Conversely, having a single general type unification algorith=
m that is used in all contexts where it makes sense makes the language simp=
ler and more beginner-friendly (I seem to recall a good blog post on this s=
ubject -- perhaps from Eric Lippert -- a few years back, about how the C# l=
anguage was simplified by using the same rules for ?: type unification and =
for type unification in return type deduction, but I can't find it righ=
t now...). A beginner expects to be able to use nullptr where they would ha=
ve used a value of a pointer type, and saying you can't do that in a re=
turn statement in a function with a deduced return type is an unnecessary c=
omplication. ("Why can't the compiler just work it out for itself?=
The intended return type is obvious.")</div></div></div></div>
<p></p>
-- <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 />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/CAOfiQq%3D_ey_QRj3mYvqX5XVwz_MGANv3e7=
Ec9ioaCx%3DBuE8r6Q%40mail.gmail.com?utm_medium=3Demail&utm_source=3Dfooter"=
>https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CAOfiQq%3D_ey=
_QRj3mYvqX5XVwz_MGANv3e7Ec9ioaCx%3DBuE8r6Q%40mail.gmail.com</a>.<br />
--000000000000b61ba3056f7eaed7--
.
Author: Nevin Liber <nevin@eviloverlord.com>
Date: Mon, 25 Jun 2018 17:26:34 -0500
Raw View
--000000000000f1365f056f7ee154
Content-Type: text/plain; charset="UTF-8"
On Mon, Jun 25, 2018 at 5:12 PM Richard Smith <richard@metafoo.co.uk> wrote:
> I think there are examples when it is worth the cost (particularly, the
> cases where the function has a primary return statement and some bailouts
> that return nullptr or nullopt or similar).
>
The question shouldn't be "does it make a few specific situations better".
The question should be "does it make every situation the same or better,
and if not, is it worth the cost?"
The current rule is very beginner-friendly: if there are multiple returns,
the types either have to match exactly or the return type has to be
specified.
Having to understand [expr.cond] is not IMO beginner-friendly, even though
it may make a few specific cases better.
--
Nevin ":-)" Liber <mailto:nevin@eviloverlord.com> +1-847-691-1404
--
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.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CAGg_6%2BPDxpjm9Fa8Hvz0%3DBSEc3iMFRnxu0AUv93gTrMYsJuM0Q%40mail.gmail.com.
--000000000000f1365f056f7ee154
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">On Mon, Jun 25, 2018 at 5:12 PM Richard Smith <<a href=
=3D"mailto:richard@metafoo.co.uk" target=3D"_blank">richard@metafoo.co.uk</=
a>> wrote:<br><div class=3D"gmail_quote"><blockquote class=3D"gmail_quot=
e" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">=
<div dir=3D"ltr"><div class=3D"gmail_extra"><div class=3D"gmail_quote"><div=
>I think there are examples when it is worth the cost (particularly, the ca=
ses where the function has a primary return statement and some bailouts tha=
t return nullptr or nullopt or similar). </div></div></div></div></blockquo=
te><div><br></div><div>The question shouldn't be "does it make a f=
ew specific situations better".=C2=A0 The question should be "doe=
s it make every situation the same or better, and if not, is it worth the c=
ost?"</div><div><br></div><div>The current rule is very beginner-frien=
dly: =C2=A0if there are multiple returns, the types either have to match ex=
actly or the return type has to be specified.</div><div><br></div><div>Havi=
ng to understand [expr.cond] is not IMO beginner-friendly, even though it m=
ay make a few specific cases better.</div></div>-- <br><div dir=3D"ltr" cla=
ss=3D"m_7944883535266556359gmail_signature" data-smartmail=3D"gmail_signatu=
re"><div dir=3D"ltr"><div><div dir=3D"ltr"><div>=C2=A0Nevin ":-)"=
Liber=C2=A0 <mailto:<a href=3D"mailto:nevin@eviloverlord.com" target=3D=
"_blank">nevin@eviloverlord.com</a>> =C2=A0+1-847-691-1404</div></div></=
div></div></div></div>
<p></p>
-- <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 />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/CAGg_6%2BPDxpjm9Fa8Hvz0%3DBSEc3iMFRnx=
u0AUv93gTrMYsJuM0Q%40mail.gmail.com?utm_medium=3Demail&utm_source=3Dfooter"=
>https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CAGg_6%2BPDxp=
jm9Fa8Hvz0%3DBSEc3iMFRnxu0AUv93gTrMYsJuM0Q%40mail.gmail.com</a>.<br />
--000000000000f1365f056f7ee154--
.
Author: Nicol Bolas <jmckesson@gmail.com>
Date: Mon, 25 Jun 2018 18:35:45 -0700 (PDT)
Raw View
------=_Part_38701_596494694.1529976946017
Content-Type: multipart/alternative;
boundary="----=_Part_38702_1437085788.1529976946017"
------=_Part_38702_1437085788.1529976946017
Content-Type: text/plain; charset="UTF-8"
On Monday, June 25, 2018 at 5:39:27 PM UTC-4, anonymous.fr...@gmail.com
wrote:
>
> On Tuesday, June 26, 2018 at 2:26:56 AM UTC+6, Nicol Bolas wrote:
>
>> To know what the return value of a function is, you have to look up the
>> rules of ?:'s common typing. Is that something we need to do? Or rather, is
>> the gain from this really worth the cost?
>
>
> I just thought that it would be easier than introducing some other
> construct.
>
You misunderstand. My point was that ?: is not the most common expression
in the world, so not everyone is 100% aware of all of its idiosyncrasies.
Therefore, if they see a complex ?: expression where the two subexpressions
are distinct types, they'd have to look up how that all works out. Which is
fine; it's not a hugely common case, so having something to look up is fine.
By contrast, figuring out the return type of a function shouldn't be hard.
You need to be able to do this to know how to use the function. If you make
figuring out the return type as hard as ?: can sometimes be, then that's a
problem.
What I'd like is basically an equivalent to the matcher macro below:
>
> #include <optional>
> #define matcher [&]()->std::optional
>
> #include <iostream>
> template <typename T>
> std::ostream& operator<<(std::ostream& os, const std::optional<T>& val)
> {
> if (val.has_value())
> os << *val;
> else
> os << "*null*";
> return os;
> }
>
> int main() {
> int target = 0;
> auto zero_matcher = matcher<int>{
> if (target == 0)
> return target;
> else
> return std::nullopt;
> };
>
> std::cout << zero_matcher() << '\n';
> target = 3;
> std::cout << zero_matcher() << '\n';
> }
>
>
What you're asking for wouldn't help. Why? Because you still have to say
`std::optional<int>` *somewhere* in that function. Observe:
[&]()
{
if(target)
return target;
return nullopt;
}
Under your requested rules, that is just as much a compile error as the
expression `target ? target : nullopt`. There is no common type between
`int` and `nullopt`, so there's no way for this to work. What you want
would only work if you do this:
[&]()
{
if(target)
return std::optional<int>(target);
return nullopt;
}
And if you have to name `std::optional<int>` anyway, what's the point? Why
not make your code more readable by just putting that in the return type?
And lastly, I don't know why I would want to support `matcher` anyway. It's
too special case to be generally useful. Ir's exactly the sort of thing a
macro is for: some internal contraction that really shouldn't leak out into
other code.
--
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.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/96cf0808-43aa-4261-8c9a-53cc8132467a%40isocpp.org.
------=_Part_38702_1437085788.1529976946017
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">On Monday, June 25, 2018 at 5:39:27 PM UTC-4, anonymous.fr=
....@gmail.com wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;ma=
rgin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=
=3D"ltr"><div>On Tuesday, June 26, 2018 at 2:26:56 AM UTC+6, Nicol Bolas wr=
ote:<br><blockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex=
;border-left:1px solid rgb(204,204,204);padding-left:1ex">To
know what the return value of a function is, you have to look up the=20
rules of ?:'s common typing. Is that something we need to do? Or rather=
,
is the gain from this really worth the cost?</blockquote></div><div><br></=
div><div>I just thought that it would be easier than introducing some other=
construct.</div></div></blockquote><div><br></div><div>You misunderstand. =
My point was that ?: is not the most common expression in the world, so not=
everyone is 100% aware of all of its idiosyncrasies. Therefore, if they se=
e a complex ?: expression where the two subexpressions are distinct types, =
they'd have to look up how that all works out. Which is fine; it's =
not a hugely common case, so having something to look up is fine.</div><div=
><br></div><div>By contrast, figuring out the return type of a function sho=
uldn't be hard. You need to be able to do this to know how to use the f=
unction. If you make figuring out the return type as hard as ?: can sometim=
es be, then that's a problem.</div><div></div><div><br></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>What I'd like =
is basically an equivalent to the matcher macro below:</div><div><br></div>=
<div><div style=3D"background-color:rgb(250,250,250);border-color:rgb(187,1=
87,187);border-style:solid;border-width:1px"><code><div><div><div><span sty=
le=3D"color:#0000ff"><span style=3D"color:#800">#include</span></span><span=
style=3D"color:#000000"><span style=3D"color:#000"> </span><span style=3D"=
color:#080"><optional></span></span></div><div><span style=3D"color:#=
0000ff"><span style=3D"color:#800">#define</span></span><span style=3D"colo=
r:#000000"><span style=3D"color:#000"> matcher </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">optional</span></span><=
/div><span style=3D"color:#000"><br></span><div><span style=3D"color:#0000f=
f"><span style=3D"color:#800">#include</span></span><span style=3D"color:#0=
00000"><span style=3D"color:#000"> </span><span style=3D"color:#080"><io=
stream></span></span></div><div><span style=3D"color:#0000ff"><span styl=
e=3D"color:#008">template</span></span><span style=3D"color:#000000"><span =
style=3D"color:#000"> </span><span style=3D"color:#660"><</span></span><=
span style=3D"color:#0000ff"><span style=3D"color:#008">typename</span></sp=
an><span style=3D"color:#000000"><span style=3D"color:#000"> T</span><span =
style=3D"color:#660">></span></span></div><div><span style=3D"color:#000=
000"><span style=3D"color:#000">std</span><span style=3D"color:#660">::</sp=
an><span style=3D"color:#000">ostream</span><span style=3D"color:#660">&=
;</span><span style=3D"color:#000"> </span></span><span style=3D"color:#000=
0ff"><span style=3D"color:#008">operator</span></span><span style=3D"color:=
#000000"><span style=3D"color:#660"><<(</span><span style=3D"color:#0=
00">std</span><span style=3D"color:#660">::</span><span style=3D"color:#000=
">ostream</span><span style=3D"color:#660">&</span><span style=3D"color=
:#000"> os</span><span style=3D"color:#660">,</span><span style=3D"color:#0=
00"> </span></span><span style=3D"color:#0000ff"><span style=3D"color:#008"=
>const</span></span><span style=3D"color:#000000"><span style=3D"color:#000=
"> std</span><span style=3D"color:#660">::</span><span style=3D"color:#000"=
>optional</span><span style=3D"color:#660"><</span><span style=3D"color:=
#000">T</span><span style=3D"color:#660">>&</span><span style=3D"col=
or:#000"> val</span><span style=3D"color:#660">)</span></span></div><div><s=
pan style=3D"color:#000000"><span style=3D"color:#660">{</span></span></div=
><div><span style=3D"color:#000000"><span style=3D"color:#000"> =C2=A0 =C2=
=A0</span></span><span style=3D"color:#0000ff"><span style=3D"color:#008">i=
f</span></span><span style=3D"color:#000000"><span style=3D"color:#000"> </=
span><span style=3D"color:#660">(</span><span style=3D"color:#000">val</spa=
n><span style=3D"color:#660">.</span><span style=3D"color:#000">has_value</=
span><span style=3D"color:#660">())</span></span></div><div><span style=3D"=
color:#000000"><span style=3D"color:#000"> =C2=A0 =C2=A0 =C2=A0 =C2=A0os </=
span><span style=3D"color:#660"><<</span><span style=3D"color:#000"> =
</span><span style=3D"color:#660">*</span><span style=3D"color:#000">val</s=
pan><span style=3D"color:#660">;</span></span></div><div><span style=3D"col=
or:#000000"><span style=3D"color:#000"> =C2=A0 =C2=A0</span></span><span st=
yle=3D"color:#0000ff"><span style=3D"color:#008">else</span></span></div><d=
iv><span style=3D"color:#000000"><span style=3D"color:#000"> =C2=A0 =C2=A0 =
=C2=A0 =C2=A0os </span><span style=3D"color:#660"><<</span><span styl=
e=3D"color:#000"> </span></span><span style=3D"color:#a31515"><span style=
=3D"color:#080">"*null*"</span></span><span style=3D"color:#00000=
0"><span style=3D"color:#660">;</span></span></div><div><span style=3D"colo=
r:#000000"><span style=3D"color:#000"> =C2=A0 =C2=A0</span></span><span sty=
le=3D"color:#0000ff"><span style=3D"color:#008">return</span></span><span s=
tyle=3D"color:#000000"><span style=3D"color:#000"> os</span><span style=3D"=
color:#660">;</span></span></div><div><span style=3D"color:#000000"><span s=
tyle=3D"color:#660">}</span></span></div><span style=3D"color:#000"><br></s=
pan><div><span style=3D"color:#0000ff"><span style=3D"color:#008">int</span=
></span><span style=3D"color:#000000"><span style=3D"color:#000"> main</spa=
n><span style=3D"color:#660">()</span><span style=3D"color:#000"> </span><s=
pan style=3D"color:#660">{</span></span></div><div><span style=3D"color:#00=
0000"><span style=3D"color:#000"> =C2=A0 =C2=A0</span></span><span style=3D=
"color:#0000ff"><span style=3D"color:#008">int</span></span><span style=3D"=
color:#000000"><span style=3D"color:#000"> target </span><span style=3D"col=
or:#660">=3D</span><span style=3D"color:#000"> </span></span><span style=3D=
"color:#09885a"><span style=3D"color:#066">0</span></span><span style=3D"co=
lor:#000000"><span style=3D"color:#660">;</span></span></div><div><span sty=
le=3D"color:#000000"><span style=3D"color:#000"> =C2=A0 =C2=A0</span></span=
><span style=3D"color:#0000ff"><span style=3D"color:#008">auto</span></span=
><span style=3D"color:#000000"><span style=3D"color:#000"> zero_matcher </s=
pan><span style=3D"color:#660">=3D</span><span style=3D"color:#000"> matche=
r</span><span style=3D"color:#080"><</span></span><span style=3D"color:#=
0000ff"><span style=3D"color:#080">int</span></span><span style=3D"color:#0=
00000"><span style=3D"color:#080">></span><span style=3D"color:#660">{</=
span></span></div><div><span style=3D"color:#000000"><span style=3D"color:#=
000"> =C2=A0 =C2=A0 =C2=A0 =C2=A0</span></span><span style=3D"color:#0000ff=
"><span style=3D"color:#008">if</span></span><span style=3D"color:#000000">=
<span style=3D"color:#000"> </span><span style=3D"color:#660">(</span><span=
style=3D"color:#000">target </span><span style=3D"color:#660">=3D=3D</span=
><span style=3D"color:#000"> </span></span><span style=3D"color:#09885a"><s=
pan style=3D"color:#066">0</span></span><span style=3D"color:#000000"><span=
style=3D"color:#660">)</span></span></div><div><span style=3D"color:#00000=
0"><span style=3D"color:#000"> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0</s=
pan></span><span style=3D"color:#0000ff"><span style=3D"color:#008">return<=
/span></span><span style=3D"color:#000000"><span style=3D"color:#000"> targ=
et</span><span style=3D"color:#660">;</span></span></div><div><span style=
=3D"color:#000000"><span style=3D"color:#000"> =C2=A0 =C2=A0 =C2=A0 =C2=A0<=
/span></span><span style=3D"color:#0000ff"><span style=3D"color:#008">else<=
/span></span></div><div><span style=3D"color:#000000"><span style=3D"color:=
#000"> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0</span></span><span style=
=3D"color:#0000ff"><span style=3D"color:#008">return</span></span><span sty=
le=3D"color:#000000"><span style=3D"color:#000"> std</span><span style=3D"c=
olor:#660">::</span><span style=3D"color:#000">nullopt</span><span style=3D=
"color:#660">;</span></span></div><div><span style=3D"color:#000000"><span =
style=3D"color:#000"> =C2=A0 =C2=A0</span><span style=3D"color:#660">};</sp=
an></span></div><div><span style=3D"color:#000000"><span style=3D"color:#00=
0"> =C2=A0 =C2=A0</span></span></div><div><span style=3D"color:#000000"><sp=
an style=3D"color:#000"> =C2=A0 =C2=A0std</span><span style=3D"color:#660">=
::</span><span style=3D"color:#000">cout </span><span style=3D"color:#660">=
<<</span><span style=3D"color:#000"> zero_matcher</span><span style=
=3D"color:#660">()</span><span style=3D"color:#000"> </span><span style=3D"=
color:#660"><<</span><span style=3D"color:#000"> </span></span><span =
style=3D"color:#a31515"><span style=3D"color:#080">'\n'</span></spa=
n><span style=3D"color:#000000"><span style=3D"color:#660">;</span></span><=
/div><div><span style=3D"color:#000000"><span style=3D"color:#000"> =C2=A0 =
=C2=A0target </span><span style=3D"color:#660">=3D</span><span style=3D"col=
or:#000"> </span></span><span style=3D"color:#09885a"><span style=3D"color:=
#066">3</span></span><span style=3D"color:#000000"><span style=3D"color:#66=
0">;</span></span></div><div><span style=3D"color:#000000"><span style=3D"c=
olor:#000"> =C2=A0 =C2=A0std</span><span style=3D"color:#660">::</span><spa=
n style=3D"color:#000">cout </span><span style=3D"color:#660"><<</spa=
n><span style=3D"color:#000"> zero_matcher</span><span style=3D"color:#660"=
>()</span><span style=3D"color:#000"> </span><span style=3D"color:#660"><=
;<</span><span style=3D"color:#000"> </span></span><span style=3D"color:=
#a31515"><span style=3D"color:#080">'\n'</span></span><span style=
=3D"color:#000000"><span style=3D"color:#660">;</span></span></div><div><sp=
an style=3D"color:#000000"><span style=3D"color:#660">}</span></span></div>=
</div></div></code></div></div><div>=C2=A0</div></div></blockquote><div><br=
></div><div>What you're asking for wouldn't help. Why? Because you =
still have to say `std::optional<int>` <i>somewhere</i> in that funct=
ion. Observe:</div><div><br></div><div style=3D"background-color: rgb(250, =
250, 250); border-color: rgb(187, 187, 187); border-style: solid; border-wi=
dth: 1px; overflow-wrap: break-word;" class=3D"prettyprint"><code class=3D"=
prettyprint"><div class=3D"subprettyprint"><span style=3D"color: #660;" cla=
ss=3D"styled-by-prettify">[&]()</span><span style=3D"color: #000;" clas=
s=3D"styled-by-prettify"><br></span><span style=3D"color: #660;" class=3D"s=
tyled-by-prettify">{</span><span style=3D"color: #000;" class=3D"styled-by-=
prettify"><br>=C2=A0 </span><span style=3D"color: #008;" class=3D"styled-by=
-prettify">if</span><span style=3D"color: #660;" class=3D"styled-by-prettif=
y">(</span><span style=3D"color: #000;" class=3D"styled-by-prettify">target=
</span><span style=3D"color: #660;" class=3D"styled-by-prettify">)</span><s=
pan style=3D"color: #000;" class=3D"styled-by-prettify"><br>=C2=A0 =C2=A0 <=
/span><span style=3D"color: #008;" class=3D"styled-by-prettify">return</spa=
n><span style=3D"color: #000;" class=3D"styled-by-prettify"> target</span><=
span style=3D"color: #660;" class=3D"styled-by-prettify">;</span><span styl=
e=3D"color: #000;" class=3D"styled-by-prettify"><br>=C2=A0 </span><span sty=
le=3D"color: #008;" class=3D"styled-by-prettify">return</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"> nullopt</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></div></code></div><div><br></div><=
div></div><div>Under your requested rules, that is just as much a compile e=
rror as the expression `target ? target : nullopt`. There is no common type=
between `int` and `nullopt`, so there's no way for this to work. What =
you want would only work if you do this:</div><div><br></div><div style=3D"=
background-color: rgb(250, 250, 250); border-color: rgb(187, 187, 187); bor=
der-style: solid; border-width: 1px; overflow-wrap: break-word;" class=3D"p=
rettyprint"><code class=3D"prettyprint"><div class=3D"subprettyprint"><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>=C2=A0 </span><span style=3D"colo=
r: #008;" class=3D"styled-by-prettify">if</span><span style=3D"color: #660;=
" class=3D"styled-by-prettify">(</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify">target</span><span style=3D"color: #660;" class=3D"=
styled-by-prettify">)</span><span style=3D"color: #000;" class=3D"styled-by=
-prettify"><br>=C2=A0 =C2=A0 </span><span style=3D"color: #008;" class=3D"s=
tyled-by-prettify">return</span><span style=3D"color: #000;" class=3D"style=
d-by-prettify"> std</span><span style=3D"color: #660;" class=3D"styled-by-p=
rettify">::</span><span style=3D"color: #000;" class=3D"styled-by-prettify"=
>optional</span><span style=3D"color: #080;" class=3D"styled-by-prettify">&=
lt;int></span><span style=3D"color: #660;" class=3D"styled-by-prettify">=
(</span><span style=3D"color: #000;" class=3D"styled-by-prettify">target</s=
pan><span style=3D"color: #660;" class=3D"styled-by-prettify">);</span><spa=
n style=3D"color: #000;" class=3D"styled-by-prettify"><br>=C2=A0 </span><sp=
an style=3D"color: #008;" class=3D"styled-by-prettify">return</span><span s=
tyle=3D"color: #000;" class=3D"styled-by-prettify"> nullopt</span><span sty=
le=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></div></code></div><div><br></div=
><div></div><div>And if you have to name `std::optional<int>` anyway,=
what's the point? Why not make your code more readable by just putting=
that in the return type?<br></div><div><br></div><div>And lastly, I don=
9;t know why I would want to support `matcher` anyway. It's too special=
case to be generally useful. Ir's exactly the sort of thing a macro is=
for: some internal contraction that really shouldn't leak out into oth=
er code.<br></div></div>
<p></p>
-- <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 />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/96cf0808-43aa-4261-8c9a-53cc8132467a%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/96cf0808-43aa-4261-8c9a-53cc8132467a=
%40isocpp.org</a>.<br />
------=_Part_38702_1437085788.1529976946017--
------=_Part_38701_596494694.1529976946017--
.
Author: Nicol Bolas <jmckesson@gmail.com>
Date: Mon, 25 Jun 2018 18:40:08 -0700 (PDT)
Raw View
------=_Part_38495_1502691337.1529977208760
Content-Type: multipart/alternative;
boundary="----=_Part_38496_2109803968.1529977208760"
------=_Part_38496_2109803968.1529977208760
Content-Type: text/plain; charset="UTF-8"
On Monday, June 25, 2018 at 6:12:57 PM UTC-4, Richard Smith wrote:
>
> On 25 June 2018 at 13:26, Nicol Bolas <jmck...@gmail.com <javascript:>>
> wrote:
>
>> On Monday, June 25, 2018 at 3:29:11 PM UTC-4, Richard Smith wrote:
>>>
>>> On 25 June 2018 at 11:39, Tony V E <tvan...@gmail.com> wrote:
>>>
>>>> We could at least avoid common_type by instead talking about as if by ?:
>>>>
>>>
>>> Yes; I wish the language rule had originally been defined that way.
>>>
>>
>> ... it *is* defined that way. `std::common_type` is defined in terms of
>> the rules for `?:`, not the other way around.
>>
>
> Sorry, we have miscommunicated: "the language rule" I'm talking about is
> return type deduction, and how it handles the case of multiple types (not
> common_type). It (return type deduction) is not defined as using ?: to
> compute a common type, as you are no doubt aware.
>
> The self-recursive function case doesn't seem sufficiently compelling to
>>> me to take priority over supporting multiple returns with different types.
>>>
>>
>> But do we really want to support that? Or more to the point, do we really
>> need to avoid writing a type name this badly?
>>
>> Return type deduction is not free. You're taking an important piece of
>> information which is well-specified in a specific location and obscuring
>> it. Being able to inspect what a function does quickly is a good thing, and
>> having to peer through its code to figure out what's going on is a bad
>> thing.
>>
>> So for me, in order for the gains of return type deduction to outweigh
>> the drawbacks, one of the following must be true:
>>
>> 1. The return type is obvious based on the function's name and its
>> parameters. A function named `add` that takes two parameters naturally
>> returns whatever type is the sum of those parameters. So telling us what we
>> can work out for ourselves is pointless redundancy.
>>
>> 2. The function is very short, 5 statements or less. Telling us what we
>> can see from within the function quite easily is pointless redundancy.
>>
>> 3. The return type is difficult to type (large metaprogramming thing
>> based on the types of parameters) or impossible to type (lambdas). Writing
>> a big, long thing at the beginning (or end) of our function makes it
>> difficult to read or understand.
>>
>> If none of these are true, I would say that return type deduction makes
>> code harder to deal with rather than easier. A function with multiple
>> return statements almost certainly fails #2. #3 can still happen, but not
>> in the case the OP outlined when dealing with a clear case of
>> `optional<int>`.
>>
>> So what we're left with is something that only rarely makes code easier
>> to read. While simultaneously not catching mistakes where you happen to
>> accidentally change the function's return type.
>>
>> Overall, I just think that this is way too much of a corner case to put
>> it into the standard. I hate to use principles as bludgeons for features I
>> don't like, but Bjarne's "Remember the Vasa" post
>> <http://wg21.link/P0977> would seem to speak to this. It's not making
>> the language easier to use; it's making the language more expert-friendly,
>> at the detriment to ease of use.
>>
>> To know what the return value of a function is, you have to look up the
>> rules of ?:'s common typing. Is that something we need to do? Or rather, is
>> the gain from this really worth the cost?
>>
>
> I think there are examples when it is worth the cost (particularly, the
> cases where the function has a primary return statement and some bailouts
> that return nullptr or nullopt or similar). Conversely, I'm not convinced
> that supporting return type deduction for (directly) recursive functions is
> worth the cost -- that seems like the expert-only feature in this context.
>
Perhaps, but we already support that. Features that already exist no longer
need to justify themselves (unless you're debating removing them, which has
to have a lot more justification due to being a breaking change). Proposed
features need to justify themselves. And they need to make sure that code
doesn't get worse.
Conversely, having a single general type unification algorithm that is used
> in all contexts where it makes sense makes the language simpler and more
> beginner-friendly (I seem to recall a good blog post on this subject --
> perhaps from Eric Lippert -- a few years back, about how the C# language
> was simplified by using the same rules for ?: type unification and for type
> unification in return type deduction, but I can't find it right now...). A
> beginner expects to be able to use nullptr where they would have used a
> value of a pointer type, and saying you can't do that in a return statement
> in a function with a deduced return type is an unnecessary complication.
> ("Why can't the compiler just work it out for itself? The intended return
> type is obvious.")
>
But the intended return type is *not* "obvious", as evidenced by the fact
that you need to create a bunch of special rules to decide what it should
be. The expression alone is insufficient.
Yes, `return nullptr;` would represent that the function returns a pointer
type. But... *what* pointer type? You don't know; you now have to go
fishing around for another `return` statement to figure out what it
actually returns. You don't even know if it's a *raw pointer*; it could be
a `unique_ptr` or whatever. And if you don't know what pointer type a
function returns, how can you use it?
Yes, you can argue that the existing recursion rules have the same problem.
I'm not exactly happy with them either, but in their defense, recursion is
a lot more rare than wanting to do the kind of stuff you're talking about.
So the problem that recursive calls create (ie: having to look at another
`return` statement) is not often encountered.
Code is read more often than it is written. So maybe let's not optimize for
the latter when it makes the former really hard.
--
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.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/0367f321-1422-4437-80a3-716aa0d7dae7%40isocpp.org.
------=_Part_38496_2109803968.1529977208760
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">On Monday, June 25, 2018 at 6:12:57 PM UTC-4, Richard Smit=
h 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"><div>=
<div class=3D"gmail_quote">On 25 June 2018 at 13:26, Nicol Bolas <span dir=
=3D"ltr"><<a href=3D"javascript:" target=3D"_blank" gdf-obfuscated-mailt=
o=3D"nEMiaTzoAwAJ" rel=3D"nofollow" onmousedown=3D"this.href=3D'javascr=
ipt:';return true;" onclick=3D"this.href=3D'javascript:';return=
true;">jmck...@gmail.com</a>></span> wrote:<br><blockquote class=3D"gma=
il_quote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-lef=
t:1ex"><div dir=3D"ltr">On Monday, June 25, 2018 at 3:29:11 PM UTC-4, Richa=
rd Smith wrote:<span><blockquote class=3D"gmail_quote" style=3D"margin:0;ma=
rgin-left:0.8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir=3D"lt=
r"><div><div class=3D"gmail_quote">On 25 June 2018 at 11:39, Tony V E <span=
dir=3D"ltr"><<a rel=3D"nofollow">tvan...@gmail.com</a>></span> wrote=
:<br><blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-le=
ft:1px #ccc solid;padding-left:1ex"><div style=3D"background-color:rgb(255,=
255,255);line-height:initial" lang=3D"en-US"> =
<div style=3D"width=
:100%;font-size:initial;font-family:Calibri,'Slate Pro',sans-serif,=
sans-serif;color:rgb(31,73,125);text-align:initial;background-color:rgb(255=
,255,255)">We could at least avoid common_type by instead talking about as =
if by ?:</div></div></blockquote><div><br></div><div>Yes; I wish the langua=
ge rule had originally been defined that way.</div></div></div></div></bloc=
kquote><div><br></div></span><div>... it <i>is</i> defined that way. `std::=
common_type` is defined in terms of the rules for `?:`, not the other way a=
round.</div></div></blockquote><div><br></div><div>Sorry, we have miscommun=
icated: "the language rule" I'm talking about is return type =
deduction, and how it handles the case of multiple types (not common_type).=
It (return type deduction) is not defined as using ?: to compute a common =
type, as you are no doubt aware.</div><div><br></div><blockquote class=3D"g=
mail_quote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-l=
eft:1ex"><div dir=3D"ltr"><span><blockquote class=3D"gmail_quote" style=3D"=
margin:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-left:1ex"><di=
v dir=3D"ltr"><div><div class=3D"gmail_quote"><div>The self-recursive funct=
ion case doesn't seem sufficiently compelling to me to take priority ov=
er supporting multiple returns with different types.</div></div></div></div=
></blockquote><div><br></div></span><div>But do we really want to support t=
hat? Or more to the point, do we really need to avoid writing a type name t=
his badly?</div><div><br></div><div>Return type deduction is not free. You&=
#39;re taking an important piece of information which is well-specified in =
a specific location and obscuring it. Being able to inspect what a function=
does quickly is a good thing, and having to peer through its code to figur=
e out what's going on is a bad thing.<br></div><div><br></div><div>So f=
or me, in order for the gains of return type deduction to outweigh the draw=
backs, one of the following must be true:</div><div><br></div><div>1. The r=
eturn type is obvious based on the function's name and its parameters. =
A function named `add` that takes two parameters naturally returns whatever=
type is the sum of those parameters. So telling us what we can work out fo=
r ourselves is pointless redundancy.<br></div><div><br></div><div>2. The fu=
nction is very short, 5 statements or less. Telling us what we can see from=
within the function quite easily is pointless redundancy.<br></div><div><b=
r></div><div>3. The return type is difficult to type (large metaprogramming=
thing based on the types of parameters) or impossible to type (lambdas). W=
riting a big, long thing at the beginning (or end) of our function makes it=
difficult to read or understand.<br></div><div><br></div><div>If none of t=
hese are true, I would say that return type deduction makes code harder to =
deal with rather than easier. A function with multiple return statements al=
most certainly fails #2. #3 can still happen, but not in the case the OP ou=
tlined when dealing with a clear case of `optional<int>`.</div><div><=
br></div><div>So what we're left with is something that only rarely mak=
es code easier to read. While simultaneously not catching mistakes where yo=
u happen to accidentally change the function's return type.</div><div><=
br></div><div>Overall, I just think that this is way too much of a corner c=
ase to put it into the standard. I hate to use principles as bludgeons for =
features I don't like, but <a href=3D"http://wg21.link/P0977" target=3D=
"_blank" rel=3D"nofollow" onmousedown=3D"this.href=3D'http://www.google=
..com/url?q\x3dhttp%3A%2F%2Fwg21.link%2FP0977\x26sa\x3dD\x26sntz\x3d1\x26usg=
\x3dAFQjCNEZ2JdeIlhq73uKuRpDMhl3nZ4_vg';return true;" onclick=3D"this.h=
ref=3D'http://www.google.com/url?q\x3dhttp%3A%2F%2Fwg21.link%2FP0977\x2=
6sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNEZ2JdeIlhq73uKuRpDMhl3nZ4_vg';ret=
urn true;">Bjarne's "Remember the Vasa" post</a> would seem t=
o speak to this. It's not making the language easier to use; it's m=
aking the language more expert-friendly, at the detriment to ease of use.</=
div><div><br></div><div>To know what the return value of a function is, you=
have to look up the rules of ?:'s common typing. Is that something we =
need to do? Or rather, is the gain from this really worth the cost?</div></=
div></blockquote><div><br></div><div>I think there are examples when it is =
worth the cost (particularly, the cases where the function has a primary re=
turn statement and some bailouts that return nullptr or nullopt or similar)=
.. Conversely, I'm not convinced that supporting return type deduction f=
or (directly) recursive functions is worth the cost -- that seems like the =
expert-only feature in this context.</div></div></div></div></blockquote><d=
iv><br></div><div>Perhaps, but we already support that. Features that alrea=
dy exist no longer need to justify themselves (unless you're debating r=
emoving them, which has to have a lot more justification due to being a bre=
aking change). Proposed features need to justify themselves. And they need =
to make sure that code doesn't get worse.<br></div><div><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;"><div dir=3D"ltr"><div><div class=3D=
"gmail_quote"><div>Conversely, having a single general type unification alg=
orithm that is used in all contexts where it makes sense makes the language=
simpler and more beginner-friendly (I seem to recall a good blog post on t=
his subject -- perhaps from Eric Lippert -- a few years back, about how the=
C# language was simplified by using the same rules for ?: type unification=
and for type unification in return type deduction, but I can't find it=
right now...). A beginner expects to be able to use nullptr where they wou=
ld have used a value of a pointer type, and saying you can't do that in=
a return statement in a function with a deduced return type is an unnecess=
ary complication. ("Why can't the compiler just work it out for it=
self? The intended return type is obvious.")</div></div></div></div></=
blockquote><div><br></div><div>But the intended return type is <i>not</i> &=
quot;obvious", as evidenced by the fact that you need to create a bunc=
h of special rules to decide what it should be. The expression alone is ins=
ufficient.<br></div><div><br></div><div>Yes, `return nullptr;` would repres=
ent that the function returns a pointer type. But... <i>what</i> pointer ty=
pe? You don't know; you now have to go fishing around for another `retu=
rn` statement to figure out what it actually returns. You don't even kn=
ow if it's a <i>raw pointer</i>; it could be a `unique_ptr` or whatever=
.. And if you don't know what pointer type a function returns, how can y=
ou use it?</div><div><br></div><div>Yes, you can argue that the existing re=
cursion rules have the same problem. I'm not exactly happy with them ei=
ther, but in their defense, recursion is a lot more rare than wanting to do=
the kind of stuff you're talking about. So the problem that recursive =
calls create (ie: having to look at another `return` statement) is not ofte=
n encountered.<br></div><div></div><div><div><br></div><div>Code is read mo=
re often than it is written. So maybe let's not optimize for the latter=
when it makes the former really hard.</div></div></div>
<p></p>
-- <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 />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/0367f321-1422-4437-80a3-716aa0d7dae7%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/0367f321-1422-4437-80a3-716aa0d7dae7=
%40isocpp.org</a>.<br />
------=_Part_38496_2109803968.1529977208760--
------=_Part_38495_1502691337.1529977208760--
.
Author: Richard Smith <richard@metafoo.co.uk>
Date: Tue, 26 Jun 2018 13:30:13 -0700
Raw View
--00000000000050b836056f915ead
Content-Type: text/plain; charset="UTF-8"
On Mon, 25 Jun 2018, 18:40 Nicol Bolas, <jmckesson@gmail.com> wrote:
> On Monday, June 25, 2018 at 6:12:57 PM UTC-4, Richard Smith wrote:
>>
>> On 25 June 2018 at 13:26, Nicol Bolas <jmck...@gmail.com> wrote:
>>
>>> On Monday, June 25, 2018 at 3:29:11 PM UTC-4, Richard Smith wrote:
>>>>
>>>> On 25 June 2018 at 11:39, Tony V E <tvan...@gmail.com> wrote:
>>>>
>>>>> We could at least avoid common_type by instead talking about as if by
>>>>> ?:
>>>>>
>>>>
>>>> Yes; I wish the language rule had originally been defined that way.
>>>>
>>>
>>> ... it *is* defined that way. `std::common_type` is defined in terms of
>>> the rules for `?:`, not the other way around.
>>>
>>
>> Sorry, we have miscommunicated: "the language rule" I'm talking about is
>> return type deduction, and how it handles the case of multiple types (not
>> common_type). It (return type deduction) is not defined as using ?: to
>> compute a common type, as you are no doubt aware.
>>
>> The self-recursive function case doesn't seem sufficiently compelling to
>>>> me to take priority over supporting multiple returns with different types.
>>>>
>>>
>>> But do we really want to support that? Or more to the point, do we
>>> really need to avoid writing a type name this badly?
>>>
>>> Return type deduction is not free. You're taking an important piece of
>>> information which is well-specified in a specific location and obscuring
>>> it. Being able to inspect what a function does quickly is a good thing, and
>>> having to peer through its code to figure out what's going on is a bad
>>> thing.
>>>
>>> So for me, in order for the gains of return type deduction to outweigh
>>> the drawbacks, one of the following must be true:
>>>
>>> 1. The return type is obvious based on the function's name and its
>>> parameters. A function named `add` that takes two parameters naturally
>>> returns whatever type is the sum of those parameters. So telling us what we
>>> can work out for ourselves is pointless redundancy.
>>>
>>> 2. The function is very short, 5 statements or less. Telling us what we
>>> can see from within the function quite easily is pointless redundancy.
>>>
>>> 3. The return type is difficult to type (large metaprogramming thing
>>> based on the types of parameters) or impossible to type (lambdas). Writing
>>> a big, long thing at the beginning (or end) of our function makes it
>>> difficult to read or understand.
>>>
>>> If none of these are true, I would say that return type deduction makes
>>> code harder to deal with rather than easier. A function with multiple
>>> return statements almost certainly fails #2. #3 can still happen, but not
>>> in the case the OP outlined when dealing with a clear case of
>>> `optional<int>`.
>>>
>>> So what we're left with is something that only rarely makes code easier
>>> to read. While simultaneously not catching mistakes where you happen to
>>> accidentally change the function's return type.
>>>
>>> Overall, I just think that this is way too much of a corner case to put
>>> it into the standard. I hate to use principles as bludgeons for features I
>>> don't like, but Bjarne's "Remember the Vasa" post
>>> <http://wg21.link/P0977> would seem to speak to this. It's not making
>>> the language easier to use; it's making the language more expert-friendly,
>>> at the detriment to ease of use.
>>>
>>> To know what the return value of a function is, you have to look up the
>>> rules of ?:'s common typing. Is that something we need to do? Or rather, is
>>> the gain from this really worth the cost?
>>>
>>
>> I think there are examples when it is worth the cost (particularly, the
>> cases where the function has a primary return statement and some bailouts
>> that return nullptr or nullopt or similar). Conversely, I'm not convinced
>> that supporting return type deduction for (directly) recursive functions is
>> worth the cost -- that seems like the expert-only feature in this context.
>>
>
> Perhaps, but we already support that. Features that already exist no
> longer need to justify themselves (unless you're debating removing them,
> which has to have a lot more justification due to being a breaking change).
> Proposed features need to justify themselves. And they need to make sure
> that code doesn't get worse.
>
Oh, I agree, and that's why I said that I wish the language rule had
originally been defined this way, not that we should change it today. The
latter is a far less appealing proposition.
Conversely, having a single general type unification algorithm that is used
>> in all contexts where it makes sense makes the language simpler and more
>> beginner-friendly (I seem to recall a good blog post on this subject --
>> perhaps from Eric Lippert -- a few years back, about how the C# language
>> was simplified by using the same rules for ?: type unification and for type
>> unification in return type deduction, but I can't find it right now...). A
>> beginner expects to be able to use nullptr where they would have used a
>> value of a pointer type, and saying you can't do that in a return statement
>> in a function with a deduced return type is an unnecessary complication.
>> ("Why can't the compiler just work it out for itself? The intended return
>> type is obvious.")
>>
>
> But the intended return type is *not* "obvious", as evidenced by the fact
> that you need to create a bunch of special rules to decide what it should
> be. The expression alone is insufficient.
>
> Yes, `return nullptr;` would represent that the function returns a pointer
> type. But... *what* pointer type? You don't know; you now have to go
> fishing around for another `return` statement to figure out what it
> actually returns. You don't even know if it's a *raw pointer*; it could
> be a `unique_ptr` or whatever. And if you don't know what pointer type a
> function returns, how can you use it?
>
> Yes, you can argue that the existing recursion rules have the same
> problem. I'm not exactly happy with them either, but in their defense,
> recursion is a lot more rare than wanting to do the kind of stuff you're
> talking about. So the problem that recursive calls create (ie: having to
> look at another `return` statement) is not often encountered.
>
> Code is read more often than it is written. So maybe let's not optimize
> for the latter when it makes the former really hard.
>
Well, that ("really hard") is subjective, and I don't think either of us
has the evidence to conclude it or its negation. But I would readily admit
that the possibility would exist for people to abuse this feature in a way
that degrades readability. However, return type deduction itself (or indeed
any type deduction) already takes information away from the reader, and
therefore should only be used where that information is a distraction or an
irrelevance rather than being useful; I don't see that this case would be
different in character (though it might be different in degree).
Earlier, you suggested that someone wishing to call a function using return
type deduction would need to read its implementation to understand how to
call it. If they do, I would suggest that function is abusing return type
deduction regardless of whether it uses the extension we're discussing. The
whole point of the function abstraction is that you don't need to pierce
the veil to use the functionality.
> --
> 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.
> To view this discussion on the web visit
> https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/0367f321-1422-4437-80a3-716aa0d7dae7%40isocpp.org
> <https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/0367f321-1422-4437-80a3-716aa0d7dae7%40isocpp.org?utm_medium=email&utm_source=footer>
> .
>
--
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.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CAOfiQq%3DTM8bMHxcykiUF9Q-G-RT_6PUwDYQop9yWSosEbYhO9Q%40mail.gmail.com.
--00000000000050b836056f915ead
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable
<div dir=3D"auto"><div><div class=3D"gmail_quote"><div dir=3D"ltr">On Mon, =
25 Jun 2018, 18:40 Nicol Bolas, <<a href=3D"mailto:jmckesson@gmail.com">=
jmckesson@gmail.com</a>> wrote:<br></div><blockquote class=3D"gmail_quot=
e" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">=
<div dir=3D"ltr">On Monday, June 25, 2018 at 6:12:57 PM UTC-4, Richard Smit=
h wrote:<blockquote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8=
ex;border-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><div><div =
class=3D"gmail_quote">On 25 June 2018 at 13:26, Nicol Bolas <span dir=3D"lt=
r"><<a rel=3D"nofollow noreferrer">jmck...@gmail.com</a>></span> wrot=
e:<br><blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-l=
eft:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr">On Monday, June 25, 2=
018 at 3:29:11 PM UTC-4, Richard Smith wrote:<span><blockquote class=3D"gma=
il_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;pa=
dding-left:1ex"><div dir=3D"ltr"><div><div class=3D"gmail_quote">On 25 June=
2018 at 11:39, Tony V E <span dir=3D"ltr"><<a rel=3D"nofollow noreferre=
r">tvan...@gmail.com</a>></span> wrote:<br><blockquote class=3D"gmail_qu=
ote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex=
"><div style=3D"background-color:rgb(255,255,255);line-height:initial" lang=
=3D"en-US"> =
<div style=3D"width:100%;font-size:initial;font-famil=
y:Calibri,'Slate Pro',sans-serif,sans-serif;color:rgb(31,73,125);te=
xt-align:initial;background-color:rgb(255,255,255)">We could at least avoid=
common_type by instead talking about as if by ?:</div></div></blockquote><=
div><br></div><div>Yes; I wish the language rule had originally been define=
d that way.</div></div></div></div></blockquote><div><br></div></span><div>=
.... it <i>is</i> defined that way. `std::common_type` is defined in terms o=
f the rules for `?:`, not the other way around.</div></div></blockquote><di=
v><br></div><div>Sorry, we have miscommunicated: "the language rule&qu=
ot; I'm talking about is return type deduction, and how it handles the =
case of multiple types (not common_type). It (return type deduction) is not=
defined as using ?: to compute a common type, as you are no doubt aware.</=
div><div><br></div><blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 =
..8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><span><b=
lockquote 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 class=3D"g=
mail_quote"><div>The self-recursive function case doesn't seem sufficie=
ntly compelling to me to take priority over supporting multiple returns wit=
h different types.</div></div></div></div></blockquote><div><br></div></spa=
n><div>But do we really want to support that? Or more to the point, do we r=
eally need to avoid writing a type name this badly?</div><div><br></div><di=
v>Return type deduction is not free. You're taking an important piece o=
f information which is well-specified in a specific location and obscuring =
it. Being able to inspect what a function does quickly is a good thing, and=
having to peer through its code to figure out what's going on is a bad=
thing.<br></div><div><br></div><div>So for me, in order for the gains of r=
eturn type deduction to outweigh the drawbacks, one of the following must b=
e true:</div><div><br></div><div>1. The return type is obvious based on the=
function's name and its parameters. A function named `add` that takes =
two parameters naturally returns whatever type is the sum of those paramete=
rs. So telling us what we can work out for ourselves is pointless redundanc=
y.<br></div><div><br></div><div>2. The function is very short, 5 statements=
or less. Telling us what we can see from within the function quite easily =
is pointless redundancy.<br></div><div><br></div><div>3. The return type is=
difficult to type (large metaprogramming thing based on the types of param=
eters) or impossible to type (lambdas). Writing a big, long thing at the be=
ginning (or end) of our function makes it difficult to read or understand.<=
br></div><div><br></div><div>If none of these are true, I would say that re=
turn type deduction makes code harder to deal with rather than easier. A fu=
nction with multiple return statements almost certainly fails #2. #3 can st=
ill happen, but not in the case the OP outlined when dealing with a clear c=
ase of `optional<int>`.</div><div><br></div><div>So what we're le=
ft with is something that only rarely makes code easier to read. While simu=
ltaneously not catching mistakes where you happen to accidentally change th=
e function's return type.</div><div><br></div><div>Overall, I just thin=
k that this is way too much of a corner case to put it into the standard. I=
hate to use principles as bludgeons for features I don't like, but <a =
href=3D"http://wg21.link/P0977" rel=3D"nofollow noreferrer" target=3D"_blan=
k">Bjarne's "Remember the Vasa" post</a> would seem to speak =
to this. It's not making the language easier to use; it's making th=
e language more expert-friendly, at the detriment to ease of use.</div><div=
><br></div><div>To know what the return value of a function is, you have to=
look up the rules of ?:'s common typing. Is that something we need to =
do? Or rather, is the gain from this really worth the cost?</div></div></bl=
ockquote><div><br></div><div>I think there are examples when it is worth th=
e cost (particularly, the cases where the function has a primary return sta=
tement and some bailouts that return nullptr or nullopt or similar). Conver=
sely, I'm not convinced that supporting return type deduction for (dire=
ctly) recursive functions is worth the cost -- that seems like the expert-o=
nly feature in this context.</div></div></div></div></blockquote><div><br><=
/div><div>Perhaps, but we already support that. Features that already exist=
no longer need to justify themselves (unless you're debating removing =
them, which has to have a lot more justification due to being a breaking ch=
ange). Proposed features need to justify themselves. And they need to make =
sure that code doesn't get worse.</div></div></blockquote></div></div><=
div dir=3D"auto"><br></div><div dir=3D"auto">Oh, I agree, and that's wh=
y I said that I wish the language rule had originally been defined this way=
, not that we should change it today. The latter is a far less appealing pr=
oposition.</div><div dir=3D"auto"><br></div><div dir=3D"auto"><div class=3D=
"gmail_quote"><blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;=
border-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><blockquote c=
lass=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1px #c=
cc solid;padding-left:1ex"><div dir=3D"ltr"><div><div class=3D"gmail_quote"=
><div>Conversely, having a single general type unification algorithm that i=
s used in all contexts where it makes sense makes the language simpler and =
more beginner-friendly (I seem to recall a good blog post on this subject -=
- perhaps from Eric Lippert -- a few years back, about how the C# language =
was simplified by using the same rules for ?: type unification and for type=
unification in return type deduction, but I can't find it right now...=
). A beginner expects to be able to use nullptr where they would have used =
a value of a pointer type, and saying you can't do that in a return sta=
tement in a function with a deduced return type is an unnecessary complicat=
ion. ("Why can't the compiler just work it out for itself? The int=
ended return type is obvious.")</div></div></div></div></blockquote><d=
iv><br></div><div>But the intended return type is <i>not</i> "obvious&=
quot;, as evidenced by the fact that you need to create a bunch of special =
rules to decide what it should be. The expression alone is insufficient.<br=
></div><div><br></div><div>Yes, `return nullptr;` would represent that the =
function returns a pointer type. But... <i>what</i> pointer type? You don&#=
39;t know; you now have to go fishing around for another `return` statement=
to figure out what it actually returns. You don't even know if it'=
s a <i>raw pointer</i>; it could be a `unique_ptr` or whatever. And if you =
don't know what pointer type a function returns, how can you use it?</d=
iv><div><br></div><div>Yes, you can argue that the existing recursion rules=
have the same problem. I'm not exactly happy with them either, but in =
their defense, recursion is a lot more rare than wanting to do the kind of =
stuff you're talking about. So the problem that recursive calls create =
(ie: having to look at another `return` statement) is not often encountered=
..<br></div><div></div><div><div><br></div><div>Code is read more often than=
it is written. So maybe let's not optimize for the latter when it make=
s the former really hard.</div></div></div></blockquote></div></div><div di=
r=3D"auto"><br></div><div dir=3D"auto">Well, that ("really hard")=
is subjective, and I don't think either of us has the evidence to conc=
lude it or its negation. But I would readily admit that the possibility wou=
ld exist for people to abuse this feature in a way that degrades readabilit=
y. However, return type deduction itself (or indeed any type deduction) alr=
eady takes information away from the reader, and therefore should only be u=
sed where that information is a distraction or an irrelevance rather than b=
eing useful; I don't see that this case would be different in character=
(though it might be different in degree).</div><div dir=3D"auto"><br></div=
><div dir=3D"auto">Earlier, you suggested that someone wishing to call a fu=
nction using return type deduction would need to read its implementation to=
understand how to call it. If they do, I would suggest that function is ab=
using return type deduction regardless of whether it uses the extension we&=
#39;re discussing. The whole point of the function abstraction is that you =
don't need to pierce the veil to use the functionality.</div><div dir=
=3D"auto"><div class=3D"gmail_quote"><blockquote class=3D"gmail_quote" styl=
e=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<p></p>
-- <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" target=3D"_=
blank" rel=3D"noreferrer">std-proposals+unsubscribe@isocpp.org</a>.<br>
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org" target=3D"_blank" rel=3D"noreferrer">std-proposals@isocpp.org</a>.<br=
>
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/0367f321-1422-4437-80a3-716aa0d7dae7%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter" target=3D"_blank" =
rel=3D"noreferrer">https://groups.google.com/a/isocpp.org/d/msgid/std-propo=
sals/0367f321-1422-4437-80a3-716aa0d7dae7%40isocpp.org</a>.<br>
</blockquote></div></div></div>
<p></p>
-- <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 />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/CAOfiQq%3DTM8bMHxcykiUF9Q-G-RT_6PUwDY=
Qop9yWSosEbYhO9Q%40mail.gmail.com?utm_medium=3Demail&utm_source=3Dfooter">h=
ttps://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CAOfiQq%3DTM8bM=
HxcykiUF9Q-G-RT_6PUwDYQop9yWSosEbYhO9Q%40mail.gmail.com</a>.<br />
--00000000000050b836056f915ead--
.
Author: anonymous.from.applecity@gmail.com
Date: Tue, 3 Jul 2018 09:39:03 -0700 (PDT)
Raw View
------=_Part_50620_2080536637.1530635943311
Content-Type: multipart/alternative;
boundary="----=_Part_50621_635745624.1530635943311"
------=_Part_50621_635745624.1530635943311
Content-Type: text/plain; charset="UTF-8"
Sorry for bothering you with so badly thought out idea last time. I'm
coming back with something that I believe is more grounded and should be
more "practical" in terms of usage. It's first time for me to participate
in such a discussion, but I hope this feature will be a big improvement.
Here are the points I tried to cover, some of them are incomplete:
- Don't break existing code and don't silently change behavior (No: but
close, requires reserving one new keyword. This is new functionality)
- Empower users without being confusing, e.g. simplify the common case
and allow people with different needs get the power (Yes)
- Play well with language and standard library
- Do not deviate from general C++ syntax and ideas (I believe yes)
I believe I know what I actually need: a way to capture and reuse *return
type and argument types* of a function. The feature should be usable in
many places, including existing and upcoming standard library functionality.
*Definition:*
Closure is a way to capture return type and argument types of a function.
The closure then can be used to match the callable with the return type and
arguments types, or used as alias to create a lambda with the properties
specified by closure.
*Closure declaration:*
closure *closure_name*(*optional-argument-list*) *optional-noexcept
optional-mutable* -> *return_type*;
Then, the closure can be used in multiple ways. First being to be named
lambda kind, to imrpove readability and better interoperate with IDEs and
tools, as they can give a hint to programmer in the right direction. Here
is the username_validator, which can be used to adjust the set of allowed
usernames:
closure username_validator(const std::string& username) -> bool;
std::copy_if(new_users.begin(), new_users.end(),
back_inserter(saved_users), username_validator {
return std::all_of(username.begin(), username.end(), std::isalpha)
//omitted cast to unsigned char for brevity
});
The *closure instantiation* above will create a lambda with the return type
and arguments specified by clojure declaration. As implied by word
instantiation, the clojure itself is not a type, but a mere set of
constraints that will be applied on a type or be used to create a lambda.
To be usable in generic functions, there is template related feature:
*template closure declaration:*
template <*template-parameter-list*>
closure *closure_name*(*optional-parameter-list*) -> *return_type*;
The syntax could be changed to one in templates for lambdas proposal. Every
template argument should be available from inside of the closure in case it
is instantiated. This can be used in many places in standard library:
template <typename T>
closure unary_predicate(const T& value) -> bool;
Then, one can use it like this:
std::remove_if(source.begin(), source.end(), dest.begin(),
unary_predicate<int> {return value % 2 == 0;} );
Template arguments are unnecessary if they cannot be deduced from arguments
into the function. In case of omitting the brackets, closure will produce
generic lambda (the one with templated operator()). To reiterate:
*valid:*
template <typename T>
closure identity(const T& value) -> T; //same as [](const T& value) {return
value;}
*invalid:*
template <typename T, typename U>
closure map(const T& value) -> U; //U cannot be deduced
In case of using the brackets, the template will be instantiated and the
resulting lambda will have definitive argument and return types. Sometimes
there might be a need to create an alias to a closure, which is handled as
well. Here is the syntax:
*closure alias declaration:*
using closure *closure_name*(*optional-rename-sequence*) =
*declared_closure*;
The rename sequence lets people to redefine the names of the input
parameters, which is a verbose future by design (user can mess up the
order), and allows programmers to retrofit the initial names to their
context. Lets create an alias to specialized unary_predicate, and name it
username_validator:
using closure username_validator(username=value) =
unary_predicate<std::string>;
Either all or no names should be renamed. The last missing feature from
lambdas is a capture list. It is handled as trailing capture list:
*closure instantiation*
*declared_closure_name*[*optional-capture-list*](*optional-rename-list*) *optional-noexcept
optional-mutable* { /**optional-code**/}
One can use it to create a unique ID generator for usernames:
closure id_generator(std::string_view username) -> std::size_t;
using id_storage = std::unordered_map<std::string_view, std::size_t>;
auto generator = id_generator[generated_ids = id_storage{}, counter =
std::size_t(0)] mutable {
auto& id = generated_ids[username];
if (id == 0)
id = counter++;
return id;
}
Closures cannot be used as template parameters, because there is
one-to-many relationship between a type and set of closures it matches.
Thus, I believe using the syntax below should be both reasonable and
flexible.
*Constraining template parameter*
template <*closure_name parameter_name, ...>*
struct *struct_name *{};
I'm not sure about the syntax of the following feature. It allows users to
create a variable with the same closure as the operand on the right side:
*Closure constrained variable declaration and definition*
*closure_name *auto* variable_name *= *lvalue_or_rvalue*;
I thought about instanceof, but it would require one more keyword to
reserve. With the above, the feature can be used in template parameter list:
template <typename It, unary_predicate<It::value_type> Predicate> //omitted
some stuff for brevity
It remove_if(It first, It last, Predicate pred);
It should be noted that there is a new template parameter silently added to
the template. The following will match the closure specified above (for
iterators referring to integers).
struct dummy {
bool operator()(int ) { return true; }
};
*Reflection*
One could also use the feature to provide introspection for the callable.
I've already written a lot, but I believe that closure_name::return_type
could be used to inspect return type, and closure_name::parameters could be
a template parameter pack. The thing is that closure already defeats the
need for the such reflection in the first place. All operations not covered
by closures I can think of are already handled by existing functionality
that operate on types.
*How is it different from combination of Concepts and lambdas?*
Not much, and it is by design. closure is a combination of lambda and
SFINAE. The feature should simplify most of the common template
metaprogramming regarding accepting callables. Also it should clarify most
of the lambda usage.Since abbreviated template parameters didn't make it
into concepts, this should be conservative replacement for the time being
(and probably used most often, as ADL and free functions are mostly used
inside templates). If the abbreviated parameters are getting into, then
there is certainly gonna be an overlap.
I'm not certain if I can implement the feature to test for edge cases as
I'm still an undergraduate, but if there is any chance of this proposal
being good and making into standard, I'll try my best.
----------------------------------
I was not sure if I should post it as a new proposal or post it here, so I
decided to reply to you first.
--
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.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/fa267cd3-42cd-4fb0-a89b-0e4e4b3b21b6%40isocpp.org.
------=_Part_50621_635745624.1530635943311
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><div>Sorry for bothering you with so badly thought out ide=
a last time.=20
I'm coming back with something that I believe is more grounded and=20
should be more "practical" in terms of usage. It's first time=
for me to=20
participate in such a discussion, but I hope this feature will be a big imp=
rovement.<br></div><div>Here are the points I tried to cover, some of them =
are incomplete:</div><div><br></div><div><ul><li>
Don't break existing code and don't silently change behavior (No: =
but=20
close, requires reserving one new keyword. This is new functionality)</li><=
li>Empower users without being confusing, e.g. simplify the common case and=
allow people with different needs get the power (Yes)</li><li>Play well wi=
th language and standard library<br></li><li>Do not deviate from general C+=
+ syntax and ideas (I believe yes)</li></ul><div>I believe I know what I ac=
tually need: a way to capture and reuse <i>return type and argument types</=
i> of a function. The feature should be usable in many places, including ex=
isting and upcoming standard library functionality.<br></div><div><br></div=
><div style=3D"text-align: center;"><b><font size=3D"4">Definition:</font><=
/b></div><div>Closure
is a way to capture return type and argument types of a function. The=20
closure then can be used to match the callable with the return type and=20
arguments types, or used as alias to create a lambda with the properties
specified by closure. <br></div><div><br></div><div><font size=3D"4"><b>Cl=
osure declaration:</b></font></div><div><span style=3D"font-family: courier=
new, monospace;">closure <i>closure_name</i>(<i>optional-argument-list</i>=
) <i>optional-noexcept optional-mutable</i> -> <i>return_type</i>;</span=
></div><div><i><br></i></div><div>Then,
the closure can be used in multiple ways. First being to be named=20
lambda kind, to imrpove readability and better interoperate with IDEs=20
and tools, as they can give a hint to programmer in the right direction.
Here is the username_validator, which can be used to adjust the set of=20
allowed usernames:</div><div><br></div><div><span style=3D"font-family: cou=
rier new, monospace;">closure username_validator(const std::string& use=
rname) -> bool;</span></div><div><span style=3D"font-family: courier new=
, monospace;"><br></span></div><div><span style=3D"font-family: courier new=
, monospace;">std::copy_if(new_users.begin(), new_users.end(), back_inserte=
r(saved_users), username_validator=C2=A0 {</span></div><div><span style=3D"=
font-family: courier new, monospace;">=C2=A0=C2=A0=C2=A0 return std::all_of=
(username.begin(), username.end(), std::isalpha) //omitted cast to unsigned=
char for brevity<br></span></div><div><span style=3D"font-family: courier =
new, monospace;">});</span><br></div><div><br></div><div>The <i>closure ins=
tantiation</i> above will create a lambda with the return type and argument=
s specified by clojure declaration. As implied by word instantiation, the c=
lojure itself is not a type, but a mere set of constraints that will be app=
lied on a type or be used to create a lambda.=C2=A0 To be usable in generic=
functions, there is template related feature:<br></div><div><br></div><div=
><font size=3D"4"><b>template closure declaration:</b></font><br></div><div=
><span style=3D"font-family: courier new, monospace;">template <<i>templ=
ate-parameter-list</i>></span></div><div><span style=3D"font-family: cou=
rier new, monospace;">closure <i>closure_name</i>(<i>optional-parameter-lis=
t</i>) -> <i>return_type</i>;</span><br></div><div><br></div><div>The sy=
ntax could be changed to one in templates for lambdas proposal. Every templ=
ate argument should be available from inside of the closure in case it is i=
nstantiated. This can be used in many places in standard library:</div><div=
><span style=3D"font-family: courier new, monospace;"><br></span></div><div=
><span style=3D"font-family: courier new, monospace;">template <typename=
T></span></div><div><span style=3D"font-family: courier new, monospace;=
">closure unary_predicate(const T& value) -> bool;</span></div><div>=
<br></div><div>Then, one can use it like this:</div><div><br></div><div><sp=
an style=3D"font-family: courier new, monospace;">std::remove_if(source.beg=
in(), source.end(), dest.begin(), unary_predicate<int> {return value =
% 2 =3D=3D 0;} );</span></div><div><br></div><div>Template arguments are un=
necessary if they cannot be deduced from arguments into the function. In ca=
se of omitting the brackets, closure will produce generic lambda (the one w=
ith templated operator()). To reiterate:</div><div><br></div><div><b>valid:=
</b></div><div><span style=3D"font-family: courier new, monospace;">templat=
e <typename T></span></div><div><span style=3D"font-family: courier n=
ew, monospace;">closure identity(const T& value) -> T; //same as [](=
const T& value) {return value;}</span><br></div><div><br></div><div><b>=
invalid:</b></div><div><span style=3D"font-family: courier new, monospace;"=
>template <typename T, typename U></span></div><div><span style=3D"fo=
nt-family: courier new, monospace;">closure map(const T& value) -> U=
; //U cannot be deduced</span><br></div><div><br></div><div> In case of usi=
ng the brackets, the template will be instantiated and the resulting lambda=
will have definitive argument and return types. Sometimes there might be a=
need to create an alias to a closure, which is handled as well. Here is th=
e syntax:</div><div><br></div><div><font size=3D"4"><b>closure alias declar=
ation:</b></font></div><div><span style=3D"font-family: courier new, monosp=
ace;">using closure <i>closure_name</i>(<i>optional-rename-sequence</i>)<i>=
</i>=3D <i>declared_closure</i>;</span><br></div><div><br></div><div>The r=
ename sequence lets people to redefine the names of the input parameters, w=
hich is a verbose future by design (user can mess up the order), and allows=
programmers to retrofit the initial names to their context. Lets create an=
alias to specialized unary_predicate, and name it username_validator:</div=
><div><br></div><div><span style=3D"font-family: courier new, monospace;">u=
sing closure username_validator(username=3Dvalue) =3D unary_predicate<st=
d::string>;</span></div><div><br></div><div>Either all or no names shoul=
d be renamed. The last missing feature from lambdas is a capture list. It i=
s handled as trailing capture list:</div><div><br></div><div><font size=3D"=
4"><b>closure instantiation</b></font><br></div><div><span style=3D"font-fa=
mily: courier new, monospace;"><i>declared_closure_name</i>[<i>optional-cap=
ture-list</i>](<i>optional-rename-list</i>) <i>optional-noexcept optional-m=
utable</i> { /*<i>optional-code</i>*/}</span><br></div><div><br></div><div>=
One can use it to create a unique ID generator for usernames:</div><div><sp=
an style=3D"font-family: courier new, monospace;"><br></span></div><div><sp=
an style=3D"font-family: courier new, monospace;">closure id_generator(std:=
:string_view username) -> std::size_t;</span></div><div><span style=3D"f=
ont-family: courier new, monospace;"><br></span></div><div><span style=3D"f=
ont-family: courier new, monospace;">using id_storage =3D std::unordered_ma=
p<std::string_view, std::size_t>;</span></div><div><span style=3D"fon=
t-family: courier new, monospace;">auto generator =3D id_generator[generate=
d_ids =3D id_storage{}, counter =3D std::size_t(0)] mutable {</span></div><=
div><span style=3D"font-family: courier new, monospace;">=C2=A0=C2=A0=C2=A0=
auto& id =3D generated_ids[username];=C2=A0=C2=A0=C2=A0 <br></span></d=
iv><div><span style=3D"font-family: courier new, monospace;">=C2=A0=C2=A0=
=C2=A0 if (id =3D=3D 0)</span></div><div><span style=3D"font-family: courie=
r new, monospace;">=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 id =3D counte=
r++;<br></span></div><div><span style=3D"font-family: courier new, monospac=
e;">=C2=A0=C2=A0=C2=A0 return id;<br></span></div><div><span style=3D"font-=
family: courier new, monospace;">}</span></div><div><br></div><div>Closures=
cannot be used as template parameters, because <font size=3D"2">there
is one-to-many relationship between a type and set of closures it=20
matches. Thus, I believe using the syntax below should be both=20
reasonable and flexible. <br></font><div><font size=3D"2"><br></font></div>=
<div><font size=3D"2"><b><font size=3D"4">Constraining template parameter</=
font></b><br></font></div><div><span style=3D"font-family: courier new, mon=
ospace;">template <<i>closure_name parameter_name, ...></i></span></d=
iv><span style=3D"font-family: courier new, monospace;">struct <i>struct_na=
me </i>{};</span></div><div><br></div><div>I'm not sure about the synta=
x of the following feature. It allows users to create a variable with the s=
ame closure as the operand on the right side:</div><div><br></div><div><fon=
t size=3D"4"><b>Closure constrained variable declaration and definition</b>=
</font><br></div><div><span style=3D"font-family: courier new, monospace;">=
<span style=3D"font-family: courier new, monospace;"><i>closure_name </i></=
span>auto<i> variable_name </i>=3D <i>lvalue_or_rvalue</i>;</span></div><di=
v><br></div><div>I thought about instanceof, but it would require one more =
keyword to reserve. With the above, the feature can be used in template par=
ameter list:</div><div><span style=3D"font-family: courier new, monospace;"=
><br></span></div><div><span style=3D"font-family: courier new, monospace;"=
>template <typename It, unary_predicate<It::value_type> Predicate&=
gt; //omitted some stuff for brevity<br></span></div><div><span style=3D"fo=
nt-family: courier new, monospace;">It remove_if(It first, It last, Predica=
te pred);</span></div><div><br></div><div>It should be noted that there is =
a new template parameter silently added to the template. The following will=
match the closure specified above (for iterators referring to integers).</=
div><div><span style=3D"font-family: courier new, monospace;"><br></span></=
div><div><span style=3D"font-family: courier new, monospace;">struct dummy =
{</span></div><div><span style=3D"font-family: courier new, monospace;">=C2=
=A0=C2=A0=C2=A0 bool operator()(int ) { return true; }<br></span></div><div=
><span style=3D"font-family: courier new, monospace;">};</span></div><div><=
br></div><div><font size=3D"4"><b>Reflection</b></font></div><div>One could=
also use the feature to provide introspection for the callable. I've a=
lready=C2=A0 written a lot, but I believe that closure_name::return_type co=
uld be used to inspect return type, and closure_name::parameters could be a=
template parameter pack. The thing is that closure already defeats the nee=
d for the such reflection in the first place. All operations not covered by=
closures I can think of are already handled by existing functionality that=
operate on types.<br></div><div><br></div><div style=3D"text-align: center=
;"><font size=3D"4"><b>How is it different from combination of Concepts and=
lambdas?</b></font></div><div style=3D"text-align: left;"><font size=3D"4"=
><font size=3D"2">Not much<font size=3D"4">, <font size=3D"2">and it is by =
design. closure is a combination of lambda and SFINAE. </font></font>The fe=
ature should simplify most of the common template metaprogramming regarding=
accepting callables. Also it should clarify most of the lambda usage</font=
>.<font size=3D"2">Since abbreviated template parameters didn't make it=
into concepts, this should be conservative replacement for the time being =
(and probably used most often, as ADL and free functions are mostly used in=
side templates). If the abbreviated parameters</font></font> are getting in=
to, then there is certainly gonna be an overlap.</div><div style=3D"text-al=
ign: left;"><br></div><div style=3D"text-align: left;">I'm not certain =
if I can implement the feature to test for edge cases as I'm still an u=
ndergraduate, but if there is any chance of this proposal being good and ma=
king into standard, I'll try my best.<br></div><div style=3D"text-align=
: left;"><br></div><div style=3D"text-align: left;">-----------------------=
-----------</div><div style=3D"text-align: left;">I was not sure if I shoul=
d post it as a new proposal or=C2=A0 post it here, so I decided to reply to=
you first. <br></div></div></div>
<p></p>
-- <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 />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/fa267cd3-42cd-4fb0-a89b-0e4e4b3b21b6%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/fa267cd3-42cd-4fb0-a89b-0e4e4b3b21b6=
%40isocpp.org</a>.<br />
------=_Part_50621_635745624.1530635943311--
------=_Part_50620_2080536637.1530635943311--
.
Author: Magnus Fromreide <magfr@lysator.liu.se>
Date: Wed, 4 Jul 2018 01:06:01 +0200
Raw View
On Tue, Jul 03, 2018 at 09:39:03AM -0700, anonymous.from.applecity@gmail.com wrote:
> Sorry for bothering you with so badly thought out idea last time. I'm
> coming back with something that I believe is more grounded and should be
> more "practical" in terms of usage. It's first time for me to participate
> in such a discussion, but I hope this feature will be a big improvement.
> Here are the points I tried to cover, some of them are incomplete:
>
>
> - Don't break existing code and don't silently change behavior (No: but
> close, requires reserving one new keyword. This is new functionality)
> - Empower users without being confusing, e.g. simplify the common case
> and allow people with different needs get the power (Yes)
You failed. I do get confused by the idea and fail to see it's obvious
greatness.
Please look at a number of other proposals, preferrably successful ones,
and you will see that they generally have a rationale up front that discuss
the problem they are trying to solve.
Why is this a great idea, or even useful?
> *Reflection*
> One could also use the feature to provide introspection for the callable.
> I've already written a lot, but I believe that closure_name::return_type
> could be used to inspect return type, and closure_name::parameters could be
> a template parameter pack. The thing is that closure already defeats the
> need for the such reflection in the first place. All operations not covered
> by closures I can think of are already handled by existing functionality
> that operate on types.
>
> *How is it different from combination of Concepts and lambdas?*
> Not much, and it is by design. closure is a combination of lambda and
> SFINAE. The feature should simplify most of the common template
> metaprogramming regarding accepting callables. Also it should clarify most
> of the lambda usage.Since abbreviated template parameters didn't make it
> into concepts, this should be conservative replacement for the time being
> (and probably used most often, as ADL and free functions are mostly used
> inside templates). If the abbreviated parameters are getting into, then
> there is certainly gonna be an overlap.
In what way does it differ?
What does it enable that isn't possible to do in the language as of today?
(or, what does it make a lot easier? (note that this hill is way steeper!))
> I'm not certain if I can implement the feature to test for edge cases as
> I'm still an undergraduate, but if there is any chance of this proposal
> being good and making into standard, I'll try my best.
>
> ----------------------------------
> I was not sure if I should post it as a new proposal or post it here, so I
> decided to reply to you first.
This is a new feature, completley unrelated to your former idea and so it
should have gotten it's own thread and its own Subject:.
/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.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/20180703230601.GA10975%40noemi.bahnhof.se.
.
Author: Jake Arkinstall <jake.arkinstall@gmail.com>
Date: Wed, 4 Jul 2018 01:01:52 +0100
Raw View
--000000000000135711057021244b
Content-Type: text/plain; charset="UTF-8"
I like what you've put forward here. Capturing the argument and return type
of a function and allowing it to be used in many places is, IMHO, a very
nice idea. WRT your suggested implementation, omitting the parameters is a
bad move. I'd go for:
closure username_validator(const std::string&) -> bool;
Which is almost equivalent to
using username_validator = std::function<bool(const std::string&)>;
But with the benefit of being able to implement it inline:
do_something(begin(usernames), end(usernames),
username_validator(const std::string&
username){ ... });
Or even as a class method:
class A{
username_validator B(const std::string&) const noexcept;
};
Where the return type is implied by the closure and an inconsistent
parameter list would be an error.
Without keeping the parameter names, you introduce possible scope issues
(closures, by definition, may interact with their environment). Besides, if
you want a more general closure you dont want that name to be fixed.
On that note, I don't quite think that closure is the right term here.
Sure, it can be used for closures (in their traditional sense) but I think
it has wider potential where the term wouldn't make sense.
As this is just a new syntax for more clearly specifying something that we
already have, I'm not sure how much support it will gain. But I think it's
elegant enough for some discussion - this current thread is not the place
for it, but if you repost as a new thread it would be beneficial.
--
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.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CAC%2B0CCNrdzmZwR%3Dqmj1DN0ke0ug3rHc3__gcARtr2PuGRaC5sA%40mail.gmail.com.
--000000000000135711057021244b
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable
<div dir=3D"auto"><div>I like what you've put forward here. Capturing t=
he argument and return type of a function and allowing it to be used in man=
y places is, IMHO, a very nice idea. WRT your suggested implementation, omi=
tting the parameters is a bad move. I'd go for:</div><div dir=3D"auto">=
<br></div><div dir=3D"auto"><span style=3D"font-family:"courier new&qu=
ot;,monospace">closure username_validator(const std::string&) -> boo=
l;</span><br><br>Which is almost equivalent to</div><div dir=3D"auto"><br><=
/div><div dir=3D"auto"><span style=3D"font-family:"courier new",m=
onospace">using username_validator =3D std::function<bool(const std::str=
ing&)>;</span><br></div><div dir=3D"auto"><br></div><div dir=3D"auto=
">But with the benefit of being able to implement it inline:</div><div dir=
=3D"auto"><br></div><div dir=3D"auto"><span style=3D"font-family:"cour=
ier new",monospace">do_something(begin(usernames), end(usernames), use=
rname_validator(const=C2=A0</span><span style=3D"font-family:"courier =
new",monospace">std::string& username){ ... });</span></div><div d=
ir=3D"auto"><br></div><div dir=3D"auto">Or even as a class method:</div><di=
v dir=3D"auto"><br></div><div dir=3D"auto"><span style=3D"font-family:"=
;courier new",monospace">class A{</span></div><div dir=3D"auto"><span =
style=3D"font-family:"courier new",monospace">=C2=A0 =C2=A0 usern=
ame_validator B(const std::string&) const noexcept;</span><br></div><di=
v dir=3D"auto"><span style=3D"font-family:"courier new",monospace=
">};</span></div><div dir=3D"auto"><span style=3D"font-family:"courier=
new",monospace"><br></span></div><div dir=3D"auto">Where the return t=
ype is implied by the closure and an inconsistent parameter list would be a=
n error.</div><div dir=3D"auto"><br></div><div dir=3D"auto">Without keeping=
the parameter names, you introduce possible scope issues (closures, by def=
inition, may interact with their environment). Besides, if you want a more =
general closure you dont want that name to be fixed.</div><div dir=3D"auto"=
><br></div><div dir=3D"auto">On that note, I don't quite think that clo=
sure is the right term here. Sure, it can be used for closures (in their tr=
aditional sense) but I think it has wider potential where the term wouldn&#=
39;t make sense.</div><div dir=3D"auto"><br></div><div dir=3D"auto">As this=
is just a new syntax for more clearly specifying something that we already=
have, I'm not sure how much support it will gain. But I think it's=
elegant enough for some discussion - this current thread is not the place =
for it, but if you repost as a new thread it would be beneficial.</div></di=
v>
<p></p>
-- <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 />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/CAC%2B0CCNrdzmZwR%3Dqmj1DN0ke0ug3rHc3=
__gcARtr2PuGRaC5sA%40mail.gmail.com?utm_medium=3Demail&utm_source=3Dfooter"=
>https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CAC%2B0CCNrdz=
mZwR%3Dqmj1DN0ke0ug3rHc3__gcARtr2PuGRaC5sA%40mail.gmail.com</a>.<br />
--000000000000135711057021244b--
.
Author: Nicol Bolas <jmckesson@gmail.com>
Date: Tue, 3 Jul 2018 17:58:44 -0700 (PDT)
Raw View
------=_Part_54116_750793795.1530665924732
Content-Type: multipart/alternative;
boundary="----=_Part_54117_1037293878.1530665924732"
------=_Part_54117_1037293878.1530665924732
Content-Type: text/plain; charset="UTF-8"
On Tuesday, July 3, 2018 at 8:02:07 PM UTC-4, Jake Arkinstall wrote:
>
> As this is just a new syntax for more clearly specifying something that we
> already have, I'm not sure how much support it will gain. But I think it's
> elegant enough for some discussion - this current thread is not the place
> for it, but if you repost as a new thread it would be beneficial.
>
Before you go starting up a new thread, you should realize that what you're
asking for is nothing more than a form of static reflection: the ability to
introspect the current function's (or a given function's) parameter/return
types. And we're already progressing on that front.
--
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.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/e1f4742b-8db7-4c81-9420-246fe0fcfe31%40isocpp.org.
------=_Part_54117_1037293878.1530665924732
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">On Tuesday, July 3, 2018 at 8:02:07 PM UTC-4, Jake Arkinst=
all 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"auto"><d=
iv dir=3D"auto"></div><div dir=3D"auto">As this is just a new syntax for mo=
re clearly specifying something that we already have, I'm not sure how =
much support it will gain. But I think it's elegant enough for some dis=
cussion - this current thread is not the place for it, but if you repost as=
a new thread it would be beneficial.</div></div></blockquote><div><br></di=
v><div>Before you go starting up a new thread, you should realize that what=
you're asking for is nothing more than a form of static reflection: th=
e ability to introspect the current function's (or a given function'=
;s) parameter/return types. And we're already progressing on that front=
..<br></div></div>
<p></p>
-- <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 />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/e1f4742b-8db7-4c81-9420-246fe0fcfe31%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/e1f4742b-8db7-4c81-9420-246fe0fcfe31=
%40isocpp.org</a>.<br />
------=_Part_54117_1037293878.1530665924732--
------=_Part_54116_750793795.1530665924732--
.