Topic: Scope as first-class object
Author: TONGARI J <tongari95@gmail.com>
Date: Fri, 5 Sep 2014 10:03:07 -0700 (PDT)
Raw View
------=_Part_4872_1728011135.1409936587096
Content-Type: text/plain; charset=UTF-8
This is not a formal proposal, and I don't know if this is possible at all,
here's the idea anyway:
*Motivation*
We need a more flexible control flow that allows us to break from inner
scope to outer scope, as well as from callee function to caller.
Currently this can be done using exceptions, while using exceptions for
control flow is usually considered anti-pattern and sub-optimal, I
think stack-unwinding itself deserves a language feature.
*Examples*
*1) nested scope*
void f()
{
for (...) // [1]
{
for (...)
{
if (...)
// break out of [1]
}
}
// other stuff
}
*2) callee-caller*
void f()
{
for (...) // [1]
{
process([&]
{
if (...)
// break out of [1]
});
}
// other stuff
}
*Current Solutions*
*1) nested scope*
void f()
{
for (...)
{
for (...)
{
if (...)
goto end1;
}
}
end1:
// other stuff
}
*2) callee-caller*
void f()
{
try
{
for (...)
{
process([&]
{
if (...)
throw end1();
});
}
}
catch (end1&) {}
// other stuff
}
*Proposed Solutions*
*1) nested scope*
void f()
{
s1:: // an object representing the scope context is constructed
{
for (...)
{
for (...)
{
if (...)
s1::unwind();
}
}
}
// other stuff
}
*2) callee-caller*
void f()
{
s1:: // an object representing the scope context is constructed
{
for (...)
{
process([&] // scope context is also captured by &
{
if (...)
s1::unwind();
});
}
}
// other stuff
}
`s1::{...}` generates a std::scope_context object, which you can access
through the scope operator inside the surrounded scope.
std::scope_context may look like:
class scope_context // non-copyable non-moveable
{
void unwind();
// other stuff I didn't think of...
};
To pass the context as argument, you can use `scope::this`, which gives you
a ptr to std::scope_context, for example:
void bar(std::scope_context* ctx)
{
if (...)
ctx->unwind();
}
void foo()
{
s1::
{
bar(s1::this);
}
}
I'm aware of the proposal for labeled beak, and I've seen other threads
that discussed labeled beak, but I think the approach I presented (if
possible) is more general since it's not restricted to single function
scope.
Thoughts?
Thanks,
Jamboree
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.
------=_Part_4872_1728011135.1409936587096
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><div><div>This is not a formal proposal, and I don't know =
if this is possible at all, here's the idea anyway:</div><b><div><b><br></b=
></div>Motivation</b><div><br></div><div>We need a more flexible control fl=
ow that allows us to break from inner scope to outer scope, as well as from=
callee function to caller.</div><div>Currently this can be done using exce=
ptions, while using exceptions for control flow is usually considered anti-=
pattern and sub-optimal, I think stack-unwinding itself deserves =
a language feature.</div><div><br></div><div><b>Examples</b></div><div><b><=
br></b></div><div><i>1) nested scope</i></div><div><div class=3D"prettyprin=
t" style=3D"border: 1px solid rgb(187, 187, 187); word-wrap: break-word; ba=
ckground-color: rgb(250, 250, 250);"><code class=3D"prettyprint"><div class=
=3D"subprettyprint"><font color=3D"#660066"><div class=3D"subprettyprint">v=
oid f()</div><div class=3D"subprettyprint">{</div><div class=3D"subprettypr=
int"> for (...) // [1]</div><div class=3D"subprettyprint">&nbs=
p; {</div><div class=3D"subprettyprint"> =
for (...)</div><div class=3D"subprettyprint"> {<=
/div><div class=3D"subprettyprint">  =
; if (...)</div><div class=3D"subprettyprint"> &=
nbsp; // break out of [1]</div><div class=3D"subpretty=
print"> }</div><div class=3D"subprettyprint">&nb=
sp; }<br> // other stuff</div><div class=3D"subprettypr=
int">}</div></font></div></code></div><div><br></div><i>2) callee-caller</i=
><br><div class=3D"prettyprint" style=3D"border: 1px solid rgb(187, 187, 18=
7); word-wrap: break-word; background-color: rgb(250, 250, 250);"><code cla=
ss=3D"prettyprint"><div class=3D"subprettyprint"><div class=3D"subprettypri=
nt" style=3D"color: rgb(102, 0, 102);"><div class=3D"subprettyprint">void f=
()</div><div class=3D"subprettyprint">{</div><div class=3D"subprettyprint">=
for (...) // [1]</div><div class=3D"subprettyprint"> &n=
bsp; {</div><div class=3D"subprettyprint"> proce=
ss([&]</div><div class=3D"subprettyprint"> {=
</div><div class=3D"subprettyprint"> &nbs=
p; if (...)</div><div class=3D"subprettyprint"> =
// break out of [1]</div><div class=3D"subprett=
yprint"> });</div><div class=3D"subprettyprint">=
}<br> // other stuff<br></div><div class=3D"subp=
rettyprint">}</div></div></div></code></div><br><b>Current Solutions</b></d=
iv><div><b><br></b></div><div><i>1) nested scope</i><b><br></b></div><div><=
div class=3D"prettyprint" style=3D"border: 1px solid rgb(187, 187, 187); wo=
rd-wrap: break-word; background-color: rgb(250, 250, 250);"><code class=3D"=
prettyprint"><div class=3D"subprettyprint"><div class=3D"subprettyprint">vo=
id f()</div><div class=3D"subprettyprint">{</div><div class=3D"subprettypri=
nt"> for (...)</div><div class=3D"subprettyprint">  =
; {</div><div class=3D"subprettyprint"> for (...=
)</div><div class=3D"subprettyprint"> {</div><di=
v class=3D"subprettyprint"> if (..=
..)</div><div class=3D"subprettyprint"> &n=
bsp; goto end1;</div><div class=3D"subprettyprint"> &nb=
sp; }</div><div class=3D"subprettyprint"> }</div=
><div class=3D"subprettyprint"> end1:</div><div class=3D"subpr=
ettyprint"> // other stuff</div><div class=3D"subprettyprint">=
}<br></div></div></code></div></div><div><br></div><div><i>2) callee-caller=
</i><br><div class=3D"prettyprint" style=3D"border: 1px solid rgb(187, 187,=
187); word-wrap: break-word; background-color: rgb(250, 250, 250);"><code =
class=3D"prettyprint"><div class=3D"subprettyprint"><div class=3D"subpretty=
print" style=3D"color: rgb(102, 0, 102);"><div class=3D"subprettyprint"><di=
v class=3D"subprettyprint">void f()</div><div class=3D"subprettyprint">{</d=
iv><div class=3D"subprettyprint"> try</div><div class=3D"subpr=
ettyprint"> {</div><div class=3D"subprettyprint"> =
for (...)</div><div class=3D"subprettyprint"> &=
nbsp; {</div><div class=3D"subprettyprint"> &nbs=
p; process([&]</div><div class=3D"subprettyprint"> =
{</div><div class=3D"subprettyprint">&nb=
sp; if (...)</div><div cla=
ss=3D"subprettyprint"> &nbs=
p; throw end1();</div><div class=3D"subprettyprint"> &n=
bsp; });</div><div class=3D"subprettyprint">&nb=
sp; }</div><div class=3D"subprettyprint"> =
}</div><div class=3D"subprettyprint"> catch (end1&) {}</d=
iv><div class=3D"subprettyprint"> // other stuff</div><div cla=
ss=3D"subprettyprint">}</div></div></div></div></code></div></div></div><di=
v><br></div><div><br></div><div><div><b>Proposed Solutions</b></div><div><b=
><br></b></div><div><i>1) nested scope</i></div></div><div><div class=3D"pr=
ettyprint" style=3D"border: 1px solid rgb(187, 187, 187); word-wrap: break-=
word; background-color: rgb(250, 250, 250);"><code class=3D"prettyprint"><d=
iv class=3D"subprettyprint"><div class=3D"subprettyprint"><div class=3D"sub=
prettyprint">void f()</div><div class=3D"subprettyprint">{</div><div class=
=3D"subprettyprint"> s1:: // an object representing the scope =
context is constructed</div><div class=3D"subprettyprint"> {</=
div><div class=3D"subprettyprint"> for (...)</di=
v><div class=3D"subprettyprint"> {</div><div cla=
ss=3D"subprettyprint"> for (...)</=
div><div class=3D"subprettyprint"> =
{</div><div class=3D"subprettyprint"> &n=
bsp; if (...)</div><div class=3D"subprettyprint">  =
; s1::unwind();</di=
v><div class=3D"subprettyprint"> }=
</div><div class=3D"subprettyprint"> }</div><div=
class=3D"subprettyprint"> }</div><div class=3D"subprettyprint=
"> // other stuff</div><div class=3D"subprettyprint">}</div></=
div></div></code></div><br><div><i>2) callee-caller</i><br><div class=3D"pr=
ettyprint" style=3D"border: 1px solid rgb(187, 187, 187); word-wrap: break-=
word; background-color: rgb(250, 250, 250);"><code class=3D"prettyprint"><d=
iv class=3D"subprettyprint"><div class=3D"subprettyprint" style=3D"color: r=
gb(102, 0, 102);"><div class=3D"subprettyprint"><div class=3D"subprettyprin=
t"><div class=3D"subprettyprint">void f()</div><div class=3D"subprettyprint=
">{</div><div class=3D"subprettyprint"> s1:: // an object repr=
esenting the scope context is constructed</div><div class=3D"subprettyprint=
"> {</div><div class=3D"subprettyprint"> &=
nbsp; for (...)</div><div class=3D"subprettyprint"> &nb=
sp; {</div><div class=3D"subprettyprint"> =
process([&] // scope context is also captured by &</div><di=
v class=3D"subprettyprint"> {</div=
><div class=3D"subprettyprint"> &n=
bsp; if (...)</div><div class=3D"subprettyprint">  =
; s1::unwind();</div><div =
class=3D"subprettyprint"> });</div=
><div class=3D"subprettyprint"> }</div><div clas=
s=3D"subprettyprint"> }</div><div class=3D"subprettyprint">&nb=
sp; // other stuff</div><div class=3D"subprettyprint">}<br></div></d=
iv></div></div></div></code></div></div></div><br>`s1::{...}` generates a s=
td::scope_context object, which you can access through the scope operator i=
nside the surrounded scope.<div><br></div><div> std::scope_context may=
look like:<br></div><div><div class=3D"prettyprint" style=3D"border: 1px s=
olid rgb(187, 187, 187); word-wrap: break-word; background-color: rgb(250, =
250, 250);"><code class=3D"prettyprint"><div class=3D"subprettyprint"><div =
class=3D"subprettyprint">class scope_context // non-copyable <span style=3D=
"font-family: Arial, Helvetica, sans-serif;">non-moveable</span></div><div =
class=3D"subprettyprint">{</div><div class=3D"subprettyprint"> =
void unwind();</div><div class=3D"subprettyprint"> // other s=
tuff I didn't think of...</div><div class=3D"subprettyprint">};</div></div>=
</code></div><br>To pass the context as argument, you can use `scope::this`=
, which gives you a ptr to std::scope_context, for example:</div><div><div =
class=3D"prettyprint" style=3D"border: 1px solid rgb(187, 187, 187); word-w=
rap: break-word; background-color: rgb(250, 250, 250);"><code class=3D"pret=
typrint"><div class=3D"subprettyprint"><font color=3D"#660066"><div class=
=3D"subprettyprint">void bar(std::scope_context* ctx)</div><div class=3D"su=
bprettyprint">{</div><div class=3D"subprettyprint"> if (...)</=
div><div class=3D"subprettyprint"> ctx->unwin=
d();</div><div class=3D"subprettyprint">}</div><div class=3D"subprettyprint=
"><br></div><div class=3D"subprettyprint">void foo()</div><div class=3D"sub=
prettyprint">{</div><div class=3D"subprettyprint"> s1::</div><=
div class=3D"subprettyprint"> {</div><div class=3D"subprettypr=
int"> bar(s1::this);</div><div class=3D"subprett=
yprint"> }</div><div class=3D"subprettyprint">}</div></font></=
div></code></div><br>I'm aware of the proposal for labeled beak, and I've s=
een other threads that discussed labeled beak, but I think the approach I p=
resented (if possible) is more general since it's not restricted to single =
function scope.</div><div><br></div><div>Thoughts?</div><div><br></div><div=
><br></div><div>Thanks,</div><div>Jamboree</div><div><br></div></div>
<p></p>
-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />
------=_Part_4872_1728011135.1409936587096--
.
Author: Ville Voutilainen <ville.voutilainen@gmail.com>
Date: Fri, 5 Sep 2014 20:20:17 +0300
Raw View
On 5 September 2014 20:03, TONGARI J <tongari95@gmail.com> wrote:
> I'm aware of the proposal for labeled beak, and I've seen other threads that
> discussed labeled beak, but I think the approach I presented (if possible)
> is more general since it's not restricted to single function scope.
If you're interested in caller-callee control transfer, I recommend looking at
the coroutine proposal:
http://open-std.org/JTC1/SC22/WG21/docs/papers/2014/n3985.pdf
Nat Goodspeed's talk about it may also be highly illuminating:
https://www.youtube.com/watch?v=S6JpbmeuzNg&list=UU5e__RG9K3cHrPotPABnrwg
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.
.
Author: Douglas Boffey <douglas.boffey@gmail.com>
Date: Mon, 8 Sep 2014 06:26:15 -0700 (PDT)
Raw View
------=_Part_317_475459508.1410182775678
Content-Type: text/plain; charset=UTF-8
On Friday, 5 September 2014 18:03:07 UTC+1, TONGARI J wrote:
>
> This is not a formal proposal, and I don't know if this is possible at
> all, here's the idea anyway:
>
> I'm aware of the proposal for labeled beak, and I've seen other threads
> that discussed labeled beak, but I think the approach I presented (if
> possible) is more general since it's not restricted to single function
> scope.
>
> Although it is more general, IMO, breaking out of loops in a different
function would only lead to confusion. Furthermore, without optimisation,
I would expect unwinding within a single function to be far less efficient
(in both time and space) than a labelled break.
>
> Thanks,
> Jamboree
>
>
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.
------=_Part_317_475459508.1410182775678
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><br><br>On Friday, 5 September 2014 18:03:07 UTC+1, TONGAR=
I J wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left=
: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr"><d=
iv><div>This is not a formal proposal, and I don't know if this is possible=
at all, here's the idea anyway:</div><b><div><b><br></b></div></b>I'm awar=
e of the proposal for labeled beak, and I've seen other threads that discus=
sed labeled beak, but I think the approach I presented (if possible) is mor=
e general since it's not restricted to single function scope.</div><div><br=
></div></div></blockquote><div>Although it is more general, IMO, breaking o=
ut of loops in a different function would only lead to confusion. Fur=
thermore, without optimisation, I would expect unwinding within a single fu=
nction to be far less efficient (in both time and space) than a labelled br=
eak. <br></div><blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-=
left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr=
"><div><br></div><div>Thanks,</div><div>Jamboree</div><div><br></div></div>=
</blockquote></div>
<p></p>
-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />
------=_Part_317_475459508.1410182775678--
.
Author: TONGARI J <tongari95@gmail.com>
Date: Mon, 8 Sep 2014 22:40:41 +0800
Raw View
--089e01493922927d5705028ecdac
Content-Type: text/plain; charset=UTF-8
2014-09-08 21:26 GMT+08:00 Douglas Boffey <douglas.boffey@gmail.com>:
>
>
> On Friday, 5 September 2014 18:03:07 UTC+1, TONGARI J wrote:
>>
>> This is not a formal proposal, and I don't know if this is possible at
>> all, here's the idea anyway:
>>
>> I'm aware of the proposal for labeled beak, and I've seen other threads
>> that discussed labeled beak, but I think the approach I presented (if
>> possible) is more general since it's not restricted to single function
>> scope.
>>
>> Although it is more general, IMO, breaking out of loops in a different
> function would only lead to confusion. Furthermore, without optimisation,
> I would expect unwinding within a single function to be far less efficient
> (in both time and space) than a labelled break.
>
I agree that a labelled break would be more efficient in that case, but we
somewhat failed to make it into the standard, so I think it'd be worth
pursuing something more general. OTOH, I don't think it'd lead to more
confusion than exception.
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.
--089e01493922927d5705028ecdac
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><div class=3D"gmail_extra"><div class=3D"gmail_quote">2014=
-09-08 21:26 GMT+08:00 Douglas Boffey <span dir=3D"ltr"><<a href=3D"mail=
to:douglas.boffey@gmail.com" target=3D"_blank">douglas.boffey@gmail.com</a>=
></span>:<br><blockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0=
px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-le=
ft-style:solid;padding-left:1ex"><div dir=3D"ltr"><span class=3D""><br><br>=
On Friday, 5 September 2014 18:03:07 UTC+1, TONGARI J wrote:</span><blockq=
uote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;border-left-wi=
dth:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-=
left:1ex"><div dir=3D"ltr"><div><span class=3D""><div>This is not a formal =
proposal, and I don't know if this is possible at all, here's the i=
dea anyway:</div><b><div><b><br></b></div></b></span><span class=3D"">I'=
;m aware of the proposal for labeled beak, and I've seen other threads =
that discussed labeled beak, but I think the approach I presented (if possi=
ble) is more general since it's not restricted to single function scope=
..</span></div><div><br></div></div></blockquote><div>Although it is more ge=
neral, IMO, breaking out of loops in a different function would only lead t=
o confusion.=C2=A0 Furthermore, without optimisation, I would expect unwind=
ing within a single function to be far less efficient (in both time and spa=
ce) than a labelled break. <br></div></div></blockquote><div><br></div><div=
>I agree that =C2=A0a labelled break would be more efficient in that case, =
but we somewhat failed to make it into the standard, so I think it'd be=
=C2=A0worth pursuing something more=C2=A0general. OTOH, I don't think i=
t'd lead to more confusion than exception.</div></div></div></div>
<p></p>
-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />
--089e01493922927d5705028ecdac--
.