Topic: capturing monads in lambda


Author: szollosi.lorand@gmail.com
Date: Wed, 7 Sep 2016 13:36:50 -0700 (PDT)
Raw View
------=_Part_469_756361778.1473280610829
Content-Type: multipart/alternative;
 boundary="----=_Part_470_1097049031.1473280610829"

------=_Part_470_1097049031.1473280610829
Content-Type: text/plain; charset=UTF-8

Hi,

While thinking about for..else, I realized that it (and other language
constructs) could be greatly simplified had we had the chance to capture
monads created by keywords like return, continue, break. Before proposing
any syntax/schematics, I'd first ask you, how would you feel about this
generally. The idea is something like:
[&return, break_=&break, break=...](){...}

Capturing a monad assumes that it is valid to write it in the calling
context.

Note that capture is schematic, i.e., 'return' inside the lambda will
destruct locals/parameters before performing caller's return; same holds
for break and continue.

What do you think?

Thanks,
-lorro

--
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/5dba8d2b-6689-4781-a95a-c94896d98e55%40isocpp.org.

------=_Part_470_1097049031.1473280610829
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">Hi,<br><br>While thinking about for..else, I realized that=
 it (and other language constructs) could be greatly simplified had we had =
the chance to capture monads created by keywords like return, continue, bre=
ak. Before proposing any syntax/schematics, I&#39;d first ask you, how woul=
d you feel about this generally. The idea is something like:<br>[&amp;retur=
n, break_=3D&amp;break, break=3D...](){...}<br><br>Capturing a monad assume=
s that it is valid to write it in the calling context.<br><br>Note that cap=
ture is schematic, i.e., &#39;return&#39; inside the lambda will destruct l=
ocals/parameters before performing caller&#39;s return; same holds for brea=
k and continue.<br><br>What do you think?<br><br>Thanks,<br>-lorro<br></div=
>

<p></p>

-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; 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/5dba8d2b-6689-4781-a95a-c94896d98e55%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/5dba8d2b-6689-4781-a95a-c94896d98e55=
%40isocpp.org</a>.<br />

------=_Part_470_1097049031.1473280610829--

------=_Part_469_756361778.1473280610829--

.


Author: edward.catmur@mavensecurities.com
Date: Wed, 7 Sep 2016 15:00:27 -0700 (PDT)
Raw View
------=_Part_232_87301542.1473285627597
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

On Wednesday, 7 September 2016 21:36:50 UTC+1, szollos...@gmail.com wrote:
>
> Hi,
>
> While thinking about for..else, I realized that it (and other language=20
> constructs) could be greatly simplified had we had the chance to capture=
=20
> monads created by keywords like return, continue, break. Before proposing=
=20
> any syntax/schematics, I'd first ask you, how would you feel about this=
=20
> generally. The idea is something like:
> [&return, break_=3D&break, break=3D...](){...}
>
> Capturing a monad assumes that it is valid to write it in the calling=20
> context.
>
> Note that capture is schematic, i.e., 'return' inside the lambda will=20
> destruct locals/parameters before performing caller's return; same holds=
=20
> for break and continue.
>

I'm assuming that a lambda capturing a control flow keyword has to have=20
return type void.

Still, what would this do?

int f() { auto&& l =3D [&return](int i){ return i; }; (l(5), puts("hello"))=
; }



--=20


This e-mail together with any attachments (the "Message") is confidential=
=20
and may contain privileged information. If you are not the intended=20
recipient or if you have received this e-mail in error, please notify the=
=20
sender immediately and permanently delete this Message from your system.=20
 Do not copy, disclose or distribute the information contained in this=20
Message.

=20

Maven Investment Partners Ltd (No. 07511928), Maven Derivatives Ltd (No.=20
07511840) , MVN Asset Management Limited (No. 09659116), Maven Europe Ltd=
=20
(No. 08966593) & Maven Securities Holding Ltd (No. 07505438) are registered=
=20
as companies in England and Wales and their registered address is Level 3,=
=20
6 Bevis Marks, London EC3A 7BA, United Kingdom. The companies=E2=80=99 VAT =
No. is=20
135539016. Only Maven Derivatives Ltd and MVN Asset Management Limited are=
=20
authorised by the Financial Conduct Authority (Maven Derivatives Ltd FRN:=
=20
607267, MVN Asset Management Limited FRN: 714429)

--=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp=
..org/d/msgid/std-proposals/6b360813-6dfd-484a-8258-3d3d1e41ca6e%40isocpp.or=
g.

------=_Part_232_87301542.1473285627597
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">On Wednesday, 7 September 2016 21:36:50 UTC+1, szollos...@=
gmail.com  wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;margi=
n-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"l=
tr">Hi,<br><br>While thinking about for..else, I realized that it (and othe=
r language constructs) could be greatly simplified had we had the chance to=
 capture monads created by keywords like return, continue, break. Before pr=
oposing any syntax/schematics, I&#39;d first ask you, how would you feel ab=
out this generally. The idea is something like:<br>[&amp;return, break_=3D&=
amp;break, break=3D...](){...}<br><br>Capturing a monad assumes that it is =
valid to write it in the calling context.<br><br>Note that capture is schem=
atic, i.e., &#39;return&#39; inside the lambda will destruct locals/paramet=
ers before performing caller&#39;s return; same holds for break and continu=
e.<br></div></blockquote><div><br></div><div>I&#39;m assuming that a lambda=
 capturing a control flow keyword has to have return type void.</div><div><=
br></div><div>Still, what would this do?</div><div><br></div><div class=3D"=
prettyprint" style=3D"border: 1px solid rgb(187, 187, 187); word-wrap: brea=
k-word; background-color: rgb(250, 250, 250);"><code class=3D"prettyprint">=
<div class=3D"subprettyprint"><span style=3D"color: #008;" class=3D"styled-=
by-prettify">int</span><span style=3D"color: #000;" class=3D"styled-by-pret=
tify"> f</span><span style=3D"color: #660;" class=3D"styled-by-prettify">()=
</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><s=
pan style=3D"color: #660;" class=3D"styled-by-prettify">{</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color=
: #008;" class=3D"styled-by-prettify">auto</span><span style=3D"color: #660=
;" class=3D"styled-by-prettify">&amp;&amp;</span><span style=3D"color: #000=
;" class=3D"styled-by-prettify"> l </span><span style=3D"color: #660;" clas=
s=3D"styled-by-prettify">=3D</span><span style=3D"color: #000;" class=3D"st=
yled-by-prettify"> </span><span style=3D"color: #660;" class=3D"styled-by-p=
rettify">[&amp;</span><span style=3D"color: #008;" class=3D"styled-by-prett=
ify">return</span><span style=3D"color: #660;" class=3D"styled-by-prettify"=
>](</span><span style=3D"color: #008;" class=3D"styled-by-prettify">int</sp=
an><span style=3D"color: #000;" class=3D"styled-by-prettify"> i</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">return</span><span style=3D"color: #0=
00;" class=3D"styled-by-prettify"> i</span><span style=3D"color: #660;" cla=
ss=3D"styled-by-prettify">;</span><span style=3D"color: #000;" class=3D"sty=
led-by-prettify"> </span><span style=3D"color: #660;" class=3D"styled-by-pr=
ettify">};</span><span style=3D"color: #000;" class=3D"styled-by-prettify">=
 </span><span style=3D"color: #660;" class=3D"styled-by-prettify">(</span><=
span style=3D"color: #000;" class=3D"styled-by-prettify">l</span><span styl=
e=3D"color: #660;" class=3D"styled-by-prettify">(</span><span style=3D"colo=
r: #066;" class=3D"styled-by-prettify">5</span><span style=3D"color: #660;"=
 class=3D"styled-by-prettify">),</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"> puts</span><span style=3D"color: #660;" class=3D"s=
tyled-by-prettify">(</span><span style=3D"color: #080;" class=3D"styled-by-=
prettify">&quot;hello&quot;</span><span style=3D"color: #660;" class=3D"sty=
led-by-prettify">));</span><span style=3D"color: #000;" class=3D"styled-by-=
prettify"> </span><span style=3D"color: #660;" class=3D"styled-by-prettify"=
>}</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br></sp=
an></div></code></div><div><br><br></div></div>
<br>
<p><font color=3D"#222222" face=3D"Arial, sans-serif"><span style=3D"font-s=
ize:13px">This e-mail together with any attachments (the &quot;Message&quot=
;) is confidential and may contain privileged information. If you are not t=
he intended recipient or if you have received this e-mail in error, please =
notify the sender immediately and permanently delete this Message from your=
 system. =C2=A0Do not copy, disclose or distribute the information containe=
d in this Message.</span></font></p><p><font color=3D"#222222" face=3D"Aria=
l, sans-serif"><span style=3D"font-size:13px">=C2=A0</span></font></p><p><f=
ont color=3D"#222222" face=3D"Arial, sans-serif"><span style=3D"font-size:1=
3px">Maven Investment Partners Ltd (No. 07511928), Maven Derivatives Ltd (N=
o. 07511840) , MVN Asset Management Limited (No. 09659116), Maven Europe Lt=
d (No. 08966593) &amp; Maven Securities Holding Ltd (No. 07505438) are regi=
stered as companies in England and Wales and their registered address is Le=
vel 3, 6 Bevis Marks, London EC3A 7BA, United Kingdom. The companies=E2=80=
=99 VAT No. is 135539016. Only Maven Derivatives Ltd and MVN Asset Manageme=
nt Limited are authorised by the Financial Conduct Authority (Maven Derivat=
ives Ltd FRN: 607267, MVN Asset Management Limited FRN: 714429)</span></fon=
t></p>

<p></p>

-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; 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/6b360813-6dfd-484a-8258-3d3d1e41ca6e%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/6b360813-6dfd-484a-8258-3d3d1e41ca6e=
%40isocpp.org</a>.<br />

------=_Part_232_87301542.1473285627597--

.


Author: szollosi.lorand@gmail.com
Date: Thu, 8 Sep 2016 11:53:35 -0700 (PDT)
Raw View
------=_Part_476_578492789.1473360815874
Content-Type: multipart/alternative;
 boundary="----=_Part_477_1964656877.1473360815874"

------=_Part_477_1964656877.1473360815874
Content-Type: text/plain; charset=UTF-8

Hi,

> I'm assuming that a lambda capturing a control flow keyword has to have
return type void.
It's actually [[noreturn]] void if you do [&return]; if you do
[return_=&return], then you can return to both points (with potentially
different return types). Note that the lambda drives, by type of value
passed to the given return monad, what context it can be called in (just as
for generic lambdas, where return type is deduced from type passed to
return). Thus it's no more a function or a functor: it's a monad.
Alternatively, you can look at it as a functor having implicit monadic
parameters.
Note that it's *not* the same as throwing an exception. It's valid after
leaving the scope that declares it, i.e., it doesn't capture 'current'
return, but the idea of returning. Simulating this via exceptions would
require every call to be in sg like a try{}catch(return_type r) { return r;
} (not recommended), which is a perfect pessimization.

Re: the function:
int f() {
    auto&& l = [&return](int i){
        return i;
    };
    (l(5), puts("hello"));
}

It's unspecified if it puts hello if that's the question, but it does not
bring nasal demons on you. It returns 5 on f(), so int j = f() is still
valid.

Thanks,
-lorro

--
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/180f2574-22d5-4e6e-81ac-db14ea31d43a%40isocpp.org.

------=_Part_477_1964656877.1473360815874
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">Hi,<br><br>&gt; I&#39;m assuming that a lambda capturing a=
 control flow keyword has to have return type void.<br>It&#39;s actually [[=
noreturn]] void if you do [&amp;return]; if you do [return_=3D&amp;return],=
 then you can return to both points (with potentially different return type=
s). Note that the lambda drives, by type of value passed to the given retur=
n monad, what context it can be called in (just as for generic lambdas, whe=
re return type is deduced from type passed to return). Thus it&#39;s no mor=
e a function or a functor: it&#39;s a monad.<br>Alternatively, you can look=
 at it as a functor having implicit monadic parameters.<br>Note that it&#39=
;s <i>not</i> the same as throwing an exception. It&#39;s valid after leavi=
ng the scope that declares it, i.e., it doesn&#39;t capture &#39;current&#3=
9; return, but the idea of returning. Simulating this via exceptions would =
require every call to be in sg like a try{}catch(return_type r) { return r;=
 } (not recommended), which is a perfect pessimization.<br><br>Re: the func=
tion:<br><div style=3D"border:1px solid rgb(187,187,187);word-wrap:break-wo=
rd;background-color:rgb(250,250,250)"><code><div><span style=3D"color:#008"=
>int</span><span style=3D"color:#000"> f</span><span style=3D"color:#660">(=
)</span><span style=3D"color:#000"> </span><span style=3D"color:#660">{</sp=
an><span style=3D"color:#000"><br>=C2=A0=C2=A0=C2=A0 </span><span style=3D"=
color:#008">auto</span><span style=3D"color:#660">&amp;&amp;</span><span st=
yle=3D"color:#000"> l </span><span style=3D"color:#660">=3D</span><span sty=
le=3D"color:#000"> </span><span style=3D"color:#660">[&amp;</span><span sty=
le=3D"color:#008">return</span><span style=3D"color:#660">](</span><span st=
yle=3D"color:#008">int</span><span style=3D"color:#000"> i</span><span styl=
e=3D"color:#660">){</span><span style=3D"color:#000"><br>=C2=A0=C2=A0=C2=A0=
=C2=A0=C2=A0=C2=A0=C2=A0 </span><span style=3D"color:#008">return</span><sp=
an style=3D"color:#000"> i</span><span style=3D"color:#660">;</span><span s=
tyle=3D"color:#000"><br>=C2=A0=C2=A0=C2=A0 </span><span style=3D"color:#660=
">};</span><span style=3D"color:#000"><br>=C2=A0=C2=A0=C2=A0 </span><span s=
tyle=3D"color:#660">(</span><span style=3D"color:#000">l</span><span style=
=3D"color:#660">(</span><span style=3D"color:#066">5</span><span style=3D"c=
olor:#660">),</span><span style=3D"color:#000"> puts</span><span style=3D"c=
olor:#660">(</span><span style=3D"color:#080">&quot;hello&quot;</span><span=
 style=3D"color:#660">));</span><span style=3D"color:#000"><br></span><span=
 style=3D"color:#660">}</span><span style=3D"color:#000"><br></span></div><=
/code></div><br>It&#39;s unspecified if it puts hello if that&#39;s the que=
stion, but it does not bring nasal demons on you. It returns 5 on f(), so i=
nt j =3D f() is still valid.<br><br>Thanks,<br>-lorro<div dir=3D"ltr"><div>=
<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&quot; 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/180f2574-22d5-4e6e-81ac-db14ea31d43a%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/180f2574-22d5-4e6e-81ac-db14ea31d43a=
%40isocpp.org</a>.<br />

------=_Part_477_1964656877.1473360815874--

------=_Part_476_578492789.1473360815874--

.


Author: Edward Catmur <ed@catmur.co.uk>
Date: Thu, 8 Sep 2016 17:06:10 -0700 (PDT)
Raw View
------=_Part_4253_1201978422.1473379570554
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

On Thursday, 8 September 2016 19:53:36 UTC+1, szollos...@gmail.com  wrote:
> Hi,
>=20
> > I'm assuming that a lambda capturing a control flow keyword has to have=
 return type void.
> It's actually [[noreturn]] void if you do [&return]; if you do [return_=
=3D&return], then you can return to both points (with potentially different=
 return types). Note that the lambda drives, by type of value passed to the=
 given return monad, what context it can be called in (just as for generic =
lambdas, where return type is deduced from type passed to return). Thus it'=
s no more a function or a functor: it's a monad.
> Alternatively, you can look at it as a functor having implicit monadic pa=
rameters.
> Note that it's not the same as throwing an exception. It's valid after le=
aving the scope that declares it, i.e., it doesn't capture 'current' return=
, but the idea of returning. Simulating this via exceptions would require e=
very call to be in sg like a try{}catch(return_type r) { return r; } (not r=
ecommended), which is a perfect pessimization.

But it does unwind the stack like throwing an exception, right? So it can u=
nwind multiple stack frames (as long as they're within the original capture=
 point) and unwind temporaries within expressions around stack nesting poin=
ts for function calls.=20

Do you have an example showing how it could be useful with the algorithms l=
ibrary e.g. for early return from accumulate?

--=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp=
..org/d/msgid/std-proposals/0ff49606-b5f9-4416-94ba-c8841e49bd12%40isocpp.or=
g.

------=_Part_4253_1201978422.1473379570554--

.


Author: Nicol Bolas <jmckesson@gmail.com>
Date: Thu, 8 Sep 2016 20:39:41 -0700 (PDT)
Raw View
------=_Part_1584_151368949.1473392381985
Content-Type: multipart/alternative;
 boundary="----=_Part_1585_986849886.1473392381986"

------=_Part_1585_986849886.1473392381986
Content-Type: text/plain; charset=UTF-8

On Wednesday, September 7, 2016 at 4:36:50 PM UTC-4, szollos...@gmail.com
wrote:
>
> Hi,
>
> While thinking about for..else, I realized that it (and other language
> constructs) could be greatly simplified had we had the chance to capture
> monads created by keywords like return, continue, break. Before proposing
> any syntax/schematics, I'd first ask you, how would you feel about this
> generally. The idea is something like:
> [&return, break_=&break, break=...](){...}
>
> Capturing a monad assumes that it is valid to write it in the calling
> context.
>
> Note that capture is schematic, i.e., 'return' inside the lambda will
> destruct locals/parameters before performing caller's return; same holds
> for break and continue.
>
> What do you think?
>

I think that I don't really understand what it's supposed to do.

My elementary-school understanding of "monad" comes entirely from skimming
Eric Lippert's series on them <https://ericlippert.com/category/monads/>.
And I'm not sure how "keywords like return, continue, break" constitute
monads, nor do I understand what it means to "capture" them.

Can you explain what this feature is supposed to do in more basic terms of
what it will do?

--
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/2110a7c6-2b24-4d10-8bb3-0c022ae89849%40isocpp.org.

------=_Part_1585_986849886.1473392381986
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">On Wednesday, September 7, 2016 at 4:36:50 PM UTC-4, szoll=
os...@gmail.com wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;=
margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=
=3D"ltr">Hi,<br><br>While thinking about for..else, I realized that it (and=
 other language constructs) could be greatly simplified had we had the chan=
ce to capture monads created by keywords like return, continue, break. Befo=
re proposing any syntax/schematics, I&#39;d first ask you, how would you fe=
el about this generally. The idea is something like:<br>[&amp;return, break=
_=3D&amp;break, break=3D...](){...}<br><br>Capturing a monad assumes that i=
t is valid to write it in the calling context.<br><br>Note that capture is =
schematic, i.e., &#39;return&#39; inside the lambda will destruct locals/pa=
rameters before performing caller&#39;s return; same holds for break and co=
ntinue.<br><br>What do you think?<br></div></blockquote><div><br>I think th=
at I don&#39;t really understand what it&#39;s supposed to do.<br><br>My el=
ementary-school understanding of &quot;monad&quot; comes entirely from <a h=
ref=3D"https://ericlippert.com/category/monads/">skimming Eric Lippert&#39;=
s series on them</a>. And I&#39;m not sure how &quot;keywords like return, =
continue, break&quot; constitute monads, nor do I understand what it means =
to &quot;capture&quot; them.<br><br>Can you explain what this feature is su=
pposed to do in more basic terms of what it will do?<br></div></div>

<p></p>

-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; 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/2110a7c6-2b24-4d10-8bb3-0c022ae89849%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/2110a7c6-2b24-4d10-8bb3-0c022ae89849=
%40isocpp.org</a>.<br />

------=_Part_1585_986849886.1473392381986--

------=_Part_1584_151368949.1473392381985--

.


Author: szollosi.lorand@gmail.com
Date: Fri, 9 Sep 2016 15:32:25 -0700 (PDT)
Raw View
------=_Part_3187_1429392093.1473460345176
Content-Type: multipart/alternative;
 boundary="----=_Part_3188_1536850988.1473460345177"

------=_Part_3188_1536850988.1473460345177
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

Hi,

Let's put aside calling them monads for a while, we'll return to that=20
later. First some examples:

1. Error codes when you have no exceptions (due to embedded system /=20
manager's wisdom / using vast amount of C libraries that return error=20
codes). Here we assume that bool(ErrorCode) =3D=3D true iff there was an er=
ror.

ErrorCode save()
{
    // note that default exit is not the same as return here
    auto return_if =3D [&return](auto retval){
        if (retval) { return retval; }
    };

    return_if(openFile());
    return_if(saveData());
    return_if(closeFile());
}



2. This can be generalized to std::variant<ReturnType, ErrorCode>.

std::variant<Record, ErrorCode> load()
{
    auto pass_error =3D [error =3D &return](auto ret){
        // error looks like a [[noreturn]] function here
        if (ret.index())
            error(std::get<ErrorCode>(ret));

        return std::get<0>(ret);
    };
    auto head =3D pass_error(loadHead());
    auto tail =3D pass_error(loadTail());
    return head + tail;
}



3. For the case of looping. Yes, I know this could be optimized.

for (auto&& elem : myVector)
{
    auto onBreak =3D [&break](){ std::cout << "Match: " << elem; break; }

    if( isPrime(elem) )
        onBreak();
    // ....
    if( isSquare(elem) )
        onBreak();

    // not sure if we want to allow this:
    //[&, break =3D &onBreak]{
    //    if( isFibonacci(elem) )
    //        break;
    //}();
}



4. For many people want to break and continue n times from a nested loop.

for (auto&& person : people)
{
    auto break_twice =3D [&break]{ break; }
    for (auto&& phone : person.phones)
    {
        if (isLandline(phone))
        {
            std::cout << person.name << " " << phone
                      << " still uses landline, do not switch it off!"
                      << std::endl;
            break_twice();
        }
    }
}


5. And, while we cannot have range for else with this, we can simulate it=
=20
like: (note the difference between capture by reference and by value)

template<typename Range, typename Body, typename Else>
void for_or(const Range& r, const Body& b, Else e)
{
    auto&& it    =3D r.begin();
    auto&& itEnd =3D r.end();
    if (it !=3D itEnd)
    {
        do
        {
            b(*it);
        } while (++it !=3D itEnd);
    }
    else
    {
        e();
    }
}

template<typename CPlugin>
bool initPlugins(const CPlugin& plugins)
{
    for_or(plugins, [=3Dreturn, &break, &continue, &](const Plugin& plugin)=
 {
        // this means we have initPlugin's return and calling point's=20
break, continue
        if (!plugin.requires_init())
            continue;
        if (!plugin.init())
            return false;
    }, [&return] {
        return DefaultPlugin::initialize();
    }
    return true;
}



-----

And now, the 'monadic benefits' :). You have seen that this essentially=20
superior to for-else *and* for-break *and* break(n), albeit with a clumsy=
=20
syntax. Which you can make a macro for.
Also, you might think of `{ ... }` code blocks as `[=3Dreturn, &break,=20
&continue, &]{ ... }();`, add `this` if defined. The benefit of this is=20
that now `if .. [else]`, `for`, `do .. while`, `while`, etc. are all=20
monads, working on a lambda (e.g. a for-loop lifts *T -> void* to *Range<T>=
=20
-> void* and calls it). This introduces the syntax `(type var : rval)` that=
=20
passes rval to the monad on the left *and *is the parameter declaration of=
=20
a lambda being declared in-place. If we now allow user-defined monads, we=
=20
can have `for_or(auto&& x : v) { ... } for_else { ... }`. If we allow=20
decoupling of `(type var : rval)`, we have the `for` monad in C+: `auto=20
initAll =3D for (auto&& x) { x.init(); }; initAll(plugins.queue());`. These=
=20
two ifs are strictly optional :).

Thanks,
-lorro

2016. szeptember 9., p=C3=A9ntek 5:39:42 UTC+2 id=C5=91pontban Nicol Bolas =
a=20
k=C3=B6vetkez=C5=91t =C3=ADrta:
>
> On Wednesday, September 7, 2016 at 4:36:50 PM UTC-4, szollos...@gmail.com=
=20
> wrote:
>>
>> Hi,
>>
>> While thinking about for..else, I realized that it (and other language=
=20
>> constructs) could be greatly simplified had we had the chance to capture=
=20
>> monads created by keywords like return, continue, break. Before proposin=
g=20
>> any syntax/schematics, I'd first ask you, how would you feel about this=
=20
>> generally. The idea is something like:
>> [&return, break_=3D&break, break=3D...](){...}
>>
>> Capturing a monad assumes that it is valid to write it in the calling=20
>> context.
>>
>> Note that capture is schematic, i.e., 'return' inside the lambda will=20
>> destruct locals/parameters before performing caller's return; same holds=
=20
>> for break and continue.
>>
>> What do you think?
>>
>
> I think that I don't really understand what it's supposed to do.
>
> My elementary-school understanding of "monad" comes entirely from skimmin=
g=20
> Eric Lippert's series on them <https://ericlippert.com/category/monads/>.=
=20
> And I'm not sure how "keywords like return, continue, break" constitute=
=20
> monads, nor do I understand what it means to "capture" them.
>
> Can you explain what this feature is supposed to do in more basic terms o=
f=20
> what it will do?
>

--=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp=
..org/d/msgid/std-proposals/973a28d5-552f-418a-9495-5a463ea61df4%40isocpp.or=
g.

------=_Part_3188_1536850988.1473460345177
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">Hi,<br><br>Let&#39;s put aside calling them monads for a w=
hile, we&#39;ll return to that later. First some examples:<br><br>1. Error =
codes when you have no exceptions (due to embedded system / manager&#39;s w=
isdom / using vast amount of C libraries that return error codes). Here we =
assume that bool(ErrorCode) =3D=3D true iff there was an error.<br><br><div=
 class=3D"prettyprint" style=3D"background-color: rgb(250, 250, 250); borde=
r-color: rgb(187, 187, 187); border-style: solid; border-width: 1px; word-w=
rap: break-word;"><code class=3D"prettyprint"><div class=3D"subprettyprint"=
><span style=3D"color: #606;" class=3D"styled-by-prettify">ErrorCode</span>=
<span style=3D"color: #000;" class=3D"styled-by-prettify"> save</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"co=
lor: #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"col=
or: #800;" class=3D"styled-by-prettify">// note that default exit is not th=
e same as return here</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">auto</span><span style=3D"color: #000;" class=3D"styled-=
by-prettify"> return_if </span><span style=3D"color: #660;" class=3D"styled=
-by-prettify">=3D</span><span style=3D"color: #000;" class=3D"styled-by-pre=
ttify"> </span><span style=3D"color: #660;" class=3D"styled-by-prettify">[&=
amp;</span><span style=3D"color: #008;" class=3D"styled-by-prettify">return=
</span><span style=3D"color: #660;" class=3D"styled-by-prettify">](</span><=
span style=3D"color: #008;" class=3D"styled-by-prettify">auto</span><span s=
tyle=3D"color: #000;" class=3D"styled-by-prettify"> retval</span><span styl=
e=3D"color: #660;" class=3D"styled-by-prettify">){</span><span style=3D"col=
or: #000;" class=3D"styled-by-prettify"><br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 </s=
pan><span style=3D"color: #008;" class=3D"styled-by-prettify">if</span><spa=
n 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">retval</span><span style=3D"color: #6=
60;" class=3D"styled-by-prettify">)</span><span style=3D"color: #000;" clas=
s=3D"styled-by-prettify"> </span><span style=3D"color: #660;" class=3D"styl=
ed-by-prettify">{</span><span style=3D"color: #000;" class=3D"styled-by-pre=
ttify"> </span><span style=3D"color: #008;" class=3D"styled-by-prettify">re=
turn</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> retva=
l</span><span style=3D"color: #660;" class=3D"styled-by-prettify">;</span><=
span style=3D"color: #000;" class=3D"styled-by-prettify"> </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: #660;" class=3D"styled-by-prettify">};</span><span style=3D"colo=
r: #000;" class=3D"styled-by-prettify"><br><br>=C2=A0 =C2=A0 return_if</spa=
n><span style=3D"color: #660;" class=3D"styled-by-prettify">(</span><span s=
tyle=3D"color: #000;" class=3D"styled-by-prettify">openFile</span><span sty=
le=3D"color: #660;" class=3D"styled-by-prettify">());</span><span style=3D"=
color: #000;" class=3D"styled-by-prettify"><br>=C2=A0 =C2=A0 return_if</spa=
n><span style=3D"color: #660;" class=3D"styled-by-prettify">(</span><span s=
tyle=3D"color: #000;" class=3D"styled-by-prettify">saveData</span><span sty=
le=3D"color: #660;" class=3D"styled-by-prettify">());</span><span style=3D"=
color: #000;" class=3D"styled-by-prettify"><br>=C2=A0 =C2=A0 return_if</spa=
n><span style=3D"color: #660;" class=3D"styled-by-prettify">(</span><span s=
tyle=3D"color: #000;" class=3D"styled-by-prettify">closeFile</span><span st=
yle=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><br><br><b=
r>2. This can be generalized to std::variant&lt;ReturnType, ErrorCode&gt;.<=
br><br><div class=3D"prettyprint" style=3D"background-color: rgb(250, 250, =
250); border-color: rgb(187, 187, 187); border-style: solid; border-width: =
1px; word-wrap: break-word;"><code class=3D"prettyprint"><div class=3D"subp=
rettyprint"><span style=3D"color: #000;" class=3D"styled-by-prettify">std</=
span><span style=3D"color: #660;" class=3D"styled-by-prettify">::</span><sp=
an style=3D"color: #000;" class=3D"styled-by-prettify">variant</span><span =
style=3D"color: #660;" class=3D"styled-by-prettify">&lt;</span><span style=
=3D"color: #606;" class=3D"styled-by-prettify">Record</span><span style=3D"=
color: #660;" class=3D"styled-by-prettify">,</span><span style=3D"color: #0=
00;" class=3D"styled-by-prettify"> </span><span style=3D"color: #606;" clas=
s=3D"styled-by-prettify">ErrorCode</span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">&gt;</span><span style=3D"color: #000;" class=3D"st=
yled-by-prettify"> load</span><span style=3D"color: #660;" class=3D"styled-=
by-prettify">()</span><span style=3D"color: #000;" class=3D"styled-by-prett=
ify"><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=
 =C2=A0 </span><span style=3D"color: #008;" class=3D"styled-by-prettify">au=
to</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> pass_er=
ror </span><span style=3D"color: #660;" class=3D"styled-by-prettify">=3D</s=
pan><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">error </span><span style=3D"col=
or: #660;" class=3D"styled-by-prettify">=3D</span><span style=3D"color: #00=
0;" class=3D"styled-by-prettify"> </span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">&amp;</span><span style=3D"color: #008;" class=3D"s=
tyled-by-prettify">return</span><span style=3D"color: #660;" class=3D"style=
d-by-prettify">](</span><span style=3D"color: #008;" class=3D"styled-by-pre=
ttify">auto</span><span style=3D"color: #000;" class=3D"styled-by-prettify"=
> ret</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 =C2=A0 =C2=A0 </span><span style=3D"color: #800;" class=3D"styled-by=
-prettify">// error looks like a [[noreturn]] function here</span><span sty=
le=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">if<=
/span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><sp=
an style=3D"color: #660;" class=3D"styled-by-prettify">(</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify">ret</span><span style=3D"col=
or: #660;" class=3D"styled-by-prettify">.</span><span style=3D"color: #000;=
" class=3D"styled-by-prettify">index</span><span style=3D"color: #660;" cla=
ss=3D"styled-by-prettify">())</span><span style=3D"color: #000;" class=3D"s=
tyled-by-prettify"><br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 error</spa=
n><span style=3D"color: #660;" class=3D"styled-by-prettify">(</span><span s=
tyle=3D"color: #000;" class=3D"styled-by-prettify">std</span><span style=3D=
"color: #660;" class=3D"styled-by-prettify">::</span><span style=3D"color: =
#008;" class=3D"styled-by-prettify">get</span><span style=3D"color: #660;" =
class=3D"styled-by-prettify">&lt;</span><span style=3D"color: #606;" class=
=3D"styled-by-prettify">ErrorCode</span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">&gt;(</span><span style=3D"color: #000;" class=3D"s=
tyled-by-prettify">ret</span><span style=3D"color: #660;" class=3D"styled-b=
y-prettify">));</span><span style=3D"color: #000;" class=3D"styled-by-prett=
ify"><br><br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 </span><span style=3D"color: #008;=
" class=3D"styled-by-prettify">return</span><span style=3D"color: #000;" cl=
ass=3D"styled-by-prettify"> std</span><span style=3D"color: #660;" class=3D=
"styled-by-prettify">::</span><span style=3D"color: #008;" class=3D"styled-=
by-prettify">get</span><span style=3D"color: #660;" class=3D"styled-by-pret=
tify">&lt;</span><span style=3D"color: #066;" class=3D"styled-by-prettify">=
0</span><span style=3D"color: #660;" class=3D"styled-by-prettify">&gt;(</sp=
an><span style=3D"color: #000;" class=3D"styled-by-prettify">ret</span><spa=
n 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><sp=
an 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><sp=
an style=3D"color: #008;" class=3D"styled-by-prettify">auto</span><span sty=
le=3D"color: #000;" class=3D"styled-by-prettify"> head </span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">=3D</span><span style=3D"col=
or: #000;" class=3D"styled-by-prettify"> pass_error</span><span style=3D"co=
lor: #660;" class=3D"styled-by-prettify">(</span><span style=3D"color: #000=
;" class=3D"styled-by-prettify">loadHead</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;" cla=
ss=3D"styled-by-prettify"> tail </span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">=3D</span><span style=3D"color: #000;" class=3D"sty=
led-by-prettify"> pass_error</span><span style=3D"color: #660;" class=3D"st=
yled-by-prettify">(</span><span style=3D"color: #000;" class=3D"styled-by-p=
rettify">loadTail</span><span style=3D"color: #660;" class=3D"styled-by-pre=
ttify">());</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-p=
rettify">return</span><span style=3D"color: #000;" class=3D"styled-by-prett=
ify"> head </span><span style=3D"color: #660;" class=3D"styled-by-prettify"=
>+</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> tail</s=
pan><span style=3D"color: #660;" class=3D"styled-by-prettify">;</span><span=
 style=3D"color: #000;" class=3D"styled-by-prettify"><br></span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">}</span><span style=3D"color=
: #000;" class=3D"styled-by-prettify"><br><br></span></div></code></div><br=
><br>3. For the case of looping. Yes, I know this could be optimized.<br><b=
r><div class=3D"prettyprint" style=3D"background-color: rgb(250, 250, 250);=
 border-color: rgb(187, 187, 187); border-style: solid; border-width: 1px; =
word-wrap: break-word;"><code class=3D"prettyprint"><div class=3D"subpretty=
print"><span style=3D"color: #008;" class=3D"styled-by-prettify">for</span>=
<span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span sty=
le=3D"color: #660;" class=3D"styled-by-prettify">(</span><span style=3D"col=
or: #008;" class=3D"styled-by-prettify">auto</span><span style=3D"color: #6=
60;" class=3D"styled-by-prettify">&amp;&amp;</span><span style=3D"color: #0=
00;" class=3D"styled-by-prettify"> elem </span><span style=3D"color: #660;"=
 class=3D"styled-by-prettify">:</span><span style=3D"color: #000;" class=3D=
"styled-by-prettify"> myVector</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-prett=
ify">{</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-pretti=
fy">auto</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> o=
nBreak </span><span style=3D"color: #660;" class=3D"styled-by-prettify">=3D=
</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><s=
pan style=3D"color: #660;" class=3D"styled-by-prettify">[&amp;</span><span =
style=3D"color: #008;" class=3D"styled-by-prettify">break</span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">](){</span><span style=3D"co=
lor: #000;" class=3D"styled-by-prettify"> std</span><span style=3D"color: #=
660;" class=3D"styled-by-prettify">::</span><span style=3D"color: #000;" cl=
ass=3D"styled-by-prettify">cout </span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">&lt;&lt;</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"> </span><span style=3D"color: #080;" class=3D"style=
d-by-prettify">&quot;Match: &quot;</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"> </span><span style=3D"color: #660;" class=3D"style=
d-by-prettify">&lt;&lt;</span><span style=3D"color: #000;" class=3D"styled-=
by-prettify"> elem</span><span style=3D"color: #660;" class=3D"styled-by-pr=
ettify">;</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> =
</span><span style=3D"color: #008;" class=3D"styled-by-prettify">break</spa=
n><span style=3D"color: #660;" class=3D"styled-by-prettify">;</span><span s=
tyle=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"c=
olor: #660;" class=3D"styled-by-prettify">}</span><span style=3D"color: #00=
0;" class=3D"styled-by-prettify"><br><br>=C2=A0 =C2=A0 </span><span style=
=3D"color: #008;" class=3D"styled-by-prettify">if</span><span style=3D"colo=
r: #660;" class=3D"styled-by-prettify">(</span><span style=3D"color: #000;"=
 class=3D"styled-by-prettify"> isPrime</span><span style=3D"color: #660;" c=
lass=3D"styled-by-prettify">(</span><span style=3D"color: #000;" class=3D"s=
tyled-by-prettify">elem</span><span style=3D"color: #660;" class=3D"styled-=
by-prettify">)</span><span style=3D"color: #000;" class=3D"styled-by-pretti=
fy"> </span><span style=3D"color: #660;" class=3D"styled-by-prettify">)</sp=
an><span style=3D"color: #000;" class=3D"styled-by-prettify"><br>=C2=A0 =C2=
=A0 =C2=A0 =C2=A0 onBreak</span><span style=3D"color: #660;" class=3D"style=
d-by-prettify">();</span><span style=3D"color: #000;" class=3D"styled-by-pr=
ettify"><br>=C2=A0 =C2=A0 </span><span style=3D"color: #800;" class=3D"styl=
ed-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">if</span><span style=3D"color: #660;" class=3D"styled-=
by-prettify">(</span><span style=3D"color: #000;" class=3D"styled-by-pretti=
fy"> isSquare</span><span style=3D"color: #660;" class=3D"styled-by-prettif=
y">(</span><span style=3D"color: #000;" class=3D"styled-by-prettify">elem</=
span><span style=3D"color: #660;" class=3D"styled-by-prettify">)</span><spa=
n style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">)</span><span style=3D"color=
: #000;" class=3D"styled-by-prettify"><br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 onBre=
ak</span><span style=3D"color: #660;" class=3D"styled-by-prettify">();</spa=
n><span style=3D"color: #000;" class=3D"styled-by-prettify"><br><br>=C2=A0 =
=C2=A0 </span><span style=3D"color: #800;" class=3D"styled-by-prettify">// =
not sure if we want to allow this:</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"><br>=C2=A0 =C2=A0 </span><span style=3D"color: #800=
;" class=3D"styled-by-prettify">//[&amp;, break =3D &amp;onBreak]{</span><s=
pan style=3D"color: #000;" class=3D"styled-by-prettify"><br>=C2=A0 =C2=A0 <=
/span><span style=3D"color: #800;" class=3D"styled-by-prettify">// =C2=A0 =
=C2=A0if( isFibonacci(elem) )</span><span style=3D"color: #000;" class=3D"s=
tyled-by-prettify"><br>=C2=A0 =C2=A0 </span><span style=3D"color: #800;" cl=
ass=3D"styled-by-prettify">// =C2=A0 =C2=A0 =C2=A0 =C2=A0break;</span><span=
 style=3D"color: #000;" class=3D"styled-by-prettify"><br>=C2=A0 =C2=A0 </sp=
an><span style=3D"color: #800;" class=3D"styled-by-prettify">//}();</span><=
span style=3D"color: #000;" class=3D"styled-by-prettify"><br></span><span s=
tyle=3D"color: #660;" class=3D"styled-by-prettify">}</span><span style=3D"c=
olor: #000;" class=3D"styled-by-prettify"><br><br></span></div></code></div=
><br><br>4. For many people want to break and continue n times from a neste=
d loop.<br><br><div class=3D"prettyprint" style=3D"background-color: rgb(25=
0, 250, 250); border-color: rgb(187, 187, 187); border-style: solid; border=
-width: 1px; word-wrap: break-word;"><code class=3D"prettyprint"><div class=
=3D"subprettyprint"><span style=3D"color: #008;" class=3D"styled-by-prettif=
y">for</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </s=
pan><span style=3D"color: #660;" class=3D"styled-by-prettify">(</span><span=
 style=3D"color: #008;" class=3D"styled-by-prettify">auto</span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">&amp;&amp;</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"> person </span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">:</span><span style=3D"color=
: #000;" class=3D"styled-by-prettify"> people</span><span style=3D"color: #=
660;" class=3D"styled-by-prettify">)</span><span style=3D"color: #000;" cla=
ss=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 =C2=A0 </span><span style=3D"color: #008;" class=3D"s=
tyled-by-prettify">auto</span><span style=3D"color: #000;" class=3D"styled-=
by-prettify"> break_twice </span><span style=3D"color: #660;" class=3D"styl=
ed-by-prettify">=3D</span><span style=3D"color: #000;" class=3D"styled-by-p=
rettify"> </span><span style=3D"color: #660;" class=3D"styled-by-prettify">=
[&amp;</span><span style=3D"color: #008;" class=3D"styled-by-prettify">brea=
k</span><span style=3D"color: #660;" class=3D"styled-by-prettify">]{</span>=
<span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span sty=
le=3D"color: #008;" class=3D"styled-by-prettify">break</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"sty=
led-by-prettify"><br>=C2=A0 =C2=A0 </span><span style=3D"color: #008;" clas=
s=3D"styled-by-prettify">for</span><span style=3D"color: #000;" class=3D"st=
yled-by-prettify"> </span><span style=3D"color: #660;" class=3D"styled-by-p=
rettify">(</span><span style=3D"color: #008;" class=3D"styled-by-prettify">=
auto</span><span style=3D"color: #660;" class=3D"styled-by-prettify">&amp;&=
amp;</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> phone=
 </span><span style=3D"color: #660;" class=3D"styled-by-prettify">:</span><=
span style=3D"color: #000;" class=3D"styled-by-prettify"> person</span><spa=
n style=3D"color: #660;" class=3D"styled-by-prettify">.</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify">phones</span><span style=3D"=
color: #660;" class=3D"styled-by-prettify">)</span><span style=3D"color: #0=
00;" class=3D"styled-by-prettify"><br>=C2=A0 =C2=A0 </span><span style=3D"c=
olor: #660;" class=3D"styled-by-prettify">{</span><span style=3D"color: #00=
0;" class=3D"styled-by-prettify"><br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 </span><sp=
an style=3D"color: #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"styled-by-prettify">isLandline</span><span style=3D"color: #660;" =
class=3D"styled-by-prettify">(</span><span style=3D"color: #000;" class=3D"=
styled-by-prettify">phone</span><span style=3D"color: #660;" class=3D"style=
d-by-prettify">))</span><span style=3D"color: #000;" class=3D"styled-by-pre=
ttify"><br>=C2=A0 =C2=A0 =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 =C2=A0 =C2=A0 =C2=A0 =C2=A0 std</span=
><span style=3D"color: #660;" class=3D"styled-by-prettify">::</span><span s=
tyle=3D"color: #000;" class=3D"styled-by-prettify">cout </span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">&lt;&lt;</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"> person</span><span style=3D=
"color: #660;" class=3D"styled-by-prettify">.</span><span style=3D"color: #=
000;" class=3D"styled-by-prettify">name </span><span style=3D"color: #660;"=
 class=3D"styled-by-prettify">&lt;&lt;</span><span style=3D"color: #000;" c=
lass=3D"styled-by-prettify"> </span><span style=3D"color: #080;" class=3D"s=
tyled-by-prettify">&quot; &quot;</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"> </span><span style=3D"color: #660;" class=3D"style=
d-by-prettify">&lt;&lt;</span><span style=3D"color: #000;" class=3D"styled-=
by-prettify"> phone<br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=
=A0 =C2=A0 =C2=A0 =C2=A0 </span><span style=3D"color: #660;" class=3D"style=
d-by-prettify">&lt;&lt;</span><span style=3D"color: #000;" class=3D"styled-=
by-prettify"> </span><span style=3D"color: #080;" class=3D"styled-by-pretti=
fy">&quot; still uses landline, do not switch it off!&quot;</span><span sty=
le=3D"color: #000;" class=3D"styled-by-prettify"><br>=C2=A0 =C2=A0 =C2=A0 =
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 </span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">&lt;&lt;</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"> std</span><span style=3D"co=
lor: #660;" class=3D"styled-by-prettify">::</span><span style=3D"color: #00=
0;" class=3D"styled-by-prettify">endl</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 =C2=A0 =C2=A0 break_twice=
</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: #660;" class=3D"styled-by-prett=
ify">}</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-pretti=
fy">}</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br><=
/span><span style=3D"color: #660;" class=3D"styled-by-prettify">}</span><sp=
an style=3D"color: #000;" class=3D"styled-by-prettify"><br><br></span></div=
></code></div><br>5. And, while we cannot have range for else with this, we=
 can simulate it like: (note the difference between capture by reference an=
d by value)<br><br><div class=3D"prettyprint" style=3D"background-color: rg=
b(250, 250, 250); border-color: rgb(187, 187, 187); border-style: solid; bo=
rder-width: 1px; word-wrap: break-word;"><code class=3D"prettyprint"><div c=
lass=3D"subprettyprint"><span style=3D"color: #008;" class=3D"styled-by-pre=
ttify">template</span><span style=3D"color: #660;" class=3D"styled-by-prett=
ify">&lt;</span><span style=3D"color: #008;" class=3D"styled-by-prettify">t=
ypename</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </=
span><span style=3D"color: #606;" class=3D"styled-by-prettify">Range</span>=
<span style=3D"color: #660;" class=3D"styled-by-prettify">,</span><span sty=
le=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"col=
or: #008;" class=3D"styled-by-prettify">typename</span><span style=3D"color=
: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #606;" =
class=3D"styled-by-prettify">Body</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">typename</span><span style=3D"color: #000;" class=3D"styled-by-pretti=
fy"> </span><span style=3D"color: #606;" class=3D"styled-by-prettify">Else<=
/span><span style=3D"color: #660;" class=3D"styled-by-prettify">&gt;</span>=
<span style=3D"color: #000;" class=3D"styled-by-prettify"><br></span><span =
style=3D"color: #008;" class=3D"styled-by-prettify">void</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"> for_or</span><span style=3D=
"color: #660;" class=3D"styled-by-prettify">(</span><span style=3D"color: #=
008;" class=3D"styled-by-prettify">const</span><span style=3D"color: #000;"=
 class=3D"styled-by-prettify"> </span><span style=3D"color: #606;" class=3D=
"styled-by-prettify">Range</span><span style=3D"color: #660;" class=3D"styl=
ed-by-prettify">&amp;</span><span style=3D"color: #000;" class=3D"styled-by=
-prettify"> r</span><span style=3D"color: #660;" class=3D"styled-by-prettif=
y">,</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </spa=
n><span style=3D"color: #008;" class=3D"styled-by-prettify">const</span><sp=
an style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=
=3D"color: #606;" class=3D"styled-by-prettify">Body</span><span style=3D"co=
lor: #660;" class=3D"styled-by-prettify">&amp;</span><span style=3D"color: =
#000;" class=3D"styled-by-prettify"> b</span><span style=3D"color: #660;" c=
lass=3D"styled-by-prettify">,</span><span style=3D"color: #000;" class=3D"s=
tyled-by-prettify"> </span><span style=3D"color: #606;" class=3D"styled-by-=
prettify">Else</span><span style=3D"color: #000;" class=3D"styled-by-pretti=
fy"> e</span><span style=3D"color: #660;" class=3D"styled-by-prettify">)</s=
pan><span style=3D"color: #000;" class=3D"styled-by-prettify"><br></span><s=
pan style=3D"color: #660;" class=3D"styled-by-prettify">{</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"><br>=C2=A0 =C2=A0 </span><sp=
an style=3D"color: #008;" class=3D"styled-by-prettify">auto</span><span sty=
le=3D"color: #660;" class=3D"styled-by-prettify">&amp;&amp;</span><span sty=
le=3D"color: #000;" class=3D"styled-by-prettify"> it =C2=A0 =C2=A0</span><s=
pan style=3D"color: #660;" class=3D"styled-by-prettify">=3D</span><span sty=
le=3D"color: #000;" class=3D"styled-by-prettify"> r</span><span style=3D"co=
lor: #660;" class=3D"styled-by-prettify">.</span><span style=3D"color: #008=
;" class=3D"styled-by-prettify">begin</span><span style=3D"color: #660;" cl=
ass=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;" c=
lass=3D"styled-by-prettify">auto</span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">&amp;&amp;</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"> itEnd </span><span style=3D"color: #660;" class=3D=
"styled-by-prettify">=3D</span><span style=3D"color: #000;" class=3D"styled=
-by-prettify"> r</span><span style=3D"color: #660;" class=3D"styled-by-pret=
tify">.</span><span style=3D"color: #008;" class=3D"styled-by-prettify">end=
</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">if</span>=
<span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span sty=
le=3D"color: #660;" class=3D"styled-by-prettify">(</span><span style=3D"col=
or: #000;" class=3D"styled-by-prettify">it </span><span style=3D"color: #66=
0;" class=3D"styled-by-prettify">!=3D</span><span style=3D"color: #000;" cl=
ass=3D"styled-by-prettify"> itEnd</span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">)</span><span style=3D"color: #000;" class=3D"style=
d-by-prettify"><br>=C2=A0 =C2=A0 </span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">{</span><span style=3D"color: #000;" class=3D"style=
d-by-prettify"><br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 </span><span style=3D"color:=
 #008;" class=3D"styled-by-prettify">do</span><span style=3D"color: #000;" =
class=3D"styled-by-prettify"><br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 </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>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =
=C2=A0 =C2=A0 b</span><span style=3D"color: #660;" class=3D"styled-by-prett=
ify">(*</span><span style=3D"color: #000;" class=3D"styled-by-prettify">it<=
/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 </span><span style=3D"color: #660;" class=3D"styled-by-pretti=
fy">}</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </sp=
an><span style=3D"color: #008;" class=3D"styled-by-prettify">while</span><s=
pan style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">(++</span><span style=3D"col=
or: #000;" class=3D"styled-by-prettify">it </span><span style=3D"color: #66=
0;" class=3D"styled-by-prettify">!=3D</span><span style=3D"color: #000;" cl=
ass=3D"styled-by-prettify"> itEnd</span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">);</span><span style=3D"color: #000;" class=3D"styl=
ed-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"style=
d-by-prettify"><br>=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 </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 =C2=A0 =C2=A0 e</span><span style=3D"col=
or: #660;" class=3D"styled-by-prettify">();</span><span style=3D"color: #00=
0;" class=3D"styled-by-prettify"><br>=C2=A0 =C2=A0 </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><br></span><span style=3D"color: #008;" class=3D"style=
d-by-prettify">template</span><span style=3D"color: #660;" class=3D"styled-=
by-prettify">&lt;</span><span style=3D"color: #008;" class=3D"styled-by-pre=
ttify">typename</span><span style=3D"color: #000;" class=3D"styled-by-prett=
ify"> </span><span style=3D"color: #606;" class=3D"styled-by-prettify">CPlu=
gin</span><span style=3D"color: #660;" class=3D"styled-by-prettify">&gt;</s=
pan><span style=3D"color: #000;" class=3D"styled-by-prettify"><br></span><s=
pan style=3D"color: #008;" class=3D"styled-by-prettify">bool</span><span st=
yle=3D"color: #000;" class=3D"styled-by-prettify"> initPlugins</span><span =
style=3D"color: #660;" class=3D"styled-by-prettify">(</span><span style=3D"=
color: #008;" class=3D"styled-by-prettify">const</span><span style=3D"color=
: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #606;" =
class=3D"styled-by-prettify">CPlugin</span><span style=3D"color: #660;" cla=
ss=3D"styled-by-prettify">&amp;</span><span style=3D"color: #000;" class=3D=
"styled-by-prettify"> plugins</span><span style=3D"color: #660;" class=3D"s=
tyled-by-prettify">)</span><span style=3D"color: #000;" class=3D"styled-by-=
prettify"><br></span><span style=3D"color: #660;" class=3D"styled-by-pretti=
fy">{</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br>=
=C2=A0 =C2=A0 for_or</span><span style=3D"color: #660;" class=3D"styled-by-=
prettify">(</span><span style=3D"color: #000;" class=3D"styled-by-prettify"=
>plugins</span><span style=3D"color: #660;" class=3D"styled-by-prettify">,<=
/span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><sp=
an style=3D"color: #660;" class=3D"styled-by-prettify">[=3D</span><span sty=
le=3D"color: #008;" class=3D"styled-by-prettify">return</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">&amp;</span><span style=3D"color: #008;" class=
=3D"styled-by-prettify">break</span><span style=3D"color: #660;" class=3D"s=
tyled-by-prettify">,</span><span style=3D"color: #000;" class=3D"styled-by-=
prettify"> </span><span style=3D"color: #660;" class=3D"styled-by-prettify"=
>&amp;</span><span style=3D"color: #008;" class=3D"styled-by-prettify">cont=
inue</span><span style=3D"color: #660;" class=3D"styled-by-prettify">,</spa=
n><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span s=
tyle=3D"color: #660;" class=3D"styled-by-prettify">&amp;](</span><span styl=
e=3D"color: #008;" class=3D"styled-by-prettify">const</span><span style=3D"=
color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #6=
06;" class=3D"styled-by-prettify">Plugin</span><span style=3D"color: #660;"=
 class=3D"styled-by-prettify">&amp;</span><span style=3D"color: #000;" clas=
s=3D"styled-by-prettify"> plugin</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: #660;" class=3D"styled-by-pret=
tify">{</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: #800;" class=3D"s=
tyled-by-prettify">// this means we have initPlugin&#39;s return and callin=
g point&#39;s break, continue</span><span style=3D"color: #000;" class=3D"s=
tyled-by-prettify"><br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 </span><span style=3D"co=
lor: #008;" class=3D"styled-by-prettify">if</span><span style=3D"color: #00=
0;" class=3D"styled-by-prettify"> </span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">(!</span><span style=3D"color: #000;" class=3D"styl=
ed-by-prettify">plugin</span><span style=3D"color: #660;" class=3D"styled-b=
y-prettify">.</span><span style=3D"color: #000;" class=3D"styled-by-prettif=
y">requires_init</span><span style=3D"color: #660;" class=3D"styled-by-pret=
tify">())</span><span 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"styled-by-prettify">continue</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 =C2=A0 =C2=A0 </span><span style=
=3D"color: #008;" class=3D"styled-by-prettify">if</span><span style=3D"colo=
r: #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">plugin</span><span style=3D"color: #660;" class=3D"=
styled-by-prettify">.</span><span style=3D"color: #000;" class=3D"styled-by=
-prettify">init</span><span style=3D"color: #660;" class=3D"styled-by-prett=
ify">())</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><b=
r>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 </span><span style=3D"color: #0=
08;" class=3D"styled-by-prettify">return</span><span style=3D"color: #000;"=
 class=3D"styled-by-prettify"> </span><span style=3D"color: #008;" class=3D=
"styled-by-prettify">false</span><span style=3D"color: #660;" class=3D"styl=
ed-by-prettify">;</span><span style=3D"color: #000;" class=3D"styled-by-pre=
ttify"><br>=C2=A0 =C2=A0 </span><span style=3D"color: #660;" class=3D"style=
d-by-prettify">},</span><span style=3D"color: #000;" class=3D"styled-by-pre=
ttify"> </span><span style=3D"color: #660;" class=3D"styled-by-prettify">[&=
amp;</span><span style=3D"color: #008;" class=3D"styled-by-prettify">return=
</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"><br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 </spa=
n><span style=3D"color: #008;" class=3D"styled-by-prettify">return</span><s=
pan style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=
=3D"color: #606;" class=3D"styled-by-prettify">DefaultPlugin</span><span st=
yle=3D"color: #660;" class=3D"styled-by-prettify">::</span><span style=3D"c=
olor: #000;" class=3D"styled-by-prettify">initialize</span><span style=3D"c=
olor: #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: #660;" class=3D"styled-by-prettify">}</span><span style=3D"color: #0=
00;" class=3D"styled-by-prettify"><br>=C2=A0 =C2=A0 </span><span style=3D"c=
olor: #008;" class=3D"styled-by-prettify">return</span><span style=3D"color=
: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #008;" =
class=3D"styled-by-prettify">true</span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">;</span><span style=3D"color: #000;" class=3D"style=
d-by-prettify"><br></span><span style=3D"color: #660;" class=3D"styled-by-p=
rettify">}</span><span style=3D"color: #000;" class=3D"styled-by-prettify">=
<br><br></span></div></code></div><br><br>-----<br><br>And now, the &#39;mo=
nadic benefits&#39; :). You have seen that this essentially superior to for=
-else <i>and</i> for-break <i>and</i> break(n), albeit with a clumsy syntax=
.. Which you can make a macro for.<br>Also, you might think of `{ ... }` cod=
e blocks as `[=3Dreturn, &amp;break, &amp;continue, &amp;]{ ... }();`, add =
`this` if defined. The benefit of this is that now `if .. [else]`, `for`, `=
do .. while`, `while`, etc. are all monads, working on a lambda (e.g. a for=
-loop lifts <i>T -&gt; void</i> to <i>Range&lt;T&gt; -&gt; void</i> and cal=
ls it). This introduces the syntax `(type var : rval)` that passes rval to =
the monad on the left <i>and </i>is the parameter declaration of a lambda b=
eing declared in-place. If we now allow user-defined monads, we can have `f=
or_or(auto&amp;&amp; x : v) { ... } for_else { ... }`. If we allow decoupli=
ng of `(type var : rval)`, we have the `for` monad in C+: `auto initAll =3D=
 for (auto&amp;&amp; x) { x.init(); }; initAll(plugins.queue());`. These tw=
o ifs are strictly optional :).<br><br>Thanks,<br>-lorro<br><br>2016. szept=
ember 9., p=C3=A9ntek 5:39:42 UTC+2 id=C5=91pontban Nicol Bolas a k=C3=B6ve=
tkez=C5=91t =C3=ADrta:<blockquote class=3D"gmail_quote" style=3D"margin: 0;=
margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=
=3D"ltr">On Wednesday, September 7, 2016 at 4:36:50 PM UTC-4, <a>szollos...=
@gmail.com</a> 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"lt=
r">Hi,<br><br>While thinking about for..else, I realized that it (and other=
 language constructs) could be greatly simplified had we had the chance to =
capture monads created by keywords like return, continue, break. Before pro=
posing any syntax/schematics, I&#39;d first ask you, how would you feel abo=
ut this generally. The idea is something like:<br>[&amp;return, break_=3D&a=
mp;break, break=3D...](){...}<br><br>Capturing a monad assumes that it is v=
alid to write it in the calling context.<br><br>Note that capture is schema=
tic, i.e., &#39;return&#39; inside the lambda will destruct locals/paramete=
rs before performing caller&#39;s return; same holds for break and continue=
..<br><br>What do you think?<br></div></blockquote><div><br>I think that I d=
on&#39;t really understand what it&#39;s supposed to do.<br><br>My elementa=
ry-school understanding of &quot;monad&quot; comes entirely from <a href=3D=
"https://ericlippert.com/category/monads/" target=3D"_blank" rel=3D"nofollo=
w" onmousedown=3D"this.href=3D&#39;https://www.google.com/url?q\x3dhttps%3A=
%2F%2Fericlippert.com%2Fcategory%2Fmonads%2F\x26sa\x3dD\x26sntz\x3d1\x26usg=
\x3dAFQjCNG1zz36MAJQTxICItLYkDrnEQZBqA&#39;;return true;" onclick=3D"this.h=
ref=3D&#39;https://www.google.com/url?q\x3dhttps%3A%2F%2Fericlippert.com%2F=
category%2Fmonads%2F\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNG1zz36MAJQTxIC=
ItLYkDrnEQZBqA&#39;;return true;">skimming Eric Lippert&#39;s series on the=
m</a>. And I&#39;m not sure how &quot;keywords like return, continue, break=
&quot; constitute monads, nor do I understand what it means to &quot;captur=
e&quot; them.<br><br>Can you explain what this feature is supposed to do in=
 more basic terms of what it will do?<br></div></div></blockquote></div>

<p></p>

-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; 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/973a28d5-552f-418a-9495-5a463ea61df4%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/973a28d5-552f-418a-9495-5a463ea61df4=
%40isocpp.org</a>.<br />

------=_Part_3188_1536850988.1473460345177--

------=_Part_3187_1429392093.1473460345176--

.


Author: Nicol Bolas <jmckesson@gmail.com>
Date: Fri, 9 Sep 2016 20:46:41 -0700 (PDT)
Raw View
------=_Part_2146_1481710412.1473479201866
Content-Type: multipart/alternative;
 boundary="----=_Part_2147_1322629697.1473479201867"

------=_Part_2147_1322629697.1473479201867
Content-Type: text/plain; charset=UTF-8

On Friday, September 9, 2016 at 6:32:25 PM UTC-4, szollos...@gmail.com
wrote:
>
> Hi,
>
> Let's put aside calling them monads for a while, we'll return to that
> later. First some examples:
>
> 1. Error codes when you have no exceptions (due to embedded system /
> manager's wisdom / using vast amount of C libraries that return error
> codes). Here we assume that bool(ErrorCode) == true iff there was an error.
>
> ErrorCode save()
> {
>     // note that default exit is not the same as return here
>     auto return_if = [&return](auto retval){
>         if (retval) { return retval; }
>     };
>
>     return_if(openFile());
>     return_if(saveData());
>     return_if(closeFile());
> }
>
>
.... So what does this do?

See, it sounds like you're trying to say that returning from *within* the
lambda will cause it to return from... well, that right there is the
question. I *think* you want it to return from the function that called it.
But how exactly is *that* supposed to happen?

After all, the function that called it is not necessarily the function that
*created* it. What happens if you do this:

ErrorCode save()
{
    std::function<void(ErrorCode)> return_if = [&return](auto retval){
        if (retval) { return retval; }
    };

    return_if(openFile());
    return_if(saveData());
    return_if(closeFile());
}

I have every reason to expect this to achieve the same effect. Yet I cannot
imagine how that would be possible. After all, I don't call it. I call
`std::function::operator()`, which (eventually) calls the lambda. So the
lambda will just provoke the return of some construct within the
`std::function::operator()`.

And you can't say that it will always return to the caller of the lambda's
creator, because I don't have to still be on the stack. I can return that
lambda to someone else, wrapped in a `std::function`. How does that work?

A lambda in C++ is not some magical construct, imbued with fantastical
powers. In C++, a lambda is an *object*. Not only that, it is an instance
of a class type. You can rewrite *any lambda* as a local struct with a
constructor and an operator() overload (except for generic lambdas, but I'd
like to see that fixed). As it currently stands, a lambda cannot do
anything that a user-created class can't also do.

And *that is good*. Lambdas are syntactic sugar. Very useful and sweet
sugar, but sugar never-the-less. It is good that C++ defines lambdas as
compiler-created class types that follow all of the rules of such types. It
makes the language more regular and ensures the sanity of both lambdas and
of the type system.

The rules of C++ functions do not allow a function call to directly affect
the control flow of the function that called it. Well, actually it does
allow that; we call that an *exception*.

What you want is to write some pattern of code that can be used repeatedly
on arbitrary inputs, which will act on its caller outside of the normal
rules of C++ functions. That the code will act as if it were actually *copied
into* its caller, rather than following the rules of calling a function.
Like a macro, only... well actually, exactly like a macro.

A C++ function, as it currently stands, cannot do that. So either you want
to create a new construct with its own rules, or you want to expand the
rules of *all functions* to include such functionality.

But we should not *abuse* lambdas by imbuing them with magical powers that
regular C++ function and types cannot achieve. If you want to give lambdas
these powers, then it needs to be done in a way that gives other functions
and types these powers too.

If you want control structures in C++ to be "monads" or whatever, then
re-define them that way. But don't try to pervert lambdas into some tool to
achieve that effect.

-----
>
> And now, the 'monadic benefits' :). You have seen that this essentially
> superior to for-else *and* for-break *and* break(n), albeit with a clumsy
> syntax.
>

I have seen no such thing. I find it very difficult to agree with the
statement that some solution is "essentially superior" to an alternative,
when that solution is essentially "wrap all your code in a bunch of
lambdas."

Since before C++11 hit, I've seen lambdas abused for all kinds of stuff
that they should never be used for. Designing language features that
*encourage* such abuse is not a good thing.

Which you can make a macro for.
>

"Just wrap it in a macro" is not a valid justification for an intrinsically
hideous language feature. *Especially* if you're designing a language
feature that actually could have avoided being Medusa-levels of ugly if the
feature had been designed properly.

--
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/6bd8c8b6-e293-430e-978a-08372b68aba9%40isocpp.org.

------=_Part_2147_1322629697.1473479201867
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">On Friday, September 9, 2016 at 6:32:25 PM UTC-4, szollos.=
...@gmail.com wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;mar=
gin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D=
"ltr">Hi,<br><br>Let&#39;s put aside calling them monads for a while, we&#3=
9;ll return to that later. First some examples:<br><br>1. Error codes when =
you have no exceptions (due to embedded system / manager&#39;s wisdom / usi=
ng vast amount of C libraries that return error codes). Here we assume that=
 bool(ErrorCode) =3D=3D true iff there was an error.<br><br><div style=3D"b=
ackground-color:rgb(250,250,250);border-color:rgb(187,187,187);border-style=
:solid;border-width:1px;word-wrap:break-word"><code><div><span style=3D"col=
or:#606">ErrorCode</span><span style=3D"color:#000"> save</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:#800">// note that default exit is not the same as re=
turn here</span><span style=3D"color:#000"><br>=C2=A0 =C2=A0 </span><span s=
tyle=3D"color:#008">auto</span><span style=3D"color:#000"> return_if </span=
><span style=3D"color:#660">=3D</span><span style=3D"color:#000"> </span><s=
pan style=3D"color:#660">[&amp;</span><span style=3D"color:#008">return</sp=
an><span style=3D"color:#660">](</span><span style=3D"color:#008">auto</spa=
n><span style=3D"color:#000"> retval</span><span style=3D"color:#660">){</s=
pan><span style=3D"color:#000"><br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 </span><span=
 style=3D"color:#008">if</span><span style=3D"color:#000"> </span><span sty=
le=3D"color:#660">(</span><span style=3D"color:#000">retval</span><span sty=
le=3D"color:#660">)</span><span style=3D"color:#000"> </span><span style=3D=
"color:#660">{</span><span style=3D"color:#000"> </span><span style=3D"colo=
r:#008">return</span><span style=3D"color:#000"> retval</span><span style=
=3D"color:#660">;</span><span style=3D"color:#000"> </span><span style=3D"c=
olor:#660">}</span><span style=3D"color:#000"><br>=C2=A0 =C2=A0 </span><spa=
n style=3D"color:#660">};</span><span style=3D"color:#000"><br><br>=C2=A0 =
=C2=A0 return_if</span><span style=3D"color:#660">(</span><span style=3D"co=
lor:#000">openFile</span><span style=3D"color:#660">());</span><span style=
=3D"color:#000"><br>=C2=A0 =C2=A0 return_if</span><span style=3D"color:#660=
">(</span><span style=3D"color:#000">saveData</span><span style=3D"color:#6=
60">());</span><span style=3D"color:#000"><br>=C2=A0 =C2=A0 return_if</span=
><span style=3D"color:#660">(</span><span style=3D"color:#000">closeFile</s=
pan><span style=3D"color:#660">());</span><span style=3D"color:#000"><br></=
span><span style=3D"color:#660">}</span></div></code></div><br></div></bloc=
kquote><div><br>... So what does this do?<br><br>See, it sounds like you&#3=
9;re trying to say that returning from <i>within</i> the lambda will cause =
it to return from... well, that right there is the question. I <i>think</i>=
 you want it to return from the function that called it. But how exactly is=
 <i>that</i> supposed to happen?<br><br>After all, the function that called=
 it is not necessarily the function that <i>created</i> it. What happens if=
 you do this:<br><br><div class=3D"prettyprint" style=3D"background-color: =
rgb(250, 250, 250); border-color: rgb(187, 187, 187); border-style: solid; =
border-width: 1px; word-wrap: break-word;"><code class=3D"prettyprint"><div=
 class=3D"subprettyprint"><span style=3D"color: #606;" class=3D"styled-by-p=
rettify">ErrorCode</span><span style=3D"color: #000;" class=3D"styled-by-pr=
ettify"> save</span><span style=3D"color: #660;" class=3D"styled-by-prettif=
y">()</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br><=
/span><span style=3D"color: #660;" class=3D"styled-by-prettify">{</span><sp=
an style=3D"color: #000;" class=3D"styled-by-prettify"><br>=C2=A0 =C2=A0 st=
d</span><span style=3D"color: #660;" class=3D"styled-by-prettify">::</span>=
<span style=3D"color: #008;" class=3D"styled-by-prettify">function</span><s=
pan style=3D"color: #660;" class=3D"styled-by-prettify">&lt;</span><span st=
yle=3D"color: #008;" class=3D"styled-by-prettify">void</span><span style=3D=
"color: #660;" class=3D"styled-by-prettify">(</span><span style=3D"color: #=
606;" class=3D"styled-by-prettify">ErrorCode</span><span style=3D"color: #6=
60;" class=3D"styled-by-prettify">)&gt;</span><span style=3D"color: #000;" =
class=3D"styled-by-prettify"> return_if </span><span style=3D"color: #660;"=
 class=3D"styled-by-prettify">=3D</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"> </span><span style=3D"color: #660;" class=3D"style=
d-by-prettify">[&amp;</span><span style=3D"color: #008;" class=3D"styled-by=
-prettify">return</span><span style=3D"color: #660;" class=3D"styled-by-pre=
ttify">](</span><span style=3D"color: #008;" class=3D"styled-by-prettify">a=
uto</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> retval=
</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-pretti=
fy">if</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </s=
pan><span style=3D"color: #660;" class=3D"styled-by-prettify">(</span><span=
 style=3D"color: #000;" class=3D"styled-by-prettify">retval</span><span sty=
le=3D"color: #660;" class=3D"styled-by-prettify">)</span><span style=3D"col=
or: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #660;=
" class=3D"styled-by-prettify">{</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"> </span><span style=3D"color: #008;" class=3D"style=
d-by-prettify">return</span><span style=3D"color: #000;" class=3D"styled-by=
-prettify"> retval</span><span style=3D"color: #660;" class=3D"styled-by-pr=
ettify">;</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> =
</span><span style=3D"color: #660;" class=3D"styled-by-prettify">}</span><s=
pan 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><s=
pan style=3D"color: #000;" class=3D"styled-by-prettify"><br><br>=C2=A0 =C2=
=A0 return_if</span><span style=3D"color: #660;" class=3D"styled-by-prettif=
y">(</span><span style=3D"color: #000;" class=3D"styled-by-prettify">openFi=
le</span><span style=3D"color: #660;" class=3D"styled-by-prettify">());</sp=
an><span style=3D"color: #000;" class=3D"styled-by-prettify"><br>=C2=A0 =C2=
=A0 return_if</span><span style=3D"color: #660;" class=3D"styled-by-prettif=
y">(</span><span style=3D"color: #000;" class=3D"styled-by-prettify">saveDa=
ta</span><span style=3D"color: #660;" class=3D"styled-by-prettify">());</sp=
an><span style=3D"color: #000;" class=3D"styled-by-prettify"><br>=C2=A0 =C2=
=A0 return_if</span><span style=3D"color: #660;" class=3D"styled-by-prettif=
y">(</span><span style=3D"color: #000;" class=3D"styled-by-prettify">closeF=
ile</span><span style=3D"color: #660;" class=3D"styled-by-prettify">());</s=
pan><span style=3D"color: #000;" class=3D"styled-by-prettify"><br></span><s=
pan style=3D"color: #660;" class=3D"styled-by-prettify">}</span></div></cod=
e></div><br>I have every reason to expect this to achieve the same effect. =
Yet I cannot imagine how that would be possible. After all, I don&#39;t cal=
l it. I call `std::function::operator()`, which (eventually) calls the lamb=
da. So the lambda will just provoke the return of some construct within the=
 `std::function::operator()`.<br><br>And you can&#39;t say that it will alw=
ays return to the caller of the lambda&#39;s creator, because I don&#39;t h=
ave to still be on the stack. I can return that lambda to someone else, wra=
pped in a `std::function`. How does that work?<br><br>A lambda in C++ is no=
t some magical construct, imbued with fantastical powers. In C++, a lambda =
is an <i>object</i>. Not only that, it is an instance of a class type. You =
can rewrite <i>any lambda</i> as a local struct with a constructor and an o=
perator() overload (except for generic lambdas, but I&#39;d like to see tha=
t fixed). As it currently stands, a lambda cannot do anything that a user-c=
reated class can&#39;t also do.<br><br>And <i>that is good</i>. Lambdas are=
 syntactic sugar. Very useful and sweet sugar, but sugar never-the-less. It=
 is good that C++ defines lambdas as compiler-created class types that foll=
ow all of the rules of such types. It makes the language more regular and e=
nsures the sanity of both lambdas and of the type system.<br><br>The rules =
of C++ functions do not allow a function call to directly affect the contro=
l flow of the function that called it. Well, actually it does allow that; w=
e call that an <i>exception</i>.<br><br>What you want is to write some patt=
ern of code that can be used repeatedly on arbitrary inputs, which will act=
 on its caller outside of the normal rules of C++ functions. That the code =
will act as if it were actually <i>copied into</i> its caller, rather than =
following the rules of calling a function. Like a macro, only... well actua=
lly, exactly like a macro.<br><br>A C++ function, as it currently stands, c=
annot do that. So either you want to create a new construct with its own ru=
les, or you want to expand the rules of <i>all functions</i> to include suc=
h functionality.<br><br>But we should not <i>abuse</i> lambdas by imbuing t=
hem with magical powers that regular C++ function and types cannot achieve.=
 If you want to give lambdas these powers, then it needs to be done in a wa=
y that gives other functions and types these powers too.<br><br>If you want=
 control structures in C++ to be &quot;monads&quot; or whatever, then re-de=
fine them that way. But don&#39;t try to pervert lambdas into some tool to =
achieve that effect.<br></div><br><blockquote class=3D"gmail_quote" style=
=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: =
1ex;"><div dir=3D"ltr">-----<br><br>And now, the &#39;monadic benefits&#39;=
 :). You have seen that this essentially superior to for-else <i>and</i> fo=
r-break <i>and</i> break(n), albeit with a clumsy syntax.</div></blockquote=
><div><br>I have seen no such thing. I find it very difficult to agree with=
 the statement that some solution is &quot;essentially superior&quot; to an=
 alternative, when that solution is essentially &quot;wrap all your code in=
 a bunch of lambdas.&quot;<br><br>Since before C++11 hit, I&#39;ve seen lam=
bdas abused for all kinds of stuff that they should never be used for. Desi=
gning language features that <i>encourage</i> such abuse is not a good thin=
g.<br><br></div><blockquote class=3D"gmail_quote" style=3D"margin: 0;margin=
-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"lt=
r">Which you can make a macro for.<br></div></blockquote><div><br>&quot;Jus=
t wrap it in a macro&quot; is not a valid justification for an intrinsicall=
y hideous language feature. <i>Especially</i> if you&#39;re designing a lan=
guage feature that actually could have avoided being Medusa-levels of ugly =
if the feature had been designed properly.<br></div></div>

<p></p>

-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; 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/6bd8c8b6-e293-430e-978a-08372b68aba9%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/6bd8c8b6-e293-430e-978a-08372b68aba9=
%40isocpp.org</a>.<br />

------=_Part_2147_1322629697.1473479201867--

------=_Part_2146_1481710412.1473479201866--

.


Author: "'Edward Catmur' via ISO C++ Standard - Future Proposals" <std-proposals@isocpp.org>
Date: Sun, 11 Sep 2016 00:23:49 +0100
Raw View
--001a1149c7a226b705053c2f8e0d
Content-Type: text/plain; charset=UTF-8

On 10 Sep 2016 04:46, "Nicol Bolas" <jmckesson@gmail.com> wrote:
> See, it sounds like you're trying to say that returning from within the
lambda will cause it to return from... well, that right there is the
question. I think you want it to return from the function that called it.
But how exactly is that supposed to happen?

Stack unwinding.

> After all, the function that called it is not necessarily the function
that created it. What happens if you do this:
>
> ErrorCode save()
> {
>     std::function<void(ErrorCode)> return_if = [&return](auto retval){
>
>         if (retval) { return retval; }
>     };
>
>     return_if(openFile());
>     return_if(saveData());
>     return_if(closeFile());
> }
>
> I have every reason to expect this to achieve the same effect. Yet I
cannot imagine how that would be possible. After all, I don't call it. I
call `std::function::operator()`, which (eventually) calls the lambda. So
the lambda will just provoke the return of some construct within the
`std::function::operator()`.

Stack unwinding isn't just for exceptions. The machinery is there for non
local jumps, such as thread cancellation, setjmp and SEH.

> And you can't say that it will always return to the caller of the
lambda's creator, because I don't have to still be on the stack. I can
return that lambda to someone else, wrapped in a `std::function`. How does
that work?

UB, just as with capturing local variables by reference. Likewise if any of
the intervening frames are not unwinding aware.

> A lambda in C++ is not some magical construct, imbued with fantastical
powers. In C++, a lambda is an object. Not only that, it is an instance of
a class type. You can rewrite any lambda as a local struct with a
constructor and an operator() overload (except for generic lambdas, but I'd
like to see that fixed). As it currently stands, a lambda cannot do
anything that a user-created class can't also do.

There's another feature you're forgetting. Lambda captures can copy arrays
by value, which user code can't do without some heavy library machinery.

If we're talking user code equivalents, setjmp would do if it's
unwind-enabled, as would a custom exception in the absence of catch (...)
blocks, or even invoking the platform unwind machinery directly.

> <snip>

Sure, I get that you like that lambdas are mostly syntactic sugar. That was
probably necessary at the beginning, but it doesn't mean they have to stay
that way.

--
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/CAJnLdOaRwRm%3Dtma%3D2trcYSY031SXvfkcXhQFBG2mS%2B0X8eqrpw%40mail.gmail.com.

--001a1149c7a226b705053c2f8e0d
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<p dir=3D"ltr"></p>
<p dir=3D"ltr">On 10 Sep 2016 04:46, &quot;Nicol Bolas&quot; &lt;<a href=3D=
"mailto:jmckesson@gmail.com">jmckesson@gmail.com</a>&gt; wrote:<br>
&gt; See, it sounds like you&#39;re trying to say that returning from withi=
n the lambda will cause it to return from... well, that right there is the =
question. I think you want it to return from the function that called it. B=
ut how exactly is that supposed to happen?</p>
<p dir=3D"ltr">Stack unwinding. </p>
<p dir=3D"ltr">&gt; After all, the function that called it is not necessari=
ly the function that created it. What happens if you do this:<br>
&gt;<br>
&gt; ErrorCode save()<br>
&gt; {<br>
&gt; =C2=A0 =C2=A0 std::function&lt;void(ErrorCode)&gt; return_if =3D [&amp=
;return](auto retval){<br>
&gt;<br>
&gt; =C2=A0 =C2=A0 =C2=A0 =C2=A0 if (retval) { return retval; }<br>
&gt; =C2=A0 =C2=A0 };<br>
&gt;<br>
&gt; =C2=A0 =C2=A0 return_if(openFile());<br>
&gt; =C2=A0 =C2=A0 return_if(saveData());<br>
&gt; =C2=A0 =C2=A0 return_if(closeFile());<br>
&gt; }<br>
&gt;<br>
&gt; I have every reason to expect this to achieve the same effect. Yet I c=
annot imagine how that would be possible. After all, I don&#39;t call it. I=
 call `std::function::operator()`, which (eventually) calls the lambda. So =
the lambda will just provoke the return of some construct within the `std::=
function::operator()`.</p>
<p dir=3D"ltr">Stack unwinding isn&#39;t just for exceptions. The machinery=
 is there for non local jumps, such as thread cancellation, setjmp and SEH.=
 </p>
<p dir=3D"ltr">&gt; And you can&#39;t say that it will always return to the=
 caller of the lambda&#39;s creator, because I don&#39;t have to still be o=
n the stack. I can return that lambda to someone else, wrapped in a `std::f=
unction`. How does that work?</p>
<p dir=3D"ltr">UB, just as with capturing local variables by reference. Lik=
ewise if any of the intervening frames are not unwinding aware. </p>
<p dir=3D"ltr">&gt; A lambda in C++ is not some magical construct, imbued w=
ith fantastical powers. In C++, a lambda is an object. Not only that, it is=
 an instance of a class type. You can rewrite any lambda as a local struct =
with a constructor and an operator() overload (except for generic lambdas, =
but I&#39;d like to see that fixed). As it currently stands, a lambda canno=
t do anything that a user-created class can&#39;t also do.</p>
<p dir=3D"ltr">There&#39;s another feature you&#39;re forgetting. Lambda ca=
ptures can copy arrays by value, which user code can&#39;t do without some =
heavy library machinery. </p>
<p dir=3D"ltr">If we&#39;re talking user code equivalents, setjmp would do =
if it&#39;s unwind-enabled, as would a custom exception in the absence of c=
atch (...) blocks, or even invoking the platform unwind machinery directly.=
 </p>
<p dir=3D"ltr">&gt; &lt;snip&gt;</p>
<p dir=3D"ltr">Sure, I get that you like that lambdas are mostly syntactic =
sugar. That was probably necessary at the beginning, but it doesn&#39;t mea=
n they have to stay that way. </p>

<p></p>

-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; 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/CAJnLdOaRwRm%3Dtma%3D2trcYSY031SXvfkc=
XhQFBG2mS%2B0X8eqrpw%40mail.gmail.com?utm_medium=3Demail&utm_source=3Dfoote=
r">https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CAJnLdOaRwR=
m%3Dtma%3D2trcYSY031SXvfkcXhQFBG2mS%2B0X8eqrpw%40mail.gmail.com</a>.<br />

--001a1149c7a226b705053c2f8e0d--

.


Author: Nicol Bolas <jmckesson@gmail.com>
Date: Sun, 11 Sep 2016 09:42:08 -0700 (PDT)
Raw View
------=_Part_182_1129952113.1473612128392
Content-Type: multipart/alternative;
 boundary="----=_Part_183_1711357595.1473612128393"

------=_Part_183_1711357595.1473612128393
Content-Type: text/plain; charset=UTF-8

On Saturday, September 10, 2016 at 7:23:50 PM UTC-4, Edward Catmur wrote:
>
> On 10 Sep 2016 04:46, "Nicol Bolas" <jmck...@gmail.com <javascript:>>
> wrote:
> > See, it sounds like you're trying to say that returning from within the
> lambda will cause it to return from... well, that right there is the
> question. I think you want it to return from the function that called it.
> But how exactly is that supposed to happen?
>
> Stack unwinding.
>
> > After all, the function that called it is not necessarily the function
> that created it. What happens if you do this:
> >
> > ErrorCode save()
> > {
> >     std::function<void(ErrorCode)> return_if = [&return](auto retval){
> >
> >         if (retval) { return retval; }
> >     };
> >
> >     return_if(openFile());
> >     return_if(saveData());
> >     return_if(closeFile());
> > }
> >
> > I have every reason to expect this to achieve the same effect. Yet I
> cannot imagine how that would be possible. After all, I don't call it. I
> call `std::function::operator()`, which (eventually) calls the lambda. So
> the lambda will just provoke the return of some construct within the
> `std::function::operator()`.
>
> Stack unwinding isn't just for exceptions. The machinery is there for non
> local jumps, such as thread cancellation, setjmp and SEH.
>

My first inclination is to say that this is just exception handling with
special cleanup work. Conceptually, it's indistinguishable from:

auto x = []() {... throw return_value(someValue);} //Class template
deduction

try
{
  auto y = x(foo);
}
catch(return_value<ReturnType> &t)
{
  return std::move(t.get());
}

Obviously that's both incredibly verbose and traps `y` within a try-block.
But the general idea you seem to want is the same; it's simply a matter of
applying syntactic sugar:

auto y = try x(foo);

Or something to that effect, with the compiler generating logic based on
certain types being thrown. `std::return_value<T>` would provoke a return
from that function of the stored `T`. `std::break_value` would provoke a
`break`. If nothing is thrown, then the code proceeds as normal.

The `try` there is important for two reasons. First, it lets the compiler
know where to stop looking. And second, it makes clear to the reader that
the code in question may experience an alternate control flow. Just as with
any other `try` block.

A lambda does not seem to be the natural form of syntax for applying this.
If you're going to start doing stack unwinding and such, then it should be
built on the language mechanism that actually does stack unwinding.

Consider `expected<T, E>`. By decoupling this feature from lambdas, by
giving *all* functions this power, we could give it an implicit `operator
T` overload that will either return a `T` or throw a return of `E`. So if
you do `auto x = try Typename(exp);`, you get automatic unpacking or a
return of the error code.

Granted, some might suggest that this is no less dangerous or
performance-costly than exceptions. To which I answer... yeah. That's what
happens when you want code to be able to transparently communicate with
some other code that is an indeterminate number of function calls below it.


> > And you can't say that it will always return to the caller of the
> lambda's creator, because I don't have to still be on the stack. I can
> return that lambda to someone else, wrapped in a `std::function`. How does
> that work?
>
> UB, just as with capturing local variables by reference. Likewise if any
> of the intervening frames are not unwinding aware.
>

The last example the OP posted makes a distinction between "capturing" by
value vs. by reference. By reference `return` means causing a return from
the most recent caller. By value `return` means causing a return from the
code that created it.

So really, the OP's proposal is kinda backwards from what you seem to be
wanting (and to be honest, I rather prefer your interpretation).
"Capturing" statements by reference is *safe* and such lambdas can be used
anywhere (in theory), while "capturing" by value is unsafe.

> A lambda in C++ is not some magical construct, imbued with fantastical
> powers. In C++, a lambda is an object. Not only that, it is an instance of
> a class type. You can rewrite any lambda as a local struct with a
> constructor and an operator() overload (except for generic lambdas, but I'd
> like to see that fixed). As it currently stands, a lambda cannot do
> anything that a user-created class can't also do.
>
> There's another feature you're forgetting. Lambda captures can copy arrays
> by value, which user code can't do without some heavy library machinery
>

It doesn't take "heavy library machinery" to copy an array. Well, so long
as the type is default-constructible and assignable.

Ultimately, the point I'm making is that a lambda is not a special thing;
it doesn't do anything you can't do yourself, even if doing it yourself is
much harder. What's being proposed here is a deviation from that: you
*cannot* replicate such behavior.

And that ultimately limits the utility of the proposal.

If we're talking user code equivalents, setjmp would do if it's
> unwind-enabled, as would a custom exception in the absence of catch (...)
> blocks, or even invoking the platform unwind machinery directly.
>
> > <snip>
>
> Sure, I get that you like that lambdas are mostly syntactic sugar. That
> was probably necessary at the beginning, but it doesn't mean they have to
> stay that way.
>

That's not a good enough reason to tie it to lambdas.

Consider two of the examples provided here: `return_if` and `error_code`.
Those patterns are quite useful for many  circumstances. And yet, there is
no way to avoid re-typing them every time you want to use them without
employing a macro. Why?

Because the feature is tied to lambdas and their capture list. Remove that
tie, and it suddenly becomes quite possible to have these as simply
standard library template functions.

--
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/dcb70287-4ee4-4cae-9e09-4f7cab8d0db8%40isocpp.org.

------=_Part_183_1711357595.1473612128393
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">On Saturday, September 10, 2016 at 7:23:50 PM UTC-4, Edwar=
d Catmur wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-=
left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><p dir=3D"ltr">=
</p>
<p dir=3D"ltr">On 10 Sep 2016 04:46, &quot;Nicol Bolas&quot; &lt;<a href=3D=
"javascript:" target=3D"_blank" gdf-obfuscated-mailto=3D"hiZRUIyVFQAJ" rel=
=3D"nofollow" onmousedown=3D"this.href=3D&#39;javascript:&#39;;return true;=
" onclick=3D"this.href=3D&#39;javascript:&#39;;return true;">jmck...@gmail.=
com</a>&gt; wrote:<br>
&gt; See, it sounds like you&#39;re trying to say that returning from withi=
n the lambda will cause it to return from... well, that right there is the =
question. I think you want it to return from the function that called it. B=
ut how exactly is that supposed to happen?</p>
<p dir=3D"ltr">Stack unwinding. </p>
<p dir=3D"ltr">&gt; After all, the function that called it is not necessari=
ly the function that created it. What happens if you do this:<br>
&gt;<br>
&gt; ErrorCode save()<br>
&gt; {<br>
&gt; =C2=A0 =C2=A0 std::function&lt;void(ErrorCode)&gt; return_if =3D [&amp=
;return](auto retval){<br>
&gt;<br>
&gt; =C2=A0 =C2=A0 =C2=A0 =C2=A0 if (retval) { return retval; }<br>
&gt; =C2=A0 =C2=A0 };<br>
&gt;<br>
&gt; =C2=A0 =C2=A0 return_if(openFile());<br>
&gt; =C2=A0 =C2=A0 return_if(saveData());<br>
&gt; =C2=A0 =C2=A0 return_if(closeFile());<br>
&gt; }<br>
&gt;<br>
&gt; I have every reason to expect this to achieve the same effect. Yet I c=
annot imagine how that would be possible. After all, I don&#39;t call it. I=
 call `std::function::operator()`, which (eventually) calls the lambda. So =
the lambda will just provoke the return of some construct within the `std::=
function::operator()`.</p>
<p dir=3D"ltr">Stack unwinding isn&#39;t just for exceptions. The machinery=
 is there for non local jumps, such as thread cancellation, setjmp and SEH.=
 </p></blockquote><div><br>My first inclination is to say that this is just=
 exception handling with special cleanup work. Conceptually, it&#39;s indis=
tinguishable from:<br><br><div class=3D"prettyprint" style=3D"background-co=
lor: rgb(250, 250, 250); border-color: rgb(187, 187, 187); border-style: so=
lid; border-width: 1px; word-wrap: break-word;"><code class=3D"prettyprint"=
><div class=3D"subprettyprint"><span style=3D"color: #008;" class=3D"styled=
-by-prettify">auto</span><span style=3D"color: #000;" class=3D"styled-by-pr=
ettify"> x </span><span style=3D"color: #660;" class=3D"styled-by-prettify"=
>=3D</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </spa=
n><span style=3D"color: #660;" class=3D"styled-by-prettify">[]()</span><spa=
n style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">{...</span><span style=3D"co=
lor: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #008=
;" class=3D"styled-by-prettify">throw</span><span style=3D"color: #000;" cl=
ass=3D"styled-by-prettify"> return_value</span><span style=3D"color: #660;"=
 class=3D"styled-by-prettify">(</span><span style=3D"color: #000;" class=3D=
"styled-by-prettify">someValue</span><span style=3D"color: #660;" class=3D"=
styled-by-prettify">);}</span><span style=3D"color: #000;" class=3D"styled-=
by-prettify"> </span><span style=3D"color: #800;" class=3D"styled-by-pretti=
fy">//Class template deduction</span><span style=3D"color: #000;" class=3D"=
styled-by-prettify"><br><br></span><span style=3D"color: #008;" class=3D"st=
yled-by-prettify">try</span><span style=3D"color: #000;" class=3D"styled-by=
-prettify"><br></span><span style=3D"color: #660;" class=3D"styled-by-prett=
ify">{</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">aut=
o</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> y </span=
><span style=3D"color: #660;" class=3D"styled-by-prettify">=3D</span><span =
style=3D"color: #000;" class=3D"styled-by-prettify"> x</span><span style=3D=
"color: #660;" class=3D"styled-by-prettify">(</span><span style=3D"color: #=
000;" class=3D"styled-by-prettify">foo</span><span style=3D"color: #660;" c=
lass=3D"styled-by-prettify">);</span><span style=3D"color: #000;" class=3D"=
styled-by-prettify"><br></span><span style=3D"color: #660;" class=3D"styled=
-by-prettify">}</span><span style=3D"color: #000;" class=3D"styled-by-prett=
ify"><br></span><span style=3D"color: #008;" class=3D"styled-by-prettify">c=
atch</span><span style=3D"color: #660;" class=3D"styled-by-prettify">(</spa=
n><span style=3D"color: #000;" class=3D"styled-by-prettify">return_value</s=
pan><span style=3D"color: #660;" class=3D"styled-by-prettify">&lt;</span><s=
pan style=3D"color: #606;" class=3D"styled-by-prettify">ReturnType</span><s=
pan style=3D"color: #660;" class=3D"styled-by-prettify">&gt;</span><span st=
yle=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"co=
lor: #660;" class=3D"styled-by-prettify">&amp;</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;" class=3D"st=
yled-by-prettify"><br></span><span style=3D"color: #660;" class=3D"styled-b=
y-prettify">{</span><span style=3D"color: #000;" class=3D"styled-by-prettif=
y"><br>=C2=A0 </span><span style=3D"color: #008;" class=3D"styled-by-pretti=
fy">return</span><span style=3D"color: #000;" class=3D"styled-by-prettify">=
 std</span><span style=3D"color: #660;" class=3D"styled-by-prettify">::</sp=
an><span style=3D"color: #000;" class=3D"styled-by-prettify">move</span><sp=
an style=3D"color: #660;" class=3D"styled-by-prettify">(</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify">t</span><span style=3D"color=
: #660;" class=3D"styled-by-prettify">.</span><span style=3D"color: #008;" =
class=3D"styled-by-prettify">get</span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">());</span><span style=3D"color: #000;" class=3D"st=
yled-by-prettify"><br></span><span style=3D"color: #660;" class=3D"styled-b=
y-prettify">}</span><span style=3D"color: #000;" class=3D"styled-by-prettif=
y"><br></span></div></code></div><br>Obviously that&#39;s both incredibly v=
erbose and traps `y` within a try-block. But the general idea you seem to w=
ant is the same; it&#39;s simply a matter of applying syntactic sugar:<br><=
br><div class=3D"prettyprint" style=3D"background-color: rgb(250, 250, 250)=
; border-color: rgb(187, 187, 187); border-style: solid; border-width: 1px;=
 word-wrap: break-word;"><code class=3D"prettyprint"><div class=3D"subprett=
yprint"><span style=3D"color: #008;" class=3D"styled-by-prettify">auto</spa=
n><span style=3D"color: #000;" class=3D"styled-by-prettify"> y </span><span=
 style=3D"color: #660;" class=3D"styled-by-prettify">=3D</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color=
: #008;" class=3D"styled-by-prettify">try</span><span style=3D"color: #000;=
" class=3D"styled-by-prettify"> x</span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">(</span><span style=3D"color: #000;" class=3D"style=
d-by-prettify">foo</span><span style=3D"color: #660;" class=3D"styled-by-pr=
ettify">);</span><span style=3D"color: #000;" class=3D"styled-by-prettify">=
<br></span></div></code></div><br>Or something to that effect, with the com=
piler generating logic based on certain types being thrown. `std::return_va=
lue&lt;T&gt;` would provoke a return from that function of the stored `T`. =
`std::break_value` would provoke a `break`. If nothing is thrown, then the =
code proceeds as normal.<br><br>The `try` there is important for two reason=
s. First, it lets the compiler know where to stop looking. And second, it m=
akes clear to the reader that the code in question may experience an altern=
ate control flow. Just as with any other `try` block.<br><br>A lambda does =
not seem to be the natural form of syntax for applying this. If you&#39;re =
going to start doing stack unwinding and such, then it should be built on t=
he language mechanism that actually does stack unwinding.<br><br>Consider `=
expected&lt;T, E&gt;`. By decoupling this feature from lambdas, by giving <=
i>all</i> functions this power, we could give it an implicit `operator T` o=
verload that will either return a `T` or throw a return of `E`. So if you d=
o `auto x =3D try Typename(exp);`, you get automatic unpacking or a return =
of the error code.<br><br>Granted, some might suggest that this is no less =
dangerous or performance-costly than exceptions. To which I answer... yeah.=
 That&#39;s what happens when you want code to be able to transparently com=
municate with some other code that is an indeterminate number of function c=
alls below it.<br>=C2=A0</div><blockquote class=3D"gmail_quote" style=3D"ma=
rgin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">
<p dir=3D"ltr">&gt; And you can&#39;t say that it will always return to the=
 caller of the lambda&#39;s creator, because I don&#39;t have to still be o=
n the stack. I can return that lambda to someone else, wrapped in a `std::f=
unction`. How does that work?</p>
<p dir=3D"ltr">UB, just as with capturing local variables by reference. Lik=
ewise if any of the intervening frames are not unwinding aware. </p></block=
quote><div><br>The last example the OP posted makes a distinction between &=
quot;capturing&quot; by value vs. by reference. By reference `return` means=
 causing a return from the most recent caller. By value `return` means caus=
ing a return from the code that created it.<br><br>So really, the OP&#39;s =
proposal is kinda backwards from what you seem to be wanting (and to be hon=
est, I rather prefer your interpretation). &quot;Capturing&quot; statements=
 by reference is *safe* and such lambdas can be used anywhere (in theory), =
while &quot;capturing&quot; by value is unsafe.<br><br></div><blockquote cl=
ass=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px =
#ccc solid;padding-left: 1ex;">
<p dir=3D"ltr">&gt; A lambda in C++ is not some magical construct, imbued w=
ith fantastical powers. In C++, a lambda is an object. Not only that, it is=
 an instance of a class type. You can rewrite any lambda as a local struct =
with a constructor and an operator() overload (except for generic lambdas, =
but I&#39;d like to see that fixed). As it currently stands, a lambda canno=
t do anything that a user-created class can&#39;t also do.</p>
<p dir=3D"ltr">There&#39;s another feature you&#39;re forgetting. Lambda ca=
ptures can copy arrays by value, which user code can&#39;t do without some =
heavy library machinery</p></blockquote><div><br>It doesn&#39;t take &quot;=
heavy library machinery&quot; to copy an array. Well, so long as the type i=
s default-constructible and assignable.<br><br>Ultimately, the point I&#39;=
m making is that a lambda is not a special thing; it doesn&#39;t do anythin=
g you can&#39;t do yourself, even if doing it yourself is much harder. What=
&#39;s being proposed here is a deviation from that: you <i>cannot</i> repl=
icate such behavior.<br><br>And that ultimately limits the utility of the p=
roposal.<br><br></div><blockquote class=3D"gmail_quote" style=3D"margin: 0;=
margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><p dir=
=3D"ltr"> </p>
<p dir=3D"ltr">If we&#39;re talking user code equivalents, setjmp would do =
if it&#39;s unwind-enabled, as would a custom exception in the absence of c=
atch (...) blocks, or even invoking the platform unwind machinery directly.=
 </p>
<p dir=3D"ltr">&gt; &lt;snip&gt;</p>
<p dir=3D"ltr">Sure, I get that you like that lambdas are mostly syntactic =
sugar. That was probably necessary at the beginning, but it doesn&#39;t mea=
n they have to stay that way.</p></blockquote><div><br>That&#39;s not a goo=
d enough reason to tie it to lambdas.<br><br>Consider two of the examples p=
rovided here: `return_if` and `error_code`. Those patterns are quite useful=
 for many=C2=A0 circumstances. And yet, there is no way to avoid re-typing =
them every time you want to use them without employing a macro. Why?<br><br=
>Because the feature is tied to lambdas and their capture list. Remove that=
 tie, and it suddenly becomes quite possible to have these as simply standa=
rd library template functions.<br></div></div>

<p></p>

-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; 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/dcb70287-4ee4-4cae-9e09-4f7cab8d0db8%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/dcb70287-4ee4-4cae-9e09-4f7cab8d0db8=
%40isocpp.org</a>.<br />

------=_Part_183_1711357595.1473612128393--

------=_Part_182_1129952113.1473612128392--

.


Author: Robert Bielik <robert.bielik@gmail.com>
Date: Sun, 11 Sep 2016 18:55:16 +0200
Raw View
--001a1145b0b8793c07053c3e3e87
Content-Type: text/plain; charset=UTF-8

Been following this thread, and I just want to chip in with a very
important aspect: Readability. In ten cases of ten, I'd use exceptions as a
mechanism to achieve the same behavior. Why? Because it's more readable,
and not obfuscated.

Den 11 sep 2016 18:42 skrev "Nicol Bolas" <jmckesson@gmail.com>:

> On Saturday, September 10, 2016 at 7:23:50 PM UTC-4, Edward Catmur wrote:
>>
>> On 10 Sep 2016 04:46, "Nicol Bolas" <jmck...@gmail.com> wrote:
>> > See, it sounds like you're trying to say that returning from within the
>> lambda will cause it to return from... well, that right there is the
>> question. I think you want it to return from the function that called it.
>> But how exactly is that supposed to happen?
>>
>> Stack unwinding.
>>
>> > After all, the function that called it is not necessarily the function
>> that created it. What happens if you do this:
>> >
>> > ErrorCode save()
>> > {
>> >     std::function<void(ErrorCode)> return_if = [&return](auto retval){
>> >
>> >         if (retval) { return retval; }
>> >     };
>> >
>> >     return_if(openFile());
>> >     return_if(saveData());
>> >     return_if(closeFile());
>> > }
>> >
>> > I have every reason to expect this to achieve the same effect. Yet I
>> cannot imagine how that would be possible. After all, I don't call it. I
>> call `std::function::operator()`, which (eventually) calls the lambda. So
>> the lambda will just provoke the return of some construct within the
>> `std::function::operator()`.
>>
>> Stack unwinding isn't just for exceptions. The machinery is there for non
>> local jumps, such as thread cancellation, setjmp and SEH.
>>
>
> My first inclination is to say that this is just exception handling with
> special cleanup work. Conceptually, it's indistinguishable from:
>
> auto x = []() {... throw return_value(someValue);} //Class template
> deduction
>
> try
> {
>   auto y = x(foo);
> }
> catch(return_value<ReturnType> &t)
> {
>   return std::move(t.get());
> }
>
> Obviously that's both incredibly verbose and traps `y` within a try-block.
> But the general idea you seem to want is the same; it's simply a matter of
> applying syntactic sugar:
>
> auto y = try x(foo);
>
> Or something to that effect, with the compiler generating logic based on
> certain types being thrown. `std::return_value<T>` would provoke a return
> from that function of the stored `T`. `std::break_value` would provoke a
> `break`. If nothing is thrown, then the code proceeds as normal.
>
> The `try` there is important for two reasons. First, it lets the compiler
> know where to stop looking. And second, it makes clear to the reader that
> the code in question may experience an alternate control flow. Just as with
> any other `try` block.
>
> A lambda does not seem to be the natural form of syntax for applying this.
> If you're going to start doing stack unwinding and such, then it should be
> built on the language mechanism that actually does stack unwinding.
>
> Consider `expected<T, E>`. By decoupling this feature from lambdas, by
> giving *all* functions this power, we could give it an implicit `operator
> T` overload that will either return a `T` or throw a return of `E`. So if
> you do `auto x = try Typename(exp);`, you get automatic unpacking or a
> return of the error code.
>
> Granted, some might suggest that this is no less dangerous or
> performance-costly than exceptions. To which I answer... yeah. That's what
> happens when you want code to be able to transparently communicate with
> some other code that is an indeterminate number of function calls below it.
>
>
>> > And you can't say that it will always return to the caller of the
>> lambda's creator, because I don't have to still be on the stack. I can
>> return that lambda to someone else, wrapped in a `std::function`. How does
>> that work?
>>
>> UB, just as with capturing local variables by reference. Likewise if any
>> of the intervening frames are not unwinding aware.
>>
>
> The last example the OP posted makes a distinction between "capturing" by
> value vs. by reference. By reference `return` means causing a return from
> the most recent caller. By value `return` means causing a return from the
> code that created it.
>
> So really, the OP's proposal is kinda backwards from what you seem to be
> wanting (and to be honest, I rather prefer your interpretation).
> "Capturing" statements by reference is *safe* and such lambdas can be used
> anywhere (in theory), while "capturing" by value is unsafe.
>
> > A lambda in C++ is not some magical construct, imbued with fantastical
>> powers. In C++, a lambda is an object. Not only that, it is an instance of
>> a class type. You can rewrite any lambda as a local struct with a
>> constructor and an operator() overload (except for generic lambdas, but I'd
>> like to see that fixed). As it currently stands, a lambda cannot do
>> anything that a user-created class can't also do.
>>
>> There's another feature you're forgetting. Lambda captures can copy
>> arrays by value, which user code can't do without some heavy library
>> machinery
>>
>
> It doesn't take "heavy library machinery" to copy an array. Well, so long
> as the type is default-constructible and assignable.
>
> Ultimately, the point I'm making is that a lambda is not a special thing;
> it doesn't do anything you can't do yourself, even if doing it yourself is
> much harder. What's being proposed here is a deviation from that: you
> *cannot* replicate such behavior.
>
> And that ultimately limits the utility of the proposal.
>
> If we're talking user code equivalents, setjmp would do if it's
>> unwind-enabled, as would a custom exception in the absence of catch (...)
>> blocks, or even invoking the platform unwind machinery directly.
>>
>> > <snip>
>>
>> Sure, I get that you like that lambdas are mostly syntactic sugar. That
>> was probably necessary at the beginning, but it doesn't mean they have to
>> stay that way.
>>
>
> That's not a good enough reason to tie it to lambdas.
>
> Consider two of the examples provided here: `return_if` and `error_code`.
> Those patterns are quite useful for many  circumstances. And yet, there is
> no way to avoid re-typing them every time you want to use them without
> employing a macro. Why?
>
> Because the feature is tied to lambdas and their capture list. Remove that
> tie, and it suddenly becomes quite possible to have these as simply
> standard library template functions.
>
> --
> 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/dcb70287-4ee4-4cae-
> 9e09-4f7cab8d0db8%40isocpp.org
> <https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/dcb70287-4ee4-4cae-9e09-4f7cab8d0db8%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/CAEvHzA29Fv7c9Vk3bN5GwHjSbgNSGHEtUuNdhxAB3kENUWKt9g%40mail.gmail.com.

--001a1145b0b8793c07053c3e3e87
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<p dir=3D"ltr">Been following this thread, and I just want to chip in with =
a very important aspect: Readability. In ten cases of ten, I&#39;d use exce=
ptions as a mechanism to achieve the same behavior. Why? Because it&#39;s m=
ore readable, and not obfuscated.</p>
<div class=3D"gmail_extra"><br><div class=3D"gmail_quote">Den 11 sep 2016 1=
8:42 skrev &quot;Nicol Bolas&quot; &lt;<a href=3D"mailto:jmckesson@gmail.co=
m">jmckesson@gmail.com</a>&gt;:<br type=3D"attribution"><blockquote class=
=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padd=
ing-left:1ex"><div dir=3D"ltr">On Saturday, September 10, 2016 at 7:23:50 P=
M UTC-4, Edward Catmur wrote:<blockquote class=3D"gmail_quote" style=3D"mar=
gin:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-left:1ex"><p dir=
=3D"ltr"></p>
<p dir=3D"ltr">On 10 Sep 2016 04:46, &quot;Nicol Bolas&quot; &lt;<a rel=3D"=
nofollow">jmck...@gmail.com</a>&gt; wrote:<br>
&gt; See, it sounds like you&#39;re trying to say that returning from withi=
n the lambda will cause it to return from... well, that right there is the =
question. I think you want it to return from the function that called it. B=
ut how exactly is that supposed to happen?</p>
<p dir=3D"ltr">Stack unwinding. </p>
<p dir=3D"ltr">&gt; After all, the function that called it is not necessari=
ly the function that created it. What happens if you do this:<br>
&gt;<br>
&gt; ErrorCode save()<br>
&gt; {<br>
&gt; =C2=A0 =C2=A0 std::function&lt;void(ErrorCode)&gt; return_if =3D [&amp=
;return](auto retval){<br>
&gt;<br>
&gt; =C2=A0 =C2=A0 =C2=A0 =C2=A0 if (retval) { return retval; }<br>
&gt; =C2=A0 =C2=A0 };<br>
&gt;<br>
&gt; =C2=A0 =C2=A0 return_if(openFile());<br>
&gt; =C2=A0 =C2=A0 return_if(saveData());<br>
&gt; =C2=A0 =C2=A0 return_if(closeFile());<br>
&gt; }<br>
&gt;<br>
&gt; I have every reason to expect this to achieve the same effect. Yet I c=
annot imagine how that would be possible. After all, I don&#39;t call it. I=
 call `std::function::operator()`, which (eventually) calls the lambda. So =
the lambda will just provoke the return of some construct within the `std::=
function::operator()`.</p>
<p dir=3D"ltr">Stack unwinding isn&#39;t just for exceptions. The machinery=
 is there for non local jumps, such as thread cancellation, setjmp and SEH.=
 </p></blockquote><div><br>My first inclination is to say that this is just=
 exception handling with special cleanup work. Conceptually, it&#39;s indis=
tinguishable from:<br><br><div style=3D"background-color:rgb(250,250,250);b=
order-color:rgb(187,187,187);border-style:solid;border-width:1px;word-wrap:=
break-word"><code><div><span style=3D"color:#008">auto</span><span style=3D=
"color:#000"> x </span><span style=3D"color:#660">=3D</span><span style=3D"=
color:#000"> </span><span style=3D"color:#660">[]()</span><span style=3D"co=
lor:#000"> </span><span style=3D"color:#660">{...</span><span style=3D"colo=
r:#000"> </span><span style=3D"color:#008">throw</span><span style=3D"color=
:#000"> return_value</span><span style=3D"color:#660">(</span><span style=
=3D"color:#000">someValue</span><span style=3D"color:#660">);}</span><span =
style=3D"color:#000"> </span><span style=3D"color:#800">//Class template de=
duction</span><span style=3D"color:#000"><br><br></span><span style=3D"colo=
r:#008">try</span><span style=3D"color:#000"><br></span><span style=3D"colo=
r:#660">{</span><span style=3D"color:#000"><br>=C2=A0 </span><span style=3D=
"color:#008">auto</span><span style=3D"color:#000"> y </span><span style=3D=
"color:#660">=3D</span><span style=3D"color:#000"> x</span><span style=3D"c=
olor:#660">(</span><span style=3D"color:#000">foo</span><span style=3D"colo=
r:#660">);</span><span style=3D"color:#000"><br></span><span style=3D"color=
:#660">}</span><span style=3D"color:#000"><br></span><span style=3D"color:#=
008">catch</span><span style=3D"color:#660">(</span><span style=3D"color:#0=
00">return_value</span><span style=3D"color:#660">&lt;</span><span style=3D=
"color:#606">ReturnType</span><span style=3D"color:#660">&gt;</span><span s=
tyle=3D"color:#000"> </span><span style=3D"color:#660">&amp;</span><span st=
yle=3D"color:#000">t</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 </span><span style=3D"color:#008">return</span><=
span style=3D"color:#000"> std</span><span style=3D"color:#660">::</span><s=
pan style=3D"color:#000">move</span><span style=3D"color:#660">(</span><spa=
n style=3D"color:#000">t</span><span style=3D"color:#660">.</span><span sty=
le=3D"color:#008">get</span><span style=3D"color:#660">());</span><span sty=
le=3D"color:#000"><br></span><span style=3D"color:#660">}</span><span style=
=3D"color:#000"><br></span></div></code></div><br>Obviously that&#39;s both=
 incredibly verbose and traps `y` within a try-block. But the general idea =
you seem to want is the same; it&#39;s simply a matter of applying syntacti=
c sugar:<br><br><div style=3D"background-color:rgb(250,250,250);border-colo=
r:rgb(187,187,187);border-style:solid;border-width:1px;word-wrap:break-word=
"><code><div><span style=3D"color:#008">auto</span><span style=3D"color:#00=
0"> y </span><span style=3D"color:#660">=3D</span><span style=3D"color:#000=
"> </span><span style=3D"color:#008">try</span><span style=3D"color:#000"> =
x</span><span style=3D"color:#660">(</span><span style=3D"color:#000">foo</=
span><span style=3D"color:#660">);</span><span style=3D"color:#000"><br></s=
pan></div></code></div><br>Or something to that effect, with the compiler g=
enerating logic based on certain types being thrown. `std::return_value&lt;=
T&gt;` would provoke a return from that function of the stored `T`. `std::b=
reak_value` would provoke a `break`. If nothing is thrown, then the code pr=
oceeds as normal.<br><br>The `try` there is important for two reasons. Firs=
t, it lets the compiler know where to stop looking. And second, it makes cl=
ear to the reader that the code in question may experience an alternate con=
trol flow. Just as with any other `try` block.<br><br>A lambda does not see=
m to be the natural form of syntax for applying this. If you&#39;re going t=
o start doing stack unwinding and such, then it should be built on the lang=
uage mechanism that actually does stack unwinding.<br><br>Consider `expecte=
d&lt;T, E&gt;`. By decoupling this feature from lambdas, by giving <i>all</=
i> functions this power, we could give it an implicit `operator T` overload=
 that will either return a `T` or throw a return of `E`. So if you do `auto=
 x =3D try Typename(exp);`, you get automatic unpacking or a return of the =
error code.<br><br>Granted, some might suggest that this is no less dangero=
us or performance-costly than exceptions. To which I answer... yeah. That&#=
39;s what happens when you want code to be able to transparently communicat=
e with some other code that is an indeterminate number of function calls be=
low it.<br>=C2=A0</div><blockquote class=3D"gmail_quote" style=3D"margin:0;=
margin-left:0.8ex;border-left:1px #ccc solid;padding-left:1ex">
<p dir=3D"ltr">&gt; And you can&#39;t say that it will always return to the=
 caller of the lambda&#39;s creator, because I don&#39;t have to still be o=
n the stack. I can return that lambda to someone else, wrapped in a `std::f=
unction`. How does that work?</p>
<p dir=3D"ltr">UB, just as with capturing local variables by reference. Lik=
ewise if any of the intervening frames are not unwinding aware. </p></block=
quote><div><br>The last example the OP posted makes a distinction between &=
quot;capturing&quot; by value vs. by reference. By reference `return` means=
 causing a return from the most recent caller. By value `return` means caus=
ing a return from the code that created it.<br><br>So really, the OP&#39;s =
proposal is kinda backwards from what you seem to be wanting (and to be hon=
est, I rather prefer your interpretation). &quot;Capturing&quot; statements=
 by reference is *safe* and such lambdas can be used anywhere (in theory), =
while &quot;capturing&quot; by value is unsafe.<br><br></div><blockquote cl=
ass=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1px #cc=
c solid;padding-left:1ex">
<p dir=3D"ltr">&gt; A lambda in C++ is not some magical construct, imbued w=
ith fantastical powers. In C++, a lambda is an object. Not only that, it is=
 an instance of a class type. You can rewrite any lambda as a local struct =
with a constructor and an operator() overload (except for generic lambdas, =
but I&#39;d like to see that fixed). As it currently stands, a lambda canno=
t do anything that a user-created class can&#39;t also do.</p>
<p dir=3D"ltr">There&#39;s another feature you&#39;re forgetting. Lambda ca=
ptures can copy arrays by value, which user code can&#39;t do without some =
heavy library machinery</p></blockquote><div><br>It doesn&#39;t take &quot;=
heavy library machinery&quot; to copy an array. Well, so long as the type i=
s default-constructible and assignable.<br><br>Ultimately, the point I&#39;=
m making is that a lambda is not a special thing; it doesn&#39;t do anythin=
g you can&#39;t do yourself, even if doing it yourself is much harder. What=
&#39;s being proposed here is a deviation from that: you <i>cannot</i> repl=
icate such behavior.<br><br>And that ultimately limits the utility of the p=
roposal.<br><br></div><blockquote class=3D"gmail_quote" style=3D"margin:0;m=
argin-left:0.8ex;border-left:1px #ccc solid;padding-left:1ex"><p dir=3D"ltr=
"> </p>
<p dir=3D"ltr">If we&#39;re talking user code equivalents, setjmp would do =
if it&#39;s unwind-enabled, as would a custom exception in the absence of c=
atch (...) blocks, or even invoking the platform unwind machinery directly.=
 </p>
<p dir=3D"ltr">&gt; &lt;snip&gt;</p>
<p dir=3D"ltr">Sure, I get that you like that lambdas are mostly syntactic =
sugar. That was probably necessary at the beginning, but it doesn&#39;t mea=
n they have to stay that way.</p></blockquote><div><br>That&#39;s not a goo=
d enough reason to tie it to lambdas.<br><br>Consider two of the examples p=
rovided here: `return_if` and `error_code`. Those patterns are quite useful=
 for many=C2=A0 circumstances. And yet, there is no way to avoid re-typing =
them every time you want to use them without employing a macro. Why?<br><br=
>Because the feature is tied to lambdas and their capture list. Remove that=
 tie, and it suddenly becomes quite possible to have these as simply standa=
rd library template functions.<br></div></div>

<p></p>

-- <br>
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; 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>
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/dcb70287-4ee4-4cae-9e09-4f7cab8d0db8%=
40isocpp.org?utm_medium=3Demail&amp;utm_source=3Dfooter" target=3D"_blank">=
https://groups.google.com/a/<wbr>isocpp.org/d/msgid/std-<wbr>proposals/dcb7=
0287-4ee4-4cae-<wbr>9e09-4f7cab8d0db8%40isocpp.org</a><wbr>.<br>
</blockquote></div></div>

<p></p>

-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; 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/CAEvHzA29Fv7c9Vk3bN5GwHjSbgNSGHEtUuNd=
hxAB3kENUWKt9g%40mail.gmail.com?utm_medium=3Demail&utm_source=3Dfooter">htt=
ps://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CAEvHzA29Fv7c9Vk3=
bN5GwHjSbgNSGHEtUuNdhxAB3kENUWKt9g%40mail.gmail.com</a>.<br />

--001a1145b0b8793c07053c3e3e87--

.


Author: szollosi.lorand@gmail.com
Date: Mon, 12 Sep 2016 00:03:00 -0700 (PDT)
Raw View
------=_Part_347_459343644.1473663780744
Content-Type: multipart/alternative;
 boundary="----=_Part_348_571051553.1473663780745"

------=_Part_348_571051553.1473663780745
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

Hi,

Thanks for the comment from both of you, it's very helpful and gives me=20
hints on what to rephrase to make it easier to understand. Please bear with=
=20
me, I hope I can make it clearer :).

First of all, I'm not planning it for lambdas only - it's just the best use=
=20
case for me. Also, it helps me bring multiple language features to a=20
simpler one. I do encourage making `return` capture available to functions,=
=20
functors, etc.. - but I still have the for-loop glasses on :).

> std::function<void(ErrorCode)> return_if =3D [&return](auto retval){ ... =
};
So, let's distinguish two use cases: (NB. I use 'stack' as a synonym of=20
scoped variables, not as a data structure)

   - [=3Dreturn], by value capture, should provide a 'noreturn functor'=20
   (terminology to be cleared up) that, when called, will unwind the stack =
to=20
   the point we *defined* it, then perform the 'return' of that point.=20
   Therefore, the type it should accept is the return type of the function =
*defining=20
   it*. As Edward wrote, it's essentially the same as setjmp() with return=
=20
   / longjmp() in an object-oriented way.
   - It can only be defined in a function. If the capturing function has=20
      returned, it's UB to call it.
      - The above implies that it's UB to call it twice.
      - It can be simulated by a `try { ... } catch(NonLocalReturn<type>&=
=20
      r) { return r.get(); }` block at the *defining* point; however, it=20
      can be done more efficiently.
      - Parameter type of the returning functor is defined by the *defining=
*=20
      context - this can be checked compile-time.
      - [&return], by reference capture might have a different meaning in=
=20
   each point of execution. At the *calling point* (thus not at the point=
=20
   of definition) it should provide a 'noreturn fuctor' that, when executed=
,=20
   will unwind the stack to the point we *called* it, then perform the=20
   'return' of that point. Therefore, the returning functor provided can on=
ly=20
   be called with the return type of the caller. It can be thought of an=20
   additional parameter to the function/functor/lambda - whether that needs=
 to=20
   be templated is up to discussion.
      - There's no restriction on where to define and call it. E.g., it's=
=20
      well-defined to call it after the defining function.
      - Calling the returning functor twice (e.g. by passing it as a=20
      parameter of the first call of it) is well-defined.
      - It can be simulated by a `try { ... } catch(NonLocalReturn<type>&=
=20
      r) { return r.get(); }` block at *each* *calling* point; however, it=
=20
      can be done more efficiently.
      - Parameter type of the returning functor is defined by the *calling*=
=20
      context - this can be checked compile-time at *each point of call*.=
=20
      Note that these types might be different (conversion rules apply).
   - break and continue:
      - [=3Dbreak], [=3Dcontinue] are defined as [=3Dreturn], except for
         - these can only be *defined* in a context where break and=20
         continue are valid;
         - [&break], [&continue] are defined as [&return], except for
         - these can only be *called* in a context where break and continue=
=20
         are valid;
         - Except for, for all the four:
         - breaking and continuing functors accept no parameters
         - these perform break and continue instead of return.
     =20
This implies that [&return] is invalid for std::function<void(ErrorCode)>,=
=20
while [=3Dreturn] should do what you expect it to do. It also implies, if w=
e=20
use careful wording, that [&return] is available for functions and member=
=20
functions - either by this capture, or the more convenient parameter syntax=
=20
(e.g.,`int f(int a, T ret =3D &return) { ... }`).


However, I'd go one step further. We can now think of code blocks, lambdas=
=20
and bodies of for-loops in a unified manner. I'm not saying to rewrite=20
compilers to this style, but it simplifies understanding for me. E.g. a=20
body {} of a for-loop (that's repeated by `for`)is nothing different from a=
=20
lambda that captures &return, redefines break and continue; and a `for`=20
becomes a transformation on the lambda. These transformations, *if we wish*=
,=20
can be made available to the user at no additional cost.


Note that the complex checks that exception handling is built upon is=20
unnecessary for this return logic. An exception must check each=20
catch()-block in reverse of the calling order and check if there's a type=
=20
match. For these captures, there's one type accepted and one point to=20
return to (per captured item), thus no checks for each stack frame is=20
necessary. It's also way more strict, providing compile-time errors if you=
=20
pass an incorrect type (rather than runtime issues that you get with=20
uncaught exceptions). The second is why I'd use this rather than exceptions=
..


As for the example with accumulate, `[return_accumulated=3Dreturn](double a=
,=20
double b){ if(b=3D=3D0) return_accumulated(0); return a*b; }` is a trivial=
=20
optimization.


Macros and syntax: I'm not committed to any specific syntax yet. The one=20
I've listed above is indeed verbose, it's simply to help discuss the scope=
=20
and functionality. At a later step we might refine syntax, simplify base=20
cases, clean it up, etc. Right now what I'd like to see is if we could=20
cover the usual for-extensions, non-local return/break/continue and=20
similar, frequently asked feature requests - and if yes, could we unify the=
=20
syntax a bit..


Thanks again for your help on this,

-lorro



2016. szeptember 11., vas=C3=A1rnap 1:23:50 UTC+2 id=C5=91pontban Edward Ca=
tmur a=20
k=C3=B6vetkez=C5=91t =C3=ADrta:
>
> On 10 Sep 2016 04:46, "Nicol Bolas" <jmck...@gmail.com <javascript:>>=20
> wrote:
> > See, it sounds like you're trying to say that returning from within the=
=20
> lambda will cause it to return from... well, that right there is the=20
> question. I think you want it to return from the function that called it.=
=20
> But how exactly is that supposed to happen?
>
> Stack unwinding.=20
>
> > After all, the function that called it is not necessarily the function=
=20
> that created it. What happens if you do this:
> >
> > ErrorCode save()
> > {
> >     std::function<void(ErrorCode)> return_if =3D [&return](auto retval)=
{
> >
> >         if (retval) { return retval; }
> >     };
> >
> >     return_if(openFile());
> >     return_if(saveData());
> >     return_if(closeFile());
> > }
> >
> > I have every reason to expect this to achieve the same effect. Yet I=20
> cannot imagine how that would be possible. After all, I don't call it. I=
=20
> call `std::function::operator()`, which (eventually) calls the lambda. So=
=20
> the lambda will just provoke the return of some construct within the=20
> `std::function::operator()`.
>
> Stack unwinding isn't just for exceptions. The machinery is there for non=
=20
> local jumps, such as thread cancellation, setjmp and SEH.=20
>
> > And you can't say that it will always return to the caller of the=20
> lambda's creator, because I don't have to still be on the stack. I can=20
> return that lambda to someone else, wrapped in a `std::function`. How doe=
s=20
> that work?
>
> UB, just as with capturing local variables by reference. Likewise if any=
=20
> of the intervening frames are not unwinding aware.=20
>
> > A lambda in C++ is not some magical construct, imbued with fantastical=
=20
> powers. In C++, a lambda is an object. Not only that, it is an instance o=
f=20
> a class type. You can rewrite any lambda as a local struct with a=20
> constructor and an operator() overload (except for generic lambdas, but I=
'd=20
> like to see that fixed). As it currently stands, a lambda cannot do=20
> anything that a user-created class can't also do.
>
> There's another feature you're forgetting. Lambda captures can copy array=
s=20
> by value, which user code can't do without some heavy library machinery.=
=20
>
> If we're talking user code equivalents, setjmp would do if it's=20
> unwind-enabled, as would a custom exception in the absence of catch (...)=
=20
> blocks, or even invoking the platform unwind machinery directly.=20
>
> > <snip>
>
> Sure, I get that you like that lambdas are mostly syntactic sugar. That=
=20
> was probably necessary at the beginning, but it doesn't mean they have to=
=20
> stay that way.=20
>

--=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp=
..org/d/msgid/std-proposals/c132d0fe-9ce5-4e1e-9d75-5766b23ad27f%40isocpp.or=
g.

------=_Part_348_571051553.1473663780745
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">Hi,<br><br>Thanks for the comment from both of you, it&#39=
;s very helpful and gives me hints on what to rephrase to make it easier to=
 understand. Please bear with me, I hope I can make it clearer :).<br><br>F=
irst of all, I&#39;m not planning it for lambdas only - it&#39;s just the b=
est use case for me. Also, it helps me bring multiple language features to =
a simpler one. I do encourage making `return` capture available to function=
s, functors, etc.. - but I still have the for-loop glasses on :).<br><br>&g=
t; std::function&lt;void(ErrorCode)&gt; return_if =3D [&amp;return](auto re=
tval){ ... };<br>So, let&#39;s distinguish two use cases: (NB. I use &#39;s=
tack&#39; as a synonym of scoped variables, not as a data structure)<br><ul=
><li>[=3Dreturn], by value capture, should provide a &#39;noreturn functor&=
#39; (terminology to be cleared up) that, when called, will unwind the stac=
k to the point we <i>defined</i> it, then perform the &#39;return&#39; of t=
hat point. Therefore, the type it should accept is the return type of the f=
unction <i>defining it</i>. As Edward wrote, it&#39;s essentially the same =
as setjmp() with return / longjmp() in an object-oriented way.<br></li><ul>=
<li>It can only be defined in a function. If the capturing function has ret=
urned, it&#39;s UB to call it.</li><li>The above implies that it&#39;s UB t=
o call it twice.</li><li>It can be simulated by a `try { ... } catch(NonLoc=
alReturn&lt;type&gt;&amp; r) { return r.get(); }` block at the <i>defining<=
/i> point; however, it can be done more efficiently.</li><li>Parameter type=
 of the returning functor is defined by the <i>defining</i> context - this =
can be checked compile-time.<br></li></ul><li>[&amp;return], by reference c=
apture might have a different meaning in each point of execution. At the <i=
>calling point</i> (thus not at the point of definition) it should provide =
a &#39;noreturn fuctor&#39; that, when executed, will unwind the stack to t=
he point we <i>called</i> it, then perform the &#39;return&#39; of that poi=
nt. Therefore, the returning functor provided can only be called with the r=
eturn type of the caller. It can be thought of an additional parameter to t=
he function/functor/lambda - whether that needs to be templated is up to di=
scussion.</li><ul><li>There&#39;s no restriction on where to define and cal=
l it. E.g., it&#39;s well-defined to call it after the defining function.</=
li><li>Calling the returning functor twice (e.g. by passing it as a paramet=
er of the first call of it) is well-defined.</li><li>It can be simulated by=
 a `try { ... }=20
catch(NonLocalReturn&lt;type&gt;&amp; r) { return r.get(); }` block at <i>e=
ach</i> <i>calling</i> point; however, it can be done more efficiently.</li=
><li>Parameter type of the returning functor is defined by the <i>calling</=
i> context - this can be checked compile-time at <i>each point of call</i>.=
 Note that these types might be different (conversion rules apply).</li></u=
l><li>break and continue:</li><ul><li>[=3Dbreak], [=3Dcontinue] are defined=
 as [=3Dreturn], except for</li><ul><li>these can only be <i>defined</i> in=
 a context where break and continue are valid;<br></li></ul><li>[&amp;break=
], [&amp;continue] are defined as [&amp;return], except for</li><ul><li>the=
se can only be <i>called</i> in a context where break and continue are vali=
d;<br></li></ul><li>Except for, for all the four:</li><ul><li>breaking and =
continuing functors accept no parameters</li><li>these perform break and co=
ntinue instead of return.</li></ul></ul></ul><p>This implies that [&amp;ret=
urn] is invalid for std::function&lt;void(ErrorCode)&gt;, while [=3Dreturn]=
 should do what you expect it to do. It also implies, if we use careful wor=
ding, that [&amp;return] is available for functions and member functions - =
either by this capture, or the more convenient parameter syntax (e.g.,`int =
f(int a, T ret =3D &amp;return) { ... }`).<br></p><p><br></p><p>However, I&=
#39;d go one step further. We can now think of code blocks, lambdas and bod=
ies of for-loops in a unified manner. I&#39;m not saying to rewrite compile=
rs to this style, but it simplifies understanding for me. E.g. a body {} of=
 a for-loop (that&#39;s repeated by `for`)is nothing different from a lambd=
a that captures &amp;return, redefines break and continue; and a `for` beco=
mes a transformation on the lambda. These transformations, <i>if we wish</i=
>, can be made available to the user at no additional cost.<br></p><p><br><=
/p><p>Note that the complex checks that exception handling is built upon is=
 unnecessary for this return logic. An exception must check each catch()-bl=
ock in reverse of the calling order and check if there&#39;s a type match. =
For these captures, there&#39;s one type accepted and one point to return t=
o (per captured item), thus no checks for each stack frame is necessary. It=
&#39;s also way more strict, providing compile-time errors if you pass an i=
ncorrect type (rather than runtime issues that you get with uncaught except=
ions). The second is why I&#39;d use this rather than exceptions.</p><p><br=
></p><p>As for the example with accumulate, `[return_accumulated=3Dreturn](=
double a, double b){ if(b=3D=3D0) return_accumulated(0); return a*b; }` is =
a trivial optimization.</p><p><br></p><p>Macros and syntax: I&#39;m not com=
mitted to any specific syntax yet. The one I&#39;ve listed above is indeed =
verbose, it&#39;s simply to help discuss the scope and functionality. At a =
later step we might refine syntax, simplify base cases, clean it up, etc. R=
ight now what I&#39;d like to see is if we could cover the usual for-extens=
ions, non-local return/break/continue and similar, frequently asked feature=
 requests - and if yes, could we unify the syntax a bit..<br></p><p><br></p=
><p>Thanks again for your help on this,</p><p>-lorro<br></p><p><br></p><p><=
br></p>2016. szeptember 11., vas=C3=A1rnap 1:23:50 UTC+2 id=C5=91pontban Ed=
ward Catmur a k=C3=B6vetkez=C5=91t =C3=ADrta:<blockquote class=3D"gmail_quo=
te" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;paddi=
ng-left: 1ex;"><p dir=3D"ltr"></p>
<p dir=3D"ltr">On 10 Sep 2016 04:46, &quot;Nicol Bolas&quot; &lt;<a href=3D=
"javascript:" target=3D"_blank" gdf-obfuscated-mailto=3D"hiZRUIyVFQAJ" rel=
=3D"nofollow" onmousedown=3D"this.href=3D&#39;javascript:&#39;;return true;=
" onclick=3D"this.href=3D&#39;javascript:&#39;;return true;">jmck...@gmail.=
com</a>&gt; wrote:<br>
&gt; See, it sounds like you&#39;re trying to say that returning from withi=
n the lambda will cause it to return from... well, that right there is the =
question. I think you want it to return from the function that called it. B=
ut how exactly is that supposed to happen?</p>
<p dir=3D"ltr">Stack unwinding. </p>
<p dir=3D"ltr">&gt; After all, the function that called it is not necessari=
ly the function that created it. What happens if you do this:<br>
&gt;<br>
&gt; ErrorCode save()<br>
&gt; {<br>
&gt; =C2=A0 =C2=A0 std::function&lt;void(ErrorCode)&gt; return_if =3D [&amp=
;return](auto retval){<br>
&gt;<br>
&gt; =C2=A0 =C2=A0 =C2=A0 =C2=A0 if (retval) { return retval; }<br>
&gt; =C2=A0 =C2=A0 };<br>
&gt;<br>
&gt; =C2=A0 =C2=A0 return_if(openFile());<br>
&gt; =C2=A0 =C2=A0 return_if(saveData());<br>
&gt; =C2=A0 =C2=A0 return_if(closeFile());<br>
&gt; }<br>
&gt;<br>
&gt; I have every reason to expect this to achieve the same effect. Yet I c=
annot imagine how that would be possible. After all, I don&#39;t call it. I=
 call `std::function::operator()`, which (eventually) calls the lambda. So =
the lambda will just provoke the return of some construct within the `std::=
function::operator()`.</p>
<p dir=3D"ltr">Stack unwinding isn&#39;t just for exceptions. The machinery=
 is there for non local jumps, such as thread cancellation, setjmp and SEH.=
 </p>
<p dir=3D"ltr">&gt; And you can&#39;t say that it will always return to the=
 caller of the lambda&#39;s creator, because I don&#39;t have to still be o=
n the stack. I can return that lambda to someone else, wrapped in a `std::f=
unction`. How does that work?</p>
<p dir=3D"ltr">UB, just as with capturing local variables by reference. Lik=
ewise if any of the intervening frames are not unwinding aware. </p>
<p dir=3D"ltr">&gt; A lambda in C++ is not some magical construct, imbued w=
ith fantastical powers. In C++, a lambda is an object. Not only that, it is=
 an instance of a class type. You can rewrite any lambda as a local struct =
with a constructor and an operator() overload (except for generic lambdas, =
but I&#39;d like to see that fixed). As it currently stands, a lambda canno=
t do anything that a user-created class can&#39;t also do.</p>
<p dir=3D"ltr">There&#39;s another feature you&#39;re forgetting. Lambda ca=
ptures can copy arrays by value, which user code can&#39;t do without some =
heavy library machinery. </p>
<p dir=3D"ltr">If we&#39;re talking user code equivalents, setjmp would do =
if it&#39;s unwind-enabled, as would a custom exception in the absence of c=
atch (...) blocks, or even invoking the platform unwind machinery directly.=
 </p>
<p dir=3D"ltr">&gt; &lt;snip&gt;</p>
<p dir=3D"ltr">Sure, I get that you like that lambdas are mostly syntactic =
sugar. That was probably necessary at the beginning, but it doesn&#39;t mea=
n they have to stay that way. </p>
</blockquote></div>

<p></p>

-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; 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/c132d0fe-9ce5-4e1e-9d75-5766b23ad27f%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/c132d0fe-9ce5-4e1e-9d75-5766b23ad27f=
%40isocpp.org</a>.<br />

------=_Part_348_571051553.1473663780745--

------=_Part_347_459343644.1473663780744--

.


Author: "D. B." <db0451@gmail.com>
Date: Mon, 12 Sep 2016 08:28:22 +0100
Raw View
--001a114e3072e5aaf5053c4a7000
Content-Type: text/plain; charset=UTF-8

I can't help but feel that the chosen capturing methods of &/= for
return-from-definer vs -caller respectively are arbitrary and confusing.
Certainly they have no parity with current variable captures, while
stealing syntax from them.. In fact, to me, it would make more sense for
return-from-definer to be captured as &return (opposite to what you have
now) and return-from-caller to be captured as an additional argument to the
lambda function call.

But that assumes you want to, or that it's possible to, implement this
while maintaining any intuitive degree of consistency with current usage.
I'm not sure that's possible.

but oh, hey - maybe you could instead distinguish between the two possible
points of return/break/whatever by hijacking static and extern instead! so
capturing "extern return" would mean 'return here, regardless of where
you're called', but capturing "static return" would mean 'return from the
cnotext in whcih you're called'. Is that a decent or terrible idea? I can't
tell.

--
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/CACGiwhH5Z8A7JSptQA6agd3pY55%2BZaim%3Dzq--%2BHp8S%3Da3Jc%3DzA%40mail.gmail.com.

--001a114e3072e5aaf5053c4a7000
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><div><div><div>I can&#39;t help but feel that the chosen c=
apturing methods of &amp;/=3D for return-from-definer vs -caller respective=
ly are arbitrary and confusing. Certainly they have no parity with current =
variable captures, while stealing syntax from them.. In fact, to me, it wou=
ld make more sense for return-from-definer to be captured as &amp;return (o=
pposite to what you have now) and return-from-caller to be captured as an a=
dditional argument to the lambda function call.<br><br></div>But that assum=
es you want to, or that it&#39;s possible to, implement this while maintain=
ing any intuitive degree of consistency with current usage. I&#39;m not sur=
e that&#39;s possible.<br><br></div>but oh, hey - maybe you could instead d=
istinguish between the two possible points of return/break/whatever by hija=
cking static and extern instead! so capturing &quot;extern return&quot; wou=
ld mean &#39;return here, regardless of where you&#39;re called&#39;, but c=
apturing &quot;static return&quot; would mean &#39;return from the cnotext =
in whcih you&#39;re called&#39;. Is that a decent or terrible idea? I can&#=
39;t tell.<br><br></div></div>

<p></p>

-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; 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/CACGiwhH5Z8A7JSptQA6agd3pY55%2BZaim%3=
Dzq--%2BHp8S%3Da3Jc%3DzA%40mail.gmail.com?utm_medium=3Demail&utm_source=3Df=
ooter">https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CACGiwh=
H5Z8A7JSptQA6agd3pY55%2BZaim%3Dzq--%2BHp8S%3Da3Jc%3DzA%40mail.gmail.com</a>=
..<br />

--001a114e3072e5aaf5053c4a7000--

.


Author: "D. B." <db0451@gmail.com>
Date: Mon, 12 Sep 2016 08:32:36 +0100
Raw View
--089e013d171c05656d053c4a8039
Content-Type: text/plain; charset=UTF-8

Gah. Aside from the numerous typos, of course I got the symbols here the
wrong way around, so that first line should read:

"I can't help but feel that the chosen capturing methods of =/& for
return-from-definer vs -caller respectively are arbitrary and confusing."

I also see that you did say that from-caller &return can be thought of as
an extra parameter, so again, not phrasing it as one is counterintuitive.
But then sandwiching it into the args might also have issues. Either
way,you're right that it might make sense to explicitly template it.

--
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/CACGiwhFE6Q47qoaKy4ww39xu-6dPt%3DSf%2Bg2z3ZcrfLxyo3zQQg%40mail.gmail.com.

--089e013d171c05656d053c4a8039
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><div><div>Gah. Aside from the numerous typos, of course I =
got the symbols here the wrong way around, so that first line should read:<=
br><br></div>&quot;I can&#39;t help but feel that the chosen capturing meth=
ods of <font size=3D"4">=3D/&amp;</font> for=20
return-from-definer vs -caller respectively are arbitrary and confusing.&qu=
ot;<br><br></div>I also see that you did say that from-caller &amp;return c=
an be thought of as an extra parameter, so again, not phrasing it as one is=
 counterintuitive. But then sandwiching it into the args might also have is=
sues. Either way,you&#39;re right that it might make sense to explicitly te=
mplate it.<br><br><div><div><div><br><br></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&quot; 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/CACGiwhFE6Q47qoaKy4ww39xu-6dPt%3DSf%2=
Bg2z3ZcrfLxyo3zQQg%40mail.gmail.com?utm_medium=3Demail&utm_source=3Dfooter"=
>https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CACGiwhFE6Q47=
qoaKy4ww39xu-6dPt%3DSf%2Bg2z3ZcrfLxyo3zQQg%40mail.gmail.com</a>.<br />

--089e013d171c05656d053c4a8039--

.


Author: szollosi.lorand@gmail.com
Date: Mon, 12 Sep 2016 12:31:47 -0700 (PDT)
Raw View
------=_Part_1444_1613366451.1473708707743
Content-Type: multipart/alternative;
 boundary="----=_Part_1445_803466509.1473708707743"

------=_Part_1445_803466509.1473708707743
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

Hi,

I'm happy with whatever syntax we come up with. Note that I'm not intending=
=20
to hijack lambda capture syntax, I'm saying that `auto myReturn =3D static=
=20
return;` and `auto myReturn =3D extern return;` are also valid e.g. in=20
functions. These will produce [[noreturn]] functors (one of them having=20
multiple overloads/templates), but also provide diagnostics if incorrect=20
type is used. What do you think?

Thanks,
-lorro

2016. szeptember 12., h=C3=A9tf=C5=91 9:32:38 UTC+2 id=C5=91pontban D. B. a=
 k=C3=B6vetkez=C5=91t=20
=C3=ADrta:
>
> Gah. Aside from the numerous typos, of course I got the symbols here the=
=20
> wrong way around, so that first line should read:
>
> "I can't help but feel that the chosen capturing methods of =3D/& for=20
> return-from-definer vs -caller respectively are arbitrary and confusing."
>
> I also see that you did say that from-caller &return can be thought of as=
=20
> an extra parameter, so again, not phrasing it as one is counterintuitive.=
=20
> But then sandwiching it into the args might also have issues. Either=20
> way,you're right that it might make sense to explicitly template it.
>
>
>
>

--=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp=
..org/d/msgid/std-proposals/39495257-0cb4-49fd-a49f-5cecb981b1bc%40isocpp.or=
g.

------=_Part_1445_803466509.1473708707743
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">Hi,<br><br>I&#39;m happy with whatever syntax we come up w=
ith. Note that I&#39;m not intending to hijack lambda capture syntax, I&#39=
;m saying that `auto myReturn =3D static return;` and `auto myReturn =3D ex=
tern return;` are also valid e.g. in functions. These will produce [[noretu=
rn]] functors (one of them having multiple overloads/templates), but also p=
rovide diagnostics if incorrect type is used. What do you think?<br><br>Tha=
nks,<br>-lorro<br><br>2016. szeptember 12., h=C3=A9tf=C5=91 9:32:38 UTC+2 i=
d=C5=91pontban D. B. a k=C3=B6vetkez=C5=91t =C3=ADrta:<blockquote class=3D"=
gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc so=
lid;padding-left: 1ex;"><div dir=3D"ltr"><div><div>Gah. Aside from the nume=
rous typos, of course I got the symbols here the wrong way around, so that =
first line should read:<br><br></div>&quot;I can&#39;t help but feel that t=
he chosen capturing methods of <font size=3D"4">=3D/&amp;</font> for=20
return-from-definer vs -caller respectively are arbitrary and confusing.&qu=
ot;<br><br></div>I also see that you did say that from-caller &amp;return c=
an be thought of as an extra parameter, so again, not phrasing it as one is=
 counterintuitive. But then sandwiching it into the args might also have is=
sues. Either way,you&#39;re right that it might make sense to explicitly te=
mplate it.<br><br><div><div><div><br><br></div></div></div></div>
</blockquote></div>

<p></p>

-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; 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/39495257-0cb4-49fd-a49f-5cecb981b1bc%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/39495257-0cb4-49fd-a49f-5cecb981b1bc=
%40isocpp.org</a>.<br />

------=_Part_1445_803466509.1473708707743--

------=_Part_1444_1613366451.1473708707743--

.


Author: szollosi.lorand@gmail.com
Date: Mon, 12 Sep 2016 13:25:08 -0700 (PDT)
Raw View
------=_Part_3296_1993062390.1473711908746
Content-Type: multipart/alternative;
 boundary="----=_Part_3297_2044650912.1473711908747"

------=_Part_3297_2044650912.1473711908747
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

P.S. how about return const (to the capture point's caller) and return=20
mutable or volatile (to the current caller)?

2016. szeptember 12., h=C3=A9tf=C5=91 21:31:47 UTC+2 id=C5=91pontban szollo=
s...@gmail.com=20
a k=C3=B6vetkez=C5=91t =C3=ADrta:
>
> Hi,
>
> I'm happy with whatever syntax we come up with. Note that I'm not=20
> intending to hijack lambda capture syntax, I'm saying that `auto myReturn=
 =3D=20
> static return;` and `auto myReturn =3D extern return;` are also valid e.g=
.. in=20
> functions. These will produce [[noreturn]] functors (one of them having=
=20
> multiple overloads/templates), but also provide diagnostics if incorrect=
=20
> type is used. What do you think?
>
> Thanks,
> -lorro
>
> 2016. szeptember 12., h=C3=A9tf=C5=91 9:32:38 UTC+2 id=C5=91pontban D. B.=
 a k=C3=B6vetkez=C5=91t=20
> =C3=ADrta:
>>
>> Gah. Aside from the numerous typos, of course I got the symbols here the=
=20
>> wrong way around, so that first line should read:
>>
>> "I can't help but feel that the chosen capturing methods of =3D/& for=20
>> return-from-definer vs -caller respectively are arbitrary and confusing.=
"
>>
>> I also see that you did say that from-caller &return can be thought of a=
s=20
>> an extra parameter, so again, not phrasing it as one is counterintuitive=
..=20
>> But then sandwiching it into the args might also have issues. Either=20
>> way,you're right that it might make sense to explicitly template it.
>>
>>
>>
>>

--=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp=
..org/d/msgid/std-proposals/ee87bb47-b1ad-40a8-ab4e-3d0791fb4c43%40isocpp.or=
g.

------=_Part_3297_2044650912.1473711908747
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">P.S. how about return const (to the capture point&#39;s ca=
ller) and return mutable or volatile (to the current caller)?<br><br>2016. =
szeptember 12., h=C3=A9tf=C5=91 21:31:47 UTC+2 id=C5=91pontban szollos...@g=
mail.com a k=C3=B6vetkez=C5=91t =C3=ADrta:<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">Hi,<br><br>I&#39;m happy with whatever syntax =
we come up with. Note that I&#39;m not intending to hijack lambda capture s=
yntax, I&#39;m saying that `auto myReturn =3D static return;` and `auto myR=
eturn =3D extern return;` are also valid e.g. in functions. These will prod=
uce [[noreturn]] functors (one of them having multiple overloads/templates)=
, but also provide diagnostics if incorrect type is used. What do you think=
?<br><br>Thanks,<br>-lorro<br><br>2016. szeptember 12., h=C3=A9tf=C5=91 9:3=
2:38 UTC+2 id=C5=91pontban D. B. a k=C3=B6vetkez=C5=91t =C3=ADrta:<blockquo=
te class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1p=
x #ccc solid;padding-left:1ex"><div dir=3D"ltr"><div><div>Gah. Aside from t=
he numerous typos, of course I got the symbols here the wrong way around, s=
o that first line should read:<br><br></div>&quot;I can&#39;t help but feel=
 that the chosen capturing methods of <font size=3D"4">=3D/&amp;</font> for=
=20
return-from-definer vs -caller respectively are arbitrary and confusing.&qu=
ot;<br><br></div>I also see that you did say that from-caller &amp;return c=
an be thought of as an extra parameter, so again, not phrasing it as one is=
 counterintuitive. But then sandwiching it into the args might also have is=
sues. Either way,you&#39;re right that it might make sense to explicitly te=
mplate it.<br><br><div><div><div><br><br></div></div></div></div>
</blockquote></div></blockquote></div>

<p></p>

-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; 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/ee87bb47-b1ad-40a8-ab4e-3d0791fb4c43%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/ee87bb47-b1ad-40a8-ab4e-3d0791fb4c43=
%40isocpp.org</a>.<br />

------=_Part_3297_2044650912.1473711908747--

------=_Part_3296_1993062390.1473711908746--

.


Author: Arthur O'Dwyer <arthur.j.odwyer@gmail.com>
Date: Mon, 12 Sep 2016 17:58:00 -0700 (PDT)
Raw View
------=_Part_48_1738796180.1473728280881
Content-Type: multipart/alternative;
 boundary="----=_Part_49_494265151.1473728280881"

------=_Part_49_494265151.1473728280881
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

Rather than bikeshedding the syntax, I think you need to take a step back=
=20
and explain what this proposed feature *is*. Right now, it reads like one=
=20
of those joke programming languages like INTERCAL or TURKEY BOMB where=20
words are just thrown together for comedic effect, rather than for=20
intrinsic meaning (let alone usefulness).

What would it mean for a function to "break, but in its caller's context"?
You need to show a specific example of the semantics you're trying to=20
achieve, in the form of
- a library solution (perhaps involving setjmp/longjmp or=20
exception-handling under the hood), and/or
- assembly code for a non-trivial use of the proposed feature.

You get close to that with your statement
> It can be simulated by a `try { ... } catch(NonLocalReturn<type>& r) {=20
return r.get(); }` block at *each* *calling* point; however, it can be done=
=20
more efficiently.

but you need to explain *how* it can be done more efficiently; and besides,
- that only helps for the "return from local caller" case, not "return from=
=20
original creator";
- that only has an obvious translation if type is known beforehand;
- the obvious translation is to wrap *literally every function call* in=20
this boilerplate (since we can't tell which functors might or might not=20
have these new semantics).

If you can't explain the practical semantics of your proposal, then you're=
=20
operating solidly in joke-language territory: "Hey, I think C++ should have=
=20
a COME FROM statement!"  "I think instead of BITs we should use AMICEDs,=20
which are negative six-sevenths of a decimal digit!"  All this bikeshedding=
=20
about the *spelling* of the COME FROM statement is completely beside the=20
point.

=E2=80=93Arthur

P.S. =E2=80=94 Yes, I know COME FROM has been implemented.=20
<http://catb.org/esr/intercal/THEORY.html#_code_generation>

On Monday, September 12, 2016 at 1:25:09 PM UTC-7, szollos...@gmail.com=20
wrote:
>
> P.S. how about return const (to the capture point's caller) and return=20
> mutable or volatile (to the current caller)?
>
> 2016. szeptember 12., h=C3=A9tf=C5=91 21:31:47 UTC+2 id=C5=91pontban szol=
los...@gmail.com=20
> a k=C3=B6vetkez=C5=91t =C3=ADrta:
>>
>> Hi,
>>
>> I'm happy with whatever syntax we come up with. Note that I'm not=20
>> intending to hijack lambda capture syntax, I'm saying that `auto myRetur=
n =3D=20
>> static return;` and `auto myReturn =3D extern return;` are also valid e.=
g. in=20
>> functions. These will produce [[noreturn]] functors (one of them having=
=20
>> multiple overloads/templates), but also provide diagnostics if incorrect=
=20
>> type is used. What do you think?
>>
>> Thanks,
>> -lorro
>>
>> 2016. szeptember 12., h=C3=A9tf=C5=91 9:32:38 UTC+2 id=C5=91pontban D. B=
.. a k=C3=B6vetkez=C5=91t=20
>> =C3=ADrta:
>>>
>>> Gah. Aside from the numerous typos, of course I got the symbols here th=
e=20
>>> wrong way around, so that first line should read:
>>>
>>> "I can't help but feel that the chosen capturing methods of =3D/& for=
=20
>>> return-from-definer vs -caller respectively are arbitrary and confusing=
.."
>>>
>>> I also see that you did say that from-caller &return can be thought of=
=20
>>> as an extra parameter, so again, not phrasing it as one is=20
>>> counterintuitive. But then sandwiching it into the args might also have=
=20
>>> issues. Either way,you're right that it might make sense to explicitly=
=20
>>> template it.
>>>
>>>
>>>
>>>

--=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp=
..org/d/msgid/std-proposals/8882ac74-62dd-4fcb-bf0f-30bc6ddaa951%40isocpp.or=
g.

------=_Part_49_494265151.1473728280881
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">Rather than bikeshedding the syntax, I think you need to t=
ake a step back and explain what this proposed feature <b><i>is</i></b>. Ri=
ght now, it reads like one of those joke programming languages like INTERCA=
L or TURKEY BOMB where words are just thrown together for comedic effect, r=
ather than for intrinsic meaning (let alone usefulness).<div><br></div><div=
>What would it mean for a function to &quot;<font face=3D"courier new, mono=
space">break</font>, but in its caller&#39;s context&quot;?</div><div>You n=
eed to show a specific example of the semantics you&#39;re trying to achiev=
e, in the form of</div><div>- a library solution (perhaps involving setjmp/=
longjmp or exception-handling under the hood), and/or</div><div>- assembly =
code for a non-trivial use of the proposed feature.</div><div><br></div><di=
v>You get close to that with your statement</div><div>&gt; It can be simula=
ted by a `try { ... } catch(NonLocalReturn&lt;type&gt;&amp; r) { return r.g=
et(); }` block at=C2=A0<i>each</i>=C2=A0<i>calling</i>=C2=A0point; however,=
 it can be done more efficiently.</div><div><br></div><div>but you need to =
explain <i>how</i> it can be done more efficiently; and besides,</div><div>=
- that only helps for the &quot;return from local caller&quot; case, not &q=
uot;return from original creator&quot;;</div><div>- that only has an obviou=
s translation if <font face=3D"courier new, monospace">type</font> is known=
 beforehand;</div><div>- the obvious translation is to wrap <font face=3D"a=
rial, sans-serif"><i>literally every function call</i></font> in this boile=
rplate (since we can&#39;t tell which functors might or might not have thes=
e new semantics).</div><div><br></div><div>If you can&#39;t explain the pra=
ctical semantics of your proposal, then you&#39;re operating solidly in jok=
e-language territory: &quot;Hey, I think C++ should have a COME FROM statem=
ent!&quot; =C2=A0&quot;I think instead of BITs we should use AMICEDs, which=
 are negative six-sevenths of a decimal digit!&quot; =C2=A0All this bikeshe=
dding about the <i>spelling</i> of the COME FROM statement is completely be=
side the point.</div><div><br></div><div>=E2=80=93Arthur</div><div><br></di=
v><div>P.S. =E2=80=94 <a href=3D"http://catb.org/esr/intercal/THEORY.html#_=
code_generation">Yes, I know COME FROM has been implemented.</a><br><br>On =
Monday, September 12, 2016 at 1:25:09 PM UTC-7, szollos...@gmail.com wrote:=
<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;bor=
der-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr">P.S. how abou=
t return const (to the capture point&#39;s caller) and return mutable or vo=
latile (to the current caller)?<br><br>2016. szeptember 12., h=C3=A9tf=C5=
=91 21:31:47 UTC+2 id=C5=91pontban <a>szollos...@gmail.com</a> a k=C3=B6vet=
kez=C5=91t =C3=ADrta:<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">Hi,<br><br>I&#39;m happy with whatever syntax we come up with. Note that=
 I&#39;m not intending to hijack lambda capture syntax, I&#39;m saying that=
 `auto myReturn =3D static return;` and `auto myReturn =3D extern return;` =
are also valid e.g. in functions. These will produce [[noreturn]] functors =
(one of them having multiple overloads/templates), but also provide diagnos=
tics if incorrect type is used. What do you think?<br><br>Thanks,<br>-lorro=
<br><br>2016. szeptember 12., h=C3=A9tf=C5=91 9:32:38 UTC+2 id=C5=91pontban=
 D. B. a k=C3=B6vetkez=C5=91t =C3=ADrta:<blockquote class=3D"gmail_quote" s=
tyle=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-left:=
1ex"><div dir=3D"ltr"><div><div>Gah. Aside from the numerous typos, of cour=
se I got the symbols here the wrong way around, so that first line should r=
ead:<br><br></div>&quot;I can&#39;t help but feel that the chosen capturing=
 methods of <font size=3D"4">=3D/&amp;</font> for=20
return-from-definer vs -caller respectively are arbitrary and confusing.&qu=
ot;<br><br></div>I also see that you did say that from-caller &amp;return c=
an be thought of as an extra parameter, so again, not phrasing it as one is=
 counterintuitive. But then sandwiching it into the args might also have is=
sues. Either way,you&#39;re right that it might make sense to explicitly te=
mplate it.<br><br><div><div><div><br><br></div></div></div></div>
</blockquote></div></blockquote></div></blockquote></div></div>

<p></p>

-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; 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/8882ac74-62dd-4fcb-bf0f-30bc6ddaa951%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/8882ac74-62dd-4fcb-bf0f-30bc6ddaa951=
%40isocpp.org</a>.<br />

------=_Part_49_494265151.1473728280881--

------=_Part_48_1738796180.1473728280881--

.


Author: Giovanni Piero Deretta <gpderetta@gmail.com>
Date: Tue, 13 Sep 2016 02:18:58 -0700 (PDT)
Raw View
------=_Part_229_2026872408.1473758338282
Content-Type: multipart/alternative;
 boundary="----=_Part_230_1802773780.1473758338282"

------=_Part_230_1802773780.1473758338282
Content-Type: text/plain; charset=UTF-8

On Tuesday, September 13, 2016 at 1:58:00 AM UTC+1, Arthur O'Dwyer wrote:
>
> Rather than bikeshedding the syntax, I think you need to take a step back
> and explain what this proposed feature *is*. Right now, it reads like one
> of those joke programming languages like INTERCAL or TURKEY BOMB where
> words are just thrown together for comedic effect, rather than for
> intrinsic meaning (let alone usefulness).
>
> What would it mean for a function to "break, but in its caller's context"?
> You need to show a specific example of the semantics you're trying to
> achieve, in the form of
> - a library solution (perhaps involving setjmp/longjmp or
> exception-handling under the hood), and/or
> - assembly code for a non-trivial use of the proposed feature.
>
>
I think that the proposal is definitely confused and mentioning monads
doesn't help. What the author is proposing is simply capture of first class
continuations. The proposed syntax only allow capturing some specific
continuations (the return, and loop and switch break continuations) and
only allow escaping to them (by throwing away the current continuation),
but it could be extended to capture any continuation and preserving the
current one. The proposal is semantically a subset of the existing
stackfull coroutine proposals and can be implemented on top of them.

--
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/f981bacf-343b-4341-b76f-3cd06737577d%40isocpp.org.

------=_Part_230_1802773780.1473758338282
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">On Tuesday, September 13, 2016 at 1:58:00 AM UTC+1, Arthur=
 O&#39;Dwyer wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;mar=
gin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D=
"ltr">Rather than bikeshedding the syntax, I think you need to take a step =
back and explain what this proposed feature <b><i>is</i></b>. Right now, it=
 reads like one of those joke programming languages like INTERCAL or TURKEY=
 BOMB where words are just thrown together for comedic effect, rather than =
for intrinsic meaning (let alone usefulness).<div><br></div><div>What would=
 it mean for a function to &quot;<font face=3D"courier new, monospace">brea=
k</font>, but in its caller&#39;s context&quot;?</div><div>You need to show=
 a specific example of the semantics you&#39;re trying to achieve, in the f=
orm of</div><div>- a library solution (perhaps involving setjmp/longjmp or =
exception-handling under the hood), and/or</div><div>- assembly code for a =
non-trivial use of the proposed feature.</div><div><div><div><br></div></di=
v></div></div></blockquote><div><br>I think that the proposal is definitely=
 confused and mentioning monads doesn&#39;t help. What the author is propos=
ing is simply capture of first class continuations. The proposed syntax onl=
y allow capturing some specific continuations (the return, and loop and swi=
tch break continuations) and only allow escaping to them (by throwing away =
the current continuation), but it could be extended to capture any continua=
tion and preserving the current one. The proposal is semantically a subset =
of the existing stackfull coroutine proposals and can be implemented on top=
 of them. <br></div></div>

<p></p>

-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; 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/f981bacf-343b-4341-b76f-3cd06737577d%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/f981bacf-343b-4341-b76f-3cd06737577d=
%40isocpp.org</a>.<br />

------=_Part_230_1802773780.1473758338282--

------=_Part_229_2026872408.1473758338282--

.


Author: Tony V E <tvaneerd@gmail.com>
Date: Tue, 13 Sep 2016 10:35:08 -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);">COME FROM is also how you can add threads to INTERCAL.</div><di=
v style=3D"width: 100%; font-size: initial; font-family: Calibri, 'Slate Pr=
o', sans-serif, sans-serif; color: rgb(31, 73, 125); text-align: initial; b=
ackground-color: rgb(255, 255, 255);"><span style=3D"font-size: initial; li=
ne-height: initial; text-align: initial; font-family: Calibri, 'Slate Pro',=
 sans-serif, sans-serif;">PLEASE.&nbsp;</span></div><div style=3D"width: 10=
0%; 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);"><span style=3D"font-size: initial; line-height: initial; =
text-align: initial; font-family: Calibri, 'Slate Pro', sans-serif, sans-se=
rif;"><br></span></div>                                                    =
                                                                           =
      <div style=3D"width: 100%; font-size: initial; font-family: Calibri, =
'Slate Pro', sans-serif, sans-serif; color: rgb(31, 73, 125); text-align: i=
nitial; background-color: rgb(255, 255, 255);"><br style=3D"display:initial=
"></div>                                                                   =
                                                                           =
                                                     <div style=3D"font-siz=
e: initial; font-family: Calibri, 'Slate Pro', sans-serif, sans-serif; colo=
r: rgb(31, 73, 125); text-align: initial; background-color: rgb(255, 255, 2=
55);">Sent&nbsp;from&nbsp;my&nbsp;BlackBerry&nbsp;portable&nbsp;Babbage&nbs=
p;Device</div>                                                             =
                                                                           =
                                          <table width=3D"100%" style=3D"ba=
ckground-color:white;border-spacing:0px;"> <tbody><tr><td colspan=3D"2" sty=
le=3D"font-size: initial; text-align: initial; background-color: rgb(255, 2=
55, 255);">                           <div style=3D"border-style: solid non=
e none; border-top-color: rgb(181, 196, 223); border-top-width: 1pt; paddin=
g: 3pt 0in 0in; font-family: Tahoma, 'BB Alpha Sans', 'Slate Pro'; font-siz=
e: 10pt;">  <div><b>From: </b>Arthur O'Dwyer</div><div><b>Sent: </b>Monday,=
 September 12, 2016 8:58 PM</div><div><b>To: </b>ISO C++ Standard - Future =
Proposals</div><div><b>Reply To: </b>std-proposals@isocpp.org</div><div><b>=
Cc: </b>szollosi.lorand@gmail.com</div><div><b>Subject: </b>Re: [std-propos=
als] Re: capturing monads in lambda</div></div></td></tr></tbody></table><d=
iv style=3D"border-style: solid none none; border-top-color: rgb(186, 188, =
209); border-top-width: 1pt; font-size: initial; text-align: initial; backg=
round-color: rgb(255, 255, 255);"></div><br><div id=3D"_originalContent" st=
yle=3D""><div dir=3D"ltr">Rather than bikeshedding the syntax, I think you =
need to take a step back and explain what this proposed feature <b><i>is</i=
></b>. Right now, it reads like one of those joke programming languages lik=
e INTERCAL or TURKEY BOMB where words are just thrown together for comedic =
effect, rather than for intrinsic meaning (let alone usefulness).<div><br><=
/div><div>What would it mean for a function to "<font face=3D"courier new, =
monospace">break</font>, but in its caller's context"?</div><div>You need t=
o show a specific example of the semantics you're trying to achieve, in the=
 form of</div><div>- a library solution (perhaps involving setjmp/longjmp o=
r exception-handling under the hood), and/or</div><div>- assembly code for =
a non-trivial use of the proposed feature.</div><div><br></div><div>You get=
 close to that with your statement</div><div>&gt; It can be simulated by a =
`try { ... } catch(NonLocalReturn&lt;type&gt;&amp; r) { return r.get(); }` =
block at&nbsp;<i>each</i>&nbsp;<i>calling</i>&nbsp;point; however, it can b=
e done more efficiently.</div><div><br></div><div>but you need to explain <=
i>how</i> it can be done more efficiently; and besides,</div><div>- that on=
ly helps for the "return from local caller" case, not "return from original=
 creator";</div><div>- that only has an obvious translation if <font face=
=3D"courier new, monospace">type</font> is known beforehand;</div><div>- th=
e obvious translation is to wrap <font face=3D"arial, sans-serif"><i>litera=
lly every function call</i></font> in this boilerplate (since we can't tell=
 which functors might or might not have these new semantics).</div><div><br=
></div><div>If you can't explain the practical semantics of your proposal, =
then you're operating solidly in joke-language territory: "Hey, I think C++=
 should have a COME FROM statement!" &nbsp;"I think instead of BITs we shou=
ld use AMICEDs, which are negative six-sevenths of a decimal digit!" &nbsp;=
All this bikeshedding about the <i>spelling</i> of the COME FROM statement =
is completely beside the point.</div><div><br></div><div>=E2=80=93Arthur</d=
iv><div><br></div><div>P.S. =E2=80=94 <a href=3D"http://catb.org/esr/interc=
al/THEORY.html#_code_generation">Yes, I know COME FROM has been implemented=
..</a><br><br>On Monday, September 12, 2016 at 1:25:09 PM UTC-7, szollos...@=
gmail.com wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin=
-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"lt=
r">P.S. how about return const (to the capture point's caller) and return m=
utable or volatile (to the current caller)?<br><br>2016. szeptember 12., h=
=C3=A9tf=C5=91 21:31:47 UTC+2 id=C5=91pontban <a>szollos...@gmail.com</a> a=
 k=C3=B6vetkez=C5=91t =C3=ADrta:<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">Hi,<br><br>I'm happy with whatever syntax we come up with. No=
te that I'm not intending to hijack lambda capture syntax, I'm saying that =
`auto myReturn =3D static return;` and `auto myReturn =3D extern return;` a=
re also valid e.g. in functions. These will produce [[noreturn]] functors (=
one of them having multiple overloads/templates), but also provide diagnost=
ics if incorrect type is used. What do you think?<br><br>Thanks,<br>-lorro<=
br><br>2016. szeptember 12., h=C3=A9tf=C5=91 9:32:38 UTC+2 id=C5=91pontban =
D. B. a k=C3=B6vetkez=C5=91t =C3=ADrta:<blockquote class=3D"gmail_quote" st=
yle=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-left:1=
ex"><div dir=3D"ltr"><div><div>Gah. Aside from the numerous typos, of cours=
e I got the symbols here the wrong way around, so that first line should re=
ad:<br><br></div>"I can't help but feel that the chosen capturing methods o=
f <font size=3D"4">=3D/&amp;</font> for=20
return-from-definer vs -caller respectively are arbitrary and confusing."<b=
r><br></div>I also see that you did say that from-caller &amp;return can be=
 thought of as an extra parameter, so again, not phrasing it as one is coun=
terintuitive. But then sandwiching it into the args might also have issues.=
 Either way,you're right that it might make sense to explicitly template it=
..<br><br><div><div><div><br><br></div></div></div></div>
</blockquote></div></blockquote></div></blockquote></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/8882ac74-62dd-4fcb-bf0f-30bc6ddaa951%=
40isocpp.org?utm_medium=3Demail&amp;utm_source=3Dfooter">https://groups.goo=
gle.com/a/isocpp.org/d/msgid/std-proposals/8882ac74-62dd-4fcb-bf0f-30bc6dda=
a951%40isocpp.org</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&quot; 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/20160913143508.4902992.18691.16938%40=
gmail.com?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.com=
/a/isocpp.org/d/msgid/std-proposals/20160913143508.4902992.18691.16938%40gm=
ail.com</a>.<br />

.


Author: Avi Kivity <avi@scylladb.com>
Date: Wed, 14 Sep 2016 13:04:26 +0300
Raw View
This is a multi-part message in MIME format.
--------------B99B43A69EEE13E0895E5659
Content-Type: text/plain; charset=UTF-8; format=flowed


On 09/11/2016 07:55 PM, Robert Bielik wrote:
>
> Been following this thread, and I just want to chip in with a very
> important aspect: Readability. In ten cases of ten, I'd use exceptions
> as a mechanism to achieve the same behavior. Why? Because it's more
> readable, and not obfuscated.
>
>

Exceptions are too slow for this use case.

> Den 11 sep 2016 18:42 skrev "Nicol Bolas" <jmckesson@gmail.com
> <mailto:jmckesson@gmail.com>>:
>
>     On Saturday, September 10, 2016 at 7:23:50 PM UTC-4, Edward Catmur
>     wrote:
>
>         On 10 Sep 2016 04:46, "Nicol Bolas" <jmck...@gmail.com> wrote:
>         > See, it sounds like you're trying to say that returning from
>         within the lambda will cause it to return from... well, that
>         right there is the question. I think you want it to return
>         from the function that called it. But how exactly is that
>         supposed to happen?
>
>         Stack unwinding.
>
>         > After all, the function that called it is not necessarily
>         the function that created it. What happens if you do this:
>         >
>         > ErrorCode save()
>         > {
>         >     std::function<void(ErrorCode)> return_if =
>         [&return](auto retval){
>         >
>         >         if (retval) { return retval; }
>         >     };
>         >
>         >     return_if(openFile());
>         >     return_if(saveData());
>         >     return_if(closeFile());
>         > }
>         >
>         > I have every reason to expect this to achieve the same
>         effect. Yet I cannot imagine how that would be possible. After
>         all, I don't call it. I call `std::function::operator()`,
>         which (eventually) calls the lambda. So the lambda will just
>         provoke the return of some construct within the
>         `std::function::operator()`.
>
>         Stack unwinding isn't just for exceptions. The machinery is
>         there for non local jumps, such as thread cancellation, setjmp
>         and SEH.
>
>
>     My first inclination is to say that this is just exception
>     handling with special cleanup work. Conceptually, it's
>     indistinguishable from:
>
>     |
>     autox =[](){...throwreturn_value(someValue);}//Class template
>     deduction
>
>     try
>     {
>     autoy =x(foo);
>     }
>     catch(return_value<ReturnType>&t)
>     {
>     returnstd::move(t.get());
>     }
>     |
>
>     Obviously that's both incredibly verbose and traps `y` within a
>     try-block. But the general idea you seem to want is the same; it's
>     simply a matter of applying syntactic sugar:
>
>     |
>     autoy =tryx(foo);
>     |
>
>     Or something to that effect, with the compiler generating logic
>     based on certain types being thrown. `std::return_value<T>` would
>     provoke a return from that function of the stored `T`.
>     `std::break_value` would provoke a `break`. If nothing is thrown,
>     then the code proceeds as normal.
>
>     The `try` there is important for two reasons. First, it lets the
>     compiler know where to stop looking. And second, it makes clear to
>     the reader that the code in question may experience an alternate
>     control flow. Just as with any other `try` block.
>
>     A lambda does not seem to be the natural form of syntax for
>     applying this. If you're going to start doing stack unwinding and
>     such, then it should be built on the language mechanism that
>     actually does stack unwinding.
>
>     Consider `expected<T, E>`. By decoupling this feature from
>     lambdas, by giving /all/ functions this power, we could give it an
>     implicit `operator T` overload that will either return a `T` or
>     throw a return of `E`. So if you do `auto x = try Typename(exp);`,
>     you get automatic unpacking or a return of the error code.
>
>     Granted, some might suggest that this is no less dangerous or
>     performance-costly than exceptions. To which I answer... yeah.
>     That's what happens when you want code to be able to transparently
>     communicate with some other code that is an indeterminate number
>     of function calls below it.
>
>         > And you can't say that it will always return to the caller
>         of the lambda's creator, because I don't have to still be on
>         the stack. I can return that lambda to someone else, wrapped
>         in a `std::function`. How does that work?
>
>         UB, just as with capturing local variables by reference.
>         Likewise if any of the intervening frames are not unwinding
>         aware.
>
>
>     The last example the OP posted makes a distinction between
>     "capturing" by value vs. by reference. By reference `return` means
>     causing a return from the most recent caller. By value `return`
>     means causing a return from the code that created it.
>
>     So really, the OP's proposal is kinda backwards from what you seem
>     to be wanting (and to be honest, I rather prefer your
>     interpretation). "Capturing" statements by reference is *safe* and
>     such lambdas can be used anywhere (in theory), while "capturing"
>     by value is unsafe.
>
>         > A lambda in C++ is not some magical construct, imbued with
>         fantastical powers. In C++, a lambda is an object. Not only
>         that, it is an instance of a class type. You can rewrite any
>         lambda as a local struct with a constructor and an operator()
>         overload (except for generic lambdas, but I'd like to see that
>         fixed). As it currently stands, a lambda cannot do anything
>         that a user-created class can't also do.
>
>         There's another feature you're forgetting. Lambda captures can
>         copy arrays by value, which user code can't do without some
>         heavy library machinery
>
>
>     It doesn't take "heavy library machinery" to copy an array. Well,
>     so long as the type is default-constructible and assignable.
>
>     Ultimately, the point I'm making is that a lambda is not a special
>     thing; it doesn't do anything you can't do yourself, even if doing
>     it yourself is much harder. What's being proposed here is a
>     deviation from that: you /cannot/ replicate such behavior.
>
>     And that ultimately limits the utility of the proposal.
>
>         If we're talking user code equivalents, setjmp would do if
>         it's unwind-enabled, as would a custom exception in the
>         absence of catch (...) blocks, or even invoking the platform
>         unwind machinery directly.
>
>         > <snip>
>
>         Sure, I get that you like that lambdas are mostly syntactic
>         sugar. That was probably necessary at the beginning, but it
>         doesn't mean they have to stay that way.
>
>
>     That's not a good enough reason to tie it to lambdas.
>
>     Consider two of the examples provided here: `return_if` and
>     `error_code`. Those patterns are quite useful for many
>     circumstances. And yet, there is no way to avoid re-typing them
>     every time you want to use them without employing a macro. Why?
>
>     Because the feature is tied to lambdas and their capture list.
>     Remove that tie, and it suddenly becomes quite possible to have
>     these as simply standard library template functions.
>     --
>     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
>     <mailto:std-proposals+unsubscribe@isocpp.org>.
>     To post to this group, send email to std-proposals@isocpp.org
>     <mailto:std-proposals@isocpp.org>.
>     To view this discussion on the web visit
>     https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/dcb70287-4ee4-4cae-9e09-4f7cab8d0db8%40isocpp.org
>     <https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/dcb70287-4ee4-4cae-9e09-4f7cab8d0db8%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
> <mailto:std-proposals+unsubscribe@isocpp.org>.
> To post to this group, send email to std-proposals@isocpp.org
> <mailto:std-proposals@isocpp.org>.
> To view this discussion on the web visit
> https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CAEvHzA29Fv7c9Vk3bN5GwHjSbgNSGHEtUuNdhxAB3kENUWKt9g%40mail.gmail.com
> <https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CAEvHzA29Fv7c9Vk3bN5GwHjSbgNSGHEtUuNdhxAB3kENUWKt9g%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/0f737271-e880-9417-1743-33ad21a34769%40scylladb.com.

--------------B99B43A69EEE13E0895E5659
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<html>
  <head>
    <meta content=3D"text/html; charset=3Dutf-8" http-equiv=3D"Content-Type=
">
  </head>
  <body bgcolor=3D"#FFFFFF" text=3D"#000000">
    <br>
    <div class=3D"moz-cite-prefix">On 09/11/2016 07:55 PM, Robert Bielik
      wrote:<br>
    </div>
    <blockquote
cite=3D"mid:CAEvHzA29Fv7c9Vk3bN5GwHjSbgNSGHEtUuNdhxAB3kENUWKt9g@mail.gmail.=
com"
      type=3D"cite">
      <p dir=3D"ltr">Been following this thread, and I just want to chip
        in with a very important aspect: Readability. In ten cases of
        ten, I'd use exceptions as a mechanism to achieve the same
        behavior. Why? Because it's more readable, and not obfuscated.</p>
      <div class=3D"gmail_extra"><br>
      </div>
    </blockquote>
    <br>
    Exceptions are too slow for this use case.<br>
    <br>
    <blockquote
cite=3D"mid:CAEvHzA29Fv7c9Vk3bN5GwHjSbgNSGHEtUuNdhxAB3kENUWKt9g@mail.gmail.=
com"
      type=3D"cite">
      <div class=3D"gmail_extra">
        <div class=3D"gmail_quote">Den 11 sep 2016 18:42 skrev "Nicol
          Bolas" &lt;<a moz-do-not-send=3D"true"
            href=3D"mailto:jmckesson@gmail.com">jmckesson@gmail.com</a>&gt;=
:<br
            type=3D"attribution">
          <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 Saturday, September 10, 2016 at 7:23:50 PM
              UTC-4, Edward Catmur wrote:
              <blockquote class=3D"gmail_quote"
                style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc
                solid;padding-left:1ex">
                <p dir=3D"ltr">On 10 Sep 2016 04:46, "Nicol Bolas" &lt;<a
                    moz-do-not-send=3D"true" rel=3D"nofollow">jmck...@gmail=
..com</a>&gt;
                  wrote:<br>
                  &gt; See, it sounds like you're trying to say that
                  returning from within the lambda will cause it to
                  return from... well, that right there is the question.
                  I think you want it to return from the function that
                  called it. But how exactly is that supposed to happen?</p=
>
                <p dir=3D"ltr">Stack unwinding. </p>
                <p dir=3D"ltr">&gt; After all, the function that called it
                  is not necessarily the function that created it. What
                  happens if you do this:<br>
                  &gt;<br>
                  &gt; ErrorCode save()<br>
                  &gt; {<br>
                  &gt; =C2=A0 =C2=A0 std::function&lt;void(ErrorCode)&gt;
                  return_if =3D [&amp;return](auto retval){<br>
                  &gt;<br>
                  &gt; =C2=A0 =C2=A0 =C2=A0 =C2=A0 if (retval) { return ret=
val; }<br>
                  &gt; =C2=A0 =C2=A0 };<br>
                  &gt;<br>
                  &gt; =C2=A0 =C2=A0 return_if(openFile());<br>
                  &gt; =C2=A0 =C2=A0 return_if(saveData());<br>
                  &gt; =C2=A0 =C2=A0 return_if(closeFile());<br>
                  &gt; }<br>
                  &gt;<br>
                  &gt; I have every reason to expect this to achieve the
                  same effect. Yet I cannot imagine how that would be
                  possible. After all, I don't call it. I call
                  `std::function::operator()`, which (eventually) calls
                  the lambda. So the lambda will just provoke the return
                  of some construct within the
                  `std::function::operator()`.</p>
                <p dir=3D"ltr">Stack unwinding isn't just for exceptions.
                  The machinery is there for non local jumps, such as
                  thread cancellation, setjmp and SEH. </p>
              </blockquote>
              <div><br>
                My first inclination is to say that this is just
                exception handling with special cleanup work.
                Conceptually, it's indistinguishable from:<br>
                <br>
                <div
style=3D"background-color:rgb(250,250,250);border-color:rgb(187,187,187);bo=
rder-style:solid;border-width:1px;word-wrap:break-word"><code>
                    <div><span style=3D"color:#008">auto</span><span
                        style=3D"color:#000"> x </span><span
                        style=3D"color:#660">=3D</span><span
                        style=3D"color:#000"> </span><span
                        style=3D"color:#660">[]()</span><span
                        style=3D"color:#000"> </span><span
                        style=3D"color:#660">{...</span><span
                        style=3D"color:#000"> </span><span
                        style=3D"color:#008">throw</span><span
                        style=3D"color:#000"> return_value</span><span
                        style=3D"color:#660">(</span><span
                        style=3D"color:#000">someValue</span><span
                        style=3D"color:#660">);}</span><span
                        style=3D"color:#000"> </span><span
                        style=3D"color:#800">//Class template deduction</sp=
an><span
                        style=3D"color:#000"><br>
                        <br>
                      </span><span style=3D"color:#008">try</span><span
                        style=3D"color:#000"><br>
                      </span><span style=3D"color:#660">{</span><span
                        style=3D"color:#000"><br>
                        =C2=A0 </span><span style=3D"color:#008">auto</span=
><span
                        style=3D"color:#000"> y </span><span
                        style=3D"color:#660">=3D</span><span
                        style=3D"color:#000"> x</span><span
                        style=3D"color:#660">(</span><span
                        style=3D"color:#000">foo</span><span
                        style=3D"color:#660">);</span><span
                        style=3D"color:#000"><br>
                      </span><span style=3D"color:#660">}</span><span
                        style=3D"color:#000"><br>
                      </span><span style=3D"color:#008">catch</span><span
                        style=3D"color:#660">(</span><span
                        style=3D"color:#000">return_value</span><span
                        style=3D"color:#660">&lt;</span><span
                        style=3D"color:#606">ReturnType</span><span
                        style=3D"color:#660">&gt;</span><span
                        style=3D"color:#000"> </span><span
                        style=3D"color:#660">&amp;</span><span
                        style=3D"color:#000">t</span><span
                        style=3D"color:#660">)</span><span
                        style=3D"color:#000"><br>
                      </span><span style=3D"color:#660">{</span><span
                        style=3D"color:#000"><br>
                        =C2=A0 </span><span style=3D"color:#008">return</sp=
an><span
                        style=3D"color:#000"> std</span><span
                        style=3D"color:#660">::</span><span
                        style=3D"color:#000">move</span><span
                        style=3D"color:#660">(</span><span
                        style=3D"color:#000">t</span><span
                        style=3D"color:#660">.</span><span
                        style=3D"color:#008">get</span><span
                        style=3D"color:#660">());</span><span
                        style=3D"color:#000"><br>
                      </span><span style=3D"color:#660">}</span><span
                        style=3D"color:#000"><br>
                      </span></div>
                  </code></div>
                <br>
                Obviously that's both incredibly verbose and traps `y`
                within a try-block. But the general idea you seem to
                want is the same; it's simply a matter of applying
                syntactic sugar:<br>
                <br>
                <div
style=3D"background-color:rgb(250,250,250);border-color:rgb(187,187,187);bo=
rder-style:solid;border-width:1px;word-wrap:break-word"><code>
                    <div><span style=3D"color:#008">auto</span><span
                        style=3D"color:#000"> y </span><span
                        style=3D"color:#660">=3D</span><span
                        style=3D"color:#000"> </span><span
                        style=3D"color:#008">try</span><span
                        style=3D"color:#000"> x</span><span
                        style=3D"color:#660">(</span><span
                        style=3D"color:#000">foo</span><span
                        style=3D"color:#660">);</span><span
                        style=3D"color:#000"><br>
                      </span></div>
                  </code></div>
                <br>
                Or something to that effect, with the compiler
                generating logic based on certain types being thrown.
                `std::return_value&lt;T&gt;` would provoke a return from
                that function of the stored `T`. `std::break_value`
                would provoke a `break`. If nothing is thrown, then the
                code proceeds as normal.<br>
                <br>
                The `try` there is important for two reasons. First, it
                lets the compiler know where to stop looking. And
                second, it makes clear to the reader that the code in
                question may experience an alternate control flow. Just
                as with any other `try` block.<br>
                <br>
                A lambda does not seem to be the natural form of syntax
                for applying this. If you're going to start doing stack
                unwinding and such, then it should be built on the
                language mechanism that actually does stack unwinding.<br>
                <br>
                Consider `expected&lt;T, E&gt;`. By decoupling this
                feature from lambdas, by giving <i>all</i> functions
                this power, we could give it an implicit `operator T`
                overload that will either return a `T` or throw a return
                of `E`. So if you do `auto x =3D try Typename(exp);`, you
                get automatic unpacking or a return of the error code.<br>
                <br>
                Granted, some might suggest that this is no less
                dangerous or performance-costly than exceptions. To
                which I answer... yeah. That's what happens when you
                want code to be able to transparently communicate with
                some other code that is an indeterminate number of
                function calls below it.<br>
                =C2=A0</div>
              <blockquote class=3D"gmail_quote"
                style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc
                solid;padding-left:1ex">
                <p dir=3D"ltr">&gt; And you can't say that it will always
                  return to the caller of the lambda's creator, because
                  I don't have to still be on the stack. I can return
                  that lambda to someone else, wrapped in a
                  `std::function`. How does that work?</p>
                <p dir=3D"ltr">UB, just as with capturing local variables
                  by reference. Likewise if any of the intervening
                  frames are not unwinding aware. </p>
              </blockquote>
              <div><br>
                The last example the OP posted makes a distinction
                between "capturing" by value vs. by reference. By
                reference `return` means causing a return from the most
                recent caller. By value `return` means causing a return
                from the code that created it.<br>
                <br>
                So really, the OP's proposal is kinda backwards from
                what you seem to be wanting (and to be honest, I rather
                prefer your interpretation). "Capturing" statements by
                reference is *safe* and such lambdas can be used
                anywhere (in theory), while "capturing" by value is
                unsafe.<br>
                <br>
              </div>
              <blockquote class=3D"gmail_quote"
                style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc
                solid;padding-left:1ex">
                <p dir=3D"ltr">&gt; A lambda in C++ is not some magical
                  construct, imbued with fantastical powers. In C++, a
                  lambda is an object. Not only that, it is an instance
                  of a class type. You can rewrite any lambda as a local
                  struct with a constructor and an operator() overload
                  (except for generic lambdas, but I'd like to see that
                  fixed). As it currently stands, a lambda cannot do
                  anything that a user-created class can't also do.</p>
                <p dir=3D"ltr">There's another feature you're forgetting.
                  Lambda captures can copy arrays by value, which user
                  code can't do without some heavy library machinery</p>
              </blockquote>
              <div><br>
                It doesn't take "heavy library machinery" to copy an
                array. Well, so long as the type is
                default-constructible and assignable.<br>
                <br>
                Ultimately, the point I'm making is that a lambda is not
                a special thing; it doesn't do anything you can't do
                yourself, even if doing it yourself is much harder.
                What's being proposed here is a deviation from that: you
                <i>cannot</i> replicate such behavior.<br>
                <br>
                And that ultimately limits the utility of the proposal.<br>
                <br>
              </div>
              <blockquote class=3D"gmail_quote"
                style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc
                solid;padding-left:1ex">
                <p dir=3D"ltr"> </p>
                <p dir=3D"ltr">If we're talking user code equivalents,
                  setjmp would do if it's unwind-enabled, as would a
                  custom exception in the absence of catch (...) blocks,
                  or even invoking the platform unwind machinery
                  directly. </p>
                <p dir=3D"ltr">&gt; &lt;snip&gt;</p>
                <p dir=3D"ltr">Sure, I get that you like that lambdas are
                  mostly syntactic sugar. That was probably necessary at
                  the beginning, but it doesn't mean they have to stay
                  that way.</p>
              </blockquote>
              <div><br>
                That's not a good enough reason to tie it to lambdas.<br>
                <br>
                Consider two of the examples provided here: `return_if`
                and `error_code`. Those patterns are quite useful for
                many=C2=A0 circumstances. And yet, there is no way to avoid
                re-typing them every time you want to use them without
                employing a macro. Why?<br>
                <br>
                Because the feature is tied to lambdas and their capture
                list. Remove that tie, and it suddenly becomes quite
                possible to have these as simply standard library
                template functions.<br>
              </div>
            </div>
            -- <br>
            You received this message because you are subscribed to the
            Google Groups "ISO C++ Standard - Future Proposals" group.<br>
            To unsubscribe from this group and stop receiving emails
            from it, send an email to <a moz-do-not-send=3D"true"
              href=3D"mailto:std-proposals+unsubscribe@isocpp.org"
              target=3D"_blank">std-proposals+unsubscribe@<wbr>isocpp.org</=
a>.<br>
            To post to this group, send email to <a
              moz-do-not-send=3D"true"
              href=3D"mailto:std-proposals@isocpp.org" target=3D"_blank">st=
d-proposals@isocpp.org</a>.<br>
            To view this discussion on the web visit <a
              moz-do-not-send=3D"true"
href=3D"https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/dcb702=
87-4ee4-4cae-9e09-4f7cab8d0db8%40isocpp.org?utm_medium=3Demail&amp;utm_sour=
ce=3Dfooter"
              target=3D"_blank">https://groups.google.com/a/<wbr>isocpp.org=
/d/msgid/std-<wbr>proposals/dcb70287-4ee4-4cae-<wbr>9e09-4f7cab8d0db8%40iso=
cpp.org</a><wbr>.<br>
          </blockquote>
        </div>
      </div>
      -- <br>
      You received this message because you are subscribed to the Google
      Groups "ISO C++ Standard - Future Proposals" group.<br>
      To unsubscribe from this group and stop receiving emails from it,
      send an email to <a moz-do-not-send=3D"true"
        href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposals+=
unsubscribe@isocpp.org</a>.<br>
      To post to this group, send email to <a moz-do-not-send=3D"true"
        href=3D"mailto:std-proposals@isocpp.org">std-proposals@isocpp.org</=
a>.<br>
      To view this discussion on the web visit <a
        moz-do-not-send=3D"true"
href=3D"https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CAEvHz=
A29Fv7c9Vk3bN5GwHjSbgNSGHEtUuNdhxAB3kENUWKt9g%40mail.gmail.com?utm_medium=
=3Demail&amp;utm_source=3Dfooter">https://groups.google.com/a/isocpp.org/d/=
msgid/std-proposals/CAEvHzA29Fv7c9Vk3bN5GwHjSbgNSGHEtUuNdhxAB3kENUWKt9g%40m=
ail.gmail.com</a>.<br>
    </blockquote>
    <br>
  </body>
</html>

<p></p>

-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; 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/0f737271-e880-9417-1743-33ad21a34769%=
40scylladb.com?utm_medium=3Demail&utm_source=3Dfooter">https://groups.googl=
e.com/a/isocpp.org/d/msgid/std-proposals/0f737271-e880-9417-1743-33ad21a347=
69%40scylladb.com</a>.<br />

--------------B99B43A69EEE13E0895E5659--

.


Author: szollosi.lorand@gmail.com
Date: Wed, 21 Sep 2016 15:21:53 -0700 (PDT)
Raw View
------=_Part_135_686686119.1474496513572
Content-Type: multipart/alternative;
 boundary="----=_Part_136_438289564.1474496513573"

------=_Part_136_438289564.1474496513573
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

Hi,

Sorry if it's confusing.. So far, it's just a sketch that I'm cleaning up=
=20
based on others' suggestions. I'm happy to see the coroutines proposal.=20
Initially, I've discarded the idea of describing these captures as I=20
thought that full continuation capture is way to slow for this (in fact,=20
this should be *exactly* as fast as loops and function returns); but you're=
=20
right, let's formulate these based on continuations, then let's see=20
optimization possibilities later. (Btw, as for the subject: is it OK to=20
rename (set new subject) a thread on this list?)
So, what I'm proposing is absolute and relative capture of specific=20
continuations, namely the ones called by return, break, continue. All of=20
these currently throw away current continuation and it should remain that=
=20
way. Absolute capture, *when requested*, should return a [[noreturn]]=20
functor that is identical, both in parameter(s, if any) and effect to=20
performing the same return, break, continue in the *capturing context*.=20
Current continuation is thrown away and destruction of any automatic=20
storage duration variables are performed in the usual=20
(reverse-of-declaration) order (i.e., unwinding is performed), before=20
calling the continuation, up to the capture point. It is UB to call the=20
functor after leaving capture context or from another thread (or coroutine)=
..
Relative capture, *when requested*, should return a [[noreturn]] functor=20
that is identical, both in parameter(s, if any) and effect to performing=20
the same return, break, continue in the *calling* context. This can either=
=20
be supported by the language; or a workaround is possible via having an=20
additional function parameter that has a default value: (as default value=
=20
is evaluated in caller's context)

#define TAKE_RETURN /* syntax to be defined */

template<typename T>
int mul_for_accumulate(int a, int b, T return2 =3D TAKE_RETURN)
{
    if (a=3D=3D0 || b=3D=3D0) return2(0);
    return a * b;
}



If language support is provided, it's only available in functions; and in=
=20
this case, it's UB to call relative return functor with a parameter that=20
not convertible to the caller's return type; similarly, it's UB to call=20
break functor or continue functor if these are not available in the=20
caller's context. Without language support we're more type-safe, but the=20
caller is aware of the capture (and can divert it); with language support=
=20
it's easier to run into UB but it's meaning is always the same.

A possible 4th continuation to capture would be backtrack (or restart or=20
cc), that captures the current continuation. It's similar to=20
setjmp()/longjmp(), but performes unwinding and can be called multiple=20
times until leaving the context. If not provided, it can be emulated by=20
while() and continue+break:

while(true)
{
    auto my_backtrack =3D TAKE_CONTINUE;
    f(..., my_backtrack);
    break;
}

Alternatively, loops can be defined in terms of backtrack.

Note that, up to this point, we only needed an unwind mechanism (that, as=
=20
noted, is already there for exceptions) and a local goto-like operation=20
(break and continue can be mechanically translated to it).

It looks preferable to be able to 'rename' return, continue and break=20
(albeit looks can be deceiving, any thoughts on that are welcome).

The 'when you've got a hammer, everything looks like a nail'-observation is=
=20
that now we can decompose 'for'. If we define:

for ( int i : range ) { ... }

as

for ([&, return =3D TAKE_RETURN]
     (int i, auto continue =3D TAKE_CONTINUE, auto break =3D TAKE_BREAK) { =
.... }
    )(range)

, then it's easy to define a 'for-function' that provides loop logic. While=
=20
we might not want to redefine for itself this way, we might use the above=
=20
syntax for *abitrary* functions, given we define the above substitution.=20
This would provide immediately the functional equivalent of 'for break',=20
with some library support, it'd do for 'for else'; as a side effect, it'd=
=20
allow to separate the loop object from it's execution, thereby allowing to=
=20
store the loop object and call it for different ranges.=20

Thanks for the valuable comments and the time,
-lorro

2016. szeptember 13., kedd 11:18:58 UTC+2 id=C5=91pontban Giovanni Piero De=
retta=20
a k=C3=B6vetkez=C5=91t =C3=ADrta:
>
> On Tuesday, September 13, 2016 at 1:58:00 AM UTC+1, Arthur O'Dwyer wrote:
>>
>> Rather than bikeshedding the syntax, I think you need to take a step bac=
k=20
>> and explain what this proposed feature *is*. Right now, it reads like=20
>> one of those joke programming languages like INTERCAL or TURKEY BOMB whe=
re=20
>> words are just thrown together for comedic effect, rather than for=20
>> intrinsic meaning (let alone usefulness).
>>
>> What would it mean for a function to "break, but in its caller's=20
>> context"?
>> You need to show a specific example of the semantics you're trying to=20
>> achieve, in the form of
>> - a library solution (perhaps involving setjmp/longjmp or=20
>> exception-handling under the hood), and/or
>> - assembly code for a non-trivial use of the proposed feature.
>>
>>
> I think that the proposal is definitely confused and mentioning monads=20
> doesn't help. What the author is proposing is simply capture of first cla=
ss=20
> continuations. The proposed syntax only allow capturing some specific=20
> continuations (the return, and loop and switch break continuations) and=
=20
> only allow escaping to them (by throwing away the current continuation),=
=20
> but it could be extended to capture any continuation and preserving the=
=20
> current one. The proposal is semantically a subset of the existing=20
> stackfull coroutine proposals and can be implemented on top of them.=20
>

--=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp=
..org/d/msgid/std-proposals/20bd8e3d-a795-4bf8-84e3-1f74ced450ed%40isocpp.or=
g.

------=_Part_136_438289564.1474496513573
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">Hi,<br><br>Sorry if it&#39;s confusing.. So far, it&#39;s =
just a sketch that I&#39;m cleaning up based on others&#39; suggestions. I&=
#39;m happy to see the coroutines proposal. Initially, I&#39;ve discarded t=
he idea of describing these captures as I thought that full continuation ca=
pture is way to slow for this (in fact, this should be <i>exactly</i> as fa=
st as loops and function returns); but you&#39;re right, let&#39;s formulat=
e these based on continuations, then let&#39;s see optimization possibiliti=
es later. (Btw, as for the subject: is it OK to rename (set new subject) a =
thread on this list?)<br>So, what I&#39;m proposing is absolute and relativ=
e capture of specific continuations, namely the ones called by return, brea=
k, continue. All of these currently throw away current continuation and it =
should remain that way. Absolute capture, <i>when requested</i>, should ret=
urn a [[noreturn]] functor that is identical, both in parameter(s, if any) =
and effect to performing the same return, break, continue in the <i>capturi=
ng context</i>. Current continuation is thrown away and destruction of any =
automatic storage duration variables are performed in the usual (reverse-of=
-declaration) order (i.e., unwinding is performed), before calling the cont=
inuation, up to the capture point. It is UB to call the functor after leavi=
ng capture context or from another thread (or coroutine).<br>Relative captu=
re, <i>when requested</i>, should return a [[noreturn]] functor that is ide=
ntical, both in parameter(s, if any) and effect to performing the same retu=
rn, break, continue in the <i>calling</i> context. This can either be suppo=
rted by the language; or a workaround is possible via having an additional =
function parameter that has a default value: (as default value is evaluated=
 in caller&#39;s context)<br><br><div class=3D"prettyprint" style=3D"backgr=
ound-color: rgb(250, 250, 250); border-color: rgb(187, 187, 187); border-st=
yle: solid; border-width: 1px; word-wrap: break-word;"><code class=3D"prett=
yprint"><div class=3D"subprettyprint"><span style=3D"color: #800;" class=3D=
"styled-by-prettify">#define</span><span style=3D"color: #000;" class=3D"st=
yled-by-prettify"> TAKE_RETURN </span><span style=3D"color: #800;" class=3D=
"styled-by-prettify">/* syntax to be defined */</span><span style=3D"color:=
 #000;" class=3D"styled-by-prettify"><br><br></span><span style=3D"color: #=
008;" class=3D"styled-by-prettify">template</span><span style=3D"color: #66=
0;" class=3D"styled-by-prettify">&lt;</span><span style=3D"color: #008;" cl=
ass=3D"styled-by-prettify">typename</span><span style=3D"color: #000;" clas=
s=3D"styled-by-prettify"> T</span><span style=3D"color: #660;" class=3D"sty=
led-by-prettify">&gt;</span><span style=3D"color: #000;" class=3D"styled-by=
-prettify"><br></span><span style=3D"color: #008;" class=3D"styled-by-prett=
ify">int</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> m=
ul_for_accumulate</span><span style=3D"color: #660;" class=3D"styled-by-pre=
ttify">(</span><span style=3D"color: #008;" class=3D"styled-by-prettify">in=
t</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> a</span>=
<span style=3D"color: #660;" class=3D"styled-by-prettify">,</span><span sty=
le=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"col=
or: #008;" class=3D"styled-by-prettify">int</span><span style=3D"color: #00=
0;" class=3D"styled-by-prettify"> b</span><span style=3D"color: #660;" clas=
s=3D"styled-by-prettify">,</span><span style=3D"color: #000;" class=3D"styl=
ed-by-prettify"> T return2 </span><span style=3D"color: #660;" class=3D"sty=
led-by-prettify">=3D</span><span style=3D"color: #000;" class=3D"styled-by-=
prettify"> TAKE_RETURN</span><span style=3D"color: #660;" class=3D"styled-b=
y-prettify">)</span><span style=3D"color: #000;" class=3D"styled-by-prettif=
y"><br></span><span style=3D"color: #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">if<=
/span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><sp=
an style=3D"color: #660;" class=3D"styled-by-prettify">(</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify">a</span><span style=3D"color=
: #660;" class=3D"styled-by-prettify">=3D=3D</span><span style=3D"color: #0=
66;" class=3D"styled-by-prettify">0</span><span style=3D"color: #000;" clas=
s=3D"styled-by-prettify"> </span><span style=3D"color: #660;" class=3D"styl=
ed-by-prettify">||</span><span style=3D"color: #000;" class=3D"styled-by-pr=
ettify"> b</span><span style=3D"color: #660;" class=3D"styled-by-prettify">=
=3D=3D</span><span style=3D"color: #066;" class=3D"styled-by-prettify">0</s=
pan><span style=3D"color: #660;" class=3D"styled-by-prettify">)</span><span=
 style=3D"color: #000;" class=3D"styled-by-prettify"> return2</span><span s=
tyle=3D"color: #660;" class=3D"styled-by-prettify">(</span><span style=3D"c=
olor: #066;" class=3D"styled-by-prettify">0</span><span style=3D"color: #66=
0;" class=3D"styled-by-prettify">);</span><span style=3D"color: #000;" clas=
s=3D"styled-by-prettify"><br>=C2=A0 =C2=A0 </span><span style=3D"color: #00=
8;" class=3D"styled-by-prettify">return</span><span style=3D"color: #000;" =
class=3D"styled-by-prettify"> a </span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">*</span><span style=3D"color: #000;" class=3D"style=
d-by-prettify"> b</span><span style=3D"color: #660;" class=3D"styled-by-pre=
ttify">;</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><b=
r></span><span style=3D"color: #660;" class=3D"styled-by-prettify">}</span>=
<span style=3D"color: #000;" class=3D"styled-by-prettify"><br><br></span></=
div></code></div><br><br>If language support is provided, it&#39;s only ava=
ilable in functions; and in this case, it&#39;s UB to call relative return =
functor with a parameter that not convertible to the caller&#39;s return ty=
pe; similarly, it&#39;s UB to call break functor or continue functor if the=
se are not available in the caller&#39;s context. Without language support =
we&#39;re more type-safe, but the caller is aware of the capture (and can d=
ivert it); with language support it&#39;s easier to run into UB but it&#39;=
s meaning is always the same.<br><br>A possible 4th continuation to capture=
 would be backtrack (or restart or cc), that captures the current continuat=
ion. It&#39;s similar to setjmp()/longjmp(), but performes unwinding and ca=
n be called multiple times until leaving the context. If not provided, it c=
an be emulated by while() and continue+break:<br><br><div class=3D"prettypr=
int" style=3D"background-color: rgb(250, 250, 250); border-color: rgb(187, =
187, 187); border-style: solid; border-width: 1px; word-wrap: break-word;">=
<code class=3D"prettyprint"><div class=3D"subprettyprint"><span style=3D"co=
lor: #008;" class=3D"styled-by-prettify">while</span><span style=3D"color: =
#660;" class=3D"styled-by-prettify">(</span><span style=3D"color: #008;" cl=
ass=3D"styled-by-prettify">true</span><span style=3D"color: #660;" class=3D=
"styled-by-prettify">)</span><span style=3D"color: #000;" class=3D"styled-b=
y-prettify"><br></span><span style=3D"color: #660;" class=3D"styled-by-pret=
tify">{</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br=
>=C2=A0 =C2=A0 </span><span style=3D"color: #008;" class=3D"styled-by-prett=
ify">auto</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> =
my_backtrack </span><span style=3D"color: #660;" class=3D"styled-by-prettif=
y">=3D</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> TAK=
E_CONTINUE</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 f</span><span style=3D"color: #660;" class=3D"styled-by-prettify=
">(...,</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> my=
_backtrack</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"=
>break</span><span style=3D"color: #660;" class=3D"styled-by-prettify">;</s=
pan><span style=3D"color: #000;" class=3D"styled-by-prettify"><br></span><s=
pan style=3D"color: #660;" class=3D"styled-by-prettify">}</span></div></cod=
e></div><br>Alternatively, loops can be defined in terms of backtrack.<br><=
br>Note that, up to this point, we only needed an unwind mechanism (that, a=
s noted, is already there for exceptions) and a local goto-like operation (=
break and continue can be mechanically translated to it).<br><br>It looks p=
referable to be able to &#39;rename&#39; return, continue and break (albeit=
 looks can be deceiving, any thoughts on that are welcome).<br><br>The &#39=
;when you&#39;ve got a hammer, everything looks like a nail&#39;-observatio=
n is that now we can decompose &#39;for&#39;. If we define:<br><br><div cla=
ss=3D"prettyprint" style=3D"background-color: rgb(250, 250, 250); border-co=
lor: rgb(187, 187, 187); border-style: solid; border-width: 1px; word-wrap:=
 break-word;"><code class=3D"prettyprint"><div class=3D"subprettyprint"><sp=
an style=3D"color: #008;" class=3D"styled-by-prettify">for</span><span styl=
e=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"colo=
r: #660;" class=3D"styled-by-prettify">(</span><span style=3D"color: #000;"=
 class=3D"styled-by-prettify"> </span><span style=3D"color: #008;" class=3D=
"styled-by-prettify">int</span><span style=3D"color: #000;" class=3D"styled=
-by-prettify"> i </span><span style=3D"color: #660;" class=3D"styled-by-pre=
ttify">:</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> r=
ange </span><span style=3D"color: #660;" class=3D"styled-by-prettify">)</sp=
an><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span =
style=3D"color: #660;" class=3D"styled-by-prettify">{</span><span style=3D"=
color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #6=
60;" class=3D"styled-by-prettify">...</span><span style=3D"color: #000;" cl=
ass=3D"styled-by-prettify"> </span><span style=3D"color: #660;" class=3D"st=
yled-by-prettify">}</span><span style=3D"color: #000;" class=3D"styled-by-p=
rettify"><br></span></div></code></div><br>as<br><br><div class=3D"prettypr=
int" style=3D"background-color: rgb(250, 250, 250); border-color: rgb(187, =
187, 187); border-style: solid; border-width: 1px; word-wrap: break-word;">=
<code class=3D"prettyprint"><div class=3D"subprettyprint"><span style=3D"co=
lor: #008;" class=3D"styled-by-prettify">for</span><span style=3D"color: #0=
00;" class=3D"styled-by-prettify"> </span><span style=3D"color: #660;" clas=
s=3D"styled-by-prettify">([&amp;,</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"> </span><span style=3D"color: #008;" class=3D"style=
d-by-prettify">return</span><span style=3D"color: #000;" class=3D"styled-by=
-prettify"> </span><span style=3D"color: #660;" class=3D"styled-by-prettify=
">=3D</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> TAKE=
_RETURN</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</span><span style=3D"color: #660;" class=3D"styled-by-prettif=
y">(</span><span style=3D"color: #008;" class=3D"styled-by-prettify">int</s=
pan><span style=3D"color: #000;" class=3D"styled-by-prettify"> i</span><spa=
n style=3D"color: #660;" class=3D"styled-by-prettify">,</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color=
: #008;" class=3D"styled-by-prettify">auto</span><span style=3D"color: #000=
;" class=3D"styled-by-prettify"> </span><span style=3D"color: #008;" class=
=3D"styled-by-prettify">continue</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"> </span><span style=3D"color: #660;" class=3D"style=
d-by-prettify">=3D</span><span style=3D"color: #000;" class=3D"styled-by-pr=
ettify"> TAKE_CONTINUE</span><span style=3D"color: #660;" class=3D"styled-b=
y-prettify">,</span><span style=3D"color: #000;" class=3D"styled-by-prettif=
y"> </span><span style=3D"color: #008;" class=3D"styled-by-prettify">auto</=
span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><spa=
n style=3D"color: #008;" class=3D"styled-by-prettify">break</span><span sty=
le=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"col=
or: #660;" class=3D"styled-by-prettify">=3D</span><span style=3D"color: #00=
0;" class=3D"styled-by-prettify"> TAKE_BREAK</span><span style=3D"color: #6=
60;" class=3D"styled-by-prettify">)</span><span style=3D"color: #000;" clas=
s=3D"styled-by-prettify"> </span><span style=3D"color: #660;" class=3D"styl=
ed-by-prettify">{</span><span style=3D"color: #000;" class=3D"styled-by-pre=
ttify"> </span><span style=3D"color: #660;" class=3D"styled-by-prettify">..=
..</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><=
span style=3D"color: #660;" class=3D"styled-by-prettify">}</span><span styl=
e=3D"color: #000;" class=3D"styled-by-prettify"><br>=C2=A0 =C2=A0 </span><s=
pan style=3D"color: #660;" class=3D"styled-by-prettify">)(</span><span styl=
e=3D"color: #000;" class=3D"styled-by-prettify">range</span><span style=3D"=
color: #660;" class=3D"styled-by-prettify">)</span></div></code></div><br>,=
 then it&#39;s easy to define a &#39;for-function&#39; that provides loop l=
ogic. While we might not want to redefine for itself this way, we might use=
 the above syntax for <i>abitrary</i> functions, given we define the above =
substitution. This would provide immediately the functional equivalent of &=
#39;for break&#39;, with some library support, it&#39;d do for &#39;for els=
e&#39;; as a side effect, it&#39;d allow to separate the loop object from i=
t&#39;s execution, thereby allowing to store the loop object and call it fo=
r different ranges. <br><br>Thanks for the valuable comments and the time,<=
br>-lorro<br><br>2016. szeptember 13., kedd 11:18:58 UTC+2 id=C5=91pontban =
Giovanni Piero Deretta a k=C3=B6vetkez=C5=91t =C3=ADrta:<blockquote class=
=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #cc=
c solid;padding-left: 1ex;"><div dir=3D"ltr">On Tuesday, September 13, 2016=
 at 1:58:00 AM UTC+1, Arthur O&#39;Dwyer wrote:<blockquote class=3D"gmail_q=
uote" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;paddin=
g-left:1ex"><div dir=3D"ltr">Rather than bikeshedding the syntax, I think y=
ou need to take a step back and explain what this proposed feature <b><i>is=
</i></b>. Right now, it reads like one of those joke programming languages =
like INTERCAL or TURKEY BOMB where words are just thrown together for comed=
ic effect, rather than for intrinsic meaning (let alone usefulness).<div><b=
r></div><div>What would it mean for a function to &quot;<font face=3D"couri=
er new, monospace">break</font>, but in its caller&#39;s context&quot;?</di=
v><div>You need to show a specific example of the semantics you&#39;re tryi=
ng to achieve, in the form of</div><div>- a library solution (perhaps invol=
ving setjmp/longjmp or exception-handling under the hood), and/or</div><div=
>- assembly code for a non-trivial use of the proposed feature.</div><div><=
div><div><br></div></div></div></div></blockquote><div><br>I think that the=
 proposal is definitely confused and mentioning monads doesn&#39;t help. Wh=
at the author is proposing is simply capture of first class continuations. =
The proposed syntax only allow capturing some specific continuations (the r=
eturn, and loop and switch break continuations) and only allow escaping to =
them (by throwing away the current continuation), but it could be extended =
to capture any continuation and preserving the current one. The proposal is=
 semantically a subset of the existing stackfull coroutine proposals and ca=
n be implemented on top of them. <br></div></div></blockquote></div>

<p></p>

-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; 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/20bd8e3d-a795-4bf8-84e3-1f74ced450ed%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/20bd8e3d-a795-4bf8-84e3-1f74ced450ed=
%40isocpp.org</a>.<br />

------=_Part_136_438289564.1474496513573--

------=_Part_135_686686119.1474496513572--

.


Author: Avi Kivity <avi@scylladb.com>
Date: Thu, 22 Sep 2016 19:30:21 +0300
Raw View
This is a multi-part message in MIME format.
--------------FB9B51287C2D2B5D488DB75F
Content-Type: text/plain; charset=UTF-8; format=flowed
Content-Transfer-Encoding: quoted-printable

This could be combined with something I've been thinking about: a macro=20
facility.


Motivating example:


     template <typename... Args>

     void log(const char* fmt, Args&&... args) {

         if (logging_enabled) {

             do_log(fmt, std::forward<Args>(args)...);

         }

     }


Now, the problem with this is that if an arg is expensive to compute, we=20
take the cost before the if (logging_enabled) check.


What we could have instead is define log as a macro.  Each arg would=20
then not be captured as a reference, but as a lambda that yields the=20
argument:


     template <typename... Args>

     macro void log(const char* fmt, Args&&... args) {

         if (logging_enabled) {

             do_log(fmt, args()...);

         }

     }


An argument x in log("%s", x) would be translated as [&] () { return x;=20
} -> decltype(x).  Combined with capturing return/break/continue etc. we=20
could introduce new syntax:


     with_lock(my_lock) {

         do things that need my_lock held

         if (some_condition) return;  // releases my_lock and returns=20
from enclosing scope

         do more things

     }


of course, need some syntax to capture the compound statement as a=20
lambda; Swift has support for that we could borrow.


On 09/22/2016 01:21 AM, szollosi.lorand@gmail.com wrote:
> Hi,
>
> Sorry if it's confusing.. So far, it's just a sketch that I'm cleaning=20
> up based on others' suggestions. I'm happy to see the coroutines=20
> proposal. Initially, I've discarded the idea of describing these=20
> captures as I thought that full continuation capture is way to slow=20
> for this (in fact, this should be /exactly/ as fast as loops and=20
> function returns); but you're right, let's formulate these based on=20
> continuations, then let's see optimization possibilities later. (Btw,=20
> as for the subject: is it OK to rename (set new subject) a thread on=20
> this list?)
> So, what I'm proposing is absolute and relative capture of specific=20
> continuations, namely the ones called by return, break, continue. All=20
> of these currently throw away current continuation and it should=20
> remain that way. Absolute capture, /when requested/, should return a=20
> [[noreturn]] functor that is identical, both in parameter(s, if any)=20
> and effect to performing the same return, break, continue in the=20
> /capturing context/. Current continuation is thrown away and=20
> destruction of any automatic storage duration variables are performed=20
> in the usual (reverse-of-declaration) order (i.e., unwinding is=20
> performed), before calling the continuation, up to the capture point.=20
> It is UB to call the functor after leaving capture context or from=20
> another thread (or coroutine).
> Relative capture, /when requested/, should return a [[noreturn]]=20
> functor that is identical, both in parameter(s, if any) and effect to=20
> performing the same return, break, continue in the /calling/ context.=20
> This can either be supported by the language; or a workaround is=20
> possible via having an additional function parameter that has a=20
> default value: (as default value is evaluated in caller's context)
>
> |
> #defineTAKE_RETURN /* syntax to be defined */
>
> template<typenameT>
> intmul_for_accumulate(inta,intb,T return2 =3DTAKE_RETURN)
> {
> if(a=3D=3D0||b=3D=3D0)return2(0);
> returna *b;
> }
>
> |
>
>
> If language support is provided, it's only available in functions; and=20
> in this case, it's UB to call relative return functor with a parameter=20
> that not convertible to the caller's return type; similarly, it's UB=20
> to call break functor or continue functor if these are not available=20
> in the caller's context. Without language support we're more=20
> type-safe, but the caller is aware of the capture (and can divert it);=20
> with language support it's easier to run into UB but it's meaning is=20
> always the same.
>
> A possible 4th continuation to capture would be backtrack (or restart=20
> or cc), that captures the current continuation. It's similar to=20
> setjmp()/longjmp(), but performes unwinding and can be called multiple=20
> times until leaving the context. If not provided, it can be emulated=20
> by while() and continue+break:
>
> |
> while(true)
> {
> automy_backtrack =3DTAKE_CONTINUE;
>     f(...,my_backtrack);
> break;
> }
> |
>
> Alternatively, loops can be defined in terms of backtrack.
>
> Note that, up to this point, we only needed an unwind mechanism (that,=20
> as noted, is already there for exceptions) and a local goto-like=20
> operation (break and continue can be mechanically translated to it).
>
> It looks preferable to be able to 'rename' return, continue and break=20
> (albeit looks can be deceiving, any thoughts on that are welcome).
>
> The 'when you've got a hammer, everything looks like a=20
> nail'-observation is that now we can decompose 'for'. If we define:
>
> |
> for(inti :range ){...}
> |
>
> as
>
> |
> for([&,return=3DTAKE_RETURN]
> (inti,autocontinue=3DTAKE_CONTINUE,autobreak=3DTAKE_BREAK){...}
> )(range)
> |
>
> , then it's easy to define a 'for-function' that provides loop logic.=20
> While we might not want to redefine for itself this way, we might use=20
> the above syntax for /abitrary/ functions, given we define the above=20
> substitution. This would provide immediately the functional equivalent=20
> of 'for break', with some library support, it'd do for 'for else'; as=20
> a side effect, it'd allow to separate the loop object from it's=20
> execution, thereby allowing to store the loop object and call it for=20
> different ranges.
>
> Thanks for the valuable comments and the time,
> -lorro
>
> 2016. szeptember 13., kedd 11:18:58 UTC+2 id=C5=91pontban Giovanni Piero=
=20
> Deretta a k=C3=B6vetkez=C5=91t =C3=ADrta:
>
>     On Tuesday, September 13, 2016 at 1:58:00 AM UTC+1, Arthur O'Dwyer
>     wrote:
>
>         Rather than bikeshedding the syntax, I think you need to take
>         a step back and explain what this proposed feature */is/*.
>         Right now, it reads like one of those joke programming
>         languages like INTERCAL or TURKEY BOMB where words are just
>         thrown together for comedic effect, rather than for intrinsic
>         meaning (let alone usefulness).
>
>         What would it mean for a function to "break, but in its
>         caller's context"?
>         You need to show a specific example of the semantics you're
>         trying to achieve, in the form of
>         - a library solution (perhaps involving setjmp/longjmp or
>         exception-handling under the hood), and/or
>         - assembly code for a non-trivial use of the proposed feature.
>
>
>     I think that the proposal is definitely confused and mentioning
>     monads doesn't help. What the author is proposing is simply
>     capture of first class continuations. The proposed syntax only
>     allow capturing some specific continuations (the return, and loop
>     and switch break continuations) and only allow escaping to them
>     (by throwing away the current continuation), but it could be
>     extended to capture any continuation and preserving the current
>     one. The proposal is semantically a subset of the existing
>     stackfull coroutine proposals and can be implemented on top of them.
>
> --=20
> You received this message because you are subscribed to the Google=20
> Groups "ISO C++ Standard - Future Proposals" group.
> To unsubscribe from this group and stop receiving emails from it, send=20
> an email to std-proposals+unsubscribe@isocpp.org=20
> <mailto:std-proposals+unsubscribe@isocpp.org>.
> To post to this group, send email to std-proposals@isocpp.org=20
> <mailto:std-proposals@isocpp.org>.
> To view this discussion on the web visit=20
> https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/20bd8e3d-a79=
5-4bf8-84e3-1f74ced450ed%40isocpp.org=20
> <https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/20bd8e3d-a7=
95-4bf8-84e3-1f74ced450ed%40isocpp.org?utm_medium=3Demail&utm_source=3Dfoot=
er>.

--=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp=
..org/d/msgid/std-proposals/9ebbe2df-3d49-1f6e-93a8-33998e83133d%40scylladb.=
com.

--------------FB9B51287C2D2B5D488DB75F
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<html>
  <head>
    <meta content=3D"text/html; charset=3Dutf-8" http-equiv=3D"Content-Type=
">
  </head>
  <body bgcolor=3D"#FFFFFF" text=3D"#000000">
    <p><tt>This could be combined with something I've been thinking
        about: a macro facility.</tt></p>
    <p><tt><br>
      </tt></p>
    <p><tt>Motivating example:</tt></p>
    <p><tt><br>
      </tt></p>
    <p><tt>=C2=A0=C2=A0=C2=A0 template &lt;typename... Args&gt;</tt></p>
    <p><tt>=C2=A0=C2=A0=C2=A0 void log(const char* fmt, Args&amp;&amp;... a=
rgs) {</tt></p>
    <p><tt>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 if (logging_enabled) =
{</tt></p>
    <p><tt>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=
=A0 do_log(fmt, std::forward&lt;Args&gt;(args)...);</tt><tt><br>
      </tt></p>
    <p><tt>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 }</tt><tt><br>
      </tt></p>
    <p><tt>=C2=A0=C2=A0=C2=A0 }</tt><br>
    </p>
    <p><br>
    </p>
    <p>Now, the problem with this is that if an arg is expensive to
      compute, we take the cost before the if (logging_enabled) check.</p>
    <p><br>
    </p>
    <p>What we could have instead is define log as a macro.=C2=A0 Each arg
      would then not be captured as a reference, but as a lambda that
      yields the argument:<br>
    </p>
    <p><br>
    </p>
    <p><tt>=C2=A0=C2=A0=C2=A0 template &lt;typename... Args&gt;</tt></p>
    <p><tt>=C2=A0=C2=A0=C2=A0 macro void log(const char* fmt, Args&amp;&amp=
;... args) {</tt></p>
    <p><tt>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 if (logging_enabled) =
{</tt></p>
    <p><tt>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=
=A0 do_log(fmt, args()...);</tt><tt><br>
      </tt></p>
    <p><tt>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 }</tt><tt><br>
      </tt></p>
    <p><tt>=C2=A0=C2=A0=C2=A0 }</tt><br>
    </p>
    <p><br>
    </p>
    <p>An argument x in log("%s", x) would be translated as [&amp;] () {
      return x; } -&gt; decltype(x).=C2=A0 Combined with capturing
      return/break/continue etc. we could introduce new syntax:</p>
    <p><br>
    </p>
    <p>=C2=A0=C2=A0=C2=A0 with_lock(my_lock) {</p>
    <p>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 do things that need my_lo=
ck held</p>
    <p>=C2=A0 =C2=A0=C2=A0 =C2=A0=C2=A0 if (some_condition) return;=C2=A0 /=
/ releases my_lock and
      returns from enclosing scope<br>
    </p>
    <p>=C2=A0 =C2=A0=C2=A0 =C2=A0=C2=A0 do more things<br>
    </p>
    <p>=C2=A0=C2=A0=C2=A0 }<br>
    </p>
    <p><br>
    </p>
    <p>of course, need some syntax to capture the compound statement as
      a lambda; Swift has support for that we could borrow.<br>
    </p>
    <p>=C2=A0=C2=A0=C2=A0 </p>
    <br>
    <div class=3D"moz-cite-prefix">On 09/22/2016 01:21 AM,
      <a class=3D"moz-txt-link-abbreviated" href=3D"mailto:szollosi.lorand@=
gmail.com">szollosi.lorand@gmail.com</a> wrote:<br>
    </div>
    <blockquote
      cite=3D"mid:20bd8e3d-a795-4bf8-84e3-1f74ced450ed@isocpp.org"
      type=3D"cite">
      <div dir=3D"ltr">Hi,<br>
        <br>
        Sorry if it's confusing.. So far, it's just a sketch that I'm
        cleaning up based on others' suggestions. I'm happy to see the
        coroutines proposal. Initially, I've discarded the idea of
        describing these captures as I thought that full continuation
        capture is way to slow for this (in fact, this should be <i>exactly=
</i>
        as fast as loops and function returns); but you're right, let's
        formulate these based on continuations, then let's see
        optimization possibilities later. (Btw, as for the subject: is
        it OK to rename (set new subject) a thread on this list?)<br>
        So, what I'm proposing is absolute and relative capture of
        specific continuations, namely the ones called by return, break,
        continue. All of these currently throw away current continuation
        and it should remain that way. Absolute capture, <i>when
          requested</i>, should return a [[noreturn]] functor that is
        identical, both in parameter(s, if any) and effect to performing
        the same return, break, continue in the <i>capturing context</i>.
        Current continuation is thrown away and destruction of any
        automatic storage duration variables are performed in the usual
        (reverse-of-declaration) order (i.e., unwinding is performed),
        before calling the continuation, up to the capture point. It is
        UB to call the functor after leaving capture context or from
        another thread (or coroutine).<br>
        Relative capture, <i>when requested</i>, should return a
        [[noreturn]] functor that is identical, both in parameter(s, if
        any) and effect to performing the same return, break, continue
        in the <i>calling</i> context. This can either be supported by
        the language; or a workaround is possible via having an
        additional function parameter that has a default value: (as
        default value is evaluated in caller's context)<br>
        <br>
        <div class=3D"prettyprint" style=3D"background-color: rgb(250, 250,
          250); border-color: rgb(187, 187, 187); border-style: solid;
          border-width: 1px; word-wrap: break-word;"><code
            class=3D"prettyprint">
            <div class=3D"subprettyprint"><span style=3D"color: #800;"
                class=3D"styled-by-prettify">#define</span><span
                style=3D"color: #000;" class=3D"styled-by-prettify">
                TAKE_RETURN </span><span style=3D"color: #800;"
                class=3D"styled-by-prettify">/* syntax to be defined */</sp=
an><span
                style=3D"color: #000;" class=3D"styled-by-prettify"><br>
                <br>
              </span><span style=3D"color: #008;"
                class=3D"styled-by-prettify">template</span><span
                style=3D"color: #660;" class=3D"styled-by-prettify">&lt;</s=
pan><span
                style=3D"color: #008;" class=3D"styled-by-prettify">typenam=
e</span><span
                style=3D"color: #000;" class=3D"styled-by-prettify"> T</spa=
n><span
                style=3D"color: #660;" class=3D"styled-by-prettify">&gt;</s=
pan><span
                style=3D"color: #000;" class=3D"styled-by-prettify"><br>
              </span><span style=3D"color: #008;"
                class=3D"styled-by-prettify">int</span><span style=3D"color=
:
                #000;" class=3D"styled-by-prettify"> mul_for_accumulate</sp=
an><span
                style=3D"color: #660;" class=3D"styled-by-prettify">(</span=
><span
                style=3D"color: #008;" class=3D"styled-by-prettify">int</sp=
an><span
                style=3D"color: #000;" class=3D"styled-by-prettify"> a</spa=
n><span
                style=3D"color: #660;" class=3D"styled-by-prettify">,</span=
><span
                style=3D"color: #000;" class=3D"styled-by-prettify"> </span=
><span
                style=3D"color: #008;" class=3D"styled-by-prettify">int</sp=
an><span
                style=3D"color: #000;" class=3D"styled-by-prettify"> b</spa=
n><span
                style=3D"color: #660;" class=3D"styled-by-prettify">,</span=
><span
                style=3D"color: #000;" class=3D"styled-by-prettify"> T
                return2 </span><span style=3D"color: #660;"
                class=3D"styled-by-prettify">=3D</span><span style=3D"color=
:
                #000;" class=3D"styled-by-prettify"> TAKE_RETURN</span><spa=
n
                style=3D"color: #660;" class=3D"styled-by-prettify">)</span=
><span
                style=3D"color: #000;" class=3D"styled-by-prettify"><br>
              </span><span 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">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"styled-by-prettify">a</span=
><span
                style=3D"color: #660;" class=3D"styled-by-prettify">=3D=3D<=
/span><span
                style=3D"color: #066;" class=3D"styled-by-prettify">0</span=
><span
                style=3D"color: #000;" class=3D"styled-by-prettify"> </span=
><span
                style=3D"color: #660;" class=3D"styled-by-prettify">||</spa=
n><span
                style=3D"color: #000;" class=3D"styled-by-prettify"> b</spa=
n><span
                style=3D"color: #660;" class=3D"styled-by-prettify">=3D=3D<=
/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"> return=
2</span><span
                style=3D"color: #660;" class=3D"styled-by-prettify">(</span=
><span
                style=3D"color: #066;" class=3D"styled-by-prettify">0</span=
><span
                style=3D"color: #660;" class=3D"styled-by-prettify">);</spa=
n><span
                style=3D"color: #000;" class=3D"styled-by-prettify"><br>
                =C2=A0 =C2=A0 </span><span style=3D"color: #008;"
                class=3D"styled-by-prettify">return</span><span
                style=3D"color: #000;" class=3D"styled-by-prettify"> a </sp=
an><span
                style=3D"color: #660;" class=3D"styled-by-prettify">*</span=
><span
                style=3D"color: #000;" class=3D"styled-by-prettify"> b</spa=
n><span
                style=3D"color: #660;" class=3D"styled-by-prettify">;</span=
><span
                style=3D"color: #000;" class=3D"styled-by-prettify"><br>
              </span><span style=3D"color: #660;"
                class=3D"styled-by-prettify">}</span><span style=3D"color:
                #000;" class=3D"styled-by-prettify"><br>
                <br>
              </span></div>
          </code></div>
        <br>
        <br>
        If language support is provided, it's only available in
        functions; and in this case, it's UB to call relative return
        functor with a parameter that not convertible to the caller's
        return type; similarly, it's UB to call break functor or
        continue functor if these are not available in the caller's
        context. Without language support we're more type-safe, but the
        caller is aware of the capture (and can divert it); with
        language support it's easier to run into UB but it's meaning is
        always the same.<br>
        <br>
        A possible 4th continuation to capture would be backtrack (or
        restart or cc), that captures the current continuation. It's
        similar to setjmp()/longjmp(), but performes unwinding and can
        be called multiple times until leaving the context. If not
        provided, it can be emulated by while() and continue+break:<br>
        <br>
        <div class=3D"prettyprint" style=3D"background-color: rgb(250, 250,
          250); border-color: rgb(187, 187, 187); border-style: solid;
          border-width: 1px; word-wrap: break-word;"><code
            class=3D"prettyprint">
            <div class=3D"subprettyprint"><span style=3D"color: #008;"
                class=3D"styled-by-prettify">while</span><span
                style=3D"color: #660;" class=3D"styled-by-prettify">(</span=
><span
                style=3D"color: #008;" class=3D"styled-by-prettify">true</s=
pan><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 =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">
                my_backtrack </span><span style=3D"color: #660;"
                class=3D"styled-by-prettify">=3D</span><span style=3D"color=
:
                #000;" class=3D"styled-by-prettify"> TAKE_CONTINUE</span><s=
pan
                style=3D"color: #660;" class=3D"styled-by-prettify">;</span=
><span
                style=3D"color: #000;" class=3D"styled-by-prettify"><br>
                =C2=A0 =C2=A0 f</span><span style=3D"color: #660;"
                class=3D"styled-by-prettify">(...,</span><span
                style=3D"color: #000;" class=3D"styled-by-prettify">
                my_backtrack</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">break</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>
        <br>
        Alternatively, loops can be defined in terms of backtrack.<br>
        <br>
        Note that, up to this point, we only needed an unwind mechanism
        (that, as noted, is already there for exceptions) and a local
        goto-like operation (break and continue can be mechanically
        translated to it).<br>
        <br>
        It looks preferable to be able to 'rename' return, continue and
        break (albeit looks can be deceiving, any thoughts on that are
        welcome).<br>
        <br>
        The 'when you've got a hammer, everything looks like a
        nail'-observation is that now we can decompose 'for'. If we
        define:<br>
        <br>
        <div class=3D"prettyprint" style=3D"background-color: rgb(250, 250,
          250); border-color: rgb(187, 187, 187); border-style: solid;
          border-width: 1px; word-wrap: break-word;"><code
            class=3D"prettyprint">
            <div class=3D"subprettyprint"><span style=3D"color: #008;"
                class=3D"styled-by-prettify">for</span><span style=3D"color=
:
                #000;" class=3D"styled-by-prettify"> </span><span
                style=3D"color: #660;" class=3D"styled-by-prettify">(</span=
><span
                style=3D"color: #000;" class=3D"styled-by-prettify"> </span=
><span
                style=3D"color: #008;" class=3D"styled-by-prettify">int</sp=
an><span
                style=3D"color: #000;" class=3D"styled-by-prettify"> i </sp=
an><span
                style=3D"color: #660;" class=3D"styled-by-prettify">:</span=
><span
                style=3D"color: #000;" class=3D"styled-by-prettify"> range =
</span><span
                style=3D"color: #660;" class=3D"styled-by-prettify">)</span=
><span
                style=3D"color: #000;" class=3D"styled-by-prettify"> </span=
><span
                style=3D"color: #660;" class=3D"styled-by-prettify">{</span=
><span
                style=3D"color: #000;" class=3D"styled-by-prettify"> </span=
><span
                style=3D"color: #660;" class=3D"styled-by-prettify">...</sp=
an><span
                style=3D"color: #000;" class=3D"styled-by-prettify"> </span=
><span
                style=3D"color: #660;" class=3D"styled-by-prettify">}</span=
><span
                style=3D"color: #000;" class=3D"styled-by-prettify"><br>
              </span></div>
          </code></div>
        <br>
        as<br>
        <br>
        <div class=3D"prettyprint" style=3D"background-color: rgb(250, 250,
          250); border-color: rgb(187, 187, 187); border-style: solid;
          border-width: 1px; word-wrap: break-word;"><code
            class=3D"prettyprint">
            <div class=3D"subprettyprint"><span style=3D"color: #008;"
                class=3D"styled-by-prettify">for</span><span style=3D"color=
:
                #000;" class=3D"styled-by-prettify"> </span><span
                style=3D"color: #660;" class=3D"styled-by-prettify">([&amp;=
,</span><span
                style=3D"color: #000;" class=3D"styled-by-prettify"> </span=
><span
                style=3D"color: #008;" class=3D"styled-by-prettify">return<=
/span><span
                style=3D"color: #000;" class=3D"styled-by-prettify"> </span=
><span
                style=3D"color: #660;" class=3D"styled-by-prettify">=3D</sp=
an><span
                style=3D"color: #000;" class=3D"styled-by-prettify">
                TAKE_RETURN</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</span><span style=3D"color: #660;"
                class=3D"styled-by-prettify">(</span><span style=3D"color:
                #008;" class=3D"styled-by-prettify">int</span><span
                style=3D"color: #000;" class=3D"styled-by-prettify"> i</spa=
n><span
                style=3D"color: #660;" class=3D"styled-by-prettify">,</span=
><span
                style=3D"color: #000;" class=3D"styled-by-prettify"> </span=
><span
                style=3D"color: #008;" class=3D"styled-by-prettify">auto</s=
pan><span
                style=3D"color: #000;" class=3D"styled-by-prettify"> </span=
><span
                style=3D"color: #008;" class=3D"styled-by-prettify">continu=
e</span><span
                style=3D"color: #000;" class=3D"styled-by-prettify"> </span=
><span
                style=3D"color: #660;" class=3D"styled-by-prettify">=3D</sp=
an><span
                style=3D"color: #000;" class=3D"styled-by-prettify">
                TAKE_CONTINUE</span><span style=3D"color: #660;"
                class=3D"styled-by-prettify">,</span><span style=3D"color:
                #000;" class=3D"styled-by-prettify"> </span><span
                style=3D"color: #008;" class=3D"styled-by-prettify">auto</s=
pan><span
                style=3D"color: #000;" class=3D"styled-by-prettify"> </span=
><span
                style=3D"color: #008;" class=3D"styled-by-prettify">break</=
span><span
                style=3D"color: #000;" class=3D"styled-by-prettify"> </span=
><span
                style=3D"color: #660;" class=3D"styled-by-prettify">=3D</sp=
an><span
                style=3D"color: #000;" class=3D"styled-by-prettify">
                TAKE_BREAK</span><span style=3D"color: #660;"
                class=3D"styled-by-prettify">)</span><span style=3D"color:
                #000;" class=3D"styled-by-prettify"> </span><span
                style=3D"color: #660;" class=3D"styled-by-prettify">{</span=
><span
                style=3D"color: #000;" class=3D"styled-by-prettify"> </span=
><span
                style=3D"color: #660;" class=3D"styled-by-prettify">...</sp=
an><span
                style=3D"color: #000;" class=3D"styled-by-prettify"> </span=
><span
                style=3D"color: #660;" class=3D"styled-by-prettify">}</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">range</span><span
                style=3D"color: #660;" class=3D"styled-by-prettify">)</span=
></div>
          </code></div>
        <br>
        , then it's easy to define a 'for-function' that provides loop
        logic. While we might not want to redefine for itself this way,
        we might use the above syntax for <i>abitrary</i> functions,
        given we define the above substitution. This would provide
        immediately the functional equivalent of 'for break', with some
        library support, it'd do for 'for else'; as a side effect, it'd
        allow to separate the loop object from it's execution, thereby
        allowing to store the loop object and call it for different
        ranges. <br>
        <br>
        Thanks for the valuable comments and the time,<br>
        -lorro<br>
        <br>
        2016. szeptember 13., kedd 11:18:58 UTC+2 id=C5=91pontban Giovanni
        Piero Deretta a k=C3=B6vetkez=C5=91t =C3=ADrta:
        <blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left:
          0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">
          <div dir=3D"ltr">On Tuesday, September 13, 2016 at 1:58:00 AM
            UTC+1, Arthur O'Dwyer 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">Rather than bikeshedding the syntax, I
                think you need to take a step back and explain what this
                proposed feature <b><i>is</i></b>. Right now, it reads
                like one of those joke programming languages like
                INTERCAL or TURKEY BOMB where words are just thrown
                together for comedic effect, rather than for intrinsic
                meaning (let alone usefulness).
                <div><br>
                </div>
                <div>What would it mean for a function to "<font
                    face=3D"courier new, monospace">break</font>, but in
                  its caller's context"?</div>
                <div>You need to show a specific example of the
                  semantics you're trying to achieve, in the form of</div>
                <div>- a library solution (perhaps involving
                  setjmp/longjmp or exception-handling under the hood),
                  and/or</div>
                <div>- assembly code for a non-trivial use of the
                  proposed feature.</div>
                <div>
                  <div>
                    <div><br>
                    </div>
                  </div>
                </div>
              </div>
            </blockquote>
            <div><br>
              I think that the proposal is definitely confused and
              mentioning monads doesn't help. What the author is
              proposing is simply capture of first class continuations.
              The proposed syntax only allow capturing some specific
              continuations (the return, and loop and switch break
              continuations) and only allow escaping to them (by
              throwing away the current continuation), but it could be
              extended to capture any continuation and preserving the
              current one. The proposal is semantically a subset of the
              existing stackfull coroutine proposals and can be
              implemented on top of them. <br>
            </div>
          </div>
        </blockquote>
      </div>
      -- <br>
      You received this message because you are subscribed to the Google
      Groups "ISO C++ Standard - Future Proposals" group.<br>
      To unsubscribe from this group and stop receiving emails from it,
      send an email to <a moz-do-not-send=3D"true"
        href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposals+=
unsubscribe@isocpp.org</a>.<br>
      To post to this group, send email to <a moz-do-not-send=3D"true"
        href=3D"mailto:std-proposals@isocpp.org">std-proposals@isocpp.org</=
a>.<br>
      To view this discussion on the web visit <a
        moz-do-not-send=3D"true"
href=3D"https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/20bd8e=
3d-a795-4bf8-84e3-1f74ced450ed%40isocpp.org?utm_medium=3Demail&amp;utm_sour=
ce=3Dfooter">https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/2=
0bd8e3d-a795-4bf8-84e3-1f74ced450ed%40isocpp.org</a>.<br>
    </blockquote>
    <br>
  </body>
</html>

<p></p>

-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; 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/9ebbe2df-3d49-1f6e-93a8-33998e83133d%=
40scylladb.com?utm_medium=3Demail&utm_source=3Dfooter">https://groups.googl=
e.com/a/isocpp.org/d/msgid/std-proposals/9ebbe2df-3d49-1f6e-93a8-33998e8313=
3d%40scylladb.com</a>.<br />

--------------FB9B51287C2D2B5D488DB75F--

.


Author: szollosi.lorand@gmail.com
Date: Mon, 26 Sep 2016 15:20:34 -0700 (PDT)
Raw View
------=_Part_12_898525331.1474928434200
Content-Type: multipart/alternative;
 boundary="----=_Part_13_187108353.1474928434205"

------=_Part_13_187108353.1474928434205
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

Hi,

I was about to say that it's a different issue, but it's actually not. I'm,=
=20
however, not convinced that we need a new keyword for this. What you want=
=20
basically is capturing an *expression* rather than its *value* as a=20
function parameter. This facility already exists in ?:, ||, &&, we just=20
need to extend that for regular functions. Something like:

template<typename T>
T my_ternary(const bool cond, ->T true_t, ->T false_t)
{
    if (cond)
        return true_t();
    return false_t();
}

int main()
{
    int i =3D 0;
    auto a =3D [&]() mutable { return ++i; };
    auto b =3D [&]() mutable { return ++i; };
    std::cout << my_ternary(rand()%2, a(), b()); // should print 1, no UB
/IDV
}

That way you can choose which params you take by value and which as=20
expression. Now, a lot of questions arise which would deserve a specific=20
thread on that.

Thanks,
-lorro


2016. szeptember 22., cs=C3=BCt=C3=B6rt=C3=B6k 18:30:26 UTC+2 id=C5=91pontb=
an Avi Kivity a=20
k=C3=B6vetkez=C5=91t =C3=ADrta:
>
> This could be combined with something I've been thinking about: a macro=
=20
> facility.
>
>
> Motivating example:
>
>
>     template <typename... Args>
>
>     void log(const char* fmt, Args&&... args) {
>
>         if (logging_enabled) {
>
>             do_log(fmt, std::forward<Args>(args)...);
>
>         }
>
>     }
>
>
> Now, the problem with this is that if an arg is expensive to compute, we=
=20
> take the cost before the if (logging_enabled) check.
>
>
> What we could have instead is define log as a macro.  Each arg would then=
=20
> not be captured as a reference, but as a lambda that yields the argument:
>
>
>     template <typename... Args>
>
>     macro void log(const char* fmt, Args&&... args) {
>
>         if (logging_enabled) {
>
>             do_log(fmt, args()...);
>
>         }
>
>     }
>
>
> An argument x in log("%s", x) would be translated as [&] () { return x; }=
=20
> -> decltype(x).  Combined with capturing return/break/continue etc. we=20
> could introduce new syntax:
>
>
>     with_lock(my_lock) {
>
>         do things that need my_lock held
>
>         if (some_condition) return;  // releases my_lock and returns from=
=20
> enclosing scope
>
>         do more things
>
>     }
>
>
> of course, need some syntax to capture the compound statement as a lambda=
;=20
> Swift has support for that we could borrow.
>
>    =20
>
> On 09/22/2016 01:21 AM, szollos...@gmail.com <javascript:> wrote:
>
> Hi,
>
> Sorry if it's confusing.. So far, it's just a sketch that I'm cleaning up=
=20
> based on others' suggestions. I'm happy to see the coroutines proposal.=
=20
> Initially, I've discarded the idea of describing these captures as I=20
> thought that full continuation capture is way to slow for this (in fact,=
=20
> this should be *exactly* as fast as loops and function returns); but=20
> you're right, let's formulate these based on continuations, then let's se=
e=20
> optimization possibilities later. (Btw, as for the subject: is it OK to=
=20
> rename (set new subject) a thread on this list?)
> So, what I'm proposing is absolute and relative capture of specific=20
> continuations, namely the ones called by return, break, continue. All of=
=20
> these currently throw away current continuation and it should remain that=
=20
> way. Absolute capture, *when requested*, should return a [[noreturn]]=20
> functor that is identical, both in parameter(s, if any) and effect to=20
> performing the same return, break, continue in the *capturing context*.=
=20
> Current continuation is thrown away and destruction of any automatic=20
> storage duration variables are performed in the usual=20
> (reverse-of-declaration) order (i.e., unwinding is performed), before=20
> calling the continuation, up to the capture point. It is UB to call the=
=20
> functor after leaving capture context or from another thread (or coroutin=
e).
> Relative capture, *when requested*, should return a [[noreturn]] functor=
=20
> that is identical, both in parameter(s, if any) and effect to performing=
=20
> the same return, break, continue in the *calling* context. This can=20
> either be supported by the language; or a workaround is possible via havi=
ng=20
> an additional function parameter that has a default value: (as default=20
> value is evaluated in caller's context)
>
> #define TAKE_RETURN /* syntax to be defined */
>
> template<typename T>
> int mul_for_accumulate(int a, int b, T return2 =3D TAKE_RETURN)
> {
>     if (a=3D=3D0 || b=3D=3D0) return2(0);
>     return a * b;
> }
>
>
>
> If language support is provided, it's only available in functions; and in=
=20
> this case, it's UB to call relative return functor with a parameter that=
=20
> not convertible to the caller's return type; similarly, it's UB to call=
=20
> break functor or continue functor if these are not available in the=20
> caller's context. Without language support we're more type-safe, but the=
=20
> caller is aware of the capture (and can divert it); with language support=
=20
> it's easier to run into UB but it's meaning is always the same.
>
> A possible 4th continuation to capture would be backtrack (or restart or=
=20
> cc), that captures the current continuation. It's similar to=20
> setjmp()/longjmp(), but performes unwinding and can be called multiple=20
> times until leaving the context. If not provided, it can be emulated by=
=20
> while() and continue+break:
>
> while(true)
> {
>     auto my_backtrack =3D TAKE_CONTINUE;
>     f(..., my_backtrack);
>     break;
> }
>
> Alternatively, loops can be defined in terms of backtrack.
>
> Note that, up to this point, we only needed an unwind mechanism (that, as=
=20
> noted, is already there for exceptions) and a local goto-like operation=
=20
> (break and continue can be mechanically translated to it).
>
> It looks preferable to be able to 'rename' return, continue and break=20
> (albeit looks can be deceiving, any thoughts on that are welcome).
>
> The 'when you've got a hammer, everything looks like a nail'-observation=
=20
> is that now we can decompose 'for'. If we define:
>
> for ( int i : range ) { ... }
>
> as
>
> for ([&, return =3D TAKE_RETURN]
>      (int i, auto continue =3D TAKE_CONTINUE, auto break =3D TAKE_BREAK) =
{ ...=20
> }
>     )(range)
>
> , then it's easy to define a 'for-function' that provides loop logic.=20
> While we might not want to redefine for itself this way, we might use the=
=20
> above syntax for *abitrary* functions, given we define the above=20
> substitution. This would provide immediately the functional equivalent of=
=20
> 'for break', with some library support, it'd do for 'for else'; as a side=
=20
> effect, it'd allow to separate the loop object from it's execution, there=
by=20
> allowing to store the loop object and call it for different ranges.=20
>
> Thanks for the valuable comments and the time,
> -lorro
>
> 2016. szeptember 13., kedd 11:18:58 UTC+2 id=C5=91pontban Giovanni Piero=
=20
> Deretta a k=C3=B6vetkez=C5=91t =C3=ADrta:=20
>>
>> On Tuesday, September 13, 2016 at 1:58:00 AM UTC+1, Arthur O'Dwyer wrote=
:=20
>>>
>>> Rather than bikeshedding the syntax, I think you need to take a step=20
>>> back and explain what this proposed feature *is*. Right now, it reads=
=20
>>> like one of those joke programming languages like INTERCAL or TURKEY BO=
MB=20
>>> where words are just thrown together for comedic effect, rather than fo=
r=20
>>> intrinsic meaning (let alone usefulness).=20
>>>
>>> What would it mean for a function to "break, but in its caller's=20
>>> context"?
>>> You need to show a specific example of the semantics you're trying to=
=20
>>> achieve, in the form of
>>> - a library solution (perhaps involving setjmp/longjmp or=20
>>> exception-handling under the hood), and/or
>>> - assembly code for a non-trivial use of the proposed feature.
>>>
>>>
>> I think that the proposal is definitely confused and mentioning monads=
=20
>> doesn't help. What the author is proposing is simply capture of first cl=
ass=20
>> continuations. The proposed syntax only allow capturing some specific=20
>> continuations (the return, and loop and switch break continuations) and=
=20
>> only allow escaping to them (by throwing away the current continuation),=
=20
>> but it could be extended to capture any continuation and preserving the=
=20
>> current one. The proposal is semantically a subset of the existing=20
>> stackfull coroutine proposals and can be implemented on top of them.=20
>>
> --=20
> You received this message because you are subscribed to the Google Groups=
=20
> "ISO C++ Standard - Future Proposals" group.
> To unsubscribe from this group and stop receiving emails from it, send an=
=20
> email to std-proposal...@isocpp.org <javascript:>.
> To post to this group, send email to std-pr...@isocpp.org <javascript:>.
> To view this discussion on the web visit=20
> https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/20bd8e3d-a79=
5-4bf8-84e3-1f74ced450ed%40isocpp.org=20
> <https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/20bd8e3d-a7=
95-4bf8-84e3-1f74ced450ed%40isocpp.org?utm_medium=3Demail&utm_source=3Dfoot=
er>
> .
>
>
>

--=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp=
..org/d/msgid/std-proposals/b2c39042-36da-485a-91f9-b02f4123dc29%40isocpp.or=
g.

------=_Part_13_187108353.1474928434205
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">Hi,<br><br>I was about to say that it&#39;s a different is=
sue, but it&#39;s actually not. I&#39;m, however, not convinced that we nee=
d a new keyword for this. What you want basically is capturing an <i>expres=
sion</i> rather than its <i>value</i> as a function parameter. This facilit=
y already exists in ?:, ||, &amp;&amp;, we just need to extend that for reg=
ular functions. Something like:<br><br><div class=3D"prettyprint" style=3D"=
background-color: rgb(250, 250, 250); border-color: rgb(187, 187, 187); bor=
der-style: solid; border-width: 1px; word-wrap: break-word;"><code class=3D=
"prettyprint"><div class=3D"subprettyprint"><span style=3D"color: #008;" cl=
ass=3D"styled-by-prettify">template</span><span style=3D"color: #660;" clas=
s=3D"styled-by-prettify">&lt;</span><span style=3D"color: #008;" class=3D"s=
tyled-by-prettify">typename</span><span style=3D"color: #000;" class=3D"sty=
led-by-prettify"> T</span><span style=3D"color: #660;" class=3D"styled-by-p=
rettify">&gt;</span><span style=3D"color: #000;" class=3D"styled-by-prettif=
y"><br>T my_ternary</span><span style=3D"color: #660;" class=3D"styled-by-p=
rettify">(</span><span style=3D"color: #008;" class=3D"styled-by-prettify">=
const</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </sp=
an><span style=3D"color: #008;" class=3D"styled-by-prettify">bool</span><sp=
an style=3D"color: #000;" class=3D"styled-by-prettify"> cond</span><span st=
yle=3D"color: #660;" class=3D"styled-by-prettify">,</span><span style=3D"co=
lor: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #660=
;" class=3D"styled-by-prettify">-&gt;</span><span style=3D"color: #000;" cl=
ass=3D"styled-by-prettify">T true_t</span><span style=3D"color: #660;" clas=
s=3D"styled-by-prettify">,</span><span style=3D"color: #000;" class=3D"styl=
ed-by-prettify"> </span><span style=3D"color: #660;" class=3D"styled-by-pre=
ttify">-&gt;</span><span style=3D"color: #000;" class=3D"styled-by-prettify=
">T false_t</span><span style=3D"color: #660;" class=3D"styled-by-prettify"=
>)</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br></sp=
an><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 </spa=
n><span style=3D"color: #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: #0=
00;" class=3D"styled-by-prettify">cond</span><span style=3D"color: #660;" c=
lass=3D"styled-by-prettify">)</span><span style=3D"color: #000;" class=3D"s=
tyled-by-prettify"><br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 </span><span style=3D"co=
lor: #008;" class=3D"styled-by-prettify">return</span><span style=3D"color:=
 #000;" class=3D"styled-by-prettify"> true_t</span><span style=3D"color: #6=
60;" class=3D"styled-by-prettify">();</span><span style=3D"color: #000;" cl=
ass=3D"styled-by-prettify"><br>=C2=A0 =C2=A0 </span><span style=3D"color: #=
008;" class=3D"styled-by-prettify">return</span><span style=3D"color: #000;=
" class=3D"styled-by-prettify"> false_t</span><span style=3D"color: #660;" =
class=3D"styled-by-prettify">();</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"><br></span><span style=3D"color: #660;" class=3D"st=
yled-by-prettify">}</span><span style=3D"color: #000;" class=3D"styled-by-p=
rettify"><br><br></span><span style=3D"color: #008;" class=3D"styled-by-pre=
ttify">int</span><span style=3D"color: #000;" class=3D"styled-by-prettify">=
 main</span><span style=3D"color: #660;" class=3D"styled-by-prettify">()</s=
pan><span style=3D"color: #000;" class=3D"styled-by-prettify"><br></span><s=
pan style=3D"color: #660;" class=3D"styled-by-prettify">{</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"><br>=C2=A0 =C2=A0 </span><sp=
an style=3D"color: #008;" class=3D"styled-by-prettify">int</span><span styl=
e=3D"color: #000;" class=3D"styled-by-prettify"> i </span><span style=3D"co=
lor: #660;" class=3D"styled-by-prettify">=3D</span><span style=3D"color: #0=
00;" class=3D"styled-by-prettify"> </span><span style=3D"color: #066;" clas=
s=3D"styled-by-prettify">0</span><span style=3D"color: #660;" class=3D"styl=
ed-by-prettify">;</span><span style=3D"color: #000;" class=3D"styled-by-pre=
ttify"><br>=C2=A0 =C2=A0 </span><span style=3D"color: #008;" class=3D"style=
d-by-prettify">auto</span><span style=3D"color: #000;" class=3D"styled-by-p=
rettify"> a </span><span style=3D"color: #660;" class=3D"styled-by-prettify=
">=3D</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </sp=
an><span style=3D"color: #660;" class=3D"styled-by-prettify">[&amp;]()</spa=
n><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span s=
tyle=3D"color: #008;" class=3D"styled-by-prettify">mutable</span><span styl=
e=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"colo=
r: #660;" class=3D"styled-by-prettify">{</span><span style=3D"color: #000;"=
 class=3D"styled-by-prettify"> </span><span style=3D"color: #008;" class=3D=
"styled-by-prettify">return</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">=
i</span><span style=3D"color: #660;" class=3D"styled-by-prettify">;</span><=
span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span styl=
e=3D"color: #660;" class=3D"styled-by-prettify">};</span><span style=3D"col=
or: #000;" class=3D"styled-by-prettify"></span><br><span style=3D"color: #0=
00;" class=3D"styled-by-prettify"><code class=3D"prettyprint"><span style=
=3D"color: #000;" class=3D"styled-by-prettify">=C2=A0 =C2=A0 </span><span s=
tyle=3D"color: #008;" class=3D"styled-by-prettify">auto</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"> b </span><span style=3D"col=
or: #660;" class=3D"styled-by-prettify">=3D</span><span style=3D"color: #00=
0;" class=3D"styled-by-prettify"> </span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">[&amp;]()</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"> </span><span style=3D"color: #008;" class=3D"style=
d-by-prettify">mutable</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"> </spa=
n><span style=3D"color: #008;" class=3D"styled-by-prettify">return</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"colo=
r: #000;" class=3D"styled-by-prettify">i</span><span style=3D"color: #660;"=
 class=3D"styled-by-prettify">;</span><span style=3D"color: #000;" class=3D=
"styled-by-prettify"> </span><span style=3D"color: #660;" class=3D"styled-b=
y-prettify">};</span><span style=3D"color: #000;" class=3D"styled-by-pretti=
fy"><br></span></code>=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"styl=
ed-by-prettify">&lt;&lt;</span><span style=3D"color: #000;" class=3D"styled=
-by-prettify"> my_ternary</span><span style=3D"color: #660;" class=3D"style=
d-by-prettify">(</span><span style=3D"color: #000;" class=3D"styled-by-pret=
tify">rand</span><span style=3D"color: #660;" class=3D"styled-by-prettify">=
()%</span><span style=3D"color: #066;" class=3D"styled-by-prettify">2</span=
><span style=3D"color: #660;" class=3D"styled-by-prettify">,</span><span st=
yle=3D"color: #000;" class=3D"styled-by-prettify"> a</span><span style=3D"c=
olor: #660;" class=3D"styled-by-prettify">(),</span><span style=3D"color: #=
000;" class=3D"styled-by-prettify"> b</span><span style=3D"color: #660;" cl=
ass=3D"styled-by-prettify">());</span><span style=3D"color: #000;" class=3D=
"styled-by-prettify"> </span><span style=3D"color: #800;" class=3D"styled-b=
y-prettify">// should print 1, no UB</span><span style=3D"color: #000;" cla=
ss=3D"styled-by-prettify">/IDV<br></span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">}</span><span style=3D"color: #000;" class=3D"style=
d-by-prettify"><br></span></div></code></div><br>That way you can choose wh=
ich params you take by value and which as expression. Now, a lot of questio=
ns arise which would deserve a specific thread on that.<br><br>Thanks,<br>-=
lorro<br> <br><br>2016. szeptember 22., cs=C3=BCt=C3=B6rt=C3=B6k 18:30:26 U=
TC+2 id=C5=91pontban Avi Kivity a k=C3=B6vetkez=C5=91t =C3=ADrta:<blockquot=
e class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-left: =
1px #ccc solid;padding-left: 1ex;">
 =20
   =20
 =20
  <div bgcolor=3D"#FFFFFF" text=3D"#000000">
    <p><tt>This could be combined with something I&#39;ve been thinking
        about: a macro facility.</tt></p>
    <p><tt><br>
      </tt></p>
    <p><tt>Motivating example:</tt></p>
    <p><tt><br>
      </tt></p>
    <p><tt>=C2=A0=C2=A0=C2=A0 template &lt;typename... Args&gt;</tt></p>
    <p><tt>=C2=A0=C2=A0=C2=A0 void log(const char* fmt, Args&amp;&amp;... a=
rgs) {</tt></p>
    <p><tt>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 if (logging_enabled) =
{</tt></p>
    <p><tt>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=
=A0 do_log(fmt, std::forward&lt;Args&gt;(args)...);</tt><tt><br>
      </tt></p>
    <p><tt>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 }</tt><tt><br>
      </tt></p>
    <p><tt>=C2=A0=C2=A0=C2=A0 }</tt><br>
    </p>
    <p><br>
    </p>
    <p>Now, the problem with this is that if an arg is expensive to
      compute, we take the cost before the if (logging_enabled) check.</p>
    <p><br>
    </p>
    <p>What we could have instead is define log as a macro.=C2=A0 Each arg
      would then not be captured as a reference, but as a lambda that
      yields the argument:<br>
    </p>
    <p><br>
    </p>
    <p><tt>=C2=A0=C2=A0=C2=A0 template &lt;typename... Args&gt;</tt></p>
    <p><tt>=C2=A0=C2=A0=C2=A0 macro void log(const char* fmt, Args&amp;&amp=
;... args) {</tt></p>
    <p><tt>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 if (logging_enabled) =
{</tt></p>
    <p><tt>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=
=A0 do_log(fmt, args()...);</tt><tt><br>
      </tt></p>
    <p><tt>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 }</tt><tt><br>
      </tt></p>
    <p><tt>=C2=A0=C2=A0=C2=A0 }</tt><br>
    </p>
    <p><br>
    </p>
    <p>An argument x in log(&quot;%s&quot;, x) would be translated as [&amp=
;] () {
      return x; } -&gt; decltype(x).=C2=A0 Combined with capturing
      return/break/continue etc. we could introduce new syntax:</p>
    <p><br>
    </p>
    <p>=C2=A0=C2=A0=C2=A0 with_lock(my_lock) {</p>
    <p>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 do things that need my_lo=
ck held</p>
    <p>=C2=A0 =C2=A0=C2=A0 =C2=A0=C2=A0 if (some_condition) return;=C2=A0 /=
/ releases my_lock and
      returns from enclosing scope<br>
    </p>
    <p>=C2=A0 =C2=A0=C2=A0 =C2=A0=C2=A0 do more things<br>
    </p>
    <p>=C2=A0=C2=A0=C2=A0 }<br>
    </p>
    <p><br>
    </p>
    <p>of course, need some syntax to capture the compound statement as
      a lambda; Swift has support for that we could borrow.<br>
    </p>
    <p>=C2=A0=C2=A0=C2=A0 </p>
    <br>
    <div>On 09/22/2016 01:21 AM,
      <a href=3D"javascript:" target=3D"_blank" gdf-obfuscated-mailto=3D"Co=
NExuYdAAAJ" rel=3D"nofollow" onmousedown=3D"this.href=3D&#39;javascript:&#3=
9;;return true;" onclick=3D"this.href=3D&#39;javascript:&#39;;return true;"=
>szollos...@gmail.com</a> wrote:<br>
    </div>
    <blockquote type=3D"cite">
      <div dir=3D"ltr">Hi,<br>
        <br>
        Sorry if it&#39;s confusing.. So far, it&#39;s just a sketch that I=
&#39;m
        cleaning up based on others&#39; suggestions. I&#39;m happy to see =
the
        coroutines proposal. Initially, I&#39;ve discarded the idea of
        describing these captures as I thought that full continuation
        capture is way to slow for this (in fact, this should be <i>exactly=
</i>
        as fast as loops and function returns); but you&#39;re right, let&#=
39;s
        formulate these based on continuations, then let&#39;s see
        optimization possibilities later. (Btw, as for the subject: is
        it OK to rename (set new subject) a thread on this list?)<br>
        So, what I&#39;m proposing is absolute and relative capture of
        specific continuations, namely the ones called by return, break,
        continue. All of these currently throw away current continuation
        and it should remain that way. Absolute capture, <i>when
          requested</i>, should return a [[noreturn]] functor that is
        identical, both in parameter(s, if any) and effect to performing
        the same return, break, continue in the <i>capturing context</i>.
        Current continuation is thrown away and destruction of any
        automatic storage duration variables are performed in the usual
        (reverse-of-declaration) order (i.e., unwinding is performed),
        before calling the continuation, up to the capture point. It is
        UB to call the functor after leaving capture context or from
        another thread (or coroutine).<br>
        Relative capture, <i>when requested</i>, should return a
        [[noreturn]] functor that is identical, both in parameter(s, if
        any) and effect to performing the same return, break, continue
        in the <i>calling</i> context. This can either be supported by
        the language; or a workaround is possible via having an
        additional function parameter that has a default value: (as
        default value is evaluated in caller&#39;s context)<br>
        <br>
        <div style=3D"background-color:rgb(250,250,250);border-color:rgb(18=
7,187,187);border-style:solid;border-width:1px;word-wrap:break-word"><code>
            <div><span style=3D"color:#800">#define</span><span style=3D"co=
lor:#000">
                TAKE_RETURN </span><span style=3D"color:#800">/* syntax to =
be defined */</span><span style=3D"color:#000"><br>
                <br>
              </span><span style=3D"color:#008">template</span><span style=
=3D"color:#660">&lt;</span><span style=3D"color:#008">typename</span><span =
style=3D"color:#000"> T</span><span style=3D"color:#660">&gt;</span><span s=
tyle=3D"color:#000"><br>
              </span><span style=3D"color:#008">int</span><span style=3D"co=
lor:#000"> mul_for_accumulate</span><span style=3D"color:#660">(</span><spa=
n style=3D"color:#008">int</span><span style=3D"color:#000"> a</span><span =
style=3D"color:#660">,</span><span style=3D"color:#000"> </span><span style=
=3D"color:#008">int</span><span style=3D"color:#000"> b</span><span style=
=3D"color:#660">,</span><span style=3D"color:#000"> T
                return2 </span><span style=3D"color:#660">=3D</span><span s=
tyle=3D"color:#000"> TAKE_RETURN</span><span style=3D"color:#660">)</span><=
span style=3D"color:#000"><br>
              </span><span style=3D"color:#660">{</span><span style=3D"colo=
r:#000"><br>
                =C2=A0 =C2=A0 </span><span style=3D"color:#008">if</span><s=
pan style=3D"color:#000"> </span><span style=3D"color:#660">(</span><span s=
tyle=3D"color:#000">a</span><span style=3D"color:#660">=3D=3D</span><span s=
tyle=3D"color:#066">0</span><span style=3D"color:#000"> </span><span style=
=3D"color:#660">||</span><span style=3D"color:#000"> b</span><span style=3D=
"color:#660">=3D=3D</span><span style=3D"color:#066">0</span><span style=3D=
"color:#660">)</span><span style=3D"color:#000"> return2</span><span style=
=3D"color:#660">(</span><span style=3D"color:#066">0</span><span style=3D"c=
olor:#660">);</span><span style=3D"color:#000"><br>
                =C2=A0 =C2=A0 </span><span style=3D"color:#008">return</spa=
n><span style=3D"color:#000"> a </span><span style=3D"color:#660">*</span><=
span style=3D"color:#000"> b</span><span style=3D"color:#660">;</span><span=
 style=3D"color:#000"><br>
              </span><span style=3D"color:#660">}</span><span style=3D"colo=
r:#000"><br>
                <br>
              </span></div>
          </code></div>
        <br>
        <br>
        If language support is provided, it&#39;s only available in
        functions; and in this case, it&#39;s UB to call relative return
        functor with a parameter that not convertible to the caller&#39;s
        return type; similarly, it&#39;s UB to call break functor or
        continue functor if these are not available in the caller&#39;s
        context. Without language support we&#39;re more type-safe, but the
        caller is aware of the capture (and can divert it); with
        language support it&#39;s easier to run into UB but it&#39;s meanin=
g is
        always the same.<br>
        <br>
        A possible 4th continuation to capture would be backtrack (or
        restart or cc), that captures the current continuation. It&#39;s
        similar to setjmp()/longjmp(), but performes unwinding and can
        be called multiple times until leaving the context. If not
        provided, it can be emulated by while() and continue+break:<br>
        <br>
        <div style=3D"background-color:rgb(250,250,250);border-color:rgb(18=
7,187,187);border-style:solid;border-width:1px;word-wrap:break-word"><code>
            <div><span style=3D"color:#008">while</span><span style=3D"colo=
r:#660">(</span><span style=3D"color:#008">true</span><span style=3D"color:=
#660">)</span><span style=3D"color:#000"><br>
              </span><span style=3D"color:#660">{</span><span style=3D"colo=
r:#000"><br>
                =C2=A0 =C2=A0 </span><span style=3D"color:#008">auto</span>=
<span style=3D"color:#000">
                my_backtrack </span><span style=3D"color:#660">=3D</span><s=
pan style=3D"color:#000"> TAKE_CONTINUE</span><span style=3D"color:#660">;<=
/span><span style=3D"color:#000"><br>
                =C2=A0 =C2=A0 f</span><span style=3D"color:#660">(...,</spa=
n><span style=3D"color:#000">
                my_backtrack</span><span style=3D"color:#660">);</span><spa=
n style=3D"color:#000"><br>
                =C2=A0 =C2=A0 </span><span style=3D"color:#008">break</span=
><span style=3D"color:#660">;</span><span style=3D"color:#000"><br>
              </span><span style=3D"color:#660">}</span></div>
          </code></div>
        <br>
        Alternatively, loops can be defined in terms of backtrack.<br>
        <br>
        Note that, up to this point, we only needed an unwind mechanism
        (that, as noted, is already there for exceptions) and a local
        goto-like operation (break and continue can be mechanically
        translated to it).<br>
        <br>
        It looks preferable to be able to &#39;rename&#39; return, continue=
 and
        break (albeit looks can be deceiving, any thoughts on that are
        welcome).<br>
        <br>
        The &#39;when you&#39;ve got a hammer, everything looks like a
        nail&#39;-observation is that now we can decompose &#39;for&#39;. I=
f we
        define:<br>
        <br>
        <div style=3D"background-color:rgb(250,250,250);border-color:rgb(18=
7,187,187);border-style:solid;border-width:1px;word-wrap:break-word"><code>
            <div><span style=3D"color:#008">for</span><span style=3D"color:=
#000"> </span><span style=3D"color:#660">(</span><span style=3D"color:#000"=
> </span><span style=3D"color:#008">int</span><span style=3D"color:#000"> i=
 </span><span style=3D"color:#660">:</span><span style=3D"color:#000"> rang=
e </span><span style=3D"color:#660">)</span><span style=3D"color:#000"> </s=
pan><span style=3D"color:#660">{</span><span style=3D"color:#000"> </span><=
span style=3D"color:#660">...</span><span style=3D"color:#000"> </span><spa=
n style=3D"color:#660">}</span><span style=3D"color:#000"><br>
              </span></div>
          </code></div>
        <br>
        as<br>
        <br>
        <div style=3D"background-color:rgb(250,250,250);border-color:rgb(18=
7,187,187);border-style:solid;border-width:1px;word-wrap:break-word"><code>
            <div><span style=3D"color:#008">for</span><span style=3D"color:=
#000"> </span><span style=3D"color:#660">([&amp;,</span><span style=3D"colo=
r:#000"> </span><span style=3D"color:#008">return</span><span style=3D"colo=
r:#000"> </span><span style=3D"color:#660">=3D</span><span style=3D"color:#=
000">
                TAKE_RETURN</span><span style=3D"color:#660">]</span><span =
style=3D"color:#000"><br>
                =C2=A0 =C2=A0 =C2=A0</span><span style=3D"color:#660">(</sp=
an><span style=3D"color:#008">int</span><span style=3D"color:#000"> i</span=
><span style=3D"color:#660">,</span><span style=3D"color:#000"> </span><spa=
n style=3D"color:#008">auto</span><span style=3D"color:#000"> </span><span =
style=3D"color:#008">continue</span><span style=3D"color:#000"> </span><spa=
n style=3D"color:#660">=3D</span><span style=3D"color:#000">
                TAKE_CONTINUE</span><span style=3D"color:#660">,</span><spa=
n style=3D"color:#000"> </span><span style=3D"color:#008">auto</span><span =
style=3D"color:#000"> </span><span style=3D"color:#008">break</span><span s=
tyle=3D"color:#000"> </span><span style=3D"color:#660">=3D</span><span styl=
e=3D"color:#000">
                TAKE_BREAK</span><span style=3D"color:#660">)</span><span s=
tyle=3D"color:#000"> </span><span style=3D"color:#660">{</span><span style=
=3D"color:#000"> </span><span style=3D"color:#660">...</span><span style=3D=
"color:#000"> </span><span style=3D"color:#660">}</span><span style=3D"colo=
r:#000"><br>
                =C2=A0 =C2=A0 </span><span style=3D"color:#660">)(</span><s=
pan style=3D"color:#000">range</span><span style=3D"color:#660">)</span></d=
iv>
          </code></div>
        <br>
        , then it&#39;s easy to define a &#39;for-function&#39; that provid=
es loop
        logic. While we might not want to redefine for itself this way,
        we might use the above syntax for <i>abitrary</i> functions,
        given we define the above substitution. This would provide
        immediately the functional equivalent of &#39;for break&#39;, with =
some
        library support, it&#39;d do for &#39;for else&#39;; as a side effe=
ct, it&#39;d
        allow to separate the loop object from it&#39;s execution, thereby
        allowing to store the loop object and call it for different
        ranges. <br>
        <br>
        Thanks for the valuable comments and the time,<br>
        -lorro<br>
        <br>
        2016. szeptember 13., kedd 11:18:58 UTC+2 id=C5=91pontban Giovanni
        Piero Deretta a k=C3=B6vetkez=C5=91t =C3=ADrta:
        <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">On Tuesday, September 13, 2016 at 1:58:00 AM
            UTC+1, Arthur O&#39;Dwyer 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">Rather than bikeshedding the syntax, I
                think you need to take a step back and explain what this
                proposed feature <b><i>is</i></b>. Right now, it reads
                like one of those joke programming languages like
                INTERCAL or TURKEY BOMB where words are just thrown
                together for comedic effect, rather than for intrinsic
                meaning (let alone usefulness).
                <div><br>
                </div>
                <div>What would it mean for a function to &quot;<font face=
=3D"courier new, monospace">break</font>, but in
                  its caller&#39;s context&quot;?</div>
                <div>You need to show a specific example of the
                  semantics you&#39;re trying to achieve, in the form of</d=
iv>
                <div>- a library solution (perhaps involving
                  setjmp/longjmp or exception-handling under the hood),
                  and/or</div>
                <div>- assembly code for a non-trivial use of the
                  proposed feature.</div>
                <div>
                  <div>
                    <div><br>
                    </div>
                  </div>
                </div>
              </div>
            </blockquote>
            <div><br>
              I think that the proposal is definitely confused and
              mentioning monads doesn&#39;t help. What the author is
              proposing is simply capture of first class continuations.
              The proposed syntax only allow capturing some specific
              continuations (the return, and loop and switch break
              continuations) and only allow escaping to them (by
              throwing away the current continuation), but it could be
              extended to capture any continuation and preserving the
              current one. The proposal is semantically a subset of the
              existing stackfull coroutine proposals and can be
              implemented on top of them. <br>
            </div>
          </div>
        </blockquote>
      </div>
      -- <br>
      You received this message because you are subscribed to the Google
      Groups &quot;ISO C++ Standard - Future Proposals&quot; group.<br>
      To unsubscribe from this group and stop receiving emails from it,
      send an email to <a href=3D"javascript:" target=3D"_blank" gdf-obfusc=
ated-mailto=3D"CoNExuYdAAAJ" rel=3D"nofollow" onmousedown=3D"this.href=3D&#=
39;javascript:&#39;;return true;" onclick=3D"this.href=3D&#39;javascript:&#=
39;;return true;">std-proposal...@<wbr>isocpp.org</a>.<br>
      To post to this group, send email to <a href=3D"javascript:" target=
=3D"_blank" gdf-obfuscated-mailto=3D"CoNExuYdAAAJ" rel=3D"nofollow" onmouse=
down=3D"this.href=3D&#39;javascript:&#39;;return true;" onclick=3D"this.hre=
f=3D&#39;javascript:&#39;;return true;">std-pr...@isocpp.org</a>.<br>
      To view this discussion on the web visit <a href=3D"https://groups.go=
ogle.com/a/isocpp.org/d/msgid/std-proposals/20bd8e3d-a795-4bf8-84e3-1f74ced=
450ed%40isocpp.org?utm_medium=3Demail&amp;utm_source=3Dfooter" target=3D"_b=
lank" rel=3D"nofollow" onmousedown=3D"this.href=3D&#39;https://groups.googl=
e.com/a/isocpp.org/d/msgid/std-proposals/20bd8e3d-a795-4bf8-84e3-1f74ced450=
ed%40isocpp.org?utm_medium\x3demail\x26utm_source\x3dfooter&#39;;return tru=
e;" onclick=3D"this.href=3D&#39;https://groups.google.com/a/isocpp.org/d/ms=
gid/std-proposals/20bd8e3d-a795-4bf8-84e3-1f74ced450ed%40isocpp.org?utm_med=
ium\x3demail\x26utm_source\x3dfooter&#39;;return true;">https://groups.goog=
le.com/a/<wbr>isocpp.org/d/msgid/std-<wbr>proposals/20bd8e3d-a795-4bf8-<wbr=
>84e3-1f74ced450ed%40isocpp.org</a><wbr>.<br>
    </blockquote>
    <br>
  </div>

</blockquote></div>

<p></p>

-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; 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/b2c39042-36da-485a-91f9-b02f4123dc29%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/b2c39042-36da-485a-91f9-b02f4123dc29=
%40isocpp.org</a>.<br />

------=_Part_13_187108353.1474928434205--

------=_Part_12_898525331.1474928434200--

.


Author: szollosi.lorand@gmail.com
Date: Sun, 9 Oct 2016 09:58:57 -0700 (PDT)
Raw View
------=_Part_364_1978464078.1476032337407
Content-Type: multipart/alternative;
 boundary="----=_Part_365_1848530513.1476032337408"

------=_Part_365_1848530513.1476032337408
Content-Type: text/plain; charset=UTF-8

Hi,

A toy model of the capture part is possible using gcc's statement
expressions extension. This is not for implementation reference, just to
have a clearer view of the idea:

#include <vector>
#include <iostream>
#include <experimental/optional>
#include <cmath>
#include <limits>

enum class return_mode { ret, brk, cont, back };
enum { parent_break };
enum { parent_continue };
enum { to_parent };

// TODO: specialize for void
template<typename R, typename P>
struct extended_return
{
    const return_mode                    which_;
    const std::experimental::optional<P> parent_retval_;
    const std::experimental::optional<R> retval_;
    extended_return(R retval)
        : which_ (return_mode::back)
        , retval_(std::move(retval)) {}
    extended_return(decltype(to_parent), P retval)
        : which_ (return_mode::ret)
        , parent_retval_(std::move(retval)) {}
    extended_return(decltype(parent_break) tgt)
        : which_ (return_mode::brk) {}
    extended_return(decltype(parent_continue) tgt)
        : which_ (return_mode::cont) {}
    operator return_mode() const { return which_; }
};

extended_return<double, double> mul2(double lhs, double rhs)
{
    if (rhs == 0) {
        return { to_parent, 0.0 };
    }
    return lhs * rhs;
}

double mul2(double lhs, double rhs, void(*parent_return)(double))
{
    if (rhs == 0) {
        parent_return(0.0);
    }
    return lhs * rhs;
}

#define take_return                           \
            else if(ret == return_mode::ret)  \
                return *ret.parent_retval_;

#define take_break                            \
            else if(ret == return_mode::brk)  \
                break;

#define take_continue                         \
            else if(ret == return_mode::cont) \
                continue;

#define invoke_with(TAKEN, F, ...)            \
        ({                                    \
            auto ret = F(__VA_ARGS__);        \
            if (false);                       \
            TAKEN                             \
            *ret.retval_;                     \
        });


#define invoke_with_abs(R, F, ...)            \
        ({                                    \
            struct parent_return_t            \
            {                                 \
                R value;                      \
            };                                \
            auto parent_return = +[](R v) {   \
                throw parent_return_t{v};     \
            };                                \
            std::experimental::optional<      \
                decltype(F(__VA_ARGS__,       \
                           parent_return))    \
            > ret;                            \
            try {                             \
                ret = F(__VA_ARGS__,          \
                        parent_return);       \
            } catch (parent_return_t r) {     \
                return std::move(r.value);    \
            } catch (...) {                   \
                throw;                        \
            }                                 \
            *ret;                             \
        });

template<typename R>
double prod(const R& r)
{
    if (r.empty()) {
        return NAN;
    }
    double p = 1.0;
    for (auto ri : r) {
        p = invoke_with(take_return, mul2, p, ri);
        //p = invoke_with_abs(double, mul2, p, ri);
    }
    return p;
}

int main()
{
    std::vector<int> v{1, 2, 0, 4};
    std::cout << prod(v);
}


Thanks,
-lorro

--
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/9fc1d216-bbe9-4702-893a-c6eb15210eb1%40isocpp.org.

------=_Part_365_1848530513.1476032337408
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">Hi,<br><br>A toy model of the capture part is possible usi=
ng gcc&#39;s statement expressions extension. This is not for implementatio=
n reference, just to have a clearer view of the idea:<br><br><div class=3D"=
prettyprint" style=3D"background-color: rgb(250, 250, 250); border-color: r=
gb(187, 187, 187); border-style: solid; border-width: 1px; word-wrap: break=
-word;"><code class=3D"prettyprint"><div class=3D"subprettyprint"><span sty=
le=3D"color: #800;" class=3D"styled-by-prettify">#include</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color=
: #080;" class=3D"styled-by-prettify">&lt;vector&gt;</span><span style=3D"c=
olor: #000;" class=3D"styled-by-prettify"><br></span><span style=3D"color: =
#800;" class=3D"styled-by-prettify">#include</span><span style=3D"color: #0=
00;" class=3D"styled-by-prettify"> </span><span style=3D"color: #080;" clas=
s=3D"styled-by-prettify">&lt;iostream&gt;</span><span style=3D"color: #000;=
" class=3D"styled-by-prettify"><br></span><span style=3D"color: #800;" clas=
s=3D"styled-by-prettify">#include</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"> </span><span style=3D"color: #660;" class=3D"style=
d-by-prettify">&lt;</span><span style=3D"color: #000;" class=3D"styled-by-p=
rettify">experimental</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"color: #660;" class=3D"styled-by-prettify">=
&gt;</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br></=
span><span style=3D"color: #800;" class=3D"styled-by-prettify">#include</sp=
an><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span =
style=3D"color: #080;" class=3D"styled-by-prettify">&lt;cmath&gt;</span><sp=
an style=3D"color: #000;" class=3D"styled-by-prettify"><br></span><span sty=
le=3D"color: #800;" class=3D"styled-by-prettify">#include</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color=
: #080;" class=3D"styled-by-prettify">&lt;limits&gt;</span><span style=3D"c=
olor: #000;" class=3D"styled-by-prettify"><br><br></span><span style=3D"col=
or: #008;" class=3D"styled-by-prettify">enum</span><span style=3D"color: #0=
00;" class=3D"styled-by-prettify"> </span><span style=3D"color: #008;" clas=
s=3D"styled-by-prettify">class</span><span style=3D"color: #000;" class=3D"=
styled-by-prettify"> return_mode </span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">{</span><span style=3D"color: #000;" class=3D"style=
d-by-prettify"> ret</span><span style=3D"color: #660;" class=3D"styled-by-p=
rettify">,</span><span style=3D"color: #000;" class=3D"styled-by-prettify">=
 brk</span><span style=3D"color: #660;" class=3D"styled-by-prettify">,</spa=
n><span style=3D"color: #000;" class=3D"styled-by-prettify"> cont</span><sp=
an style=3D"color: #660;" class=3D"styled-by-prettify">,</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"> back </span><span style=3D"=
color: #660;" class=3D"styled-by-prettify">};</span><span style=3D"color: #=
000;" class=3D"styled-by-prettify"><br></span><span style=3D"color: #008;" =
class=3D"styled-by-prettify">enum</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"> </span><span style=3D"color: #660;" class=3D"style=
d-by-prettify">{</span><span style=3D"color: #000;" class=3D"styled-by-pret=
tify"> parent_break </span><span style=3D"color: #660;" class=3D"styled-by-=
prettify">};</span><span style=3D"color: #000;" class=3D"styled-by-prettify=
"><br></span><span style=3D"color: #008;" class=3D"styled-by-prettify">enum=
</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><s=
pan style=3D"color: #660;" class=3D"styled-by-prettify">{</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"> parent_continue </span><spa=
n style=3D"color: #660;" class=3D"styled-by-prettify">};</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"><br></span><span style=3D"co=
lor: #008;" class=3D"styled-by-prettify">enum</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"sty=
led-by-prettify"> to_parent </span><span style=3D"color: #660;" class=3D"st=
yled-by-prettify">};</span><span style=3D"color: #000;" class=3D"styled-by-=
prettify"><br><br></span><span style=3D"color: #800;" class=3D"styled-by-pr=
ettify">// TODO: specialize for void</span><span style=3D"color: #000;" cla=
ss=3D"styled-by-prettify"><br></span><span style=3D"color: #008;" class=3D"=
styled-by-prettify">template</span><span style=3D"color: #660;" class=3D"st=
yled-by-prettify">&lt;</span><span style=3D"color: #008;" class=3D"styled-b=
y-prettify">typename</span><span style=3D"color: #000;" class=3D"styled-by-=
prettify"> R</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">typename</span><=
span style=3D"color: #000;" class=3D"styled-by-prettify"> P</span><span sty=
le=3D"color: #660;" class=3D"styled-by-prettify">&gt;</span><span style=3D"=
color: #000;" class=3D"styled-by-prettify"><br></span><span style=3D"color:=
 #008;" class=3D"styled-by-prettify">struct</span><span style=3D"color: #00=
0;" class=3D"styled-by-prettify"> extended_return<br></span><span style=3D"=
color: #660;" class=3D"styled-by-prettify">{</span><span style=3D"color: #0=
00;" class=3D"styled-by-prettify"><br>=C2=A0 =C2=A0 </span><span style=3D"c=
olor: #008;" class=3D"styled-by-prettify">const</span><span style=3D"color:=
 #000;" class=3D"styled-by-prettify"> return_mode =C2=A0 =C2=A0 =C2=A0 =C2=
=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0which_</span><span style=3D"co=
lor: #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"col=
or: #008;" class=3D"styled-by-prettify">const</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">experimental</span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">::</span><span style=3D"color: #000;" class=3D"styl=
ed-by-prettify">optional</span><span style=3D"color: #660;" class=3D"styled=
-by-prettify">&lt;</span><span style=3D"color: #000;" class=3D"styled-by-pr=
ettify">P</span><span style=3D"color: #660;" class=3D"styled-by-prettify">&=
gt;</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> parent=
_retval_</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">con=
st</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> std</sp=
an><span style=3D"color: #660;" class=3D"styled-by-prettify">::</span><span=
 style=3D"color: #000;" class=3D"styled-by-prettify">experimental</span><sp=
an 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"color: #660;" class=3D"styled-by-prettify">&lt;</span><span style=3D"co=
lor: #000;" class=3D"styled-by-prettify">R</span><span style=3D"color: #660=
;" class=3D"styled-by-prettify">&gt;</span><span style=3D"color: #000;" cla=
ss=3D"styled-by-prettify"> retval_</span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">;</span><span style=3D"color: #000;" class=3D"style=
d-by-prettify"><br>=C2=A0 =C2=A0 extended_return</span><span style=3D"color=
: #660;" class=3D"styled-by-prettify">(</span><span style=3D"color: #000;" =
class=3D"styled-by-prettify">R retval</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: #660;" class=3D"styled-by-prettify">:</span><span style=3D"color: #000;=
" class=3D"styled-by-prettify"> which_ </span><span style=3D"color: #660;" =
class=3D"styled-by-prettify">(</span><span style=3D"color: #000;" class=3D"=
styled-by-prettify">return_mode</span><span style=3D"color: #660;" class=3D=
"styled-by-prettify">::</span><span style=3D"color: #000;" class=3D"styled-=
by-prettify">back</span><span style=3D"color: #660;" class=3D"styled-by-pre=
ttify">)</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><b=
r>=C2=A0 =C2=A0 =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"> retval_</span><span style=3D"color: #660;" class=3D"styled-by-p=
rettify">(</span><span style=3D"color: #000;" class=3D"styled-by-prettify">=
std</span><span style=3D"color: #660;" class=3D"styled-by-prettify">::</spa=
n><span style=3D"color: #000;" class=3D"styled-by-prettify">move</span><spa=
n style=3D"color: #660;" class=3D"styled-by-prettify">(</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify">retval</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"st=
yled-by-prettify"><br>=C2=A0 =C2=A0 extended_return</span><span style=3D"co=
lor: #660;" class=3D"styled-by-prettify">(</span><span style=3D"color: #008=
;" class=3D"styled-by-prettify">decltype</span><span style=3D"color: #660;"=
 class=3D"styled-by-prettify">(</span><span style=3D"color: #000;" class=3D=
"styled-by-prettify">to_parent</span><span style=3D"color: #660;" class=3D"=
styled-by-prettify">),</span><span style=3D"color: #000;" class=3D"styled-b=
y-prettify"> P retval</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: #660;" class=
=3D"styled-by-prettify">:</span><span style=3D"color: #000;" class=3D"style=
d-by-prettify"> which_ </span><span style=3D"color: #660;" class=3D"styled-=
by-prettify">(</span><span style=3D"color: #000;" class=3D"styled-by-pretti=
fy">return_mode</span><span style=3D"color: #660;" class=3D"styled-by-prett=
ify">::</span><span style=3D"color: #000;" class=3D"styled-by-prettify">ret=
</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 </span><span style=3D"color: #660;" class=3D"styled-by-pretti=
fy">,</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> pare=
nt_retval_</span><span style=3D"color: #660;" class=3D"styled-by-prettify">=
(</span><span style=3D"color: #000;" class=3D"styled-by-prettify">std</span=
><span style=3D"color: #660;" class=3D"styled-by-prettify">::</span><span s=
tyle=3D"color: #000;" class=3D"styled-by-prettify">move</span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">(</span><span style=3D"color=
: #000;" class=3D"styled-by-prettify">retval</span><span style=3D"color: #6=
60;" class=3D"styled-by-prettify">))</span><span style=3D"color: #000;" cla=
ss=3D"styled-by-prettify"> </span><span style=3D"color: #660;" class=3D"sty=
led-by-prettify">{}</span><span style=3D"color: #000;" class=3D"styled-by-p=
rettify"><br>=C2=A0 =C2=A0 extended_return</span><span style=3D"color: #660=
;" class=3D"styled-by-prettify">(</span><span style=3D"color: #008;" class=
=3D"styled-by-prettify">decltype</span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">(</span><span style=3D"color: #000;" class=3D"style=
d-by-prettify">parent_break</span><span style=3D"color: #660;" class=3D"sty=
led-by-prettify">)</span><span style=3D"color: #000;" class=3D"styled-by-pr=
ettify"> tgt</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: #660;" class=3D"style=
d-by-prettify">:</span><span style=3D"color: #000;" class=3D"styled-by-pret=
tify"> which_ </span><span style=3D"color: #660;" class=3D"styled-by-pretti=
fy">(</span><span style=3D"color: #000;" class=3D"styled-by-prettify">retur=
n_mode</span><span style=3D"color: #660;" class=3D"styled-by-prettify">::</=
span><span style=3D"color: #000;" class=3D"styled-by-prettify">brk</span><s=
pan style=3D"color: #660;" class=3D"styled-by-prettify">)</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color=
: #660;" class=3D"styled-by-prettify">{}</span><span style=3D"color: #000;"=
 class=3D"styled-by-prettify"><br>=C2=A0 =C2=A0 extended_return</span><span=
 style=3D"color: #660;" class=3D"styled-by-prettify">(</span><span style=3D=
"color: #008;" class=3D"styled-by-prettify">decltype</span><span style=3D"c=
olor: #660;" class=3D"styled-by-prettify">(</span><span style=3D"color: #00=
0;" class=3D"styled-by-prettify">parent_continue</span><span style=3D"color=
: #660;" class=3D"styled-by-prettify">)</span><span style=3D"color: #000;" =
class=3D"styled-by-prettify"> tgt</span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">)</span><span style=3D"color: #000;" class=3D"style=
d-by-prettify"><br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 </span><span style=3D"color:=
 #660;" class=3D"styled-by-prettify">:</span><span style=3D"color: #000;" c=
lass=3D"styled-by-prettify"> which_ </span><span style=3D"color: #660;" cla=
ss=3D"styled-by-prettify">(</span><span style=3D"color: #000;" class=3D"sty=
led-by-prettify">return_mode</span><span style=3D"color: #660;" class=3D"st=
yled-by-prettify">::</span><span style=3D"color: #000;" class=3D"styled-by-=
prettify">cont</span><span style=3D"color: #660;" class=3D"styled-by-pretti=
fy">)</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </sp=
an><span style=3D"color: #660;" class=3D"styled-by-prettify">{}</span><span=
 style=3D"color: #000;" class=3D"styled-by-prettify"><br>=C2=A0 =C2=A0 </sp=
an><span style=3D"color: #008;" class=3D"styled-by-prettify">operator</span=
><span style=3D"color: #000;" class=3D"styled-by-prettify"> return_mode</sp=
an><span style=3D"color: #660;" class=3D"styled-by-prettify">()</span><span=
 style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D=
"color: #008;" class=3D"styled-by-prettify">const</span><span style=3D"colo=
r: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #660;"=
 class=3D"styled-by-prettify">{</span><span style=3D"color: #000;" class=3D=
"styled-by-prettify"> </span><span style=3D"color: #008;" class=3D"styled-b=
y-prettify">return</span><span style=3D"color: #000;" class=3D"styled-by-pr=
ettify"> which_</span><span style=3D"color: #660;" class=3D"styled-by-prett=
ify">;</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </s=
pan><span style=3D"color: #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"colo=
r: #000;" class=3D"styled-by-prettify"><br><br>extended_return</span><span =
style=3D"color: #660;" class=3D"styled-by-prettify">&lt;</span><span style=
=3D"color: #008;" class=3D"styled-by-prettify">double</span><span style=3D"=
color: #660;" class=3D"styled-by-prettify">,</span><span style=3D"color: #0=
00;" class=3D"styled-by-prettify"> </span><span style=3D"color: #008;" clas=
s=3D"styled-by-prettify">double</span><span style=3D"color: #660;" class=3D=
"styled-by-prettify">&gt;</span><span style=3D"color: #000;" class=3D"style=
d-by-prettify"> mul2</span><span style=3D"color: #660;" class=3D"styled-by-=
prettify">(</span><span style=3D"color: #008;" class=3D"styled-by-prettify"=
>double</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> lh=
s</span><span style=3D"color: #660;" class=3D"styled-by-prettify">,</span><=
span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span styl=
e=3D"color: #008;" class=3D"styled-by-prettify">double</span><span style=3D=
"color: #000;" class=3D"styled-by-prettify"> rhs</span><span style=3D"color=
: #660;" class=3D"styled-by-prettify">)</span><span style=3D"color: #000;" =
class=3D"styled-by-prettify"><br></span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">{</span><span style=3D"color: #000;" class=3D"style=
d-by-prettify"><br>=C2=A0 =C2=A0 </span><span style=3D"color: #008;" class=
=3D"styled-by-prettify">if</span><span style=3D"color: #000;" class=3D"styl=
ed-by-prettify"> </span><span style=3D"color: #660;" class=3D"styled-by-pre=
ttify">(</span><span style=3D"color: #000;" class=3D"styled-by-prettify">rh=
s </span><span style=3D"color: #660;" class=3D"styled-by-prettify">=3D=3D</=
span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><spa=
n 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"> </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"c=
olor: #008;" class=3D"styled-by-prettify">return</span><span style=3D"color=
: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #660;" =
class=3D"styled-by-prettify">{</span><span style=3D"color: #000;" class=3D"=
styled-by-prettify"> to_parent</span><span style=3D"color: #660;" class=3D"=
styled-by-prettify">,</span><span style=3D"color: #000;" class=3D"styled-by=
-prettify"> </span><span style=3D"color: #066;" class=3D"styled-by-prettify=
">0.0</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </sp=
an><span style=3D"color: #660;" class=3D"styled-by-prettify">};</span><span=
 style=3D"color: #000;" class=3D"styled-by-prettify"><br>=C2=A0 =C2=A0 </sp=
an><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 </spa=
n><span style=3D"color: #008;" class=3D"styled-by-prettify">return</span><s=
pan style=3D"color: #000;" class=3D"styled-by-prettify"> lhs </span><span s=
tyle=3D"color: #660;" class=3D"styled-by-prettify">*</span><span style=3D"c=
olor: #000;" class=3D"styled-by-prettify"> rhs</span><span style=3D"color: =
#660;" class=3D"styled-by-prettify">;</span><span style=3D"color: #000;" cl=
ass=3D"styled-by-prettify"><br></span><span style=3D"color: #660;" class=3D=
"styled-by-prettify">}</span><span style=3D"color: #000;" class=3D"styled-b=
y-prettify"><br><br></span><span style=3D"color: #008;" class=3D"styled-by-=
prettify">double</span><span style=3D"color: #000;" class=3D"styled-by-pret=
tify"> mul2</span><span style=3D"color: #660;" class=3D"styled-by-prettify"=
>(</span><span style=3D"color: #008;" class=3D"styled-by-prettify">double</=
span><span style=3D"color: #000;" class=3D"styled-by-prettify"> lhs</span><=
span style=3D"color: #660;" class=3D"styled-by-prettify">,</span><span styl=
e=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"colo=
r: #008;" class=3D"styled-by-prettify">double</span><span style=3D"color: #=
000;" class=3D"styled-by-prettify"> rhs</span><span style=3D"color: #660;" =
class=3D"styled-by-prettify">,</span><span style=3D"color: #000;" class=3D"=
styled-by-prettify"> </span><span style=3D"color: #008;" class=3D"styled-by=
-prettify">void</span><span style=3D"color: #660;" class=3D"styled-by-prett=
ify">(*</span><span style=3D"color: #000;" class=3D"styled-by-prettify">par=
ent_return</span><span style=3D"color: #660;" class=3D"styled-by-prettify">=
)(</span><span style=3D"color: #008;" class=3D"styled-by-prettify">double</=
span><span style=3D"color: #660;" class=3D"styled-by-prettify">))</span><sp=
an style=3D"color: #000;" class=3D"styled-by-prettify"><br></span><span sty=
le=3D"color: #660;" class=3D"styled-by-prettify">{</span><span style=3D"col=
or: #000;" class=3D"styled-by-prettify"><br>=C2=A0 =C2=A0 </span><span styl=
e=3D"color: #008;" class=3D"styled-by-prettify">if</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: #000;" class=
=3D"styled-by-prettify">rhs </span><span style=3D"color: #660;" class=3D"st=
yled-by-prettify">=3D=3D</span><span style=3D"color: #000;" class=3D"styled=
-by-prettify"> </span><span style=3D"color: #066;" class=3D"styled-by-prett=
ify">0</span><span style=3D"color: #660;" class=3D"styled-by-prettify">)</s=
pan><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span=
 style=3D"color: #660;" class=3D"styled-by-prettify">{</span><span style=3D=
"color: #000;" class=3D"styled-by-prettify"><br>=C2=A0 =C2=A0 =C2=A0 =C2=A0=
 parent_return</span><span style=3D"color: #660;" class=3D"styled-by-pretti=
fy">(</span><span style=3D"color: #066;" class=3D"styled-by-prettify">0.0</=
span><span style=3D"color: #660;" class=3D"styled-by-prettify">);</span><sp=
an 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><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"> lhs </span><span=
 style=3D"color: #660;" class=3D"styled-by-prettify">*</span><span style=3D=
"color: #000;" class=3D"styled-by-prettify"> rhs</span><span style=3D"color=
: #660;" class=3D"styled-by-prettify">;</span><span style=3D"color: #000;" =
class=3D"styled-by-prettify"><br></span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">}</span><span style=3D"color: #000;" class=3D"style=
d-by-prettify"><br><br></span><span style=3D"color: #800;" class=3D"styled-=
by-prettify">#define</span><span style=3D"color: #000;" class=3D"styled-by-=
prettify"> take_return =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=
=A0 =C2=A0 =C2=A0 =C2=A0 =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 =C2=A0 =C2=A0 =C2=A0 =C2=A0 </span><s=
pan style=3D"color: #008;" class=3D"styled-by-prettify">else</span><span st=
yle=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"co=
lor: #008;" class=3D"styled-by-prettify">if</span><span style=3D"color: #66=
0;" class=3D"styled-by-prettify">(</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify">ret </span><span style=3D"color: #660;" class=3D"st=
yled-by-prettify">=3D=3D</span><span style=3D"color: #000;" class=3D"styled=
-by-prettify"> return_mode</span><span style=3D"color: #660;" class=3D"styl=
ed-by-prettify">::</span><span style=3D"color: #000;" class=3D"styled-by-pr=
ettify">ret</span><span style=3D"color: #660;" class=3D"styled-by-prettify"=
>)</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> =C2=A0<=
/span><span style=3D"color: #660;" class=3D"styled-by-prettify">\</span><sp=
an style=3D"color: #000;" class=3D"styled-by-prettify"><br>=C2=A0 =C2=A0 =
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 </span><span style=3D"color: #008=
;" class=3D"styled-by-prettify">return</span><span style=3D"color: #000;" c=
lass=3D"styled-by-prettify"> </span><span style=3D"color: #660;" class=3D"s=
tyled-by-prettify">*</span><span style=3D"color: #000;" class=3D"styled-by-=
prettify">ret</span><span style=3D"color: #660;" class=3D"styled-by-prettif=
y">.</span><span style=3D"color: #000;" class=3D"styled-by-prettify">parent=
_retval_</span><span style=3D"color: #660;" class=3D"styled-by-prettify">;<=
/span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br><br></s=
pan><span style=3D"color: #800;" class=3D"styled-by-prettify">#define</span=
><span style=3D"color: #000;" class=3D"styled-by-prettify"> take_break =C2=
=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =
=C2=A0 =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 =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"styled-by-prettify"> </span><span style=3D"color: #008;" class=
=3D"styled-by-prettify">if</span><span style=3D"color: #660;" class=3D"styl=
ed-by-prettify">(</span><span style=3D"color: #000;" class=3D"styled-by-pre=
ttify">ret </span><span style=3D"color: #660;" class=3D"styled-by-prettify"=
>=3D=3D</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> re=
turn_mode</span><span style=3D"color: #660;" class=3D"styled-by-prettify">:=
:</span><span style=3D"color: #000;" class=3D"styled-by-prettify">brk</span=
><span style=3D"color: #660;" class=3D"styled-by-prettify">)</span><span st=
yle=3D"color: #000;" class=3D"styled-by-prettify"> =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 =C2=A0 =C2=A0 =C2=
=A0 =C2=A0 =C2=A0 =C2=A0 </span><span style=3D"color: #008;" class=3D"style=
d-by-prettify">break</span><span style=3D"color: #660;" class=3D"styled-by-=
prettify">;</span><span style=3D"color: #000;" class=3D"styled-by-prettify"=
><br><br></span><span style=3D"color: #800;" class=3D"styled-by-prettify">#=
define</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> tak=
e_continue =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =
=C2=A0 =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 =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"styled-by-prettify"> </span><span style=3D"color: #008;" class=
=3D"styled-by-prettify">if</span><span style=3D"color: #660;" class=3D"styl=
ed-by-prettify">(</span><span style=3D"color: #000;" class=3D"styled-by-pre=
ttify">ret </span><span style=3D"color: #660;" class=3D"styled-by-prettify"=
>=3D=3D</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> re=
turn_mode</span><span style=3D"color: #660;" class=3D"styled-by-prettify">:=
:</span><span style=3D"color: #000;" class=3D"styled-by-prettify">cont</spa=
n><span style=3D"color: #660;" class=3D"styled-by-prettify">)</span><span s=
tyle=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"c=
olor: #660;" class=3D"styled-by-prettify">\</span><span style=3D"color: #00=
0;" class=3D"styled-by-prettify"><br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=
=A0 =C2=A0 =C2=A0 </span><span style=3D"color: #008;" class=3D"styled-by-pr=
ettify">continue</span><span style=3D"color: #660;" class=3D"styled-by-pret=
tify">;</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br=
><br></span><span style=3D"color: #800;" class=3D"styled-by-prettify">#defi=
ne</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> invoke_=
with</span><span style=3D"color: #660;" class=3D"styled-by-prettify">(</spa=
n><span style=3D"color: #000;" class=3D"styled-by-prettify">TAKEN</span><sp=
an style=3D"color: #660;" class=3D"styled-by-prettify">,</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"> F</span><span style=3D"colo=
r: #660;" class=3D"styled-by-prettify">,</span><span style=3D"color: #000;"=
 class=3D"styled-by-prettify"> </span><span style=3D"color: #660;" class=3D=
"styled-by-prettify">...)</span><span style=3D"color: #000;" class=3D"style=
d-by-prettify"> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =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 =C2=A0 =C2=A0 </spa=
n><span style=3D"color: #660;" class=3D"styled-by-prettify">({</span><span =
style=3D"color: #000;" class=3D"styled-by-prettify"> =C2=A0 =C2=A0 =C2=A0 =
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=
=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0</span><span style=3D"color: #660;" class=3D=
"styled-by-prettify">\</span><span style=3D"color: #000;" class=3D"styled-b=
y-prettify"><br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 </span><span styl=
e=3D"color: #008;" class=3D"styled-by-prettify">auto</span><span style=3D"c=
olor: #000;" class=3D"styled-by-prettify"> ret </span><span style=3D"color:=
 #660;" class=3D"styled-by-prettify">=3D</span><span style=3D"color: #000;"=
 class=3D"styled-by-prettify"> F</span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">(</span><span style=3D"color: #000;" class=3D"style=
d-by-prettify">__VA_ARGS__</span><span style=3D"color: #660;" class=3D"styl=
ed-by-prettify">);</span><span style=3D"color: #000;" class=3D"styled-by-pr=
ettify"> =C2=A0 =C2=A0 =C2=A0 =C2=A0</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 =C2=A0 =C2=A0 =C2=A0 =C2=A0 </span><span=
 style=3D"color: #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: #008;" =
class=3D"styled-by-prettify">false</span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">);</span><span style=3D"color: #000;" class=3D"styl=
ed-by-prettify"> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =
=C2=A0 =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 =C2=A0 =C2=A0 =C2=A0 =C2=A0 TAKEN =C2=A0 =C2=A0 =C2=A0 =
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=
=A0 </span><span style=3D"color: #660;" class=3D"styled-by-prettify">\</spa=
n><span style=3D"color: #000;" class=3D"styled-by-prettify"><br>=C2=A0 =C2=
=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 </span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">*</span><span style=3D"color: #000;" class=3D"style=
d-by-prettify">ret</span><span style=3D"color: #660;" class=3D"styled-by-pr=
ettify">.</span><span style=3D"color: #000;" class=3D"styled-by-prettify">r=
etval_</span><span style=3D"color: #660;" class=3D"styled-by-prettify">;</s=
pan><span style=3D"color: #000;" class=3D"styled-by-prettify"> =C2=A0 =C2=
=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 </span><span st=
yle=3D"color: #660;" class=3D"styled-by-prettify">\</span><span style=3D"co=
lor: #000;" class=3D"styled-by-prettify"><br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 </=
span><span style=3D"color: #660;" class=3D"styled-by-prettify">});</span><s=
pan style=3D"color: #000;" class=3D"styled-by-prettify"><br><br><br></span>=
<span style=3D"color: #800;" class=3D"styled-by-prettify">#define</span><sp=
an style=3D"color: #000;" class=3D"styled-by-prettify"> invoke_with_abs</sp=
an><span style=3D"color: #660;" class=3D"styled-by-prettify">(</span><span =
style=3D"color: #000;" class=3D"styled-by-prettify">R</span><span style=3D"=
color: #660;" class=3D"styled-by-prettify">,</span><span style=3D"color: #0=
00;" class=3D"styled-by-prettify"> F</span><span style=3D"color: #660;" cla=
ss=3D"styled-by-prettify">,</span><span style=3D"color: #000;" class=3D"sty=
led-by-prettify"> </span><span style=3D"color: #660;" class=3D"styled-by-pr=
ettify">...)</span><span style=3D"color: #000;" class=3D"styled-by-prettify=
"> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0</span><span style=3D"color: #6=
60;" class=3D"styled-by-prettify">\</span><span style=3D"color: #000;" clas=
s=3D"styled-by-prettify"><br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 </span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">({</span><span style=3D"colo=
r: #000;" class=3D"styled-by-prettify"> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=
=A0 =C2=A0 =C2=A0</span><span style=3D"color: #660;" class=3D"styled-by-pre=
ttify">\</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><b=
r>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 </span><span style=3D"color: #0=
08;" class=3D"styled-by-prettify">struct</span><span style=3D"color: #000;"=
 class=3D"styled-by-prettify"> parent_return_t =C2=A0 =C2=A0 =C2=A0 =C2=A0 =
=C2=A0 =C2=A0</span><span style=3D"color: #660;" class=3D"styled-by-prettif=
y">\</span><span 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: #660=
;" class=3D"styled-by-prettify">{</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =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 =C2=A0 =C2=A0=
 =C2=A0 =C2=A0 =C2=A0 =C2=A0 R value</span><span style=3D"color: #660;" cla=
ss=3D"styled-by-prettify">;</span><span style=3D"color: #000;" class=3D"sty=
led-by-prettify"> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =
=C2=A0 =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 =C2=A0 =C2=A0 =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"> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=
=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0</span><s=
pan style=3D"color: #660;" class=3D"styled-by-prettify">\</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"><br>=C2=A0 =C2=A0 =C2=A0 =C2=
=A0 =C2=A0 =C2=A0 </span><span style=3D"color: #008;" class=3D"styled-by-pr=
ettify">auto</span><span style=3D"color: #000;" class=3D"styled-by-prettify=
"> parent_return </span><span style=3D"color: #660;" class=3D"styled-by-pre=
ttify">=3D</span><span style=3D"color: #000;" class=3D"styled-by-prettify">=
 </span><span style=3D"color: #660;" class=3D"styled-by-prettify">+[](</spa=
n><span style=3D"color: #000;" class=3D"styled-by-prettify">R v</span><span=
 style=3D"color: #660;" class=3D"styled-by-prettify">)</span><span style=3D=
"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #=
660;" class=3D"styled-by-prettify">{</span><span style=3D"color: #000;" cla=
ss=3D"styled-by-prettify"> =C2=A0 </span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">\</span><span style=3D"color: #000;" class=3D"style=
d-by-prettify"><br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =
</span><span style=3D"color: #008;" class=3D"styled-by-prettify">throw</spa=
n><span style=3D"color: #000;" class=3D"styled-by-prettify"> parent_return_=
t</span><span style=3D"color: #660;" class=3D"styled-by-prettify">{</span><=
span style=3D"color: #000;" class=3D"styled-by-prettify">v</span><span styl=
e=3D"color: #660;" class=3D"styled-by-prettify">};</span><span style=3D"col=
or: #000;" class=3D"styled-by-prettify"> =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 =C2=A0 =C2=A0 =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"> =C2=A0=
 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=
=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0</span><span style=3D"color: #660;" class=3D=
"styled-by-prettify">\</span><span style=3D"color: #000;" class=3D"styled-b=
y-prettify"><br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 std</span><span s=
tyle=3D"color: #660;" class=3D"styled-by-prettify">::</span><span style=3D"=
color: #000;" class=3D"styled-by-prettify">experimental</span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">::</span><span style=3D"colo=
r: #000;" class=3D"styled-by-prettify">optional</span><span style=3D"color:=
 #660;" class=3D"styled-by-prettify">&lt;</span><span style=3D"color: #000;=
" class=3D"styled-by-prettify"> =C2=A0 =C2=A0 =C2=A0</span><span style=3D"c=
olor: #660;" class=3D"styled-by-prettify">\</span><span style=3D"color: #00=
0;" class=3D"styled-by-prettify"><br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=
=A0 =C2=A0 =C2=A0 </span><span style=3D"color: #008;" class=3D"styled-by-pr=
ettify">decltype</span><span style=3D"color: #660;" class=3D"styled-by-pret=
tify">(</span><span style=3D"color: #000;" class=3D"styled-by-prettify">F</=
span><span style=3D"color: #660;" class=3D"styled-by-prettify">(</span><spa=
n style=3D"color: #000;" class=3D"styled-by-prettify">__VA_ARGS__</span><sp=
an style=3D"color: #660;" class=3D"styled-by-prettify">,</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"> =C2=A0 =C2=A0 =C2=A0 </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 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=
=A0parent_return</span><span style=3D"color: #660;" class=3D"styled-by-pret=
tify">))</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> =
=C2=A0 =C2=A0</span><span style=3D"color: #660;" class=3D"styled-by-prettif=
y">\</span><span 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: #660=
;" class=3D"styled-by-prettify">&gt;</span><span style=3D"color: #000;" cla=
ss=3D"styled-by-prettify"> ret</span><span style=3D"color: #660;" class=3D"=
styled-by-prettify">;</span><span style=3D"color: #000;" class=3D"styled-by=
-prettify"> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0</span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">\</span><span style=3D"color: #000;" class=3D"style=
d-by-prettify"><br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 </span><span s=
tyle=3D"color: #008;" class=3D"styled-by-prettify">try</span><span style=3D=
"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #=
660;" class=3D"styled-by-prettify">{</span><span style=3D"color: #000;" cla=
ss=3D"styled-by-prettify"> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0=
 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 </span><span style=3D"col=
or: #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 =C2=A0 =C2=
=A0 =C2=A0 =C2=A0 ret </span><span style=3D"color: #660;" class=3D"styled-b=
y-prettify">=3D</span><span style=3D"color: #000;" class=3D"styled-by-prett=
ify"> F</span><span style=3D"color: #660;" class=3D"styled-by-prettify">(</=
span><span style=3D"color: #000;" class=3D"styled-by-prettify">__VA_ARGS__<=
/span><span style=3D"color: #660;" class=3D"styled-by-prettify">,</span><sp=
an style=3D"color: #000;" class=3D"styled-by-prettify"> =C2=A0 =C2=A0 =C2=
=A0 =C2=A0 =C2=A0</span><span style=3D"color: #660;" class=3D"styled-by-pre=
ttify">\</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><b=
r>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=
=A0 =C2=A0 parent_return</span><span style=3D"color: #660;" class=3D"styled=
-by-prettify">);</span><span style=3D"color: #000;" class=3D"styled-by-pret=
tify"> =C2=A0 =C2=A0 =C2=A0 </span><span style=3D"color: #660;" class=3D"st=
yled-by-prettify">\</span><span style=3D"color: #000;" class=3D"styled-by-p=
rettify"><br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =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"> </span><span style=3D"color: #008;" =
class=3D"styled-by-prettify">catch</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"> </span><span style=3D"color: #660;" class=3D"style=
d-by-prettify">(</span><span style=3D"color: #000;" class=3D"styled-by-pret=
tify">parent_return_t r</span><span style=3D"color: #660;" class=3D"styled-=
by-prettify">)</span><span style=3D"color: #000;" class=3D"styled-by-pretti=
fy"> </span><span style=3D"color: #660;" class=3D"styled-by-prettify">{</sp=
an><span style=3D"color: #000;" class=3D"styled-by-prettify"> =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 =
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 </span><span style=3D"color: #008=
;" class=3D"styled-by-prettify">return</span><span style=3D"color: #000;" c=
lass=3D"styled-by-prettify"> std</span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">::</span><span style=3D"color: #000;" class=3D"styl=
ed-by-prettify">move</span><span style=3D"color: #660;" class=3D"styled-by-=
prettify">(</span><span style=3D"color: #000;" class=3D"styled-by-prettify"=
>r</span><span style=3D"color: #660;" class=3D"styled-by-prettify">.</span>=
<span style=3D"color: #000;" class=3D"styled-by-prettify">value</span><span=
 style=3D"color: #660;" class=3D"styled-by-prettify">);</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"> =C2=A0 =C2=A0</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>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =
=C2=A0 =C2=A0 </span><span style=3D"color: #660;" class=3D"styled-by-pretti=
fy">}</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </sp=
an><span style=3D"color: #008;" class=3D"styled-by-prettify">catch</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"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"> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =
=C2=A0 =C2=A0 </span><span style=3D"color: #660;" class=3D"styled-by-pretti=
fy">\</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br>=
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 </span><span style=
=3D"color: #008;" class=3D"styled-by-prettify">throw</span><span style=3D"c=
olor: #660;" class=3D"styled-by-prettify">;</span><span style=3D"color: #00=
0;" class=3D"styled-by-prettify"> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0=
 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =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 =C2=A0 =C2=A0 =C2=A0 =C2=A0 </spa=
n><span style=3D"color: #660;" class=3D"styled-by-prettify">}</span><span s=
tyle=3D"color: #000;" class=3D"styled-by-prettify"> =C2=A0 =C2=A0 =C2=A0 =
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=
=A0 =C2=A0 =C2=A0 </span><span style=3D"color: #660;" class=3D"styled-by-pr=
ettify">\</span><span 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: #=
660;" class=3D"styled-by-prettify">*</span><span style=3D"color: #000;" cla=
ss=3D"styled-by-prettify">ret</span><span style=3D"color: #660;" class=3D"s=
tyled-by-prettify">;</span><span style=3D"color: #000;" class=3D"styled-by-=
prettify"> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 </span><span style=3D"color: #660;" clas=
s=3D"styled-by-prettify">\</span><span style=3D"color: #000;" class=3D"styl=
ed-by-prettify"><br>=C2=A0 =C2=A0 =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><br></span><span style=3D"color: #008;" =
class=3D"styled-by-prettify">template</span><span style=3D"color: #660;" cl=
ass=3D"styled-by-prettify">&lt;</span><span style=3D"color: #008;" class=3D=
"styled-by-prettify">typename</span><span style=3D"color: #000;" class=3D"s=
tyled-by-prettify"> R</span><span style=3D"color: #660;" class=3D"styled-by=
-prettify">&gt;</span><span style=3D"color: #000;" class=3D"styled-by-prett=
ify"><br></span><span style=3D"color: #008;" class=3D"styled-by-prettify">d=
ouble</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> prod=
</span><span style=3D"color: #660;" class=3D"styled-by-prettify">(</span><s=
pan style=3D"color: #008;" class=3D"styled-by-prettify">const</span><span s=
tyle=3D"color: #000;" class=3D"styled-by-prettify"> R</span><span style=3D"=
color: #660;" class=3D"styled-by-prettify">&amp;</span><span style=3D"color=
: #000;" class=3D"styled-by-prettify"> r</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"style=
d-by-prettify">{</span><span style=3D"color: #000;" class=3D"styled-by-pret=
tify"><br>=C2=A0 =C2=A0 </span><span style=3D"color: #008;" class=3D"styled=
-by-prettify">if</span><span style=3D"color: #000;" class=3D"styled-by-pret=
tify"> </span><span style=3D"color: #660;" class=3D"styled-by-prettify">(</=
span><span style=3D"color: #000;" class=3D"styled-by-prettify">r</span><spa=
n style=3D"color: #660;" class=3D"styled-by-prettify">.</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify">empty</span><span style=3D"c=
olor: #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"sty=
led-by-prettify"><br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 </span><span style=3D"colo=
r: #008;" class=3D"styled-by-prettify">return</span><span style=3D"color: #=
000;" class=3D"styled-by-prettify"> NAN</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: #660;" c=
lass=3D"styled-by-prettify">}</span><span style=3D"color: #000;" class=3D"s=
tyled-by-prettify"><br>=C2=A0 =C2=A0 </span><span style=3D"color: #008;" cl=
ass=3D"styled-by-prettify">double</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"> p </span><span style=3D"color: #660;" class=3D"sty=
led-by-prettify">=3D</span><span style=3D"color: #000;" class=3D"styled-by-=
prettify"> </span><span style=3D"color: #066;" class=3D"styled-by-prettify"=
>1.0</span><span style=3D"color: #660;" class=3D"styled-by-prettify">;</spa=
n><span style=3D"color: #000;" class=3D"styled-by-prettify"><br>=C2=A0 =C2=
=A0 </span><span style=3D"color: #008;" class=3D"styled-by-prettify">for</s=
pan><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span=
 style=3D"color: #660;" class=3D"styled-by-prettify">(</span><span style=3D=
"color: #008;" class=3D"styled-by-prettify">auto</span><span style=3D"color=
: #000;" class=3D"styled-by-prettify"> ri </span><span style=3D"color: #660=
;" class=3D"styled-by-prettify">:</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"> r</span><span style=3D"color: #660;" class=3D"styl=
ed-by-prettify">)</span><span style=3D"color: #000;" class=3D"styled-by-pre=
ttify"> </span><span style=3D"color: #660;" class=3D"styled-by-prettify">{<=
/span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br>=C2=A0 =
=C2=A0 =C2=A0 =C2=A0 p </span><span style=3D"color: #660;" class=3D"styled-=
by-prettify">=3D</span><span style=3D"color: #000;" class=3D"styled-by-pret=
tify"> invoke_with</span><span style=3D"color: #660;" class=3D"styled-by-pr=
ettify">(</span><span style=3D"color: #000;" class=3D"styled-by-prettify">t=
ake_return</span><span style=3D"color: #660;" class=3D"styled-by-prettify">=
,</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> mul2</sp=
an><span style=3D"color: #660;" class=3D"styled-by-prettify">,</span><span =
style=3D"color: #000;" class=3D"styled-by-prettify"> p</span><span style=3D=
"color: #660;" class=3D"styled-by-prettify">,</span><span style=3D"color: #=
000;" class=3D"styled-by-prettify"> ri</span><span style=3D"color: #660;" c=
lass=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"c=
olor: #800;" class=3D"styled-by-prettify">//p =3D invoke_with_abs(double, m=
ul2, p, ri);</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 </span><span style=3D"color: #008;" class=3D"styled-by-p=
rettify">return</span><span style=3D"color: #000;" class=3D"styled-by-prett=
ify"> p</span><span style=3D"color: #660;" class=3D"styled-by-prettify">;</=
span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br></span><=
span style=3D"color: #660;" class=3D"styled-by-prettify">}</span><span styl=
e=3D"color: #000;" class=3D"styled-by-prettify"><br><br></span><span style=
=3D"color: #008;" class=3D"styled-by-prettify">int</span><span style=3D"col=
or: #000;" class=3D"styled-by-prettify"> main</span><span style=3D"color: #=
660;" class=3D"styled-by-prettify">()</span><span style=3D"color: #000;" cl=
ass=3D"styled-by-prettify"><br></span><span style=3D"color: #660;" class=3D=
"styled-by-prettify">{</span><span style=3D"color: #000;" class=3D"styled-b=
y-prettify"><br>=C2=A0 =C2=A0 std</span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">::</span><span style=3D"color: #000;" class=3D"styl=
ed-by-prettify">vector</span><span style=3D"color: #080;" class=3D"styled-b=
y-prettify">&lt;int&gt;</span><span style=3D"color: #000;" class=3D"styled-=
by-prettify"> v</span><span style=3D"color: #660;" class=3D"styled-by-prett=
ify">{</span><span style=3D"color: #066;" class=3D"styled-by-prettify">1</s=
pan><span style=3D"color: #660;" class=3D"styled-by-prettify">,</span><span=
 style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D=
"color: #066;" class=3D"styled-by-prettify">2</span><span style=3D"color: #=
660;" class=3D"styled-by-prettify">,</span><span style=3D"color: #000;" cla=
ss=3D"styled-by-prettify"> </span><span style=3D"color: #066;" class=3D"sty=
led-by-prettify">0</span><span style=3D"color: #660;" class=3D"styled-by-pr=
ettify">,</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> =
</span><span style=3D"color: #066;" class=3D"styled-by-prettify">4</span><s=
pan style=3D"color: #660;" class=3D"styled-by-prettify">};</span><span styl=
e=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 s=
tyle=3D"color: #000;" class=3D"styled-by-prettify">cout </span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">&lt;&lt;</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"> prod</span><span style=3D"c=
olor: #660;" class=3D"styled-by-prettify">(</span><span style=3D"color: #00=
0;" class=3D"styled-by-prettify">v</span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">);</span><span style=3D"color: #000;" class=3D"styl=
ed-by-prettify"><br></span><span style=3D"color: #660;" class=3D"styled-by-=
prettify">}</span></div></code></div><br><br>Thanks,<br>-lorro<br></div>

<p></p>

-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; 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/9fc1d216-bbe9-4702-893a-c6eb15210eb1%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/9fc1d216-bbe9-4702-893a-c6eb15210eb1=
%40isocpp.org</a>.<br />

------=_Part_365_1848530513.1476032337408--

------=_Part_364_1978464078.1476032337407--

.


Author: szollosi.lorand@gmail.com
Date: Sat, 15 Oct 2016 10:25:34 -0700 (PDT)
Raw View
------=_Part_1424_1807162400.1476552334646
Content-Type: multipart/alternative;
 boundary="----=_Part_1425_942901630.1476552334648"

------=_Part_1425_942901630.1476552334648
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

Hi,

On another thread, `expr` was proposed for a lambda-like construct that's=
=20
forwarding as-is (i.e., no need for std::forward<T>(expr)). We might use=20
that syntax for passing return, break and continue:

template<typename T>
void g(int i, T brk)
{
    std:cout << i;
    if (i % 2) brk();
}

bool f(std::vector<int> v)
{
    for (auto&& i : v) {
        g(i, []`break;`);
    }
}



What do you think?

Thanks,
-lorro

2016. okt=C3=B3ber 9., vas=C3=A1rnap 18:58:57 UTC+2 id=C5=91pontban szollos=
....@gmail.com a=20
k=C3=B6vetkez=C5=91t =C3=ADrta:
>
> Hi,
>
> A toy model of the capture part is possible using gcc's statement=20
> expressions extension. This is not for implementation reference, just to=
=20
> have a clearer view of the idea:
>
> #include <vector>
> #include <iostream>
> #include <experimental/optional>
> #include <cmath>
> #include <limits>
>
> enum class return_mode { ret, brk, cont, back };
> enum { parent_break };
> enum { parent_continue };
> enum { to_parent };
>
> // TODO: specialize for void
> template<typename R, typename P>
> struct extended_return
> {
>     const return_mode                    which_;
>     const std::experimental::optional<P> parent_retval_;
>     const std::experimental::optional<R> retval_;
>     extended_return(R retval)
>         : which_ (return_mode::back)
>         , retval_(std::move(retval)) {}
>     extended_return(decltype(to_parent), P retval)
>         : which_ (return_mode::ret)
>         , parent_retval_(std::move(retval)) {}
>     extended_return(decltype(parent_break) tgt)
>         : which_ (return_mode::brk) {}
>     extended_return(decltype(parent_continue) tgt)
>         : which_ (return_mode::cont) {}
>     operator return_mode() const { return which_; }
> };
>
> extended_return<double, double> mul2(double lhs, double rhs)
> {
>     if (rhs =3D=3D 0) {
>         return { to_parent, 0.0 };
>     }
>     return lhs * rhs;
> }
>
> double mul2(double lhs, double rhs, void(*parent_return)(double))
> {
>     if (rhs =3D=3D 0) {
>         parent_return(0.0);
>     }
>     return lhs * rhs;
> }
>
> #define take_return                           \
>             else if(ret =3D=3D return_mode::ret)  \
>                 return *ret.parent_retval_;
>
> #define take_break                            \
>             else if(ret =3D=3D return_mode::brk)  \
>                 break;
>
> #define take_continue                         \
>             else if(ret =3D=3D return_mode::cont) \
>                 continue;
>
> #define invoke_with(TAKEN, F, ...)            \
>         ({                                    \
>             auto ret =3D F(__VA_ARGS__);        \
>             if (false);                       \
>             TAKEN                             \
>             *ret.retval_;                     \
>         });
>
>
> #define invoke_with_abs(R, F, ...)            \
>         ({                                    \
>             struct parent_return_t            \
>             {                                 \
>                 R value;                      \
>             };                                \
>             auto parent_return =3D +[](R v) {   \
>                 throw parent_return_t{v};     \
>             };                                \
>             std::experimental::optional<      \
>                 decltype(F(__VA_ARGS__,       \
>                            parent_return))    \
>             > ret;                            \
>             try {                             \
>                 ret =3D F(__VA_ARGS__,          \
>                         parent_return);       \
>             } catch (parent_return_t r) {     \
>                 return std::move(r.value);    \
>             } catch (...) {                   \
>                 throw;                        \
>             }                                 \
>             *ret;                             \
>         });
>
> template<typename R>
> double prod(const R& r)
> {
>     if (r.empty()) {
>         return NAN;
>     }
>     double p =3D 1.0;
>     for (auto ri : r) {
>         p =3D invoke_with(take_return, mul2, p, ri);
>         //p =3D invoke_with_abs(double, mul2, p, ri);
>     }
>     return p;
> }
>
> int main()
> {
>     std::vector<int> v{1, 2, 0, 4};
>     std::cout << prod(v);
> }
>
>
> Thanks,
> -lorro
>

--=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp=
..org/d/msgid/std-proposals/7b2d8f2c-b50f-40a7-83e5-e3b7e57865d0%40isocpp.or=
g.

------=_Part_1425_942901630.1476552334648
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">Hi,<br><br>On another thread, `expr` was proposed for a la=
mbda-like construct that&#39;s forwarding as-is (i.e., no need for std::for=
ward&lt;T&gt;(expr)). We might use that syntax for passing return, break an=
d continue:<br><br><div class=3D"prettyprint" style=3D"background-color: rg=
b(250, 250, 250); border-color: rgb(187, 187, 187); border-style: solid; bo=
rder-width: 1px; word-wrap: break-word;"><code class=3D"prettyprint"><div c=
lass=3D"subprettyprint"><span style=3D"color: #008;" class=3D"styled-by-pre=
ttify">template</span><span style=3D"color: #660;" class=3D"styled-by-prett=
ify">&lt;</span><span style=3D"color: #008;" class=3D"styled-by-prettify">t=
ypename</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> T<=
/span><span style=3D"color: #660;" class=3D"styled-by-prettify">&gt;</span>=
<span style=3D"color: #000;" class=3D"styled-by-prettify"><br></span><span =
style=3D"color: #008;" class=3D"styled-by-prettify">void</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"> g</span><span style=3D"colo=
r: #660;" class=3D"styled-by-prettify">(</span><span style=3D"color: #008;"=
 class=3D"styled-by-prettify">int</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"> i</span><span style=3D"color: #660;" class=3D"styl=
ed-by-prettify">,</span><span style=3D"color: #000;" class=3D"styled-by-pre=
ttify"> T brk</span><span style=3D"color: #660;" class=3D"styled-by-prettif=
y">)</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br></=
span><span style=3D"color: #660;" class=3D"styled-by-prettify">{</span><spa=
n 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><s=
pan style=3D"color: #000;" class=3D"styled-by-prettify">cout </span><span s=
tyle=3D"color: #660;" class=3D"styled-by-prettify">&lt;&lt;</span><span sty=
le=3D"color: #000;" class=3D"styled-by-prettify"> i</span><span style=3D"co=
lor: #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"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">i </span><span style=3D"color: #660;" class=3D"styled-by-pre=
ttify">%</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> <=
/span><span style=3D"color: #066;" class=3D"styled-by-prettify">2</span><sp=
an style=3D"color: #660;" class=3D"styled-by-prettify">)</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"> brk</span><span style=3D"co=
lor: #660;" class=3D"styled-by-prettify">();</span><span style=3D"color: #0=
00;" class=3D"styled-by-prettify"><br></span><span style=3D"color: #660;" c=
lass=3D"styled-by-prettify">}</span><span style=3D"color: #000;" class=3D"s=
tyled-by-prettify"><br><br></span><span style=3D"color: #008;" class=3D"sty=
led-by-prettify">bool</span><span style=3D"color: #000;" class=3D"styled-by=
-prettify"> f</span><span style=3D"color: #660;" class=3D"styled-by-prettif=
y">(</span><span style=3D"color: #000;" class=3D"styled-by-prettify">std</s=
pan><span style=3D"color: #660;" class=3D"styled-by-prettify">::</span><spa=
n style=3D"color: #000;" class=3D"styled-by-prettify">vector</span><span st=
yle=3D"color: #080;" class=3D"styled-by-prettify">&lt;int&gt;</span><span s=
tyle=3D"color: #000;" class=3D"styled-by-prettify"> v</span><span style=3D"=
color: #660;" class=3D"styled-by-prettify">)</span><span style=3D"color: #0=
00;" class=3D"styled-by-prettify"><br></span><span style=3D"color: #660;" c=
lass=3D"styled-by-prettify">{</span><span style=3D"color: #000;" class=3D"s=
tyled-by-prettify"><br>=C2=A0 =C2=A0 </span><span style=3D"color: #008;" cl=
ass=3D"styled-by-prettify">for</span><span style=3D"color: #000;" class=3D"=
styled-by-prettify"> </span><span style=3D"color: #660;" class=3D"styled-by=
-prettify">(</span><span style=3D"color: #008;" class=3D"styled-by-prettify=
">auto</span><span style=3D"color: #660;" class=3D"styled-by-prettify">&amp=
;&amp;</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> i <=
/span><span style=3D"color: #660;" class=3D"styled-by-prettify">:</span><sp=
an style=3D"color: #000;" class=3D"styled-by-prettify"> v</span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">)</span><span style=3D"color=
: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #660;" =
class=3D"styled-by-prettify">{</span><span style=3D"color: #000;" class=3D"=
styled-by-prettify"><br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 g</span><span style=3D"=
color: #660;" class=3D"styled-by-prettify">(</span><span style=3D"color: #0=
00;" class=3D"styled-by-prettify">i</span><span style=3D"color: #660;" clas=
s=3D"styled-by-prettify">,</span><span style=3D"color: #000;" class=3D"styl=
ed-by-prettify"> </span><span style=3D"color: #660;" class=3D"styled-by-pre=
ttify">[]</span><span style=3D"color: #080;" class=3D"styled-by-prettify">`=
break;`</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: #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 styl=
e=3D"color: #000;" class=3D"styled-by-prettify"><br><br></span></div></code=
></div><br><br>What do you think?<br><br>Thanks,<br>-lorro<br><br>2016. okt=
=C3=B3ber 9., vas=C3=A1rnap 18:58:57 UTC+2 id=C5=91pontban szollos...@gmail=
..com a k=C3=B6vetkez=C5=91t =C3=ADrta:<blockquote class=3D"gmail_quote" sty=
le=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left=
: 1ex;"><div dir=3D"ltr">Hi,<br><br>A toy model of the capture part is poss=
ible using gcc&#39;s statement expressions extension. This is not for imple=
mentation reference, just to have a clearer view of the idea:<br><br><div s=
tyle=3D"background-color:rgb(250,250,250);border-color:rgb(187,187,187);bor=
der-style:solid;border-width:1px;word-wrap:break-word"><code><div><span sty=
le=3D"color:#800">#include</span><span style=3D"color:#000"> </span><span s=
tyle=3D"color:#080">&lt;vector&gt;</span><span style=3D"color:#000"><br></s=
pan><span style=3D"color:#800">#include</span><span style=3D"color:#000"> <=
/span><span style=3D"color:#080">&lt;iostream&gt;</span><span style=3D"colo=
r:#000"><br></span><span style=3D"color:#800">#include</span><span style=3D=
"color:#000"> </span><span style=3D"color:#660">&lt;</span><span style=3D"c=
olor:#000">experimental</span><span style=3D"color:#660">/</span><span styl=
e=3D"color:#000">optional</span><span style=3D"color:#660">&gt;</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">&lt;cmath&gt;=
</span><span style=3D"color:#000"><br></span><span style=3D"color:#800">#in=
clude</span><span style=3D"color:#000"> </span><span style=3D"color:#080">&=
lt;limits&gt;</span><span style=3D"color:#000"><br><br></span><span style=
=3D"color:#008">enum</span><span style=3D"color:#000"> </span><span style=
=3D"color:#008">class</span><span style=3D"color:#000"> return_mode </span>=
<span style=3D"color:#660">{</span><span style=3D"color:#000"> ret</span><s=
pan style=3D"color:#660">,</span><span style=3D"color:#000"> brk</span><spa=
n style=3D"color:#660">,</span><span style=3D"color:#000"> cont</span><span=
 style=3D"color:#660">,</span><span style=3D"color:#000"> back </span><span=
 style=3D"color:#660">};</span><span style=3D"color:#000"><br></span><span =
style=3D"color:#008">enum</span><span style=3D"color:#000"> </span><span st=
yle=3D"color:#660">{</span><span style=3D"color:#000"> parent_break </span>=
<span style=3D"color:#660">};</span><span style=3D"color:#000"><br></span><=
span style=3D"color:#008">enum</span><span style=3D"color:#000"> </span><sp=
an style=3D"color:#660">{</span><span style=3D"color:#000"> parent_continue=
 </span><span style=3D"color:#660">};</span><span style=3D"color:#000"><br>=
</span><span style=3D"color:#008">enum</span><span style=3D"color:#000"> </=
span><span style=3D"color:#660">{</span><span style=3D"color:#000"> to_pare=
nt </span><span style=3D"color:#660">};</span><span style=3D"color:#000"><b=
r><br></span><span style=3D"color:#800">// TODO: specialize for void</span>=
<span style=3D"color:#000"><br></span><span style=3D"color:#008">template</=
span><span style=3D"color:#660">&lt;</span><span style=3D"color:#008">typen=
ame</span><span style=3D"color:#000"> R</span><span style=3D"color:#660">,<=
/span><span style=3D"color:#000"> </span><span style=3D"color:#008">typenam=
e</span><span style=3D"color:#000"> P</span><span style=3D"color:#660">&gt;=
</span><span style=3D"color:#000"><br></span><span style=3D"color:#008">str=
uct</span><span style=3D"color:#000"> extended_return<br></span><span style=
=3D"color:#660">{</span><span style=3D"color:#000"><br>=C2=A0 =C2=A0 </span=
><span style=3D"color:#008">const</span><span style=3D"color:#000"> return_=
mode =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0w=
hich_</span><span style=3D"color:#660">;</span><span style=3D"color:#000"><=
br>=C2=A0 =C2=A0 </span><span style=3D"color:#008">const</span><span style=
=3D"color:#000"> std</span><span style=3D"color:#660">::</span><span style=
=3D"color:#000">experimental</span><span style=3D"color:#660">::</span><spa=
n style=3D"color:#000">optional</span><span style=3D"color:#660">&lt;</span=
><span style=3D"color:#000">P</span><span style=3D"color:#660">&gt;</span><=
span style=3D"color:#000"> parent_retval_</span><span style=3D"color:#660">=
;</span><span style=3D"color:#000"><br>=C2=A0 =C2=A0 </span><span style=3D"=
color:#008">const</span><span style=3D"color:#000"> std</span><span style=
=3D"color:#660">::</span><span style=3D"color:#000">experimental</span><spa=
n style=3D"color:#660">::</span><span style=3D"color:#000">optional</span><=
span style=3D"color:#660">&lt;</span><span style=3D"color:#000">R</span><sp=
an style=3D"color:#660">&gt;</span><span style=3D"color:#000"> retval_</spa=
n><span style=3D"color:#660">;</span><span style=3D"color:#000"><br>=C2=A0 =
=C2=A0 extended_return</span><span style=3D"color:#660">(</span><span style=
=3D"color:#000">R retval</span><span style=3D"color:#660">)</span><span sty=
le=3D"color:#000"><br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 </span><span style=3D"col=
or:#660">:</span><span style=3D"color:#000"> which_ </span><span style=3D"c=
olor:#660">(</span><span style=3D"color:#000">return_mode</span><span style=
=3D"color:#660">::</span><span style=3D"color:#000">back</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:#660">,</span><span style=3D"color:#000=
"> retval_</span><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=
">move</span><span style=3D"color:#660">(</span><span style=3D"color:#000">=
retval</span><span style=3D"color:#660">))</span><span style=3D"color:#000"=
> </span><span style=3D"color:#660">{}</span><span style=3D"color:#000"><br=
>=C2=A0 =C2=A0 extended_return</span><span style=3D"color:#660">(</span><sp=
an style=3D"color:#008">decltype</span><span style=3D"color:#660">(</span><=
span style=3D"color:#000">to_<wbr>parent</span><span style=3D"color:#660">)=
,</span><span style=3D"color:#000"> P retval</span><span style=3D"color:#66=
0">)</span><span style=3D"color:#000"><br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 </spa=
n><span style=3D"color:#660">:</span><span style=3D"color:#000"> which_ </s=
pan><span style=3D"color:#660">(</span><span style=3D"color:#000">return_mo=
de</span><span style=3D"color:#660">::</span><span style=3D"color:#000">ret=
</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:#660">,</span><span=
 style=3D"color:#000"> parent_retval_</span><span style=3D"color:#660">(</s=
pan><span style=3D"color:#000">std</span><span style=3D"color:#660">::</spa=
n><span style=3D"color:#000">move</span><span style=3D"color:#660">(</span>=
<span style=3D"color:#000">retva<wbr>l</span><span style=3D"color:#660">))<=
/span><span style=3D"color:#000"> </span><span style=3D"color:#660">{}</spa=
n><span style=3D"color:#000"><br>=C2=A0 =C2=A0 extended_return</span><span =
style=3D"color:#660">(</span><span style=3D"color:#008">decltype</span><spa=
n style=3D"color:#660">(</span><span style=3D"color:#000">paren<wbr>t_break=
</span><span style=3D"color:#660">)</span><span style=3D"color:#000"> tgt</=
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:#660">:</span><span st=
yle=3D"color:#000"> which_ </span><span style=3D"color:#660">(</span><span =
style=3D"color:#000">return_mode</span><span style=3D"color:#660">::</span>=
<span style=3D"color:#000">brk</span><span style=3D"color:#660">)</span><sp=
an style=3D"color:#000"> </span><span style=3D"color:#660">{}</span><span s=
tyle=3D"color:#000"><br>=C2=A0 =C2=A0 extended_return</span><span style=3D"=
color:#660">(</span><span style=3D"color:#008">decltype</span><span style=
=3D"color:#660">(</span><span style=3D"color:#000">paren<wbr>t_continue</sp=
an><span style=3D"color:#660">)</span><span style=3D"color:#000"> tgt</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:#660">:</span><span style=
=3D"color:#000"> which_ </span><span style=3D"color:#660">(</span><span sty=
le=3D"color:#000">return_mode</span><span style=3D"color:#660">::</span><sp=
an style=3D"color:#000">cont</span><span style=3D"color:#660">)</span><span=
 style=3D"color:#000"> </span><span style=3D"color:#660">{}</span><span sty=
le=3D"color:#000"><br>=C2=A0 =C2=A0 </span><span style=3D"color:#008">opera=
tor</span><span style=3D"color:#000"> return_mode</span><span style=3D"colo=
r:#660">()</span><span style=3D"color:#000"> </span><span style=3D"color:#0=
08">const</span><span style=3D"color:#000"> </span><span style=3D"color:#66=
0">{</span><span style=3D"color:#000"> </span><span style=3D"color:#008">re=
turn</span><span style=3D"color:#000"> which_</span><span style=3D"color:#6=
60">;</span><span style=3D"color:#000"> </span><span style=3D"color:#660">}=
</span><span style=3D"color:#000"><br></span><span style=3D"color:#660">};<=
/span><span style=3D"color:#000"><br><br>extended_return</span><span style=
=3D"color:#660">&lt;</span><span style=3D"color:#008">double</span><span st=
yle=3D"color:#660">,</span><span style=3D"color:#000"> </span><span style=
=3D"color:#008">double</span><span style=3D"color:#660">&gt;</span><span st=
yle=3D"color:#000"> mul2</span><span style=3D"color:#660">(</span><span sty=
le=3D"color:#008">double</span><span style=3D"color:#000"> lhs</span><span =
style=3D"color:#660">,</span><span style=3D"color:#000"> </span><span style=
=3D"color:#008">double</span><span style=3D"color:#000"> rhs</span><span st=
yle=3D"color:#660">)</span><span style=3D"color:#000"><br></span><span styl=
e=3D"color:#660">{</span><span style=3D"color:#000"><br>=C2=A0 =C2=A0 </spa=
n><span style=3D"color:#008">if</span><span style=3D"color:#000"> </span><s=
pan style=3D"color:#660">(</span><span style=3D"color:#000">rhs </span><spa=
n style=3D"color:#660">=3D=3D</span><span style=3D"color:#000"> </span><spa=
n style=3D"color:#066">0</span><span style=3D"color:#660">)</span><span sty=
le=3D"color:#000"> </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:#0=
08">return</span><span style=3D"color:#000"> </span><span style=3D"color:#6=
60">{</span><span style=3D"color:#000"> to_parent</span><span style=3D"colo=
r:#660">,</span><span style=3D"color:#000"> </span><span style=3D"color:#06=
6">0.0</span><span style=3D"color:#000"> </span><span style=3D"color:#660">=
};</span><span style=3D"color:#000"><br>=C2=A0 =C2=A0 </span><span style=3D=
"color:#660">}</span><span style=3D"color:#000"><br>=C2=A0 =C2=A0 </span><s=
pan style=3D"color:#008">return</span><span style=3D"color:#000"> lhs </spa=
n><span style=3D"color:#660">*</span><span style=3D"color:#000"> rhs</span>=
<span style=3D"color:#660">;</span><span style=3D"color:#000"><br></span><s=
pan style=3D"color:#660">}</span><span style=3D"color:#000"><br><br></span>=
<span style=3D"color:#008">double</span><span style=3D"color:#000"> mul2</s=
pan><span style=3D"color:#660">(</span><span style=3D"color:#008">double</s=
pan><span style=3D"color:#000"> lhs</span><span style=3D"color:#660">,</spa=
n><span style=3D"color:#000"> </span><span style=3D"color:#008">double</spa=
n><span style=3D"color:#000"> rhs</span><span style=3D"color:#660">,</span>=
<span style=3D"color:#000"> </span><span style=3D"color:#008">void</span><s=
pan style=3D"color:#660">(*</span><span style=3D"color:#000">parent_return<=
/span><span style=3D"color:#660">)(</span><span style=3D"color:#008">double=
</span><span style=3D"color:#660">))</span><span style=3D"color:#000"><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><span style=3D"color:#660">(</span><span style=3D"color:#000"=
>rhs </span><span style=3D"color:#660">=3D=3D</span><span style=3D"color:#0=
00"> </span><span style=3D"color:#066">0</span><span style=3D"color:#660">)=
</span><span style=3D"color:#000"> </span><span style=3D"color:#660">{</spa=
n><span style=3D"color:#000"><br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 parent_return<=
/span><span style=3D"color:#660">(</span><span style=3D"color:#066">0.0</sp=
an><span style=3D"color:#660">);</span><span style=3D"color:#000"><br>=C2=
=A0 =C2=A0 </span><span style=3D"color:#660">}</span><span style=3D"color:#=
000"><br>=C2=A0 =C2=A0 </span><span style=3D"color:#008">return</span><span=
 style=3D"color:#000"> lhs </span><span style=3D"color:#660">*</span><span =
style=3D"color:#000"> rhs</span><span style=3D"color:#660">;</span><span st=
yle=3D"color:#000"><br></span><span style=3D"color:#660">}</span><span styl=
e=3D"color:#000"><br><br></span><span style=3D"color:#800">#define</span><s=
pan style=3D"color:#000"> take_return =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 </span><span style=
=3D"color:#660">\</span><span style=3D"color:#000"><br>=C2=A0 =C2=A0 =C2=A0=
 =C2=A0 =C2=A0 =C2=A0 </span><span style=3D"color:#008">else</span><span st=
yle=3D"color:#000"> </span><span style=3D"color:#008">if</span><span style=
=3D"color:#660">(</span><span style=3D"color:#000">ret </span><span style=
=3D"color:#660">=3D=3D</span><span style=3D"color:#000"> return_mode</span>=
<span style=3D"color:#660">::</span><span style=3D"color:#000">ret</span><s=
pan style=3D"color:#660">)</span><span style=3D"color:#000"> =C2=A0</span><=
span style=3D"color:#660">\</span><span style=3D"color:#000"><br>=C2=A0 =C2=
=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 </span><span style=3D"color:#=
008">return</span><span style=3D"color:#000"> </span><span style=3D"color:#=
660">*</span><span style=3D"color:#000">ret</span><span style=3D"color:#660=
">.</span><span style=3D"color:#000">parent_retval_</span><span style=3D"co=
lor:#660">;</span><span style=3D"color:#000"><br><br></span><span style=3D"=
color:#800">#define</span><span style=3D"color:#000"> take_break =C2=A0 =C2=
=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =
=C2=A0 =C2=A0</span><span style=3D"color:#660">\</span><span style=3D"color=
:#000"><br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 </span><span style=3D"=
color:#008">else</span><span style=3D"color:#000"> </span><span style=3D"co=
lor:#008">if</span><span style=3D"color:#660">(</span><span style=3D"color:=
#000">ret </span><span style=3D"color:#660">=3D=3D</span><span style=3D"col=
or:#000"> return_mode</span><span style=3D"color:#660">::</span><span style=
=3D"color:#000">brk</span><span style=3D"color:#660">)</span><span style=3D=
"color:#000"> =C2=A0</span><span style=3D"color:#660">\</span><span style=
=3D"color:#000"><br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0=
 </span><span style=3D"color:#008">break</span><span style=3D"color:#660">;=
</span><span style=3D"color:#000"><br><br></span><span style=3D"color:#800"=
>#define</span><span style=3D"color:#000"> take_continue =C2=A0 =C2=A0 =C2=
=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 </span><=
span style=3D"color:#660">\</span><span style=3D"color:#000"><br>=C2=A0 =C2=
=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 </span><span style=3D"color:#008">else</spa=
n><span style=3D"color:#000"> </span><span style=3D"color:#008">if</span><s=
pan style=3D"color:#660">(</span><span style=3D"color:#000">ret </span><spa=
n style=3D"color:#660">=3D=3D</span><span style=3D"color:#000"> return_mode=
</span><span style=3D"color:#660">::</span><span style=3D"color:#000">cont<=
/span><span style=3D"color:#660">)</span><span style=3D"color:#000"> </span=
><span style=3D"color:#660">\</span><span style=3D"color:#000"><br>=C2=A0 =
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 </span><span style=3D"colo=
r:#008">continue</span><span style=3D"color:#660">;</span><span style=3D"co=
lor:#000"><br><br></span><span style=3D"color:#800">#define</span><span sty=
le=3D"color:#000"> invoke_with</span><span style=3D"color:#660">(</span><sp=
an style=3D"color:#000">TAKEN</span><span style=3D"color:#660">,</span><spa=
n style=3D"color:#000"> F</span><span style=3D"color:#660">,</span><span st=
yle=3D"color:#000"> </span><span style=3D"color:#660">...)</span><span styl=
e=3D"color:#000"> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0</span><span sty=
le=3D"color:#660">\</span><span style=3D"color:#000"><br>=C2=A0 =C2=A0 =C2=
=A0 =C2=A0 </span><span style=3D"color:#660">({</span><span style=3D"color:=
#000"> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=
=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0</span><span sty=
le=3D"color:#660">\</span><span style=3D"color:#000"><br>=C2=A0 =C2=A0 =C2=
=A0 =C2=A0 =C2=A0 =C2=A0 </span><span style=3D"color:#008">auto</span><span=
 style=3D"color:#000"> ret </span><span style=3D"color:#660">=3D</span><spa=
n style=3D"color:#000"> F</span><span style=3D"color:#660">(</span><span st=
yle=3D"color:#000">__VA_ARGS__</span><span style=3D"color:#660">);</span><s=
pan style=3D"color:#000"> =C2=A0 =C2=A0 =C2=A0 =C2=A0</span><span style=3D"=
color:#660">\</span><span style=3D"color:#000"><br>=C2=A0 =C2=A0 =C2=A0 =C2=
=A0 =C2=A0 =C2=A0 </span><span style=3D"color:#008">if</span><span style=3D=
"color:#000"> </span><span style=3D"color:#660">(</span><span style=3D"colo=
r:#008">false</span><span style=3D"color:#660">);</span><span style=3D"colo=
r:#000"> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=
=A0 =C2=A0 </span><span style=3D"color:#660">\</span><span style=3D"color:#=
000"><br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 TAKEN =C2=A0 =C2=A0 =C2=
=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =
=C2=A0 </span><span style=3D"color:#660">\</span><span style=3D"color:#000"=
><br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 </span><span style=3D"color:=
#660">*</span><span style=3D"color:#000">ret</span><span style=3D"color:#66=
0">.</span><span style=3D"color:#000">retval_</span><span style=3D"color:#6=
60">;</span><span style=3D"color:#000"> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 </span><span style=3D"color:#660">\</spa=
n><span style=3D"color:#000"><br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 </span><span s=
tyle=3D"color:#660">});</span><span style=3D"color:#000"><br><br><br></span=
><span style=3D"color:#800">#define</span><span style=3D"color:#000"> invok=
e_with_abs</span><span style=3D"color:#660">(</span><span style=3D"color:#0=
00">R</span><span style=3D"color:#660">,</span><span style=3D"color:#000"> =
F</span><span style=3D"color:#660">,</span><span style=3D"color:#000"> </sp=
an><span style=3D"color:#660">...)</span><span style=3D"color:#000"> =C2=A0=
 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0</span><span style=3D"color:#660">\</spa=
n><span style=3D"color:#000"><br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 </span><span s=
tyle=3D"color:#660">({</span><span style=3D"color:#000"> =C2=A0 =C2=A0 =C2=
=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0</span><span style=3D"color:#660">\</span=
><span style=3D"color:#000"><br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 <=
/span><span style=3D"color:#008">struct</span><span style=3D"color:#000"> p=
arent_return_t =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0</span><span style=
=3D"color:#660">\</span><span style=3D"color:#000"><br>=C2=A0 =C2=A0 =C2=A0=
 =C2=A0 =C2=A0 =C2=A0 </span><span style=3D"color:#660">{</span><span style=
=3D"color:#000"> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 </span><span style=
=3D"color:#660">\</span><span style=3D"color:#000"><br>=C2=A0 =C2=A0 =C2=A0=
 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 R value</span><span style=3D"color:#660=
">;</span><span style=3D"color:#000"> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0</span><span style=3D"color:#660">=
\</span><span style=3D"color:#000"><br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =
=C2=A0 </span><span style=3D"color:#660">};</span><span style=3D"color:#000=
"> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0</span><span style=3D"color:#660">=
\</span><span style=3D"color:#000"><br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =
=C2=A0 </span><span style=3D"color:#008">auto</span><span style=3D"color:#0=
00"> parent_return </span><span style=3D"color:#660">=3D</span><span style=
=3D"color:#000"> </span><span style=3D"color:#660">+[](</span><span style=
=3D"color:#000">R v</span><span style=3D"color:#660">)</span><span style=3D=
"color:#000"> </span><span style=3D"color:#660">{</span><span style=3D"colo=
r:#000"> =C2=A0 </span><span style=3D"color:#660">\</span><span style=3D"co=
lor:#000"><br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 </spa=
n><span style=3D"color:#008">throw</span><span style=3D"color:#000"> parent=
_return_t</span><span style=3D"color:#660">{</span><span style=3D"color:#00=
0">v</span><span style=3D"color:#660">};</span><span style=3D"color:#000"> =
=C2=A0 =C2=A0 </span><span style=3D"color:#660">\</span><span style=3D"colo=
r:#000"><br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 </span><span style=3D=
"color:#660">};</span><span style=3D"color:#000"> =C2=A0 =C2=A0 =C2=A0 =C2=
=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =
=C2=A0 =C2=A0</span><span style=3D"color:#660">\</span><span style=3D"color=
:#000"><br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 std</span><span style=
=3D"color:#660">::</span><span style=3D"color:#000">experimental</span><spa=
n style=3D"color:#660">::</span><span style=3D"color:#000">optional</span><=
span style=3D"color:#660">&lt;</span><span style=3D"color:#000"> =C2=A0 =C2=
=A0 =C2=A0</span><span style=3D"color:#660">\</span><span style=3D"color:#0=
00"><br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 </span><spa=
n style=3D"color:#008">decltype</span><span style=3D"color:#660">(</span><s=
pan style=3D"color:#000">F</span><span style=3D"color:#660">(</span><span s=
tyle=3D"color:#000">__VA_ARGS__</span><span style=3D"color:#660">,</span><s=
pan style=3D"color:#000"> =C2=A0 =C2=A0 =C2=A0 </span><span style=3D"color:=
#660">\</span><span style=3D"color:#000"><br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0parent=
_return</span><span style=3D"color:#660">))</span><span style=3D"color:#000=
"> =C2=A0 =C2=A0</span><span style=3D"color:#660">\</span><span style=3D"co=
lor:#000"><br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 </span><span style=
=3D"color:#660">&gt;</span><span style=3D"color:#000"> ret</span><span styl=
e=3D"color:#660">;</span><span style=3D"color:#000"> =C2=A0 =C2=A0 =C2=A0 =
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=
=A0</span><span style=3D"color:#660">\</span><span style=3D"color:#000"><br=
>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 </span><span style=3D"color:#008=
">try</span><span style=3D"color:#000"> </span><span style=3D"color:#660">{=
</span><span style=3D"color:#000"> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=
=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 </span><span st=
yle=3D"color:#660">\</span><span style=3D"color:#000"><br>=C2=A0 =C2=A0 =C2=
=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 ret </span><span style=3D"color:#660=
">=3D</span><span style=3D"color:#000"> F</span><span style=3D"color:#660">=
(</span><span style=3D"color:#000">__VA_ARGS__</span><span style=3D"color:#=
660">,</span><span style=3D"color:#000"> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0=
</span><span style=3D"color:#660">\</span><span style=3D"color:#000"><br>=
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=
=A0 =C2=A0 parent_return</span><span style=3D"color:#660">);</span><span st=
yle=3D"color:#000"> =C2=A0 =C2=A0 =C2=A0 </span><span style=3D"color:#660">=
\</span><span style=3D"color:#000"><br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =
=C2=A0 </span><span style=3D"color:#660">}</span><span style=3D"color:#000"=
> </span><span style=3D"color:#008">catch</span><span style=3D"color:#000">=
 </span><span style=3D"color:#660">(</span><span style=3D"color:#000">paren=
t_return_t r</span><span style=3D"color:#660">)</span><span style=3D"color:=
#000"> </span><span style=3D"color:#660">{</span><span style=3D"color:#000"=
> =C2=A0 =C2=A0 </span><span style=3D"color:#660">\</span><span style=3D"co=
lor:#000"><br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 </spa=
n><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">move</s=
pan><span style=3D"color:#660">(</span><span style=3D"color:#000">r</span><=
span style=3D"color:#660">.</span><span style=3D"color:#000">value</span><s=
pan style=3D"color:#660">);</span><span style=3D"color:#000"> =C2=A0 =C2=A0=
</span><span style=3D"color:#660">\</span><span style=3D"color:#000"><br>=
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 </span><span style=3D"color:#660"=
>}</span><span style=3D"color:#000"> </span><span style=3D"color:#008">catc=
h</span><span style=3D"color:#000"> </span><span style=3D"color:#660">(...)=
</span><span style=3D"color:#000"> </span><span style=3D"color:#660">{</spa=
n><span style=3D"color:#000"> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=
=A0 =C2=A0 =C2=A0 </span><span style=3D"color:#660">\</span><span style=3D"=
color:#000"><br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 </s=
pan><span style=3D"color:#008">throw</span><span style=3D"color:#660">;</sp=
an><span style=3D"color:#000"> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0</span><span style=3D"color:#660">=
\</span><span style=3D"color:#000"><br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =
=C2=A0 </span><span style=3D"color:#660">}</span><span style=3D"color:#000"=
> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=
=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 </span><span style=3D"color:#660">\<=
/span><span style=3D"color:#000"><br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=
=A0 </span><span style=3D"color:#660">*</span><span style=3D"color:#000">re=
t</span><span style=3D"color:#660">;</span><span style=3D"color:#000"> =C2=
=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =
=C2=A0 =C2=A0 =C2=A0 </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=
:#660">});</span><span style=3D"color:#000"><br><br></span><span style=3D"c=
olor:#008">template</span><span style=3D"color:#660">&lt;</span><span style=
=3D"color:#008">typename</span><span style=3D"color:#000"> R</span><span st=
yle=3D"color:#660">&gt;</span><span style=3D"color:#000"><br></span><span s=
tyle=3D"color:#008">double</span><span style=3D"color:#000"> prod</span><sp=
an style=3D"color:#660">(</span><span style=3D"color:#008">const</span><spa=
n style=3D"color:#000"> R</span><span style=3D"color:#660">&amp;</span><spa=
n style=3D"color:#000"> r</span><span style=3D"color:#660">)</span><span st=
yle=3D"color:#000"><br></span><span style=3D"color:#660">{</span><span styl=
e=3D"color:#000"><br>=C2=A0 =C2=A0 </span><span style=3D"color:#008">if</sp=
an><span style=3D"color:#000"> </span><span style=3D"color:#660">(</span><s=
pan style=3D"color:#000">r</span><span style=3D"color:#660">.</span><span s=
tyle=3D"color:#000">empty</span><span style=3D"color:#660">())</span><span =
style=3D"color:#000"> </span><span style=3D"color:#660">{</span><span style=
=3D"color:#000"><br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 </span><span style=3D"color=
:#008">return</span><span style=3D"color:#000"> NAN</span><span style=3D"co=
lor:#660">;</span><span style=3D"color:#000"><br>=C2=A0 =C2=A0 </span><span=
 style=3D"color:#660">}</span><span style=3D"color:#000"><br>=C2=A0 =C2=A0 =
</span><span style=3D"color:#008">double</span><span style=3D"color:#000"> =
p </span><span style=3D"color:#660">=3D</span><span style=3D"color:#000"> <=
/span><span style=3D"color:#066">1.0</span><span style=3D"color:#660">;</sp=
an><span style=3D"color:#000"><br>=C2=A0 =C2=A0 </span><span style=3D"color=
:#008">for</span><span style=3D"color:#000"> </span><span style=3D"color:#6=
60">(</span><span style=3D"color:#008">auto</span><span style=3D"color:#000=
"> ri </span><span style=3D"color:#660">:</span><span style=3D"color:#000">=
 r</span><span style=3D"color:#660">)</span><span style=3D"color:#000"> </s=
pan><span style=3D"color:#660">{</span><span style=3D"color:#000"><br>=C2=
=A0 =C2=A0 =C2=A0 =C2=A0 p </span><span style=3D"color:#660">=3D</span><spa=
n style=3D"color:#000"> invoke_with</span><span style=3D"color:#660">(</spa=
n><span style=3D"color:#000">take_return</span><span style=3D"color:#660">,=
</span><span style=3D"color:#000"> mul2</span><span style=3D"color:#660">,<=
/span><span style=3D"color:#000"> p</span><span style=3D"color:#660">,</spa=
n><span style=3D"color:#000"> ri</span><span style=3D"color:#660">);</span>=
<span style=3D"color:#000"><br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 </span><span sty=
le=3D"color:#800">//p =3D invoke_with_abs(double, mul2, p, ri);</span><span=
 style=3D"color:#000"><br>=C2=A0 =C2=A0 </span><span style=3D"color:#660">}=
</span><span style=3D"color:#000"><br>=C2=A0 =C2=A0 </span><span style=3D"c=
olor:#008">return</span><span style=3D"color:#000"> p</span><span style=3D"=
color:#660">;</span><span style=3D"color:#000"><br></span><span style=3D"co=
lor:#660">}</span><span style=3D"color:#000"><br><br></span><span style=3D"=
color:#008">int</span><span style=3D"color:#000"> main</span><span style=3D=
"color:#660">()</span><span style=3D"color:#000"><br></span><span style=3D"=
color:#660">{</span><span style=3D"color:#000"><br>=C2=A0 =C2=A0 std</span>=
<span style=3D"color:#660">::</span><span style=3D"color:#000">vector</span=
><span style=3D"color:#080">&lt;int&gt;</span><span style=3D"color:#000"> v=
</span><span style=3D"color:#660">{</span><span style=3D"color:#066">1</spa=
n><span style=3D"color:#660">,</span><span style=3D"color:#000"> </span><sp=
an style=3D"color:#066">2</span><span style=3D"color:#660">,</span><span st=
yle=3D"color:#000"> </span><span style=3D"color:#066">0</span><span style=
=3D"color:#660">,</span><span style=3D"color:#000"> </span><span style=3D"c=
olor:#066">4</span><span style=3D"color:#660">};</span><span style=3D"color=
:#000"><br>=C2=A0 =C2=A0 std</span><span style=3D"color:#660">::</span><spa=
n style=3D"color:#000">cout </span><span style=3D"color:#660">&lt;&lt;</spa=
n><span style=3D"color:#000"> prod</span><span style=3D"color:#660">(</span=
><span style=3D"color:#000">v</span><span style=3D"color:#660">);</span><sp=
an style=3D"color:#000"><br></span><span style=3D"color:#660">}</span></div=
></code></div><br><br>Thanks,<br>-lorro<br></div></blockquote></div>

<p></p>

-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; 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/7b2d8f2c-b50f-40a7-83e5-e3b7e57865d0%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/7b2d8f2c-b50f-40a7-83e5-e3b7e57865d0=
%40isocpp.org</a>.<br />

------=_Part_1425_942901630.1476552334648--

------=_Part_1424_1807162400.1476552334646--

.


Author: Tony V E <tvaneerd@gmail.com>
Date: Sat, 15 Oct 2016 13:37:56 -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);">To me, that syntax is understandable just by looking at it.</di=
v><div style=3D"width: 100%; font-size: initial; font-family: Calibri, 'Sla=
te Pro', sans-serif, sans-serif; color: rgb(31, 73, 125); text-align: initi=
al; background-color: rgb(255, 255, 255);"><br></div><div style=3D"width: 1=
00%; font-size: initial; font-family: Calibri, 'Slate Pro', sans-serif, san=
s-serif; color: rgb(31, 73, 125); text-align: initial; background-color: rg=
b(255, 255, 255);">All the other syntax up to now was just confusing. </div=
>                                                                          =
                                                           <div style=3D"wi=
dth: 100%; font-size: initial; font-family: Calibri, 'Slate Pro', sans-seri=
f, sans-serif; color: rgb(31, 73, 125); text-align: initial; background-col=
or: rgb(255, 255, 255);"><br style=3D"display:initial"></div>              =
                                                                           =
                                                                           =
                               <div style=3D"font-size: initial; font-famil=
y: Calibri, 'Slate Pro', sans-serif, sans-serif; color: rgb(31, 73, 125); t=
ext-align: initial; background-color: rgb(255, 255, 255);">Sent&nbsp;from&n=
bsp;my&nbsp;BlackBerry&nbsp;portable&nbsp;Babbage&nbsp;Device</div>        =
                                                                           =
                                                                           =
                    <table width=3D"100%" style=3D"background-color:white;b=
order-spacing:0px;"> <tbody><tr><td colspan=3D"2" style=3D"font-size: initi=
al; text-align: initial; background-color: rgb(255, 255, 255);">           =
                <div style=3D"border-style: solid none none; border-top-col=
or: rgb(181, 196, 223); border-top-width: 1pt; padding: 3pt 0in 0in; font-f=
amily: Tahoma, 'BB Alpha Sans', 'Slate Pro'; font-size: 10pt;">  <div><b>Fr=
om: </b>szollosi.lorand@gmail.com</div><div><b>Sent: </b>Saturday, October =
15, 2016 1:25 PM</div><div><b>To: </b>ISO C++ Standard - Future Proposals</=
div><div><b>Reply To: </b>std-proposals@isocpp.org</div><div><b>Cc: </b>szo=
llosi.lorand@gmail.com</div><div><b>Subject: </b>Re: [std-proposals] Re: ca=
pturing monads in lambda</div></div></td></tr></tbody></table><div style=3D=
"border-style: solid none none; border-top-color: rgb(186, 188, 209); borde=
r-top-width: 1pt; font-size: initial; text-align: initial; background-color=
: rgb(255, 255, 255);"></div><br><div id=3D"_originalContent" style=3D""><d=
iv dir=3D"ltr">Hi,<br><br>On another thread, `expr` was proposed for a lamb=
da-like construct that's forwarding as-is (i.e., no need for std::forward&l=
t;T&gt;(expr)). We might use that syntax for passing return, break and cont=
inue:<br><br><div class=3D"prettyprint" style=3D"background-color: rgb(250,=
 250, 250); border-color: rgb(187, 187, 187); border-style: solid; border-w=
idth: 1px; word-wrap: break-word;"><code class=3D"prettyprint"><div class=
=3D"subprettyprint"><span style=3D"color: #008;" class=3D"styled-by-prettif=
y">template</span><span style=3D"color: #660;" class=3D"styled-by-prettify"=
>&lt;</span><span style=3D"color: #008;" class=3D"styled-by-prettify">typen=
ame</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> T</spa=
n><span style=3D"color: #660;" class=3D"styled-by-prettify">&gt;</span><spa=
n style=3D"color: #000;" class=3D"styled-by-prettify"><br></span><span styl=
e=3D"color: #008;" class=3D"styled-by-prettify">void</span><span style=3D"c=
olor: #000;" class=3D"styled-by-prettify"> g</span><span style=3D"color: #6=
60;" class=3D"styled-by-prettify">(</span><span style=3D"color: #008;" clas=
s=3D"styled-by-prettify">int</span><span style=3D"color: #000;" class=3D"st=
yled-by-prettify"> i</span><span style=3D"color: #660;" class=3D"styled-by-=
prettify">,</span><span style=3D"color: #000;" class=3D"styled-by-prettify"=
> T brk</span><span style=3D"color: #660;" class=3D"styled-by-prettify">)</=
span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br></span><=
span style=3D"color: #660;" class=3D"styled-by-prettify">{</span><span styl=
e=3D"color: #000;" class=3D"styled-by-prettify"><br>&nbsp; &nbsp; std</span=
><span style=3D"color: #660;" class=3D"styled-by-prettify">:</span><span st=
yle=3D"color: #000;" class=3D"styled-by-prettify">cout </span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">&lt;&lt;</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"> i</span><span style=3D"colo=
r: #660;" class=3D"styled-by-prettify">;</span><span style=3D"color: #000;"=
 class=3D"styled-by-prettify"><br>&nbsp; &nbsp; </span><span style=3D"color=
: #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"styled-b=
y-prettify">i </span><span style=3D"color: #660;" class=3D"styled-by-pretti=
fy">%</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </sp=
an><span style=3D"color: #066;" class=3D"styled-by-prettify">2</span><span =
style=3D"color: #660;" class=3D"styled-by-prettify">)</span><span style=3D"=
color: #000;" class=3D"styled-by-prettify"> brk</span><span style=3D"color:=
 #660;" class=3D"styled-by-prettify">();</span><span style=3D"color: #000;"=
 class=3D"styled-by-prettify"><br></span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">}</span><span style=3D"color: #000;" class=3D"style=
d-by-prettify"><br><br></span><span style=3D"color: #008;" class=3D"styled-=
by-prettify">bool</span><span style=3D"color: #000;" class=3D"styled-by-pre=
ttify"> f</span><span style=3D"color: #660;" class=3D"styled-by-prettify">(=
</span><span style=3D"color: #000;" class=3D"styled-by-prettify">std</span>=
<span style=3D"color: #660;" class=3D"styled-by-prettify">::</span><span st=
yle=3D"color: #000;" class=3D"styled-by-prettify">vector</span><span style=
=3D"color: #080;" class=3D"styled-by-prettify">&lt;int&gt;</span><span styl=
e=3D"color: #000;" class=3D"styled-by-prettify"> v</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><span style=3D"color: #000;" class=3D"styl=
ed-by-prettify"><br>&nbsp; &nbsp; </span><span style=3D"color: #008;" class=
=3D"styled-by-prettify">for</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: #008;" class=3D"styled-by-prettify">a=
uto</span><span style=3D"color: #660;" class=3D"styled-by-prettify">&amp;&a=
mp;</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> i </sp=
an><span style=3D"color: #660;" class=3D"styled-by-prettify">:</span><span =
style=3D"color: #000;" class=3D"styled-by-prettify"> v</span><span style=3D=
"color: #660;" class=3D"styled-by-prettify">)</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"sty=
led-by-prettify"><br>&nbsp; &nbsp; &nbsp; &nbsp; g</span><span style=3D"col=
or: #660;" class=3D"styled-by-prettify">(</span><span style=3D"color: #000;=
" class=3D"styled-by-prettify">i</span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">,</span><span style=3D"color: #000;" class=3D"style=
d-by-prettify"> </span><span style=3D"color: #660;" class=3D"styled-by-pret=
tify">[]</span><span style=3D"color: #080;" class=3D"styled-by-prettify">`b=
reak;`</span><span style=3D"color: #660;" class=3D"styled-by-prettify">);</=
span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br>&nbsp; &=
nbsp; </span><span style=3D"color: #660;" class=3D"styled-by-prettify">}</s=
pan><span style=3D"color: #000;" class=3D"styled-by-prettify"><br></span><s=
pan style=3D"color: #660;" class=3D"styled-by-prettify">}</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"><br><br></span></div></code>=
</div><br><br>What do you think?<br><br>Thanks,<br>-lorro<br><br>2016. okt=
=C3=B3ber 9., vas=C3=A1rnap 18:58:57 UTC+2 id=C5=91pontban szollos...@gmail=
..com a k=C3=B6vetkez=C5=91t =C3=ADrta:<blockquote class=3D"gmail_quote" sty=
le=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left=
: 1ex;"><div dir=3D"ltr">Hi,<br><br>A toy model of the capture part is poss=
ible using gcc's statement expressions extension. This is not for implement=
ation reference, just to have a clearer view of the idea:<br><br><div style=
=3D"background-color:rgb(250,250,250);border-color:rgb(187,187,187);border-=
style:solid;border-width:1px;word-wrap:break-word"><code><div><span style=
=3D"color:#800">#include</span><span style=3D"color:#000"> </span><span sty=
le=3D"color:#080">&lt;vector&gt;</span><span style=3D"color:#000"><br></spa=
n><span style=3D"color:#800">#include</span><span style=3D"color:#000"> </s=
pan><span style=3D"color:#080">&lt;iostream&gt;</span><span style=3D"color:=
#000"><br></span><span style=3D"color:#800">#include</span><span style=3D"c=
olor:#000"> </span><span style=3D"color:#660">&lt;</span><span style=3D"col=
or:#000">experimental</span><span style=3D"color:#660">/</span><span style=
=3D"color:#000">optional</span><span style=3D"color:#660">&gt;</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">&lt;cmath&gt;<=
/span><span style=3D"color:#000"><br></span><span style=3D"color:#800">#inc=
lude</span><span style=3D"color:#000"> </span><span style=3D"color:#080">&l=
t;limits&gt;</span><span style=3D"color:#000"><br><br></span><span style=3D=
"color:#008">enum</span><span style=3D"color:#000"> </span><span style=3D"c=
olor:#008">class</span><span style=3D"color:#000"> return_mode </span><span=
 style=3D"color:#660">{</span><span style=3D"color:#000"> ret</span><span s=
tyle=3D"color:#660">,</span><span style=3D"color:#000"> brk</span><span sty=
le=3D"color:#660">,</span><span style=3D"color:#000"> cont</span><span styl=
e=3D"color:#660">,</span><span style=3D"color:#000"> back </span><span styl=
e=3D"color:#660">};</span><span style=3D"color:#000"><br></span><span style=
=3D"color:#008">enum</span><span style=3D"color:#000"> </span><span style=
=3D"color:#660">{</span><span style=3D"color:#000"> parent_break </span><sp=
an style=3D"color:#660">};</span><span style=3D"color:#000"><br></span><spa=
n style=3D"color:#008">enum</span><span style=3D"color:#000"> </span><span =
style=3D"color:#660">{</span><span style=3D"color:#000"> parent_continue </=
span><span style=3D"color:#660">};</span><span style=3D"color:#000"><br></s=
pan><span style=3D"color:#008">enum</span><span style=3D"color:#000"> </spa=
n><span style=3D"color:#660">{</span><span style=3D"color:#000"> to_parent =
</span><span style=3D"color:#660">};</span><span style=3D"color:#000"><br><=
br></span><span style=3D"color:#800">// TODO: specialize for void</span><sp=
an style=3D"color:#000"><br></span><span style=3D"color:#008">template</spa=
n><span style=3D"color:#660">&lt;</span><span style=3D"color:#008">typename=
</span><span style=3D"color:#000"> R</span><span style=3D"color:#660">,</sp=
an><span style=3D"color:#000"> </span><span style=3D"color:#008">typename</=
span><span style=3D"color:#000"> P</span><span style=3D"color:#660">&gt;</s=
pan><span style=3D"color:#000"><br></span><span style=3D"color:#008">struct=
</span><span style=3D"color:#000"> extended_return<br></span><span style=3D=
"color:#660">{</span><span style=3D"color:#000"><br>&nbsp; &nbsp; </span><s=
pan style=3D"color:#008">const</span><span style=3D"color:#000"> return_mod=
e &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;whic=
h_</span><span style=3D"color:#660">;</span><span style=3D"color:#000"><br>=
&nbsp; &nbsp; </span><span style=3D"color:#008">const</span><span style=3D"=
color:#000"> std</span><span style=3D"color:#660">::</span><span style=3D"c=
olor:#000">experimental</span><span style=3D"color:#660">::</span><span sty=
le=3D"color:#000">optional</span><span style=3D"color:#660">&lt;</span><spa=
n style=3D"color:#000">P</span><span style=3D"color:#660">&gt;</span><span =
style=3D"color:#000"> parent_retval_</span><span style=3D"color:#660">;</sp=
an><span style=3D"color:#000"><br>&nbsp; &nbsp; </span><span style=3D"color=
:#008">const</span><span style=3D"color:#000"> std</span><span style=3D"col=
or:#660">::</span><span style=3D"color:#000">experimental</span><span style=
=3D"color:#660">::</span><span style=3D"color:#000">optional</span><span st=
yle=3D"color:#660">&lt;</span><span style=3D"color:#000">R</span><span styl=
e=3D"color:#660">&gt;</span><span style=3D"color:#000"> retval_</span><span=
 style=3D"color:#660">;</span><span style=3D"color:#000"><br>&nbsp; &nbsp; =
extended_return</span><span style=3D"color:#660">(</span><span style=3D"col=
or:#000">R retval</span><span style=3D"color:#660">)</span><span style=3D"c=
olor:#000"><br>&nbsp; &nbsp; &nbsp; &nbsp; </span><span style=3D"color:#660=
">:</span><span style=3D"color:#000"> which_ </span><span style=3D"color:#6=
60">(</span><span style=3D"color:#000">return_mode</span><span style=3D"col=
or:#660">::</span><span style=3D"color:#000">back</span><span style=3D"colo=
r:#660">)</span><span style=3D"color:#000"><br>&nbsp; &nbsp; &nbsp; &nbsp; =
</span><span style=3D"color:#660">,</span><span style=3D"color:#000"> retva=
l_</span><span style=3D"color:#660">(</span><span style=3D"color:#000">std<=
/span><span style=3D"color:#660">::</span><span style=3D"color:#000">move</=
span><span style=3D"color:#660">(</span><span style=3D"color:#000">retval</=
span><span style=3D"color:#660">))</span><span style=3D"color:#000"> </span=
><span style=3D"color:#660">{}</span><span style=3D"color:#000"><br>&nbsp; =
&nbsp; extended_return</span><span style=3D"color:#660">(</span><span style=
=3D"color:#008">decltype</span><span style=3D"color:#660">(</span><span sty=
le=3D"color:#000">to_<wbr>parent</span><span style=3D"color:#660">),</span>=
<span style=3D"color:#000"> P retval</span><span style=3D"color:#660">)</sp=
an><span style=3D"color:#000"><br>&nbsp; &nbsp; &nbsp; &nbsp; </span><span =
style=3D"color:#660">:</span><span style=3D"color:#000"> which_ </span><spa=
n style=3D"color:#660">(</span><span style=3D"color:#000">return_mode</span=
><span style=3D"color:#660">::</span><span style=3D"color:#000">ret</span><=
span style=3D"color:#660">)</span><span style=3D"color:#000"><br>&nbsp; &nb=
sp; &nbsp; &nbsp; </span><span style=3D"color:#660">,</span><span style=3D"=
color:#000"> parent_retval_</span><span style=3D"color:#660">(</span><span =
style=3D"color:#000">std</span><span style=3D"color:#660">::</span><span st=
yle=3D"color:#000">move</span><span style=3D"color:#660">(</span><span styl=
e=3D"color:#000">retva<wbr>l</span><span style=3D"color:#660">))</span><spa=
n style=3D"color:#000"> </span><span style=3D"color:#660">{}</span><span st=
yle=3D"color:#000"><br>&nbsp; &nbsp; extended_return</span><span style=3D"c=
olor:#660">(</span><span style=3D"color:#008">decltype</span><span style=3D=
"color:#660">(</span><span style=3D"color:#000">paren<wbr>t_break</span><sp=
an style=3D"color:#660">)</span><span style=3D"color:#000"> tgt</span><span=
 style=3D"color:#660">)</span><span style=3D"color:#000"><br>&nbsp; &nbsp; =
&nbsp; &nbsp; </span><span style=3D"color:#660">:</span><span style=3D"colo=
r:#000"> which_ </span><span style=3D"color:#660">(</span><span style=3D"co=
lor:#000">return_mode</span><span style=3D"color:#660">::</span><span style=
=3D"color:#000">brk</span><span style=3D"color:#660">)</span><span style=3D=
"color:#000"> </span><span style=3D"color:#660">{}</span><span style=3D"col=
or:#000"><br>&nbsp; &nbsp; extended_return</span><span style=3D"color:#660"=
>(</span><span style=3D"color:#008">decltype</span><span style=3D"color:#66=
0">(</span><span style=3D"color:#000">paren<wbr>t_continue</span><span styl=
e=3D"color:#660">)</span><span style=3D"color:#000"> tgt</span><span style=
=3D"color:#660">)</span><span style=3D"color:#000"><br>&nbsp; &nbsp; &nbsp;=
 &nbsp; </span><span style=3D"color:#660">:</span><span style=3D"color:#000=
"> which_ </span><span style=3D"color:#660">(</span><span style=3D"color:#0=
00">return_mode</span><span style=3D"color:#660">::</span><span style=3D"co=
lor:#000">cont</span><span style=3D"color:#660">)</span><span style=3D"colo=
r:#000"> </span><span style=3D"color:#660">{}</span><span style=3D"color:#0=
00"><br>&nbsp; &nbsp; </span><span style=3D"color:#008">operator</span><spa=
n style=3D"color:#000"> return_mode</span><span style=3D"color:#660">()</sp=
an><span style=3D"color:#000"> </span><span style=3D"color:#008">const</spa=
n><span style=3D"color:#000"> </span><span style=3D"color:#660">{</span><sp=
an style=3D"color:#000"> </span><span style=3D"color:#008">return</span><sp=
an style=3D"color:#000"> which_</span><span style=3D"color:#660">;</span><s=
pan style=3D"color:#000"> </span><span style=3D"color:#660">}</span><span s=
tyle=3D"color:#000"><br></span><span style=3D"color:#660">};</span><span st=
yle=3D"color:#000"><br><br>extended_return</span><span style=3D"color:#660"=
>&lt;</span><span style=3D"color:#008">double</span><span style=3D"color:#6=
60">,</span><span style=3D"color:#000"> </span><span style=3D"color:#008">d=
ouble</span><span style=3D"color:#660">&gt;</span><span style=3D"color:#000=
"> mul2</span><span style=3D"color:#660">(</span><span style=3D"color:#008"=
>double</span><span style=3D"color:#000"> lhs</span><span style=3D"color:#6=
60">,</span><span style=3D"color:#000"> </span><span style=3D"color:#008">d=
ouble</span><span style=3D"color:#000"> rhs</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>&nbsp; &nbsp; </span><span style=3D"=
color:#008">if</span><span style=3D"color:#000"> </span><span style=3D"colo=
r:#660">(</span><span style=3D"color:#000">rhs </span><span style=3D"color:=
#660">=3D=3D</span><span style=3D"color:#000"> </span><span style=3D"color:=
#066">0</span><span style=3D"color:#660">)</span><span style=3D"color:#000"=
> </span><span style=3D"color:#660">{</span><span style=3D"color:#000"><br>=
&nbsp; &nbsp; &nbsp; &nbsp; </span><span style=3D"color:#008">return</span>=
<span style=3D"color:#000"> </span><span style=3D"color:#660">{</span><span=
 style=3D"color:#000"> to_parent</span><span style=3D"color:#660">,</span><=
span style=3D"color:#000"> </span><span style=3D"color:#066">0.0</span><spa=
n style=3D"color:#000"> </span><span style=3D"color:#660">};</span><span st=
yle=3D"color:#000"><br>&nbsp; &nbsp; </span><span style=3D"color:#660">}</s=
pan><span style=3D"color:#000"><br>&nbsp; &nbsp; </span><span style=3D"colo=
r:#008">return</span><span style=3D"color:#000"> lhs </span><span style=3D"=
color:#660">*</span><span style=3D"color:#000"> rhs</span><span style=3D"co=
lor:#660">;</span><span style=3D"color:#000"><br></span><span style=3D"colo=
r:#660">}</span><span style=3D"color:#000"><br><br></span><span style=3D"co=
lor:#008">double</span><span style=3D"color:#000"> mul2</span><span style=
=3D"color:#660">(</span><span style=3D"color:#008">double</span><span style=
=3D"color:#000"> lhs</span><span style=3D"color:#660">,</span><span style=
=3D"color:#000"> </span><span style=3D"color:#008">double</span><span style=
=3D"color:#000"> rhs</span><span style=3D"color:#660">,</span><span style=
=3D"color:#000"> </span><span style=3D"color:#008">void</span><span style=
=3D"color:#660">(*</span><span style=3D"color:#000">parent_return</span><sp=
an style=3D"color:#660">)(</span><span style=3D"color:#008">double</span><s=
pan style=3D"color:#660">))</span><span style=3D"color:#000"><br></span><sp=
an style=3D"color:#660">{</span><span style=3D"color:#000"><br>&nbsp; &nbsp=
; </span><span style=3D"color:#008">if</span><span style=3D"color:#000"> </=
span><span style=3D"color:#660">(</span><span style=3D"color:#000">rhs </sp=
an><span style=3D"color:#660">=3D=3D</span><span style=3D"color:#000"> </sp=
an><span style=3D"color:#066">0</span><span style=3D"color:#660">)</span><s=
pan style=3D"color:#000"> </span><span style=3D"color:#660">{</span><span s=
tyle=3D"color:#000"><br>&nbsp; &nbsp; &nbsp; &nbsp; parent_return</span><sp=
an style=3D"color:#660">(</span><span style=3D"color:#066">0.0</span><span =
style=3D"color:#660">);</span><span style=3D"color:#000"><br>&nbsp; &nbsp; =
</span><span style=3D"color:#660">}</span><span style=3D"color:#000"><br>&n=
bsp; &nbsp; </span><span style=3D"color:#008">return</span><span style=3D"c=
olor:#000"> lhs </span><span style=3D"color:#660">*</span><span style=3D"co=
lor:#000"> rhs</span><span style=3D"color:#660">;</span><span style=3D"colo=
r:#000"><br></span><span style=3D"color:#660">}</span><span style=3D"color:=
#000"><br><br></span><span style=3D"color:#800">#define</span><span style=
=3D"color:#000"> take_return &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbs=
p; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </span><span style=3D"color:#6=
60">\</span><span style=3D"color:#000"><br>&nbsp; &nbsp; &nbsp; &nbsp; &nbs=
p; &nbsp; </span><span style=3D"color:#008">else</span><span style=3D"color=
:#000"> </span><span style=3D"color:#008">if</span><span style=3D"color:#66=
0">(</span><span style=3D"color:#000">ret </span><span style=3D"color:#660"=
>=3D=3D</span><span style=3D"color:#000"> return_mode</span><span style=3D"=
color:#660">::</span><span style=3D"color:#000">ret</span><span style=3D"co=
lor:#660">)</span><span style=3D"color:#000"> &nbsp;</span><span style=3D"c=
olor:#660">\</span><span style=3D"color:#000"><br>&nbsp; &nbsp; &nbsp; &nbs=
p; &nbsp; &nbsp; &nbsp; &nbsp; </span><span style=3D"color:#008">return</sp=
an><span style=3D"color:#000"> </span><span style=3D"color:#660">*</span><s=
pan style=3D"color:#000">ret</span><span style=3D"color:#660">.</span><span=
 style=3D"color:#000">parent_retval_</span><span style=3D"color:#660">;</sp=
an><span style=3D"color:#000"><br><br></span><span style=3D"color:#800">#de=
fine</span><span style=3D"color:#000"> take_break &nbsp; &nbsp; &nbsp; &nbs=
p; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;</s=
pan><span style=3D"color:#660">\</span><span style=3D"color:#000"><br>&nbsp=
; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </span><span style=3D"color:#008">else=
</span><span style=3D"color:#000"> </span><span style=3D"color:#008">if</sp=
an><span style=3D"color:#660">(</span><span style=3D"color:#000">ret </span=
><span style=3D"color:#660">=3D=3D</span><span style=3D"color:#000"> return=
_mode</span><span style=3D"color:#660">::</span><span style=3D"color:#000">=
brk</span><span style=3D"color:#660">)</span><span style=3D"color:#000"> &n=
bsp;</span><span style=3D"color:#660">\</span><span style=3D"color:#000"><b=
r>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </span><span styl=
e=3D"color:#008">break</span><span style=3D"color:#660">;</span><span style=
=3D"color:#000"><br><br></span><span style=3D"color:#800">#define</span><sp=
an style=3D"color:#000"> take_continue &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &=
nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </span><span style=3D"color=
:#660">\</span><span style=3D"color:#000"><br>&nbsp; &nbsp; &nbsp; &nbsp; &=
nbsp; &nbsp; </span><span style=3D"color:#008">else</span><span style=3D"co=
lor:#000"> </span><span style=3D"color:#008">if</span><span style=3D"color:=
#660">(</span><span style=3D"color:#000">ret </span><span style=3D"color:#6=
60">=3D=3D</span><span style=3D"color:#000"> return_mode</span><span style=
=3D"color:#660">::</span><span style=3D"color:#000">cont</span><span style=
=3D"color:#660">)</span><span style=3D"color:#000"> </span><span style=3D"c=
olor:#660">\</span><span style=3D"color:#000"><br>&nbsp; &nbsp; &nbsp; &nbs=
p; &nbsp; &nbsp; &nbsp; &nbsp; </span><span style=3D"color:#008">continue</=
span><span style=3D"color:#660">;</span><span style=3D"color:#000"><br><br>=
</span><span style=3D"color:#800">#define</span><span style=3D"color:#000">=
 invoke_with</span><span style=3D"color:#660">(</span><span style=3D"color:=
#000">TAKEN</span><span style=3D"color:#660">,</span><span style=3D"color:#=
000"> F</span><span style=3D"color:#660">,</span><span style=3D"color:#000"=
> </span><span style=3D"color:#660">...)</span><span style=3D"color:#000"> =
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;</span><span style=3D"color:#660">=
\</span><span style=3D"color:#000"><br>&nbsp; &nbsp; &nbsp; &nbsp; </span><=
span style=3D"color:#660">({</span><span style=3D"color:#000"> &nbsp; &nbsp=
; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nb=
sp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;</span><span style=3D"color:#660">\</=
span><span style=3D"color:#000"><br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbs=
p; </span><span style=3D"color:#008">auto</span><span style=3D"color:#000">=
 ret </span><span style=3D"color:#660">=3D</span><span style=3D"color:#000"=
> F</span><span style=3D"color:#660">(</span><span style=3D"color:#000">__V=
A_ARGS__</span><span style=3D"color:#660">);</span><span style=3D"color:#00=
0"> &nbsp; &nbsp; &nbsp; &nbsp;</span><span style=3D"color:#660">\</span><s=
pan style=3D"color:#000"><br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </sp=
an><span style=3D"color:#008">if</span><span style=3D"color:#000"> </span><=
span style=3D"color:#660">(</span><span style=3D"color:#008">false</span><s=
pan style=3D"color:#660">);</span><span style=3D"color:#000"> &nbsp; &nbsp;=
 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </span><spa=
n style=3D"color:#660">\</span><span style=3D"color:#000"><br>&nbsp; &nbsp;=
 &nbsp; &nbsp; &nbsp; &nbsp; TAKEN &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp=
; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </span><span styl=
e=3D"color:#660">\</span><span style=3D"color:#000"><br>&nbsp; &nbsp; &nbsp=
; &nbsp; &nbsp; &nbsp; </span><span style=3D"color:#660">*</span><span styl=
e=3D"color:#000">ret</span><span style=3D"color:#660">.</span><span style=
=3D"color:#000">retval_</span><span style=3D"color:#660">;</span><span styl=
e=3D"color:#000"> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &=
nbsp; &nbsp; </span><span style=3D"color:#660">\</span><span style=3D"color=
:#000"><br>&nbsp; &nbsp; &nbsp; &nbsp; </span><span style=3D"color:#660">})=
;</span><span style=3D"color:#000"><br><br><br></span><span style=3D"color:=
#800">#define</span><span style=3D"color:#000"> invoke_with_abs</span><span=
 style=3D"color:#660">(</span><span style=3D"color:#000">R</span><span styl=
e=3D"color:#660">,</span><span style=3D"color:#000"> F</span><span style=3D=
"color:#660">,</span><span style=3D"color:#000"> </span><span style=3D"colo=
r:#660">...)</span><span style=3D"color:#000"> &nbsp; &nbsp; &nbsp; &nbsp; =
&nbsp; &nbsp;</span><span style=3D"color:#660">\</span><span style=3D"color=
:#000"><br>&nbsp; &nbsp; &nbsp; &nbsp; </span><span style=3D"color:#660">({=
</span><span style=3D"color:#000"> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp=
; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nb=
sp; &nbsp;</span><span style=3D"color:#660">\</span><span style=3D"color:#0=
00"><br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </span><span style=3D"col=
or:#008">struct</span><span style=3D"color:#000"> parent_return_t &nbsp; &n=
bsp; &nbsp; &nbsp; &nbsp; &nbsp;</span><span style=3D"color:#660">\</span><=
span style=3D"color:#000"><br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </s=
pan><span style=3D"color:#660">{</span><span style=3D"color:#000"> &nbsp; &=
nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;=
 &nbsp; &nbsp; &nbsp; &nbsp; </span><span style=3D"color:#660">\</span><spa=
n style=3D"color:#000"><br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;=
 &nbsp; R value</span><span style=3D"color:#660">;</span><span style=3D"col=
or:#000"> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &n=
bsp; &nbsp;</span><span style=3D"color:#660">\</span><span style=3D"color:#=
000"><br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </span><span style=3D"co=
lor:#660">};</span><span style=3D"color:#000"> &nbsp; &nbsp; &nbsp; &nbsp; =
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp=
; &nbsp;</span><span style=3D"color:#660">\</span><span style=3D"color:#000=
"><br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </span><span style=3D"color=
:#008">auto</span><span style=3D"color:#000"> parent_return </span><span st=
yle=3D"color:#660">=3D</span><span style=3D"color:#000"> </span><span style=
=3D"color:#660">+[](</span><span style=3D"color:#000">R v</span><span style=
=3D"color:#660">)</span><span style=3D"color:#000"> </span><span style=3D"c=
olor:#660">{</span><span style=3D"color:#000"> &nbsp; </span><span style=3D=
"color:#660">\</span><span style=3D"color:#000"><br>&nbsp; &nbsp; &nbsp; &n=
bsp; &nbsp; &nbsp; &nbsp; &nbsp; </span><span style=3D"color:#008">throw</s=
pan><span style=3D"color:#000"> parent_return_t</span><span style=3D"color:=
#660">{</span><span style=3D"color:#000">v</span><span style=3D"color:#660"=
>};</span><span style=3D"color:#000"> &nbsp; &nbsp; </span><span style=3D"c=
olor:#660">\</span><span style=3D"color:#000"><br>&nbsp; &nbsp; &nbsp; &nbs=
p; &nbsp; &nbsp; </span><span style=3D"color:#660">};</span><span style=3D"=
color:#000"> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;=
 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;</span><span style=3D"colo=
r:#660">\</span><span style=3D"color:#000"><br>&nbsp; &nbsp; &nbsp; &nbsp; =
&nbsp; &nbsp; std</span><span style=3D"color:#660">::</span><span style=3D"=
color:#000">experimental</span><span style=3D"color:#660">::</span><span st=
yle=3D"color:#000">optional</span><span style=3D"color:#660">&lt;</span><sp=
an style=3D"color:#000"> &nbsp; &nbsp; &nbsp;</span><span style=3D"color:#6=
60">\</span><span style=3D"color:#000"><br>&nbsp; &nbsp; &nbsp; &nbsp; &nbs=
p; &nbsp; &nbsp; &nbsp; </span><span style=3D"color:#008">decltype</span><s=
pan style=3D"color:#660">(</span><span style=3D"color:#000">F</span><span s=
tyle=3D"color:#660">(</span><span style=3D"color:#000">__VA_ARGS__</span><s=
pan style=3D"color:#660">,</span><span style=3D"color:#000"> &nbsp; &nbsp; =
&nbsp; </span><span style=3D"color:#660">\</span><span style=3D"color:#000"=
><br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; =
&nbsp; &nbsp; &nbsp; &nbsp;parent_return</span><span style=3D"color:#660">)=
)</span><span style=3D"color:#000"> &nbsp; &nbsp;</span><span style=3D"colo=
r:#660">\</span><span style=3D"color:#000"><br>&nbsp; &nbsp; &nbsp; &nbsp; =
&nbsp; &nbsp; </span><span style=3D"color:#660">&gt;</span><span style=3D"c=
olor:#000"> ret</span><span style=3D"color:#660">;</span><span style=3D"col=
or:#000"> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &n=
bsp; &nbsp; &nbsp; &nbsp; &nbsp;</span><span style=3D"color:#660">\</span><=
span style=3D"color:#000"><br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </s=
pan><span style=3D"color:#008">try</span><span style=3D"color:#000"> </span=
><span style=3D"color:#660">{</span><span style=3D"color:#000"> &nbsp; &nbs=
p; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &n=
bsp; &nbsp; </span><span style=3D"color:#660">\</span><span style=3D"color:=
#000"><br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ret </spa=
n><span style=3D"color:#660">=3D</span><span style=3D"color:#000"> F</span>=
<span style=3D"color:#660">(</span><span style=3D"color:#000">__VA_ARGS__</=
span><span style=3D"color:#660">,</span><span style=3D"color:#000"> &nbsp; =
&nbsp; &nbsp; &nbsp; &nbsp;</span><span style=3D"color:#660">\</span><span =
style=3D"color:#000"><br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &=
nbsp; &nbsp; &nbsp; &nbsp; &nbsp; parent_return</span><span style=3D"color:=
#660">);</span><span style=3D"color:#000"> &nbsp; &nbsp; &nbsp; </span><spa=
n style=3D"color:#660">\</span><span style=3D"color:#000"><br>&nbsp; &nbsp;=
 &nbsp; &nbsp; &nbsp; &nbsp; </span><span style=3D"color:#660">}</span><spa=
n style=3D"color:#000"> </span><span style=3D"color:#008">catch</span><span=
 style=3D"color:#000"> </span><span style=3D"color:#660">(</span><span styl=
e=3D"color:#000">parent_return_t r</span><span style=3D"color:#660">)</span=
><span style=3D"color:#000"> </span><span style=3D"color:#660">{</span><spa=
n style=3D"color:#000"> &nbsp; &nbsp; </span><span style=3D"color:#660">\</=
span><span style=3D"color:#000"><br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbs=
p; &nbsp; &nbsp; </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">move</span><span style=3D"color:#660">(</span><span style=
=3D"color:#000">r</span><span style=3D"color:#660">.</span><span style=3D"c=
olor:#000">value</span><span style=3D"color:#660">);</span><span style=3D"c=
olor:#000"> &nbsp; &nbsp;</span><span style=3D"color:#660">\</span><span st=
yle=3D"color:#000"><br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </span><sp=
an style=3D"color:#660">}</span><span style=3D"color:#000"> </span><span st=
yle=3D"color:#008">catch</span><span style=3D"color:#000"> </span><span sty=
le=3D"color:#660">(...)</span><span style=3D"color:#000"> </span><span styl=
e=3D"color:#660">{</span><span style=3D"color:#000"> &nbsp; &nbsp; &nbsp; &=
nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </span><span style=3D"color:#660">=
\</span><span style=3D"color:#000"><br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &=
nbsp; &nbsp; &nbsp; </span><span style=3D"color:#008">throw</span><span sty=
le=3D"color:#660">;</span><span style=3D"color:#000"> &nbsp; &nbsp; &nbsp; =
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;</span><span =
style=3D"color:#660">\</span><span style=3D"color:#000"><br>&nbsp; &nbsp; &=
nbsp; &nbsp; &nbsp; &nbsp; </span><span style=3D"color:#660">}</span><span =
style=3D"color:#000"> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbs=
p; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </span><span sty=
le=3D"color:#660">\</span><span style=3D"color:#000"><br>&nbsp; &nbsp; &nbs=
p; &nbsp; &nbsp; &nbsp; </span><span style=3D"color:#660">*</span><span sty=
le=3D"color:#000">ret</span><span style=3D"color:#660">;</span><span style=
=3D"color:#000"> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &n=
bsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </span><span style=3D"color:#660">\=
</span><span style=3D"color:#000"><br>&nbsp; &nbsp; &nbsp; &nbsp; </span><s=
pan style=3D"color:#660">});</span><span style=3D"color:#000"><br><br></spa=
n><span style=3D"color:#008">template</span><span style=3D"color:#660">&lt;=
</span><span style=3D"color:#008">typename</span><span style=3D"color:#000"=
> R</span><span style=3D"color:#660">&gt;</span><span style=3D"color:#000">=
<br></span><span style=3D"color:#008">double</span><span style=3D"color:#00=
0"> prod</span><span style=3D"color:#660">(</span><span style=3D"color:#008=
">const</span><span style=3D"color:#000"> R</span><span style=3D"color:#660=
">&amp;</span><span style=3D"color:#000"> r</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>&nbsp; &nbsp; </span><span style=3D"=
color:#008">if</span><span style=3D"color:#000"> </span><span style=3D"colo=
r:#660">(</span><span style=3D"color:#000">r</span><span style=3D"color:#66=
0">.</span><span style=3D"color:#000">empty</span><span style=3D"color:#660=
">())</span><span style=3D"color:#000"> </span><span style=3D"color:#660">{=
</span><span style=3D"color:#000"><br>&nbsp; &nbsp; &nbsp; &nbsp; </span><s=
pan style=3D"color:#008">return</span><span style=3D"color:#000"> NAN</span=
><span style=3D"color:#660">;</span><span style=3D"color:#000"><br>&nbsp; &=
nbsp; </span><span style=3D"color:#660">}</span><span style=3D"color:#000">=
<br>&nbsp; &nbsp; </span><span style=3D"color:#008">double</span><span styl=
e=3D"color:#000"> p </span><span style=3D"color:#660">=3D</span><span style=
=3D"color:#000"> </span><span style=3D"color:#066">1.0</span><span style=3D=
"color:#660">;</span><span style=3D"color:#000"><br>&nbsp; &nbsp; </span><s=
pan style=3D"color:#008">for</span><span style=3D"color:#000"> </span><span=
 style=3D"color:#660">(</span><span style=3D"color:#008">auto</span><span s=
tyle=3D"color:#000"> ri </span><span style=3D"color:#660">:</span><span sty=
le=3D"color:#000"> r</span><span style=3D"color:#660">)</span><span style=
=3D"color:#000"> </span><span style=3D"color:#660">{</span><span style=3D"c=
olor:#000"><br>&nbsp; &nbsp; &nbsp; &nbsp; p </span><span style=3D"color:#6=
60">=3D</span><span style=3D"color:#000"> invoke_with</span><span style=3D"=
color:#660">(</span><span style=3D"color:#000">take_return</span><span styl=
e=3D"color:#660">,</span><span style=3D"color:#000"> mul2</span><span style=
=3D"color:#660">,</span><span style=3D"color:#000"> p</span><span style=3D"=
color:#660">,</span><span style=3D"color:#000"> ri</span><span style=3D"col=
or:#660">);</span><span style=3D"color:#000"><br>&nbsp; &nbsp; &nbsp; &nbsp=
; </span><span style=3D"color:#800">//p =3D invoke_with_abs(double, mul2, p=
, ri);</span><span style=3D"color:#000"><br>&nbsp; &nbsp; </span><span styl=
e=3D"color:#660">}</span><span style=3D"color:#000"><br>&nbsp; &nbsp; </spa=
n><span style=3D"color:#008">return</span><span style=3D"color:#000"> p</sp=
an><span style=3D"color:#660">;</span><span style=3D"color:#000"><br></span=
><span style=3D"color:#660">}</span><span style=3D"color:#000"><br><br></sp=
an><span style=3D"color:#008">int</span><span style=3D"color:#000"> main</s=
pan><span style=3D"color:#660">()</span><span style=3D"color:#000"><br></sp=
an><span style=3D"color:#660">{</span><span style=3D"color:#000"><br>&nbsp;=
 &nbsp; std</span><span style=3D"color:#660">::</span><span style=3D"color:=
#000">vector</span><span style=3D"color:#080">&lt;int&gt;</span><span style=
=3D"color:#000"> v</span><span style=3D"color:#660">{</span><span style=3D"=
color:#066">1</span><span style=3D"color:#660">,</span><span style=3D"color=
:#000"> </span><span style=3D"color:#066">2</span><span style=3D"color:#660=
">,</span><span style=3D"color:#000"> </span><span style=3D"color:#066">0</=
span><span style=3D"color:#660">,</span><span style=3D"color:#000"> </span>=
<span style=3D"color:#066">4</span><span style=3D"color:#660">};</span><spa=
n style=3D"color:#000"><br>&nbsp; &nbsp; std</span><span style=3D"color:#66=
0">::</span><span style=3D"color:#000">cout </span><span style=3D"color:#66=
0">&lt;&lt;</span><span style=3D"color:#000"> prod</span><span style=3D"col=
or:#660">(</span><span style=3D"color:#000">v</span><span style=3D"color:#6=
60">);</span><span style=3D"color:#000"><br></span><span style=3D"color:#66=
0">}</span></div></code></div><br><br>Thanks,<br>-lorro<br></div></blockquo=
te></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/7b2d8f2c-b50f-40a7-83e5-e3b7e57865d0%=
40isocpp.org?utm_medium=3Demail&amp;utm_source=3Dfooter">https://groups.goo=
gle.com/a/isocpp.org/d/msgid/std-proposals/7b2d8f2c-b50f-40a7-83e5-e3b7e578=
65d0%40isocpp.org</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&quot; 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/20161015173756.4907089.52920.18543%40=
gmail.com?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.com=
/a/isocpp.org/d/msgid/std-proposals/20161015173756.4907089.52920.18543%40gm=
ail.com</a>.<br />

.


Author: Bjorn Reese <breese@mail1.stofanet.dk>
Date: Sun, 16 Oct 2016 14:24:39 +0200
Raw View
On 10/15/2016 07:25 PM, szollosi.lorand@gmail.com wrote:

>         g(i,[]`break;`);

or g(i, inline [] { break; });

--
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/0292a181-741c-ba12-c9ef-ecab8cc6b6ab%40mail1.stofanet.dk.

.


Author: szollosi.lorand@gmail.com
Date: Tue, 18 Oct 2016 00:28:03 -0700 (PDT)
Raw View
------=_Part_609_918318719.1476775683372
Content-Type: multipart/alternative;
 boundary="----=_Part_610_2051308445.1476775683372"

------=_Part_610_2051308445.1476775683372
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

Hi,

Hmm, I like it for break, but we also wanted `return;` (for return to=20
caller's caller). Wouldn't that be confusing?

Thanks,
-lorro

2016. okt=C3=B3ber 16., vas=C3=A1rnap 14:18:09 UTC+2 id=C5=91pontban Bjorn =
Reese a=20
k=C3=B6vetkez=C5=91t =C3=ADrta:
>
> On 10/15/2016 07:25 PM, szollos...@gmail.com <javascript:> wrote:=20
>
> >         g(i,[]`break;`);=20
>
> or g(i, inline [] { break; });=20
>
>

--=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp=
..org/d/msgid/std-proposals/1e895e5f-3b23-443a-b05f-14086d625dde%40isocpp.or=
g.

------=_Part_610_2051308445.1476775683372
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">Hi,<br><br>Hmm, I like it for break, but we also wanted `r=
eturn;` (for return to caller&#39;s caller). Wouldn&#39;t that be confusing=
?<br><br>Thanks,<br>-lorro<br><br>2016. okt=C3=B3ber 16., vas=C3=A1rnap 14:=
18:09 UTC+2 id=C5=91pontban Bjorn Reese a k=C3=B6vetkez=C5=91t =C3=ADrta:<b=
lockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;borde=
r-left: 1px #ccc solid;padding-left: 1ex;">On 10/15/2016 07:25 PM, <a href=
=3D"javascript:" target=3D"_blank" gdf-obfuscated-mailto=3D"gC0yj5WWAgAJ" r=
el=3D"nofollow" onmousedown=3D"this.href=3D&#39;javascript:&#39;;return tru=
e;" onclick=3D"this.href=3D&#39;javascript:&#39;;return true;">szollos...@g=
mail.com</a> wrote:
<br>
<br>&gt; =C2=A0 =C2=A0 =C2=A0 =C2=A0 g(i,[]`break;`);
<br>
<br>or g(i, inline [] { break; });
<br>
<br></blockquote></div>

<p></p>

-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; 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/1e895e5f-3b23-443a-b05f-14086d625dde%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/1e895e5f-3b23-443a-b05f-14086d625dde=
%40isocpp.org</a>.<br />

------=_Part_610_2051308445.1476775683372--

------=_Part_609_918318719.1476775683372--

.


Author: szollosi.lorand@gmail.com
Date: Mon, 30 Jan 2017 15:10:51 -0800 (PST)
Raw View
------=_Part_1705_247117467.1485817851910
Content-Type: multipart/alternative;
 boundary="----=_Part_1706_74598835.1485817851911"

------=_Part_1706_74598835.1485817851911
Content-Type: text/plain; charset=UTF-8

Hi,

[For those just joining in: it's actually 'capturing the return
continuation for for-else / for-break']
I've made a few prototypes based on different approaches (incl. exceptions,
continuations, wrapper macros around `for', variant return types,
continuation-as-a-class, etc.). It looks to me now that these *are*
exceptions, but inline ones. How would you like something like:

#include <vector>
#include <iostream>

extern bool g();

struct Break {};

int sum(const std::vector<int>& v)
{
    int ret = 0;
    for (auto&& elem : v) {
        if (g(elem)) throw inline Break();
        ret += elem;
    }
}

int main()
{
    std::vector<int> v{ 1, 2, 3 };
    try {
        std::cout << sum(v);
    } catch inline (const Break&) {
        std::cout << "break";
    }
}

Where `throw inline' means that only inlineable calls appear on the return
path from the throw point to `catch inline'. Thus no non-final virtual
calls, no non-constexpr fnptr / mem fnptr calls, definitions in the same
compilation unit, etc. This means that the compiler 'sees' the return path
and can compile as efficient code as an inline call would be for the
various returns (possibly *more* efficient than a variant return type;
surely more efficient than regular exceptions / continuations; also, it
expresses intent more clearly). It also means that a non-constexpr function
pointer cannot be formed to a function which 'leaks' inline exceptions;
also, such a function can only be called from a virtual function if the
virtual fn catches all exceptions.

Since these are inlineable (*not* necessarily inlined), one might even
write template catch:
try { /* ... */
}
template<typename T>
catch (const T& t) { /* ...*/
}

Note that this does not give us language-level visitations as the try block
cannot `throw inline' from a virtual call. If - and only if - one aims to
solve visitation, one might consider:
enum MyEnum { a, b, c };

void visit(const MyEnum e) {
    switch (e) {
    template<MyEnum enumVal>
    catch enumVal:
        throw inline std::integral_constant<MyEnum, enumVal>();
    }
}

The latter part is strictly optional (and can be implemented in terms of
the enum reflection proposal).

Do you think it's feasible?

Thanks in advance,
-lorro

--
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/3668127e-b7f0-4888-adbb-dfdd07c73b89%40isocpp.org.

------=_Part_1706_74598835.1485817851911
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">Hi,<br><br>[For those just joining in: it&#39;s actually &=
#39;capturing the return continuation for for-else / for-break&#39;]<br>I&#=
39;ve made a few prototypes based on different approaches (incl. exceptions=
, continuations, wrapper macros around `for&#39;, variant return types, con=
tinuation-as-a-class, etc.). It looks to me now that these <i>are</i> excep=
tions, but inline ones. How would you like something like:<br><br><div styl=
e=3D"background-color: rgb(250, 250, 250); border-color: rgb(187, 187, 187)=
; border-style: solid; border-width: 1px; overflow-wrap: break-word;" class=
=3D"prettyprint"><code class=3D"prettyprint"><div class=3D"subprettyprint">=
<span style=3D"color: #800;" class=3D"styled-by-prettify">#include</span><s=
pan style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=
=3D"color: #080;" class=3D"styled-by-prettify">&lt;vector&gt;</span><span s=
tyle=3D"color: #000;" class=3D"styled-by-prettify"><br></span><span style=
=3D"color: #800;" class=3D"styled-by-prettify">#include</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color=
: #080;" class=3D"styled-by-prettify">&lt;iostream&gt;</span><span style=3D=
"color: #000;" class=3D"styled-by-prettify"><br><br></span><span style=3D"c=
olor: #008;" class=3D"styled-by-prettify">extern</span><span style=3D"color=
: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #008;" =
class=3D"styled-by-prettify">bool</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"> g</span><span style=3D"color: #660;" class=3D"styl=
ed-by-prettify">();</span><span style=3D"color: #000;" class=3D"styled-by-p=
rettify"><br><br></span><span style=3D"color: #008;" class=3D"styled-by-pre=
ttify">struct</span><span style=3D"color: #000;" class=3D"styled-by-prettif=
y"> </span><span style=3D"color: #606;" class=3D"styled-by-prettify">Break<=
/span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><sp=
an style=3D"color: #660;" class=3D"styled-by-prettify">{};</span><span styl=
e=3D"color: #000;" class=3D"styled-by-prettify"><br><br></span><span style=
=3D"color: #008;" class=3D"styled-by-prettify">int</span><span style=3D"col=
or: #000;" class=3D"styled-by-prettify"> sum</span><span style=3D"color: #6=
60;" class=3D"styled-by-prettify">(</span><span style=3D"color: #008;" clas=
s=3D"styled-by-prettify">const</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-pret=
tify">vector</span><span style=3D"color: #080;" class=3D"styled-by-prettify=
">&lt;int&gt;</span><span style=3D"color: #660;" class=3D"styled-by-prettif=
y">&amp;</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> v=
</span><span style=3D"color: #660;" class=3D"styled-by-prettify">)</span><s=
pan style=3D"color: #000;" class=3D"styled-by-prettify"><br></span><span st=
yle=3D"color: #660;" class=3D"styled-by-prettify">{</span><span style=3D"co=
lor: #000;" class=3D"styled-by-prettify"><br>=C2=A0 =C2=A0 </span><span sty=
le=3D"color: #008;" class=3D"styled-by-prettify">int</span><span style=3D"c=
olor: #000;" class=3D"styled-by-prettify"> ret </span><span style=3D"color:=
 #660;" class=3D"styled-by-prettify">=3D</span><span style=3D"color: #000;"=
 class=3D"styled-by-prettify"> </span><span style=3D"color: #066;" class=3D=
"styled-by-prettify">0</span><span style=3D"color: #660;" class=3D"styled-b=
y-prettify">;</span><span style=3D"color: #000;" class=3D"styled-by-prettif=
y"><br>=C2=A0 =C2=A0 </span><span style=3D"color: #008;" class=3D"styled-by=
-prettify">for</span><span style=3D"color: #000;" class=3D"styled-by-pretti=
fy"> </span><span style=3D"color: #660;" class=3D"styled-by-prettify">(</sp=
an><span style=3D"color: #008;" class=3D"styled-by-prettify">auto</span><sp=
an style=3D"color: #660;" class=3D"styled-by-prettify">&amp;&amp;</span><sp=
an style=3D"color: #000;" class=3D"styled-by-prettify"> elem </span><span s=
tyle=3D"color: #660;" class=3D"styled-by-prettify">:</span><span style=3D"c=
olor: #000;" class=3D"styled-by-prettify"> v</span><span style=3D"color: #6=
60;" class=3D"styled-by-prettify">)</span><span style=3D"color: #000;" clas=
s=3D"styled-by-prettify"> </span><span style=3D"color: #660;" class=3D"styl=
ed-by-prettify">{</span><span style=3D"color: #000;" class=3D"styled-by-pre=
ttify"><br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 </span><span style=3D"color: #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-b=
y-prettify">(</span><span style=3D"color: #000;" class=3D"styled-by-prettif=
y">g</span><span style=3D"color: #660;" class=3D"styled-by-prettify">(</spa=
n><span style=3D"color: #000;" class=3D"styled-by-prettify">elem</span><spa=
n style=3D"color: #660;" class=3D"styled-by-prettify">))</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color=
: #008;" class=3D"styled-by-prettify">throw</span><span style=3D"color: #00=
0;" class=3D"styled-by-prettify"> </span><span style=3D"color: #008;" class=
=3D"styled-by-prettify">inline</span><span style=3D"color: #000;" class=3D"=
styled-by-prettify"> </span><span style=3D"color: #606;" class=3D"styled-by=
-prettify">Break</span><span style=3D"color: #660;" class=3D"styled-by-pret=
tify">();</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><=
br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 ret </span><span style=3D"color: #660;" clas=
s=3D"styled-by-prettify">+=3D</span><span style=3D"color: #000;" class=3D"s=
tyled-by-prettify"> elem</span><span style=3D"color: #660;" class=3D"styled=
-by-prettify">;</span><span style=3D"color: #000;" class=3D"styled-by-prett=
ify"><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-pretti=
fy"><br></span><span style=3D"color: #660;" class=3D"styled-by-prettify">}<=
/span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br><br></s=
pan><span style=3D"color: #008;" class=3D"styled-by-prettify">int</span><sp=
an style=3D"color: #000;" class=3D"styled-by-prettify"> main</span><span st=
yle=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>=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">vector</span><span style=3D"color: #080;" cla=
ss=3D"styled-by-prettify">&lt;int&gt;</span><span style=3D"color: #000;" cl=
ass=3D"styled-by-prettify"> v</span><span style=3D"color: #660;" class=3D"s=
tyled-by-prettify">{</span><span style=3D"color: #000;" class=3D"styled-by-=
prettify"> </span><span style=3D"color: #066;" class=3D"styled-by-prettify"=
>1</span><span style=3D"color: #660;" class=3D"styled-by-prettify">,</span>=
<span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span sty=
le=3D"color: #066;" class=3D"styled-by-prettify">2</span><span style=3D"col=
or: #660;" class=3D"styled-by-prettify">,</span><span style=3D"color: #000;=
" class=3D"styled-by-prettify"> </span><span style=3D"color: #066;" class=
=3D"styled-by-prettify">3</span><span style=3D"color: #000;" class=3D"style=
d-by-prettify"> </span><span style=3D"color: #660;" class=3D"styled-by-pret=
tify">};</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><b=
r>=C2=A0 =C2=A0 </span><span style=3D"color: #008;" class=3D"styled-by-pret=
tify">try</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> =
</span><span style=3D"color: #660;" class=3D"styled-by-prettify">{</span><s=
pan style=3D"color: #000;" class=3D"styled-by-prettify"><br>=C2=A0 =C2=A0 =
=C2=A0 =C2=A0 std</span><span style=3D"color: #660;" class=3D"styled-by-pre=
ttify">::</span><span style=3D"color: #000;" class=3D"styled-by-prettify">c=
out </span><span style=3D"color: #660;" class=3D"styled-by-prettify">&lt;&l=
t;</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> sum</sp=
an><span style=3D"color: #660;" class=3D"styled-by-prettify">(</span><span =
style=3D"color: #000;" class=3D"styled-by-prettify">v</span><span style=3D"=
color: #660;" class=3D"styled-by-prettify">);</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: #0=
00;" class=3D"styled-by-prettify"> </span><span style=3D"color: #008;" clas=
s=3D"styled-by-prettify">catch</span><span style=3D"color: #000;" class=3D"=
styled-by-prettify"> </span><span style=3D"color: #008;" class=3D"styled-by=
-prettify">inline</span><span style=3D"color: #000;" class=3D"styled-by-pre=
ttify"> </span><span style=3D"color: #660;" class=3D"styled-by-prettify">(<=
/span><span style=3D"color: #008;" class=3D"styled-by-prettify">const</span=
><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span st=
yle=3D"color: #606;" class=3D"styled-by-prettify">Break</span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">&amp;)</span><span style=3D"=
color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #6=
60;" class=3D"styled-by-prettify">{</span><span style=3D"color: #000;" clas=
s=3D"styled-by-prettify"><br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 std</span><span st=
yle=3D"color: #660;" class=3D"styled-by-prettify">::</span><span style=3D"c=
olor: #000;" class=3D"styled-by-prettify">cout </span><span style=3D"color:=
 #660;" class=3D"styled-by-prettify">&lt;&lt;</span><span style=3D"color: #=
000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #080;" cla=
ss=3D"styled-by-prettify">&quot;break&quot;</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></span><span style=3D"color: #660;" class=3D"st=
yled-by-prettify">}</span><span style=3D"color: #000;" class=3D"styled-by-p=
rettify"><br></span></div></code></div><br>Where `throw inline&#39; means t=
hat only inlineable calls appear on the return path from the throw point to=
 `catch inline&#39;. Thus no non-final virtual calls, no non-constexpr fnpt=
r / mem fnptr calls, definitions in the same compilation unit, etc. This me=
ans that the compiler &#39;sees&#39; the return path and can compile as eff=
icient code as an inline call would be for the various returns (possibly <i=
>more</i> efficient than a variant return type; surely more efficient than =
regular exceptions / continuations; also, it expresses intent more clearly)=
.. It also means that a non-constexpr function pointer cannot be formed to a=
 function which &#39;leaks&#39; inline exceptions; also, such a function ca=
n only be called from a virtual function if the virtual fn catches all exce=
ptions.<br><br>Since these are inlineable (<i>not</i> necessarily inlined),=
 one might even write template catch:<br><div style=3D"background-color: rg=
b(250, 250, 250); border-color: rgb(187, 187, 187); border-style: solid; bo=
rder-width: 1px; overflow-wrap: break-word;" class=3D"prettyprint"><code cl=
ass=3D"prettyprint"><div class=3D"subprettyprint"><span style=3D"color: #00=
8;" class=3D"styled-by-prettify">try</span><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"> </span><span style=3D"color: #800;" class=3D"styled-by-prettify">/=
* ... */</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><b=
r></span><span style=3D"color: #660;" class=3D"styled-by-prettify">}</span>=
<span style=3D"color: #000;" class=3D"styled-by-prettify"><br></span><span =
style=3D"color: #008;" class=3D"styled-by-prettify">template</span><span st=
yle=3D"color: #660;" class=3D"styled-by-prettify">&lt;</span><span style=3D=
"color: #008;" class=3D"styled-by-prettify">typename</span><span style=3D"c=
olor: #000;" class=3D"styled-by-prettify"> T</span><span style=3D"color: #6=
60;" class=3D"styled-by-prettify">&gt;</span><span style=3D"color: #000;" c=
lass=3D"styled-by-prettify"><br></span><span style=3D"color: #008;" class=
=3D"styled-by-prettify">catch</span><span style=3D"color: #000;" class=3D"s=
tyled-by-prettify"> </span><span style=3D"color: #660;" class=3D"styled-by-=
prettify">(</span><span style=3D"color: #008;" class=3D"styled-by-prettify"=
>const</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> T</=
span><span style=3D"color: #660;" class=3D"styled-by-prettify">&amp;</span>=
<span style=3D"color: #000;" class=3D"styled-by-prettify"> t</span><span st=
yle=3D"color: #660;" class=3D"styled-by-prettify">)</span><span style=3D"co=
lor: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #660=
;" class=3D"styled-by-prettify">{</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"> </span><span style=3D"color: #800;" class=3D"style=
d-by-prettify">/* ...*/</span><span style=3D"color: #000;" class=3D"styled-=
by-prettify"><br></span><span style=3D"color: #660;" class=3D"styled-by-pre=
ttify">}</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><b=
r></span></div></code></div><br>Note that this does not give us language-le=
vel visitations as the try block cannot `throw inline&#39; from a virtual c=
all. If - and only if - one aims to solve visitation, one might consider:<b=
r><div style=3D"background-color: rgb(250, 250, 250); border-color: rgb(187=
, 187, 187); border-style: solid; border-width: 1px; overflow-wrap: break-w=
ord;" class=3D"prettyprint"><code class=3D"prettyprint"><div class=3D"subpr=
ettyprint"><span style=3D"color: #008;" class=3D"styled-by-prettify">enum</=
span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><spa=
n style=3D"color: #606;" class=3D"styled-by-prettify">MyEnum</span><span st=
yle=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"co=
lor: #660;" class=3D"styled-by-prettify">{</span><span style=3D"color: #000=
;" class=3D"styled-by-prettify"> a</span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">,</span><span style=3D"color: #000;" class=3D"style=
d-by-prettify"> b</span><span style=3D"color: #660;" class=3D"styled-by-pre=
ttify">,</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> c=
 </span><span style=3D"color: #660;" class=3D"styled-by-prettify">};</span>=
<span style=3D"color: #000;" class=3D"styled-by-prettify"><br><br></span><s=
pan style=3D"color: #008;" class=3D"styled-by-prettify">void</span><span st=
yle=3D"color: #000;" class=3D"styled-by-prettify"> visit</span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">(</span><span style=3D"color=
: #008;" class=3D"styled-by-prettify">const</span><span style=3D"color: #00=
0;" class=3D"styled-by-prettify"> </span><span style=3D"color: #606;" class=
=3D"styled-by-prettify">MyEnum</span><span style=3D"color: #000;" class=3D"=
styled-by-prettify"> e</span><span style=3D"color: #660;" class=3D"styled-b=
y-prettify">)</span><span style=3D"color: #000;" class=3D"styled-by-prettif=
y"> </span><span style=3D"color: #660;" class=3D"styled-by-prettify">{</spa=
n><span style=3D"color: #000;" class=3D"styled-by-prettify"><br>=C2=A0 =C2=
=A0 </span><span style=3D"color: #008;" class=3D"styled-by-prettify">switch=
</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><s=
pan style=3D"color: #660;" class=3D"styled-by-prettify">(</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify">e</span><span style=3D"color=
: #660;" class=3D"styled-by-prettify">)</span><span style=3D"color: #000;" =
class=3D"styled-by-prettify"> </span><span style=3D"color: #660;" class=3D"=
styled-by-prettify">{</span><span style=3D"color: #000;" class=3D"styled-by=
-prettify"><br>=C2=A0 =C2=A0 </span><span style=3D"color: #008;" class=3D"s=
tyled-by-prettify">template</span><span style=3D"color: #660;" class=3D"sty=
led-by-prettify">&lt;</span><span style=3D"color: #606;" class=3D"styled-by=
-prettify">MyEnum</span><span style=3D"color: #000;" class=3D"styled-by-pre=
ttify"> enumVal</span><span style=3D"color: #660;" class=3D"styled-by-prett=
ify">&gt;</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-pre=
ttify">catch</span><span style=3D"color: #000;" class=3D"styled-by-prettify=
"> enumVal</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"style=
d-by-prettify">throw</span><span style=3D"color: #000;" class=3D"styled-by-=
prettify"> </span><span style=3D"color: #008;" class=3D"styled-by-prettify"=
>inline</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> st=
d</span><span style=3D"color: #660;" class=3D"styled-by-prettify">::</span>=
<span style=3D"color: #000;" class=3D"styled-by-prettify">integral_constant=
</span><span style=3D"color: #660;" class=3D"styled-by-prettify">&lt;</span=
><span style=3D"color: #606;" class=3D"styled-by-prettify">MyEnum</span><sp=
an style=3D"color: #660;" class=3D"styled-by-prettify">,</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"> enumVal</span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">&gt;();</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></span><span style=3D"color:=
 #660;" class=3D"styled-by-prettify">}</span><span style=3D"color: #000;" c=
lass=3D"styled-by-prettify"><br></span></div></code></div><br>The latter pa=
rt is strictly optional (and can be implemented in terms of the enum reflec=
tion proposal).<br><br>Do you think it&#39;s feasible?<br><br>Thanks in adv=
ance,<br>-lorro<br></div>

<p></p>

-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; 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/3668127e-b7f0-4888-adbb-dfdd07c73b89%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/3668127e-b7f0-4888-adbb-dfdd07c73b89=
%40isocpp.org</a>.<br />

------=_Part_1706_74598835.1485817851911--

------=_Part_1705_247117467.1485817851910--

.