Topic: is await an extension of the do-notation? (was Re:
Author: Evgeny Panasyuk <evgeny.panasyuk@gmail.com>
Date: Mon, 12 Oct 2015 08:08:13 +0300
Raw View
04.10.2015 18:44, Vicente J. Botet Escriba:
>>>
>>> I suggest to look at this presentation:
>>>
>>> http://open-std.org/JTC1/SC22/WG21/docs/papers/2014/n4287.pdf
>>>
>>> which walks through some of the aspects of P0057 proposal. Note, that
>>> the
>>> await syntax is actually quite old. It first appeared as do-notation in
>>> Haskell in 1998 and you may notice that P0057 can be used to perform
>>> more
>>> general "monadic" transformations and not only limited to coroutines.
> Hmm, await can not work with list as a monad, isn't it?
> Bit no proposal is tempting to take care of this case.
If use same underlying technique as was used at macro-based stackless
coroutines of Boost.Asio then it can work with list monad, because such
coroutine is just value type which can be copied/moved.
Here is small live demo of list-moand-like based on stackless coroutines
from Boost.Asio: http://coliru.stacked-crooked.com/a/465f5bcb59c8b0b3
--
Evgeny Panasyuk
--
---
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: Richard Smith <richard@metafoo.co.uk>
Date: Mon, 12 Oct 2015 11:46:51 -0700
Raw View
--001a1143b1acaa8fb70521ecc099
Content-Type: text/plain; charset=UTF-8
On Sun, Oct 11, 2015 at 10:08 PM, Evgeny Panasyuk <evgeny.panasyuk@gmail.com
> wrote:
> 04.10.2015 18:44, Vicente J. Botet Escriba:
>
>>
>>>> I suggest to look at this presentation:
>>>>
>>>> http://open-std.org/JTC1/SC22/WG21/docs/papers/2014/n4287.pdf
>>>>
>>>> which walks through some of the aspects of P0057 proposal. Note, that
>>>> the
>>>> await syntax is actually quite old. It first appeared as do-notation in
>>>> Haskell in 1998 and you may notice that P0057 can be used to perform
>>>> more
>>>> general "monadic" transformations and not only limited to coroutines.
>>>>
>>> Hmm, await can not work with list as a monad, isn't it?
>> Bit no proposal is tempting to take care of this case.
>>
>
>
> If use same underlying technique as was used at macro-based stackless
> coroutines of Boost.Asio then it can work with list monad, because such
> coroutine is just value type which can be copied/moved.
It doesn't really work; you can't support local variables with such a
model, because their lifetimes could be reentered after they end. P0057 is
fundamentally a coroutines proposal, not a monads proposal, because it does
not support repeated resumption from the same suspension state; I think
this is the right semantic match for an impure language such as C++.
--
---
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/.
--001a1143b1acaa8fb70521ecc099
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><div class=3D"gmail_extra"><div class=3D"gmail_quote">On S=
un, Oct 11, 2015 at 10:08 PM, Evgeny Panasyuk <span dir=3D"ltr"><<a href=
=3D"mailto:evgeny.panasyuk@gmail.com" target=3D"_blank">evgeny.panasyuk@gma=
il.com</a>></span> wrote:<br><blockquote class=3D"gmail_quote" style=3D"=
margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">04.10.2015 1=
8:44, Vicente J. Botet Escriba:<span class=3D""><br>
<blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1p=
x #ccc solid;padding-left:1ex"><blockquote class=3D"gmail_quote" style=3D"m=
argin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><blockquote c=
lass=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;=
padding-left:1ex">
<br>
I suggest to look at this presentation:<br>
<br>
<a href=3D"http://open-std.org/JTC1/SC22/WG21/docs/papers/2014/n4287.pdf" r=
el=3D"noreferrer" target=3D"_blank">http://open-std.org/JTC1/SC22/WG21/docs=
/papers/2014/n4287.pdf</a><br>
<br>
which walks through some of the aspects of P0057 proposal. Note, that<br>
the<br>
await syntax is actually quite old. It first appeared as do-notation in<br>
Haskell in 1998 and you may notice that P0057 can be used to perform<br>
more<br>
general "monadic" transformations and not only limited to corouti=
nes.<br>
</blockquote></blockquote>
Hmm, await can not work with list as a monad, isn't it?<br>
Bit no proposal is tempting to take care of this case.<br>
</blockquote>
<br>
<br></span>
If use same underlying technique as was used at macro-based stackless corou=
tines of Boost.Asio then it can work with list monad, because such coroutin=
e is just value type which can be copied/moved.</blockquote><div><br></div>=
<div>It doesn't really work; you can't support local variables with=
such a model, because their lifetimes could be reentered after they end. P=
0057 is fundamentally a coroutines proposal, not a monads proposal, because=
it does not support repeated resumption from the same suspension state; I =
think this is the right semantic match for an impure language such as C++.<=
/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 />
--001a1143b1acaa8fb70521ecc099--
.
Author: Evgeny Panasyuk <evgeny.panasyuk@gmail.com>
Date: Mon, 12 Oct 2015 22:19:45 +0300
Raw View
12.10.2015 21:46, Richard Smith:
> If use same underlying technique as was used at macro-based
> stackless coroutines of Boost.Asio then it can work with list monad,
> because such coroutine is just value type which can be copied/moved.
>
>
> It doesn't really work; you can't support local variables with such a
> model, because their lifetimes could be reentered after they end.
Local variables do work with technique used by stackless coroutines of
Boost.Asio (and proposals like N4244).
With such approach coroutine is transformed into class. Local variables
are transformed into fields of class (more precisely into nested unions
corresponding to scopes, as described in N4244), and coroutine body is
transformed into method-state-machine, where it's states correspond to
yield points.
This already can be implemented via macros to some extent.
Moreover, C#'s await is implemented based on similar approach:
http://www.codeproject.com/Articles/535635/Async-Await-and-the-Generated-StateMachine
> P0057
> is fundamentally a coroutines proposal, not a monads proposal, because
> it does not support repeated resumption from the same suspension state;
> I think this is the right semantic match for an impure language such as C++.
It is intrinsically non-zero overhead, due to type-erasure/allocations.
This fact alone is strong argument against it.
While with approach based on method-state-machine - we can get both:
generality and performance.
--
---
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: Gor Nishanov <gornishanov@gmail.com>
Date: Mon, 12 Oct 2015 12:30:44 -0700 (PDT)
Raw View
------=_Part_3_1741757521.1444678244165
Content-Type: multipart/alternative;
boundary="----=_Part_4_1907785914.1444678244166"
------=_Part_4_1907785914.1444678244166
Content-Type: text/plain; charset=UTF-8
Evgeny:
Note the "purity" word in Richard's answer.
If you write a body of the coroutine in a pure manner, you can hack P0057
and in your await_suspend for the list monad resume the coroutine multiple
times.
You need to provide proper final_suspend and return_value to make it work.
But it will work ONLY if your body is pure :-). That is the body of your
coroutine. And you cannot save any state in the awaiter, since it is torn
down at the end of the full expressions, hence, I am using thread_local to
ferry a value from await_suspend to await_resume.
Here is "do not try this at home" awaiter for the list<T>. Untested. Just
an idea of how it can look like.
auto operator await(list<T> const& l) {
struct awaiter {
list<T> const * list_;
static thread_local T* result_;
bool await_ready() { return false; }
void await_suspend(coroutine_handle<> h) {
auto l = list_;
for (auto && item : *l) { result_ = &item; h.resume(); }
// add code to extract the result from the promise and do something
with it.
}
// for every element of the list return the value that we stashed in
thread_local
T const & await_resume() { return *result_; }
}
return awaiter{&l};
}
--
---
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_4_1907785914.1444678244166
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">Evgeny:<div><br></div><div>Note the "purity" wor=
d in Richard's answer.</div><div>If you write a body of the coroutine i=
n a pure manner, you can hack P0057 and in your await_suspend for the list =
monad resume the coroutine multiple times.</div><div>You need to provide pr=
oper final_suspend and return_value to make it work. But it will work ONLY =
if your body is pure :-). That is the body of your coroutine. And you canno=
t save any state in the awaiter, since it is torn down at the end of the fu=
ll expressions, hence, I am using thread_local to ferry a value from await_=
suspend to await_resume.</div><div><br></div><div>Here is "do not try =
this at home" awaiter for the list<T>. Untested. Just an idea of=
how it can look like.</div><div><br></div><div><div class=3D"prettyprint" =
style=3D"border: 1px solid rgb(187, 187, 187); word-wrap: break-word; backg=
round-color: rgb(250, 250, 250);"><code class=3D"prettyprint"><div class=3D=
"subprettyprint"><span style=3D"color: #008;" class=3D"styled-by-prettify">=
auto</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </spa=
n><span style=3D"color: #008;" class=3D"styled-by-prettify">operator</span>=
<span style=3D"color: #000;" class=3D"styled-by-prettify"> await</span><spa=
n style=3D"color: #660;" class=3D"styled-by-prettify">(</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify">list</span><span style=3D"co=
lor: #660;" class=3D"styled-by-prettify"><</span><span style=3D"color: #=
000;" class=3D"styled-by-prettify">T</span><span style=3D"color: #660;" cla=
ss=3D"styled-by-prettify">></span><span style=3D"color: #000;" class=3D"=
styled-by-prettify"> </span><span style=3D"color: #008;" class=3D"styled-by=
-prettify">const</span><span style=3D"color: #660;" class=3D"styled-by-pret=
tify">&</span><span style=3D"color: #000;" class=3D"styled-by-prettify"=
> 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 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 </span><span style=3D"c=
olor: #008;" class=3D"styled-by-prettify">struct</span><span style=3D"color=
: #000;" class=3D"styled-by-prettify"> awaiter </span><span style=3D"color:=
#660;" class=3D"styled-by-prettify">{</span><span style=3D"color: #000;" c=
lass=3D"styled-by-prettify"> <br>=C2=A0 =C2=A0 list</span><span style=3D"co=
lor: #660;" class=3D"styled-by-prettify"><</span><span style=3D"color: #=
000;" class=3D"styled-by-prettify">T</span><span style=3D"color: #660;" cla=
ss=3D"styled-by-prettify">></span><span style=3D"color: #000;" class=3D"=
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-pret=
tify"> </span><span style=3D"color: #660;" class=3D"styled-by-prettify">*</=
span><span style=3D"color: #000;" class=3D"styled-by-prettify"> list_</span=
><span style=3D"color: #660;" class=3D"styled-by-prettify">;</span><span st=
yle=3D"color: #000;" class=3D"styled-by-prettify"> <br><br>=C2=A0 =C2=A0 </=
span><span style=3D"color: #008;" class=3D"styled-by-prettify">static</span=
><span style=3D"color: #000;" class=3D"styled-by-prettify"> thread_local T<=
/span><span style=3D"color: #660;" class=3D"styled-by-prettify">*</span><sp=
an style=3D"color: #000;" class=3D"styled-by-prettify"> result_</span><span=
style=3D"color: #660;" class=3D"styled-by-prettify">;</span><span style=3D=
"color: #000;" class=3D"styled-by-prettify"> <br><br>=C2=A0 =C2=A0 </span><=
span style=3D"color: #008;" class=3D"styled-by-prettify">bool</span><span s=
tyle=3D"color: #000;" class=3D"styled-by-prettify"> await_ready</span><span=
style=3D"color: #660;" class=3D"styled-by-prettify">()</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color=
: #660;" class=3D"styled-by-prettify">{</span><span style=3D"color: #000;" =
class=3D"styled-by-prettify"> </span><span style=3D"color: #008;" class=3D"=
styled-by-prettify">return</span><span style=3D"color: #000;" class=3D"styl=
ed-by-prettify"> </span><span style=3D"color: #008;" class=3D"styled-by-pre=
ttify">false</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 st=
yle=3D"color: #000;" class=3D"styled-by-prettify"> <br><br>=C2=A0 =C2=A0 </=
span><span style=3D"color: #008;" class=3D"styled-by-prettify">void</span><=
span style=3D"color: #000;" class=3D"styled-by-prettify"> await_suspend</sp=
an><span style=3D"color: #660;" class=3D"styled-by-prettify">(</span><span =
style=3D"color: #000;" class=3D"styled-by-prettify">coroutine_handle</span>=
<span style=3D"color: #660;" class=3D"styled-by-prettify"><></span><s=
pan style=3D"color: #000;" class=3D"styled-by-prettify"> h</span><span styl=
e=3D"color: #660;" class=3D"styled-by-prettify">)</span><span style=3D"colo=
r: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #660;"=
class=3D"styled-by-prettify">{</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">auto</span><span style=3D"color:=
#000;" class=3D"styled-by-prettify"> l </span><span style=3D"color: #660;"=
class=3D"styled-by-prettify">=3D</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"> list_</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: #00=
8;" class=3D"styled-by-prettify">for</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: #008;" class=3D"styled-by-pr=
ettify">auto</span><span style=3D"color: #000;" class=3D"styled-by-prettify=
"> </span><span style=3D"color: #660;" class=3D"styled-by-prettify">&&a=
mp;</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> item <=
/span><span style=3D"color: #660;" class=3D"styled-by-prettify">:</span><sp=
an style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">*</span><span style=3D"color=
: #000;" class=3D"styled-by-prettify">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 style=3D"color: #660;" class=3D"styled-by=
-prettify">{</span><span style=3D"color: #000;" class=3D"styled-by-prettify=
"> result_ </span><span style=3D"color: #660;" class=3D"styled-by-prettify"=
>=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><sp=
an style=3D"color: #000;" class=3D"styled-by-prettify">item</span><span sty=
le=3D"color: #660;" class=3D"styled-by-prettify">;</span><span style=3D"col=
or: #000;" class=3D"styled-by-prettify"> h</span><span style=3D"color: #660=
;" class=3D"styled-by-prettify">.</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify">resume</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-pretti=
fy">}</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"sty=
led-by-prettify">// add code to extract the result from the promise and do =
something with it. </span><span style=3D"color: #000;" class=3D"styled-by-p=
rettify"><br>=C2=A0 =C2=A0 </span><span style=3D"color: #660;" class=3D"sty=
led-by-prettify">}</span><span style=3D"color: #000;" class=3D"styled-by-pr=
ettify"> <br><br>=C2=A0 =C2=A0 </span><span style=3D"color: #800;" class=3D=
"styled-by-prettify">// for every element of the list return the value that=
we stashed in thread_local</span><span style=3D"color: #000;" class=3D"sty=
led-by-prettify"><br>=C2=A0 =C2=A0 T </span><span style=3D"color: #008;" cl=
ass=3D"styled-by-prettify">const</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"> </span><span style=3D"color: #660;" class=3D"style=
d-by-prettify">&</span><span style=3D"color: #000;" class=3D"styled-by-=
prettify"> await_resume</span><span style=3D"color: #660;" class=3D"styled-=
by-prettify">()</span><span style=3D"color: #000;" class=3D"styled-by-prett=
ify"> </span><span style=3D"color: #660;" class=3D"styled-by-prettify">{</s=
pan><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span=
style=3D"color: #008;" class=3D"styled-by-prettify">return</span><span sty=
le=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"col=
or: #660;" class=3D"styled-by-prettify">*</span><span style=3D"color: #000;=
" class=3D"styled-by-prettify">result_</span><span style=3D"color: #660;" c=
lass=3D"styled-by-prettify">;</span><span style=3D"color: #000;" class=3D"s=
tyled-by-prettify"> </span><span style=3D"color: #660;" class=3D"styled-by-=
prettify">}</span><span style=3D"color: #000;" class=3D"styled-by-prettify"=
><br>=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 </span><span style=3D"color: #008;" class=3D"styled-by-prettify">ret=
urn</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> awaite=
r</span><span style=3D"color: #660;" class=3D"styled-by-prettify">{&</s=
pan><span style=3D"color: #000;" class=3D"styled-by-prettify">l</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"c=
olor: #660;" class=3D"styled-by-prettify">}</span></div></code></div><p cla=
ss=3D"MsoNormal"><span style=3D"font-size:11.0pt;font-family:"Calibri&=
quot;,sans-serif;
color:#1F497D"><br><o:p></o:p></span></p></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_4_1907785914.1444678244166--
------=_Part_3_1741757521.1444678244165--
.
Author: Richard Smith <richard@metafoo.co.uk>
Date: Mon, 12 Oct 2015 12:53:38 -0700
Raw View
--001a11438a8e7859710521edaf7a
Content-Type: text/plain; charset=UTF-8
On Mon, Oct 12, 2015 at 12:19 PM, Evgeny Panasyuk <evgeny.panasyuk@gmail.com
> wrote:
> 12.10.2015 21:46, Richard Smith:
>
>> If use same underlying technique as was used at macro-based
>> stackless coroutines of Boost.Asio then it can work with list monad,
>> because such coroutine is just value type which can be copied/moved.
>>
>>
>> It doesn't really work; you can't support local variables with such a
>> model, because their lifetimes could be reentered after they end.
>>
>
> Local variables do work with technique used by stackless coroutines of
> Boost.Asio (and proposals like N4244).
>
> With such approach coroutine is transformed into class. Local variables
> are transformed into fields of class (more precisely into nested unions
> corresponding to scopes, as described in N4244), and coroutine body is
> transformed into method-state-machine, where it's states correspond to
> yield points.
> This already can be implemented via macros to some extent.
>
I think you've missed my point about object lifetime. Consider:
list_monad<int> f(list_monad<int> ints) {
{
auto x = make_shared<int>(42);
auto &r = x;
int y = await ints; // #1, suppose this behaves like a list monad
cout << *r + y;
} // #2
return 0;
}
No matter how you transform this into a class, it won't actually work (and
rightly so): the lifetime of the x object ends the first time line #2 is
reached. When you try to resume at line #1, there's no way to bring x back
to life again. Now, you might suggest that the way to solve this is to make
a copy of the monad state at the point where we hit the 'await', so you can
"safely" resume it multiple times. But that doesn't work either: your
copy's 'r' would refer to the original's 'x' (whose lifetime has ended),
not to the copy's 'x'.
Moreover, C#'s await is implemented based on similar approach:
> http://www.codeproject.com/Articles/535635/Async-Await-and-the-Generated-StateMachine
The implementation approach is fine for coroutines (C#'s await doesn't
support the list monad / continuations), but doesn't work for the full
generality of monads in a system with mutable state.
--
---
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/.
--001a11438a8e7859710521edaf7a
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><div class=3D"gmail_extra"><div class=3D"gmail_quote">On M=
on, Oct 12, 2015 at 12:19 PM, Evgeny Panasyuk <span dir=3D"ltr"><<a href=
=3D"mailto:evgeny.panasyuk@gmail.com" target=3D"_blank">evgeny.panasyuk@gma=
il.com</a>></span> wrote:<br><blockquote class=3D"gmail_quote" style=3D"=
margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,20=
4,204);border-left-style:solid;padding-left:1ex">12.10.2015 21:46, Richard =
Smith:<span class=3D""><br>
<blockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;border-=
left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;p=
adding-left:1ex">
=C2=A0 =C2=A0 If use same underlying technique as was used at macro-based<b=
r>
=C2=A0 =C2=A0 stackless coroutines of Boost.Asio then it can work with list=
monad,<br>
=C2=A0 =C2=A0 because such coroutine is just value type which can be copied=
/moved.<br>
<br>
<br>
It doesn't really work; you can't support local variables with such=
a<br>
model, because their lifetimes could be reentered after they end.<br>
</blockquote>
<br></span>
Local variables do work with technique used by stackless coroutines of Boos=
t.Asio (and proposals like N4244).<br>
<br>
With such approach coroutine is transformed into class. Local variables are=
transformed into fields of class (more precisely into nested unions corres=
ponding to scopes, as described in N4244), and coroutine body is transforme=
d into method-state-machine, where it's states correspond to yield poin=
ts.<br>
This already can be implemented via macros to some extent.<br></blockquote>=
<div><br></div><div>I think you've missed my point about object lifetim=
e. Consider:</div><div><br></div><div>list_monad<int> f(list_monad<=
;int> ints) {</div><div>=C2=A0 {<br></div><div>=C2=A0 =C2=A0 auto x =3D =
make_shared<int>(42);<br></div><div>=C2=A0 =C2=A0 auto &r =3D x;<=
/div><div>=C2=A0 =C2=A0 int y =3D await ints; // #1, suppose this behaves l=
ike a list monad<br></div><div>=C2=A0 =C2=A0 cout << *r + y;</div><di=
v>=C2=A0 } // #2</div><div>=C2=A0 return 0;</div><div>}<br></div><div><br><=
/div><div>No matter how you transform this into a class, it won't actua=
lly work (and rightly so): the lifetime of the x object ends the first time=
line #2 is reached. When you try to resume at line #1, there's no way =
to bring x back to life again. Now, you might suggest that the way to solve=
this is to make a copy of the monad state at the point where we hit the &#=
39;await', so you can "safely" resume it multiple times. But =
that doesn't work either: your copy's 'r' would refer to th=
e original's 'x' (whose lifetime has ended), not to the copy=
9;s 'x'.</div><div><br></div><blockquote class=3D"gmail_quote" styl=
e=3D"margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(2=
04,204,204);border-left-style:solid;padding-left:1ex">
Moreover, C#'s await is implemented based on similar approach: <a href=
=3D"http://www.codeproject.com/Articles/535635/Async-Await-and-the-Generate=
d-StateMachine" rel=3D"noreferrer" target=3D"_blank">http://www.codeproject=
..com/Articles/535635/Async-Await-and-the-Generated-StateMachine</a></blockq=
uote><div><br></div><div>The implementation approach is fine for coroutines=
(C#'s await doesn't support the list monad / continuations), but d=
oesn't work for the full generality of monads in a system with mutable =
state.</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 />
--001a11438a8e7859710521edaf7a--
.
Author: Richard Smith <richard@metafoo.co.uk>
Date: Mon, 12 Oct 2015 12:59:26 -0700
Raw View
--001a114391283726880521edc412
Content-Type: text/plain; charset=UTF-8
On Mon, Oct 12, 2015 at 12:30 PM, Gor Nishanov <gornishanov@gmail.com>
wrote:
> Evgeny:
>
> Note the "purity" word in Richard's answer.
> If you write a body of the coroutine in a pure manner, you can hack P0057
> and in your await_suspend for the list monad resume the coroutine multiple
> times.
> You need to provide proper final_suspend and return_value to make it work.
> But it will work ONLY if your body is pure :-). That is the body of your
> coroutine. And you cannot save any state in the awaiter, since it is torn
> down at the end of the full expressions, hence, I am using thread_local to
> ferry a value from await_suspend to await_resume.
>
> Here is "do not try this at home" awaiter for the list<T>. Untested. Just
> an idea of how it can look like.
>
> auto operator await(list<T> const& l) {
> struct awaiter {
> list<T> const * list_;
>
> static thread_local T* result_;
>
> bool await_ready() { return false; }
>
> void await_suspend(coroutine_handle<> h) {
> auto l = list_;
> for (auto && item : *l) { result_ = &item; h.resume(); }
>
For this to work, I think you'd need your coroutine to (somehow) repeatedly
await the list item. That is, instead of:
list_monad<int> foo(list_monad<int> v) {
int x = await v;
return x * x;
}
.... you'd need to write:
list_monad<int> foo(list_monad<int> v) {
loop:
int x = await v;
// somehow return x * x then conditionally goto loop.
}
.... because you don't have any kind of call/cc primitive.
--
---
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/.
--001a114391283726880521edc412
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><div class=3D"gmail_extra"><div class=3D"gmail_quote">On M=
on, Oct 12, 2015 at 12:30 PM, Gor Nishanov <span dir=3D"ltr"><<a href=3D=
"mailto:gornishanov@gmail.com" target=3D"_blank">gornishanov@gmail.com</a>&=
gt;</span> wrote:<br><blockquote class=3D"gmail_quote" style=3D"margin:0px =
0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);bord=
er-left-style:solid;padding-left:1ex"><div dir=3D"ltr">Evgeny:<div><br></di=
v><div>Note the "purity" word in Richard's answer.</div><div>=
If you write a body of the coroutine in a pure manner, you can hack P0057 a=
nd in your await_suspend for the list monad resume the coroutine multiple t=
imes.</div><div>You need to provide proper final_suspend and return_value t=
o make it work. But it will work ONLY if your body is pure :-). That is the=
body of your coroutine. And you cannot save any state in the awaiter, sinc=
e it is torn down at the end of the full expressions, hence, I am using thr=
ead_local to ferry a value from await_suspend to await_resume.</div><div><b=
r></div><div>Here is "do not try this at home" awaiter for the li=
st<T>. Untested. Just an idea of how it can look like.</div><div><br>=
</div><div><div style=3D"border:1px solid rgb(187,187,187);word-wrap:break-=
word;background-color:rgb(250,250,250)"><code><div><span style=3D"color:rgb=
(0,0,136)">auto</span><span style=3D"color:rgb(0,0,0)"> </span><span style=
=3D"color:rgb(0,0,136)">operator</span><span style=3D"color:rgb(0,0,0)"> aw=
ait</span><span style=3D"color:rgb(102,102,0)">(</span><span style=3D"color=
:rgb(0,0,0)">list</span><span style=3D"color:rgb(102,102,0)"><</span><sp=
an style=3D"color:rgb(0,0,0)">T</span><span style=3D"color:rgb(102,102,0)">=
></span><span style=3D"color:rgb(0,0,0)"> </span><span style=3D"color:rg=
b(0,0,136)">const</span><span style=3D"color:rgb(102,102,0)">&</span><s=
pan style=3D"color:rgb(0,0,0)"> l</span><span style=3D"color:rgb(102,102,0)=
">)</span><span style=3D"color:rgb(0,0,0)"> </span><span style=3D"color:rgb=
(102,102,0)">{</span><span style=3D"color:rgb(0,0,0)"><br>=C2=A0 </span><sp=
an style=3D"color:rgb(0,0,136)">struct</span><span style=3D"color:rgb(0,0,0=
)"> awaiter </span><span style=3D"color:rgb(102,102,0)">{</span><span style=
=3D"color:rgb(0,0,0)"> <br>=C2=A0 =C2=A0 list</span><span style=3D"color:rg=
b(102,102,0)"><</span><span style=3D"color:rgb(0,0,0)">T</span><span sty=
le=3D"color:rgb(102,102,0)">></span><span style=3D"color:rgb(0,0,0)"> </=
span><span style=3D"color:rgb(0,0,136)">const</span><span style=3D"color:rg=
b(0,0,0)"> </span><span style=3D"color:rgb(102,102,0)">*</span><span style=
=3D"color:rgb(0,0,0)"> list_</span><span style=3D"color:rgb(102,102,0)">;</=
span><span style=3D"color:rgb(0,0,0)"> <br><br>=C2=A0 =C2=A0 </span><span s=
tyle=3D"color:rgb(0,0,136)">static</span><span style=3D"color:rgb(0,0,0)"> =
thread_local T</span><span style=3D"color:rgb(102,102,0)">*</span><span sty=
le=3D"color:rgb(0,0,0)"> result_</span><span style=3D"color:rgb(102,102,0)"=
>;</span><span style=3D"color:rgb(0,0,0)"> <br><br>=C2=A0 =C2=A0 </span><sp=
an style=3D"color:rgb(0,0,136)">bool</span><span style=3D"color:rgb(0,0,0)"=
> await_ready</span><span style=3D"color:rgb(102,102,0)">()</span><span sty=
le=3D"color:rgb(0,0,0)"> </span><span style=3D"color:rgb(102,102,0)">{</spa=
n><span style=3D"color:rgb(0,0,0)"> </span><span style=3D"color:rgb(0,0,136=
)">return</span><span style=3D"color:rgb(0,0,0)"> </span><span style=3D"col=
or:rgb(0,0,136)">false</span><span style=3D"color:rgb(102,102,0)">;</span><=
span style=3D"color:rgb(0,0,0)"> </span><span style=3D"color:rgb(102,102,0)=
">}</span><span style=3D"color:rgb(0,0,0)"> <br><br>=C2=A0 =C2=A0 </span><s=
pan style=3D"color:rgb(0,0,136)">void</span><span style=3D"color:rgb(0,0,0)=
"> await_suspend</span><span style=3D"color:rgb(102,102,0)">(</span><span s=
tyle=3D"color:rgb(0,0,0)">coroutine_handle</span><span style=3D"color:rgb(1=
02,102,0)"><></span><span style=3D"color:rgb(0,0,0)"> h</span><span s=
tyle=3D"color:rgb(102,102,0)">)</span><span style=3D"color:rgb(0,0,0)"> </s=
pan><span style=3D"color:rgb(102,102,0)">{</span><span style=3D"color:rgb(0=
,0,0)"> <br>=C2=A0 =C2=A0 =C2=A0 =C2=A0</span><span style=3D"color:rgb(0,0,=
136)">auto</span><span style=3D"color:rgb(0,0,0)"> l </span><span style=3D"=
color:rgb(102,102,0)">=3D</span><span style=3D"color:rgb(0,0,0)"> list_</sp=
an><span style=3D"color:rgb(102,102,0)">;</span><span style=3D"color:rgb(0,=
0,0)"> <br>=C2=A0 =C2=A0 =C2=A0 =C2=A0</span><span style=3D"color:rgb(0,0,1=
36)">for</span><span style=3D"color:rgb(0,0,0)"> </span><span style=3D"colo=
r:rgb(102,102,0)">(</span><span style=3D"color:rgb(0,0,136)">auto</span><sp=
an style=3D"color:rgb(0,0,0)"> </span><span style=3D"color:rgb(102,102,0)">=
&&</span><span style=3D"color:rgb(0,0,0)"> item </span><span style=
=3D"color:rgb(102,102,0)">:</span><span style=3D"color:rgb(0,0,0)"> </span>=
<span style=3D"color:rgb(102,102,0)">*</span><span style=3D"color:rgb(0,0,0=
)">l</span><span style=3D"color:rgb(102,102,0)">)</span><span style=3D"colo=
r:rgb(0,0,0)"> </span><span style=3D"color:rgb(102,102,0)">{</span><span st=
yle=3D"color:rgb(0,0,0)"> result_ </span><span style=3D"color:rgb(102,102,0=
)">=3D</span><span style=3D"color:rgb(0,0,0)"> </span><span style=3D"color:=
rgb(102,102,0)">&</span><span style=3D"color:rgb(0,0,0)">item</span><sp=
an style=3D"color:rgb(102,102,0)">;</span><span style=3D"color:rgb(0,0,0)">=
h</span><span style=3D"color:rgb(102,102,0)">.</span><span style=3D"color:=
rgb(0,0,0)">resume</span><span style=3D"color:rgb(102,102,0)">();</span><sp=
an style=3D"color:rgb(0,0,0)"> </span><span style=3D"color:rgb(102,102,0)">=
}</span><span style=3D"color:rgb(0,0,0)"> <br></span></div></code></div></d=
iv></div></blockquote><div><br></div><div>For this to work, I think you'=
;d need your coroutine to (somehow) repeatedly await the list item. That is=
, instead of:</div><div><br></div><div>list_monad<int> foo(list_monad=
<int> v) {</div><div>=C2=A0 int x =3D await v;</div><div>=C2=A0 retur=
n x * x;</div><div>}</div><div><br></div><div>... you'd need to write:<=
/div><div><br></div><div><div>list_monad<int> foo(list_monad<int&g=
t; v) {</div><div>loop:</div><div>=C2=A0 int x =3D await v;</div><div>=C2=
=A0 // somehow return x * x then conditionally goto loop.</div><div>}</div>=
</div><div><br></div><div>... because you don't have any kind of call/c=
c primitive.</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 />
--001a114391283726880521edc412--
.
Author: Gor Nishanov <gornishanov@gmail.com>
Date: Mon, 12 Oct 2015 13:24:56 -0700 (PDT)
Raw View
------=_Part_48_1785608203.1444681496180
Content-Type: multipart/alternative;
boundary="----=_Part_49_960723718.1444681496180"
------=_Part_49_960723718.1444681496180
Content-Type: text/plain; charset=UTF-8
>
> ... you'd need to write:
>
> list_monad<int> foo(list_monad<int> v) {
> loop:
> int x = await v;
> // somehow return x * x then conditionally goto loop.
> }
>
> ... because you don't have any kind of call/cc primitive.
>
Yep. You are are right. Without "checkpointing" of the coroutine state you
would need a loop. But if you had :-) checkpointing, then:
Maybe this:
void await_suspend(coroutine_handle<> h) {
auto l = list_;
auto checkpoint = h.checkpoint();
for (auto && item : *l) { result_ = &item; h.resume(); h.load(
checkpoint); }
// add code to extract the result from the promise and do something
with it.
}
For "pure" functions checkpointing is cheap. The only state they have is
which suspend point they are at.
In no way I am suggesting that we are going to do checkpointing. Just
geeking out.
--
---
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_49_960723718.1444681496180
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><blockquote class=3D"gmail_quote" style=3D"margin: 0;margi=
n-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"l=
tr"><div><div class=3D"gmail_quote"><div>... you'd need to write:</div>=
<div><br></div><div><div>list_monad<int> foo(list_monad<int> v)=
{</div><div>loop:</div><div>=C2=A0 int x =3D await v;</div><div>=C2=A0 // =
somehow return x * x then conditionally goto loop.</div><div>}</div></div><=
div><br></div><div>... because you don't have any kind of call/cc primi=
tive.</div></div></div></div></blockquote><div><br></div><div>Yep. You are =
are right. Without "checkpointing" of the coroutine state you wou=
ld need a loop. But if you had :-) checkpointing, then:</div><div>Maybe thi=
s:</div><div><br></div><div class=3D"prettyprint" style=3D"border: 1px soli=
d rgb(187, 187, 187); word-wrap: break-word; background-color: rgb(250, 250=
, 250);"><code class=3D"prettyprint"><div class=3D"subprettyprint"><span st=
yle=3D"color: #000;" class=3D"styled-by-prettify">=C2=A0 =C2=A0 </span><spa=
n style=3D"color: #008;" class=3D"styled-by-prettify">void</span><span styl=
e=3D"color: #000;" class=3D"styled-by-prettify"> await_suspend</span><span =
style=3D"color: #660;" class=3D"styled-by-prettify">(</span><span style=3D"=
color: #000;" class=3D"styled-by-prettify">coroutine_handle</span><span sty=
le=3D"color: #660;" class=3D"styled-by-prettify"><></span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"> h</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"styled-b=
y-prettify"> <br>=C2=A0 =C2=A0 =C2=A0 =C2=A0</span><span style=3D"color: #0=
08;" class=3D"styled-by-prettify">auto</span><span style=3D"color: #000;" c=
lass=3D"styled-by-prettify"> l </span><span style=3D"color: #660;" class=3D=
"styled-by-prettify">=3D</span><span style=3D"color: #000;" class=3D"styled=
-by-prettify"> list_</span><span style=3D"color: #660;" class=3D"styled-by-=
prettify">;</span><span style=3D"color: #000;" class=3D"styled-by-prettify"=
><br>=C2=A0 =C2=A0 =C2=A0 =C2=A0</span><span style=3D"color: #008;" class=
=3D"styled-by-prettify">auto</span><span style=3D"color: #000;" class=3D"st=
yled-by-prettify"> checkpoint </span><span style=3D"color: #660;" class=3D"=
styled-by-prettify">=3D</span><span style=3D"color: #000;" class=3D"styled-=
by-prettify"> h</span><span style=3D"color: #660;" class=3D"styled-by-prett=
ify">.</span><span style=3D"color: #000;" class=3D"styled-by-prettify">chec=
kpoint</span><span style=3D"color: #660;" class=3D"styled-by-prettify">();<=
/span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br>=C2=A0 =
=C2=A0 =C2=A0 =C2=A0</span><span style=3D"color: #008;" class=3D"styled-by-=
prettify">for</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: #008;" class=3D"styled-by-prettify">auto</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"> item </span><span style=3D"=
color: #660;" class=3D"styled-by-prettify">:</span><span style=3D"color: #0=
00;" class=3D"styled-by-prettify"> </span><span style=3D"color: #660;" clas=
s=3D"styled-by-prettify">*</span><span style=3D"color: #000;" class=3D"styl=
ed-by-prettify">l</span><span style=3D"color: #660;" class=3D"styled-by-pre=
ttify">)</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> <=
/span><span style=3D"color: #660;" class=3D"styled-by-prettify">{</span><sp=
an style=3D"color: #000;" class=3D"styled-by-prettify"> result_ </span><spa=
n style=3D"color: #660;" class=3D"styled-by-prettify">=3D</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color=
: #660;" class=3D"styled-by-prettify">&</span><span style=3D"color: #00=
0;" class=3D"styled-by-prettify">item</span><span style=3D"color: #660;" cl=
ass=3D"styled-by-prettify">;</span><span style=3D"color: #000;" class=3D"st=
yled-by-prettify"> h</span><span style=3D"color: #660;" class=3D"styled-by-=
prettify">.</span><span style=3D"color: #000;" class=3D"styled-by-prettify"=
>resume</span><span style=3D"color: #660;" class=3D"styled-by-prettify">();=
</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> h</span><=
span style=3D"color: #660;" class=3D"styled-by-prettify">.</span><span styl=
e=3D"color: #000;" class=3D"styled-by-prettify">load</span><span style=3D"c=
olor: #660;" class=3D"styled-by-prettify">(</span><span style=3D"color: #00=
0;" class=3D"styled-by-prettify">checkpoint</span><span style=3D"color: #66=
0;" 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: #800;" =
class=3D"styled-by-prettify">// add code to extract the result from the pro=
mise and do something with it. </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></div></code></div><div><br></div><div>For &=
quot;pure" functions checkpointing is cheap. The only state they have =
is which suspend point they are at.</div><div>In no way I am suggesting tha=
t we are going to do checkpointing. Just geeking out.<br><span style=3D"fon=
t-family: monospace; color: rgb(102, 102, 0); background-color: rgb(250, 25=
0, 250);"><br></span></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_49_960723718.1444681496180--
------=_Part_48_1785608203.1444681496180--
.
Author: Evgeny Panasyuk <evgeny.panasyuk@gmail.com>
Date: Tue, 13 Oct 2015 00:08:15 +0300
Raw View
12.10.2015 22:53, Richard Smith:
>
> I think you've missed my point about object lifetime. Consider:
>
> list_monad<int> f(list_monad<int> ints) {
>
> No matter how you transform this into a class, it won't actually work
> (and rightly so): the lifetime of the x object ends the first time line
> #2 is reached. When you try to resume at line #1, there's no way to
> bring x back to life again. Now, you might suggest that the way to solve
> this is to make a copy of the monad state at the point where we hit the
> 'await', so you can "safely" resume it multiple times. But that doesn't
> work either: your copy's 'r' would refer to the original's 'x' (whose
> lifetime has ended), not to the copy's 'x'.
Thank you for detailed description, I get your point.
I am aware of this issue, and I agree that it can lead to subtle bugs -
because such code works in unintuitive/unaccustomed manner.
Nevertheless, I don't think that possibility of such bugs makes whole
approach non-usable. I think it is acceptable price for performance and
generality/features/power it provides.
C++ was never a defensive language.
For instance I want to use non-owning raw pointers, and I accept the
price of increased possibility of memory corruption. And if one needs
higher defensiveness - it is possible to use shared/weak_ptr in
casual/wasteful manner.
Same applies here - I want to copy/move/fork/serialize/etc coroutines,
and I agree to pay for possibility of problems with locals lifetime
issues. But if someone would like to avoid such issues, and do not need
fork/etc - then he could use non-copyable non-movable coroutines
allocated on heaps.
>
> Moreover, C#'s await is implemented based on similar approach:
> http://www.codeproject.com/Articles/535635/Async-Await-and-the-Generated-StateMachine
>
>
> The implementation approach is fine for coroutines (C#'s await doesn't
> support the list monad / continuations),
Yes, C# await doesn't support copy of state (at least in straightforward
way).
My point here is that approach based on such kind of transformation
(coroutine body into method-state-machine, locals to class fields) is
already implemented and used in one of mainstream languages.
> but doesn't work for the full
> generality of monads in a system with mutable state.
Why? As I can see copying of coroutine is similar to call/cc, which in
turn is somewhat dual to monads.
By the way, I did an example sometime ago how to use call/cc to get
"monadic flow", including List monad: http://ideone.com/7uOVe2
--
---
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: Gor Nishanov <gornishanov@gmail.com>
Date: Mon, 12 Oct 2015 15:18:24 -0700 (PDT)
Raw View
------=_Part_6558_1284308517.1444688304233
Content-Type: multipart/alternative;
boundary="----=_Part_6559_1090410128.1444688304233"
------=_Part_6559_1090410128.1444688304233
Content-Type: text/plain; charset=UTF-8
On Monday, October 12, 2015 at 2:08:21 PM UTC-7, Evgeny Panasyuk wrote:
>
> Same applies here - I want to copy/move/fork/serialize/etc coroutines,
> and I agree to pay for possibility of problems with locals lifetime
> issues.
Write a proposal. It is trivial to add, clone(), checkpoint(), save(),
restore() members to coroutine_handle<>. Coroutine handle is just a
pointer to a blob of memory representing the current state of the coroutine.
In fact, you can probably hack it up today using VS 2015 RTM, by providing
your own allocator and learning the size and location of the memory block
representing the coroutine state. Once you now it, you can pretty much do
whatever you want with 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.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.
------=_Part_6559_1090410128.1444688304233
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><br><br>On Monday, October 12, 2015 at 2:08:21 PM UTC-7, E=
vgeny Panasyuk wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;m=
argin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">Same appl=
ies here - I want to copy/move/fork/serialize/etc coroutines,=20
<br>and I agree to pay for possibility of problems with locals lifetime=20
<br>issues. </blockquote><div><br></div><div>Write a proposal. It is trivia=
l to add, clone(), checkpoint(), save(), restore() members to coroutine_han=
dle<>. =C2=A0Coroutine handle is just a pointer to a blob of memory r=
epresenting the current state of the coroutine.</div><div><br></div><div>In=
fact, you can probably hack it up today using VS 2015 RTM, by providing yo=
ur own allocator and learning the size and location of the memory block rep=
resenting the coroutine state. Once you now it, you can pretty much do what=
ever you want with it.=C2=A0</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_6559_1090410128.1444688304233--
------=_Part_6558_1284308517.1444688304233--
.
Author: Evgeny Panasyuk <evgeny.panasyuk@gmail.com>
Date: Tue, 13 Oct 2015 01:47:17 +0300
Raw View
13.10.2015 1:18, Gor Nishanov:
> Same applies here - I want to copy/move/fork/serialize/etc coroutines,
> and I agree to pay for possibility of problems with locals lifetime
> issues.
> Write a proposal. It is trivial to add, clone(), checkpoint(), save(),
> restore() members to coroutine_handle<>. Coroutine handle is just a
> pointer to a blob of memory representing the current state of the coroutine.
My main concern about P0057R0 is type-erasure - it is far from being
zero-overhead.
And as I can see - stackless coroutine can be implemented without such
type-erasure. It's size is known at compile-time - and it can be just
normal type with all data contained within it's sizeof - there is no
need for any special allocation/deallocation of "remote" parts.
> In fact, you can probably hack it up today using VS 2015 RTM, by
> providing your own allocator and learning the size and location of the
> memory block representing the coroutine state. Once you now it, you can
> pretty much do whatever you want with it.
Well, same is possible with stackful coroutines and even with threads.
But it is just chunk of raw bits. And all type info required to do
proper copy/move (not just memcpy) is removed during compilation.
--
---
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: Gor Nishanov <gornishanov@gmail.com>
Date: Mon, 12 Oct 2015 16:03:34 -0700 (PDT)
Raw View
------=_Part_6330_1593848067.1444691014146
Content-Type: multipart/alternative;
boundary="----=_Part_6331_884847826.1444691014146"
------=_Part_6331_884847826.1444691014146
Content-Type: text/plain; charset=UTF-8
On Monday, October 12, 2015 at 3:47:24 PM UTC-7, Evgeny Panasyuk wrote:
>
> My main concern about P0057R0 is type-erasure - it is far from being
> zero-overhead.
>
I have had an outstanding challenge for a year already to anyone who thinks
that way to come up with a real world problem, reduce it to managable size
(say async_tcp_reader) write it up it both ways using P0057 and whatever
you consider zero overhead and evaluate on three criteria:
1) How much code end-user have to write
2) How much library support required
3) What is an abstraction penalty, how many instructions need to get
executed to get from, say, await Read(buf, len) to an low-level
API/hardware, say WSARecv
My statement is that P0057 is as good or better on all 3 criteria than any
other proposal I've seen. If you want to accept the challenge, write up an
equivalent to TcpReader described in one of these two presentations:
Compared to hand-crafted state machines using callbacks, P0057 has negative
overhead.
See: https://github.com/CppCon/CppCon2015/blob/master/Presentations/C%2B%2B%20Coroutines/C%2B%2B%20Coroutines%20-%20Gor%20Nishanov%20-%20CppCon%202015.pdf
or
http://open-std.org/JTC1/SC22/WG21/docs/papers/2014/n4287.pdf
--
---
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_6331_884847826.1444691014146
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><br><br>On Monday, October 12, 2015 at 3:47:24 PM UTC-7, E=
vgeny Panasyuk wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;m=
argin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">My main c=
oncern about P0057R0 is type-erasure - it is far from being=20
<br>zero-overhead.
<br></blockquote><div><br></div><div>I have had an outstanding challenge fo=
r a year already to anyone who thinks that way to come up with a real world=
problem, reduce it to managable size (say async_tcp_reader) write it up it=
both ways using P0057 and whatever you consider zero overhead and evaluate=
on three criteria:</div><div><br></div><div>1) How much code end-user have=
to write</div><div>2) How much library support required</div><div>3) What =
is an abstraction penalty, how many instructions need to get executed to ge=
t from, say, await Read(buf, len) to an low-level API/hardware, say WSARecv=
</div><div><br></div><div>My statement is that P0057 is as good or better o=
n all 3 criteria than any other proposal I've seen. If you want to acce=
pt the challenge, write up an equivalent to TcpReader described in one of t=
hese two presentations:</div><div><br></div><div>Compared to hand-crafted s=
tate machines using callbacks, P0057 has negative overhead. See:=C2=A0https=
://github.com/CppCon/CppCon2015/blob/master/Presentations/C%2B%2B%20Corouti=
nes/C%2B%2B%20Coroutines%20-%20Gor%20Nishanov%20-%20CppCon%202015.pdf</div>=
<div><br></div><div>or</div><div><br></div><div>http://open-std.org/JTC1/SC=
22/WG21/docs/papers/2014/n4287.pdf<br></div><div><br></div></div>
<p></p>
-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />
------=_Part_6331_884847826.1444691014146--
------=_Part_6330_1593848067.1444691014146--
.
Author: Evgeny Panasyuk <evgeny.panasyuk@gmail.com>
Date: Mon, 12 Oct 2015 19:28:35 -0700 (PDT)
Raw View
------=_Part_1901_324366431.1444703315415
Content-Type: multipart/alternative;
boundary="----=_Part_1902_879775368.1444703315415"
------=_Part_1902_879775368.1444703315415
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
12 oct 2015 =D0=B3., 22:30:44 UTC+3 Gor Nishanov :
>
> Evgeny:
>
> Note the "purity" word in Richard's answer.
> If you write a body of the coroutine in a pure manner, you can hack P0057=
=20
> and in your await_suspend for the list monad resume the coroutine multipl=
e=20
> times.
>
Here is an example of how it can be implemented using method-state-machine=
=20
macros :
http://coliru.stacked-crooked.com/a/a463b0a5504c7401
COROUTINE(vector<int>, list_demo, (int, param),
(int, local_x)
(int, local_y))
{
AWAIT(local_x =3D) vector<int>{1,2,3};
AWAIT(local_y =3D) vector<int>{10, 20, 30};
RETURN(local_x + local_y + param);
}
COROUTINE_END;
int main()
{
auto xs =3D list_demo{1000}();
for(auto x : xs)
cout << x << " ";
}
// Prints: 1011 1021 1031 1012 1022 1032 1013 1023 1033
There is no purity requirement, and actually coroutine body may contain=20
imperative loops.
Possible syntax with language support:
vector<int> list_demo(int param)
{
int local_x =3D await vector<int>{1,2,3};
int local_y =3D await vector<int>{10, 20, 30};
=20
return local_x + local_y + param;
}
As you can see - it is straightforward syntax transformation from=20
macro-based version.
--=20
---=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.
------=_Part_1902_879775368.1444703315415
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">12 oct 2015 =D0=B3., 22:30:44 UTC+3 Gor Nishanov :<blockqu=
ote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-left=
: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr">Evgeny:<div><br></div=
><div>Note the "purity" word in Richard's answer.</div><div>I=
f you write a body of the coroutine in a pure manner, you can hack P0057 an=
d in your await_suspend for the list monad resume the coroutine multiple ti=
mes.</div></div></blockquote><br>Here is an example of how it can be implem=
ented using method-state-machine macros :<br>http://coliru.stacked-crooked.=
com/a/a463b0a5504c7401<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: #000;" class=3D"styled=
-by-prettify">COROUTINE</span><span style=3D"color: #660;" class=3D"styled-=
by-prettify">(</span><span style=3D"color: #000;" class=3D"styled-by-pretti=
fy">vector</span><span style=3D"color: #080;" class=3D"styled-by-prettify">=
<int></span><span style=3D"color: #660;" class=3D"styled-by-prettify"=
>,</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> list_de=
mo</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: #660;" class=3D"styled-by-prettify">(</span><span style=3D"col=
or: #008;" class=3D"styled-by-prettify">int</span><span style=3D"color: #66=
0;" class=3D"styled-by-prettify">,</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"> param</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 </span><span style=3D"color: #660;" class=3D"=
styled-by-prettify">(</span><span style=3D"color: #008;" class=3D"styled-by=
-prettify">int</span><span style=3D"color: #660;" class=3D"styled-by-pretti=
fy">,</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> loca=
l_x</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">(</spa=
n><span style=3D"color: #008;" class=3D"styled-by-prettify">int</span><span=
style=3D"color: #660;" class=3D"styled-by-prettify">,</span><span style=3D=
"color: #000;" class=3D"styled-by-prettify"> local_y</span><span style=3D"c=
olor: #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 AWAIT</span><span style=3D"color: #660=
;" class=3D"styled-by-prettify">(</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify">local_x </span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">=3D)</span><span style=3D"color: #000;" class=3D"st=
yled-by-prettify"> vector</span><span style=3D"color: #080;" class=3D"style=
d-by-prettify"><int></span><span style=3D"color: #660;" class=3D"styl=
ed-by-prettify">{</span><span style=3D"color: #066;" class=3D"styled-by-pre=
ttify">1</span><span style=3D"color: #660;" class=3D"styled-by-prettify">,<=
/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: #066;" class=3D"styled-by-prettify">3</span><span style=3D"color=
: #660;" class=3D"styled-by-prettify">};</span><span style=3D"color: #000;"=
class=3D"styled-by-prettify"><br>=C2=A0 =C2=A0 AWAIT</span><span style=3D"=
color: #660;" class=3D"styled-by-prettify">(</span><span style=3D"color: #0=
00;" class=3D"styled-by-prettify">local_y </span><span style=3D"color: #660=
;" class=3D"styled-by-prettify">=3D)</span><span style=3D"color: #000;" cla=
ss=3D"styled-by-prettify"> vector</span><span style=3D"color: #080;" class=
=3D"styled-by-prettify"><int></span><span style=3D"color: #660;" clas=
s=3D"styled-by-prettify">{</span><span style=3D"color: #066;" class=3D"styl=
ed-by-prettify">10</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">20</span><=
span style=3D"color: #660;" class=3D"styled-by-prettify">,</span><span styl=
e=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"colo=
r: #066;" class=3D"styled-by-prettify">30</span><span style=3D"color: #660;=
" class=3D"styled-by-prettify">};</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"><br><br>=C2=A0 =C2=A0 RETURN</span><span style=3D"c=
olor: #660;" class=3D"styled-by-prettify">(</span><span style=3D"color: #00=
0;" class=3D"styled-by-prettify">local_x </span><span style=3D"color: #660;=
" class=3D"styled-by-prettify">+</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"> local_y </span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">+</span><span style=3D"color: #000;" class=3D"style=
d-by-prettify"> param</span><span style=3D"color: #660;" class=3D"styled-by=
-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>COROUTIN=
E_END</span><span style=3D"color: #660;" class=3D"styled-by-prettify">;</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">int</span><span =
style=3D"color: #000;" class=3D"styled-by-prettify"> main</span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">()</span><span style=3D"colo=
r: #000;" class=3D"styled-by-prettify"><br></span><span style=3D"color: #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: #008=
;" class=3D"styled-by-prettify">auto</span><span style=3D"color: #000;" cla=
ss=3D"styled-by-prettify"> xs </span><span style=3D"color: #660;" class=3D"=
styled-by-prettify">=3D</span><span style=3D"color: #000;" class=3D"styled-=
by-prettify"> list_demo</span><span style=3D"color: #660;" class=3D"styled-=
by-prettify">{</span><span style=3D"color: #066;" class=3D"styled-by-pretti=
fy">1000</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"=
>for</span><span style=3D"color: #660;" class=3D"styled-by-prettify">(</spa=
n><span style=3D"color: #008;" class=3D"styled-by-prettify">auto</span><spa=
n 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"> xs</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 cout </span><span s=
tyle=3D"color: #660;" class=3D"styled-by-prettify"><<</span><span sty=
le=3D"color: #000;" class=3D"styled-by-prettify"> x </span><span style=3D"c=
olor: #660;" class=3D"styled-by-prettify"><<</span><span style=3D"col=
or: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #080;=
" 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></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: #800;" class=3D"styled-by-pretti=
fy">// Prints: 1011 1021 1031 1012 1022 1032 1013 1023 1033</span><span sty=
le=3D"color: #000;" class=3D"styled-by-prettify"><br></span></div></code></=
div><br>There is no purity requirement, and actually coroutine body may con=
tain imperative loops.<br><br>Possible syntax with language support:<br><di=
v class=3D"prettyprint" style=3D"background-color: rgb(250, 250, 250); bord=
er-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: #000;" class=3D"styled-by-prettify">vector</span><s=
pan style=3D"color: #080;" class=3D"styled-by-prettify"><int></span><=
span style=3D"color: #000;" class=3D"styled-by-prettify"> list_demo</span><=
span style=3D"color: #660;" class=3D"styled-by-prettify">(</span><span styl=
e=3D"color: #008;" class=3D"styled-by-prettify">int</span><span style=3D"co=
lor: #000;" class=3D"styled-by-prettify"> param</span><span style=3D"color:=
#660;" class=3D"styled-by-prettify">)</span><span style=3D"color: #000;" c=
lass=3D"styled-by-prettify"><br></span><span style=3D"color: #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">int</span><span style=3D"color: #000;" class=3D"sty=
led-by-prettify"> local_x </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"> await vector</span><span style=3D"color: #080;" class=3D"styled-b=
y-prettify"><int></span><span style=3D"color: #660;" class=3D"styled-=
by-prettify">{</span><span style=3D"color: #066;" class=3D"styled-by-pretti=
fy">1</span><span style=3D"color: #660;" 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: #066;" class=3D"styled-by-prettify">3</span><span style=3D"color: #6=
60;" class=3D"styled-by-prettify">};</span><span style=3D"color: #000;" cla=
ss=3D"styled-by-prettify"><br>=C2=A0 =C2=A0 </span><span style=3D"color: #0=
08;" class=3D"styled-by-prettify">int</span><span style=3D"color: #000;" cl=
ass=3D"styled-by-prettify"> local_y </span><span style=3D"color: #660;" cla=
ss=3D"styled-by-prettify">=3D</span><span style=3D"color: #000;" class=3D"s=
tyled-by-prettify"> await vector</span><span style=3D"color: #080;" class=
=3D"styled-by-prettify"><int></span><span style=3D"color: #660;" clas=
s=3D"styled-by-prettify">{</span><span style=3D"color: #066;" class=3D"styl=
ed-by-prettify">10</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">20</span><=
span style=3D"color: #660;" class=3D"styled-by-prettify">,</span><span styl=
e=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"colo=
r: #066;" class=3D"styled-by-prettify">30</span><span style=3D"color: #660;=
" class=3D"styled-by-prettify">};</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"><br>=C2=A0 =C2=A0 <br>=C2=A0 =C2=A0 </span><span st=
yle=3D"color: #008;" class=3D"styled-by-prettify">return</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"> local_x </span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">+</span><span style=3D"color=
: #000;" class=3D"styled-by-prettify"> local_y </span><span style=3D"color:=
#660;" class=3D"styled-by-prettify">+</span><span style=3D"color: #000;" c=
lass=3D"styled-by-prettify"> param</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></div></code></div>As you can see - it is straightforward =
syntax transformation from macro-based version.<br></div>
<p></p>
-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />
------=_Part_1902_879775368.1444703315415--
------=_Part_1901_324366431.1444703315415--
.
Author: =?UTF-8?Q?Germ=C3=A1n_Diago?= <germandiago@gmail.com>
Date: Tue, 13 Oct 2015 04:58:01 -0700 (PDT)
Raw View
------=_Part_2384_570217774.1444737481264
Content-Type: multipart/alternative;
boundary="----=_Part_2385_1057187320.1444737481264"
------=_Part_2385_1057187320.1444737481264
Content-Type: text/plain; charset=UTF-8
> It is intrinsically non-zero overhead, due to type-erasure/allocations.
> This fact alone is strong argument against it.
>
> This is my main concern with the proposal: type-erasure and allocations.
Seems that there are some fancy optimizations possible, but I am not sure
why we should rely on these when there are other alternatives.
> While with approach based on method-state-machine - we can get both:
> generality and performance.
>
I agree with this. On top of that I do think you can implement everything on
top of this without polluting the core language.
--
---
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_2385_1057187320.1444737481264
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><br><blockquote class=3D"gmail_quote" style=3D"margin: 0;m=
argin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">It is int=
rinsically non-zero overhead, due to type-erasure/allocations.=20
<br>This fact alone is strong argument against it.
<br>
<br></blockquote><div>This is my main concern with the proposal: type-erasu=
re and allocations.<br>Seems that there are some fancy optimizations possib=
le, but I am not sure<br>why we should rely on these when there are other a=
lternatives.<br>=C2=A0<br></div><blockquote class=3D"gmail_quote" style=3D"=
margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;=
">While with approach based on method-state-machine - we can get both:=20
<br>generality and performance.
<br></blockquote><div><br>I agree with this. On top of that I do think you =
can implement everything on<br>top of this without polluting the core langu=
age.<br><br>=C2=A0<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_2385_1057187320.1444737481264--
------=_Part_2384_570217774.1444737481264--
.
Author: Gor Nishanov <gornishanov@gmail.com>
Date: Tue, 13 Oct 2015 06:25:22 -0700 (PDT)
Raw View
------=_Part_56_1305846630.1444742722813
Content-Type: multipart/alternative;
boundary="----=_Part_57_1122194364.1444742722813"
------=_Part_57_1122194364.1444742722813
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
On Tuesday, October 13, 2015 at 4:58:01 AM UTC-7, Germ=C3=A1n Diago wrote:
>
> This is my main concern with the proposal: type-erasure and allocations.
> Seems that there are some fancy optimizations possible, but I am not sure
> why we should rely on these when there are other alternatives.
>
At the moment, there is NO alternative that can match zero-overhead of the=
=20
P0057. If you believe there is one, I offered you earlier in this thread a=
=20
way how you can validate whether you belief is true or not.
--=20
---=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.
------=_Part_57_1122194364.1444742722813
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><br><br>On Tuesday, October 13, 2015 at 4:58:01 AM UTC-7, =
Germ=C3=A1n Diago wrote:<blockquote class=3D"gmail_quote" style=3D"margin: =
0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div d=
ir=3D"ltr"><div>This is my main concern with the proposal: type-erasure and=
allocations.<br>Seems that there are some fancy optimizations possible, bu=
t I am not sure<br>why we should rely on these when there are other alterna=
tives.<br></div></div></blockquote><div><br></div><div>At the moment, there=
is NO=C2=A0alternative that can match zero-overhead of the P0057. If you b=
elieve there is one, I offered you earlier in this thread a way how you can=
validate whether you belief is true or not.</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_57_1122194364.1444742722813--
------=_Part_56_1305846630.1444742722813--
.
Author: Evgeny Panasyuk <evgeny.panasyuk@gmail.com>
Date: Wed, 14 Oct 2015 00:37:43 +0300
Raw View
13.10.2015 2:03, Gor Nishanov:
>
> My main concern about P0057R0 is type-erasure - it is far from being
> zero-overhead.
>
>
> I have had an outstanding challenge for a year already to anyone who
> thinks that way to come up with a real world problem, reduce it to
> managable size (say async_tcp_reader) write it up it both ways using
> P0057 and whatever you consider zero overhead and evaluate on three
> criteria:
Example of real world problem is generator/yield.
An extra allocation here results in significant overhead. Even if some
kind of "small object optimization" scheme is used - it is still not
zero overhead.
> 1) How much code end-user have to write
Code is very similar in both cases.
> 2) How much library support required
Nearly the same. Maybe some additional customization points.
> 3) What is an abstraction penalty, how many instructions need to get
> executed to get from, say, await Read(buf, len) to an low-level
> API/hardware, say WSARecv
Because of concrete types instead of type-erasure (and allocations) -
abstraction penalty is much lower in subset of cases, like generators.
Execution path is very similar, perhaps even less due to less indirections.
> My statement is that P0057 is as good or better on all 3 criteria than
> any other proposal I've seen. If you want to accept the challenge, write
> up an equivalent to TcpReader described in one of these two presentations:
There are use-cases where allocation is OK. For instance in case of
large structure and/or because it is moved around many times. Your
example shows exactly this. But it is not the only one use case for
stackless coroutines.
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.
.
Author: Nicol Bolas <jmckesson@gmail.com>
Date: Tue, 13 Oct 2015 15:22:39 -0700 (PDT)
Raw View
------=_Part_3781_961209670.1444774959910
Content-Type: multipart/alternative;
boundary="----=_Part_3782_700194794.1444774959910"
------=_Part_3782_700194794.1444774959910
Content-Type: text/plain; charset=UTF-8
On Tuesday, October 13, 2015 at 5:37:50 PM UTC-4, Evgeny Panasyuk wrote:
>
> 13.10.2015 2:03, Gor Nishanov:
> >
> > My main concern about P0057R0 is type-erasure - it is far from being
> > zero-overhead.
> >
> >
> > I have had an outstanding challenge for a year already to anyone who
> > thinks that way to come up with a real world problem, reduce it to
> > managable size (say async_tcp_reader) write it up it both ways using
> > P0057 and whatever you consider zero overhead and evaluate on three
> > criteria:
>
> Example of real world problem is generator/yield.
> An extra allocation here results in significant overhead. Even if some
> kind of "small object optimization" scheme is used - it is still not
> zero overhead.
>
Except that he's already proven (in this thread no less) that a good
optimizer can elide the allocation. If the compiler can reasonably *make*
it zero overhead, then it *is* zero overhead.
--
---
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_3782_700194794.1444774959910
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">On Tuesday, October 13, 2015 at 5:37:50 PM UTC-4, Evgeny P=
anasyuk wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-l=
eft: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">13.10.2015 2:03,=
Gor Nishanov:
<br>>
<br>> =C2=A0 =C2=A0 My main concern about P0057R0 is type-erasure - it i=
s far from being
<br>> =C2=A0 =C2=A0 zero-overhead.
<br>>
<br>>
<br>> I have had an outstanding challenge for a year already to anyone w=
ho
<br>> thinks that way to come up with a real world problem, reduce it to
<br>> managable size (say async_tcp_reader) write it up it both ways usi=
ng
<br>> P0057 and whatever you consider zero overhead and evaluate on thre=
e
<br>> criteria:
<br>
<br>Example of real world problem is generator/yield.
<br>An extra allocation here results in significant overhead. Even if some=
=20
<br>kind of "small object optimization" scheme is used - it is st=
ill not=20
<br>zero overhead.
<br></blockquote><div><br>Except that he's already proven (in this thre=
ad no less) that a good optimizer can elide the allocation. If the compiler=
can reasonably <i>make</i> it zero overhead, then it <i>is</i> zero overhe=
ad.</div><br></div>
<p></p>
-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />
------=_Part_3782_700194794.1444774959910--
------=_Part_3781_961209670.1444774959910--
.
Author: Evgeny Panasyuk <evgeny.panasyuk@gmail.com>
Date: Tue, 13 Oct 2015 16:45:41 -0700 (PDT)
Raw View
------=_Part_1109_1975179033.1444779941441
Content-Type: multipart/alternative;
boundary="----=_Part_1110_1975197846.1444779941441"
------=_Part_1110_1975197846.1444779941441
Content-Type: text/plain; charset=UTF-8
14.10.2015 1:22, Nicol Bolas:
>
> On Tuesday, October 13, 2015 at 5:37:50 PM UTC-4, Evgeny Panasyuk wrote:
>>
>> 13.10.2015 2:03, Gor Nishanov:
>> >
>> > My main concern about P0057R0 is type-erasure - it is far from
>> being
>> > zero-overhead.
>> >
>> >
>> > I have had an outstanding challenge for a year already to anyone who
>> > thinks that way to come up with a real world problem, reduce it to
>> > managable size (say async_tcp_reader) write it up it both ways using
>> > P0057 and whatever you consider zero overhead and evaluate on three
>> > criteria:
>>
>> Example of real world problem is generator/yield.
>> An extra allocation here results in significant overhead. Even if some
>> kind of "small object optimization" scheme is used - it is still not
>> zero overhead.
>>
>
> Except that he's already proven (in this thread no less) that a good
> optimizer can elide the allocation. If the compiler can reasonably *make*
> it zero overhead, then it *is* zero overhead.
>
>
1. It is impossible (practically) in general case.
For instance in case when we put coroutines in container, like:
vector<coroutine> x(N);
In case of coroutines with concrete types and sizeof known at compile -
this can be done within single allocation.
But if coroutine type is erased the we will have N+1 allocations in general
case - it can't be practically elided.
2. Even if consider only functions scopes - escape analysis would not give
100% guarantee for elision in every case. First of all - I think it would
hit halting problem, second - some of functions in call tree may not be
inlined for adequate reasons - and this would blind analysis.
3. This would put additional burden on implementers, and I don't see
reasonable benefits which we get for such burden.
4. C++11 has lambdas with concrete type - this ensures zero overhead, and
fits naturally into language. We don't have type-erasured closures. We can
use external type erasure like std::function when needed.
Why we should have type-erasure for stackless coroutines?
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.
------=_Part_1110_1975197846.1444779941441
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
14.10.2015 1:22, Nicol Bolas:<blockquote class=3D"gmail_quote" style=3D"mar=
gin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><=
div dir=3D"ltr">On Tuesday, October 13, 2015 at 5:37:50 PM UTC-4, Evgeny Pa=
nasyuk wrote:<blockquote class=3D"gmail_quote" style=3D"margin:0;margin-lef=
t:0.8ex;border-left:1px #ccc solid;padding-left:1ex">13.10.2015 2:03, Gor N=
ishanov:
<br>>
<br>> =C2=A0 =C2=A0 My main concern about P0057R0 is type-erasure - it i=
s far from being
<br>> =C2=A0 =C2=A0 zero-overhead.
<br>>
<br>>
<br>> I have had an outstanding challenge for a year already to anyone w=
ho
<br>> thinks that way to come up with a real world problem, reduce it to
<br>> managable size (say async_tcp_reader) write it up it both ways usi=
ng
<br>> P0057 and whatever you consider zero overhead and evaluate on thre=
e
<br>> criteria:
<br>
<br>Example of real world problem is generator/yield.
<br>An extra allocation here results in significant overhead. Even if some=
=20
<br>kind of "small object optimization" scheme is used - it is st=
ill not=20
<br>zero overhead.
<br></blockquote><div><br>Except that he's already proven (in this thre=
ad no less) that a good optimizer can elide the allocation. If the compiler=
can reasonably <i>make</i> it zero overhead, then it <i>is</i> zero overhe=
ad.</div><br></div></blockquote><div><br><br>1. It is impossible (practical=
ly) in general case.<br>For instance in case when we put coroutines in cont=
ainer, like:<br><div class=3D"prettyprint" style=3D"background-color: rgb(2=
50, 250, 250); border-color: rgb(187, 187, 187); border-style: solid; borde=
r-width: 1px; word-wrap: break-word;"><code class=3D"prettyprint"><div clas=
s=3D"subprettyprint"><span style=3D"color: #000;" class=3D"styled-by-pretti=
fy">vector</span><span style=3D"color: #080;" class=3D"styled-by-prettify">=
<coroutine></span><span style=3D"color: #000;" class=3D"styled-by-pre=
ttify"> x</span><span style=3D"color: #660;" class=3D"styled-by-prettify">(=
</span><span style=3D"color: #000;" class=3D"styled-by-prettify">N</span><s=
pan style=3D"color: #660;" class=3D"styled-by-prettify">);</span></div></co=
de></div>In case of coroutines with concrete types and sizeof known at comp=
ile - this can be done within single allocation.<br>But if coroutine type i=
s erased the we will have N+1 allocations in general case - it can't be=
practically elided.<br><br>2. Even if consider only functions scopes - esc=
ape analysis would not give 100% guarantee for elision in every case. First=
of all - I think it would hit halting problem, second - some of functions =
in call tree may not be inlined for adequate reasons - and this would blind=
analysis.<br><br>3. This would put additional burden on implementers, and =
I don't see reasonable benefits which we get for such burden.<br><br>4.=
C++11 has lambdas with concrete type - this ensures zero overhead, and fit=
s naturally into language. We don't have type-erasured closures. We can=
use external type erasure like std::function when needed.<br>Why we should=
have type-erasure for stackless coroutines?<br>=C2=A0</div>
<p></p>
-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />
------=_Part_1110_1975197846.1444779941441--
------=_Part_1109_1975179033.1444779941441--
.
Author: Gor Nishanov <gornishanov@gmail.com>
Date: Tue, 13 Oct 2015 17:03:55 -0700 (PDT)
Raw View
------=_Part_3188_520458628.1444781036332
Content-Type: multipart/alternative;
boundary="----=_Part_3189_190660412.1444781036332"
------=_Part_3189_190660412.1444781036332
Content-Type: text/plain; charset=UTF-8
Please see this thread from the last year.
https://groups.google.com/a/isocpp.org/forum/?fromgroups#!searchin/std-proposals/resumable$20lambdas/std-proposals/_ssbHm4C2t8/VnQF63au8U0J
Make sure to read to the point where Ville said: "Ouch" and what followed
afterwards.
--
---
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_3189_190660412.1444781036332
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">Please see this thread from the last year.=C2=A0<div><br><=
div><div><div>https://groups.google.com/a/isocpp.org/forum/?fromgroups#!sea=
rchin/std-proposals/resumable$20lambdas/std-proposals/_ssbHm4C2t8/VnQF63au8=
U0J</div><div><br></div></div></div></div><div>Make sure to read to the poi=
nt where Ville said: "Ouch" and what followed afterwards.</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_3189_190660412.1444781036332--
------=_Part_3188_520458628.1444781036332--
.
Author: Gor Nishanov <gornishanov@gmail.com>
Date: Tue, 13 Oct 2015 17:11:57 -0700 (PDT)
Raw View
------=_Part_8063_105748413.1444781517886
Content-Type: multipart/alternative;
boundary="----=_Part_8064_1205241062.1444781517886"
------=_Part_8064_1205241062.1444781517886
Content-Type: text/plain; charset=UTF-8
Okay. Slightly less cryptic reply. Coroutine frame must be stationary once
the coroutine starts running.
Resumable Expressions abandoned movability/copyability of the lambda* that
was present in earlier resumable lambda proposal. Due to the reasons
highlighted in the thread I linked earlier. Thus, the resumable expressions
is in exactly the same boat as P0057.
The difference is that in Resumable Expressions you must do type erasure by
hand which is difficult to eliminate.
Whereas in P0057 compiler decides whether it needs to do type erasure or
not, thus, allowing to optimize it out when unnecessary.
--
---
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_8064_1205241062.1444781517886
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">Okay. Slightly less cryptic reply. Coroutine frame must be=
stationary once the coroutine starts running.<div>Resumable Expressions ab=
andoned movability/copyability of the lambda* that was present in earlier r=
esumable lambda proposal. Due to the reasons highlighted in the thread I li=
nked earlier. Thus, the resumable expressions is in exactly the same boat a=
s P0057.</div><div><br></div><div>The difference is that in Resumable Expre=
ssions you must do type erasure by hand which is difficult to eliminate.</d=
iv><div>Whereas in P0057 compiler decides whether it needs to do type erasu=
re or not, thus, allowing to optimize it out when unnecessary.<br><br><br><=
/div></div>
<p></p>
-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />
------=_Part_8064_1205241062.1444781517886--
------=_Part_8063_105748413.1444781517886--
.
Author: Evgeny Panasyuk <evgeny.panasyuk@gmail.com>
Date: Wed, 14 Oct 2015 03:20:18 +0300
Raw View
14.10.2015 3:03, Gor Nishanov:
> Please see this thread from the last year.
>
> https://groups.google.com/a/isocpp.org/forum/?fromgroups#!searchin/std-proposals/resumable$20lambdas/std-proposals/_ssbHm4C2t8/VnQF63au8U0J
>
> Make sure to read to the point where Ville said: "Ouch" and what
> followed afterwards.
Thanks for link. I already commented on this issue in current topic:
https://groups.google.com/a/isocpp.org/d/msg/std-proposals/L5ZsY1SYnrA/kGXSVV4RDgAJ
In short, yes - I agree, it could lead to subtle bugs.
But same applies to raw non-owning pointers - they could lead to subtle
bugs too, but we still use them.
And in general: we do not ban square root just because we have negative
numbers.
--
---
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: Evgeny Panasyuk <evgeny.panasyuk@gmail.com>
Date: Wed, 14 Oct 2015 03:25:39 +0300
Raw View
14.10.2015 3:11, Gor Nishanov:
> Whereas in P0057 compiler decides whether it needs to do type erasure or
> not, thus, allowing to optimize it out when unnecessary.
What about "vector<coroutine>(N)" use case? As I can see - overhead of N
allocations can't be elided automatically.
--
---
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: Gor Nishanov <gornishanov@gmail.com>
Date: Tue, 13 Oct 2015 17:32:47 -0700 (PDT)
Raw View
------=_Part_3214_1650878581.1444782767453
Content-Type: multipart/alternative;
boundary="----=_Part_3215_1021770899.1444782767453"
------=_Part_3215_1021770899.1444782767453
Content-Type: text/plain; charset=UTF-8
You can add an ability to clone() and restore() the coroutine state on top
of either proposals.
If someone feel strongly about it, he/she can write and submit a proposal
to make it happen.
--
---
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_3215_1021770899.1444782767453
Content-Type: text/html; charset=UTF-8
<div dir="ltr"><div><div>You can add an ability to clone() and restore() the coroutine state on top of either proposals.</div><div>If someone feel strongly about it, he/she can write and submit a proposal to make it happen.</div></div></div>
<p></p>
-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an email to <a href="mailto:std-proposals+unsubscribe@isocpp.org">std-proposals+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href="mailto:std-proposals@isocpp.org">std-proposals@isocpp.org</a>.<br />
Visit this group at <a href="http://groups.google.com/a/isocpp.org/group/std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/</a>.<br />
------=_Part_3215_1021770899.1444782767453--
------=_Part_3214_1650878581.1444782767453--
.
Author: Gor Nishanov <gornishanov@gmail.com>
Date: Tue, 13 Oct 2015 17:34:34 -0700 (PDT)
Raw View
------=_Part_8197_875834854.1444782874746
Content-Type: multipart/alternative;
boundary="----=_Part_8198_683758905.1444782874746"
------=_Part_8198_683758905.1444782874746
Content-Type: text/plain; charset=UTF-8
On Tuesday, October 13, 2015 at 5:25:45 PM UTC-7, Evgeny Panasyuk wrote:
>
> What about "vector<coroutine>(N)" use case? As I can see - overhead of N
> allocations can't be elided automatically.
>
How can P0114 help you with that? Coroutine state is uncopyable and
unmovable there as well.
--
---
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_8198_683758905.1444782874746
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><br>On Tuesday, October 13, 2015 at 5:25:45 PM UTC-7, Evge=
ny Panasyuk wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;marg=
in-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">What about &=
quot;vector<coroutine>(N)" use case? As I can see - overhead of =
N=20
<br>allocations can't be elided automatically.
<br></blockquote><div><br></div><div>How can P0114 help you with that? Coro=
utine state is uncopyable and unmovable there as well.=C2=A0</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_8198_683758905.1444782874746--
------=_Part_8197_875834854.1444782874746--
.
Author: Evgeny Panasyuk <evgeny.panasyuk@gmail.com>
Date: Wed, 14 Oct 2015 03:44:44 +0300
Raw View
14.10.2015 3:32, Gor Nishanov:
> You can add an ability to clone() and restore() the coroutine state on
> top of either proposals.
> If someone feel strongly about it, he/she can write and submit a
> proposal to make it happen.
clone/restore are just desirable features. Yes, maybe they can be added
separately.
But I am talking about allocation overhead, which exists here due to
erased type - it is separate issue. If we would have erased type in ISO
- it will be there for a long time, and it would be hard to make it fix it.
For instance, I expect that generators would be fast small zero (or at
least almost zero) overhead things - for instance like transform
iterator. I do not want transform iterator which is allocated on heap.
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.
.
Author: Nicol Bolas <jmckesson@gmail.com>
Date: Tue, 13 Oct 2015 18:57:55 -0700 (PDT)
Raw View
------=_Part_6398_952166055.1444787875086
Content-Type: multipart/alternative;
boundary="----=_Part_6399_1366650080.1444787875087"
------=_Part_6399_1366650080.1444787875087
Content-Type: text/plain; charset=UTF-8
On Tuesday, October 13, 2015 at 7:45:42 PM UTC-4, Evgeny Panasyuk wrote:
>
> 14.10.2015 1:22, Nicol Bolas:
>>
>> On Tuesday, October 13, 2015 at 5:37:50 PM UTC-4, Evgeny Panasyuk wrote:
>>>
>>> 13.10.2015 2:03, Gor Nishanov:
>>> >
>>> > My main concern about P0057R0 is type-erasure - it is far from
>>> being
>>> > zero-overhead.
>>> >
>>> >
>>> > I have had an outstanding challenge for a year already to anyone who
>>> > thinks that way to come up with a real world problem, reduce it to
>>> > managable size (say async_tcp_reader) write it up it both ways using
>>> > P0057 and whatever you consider zero overhead and evaluate on three
>>> > criteria:
>>>
>>> Example of real world problem is generator/yield.
>>> An extra allocation here results in significant overhead. Even if some
>>> kind of "small object optimization" scheme is used - it is still not
>>> zero overhead.
>>>
>>
>> Except that he's already proven (in this thread no less) that a good
>> optimizer can elide the allocation. If the compiler can reasonably *make*
>> it zero overhead, then it *is* zero overhead.
>>
>>
>
> 1. It is impossible (practically) in general case.
> For instance in case when we put coroutines in container, like:
> vector<coroutine> x(N);
> In case of coroutines with concrete types and sizeof known at compile -
> this can be done within single allocation.
> But if coroutine type is erased the we will have N+1 allocations in
> general case - it can't be practically elided.
>
Ignoring the rest of the discussion on this point, I never claimed that
P0057 could guarantee elision in the case you present here. Before, you
asked about a *specific* problem, and I answered with a specific example
showing that it was elidable. What you've shown here hardly disproves my
point.
Also... how does `vector<coroutine>` make any kind of sense with regard to
P0114? The type isn't type erased, so each coroutine has its own type.
Therefore, in order to put them in a homogeneous container like `vector`,
you'll have to type-erase them. Which requires memory allocation.
At which point, your version gains *nothing* over P0057.
> 2. Even if consider only functions scopes - escape analysis would not give
> 100% guarantee for elision in every case. First of all - I think it would
> hit halting problem, second - some of functions in call tree may not be
> inlined for adequate reasons - and this would blind analysis.
>
P0114 *requires* that all resumable functions you call are inlined. If
they're not inlined, you have to manually box them (and the boxing function
is no longer resumable). Boxing involves type erasure. And as previously
stated, memory allocation.
In order for P0114 to not require the same allocations as P0057, you must
be using resumable functions directly, without boxing. So they must be
inline. And therefore, your second problem is a non-issue for comparable
cases: the compiler for the TU has access to all relevant code.
The only question that remains is this: given full inlining, where does the
optimizer break down?
Do you have any actual knowledge that it breaks down in common cases? Or
can a smart one cover 80-90% of these cases? Stop talking theory as though
this weren't an idea that has already been implemented on at least one
compiler.
> 3. This would put additional burden on implementers, and I don't see
> reasonable benefits which we get for such burden.
>
No, it doesn't. Or rather, it's the same burden, it's just in a different
place.
P0114 requires implementations to go through whole hierarchies of inline
function calls and generate types that represent their stacks. It puts a
lot of burden on implementer too; it's just in the implementation of the
feature rather than the *optimization* phase.
It's more or less the same work either way. Though admittedly, the P0114
does make it a bit easier for the compiler to see it.
4. C++11 has lambdas with concrete type - this ensures zero overhead, and
> fits naturally into language. We don't have type-erasured closures. We can
> use external type erasure like std::function when needed.
> Why we should have type-erasure for stackless coroutines?
>
Because implementing await machinery (promises, awaitable, etc) is hard
enough as it is. Adding a template on top of everything only makes things
harder.
--
---
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_6399_1366650080.1444787875087
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
On Tuesday, October 13, 2015 at 7:45:42 PM UTC-4, Evgeny Panasyuk wrote:<bl=
ockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border=
-left: 1px #ccc solid;padding-left: 1ex;">14.10.2015 1:22, Nicol Bolas:<blo=
ckquote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-le=
ft:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr">On Tuesday, October 13=
, 2015 at 5:37:50 PM UTC-4, Evgeny Panasyuk wrote:<blockquote class=3D"gmai=
l_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;pad=
ding-left:1ex">13.10.2015 2:03, Gor Nishanov:
<br>>
<br>> =C2=A0 =C2=A0 My main concern about P0057R0 is type-erasure - it i=
s far from being
<br>> =C2=A0 =C2=A0 zero-overhead.
<br>>
<br>>
<br>> I have had an outstanding challenge for a year already to anyone w=
ho
<br>> thinks that way to come up with a real world problem, reduce it to
<br>> managable size (say async_tcp_reader) write it up it both ways usi=
ng
<br>> P0057 and whatever you consider zero overhead and evaluate on thre=
e
<br>> criteria:
<br>
<br>Example of real world problem is generator/yield.
<br>An extra allocation here results in significant overhead. Even if some=
=20
<br>kind of "small object optimization" scheme is used - it is st=
ill not=20
<br>zero overhead.
<br></blockquote><div><br>Except that he's already proven (in this thre=
ad no less) that a good optimizer can elide the allocation. If the compiler=
can reasonably <i>make</i> it zero overhead, then it <i>is</i> zero overhe=
ad.</div><br></div></blockquote><div><br><br>1. It is impossible (practical=
ly) in general case.<br>For instance in case when we put coroutines in cont=
ainer, like:<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:#000">vector</span><span style=3D"color:#=
080"><coroutine></span><span style=3D"color:#000"> x</span><span styl=
e=3D"color:#660">(</span><span style=3D"color:#000">N</span><span style=3D"=
color:#660">);</span></div></code></div>In case of coroutines with concrete=
types and sizeof known at compile - this can be done within single allocat=
ion.<br>But if coroutine type is erased the we will have N+1 allocations in=
general case - it can't be practically elided.<br></div></blockquote><=
div><br>Ignoring the rest of the discussion on this point, I never claimed =
that P0057 could guarantee elision in the case you present here. Before, yo=
u asked about a <i>specific</i> problem, and I answered with a specific exa=
mple showing that it was elidable. What you've shown here hardly dispro=
ves my point.<br><br>Also... how does `vector<coroutine>` make any ki=
nd of sense with regard to P0114? The type isn't type erased, so each c=
oroutine has its own type. Therefore, in order to put them in a homogeneous=
container like `vector`, you'll have to type-erase them. Which require=
s memory allocation.<br><br>At which point, your version gains <i>nothing</=
i> over P0057.<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;">=
<div>2. Even if consider only functions scopes - escape analysis would not =
give 100% guarantee for elision in every case. First of all - I think it wo=
uld hit halting problem, second - some of functions in call tree may not be=
inlined for adequate reasons - and this would blind analysis.<br></div></b=
lockquote><div><br>P0114 <i>requires</i> that all resumable functions you c=
all are inlined. If they're not inlined, you have to manually box them =
(and the boxing function is no longer resumable). Boxing involves type eras=
ure. And as previously stated, memory allocation.<br><br>In order for P0114=
to not require the same allocations as P0057, you must be using resumable =
functions directly, without boxing. So they must be inline. And therefore, =
your second problem is a non-issue for comparable cases: the compiler for t=
he TU has access to all relevant code.<br><br>The only question that remain=
s is this: given full inlining, where does the optimizer break down?<br><br=
>Do you have any actual knowledge that it breaks down in common cases? Or c=
an a smart one cover 80-90% of these cases? Stop talking theory as though t=
his weren't an idea that has already been implemented on at least one c=
ompiler.<br>=C2=A0<br></div><blockquote class=3D"gmail_quote" style=3D"marg=
in: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><d=
iv>3. This would put additional burden on implementers, and I don't see=
reasonable benefits which we get for such burden.<br></div></blockquote><d=
iv><br>No, it doesn't. Or rather, it's the same burden, it's ju=
st in a different place.<br><br>P0114 requires implementations to go throug=
h whole hierarchies of inline function calls and generate types that repres=
ent their stacks. It puts a lot of burden on implementer too; it's just=
in the implementation of the feature rather than the <i>optimization</i> p=
hase.<br><br>It's more or less the same work either way. Though admitte=
dly, the P0114 does make it a bit easier for the compiler to see it.<br><br=
></div><blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.=
8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div>4. C++11 has lambd=
as with concrete type - this ensures zero overhead, and fits naturally into=
language. We don't have type-erasured closures. We can use external ty=
pe erasure like std::function when needed.<br>Why we should have type-erasu=
re for stackless coroutines?<br></div></blockquote><div><br>Because impleme=
nting await machinery (promises, awaitable, etc) is hard enough as it is. A=
dding a template on top of everything only makes things harder.<br></div>
<p></p>
-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />
------=_Part_6399_1366650080.1444787875087--
------=_Part_6398_952166055.1444787875086--
.
Author: Evgeny Panasyuk <evgeny.panasyuk@gmail.com>
Date: Wed, 14 Oct 2015 05:18:36 +0300
Raw View
14.10.2015 3:34, Gor Nishanov:
>
> On Tuesday, October 13, 2015 at 5:25:45 PM UTC-7, Evgeny Panasyuk wrote:
>
> What about "vector<coroutine>(N)" use case? As I can see - overhead
> of N
> allocations can't be elided automatically.
>
>
> How can P0114 help you with that? Coroutine state is uncopyable and
> unmovable there as well.
It does not erase type:
"
No hidden memory allocations. The memory representation of a resumable
expression can be wherever you need it: on the stack, a global, or a
member of a possibly heap-allocated object.
"
And there is possibility for copyability:
"
10.1 Allowing copyability
By allowing copyability of resumable objects, we enable interesting use
cases such as undo stacks. Although this behaviour comes with risk
associated with aliasing of local variables, an explicit opt in may be
feasible.
"
But, even if there would be no copyability/moveability, and as the
result we cannot use std::vector - we still can place N coroutines into
array with single allocation: make_unique<coroutine[]>(N)
--
---
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: Gor Nishanov <gornishanov@gmail.com>
Date: Tue, 13 Oct 2015 19:31:33 -0700 (PDT)
Raw View
------=_Part_225_539591925.1444789894099
Content-Type: multipart/alternative;
boundary="----=_Part_226_1357669275.1444789894100"
------=_Part_226_1357669275.1444789894100
Content-Type: text/plain; charset=UTF-8
On Tuesday, October 13, 2015 at 7:18:44 PM UTC-7, Evgeny Panasyuk wrote:
>
>
> It does not erase type:
>
It forces you to do it by hand, as you can see this in both generator and
async examples. The key is it requires stationary frame and for that you
either need to heap allocate or keep the lifetime of the coroutine fully
enclosed in the lifetime of its consumer. Exactly the same case where heap
elision is done.
> But, even if there would be no copyability/moveability, and as the
> result we cannot use std::vector - we still can place N coroutines into
> array with single allocation: make_unique<coroutine[]>(N)
>
P0057 allows you to customize allocation, thus you can achieve the same
goal, but with different means.
I do not claim that feature lists are identical for P0057 and P0114. I
claim that for a complicated problem, like async programming, for example,
P0057 solution will results in:
1) less user written code
2) less library support code
3) less abstraction overhead (see TcpReader, for example)
Than a solution to the same problem in P0114.
If you want to argue superiority of P0114, pick a problem (hint, hint async
programming) write a solution, compare with equivalent of P0057.
--
---
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_226_1357669275.1444789894100
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><br>On Tuesday, October 13, 2015 at 7:18:44 PM UTC-7, Evge=
ny Panasyuk wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;marg=
in-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><br>It does =
not erase type:
<br></blockquote><div><br></div><div>It forces you to do it by hand, as you=
can see this in both generator and async examples. The key is it requires =
stationary frame and for that you either need to heap allocate or keep the =
lifetime of the coroutine fully enclosed in the lifetime of its consumer. E=
xactly the same case where heap elision is done.</div><div>=C2=A0</div><blo=
ckquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-=
left: 1px #ccc solid;padding-left: 1ex;">But, even if there would be no cop=
yability/moveability, and as the=20
<br>result we cannot use std::vector - we still can place N coroutines into=
=20
<br>array with single allocation: make_unique<coroutine[]>(N)
<br></blockquote><div><br></div><div>P0057 allows you to customize allocati=
on, thus you can achieve the same goal, but with different means.</div><div=
>I do not claim that feature lists are identical for P0057 and P0114. I cla=
im that for a complicated problem, like async programming, for example,</di=
v><div><br></div><div>P0057 solution will results in:</div><div><br></div><=
div>1) less user written code</div><div>2) less library support code</div><=
div>3) less abstraction overhead (see TcpReader, for example)</div><div><br=
></div><div>Than a solution to the same problem in P0114.</div><div>If you =
want to argue superiority of P0114, pick a problem (hint, hint async progra=
mming) write a solution, compare with equivalent of P0057.</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_226_1357669275.1444789894100--
------=_Part_225_539591925.1444789894099--
.
Author: Evgeny Panasyuk <evgeny.panasyuk@gmail.com>
Date: Wed, 14 Oct 2015 06:17:43 +0300
Raw View
14.10.2015 4:57, Nicol Bolas:
> Except that he's already proven (in this thread no less) that a
> good optimizer can elide the allocation. If the compiler can
> reasonably /make/ it zero overhead, then it /is/ zero overhead.
>
>
>
> 1. It is impossible (practically) in general case.
> For instance in case when we put coroutines in container, like:
> |
> vector<coroutine>x(N);
> |
> In case of coroutines with concrete types and sizeof known at
> compile - this can be done within single allocation.
> But if coroutine type is erased the we will have N+1 allocations in
> general case - it can't be practically elided.
>
>
> Ignoring the rest of the discussion on this point, I never claimed that
> P0057 could guarantee elision in the case you present here. Before, you
> asked about a /specific/ problem, and I answered with a specific example
> showing that it was elidable. What you've shown here hardly disproves my
> point.
It is not zero overhead even with good optimizer/compiler, because they
can't elide every allocation, and I am not talking about some exotic cases.
>
> Also... how does `vector<coroutine>` make any kind of sense with regard
> to P0114? The type isn't type erased, so each coroutine has its own
> type. Therefore, in order to put them in a homogeneous container like
> `vector`, you'll have to type-erase them. Which requires memory allocation.
> At which point, your version gains /nothing/ over P0057.
Same coroutines have same concrete types. For instance, with P0114 it
may be:
|
struct concrete_coroutine
{
resumable auto r = expression;
// ...
};
....
make_unique<concrete_coroutine[]>(N);
|
For example, imagine some kind of TCP server, coroutine for each
incoming connection does same job, has same locals, and as the
consequence they have same type.
LIVE DEMO using macro-based stackless coroutines from Boost.Asio:
http://coliru.stacked-crooked.com/a/0c09744abd5e57ae
>
> 2. Even if consider only functions scopes - escape analysis would
> not give 100% guarantee for elision in every case. First of all - I
> think it would hit halting problem, second - some of functions in
> call tree may not be inlined for adequate reasons - and this would
> blind analysis.
>
>
> P0114 /requires/ that all resumable functions you call are inlined. If
> they're not inlined, you have to manually box them (and the boxing
> function is no longer resumable). Boxing involves type erasure. And as
> previously stated, memory allocation.
>
> In order for P0114 to not require the same allocations as P0057, you
> must be using resumable functions directly, without boxing. So they must
> be inline. And therefore, your second problem is a non-issue for
> comparable cases: the compiler for the TU has access to all relevant
code.
It requires inlining of resumable things which are inside body of
resumable functions.
Outside of resumable context you can .resume() coroutine without inlining.
>
> The only question that remains is this: given full inlining, where does
> the optimizer break down?
For instance, when you store coroutine in some container, not an unusual
case.
> Stop talking theory as
> though this weren't an idea that has already been implemented on at
> least one compiler.
I am not talking specifically about P0114. I am talking about stackless
coroutines with concrete non-type-erased types.
And this is already implementable in macro-library form. I already
showed several examples in current topic, even await for List Monad. And
these example are live - you can test them - modify and recompile it
with your browser just by several mouse clicks - it is not just a
theory, it is proven to work approach.
>
> 3. This would put additional burden on implementers, and I don't see
> reasonable benefits which we get for such burden.
>
>
> No, it doesn't. Or rather, it's the same burden, it's just in a
> different place.
It is not the same burden. Stackless coroutines with concrete types,
P0114, as well as macro-based solutions - do not need special tricky
allocation elision, they just don't do any allocation in a first place.
> P0114 requires implementations to go through whole hierarchies of inline
> function calls and generate types that represent their stacks. It puts a
> lot of burden on implementer too; it's just in the implementation of the
> feature rather than the /optimization/ phase.
>
> It's more or less the same work either way. Though admittedly, the P0114
> does make it a bit easier for the compiler to see it.
Again, I am not talking specifically about P0114. Even P0057 can be
changed to have concrete coroutine type.
>
> 4. C++11 has lambdas with concrete type - this ensures zero
> overhead, and fits naturally into language. We don't have
> type-erasured closures. We can use external type erasure like
> std::function when needed.
> Why we should have type-erasure for stackless coroutines?
>
>
> Because implementing await machinery (promises, awaitable, etc) is hard
> enough as it is.
It is implementable to some extent even which macros, but with not
pretty syntax.
> Adding a template on top of everything only makes
> things harder.
Which template? Do you mean mandatory inlining in P0114? It requires
this inlining in order to solve orthogonal and harder problem, not
problem of allocations.
N4244, somewhat predecessor of P0114 - also does not force type-erasure
and allocation, but it does not require inlining you are referring to.
--
---
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: Evgeny Panasyuk <evgeny.panasyuk@gmail.com>
Date: Wed, 14 Oct 2015 06:46:23 +0300
Raw View
14.10.2015 5:31, Gor Nishanov:
>
> It does not erase type:
>
>
> It forces you to do it by hand, as you can see this in both generator
> and async examples.
Not "by hand" - this type-erasure can be within standard library. Just
like std::function. And it is not hard at all to use lambdas with
std::function, when needed.
> The key is it requires stationary frame and for that
> you either need to heap allocate or keep the lifetime of the coroutine
> fully enclosed in the lifetime of its consumer. Exactly the same case
> where heap elision is done.
1. Even if consider only functions scopes - escape analysis would not
give 100% guarantee for elision in every case. First of all - I think it
would hit halting problem, second - some of functions in call tree may
not be inlined for adequate reasons - and this would blind analysis.
While in cases of concrete coroutine type - no analysis is required at all.
2. Coroutine locals can be copied/moved with coroutine itself - this is
already implementable via macros. P0144 does not exclude copying
possibility.
But even if add .clone() to P0057 - we still would have erased type.
3. Again, consider case when coroutine is stored in structure or array
like: make_unique<coroutine[]>(N).
Yes, it will be in heap, but each coroutine would not be allocated
separately, it will be just one allocation.
Same applies to structures. For instance if we have:
struct Foo
{
coroutine x;
// ...
};
and then do make_unique<Foo>() - then in case of type-erased coroutine
there will be two allocations, but for coroutine with concrete type -
just one.
>
> But, even if there would be no copyability/moveability, and as the
> result we cannot use std::vector - we still can place N coroutines into
> array with single allocation: make_unique<coroutine[]>(N)
>
>
> P0057 allows you to customize allocation, thus you can achieve the same
> goal, but with different means.
1. Even with custom allocation, in case of array of coroutines there
will be O(N) overhead vs possible O(1).
2. You still need place somewhere for allocation buffer. And things
complicated (resulting in overhead) by fact that you do not know at
compile time how much each coroutine would take.
> I do not claim that feature lists are identical for P0057 and P0114. I
> claim that for a complicated problem, like async programming, for example,
>
> P0057 solution will results in:
>
> 1) less user written code
> 2) less library support code
> 3) less abstraction overhead (see TcpReader, for example)
>
> Than a solution to the same problem in P0114.
> If you want to argue superiority of P0114, pick a problem (hint, hint
> async programming) write a solution, compare with equivalent of P0057.
I am not talking specifically about P0114. Right now I am talking about
stackless coroutines with concrete non-type-erased types. And this is
possible even for P0057, without any major syntax change.
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.
.
Author: Gor Nishanov <gornishanov@gmail.com>
Date: Tue, 13 Oct 2015 20:50:15 -0700 (PDT)
Raw View
------=_Part_8692_1367027462.1444794616017
Content-Type: multipart/alternative;
boundary="----=_Part_8693_1370886794.1444794616017"
------=_Part_8693_1370886794.1444794616017
Content-Type: text/plain; charset=UTF-8
On Tuesday, October 13, 2015 at 8:17:53 PM UTC-7, Evgeny Panasyuk wrote:
>
> I am not talking specifically about P0114. I am talking about stackless
> coroutines with concrete non-type-erased types.
>
The starting point of my design was a lambda* with the properties you
describe. When applied to problems I needed solving I found it
unsatisfactory and therefore went with N4134 proposal. That does not mean
that at some point, somebody won't be able to invent a better lambda* and
get it standardized.
P0114, P0057 and lambda* are all powered by the same underlying machinery.
A transformation of a state machine written in imperative fashion into an
actual state machine. The difference is in a public face of the state
machine. You just need to figure out compelling use-cases and sane
semantics that are not already covered efficiently by P0057 and write a
proposal. I cannot do it for you as the problems I need solving, namely
async I/O and async programming in general, are addressed by P0057
succinctly and efficiently.
--
---
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_8693_1370886794.1444794616017
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><br><br>On Tuesday, October 13, 2015 at 8:17:53 PM UTC-7, =
Evgeny Panasyuk wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;=
margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">I am not=
talking specifically about P0114. I am talking about stackless=20
<br>coroutines with concrete non-type-erased types.
<br></blockquote><div><br></div><div>The starting point of my design was a =
lambda* with the properties you describe. When applied to problems I needed=
solving I found it unsatisfactory and therefore went with N4134 proposal. =
That does not mean that at some point, somebody won't be able to invent=
a better lambda* and get it standardized.<br></div><div><br></div><div>P01=
14, P0057 and lambda* are all powered by the same underlying machinery. A t=
ransformation of a state machine written in imperative fashion into an actu=
al state machine. The difference is in a public face of the state machine. =
You just need to figure out compelling use-cases and sane semantics that ar=
e not already covered efficiently by P0057 and write a proposal. I cannot d=
o it for you as the problems I need solving, namely async I/O and async pro=
gramming in general, are addressed by P0057 succinctly and efficiently.</di=
v><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_8693_1370886794.1444794616017--
------=_Part_8692_1367027462.1444794616017--
.
Author: Evgeny Panasyuk <evgeny.panasyuk@gmail.com>
Date: Tue, 13 Oct 2015 21:14:59 -0700 (PDT)
Raw View
------=_Part_6550_746428769.1444796099213
Content-Type: multipart/alternative;
boundary="----=_Part_6551_559606608.1444796099213"
------=_Part_6551_559606608.1444796099213
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
14 October 2015 =D0=B3., 6:50:16 UTC+3 Gor Nishanov :
>
>
>
> On Tuesday, October 13, 2015 at 8:17:53 PM UTC-7, Evgeny Panasyuk wrote:
>>
>> I am not talking specifically about P0114. I am talking about stackless=
=20
>> coroutines with concrete non-type-erased types.=20
>>
>
> The starting point of my design was a lambda* with the properties you=20
> describe. When applied to problems I needed solving I found it=20
> unsatisfactory and therefore went with N4134 proposal. That does not mean=
=20
> that at some point, somebody won't be able to invent a better lambda* and=
=20
> get it standardized.
>
>
Well, this is also the problem. If we already would have some stackless=20
coroutines in ISO - it would be much harder to get additional one into it.
=20
> P0114, P0057 and lambda* are all powered by the same underlying machinery=
..=20
> A transformation of a state machine written in imperative fashion into an=
=20
> actual state machine. The difference is in a public face of the state=20
> machine. You just need to figure out compelling use-cases and sane=20
> semantics that are not already covered efficiently by P0057 and write a=
=20
> proposal. I cannot do it for you as the problems I need solving, namely=
=20
> async I/O and async programming in general, are addressed by P0057=20
> succinctly and efficiently.
>
>
If you need only async I/O - yes, I could imagine that extra allocation is=
=20
tolerable in such context. But P0057 describes not only async I/O - but=20
also for instance generators. And for generators (like transform iterators)=
=20
an extra allocation is huge price.
It is acceptable price for languages like C# (especially taking into=20
account fast happy-path allocations in first generation of copying GC), but=
=20
it is definitely not acceptable for C++ which has costly default=20
allocations and ambitious zero-overhead goal.
And if you consider only performance of async I/O use cases - then I think=
=20
proposal should directly reflect this somehow.
--=20
---=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.
------=_Part_6551_559606608.1444796099213
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">14 October 2015 =D0=B3., 6:50:16 UTC+3 Gor Nishanov :<bloc=
kquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-l=
eft: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr"><br><br>On Tuesday=
, October 13, 2015 at 8:17:53 PM UTC-7, Evgeny Panasyuk wrote:<blockquote c=
lass=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1px #c=
cc solid;padding-left:1ex">I am not talking specifically about P0114. I am =
talking about stackless=20
<br>coroutines with concrete non-type-erased types.
<br></blockquote><div><br></div><div>The starting point of my design was a =
lambda* with the properties you describe. When applied to problems I needed=
solving I found it unsatisfactory and therefore went with N4134 proposal. =
That does not mean that at some point, somebody won't be able to invent=
a better lambda* and get it standardized.<br></div><div><br></div></div></=
blockquote><div><br>Well, this is also the problem. If we already would hav=
e some stackless coroutines in ISO - it would be much harder to get additio=
nal one into 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;=
"><div dir=3D"ltr"><div></div><div>P0114, P0057 and lambda* are all powered=
by the same underlying machinery. A transformation of a state machine writ=
ten in imperative fashion into an actual state machine. The difference is i=
n a public face of the state machine. You just need to figure out compellin=
g use-cases and sane semantics that are not already covered efficiently by =
P0057 and write a proposal. I cannot do it for you as the problems I need s=
olving, namely async I/O and async programming in general, are addressed by=
P0057 succinctly and efficiently.</div><div><br></div></div></blockquote><=
div><br>If you need only async I/O - yes, I could imagine that extra alloca=
tion is tolerable in such context. But P0057 describes not only async I/O -=
but also for instance generators. And for generators (like transform itera=
tors) an extra allocation is huge price.<br>It is acceptable price for lang=
uages like C# (especially taking into account fast happy-path allocations i=
n first generation of copying GC), but it is definitely not acceptable for =
C++ which has costly default allocations and ambitious zero-overhead goal.<=
br><br>And if you consider only performance of async I/O use cases - then I=
think proposal should directly reflect this somehow.<br><br></div></div>
<p></p>
-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />
------=_Part_6551_559606608.1444796099213--
------=_Part_6550_746428769.1444796099213--
.
Author: Nicol Bolas <jmckesson@gmail.com>
Date: Tue, 13 Oct 2015 21:46:50 -0700 (PDT)
Raw View
------=_Part_6485_1764221694.1444798011001
Content-Type: multipart/alternative;
boundary="----=_Part_6486_896213012.1444798011002"
------=_Part_6486_896213012.1444798011002
Content-Type: text/plain; charset=UTF-8
On Tuesday, October 13, 2015 at 11:17:53 PM UTC-4, Evgeny Panasyuk wrote:
>
> 14.10.2015 4:57, Nicol Bolas:
> > Except that he's already proven (in this thread no less) that a
> > good optimizer can elide the allocation. If the compiler can
> > reasonably /make/ it zero overhead, then it /is/ zero overhead.
> >
> >
> >
> > 1. It is impossible (practically) in general case.
> > For instance in case when we put coroutines in container, like:
> > |
> > vector<coroutine>x(N);
> > |
> > In case of coroutines with concrete types and sizeof known at
> > compile - this can be done within single allocation.
> > But if coroutine type is erased the we will have N+1 allocations in
> > general case - it can't be practically elided.
> >
> >
> > Ignoring the rest of the discussion on this point, I never claimed that
> > P0057 could guarantee elision in the case you present here. Before, you
> > asked about a /specific/ problem, and I answered with a specific example
> > showing that it was elidable. What you've shown here hardly disproves my
> > point.
>
> It is not zero overhead even with good optimizer/compiler, because they
> can't elide every allocation, and I am not talking about some exotic
> cases.
>
Thus far, including in this post, you haven't mentioned an example that
would actually compile.
You linked to some macro code, but macros are, basically, *cheating*. They
get to break all kinds of C++ rules, which an actual language feature would
not.
> >
> > Also... how does `vector<coroutine>` make any kind of sense with regard
> > to P0114? The type isn't type erased, so each coroutine has its own
> > type. Therefore, in order to put them in a homogeneous container like
> > `vector`, you'll have to type-erase them. Which requires memory
> allocation.
> > At which point, your version gains /nothing/ over P0057.
>
> Same coroutines have same concrete types. For instance, with P0114 it
> may be:
> |
> struct concrete_coroutine
> {
> resumable auto r = expression;
> // ...
> };
> ...
> make_unique<concrete_coroutine[]>(N);
> |
>
`auto` doesn't work that way. Non-static data members cannot be `auto`.
Normally I wouldn't care about a small issue like that, but it basically
makes your code impossible.
Without `auto` NSDMI (and I wouldn't hold my breath on seeing it
<http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2014/n3897.html>), you
can't store a resumable expression. So you can't make containers of them.
Unless you erase their types. So again, you've gained *nothing*.
Your macro solution gets around this because it uses macros.
> Again, I am not talking specifically about P0114. Even P0057 can be
> changed to have concrete coroutine type.
>
I'd be curious to see how, exactly.
And I don't mean some macro nonsense. I mean the specific details of how
you turn P0057's `coroutine_handle` into a type.
See, the way P0057 works is that the coroutine object is introduced in one
specific place: the awaiter object's `await_suspend` method. That's the
first place where user code gets to touch a coroutine, and if the method
doesn't store it or otherwise keep it around, it's also the last.
That's what I meant when I said "adding a template". Because now,
`await_suspend` *must* become a template function. There's no other way to
capture a parameter of an arbitrary, compiler-generated type.
But what of generators and promises in such a scenario? A `generator<int>`
needs to be able to store any coroutine, so it has to... type erase it. The
promise type cannot be a template on the coroutine type, since it was
declared long before the coroutine handle appeared. And so forth.
In short, the entirety of P0057 is designed around a type-erased
`coroutine_handle`. You can't simply declare that it's not type-erased and
expect everything to work reasonably. The entire design would need to be
rethought.
If you want this done, then you're going to need to go through the effort
of designing the feature to work without type erasure. Then you have to get
someone to implement it. Then, you can know whether it works just as well
as P0057, whether it's equally easy to use, and how much of a performance
advantage it gets.
If any.
--
---
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_6486_896213012.1444798011002
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
On Tuesday, October 13, 2015 at 11:17:53 PM UTC-4, Evgeny Panasyuk wrote:<b=
lockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;borde=
r-left: 1px #ccc solid;padding-left: 1ex;">14.10.2015 4:57, Nicol Bolas:
<br>> =C2=A0 =C2=A0 =C2=A0 =C2=A0 Except that he's already proven (i=
n this thread no less) that a
<br>> =C2=A0 =C2=A0 =C2=A0 =C2=A0 good optimizer can elide the allocatio=
n. If the compiler can
<br>> =C2=A0 =C2=A0 =C2=A0 =C2=A0 reasonably /make/ it zero overhead, th=
en it /is/ zero overhead.
<br>>
<br>>
<br>>
<br>> =C2=A0 =C2=A0 1. It is impossible (practically) in general case.
<br>> =C2=A0 =C2=A0 For instance in case when we put coroutines in conta=
iner, like:
<br>> =C2=A0 =C2=A0 |
<br>> =C2=A0 =C2=A0 vector<coroutine>x(N);
<br>> =C2=A0 =C2=A0 |
<br>> =C2=A0 =C2=A0 In case of coroutines with concrete types and sizeof=
known at
<br>> =C2=A0 =C2=A0 compile - this can be done within single allocation.
<br>> =C2=A0 =C2=A0 But if coroutine type is erased the we will have N+1=
allocations in
<br>> =C2=A0 =C2=A0 general case - it can't be practically elided.
<br>>
<br>>
<br>> Ignoring the rest of the discussion on this point, I never claimed=
that
<br>> P0057 could guarantee elision in the case you present here. Before=
, you
<br>> asked about a /specific/ problem, and I answered with a specific e=
xample
<br>> showing that it was elidable. What you've shown here hardly di=
sproves my
<br>> point.
<br>
<br>It is not zero overhead even with good optimizer/compiler, because they=
=20
<br>can't elide every allocation, and I am not talking about some exoti=
c cases.
<br></blockquote><div><br>Thus far, including in this post, you haven't=
mentioned an example that would actually compile.<br><br>You linked to som=
e macro code, but macros are, basically, <i>cheating</i>. They get to break=
all kinds of C++ rules, which an actual language feature would not.<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;">
>
<br>> Also... how does `vector<coroutine>` make any kind of sense =
with regard
<br>> to P0114? The type isn't type erased, so each coroutine has it=
s own
<br>> type. Therefore, in order to put them in a homogeneous container l=
ike
<br>> `vector`, you'll have to type-erase them. Which requires memor=
y allocation.
<br>=C2=A0> At which point, your version gains /nothing/ over P0057.
<br>
<br>Same coroutines have same concrete types. For instance, with P0114 it=
=20
<br>may be:
<br>|
<br>struct concrete_coroutine
<br>{
<br>=C2=A0 =C2=A0 =C2=A0resumable auto r =3D expression;
<br>=C2=A0 =C2=A0 =C2=A0// ...
<br>};
<br>...
<br>make_unique<concrete_<wbr>coroutine[]>(N);
<br>|<br></blockquote><div><br>`auto` doesn't work that way. Non-static=
data members cannot be `auto`. Normally I wouldn't care about a small =
issue like that, but it basically makes your code impossible.<br><br>Withou=
t `auto` NSDMI (and <a href=3D"http://www.open-std.org/JTC1/SC22/WG21/docs/=
papers/2014/n3897.html">I wouldn't hold my breath on seeing it</a>), yo=
u can't store a resumable expression. So you can't make containers =
of them.<br><br>Unless you erase their types. So again, you've gained <=
i>nothing</i>.<br><br>Your macro solution gets around this because it uses =
macros.<br></div><div>=C2=A0</div><blockquote class=3D"gmail_quote" style=
=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: =
1ex;">
Again, I am not talking specifically about P0114. Even P0057 can be=20
<br>changed to have concrete coroutine type.
<br></blockquote><div><br>I'd be curious to see how, exactly.<br><br>An=
d I don't mean some macro nonsense. I mean the specific details of how =
you turn P0057's `coroutine_handle` into a type.<br><br>See, the way P0=
057 works is that the coroutine object is introduced in one specific place:=
the awaiter object's `await_suspend` method. That's the first plac=
e where user code gets to touch a coroutine, and if the method doesn't =
store it or otherwise keep it around, it's also the last.<br><br>That&#=
39;s what I meant when I said "adding a template". Because now, `=
await_suspend` <i>must</i> become a template function. There's no other=
way to capture a parameter of an arbitrary, compiler-generated type.<br><b=
r>But what of generators and promises in such a scenario? A `generator<i=
nt>` needs to be able to store any coroutine, so it has to... type erase=
it. The promise type cannot be a template on the coroutine type, since it =
was declared long before the coroutine handle appeared. And so forth.<br><b=
r>In short, the entirety of P0057 is designed around a type-erased `corouti=
ne_handle`. You can't simply declare that it's not type-erased and =
expect everything to work reasonably. The entire design would need to be re=
thought.<br><br>If you want this done, then you're going to need to go =
through the effort of designing the feature to work without type erasure. T=
hen you have to get someone to implement it. Then, you can know whether it =
works just as well as P0057, whether it's equally easy to use, and how =
much of a performance advantage it gets.<br><br>If any.<br></div>
<p></p>
-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />
------=_Part_6486_896213012.1444798011002--
------=_Part_6485_1764221694.1444798011001--
.
Author: Nicol Bolas <jmckesson@gmail.com>
Date: Tue, 13 Oct 2015 21:51:07 -0700 (PDT)
Raw View
------=_Part_3941_861677792.1444798267244
Content-Type: multipart/alternative;
boundary="----=_Part_3942_1258553588.1444798267244"
------=_Part_3942_1258553588.1444798267244
Content-Type: text/plain; charset=UTF-8
On Wednesday, October 14, 2015 at 12:14:59 AM UTC-4, Evgeny Panasyuk wrote:
>
> If you need only async I/O - yes, I could imagine that extra allocation is
> tolerable in such context. But P0057 describes not only async I/O - but
> also for instance generators. And for generators (like transform iterators)
> an extra allocation is huge price.
>
A price you will never pay because it will be elided.
Please stop repeating statements that have been disproven; it's not helping
your case. You have yet to post an example of a generator that would not be
elided.
--
---
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_3942_1258553588.1444798267244
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">On Wednesday, October 14, 2015 at 12:14:59 AM UTC-4, Evgen=
y Panasyuk 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">If you need only async I/O - yes, I could imagine that extra allocation=
is tolerable in such context. But P0057 describes not only async I/O - but=
also for instance generators. And for generators (like transform iterators=
) an extra allocation is huge price.<br></div></blockquote><div><br>A price=
you will never pay because it will be elided.<br><br>Please stop repeating=
statements that have been disproven; it's not helping your case. You h=
ave yet to post an example of a generator that would not be elided.<br></di=
v></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_3942_1258553588.1444798267244--
------=_Part_3941_861677792.1444798267244--
.
Author: Evgeny Panasyuk <evgeny.panasyuk@gmail.com>
Date: Wed, 14 Oct 2015 08:13:44 +0300
Raw View
14.10.2015 7:51, Nicol Bolas:
> If you need only async I/O - yes, I could imagine that extra
> allocation is tolerable in such context. But P0057 describes not
> only async I/O - but also for instance generators. And for
> generators (like transform iterators) an extra allocation is huge price.
>
>
> A price you will never pay because it will be elided.
>
> Please stop repeating statements that have been disproven; it's not
> helping your case. You have yet to post an example of a generator that
> would not be elided.
I already described it several times, just put generator into some
structure/array or return somewhere.
In similar situation:
http://coliru.stacked-crooked.com/a/0c09744abd5e57ae
- allocation of P0057 generator will not be elided, there will be N
allocations, i.e. for each coroutine.
You can read what Gor said previously in this topic:
"If coroutine lifetime is fully enclosed in the lifetime of the calling
function, then we can
1) elide allocation and use a temporary on the stack of the caller
2) replace indirect calls with direct calls and inline as appropriate:"
There is "if" condition. Even if we assume that optimizers always do
elision when condition is true, there is still no elision for cases with
false condition.
--
---
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: Ville Voutilainen <ville.voutilainen@gmail.com>
Date: Wed, 14 Oct 2015 08:36:26 +0300
Raw View
On 14 October 2015 at 07:14, Evgeny Panasyuk <evgeny.panasyuk@gmail.com> wrote:
>> The starting point of my design was a lambda* with the properties you
>> describe. When applied to problems I needed solving I found it
>> unsatisfactory and therefore went with N4134 proposal. That does not mean
>> that at some point, somebody won't be able to invent a better lambda* and
>> get it standardized.
> Well, this is also the problem. If we already would have some stackless
> coroutines in ISO - it would be much harder to get additional one into it.
That "much harder" is fairly questionable. While there apparently are people
who think working on e.g. stackful coroutines becomes a pointless exercise
if Gor's proposal is accepted, and while there are people who prefer
picking one rather than many solutions (albeit the problems being different),
- we have plenty of people in the committee who understand that the different
solutions are tackling different problems,
- for those who don't understand it, the proposal authors can fairly easily
re-explain it
- while they are doing that re-explaining, Gor is going to nod vigorously
and help them explain it, even though it's not the main focus of his
attention as far as the overall design space of these facilities goes,
so, compared to almost any other facility that would provide an
alternative/additional
approach for something already partially tackled by a standard facility,
standardizing something additional in this area may be much easier than people
fear.
--
---
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: Evgeny Panasyuk <evgeny.panasyuk@gmail.com>
Date: Wed, 14 Oct 2015 09:02:37 +0300
Raw View
14.10.2015 8:36, Ville Voutilainen:
> On 14 October 2015 at 07:14, Evgeny Panasyuk <evgeny.panasyuk@gmail.com> wrote:
>>> The starting point of my design was a lambda* with the properties you
>>> describe. When applied to problems I needed solving I found it
>>> unsatisfactory and therefore went with N4134 proposal. That does not mean
>>> that at some point, somebody won't be able to invent a better lambda* and
>>> get it standardized.
>> Well, this is also the problem. If we already would have some stackless
>> coroutines in ISO - it would be much harder to get additional one into it.
>
> That "much harder" is fairly questionable. While there apparently are people
> who think working on e.g. stackful coroutines becomes a pointless exercise
> if Gor's proposal is accepted, and while there are people who prefer
> picking one rather than many solutions (albeit the problems being different),
Indeed, there is overlap between use cases of stackless and stackful
coroutines. But in addition, each one has it's own area where it beats
another approach.
And I think C++ ISO needs both - stackless and stackful coroutines.
(though I would prefer to get stackless into ISO first, because stackful
can be completely implemented in library, like Boost.Context/Coroutine)
But here is another situation - both options aim to exactly same use
cases, and even one is strictly more powerful than another. If we would
have stackless coroutine with concrete type - then we always can
implement type-erasure on top of it. Just like we have std::function
type-erasure for concrete lambda types.
--
---
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: German Diago <german.diago@hubblehome.com>
Date: Wed, 14 Oct 2015 14:12:19 +0700
Raw View
--94eb2c0b865e7dcac605220b48ad
Content-Type: text/plain; charset=UTF-8
On Wed, Oct 14, 2015 at 7:11 AM, Gor Nishanov <gornishanov@gmail.com> wrote:
> Okay. Slightly less cryptic reply. Coroutine frame must be stationary once
> the coroutine starts running.
> Resumable Expressions abandoned movability/copyability of the lambda* that
> was present in earlier resumable lambda proposal.
>
The new paper mentions about opt-in to move/copy. Could be proposed. I find
it useful.
>
> The difference is that in Resumable Expressions you must do type erasure
> by hand which is difficult to eliminate.
> Whereas in P0057 compiler decides whether it needs to do type erasure or
> not, thus, allowing to optimize it out when unnecessary.
>
What I really like about resumable expressions is that it is really, really
obvious and lightweight how it works.
Your implementation, Gor, looks good to me. But I am concerned we can avoid
some of the trouble. I do not see a problem
in having library-abstracted generators on top of resumable expressions.
Why should we embed a full protocol in the language itself
when we can get it done with only "break resumable" and have the rest on
top of library abstractions. I just do not get why,
because additionally, you can have your generators, your await, everything,
and remove type erasure and have *real* zero overhead
from the beginning. Without any fancy optimizations or escape analysis. I
am against introducing in the language something that
is not inherently zero-overhead when we have alternatives. Do not get me
wrong, the proposal gives a lot of inspiration, in my opinion,
for how to do a few great things. But I honestly think we can do better.
I know about your suggestion on how to compare, but I simply do not have
enough time. I hope I had, but I am short on time.
I see resumable expressions more understandable respect to the traditional
c++ model and I think they guarantee zero-overhead
in more cases than your proposal. Though, I recognize that the numbers you
show for your implementation look good, but, again:
1. need compiler optimizations such as escape analysis.
2. no matter the way you put it, they are not inherently zero-overhead for
the curent state of the art. Even you mentioned clang
is planning to introduce some optimization that is not available already. I
think we should not get into that trouble,
we have alternatives. There are more compilers around also: Intel, IBM...
--
---
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/.
--94eb2c0b865e7dcac605220b48ad
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><br><div class=3D"gmail_extra"><br><div class=3D"gmail_quo=
te">On Wed, Oct 14, 2015 at 7:11 AM, Gor Nishanov <span dir=3D"ltr"><<a =
href=3D"mailto:gornishanov@gmail.com" target=3D"_blank">gornishanov@gmail.c=
om</a>></span> wrote:<br><blockquote class=3D"gmail_quote" style=3D"marg=
in:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"=
>Okay. Slightly less cryptic reply. Coroutine frame must be stationary once=
the coroutine starts running.<div>Resumable Expressions abandoned movabili=
ty/copyability of the lambda* that was present in earlier resumable lambda =
proposal. <br></div></div></blockquote><div><br></div><div>The new paper me=
ntions about opt-in to move/copy. Could be proposed. I find it useful.<br>=
=C2=A0<br></div><blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8e=
x;border-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><div></div>=
<div><br></div><div>The difference is that in Resumable Expressions you mus=
t do type erasure by hand which is difficult to eliminate.</div><div>Wherea=
s in P0057 compiler decides whether it needs to do type erasure or not, thu=
s, allowing to optimize it out when unnecessary.<br></div></div></blockquot=
e><div><br></div><div>What I really like about resumable expressions is tha=
t it is really, really obvious and lightweight how it works.<br></div><div>=
Your implementation, Gor, looks good to me. But I am concerned we can avoid=
some of the trouble. I do not see a problem<br></div><div>in having librar=
y-abstracted generators on top of resumable expressions. Why should we embe=
d a full protocol in the language itself<br></div><div>when we can get it d=
one with only "break resumable" and have the rest on top of libra=
ry abstractions. I just do not get why,<br></div><div>because additionally,=
you can have your generators, your await, everything, and remove type eras=
ure and have *real* zero overhead<br></div><div>from the beginning. Without=
any fancy optimizations or escape analysis. I am against introducing in th=
e language something that<br></div><div>is not inherently zero-overhead whe=
n we have alternatives. Do not get me wrong, the proposal gives a lot of in=
spiration, in my opinion,<br></div><div>for how to do a few great things. B=
ut I honestly think we can do better.<br><br></div><div>I know about your s=
uggestion on how to compare, but I simply do not have enough time. I hope I=
had, but I am short on time.<br></div><div>I see resumable expressions mor=
e understandable respect to the traditional c++ model and I think they guar=
antee zero-overhead<br></div><div>in more cases than your proposal. Though,=
I recognize that the numbers you show for your implementation look good, b=
ut, again:<br><br></div><div>1. need compiler optimizations such as escape =
analysis.<br></div><div>2.=C2=A0 no matter the way you put it, they are not=
inherently zero-overhead for the curent state of the art. Even you mention=
ed clang<br></div><div>is planning to introduce some optimization that is n=
ot available already. I think we should not get into that trouble,<br></div=
><div>we have alternatives. There are more compilers around also: Intel, IB=
M... <br><br><br></div></div></div></div>
<p></p>
-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />
--94eb2c0b865e7dcac605220b48ad--
.
Author: German Diago <german.diago@hubblehome.com>
Date: Wed, 14 Oct 2015 14:14:47 +0700
Raw View
--001a1140cd7e548b1605220b5186
Content-Type: text/plain; charset=UTF-8
> P0114 *requires* that all resumable functions you call are inlined. If
> they're not inlined, you have to manually box them (and the boxing function
> is no longer resumable). Boxing involves type erasure. And as previously
> stated, memory allocation.
>
You can box it. You *can*, you do not *need*. And you do not need to have
an inline resumable expression if you just implement and type-erase in a
..cpp file. You still have the same amount of power as your proposal, just
you have the *additional* option of inlining.
I think this alone makes already that proposal inherently "more
zero-overhead".
--
---
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/.
--001a1140cd7e548b1605220b5186
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><br><div class=3D"gmail_extra"><div class=3D"gmail_quote">=
<blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1p=
x #ccc solid;padding-left:1ex"><div>P0114 <i>requires</i> that all resumabl=
e functions you call are inlined. If they're not inlined, you have to m=
anually box them (and the boxing function is no longer resumable). Boxing i=
nvolves type erasure. And as previously stated, memory allocation.<br></div=
></blockquote><div><br></div><div>You can box it. You *can*, you do not *ne=
ed*. And you do not need to have an inline resumable expression if you just=
implement and type-erase in a .cpp file. You still have the same amount of=
power as your proposal, just you have the *additional* option of inlining.=
<br></div><div>I think this alone makes already that proposal inherently &q=
uot;more zero-overhead".<br>=C2=A0<br></div><br></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 />
--001a1140cd7e548b1605220b5186--
.
Author: German Diago <german.diago@hubblehome.com>
Date: Wed, 14 Oct 2015 14:18:49 +0700
Raw View
--94eb2c0b865ebedb1305220b5fa1
Content-Type: text/plain; charset=UTF-8
Not "by hand" - this type-erasure can be within standard library. Just like
std::function. And it is not hard at all to use lambdas with std::function,
when needed.
Completely agree. This is the way it should be done, IMHO. Not embedding it
into the language for no gain.
> I do not claim that feature lists are identical for P0057 and P0114. I
>> claim that for a complicated problem, like async programming, for example,
>>
>> P0057 solution will results in:
>>
>> 1) less user written code
>>
>
This is due to embedding more into the language. The resumable expressions
can do all of it in libraries.
So as a solution, I find it superior a library than embedding into the
language
> 2) less library support code
>>
>
Again, because it is embedded.
> 3) less abstraction overhead (see TcpReader, for example)
>>
>> This is a carefully chosen use-case. There are many others. Though, it is
a real one, I cannot say it is not.
> Than a solution to the same problem in P0114.
>> If you want to argue superiority of P0114, pick a problem (hint, hint
>> async programming) write a solution, compare with equivalent of P0057.
>>
>
> You need to write less code does not mean that it is zero-overhead, which
is a main point of the discussion.
--
---
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/.
--94eb2c0b865ebedb1305220b5fa1
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><br><div class=3D"gmail_extra"><span class=3D""><br></span=
>
Not "by hand" - this type-erasure can be within standard library.=
Just like std::function. And it is not hard at all to use lambdas with std=
::function, when needed.<br><br></div><div class=3D"gmail_extra">Completely=
agree. This is the way it should be done, IMHO. Not embedding it into the =
language for no gain.<br>
</div><div class=3D"gmail_extra"><div class=3D"gmail_quote"><blockquote cla=
ss=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;pa=
dding-left:1ex"><span class=3D""><blockquote class=3D"gmail_quote" style=3D=
"margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
I do not claim that feature lists are identical for P0057 and P0114. I<br>
claim that for a complicated problem, like async programming, for example,<=
br>
<br>
P0057 solution will results in:<br>
<br>
1) less user written code<br></blockquote></span></blockquote><div><br></di=
v><div>This is due to embedding more into the language. The resumable expre=
ssions can do all of it in libraries.<br></div><div>So as a solution, I fin=
d it superior a library than embedding into the language<br>=C2=A0<br></div=
><blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1=
px #ccc solid;padding-left:1ex"><span class=3D""><blockquote class=3D"gmail=
_quote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:=
1ex">
2) less library support code<br></blockquote></span></blockquote><div><br><=
/div><div>Again, because it is embedded.<br>=C2=A0<br></div><blockquote cla=
ss=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;pa=
dding-left:1ex"><span class=3D""><blockquote class=3D"gmail_quote" style=3D=
"margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
3) less abstraction overhead (see TcpReader, for example)<br>
<br></blockquote></span></blockquote><div>This is a carefully chosen use-ca=
se. There are many others. Though, it is a real one, I cannot say it is not=
..<br>=C2=A0<br></div><blockquote class=3D"gmail_quote" style=3D"margin:0 0 =
0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><span class=3D""><block=
quote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc=
solid;padding-left:1ex">
Than a solution to the same problem in P0114.<br>
If you want to argue superiority of P0114, pick a problem (hint, hint<br>
async programming) write a solution, compare with equivalent of P0057.<br>
</blockquote>
<br></span></blockquote><div>You need to write less code does not mean that=
it is zero-overhead, which is a main point of the discussion. <br></div><d=
iv>=C2=A0<br></div></div></div></div>
<p></p>
-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />
--94eb2c0b865ebedb1305220b5fa1--
.
Author: Ville Voutilainen <ville.voutilainen@gmail.com>
Date: Wed, 14 Oct 2015 10:42:51 +0300
Raw View
On 14 October 2015 at 09:02, Evgeny Panasyuk <evgeny.panasyuk@gmail.com> wrote:
>> That "much harder" is fairly questionable. While there apparently are
>> people
>> who think working on e.g. stackful coroutines becomes a pointless exercise
>> if Gor's proposal is accepted, and while there are people who prefer
>> picking one rather than many solutions (albeit the problems being
>> different),
>
>
> Indeed, there is overlap between use cases of stackless and stackful
> coroutines. But in addition, each one has it's own area where it beats
> another approach.
Correct.
> And I think C++ ISO needs both - stackless and stackful coroutines. (though
> I would prefer to get stackless into ISO first, because stackful can be
> completely implemented in library, like Boost.Context/Coroutine)
Fully agreed.
> But here is another situation - both options aim to exactly same use cases,
> and even one is strictly more powerful than another. If we would have
> stackless coroutine with concrete type - then we always can implement
> type-erasure on top of it. Just like we have std::function type-erasure for
> concrete lambda types.
The use cases may be slightly different, because stackful coroutines
do not require an Awaitable type all through the call stack, whereas
stackless coroutines do. The use case may be the same, but which
facility to apply depends on other less-technical-things, like whether
the user of a coroutine controls the full call stack.
As far as having the concrete type goes, that sounds like it requires even
more inlining and across-call-stack transparency. In a stackless coroutine,
the erased type combined with elision of the erasure and allocations avoids
having all coroutines have a different type.
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.
.
Author: Oliver Kowalke <oliver.kowalke@gmail.com>
Date: Wed, 14 Oct 2015 10:39:58 +0200
Raw View
--047d7b6784261ca7b105220c8340
Content-Type: text/plain; charset=UTF-8
2015-10-14 8:02 GMT+02:00 Evgeny Panasyuk <evgeny.panasyuk@gmail.com>:
>
> And I think C++ ISO needs both - stackless and stackful coroutines.
> (though I would prefer to get stackless into ISO first, because stackful
> can be completely implemented in library, like Boost.Context/Coroutine)
>
but implementing context switching is cumbersome (because assembler) -
better the compiler vendors provide implementations for all those
combinations of architecture + ABI + binary format
--
---
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/.
--047d7b6784261ca7b105220c8340
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">2015=
-10-14 8:02 GMT+02:00 Evgeny Panasyuk <span dir=3D"ltr"><<a href=3D"mail=
to:evgeny.panasyuk@gmail.com" target=3D"_blank">evgeny.panasyuk@gmail.com</=
a>></span>:<br><blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .=
8ex;border-left:1px #ccc solid;padding-left:1ex"><br>
And I think C++ ISO needs both - stackless and stackful coroutines. (though=
I would prefer to get stackless into ISO first, because stackful can be co=
mpletely implemented in library, like Boost.Context/Coroutine)<br></blockqu=
ote></div><br></div><div class=3D"gmail_extra">but implementing context swi=
tching is cumbersome (because assembler) - better the compiler vendors prov=
ide implementations for all those combinations of architecture + ABI + bina=
ry format<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 />
--047d7b6784261ca7b105220c8340--
.
Author: thorsten.ottosen@gmail.com
Date: Wed, 14 Oct 2015 04:50:33 -0700 (PDT)
Raw View
------=_Part_271_1998080566.1444823433810
Content-Type: multipart/alternative;
boundary="----=_Part_272_62579400.1444823433810"
------=_Part_272_62579400.1444823433810
Content-Type: text/plain; charset=UTF-8
On Tuesday, October 13, 2015 at 1:03:34 AM UTC+2, Gor Nishanov wrote:
>
>
> I have had an outstanding challenge for a year already to anyone who
> thinks that way to come up with a real world problem, reduce it to
> managable size (say async_tcp_reader) write it up it both ways using P0057
> and whatever you consider zero overhead and evaluate on three criteria:
>
> 1) How much code end-user have to write
> 2) How much library support required
> 3) What is an abstraction penalty, how many instructions need to get
> executed to get from, say, await Read(buf, len) to an low-level
> API/hardware, say WSARecv
>
> My statement is that P0057 is as good or better on all 3 criteria than any
> other proposal I've seen. If you want to accept the challenge, write up an
> equivalent to TcpReader described in one of these two presentations:
>
>
That is a good way forward. I think the abstraction penalty should be the
same, otherwise the "resumable" proposal is dead. Given that, I don't agree
that the amount of code is the most important aspect. What matters here is
that normal programmers should be able to write correct programs without
subtle bugs. I don't mind writing a little more code, if the resulting code
is easier to get correct.
kind regards
Thorsten
--
---
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_272_62579400.1444823433810
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<br><br>On Tuesday, October 13, 2015 at 1:03:34 AM UTC+2, Gor Nishanov wrot=
e:<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;b=
order-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr"><br><div>I =
have had an outstanding challenge for a year already to anyone who thinks t=
hat way to come up with a real world problem, reduce it to managable size (=
say async_tcp_reader) write it up it both ways using P0057 and whatever you=
consider zero overhead and evaluate on three criteria:</div><div><br></div=
><div>1) How much code end-user have to write</div><div>2) How much library=
support required</div><div>3) What is an abstraction penalty, how many ins=
tructions need to get executed to get from, say, await Read(buf, len) to an=
low-level API/hardware, say WSARecv</div><div><br></div><div>My statement =
is that P0057 is as good or better on all 3 criteria than any other proposa=
l I've seen. If you want to accept the challenge, write up an equivalen=
t to TcpReader described in one of these two presentations:</div><br></div>=
</blockquote><div><br>That is a good way forward. I think the abstraction p=
enalty should be the same, otherwise the "resumable" proposal is =
dead. Given that, I don't agree that the amount of code is the most imp=
ortant aspect. What matters here is that normal programmers should be able =
to write correct programs without subtle bugs. I don't mind writing a l=
ittle more code, if the resulting code is easier to get correct. <br><br>ki=
nd regards<br><br>Thorsten<br>=C2=A0</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_272_62579400.1444823433810--
------=_Part_271_1998080566.1444823433810--
.
Author: Gor Nishanov <gornishanov@gmail.com>
Date: Wed, 14 Oct 2015 06:37:50 -0700 (PDT)
Raw View
------=_Part_1556_1021943582.1444829870177
Content-Type: multipart/alternative;
boundary="----=_Part_1557_71016232.1444829870177"
------=_Part_1557_71016232.1444829870177
Content-Type: text/plain; charset=UTF-8
On Wednesday, October 14, 2015 at 4:50:33 AM UTC-7, thorsten...@gmail.com
wrote:
>
> 3) What is an abstraction penalty, how many instructions need to get
>> executed to get from, say, await Read(buf, len) to an low-level
>> API/hardware, say WSARecv
>>
>> My statement is that P0057 is as good or better on all 3 criteria than
>> any other proposal I've seen. If you want to accept the challenge, write up
>> an equivalent to TcpReader described in one of these two presentations:
>>
>
> That is a good way forward. I think the abstraction penalty should be the
> same,
>
I really hoped that one of the proponents will do the exercise and reach
the same conclusion as I did. Namely that P0114 has significantly higher
overhead measured in hundreds more instructions, memory barriers, type
erasure and memory allocations.
If you look at
http://open-std.org/JTC1/SC22/WG21/docs/papers/2015/p0055r0.html, it shows
how you can automate creation of awaitables for template based libraries
dealing with async I/O that gets you code equivalent to hand written
assembly.
ResultType r = await async_xyz(p);
becomes
async_xyz`Awaiter __tmp{p};
$promise.resume_addr = &__resume_label; // save the resumption point of the coroutine
__tmp.resume = $RBP; // inlined await_suspend
os_xyz(p,&OsContextBase::Invoke, &__tmp); // inlined await_suspend
jmp Epilogue; // suspends the coroutine
__resume_label: // will be resumed at this point once the operation is finished
R r = move(__tmp.result); // inlined await_resume
which is pretty much what you would have written by hand if you would write
your coroutine in assembly.
Compare that to "can do it in a library" approach.
First, look at heavy-weight await emulation machinery described in 12.5 of
P0114R0 starting on page 21.
But, let's say, await is not a natural pattern for P0114, that is why it is
heavy weight. Let's look at what could be more natural pattern, shown in:
https://github.com/chriskohlhoff/resumable-expressions/blob/master/examples/await4.cpp
.. Same situtation, not as bad as with await emulation, but, still bad.
Though, I think that this is fixable. P0114RX can get syntactic sugar
equivalent of await and yield, it would not need to do as much work in the
library. So it will become as efficient P0057.
What remains are various inconveniences of how coroutines are presented to
the user.
You need to do manual type erasure, like in this example (await4.cpp):
resumable void echo(tcp::socket socket);
resumable void listen(tcp::acceptor acceptor) {
...
spawn([s = std::move(socket)]() mutable { echo(std::move(s)); });
When I say manual type erasure, I mean that instead of just calling echo,
you need to wrap it in a lambda and give to type-erasing library helper
spawn that does wrapping and allocation for you.
Another limitation is that you have to put everything in one file to the
code above to work, since in order for listen to be able to use echo in
resumable expression, it needs to see the body of the echo, thus, it needs
to be defined in the same TU. If you want to put them in different files
you need to create little type erasing wrappers, as in:
echo.h:
void echo(tcp::socket socket);
echo.cpp:
resumable echo_impl(tcp::socket socket) { ... }
void echo(tcp::socket socket) {
spawn([s = std::move(socket)]() mutable { echo_impl(std::move(s)); });
}
I am not so much critisizing Chris, as critisizing myself. I went through
this design already when exploring lambda* nearly two years ago. I reached
a conclusion that for the problems I tried to apply it to, it did not offer
anything to compensate for the complexity compared to boring C# like await
syntax. Hence, I no longer pursue this approach.
It does not mean that for *some* problems, some incarnation of lambda*
*might* be better than P0057. That is wonderful. When this happen, let's
add it in, in addition to P0057 and P0099 (modestly called "A low-level API
for stackful context switching").
--
---
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_1557_71016232.1444829870177
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><br><br>On Wednesday, October 14, 2015 at 4:50:33 AM UTC-7=
, thorsten...@gmail.com wrote:<blockquote class=3D"gmail_quote" style=3D"ma=
rgin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">=
<blockquote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;borde=
r-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><div>3) What is an=
abstraction penalty, how many instructions need to get executed to get fro=
m, say, await Read(buf, len) to an low-level API/hardware, say WSARecv</div=
><div><br></div><div>My statement is that P0057 is as good or better on all=
3 criteria than any other proposal I've seen. If you want to accept th=
e challenge, write up an equivalent to TcpReader described in one of these =
two presentations:</div></div></blockquote><div><br>That is a good way forw=
ard. I think the abstraction penalty should be the same, </div></blockquote=
><div><br></div><div>I really hoped that one of the proponents will do the =
exercise and reach the same conclusion as I did. Namely that P0114 has sign=
ificantly higher overhead measured in hundreds more instructions, memory ba=
rriers, type erasure and memory allocations.</div><div><br></div><div>If yo=
u look at http://open-std.org/JTC1/SC22/WG21/docs/papers/2015/p0055r0.html,=
it shows how you can automate creation of awaitables for template based li=
braries dealing with async I/O that gets you code equivalent to hand writte=
n assembly.</div><div><br></div><div><pre style=3D"padding: 6px 10px; borde=
r: 1px solid rgb(204, 204, 204); font-family: Consolas, 'Liberation Mon=
o', Courier, monospace; line-height: 19px; overflow: auto; border-radiu=
s: 3px; color: rgb(51, 51, 51); background-color: rgb(248, 248, 248);"><cod=
e style=3D"border-style: none; border-width: initial; font-size: 12px; font=
-family: Consolas, 'Liberation Mono', Courier, monospace; border-ra=
dius: 3px; background: transparent;"> ResultType r =3D await async_xyz(=
p);
becomes
async_xyz`Awaiter __tmp{p};=20
$promise.resume_addr =3D &__resume_label; // save the resumption=
point of the coroutine
__tmp.resume =3D $RBP; // inlined await_suspend
os_xyz(p,&OsContextBase::Invoke, &__tmp); // inlined await_sus=
pend
jmp Epilogue; // suspends the coroutine
__resume_label: // will be resumed at this point once the operation is f=
inished
R r =3D move(__tmp.result); // inlined await_resume</code></pre></div>=
<div><br></div><div>which is pretty much what you would have written by han=
d if you would write your coroutine in assembly.</div><div>Compare that to =
"can do it in a library" approach.</div><div><br></div><div>First=
, look at heavy-weight await emulation machinery described in 12.5 of P0114=
R0 starting on page 21.</div><div><br>But, let's say, await is not a na=
tural pattern for P0114, that is why it is heavy weight. Let's look at =
what could be more natural pattern, shown in:</div><div>https://github.com/=
chriskohlhoff/resumable-expressions/blob/master/examples/await4.cpp . Same =
situtation, not as bad as with await emulation, but, still bad.<br></div><d=
iv><br></div><div>Though, I think that this is fixable. P0114RX can get syn=
tactic sugar equivalent of await and yield, it would not need to do as much=
work in the library. So it will become as efficient P0057.=C2=A0</div><div=
><br></div><div>What remains are various inconveniences of how coroutines a=
re presented to the user.</div><div>You need to do manual type erasure, lik=
e in this example (await4.cpp):</div><div><br></div><div class=3D"prettypri=
nt" style=3D"border: 1px solid rgb(187, 187, 187); word-wrap: break-word; b=
ackground-color: rgb(250, 250, 250);"><code class=3D"prettyprint"><div clas=
s=3D"subprettyprint"><span style=3D"color: #000;" class=3D"styled-by-pretti=
fy">resumable </span><span style=3D"color: #008;" class=3D"styled-by-pretti=
fy">void</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> e=
cho</span><span style=3D"color: #660;" class=3D"styled-by-prettify">(</span=
><span style=3D"color: #000;" class=3D"styled-by-prettify">tcp</span><span =
style=3D"color: #660;" class=3D"styled-by-prettify">::</span><span style=3D=
"color: #000;" class=3D"styled-by-prettify">socket socket</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>resumable </span><span style=
=3D"color: #008;" class=3D"styled-by-prettify">void</span><span style=3D"co=
lor: #000;" class=3D"styled-by-prettify"> listen</span><span style=3D"color=
: #660;" class=3D"styled-by-prettify">(</span><span style=3D"color: #000;" =
class=3D"styled-by-prettify">tcp</span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">::</span><span style=3D"color: #000;" class=3D"styl=
ed-by-prettify">acceptor acceptor</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: #660;" class=3D"s=
tyled-by-prettify">...</span><span style=3D"color: #000;" class=3D"styled-b=
y-prettify"><br>=C2=A0 =C2=A0 spawn</span><span style=3D"color: #660;" clas=
s=3D"styled-by-prettify">([</span><span style=3D"color: #000;" class=3D"sty=
led-by-prettify">s </span><span style=3D"color: #660;" class=3D"styled-by-p=
rettify">=3D</span><span style=3D"color: #000;" class=3D"styled-by-prettify=
"> std</span><span style=3D"color: #660;" class=3D"styled-by-prettify">::</=
span><span style=3D"color: #000;" class=3D"styled-by-prettify">move</span><=
span style=3D"color: #660;" class=3D"styled-by-prettify">(</span><span styl=
e=3D"color: #000;" class=3D"styled-by-prettify">socket</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">mutable</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"> echo</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">move</span><span styl=
e=3D"color: #660;" class=3D"styled-by-prettify">(</span><span style=3D"colo=
r: #000;" class=3D"styled-by-prettify">s</span><span style=3D"color: #660;"=
class=3D"styled-by-prettify">));</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"> </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></span></div></code></div><div><br>When I say manual type erasu=
re, I mean that instead of just calling echo, you need to wrap it in a lamb=
da and give to type-erasing library helper spawn that does wrapping and all=
ocation for you.</div><div><br></div><div>Another limitation is that you ha=
ve to put everything in one file to the code above to work, since in order =
for listen to be able to use echo in resumable expression, it needs to see =
the body of the echo, thus, it needs to be defined in the same TU. If you w=
ant to put them in different files you need to create little type erasing w=
rappers, as in:</div><div><br></div><div class=3D"prettyprint" style=3D"bor=
der: 1px solid rgb(187, 187, 187); word-wrap: break-word; background-color:=
rgb(250, 250, 250);"><code class=3D"prettyprint"><div class=3D"subprettypr=
int"><span style=3D"color: #000;" class=3D"styled-by-prettify">echo</span><=
span style=3D"color: #660;" class=3D"styled-by-prettify">.</span><span styl=
e=3D"color: #000;" class=3D"styled-by-prettify">h</span><span style=3D"colo=
r: #660;" class=3D"styled-by-prettify">:</span><span style=3D"color: #000;"=
class=3D"styled-by-prettify"><br></span><span style=3D"color: #008;" class=
=3D"styled-by-prettify">void</span><span style=3D"color: #000;" class=3D"st=
yled-by-prettify"> echo</span><span style=3D"color: #660;" class=3D"styled-=
by-prettify">(</span><span style=3D"color: #000;" class=3D"styled-by-pretti=
fy">tcp</span><span style=3D"color: #660;" class=3D"styled-by-prettify">::<=
/span><span style=3D"color: #000;" class=3D"styled-by-prettify">socket sock=
et</span><span style=3D"color: #660;" class=3D"styled-by-prettify">);</span=
><span style=3D"color: #000;" class=3D"styled-by-prettify"><br><br>echo</sp=
an><span style=3D"color: #660;" class=3D"styled-by-prettify">.</span><span =
style=3D"color: #000;" class=3D"styled-by-prettify">cpp</span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">:</span><span style=3D"color=
: #000;" class=3D"styled-by-prettify"><br><br>resumable echo_impl</span><fo=
nt color=3D"#666600"><span style=3D"color: #660;" class=3D"styled-by-pretti=
fy">(</span><span style=3D"color: #000;" class=3D"styled-by-prettify">tcp</=
span><span style=3D"color: #660;" class=3D"styled-by-prettify">::</span><sp=
an style=3D"color: #000;" class=3D"styled-by-prettify">socket socket</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: #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"sty=
led-by-prettify"> </span><span style=3D"color: #660;" class=3D"styled-by-pr=
ettify">}</span></font><span style=3D"color: #000;" class=3D"styled-by-pret=
tify"><br><br></span><span style=3D"color: #008;" class=3D"styled-by-pretti=
fy">void</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> e=
cho</span><span style=3D"color: #660;" class=3D"styled-by-prettify">(</span=
><span style=3D"color: #000;" class=3D"styled-by-prettify">tcp</span><span =
style=3D"color: #660;" class=3D"styled-by-prettify">::</span><span style=3D=
"color: #000;" class=3D"styled-by-prettify">socket socket</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 spawn</span><span style=3D"color: #66=
0;" class=3D"styled-by-prettify">([</span><span style=3D"color: #000;" clas=
s=3D"styled-by-prettify">s </span><span style=3D"color: #660;" class=3D"sty=
led-by-prettify">=3D</span><span style=3D"color: #000;" class=3D"styled-by-=
prettify"> std</span><span style=3D"color: #660;" class=3D"styled-by-pretti=
fy">::</span><span style=3D"color: #000;" class=3D"styled-by-prettify">move=
</span><span style=3D"color: #660;" class=3D"styled-by-prettify">(</span><s=
pan style=3D"color: #000;" class=3D"styled-by-prettify">socket</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">mutable</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"> echo_impl</span><span style=3D"color: #660;" class=3D"sty=
led-by-prettify">(</span><span style=3D"color: #000;" class=3D"styled-by-pr=
ettify">std</span><span style=3D"color: #660;" class=3D"styled-by-prettify"=
>::</span><span style=3D"color: #000;" class=3D"styled-by-prettify">move</s=
pan><span style=3D"color: #660;" class=3D"styled-by-prettify">(</span><span=
style=3D"color: #000;" class=3D"styled-by-prettify">s</span><span style=3D=
"color: #660;" class=3D"styled-by-prettify">));</span><span style=3D"color:=
#000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #660;" c=
lass=3D"styled-by-prettify">});</span><span style=3D"color: #000;" class=3D=
"styled-by-prettify"><br></span><span style=3D"color: #660;" class=3D"style=
d-by-prettify">}</span></div></code></div><div><br></div><div>I am not so m=
uch critisizing Chris, as critisizing myself. I went through this design al=
ready when exploring lambda* nearly two years ago. I reached a conclusion t=
hat for the problems I tried to apply it to, it did not offer anything to c=
ompensate for the complexity compared to boring C# like await syntax. Hence=
, I no longer pursue this approach.</div><div><br></div><div>It does not me=
an that for <b>some</b> problems, some incarnation of lambda* <b>might</b> =
be better than P0057. That is wonderful. When this happen, let's add it=
in, in addition to P0057 and P0099 (modestly called "A low-level API =
for stackful context switching").</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_1557_71016232.1444829870177--
------=_Part_1556_1021943582.1444829870177--
.
Author: Nicol Bolas <jmckesson@gmail.com>
Date: Wed, 14 Oct 2015 06:47:09 -0700 (PDT)
Raw View
------=_Part_47_2041749954.1444830429386
Content-Type: multipart/alternative;
boundary="----=_Part_48_232803820.1444830429387"
------=_Part_48_232803820.1444830429387
Content-Type: text/plain; charset=UTF-8
On Wednesday, October 14, 2015 at 1:13:56 AM UTC-4, Evgeny Panasyuk wrote:
>
> 14.10.2015 7:51, Nicol Bolas:
>
> > If you need only async I/O - yes, I could imagine that extra
> > allocation is tolerable in such context. But P0057 describes not
> > only async I/O - but also for instance generators. And for
> > generators (like transform iterators) an extra allocation is huge
> price.
> >
> >
> > A price you will never pay because it will be elided.
> >
> > Please stop repeating statements that have been disproven; it's not
> > helping your case. You have yet to post an example of a generator that
> > would not be elided.
>
> I already described it several times, just put generator into some
> structure/array or return somewhere.
> In similar situation:
> http://coliru.stacked-crooked.com/a/0c09744abd5e57ae
> - allocation of P0057 generator will not be elided, there will be N
> allocations, i.e. for each coroutine.
>
And in your case, the `Coroutine` will have to type-erase them too. Thus
performing N allocations.
Put it another way. In order to make something a member of a struct, you
must first be able to name it. In C++ as it currently stands, it is
*impossible* to store an unnamable type in a non-static data member.
Whether it's a lambda or the result of a resumable expression or anything
else, it simply *cannot happen*.
Templates will not save you, because you can't do this:
Coroutine<resumable {expr}>.
You can't even do this:
using coroutine_type = decltype(resumable {expr});
Why do these fail? Because each separate `expr`, even if it's technically
the exact same function, will result in a different type. Just like a
lambda, copying-and-pasting the expression will yield a different type.
What you're suggesting is impossible. Or at least, it's impossible without
trickery (ie: macros).
So Boost.Asio is either doing type erasure or it is cheating. Any core
feature will not be allowed to cheat, so you'll *have* to use type erasure
to store the result of such an operation.
You can read what Gor said previously in this topic:
>
>
> "If coroutine lifetime is fully enclosed in the lifetime of the calling
> function, then we can
> 1) elide allocation and use a temporary on the stack of the caller
> 2) replace indirect calls with direct calls and inline as appropriate:"
>
> There is "if" condition. Even if we assume that optimizers always do
> elision when condition is true, there is still no elision for cases with
> false condition.
>
The only way you could avoid a dynamic allocation while still leaving the
lifetime of the calling function is if you could copy/move the coroutine
type. And that's just not reasonable.
Or rather, whether a coroutine is movable is based *entirely* on its
implementation. An implementation that you may not have access to. So how
could the compiler possibly know that function X will return an immobile
type while function Y returns a mobile one?
Of course, for P0114, the question is moot: all resumable functions must be
inline, and thus any code catching them will know whether they're mobile or
not. But for any other suggestion, the question still stands: if the
function isn't inline, how do you know if the coroutine type is mobile?
This is a question that has yet to yield a satisfactory answer. P0114 says
that you have to box non-inline functions, which means you *always* pay
overhead for them, unlike P0057, which allows the possibility of optimizing
the overhead based on usage.
Without a plan to deal with coroutine type mobility for non-inline cases,
there's no reason to talk about what happens if a non-erased coroutine type
escapes its owning function.
P0057 has a plan for this. You don't thus far.
--
---
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_48_232803820.1444830429387
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
On Wednesday, October 14, 2015 at 1:13:56 AM UTC-4, Evgeny Panasyuk wrote:<=
blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;bord=
er-left: 1px #ccc solid;padding-left: 1ex;">14.10.2015 7:51, Nicol Bolas:
<br>
<br>> =C2=A0 =C2=A0 If you need only async I/O - yes, I could imagine th=
at extra
<br>> =C2=A0 =C2=A0 allocation is tolerable in such context. But P0057 d=
escribes not
<br>> =C2=A0 =C2=A0 only async I/O - but also for instance generators. A=
nd for
<br>> =C2=A0 =C2=A0 generators (like transform iterators) an extra alloc=
ation is huge price.
<br>>
<br>>
<br>> A price you will never pay because it will be elided.
<br>>
<br>> Please stop repeating statements that have been disproven; it'=
s not
<br>> helping your case. You have yet to post an example of a generator =
that
<br>> would not be elided.
<br>
<br>I already described it several times, just put generator into some=20
<br>structure/array or return somewhere.
<br>In similar situation:
<br><a href=3D"http://coliru.stacked-crooked.com/a/0c09744abd5e57ae" target=
=3D"_blank" rel=3D"nofollow" onmousedown=3D"this.href=3D'http://www.goo=
gle.com/url?q\75http%3A%2F%2Fcoliru.stacked-crooked.com%2Fa%2F0c09744abd5e5=
7ae\46sa\75D\46sntz\0751\46usg\75AFQjCNEx46W0ovPGreVk53aziTYTbJG0dg';re=
turn true;" onclick=3D"this.href=3D'http://www.google.com/url?q\75http%=
3A%2F%2Fcoliru.stacked-crooked.com%2Fa%2F0c09744abd5e57ae\46sa\75D\46sntz\0=
751\46usg\75AFQjCNEx46W0ovPGreVk53aziTYTbJG0dg';return true;">http://co=
liru.stacked-crooked.<wbr>com/a/0c09744abd5e57ae</a>
<br>- allocation of P0057 generator will not be elided, there will be N=20
<br>allocations, i.e. for each coroutine.<br></blockquote><div><br>And in y=
our case, the `Coroutine` will have to type-erase them too. Thus performing=
N allocations.<br><br>Put it another way. In order to make something a mem=
ber of a struct, you must first be able to name it. In C++ as it currently =
stands, it is <i>impossible</i> to store an unnamable type in a non-static =
data member. Whether it's a lambda or the result of a resumable express=
ion or anything else, it simply <i>cannot happen</i>.<br><br>Templates will=
not save you, because you can't do this:<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: #606;" class=3D"styled-by-prettify">Coroutine</span><span style=3D"col=
or: #660;" class=3D"styled-by-prettify"><</span><span style=3D"color: #0=
00;" class=3D"styled-by-prettify">resumable </span><span style=3D"color: #6=
60;" class=3D"styled-by-prettify">{</span><span style=3D"color: #000;" clas=
s=3D"styled-by-prettify">expr</span><span style=3D"color: #660;" class=3D"s=
tyled-by-prettify">}>.</span></div></code></div><br>You can't even d=
o this:<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">using</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> c=
oroutine_type </span><span style=3D"color: #660;" class=3D"styled-by-pretti=
fy">=3D</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </=
span><span style=3D"color: #008;" class=3D"styled-by-prettify">decltype</sp=
an><span style=3D"color: #660;" class=3D"styled-by-prettify">(</span><span =
style=3D"color: #000;" class=3D"styled-by-prettify">resumable </span><span =
style=3D"color: #660;" class=3D"styled-by-prettify">{</span><span style=3D"=
color: #000;" class=3D"styled-by-prettify">expr</span><span style=3D"color:=
#660;" class=3D"styled-by-prettify">});</span></div></code></div><br>Why d=
o these fail? Because each separate `expr`, even if it's technically th=
e exact same function, will result in a different type. Just like a lambda,=
copying-and-pasting the expression will yield a different type.<br><br>Wha=
t you're suggesting is impossible. Or at least, it's impossible wit=
hout trickery (ie: macros).<br><br>So Boost.Asio is either doing type erasu=
re or it is cheating. Any core feature will not be allowed to cheat, so you=
'll <i>have</i> to use type erasure to store the result of such an oper=
ation.<br><br></div><blockquote class=3D"gmail_quote" style=3D"margin: 0;ma=
rgin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">
You can read what Gor said previously in this topic:
<br>
<br>
<br>"If coroutine lifetime is fully enclosed in the lifetime of the ca=
lling=20
<br>function, then we can
<br>1) elide allocation and use a temporary on the stack of the caller
<br>2) replace indirect calls with direct calls and inline as appropriate:&=
quot;
<br>
<br>
There is "if" condition. Even if we assume that optimizers always=
do=20
<br>elision when condition is true, there is still no elision for cases wit=
h=20
<br>false condition.<br></blockquote><div><br>The only way you could avoid =
a dynamic allocation while still leaving the lifetime of the calling functi=
on is if you could copy/move the coroutine type. And that's just not re=
asonable.<br><br>Or rather, whether a coroutine is movable is based <i>enti=
rely</i> on its implementation. An implementation that you may not have acc=
ess to. So how could the compiler possibly know that function X will return=
an immobile type while function Y returns a mobile one?<br><br>Of course, =
for P0114, the question is moot: all resumable functions must be inline, an=
d thus any code catching them will know whether they're mobile or not. =
But for any other suggestion, the question still stands: if the function is=
n't inline, how do you know if the coroutine type is mobile?<br><br>Thi=
s is a question that has yet to yield a satisfactory answer. P0114 says tha=
t you have to box non-inline functions, which means you <i>always</i> pay o=
verhead for them, unlike P0057, which allows the possibility of optimizing =
the overhead based on usage.<br><br>Without a plan to deal with coroutine t=
ype mobility for non-inline cases, there's no reason to talk about what=
happens if a non-erased coroutine type escapes its owning function.<br><br=
>P0057 has a plan for this. You don't thus far.<br></div>
<p></p>
-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />
------=_Part_48_232803820.1444830429387--
------=_Part_47_2041749954.1444830429386--
.
Author: Nicol Bolas <jmckesson@gmail.com>
Date: Wed, 14 Oct 2015 06:59:33 -0700 (PDT)
Raw View
------=_Part_254_1892763629.1444831173352
Content-Type: multipart/alternative;
boundary="----=_Part_255_1001357200.1444831173356"
------=_Part_255_1001357200.1444831173356
Content-Type: text/plain; charset=UTF-8
On Wednesday, October 14, 2015 at 9:37:50 AM UTC-4, Gor Nishanov wrote:
>
> It does not mean that for *some* problems, some incarnation of lambda*
> *might* be better than P0057. That is wonderful. When this happen, let's
> add it in, in addition to P0057 and P0099 (modestly called "A low-level API
> for stackful context switching").
>
There are two problems with the "let's add it in" approach.
First, how do you teach when to use which? For stackful vs. stackless, it's
quite easy. You usually know when you genuinely want a stack, and emulating
that with stackless (as I discovered) becomes amazingly difficult very
quickly. Similarly, stackful makes it very apparent that creating an
execution_context is allocating memory, so it's not cheap (though I was
surprised to see that Boost.Context's switching only cost ~50 cycles or so).
So with P0114 in the mix, how do you tell people when to use which? Do you
use P0114 when you want stackless that can go farther than one or two
functions? Is there some simple guideline you can tell beginners about when
to use which tool?
The second problem is interoperation. How P0099 and P0057 interoperate is
pretty obvious. How P0114 would interop with P0057 is... less obvious. What
happens if you `break resume` in an awaitable? Can you use `await` in a
resumable function? What madness does `await resumable <expr>` accomplish?
Now, they may have obvious interactions. I haven't gone through a detailed
analysis of both. But it is disconcerting.
--
---
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_255_1001357200.1444831173356
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">On Wednesday, October 14, 2015 at 9:37:50 AM UTC-4, Gor Ni=
shanov wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-le=
ft: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr">=
<div>It does not mean that for <b>some</b> problems, some incarnation of la=
mbda* <b>might</b> be better than P0057. That is wonderful. When this happe=
n, let's add it in, in addition to P0057 and P0099 (modestly called &qu=
ot;A low-level API for stackful context switching").</div></div></bloc=
kquote><div><br>There are two problems with the "let's add it in&q=
uot; approach.<br><br>First, how do you teach when to use which? For stackf=
ul vs. stackless, it's quite easy. You usually know when you genuinely =
want a stack, and emulating that with stackless (as I discovered) becomes a=
mazingly difficult very quickly. Similarly, stackful makes it very apparent=
that creating an execution_context is allocating memory, so it's not c=
heap (though I was surprised to see that Boost.Context's switching only=
cost ~50 cycles or so).<br><br>So with P0114 in the mix, how do you tell p=
eople when to use which? Do you use P0114 when you want stackless that can =
go farther than one or two functions? Is there some simple guideline you ca=
n tell beginners about when to use which tool?<br><br>The second problem is=
interoperation. How P0099 and P0057 interoperate is pretty obvious. How P0=
114 would interop with P0057 is... less obvious. What happens if you `break=
resume` in an awaitable? Can you use `await` in a resumable function? What=
madness does `await resumable <expr>` accomplish?<br><br>Now, they m=
ay have obvious interactions. I haven't gone through a detailed analysi=
s of both. But it is disconcerting.<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_255_1001357200.1444831173356--
------=_Part_254_1892763629.1444831173352--
.
Author: Gor Nishanov <gornishanov@gmail.com>
Date: Wed, 14 Oct 2015 07:12:13 -0700 (PDT)
Raw View
------=_Part_8883_731290095.1444831933125
Content-Type: multipart/alternative;
boundary="----=_Part_8884_826478480.1444831933125"
------=_Part_8884_826478480.1444831933125
Content-Type: text/plain; charset=UTF-8
On Wednesday, October 14, 2015 at 6:59:33 AM UTC-7, Nicol Bolas wrote:
>
> On Wednesday, October 14, 2015 at 9:37:50 AM UTC-4, Gor Nishanov wrote:
>>
>> It does not mean that for *some* problems, some incarnation of lambda*
>> *might* be better than P0057. That is wonderful. When this happen, let's
>> add it in, in addition to P0057 and P0099 (modestly called "A low-level API
>> for stackful context switching").
>>
>
> There are two problems with the "let's add it in" approach.
>
> First, how do you teach when to use which?
>
The second problem is interoperation. How P0114 would interop with P0057?
>
I need to learn to be more direct. The answers to your questions are in two
"some" I used in the sentence you quoted.
First *some*, means, that there must be a problem which gives a lambda* a
clear benefit over P0057. Thus, if lambda* is accepted, there is some
important problem that P0057 does not address it efficiently. That should
give a pretty clear indication when you should not use P0057 and use
lambda* instead.
The second *some*, states that: "for *some* incarnation of lambda*". We
don't know what it is at the moment. Thus it is premature to worry how it
will interoperate. It might do so magnificently or not at all. We don't
know.
--
---
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_8884_826478480.1444831933125
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<br><br>On Wednesday, October 14, 2015 at 6:59:33 AM UTC-7, Nicol Bolas wro=
te:<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 Wednesd=
ay, October 14, 2015 at 9:37:50 AM UTC-4, Gor Nishanov wrote:<blockquote cl=
ass=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1px #cc=
c solid;padding-left:1ex"><div dir=3D"ltr"><div>It does not mean that for <=
b>some</b> problems, some incarnation of lambda* <b>might</b> be better tha=
n P0057. That is wonderful. When this happen, let's add it in, in addit=
ion to P0057 and P0099 (modestly called "A low-level API for stackful =
context switching").</div></div></blockquote><div><br>There are two pr=
oblems with the "let's add it in" approach.<br><br>First, how=
do you teach when to use which?=C2=A0<br></div></div></blockquote><div><br=
></div><blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.=
8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr"><div>T=
he second problem is interoperation. How P0114 would interop with P0057?</d=
iv></div></blockquote><div>=C2=A0</div><div>I need to learn to be more dire=
ct. The answers to your questions are in two "some" I used in the=
sentence you quoted.</div><div>First <b>some</b>, means, that there must b=
e a problem which gives a lambda* a clear benefit over P0057. Thus, if lamb=
da* is accepted, there is some important problem that P0057 does not addres=
s it efficiently. That should give a pretty clear indication when you shoul=
d not use P0057 and use lambda* instead.</div><div><br></div><div>The secon=
d <b>some</b>, states that: "for <b>some</b> incarnation of lambda*&qu=
ot;. We don't know what it is at the moment. Thus it is premature to wo=
rry how it will interoperate. It might do so magnificently or not at all. W=
e don't know.<br></div>
<p></p>
-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />
------=_Part_8884_826478480.1444831933125--
------=_Part_8883_731290095.1444831933125--
.
Author: Giovanni Piero Deretta <gpderetta@gmail.com>
Date: Wed, 14 Oct 2015 08:16:34 -0700 (PDT)
Raw View
------=_Part_7245_699210662.1444835794817
Content-Type: multipart/alternative;
boundary="----=_Part_7246_923534100.1444835794818"
------=_Part_7246_923534100.1444835794818
Content-Type: text/plain; charset=UTF-8
On Wednesday, October 14, 2015 at 2:47:09 PM UTC+1, Nicol Bolas wrote:
>
> On Wednesday, October 14, 2015 at 1:13:56 AM UTC-4, Evgeny Panasyuk wrote:
>>
>> 14.10.2015 7:51, Nicol Bolas:
>>
>> > If you need only async I/O - yes, I could imagine that extra
>> > allocation is tolerable in such context. But P0057 describes not
>> > only async I/O - but also for instance generators. And for
>> > generators (like transform iterators) an extra allocation is huge
>> price.
>> >
>> >
>> > A price you will never pay because it will be elided.
>> >
>> > Please stop repeating statements that have been disproven; it's not
>> > helping your case. You have yet to post an example of a generator that
>> > would not be elided.
>>
>> I already described it several times, just put generator into some
>> structure/array or return somewhere.
>> In similar situation:
>> http://coliru.stacked-crooked.com/a/0c09744abd5e57ae
>> - allocation of P0057 generator will not be elided, there will be N
>> allocations, i.e. for each coroutine.
>>
>
> And in your case, the `Coroutine` will have to type-erase them too. Thus
> performing N allocations.
>
> Put it another way. In order to make something a member of a struct, you
> must first be able to name it. In C++ as it currently stands, it is
> *impossible* to store an unnamable type in a non-static data member.
> Whether it's a lambda or the result of a resumable expression or anything
> else, it simply *cannot happen*.
>
It is trivially possible. The name is unimportant, only the type is. In
this example a lambda stands for an unnamed type. I could have used other
unnamed types.
template<class Impl> struct Coroutine { Impl body; };
auto createACoroutine()
{
auto coro = [] {...};
Coroutine<decltype(coro)> coroWrapper = {coro};
return coroWrapper;
}
-- gpd
--
---
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_7246_923534100.1444835794818
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
On Wednesday, October 14, 2015 at 2:47:09 PM UTC+1, Nicol Bolas wrote:<bloc=
kquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-l=
eft: 1px #ccc solid;padding-left: 1ex;">On Wednesday, October 14, 2015 at 1=
:13:56 AM UTC-4, Evgeny Panasyuk wrote:<blockquote class=3D"gmail_quote" st=
yle=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-left:1=
ex">14.10.2015 7:51, Nicol Bolas:
<br>
<br>> =C2=A0 =C2=A0 If you need only async I/O - yes, I could imagine th=
at extra
<br>> =C2=A0 =C2=A0 allocation is tolerable in such context. But P0057 d=
escribes not
<br>> =C2=A0 =C2=A0 only async I/O - but also for instance generators. A=
nd for
<br>> =C2=A0 =C2=A0 generators (like transform iterators) an extra alloc=
ation is huge price.
<br>>
<br>>
<br>> A price you will never pay because it will be elided.
<br>>
<br>> Please stop repeating statements that have been disproven; it'=
s not
<br>> helping your case. You have yet to post an example of a generator =
that
<br>> would not be elided.
<br>
<br>I already described it several times, just put generator into some=20
<br>structure/array or return somewhere.
<br>In similar situation:
<br><a href=3D"http://coliru.stacked-crooked.com/a/0c09744abd5e57ae" rel=3D=
"nofollow" target=3D"_blank" onmousedown=3D"this.href=3D'http://www.goo=
gle.com/url?q\75http%3A%2F%2Fcoliru.stacked-crooked.com%2Fa%2F0c09744abd5e5=
7ae\46sa\75D\46sntz\0751\46usg\75AFQjCNEx46W0ovPGreVk53aziTYTbJG0dg';re=
turn true;" onclick=3D"this.href=3D'http://www.google.com/url?q\75http%=
3A%2F%2Fcoliru.stacked-crooked.com%2Fa%2F0c09744abd5e57ae\46sa\75D\46sntz\0=
751\46usg\75AFQjCNEx46W0ovPGreVk53aziTYTbJG0dg';return true;">http://co=
liru.stacked-crooked.<wbr>com/a/0c09744abd5e57ae</a>
<br>- allocation of P0057 generator will not be elided, there will be N=20
<br>allocations, i.e. for each coroutine.<br></blockquote><div><br>And in y=
our case, the `Coroutine` will have to type-erase them too. Thus performing=
N allocations.<br><br>Put it another way. In order to make something a mem=
ber of a struct, you must first be able to name it. In C++ as it currently =
stands, it is <i>impossible</i> to store an unnamable type in a non-static =
data member. Whether it's a lambda or the result of a resumable express=
ion or anything else, it simply <i>cannot happen</i>.<br></div></blockquote=
><div><br>It is trivially possible. The name is unimportant, only the type =
is. In this example a lambda stands for an unnamed type. I could have used =
other unnamed types.<br><br>template<class Impl> struct Coroutine { I=
mpl body; };<br><br>auto createACoroutine()<br>{<br>=C2=A0=C2=A0 auto coro =
=3D [] {...};<br>=C2=A0=C2=A0 Coroutine<decltype(coro)> coroWrapper =
=3D {coro};<br>=C2=A0=C2=A0 return coroWrapper;<br>}=C2=A0</div><br><br>-- =
gpd<br>
<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_7246_923534100.1444835794818--
------=_Part_7245_699210662.1444835794817--
.
Author: Nicol Bolas <jmckesson@gmail.com>
Date: Wed, 14 Oct 2015 08:31:39 -0700 (PDT)
Raw View
------=_Part_166_1549063732.1444836699749
Content-Type: multipart/alternative;
boundary="----=_Part_167_581211030.1444836699749"
------=_Part_167_581211030.1444836699749
Content-Type: text/plain; charset=UTF-8
On Wednesday, October 14, 2015 at 11:16:35 AM UTC-4, Giovanni Piero Deretta
wrote:
>
> On Wednesday, October 14, 2015 at 2:47:09 PM UTC+1, Nicol Bolas wrote:
>>
>> On Wednesday, October 14, 2015 at 1:13:56 AM UTC-4, Evgeny Panasyuk wrote:
>>>
>>> 14.10.2015 7:51, Nicol Bolas:
>>>
>>> > If you need only async I/O - yes, I could imagine that extra
>>> > allocation is tolerable in such context. But P0057 describes not
>>> > only async I/O - but also for instance generators. And for
>>> > generators (like transform iterators) an extra allocation is huge
>>> price.
>>> >
>>> >
>>> > A price you will never pay because it will be elided.
>>> >
>>> > Please stop repeating statements that have been disproven; it's not
>>> > helping your case. You have yet to post an example of a generator that
>>> > would not be elided.
>>>
>>> I already described it several times, just put generator into some
>>> structure/array or return somewhere.
>>> In similar situation:
>>> http://coliru.stacked-crooked.com/a/0c09744abd5e57ae
>>> - allocation of P0057 generator will not be elided, there will be N
>>> allocations, i.e. for each coroutine.
>>>
>>
>> And in your case, the `Coroutine` will have to type-erase them too. Thus
>> performing N allocations.
>>
>> Put it another way. In order to make something a member of a struct, you
>> must first be able to name it. In C++ as it currently stands, it is
>> *impossible* to store an unnamable type in a non-static data member.
>> Whether it's a lambda or the result of a resumable expression or anything
>> else, it simply *cannot happen*.
>>
>
> It is trivially possible. The name is unimportant, only the type is. In
> this example a lambda stands for an unnamed type. I could have used other
> unnamed types.
>
> template<class Impl> struct Coroutine { Impl body; };
>
> auto createACoroutine()
> {
> auto coro = [] {...};
> Coroutine<decltype(coro)> coroWrapper = {coro};
> return coroWrapper;
> }
>
OK, yes you can do that. My mistake.
However, that code is not a complete example. It doesn't match with your
sample code (which currently uses type erasure/chicanery). So what does the
non-trick version look like?
const int numCoroutines = 10000;
std::vector<What> v;
v.reserve(10000);
for(int i : range(0, 10000))
v.emplace_back(createACoroutine);
What goes in `What`?
Oh sure, you can do it if you invert it and wrap it in a function call:
auto createCoroutineVector(const int numCoroutines)
{
std::vector<decltype(createACoroutine())> v;
v.reserve(numCoroutines);
for(int i : range(0, 10000))
v.emplace_back(createACoroutine);
return v;
}
But this now forces every piece of code to use template deduction to
interact with this data. This makes the code a lot less readable.
Just look at this example for inscrutability. To be able to know what to do
with the return value, I have to look through two function definitions. The
more layers between the source type and the destination, the less readable
the code gets.
I would much rather have a genuine type and type-erasure than to have to
search through 5 function calls just to figure out what a type is supposed
to be.
--
---
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_167_581211030.1444836699749
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<br><br>On Wednesday, October 14, 2015 at 11:16:35 AM UTC-4, Giovanni Piero=
Deretta wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-=
left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">On Wednesday, O=
ctober 14, 2015 at 2:47:09 PM UTC+1, Nicol Bolas wrote:<blockquote class=3D=
"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc soli=
d;padding-left:1ex">On Wednesday, October 14, 2015 at 1:13:56 AM UTC-4, Evg=
eny Panasyuk wrote:<blockquote class=3D"gmail_quote" style=3D"margin:0;marg=
in-left:0.8ex;border-left:1px #ccc solid;padding-left:1ex">14.10.2015 7:51,=
Nicol Bolas:
<br>
<br>> =C2=A0 =C2=A0 If you need only async I/O - yes, I could imagine th=
at extra
<br>> =C2=A0 =C2=A0 allocation is tolerable in such context. But P0057 d=
escribes not
<br>> =C2=A0 =C2=A0 only async I/O - but also for instance generators. A=
nd for
<br>> =C2=A0 =C2=A0 generators (like transform iterators) an extra alloc=
ation is huge price.
<br>>
<br>>
<br>> A price you will never pay because it will be elided.
<br>>
<br>> Please stop repeating statements that have been disproven; it'=
s not
<br>> helping your case. You have yet to post an example of a generator =
that
<br>> would not be elided.
<br>
<br>I already described it several times, just put generator into some=20
<br>structure/array or return somewhere.
<br>In similar situation:
<br><a href=3D"http://coliru.stacked-crooked.com/a/0c09744abd5e57ae" rel=3D=
"nofollow" target=3D"_blank" onmousedown=3D"this.href=3D'http://www.goo=
gle.com/url?q\75http%3A%2F%2Fcoliru.stacked-crooked.com%2Fa%2F0c09744abd5e5=
7ae\46sa\75D\46sntz\0751\46usg\75AFQjCNEx46W0ovPGreVk53aziTYTbJG0dg';re=
turn true;" onclick=3D"this.href=3D'http://www.google.com/url?q\75http%=
3A%2F%2Fcoliru.stacked-crooked.com%2Fa%2F0c09744abd5e57ae\46sa\75D\46sntz\0=
751\46usg\75AFQjCNEx46W0ovPGreVk53aziTYTbJG0dg';return true;">http://co=
liru.stacked-crooked.<wbr>com/a/0c09744abd5e57ae</a>
<br>- allocation of P0057 generator will not be elided, there will be N=20
<br>allocations, i.e. for each coroutine.<br></blockquote><div><br>And in y=
our case, the `Coroutine` will have to type-erase them too. Thus performing=
N allocations.<br><br>Put it another way. In order to make something a mem=
ber of a struct, you must first be able to name it. In C++ as it currently =
stands, it is <i>impossible</i> to store an unnamable type in a non-static =
data member. Whether it's a lambda or the result of a resumable express=
ion or anything else, it simply <i>cannot happen</i>.<br></div></blockquote=
><div><br>It is trivially possible. The name is unimportant, only the type =
is. In this example a lambda stands for an unnamed type. I could have used =
other unnamed types.<br><br>template<class Impl> struct Coroutine { I=
mpl body; };<br><br>auto createACoroutine()<br>{<br>=C2=A0=C2=A0 auto coro =
=3D [] {...};<br>=C2=A0=C2=A0 Coroutine<decltype(coro)> coroWrapper =
=3D {coro};<br>=C2=A0=C2=A0 return coroWrapper;<br>}<br></div></blockquote>=
<div><br>OK, yes you can do that. My mistake.<br><br>However, that code is =
not a=20
complete example. It doesn't match with your sample code (which=20
currently uses type erasure/chicanery). So what does the non-trick version =
look like?<br><br><div class=3D"prettyprint" style=3D"background-color: rgb=
(250, 250, 250); border-color: rgb(187, 187, 187); border-style: solid; bor=
der-width: 1px; word-wrap: break-word;"><code class=3D"prettyprint"><div cl=
ass=3D"subprettyprint"><span style=3D"color: #008;" class=3D"styled-by-pret=
tify">const</span><span style=3D"color: #000;" class=3D"styled-by-prettify"=
> </span><span style=3D"color: #008;" class=3D"styled-by-prettify">int</spa=
n><span style=3D"color: #000;" class=3D"styled-by-prettify"> numCoroutines =
</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 sty=
le=3D"color: #066;" class=3D"styled-by-prettify">10000</span><span style=3D=
"color: #660;" class=3D"styled-by-prettify">;</span><span style=3D"color: #=
000;" class=3D"styled-by-prettify"><br>std</span><span style=3D"color: #660=
;" class=3D"styled-by-prettify">::</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify">vector</span><span style=3D"color: #660;" class=3D"=
styled-by-prettify"><</span><span style=3D"color: #606;" class=3D"styled=
-by-prettify">What</span><span style=3D"color: #660;" class=3D"styled-by-pr=
ettify">></span><span style=3D"color: #000;" class=3D"styled-by-prettify=
"> v</span><span style=3D"color: #660;" class=3D"styled-by-prettify">;</spa=
n><span style=3D"color: #000;" class=3D"styled-by-prettify"><br>v</span><sp=
an style=3D"color: #660;" class=3D"styled-by-prettify">.</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify">reserve</span><span style=3D=
"color: #660;" class=3D"styled-by-prettify">(</span><span style=3D"color: #=
066;" class=3D"styled-by-prettify">10000</span><span style=3D"color: #660;"=
class=3D"styled-by-prettify">);</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"><br></span><span style=3D"color: #008;" class=3D"st=
yled-by-prettify">for</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 </=
span><span style=3D"color: #660;" class=3D"styled-by-prettify">:</span><spa=
n style=3D"color: #000;" class=3D"styled-by-prettify"> range</span><span st=
yle=3D"color: #660;" class=3D"styled-by-prettify">(</span><span style=3D"co=
lor: #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: #066;" class=3D"style=
d-by-prettify">10000</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 v</span><span style=3D"color: #660;" class=3D"styled-by-pretti=
fy">.</span><span style=3D"color: #000;" class=3D"styled-by-prettify">empla=
ce_back</span><span style=3D"color: #660;" class=3D"styled-by-prettify">(</=
span><span style=3D"color: #000;" class=3D"styled-by-prettify">createACorou=
tine</span><span style=3D"color: #660;" class=3D"styled-by-prettify">);</sp=
an></div></code></div><br>What goes in `What`?<br><br>Oh sure, you can do i=
t if you invert it and wrap it in a function call:<br><br><div class=3D"pre=
ttyprint" style=3D"background-color: rgb(250, 250, 250); border-color: rgb(=
187, 187, 187); border-style: solid; border-width: 1px; word-wrap: break-wo=
rd;"><code class=3D"prettyprint"><div class=3D"subprettyprint"><span style=
=3D"color: #008;" class=3D"styled-by-prettify">auto</span><span style=3D"co=
lor: #000;" class=3D"styled-by-prettify"> createCoroutineVector</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"colo=
r: #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"> numCoroutines</span><span style=3D"color: #660;" c=
lass=3D"styled-by-prettify">)</span><span style=3D"color: #000;" class=3D"s=
tyled-by-prettify"><br></span><span style=3D"color: #660;" class=3D"styled-=
by-prettify">{</span><span style=3D"color: #000;" class=3D"styled-by-pretti=
fy"><br>=C2=A0 std</span><span style=3D"color: #660;" class=3D"styled-by-pr=
ettify">::</span><span style=3D"color: #000;" class=3D"styled-by-prettify">=
vector</span><span style=3D"color: #660;" class=3D"styled-by-prettify"><=
</span><span style=3D"color: #008;" class=3D"styled-by-prettify">decltype</=
span><span style=3D"color: #660;" class=3D"styled-by-prettify">(</span><spa=
n style=3D"color: #000;" class=3D"styled-by-prettify">createACoroutine</spa=
n><span style=3D"color: #660;" class=3D"styled-by-prettify">())></span><=
span style=3D"color: #000;" class=3D"styled-by-prettify"> v</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 v</span><span style=3D"c=
olor: #660;" class=3D"styled-by-prettify">.</span><span style=3D"color: #00=
0;" class=3D"styled-by-prettify">reserve</span><span style=3D"color: #660;"=
class=3D"styled-by-prettify">(</span><span style=3D"color: #000;" class=3D=
"styled-by-prettify">numCoroutines</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 </span><span style=3D"color: #008;" class=3D"sty=
led-by-prettify">for</span><span style=3D"color: #660;" class=3D"styled-by-=
prettify">(</span><span style=3D"color: #008;" class=3D"styled-by-prettify"=
>int</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> i </s=
pan><span style=3D"color: #660;" class=3D"styled-by-prettify">:</span><span=
style=3D"color: #000;" class=3D"styled-by-prettify"> range</span><span sty=
le=3D"color: #660;" class=3D"styled-by-prettify">(</span><span style=3D"col=
or: #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: #066;" class=3D"style=
d-by-prettify">10000</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 v</span><span style=3D"color: #660;" class=3D"styled-by=
-prettify">.</span><span style=3D"color: #000;" class=3D"styled-by-prettify=
">emplace_back</span><span style=3D"color: #660;" class=3D"styled-by-pretti=
fy">(</span><span style=3D"color: #000;" class=3D"styled-by-prettify">creat=
eACoroutine</span><span style=3D"color: #660;" class=3D"styled-by-prettify"=
>);</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br>=C2=
=A0 </span><span style=3D"color: #008;" class=3D"styled-by-prettify">return=
</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 styl=
e=3D"color: #000;" class=3D"styled-by-prettify"><br></span><span style=3D"c=
olor: #660;" class=3D"styled-by-prettify">}</span><span style=3D"color: #00=
0;" class=3D"styled-by-prettify"><br></span></div></code></div><br>But
this now forces every piece of code to use template deduction to interact w=
ith this data. This makes the code a lot less readable.<br><br>Just look at=
this example for inscrutability. To be able to know what to do with the re=
turn value, I have to look through two function definitions. The more layer=
s between the source type and the destination, the less readable the code g=
ets.<br><br>I would much rather have a genuine type and type-erasure than t=
o have to search through 5 function calls just to figure out what a type is=
supposed to be.<br></div>
<p></p>
-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />
------=_Part_167_581211030.1444836699749--
------=_Part_166_1549063732.1444836699749--
.
Author: Giovanni Piero Deretta <gpderetta@gmail.com>
Date: Wed, 14 Oct 2015 08:42:41 -0700 (PDT)
Raw View
------=_Part_651_995804427.1444837361774
Content-Type: multipart/alternative;
boundary="----=_Part_652_1896260871.1444837361774"
------=_Part_652_1896260871.1444837361774
Content-Type: text/plain; charset=UTF-8
On Wednesday, October 14, 2015 at 4:31:39 PM UTC+1, Nicol Bolas wrote:
>
>
>
> On Wednesday, October 14, 2015 at 11:16:35 AM UTC-4, Giovanni Piero
> Deretta wrote:
>>
>> On Wednesday, October 14, 2015 at 2:47:09 PM UTC+1, Nicol Bolas wrote:
>>>
>>> On Wednesday, October 14, 2015 at 1:13:56 AM UTC-4, Evgeny Panasyuk
>>> wrote:
>>>>
>>>> 14.10.2015 7:51, Nicol Bolas:
>>>>
>>>> > If you need only async I/O - yes, I could imagine that extra
>>>> > allocation is tolerable in such context. But P0057 describes not
>>>> > only async I/O - but also for instance generators. And for
>>>> > generators (like transform iterators) an extra allocation is huge
>>>> price.
>>>> >
>>>> >
>>>> > A price you will never pay because it will be elided.
>>>> >
>>>> > Please stop repeating statements that have been disproven; it's not
>>>> > helping your case. You have yet to post an example of a generator
>>>> that
>>>> > would not be elided.
>>>>
>>>> I already described it several times, just put generator into some
>>>> structure/array or return somewhere.
>>>> In similar situation:
>>>> http://coliru.stacked-crooked.com/a/0c09744abd5e57ae
>>>> - allocation of P0057 generator will not be elided, there will be N
>>>> allocations, i.e. for each coroutine.
>>>>
>>>
>>> And in your case, the `Coroutine` will have to type-erase them too. Thus
>>> performing N allocations.
>>>
>>> Put it another way. In order to make something a member of a struct, you
>>> must first be able to name it. In C++ as it currently stands, it is
>>> *impossible* to store an unnamable type in a non-static data member.
>>> Whether it's a lambda or the result of a resumable expression or anything
>>> else, it simply *cannot happen*.
>>>
>>
>> It is trivially possible. The name is unimportant, only the type is. In
>> this example a lambda stands for an unnamed type. I could have used other
>> unnamed types.
>> [...]
>>
>
> OK, yes you can do that. My mistake.
>
> However, that code is not a complete example. It doesn't match with your
> sample code (which currently uses type erasure/chicanery). So what does the
> non-trick version look like?
>
Note that I'm not the original poster.
You write the same code directly inside createACoroutineVector. No need for
the extra function call, createACoroutine was purely an example.
-- gpd
--
---
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_652_1896260871.1444837361774
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
On Wednesday, October 14, 2015 at 4:31:39 PM UTC+1, Nicol Bolas wrote:<bloc=
kquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-l=
eft: 1px #ccc solid;padding-left: 1ex;"><br><br>On Wednesday, October 14, 2=
015 at 11:16:35 AM UTC-4, Giovanni Piero Deretta wrote:<blockquote class=3D=
"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc soli=
d;padding-left:1ex">On Wednesday, October 14, 2015 at 2:47:09 PM UTC+1, Nic=
ol Bolas wrote:<blockquote class=3D"gmail_quote" style=3D"margin:0;margin-l=
eft:0.8ex;border-left:1px #ccc solid;padding-left:1ex">On Wednesday, Octobe=
r 14, 2015 at 1:13:56 AM UTC-4, Evgeny Panasyuk wrote:<blockquote class=3D"=
gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid=
;padding-left:1ex">14.10.2015 7:51, Nicol Bolas:
<br>
<br>> =C2=A0 =C2=A0 If you need only async I/O - yes, I could imagine th=
at extra
<br>> =C2=A0 =C2=A0 allocation is tolerable in such context. But P0057 d=
escribes not
<br>> =C2=A0 =C2=A0 only async I/O - but also for instance generators. A=
nd for
<br>> =C2=A0 =C2=A0 generators (like transform iterators) an extra alloc=
ation is huge price.
<br>>
<br>>
<br>> A price you will never pay because it will be elided.
<br>>
<br>> Please stop repeating statements that have been disproven; it'=
s not
<br>> helping your case. You have yet to post an example of a generator =
that
<br>> would not be elided.
<br>
<br>I already described it several times, just put generator into some=20
<br>structure/array or return somewhere.
<br>In similar situation:
<br><a href=3D"http://coliru.stacked-crooked.com/a/0c09744abd5e57ae" rel=3D=
"nofollow" target=3D"_blank" onmousedown=3D"this.href=3D'http://www.goo=
gle.com/url?q\75http%3A%2F%2Fcoliru.stacked-crooked.com%2Fa%2F0c09744abd5e5=
7ae\46sa\75D\46sntz\0751\46usg\75AFQjCNEx46W0ovPGreVk53aziTYTbJG0dg';re=
turn true;" onclick=3D"this.href=3D'http://www.google.com/url?q\75http%=
3A%2F%2Fcoliru.stacked-crooked.com%2Fa%2F0c09744abd5e57ae\46sa\75D\46sntz\0=
751\46usg\75AFQjCNEx46W0ovPGreVk53aziTYTbJG0dg';return true;">http://co=
liru.stacked-crooked.<wbr>com/a/0c09744abd5e57ae</a>
<br>- allocation of P0057 generator will not be elided, there will be N=20
<br>allocations, i.e. for each coroutine.<br></blockquote><div><br>And in y=
our case, the `Coroutine` will have to type-erase them too. Thus performing=
N allocations.<br><br>Put it another way. In order to make something a mem=
ber of a struct, you must first be able to name it. In C++ as it currently =
stands, it is <i>impossible</i> to store an unnamable type in a non-static =
data member. Whether it's a lambda or the result of a resumable express=
ion or anything else, it simply <i>cannot happen</i>.<br></div></blockquote=
><div><br>It is trivially possible. The name is unimportant, only the type =
is. In this example a lambda stands for an unnamed type. I could have used =
other unnamed types.<br>[...]<br></div></blockquote><div><br>OK, yes you ca=
n do that. My mistake.<br><br>However, that code is not a=20
complete example. It doesn't match with your sample code (which=20
currently uses type erasure/chicanery). So what does the non-trick version =
look like?<br></div></blockquote><div><br>Note that I'm not the origina=
l poster.<br><br>You write the same code directly inside createACoroutineVe=
ctor. No need for the extra function call, createACoroutine was purely an e=
xample.</div><br>-- gpd<br>
<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_652_1896260871.1444837361774--
------=_Part_651_995804427.1444837361774--
.
Author: Evgeny Panasyuk <evgeny.panasyuk@gmail.com>
Date: Wed, 14 Oct 2015 11:29:22 -0700 (PDT)
Raw View
------=_Part_418_1074316711.1444847362386
Content-Type: multipart/alternative;
boundary="----=_Part_419_1957335235.1444847362387"
------=_Part_419_1957335235.1444847362387
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
14 October 2015 =D0=B3., 7:46:51 UTC+3 Nicol Bolas :
>
>
> Thus far, including in this post, you haven't mentioned an example that=
=20
> would actually compile.
>
>
Actually examples do compile and do run.
=20
> You linked to some macro code, but macros are, basically, *cheating*.=20
> They get to break all kinds of C++ rules, which an actual language featur=
e=20
> would not.
>
Macros allow us to emulate language feature, to test it now, with current=
=20
compilers. Even Stroustrup uses macros in Mach7 library to emulate language=
=20
feature.
I think it is obvious that following macro-based code:
COROUTINE(vector<int>, list_demo, (int, param),
(int, local_x)
(int, local_y))
{
AWAIT(local_x =3D) vector<int>{1,2,3};
AWAIT(local_y =3D) vector<int>{10, 20, 30};
RETURN(local_x + local_y + param);
}
COROUTINE_END;
Is equivalent to following code with language support:
vector<int> list_demo(int param)
{
int local_x =3D await vector<int>{1,2,3};
int local_y =3D await vector<int>{10, 20, 30};
=20
return local_x + local_y + param;
}
And if macro-based version does work, then this one will work without=20
problems.
=20
>
>> >=20
>> > Also... how does `vector<coroutine>` make any kind of sense with regar=
d=20
>> > to P0114? The type isn't type erased, so each coroutine has its own=20
>> > type. Therefore, in order to put them in a homogeneous container like=
=20
>> > `vector`, you'll have to type-erase them. Which requires memory=20
>> allocation.=20
>> > At which point, your version gains /nothing/ over P0057.=20
>>
>> Same coroutines have same concrete types. For instance, with P0114 it=20
>> may be:=20
>> |=20
>> struct concrete_coroutine=20
>> {=20
>> resumable auto r =3D expression;=20
>> // ...=20
>> };=20
>> ...=20
>> make_unique<concrete_coroutine[]>(N);=20
>> |
>>
>
> `auto` doesn't work that way. Non-static data members cannot be `auto`.=
=20
> Normally I wouldn't care about a small issue like that, but it basically=
=20
> makes your code impossible.
>
Such usage of auto is at p0114r0.pdf at page 11.
=20
>
> Without `auto` NSDMI (and I wouldn't hold my breath on seeing it=20
> <http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2014/n3897.html>),=20
> you can't store a resumable expression. So you can't make containers of=
=20
> them.
>
> Unless you erase their types. So again, you've gained *nothing*.
>
> Your macro solution gets around this because it uses macros.
> =20
>
I showed two versions above - macro based version and possible syntax with=
=20
language support.
Do you have any concrete reasoning why it would be impossible without=20
macros?
=20
> Again, I am not talking specifically about P0114. Even P0057 can be=20
>> changed to have concrete coroutine type.=20
>>
>
> I'd be curious to see how, exactly.
>
>
Currently it works like this:
struct generator
{
...
coroutine_handle<promise_type> coro;
};
generator example_generator()
{
yield 1;
}
int main()
{
generator x =3D example_generator();
x.move_next();
g.current_value();
}
With concrete coroutine type it could be something like this:
template<template<typename> class coroutine_value>
struct generator
{
...
coroutine_value<promise_type> coro;
};
generator example_generator()
{
yield 1;
}
// example_generator is transformed to:
using example_generator =3D generator< synthesized_coroutine >;
int main()
{
example_generator x{};
x.move_next();
g.current_value();
}
=20
>
> If you want this done, then you're going to need to go through the effort=
=20
> of designing the feature to work without type erasure. Then you have to g=
et=20
> someone to implement it.
>
It could be implemented even with macros, to some extent. And I think=20
macro-based solution is enough for proof-of-concept.
=20
> Then, you can know whether it works just as well as P0057, whether it's=
=20
> equally easy to use, and how much of a performance advantage it gets.
>
> If any.
>
Of course it gives performance advantage, because does not impose extra=20
mandatory allocation.=20
--=20
---=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.
------=_Part_419_1957335235.1444847362387
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">14 October 2015 =D0=B3., 7:46:51 UTC+3 Nicol Bolas :<block=
quote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-le=
ft: 1px #ccc solid;padding-left: 1ex;"><br><div>Thus far, including in this=
post, you haven't mentioned an example that would actually compile.<br=
><br></div></blockquote><div><br>Actually examples do compile and do run.<b=
r>=C2=A0</div><blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-l=
eft: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div>You linked =
to some macro code, but macros are, basically, <i>cheating</i>. They get to=
break all kinds of C++ rules, which an actual language feature would not.<=
br></div></blockquote><div><br>Macros allow us to emulate language feature,=
to test it now, with current compilers. Even Stroustrup uses macros in Mac=
h7 library to emulate language feature.<br>I think it is obvious that follo=
wing macro-based code:<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: #000;" class=3D"styled=
-by-prettify">COROUTINE</span><span style=3D"color: #660;" class=3D"styled-=
by-prettify">(</span><span style=3D"color: #000;" class=3D"styled-by-pretti=
fy">vector</span><span style=3D"color: #080;" class=3D"styled-by-prettify">=
<int></span><span style=3D"color: #660;" class=3D"styled-by-prettify"=
>,</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> list_de=
mo</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: #660;" class=3D"styled-by-prettify">(</span><span style=3D"col=
or: #008;" class=3D"styled-by-prettify">int</span><span style=3D"color: #66=
0;" class=3D"styled-by-prettify">,</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"> param</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 </span><span style=3D"color: #660;" class=3D"=
styled-by-prettify">(</span><span style=3D"color: #008;" class=3D"styled-by=
-prettify">int</span><span style=3D"color: #660;" class=3D"styled-by-pretti=
fy">,</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> loca=
l_x</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">(</spa=
n><span style=3D"color: #008;" class=3D"styled-by-prettify">int</span><span=
style=3D"color: #660;" class=3D"styled-by-prettify">,</span><span style=3D=
"color: #000;" class=3D"styled-by-prettify"> local_y</span><span style=3D"c=
olor: #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 AWAIT</span><span style=3D"color: #660=
;" class=3D"styled-by-prettify">(</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify">local_x </span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">=3D)</span><span style=3D"color: #000;" class=3D"st=
yled-by-prettify"> vector</span><span style=3D"color: #080;" class=3D"style=
d-by-prettify"><int></span><span style=3D"color: #660;" class=3D"styl=
ed-by-prettify">{</span><span style=3D"color: #066;" class=3D"styled-by-pre=
ttify">1</span><span style=3D"color: #660;" class=3D"styled-by-prettify">,<=
/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: #066;" class=3D"styled-by-prettify">3</span><span style=3D"color=
: #660;" class=3D"styled-by-prettify">};</span><span style=3D"color: #000;"=
class=3D"styled-by-prettify"><br>=C2=A0 =C2=A0 AWAIT</span><span style=3D"=
color: #660;" class=3D"styled-by-prettify">(</span><span style=3D"color: #0=
00;" class=3D"styled-by-prettify">local_y </span><span style=3D"color: #660=
;" class=3D"styled-by-prettify">=3D)</span><span style=3D"color: #000;" cla=
ss=3D"styled-by-prettify"> vector</span><span style=3D"color: #080;" class=
=3D"styled-by-prettify"><int></span><span style=3D"color: #660;" clas=
s=3D"styled-by-prettify">{</span><span style=3D"color: #066;" class=3D"styl=
ed-by-prettify">10</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">20</span><=
span style=3D"color: #660;" class=3D"styled-by-prettify">,</span><span styl=
e=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"colo=
r: #066;" class=3D"styled-by-prettify">30</span><span style=3D"color: #660;=
" class=3D"styled-by-prettify">};</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"><br><br>=C2=A0 =C2=A0 RETURN</span><span style=3D"c=
olor: #660;" class=3D"styled-by-prettify">(</span><span style=3D"color: #00=
0;" class=3D"styled-by-prettify">local_x </span><span style=3D"color: #660;=
" class=3D"styled-by-prettify">+</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"> local_y </span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">+</span><span style=3D"color: #000;" class=3D"style=
d-by-prettify"> param</span><span style=3D"color: #660;" class=3D"styled-by=
-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>COROUTIN=
E_END</span><span style=3D"color: #660;" class=3D"styled-by-prettify">;</sp=
an></div></code></div><br>Is equivalent to following code with language sup=
port:<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: #000;" class=3D"styled-by-prettif=
y">vector</span><span style=3D"color: #080;" class=3D"styled-by-prettify">&=
lt;int></span><span style=3D"color: #000;" class=3D"styled-by-prettify">=
list_demo</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"> param</span><sp=
an style=3D"color: #660;" class=3D"styled-by-prettify">)</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"><br></span><span style=3D"co=
lor: #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">int</span><span style=3D"color: #00=
0;" class=3D"styled-by-prettify"> local_x </span><span style=3D"color: #660=
;" class=3D"styled-by-prettify">=3D</span><span style=3D"color: #000;" clas=
s=3D"styled-by-prettify"> await vector</span><span style=3D"color: #080;" c=
lass=3D"styled-by-prettify"><int></span><span style=3D"color: #660;" =
class=3D"styled-by-prettify">{</span><span style=3D"color: #066;" class=3D"=
styled-by-prettify">1</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 style=3D"color: #066;" class=3D"styled-by-prettify">3</span><span st=
yle=3D"color: #660;" class=3D"styled-by-prettify">};</span><span style=3D"c=
olor: #000;" class=3D"styled-by-prettify"><br>=C2=A0 =C2=A0 </span><span st=
yle=3D"color: #008;" class=3D"styled-by-prettify">int</span><span style=3D"=
color: #000;" class=3D"styled-by-prettify"> local_y </span><span style=3D"c=
olor: #660;" class=3D"styled-by-prettify">=3D</span><span style=3D"color: #=
000;" class=3D"styled-by-prettify"> await vector</span><span style=3D"color=
: #080;" class=3D"styled-by-prettify"><int></span><span style=3D"colo=
r: #660;" class=3D"styled-by-prettify">{</span><span style=3D"color: #066;"=
class=3D"styled-by-prettify">10</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: #066;" class=3D"styled-by-pret=
tify">20</span><span style=3D"color: #660;" class=3D"styled-by-prettify">,<=
/span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><sp=
an style=3D"color: #066;" class=3D"styled-by-prettify">30</span><span style=
=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<br>=C2=A0 =C2=A0 <=
/span><span style=3D"color: #008;" class=3D"styled-by-prettify">return</spa=
n><span style=3D"color: #000;" class=3D"styled-by-prettify"> local_x </span=
><span style=3D"color: #660;" class=3D"styled-by-prettify">+</span><span st=
yle=3D"color: #000;" class=3D"styled-by-prettify"> local_y </span><span sty=
le=3D"color: #660;" class=3D"styled-by-prettify">+</span><span style=3D"col=
or: #000;" class=3D"styled-by-prettify"> param</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></span></div></code></div><br>And if macro-based version do=
es work, then this one will work without problems.<br><br><br></div><blockq=
uote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-lef=
t: 1px #ccc solid;padding-left: 1ex;"><div>=C2=A0</div><blockquote class=3D=
"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc soli=
d;padding-left:1ex">
>
<br>> Also... how does `vector<coroutine>` make any kind of sense =
with regard
<br>> to P0114? The type isn't type erased, so each coroutine has it=
s own
<br>> type. Therefore, in order to put them in a homogeneous container l=
ike
<br>> `vector`, you'll have to type-erase them. Which requires memor=
y allocation.
<br>=C2=A0> At which point, your version gains /nothing/ over P0057.
<br>
<br>Same coroutines have same concrete types. For instance, with P0114 it=
=20
<br>may be:
<br>|
<br>struct concrete_coroutine
<br>{
<br>=C2=A0 =C2=A0 =C2=A0resumable auto r =3D expression;
<br>=C2=A0 =C2=A0 =C2=A0// ...
<br>};
<br>...
<br>make_unique<concrete_<wbr>coroutine[]>(N);
<br>|<br></blockquote><div><br>`auto` doesn't work that way. Non-static=
data members cannot be `auto`. Normally I wouldn't care about a small =
issue like that, but it basically makes your code impossible.<br></div></bl=
ockquote><div><br><br>Such usage of auto is at p0114r0.pdf at page 11.<br>=
=C2=A0</div><blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-lef=
t: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div><br>Without `=
auto` NSDMI (and <a href=3D"http://www.open-std.org/JTC1/SC22/WG21/docs/pap=
ers/2014/n3897.html" target=3D"_blank" rel=3D"nofollow" onmousedown=3D"this=
..href=3D'http://www.google.com/url?q\75http%3A%2F%2Fwww.open-std.org%2F=
JTC1%2FSC22%2FWG21%2Fdocs%2Fpapers%2F2014%2Fn3897.html\46sa\75D\46sntz\0751=
\46usg\75AFQjCNEJvBna1E4DHihTG8kJWVjTL7CIZw';return true;" onclick=3D"t=
his.href=3D'http://www.google.com/url?q\75http%3A%2F%2Fwww.open-std.org=
%2FJTC1%2FSC22%2FWG21%2Fdocs%2Fpapers%2F2014%2Fn3897.html\46sa\75D\46sntz\0=
751\46usg\75AFQjCNEJvBna1E4DHihTG8kJWVjTL7CIZw';return true;">I wouldn&=
#39;t hold my breath on seeing it</a>), you can't store a resumable exp=
ression. So you can't make containers of them.<br><br>Unless you erase =
their types. So again, you've gained <i>nothing</i>.<br><br>Your macro =
solution gets around this because it uses macros.<br></div><div>=C2=A0</div=
></blockquote><div><br>I showed two versions above - macro based version an=
d possible syntax with language support.<br>Do you have any concrete reason=
ing why it would be impossible without macros?<br>=C2=A0</div><blockquote c=
lass=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px=
#ccc solid;padding-left: 1ex;"><blockquote class=3D"gmail_quote" style=3D"=
margin:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-left:1ex">
Again, I am not talking specifically about P0114. Even P0057 can be=20
<br>changed to have concrete coroutine type.
<br></blockquote><div><br>I'd be curious to see how, exactly.<br><br></=
div></blockquote><div><br>Currently it works like this:<br><div class=3D"pr=
ettyprint" style=3D"background-color: rgb(250, 250, 250); border-color: rgb=
(187, 187, 187); border-style: solid; border-width: 1px; word-wrap: break-w=
ord;"><code class=3D"prettyprint"><div class=3D"subprettyprint"><span style=
=3D"color: #008;" class=3D"styled-by-prettify">struct</span><span style=3D"=
color: #000;" class=3D"styled-by-prettify"> generator<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 =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=A0coro=
utine_handle</span><span style=3D"color: #080;" class=3D"styled-by-prettify=
"><promise_type></span><span style=3D"color: #000;" class=3D"styled-b=
y-prettify"> coro</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>generato=
r example_generator</span><span style=3D"color: #660;" class=3D"styled-by-p=
rettify">()</span><span style=3D"color: #000;" class=3D"styled-by-prettify"=
><br></span><span style=3D"color: #660;" class=3D"styled-by-prettify">{</sp=
an><span style=3D"color: #000;" class=3D"styled-by-prettify"><br>=C2=A0 =C2=
=A0 </span><span style=3D"color: #008;" class=3D"styled-by-prettify">yield<=
/span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><sp=
an 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"><br></span><span style=3D"color: #660=
;" class=3D"styled-by-prettify">}</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"><br><br></span><span style=3D"color: #008;" class=
=3D"styled-by-prettify">int</span><span style=3D"color: #000;" class=3D"sty=
led-by-prettify"> main</span><span style=3D"color: #660;" class=3D"styled-b=
y-prettify">()</span><span style=3D"color: #000;" class=3D"styled-by-pretti=
fy"><br></span><span style=3D"color: #660;" class=3D"styled-by-prettify">{<=
/span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br>=C2=A0 =
=C2=A0 generator x </span><span style=3D"color: #660;" class=3D"styled-by-p=
rettify">=3D</span><span style=3D"color: #000;" class=3D"styled-by-prettify=
"> example_generator</span><span style=3D"color: #660;" class=3D"styled-by-=
prettify">();</span><span style=3D"color: #000;" class=3D"styled-by-prettif=
y"><br>=C2=A0 =C2=A0 x</span><span style=3D"color: #660;" class=3D"styled-b=
y-prettify">.</span><span style=3D"color: #000;" class=3D"styled-by-prettif=
y">move_next</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 g</span><span style=3D"color: #660;" class=3D"styled-by-prett=
ify">.</span><span style=3D"color: #000;" class=3D"styled-by-prettify">curr=
ent_value</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></span></div></code=
></div><br>With concrete coroutine type it could be something like this:<br=
><br><div class=3D"prettyprint" style=3D"background-color: rgb(250, 250, 25=
0); border-color: rgb(187, 187, 187); border-style: solid; border-width: 1p=
x; word-wrap: break-word;"><code class=3D"prettyprint"><div class=3D"subpre=
ttyprint"><span style=3D"color: #008;" class=3D"styled-by-prettify">templat=
e</span><span style=3D"color: #660;" class=3D"styled-by-prettify"><</spa=
n><span style=3D"color: #008;" class=3D"styled-by-prettify">template</span>=
<span style=3D"color: #080;" class=3D"styled-by-prettify"><typename><=
/span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><sp=
an style=3D"color: #008;" class=3D"styled-by-prettify">class</span><span st=
yle=3D"color: #000;" class=3D"styled-by-prettify"> coroutine_value</span><s=
pan style=3D"color: #660;" class=3D"styled-by-prettify">></span><span st=
yle=3D"color: #000;" class=3D"styled-by-prettify"><br></span><span style=3D=
"color: #008;" class=3D"styled-by-prettify">struct</span><span style=3D"col=
or: #000;" class=3D"styled-by-prettify"> generator<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 =C2=A0</span><span sty=
le=3D"color: #660;" class=3D"styled-by-prettify">...</span><span style=3D"c=
olor: #000;" class=3D"styled-by-prettify"><br>=C2=A0 =C2=A0 =C2=A0coroutine=
_value</span><span style=3D"color: #080;" class=3D"styled-by-prettify"><=
promise_type></span><span style=3D"color: #000;" class=3D"styled-by-pret=
tify"> coro</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><br>generator exam=
ple_generator</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 </=
span><span style=3D"color: #008;" class=3D"styled-by-prettify">yield</span>=
<span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span sty=
le=3D"color: #066;" class=3D"styled-by-prettify">1</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></span><span style=3D"color: #800;" class=3D"styled-by-=
prettify">// example_generator is transformed to:</span><span style=3D"colo=
r: #000;" class=3D"styled-by-prettify"><br></span><span style=3D"color: #00=
8;" class=3D"styled-by-prettify">using</span><span style=3D"color: #000;" c=
lass=3D"styled-by-prettify"> example_generator </span><span style=3D"color:=
#660;" class=3D"styled-by-prettify">=3D</span><span style=3D"color: #000;"=
class=3D"styled-by-prettify"> generator</span><span style=3D"color: #660;"=
class=3D"styled-by-prettify"><</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"> synthesized_coroutine </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">int</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"> main</span><span style=3D"color: #660;" class=3D"s=
tyled-by-prettify">()</span><span style=3D"color: #000;" class=3D"styled-by=
-prettify"><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 example_generator x</span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">{};</span><span style=3D"color: #000;" class=3D"sty=
led-by-prettify"><br>=C2=A0 =C2=A0 x</span><span style=3D"color: #660;" cla=
ss=3D"styled-by-prettify">.</span><span style=3D"color: #000;" class=3D"sty=
led-by-prettify">move_next</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>=C2=A0 =C2=A0 g</span><span style=3D"color: #660;" class=3D"st=
yled-by-prettify">.</span><span style=3D"color: #000;" class=3D"styled-by-p=
rettify">current_value</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></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>=C2=A0</div><blockquote class=3D"gmail_quote" style=
=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: =
1ex;"><div><br>If you want this done, then you're going to need to go t=
hrough the effort of designing the feature to work without type erasure. Th=
en you have to get someone to implement it.</div></blockquote><div><br>It c=
ould be implemented even with macros, to some extent. And I think macro-bas=
ed solution is enough for proof-of-concept.<br>=C2=A0</div><blockquote clas=
s=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #c=
cc solid;padding-left: 1ex;"><div>Then, you can know whether it works just =
as well as P0057, whether it's equally easy to use, and how much of a p=
erformance advantage it gets.<br><br>If any.<br></div></blockquote><div><br=
>Of course it gives performance advantage, because does not impose extra ma=
ndatory allocation. <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_419_1957335235.1444847362387--
------=_Part_418_1074316711.1444847362386--
.
Author: Nicol Bolas <jmckesson@gmail.com>
Date: Wed, 14 Oct 2015 12:35:49 -0700 (PDT)
Raw View
------=_Part_7377_311609544.1444851349266
Content-Type: multipart/alternative;
boundary="----=_Part_7378_1568985563.1444851349267"
------=_Part_7378_1568985563.1444851349267
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
On Wednesday, October 14, 2015 at 2:29:22 PM UTC-4, Evgeny Panasyuk wrote:
>
> 14 October 2015 =D0=B3., 7:46:51 UTC+3 Nicol Bolas :
>>
>>
>> Thus far, including in this post, you haven't mentioned an example that=
=20
>> would actually compile.
>>
>>
> Actually examples do compile and do run.
> =20
>
>> You linked to some macro code, but macros are, basically, *cheating*.=20
>> They get to break all kinds of C++ rules, which an actual language featu=
re=20
>> would not.
>>
>
> Macros allow us to emulate language feature, to test it now, with current=
=20
> compilers. Even Stroustrup uses macros in Mach7 library to emulate langua=
ge=20
> feature.
> I think it is obvious that following macro-based code:
> COROUTINE(vector<int>, list_demo, (int, param),
> (int, local_x)
> (int, local_y))
> {
> AWAIT(local_x =3D) vector<int>{1,2,3};
> AWAIT(local_y =3D) vector<int>{10, 20, 30};
>
> RETURN(local_x + local_y + param);
> }
> COROUTINE_END;
>
> Is equivalent to following code with language support:
>
> vector<int> list_demo(int param)
> {
> int local_x =3D await vector<int>{1,2,3};
> int local_y =3D await vector<int>{10, 20, 30};
> =20
> return local_x + local_y + param;
> }
>
> And if macro-based version does work, then this one will work without=20
> problems.
>
I'll talk about this more later, but a good language feature should be=20
*minimal*, not do whatever it takes. That's why a macro approach is a bad=
=20
idea for a proposal. It's fine for a general sketch. But macros make you=20
brave; you can do anything with them.
When it comes to a language feature, you shouldn't do *anything*. You=20
should do just enough, and no more.
Same coroutines have same concrete types. For instance, with P0114 it=20
>>> may be:=20
>>> |=20
>>> struct concrete_coroutine=20
>>> {=20
>>> resumable auto r =3D expression;=20
>>> // ...=20
>>> };=20
>>> ...=20
>>> make_unique<concrete_coroutine[]>(N);=20
>>> |
>>>
>>
>> `auto` doesn't work that way. Non-static data members cannot be `auto`.=
=20
>> Normally I wouldn't care about a small issue like that, but it basically=
=20
>> makes your code impossible.
>>
>
>
> Such usage of auto is at p0114r0.pdf at page 11.
>
True, but that doesn't make it *correct*. C++14 doesn't let `auto` do that;=
=20
the standard is very clear on that. And P0114 does not actually propose=20
allowing `auto` to do that.
All you've shown is that P0114 is in error.
Without `auto` NSDMI (and I wouldn't hold my breath on seeing it=20
>> <http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2014/n3897.html>),=
=20
>> you can't store a resumable expression. So you can't make containers of=
=20
>> them.
>>
>> Unless you erase their types. So again, you've gained *nothing*.
>>
>> Your macro solution gets around this because it uses macros.
>> =20
>>
>
> I showed two versions above - macro based version and possible syntax wit=
h=20
> language support.
> Do you have any concrete reasoning why it would be impossible without=20
> macros?
>
Because you'd have to get language support for `auto` in NSDMI's. And I=20
just linked to you a discussion about precisely that and how it's *not=20
gonna happen*. So your "possible syntax with language support" doesn't hold=
=20
water.
Again, I am not talking specifically about P0114. Even P0057 can be=20
>>> changed to have concrete coroutine type.=20
>>>
>>
>> I'd be curious to see how, exactly.
>>
>>
> Currently it works like this:
> struct generator
> {
> ...
> coroutine_handle<promise_type> coro;
> };
>
> generator example_generator()
> {
> yield 1;
> }
>
> int main()
> {
> generator x =3D example_generator();
> x.move_next();
> g.current_value();
> }
>
> With concrete coroutine type it could be something like this:
>
> template<template<typename> class coroutine_value>
> struct generator
> {
> ...
> coroutine_value<promise_type> coro;
> };
>
> generator example_generator()
> {
> yield 1;
> }
> // example_generator is transformed to:
> using example_generator =3D generator< synthesized_coroutine >;
>
> int main()
> {
> example_generator x{};
> x.move_next();
> g.current_value();
> }
>
>
Um, what does that code mean? Where does `synthesized_coroutine` come from?=
=20
How does `example_generator` get defined twice? And how does=20
`example_generator` return a template that has no template arguments?
A nice thing about resumable functions is that it doesn't take a=20
sledgehammer to basic elements of the language. If a coroutine function=20
returns a type, it *returns that type*, and the return value has all the=20
rights and behaviors of a return value from a regular function.
With P0057, C++ works as normal, except where absolutely *necessary*.
What you're suggesting requires a bunch of different changes to lots of=20
elements of C++. You have to be able to return a template with no=20
arguments, who's arguments are provided by that `using` declaration, I=20
guess. And that the argument has to be able to be generated from...=20
whatever `synthesized_coroutine` is. And so on.
That's a huge amount of work to do just to avoid type erasure. And not just=
=20
library work; that's *core language* work. Lots of it.
After all, there's no proposal even *remotely* like this at present. Even=
=20
your idea above is incomplete, as it's not clear what all of those pieces=
=20
actually mean or do (P0057 makes `await` mean one thing. What does it mean=
=20
in your idea?). You have one general notion: coroutines having a firm type.=
=20
And you're ready and willing invent a plethora of subsidiary C++ language=
=20
features that exist for the sole purpose of making that work.
That's not a good way to make a solid proposal. If that one thing requires=
=20
so many subsidiary language features... maybe that one thing is not worth=
=20
it.
Even if we accept that this is a good way to make a proposal... it's not a=
=20
*proposal* yet. It's just some ideas being batted around on a forum. None=
=20
of the various coroutine proposals do anything like what you've suggested.=
=20
Why should we halt or delay progress on P0057 because you *think* you might=
=20
be able to do better?
I hate to use this phrase as a way to win arguments, but "perfect is the=20
enemy of good".
--=20
---=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.
------=_Part_7378_1568985563.1444851349267
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
On Wednesday, October 14, 2015 at 2:29:22 PM UTC-4, Evgeny Panasyuk wrote:<=
blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;bord=
er-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr">14 October 201=
5 =D0=B3., 7:46:51 UTC+3 Nicol Bolas :<blockquote class=3D"gmail_quote" sty=
le=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-left:1e=
x"><br><div>Thus far, including in this post, you haven't mentioned an =
example that would actually compile.<br><br></div></blockquote><div><br>Act=
ually examples do compile and do run.<br>=C2=A0</div><blockquote class=3D"g=
mail_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;=
padding-left:1ex"><div>You linked to some macro code, but macros are, basic=
ally, <i>cheating</i>. They get to break all kinds of C++ rules, which an a=
ctual language feature would not.<br></div></blockquote><div><br>Macros all=
ow us to emulate language feature, to test it now, with current compilers. =
Even Stroustrup uses macros in Mach7 library to emulate language feature.<b=
r>I think it is obvious that following macro-based code:<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:#000">COROUTINE</span><span style=3D"color:#660">(</span><span style=3D"=
color:#000">vector</span><span style=3D"color:#080"><int></span><span=
style=3D"color:#660">,</span><span style=3D"color:#000"> list_demo</span><=
span style=3D"color:#660">,</span><span style=3D"color:#000"> </span><span =
style=3D"color:#660">(</span><span style=3D"color:#008">int</span><span sty=
le=3D"color:#660">,</span><span style=3D"color:#000"> param</span><span sty=
le=3D"color:#660">),</span><span style=3D"color:#000"><br>=C2=A0 =C2=A0 </s=
pan><span style=3D"color:#660">(</span><span style=3D"color:#008">int</span=
><span style=3D"color:#660">,</span><span style=3D"color:#000"> local_x</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:#008=
">int</span><span style=3D"color:#660">,</span><span style=3D"color:#000"> =
local_y</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 AWAIT</span><span style=3D"color:#660">(</span><span styl=
e=3D"color:#000">local_x </span><span style=3D"color:#660">=3D)</span><span=
style=3D"color:#000"> vector</span><span style=3D"color:#080"><int><=
/span><span style=3D"color:#660">{</span><span style=3D"color:#066">1</span=
><span style=3D"color:#660">,</span><span style=3D"color:#066">2</span><spa=
n style=3D"color:#660">,</span><span style=3D"color:#066">3</span><span sty=
le=3D"color:#660">};</span><span style=3D"color:#000"><br>=C2=A0 =C2=A0 AWA=
IT</span><span style=3D"color:#660">(</span><span style=3D"color:#000">loca=
l_y </span><span style=3D"color:#660">=3D)</span><span style=3D"color:#000"=
> vector</span><span style=3D"color:#080"><int></span><span style=3D"=
color:#660">{</span><span style=3D"color:#066">10</span><span style=3D"colo=
r:#660">,</span><span style=3D"color:#000"> </span><span style=3D"color:#06=
6">20</span><span style=3D"color:#660">,</span><span style=3D"color:#000"> =
</span><span style=3D"color:#066">30</span><span style=3D"color:#660">};</s=
pan><span style=3D"color:#000"><br><br>=C2=A0 =C2=A0 RETURN</span><span sty=
le=3D"color:#660">(</span><span style=3D"color:#000">local_x </span><span s=
tyle=3D"color:#660">+</span><span style=3D"color:#000"> local_y </span><spa=
n style=3D"color:#660">+</span><span style=3D"color:#000"> param</span><spa=
n style=3D"color:#660">);</span><span style=3D"color:#000"><br></span><span=
style=3D"color:#660">}</span><span style=3D"color:#000"><br>COROUTINE_END<=
/span><span style=3D"color:#660">;</span></div></code></div><br>Is equivale=
nt to following code with language support:<br><br><div style=3D"background=
-color:rgb(250,250,250);border-color:rgb(187,187,187);border-style:solid;bo=
rder-width:1px;word-wrap:break-word"><code><div><span style=3D"color:#000">=
vector</span><span style=3D"color:#080"><int></span><span style=3D"co=
lor:#000"> list_demo</span><span style=3D"color:#660">(</span><span style=
=3D"color:#008">int</span><span style=3D"color:#000"> param</span><span sty=
le=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">int</span><span style=3D"color:#000"> local_x <=
/span><span style=3D"color:#660">=3D</span><span style=3D"color:#000"> awai=
t vector</span><span style=3D"color:#080"><int></span><span style=3D"=
color:#660">{</span><span style=3D"color:#066">1</span><span style=3D"color=
:#660">,</span><span style=3D"color:#066">2</span><span style=3D"color:#660=
">,</span><span style=3D"color:#066">3</span><span style=3D"color:#660">};<=
/span><span style=3D"color:#000"><br>=C2=A0 =C2=A0 </span><span style=3D"co=
lor:#008">int</span><span style=3D"color:#000"> local_y </span><span style=
=3D"color:#660">=3D</span><span style=3D"color:#000"> await vector</span><s=
pan style=3D"color:#080"><int></span><span style=3D"color:#660">{</sp=
an><span style=3D"color:#066">10</span><span style=3D"color:#660">,</span><=
span style=3D"color:#000"> </span><span style=3D"color:#066">20</span><span=
style=3D"color:#660">,</span><span style=3D"color:#000"> </span><span styl=
e=3D"color:#066">30</span><span style=3D"color:#660">};</span><span style=
=3D"color:#000"><br>=C2=A0 =C2=A0<br>=C2=A0 =C2=A0 </span><span style=3D"co=
lor:#008">return</span><span style=3D"color:#000"> local_x </span><span sty=
le=3D"color:#660">+</span><span style=3D"color:#000"> local_y </span><span =
style=3D"color:#660">+</span><span style=3D"color:#000"> param</span><span =
style=3D"color:#660">;</span><span style=3D"color:#000"><br></span><span st=
yle=3D"color:#660">}</span><span style=3D"color:#000"><br></span></div></co=
de></div><br>And if macro-based version does work, then this one will work =
without problems.<br></div></div></blockquote><div><br>I'll talk about =
this more later, but a good language feature should be <i>minimal</i>, not =
do whatever it takes. That's why a macro approach is a bad idea for a p=
roposal. It's fine for a general sketch. But macros make you brave; you=
can do anything with them.<br><br>When it comes to a language feature, you=
shouldn't do <i>anything</i>. You should do just enough, and no more.<=
br><br></div><blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-le=
ft: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr">=
<div></div><blockquote class=3D"gmail_quote" style=3D"margin:0;margin-left:=
0.8ex;border-left:1px #ccc solid;padding-left:1ex"><div></div><blockquote c=
lass=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1px #c=
cc solid;padding-left:1ex">
Same coroutines have same concrete types. For instance, with P0114 it=20
<br>may be:
<br>|
<br>struct concrete_coroutine
<br>{
<br>=C2=A0 =C2=A0 =C2=A0resumable auto r =3D expression;
<br>=C2=A0 =C2=A0 =C2=A0// ...
<br>};
<br>...
<br>make_unique<concrete_<wbr>coroutine[]>(N);
<br>|<br></blockquote><div><br>`auto` doesn't work that way. Non-static=
data members cannot be `auto`. Normally I wouldn't care about a small =
issue like that, but it basically makes your code impossible.<br></div></bl=
ockquote><div><br><br>Such usage of auto is at p0114r0.pdf at page 11.<br><=
/div></div></blockquote><div><br>True, but that doesn't make it <i>corr=
ect</i>. C++14 doesn't let `auto` do that; the standard is very clear o=
n that. And P0114 does not actually propose allowing `auto` to do that.<br>=
<br>All you've shown is that P0114 is in error.<br><br></div><blockquot=
e class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-left: =
1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr"><blockquote class=3D"gm=
ail_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;p=
adding-left:1ex"><div>Without `auto` NSDMI (and <a href=3D"http://www.open-=
std.org/JTC1/SC22/WG21/docs/papers/2014/n3897.html" rel=3D"nofollow" target=
=3D"_blank" onmousedown=3D"this.href=3D'http://www.google.com/url?q\75h=
ttp%3A%2F%2Fwww.open-std.org%2FJTC1%2FSC22%2FWG21%2Fdocs%2Fpapers%2F2014%2F=
n3897.html\46sa\75D\46sntz\0751\46usg\75AFQjCNEJvBna1E4DHihTG8kJWVjTL7CIZw&=
#39;;return true;" onclick=3D"this.href=3D'http://www.google.com/url?q\=
75http%3A%2F%2Fwww.open-std.org%2FJTC1%2FSC22%2FWG21%2Fdocs%2Fpapers%2F2014=
%2Fn3897.html\46sa\75D\46sntz\0751\46usg\75AFQjCNEJvBna1E4DHihTG8kJWVjTL7CI=
Zw';return true;">I wouldn't hold my breath on seeing it</a>), you =
can't store a resumable expression. So you can't make containers of=
them.<br><br>Unless you erase their types. So again, you've gained <i>=
nothing</i>.<br><br>Your macro solution gets around this because it uses ma=
cros.<br></div><div>=C2=A0</div></blockquote><div><br>I showed two versions=
above - macro based version and possible syntax with language support.<br>=
Do you have any concrete reasoning why it would be impossible without macro=
s?<br></div></div></blockquote><div><br>Because you'd have to get langu=
age support for `auto` in NSDMI's. And I just linked to you a discussio=
n about precisely that and how it's <i>not gonna happen</i>. So your &q=
uot;possible syntax with language support" doesn't hold water.<br>=
<br></div><blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left:=
0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr"><di=
v></div><blockquote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8=
ex;border-left:1px #ccc solid;padding-left:1ex"><blockquote class=3D"gmail_=
quote" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;paddi=
ng-left:1ex">
Again, I am not talking specifically about P0114. Even P0057 can be=20
<br>changed to have concrete coroutine type.
<br></blockquote><div><br>I'd be curious to see how, exactly.<br><br></=
div></blockquote><div><br>Currently it works like this:<br><div style=3D"ba=
ckground-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"colo=
r:#008">struct</span><span style=3D"color:#000"> generator<br></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">...</span><span style=3D"color:#000=
"><br>=C2=A0 =C2=A0 =C2=A0coroutine_handle</span><span style=3D"color:#080"=
><promise_<wbr>type></span><span style=3D"color:#000"> coro</span><sp=
an 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>generator=
example_generator</span><span style=3D"color:#660">()</span><span style=3D=
"color:#000"><br></span><span style=3D"color:#660">{</span><span style=3D"c=
olor:#000"><br>=C2=A0 =C2=A0 </span><span style=3D"color:#008">yield</span>=
<span style=3D"color:#000"> </span><span style=3D"color:#066">1</span><span=
style=3D"color:#660">;</span><span style=3D"color:#000"><br></span><span s=
tyle=3D"color:#660">}</span><span style=3D"color:#000"><br><br></span><span=
style=3D"color:#008">int</span><span style=3D"color:#000"> main</span><spa=
n 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 =
generator x </span><span style=3D"color:#660">=3D</span><span style=3D"colo=
r:#000"> example_generator</span><span style=3D"color:#660">();</span><span=
style=3D"color:#000"><br>=C2=A0 =C2=A0 x</span><span style=3D"color:#660">=
..</span><span style=3D"color:#000">move_next</span><span style=3D"color:#66=
0">();</span><span style=3D"color:#000"><br>=C2=A0 =C2=A0 g</span><span sty=
le=3D"color:#660">.</span><span style=3D"color:#000">current_value</span><s=
pan 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></span></di=
v></code></div><br>With concrete coroutine type it could be something like =
this:<br><br><div style=3D"background-color:rgb(250,250,250);border-color:r=
gb(187,187,187);border-style:solid;border-width:1px;word-wrap:break-word"><=
code><div><span style=3D"color:#008">template</span><span style=3D"color:#6=
60"><</span><span style=3D"color:#008">template</span><span style=3D"col=
or:#080"><typename></span><span style=3D"color:#000"> </span><span st=
yle=3D"color:#008">class</span><span style=3D"color:#000"> coroutine_value<=
/span><span style=3D"color:#660">></span><span style=3D"color:#000"><br>=
</span><span style=3D"color:#008">struct</span><span style=3D"color:#000"> =
generator<br></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">...</span>=
<span style=3D"color:#000"><br>=C2=A0 =C2=A0 =C2=A0coroutine_value</span><s=
pan style=3D"color:#080"><promise_type></span><span style=3D"color:#0=
00"> coro</span><span style=3D"color:#660">;</span><span style=3D"color:#00=
0"><br></span><span style=3D"color:#660">};</span><span style=3D"color:#000=
"><br><br>generator example_generator</span><span style=3D"color:#660">()</=
span><span style=3D"color:#000"><br></span><span style=3D"color:#660">{</sp=
an><span style=3D"color:#000"><br>=C2=A0 =C2=A0 </span><span style=3D"color=
:#008">yield</span><span style=3D"color:#000"> </span><span style=3D"color:=
#066">1</span><span style=3D"color:#660">;</span><span style=3D"color:#000"=
><br></span><span style=3D"color:#660">}</span><span style=3D"color:#000"><=
br></span><span style=3D"color:#800">// example_generator is transformed to=
:</span><span style=3D"color:#000"><br></span><span style=3D"color:#008">us=
ing</span><span style=3D"color:#000"> example_generator </span><span style=
=3D"color:#660">=3D</span><span style=3D"color:#000"> generator</span><span=
style=3D"color:#660"><</span><span style=3D"color:#000"> synthesized_co=
routine </span><span style=3D"color:#660">>;</span><span style=3D"color:=
#000"><br><br></span><span style=3D"color:#008">int</span><span style=3D"co=
lor:#000"> main</span><span style=3D"color:#660">()</span><span style=3D"co=
lor:#000"><br></span><span style=3D"color:#660">{</span><span style=3D"colo=
r:#000"><br>=C2=A0 =C2=A0 example_generator x</span><span style=3D"color:#6=
60">{};</span><span style=3D"color:#000"><br>=C2=A0 =C2=A0 x</span><span st=
yle=3D"color:#660">.</span><span style=3D"color:#000">move_next</span><span=
style=3D"color:#660">();</span><span style=3D"color:#000"><br>=C2=A0 =C2=
=A0 g</span><span style=3D"color:#660">.</span><span style=3D"color:#000">c=
urrent_value</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></span></div></code></div><br></div></div></blockquote><div><br>U=
m, what does that code mean? Where does `synthesized_coroutine` come from? =
How does `example_generator` get defined twice? And how does `example_gener=
ator` return a template that has no template arguments?<br><br>A nice thing=
about resumable functions is that it doesn't take a sledgehammer to ba=
sic elements of the language. If a coroutine function returns a type, it <i=
>returns that type</i>, and the return value has all the rights and behavio=
rs of a return value from a regular function.<br><br>With P0057, C++ works =
as normal, except where absolutely <i>necessary</i>.<br><br>What you're=
suggesting requires a bunch of different changes to lots of elements of C+=
+. You have to be able to return a template with no arguments, who's ar=
guments are provided by that `using` declaration, I guess. And that the arg=
ument has to be able to be generated from... whatever `synthesized_coroutin=
e` is. And so on.<br><br>That's a huge amount of work to do just to avo=
id type erasure. And not just library work; that's <i>core language</i>=
work. Lots of it.<br><br>After all, there's no proposal even <i>remote=
ly</i> like this at present. Even your idea above is incomplete, as it'=
s not clear what all of those pieces actually mean or do (P0057 makes `awai=
t` mean one thing. What does it mean in your idea?). You have one general n=
otion: coroutines having a firm type. And you're ready and willing inve=
nt a plethora of subsidiary C++ language features that exist for the sole p=
urpose of making that work.<br><br>That's not a good way to make a soli=
d proposal. If that one thing requires so many subsidiary language features=
.... maybe that one thing is not worth it.<br><br>Even if we accept that thi=
s is a good way to make a proposal... it's not a <i>proposal</i> yet. I=
t's just some ideas being batted around on a forum. None of the various=
coroutine proposals do anything like what you've suggested. Why should=
we halt or delay progress on P0057 because you <i>think</i> you might be a=
ble to do better?<br><br>I hate to use this phrase as a way to win argument=
s, but "perfect is the enemy of good".<br></div>
<p></p>
-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />
------=_Part_7378_1568985563.1444851349267--
------=_Part_7377_311609544.1444851349266--
.
Author: Evgeny Panasyuk <evgeny.panasyuk@gmail.com>
Date: Wed, 14 Oct 2015 13:14:30 -0700 (PDT)
Raw View
------=_Part_8_33436332.1444853670777
Content-Type: multipart/alternative;
boundary="----=_Part_9_1536708593.1444853670778"
------=_Part_9_1536708593.1444853670778
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
14 October 2015 =D0=B3., 22:35:49 UTC+3 Nicol Bolas:
>
>
> And if macro-based version does work, then this one will work without=20
>> problems.
>>
>
> I'll talk about this more later, but a good language feature should be=20
> *minimal*, not do whatever it takes. That's why a macro approach is a bad=
=20
> idea for a proposal. It's fine for a general sketch. But macros make you=
=20
> brave; you can do anything with them.
>
> When it comes to a language feature, you shouldn't do *anything*. You=20
> should do just enough, and no more.
>
I don't do "anything" here. And I don't see that it requires "anything".=20
Syntax is very similar to what P0057 proposes.
=20
>
> Without `auto` NSDMI (and I wouldn't hold my breath on seeing it=20
>>> <http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2014/n3897.html>),=
=20
>>> you can't store a resumable expression. So you can't make containers of=
=20
>>> them.
>>>
>>> Unless you erase their types. So again, you've gained *nothing*.
>>>
>>> Your macro solution gets around this because it uses macros.
>>> =20
>>>
>>
>> I showed two versions above - macro based version and possible syntax=20
>> with language support.
>> Do you have any concrete reasoning why it would be impossible without=20
>> macros?
>>
>
> Because you'd have to get language support for `auto` in NSDMI's. And I=
=20
> just linked to you a discussion about precisely that and how it's *not=20
> gonna happen*. So your "possible syntax with language support" doesn't=20
> hold water.
>
Again, here I am not talking about P0114. Example code above is much more=
=20
closer to P0057 than to P0114. And it does not requires ''auto in NSDMI" -=
=20
it is clearly seen from code.
=20
>
>
>> With concrete coroutine type it could be something like this:
>>
>> template<template<typename> class coroutine_value>
>> struct generator
>> {
>> ...
>> coroutine_value<promise_type> coro;
>> };
>>
>> generator example_generator()
>> {
>> yield 1;
>> }
>> // example_generator is transformed to:
>> using example_generator =3D generator< synthesized_coroutine >;
>>
>> int main()
>> {
>> example_generator x{};
>> x.move_next();
>> g.current_value();
>> }
>>
>>
> Um, what does that code mean? Where does `synthesized_coroutine` come fro=
m?
>
"using" part is done by compiler, synthesized_coroutine comes from compiler=
..
=20
> How does `example_generator` get defined twice?
>
It is not defined twice. First one is what user writes, second one ("using"=
=20
part) is what compiler does for this code. In essence user code is=20
transformed into type with name example_generator.
=20
> And how does `example_generator` return a template that has no template=
=20
> arguments?
>
>
If you don't like it, it is possible to return type with template inside.=
=20
For instance
struct generator
{
template<template<typename> class coroutine_value>
struct apply { ... };
};
=20
> =20
>
A nice thing about resumable functions is that it doesn't take a=20
> sledgehammer to basic elements of the language. If a coroutine function=
=20
> returns a type, it *returns that type*, and the return value has all the=
=20
> rights and behaviors of a return value from a regular function.
>
>
It is not truly return type. Even P0057 does not have true return type, you=
=20
can't return value of that type from body - it just mimics normal function=
=20
syntax, but it is not normal function at all, it is just synthetic language=
=20
construction.
=20
> What you're suggesting requires a bunch of different changes to lots of=
=20
> elements of C++. You have to be able to return a template with no=20
> arguments, who's arguments are provided by that `using` declaration, I=20
> guess.
>
No, it does not require changes to lots of C++ elements. In both cases this=
=20
is not true function, it is just something with function-like syntax that=
=20
defines coroutine.
=20
After all, there's no proposal even *remotely* like this at present. Even=
=20
> your idea above is incomplete, as it's not clear what all of those pieces=
=20
> actually mean or do (P0057 makes `await` mean one thing. What does it mea=
n=20
> in your idea?). You have one general notion: coroutines having a firm typ=
e.=20
> And you're ready and willing invent a plethora of subsidiary C++ language=
=20
> features that exist for the sole purpose of making that work.
>
>
I do not offer to invent plethora of subsidiary features.
=20
> That's not a good way to make a solid proposal. If that one thing require=
s=20
> so many subsidiary language features... maybe that one thing is not worth=
=20
> it.
>
>
No, this does not requires subsidiary language features.
=20
> Even if we accept that this is a good way to make a proposal... it's not =
a=20
> *proposal* yet. It's just some ideas being batted around on a forum. None=
=20
> of the various coroutine proposals do anything like what you've suggested=
..=20
> Why should we halt or delay progress on P0057 because you *think* you=20
> might be able to do better?
>
>
If authors of P0057 still would insist on design with intrinsic overhead=20
and high burden on optimizers, then you are right - probably viable path is=
=20
to make another proposal.
Personally I would prefer to get fast coroutines in like 2020, then to get=
=20
some coroutines in 2017.
--=20
---=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.
------=_Part_9_1536708593.1444853670778
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">14 October 2015 =D0=B3., 22:35:49 UTC+3 Nicol Bolas:<block=
quote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-le=
ft: 1px #ccc solid;padding-left: 1ex;"><br><blockquote class=3D"gmail_quote=
" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-le=
ft:1ex"><div dir=3D"ltr"><div>And if macro-based version does work, then th=
is one will work without problems.<br></div></div></blockquote><div><br>I&#=
39;ll talk about this more later, but a good language feature should be <i>=
minimal</i>, not do whatever it takes. That's why a macro approach is a=
bad idea for a proposal. It's fine for a general sketch. But macros ma=
ke you brave; you can do anything with them.<br><br>When it comes to a lang=
uage feature, you shouldn't do <i>anything</i>. You should do just enou=
gh, and no more.<br></div></blockquote><div><br>I don't do "anythi=
ng" here. And I don't see that it requires "anything". S=
yntax is very similar to what P0057 proposes.<br>=C2=A0</div><blockquote cl=
ass=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px =
#ccc solid;padding-left: 1ex;"><div><br></div><blockquote class=3D"gmail_qu=
ote" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;padding=
-left:1ex"><div dir=3D"ltr"><blockquote class=3D"gmail_quote" style=3D"marg=
in:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-left:1ex"><div>Wi=
thout `auto` NSDMI (and <a href=3D"http://www.open-std.org/JTC1/SC22/WG21/d=
ocs/papers/2014/n3897.html" rel=3D"nofollow" target=3D"_blank" onmousedown=
=3D"this.href=3D'http://www.google.com/url?q\75http%3A%2F%2Fwww.open-st=
d.org%2FJTC1%2FSC22%2FWG21%2Fdocs%2Fpapers%2F2014%2Fn3897.html\46sa\75D\46s=
ntz\0751\46usg\75AFQjCNEJvBna1E4DHihTG8kJWVjTL7CIZw';return true;" oncl=
ick=3D"this.href=3D'http://www.google.com/url?q\75http%3A%2F%2Fwww.open=
-std.org%2FJTC1%2FSC22%2FWG21%2Fdocs%2Fpapers%2F2014%2Fn3897.html\46sa\75D\=
46sntz\0751\46usg\75AFQjCNEJvBna1E4DHihTG8kJWVjTL7CIZw';return true;">I=
wouldn't hold my breath on seeing it</a>), you can't store a resum=
able expression. So you can't make containers of them.<br><br>Unless yo=
u erase their types. So again, you've gained <i>nothing</i>.<br><br>You=
r macro solution gets around this because it uses macros.<br></div><div>=C2=
=A0</div></blockquote><div><br>I showed two versions above - macro based ve=
rsion and possible syntax with language support.<br>Do you have any concret=
e reasoning why it would be impossible without macros?<br></div></div></blo=
ckquote><div><br>Because you'd have to get language support for `auto` =
in NSDMI's. And I just linked to you a discussion about precisely that =
and how it's <i>not gonna happen</i>. So your "possible syntax wit=
h language support" doesn't hold water.<br></div></blockquote><div=
><br>Again, here I am not talking about P0114. Example code above is much m=
ore closer to P0057 than to P0114. And it does not requires ''auto =
in NSDMI" - it is clearly seen from code.<br>=C2=A0</div><blockquote c=
lass=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px=
#ccc solid;padding-left: 1ex;"><div><br></div><blockquote class=3D"gmail_q=
uote" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;paddin=
g-left:1ex"><div dir=3D"ltr"><div></div><br><div>With concrete coroutine ty=
pe it could be something like this:<br><br><div style=3D"background-color:r=
gb(250,250,250);border-color:rgb(187,187,187);border-style:solid;border-wid=
th:1px;word-wrap:break-word"><code><div><span style=3D"color:#008">template=
</span><span style=3D"color:#660"><</span><span style=3D"color:#008">tem=
plate</span><span style=3D"color:#080"><typename></span><span style=
=3D"color:#000"> </span><span style=3D"color:#008">class</span><span style=
=3D"color:#000"> coroutine_value</span><span style=3D"color:#660">></spa=
n><span style=3D"color:#000"><br></span><span style=3D"color:#008">struct</=
span><span style=3D"color:#000"> generator<br></span><span style=3D"color:#=
660">{</span><span style=3D"color:#000"><br>=C2=A0 =C2=A0 =C2=A0</span><spa=
n style=3D"color:#660">...</span><span style=3D"color:#000"><br>=C2=A0 =C2=
=A0 =C2=A0coroutine_value</span><span style=3D"color:#080"><promise_type=
></span><span style=3D"color:#000"> coro</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>generator example_generator</sp=
an><span style=3D"color:#660">()</span><span style=3D"color:#000"><br></spa=
n><span style=3D"color:#660">{</span><span style=3D"color:#000"><br>=C2=A0 =
=C2=A0 </span><span style=3D"color:#008">yield</span><span style=3D"color:#=
000"> </span><span style=3D"color:#066">1</span><span style=3D"color:#660">=
;</span><span style=3D"color:#000"><br></span><span style=3D"color:#660">}<=
/span><span style=3D"color:#000"><br></span><span style=3D"color:#800">// e=
xample_generator is transformed to:</span><span style=3D"color:#000"><br></=
span><span style=3D"color:#008">using</span><span style=3D"color:#000"> exa=
mple_generator </span><span style=3D"color:#660">=3D</span><span style=3D"c=
olor:#000"> generator</span><span style=3D"color:#660"><</span><span sty=
le=3D"color:#000"> synthesized_coroutine </span><span style=3D"color:#660">=
>;</span><span style=3D"color:#000"><br><br></span><span style=3D"color:=
#008">int</span><span style=3D"color:#000"> 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 example_generato=
r x</span><span style=3D"color:#660">{};</span><span style=3D"color:#000"><=
br>=C2=A0 =C2=A0 x</span><span style=3D"color:#660">.</span><span style=3D"=
color:#000">move_next</span><span style=3D"color:#660">();</span><span styl=
e=3D"color:#000"><br>=C2=A0 =C2=A0 g</span><span style=3D"color:#660">.</sp=
an><span style=3D"color:#000">current_value</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></di=
v></div></blockquote><div><br>Um, what does that code mean? Where does `syn=
thesized_coroutine` come from?</div></blockquote><div><br>"using"=
part is done by compiler, synthesized_coroutine comes from compiler.<br>=
=C2=A0</div><blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-lef=
t: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div>How does `exa=
mple_generator` get defined twice?</div></blockquote><div><br>It is not def=
ined twice. First one is what user writes, second one ("using" pa=
rt) is what compiler does for this code. In essence user code is transforme=
d into type with name example_generator.<br>=C2=A0</div><blockquote class=
=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #cc=
c solid;padding-left: 1ex;"><div>And how does `example_generator` return a =
template that has no template arguments?<br><br></div></blockquote><div><br=
>If you don't like it, it is possible to return type with template insi=
de. For instance<br><div class=3D"prettyprint" style=3D"background-color: r=
gb(250, 250, 250); border-color: rgb(187, 187, 187); border-style: solid; b=
order-width: 1px; word-wrap: break-word;"><code class=3D"prettyprint"><div =
class=3D"subprettyprint"><span style=3D"color: #008;" class=3D"styled-by-pr=
ettify">struct</span><span style=3D"color: #000;" class=3D"styled-by-pretti=
fy"> generator<br></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 </span><span style=3D"color: #008;" class=3D"styled-by-pre=
ttify">template</span><span style=3D"color: #660;" class=3D"styled-by-prett=
ify"><</span><code><span style=3D"color:#660"></span><span style=3D"colo=
r:#008"><span style=3D"color: #008;" class=3D"styled-by-prettify">template<=
/span></span><span style=3D"color:#080"><span style=3D"color: #080;" class=
=3D"styled-by-prettify"><typename></span></span><span style=3D"color:=
#000"><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span></s=
pan><span style=3D"color:#008"><span style=3D"color: #008;" class=3D"styled=
-by-prettify">class</span></span><span style=3D"color:#000"><span style=3D"=
color: #000;" class=3D"styled-by-prettify"> coroutine_value</span></span><s=
pan style=3D"color:#660"></span></code><span style=3D"color: #660;" class=
=3D"styled-by-prettify">></span><span style=3D"color: #000;" class=3D"st=
yled-by-prettify"><br>=C2=A0 =C2=A0 </span><span style=3D"color: #008;" cla=
ss=3D"styled-by-prettify">struct</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"> apply </span><span style=3D"color: #660;" class=3D=
"styled-by-prettify">{</span><span style=3D"color: #000;" class=3D"styled-b=
y-prettify"> </span><span style=3D"color: #660;" class=3D"styled-by-prettif=
y">...</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </s=
pan><span style=3D"color: #660;" class=3D"styled-by-prettify">};</span><spa=
n style=3D"color: #000;" class=3D"styled-by-prettify"><br></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></span></div></code></div><br>=
=C2=A0</div><blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-lef=
t: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div>=C2=A0</div><=
/blockquote><blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-lef=
t: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div>A nice thing =
about resumable functions is that it doesn't take a sledgehammer to bas=
ic elements of the language. If a coroutine function returns a type, it <i>=
returns that type</i>, and the return value has all the rights and behavior=
s of a return value from a regular function.<br><br></div></blockquote><div=
><br>It is not truly return type. Even P0057 does not have true return type=
, you can't return value of that type from body - it just mimics normal=
function syntax, but it is not normal function at all, it is just syntheti=
c language construction.<br>=C2=A0</div><blockquote class=3D"gmail_quote" s=
tyle=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-le=
ft: 1ex;"><div>What you're suggesting requires a bunch of different cha=
nges to lots of elements of C++. You have to be able to return a template w=
ith no arguments, who's arguments are provided by that `using` declarat=
ion, I guess.<br></div></blockquote><div><br>No, it does not require change=
s to lots of C++ elements. In both cases this is not true function, it is j=
ust something with function-like syntax that defines coroutine.<br>=C2=A0</=
div><div><br></div><blockquote class=3D"gmail_quote" style=3D"margin: 0;mar=
gin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div>After =
all, there's no proposal even <i>remotely</i> like this at present. Eve=
n your idea above is incomplete, as it's not clear what all of those pi=
eces actually mean or do (P0057 makes `await` mean one thing. What does it =
mean in your idea?). You have one general notion: coroutines having a firm =
type. And you're ready and willing invent a plethora of subsidiary C++ =
language features that exist for the sole purpose of making that work.<br><=
br></div></blockquote><div><br>I do not offer to invent plethora of subsidi=
ary features.<br>=C2=A0</div><blockquote class=3D"gmail_quote" style=3D"mar=
gin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><=
div>That's not a good way to make a solid proposal. If that one thing r=
equires so many subsidiary language features... maybe that one thing is not=
worth it.<br><br></div></blockquote><div><br>No, this does not requires su=
bsidiary language features.<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;"><div>Even if we accept that this is a good way to make a propo=
sal... it's not a <i>proposal</i> yet. It's just some ideas being b=
atted around on a forum. None of the various coroutine proposals do anythin=
g like what you've suggested. Why should we halt or delay progress on P=
0057 because you <i>think</i> you might be able to do better?<br><br></div>=
</blockquote><div><br>If authors of P0057 still would insist on design with=
intrinsic overhead and high burden on optimizers, then you are right - pro=
bably viable path is to make another proposal.<br>Personally I would prefer=
to get fast coroutines in like 2020, then to get some coroutines in 2017.<=
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_9_1536708593.1444853670778--
------=_Part_8_33436332.1444853670777--
.
Author: Evgeny Panasyuk <evgeny.panasyuk@gmail.com>
Date: Wed, 14 Oct 2015 14:09:05 -0700 (PDT)
Raw View
------=_Part_3108_185433559.1444856945550
Content-Type: multipart/alternative;
boundary="----=_Part_3109_627158957.1444856945550"
------=_Part_3109_627158957.1444856945550
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
14 October 2015 =D0=B3., 10:42:53 UTC+3 Ville Voutilainen :
>
>
> As far as having the concrete type goes, that sounds like it requires eve=
n=20
> more inlining and across-call-stack transparency.
It actually requires less inlining and transparency. For instance, this=20
code:
future<int> concrete_coroutine()
{
int local =3D await async_operation();
return local;
}
Can be straightforwardly transformed to something like:
struct concrete_coroutine
{
state_value_type current_state;
int local;
future<int> method_state_machine(); // or operator()()
};
Where method_state_machine can be compiled separately, in another=20
translation unit.
And actually this approach is already implementable with macros, to some=20
extent (it works, but compiler-side transformation will give better result)=
..
=20
> In a stackless coroutine,=20
> the erased type combined with elision of the erasure and allocations=20
> avoids=20
> having all coroutines have a different type.=20
>
Yes, but it is easy to get erased type from concrete when needed.
For instance different lambdas have different types, but can be easily=20
placed into std::function (if has appropriate signature).=20
--=20
---=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.
------=_Part_3109_627158957.1444856945550
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">=C2=A014 October 2015 =D0=B3., 10:42:53 UTC+3 Ville Voutil=
ainen :<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.=
8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><br>As far as having th=
e concrete type goes, that sounds like it requires even
<br>more inlining and across-call-stack transparency.</blockquote><div><br>=
It actually requires less inlining and transparency. For instance, this cod=
e:<br><div class=3D"prettyprint" style=3D"background-color: rgb(250, 250, 2=
50); border-color: rgb(187, 187, 187); border-style: solid; border-width: 1=
px; word-wrap: break-word;"><code class=3D"prettyprint"><div class=3D"subpr=
ettyprint"><span style=3D"color: #000;" class=3D"styled-by-prettify">future=
</span><span style=3D"color: #080;" class=3D"styled-by-prettify"><int>=
;</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> concrete=
_coroutine</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">int</span><span=
style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D=
"color: #008;" class=3D"styled-by-prettify">local</span><span style=3D"colo=
r: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #660;"=
class=3D"styled-by-prettify">=3D</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"> await async_operation</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">return</span><span style=3D"color: #00=
0;" class=3D"styled-by-prettify"> </span><span style=3D"color: #008;" class=
=3D"styled-by-prettify">local</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><=
/span></div></code></div>Can be straightforwardly transformed to something =
like:<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"su=
bprettyprint"><span style=3D"color: #008;" class=3D"styled-by-prettify">str=
uct</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> concre=
te_coroutine<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 state_value_type current_state</span><span style=3D"color: #=
660;" class=3D"styled-by-prettify">;</span><span style=3D"color: #000;" cla=
ss=3D"styled-by-prettify"><br>=C2=A0 =C2=A0 </span><span style=3D"color: #0=
08;" class=3D"styled-by-prettify">int</span><span style=3D"color: #000;" cl=
ass=3D"styled-by-prettify"> </span><span style=3D"color: #008;" class=3D"st=
yled-by-prettify">local</span><span style=3D"color: #660;" class=3D"styled-=
by-prettify">;</span><span style=3D"color: #000;" class=3D"styled-by-pretti=
fy"><br><br>=C2=A0 =C2=A0 future</span><span style=3D"color: #080;" class=
=3D"styled-by-prettify"><int></span><span style=3D"color: #000;" clas=
s=3D"styled-by-prettify"> method_state_machine</span><span style=3D"color: =
#660;" class=3D"styled-by-prettify">();</span><span style=3D"color: #000;" =
class=3D"styled-by-prettify"> </span><span style=3D"color: #800;" class=3D"=
styled-by-prettify">// or operator()()</span><span style=3D"color: #000;" c=
lass=3D"styled-by-prettify"><br></span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">};</span><span style=3D"color: #000;" class=3D"styl=
ed-by-prettify"><br></span></div></code></div>Where method_state_machine ca=
n be compiled separately, in another translation unit.<br>And actually this=
approach is already implementable with macros, to some extent (it works, b=
ut compiler-side transformation will give better result).<br><br>=C2=A0</di=
v><blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;b=
order-left: 1px #ccc solid;padding-left: 1ex;">In a stackless coroutine,
<br>the erased type combined with elision of the erasure and allocations av=
oids
<br>having all coroutines have a different type.
<br></blockquote><div><br>Yes, but it is easy to get erased type from concr=
ete when needed.<br>For instance different lambdas have different types, bu=
t can be easily placed into std::function (if has appropriate signature). <=
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_3109_627158957.1444856945550--
------=_Part_3108_185433559.1444856945550--
.
Author: Ville Voutilainen <ville.voutilainen@gmail.com>
Date: Thu, 15 Oct 2015 00:18:18 +0300
Raw View
On 15 October 2015 at 00:09, Evgeny Panasyuk <evgeny.panasyuk@gmail.com> wr=
ote:
> 14 October 2015 =D0=B3., 10:42:53 UTC+3 Ville Voutilainen :
>>
>>
>> As far as having the concrete type goes, that sounds like it requires ev=
en
>> more inlining and across-call-stack transparency.
>
>
> It actually requires less inlining and transparency. For instance, this
> code:
> future<int> concrete_coroutine()
> {
> int local =3D await async_operation();
> return local;
> }
> Can be straightforwardly transformed to something like:
> struct concrete_coroutine
> {
> state_value_type current_state;
> int local;
>
> future<int> method_state_machine(); // or operator()()
> };
> Where method_state_machine can be compiled separately, in another
> translation unit.
> And actually this approach is already implementable with macros, to some
> extent (it works, but compiler-side transformation will give better resul=
t).
Where does this transformation happen translation-unit-wise, and how
would the method_state_machine get compiled in a different translation
unit? What type does the caller of the previous concrete_coroutine() see?
>> In a stackless coroutine,
>> the erased type combined with elision of the erasure and allocations
>> avoids
>> having all coroutines have a different type.
> Yes, but it is easy to get erased type from concrete when needed.
> For instance different lambdas have different types, but can be easily
> placed into std::function (if has appropriate signature).
For some values of "easily". For the many users who don't care about the
underlying type of the coroutine, it's not so easy when they have to wrap e=
very
time they use a coroutine.
--=20
---=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.
.
Author: Evgeny Panasyuk <evgeny.panasyuk@gmail.com>
Date: Wed, 14 Oct 2015 14:46:34 -0700 (PDT)
Raw View
------=_Part_13_761263283.1444859194339
Content-Type: multipart/alternative;
boundary="----=_Part_14_914823304.1444859194340"
------=_Part_14_914823304.1444859194340
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
15 October 2015 =D0=B3., 0:18:21 UTC+3 Ville Voutilainen:
>
> On 15 October 2015 at 00:09, Evgeny Panasyuk <evgeny....@gmail.com=20
> <javascript:>> wrote:=20
> > 14 October 2015 =D0=B3., 10:42:53 UTC+3 Ville Voutilainen :=20
> >>=20
> >>=20
> >> As far as having the concrete type goes, that sounds like it requires=
=20
> even=20
> >> more inlining and across-call-stack transparency.=20
> >=20
> >=20
> > It actually requires less inlining and transparency. For instance, this=
=20
> > code:=20
> > future<int> concrete_coroutine()=20
> > {=20
> > int local =3D await async_operation();=20
> > return local;=20
> > }=20
> > Can be straightforwardly transformed to something like:=20
> > struct concrete_coroutine=20
> > {=20
> > state_value_type current_state;=20
> > int local;=20
> >=20
> > future<int> method_state_machine(); // or operator()()=20
> > };=20
> > Where method_state_machine can be compiled separately, in another=20
> > translation unit.=20
> > And actually this approach is already implementable with macros, to som=
e=20
> > extent (it works, but compiler-side transformation will give better=20
> result).=20
>
> Where does this transformation happen translation-unit-wise, and how=20
> would the method_state_machine get compiled in a different translation=20
> unit?
This is a good point. Looks like such transformation should happen in each=
=20
translation unit which uses it - in order to deduce size of structure=20
(maybe not full code generation, just analysis of locals). Method itself=20
can be compiled only in one of translation units using mechanism similar to=
=20
extern and explicit instantiation.
But my point still holds, this method can be not inlined (in optimizer=20
sense) and still produce zero allocations.
=20
> What type does the caller of the previous concrete_coroutine() see?=20
>
>
What do you mean? Which "previous"?
=20
> >> In a stackless coroutine,=20
> >> the erased type combined with elision of the erasure and allocations=
=20
> >> avoids=20
> >> having all coroutines have a different type.=20
> > Yes, but it is easy to get erased type from concrete when needed.=20
> > For instance different lambdas have different types, but can be easily=
=20
> > placed into std::function (if has appropriate signature).=20
>
> For some values of "easily". For the many users who don't care about the=
=20
> underlying type of the coroutine, it's not so easy when they have to wrap=
=20
> every=20
> time they use a coroutine.=20
>
It can be done even without explicit wrapping, but just relying on=20
different coroutine_traits specializations. One trait may give concrete=20
coroutine type, and another can erase concrete and give erased type to user=
..
For instance:
concrete_generator<int> cg1()
{
yield 1;
}
concrete_generator<int> cg2()
{
yield 2;
}
Here cg1 and cg2 are different types.
But here:
type_erased_generator<int> teg1()
{
yield 1;
}
type_erased_generator<int> teg2()
{
yield 2;
}
teg1 and teg2 would have same type.
User do not have to wrap manually cg1 and cg2 (but he can do this also) -=
=20
instead he may use type_erased_generator from the start, and it will do=20
type erasure itself via coroutine_traits mechanism.
--=20
---=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.
------=_Part_14_914823304.1444859194340
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
15 October 2015 =D0=B3., 0:18:21 UTC+3 Ville Voutilainen:<blockquote class=
=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #cc=
c solid;padding-left: 1ex;">On 15 October 2015 at 00:09, Evgeny Panasyuk &l=
t;<a href=3D"javascript:" target=3D"_blank" gdf-obfuscated-mailto=3D"8j9LEh=
OvDgAJ" rel=3D"nofollow" onmousedown=3D"this.href=3D'javascript:';r=
eturn true;" onclick=3D"this.href=3D'javascript:';return true;">evg=
eny....@gmail.com</a>> wrote:
<br>> =C2=A014 October 2015 =D0=B3., 10:42:53 UTC+3 Ville Voutilainen :
<br>>>
<br>>>
<br>>> As far as having the concrete type goes, that sounds like it r=
equires even
<br>>> more inlining and across-call-stack transparency.
<br>>
<br>>
<br>> It actually requires less inlining and transparency. For instance,=
this
<br>> code:
<br>> future<int> concrete_coroutine()
<br>> {
<br>> =C2=A0 =C2=A0 int local =3D await async_operation();
<br>> =C2=A0 =C2=A0 return local;
<br>> }
<br>> Can be straightforwardly transformed to something like:
<br>> struct concrete_coroutine
<br>> {
<br>> =C2=A0 =C2=A0 state_value_type current_state;
<br>> =C2=A0 =C2=A0 int local;
<br>>
<br>> =C2=A0 =C2=A0 future<int> method_state_machine(); // or oper=
ator()()
<br>> };
<br>> Where method_state_machine can be compiled separately, in another
<br>> translation unit.
<br>> And actually this approach is already implementable with macros, t=
o some
<br>> extent (it works, but compiler-side transformation will give bette=
r result).
<br>
<br>Where does this transformation happen translation-unit-wise, and how
<br>would the method_state_machine get compiled in a different translation
<br>unit?</blockquote><div><br>This is a good point. Looks like such transf=
ormation should happen in each translation unit which uses it - in order to=
deduce size of structure (maybe not full code generation, just analysis of=
locals). Method itself can be compiled only in one of translation units us=
ing mechanism similar to extern and explicit instantiation.<br>But my point=
still holds, this method can be not inlined (in optimizer sense) and still=
produce zero allocations.<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;">What type does the caller of the previous concrete_coroutine() =
see?
<br>
<br></blockquote><div><br>What do you mean? Which "previous"?<br>=
=C2=A0</div><blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-lef=
t: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">>> In a stac=
kless coroutine,
<br>>> the erased type combined with elision of the erasure and alloc=
ations
<br>>> avoids
<br>>> having all coroutines have a different type.
<br>> Yes, but it is easy to get erased type from concrete when needed.
<br>> For instance different lambdas have different types, but can be ea=
sily
<br>> placed into std::function (if has appropriate signature).
<br>
<br>For some values of "easily". For the many users who don't=
care about the
<br>underlying type of the coroutine, it's not so easy when they have t=
o wrap every
<br>time they use a coroutine.
<br></blockquote><div><br>It can be done even without explicit wrapping, bu=
t just relying on different coroutine_traits specializations. One trait may=
give concrete coroutine type, and another can erase concrete and give eras=
ed type to user.<br>For instance:<br><div class=3D"prettyprint" style=3D"ba=
ckground-color: rgb(250, 250, 250); border-color: rgb(187, 187, 187); borde=
r-style: solid; border-width: 1px; word-wrap: break-word;"><code class=3D"p=
rettyprint"><div class=3D"subprettyprint"><span style=3D"color: #000;" clas=
s=3D"styled-by-prettify">concrete_generator</span><span style=3D"color: #08=
0;" class=3D"styled-by-prettify"><int></span><span style=3D"color: #0=
00;" class=3D"styled-by-prettify"> cg1</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>=C2=A0 =C2=A0 </span><span style=3D"color: #008;" class=3D"styled-=
by-prettify">yield</span><span style=3D"color: #000;" class=3D"styled-by-pr=
ettify"> </span><span style=3D"color: #066;" class=3D"styled-by-prettify">1=
</span><span style=3D"color: #660;" class=3D"styled-by-prettify">;</span><s=
pan style=3D"color: #000;" class=3D"styled-by-prettify"><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></span><br><span style=3D"colo=
r: #000;" class=3D"styled-by-prettify"><code class=3D"prettyprint"><span st=
yle=3D"color: #000;" class=3D"styled-by-prettify">concrete_generator</span>=
<span style=3D"color: #080;" class=3D"styled-by-prettify"><int></span=
><span style=3D"color: #000;" class=3D"styled-by-prettify"> cg2</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: #008;" class=3D"styled-by-prettify">yield</span><span style=3D"color: #=
000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #066;" cla=
ss=3D"styled-by-prettify">2</span><span style=3D"color: #660;" class=3D"sty=
led-by-prettify">;</span><span style=3D"color: #000;" class=3D"styled-by-pr=
ettify"><br></span><span style=3D"color: #660;" class=3D"styled-by-prettify=
">}</span><span style=3D"color: #000;" class=3D"styled-by-prettify"></span>=
</code><br></span></div></code></div>Here cg1 and cg2 are different types.<=
br><br>But here:<br><div class=3D"prettyprint" style=3D"background-color: r=
gb(250, 250, 250); border-color: rgb(187, 187, 187); border-style: solid; b=
order-width: 1px; word-wrap: break-word;"><code class=3D"prettyprint"><div =
class=3D"subprettyprint"><code class=3D"prettyprint"><span style=3D"color: =
#000;" class=3D"styled-by-prettify">type_erased_generator</span><span style=
=3D"color: #080;" class=3D"styled-by-prettify"><int></span><span styl=
e=3D"color: #000;" class=3D"styled-by-prettify"> teg1</span><span style=3D"=
color: #660;" class=3D"styled-by-prettify">()</span><span style=3D"color: #=
000;" class=3D"styled-by-prettify"><br></span><span style=3D"color: #660;" =
class=3D"styled-by-prettify">{</span><span style=3D"color: #000;" class=3D"=
styled-by-prettify"><br>=C2=A0 =C2=A0 </span><span style=3D"color: #008;" c=
lass=3D"styled-by-prettify">yield</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"> </span><span style=3D"color: #066;" class=3D"style=
d-by-prettify">1</span><span style=3D"color: #660;" class=3D"styled-by-pret=
tify">;</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br=
></span><span style=3D"color: #660;" class=3D"styled-by-prettify">}</span><=
span style=3D"color: #000;" class=3D"styled-by-prettify"><br></span><br><sp=
an style=3D"color: #000;" class=3D"styled-by-prettify"><code class=3D"prett=
yprint"><span style=3D"color: #000;" class=3D"styled-by-prettify"></span></=
code></span></code><code class=3D"prettyprint"><span style=3D"color: #000;"=
class=3D"styled-by-prettify"><code class=3D"prettyprint"><span style=3D"co=
lor: #000;" class=3D"styled-by-prettify"><code class=3D"prettyprint"><code =
class=3D"prettyprint"><span style=3D"color: #000;" class=3D"styled-by-prett=
ify">type_erased_generator</span><span style=3D"color: #080;" class=3D"styl=
ed-by-prettify"></span></code></code></span><span style=3D"color: #080;" cl=
ass=3D"styled-by-prettify"><int></span><span style=3D"color: #000;" c=
lass=3D"styled-by-prettify"> teg2</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><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">yield</span><span style=3D"color: #000;" class=3D"styled-by-pretti=
fy"> </span><span style=3D"color: #066;" class=3D"styled-by-prettify">2</sp=
an><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"></span></code></span></code><span sty=
le=3D"color: #660;" class=3D"styled-by-prettify"></span></div></code></div>=
teg1 and teg2 would have same type.<br><br>User do not have to wrap manuall=
y cg1 and cg2 (but he can do this also) - instead he may use type_erased_ge=
nerator from the start, and it will do type erasure itself via coroutine_tr=
aits mechanism.<br></div>
<p></p>
-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />
------=_Part_14_914823304.1444859194340--
------=_Part_13_761263283.1444859194339--
.
Author: Ville Voutilainen <ville.voutilainen@gmail.com>
Date: Thu, 15 Oct 2015 00:53:39 +0300
Raw View
On 15 October 2015 at 00:46, Evgeny Panasyuk <evgeny.panasyuk@gmail.com> wrote:
>> What type does the caller of the previous concrete_coroutine() see?
> What do you mean? Which "previous"?
You described how
future<int> concrete_coroutine()
is supposedly transformed. I don't know what that transformation does
from the point of view of the caller of concrete_coroutine.
--
---
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: Evgeny Panasyuk <evgeny.panasyuk@gmail.com>
Date: Wed, 14 Oct 2015 15:32:26 -0700 (PDT)
Raw View
------=_Part_55_1711697450.1444861946536
Content-Type: multipart/alternative;
boundary="----=_Part_56_740285886.1444861946537"
------=_Part_56_740285886.1444861946537
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
15 October 2015 =D0=B3., 0:53:41 UTC+3 Ville Voutilainen:
>
> On 15 October 2015 at 00:46, Evgeny Panasyuk <evgeny....@gmail.com=20
> <javascript:>> wrote:=20
> >> What type does the caller of the previous concrete_coroutine() see?=20
> > What do you mean? Which "previous"?=20
>
> You described how=20
>
> future<int> concrete_coroutine()=20
>
> is supposedly transformed. I don't know what that transformation does=20
> from the point of view of the caller of concrete_coroutine.=20
>
At low level it gives type of coroutine with several methods like resume=20
and is_terminated. And can be used like:
void test()
{
concrete_coroutine coro{};
future<int> f =3D coro.resume(); // or coro()
}
_______________
Another example:
concrete_low_level_generator<int> positive_numbers(int N)
{
for(int x=3D1; x<=3DN; ++x)
yield x;
}
void test()
{
positive_numbers xs{100};
while(xs.resume())
print(xs.current_value());
}
This example is very similar to one described at page 14 of p0057r0.
Coroutine traits may provide higher level abstractions on top of this, like=
=20
give type which behaves like a range:
concrete_high_level_generator<int> positive_numbers(unsigned N)
{
for(int x=3D1; x<=3DN; ++x)
yield x;
}
void test()
{
for(auto x : positive_numbers{100});
print(x);
}
=20
--=20
---=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.
------=_Part_56_740285886.1444861946537
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">15 October 2015 =D0=B3., 0:53:41 UTC+3=C2=A0 Ville Voutila=
inen:<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8e=
x;border-left: 1px #ccc solid;padding-left: 1ex;">On 15 October 2015 at 00:=
46, Evgeny Panasyuk <<a href=3D"javascript:" target=3D"_blank" gdf-obfus=
cated-mailto=3D"qyr9kgCxDgAJ" rel=3D"nofollow" onmousedown=3D"this.href=3D&=
#39;javascript:';return true;" onclick=3D"this.href=3D'javascript:&=
#39;;return true;">evgeny....@gmail.com</a>> wrote:
<br>>> What type does the caller of the previous concrete_coroutine()=
see?
<br>> What do you mean? Which "previous"?
<br>
<br>You described how
<br>
<br>future<int> concrete_coroutine()
<br>
<br>is supposedly transformed. I don't know what that transformation do=
es
<br>from the point of view of the caller of concrete_coroutine.
<br></blockquote><div><br>At low level it gives type of coroutine with seve=
ral methods like resume and is_terminated. And can be used like:<br><div cl=
ass=3D"prettyprint" style=3D"background-color: rgb(250, 250, 250); border-c=
olor: rgb(187, 187, 187); border-style: solid; border-width: 1px; word-wrap=
: break-word;"><code class=3D"prettyprint"><div class=3D"subprettyprint"><s=
pan style=3D"color: #008;" class=3D"styled-by-prettify">void</span><span st=
yle=3D"color: #000;" class=3D"styled-by-prettify"> test</span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">()</span><span style=3D"colo=
r: #000;" class=3D"styled-by-prettify"><br></span><span style=3D"color: #66=
0;" class=3D"styled-by-prettify">{</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"><br>=C2=A0 =C2=A0 concrete_coroutine coro</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>=C2=A0 =C2=A0 future</s=
pan><span style=3D"color: #080;" class=3D"styled-by-prettify"><int></=
span><span style=3D"color: #000;" class=3D"styled-by-prettify"> f </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"> coro</span><span style=3D=
"color: #660;" class=3D"styled-by-prettify">.</span><span style=3D"color: #=
000;" class=3D"styled-by-prettify">resume</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">// or coro()</span><span style=3D"color: #000;" class=3D"sty=
led-by-prettify"><br></span><span style=3D"color: #660;" class=3D"styled-by=
-prettify">}</span><span style=3D"color: #000;" class=3D"styled-by-prettify=
"><br></span></div></code></div><br>_______________<br>Another example:<br>=
<div class=3D"prettyprint" style=3D"background-color: rgb(250, 250, 250); b=
order-color: rgb(187, 187, 187); border-style: solid; border-width: 1px; wo=
rd-wrap: break-word;"><code class=3D"prettyprint"><div class=3D"subprettypr=
int"><span style=3D"color: #000;" class=3D"styled-by-prettify">concrete_low=
_level_generator</span><span style=3D"color: #080;" class=3D"styled-by-pret=
tify"><int></span><span style=3D"color: #000;" class=3D"styled-by-pre=
ttify"> positive_numbers</span><span style=3D"color: #660;" class=3D"styled=
-by-prettify">(</span><span style=3D"color: #008;" class=3D"styled-by-prett=
ify">int</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> N=
</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">for</span><span style=3D"c=
olor: #660;" class=3D"styled-by-prettify">(</span><span style=3D"color: #00=
8;" class=3D"styled-by-prettify">int</span><span style=3D"color: #000;" cla=
ss=3D"styled-by-prettify"> x</span><span style=3D"color: #660;" class=3D"st=
yled-by-prettify">=3D</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"> x</spa=
n><span style=3D"color: #660;" class=3D"styled-by-prettify"><=3D</span><=
span style=3D"color: #000;" class=3D"styled-by-prettify">N</span><span styl=
e=3D"color: #660;" class=3D"styled-by-prettify">;</span><span style=3D"colo=
r: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #660;"=
class=3D"styled-by-prettify">++</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify">x</span><span style=3D"color: #660;" class=3D"style=
d-by-prettify">)</span><span style=3D"color: #000;" class=3D"styled-by-pret=
tify"><br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 </span><span style=3D"color: #008;" c=
lass=3D"styled-by-prettify">yield</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"> x</span><span style=3D"color: #660;" class=3D"styl=
ed-by-prettify">;</span><span style=3D"color: #000;" class=3D"styled-by-pre=
ttify"><br></span><span style=3D"color: #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">void</span=
><span style=3D"color: #000;" class=3D"styled-by-prettify"> test</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: #660;" class=3D"styled-by-prettify">{</span><span style=3D"color: #000=
;" class=3D"styled-by-prettify"><br>=C2=A0 =C2=A0 positive_numbers xs</span=
><span style=3D"color: #660;" class=3D"styled-by-prettify">{</span><span st=
yle=3D"color: #066;" class=3D"styled-by-prettify">100</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">while</span><span style=3D"color=
: #660;" class=3D"styled-by-prettify">(</span><span style=3D"color: #000;" =
class=3D"styled-by-prettify">xs</span><span style=3D"color: #660;" class=3D=
"styled-by-prettify">.</span><span style=3D"color: #000;" class=3D"styled-b=
y-prettify">resume</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 </span><span style=3D"color: #008;" class=
=3D"styled-by-prettify">print</span><span style=3D"color: #660;" class=3D"s=
tyled-by-prettify">(</span><span style=3D"color: #000;" class=3D"styled-by-=
prettify">xs</span><span style=3D"color: #660;" class=3D"styled-by-prettify=
">.</span><span style=3D"color: #000;" class=3D"styled-by-prettify">current=
_value</span><span style=3D"color: #660;" class=3D"styled-by-prettify">());=
</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br></span=
><span style=3D"color: #660;" class=3D"styled-by-prettify">}</span><span st=
yle=3D"color: #000;" class=3D"styled-by-prettify"><br></span></div></code><=
/div>This example is very similar to one described at page 14 of p0057r0.<b=
r>Coroutine traits may provide higher level abstractions on top of this, li=
ke give type which behaves like a range:<br><div class=3D"prettyprint" styl=
e=3D"background-color: rgb(250, 250, 250); border-color: rgb(187, 187, 187)=
; border-style: solid; border-width: 1px; word-wrap: break-word;"><code cla=
ss=3D"prettyprint"><div class=3D"subprettyprint"><span style=3D"color: #000=
;" class=3D"styled-by-prettify">concrete_high_level_generator</span><span s=
tyle=3D"color: #080;" class=3D"styled-by-prettify"><int></span><span =
style=3D"color: #000;" class=3D"styled-by-prettify"> positive_numbers</span=
><span style=3D"color: #660;" class=3D"styled-by-prettify">(</span><span st=
yle=3D"color: #008;" class=3D"styled-by-prettify">unsigned</span><span styl=
e=3D"color: #000;" class=3D"styled-by-prettify"> N</span><span style=3D"col=
or: #660;" class=3D"styled-by-prettify">)</span><span style=3D"color: #000;=
" class=3D"styled-by-prettify"><br></span><span style=3D"color: #660;" clas=
s=3D"styled-by-prettify">{</span><span style=3D"color: #000;" class=3D"styl=
ed-by-prettify"><br>=C2=A0 =C2=A0 </span><span style=3D"color: #008;" class=
=3D"styled-by-prettify">for</span><span style=3D"color: #660;" class=3D"sty=
led-by-prettify">(</span><span style=3D"color: #008;" class=3D"styled-by-pr=
ettify">int</span><span style=3D"color: #000;" class=3D"styled-by-prettify"=
> x</span><span style=3D"color: #660;" class=3D"styled-by-prettify">=3D</sp=
an><span style=3D"color: #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"> x</span><span style=3D"color: #=
660;" class=3D"styled-by-prettify"><=3D</span><span style=3D"color: #000=
;" class=3D"styled-by-prettify">N</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">x<=
/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 </span><span style=3D"color: #008;" class=3D"styled-by-pretti=
fy">yield</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> =
x</span><span style=3D"color: #660;" class=3D"styled-by-prettify">;</span><=
span style=3D"color: #000;" class=3D"styled-by-prettify"><br></span><span s=
tyle=3D"color: #660;" class=3D"styled-by-prettify">}</span><span style=3D"c=
olor: #000;" class=3D"styled-by-prettify"><br><br></span><span style=3D"col=
or: #008;" class=3D"styled-by-prettify">void</span><span style=3D"color: #0=
00;" class=3D"styled-by-prettify"> test</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">for</span><span style=3D"color: #660;" class=3D"styled-by-pre=
ttify">(</span><span style=3D"color: #008;" class=3D"styled-by-prettify">au=
to</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> x </spa=
n><span style=3D"color: #660;" class=3D"styled-by-prettify">:</span><span s=
tyle=3D"color: #000;" class=3D"styled-by-prettify"> positive_numbers</span>=
<span style=3D"color: #660;" class=3D"styled-by-prettify">{</span><span sty=
le=3D"color: #066;" class=3D"styled-by-prettify">100</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 =C2=A0 =C2=A0 </span><=
span style=3D"color: #008;" class=3D"styled-by-prettify">print</span><span =
style=3D"color: #660;" class=3D"styled-by-prettify">(</span><span style=3D"=
color: #000;" class=3D"styled-by-prettify">x</span><span style=3D"color: #6=
60;" class=3D"styled-by-prettify">);</span><span style=3D"color: #000;" cla=
ss=3D"styled-by-prettify"><br></span><span style=3D"color: #660;" class=3D"=
styled-by-prettify">}</span><span style=3D"color: #000;" class=3D"styled-by=
-prettify"><br></span></div></code></div><br><br><br>=C2=A0</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_56_740285886.1444861946537--
------=_Part_55_1711697450.1444861946536--
.
Author: Evgeny Panasyuk <evgeny.panasyuk@gmail.com>
Date: Thu, 15 Oct 2015 03:21:50 +0300
Raw View
14.10.2015 16:47, Nicol Bolas:
> I already described it several times, just put generator into some
> structure/array or return somewhere.
> In similar situation:
> http://coliru.stacked-crooked.com/a/0c09744abd5e57ae
> <http://coliru.stacked-crooked.com/a/0c09744abd5e57ae>
> - allocation of P0057 generator will not be elided, there will be N
> allocations, i.e. for each coroutine.
>
>
> And in your case, the `Coroutine` will have to type-erase them too. Thus
> performing N allocations.
No need for type-erasure - no need for N allocations.
>
> Put it another way. In order to make something a member of a struct, you
> must first be able to name it. In C++ as it currently stands, it is
> /impossible/ to store an unnamable type in a non-static data member.
> Whether it's a lambda or the result of a resumable expression or
> anything else, it simply /cannot happen/.
Again, I am not talking specifically about P0114r0. I am talking about
at least adding possibility to have concrete types in P0057R0-like proposal.
For instance, here:
generator<int> numbers()
{
yield 1;
}
we can use "numbers" as a name for synthesized class (which represents
concrete coroutine), instead of name for synthesized function.
>
> What you're suggesting is impossible. Or at least, it's impossible
> without trickery (ie: macros).
It is possible without any trickery. It is just transformation of
function-like code into class which has name of that function-like entity.
>
> So Boost.Asio is either doing type erasure or it is cheating. Any core
> feature will not be allowed to cheat, so you'll /have/ to use type
> erasure to store the result of such an operation.
There is no cheating and type erasure. We just can use name given by user.
>
> The only way you could avoid a dynamic allocation while still leaving
> the lifetime of the calling function is if you could copy/move the
> coroutine type. And that's just not reasonable.
First of all, I would like to have copy and move semantics, at least
some explicit control for it.
Anyway, even if we would not have copy and move semantics, yes - there
will be some allocation when needed to leave lifetime of calling
function, but there will be less allocations than in proposed P0057R0.
For instance make_unique<concrete_coroutine[]>(N) is just one
allocation, instead of N+1.
Another example is
struct Widget { concrete_coroutine x; };
make_unique<Widget>()
This is also one allocation, while P0057R0 would result in two
allocations - one for Widget itself and another for coroutine.
--
---
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: german.diago@hubblehome.com
Date: Thu, 15 Oct 2015 20:41:54 -0700 (PDT)
Raw View
------=_Part_262_1858986703.1444966914815
Content-Type: multipart/alternative;
boundary="----=_Part_263_377309216.1444966914815"
------=_Part_263_377309216.1444966914815
Content-Type: text/plain; charset=UTF-8
>
> First of all, I would like to have copy and move semantics, at least
> some explicit control for it.
>
+1
--
---
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_263_377309216.1444966914815
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<br><blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex=
;border-left: 1px #ccc solid;padding-left: 1ex;">
<br>First of all, I would like to have copy and move semantics, at least=20
<br>some explicit control for it.
<br></blockquote><div><br>+1<br>=C2=A0<br></div>
<p></p>
-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />
------=_Part_263_377309216.1444966914815--
------=_Part_262_1858986703.1444966914815--
.
Author: Nicol Bolas <jmckesson@gmail.com>
Date: Fri, 16 Oct 2015 08:52:28 -0700 (PDT)
Raw View
------=_Part_668_1314608535.1445010748240
Content-Type: multipart/alternative;
boundary="----=_Part_669_308680695.1445010748241"
------=_Part_669_308680695.1445010748241
Content-Type: text/plain; charset=UTF-8
On Wednesday, October 14, 2015 at 8:22:00 PM UTC-4, Evgeny Panasyuk wrote:
>
> 14.10.2015 16:47, Nicol Bolas:
>
> > I already described it several times, just put generator into some
> > structure/array or return somewhere.
> > In similar situation:
> > http://coliru.stacked-crooked.com/a/0c09744abd5e57ae
> > <http://coliru.stacked-crooked.com/a/0c09744abd5e57ae>
> > - allocation of P0057 generator will not be elided, there will be N
> > allocations, i.e. for each coroutine.
> >
> >
> > And in your case, the `Coroutine` will have to type-erase them too. Thus
> > performing N allocations.
>
> No need for type-erasure - no need for N allocations.
>
> >
> > Put it another way. In order to make something a member of a struct, you
> > must first be able to name it. In C++ as it currently stands, it is
> > /impossible/ to store an unnamable type in a non-static data member.
> > Whether it's a lambda or the result of a resumable expression or
> > anything else, it simply /cannot happen/.
>
>
> Again, I am not talking specifically about P0114r0. I am talking about
> at least adding possibility to have concrete types in P0057R0-like
> proposal.
>
Well, it's hard to gauge how reasonable a proposal is when said proposal *doesn't
actually exist*. You don't have a proposal; you just have some general
notions of how you think it ought to act, with no demonstrated knowledge of
how feasible that will be to implement.
And no, Boost.Asio's macro hacks are not a feasibility study.
For an example of the feasibility issue, let's use your example:
> generator<int> numbers()
> {
> yield 1;
> }
>
> we can use "numbers" as a name for synthesized class (which represents
> concrete coroutine), instead of name for synthesized function.
>
No, you cannot. Why? Well:
generator<int> numbers();
static_assert(std::is_function_v<decltype(numbers)>);
This assert should never fire. Yet you want to *make* it fire.
That's breaking basic rules of C++: a function declaration should be a
function declaration, not a struct declaration. Even lambdas don't look
like non-lambda functions.
So let's skip past that obviously non-functional idea. Let's say that you
allow users to decorate a function definition. Maybe you even use lambda
syntax, since it is similar:
[]numbers() -> generator<int>;
OK, so the compiler sees this and knows that `numbers` is a struct.
How big is it?
The compiler doesn't know. The compiler *cannot know*. Not from the
information presented here. What `numbers` is here is an incomplete type.
The only way to generate a complete type is to complete the function
definition of `numbers`. That way, the alignment and storage of the stack
data is available.
And that means that the function must be inline. Not only that, you can't
have virtual functions use this at all.
So all you've done is *re-invent P0114* with slightly different syntax. For
someone who keeps claiming that their idea isn't P0114, it seems to have a
lot of P0114's *restrictions*.
The beauty of P0057's design is that it works with C++ as it currently
exists. It changes the bare minimum needed to make the feature work. It
doesn't require that resumable functions are inlined or anything like that.
It doesn't make function declarations automatically become struct
declarations.
All of the work for resumable functions happens *within* the function that
is resumable, and external code is none-the-wiser. I can manipulate a
resumable function as normal, I can stick one in a std::function, I can
make it virtual, non-inline, anything. It's just a normal function.
What, did you think P0057 made the decision to type-erase coroutines on a
whim? It is there *specifically* to avoid all of these elements. That
design decision is what allows P0057 to work *generally*. No forced
inlining. Virtual calls are allowed. Resumable functions look and behave
just like any other 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.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.
------=_Part_669_308680695.1445010748241
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
On Wednesday, October 14, 2015 at 8:22:00 PM UTC-4, Evgeny Panasyuk wrote:<=
blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;bord=
er-left: 1px #ccc solid;padding-left: 1ex;">14.10.2015 16:47, Nicol Bolas:
<br>
<br>> =C2=A0 =C2=A0 I already described it several times, just put gener=
ator into some
<br>> =C2=A0 =C2=A0 structure/array or return somewhere.
<br>> =C2=A0 =C2=A0 In similar situation:
<br>> =C2=A0 =C2=A0 <a href=3D"http://coliru.stacked-crooked.com/a/0c097=
44abd5e57ae" target=3D"_blank" rel=3D"nofollow" onmousedown=3D"this.href=3D=
'http://www.google.com/url?q\75http%3A%2F%2Fcoliru.stacked-crooked.com%=
2Fa%2F0c09744abd5e57ae\46sa\75D\46sntz\0751\46usg\75AFQjCNEx46W0ovPGreVk53a=
ziTYTbJG0dg';return true;" onclick=3D"this.href=3D'http://www.googl=
e.com/url?q\75http%3A%2F%2Fcoliru.stacked-crooked.com%2Fa%2F0c09744abd5e57a=
e\46sa\75D\46sntz\0751\46usg\75AFQjCNEx46W0ovPGreVk53aziTYTbJG0dg';retu=
rn true;">http://coliru.stacked-crooked.<wbr>com/a/0c09744abd5e57ae</a>
<br>> =C2=A0 =C2=A0 <<a href=3D"http://coliru.stacked-crooked.com/a/0=
c09744abd5e57ae" target=3D"_blank" rel=3D"nofollow" onmousedown=3D"this.hre=
f=3D'http://www.google.com/url?q\75http%3A%2F%2Fcoliru.stacked-crooked.=
com%2Fa%2F0c09744abd5e57ae\46sa\75D\46sntz\0751\46usg\75AFQjCNEx46W0ovPGreV=
k53aziTYTbJG0dg';return true;" onclick=3D"this.href=3D'http://www.g=
oogle.com/url?q\75http%3A%2F%2Fcoliru.stacked-crooked.com%2Fa%2F0c09744abd5=
e57ae\46sa\75D\46sntz\0751\46usg\75AFQjCNEx46W0ovPGreVk53aziTYTbJG0dg';=
return true;">http://coliru.stacked-<wbr>crooked.com/a/0c09744abd5e57ae</a>=
<wbr>>
<br>> =C2=A0 =C2=A0 - allocation of P0057 generator will not be elided, =
there will be N
<br>> =C2=A0 =C2=A0 allocations, i.e. for each coroutine.
<br>>
<br>>
<br>> And in your case, the `Coroutine` will have to type-erase them too=
.. Thus
<br>> performing N allocations.
<br>
<br>No need for type-erasure - no need for N allocations.
<br>
<br>>
<br>> Put it another way. In order to make something a member of a struc=
t, you
<br>> must first be able to name it. In C++ as it currently stands, it i=
s
<br>> /impossible/ to store an unnamable type in a non-static data membe=
r.
<br>> Whether it's a lambda or the result of a resumable expression =
or
<br>> anything else, it simply /cannot happen/.
<br>
<br>
<br>Again, I am not talking specifically about P0114r0. I am talking about=
=20
<br>at least adding possibility to have concrete types in P0057R0-like prop=
osal.<br></blockquote><div><br>Well, it's hard to gauge how reasonable =
a proposal is when said proposal <i>doesn't actually exist</i>. You don=
't have a proposal; you just have some general notions of how you think=
it ought to act, with no demonstrated knowledge of how feasible that will =
be to implement.<br><br>And no, Boost.Asio's macro hacks are not a feas=
ibility study.<br><br>For an example of the feasibility issue, let's us=
e your example:<br>=C2=A0</div><blockquote class=3D"gmail_quote" style=3D"m=
argin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"=
>
generator<int> numbers()
<br>{
<br>=C2=A0 =C2=A0 yield 1;
<br>}
<br>
<br>we can use "numbers" as a name for synthesized class (which r=
epresents=20
<br>concrete coroutine), instead of name for synthesized function.
<br></blockquote><div><br>No, you cannot. Why? Well:<br><br><div class=3D"p=
rettyprint" style=3D"background-color: rgb(250, 250, 250); border-color: rg=
b(187, 187, 187); border-style: solid; border-width: 1px; word-wrap: break-=
word;"><code class=3D"prettyprint"><div class=3D"subprettyprint"><span styl=
e=3D"color: #000;" class=3D"styled-by-prettify">generator</span><span style=
=3D"color: #080;" class=3D"styled-by-prettify"><int></span><span styl=
e=3D"color: #000;" class=3D"styled-by-prettify"> numbers</span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">();</span><span style=3D"col=
or: #000;" class=3D"styled-by-prettify"><br><br></span><span style=3D"color=
: #008;" class=3D"styled-by-prettify">static_assert</span><span style=3D"co=
lor: #660;" class=3D"styled-by-prettify">(</span><span style=3D"color: #000=
;" class=3D"styled-by-prettify">std</span><span style=3D"color: #660;" clas=
s=3D"styled-by-prettify">::</span><span style=3D"color: #000;" class=3D"sty=
led-by-prettify">is_function_v</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-b=
y-prettify">(</span><span style=3D"color: #000;" class=3D"styled-by-prettif=
y">numbers</span><span style=3D"color: #660;" class=3D"styled-by-prettify">=
)>);</span></div></code></div><br>This assert should never fire. Yet you=
want to <i>make</i> it fire. <br><br>That's breaking basic rules of C+=
+: a function declaration should be a function declaration, not a struct de=
claration. Even lambdas don't look like non-lambda functions.<br><br>So=
let's skip past that obviously non-functional idea. Let's say that=
you allow users to decorate a function definition. Maybe you even use lamb=
da syntax, since it is similar:<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: #660;" cl=
ass=3D"styled-by-prettify">[]</span><span style=3D"color: #000;" class=3D"s=
tyled-by-prettify">numbers</span><span style=3D"color: #660;" class=3D"styl=
ed-by-prettify">()</span><span style=3D"color: #000;" class=3D"styled-by-pr=
ettify"> </span><span style=3D"color: #660;" class=3D"styled-by-prettify">-=
></span><span style=3D"color: #000;" class=3D"styled-by-prettify"> gener=
ator</span><span style=3D"color: #080;" class=3D"styled-by-prettify"><in=
t></span><span style=3D"color: #660;" class=3D"styled-by-prettify">;</sp=
an></div></code></div><br>OK, so the compiler sees this and knows that `num=
bers` is a struct.<br><br>How big is it?<br><br>The compiler doesn't kn=
ow. The compiler <i>cannot know</i>. Not from the information presented her=
e. What `numbers` is here is an incomplete type.<br><br>The only way to gen=
erate a complete type is to complete the function definition of `numbers`. =
That way, the alignment and storage of the stack data is available.<br><br>=
And that means that the function must be inline. Not only that, you can'=
;t have virtual functions use this at all.<br><br>So all you've done is=
<i>re-invent P0114</i> with slightly different syntax. For someone who kee=
ps claiming that their idea isn't P0114, it seems to have a lot of P011=
4's <i>restrictions</i>.<br><br>The beauty of P0057's design is tha=
t it works with C++ as it currently=20
exists. It changes the bare minimum needed to make the feature work. It=20
doesn't require that resumable functions are inlined or anything like=
=20
that. It doesn't make function declarations automatically become struct=
=20
declarations.<br><br>All of the work for resumable functions happens <i>wit=
hin</i>
the function that is resumable, and external code is none-the-wiser. I=20
can manipulate a resumable function as normal, I can stick one in a=20
std::function, I can make it virtual, non-inline, anything. It's just a=
=20
normal function.<br><br>What, did you think P0057 made the decision to type=
-erase coroutines on a whim? It is there <i>specifically</i> to avoid all o=
f these elements. That design decision is what allows P0057 to work <i>gene=
rally</i>. No forced inlining. Virtual calls are allowed. Resumable functio=
ns look and behave just like any other functions.<br></div>
<p></p>
-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />
------=_Part_669_308680695.1445010748241--
------=_Part_668_1314608535.1445010748240--
.
Author: Nicol Bolas <jmckesson@gmail.com>
Date: Fri, 16 Oct 2015 09:26:18 -0700 (PDT)
Raw View
------=_Part_625_1782543947.1445012778773
Content-Type: multipart/alternative;
boundary="----=_Part_626_307881854.1445012778774"
------=_Part_626_307881854.1445012778774
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
On Wednesday, October 14, 2015 at 4:14:31 PM UTC-4, Evgeny Panasyuk wrote:
>
> 14 October 2015 =D0=B3., 22:35:49 UTC+3 Nicol Bolas:
>
>> With concrete coroutine type it could be something like this:
>>>
>>> template<template<typename> class coroutine_value>
>>> struct generator
>>> {
>>> ...
>>> coroutine_value<promise_type> coro;
>>> };
>>>
>>> generator example_generator()
>>> {
>>> yield 1;
>>> }
>>> // example_generator is transformed to:
>>> using example_generator =3D generator< synthesized_coroutine >;
>>>
>>> int main()
>>> {
>>> example_generator x{};
>>> x.move_next();
>>> g.current_value();
>>> }
>>>
>>>
>> Um, what does that code mean? Where does `synthesized_coroutine` come=20
>> from?
>>
>
> "using" part is done by compiler, synthesized_coroutine comes from=20
> compiler.
> =20
>
>> How does `example_generator` get defined twice?
>>
>
> It is not defined twice. First one is what user writes, second one=20
> ("using" part) is what compiler does for this code. In essence user code =
is=20
> transformed into type with name example_generator.
>
=20
>
And how does `example_generator` return a template that has no template=20
>> arguments?
>>
>>
> If you don't like it,
>
It's not a question of what I like. It is simply *not possible in C++*. You=
=20
cannot return a template; you can only return a concrete type. This may be=
=20
a specific instantiation of a template, but you cannot return a template=20
itself.
What you wrote is syntactic nonsense. Therefore, if you want it to stop=20
being syntactic nonsense, your proposal will need to define what it means.
That's fine, but it is another feature added to your idea. Hence the whole=
=20
"plethora of subsidiary features" I was talking about. Every time someone=
=20
points out a problem with making coroutines concrete types, you resolve it=
=20
by adding another feature to the language. I remind you that it's=20
impossible to return a template, so you then define how being a coroutine=
=20
makes the previously impossible possible.
That's a new feature.
The nice thing about P0057 is that it doesn't have very many new features.=
=20
It pretty much stops at function suspend/resume and internally-generated=20
promise types. The return type of a coroutine is no different from any=20
other type. The awaiter type, even the promise type are all types using the=
=20
C++ rules for types.
Your proposal seems to require a lot of special-case handling at the type=
=20
level.
it is possible to return type with template inside. For instance
> struct generator
> {
> template<template<typename> class coroutine_value>
> struct apply { ... };
> };
>
>
OK, so... what does that do? Does `generator` store the coroutine? That=20
seems more or less impossible, since you have the same problem: a template=
=20
parameter for the return type getting filled in by the function returning=
=20
it.
Somewhere, there's a variable who's type, an instantiation of a template,=
=20
has one of its template arguments get filled in by the compiler. That's a=
=20
very new thing that's unlike normal C++ code.
A nice thing about resumable functions is that it doesn't take a=20
>> sledgehammer to basic elements of the language. If a coroutine function=
=20
>> returns a type, it *returns that type*, and the return value has all the=
=20
>> rights and behaviors of a return value from a regular function.
>>
>>
> It is not truly return type. Even P0057 does not have true return type,=
=20
> you can't return value of that type from body - it just mimics normal=20
> function syntax, but it is not normal function at all, it is just synthet=
ic=20
> language construction.
>
OK, internally it may only "mimic normal function syntax", but by design,=
=20
the "mimicry" is *complete*. It looks and behaves no different from any=20
other function. There is absolutely no way to tell the difference between=
=20
it and non-coroutine functions.
Your proposal exposes *everyone* to the deep guts of working with a=20
coroutine. All just for some minor performance gain that in most situations=
=20
compilers can optimize out. And even when they can't, *you* can optimize=20
them out with a decent allocator.
Even if we accept that this is a good way to make a proposal... it's not a=
=20
>> *proposal* yet. It's just some ideas being batted around on a forum.=20
>> None of the various coroutine proposals do anything like what you've=20
>> suggested. Why should we halt or delay progress on P0057 because you=20
>> *think* you might be able to do better?
>>
>>
> If authors of P0057 still would insist on design with intrinsic overhead=
=20
> and high burden on optimizers, then you are right - probably viable path =
is=20
> to make another proposal.
>
Passive-aggressiveness does not prove your point. For example, you have yet=
=20
to prove that the "burden on optimizers" is "high" by some definition of=20
that word. It's merely "non-zero".
Just like the burden on optimizers for dealing with template code,=20
inlining, and the like.
Personally I would prefer to get fast coroutines in like 2020, then to get=
=20
> some coroutines in 2017.
>
Considering that you haven't proven that P0057 is particularly slow, I=20
remain yet unconvinced that the performance gains you claim are necessary=
=20
to be "fast" are actually worth those 3 years.
--=20
---=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.
------=_Part_626_307881854.1445012778774
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
On Wednesday, October 14, 2015 at 4:14:31 PM UTC-4, Evgeny Panasyuk wrote:<=
blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;bord=
er-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr">14 October 201=
5 =D0=B3., 22:35:49 UTC+3 Nicol Bolas:<br><blockquote class=3D"gmail_quote"=
style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-lef=
t:1ex"><blockquote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8e=
x;border-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><div></div>=
<div>With concrete coroutine type it could be something like this:<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><spa=
n style=3D"color:#008">template</span><span style=3D"color:#660"><</span=
><span style=3D"color:#008">template</span><span style=3D"color:#080"><t=
ypename></span><span style=3D"color:#000"> </span><span style=3D"color:#=
008">class</span><span style=3D"color:#000"> coroutine_value</span><span st=
yle=3D"color:#660">></span><span style=3D"color:#000"><br></span><span s=
tyle=3D"color:#008">struct</span><span style=3D"color:#000"> generator<br><=
/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">...</span><span style=3D=
"color:#000"><br>=C2=A0 =C2=A0 =C2=A0coroutine_value</span><span style=3D"c=
olor:#080"><promise_type></span><span style=3D"color:#000"> coro</spa=
n><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>gene=
rator example_generator</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>=C2=A0 =C2=A0 </span><span style=3D"color:#008">yield</=
span><span style=3D"color:#000"> </span><span style=3D"color:#066">1</span>=
<span style=3D"color:#660">;</span><span style=3D"color:#000"><br></span><s=
pan style=3D"color:#660">}</span><span style=3D"color:#000"><br></span><spa=
n style=3D"color:#800">// example_generator is transformed to:</span><span =
style=3D"color:#000"><br></span><span style=3D"color:#008">using</span><spa=
n style=3D"color:#000"> example_generator </span><span style=3D"color:#660"=
>=3D</span><span style=3D"color:#000"> generator</span><span style=3D"color=
:#660"><</span><span style=3D"color:#000"> synthesized_coroutine </span>=
<span style=3D"color:#660">>;</span><span style=3D"color:#000"><br><br><=
/span><span style=3D"color:#008">int</span><span style=3D"color:#000"> 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 example_generator x</span><span style=3D"color:#660">{};</span><=
span style=3D"color:#000"><br>=C2=A0 =C2=A0 x</span><span style=3D"color:#6=
60">.</span><span style=3D"color:#000">move_next</span><span style=3D"color=
:#660">();</span><span style=3D"color:#000"><br>=C2=A0 =C2=A0 g</span><span=
style=3D"color:#660">.</span><span style=3D"color:#000">current_value</spa=
n><span style=3D"color:#660">();</span><span style=3D"color:#000"><br></spa=
n><span style=3D"color:#660">}</span><span style=3D"color:#000"><br></span>=
</div></code></div><br></div></div></blockquote><div><br>Um, what does that=
code mean? Where does `synthesized_coroutine` come from?</div></blockquote=
><div><br>"using" part is done by compiler, synthesized_coroutine=
comes from compiler.<br>=C2=A0</div><blockquote class=3D"gmail_quote" styl=
e=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-left:1ex=
"><div>How does `example_generator` get defined twice?</div></blockquote><d=
iv><br>It is not defined twice. First one is what user writes, second one (=
"using" part) is what compiler does for this code. In essence use=
r code is transformed into type with name example_generator.<br></div></div=
></blockquote><blockquote style=3D"margin: 0px 0px 0px 0.8ex; border-left: =
1px solid rgb(204, 204, 204); padding-left: 1ex;" class=3D"gmail_quote"><di=
v>=C2=A0</div></blockquote><blockquote class=3D"gmail_quote" style=3D"margi=
n: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><di=
v dir=3D"ltr"><div></div><blockquote class=3D"gmail_quote" style=3D"margin:=
0;margin-left:0.8ex;border-left:1px #ccc solid;padding-left:1ex"><div>And h=
ow does `example_generator` return a template that has no template argument=
s?<br><br></div></blockquote><div><br>If you don't like it,</div></div>=
</blockquote><div><br>It's not a question of what I like. It is simply =
<i>not possible in C++</i>. You cannot return a template; you can only retu=
rn a concrete type. This may be a specific instantiation of a template, but=
you cannot return a template itself.<br><br>What you wrote is syntactic no=
nsense. Therefore, if you want it to stop being syntactic nonsense, your pr=
oposal will need to define what it means.<br><br>That's fine, but it is=
another feature added to your idea. Hence the whole "plethora of subs=
idiary features" I was talking about. Every time someone points out a =
problem with making coroutines concrete types, you resolve it by adding ano=
ther feature to the language. I remind you that it's impossible to retu=
rn a template, so you then define how being a coroutine makes the previousl=
y=C2=A0 impossible possible.<br><br>That's a new feature.<br><br>The ni=
ce thing about P0057 is that it doesn't have very many new features. It=
pretty much stops at function suspend/resume and internally-generated prom=
ise types. The return type of a coroutine is no different from any other ty=
pe. The awaiter type, even the promise type are all types using the C++ rul=
es for types.<br><br>Your proposal seems to require a lot of special-case h=
andling at the type level.<br><br></div><blockquote class=3D"gmail_quote" s=
tyle=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-le=
ft: 1ex;"><div dir=3D"ltr"><div>it is possible to return type with template=
inside. For instance<br><div style=3D"background-color:rgb(250,250,250);bo=
rder-color:rgb(187,187,187);border-style:solid;border-width:1px;word-wrap:b=
reak-word"><code><div><span style=3D"color:#008">struct</span><span style=
=3D"color:#000"> generator<br></span><span style=3D"color:#660">{</span><sp=
an style=3D"color:#000"><br>=C2=A0 =C2=A0 </span><span style=3D"color:#008"=
>template</span><span style=3D"color:#660"><</span><code><span style=3D"=
color:#660"></span><span style=3D"color:#008"><span style=3D"color:#008">te=
mplate</span></span><span style=3D"color:#080"><span style=3D"color:#080">&=
lt;typename></span></span><span style=3D"color:#000"><span style=3D"colo=
r:#000"> </span></span><span style=3D"color:#008"><span style=3D"color:#008=
">class</span></span><span style=3D"color:#000"><span style=3D"color:#000">=
coroutine_value</span></span><span style=3D"color:#660"></span></code><spa=
n style=3D"color:#660">></span><span style=3D"color:#000"><br>=C2=A0 =C2=
=A0 </span><span style=3D"color:#008">struct</span><span style=3D"color:#00=
0"> apply </span><span style=3D"color:#660">{</span><span style=3D"color:#0=
00"> </span><span style=3D"color:#660">...</span><span style=3D"color:#000"=
> </span><span style=3D"color:#660">};</span><span style=3D"color:#000"><br=
></span><span style=3D"color:#660">};</span><span style=3D"color:#000"><br>=
</span></div></code></div><br></div></div></blockquote><div><br>OK, so... w=
hat does that do? Does `generator` store the coroutine? That seems more or =
less impossible, since you have the same problem: a template parameter for =
the return type getting filled in by the function returning it.<br><br>Some=
where, there's a variable who's type, an instantiation of a templat=
e, has one of its template arguments get filled in by the compiler. That=
9;s a very new thing that's unlike normal C++ code.<br><br></div><block=
quote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-le=
ft: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr"><div></div><blockqu=
ote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1=
px #ccc solid;padding-left:1ex"></blockquote><blockquote class=3D"gmail_quo=
te" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-=
left:1ex"><div>A nice thing about resumable functions is that it doesn'=
t take a sledgehammer to basic elements of the language. If a coroutine fun=
ction returns a type, it <i>returns that type</i>, and the return value has=
all the rights and behaviors of a return value from a regular function.<br=
><br></div></blockquote><div><br>It is not truly return type. Even P0057 do=
es not have true return type, you can't return value of that type from =
body - it just mimics normal function syntax, but it is not normal function=
at all, it is just synthetic language construction.<br></div></div></block=
quote><div><br>OK, internally it may only "mimic normal function synta=
x", but by design, the "mimicry" is <i>complete</i>. It look=
s and behaves no different from any other function. There is absolutely no =
way to tell the difference between it and non-coroutine functions.<br><br>Y=
our proposal exposes <i>everyone</i> to the deep guts of working with a cor=
outine. All just for some minor performance gain that in most situations co=
mpilers can optimize out. And even when they can't, <i>you</i> can opti=
mize them out with a decent allocator.<br><br></div><blockquote class=3D"gm=
ail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc soli=
d;padding-left: 1ex;"><div dir=3D"ltr"><div></div><div></div><blockquote cl=
ass=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1px #cc=
c solid;padding-left:1ex"><div>Even if we accept that this is a good way to=
make a proposal... it's not a <i>proposal</i> yet. It's just some =
ideas being batted around on a forum. None of the various coroutine proposa=
ls do anything like what you've suggested. Why should we halt or delay =
progress on P0057 because you <i>think</i> you might be able to do better?<=
br><br></div></blockquote><div><br>If authors of P0057 still would insist o=
n design with intrinsic overhead and high burden on optimizers, then you ar=
e right - probably viable path is to make another proposal.<br></div></div>=
</blockquote><div><br>Passive-aggressiveness does not prove your point. For=
example, you have yet to prove that the "burden on optimizers" i=
s "high" by some definition of that word. It's merely "n=
on-zero".<br><br>Just like the burden on optimizers for dealing with t=
emplate code, inlining, and the like.<br><br></div><blockquote class=3D"gma=
il_quote" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid=
;padding-left: 1ex;"><div dir=3D"ltr"><div>Personally I would prefer to get=
fast coroutines in like 2020, then to get some coroutines in 2017.<br></di=
v></div></blockquote><div><br>Considering that you haven't proven that =
P0057 is particularly slow, I remain yet unconvinced that the performance g=
ains you claim are necessary to be "fast" are actually worth thos=
e 3 years.<br></div>
<p></p>
-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />
------=_Part_626_307881854.1445012778774--
------=_Part_625_1782543947.1445012778773--
.
Author: =?UTF-8?Q?Germ=C3=A1n_Diago?= <germandiago@gmail.com>
Date: Sat, 17 Oct 2015 15:52:10 +0700
Raw View
--001a114dbd1a1f5deb052249071c
Content-Type: text/plain; charset=UTF-8
> Passive-aggressiveness does not prove your point. For example, you have
yet to prove that the "burden on optimizers" is "high" by some definition
of that word. It's merely "non-zero".
I think there is no need to, well, insult anyone for having a different
view insinuating he is being too agressive. I think it is good to have
discussion.
That said, one of the principles of C++ is the zero-overhead principle. Not
the "little overhead" principle. Why? Because c++ is for max. performance,
and if u do something suboptimal by design, people are going to invent
another solution.
Herb Sutter defined this zero overhead as nothing between c++ that is not
assembly. I agrew with that. P
The only library that does have a design I dnt like, and u mentioned
before, is iostreams. No lib ever followed iostream path since then. We
have templated non-inheritance components that are generic mostly.
Erasure does have costs and there are alternatives. Chris paper mentions
about the inherent erasure overhead. Why it is mentioned if it is not that
important... Erasure cannot be controlled in all scenarios once it is
embedded into the design. That is something that is simply true. So the
question here should be if we can have a design with inherently minimal
overhead, not if you sympathize with one solution or another only.
--
---
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/.
--001a114dbd1a1f5deb052249071c
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<p dir=3D"ltr"><br>
> Passive-aggressiveness does not prove your point. For example, you hav=
e yet to prove that the "burden on optimizers" is "high"=
; by some definition of that word. It's merely "non-zero".<br=
>
<br>
I think there is no need to, well, insult anyone for having a different vie=
w insinuating he is being too agressive. I think it is good to have discuss=
ion.<br></p>
<p dir=3D"ltr">That said, one of the principles of C++ is the zero-overhead=
principle. Not the "little overhead" principle. Why? Because c++=
is for max. performance, and if u do something suboptimal by design, peopl=
e are going to invent another solution.</p>
<p dir=3D"ltr"> Herb Sutter defined this zero overhead as nothing between c=
++ that is not assembly. I agrew with that. P<br>
The only library that does have a design I dnt like, and u mentioned before=
, is iostreams. No lib ever followed iostream path since then. We have temp=
lated non-inheritance components that are generic mostly.</p>
<p dir=3D"ltr">Erasure does have costs and there are alternatives. Chris pa=
per mentions about the inherent erasure overhead. Why it is mentioned if it=
is not that important... Erasure cannot be controlled in all scenarios onc=
e it is embedded into the design. That is something that is simply true. So=
the question here should be if we can have a design with inherently minima=
l overhead, not if you sympathize with one solution or another only.</p>
<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 />
--001a114dbd1a1f5deb052249071c--
.
Author: Evgeny Panasyuk <evgeny.panasyuk@gmail.com>
Date: Sat, 17 Oct 2015 04:14:39 -0700 (PDT)
Raw View
------=_Part_307_1124036321.1445080479705
Content-Type: multipart/alternative;
boundary="----=_Part_308_194365911.1445080479705"
------=_Part_308_194365911.1445080479705
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
16 October 2015 =D0=B3., 18:52:28 UTC+3 Nicol Bolas:
>
>
> Again, I am not talking specifically about P0114r0. I am talking about=20
>> at least adding possibility to have concrete types in P0057R0-like=20
>> proposal.
>>
>
> Well, it's hard to gauge how reasonable a proposal is when said proposal =
*doesn't=20
> actually exist*. You don't have a proposal; you just have some general=20
> notions of how you think it ought to act, with no demonstrated knowledge =
of=20
> how feasible that will be to implement.
>
Having just some feature proposal and some implementation is not enough=20
reason to standardize. Proposed feature must also fit main design goals of=
=20
language.
I am showing major flow in existing proposal. Do you think it should not be=
=20
discussed?
I agree that the best way is to make full-featured proposal, but first I=20
want to discuss it here.
=20
>
> And no, Boost.Asio's macro hacks are not a feasibility study.
>
>
These hacks allow us to investigate possible paths with low efforts.
=20
>
> That's breaking basic rules of C++: a function declaration should be a=20
> function declaration, not a struct declaration. Even lambdas don't look=
=20
> like non-lambda functions.
>
I agree, if it would be not function - it should not pretend to be a=20
function.
=20
> OK, so the compiler sees this and knows that `numbers` is a struct.
>
> How big is it?
>
> The compiler doesn't know. The compiler *cannot know*. Not from the=20
> information presented here. What `numbers` is here is an incomplete type.
>
> The only way to generate a complete type is to complete the function=20
> definition of `numbers`. That way, the alignment and storage of the stack=
=20
> data is available.
>
> And that means that the function must be inline.=20
>
Yes, if someone want coroutine with concrete type - it's body should be=20
visible to compiler at point of usage. If type-erasure is OK - then body=20
can be hidden it completely. And this is orthogonal to syntax issues.
=20
>
> So all you've done is *re-invent P0114* with slightly different syntax.=
=20
> For someone who keeps claiming that their idea isn't P0114, it seems to=
=20
> have a lot of P0114's *restrictions*.
>
P0114 sets much more ambitious goal, it tries to merge/fuse several stack=
=20
frames into one coroutine.
=20
>
> The beauty of P0057's design is that it works with C++ as it currently=20
> exists. It changes the bare minimum needed to make the feature work. It=
=20
> doesn't require that resumable functions are inlined or anything like tha=
t.=20
> It doesn't make function declarations automatically become struct=20
> declarations.
>
P0057 can be changed to allow concrete coroutine types with very small=20
syntax modifications. For instance:
// Type erasure version:
generator<int> numbers(int x)
{
yield x;
...
}
// Compiler uses std::coroutine_triats<generator<int>, int> (as it is=20
proposed in P0057)
/**************************/
// Version with concrete coroutine type:
auto numbers(int x, concrete_generator_tag =3D 0)
{
yield x;
...
}
// Compiler uses coroutine_triats<auto_result_tag, int,=20
concrete_generator_tag> , and based on this specialization it will generate=
=20
return type and value.
// Type of coroutine is decltype(numbers(1)), i.e.:
decltype(numbers(1)) coro =3D numbers(1);
This approach is even closer to P0057.
=20
>
> What, did you think P0057 made the decision to type-erase coroutines on a=
=20
> whim? It is there *specifically* to avoid all of these elements. That=20
> design decision is what allows P0057 to work *generally*. No forced=20
> inlining. Virtual calls are allowed. Resumable functions look and behave=
=20
> just like any other functions.
>
Type-erasure can be optional, it should not be the only way.
One of main use cases for coroutines are generators, even authors of P0057=
=20
refer frequently this use-case. Many languages which has some kind of=20
stackless coroutines start with support of this uses case, like Python/C#=
=20
yield.
While mandatory type-erasure can be tolerated in cases like async I/O, but=
=20
for generators it adds huge overhead, which can't be tolerated for C++.
--=20
---=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.
------=_Part_308_194365911.1445080479705
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">16 October 2015 =D0=B3., 18:52:28 UTC+3 Nicol Bolas:<block=
quote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-le=
ft: 1px #ccc solid;padding-left: 1ex;"><br><blockquote class=3D"gmail_quote=
" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-le=
ft:1ex">Again, I am not talking specifically about P0114r0. I am talking ab=
out=20
<br>at least adding possibility to have concrete types in P0057R0-like prop=
osal.<br></blockquote><div><br>Well, it's hard to gauge how reasonable =
a proposal is when said proposal <i>doesn't actually exist</i>. You don=
't have a proposal; you just have some general notions of how you think=
it ought to act, with no demonstrated knowledge of how feasible that will =
be to implement.<br></div></blockquote><div><br>Having just some feature pr=
oposal and some implementation is not enough reason to standardize. Propose=
d feature must also fit main design goals of language.<br>I am showing majo=
r flow in existing proposal. Do you think it should not be discussed?<br>I =
agree that the best way is to make full-featured proposal, but first I want=
to discuss it here.<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;"><div><br>And no, Boost.Asio's macro hacks are not a feasibility s=
tudy.<br><br></div></blockquote><div><br>These hacks allow us to investigat=
e possible paths with low efforts.<br>=C2=A0</div><blockquote class=3D"gmai=
l_quote" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;=
padding-left: 1ex;"><div><br>That's breaking basic rules of C++: a func=
tion declaration should be a function declaration, not a struct declaration=
.. Even lambdas don't look like non-lambda functions.<br></div></blockqu=
ote><div><br>I agree, if it would be not function - it should not pretend t=
o be a function.<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;=
"><div>OK, so the compiler sees this and knows that `numbers` is a struct.<=
br><br>How big is it?<br><br>The compiler doesn't know. The compiler <i=
>cannot know</i>. Not from the information presented here. What `numbers` i=
s here is an incomplete type.<br><br>The only way to generate a complete ty=
pe is to complete the function definition of `numbers`. That way, the align=
ment and storage of the stack data is available.<br><br>And that means that=
the function must be inline. </div></blockquote><div><br>Yes, if someone w=
ant coroutine with concrete type - it's body should be visible to compi=
ler at point of usage. If type-erasure is OK - then body can be hidden it c=
ompletely. And this is orthogonal to syntax issues.<br>=C2=A0</div><blockqu=
ote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-left=
: 1px #ccc solid;padding-left: 1ex;"><div><br>So all you've done is <i>=
re-invent P0114</i> with slightly different syntax. For someone who keeps c=
laiming that their idea isn't P0114, it seems to have a lot of P0114=
9;s <i>restrictions</i>.<br></div></blockquote><div><br><br>P0114 sets much=
more ambitious goal, it tries to merge/fuse several stack frames into one =
coroutine.<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;"><div=
><br>The beauty of P0057's design is that it works with C++ as it curre=
ntly=20
exists. It changes the bare minimum needed to make the feature work. It=20
doesn't require that resumable functions are inlined or anything like=
=20
that. It doesn't make function declarations automatically become struct=
=20
declarations.<br></div></blockquote><div><br>P0057 can be changed to allow =
concrete coroutine types with very small syntax modifications. For instance=
:<br><div class=3D"prettyprint" style=3D"background-color: rgb(250, 250, 25=
0); border-color: rgb(187, 187, 187); border-style: solid; border-width: 1p=
x; word-wrap: break-word;"><code class=3D"prettyprint"><div class=3D"subpre=
ttyprint"><span style=3D"color: #800;" class=3D"styled-by-prettify">// Type=
erasure version</span><span style=3D"color: #000;" class=3D"styled-by-pret=
tify">:<br>generator</span><span style=3D"color: #080;" class=3D"styled-by-=
prettify"><int></span><span style=3D"color: #000;" class=3D"styled-by=
-prettify"> numbers</span><span style=3D"color: #660;" class=3D"styled-by-p=
rettify">(</span><span style=3D"color: #008;" class=3D"styled-by-prettify">=
int</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> x</spa=
n><span style=3D"color: #660;" class=3D"styled-by-prettify">)</span><span s=
tyle=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">yield</span><span style=3D"c=
olor: #000;" class=3D"styled-by-prettify"> x</span><span style=3D"color: #6=
60;" class=3D"styled-by-prettify">;</span><span style=3D"color: #000;" clas=
s=3D"styled-by-prettify"><br>=C2=A0 =C2=A0 </span><span style=3D"color: #66=
0;" 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></span><span style=3D"color: #800;" class=3D"styled-by-prett=
ify">// Compiler uses std::coroutine_triats<</span><span style=3D"color:=
#800;" class=3D"styled-by-prettify"><code class=3D"prettyprint"><span styl=
e=3D"color: #000;" class=3D"styled-by-prettify">generator</span><span style=
=3D"color: #080;" class=3D"styled-by-prettify"><int></span><span styl=
e=3D"color: #000;" class=3D"styled-by-prettify">, int</span></code>></sp=
an><span style=3D"color: #000;" class=3D"styled-by-prettify"> (as it is pro=
posed in P0057)<br>/**************************/<br><br>// Version with conc=
rete coroutine type:</span><br><code class=3D"prettyprint"><span style=3D"c=
olor: #000;" class=3D"styled-by-prettify">auto</span><span style=3D"color: =
#000;" class=3D"styled-by-prettify"> numbers</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"> x</span><span style=3D"color: #660;" class=3D"styled-by-=
prettify">, concrete_generator_tag =3D 0)</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>=C2=A0 =C2=A0 </span><span style=3D"color: #008;" class=
=3D"styled-by-prettify">yield</span><span style=3D"color: #000;" class=3D"s=
tyled-by-prettify"> x</span><span style=3D"color: #660;" class=3D"styled-by=
-prettify">;</span><span style=3D"color: #000;" class=3D"styled-by-prettify=
"><br>=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-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></span><=
span style=3D"color: #800;" class=3D"styled-by-prettify">// Compiler uses c=
oroutine_triats<auto_result_tag</span><span style=3D"color: #800;" class=
=3D"styled-by-prettify"><code class=3D"prettyprint"><span style=3D"color: #=
000;" class=3D"styled-by-prettify">, int</span></code>, </span></code><code=
class=3D"prettyprint"><span style=3D"color: #800;" class=3D"styled-by-pret=
tify"><code class=3D"prettyprint"><code class=3D"prettyprint"><span style=
=3D"color: #660;" class=3D"styled-by-prettify">concrete_generator_tag</span=
></code></code>></span><span style=3D"color: #000;" class=3D"styled-by-p=
rettify"> , and based on this specialization it will generate return type a=
nd value.<br>// Type of coroutine is </span></code><code class=3D"prettypri=
nt"><span style=3D"color: #000;" class=3D"styled-by-prettify"><code class=
=3D"prettyprint"><code class=3D"prettyprint"><span style=3D"color: #000;" c=
lass=3D"styled-by-prettify">decltype(numbers(1)), i.e.:<br></span></code></=
code>decltype(numbers(1)) coro =3D numbers(1);</span></code><br></div></cod=
e></div>This approach is even closer to P0057.<br>=C2=A0</div><blockquote c=
lass=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px=
#ccc solid;padding-left: 1ex;"><div><br>What, did you think P0057 made the=
decision to type-erase coroutines on a whim? It is there <i>specifically</=
i> to avoid all of these elements. That design decision is what allows P005=
7 to work <i>generally</i>. No forced inlining. Virtual calls are allowed. =
Resumable functions look and behave just like any other functions.<br></div=
></blockquote><div><br>Type-erasure can be optional, it should not be the o=
nly way.<br><br>One of main use cases for coroutines are generators, even a=
uthors of P0057 refer frequently this use-case. Many languages which has so=
me kind of stackless coroutines start with support of this uses case, like =
Python/C# yield.<br><br>While mandatory type-erasure can be tolerated in ca=
ses like async I/O, but for generators it adds huge overhead, which can'=
;t be tolerated for C++.<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_308_194365911.1445080479705--
------=_Part_307_1124036321.1445080479705--
.
Author: Evgeny Panasyuk <evgeny.panasyuk@gmail.com>
Date: Sat, 17 Oct 2015 04:35:35 -0700 (PDT)
Raw View
------=_Part_149_135363989.1445081735529
Content-Type: multipart/alternative;
boundary="----=_Part_150_225925756.1445081735530"
------=_Part_150_225925756.1445081735530
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
16 =D0=BE=D0=BA=D1=82=D1=8F=D0=B1=D1=80=D1=8F 2015 =D0=B3., 19:26:18 UTC+3 =
Nicol Bolas :
>
>
> It's not a question of what I like. It is simply *not possible in C++*.=
=20
> You cannot return a template; you can only return a concrete type. This m=
ay=20
> be a specific instantiation of a template, but you cannot return a templa=
te=20
> itself.
>
You can return concrete type which has template inside.
=20
>
> What you wrote is syntactic nonsense. Therefore, if you want it to stop=
=20
> being syntactic nonsense, your proposal will need to define what it means=
..
>
Again, it is not ready proposal.
At first I am pointing to flaws of existing proposal, and want to discuss=
=20
it.
=20
>
> Your proposal seems to require a lot of special-case handling at the type=
=20
> level.
>
No, it does not require much of special-case handling.
=20
>
> it is possible to return type with template inside. For instance
>> struct generator
>> {
>> template<template<typename> class coroutine_value>
>> struct apply { ... };
>> };
>>
>>
> OK, so... what does that do? Does `generator` store the coroutine?
>
It describes how to create result type.
=20
>
> OK, internally it may only "mimic normal function syntax", but by design,=
=20
> the "mimicry" is *complete*. It looks and behaves no different from any=
=20
> other function. There is absolutely no way to tell the difference between=
=20
> it and non-coroutine functions.
>
This is possible (if it is required to mimic function syntax) for concrete=
=20
coroutines. We already have "auto" return types on functions - this=20
mechanism can be used for concrete coroutines. Check my previous message.
=20
> Your proposal exposes *everyone* to the deep guts of working with a=20
> coroutine. All just for some minor performance gain that in most situatio=
ns=20
> compilers can optimize out.
>
It is not a minor difference. One allocation and virtual/indirect calls for=
=20
resumption is a huge overhead for things like generators.
=20
> And even when they can't, *you* can optimize them out with a decent=20
> allocator.
>
First of all, I don't want to use custom allocators for simple things like=
=20
generators.
Second, even custom allocator is not zero-overhead - at least it must check=
=20
size, because it is not known at compile time.
=20
>
> Even if we accept that this is a good way to make a proposal... it's not =
a=20
>>> *proposal* yet. It's just some ideas being batted around on a forum.=20
>>> None of the various coroutine proposals do anything like what you've=20
>>> suggested. Why should we halt or delay progress on P0057 because you=20
>>> *think* you might be able to do better?
>>>
>>>
>> If authors of P0057 still would insist on design with intrinsic overhead=
=20
>> and high burden on optimizers, then you are right - probably viable path=
is=20
>> to make another proposal.
>>
>
> Passive-aggressiveness does not prove your point.
>
Constantly calling things "nonsense" things you do not like - does not=20
prove your point either.
=20
> For example, you have yet to prove that the "burden on optimizers" is=20
> "high" by some definition of that word. It's merely "non-zero".=20
>
> Just like the burden on optimizers for dealing with template code,=20
> inlining, and the like.
>
Well, I agree. I think that I should make detailed report on this issue.=20
Showing concrete aspects of overhead, showing what compilers can do today,=
=20
etc.
=20
>
> Personally I would prefer to get fast coroutines in like 2020, then to ge=
t=20
>> some coroutines in 2017.
>>
>
> Considering that you haven't proven that P0057 is particularly slow, I=20
> remain yet unconvinced that the performance gains you claim are necessary=
=20
> to be "fast" are actually worth those 3 years.
>
I already made some tests, checked ASM for both versions, etc. I should do=
=20
more tests and then create some kind of report based on this.
--=20
---=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.
------=_Part_150_225925756.1445081735530
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">16 =D0=BE=D0=BA=D1=82=D1=8F=D0=B1=D1=80=D1=8F 2015 =D0=B3.=
, 19:26:18 UTC+3 Nicol Bolas :<blockquote class=3D"gmail_quote" style=3D"ma=
rgin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">=
<br><div>It's not a question of what I like. It is simply <i>not possib=
le in C++</i>. You cannot return a template; you can only return a concrete=
type. This may be a specific instantiation of a template, but you cannot r=
eturn a template itself.<br></div></blockquote><div><br>You can return conc=
rete type which has template inside.<br>=C2=A0</div><blockquote class=3D"gm=
ail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc soli=
d;padding-left: 1ex;"><div><br>What you wrote is syntactic nonsense. Theref=
ore, if you want it to stop being syntactic nonsense, your proposal will ne=
ed to define what it means.<br></div></blockquote><div><br>Again, it is not=
ready proposal.<br>At first I am pointing to flaws of existing proposal, a=
nd want to discuss it.<br>=C2=A0</div><blockquote class=3D"gmail_quote" sty=
le=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left=
: 1ex;"><div><br>Your proposal seems to require a lot of special-case handl=
ing at the type level.<br></div></blockquote><div><br>No, it does not requi=
re much of special-case handling.<br>=C2=A0</div><blockquote class=3D"gmail=
_quote" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;p=
adding-left: 1ex;"><div><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>it is possible to return type with template inside. =
For instance<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">struct</span><span style=3D"color:#=
000"> generator<br></span><span style=3D"color:#660">{</span><span style=3D=
"color:#000"><br>=C2=A0 =C2=A0 </span><span style=3D"color:#008">template</=
span><span style=3D"color:#660"><</span><code><span style=3D"color:#660"=
></span><span style=3D"color:#008"><span style=3D"color:#008">template</spa=
n></span><span style=3D"color:#080"><span style=3D"color:#080"><typename=
></span></span><span style=3D"color:#000"><span style=3D"color:#000"> </=
span></span><span style=3D"color:#008"><span style=3D"color:#008">class</sp=
an></span><span style=3D"color:#000"><span style=3D"color:#000"> coroutine_=
value</span></span><span style=3D"color:#660"></span></code><span style=3D"=
color:#660">></span><span style=3D"color:#000"><br>=C2=A0 =C2=A0 </span>=
<span style=3D"color:#008">struct</span><span style=3D"color:#000"> apply <=
/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><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></span></di=
v></code></div><br></div></div></blockquote><div><br>OK, so... what does th=
at do? Does `generator` store the coroutine?</div></blockquote><div><br>It =
describes how to create result type.<br>=C2=A0</div><blockquote class=3D"gm=
ail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc soli=
d;padding-left: 1ex;"><br><div>OK, internally it may only "mimic norma=
l function syntax", but by design, the "mimicry" is <i>compl=
ete</i>. It looks and behaves no different from any other function. There i=
s absolutely no way to tell the difference between it and non-coroutine fun=
ctions.<br></div></blockquote><div><br>This is possible (if it is required =
to mimic function syntax) for concrete coroutines. We already have "au=
to" return types on functions - this mechanism can be used for concret=
e coroutines. Check my previous message.<br>=C2=A0</div><blockquote class=
=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #cc=
c solid;padding-left: 1ex;"><div>Your proposal exposes <i>everyone</i> to t=
he deep guts of working with a coroutine. All just for some minor performan=
ce gain that in most situations compilers can optimize out.</div></blockquo=
te><div><br>It is not a minor difference. One allocation and virtual/indire=
ct calls for resumption is a huge overhead for things like generators.<br>=
=C2=A0</div><blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-lef=
t: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div>And even when=
they can't, <i>you</i> can optimize them out with a decent allocator.<=
br></div></blockquote><div><br>First of all, I don't want to use custom=
allocators for simple things like generators.<br>Second, even custom alloc=
ator is not zero-overhead - at least it must check size, because it is not =
known at compile time.<br>=C2=A0</div><blockquote class=3D"gmail_quote" sty=
le=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left=
: 1ex;"><div><br></div><blockquote class=3D"gmail_quote" style=3D"margin:0;=
margin-left:0.8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir=3D"=
ltr"><div></div><div></div><blockquote class=3D"gmail_quote" style=3D"margi=
n:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-left:1ex"><div>Eve=
n if we accept that this is a good way to make a proposal... it's not a=
<i>proposal</i> yet. It's just some ideas being batted around on a for=
um. None of the various coroutine proposals do anything like what you'v=
e suggested. Why should we halt or delay progress on P0057 because you <i>t=
hink</i> you might be able to do better?<br><br></div></blockquote><div><br=
>If authors of P0057 still would insist on design with intrinsic overhead a=
nd high burden on optimizers, then you are right - probably viable path is =
to make another proposal.<br></div></div></blockquote><div><br>Passive-aggr=
essiveness does not prove your point.</div></blockquote><div><br>Constantly=
calling things "nonsense" things you do not like - does not prov=
e your point either.<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;"><div>For example, you have yet to prove that the "burden on opti=
mizers" is "high" by some definition of that word. It's =
merely "non-zero". <br></div></blockquote><blockquote class=3D"gm=
ail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc soli=
d;padding-left: 1ex;"><div><br>Just like the burden on optimizers for deali=
ng with template code, inlining, and the like.<br></div></blockquote><div><=
br>Well, I agree. I think that I should make detailed report on this issue.=
Showing concrete aspects of overhead, showing what compilers can do today,=
etc.<br>=C2=A0</div><blockquote class=3D"gmail_quote" style=3D"margin: 0;m=
argin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div><br>=
</div><blockquote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex=
;border-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><div>Persona=
lly I would prefer to get fast coroutines in like 2020, then to get some co=
routines in 2017.<br></div></div></blockquote><div><br>Considering that you=
haven't proven that P0057 is particularly slow, I remain yet unconvinc=
ed that the performance gains you claim are necessary to be "fast"=
; are actually worth those 3 years.<br></div></blockquote><div><br>=C2=A0I =
already made some tests, checked ASM for both versions, etc. I should do mo=
re tests and then create some kind of report based on this.<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_150_225925756.1445081735530--
------=_Part_149_135363989.1445081735529--
.
Author: Nicol Bolas <jmckesson@gmail.com>
Date: Sat, 17 Oct 2015 06:31:25 -0700 (PDT)
Raw View
------=_Part_38_614041291.1445088685229
Content-Type: multipart/alternative;
boundary="----=_Part_39_1241265271.1445088685230"
------=_Part_39_1241265271.1445088685230
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
On Saturday, October 17, 2015 at 7:14:40 AM UTC-4, Evgeny Panasyuk wrote:
>
> 16 October 2015 =D0=B3., 18:52:28 UTC+3 Nicol Bolas:
>>
>>
>> Again, I am not talking specifically about P0114r0. I am talking about=
=20
>>> at least adding possibility to have concrete types in P0057R0-like=20
>>> proposal.
>>>
>>
>> Well, it's hard to gauge how reasonable a proposal is when said proposal=
*doesn't=20
>> actually exist*. You don't have a proposal; you just have some general=
=20
>> notions of how you think it ought to act, with no demonstrated knowledge=
of=20
>> how feasible that will be to implement.
>>
>
> Having just some feature proposal and some implementation is not enough=
=20
> reason to standardize.
>
You are absolutely right. Having a well-designed proposal along with=20
standards wording and an implementation, is not by itself enough reason to=
=20
standardize (that's not sarcasm, I'm being serious).
However, it is *necessary* for that process. That alone may not be=20
sufficient, but it is necessary.
A necessary step that your idea has not taken. No implementation, no=20
standards wording, not even a fully-fleshed out design. Your idea isn't=20
anywhere near as well-formed as P0114.
P0057 is the result of numerous revisions of an idea, across several years,=
=20
as well as with lots of implementation experience. Why should we impair=20
such a design just because you think that, one day, someone *might* propose=
=20
a better one? After all, yours is not a proposal; you're just kicking=20
around ideas.
Proposed feature must also fit main design goals of language.
> I am showing major flow in existing proposal. Do you think it should not=
=20
> be discussed?
>
Discussed? Sure.
Should that discussion, merely by *existing*, justify torpedoing any and=20
all process on that spec, or automatically force it to change? No.
The zero-overhead principle *is not a club!* Stop using a principle to bash=
=20
things over the head.
=20
> I agree that the best way is to make full-featured proposal, but first I=
=20
> want to discuss it here.
> =20
>
>>
>> And no, Boost.Asio's macro hacks are not a feasibility study.
>>
>>
> These hacks allow us to investigate possible paths with low efforts.
>
Yes, they are useful for brainstorming. But they are still not a=20
feasibility study.
So all you've done is *re-invent P0114* with slightly different syntax. For=
=20
>> someone who keeps claiming that their idea isn't P0114, it seems to have=
a=20
>> lot of P0114's *restrictions*.
>>
>
>
> P0114 sets much more ambitious goal, it tries to merge/fuse several stack=
=20
> frames into one coroutine.
>
Yes, it does. But think about why it does that. Or rather, how it *can* do=
=20
that.
It can do that because P0114 requires that all resumable functions are=20
inline. *Your* idea requires all resumable functions are inline.
So why should your idea *not* allow this? Just to be similar to P0057? As I=
=20
will point out in the next section, your idea doesn't behave at all like=20
P0057. So why should it look like it?
The need for inlining functions makes this feature possible and easy to=20
implement. And it is a feature that people would find useful.
Your idea will force people to inline this code anyway; you may as well let=
=20
people *benefit* from it. More than just forgoing allocations.
The beauty of P0057's design is that it works with C++ as it currently=20
>> exists. It changes the bare minimum needed to make the feature work. It=
=20
>> doesn't require that resumable functions are inlined or anything like th=
at.=20
>> It doesn't make function declarations automatically become struct=20
>> declarations.
>>
>
> P0057 can be changed to allow concrete coroutine types with very small=20
> syntax modifications. For instance:
> // Type erasure version:
> generator<int> numbers(int x)
> {
> yield x;
> ...
> }
> // Compiler uses std::coroutine_triats<generator<int>, int> (as it is=20
> proposed in P0057)
> /**************************/
>
> // Version with concrete coroutine type:
> auto numbers(int x, concrete_generator_tag =3D 0)
> {
> yield x;
> ...
> }
> // Compiler uses coroutine_triats<auto_result_tag, int,=20
> concrete_generator_tag> , and based on this specialization it will=20
> generate return type and value.
> // Type of coroutine is decltype(numbers(1)), i.e.:
> decltype(numbers(1)) coro =3D numbers(1);
> This approach is even closer to P0057.
>
That is, quite frankly, a terrible way to specify that a function is an=20
unboxed coroutine. A special tag type in the function signature?
I'd much rather have a keyword. Especially since this fundamentally changes=
=20
how the function behaves, that's generally the sort of thing a keyword=20
would do, not a type in the signature.
And no, your approach is not "closer" to P0057. It's farther. The return=20
type is a coroutine now, not a future, or generator, or other user-defined=
=20
type. It's an actual coroutine.
That's not how P0057 works. Indeed, that's not what P0057 is *for*.=20
Remember the general idea of await in P0057: it halts the function, but it=
=20
also *explicitly* allows the transfer of control of the function to the *aw=
ait=20
expression*. And thus, control is not necessarily transferred to the return=
=20
value.
In P0057, the return value is not *necessarily* the resumable part. That's=
=20
why it's not necessarily a coroutine or anything that stores the coroutine.=
=20
Because at the end of the day, P0057 is not about returning control to the=
=20
caller: it's also about allowing the await expression to continue to=20
execute the code elsewhere.
Quite a few uses of `await` use an awaiter whose `await_suspend` method=20
looks like this:
auto await_suspend(coroutine_handle<> h)
{
some_future.then([h]() {h();}
}
The awaiter is going to complete the function, not the return value. The=20
return value may be a future or whatever that knows when `h` is finished,=
=20
but that return value is not itself responsible for actually *completing*=
=20
that execution.
If the return value is a coroutine, then this is not possible. It is then=
=20
on the caller, not the expression being awaited on, to continue the=20
function.
There is a stackless coroutine system that always transfers control to the=
=20
caller the way yours does here. Yes, you have *yet again* made a proposal=
=20
that's closer to P0114 than P0057.
Oh sure, you use different keywords. But the behavior of those keywords is=
=20
basically the behavior of the functions P0114 implements. Basically, P0114=
=20
is what you want, even if you would prefer that the form appeared more like=
=20
P0057.
I think one thing this conversation has proven is that the most fundamental=
=20
differences between P0057 and P0114 are:
1) The use of type-erased coroutines. If you don't type-erase your=20
coroutine, you *will* end up with all the limitations of P0114.
2) The ability to transfer control internally rather than externally. P0057=
=20
is all about allowing the await expression to decide when the coroutine=20
gets to be continued. P0114 doesn't really allow that; even its prospective=
=20
`await` function doesn't really implement await the way P0057 does. In=20
P0114, and in your example, if you want the awaiting call to be resumed in=
=20
some other thread, it's up to the *caller* to decide this, not the=20
implementation of the resumable function.
You seem to want to inject #1 and #2 into P0057, transforming it into a=20
mere syntactic alteration of P0114.
What, did you think P0057 made the decision to type-erase coroutines on a=
=20
>> whim? It is there *specifically* to avoid all of these elements. That=20
>> design decision is what allows P0057 to work *generally*. No forced=20
>> inlining. Virtual calls are allowed. Resumable functions look and behave=
=20
>> just like any other functions.
>>
>
> Type-erasure can be optional, it should not be the only way.
>
> One of main use cases for coroutines are generators, even authors of P005=
7=20
> refer frequently this use-case. Many languages which has some kind of=20
> stackless coroutines start with support of this uses case, like Python/C#=
=20
> yield.
>
> While mandatory type-erasure can be tolerated in cases like async I/O, bu=
t=20
> for generators it adds huge overhead, which can't be tolerated for C++.
>
Where is your evidence for this "huge overhead" for generators? You ignore=
=20
the fact that allocation can be elided. You ignore the fact that you can=20
overload the allocation manually, thus allowing you to use preallocated=20
chunks, stack space, or whatever else to make the allocation take virtually=
=20
no time.
Repeatedly declaring something to be true does not make it true.
--=20
---=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.
------=_Part_39_1241265271.1445088685230
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
On Saturday, October 17, 2015 at 7:14:40 AM UTC-4, Evgeny Panasyuk wrote:<b=
lockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;borde=
r-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr">16 October 2015=
=D0=B3., 18:52:28 UTC+3 Nicol Bolas:<blockquote class=3D"gmail_quote" styl=
e=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-left:1ex=
"><br><blockquote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex=
;border-left:1px #ccc solid;padding-left:1ex">Again, I am not talking speci=
fically about P0114r0. I am talking about=20
<br>at least adding possibility to have concrete types in P0057R0-like prop=
osal.<br></blockquote><div><br>Well, it's hard to gauge how reasonable =
a proposal is when said proposal <i>doesn't actually exist</i>. You don=
't have a proposal; you just have some general notions of how you think=
it ought to act, with no demonstrated knowledge of how feasible that will =
be to implement.<br></div></blockquote><div><br>Having just some feature pr=
oposal and some implementation is not enough reason to standardize.</div></=
div></blockquote><div><br>You are absolutely right. Having a well-designed =
proposal along with standards wording and an implementation, is not by itse=
lf enough reason to standardize (that's not sarcasm, I'm being seri=
ous).<br><br>However, it is <i>necessary</i> for that process. That alone m=
ay not be sufficient, but it is necessary.<br><br>A necessary step that you=
r idea has not taken. No implementation, no standards wording, not even a f=
ully-fleshed out design. Your idea isn't anywhere near as well-formed a=
s P0114.<br><br>P0057 is the result of numerous revisions of an idea, acros=
s several years, as well as with lots of implementation experience. Why sho=
uld we impair such a design just because you think that, one day, someone <=
i>might</i> propose a better one? After all, yours is not a proposal; you&#=
39;re just kicking around ideas.<br><br></div><blockquote class=3D"gmail_qu=
ote" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padd=
ing-left: 1ex;"><div dir=3D"ltr"><div>Proposed feature must also fit main d=
esign goals of language.<br>I am showing major flow in existing proposal. D=
o you think it should not be discussed?<br></div></div></blockquote><div><b=
r>Discussed? Sure.<br><br>Should that discussion, merely by <i>existing</i>=
, justify torpedoing any and all process on that spec, or automatically for=
ce it to change? No.<br><br>The zero-overhead principle <i>is not a club!</=
i> Stop using a principle to bash things over the head.<br>=C2=A0</div><blo=
ckquote 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>I agree that=
the best way is to make full-featured proposal, but first I want to discus=
s it here.<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"><div><br>=
And no, Boost.Asio's macro hacks are not a feasibility study.<br><br></=
div></blockquote><div><br>These hacks allow us to investigate possible path=
s with low efforts.<br></div></div></blockquote><div><br>Yes, they are usef=
ul for brainstorming. But they are still not a feasibility study.<br><br></=
div><blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex=
;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr"><div></di=
v><blockquote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;bor=
der-left:1px #ccc solid;padding-left:1ex"><div>So all you've done is <i=
>re-invent P0114</i> with slightly different syntax. For someone who keeps =
claiming that their idea isn't P0114, it seems to have a lot of P0114&#=
39;s <i>restrictions</i>.<br></div></blockquote><div><br><br>P0114 sets muc=
h more ambitious goal, it tries to merge/fuse several stack frames into one=
coroutine.<br></div></div></blockquote><div><br>Yes, it does. But think ab=
out why it does that. Or rather, how it <i>can</i> do that.<br><br>It can d=
o that because P0114 requires that all resumable functions are inline. <i>Y=
our</i> idea requires all resumable functions are inline.<br><br>So why sho=
uld your idea <i>not</i> allow this? Just to be similar to P0057? As I will=
point out in the next section, your idea doesn't behave at all like P0=
057. So why should it look like it?<br><br>The need for inlining functions =
makes this feature possible and easy to implement. And it is a feature that=
people would find useful.<br><br>Your idea will force people to inline thi=
s code anyway; you may as well let people <i>benefit</i> from it. More than=
just forgoing allocations.<br><br></div><blockquote class=3D"gmail_quote" =
style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-l=
eft: 1ex;"><div dir=3D"ltr"><blockquote class=3D"gmail_quote" style=3D"marg=
in:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-left:1ex"><div>Th=
e beauty of P0057's design is that it works with C++ as it currently=20
exists. It changes the bare minimum needed to make the feature work. It=20
doesn't require that resumable functions are inlined or anything like=
=20
that. It doesn't make function declarations automatically become struct=
=20
declarations.<br></div></blockquote><div><br>P0057 can be changed to allow =
concrete coroutine types with very small syntax modifications. For instance=
:<br><div style=3D"background-color:rgb(250,250,250);border-color:rgb(187,1=
87,187);border-style:solid;border-width:1px;word-wrap:break-word"><code><di=
v><span style=3D"color:#800">// Type erasure version</span><span style=3D"c=
olor:#000">:<br>generator</span><span style=3D"color:#080"><int></spa=
n><span style=3D"color:#000"> numbers</span><span style=3D"color:#660">(</s=
pan><span style=3D"color:#008">int</span><span style=3D"color:#000"> x</spa=
n><span style=3D"color:#660">)</span><span style=3D"color:#000"><br></span>=
<span style=3D"color:#660">{</span><span style=3D"color:#000"><br>=C2=A0 =
=C2=A0 </span><span style=3D"color:#008">yield</span><span style=3D"color:#=
000"> x</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></span><span style=3D"color:#660">}</span><span style=
=3D"color:#000"><br></span><span style=3D"color:#800">// Compiler uses std:=
:coroutine_triats<</span><span style=3D"color:#800"><code><span style=3D=
"color:#000">generato<wbr>r</span><span style=3D"color:#080"><int></s=
pan><span style=3D"color:#000">, int</span></code>></span><span style=3D=
"color:#000"> (as it is proposed in P0057)<br>/**************************/<=
br><br>// Version with concrete coroutine type:</span><br><code><span style=
=3D"color:#000">auto</span><span style=3D"color:#000"> numbers</span><span =
style=3D"color:#660">(</span><span style=3D"color:#008">int</span><span sty=
le=3D"color:#000"> x</span><span style=3D"color:#660">, concrete_generator_=
tag =3D 0)</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 st=
yle=3D"color:#008">yield</span><span style=3D"color:#000"> x</span><span st=
yle=3D"color:#660">;</span><span style=3D"color:#000"><br>=C2=A0 =C2=A0 </s=
pan><span style=3D"color:#660">...</span><span style=3D"color:#000"><br></s=
pan><span style=3D"color:#660">}</span><span style=3D"color:#000"><br></spa=
n><span style=3D"color:#800">// Compiler uses coroutine_triats<auto_resu=
lt_<wbr>tag</span><span style=3D"color:#800"><code><span style=3D"color:#00=
0">, int</span></code>, </span></code><code><span style=3D"color:#800"><cod=
e><code><span style=3D"color:#660">concrete_generator_tag</span></code></co=
de>></span><span style=3D"color:#000"> , and based on this specializatio=
n it will generate return type and value.<br>// Type of coroutine is </span=
></code><code><span style=3D"color:#000"><code><code><span style=3D"color:#=
000">decltype(numbers(1)), i.e.:<br></span></code></code>decltype(numbers(1=
)) coro =3D numbers(1);</span></code><br></div></code></div>This approach i=
s even closer to P0057.<br></div></div></blockquote><div><br>That is, quite=
frankly, a terrible way to specify that a function is an unboxed coroutine=
.. A special tag type in the function signature?<br><br>I'd much rather =
have a keyword. Especially since this fundamentally changes how the functio=
n behaves, that's generally the sort of thing a keyword would do, not a=
type in the signature.<br><br>And no, your approach is not "closer&qu=
ot; to P0057. It's farther. The return type is a coroutine now, not a f=
uture, or generator, or other user-defined type. It's an actual corouti=
ne.<br><br>That's not how P0057 works. Indeed, that's not what P005=
7 is <i>for</i>. Remember the general idea of await in P0057: it halts the =
function, but it also <i>explicitly</i> allows the transfer of control of t=
he function to the <i>await expression</i>. And thus, control is not necess=
arily transferred to the return value.<br><br>In P0057, the return value is=
not <i>necessarily</i> the resumable part. That's why it's not nec=
essarily a coroutine or anything that stores the coroutine. Because at the =
end of the day, P0057 is not about returning control to the caller: it'=
s also about allowing the await expression to continue to execute the code =
elsewhere.<br><br>Quite a few uses of `await` use an awaiter whose `await_s=
uspend` method looks like this:<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">auto</span><span style=3D"color: #000;" class=3D=
"styled-by-prettify"> await_suspend</span><span style=3D"color: #660;" clas=
s=3D"styled-by-prettify">(</span><span style=3D"color: #000;" class=3D"styl=
ed-by-prettify">coroutine_handle</span><span style=3D"color: #660;" class=
=3D"styled-by-prettify"><></span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"> h</span><span style=3D"color: #660;" class=3D"styl=
ed-by-prettify">)</span><span style=3D"color: #000;" class=3D"styled-by-pre=
ttify"><br></span><span style=3D"color: #660;" class=3D"styled-by-prettify"=
>{</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br>=C2=
=A0 some_future</span><span style=3D"color: #660;" class=3D"styled-by-prett=
ify">.</span><span style=3D"color: #008;" class=3D"styled-by-prettify">then=
</span><span style=3D"color: #660;" class=3D"styled-by-prettify">([</span><=
span style=3D"color: #000;" class=3D"styled-by-prettify">h</span><span styl=
e=3D"color: #660;" class=3D"styled-by-prettify">]()</span><span style=3D"co=
lor: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #660=
;" class=3D"styled-by-prettify">{</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify">h</span><span style=3D"color: #660;" class=3D"style=
d-by-prettify">();}</span><span style=3D"color: #000;" class=3D"styled-by-p=
rettify"><br></span><span style=3D"color: #660;" class=3D"styled-by-prettif=
y">}</span></div></code></div><br>The awaiter is going to complete the func=
tion, not the return value. The return value may be a future or whatever th=
at knows when `h` is finished, but that return value is not itself responsi=
ble for actually <i>completing</i> that execution.<br><br>If the return val=
ue is a coroutine, then this is not possible. It is then on the caller, not=
the expression being awaited on, to continue the function.<br><br>There is=
a stackless coroutine system that always transfers control to the caller t=
he way yours does here. Yes, you have <i>yet again</i> made a proposal that=
's closer to P0114 than P0057.<br><br>Oh sure, you use different keywor=
ds. But the behavior of those keywords is basically the behavior of the fun=
ctions P0114 implements. Basically, P0114 is what you want, even if you wou=
ld prefer that the form appeared more like P0057.<br><br>I think one thing =
this conversation has proven is that the most fundamental differences betwe=
en P0057 and P0114 are:<br><br>1) The use of type-erased coroutines. If you=
don't type-erase your coroutine, you <i>will</i> end up with all the l=
imitations of P0114.<br><br>2) The ability to transfer control internally r=
ather than externally. P0057 is all about allowing the await expression to =
decide when the coroutine gets to be continued. P0114 doesn't really al=
low that; even its prospective `await` function doesn't really implemen=
t await the way P0057 does. In P0114, and in your example, if you want the =
awaiting call to be resumed in some other thread, it's up to the <i>cal=
ler</i> to decide this, not the implementation of the resumable function.<b=
r><br>You seem to want to inject #1 and #2 into P0057, transforming it into=
a mere syntactic alteration of P0114.<br><br></div><blockquote class=3D"gm=
ail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc soli=
d;padding-left: 1ex;"><div dir=3D"ltr"><div></div><blockquote class=3D"gmai=
l_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;pad=
ding-left:1ex"><div>What, did you think P0057 made the decision to type-era=
se coroutines on a whim? It is there <i>specifically</i> to avoid all of th=
ese elements. That design decision is what allows P0057 to work <i>generall=
y</i>. No forced inlining. Virtual calls are allowed. Resumable functions l=
ook and behave just like any other functions.<br></div></blockquote><div><b=
r>Type-erasure can be optional, it should not be the only way.<br><br>One o=
f main use cases for coroutines are generators, even authors of P0057 refer=
frequently this use-case. Many languages which has some kind of stackless =
coroutines start with support of this uses case, like Python/C# yield.<br><=
br>While mandatory type-erasure can be tolerated in cases like async I/O, b=
ut for generators it adds huge overhead, which can't be tolerated for C=
++.<br></div></div></blockquote><div><br>Where is your evidence for this &q=
uot;huge overhead" for generators? You ignore the fact that allocation=
can be elided. You ignore the fact that you can overload the allocation ma=
nually, thus allowing you to use preallocated chunks, stack space, or whate=
ver else to make the allocation take virtually no time.<br><br>Repeatedly d=
eclaring something to be true does not make it true.<br></div>
<p></p>
-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />
------=_Part_39_1241265271.1445088685230--
------=_Part_38_614041291.1445088685229--
.
Author: Giovanni Piero Deretta <gpderetta@gmail.com>
Date: Sat, 17 Oct 2015 15:24:25 +0100
Raw View
--001a11c333f258f61405224dabbb
Content-Type: text/plain; charset=UTF-8
On 16 Oct 2015 5:26 p.m., "Nicol Bolas" <jmckesson@gmail.com> wrote:
..
>
> The nice thing about P0057 is that it doesn't have very many new
features. It pretty much stops at function suspend/resume and
internally-generated promise types. The return type of a coroutine is no
different from any other type. The awaiter type, even the promise type are
all types using the C++ rules for types.
>
If the criterion is minimising the number of new language features, we
should just standardise Boost.coroutine. It is provably implementable as a
pure library, there is significant industry experience with it and it is
significantly more expressive than any stackless proposal.
The only advantage of P0057 is that its coroutines are guaranteed to need a
single frame instead of a whole side stack. It doesn't guarantee freedom
from heap allocation nor from type erasure. Sure, the overhead might
optimisable away in some cases, but there is no guarantee, also the same
exact optimisations are applicable to a Boost.coroutine-like design. In
fact the same analysis used to remove heap allocation can be used to remove
the side stack.
I do not see why we have to pay significant loss of expressiveness for one
guaranteed optimisation while still missing others equally important ones.
-- gpd
--
---
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/.
--001a11c333f258f61405224dabbb
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<p dir=3D"ltr"><br>
On 16 Oct 2015 5:26 p.m., "Nicol Bolas" <<a href=3D"mailto:jmc=
kesson@gmail.com">jmckesson@gmail.com</a>> wrote:<br>
..<br>
><br>
> The nice thing about P0057 is that it doesn't have very many new f=
eatures. It pretty much stops at function suspend/resume and internally-gen=
erated promise types. The return type of a coroutine is no different from a=
ny other type. The awaiter type, even the promise type are all types using =
the C++ rules for types.<br>
></p>
<p dir=3D"ltr">If the criterion is minimising the number of new language fe=
atures, we should just standardise Boost.coroutine. It is provably implemen=
table as a pure library, there is significant industry experience with it a=
nd it is significantly more expressive than any stackless proposal.</p>
<p dir=3D"ltr">The only advantage of P0057 is that its coroutines are guara=
nteed to need a single frame instead of a whole side stack. It doesn't =
guarantee freedom from heap allocation nor from type erasure. Sure, the ove=
rhead might optimisable away in some cases, but there is no guarantee, also=
the same exact optimisations are applicable to a Boost.coroutine-like desi=
gn. In fact the same analysis used to remove heap allocation can be used to=
remove the side stack.</p>
<p dir=3D"ltr">I do not see why we have to pay significant loss of expressi=
veness for one guaranteed optimisation while still missing others equally i=
mportant ones. </p>
<p dir=3D"ltr">-- gpd</p>
<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 />
--001a11c333f258f61405224dabbb--
.
Author: Gor Nishanov <gornishanov@gmail.com>
Date: Sat, 17 Oct 2015 08:08:07 -0700 (PDT)
Raw View
------=_Part_678_1660439287.1445094487678
Content-Type: multipart/alternative;
boundary="----=_Part_679_1799269438.1445094487678"
------=_Part_679_1799269438.1445094487678
Content-Type: text/plain; charset=UTF-8
On Saturday, October 17, 2015 at 6:31:25 AM UTC-7, Nicol Bolas wrote:
>
> The zero-overhead principle *is not a club!* Stop using a principle to
> bash things over the head.
>
How about negative-overhead principle. :-)
The CppCon 2015 coroutine talk is up with an appropriate title:
"Coroutines: a negative overhead abstraction"
https://www.youtube.com/watch?v=_fu0gx-xseY
--
---
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_679_1799269438.1445094487678
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><br>On Saturday, October 17, 2015 at 6:31:25 AM UTC-7, Nic=
ol Bolas wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0px 0px 0=
px 0.8ex; padding-left: 1ex; border-left-color: rgb(204, 204, 204); border-=
left-width: 1px; border-left-style: solid;"><div>The zero-overhead principl=
e <i>is not a club!</i> Stop using a principle to bash things over the head=
..<br></div></blockquote><div><br></div><div>How about negative-overhead pri=
nciple. :-)</div><div>The CppCon 2015 coroutine=C2=A0talk is up with an app=
ropriate title: "Coroutines: a negative overhead abstraction"</di=
v><div><br></div><div><a href=3D"https://www.youtube.com/watch?v=3D_fu0gx-x=
seY">https://www.youtube.com/watch?v=3D_fu0gx-xseY</a></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_679_1799269438.1445094487678--
------=_Part_678_1660439287.1445094487678--
.
Author: Nicol Bolas <jmckesson@gmail.com>
Date: Sat, 17 Oct 2015 08:08:52 -0700 (PDT)
Raw View
------=_Part_19_1073346561.1445094532903
Content-Type: multipart/alternative;
boundary="----=_Part_20_198429440.1445094532904"
------=_Part_20_198429440.1445094532904
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
On Saturday, October 17, 2015 at 7:35:35 AM UTC-4, Evgeny Panasyuk wrote:
>
> 16 =D0=BE=D0=BA=D1=82=D1=8F=D0=B1=D1=80=D1=8F 2015 =D0=B3., 19:26:18 UTC+=
3 Nicol Bolas :
>
Your proposal seems to require a lot of special-case handling at the type=
=20
>> level.
>>
>
> No, it does not require much of special-case handling.
> =20
>
>>
>> it is possible to return type with template inside. For instance
>>> struct generator
>>> {
>>> template<template<typename> class coroutine_value>
>>> struct apply { ... };
>>> };
>>>
>>>
>> OK, so... what does that do? Does `generator` store the coroutine?
>>
>
> It describes how to create result type.
>
Are you saying that if the function says `generator foo()`, then the=20
function *really* returns `generator::apply<InsertCompilerThingHere>`?
How exactly is this auto-magic transformation *not* "special-case=20
handling"? Because it looks pretty special-case to me.
Your proposal exposes *everyone* to the deep guts of working with a=20
>> coroutine. All just for some minor performance gain that in most situati=
ons=20
>> compilers can optimize out.
>>
>
> It is not a minor difference. One allocation and virtual/indirect calls=
=20
> for resumption is a huge overhead for things like generators.
>
Two words: citation needed.
See below for details:
And even when they can't, *you* can optimize them out with a decent=20
>> allocator.
>>
>
> First of all, I don't want to use custom allocators for simple things lik=
e=20
> generators. Second, even custom allocator is not zero-overhead - at least=
=20
> it must check size, because it is not known at compile time.
>
You are genuinely and seriously claiming that a conditional branch based on=
=20
two numbers constitutes "overhead". And this overhead is so incredibly=20
*burdensome* (despite only happening in the generator's initialization)=20
that any and all language changes to remove said overhead are completely=20
justified.
It's statements like this that are why I hate it when people start bringing=
=20
up the zero-overhead principle as some kind of religious doctrine.
Why does this overhead matter?
The performance of a generator that returns integers on a fixed range is=20
*irrelevant*. Nobody in their right mind is going to use generators for=20
that. We have *ranges* for that.
The purpose of a generator, in a *real application*, is to be able to have=
=20
a process take an arbitrary amount of time. You get a value from that=20
process, then you do something, then get another. Until the next value is=
=20
available, your process stops. That's the idea.
If the cost of generating that value is non-trivial, then the cost of the=
=20
virtual call to do said generation is negligible. If the cost of *using*=20
that value is non-trivial, then the cost of the virtual call is again=20
irrelevant.
Which means that, if either the creation or consumption of that data is at=
=20
all meaningful, if it requires anything more than the most basic few lines=
=20
of code, then it *does not matter* what the overhead of the call is. It=20
will be a rounding error in any performance analysis you would care to=20
perform on your code.
The overhead here is only "huge" if your generators *and* processing code=
=20
are so trivial that your code would be written better as a straight-up=20
range-based for loop. If you are actually doing meaningful work, then any=
=20
call overhead will be insignificant next to that.
This is why the zero-overhead principle is not some inviolate rule of=20
*doctrine* which justifies any and all language changes. It is a *principle=
*,=20
who's application must be weighed against all other applicable factors.=20
It's there to remind us not to needlessly add undue overhead. It is not=20
mean to be used to judge that any proposal is a priori wrong just because=
=20
there may be a lower overhead way to do it.
And P0057 does gain something from this overhead. It gains not having=20
automatic generation of return types, so functions still make sense. It=20
gains the ability to transfer control to someone other than the caller=20
(which your proposal does not), allowing the feature to be useful for *more=
=20
than* just "generators". And so forth.
Even if we accept that this is a good way to make a proposal... it's not a=
=20
>>>> *proposal* yet. It's just some ideas being batted around on a forum.=
=20
>>>> None of the various coroutine proposals do anything like what you've=
=20
>>>> suggested. Why should we halt or delay progress on P0057 because you=
=20
>>>> *think* you might be able to do better?
>>>>
>>>>
>>> If authors of P0057 still would insist on design with intrinsic overhea=
d=20
>>> and high burden on optimizers, then you are right - probably viable pat=
h is=20
>>> to make another proposal.
>>>
>>
>> Passive-aggressiveness does not prove your point.
>>
>
> Constantly calling things "nonsense" things you do not like - does not=20
> prove your point either.
>
Except that what I called "syntactic nonsense" really was syntactic=20
nonsense. You declared that `generator` was a template type in your=20
original code. And you returned it without providing a template argument.=
=20
That's not legal C++ code, so calling it "syntactic nonsense" is perfectly=
=20
valid.
Whereas the "high burden on optimizers" statement remains without=20
foundation.
>
--=20
---=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.
------=_Part_20_198429440.1445094532904
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
On Saturday, October 17, 2015 at 7:35:35 AM UTC-4, Evgeny Panasyuk wrote:<b=
lockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;borde=
r-left: 1px #ccc solid;padding-left: 1ex;"><div>16 =D0=BE=D0=BA=D1=82=D1=8F=
=D0=B1=D1=80=D1=8F 2015 =D0=B3., 19:26:18 UTC+3 Nicol Bolas :<br></div></bl=
ockquote><blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: =
0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr"><div=
></div><div></div><blockquote class=3D"gmail_quote" style=3D"margin:0;margi=
n-left:0.8ex;border-left:1px #ccc solid;padding-left:1ex"><div>Your proposa=
l seems to require a lot of special-case handling at the type level.<br></d=
iv></blockquote><div><br>No, it does not require much of special-case handl=
ing.<br>=C2=A0</div><blockquote class=3D"gmail_quote" style=3D"margin:0;mar=
gin-left:0.8ex;border-left:1px #ccc solid;padding-left:1ex"><div><br></div>=
<blockquote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;borde=
r-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><div>it is possibl=
e to return type with template inside. For instance<br><div style=3D"backgr=
ound-color:rgb(250,250,250);border-color:rgb(187,187,187);border-style:soli=
d;border-width:1px;word-wrap:break-word"><code><div><span style=3D"color:#0=
08">struct</span><span style=3D"color:#000"> generator<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">template</span><span style=3D"color:#660"><=
</span><code><span style=3D"color:#660"></span><span style=3D"color:#008"><=
span style=3D"color:#008">template</span></span><span style=3D"color:#080">=
<span style=3D"color:#080"><typename></span></span><span style=3D"col=
or:#000"><span style=3D"color:#000"> </span></span><span style=3D"color:#00=
8"><span style=3D"color:#008">class</span></span><span style=3D"color:#000"=
><span style=3D"color:#000"> coroutine_value</span></span><span style=3D"co=
lor:#660"></span></code><span style=3D"color:#660">></span><span style=
=3D"color:#000"><br>=C2=A0 =C2=A0 </span><span style=3D"color:#008">struct<=
/span><span style=3D"color:#000"> apply </span><span style=3D"color:#660">{=
</span><span style=3D"color:#000"> </span><span style=3D"color:#660">...</s=
pan><span style=3D"color:#000"> </span><span style=3D"color:#660">};</span>=
<span style=3D"color:#000"><br></span><span style=3D"color:#660">};</span><=
span style=3D"color:#000"><br></span></div></code></div><br></div></div></b=
lockquote><div><br>OK, so... what does that do? Does `generator` store the =
coroutine?</div></blockquote><div><br>It describes how to create result typ=
e.<br></div></div></blockquote><div><br>Are you saying that if the function=
says `generator foo()`, then the function <i>really</i> returns `generator=
::apply<InsertCompilerThingHere>`?<br><br>How exactly is this auto-ma=
gic transformation <i>not</i> "special-case handling"? Because it=
looks pretty special-case to me.<br><br></div><blockquote class=3D"gmail_q=
uote" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;pad=
ding-left: 1ex;"><div dir=3D"ltr"><div></div><blockquote class=3D"gmail_quo=
te" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-=
left:1ex"><div>Your proposal exposes <i>everyone</i> to the deep guts of wo=
rking with a coroutine. All just for some minor performance gain that in mo=
st situations compilers can optimize out.</div></blockquote><div><br>It is =
not a minor difference. One allocation and virtual/indirect calls for resum=
ption is a huge overhead for things like generators.</div></div></blockquot=
e><div><br>Two words: citation needed.<br><br>See below for details:<br><br=
></div><blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.=
8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr"><div> =
</div><blockquote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex=
;border-left:1px #ccc solid;padding-left:1ex"><div>And even when they can&#=
39;t, <i>you</i> can optimize them out with a decent allocator.<br></div></=
blockquote><div><br>First of all, I don't want to use custom allocators=
for simple things like generators. Second, even custom allocator is not ze=
ro-overhead - at least it must check size, because it is not known at compi=
le time.<br></div></div></blockquote><div><br>You are genuinely and serious=
ly claiming that a conditional branch based on two numbers constitutes &quo=
t;overhead". And this overhead is so incredibly <i>burdensome</i> (des=
pite only happening in the generator's initialization) that any and all=
language changes to remove said overhead are completely justified.<br><br>=
It's statements like this that are why I hate it when people start=20
bringing up the zero-overhead principle as some kind of religious=20
doctrine.<br><br>Why does this overhead matter?<br><br>The performance of a=
generator that returns integers on a fixed range is <i>irrelevant</i>. Nob=
ody in their right mind is going to use generators for that. We have <i>ran=
ges</i> for that.<br><br>The purpose of a generator, in a <i>real applicati=
on</i>, is to be able to have a process take an arbitrary amount of time. Y=
ou get a value from that process, then you do something, then get another. =
Until the next value is available, your process stops. That's the idea.=
<br><br>If the cost of generating that value is non-trivial, then the cost =
of the virtual call to do said generation is negligible. If the cost of <i>=
using</i> that value is non-trivial, then the cost of the virtual call is a=
gain irrelevant.<br><br>Which means that, if either the creation or consump=
tion of that data is at all meaningful, if it requires anything more than t=
he most basic few lines of code, then it <i>does not matter</i> what the ov=
erhead of the call is. It will be a rounding error in any performance analy=
sis you would care to perform on your code.<br><br>The overhead here is onl=
y "huge" if your generators <i>and</i> processing code are so tri=
vial that your code would be written better as a straight-up range-based fo=
r loop. If you are actually doing meaningful work, then any call overhead w=
ill be insignificant next to that.<br><br>This is why the zero-overhead pri=
nciple is not some inviolate rule of <i>doctrine</i> which justifies any an=
d all language changes. It is a <i>principle</i>, who's application mus=
t be weighed against all other applicable factors. It's there to remind=
us not to needlessly add undue overhead. It is not mean to be used to judg=
e that any proposal is a priori wrong just because there may be a lower ove=
rhead way to do it.<br><br>And P0057 does gain something from this overhead=
.. It gains not having automatic generation of return types, so functions st=
ill make sense. It gains the ability to transfer control to someone other t=
han the caller (which your proposal does not), allowing the feature to be u=
seful for <i>more than</i> just "generators". And so forth.<br><b=
r></div><blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0=
..8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr"><bloc=
kquote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-lef=
t:1px #ccc solid;padding-left:1ex"><blockquote class=3D"gmail_quote" style=
=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-left:1ex"=
><div dir=3D"ltr"><blockquote class=3D"gmail_quote" style=3D"margin:0;margi=
n-left:0.8ex;border-left:1px #ccc solid;padding-left:1ex"><div>Even if we a=
ccept that this is a good way to make a proposal... it's not a <i>propo=
sal</i> yet. It's just some ideas being batted around on a forum. None =
of the various coroutine proposals do anything like what you've suggest=
ed. Why should we halt or delay progress on P0057 because you <i>think</i> =
you might be able to do better?<br><br></div></blockquote><div><br>If autho=
rs of P0057 still would insist on design with intrinsic overhead and high b=
urden on optimizers, then you are right - probably viable path is to make a=
nother proposal.<br></div></div></blockquote><div><br>Passive-aggressivenes=
s does not prove your point.</div></blockquote><div><br>Constantly calling =
things "nonsense" things you do not like - does not prove your po=
int either.<br></div></div></blockquote><div><br>Except that what I called =
"syntactic nonsense" really was syntactic nonsense. You declared =
that `generator` was a template type in your original code. And you returne=
d it without providing a template argument. That's not legal C++ code, =
so calling it "syntactic nonsense" is perfectly valid.<br><br>Whe=
reas the "high burden on optimizers" statement remains without fo=
undation.<br></div><blockquote class=3D"gmail_quote" style=3D"margin: 0;mar=
gin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D=
"ltr"></div></blockquote>
<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_20_198429440.1445094532904--
------=_Part_19_1073346561.1445094532903--
.
Author: Nicol Bolas <jmckesson@gmail.com>
Date: Sat, 17 Oct 2015 08:19:52 -0700 (PDT)
Raw View
------=_Part_496_924985818.1445095192878
Content-Type: multipart/alternative;
boundary="----=_Part_497_2017594577.1445095192878"
------=_Part_497_2017594577.1445095192878
Content-Type: text/plain; charset=UTF-8
On Saturday, October 17, 2015 at 11:08:07 AM UTC-4, Gor Nishanov wrote:
>
>
> On Saturday, October 17, 2015 at 6:31:25 AM UTC-7, Nicol Bolas wrote:
>>
>> The zero-overhead principle *is not a club!* Stop using a principle to
>> bash things over the head.
>>
>
> How about negative-overhead principle. :-)
> The CppCon 2015 coroutine talk is up with an appropriate title:
> "Coroutines: a negative overhead abstraction"
>
> https://www.youtube.com/watch?v=_fu0gx-xseY
>
>
The problem with your "negative overhead" claim is that it is "negative"
only relative to a specific implementation of a specific problem. And that
particular problem isn't even a generator, which is the primary thing
people are talking about here.
So saying that it has negative overhead won't convince people when it has
positive overhead in *their* use cases.
I think the real problem is that P0057 is *not meant* to be used for
generators. It *can* be, but this functionality is essentially bolted on
after-the-fact. P0057 is primarily designed for making `.then`
continuations much more reasonable to use. *That* is the circumstance where
it has "negative overhead".
And I think this answers the question that I asked earlier, about how to
teach when to use P0114 and when to use P0057.
* P0057 is for .then-style continuations: when you want the expression
being waited on the schedule the continuation of the function.
* P0114 is for lightweight generators. The inlining requirements and so
forth are designed around that use case. Indeed, if you look at how P0114's
`await` function is implemented, it doesn't work like P0057. It doesn't
allow `.then` continuations; it doesn't allow the expression *itself* to
decide when and where to continue the function.
* P0099 is for heavyweight generators (and other things), where having a
real callstack is an undeniable *need* for the problem domain.
So I would say we really do need 3 kinds of coroutines: stackless
continuations, stackless generators, and stackful coroutines.
--
---
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_497_2017594577.1445095192878
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<br><br>On Saturday, October 17, 2015 at 11:08:07 AM UTC-4, Gor Nishanov wr=
ote:<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>On Sa=
turday, October 17, 2015 at 6:31:25 AM UTC-7, Nicol Bolas wrote:<blockquote=
class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;padding-left:1ex;b=
order-left-color:rgb(204,204,204);border-left-width:1px;border-left-style:s=
olid"><div>The zero-overhead principle <i>is not a club!</i> Stop using a p=
rinciple to bash things over the head.<br></div></blockquote><div><br></div=
><div>How about negative-overhead principle. :-)</div><div>The CppCon 2015 =
coroutine=C2=A0talk is up with an appropriate title: "Coroutines: a ne=
gative overhead abstraction"</div><div><br></div><div><a href=3D"https=
://www.youtube.com/watch?v=3D_fu0gx-xseY" target=3D"_blank" rel=3D"nofollow=
" onmousedown=3D"this.href=3D'https://www.youtube.com/watch?v\75_fu0gx-=
xseY';return true;" onclick=3D"this.href=3D'https://www.youtube.com=
/watch?v\75_fu0gx-xseY';return true;">https://www.youtube.com/watch?<wb=
r>v=3D_fu0gx-xseY</a></div><div><br></div></div></blockquote><div><br>The p=
roblem with your "negative overhead" claim is that it is "ne=
gative" only relative to a specific implementation of a specific probl=
em. And that particular problem isn't even a generator, which is the pr=
imary thing people are talking about here.<br><br>So saying that it has neg=
ative overhead won't convince people when it has positive overhead in <=
i>their</i> use cases.<br><br>I think the real problem is that P0057 is <i>=
not meant</i> to be used for generators. It <i>can</i> be, but this functio=
nality is essentially bolted on after-the-fact. P0057 is primarily designed=
for making `.then` continuations much more reasonable to use. <i>That</i> =
is the circumstance where it has "negative overhead".<br><br>And =
I think this answers the question that I asked earlier, about how to teach =
when to use P0114 and when to use P0057.<br><br>* P0057 is for .then-style =
continuations: when you want the expression being waited on the schedule th=
e continuation of the function.<br><br>* P0114 is for lightweight generator=
s. The inlining requirements and so forth are designed around that use case=
.. Indeed, if you look at how P0114's `await` function is implemented, i=
t doesn't work like P0057. It doesn't allow `.then` continuations; =
it doesn't allow the expression <i>itself</i> to decide when and where =
to continue the function.<br><br>* P0099 is for heavyweight generators (and=
other things), where having a real callstack is an undeniable <i>need</i> =
for the problem domain.<br><br>So I would say we really do need 3 kinds of =
coroutines: stackless continuations, stackless generators, and stackful cor=
outines.<br></div>
<p></p>
-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />
------=_Part_497_2017594577.1445095192878--
------=_Part_496_924985818.1445095192878--
.
Author: Gor Nishanov <gornishanov@gmail.com>
Date: Sat, 17 Oct 2015 08:41:18 -0700 (PDT)
Raw View
------=_Part_705_210623653.1445096478452
Content-Type: multipart/alternative;
boundary="----=_Part_706_802847780.1445096478453"
------=_Part_706_802847780.1445096478453
Content-Type: text/plain; charset=UTF-8
On Saturday, October 17, 2015 at 8:19:53 AM UTC-7, Nicol Bolas wrote:
I think the real problem is that P0057 is *not meant* to be used for
> generators. It *can* be, but this functionality is essentially bolted on
> after-the-fact.
>
Indeed, for P0057 the staring point was Haskell do-notation and its C# less
generic variant 'await'. Starting point for P0114 was a generator.
Nevertheless, P0057 generators are at least as efficient as P0114. If you
have a counter-example, please provide one.
* P0114 is for lightweight generators.
>
Do you have an example where P0114 will result in more efficient generator
than P0057?
BTW, In Kona, we may get a wording to make heap elision mandatory for some
common scenarios, thus, you will be guaranteed that efficiency, not just
hope for it.
* P0099 is for heavyweight generators (and other things), where having a
> real callstack is an undeniable *need* for the problem domain.
>
I am a supporter of P0099 and encouraged Oliver and Nat to work on getting
fibers in the library when we had discussions on it a year ago.
There are definitely cases where using fibers built on top of P0099 is more
appropriate than using coroutines of P0057.
--
---
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_706_802847780.1445096478453
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">On Saturday, October 17, 2015 at 8:19:53 AM UTC-7, Nicol B=
olas wrote:<div><br><blockquote class=3D"gmail_quote" style=3D"margin: 0;ma=
rgin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div>I thi=
nk the real problem is that P0057 is <i>not meant</i> to be used for genera=
tors. It <i>can</i> be, but this functionality is essentially bolted on aft=
er-the-fact. </div></blockquote><div><br></div><div>Indeed, for P0057 the s=
taring point was Haskell do-notation and its C# less generic variant 'a=
wait'. Starting point for P0114 was a generator.</div><div>Nevertheless=
, P0057 generators are at least as efficient as P0114. If you have a counte=
r-example, please provide one.</div><div><br></div><blockquote class=3D"gma=
il_quote" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid=
;padding-left: 1ex;"><div>* P0114 is for lightweight generators. </div></bl=
ockquote><div><br></div><div>Do you have an example where P0114 will result=
in more efficient generator than P0057?</div><div>BTW, In Kona, we may get=
a wording to make heap elision mandatory for some common scenarios, thus, =
you will be guaranteed that efficiency, not just hope for it.</div><div><br=
></div><blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.=
8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div>* P0099 is for hea=
vyweight generators (and other things), where having a real callstack is an=
undeniable <i>need</i> for the problem domain.<br></div></blockquote><div>=
<br></div><div>I am a supporter of P0099 and encouraged Oliver and Nat to w=
ork on getting fibers in the library when we had discussions on it a year a=
go.</div><div>There are definitely cases where using fibers built on top of=
P0099 is more appropriate than using coroutines of P0057.</div></div></div=
>
<p></p>
-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />
------=_Part_706_802847780.1445096478453--
------=_Part_705_210623653.1445096478452--
.
Author: Nicol Bolas <jmckesson@gmail.com>
Date: Sat, 17 Oct 2015 08:41:27 -0700 (PDT)
Raw View
------=_Part_277_1478882357.1445096487785
Content-Type: multipart/alternative;
boundary="----=_Part_278_1567546115.1445096487785"
------=_Part_278_1567546115.1445096487785
Content-Type: text/plain; charset=UTF-8
On Saturday, October 17, 2015 at 10:24:29 AM UTC-4, Giovanni Piero Deretta
wrote:
>
>
> On 16 Oct 2015 5:26 p.m., "Nicol Bolas" <jmck...@gmail.com <javascript:>>
> wrote:
> .
> >
> > The nice thing about P0057 is that it doesn't have very many new
> features. It pretty much stops at function suspend/resume and
> internally-generated promise types. The return type of a coroutine is no
> different from any other type. The awaiter type, even the promise type are
> all types using the C++ rules for types.
> >
>
> If the criterion is minimising the number of new language features, we
> should just standardise Boost.coroutine. It is provably implementable as a
> pure library, there is significant industry experience with it and it is
> significantly more expressive than any stackless proposal.
>
I think you mean Boost.Context. Boost.Coroutine is just an add-on library
for "asymmetric" coroutines, built ontop of Boost.Context. And we already
have Boost.Context proposed in P0099. Though adding Boost.Coroutines onto
it wouldn't go amiss.
In any case, my point was that P0057 is able to provide significant and
useful features *without* breaking the language substantially. So
prospective "improvements" on it should be judged accordingly.
The only advantage of P0057 is that its coroutines are guaranteed to need a
> single frame instead of a whole side stack. It doesn't guarantee freedom
> from heap allocation nor from type erasure. Sure, the overhead might
> optimisable away in some cases, but there is no guarantee, also the same
> exact optimisations are applicable to a Boost.coroutine-like design.
>
The cost of a Boost.Context switch is *massive* compared to the cost of a
type-erased function call. The cost of allocating even a small
execution_context is massive compared to the small stacks of P0057.
I hope you are not seriously claiming that all costs greater than zero are
equal. Things like this are a good example of why principles should not be
treated as bludgeons.
In fact the same analysis used to remove heap allocation can be used to
> remove the side stack.
>
No, it can't.
In P0057, there are exactly two places where you can get access to the
coroutine_handle: from within `await_suspend` called via an explicit
`await` expression and from within the promise object itself. The
interaction between the promise and the return type allow the return type
to store the handle. And thus, the compiler (assuming all of these are
inlined) can track exactly where the coroutine_handle ends up. It knows
where it gets resumed and it can see if the `generator` return object is
moved after its final destination.
`execution_context` is much broader in scope. A context can be exited from
any function in the call stack. Equally importantly, this does not
necessarily resume the *previous* context; it can exit to any other context
in existence. Any function can access the current context and stick it into
any variable they wish.
So there is no way for the optimizer to know that a particular
`execution_context` is local to a function. Without that locality, nothing
can be optimized away.
Again, there's a reason why P0114 requires full inlining of the resumable
function call graph.
I do not see why we have to pay significant loss of expressiveness for one
> guaranteed optimisation while still missing others equally important ones.
>
I'd guess that P0099 will find its way into the standard. If you truly
believe that P0057 and P0099 are equally performance unfriendly, then feel
free to use `execution_context` rather than P0057.
The rest of us will be using it for its intended purpose: stackless
continuations.
--
---
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_278_1567546115.1445096487785
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
On Saturday, October 17, 2015 at 10:24:29 AM UTC-4, Giovanni Piero Deretta =
wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8=
ex;border-left: 1px #ccc solid;padding-left: 1ex;"><p dir=3D"ltr"><br>
On 16 Oct 2015 5:26 p.m., "Nicol Bolas" <<a href=3D"javascript=
:" target=3D"_blank" gdf-obfuscated-mailto=3D"nRp7FTuEDwAJ" rel=3D"nofollow=
" onmousedown=3D"this.href=3D'javascript:';return true;" onclick=3D=
"this.href=3D'javascript:';return true;">jmck...@gmail.com</a>> =
wrote:<br>
..<br>
><br>
> The nice thing about P0057 is that it doesn't have very many new f=
eatures. It pretty much stops at function suspend/resume and internally-gen=
erated promise types. The return type of a coroutine is no different from a=
ny other type. The awaiter type, even the promise type are all types using =
the C++ rules for types.<br>
></p>
<p dir=3D"ltr">If the criterion is minimising the number of new language fe=
atures, we should just standardise Boost.coroutine. It is provably implemen=
table as a pure library, there is significant industry experience with it a=
nd it is significantly more expressive than any stackless proposal.</p></bl=
ockquote><div><br>I think you mean Boost.Context. Boost.Coroutine is just a=
n add-on library for "asymmetric" coroutines, built ontop of Boos=
t.Context. And we already have Boost.Context proposed in P0099. Though addi=
ng Boost.Coroutines onto it wouldn't go amiss.<br><br>In any case, my p=
oint was that P0057 is able to provide significant and useful features <i>w=
ithout</i> breaking the language substantially. So prospective "improv=
ements" on it should be judged accordingly.<br><br></div><blockquote c=
lass=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px=
#ccc solid;padding-left: 1ex;">
<p dir=3D"ltr">The only advantage of P0057 is that its coroutines are guara=
nteed to need a single frame instead of a whole side stack. It doesn't =
guarantee freedom from heap allocation nor from type erasure. Sure, the ove=
rhead might optimisable away in some cases, but there is no guarantee, also=
the same exact optimisations are applicable to a Boost.coroutine-like desi=
gn.</p></blockquote><div><br>The cost of a Boost.Context switch is <i>massi=
ve</i> compared to the cost of a type-erased function call. The cost of all=
ocating even a small execution_context is massive compared to the small sta=
cks of P0057.<br><br>I hope you are not seriously claiming that all costs g=
reater than zero are equal. Things like this are a good example of why prin=
ciples should not be treated as bludgeons.<br><br></div><blockquote class=
=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #cc=
c solid;padding-left: 1ex;">
<p dir=3D"ltr"> In fact the same analysis used to remove heap allocation ca=
n be used to remove the side stack.</p></blockquote><div><br>No, it can'=
;t.<br><br>In P0057, there are exactly two places where you can get access =
to the coroutine_handle: from within `await_suspend` called via an explicit=
`await` expression and from within the promise object itself. The interact=
ion between the promise and the return type allow the return type to store =
the handle. And thus, the compiler (assuming all of these are inlined) can =
track exactly where the coroutine_handle ends up. It knows where it gets re=
sumed and it can see if the `generator` return object is moved after its fi=
nal destination.<br><br>`execution_context` is much broader in scope. A con=
text can be exited from any function in the call stack. Equally importantly=
, this does not necessarily resume the <i>previous</i> context; it can exit=
to any other context in existence. Any function can access the current con=
text and stick it into any variable they wish.<br><br>So there is no way fo=
r the optimizer to know that a particular `execution_context` is local to a=
function. Without that locality, nothing can be optimized away.<br><br>Aga=
in, there's a reason why P0114 requires full inlining of the resumable =
function call graph.<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">I do not see why we have to pay significant loss of ex=
pressiveness for one guaranteed optimisation while still missing others equ=
ally important ones.</p></blockquote><div><br>I'd guess that P0099 will=
find its way into the standard. If you truly believe that P0057 and P0099 =
are equally performance unfriendly, then feel free to use `execution_contex=
t` rather than P0057.<br><br>The rest of us will be using it for its intend=
ed purpose: stackless continuations.<br></div>
<p></p>
-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />
------=_Part_278_1567546115.1445096487785--
------=_Part_277_1478882357.1445096487785--
.
Author: Evgeny Panasyuk <evgeny.panasyuk@gmail.com>
Date: Sat, 17 Oct 2015 08:43:31 -0700 (PDT)
Raw View
------=_Part_544_1396875066.1445096612086
Content-Type: multipart/alternative;
boundary="----=_Part_545_2060334880.1445096612093"
------=_Part_545_2060334880.1445096612093
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
17 October 2015 =D0=B3., 16:31:25 UTC+3 Nicol Bolas:
>
>
> However, it is *necessary* for that process. That alone may not be=20
> sufficient, but it is necessary.
>
Yes, of course.=20
>
> A necessary step that your idea has not taken. No implementation, no=20
> standards wording, not even a fully-fleshed out design. Your idea isn't=
=20
> anywhere near as well-formed as P0114.
>
I agree that it should be more formally described.
=20
>
> P0057 is the result of numerous revisions of an idea, across several=20
> years, as well as with lots of implementation experience. Why should we=
=20
> impair such a design just because you think that, one day, someone *might=
*=20
> propose a better one?=20
>
Yes, better design is possible.
But that is not the only issue - if there will be big overhead, it would=20
have limited usability. As Giovanni mentioned above, if performance is not=
=20
an issue - stackful coroutines would cover most of use cases of slow=20
stackless coroutines.
=20
>
> Proposed feature must also fit main design goals of language.
>> I am showing major flow in existing proposal. Do you think it should not=
=20
>> be discussed?
>>
>
> Discussed? Sure.
>
> Should that discussion, merely by *existing*, justify torpedoing any and=
=20
> all process on that spec, or automatically force it to change? No.
>
Of course it would not automagically change something. But people should=20
know about flaws, and should know about possibility to have better=20
alternative. This is just a first step.
=20
> The zero-overhead principle *is not a club!* Stop using a principle to=20
> bash things over the head.
>
Constantly telling to opponent to stop doing something does not increase=20
level of your argumentation.=20
> It can do that because P0114 requires that all resumable functions are=20
> inline. *Your* idea requires all resumable functions are inline.
>
>
My idea is (at least) to add concrete coroutine types in P0057. If someone=
=20
would use type-erasure - there is no need for inline functions.=20
=20
>
> That is, quite frankly, a terrible way to specify that a function is an=
=20
> unboxed coroutine. A special tag type in the function signature?
>
> I'd much rather have a keyword. Especially since this fundamentally=20
> changes how the function behaves, that's generally the sort of thing a=20
> keyword would do, not a type in the signature.
>
You said that you do not want to change mechanics of function signature.=20
Using tag type helps to achieve this. Forward declaration could look just=
=20
as normal function:
auto numbers(int x, concrete_generator_tag =3D {});
Personally, I am OK with both possibilities - tags or keywords. But if goal=
=20
is to make it look like a function from external point of view - then we=20
should use tags.
=20
>
> And no, your approach is not "closer" to P0057. It's farther. The return=
=20
> type is a coroutine now, not a future, or generator, or other user-define=
d=20
> type. It's an actual coroutine.
>
No, I mean that actual return type would be specified by specialization of=
=20
coroutine_traits.
For instance return type could be some class with coroutine inside as a=20
field-member. Or maybe coroutine_handle. Or it is even possible that it=20
would not have any handle to coroutine (just an extreme case - coroutine=20
can be stored in global "singleton" var).
=20
>
> That's not how P0057 works. Indeed, that's not what P0057 is *for*.=20
> Remember the general idea of await in P0057: it halts the function, but i=
t=20
> also *explicitly* allows the transfer of control of the function to the *=
await=20
> expression*. And thus, control is not necessarily transferred to the=20
> return value.
>
Yes, of course, it does not have to.=20
Oh sure, you use different keywords. But the behavior of those keywords is=
=20
> basically the behavior of the functions P0114 implements. Basically, P011=
4=20
> is what you want, even if you would prefer that the form appeared more li=
ke=20
> P0057.
>
Personally I prefer P0114 - it is more powerful, gives less overhead, and=
=20
shifts from concrete await or yield features towards more general language=
=20
feature.
But if P0057 is much more likely to get into ISO, then I would like to=20
remove discussed overhead.
=20
>
> I think one thing this conversation has proven is that the most=20
> fundamental differences between P0057 and P0114 are:
>
> 1) The use of type-erased coroutines. If you don't type-erase your=20
> coroutine, you *will* end up with all the limitations of P0114.
>
P0114 allow to build type-erased coroutines on top of it. But P0057 does=20
not allow to get concrete coroutines.
=20
>
> 2) The ability to transfer control internally rather than externally.=20
> P0057 is all about allowing the await expression to decide when the=20
> coroutine gets to be continued. P0114 doesn't really allow that; even its=
=20
> prospective `await` function doesn't really implement await the way P0057=
=20
> does. In P0114, and in your example, if you want the awaiting call to be=
=20
> resumed in some other thread, it's up to the *caller* to decide this, not=
=20
> the implementation of the resumable function.
>
No, coroutine itself can decide where it would go, returning void to caller=
..
=20
> While mandatory type-erasure can be tolerated in cases like async I/O, bu=
t=20
>> for generators it adds huge overhead, which can't be tolerated for C++.
>>
>
> Where is your evidence for this "huge overhead" for generators?
>
Again, I should prepare detailed report (in order for it to have real=20
effect).
If you want to see some results now - no problem, I can post them here.
=20
> You ignore the fact that allocation can be elided.
>
I do not ignore it. I already described cases where it can't be elided in=
=20
principle.
=20
> You ignore the fact that you can overload the allocation manually, thus=
=20
> allowing you to use preallocated chunks, stack space, or whatever else to=
=20
> make the allocation take virtually no time.
>
I do not ignore it. I already mentioned this several times.
--=20
---=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.
------=_Part_545_2060334880.1445096612093
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">17 October 2015 =D0=B3., 16:31:25 UTC+3 Nicol Bolas:<block=
quote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-le=
ft: 1px #ccc solid;padding-left: 1ex;"><br><div>However, it is <i>necessary=
</i> for that process. That alone may not be sufficient, but it is necessar=
y.<br></div></blockquote><div><br>Yes, of course. <br></div><blockquote cla=
ss=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #=
ccc solid;padding-left: 1ex;"><div><br>A necessary step that your idea has =
not taken. No implementation, no standards wording, not even a fully-fleshe=
d out design. Your idea isn't anywhere near as well-formed as P0114.<br=
></div></blockquote><div><br>I agree that it should be more formally descri=
bed.<br>=C2=A0</div><blockquote class=3D"gmail_quote" style=3D"margin: 0;ma=
rgin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div><br>P=
0057 is the result of numerous revisions of an idea, across several years, =
as well as with lots of implementation experience. Why should we impair suc=
h a design just because you think that, one day, someone <i>might</i> propo=
se a better one? <br></div></blockquote><div><br>Yes, better design is poss=
ible.<br>But that is not the only issue - if there will be big overhead, it=
would have limited usability. As Giovanni mentioned above, if performance =
is not an issue - stackful coroutines would cover most of use cases of slow=
stackless coroutines.<br>=C2=A0</div><blockquote class=3D"gmail_quote" sty=
le=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left=
: 1ex;"><div><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>Proposed feature must also fit main design goals of language.<br>=
I am showing major flow in existing proposal. Do you think it should not be=
discussed?<br></div></div></blockquote><div><br>Discussed? Sure.<br><br>Sh=
ould that discussion, merely by <i>existing</i>, justify torpedoing any and=
all process on that spec, or automatically force it to change? No.<br></di=
v></blockquote><div><br>Of course it would not automagically change somethi=
ng. But people should know about flaws, and should know about possibility t=
o have better alternative. This is just a first step.<br>=C2=A0</div><block=
quote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-le=
ft: 1px #ccc solid;padding-left: 1ex;"><div>The zero-overhead principle <i>=
is not a club!</i> Stop using a principle to bash things over the head.<br>=
</div></blockquote><div><br>Constantly telling to opponent to stop doing so=
mething does not increase level of your argumentation. <br><br></div><block=
quote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-le=
ft: 1px #ccc solid;padding-left: 1ex;"><div><br>It can do that because P011=
4 requires that all resumable functions are inline. <i>Your</i> idea requir=
es all resumable functions are inline.<br><br></div></blockquote><div><br>M=
y idea is (at least) to add concrete coroutine types in P0057. If someone w=
ould use type-erasure - there is no need for inline functions. <br>=C2=A0<b=
r></div><blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0=
..8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div></div><br><div>Th=
at is, quite frankly, a terrible way to specify that a function is an unbox=
ed coroutine. A special tag type in the function signature?<br></div></bloc=
kquote><blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.=
8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div><br>I'd much r=
ather have a keyword. Especially since this fundamentally changes how the f=
unction behaves, that's generally the sort of thing a keyword would do,=
not a type in the signature.<br></div></blockquote><div><br>You said that =
you do not want to change mechanics of function signature. Using tag type h=
elps to achieve this. Forward declaration could look just as normal functio=
n:<br><div class=3D"prettyprint" style=3D"background-color: rgb(250, 250, 2=
50); border-color: rgb(187, 187, 187); border-style: solid; border-width: 1=
px; word-wrap: break-word;"><code class=3D"prettyprint"><div class=3D"subpr=
ettyprint"><span style=3D"color: #008;" class=3D"styled-by-prettify">auto</=
span><span style=3D"color: #000;" class=3D"styled-by-prettify"> numbers</sp=
an><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"> x</span><span style=3D"colo=
r: #660;" class=3D"styled-by-prettify">,</span><span style=3D"color: #000;"=
class=3D"styled-by-prettify"> concrete_generator_tag </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;" c=
lass=3D"styled-by-prettify">{});</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"><br></span></div></code></div><br>Personally, I am =
OK with both possibilities - tags or keywords. But if goal is to make it lo=
ok like a function from external point of view - then we should use tags.<b=
r>=C2=A0</div><blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-l=
eft: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div><br>And no,=
your approach is not "closer" to P0057. It's farther. The re=
turn type is a coroutine now, not a future, or generator, or other user-def=
ined type. It's an actual coroutine.<br></div></blockquote><div><br>No,=
I mean that actual return type would be specified by specialization of cor=
outine_traits.<br>For instance return type could be some class with corouti=
ne inside as a field-member. Or maybe coroutine_handle. Or it is even possi=
ble that it would not have any handle to coroutine (just an extreme case - =
coroutine can be stored in global "singleton" var).<br>=C2=A0</di=
v><blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;b=
order-left: 1px #ccc solid;padding-left: 1ex;"><div><br>That's not how =
P0057 works. Indeed, that's not what P0057 is <i>for</i>. Remember the =
general idea of await in P0057: it halts the function, but it also <i>expli=
citly</i> allows the transfer of control of the function to the <i>await ex=
pression</i>. And thus, control is not necessarily transferred to the retur=
n value.<br></div></blockquote><div><br>Yes, of course, it does not have to=
.. <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>Oh sure, =
you use different keywords. But the behavior of those keywords is basically=
the behavior of the functions P0114 implements. Basically, P0114 is what y=
ou want, even if you would prefer that the form appeared more like P0057.<b=
r></div></blockquote><div><br>Personally I prefer P0114 - it is more powerf=
ul, gives less overhead, and shifts from concrete await or yield features t=
owards more general language feature.<br>But if P0057 is much more likely t=
o get into ISO, then I would like to remove discussed overhead.<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;"><div><br>I think one thing=
this conversation has proven is that the most fundamental differences betw=
een P0057 and P0114 are:<br><br>1) The use of type-erased coroutines. If yo=
u don't type-erase your coroutine, you <i>will</i> end up with all the =
limitations of P0114.<br></div></blockquote><div><br>P0114 allow to build t=
ype-erased coroutines on top of it. But P0057 does not allow to get concret=
e coroutines.<br>=C2=A0</div><blockquote class=3D"gmail_quote" style=3D"mar=
gin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><=
div><br>2) The ability to transfer control internally rather than externall=
y. P0057 is all about allowing the await expression to decide when the coro=
utine gets to be continued. P0114 doesn't really allow that; even its p=
rospective `await` function doesn't really implement await the way P005=
7 does. In P0114, and in your example, if you want the awaiting call to be =
resumed in some other thread, it's up to the <i>caller</i> to decide th=
is, not the implementation of the resumable function.<br></div></blockquote=
><div><br>No, coroutine itself can decide where it would go, returning void=
to caller.<br>=C2=A0</div><blockquote class=3D"gmail_quote" style=3D"margi=
n: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><bl=
ockquote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-l=
eft:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><div>While mandatory =
type-erasure can be tolerated in cases like async I/O, but for generators i=
t adds huge overhead, which can't be tolerated for C++.<br></div></div>=
</blockquote><div><br>Where is your evidence for this "huge overhead&q=
uot; for generators?</div></blockquote><div><br>Again, I should prepare det=
ailed report (in order for it to have real effect).<br>If you want to see s=
ome results now - no problem, I can post them here.<br>=C2=A0</div><blockqu=
ote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-left=
: 1px #ccc solid;padding-left: 1ex;"><div>You ignore the fact that allocati=
on can be elided.</div></blockquote><div><br>I do not ignore it. I already =
described cases where it can't be elided in principle.<br>=C2=A0</div><=
blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;bord=
er-left: 1px #ccc solid;padding-left: 1ex;"><div>You ignore the fact that y=
ou can overload the allocation manually, thus allowing you to use prealloca=
ted chunks, stack space, or whatever else to make the allocation take virtu=
ally no time.<br></div></blockquote><div><br>I do not ignore it. I already =
mentioned this several times.<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_545_2060334880.1445096612093--
------=_Part_544_1396875066.1445096612086--
.
Author: Evgeny Panasyuk <evgeny.panasyuk@gmail.com>
Date: Sat, 17 Oct 2015 19:12:48 +0300
Raw View
17.10.2015 18:19, Nicol Bolas:
>
> How about negative-overhead principle. :-)
> The CppCon 2015 coroutine talk is up with an appropriate title:
> "Coroutines: a negative overhead abstraction"
>
> https://www.youtube.com/watch?v=_fu0gx-xseY
> <https://www.youtube.com/watch?v=_fu0gx-xseY>
>
>
> The problem with your "negative overhead" claim is that it is "negative"
> only relative to a specific implementation of a specific problem. And
> that particular problem isn't even a generator, which is the primary
> thing people are talking about here.
Fully agree.
>
> So I would say we really do need 3 kinds of coroutines: stackless
> continuations, stackless generators, and stackful coroutines.
I think both stackless use cases (await/yield/etc) can be covered by one
language feature, without inconveniences - we do not need to bloat
language specification with an extra special-case variation.
And we do not need to force optimizers to implement special
optimizations which are applicable just for one language feature in
order to remove it's overhead, and even not in all cases.
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.
.
Author: Nicol Bolas <jmckesson@gmail.com>
Date: Sat, 17 Oct 2015 09:30:02 -0700 (PDT)
Raw View
------=_Part_209_1383834107.1445099402318
Content-Type: multipart/alternative;
boundary="----=_Part_210_1037908294.1445099402318"
------=_Part_210_1037908294.1445099402318
Content-Type: text/plain; charset=UTF-8
On Saturday, October 17, 2015 at 12:13:01 PM UTC-4, Evgeny Panasyuk wrote:
>
> 17.10.2015 18:19, Nicol Bolas:
> >
> > How about negative-overhead principle. :-)
> > The CppCon 2015 coroutine talk is up with an appropriate title:
> > "Coroutines: a negative overhead abstraction"
> >
> > https://www.youtube.com/watch?v=_fu0gx-xseY
> > <https://www.youtube.com/watch?v=_fu0gx-xseY>
> >
> >
> > The problem with your "negative overhead" claim is that it is "negative"
> > only relative to a specific implementation of a specific problem. And
> > that particular problem isn't even a generator, which is the primary
> > thing people are talking about here.
>
> Fully agree.
>
> >
> > So I would say we really do need 3 kinds of coroutines: stackless
> > continuations, stackless generators, and stackful coroutines.
>
> I think both stackless use cases (await/yield/etc) can be covered by one
> language feature, without inconveniences - we do not need to bloat
> language specification with an extra special-case variation.
> And we do not need to force optimizers to implement special
> optimizations which are applicable just for one language feature in
> order to remove it's overhead, and even not in all cases.
>
I have yet to see a stackless proposal that provides all of these:
* Ease of use equivalent to or better than P0057.
* Equal functionality to P0057 (P0114 makes .then continuations difficult).
* Syntax does not favor typed or type-erasure. That is, you pick one based
solely on your needs, not on how difficult it is to use (P0114 fails here,
as type-erasure requires lots of explicit user effort).
* Syntax does not make functions behave visibly differently. If a function
signature says that it returns X, then it ought to return X, not even some
type implicitly convertible to X.
Until you can get all of these in one proposal, I must remain skeptical of
your claim.
--
---
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_210_1037908294.1445099402318
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<br><br>On Saturday, October 17, 2015 at 12:13:01 PM UTC-4, Evgeny Panasyuk=
wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.=
8ex;border-left: 1px #ccc solid;padding-left: 1ex;">17.10.2015 18:19, Nicol=
Bolas:
<br>>
<br>> =C2=A0 =C2=A0 How about negative-overhead principle. :-)
<br>> =C2=A0 =C2=A0 The CppCon 2015 coroutine talk is up with an appropr=
iate title:
<br>> =C2=A0 =C2=A0 "Coroutines: a negative overhead abstraction&qu=
ot;
<br>>
<br>> =C2=A0 =C2=A0 <a href=3D"https://www.youtube.com/watch?v=3D_fu0gx-=
xseY" target=3D"_blank" rel=3D"nofollow" onmousedown=3D"this.href=3D'ht=
tps://www.youtube.com/watch?v\75_fu0gx-xseY';return true;" onclick=3D"t=
his.href=3D'https://www.youtube.com/watch?v\75_fu0gx-xseY';return t=
rue;">https://www.youtube.com/watch?<wbr>v=3D_fu0gx-xseY</a>
<br>> =C2=A0 =C2=A0 <<a href=3D"https://www.youtube.com/watch?v=3D_fu=
0gx-xseY" target=3D"_blank" rel=3D"nofollow" onmousedown=3D"this.href=3D=
9;https://www.youtube.com/watch?v\75_fu0gx-xseY';return true;" onclick=
=3D"this.href=3D'https://www.youtube.com/watch?v\75_fu0gx-xseY';ret=
urn true;">https://www.youtube.com/<wbr>watch?v=3D_fu0gx-xseY</a>>
<br>>
<br>>
<br>> The problem with your "negative overhead" claim is that =
it is "negative"
<br>> only relative to a specific implementation of a specific problem. =
And
<br>> that particular problem isn't even a generator, which is the p=
rimary
<br>> thing people are talking about here.
<br>
<br>Fully agree.
<br>
<br>>
<br>> So I would say we really do need 3 kinds of coroutines: stackless
<br>> continuations, stackless generators, and stackful coroutines.
<br>
<br>I think both stackless use cases (await/yield/etc) can be covered by on=
e=20
<br>language feature, without inconveniences - we do not need to bloat=20
<br>language specification with an extra special-case variation.
<br>And we do not need to force optimizers to implement special=20
<br>optimizations which are applicable just for one language feature in=20
<br>order to remove it's overhead, and even not in all cases.
<br></blockquote><div><br>I have yet to see a stackless proposal that provi=
des all of these:<br><br>* Ease of use equivalent to or better than P0057.<=
br><br>* Equal functionality to P0057 (P0114 makes .then continuations diff=
icult).<br><br>* Syntax does not favor typed or type-erasure. That is, you =
pick one based solely on your needs, not on how difficult it is to use (P01=
14 fails here, as type-erasure requires lots of explicit user effort).<br><=
br>* Syntax does not make functions behave visibly differently. If a functi=
on signature says that it returns X, then it ought to return X, not even so=
me type implicitly convertible to X.<br><br>Until you can get all of these =
in one proposal, I must remain skeptical of your claim.<br></div>
<p></p>
-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />
------=_Part_210_1037908294.1445099402318--
------=_Part_209_1383834107.1445099402318--
.
Author: Nicol Bolas <jmckesson@gmail.com>
Date: Sat, 17 Oct 2015 10:07:11 -0700 (PDT)
Raw View
------=_Part_572_292874999.1445101631790
Content-Type: multipart/alternative;
boundary="----=_Part_573_1939144022.1445101631790"
------=_Part_573_1939144022.1445101631790
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
On Saturday, October 17, 2015 at 11:43:32 AM UTC-4, Evgeny Panasyuk wrote:
>
> 17 October 2015 =D0=B3., 16:31:25 UTC+3 Nicol Bolas:
>
>> P0057 is the result of numerous revisions of an idea, across several=20
>> years, as well as with lots of implementation experience. Why should we=
=20
>> impair such a design just because you think that, one day, someone=20
>> *might* propose a better one?=20
>>
>
> Yes, better design is possible.
> But that is not the only issue - if there will be big overhead, it would=
=20
> have limited usability. As Giovanni mentioned above, if performance is no=
t=20
> an issue - stackful coroutines would cover most of use cases of slow=20
> stackless coroutines.
>
I don't understand you rhetoric here. On the one hand, you claim that there=
=20
is "big overhead" and that P0057 are "slow stackless coroutines." Yet=20
later, you specifically state that "Again, I should prepare detailed report=
=20
(in order for it to have real effect)". Which means that you, as of yet,=20
have no actual evidence that overhead is "big" or that P0057 is "slow".
You have repeatedly made the positive claims that P0057 is "slow", that it=
=20
has "big overhead". It's time to put up or shut up: present your evidence=
=20
for these claims, or we should consider your statements to be at best=20
conjecture.
Note: "evidence" means actual evidence. Not "well, if you do this, the=20
optimizer might not work" or whatever. Actual, good-faith evidence.
There is apparently an implementation of P0114. And there is an=20
implementation of await. Use them to provide us with evidence of your=20
claims.
The zero-overhead principle *is not a club!* Stop using a principle to bash=
=20
>> things over the head.
>>
>
> Constantly telling to opponent to stop doing something does not increase=
=20
> level of your argumentation.
>
No, but it does tell you that you're not convincing anyone by continuing to=
=20
use the principle as a club.
=20
> That is, quite frankly, a terrible way to specify that a function is an=
=20
>> unboxed coroutine. A special tag type in the function signature?
>>
>
>> I'd much rather have a keyword. Especially since this fundamentally=20
>> changes how the function behaves, that's generally the sort of thing a=
=20
>> keyword would do, not a type in the signature.
>>
>
> You said that you do not want to change mechanics of function signature.
>
No, what I didn't want was for a function signature to *lie*. Where it=20
magically is transformed into a struct, or the return type gets replaced by=
=20
something else or some such.
A function should be a function, and it should behave like functions=20
behave. A `constexpr` function is still a function even if it is=20
`constexpr`. It has a function signature which behaves like a regular=20
function signature and so forth. It doesn't arbitrarily decide that its=20
return value is not really what it appears to be.
I'm fine with adding syntax to designate a function as being special. What=
=20
I'm not fine with is having that function implicitly be a class definition=
=20
or having the function's return type not really be the apparent return type=
=20
or whatever.
Add syntax if you must. But do not *lie* to the user.
And that part is what keeps tripping you up. Because if you insist on being=
=20
able to return a compiler-generated type (whether it's directly or stored=
=20
in the return object), there is no way to specify such a thing in C++. And=
=20
therefore, there is going to have to be some place where you *cheat*.
=20
> And no, your approach is not "closer" to P0057. It's farther. The return=
=20
>> type is a coroutine now, not a future, or generator, or other user-defin=
ed=20
>> type. It's an actual coroutine.
>>
>
> No, I mean that actual return type would be specified by specialization o=
f=20
> coroutine_traits.
>
Which is rather the opposite of how P0057 works, where the return type is=
=20
the return type, and the promise type is *deduced* from that.
So again, you're deviating farther from P0057, not closer.
That's not how P0057 works. Indeed, that's not what P0057 is *for*.=20
>> Remember the general idea of await in P0057: it halts the function, but =
it=20
>> also *explicitly* allows the transfer of control of the function to the =
*await=20
>> expression*. And thus, control is not necessarily transferred to the=20
>> return value.
>>
>
> Yes, of course, it does not have to.=20
>
So... how do you do it? In P0057, it happens through `await_suspend`, which=
=20
takes a coroutine_handle<>. So in your idea, how does it work?
Oh sure, you use different keywords. But the behavior of those keywords is=
=20
>> basically the behavior of the functions P0114 implements. Basically, P01=
14=20
>> is what you want, even if you would prefer that the form appeared more l=
ike=20
>> P0057.
>>
>
> Personally I prefer P0114 - it is more powerful, gives less overhead, and=
=20
> shifts from concrete await or yield features towards more general languag=
e=20
> feature.
> But if P0057 is much more likely to get into ISO, then I would like to=20
> remove discussed overhead.
>
Here's my problem with that notion.
What you really want is P0114. But you don't believe that it'll make it in.=
=20
So instead, you propose suggestions to change P0057. Which will in the=20
end... turn it into a *gimped* version of P0114.
To me, the advantages of P0114 have nothing to do with "efficiency" (as=20
I've made clear, I consider that argument to be specious, outside of=20
trivial cases nobody would bother with). Its advantages are the ability to=
=20
"await" within nested layers and to magically transform non-resumable=20
functions into resumable functions without changing their direct=20
implementations.
It's a limited version of P0099, but one that requires explicit language=20
support.
What P0114 fails is at .then-style continuations. That's where we need=20
P0057, and that's where it should be focused. I would much rather have the=
=20
actual P0114 alongside P0057 than to put a half-version of P0114 into=20
P0057, making both worse than they could be as pure features.
--=20
---=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.
------=_Part_573_1939144022.1445101631790
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">On Saturday, October 17, 2015 at 11:43:32 AM UTC-4, Evgeny=
Panasyuk 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">17 October 2015 =D0=B3., 16:31:25 UTC+3 Nicol Bolas:<br><blockquote clas=
s=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc =
solid;padding-left:1ex"><div>P0057 is the result of numerous revisions of a=
n idea, across several years, as well as with lots of implementation experi=
ence. Why should we impair such a design just because you think that, one d=
ay, someone <i>might</i> propose a better one? <br></div></blockquote><div>=
<br>Yes, better design is possible.<br>But that is not the only issue - if =
there will be big overhead, it would have limited usability. As Giovanni me=
ntioned above, if performance is not an issue - stackful coroutines would c=
over most of use cases of slow stackless coroutines.<br></div></div></block=
quote><div><br>I don't understand you rhetoric here. On the one hand, y=
ou claim that there is "big overhead" and that P0057 are "sl=
ow stackless coroutines." Yet later, you specifically state that "=
;Again, I should prepare detailed report (in order for it to have real effe=
ct)". Which means that you, as of yet, have no actual evidence that ov=
erhead is "big" or that P0057 is "slow".<br><br>You hav=
e repeatedly made the positive claims that P0057 is "slow", that =
it has "big overhead". It's time to put up or shut up: presen=
t your evidence for these claims, or we should consider your statements to =
be at best conjecture.<br><br>Note: "evidence" means actual evide=
nce. Not "well, if you do this, the optimizer might not work" or =
whatever. Actual, good-faith evidence.<br><br>There is apparently an implem=
entation of P0114. And there is an implementation of await. Use them to pro=
vide us with evidence of your claims.<br><br></div><blockquote class=3D"gma=
il_quote" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid=
;padding-left: 1ex;"><div dir=3D"ltr"><blockquote class=3D"gmail_quote" sty=
le=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-left:1e=
x"><div>The zero-overhead principle <i>is not a club!</i> Stop using a prin=
ciple to bash things over the head.<br></div></blockquote><div><br>Constant=
ly telling to opponent to stop doing something does not increase level of y=
our argumentation.<br></div></div></blockquote><div><br>No, but it does tel=
l you that you're not convincing anyone by continuing to use the princi=
ple as a club.<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;">=
<div dir=3D"ltr"><div></div><blockquote class=3D"gmail_quote" style=3D"marg=
in:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-left:1ex"><div></=
div><div>That is, quite frankly, a terrible way to specify that a function =
is an unboxed coroutine. A special tag type in the function signature?<br><=
/div></blockquote><blockquote class=3D"gmail_quote" style=3D"margin:0;margi=
n-left:0.8ex;border-left:1px #ccc solid;padding-left:1ex"><div><br>I'd =
much rather have a keyword. Especially since this fundamentally changes how=
the function behaves, that's generally the sort of thing a keyword wou=
ld do, not a type in the signature.<br></div></blockquote><div><br>You said=
that you do not want to change mechanics of function signature.</div></div=
></blockquote><div><br>No, what I didn't want was for a function signat=
ure to <i>lie</i>. Where it magically is transformed into a struct, or the =
return type gets replaced by something else or some such.<br><br>A function=
should be a function, and it should behave like functions behave. A `const=
expr` function is still a function even if it is `constexpr`. It has a func=
tion signature which behaves like a regular function signature and so forth=
.. It doesn't arbitrarily decide that its return value is not really wha=
t it appears to be.<br><br>I'm fine with adding syntax to designate a f=
unction as being special. What I'm not fine with is having that functio=
n implicitly be a class definition or having the function's return type=
not really be the apparent return type or whatever.<br><br>Add syntax if y=
ou must. But do not <i>lie</i> to the user.<br><br>And that part is what ke=
eps tripping you up. Because if you insist on being able to return a compil=
er-generated type (whether it's directly or stored in the return object=
), there is no way to specify such a thing in C++. And therefore, there is =
going to have to be some place where you <i>cheat</i>.<br>=C2=A0</div><bloc=
kquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-l=
eft: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr"><blockquote class=
=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc s=
olid;padding-left:1ex"><div>And no, your approach is not "closer"=
to P0057. It's farther. The return type is a coroutine now, not a futu=
re, or generator, or other user-defined type. It's an actual coroutine.=
<br></div></blockquote><div><br>No, I mean that actual return type would be=
specified by specialization of coroutine_traits.<br></div></div></blockquo=
te><div><br>Which is rather the opposite of how P0057 works, where the retu=
rn type is the return type, and the promise type is <i>deduced</i> from tha=
t.<br><br>So again, you're deviating farther from P0057, not closer.<br=
></div><div><br></div><blockquote class=3D"gmail_quote" style=3D"margin: 0;=
margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=
=3D"ltr"><blockquote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.=
8ex;border-left:1px #ccc solid;padding-left:1ex"><div>That's not how P0=
057 works. Indeed, that's not what P0057 is <i>for</i>. Remember the ge=
neral idea of await in P0057: it halts the function, but it also <i>explici=
tly</i> allows the transfer of control of the function to the <i>await expr=
ession</i>. And thus, control is not necessarily transferred to the return =
value.<br></div></blockquote><div><br>Yes, of course, it does not have to. =
<br></div></div></blockquote><div><br>So... how do you do it? In P0057, it =
happens through `await_suspend`, which takes a coroutine_handle<>. So=
in your idea, how does it work?<br><br></div><blockquote class=3D"gmail_qu=
ote" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padd=
ing-left: 1ex;"><div dir=3D"ltr"><div></div><blockquote class=3D"gmail_quot=
e" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-l=
eft:1ex"><div>Oh sure, you use different keywords. But the behavior of thos=
e keywords is basically the behavior of the functions P0114 implements. Bas=
ically, P0114 is what you want, even if you would prefer that the form appe=
ared more like P0057.<br></div></blockquote><div><br>Personally I prefer P0=
114 - it is more powerful, gives less overhead, and shifts from concrete aw=
ait or yield features towards more general language feature.<br>But if P005=
7 is much more likely to get into ISO, then I would like to remove discusse=
d overhead.<br></div></div></blockquote><div><br>Here's my problem with=
that notion.<br><br>What you really want is P0114. But you don't belie=
ve that it'll make it in. So instead, you propose suggestions to change=
P0057. Which will in the end... turn it into a <i>gimped</i> version of P0=
114.<br><br>To me, the advantages of P0114 have nothing to do with "ef=
ficiency" (as I've made clear, I consider that argument to be spec=
ious, outside of trivial cases nobody would bother with). Its advantages ar=
e the ability to "await" within nested layers and to magically tr=
ansform non-resumable functions into resumable functions without changing t=
heir direct implementations.<br><br>It's a limited version of P0099, bu=
t one that requires explicit language support.<br><br>What P0114 fails is a=
t .then-style continuations. That's where we need P0057, and that's=
where it should be focused. I would much rather have the actual P0114 alon=
gside P0057 than to put a half-version of P0114 into P0057, making both wor=
se than they could be as pure features.</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_573_1939144022.1445101631790--
------=_Part_572_292874999.1445101631790--
.
Author: Gor Nishanov <gornishanov@gmail.com>
Date: Sat, 17 Oct 2015 10:22:12 -0700 (PDT)
Raw View
------=_Part_870_1802574734.1445102532975
Content-Type: multipart/alternative;
boundary="----=_Part_871_750162294.1445102532975"
------=_Part_871_750162294.1445102532975
Content-Type: text/plain; charset=UTF-8
Two quick points:
On Saturday, October 17, 2015 at 10:07:12 AM UTC-7, Nicol Bolas wrote:
There is apparently an implementation of P0114. And there is an
> implementation of await. Use them to provide us with evidence of your
> claims.
>
Unless something changed today. There is no a proof of concept
implementation of P0114, the only thing that I was able to find was a
library emulation using stackful coroutines that do not address some
questions raised about P0114 proposal with respect to how embedding of
a coroutine state machine class would actually work in the language.
I will be content with just snippets that show for some problem the code
for definition, declaration and the use of the coroutines where there is a
concern that P0057 is less efficient than P0114. So far, I've been making
the claim for more than a year that P0057 (and predecessors) are as or more
efficient than P0114 (and its predecessors). Nobody come with an example,
yet.
would bother with). Its advantages are the ability to "await" within nested
> layers and to magically transform non-resumable functions into resumable
> functions without changing their direct implementations.
>
I described a kludge how P0057 can support it in P0054 paper. Since I too
find that particular example appealing.
Cheers,
Gor
--
---
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_871_750162294.1445102532975
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><p>Two quick points:<br><br>On Saturday, October 17, 2015 =
at 10:07:12 AM UTC-7, Nicol Bolas wrote:</p><div><br></div><blockquote clas=
s=3D"gmail_quote" style=3D"margin: 0px 0px 0px 0.8ex; padding-left: 1ex; bo=
rder-left-color: rgb(204, 204, 204); border-left-width: 1px; border-left-st=
yle: solid;"><div dir=3D"ltr">There is apparently an implementation of P011=
4. And there is an implementation of await. Use them to provide us with evi=
dence of your claims.<br></div></blockquote><div><br></div><div>Unless some=
thing changed today. There is no a proof of concept implementation of P0114=
, the only thing that I was able to find=C2=A0was a library emulation using=
stackful coroutines that do not address some questions raised about P0114 =
proposal with respect to how embedding of a=C2=A0coroutine state machine cl=
ass would actually work in the language.</div><div><br></div><div>I will be=
content with just snippets that show for some problem=C2=A0the code for de=
finition, declaration and the use of the coroutines where there is a concer=
n that P0057 is less efficient than P0114. So far, I've been making the=
claim for more than a year that P0057 (and predecessors)=C2=A0are as or mo=
re efficient than P0114 (and its predecessors).=C2=A0Nobody come with an ex=
ample, yet.</div><div><br></div><blockquote class=3D"gmail_quote" style=3D"=
margin: 0px 0px 0px 0.8ex; padding-left: 1ex; border-left-color: rgb(204, 2=
04, 204); border-left-width: 1px; border-left-style: solid;"><div dir=3D"lt=
r">would bother with). Its advantages are the ability to "await" =
within nested layers and to magically transform non-resumable functions int=
o resumable functions without changing their direct implementations.<br></d=
iv></blockquote><div><br></div><div>I described a=C2=A0kludge how P0057=C2=
=A0can support it in P0054 paper. Since I too find that particular example =
appealing.</div><div><br></div><div>Cheers,</div><div>Gor</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_871_750162294.1445102532975--
------=_Part_870_1802574734.1445102532975--
.
Author: Evgeny Panasyuk <evgeny.panasyuk@gmail.com>
Date: Sat, 17 Oct 2015 10:28:25 -0700 (PDT)
Raw View
------=_Part_282_1389625184.1445102905538
Content-Type: multipart/alternative;
boundary="----=_Part_283_1272462543.1445102905538"
------=_Part_283_1272462543.1445102905538
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
17 October 2015 =D0=B3., 18:08:53 UTC+3 Nicol Bolas:
>
>
> It describes how to create result type.
>
> Are you saying that if the function says `generator foo()`, then the=20
> function *really* returns `generator::apply<InsertCompilerThingHere>`?
>
Yes, or (for "tag" syntax) something like:
coroutine_traits<auto_tag,param1,param2,..., generator_tag>::result_type
<concrete_coroutine_ie_compiler_thing>::type
=20
>
> And even when they can't, *you* can optimize them out with a decent=20
>>> allocator.
>>>
>>
>> First of all, I don't want to use custom allocators for simple things=20
>> like generators. Second, even custom allocator is not zero-overhead - at=
=20
>> least it must check size, because it is not known at compile time.
>>
>
> You are genuinely and seriously claiming that a conditional branch based=
=20
> on two numbers constitutes "overhead". And this overhead is so incredibly=
=20
> *burdensome* (despite only happening in the generator's initialization)=
=20
> that any and all language changes to remove said overhead are completely=
=20
> justified.
>
This is not the only overhead.
If you create array of structs that contain coroutine inside - there will=
=20
be N+1 allocations, instead of 1. Even if allocation itself is negligible=
=20
(like region/arena/freelist) there is still price of separating one struct=
=20
into two different places, and having additional indirection.
Only in some cases things like small size optimization would be possible,=
=20
and even when possible - very likely it would lead to extra memory=20
consumption, which is significant in cases like "billions of coroutines"=20
(also mentioned by authors of P0057).
=20
>
> The performance of a generator that returns integers on a fixed range is=
=20
> *irrelevant*. Nobody in their right mind is going to use generators for=
=20
> that. We have *ranges* for that.=20
>
> The purpose of a generator, in a *real application*, is to be able to=20
> have a process take an arbitrary amount of time. You get a value from tha=
t=20
> process, then you do something, then get another. Until the next value is=
=20
> available, your process stops. That's the idea.
>
> =20
That's not the only case. For instance consider "flatten" generator which=
=20
takes things like container1<container2<T>> and gives linear sequence of T=
=20
values - it is hard to do it proper manually, at least much harder than=20
with yield/generator.
=20
> =20
>
If the cost of generating that value is non-trivial, then the cost of the=
=20
> virtual call to do said generation is negligible.
>
If the cost of *using* that value is non-trivial, then the cost of the=20
> virtual call is again irrelevant.
>
virtual calls makes inlining much harder, i.e. prevents further=20
optimizations.
=20
> The overhead here is only "huge" if your generators *and* processing code=
=20
> are so trivial that your code would be written better as a straight-up=20
> range-based for loop.
>
Why better? Yield simplifies a lot of cases like "flatten".
It can be even used as drop-in emulation of list comprehension (as far as I=
=20
remember this was even mentioned in one of earlier versions of P0057).
And I want to use convenient features even in code with performance=20
requirements. This is one of main C++ strength.
=20
>
> This is why the zero-overhead principle is not some inviolate rule of=20
> *doctrine* which justifies any and all language changes. It is a=20
> *principle*, who's application must be weighed against all other=20
> applicable factors. It's there to remind us not to needlessly add undue=
=20
> overhead. It is not mean to be used to judge that any proposal is a prior=
i=20
> wrong just because there may be a lower overhead way to do it.
>
Yes, I agree. But in this case we indeed have "needlessly add undue=20
overhead", which can be avoided, and should be avoided in order to increase=
=20
applicability.
And it is not that I just randomly select proposal and trying to blindly=20
apply "zero-overhead doctrine". I knew that it should be nearly-zero=20
overhead exactly in this place, long before I read this proposal
=20
> And P0057 does gain something from this overhead. It gains not having=20
> automatic generation of return types, so functions still make sense.
>
Within almost same design it could give both variants - auto generation of=
=20
return types, and some fixed ones.
=20
> It gains the ability to transfer control to someone other than the caller=
=20
> (which your proposal does not),
>
I do not exclude this feature, it can be implemented too.
=20
> allowing the feature to be useful for *more than* just "generators". And=
=20
> so forth.
>
Well, to be really widely useful - we need copyability, movability, etc.=20
Without this things like for example list monad or software transactional=
=20
memory cannot be implemented.=20
--=20
---=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.
------=_Part_283_1272462543.1445102905538
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">17 October 2015 =D0=B3., 18:08:53 UTC+3 Nicol Bolas:<block=
quote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-le=
ft: 1px #ccc solid;padding-left: 1ex;"><br><div dir=3D"ltr"><div>It describ=
es how to create result type.<br></div></div><div><br>Are you saying that i=
f the function says `generator foo()`, then the function <i>really</i> retu=
rns `generator::apply<<wbr>InsertCompilerThingHere>`?<br></div></bloc=
kquote><div><br>Yes, or (for "tag" syntax) something like:<br><di=
v class=3D"prettyprint" style=3D"background-color: rgb(250, 250, 250); bord=
er-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: #000;" class=3D"styled-by-prettify">coroutine_trait=
s</span><span style=3D"color: #660;" class=3D"styled-by-prettify"><</spa=
n><span style=3D"color: #000;" class=3D"styled-by-prettify">auto_tag</span>=
<span style=3D"color: #660;" class=3D"styled-by-prettify">,</span><span sty=
le=3D"color: #000;" class=3D"styled-by-prettify">param1</span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">,</span><span style=3D"color=
: #000;" class=3D"styled-by-prettify">param2</span><span style=3D"color: #6=
60;" class=3D"styled-by-prettify">,...,</span><span style=3D"color: #000;" =
class=3D"styled-by-prettify"> generator_tag</span><span style=3D"color: #66=
0;" class=3D"styled-by-prettify">>::</span><span style=3D"color: #000;" =
class=3D"styled-by-prettify">result_type</span><span style=3D"color: #080;"=
class=3D"styled-by-prettify"><concrete_coroutine_ie_compiler_thing><=
/span><span style=3D"color: #660;" class=3D"styled-by-prettify">::</span><s=
pan style=3D"color: #000;" class=3D"styled-by-prettify">type<br></span></di=
v></code></div>=C2=A0</div><blockquote class=3D"gmail_quote" style=3D"margi=
n: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><br=
><blockquote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;bord=
er-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><div> </div><bloc=
kquote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-lef=
t:1px #ccc solid;padding-left:1ex"><div>And even when they can't, <i>yo=
u</i> can optimize them out with a decent allocator.<br></div></blockquote>=
<div><br>First of all, I don't want to use custom allocators for simple=
things like generators. Second, even custom allocator is not zero-overhead=
- at least it must check size, because it is not known at compile time.<br=
></div></div></blockquote><div><br>You are genuinely and seriously claiming=
that a conditional branch based on two numbers constitutes "overhead&=
quot;. And this overhead is so incredibly <i>burdensome</i> (despite only h=
appening in the generator's initialization) that any and all language c=
hanges to remove said overhead are completely justified.<br></div></blockqu=
ote><div><br>This is not the only overhead.<br>If you create array of struc=
ts that contain coroutine inside - there will be N+1 allocations, instead o=
f 1. Even if allocation itself is negligible (like region/arena/freelist) t=
here is still price of separating one struct into two different places, and=
having additional indirection.<br>Only in some cases things like small siz=
e optimization would be possible, and even when possible - very likely it w=
ould lead to extra memory consumption, which is significant in cases like &=
quot;billions of coroutines" (also mentioned by authors of P0057).<br>=
=C2=A0</div><blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-lef=
t: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div><br>The perfo=
rmance of a generator that returns integers on a fixed range is <i>irreleva=
nt</i>. Nobody in their right mind is going to use generators for that. We =
have <i>ranges</i> for that. <br></div></blockquote><blockquote class=3D"gm=
ail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc soli=
d;padding-left: 1ex;"><div><br>The purpose of a generator, in a <i>real app=
lication</i>, is to be able to have a process take an arbitrary amount of t=
ime. You get a value from that process, then you do something, then get ano=
ther. Until the next value is available, your process stops. That's the=
idea.<br><br></div></blockquote><div>=C2=A0<br>That's not the only cas=
e. For instance consider "flatten" generator which takes things l=
ike container1<container2<T>> and gives linear sequence of T va=
lues - it is hard to do it proper manually, at least much harder than with =
yield/generator.<br></div><div>=C2=A0</div><blockquote class=3D"gmail_quote=
" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding=
-left: 1ex;"><div>=C2=A0</div></blockquote><blockquote class=3D"gmail_quote=
" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding=
-left: 1ex;"><div>If the cost of generating that value is non-trivial, then=
the cost of the virtual call to do said generation is negligible.</div></b=
lockquote><blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left:=
0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div>If the cost of =
<i>using</i> that value is non-trivial, then the cost of the virtual call i=
s again irrelevant.<br></div></blockquote><div><br>virtual calls makes inli=
ning much harder, i.e. prevents further optimizations.<br>=C2=A0</div><bloc=
kquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-l=
eft: 1px #ccc solid;padding-left: 1ex;"><div>The overhead here is only &quo=
t;huge" if your generators <i>and</i> processing code are so trivial t=
hat your code would be written better as a straight-up range-based for loop=
..</div></blockquote><div><br>Why better? Yield simplifies a lot of cases li=
ke "flatten".<br>It can be even used as drop-in emulation of list=
comprehension (as far as I remember this was even mentioned in one of earl=
ier versions of P0057).<br>And I want to use convenient features even in co=
de with performance requirements. This is one of main C++ strength.<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;"><div><br>This is why =
the zero-overhead principle is not some inviolate rule of <i>doctrine</i> w=
hich justifies any and all language changes. It is a <i>principle</i>, who&=
#39;s application must be weighed against all other applicable factors. It&=
#39;s there to remind us not to needlessly add undue overhead. It is not me=
an to be used to judge that any proposal is a priori wrong just because the=
re may be a lower overhead way to do it.<br></div></blockquote><div><br>Yes=
, I agree. But in this case we indeed have "needlessly add undue overh=
ead", which can be avoided, and should be avoided in order to increase=
applicability.<br>And it is not that I just randomly select proposal and t=
rying to blindly apply "zero-overhead doctrine". I knew that it s=
hould be nearly-zero overhead exactly in this place, long before I read thi=
s proposal<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;"><div=
>And P0057 does gain something from this overhead. It gains not having auto=
matic generation of return types, so functions still make sense.</div></blo=
ckquote><div><br>Within almost same design it could give both variants - au=
to generation of return types, and some fixed ones.<br>=C2=A0</div><blockqu=
ote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-left=
: 1px #ccc solid;padding-left: 1ex;"><div>It gains the ability to transfer =
control to someone other than the caller (which your proposal does not),</d=
iv></blockquote><div><br><span id=3D"result_box" class=3D"short_text" lang=
=3D"en"><span class=3D"hps">I do not exclude</span> <span class=3D"hps">thi=
s feature, it can be implemented too.</span></span><br>=C2=A0</div><blockqu=
ote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-left=
: 1px #ccc solid;padding-left: 1ex;"><div>allowing the feature to be useful=
for <i>more than</i> just "generators". And so forth.<br></div><=
/blockquote><div><br>Well, to be really widely useful - we need copyability=
, movability, etc. Without this things like for example list monad or softw=
are transactional memory cannot be implemented. <br></div><br></div>
<p></p>
-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />
------=_Part_283_1272462543.1445102905538--
------=_Part_282_1389625184.1445102905538--
.
Author: Gor Nishanov <gornishanov@gmail.com>
Date: Sat, 17 Oct 2015 11:31:36 -0700 (PDT)
Raw View
------=_Part_864_1239636397.1445106696529
Content-Type: multipart/alternative;
boundary="----=_Part_865_2143926174.1445106696529"
------=_Part_865_2143926174.1445106696529
Content-Type: text/plain; charset=UTF-8
On Saturday, October 17, 2015 at 10:28:25 AM UTC-7, Evgeny Panasyuk wrote:
>
> Well, to be really widely useful - we need copyability, movability, etc.
> Without this things like for example list monad
>
If you'd like to help getting your ideas through the committee, I would
suggest the following approach.
Start with a real problem that is hard to do today.
Show a good faith best solution to the problem how it can be done today
without feature X.
Show, how using a particular language/library feature you want to add can
make solving that problem simpler/less-error-prone/faster/etc.
Grab clang and prototype your ideas and try them out.
If you like the result, write a paper and start the ball rolling.
--
---
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_865_2143926174.1445106696529
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">On Saturday, October 17, 2015 at 10:28:25 AM UTC-7, Evgeny=
Panasyuk 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"><div>Well, to be really widely useful - we need copyability, movability,=
etc. Without this things like for example list monad</div></div></blockquo=
te><div><br></div><div>If you'd like to help getting your ideas through=
the committee, I would suggest the following approach.</div><div><br></div=
><div>Start with a real problem that is hard to do today.</div><div>Show a =
good faith best solution to the problem how it can be done today without fe=
ature X.<br></div><div>Show, how using a particular language/library featur=
e you want to add can make solving that problem simpler/less-error-prone/fa=
ster/etc.</div><div>Grab clang and prototype your ideas and try them out.<b=
r></div><div>If you like the result, write a paper and start the ball rolli=
ng.</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_865_2143926174.1445106696529--
------=_Part_864_1239636397.1445106696529--
.
Author: Nicol Bolas <jmckesson@gmail.com>
Date: Sat, 17 Oct 2015 12:08:38 -0700 (PDT)
Raw View
------=_Part_657_1257181696.1445108918622
Content-Type: multipart/alternative;
boundary="----=_Part_658_1488580982.1445108918623"
------=_Part_658_1488580982.1445108918623
Content-Type: text/plain; charset=UTF-8
On Saturday, October 17, 2015 at 1:22:13 PM UTC-4, Gor Nishanov wrote:
>
> Two quick points:
>
> On Saturday, October 17, 2015 at 10:07:12 AM UTC-7, Nicol Bolas wrote:
>
> There is apparently an implementation of P0114. And there is an
>> implementation of await. Use them to provide us with evidence of your
>> claims.
>>
>
> Unless something changed today. There is no a proof of concept
> implementation of P0114,
>
Oh. When I mentioned earlier that resumable expressions wasn't implemented,
someone else said that it had been. My mistake.
> would bother with). Its advantages are the ability to "await" within
>> nested layers and to magically transform non-resumable functions into
>> resumable functions without changing their direct implementations.
>>
>
> I described a kludge how P0057 can support it in P0054 paper. Since I too
> find that particular example appealing.
>
The problem is that the kludge doesn't work. Or at least, it doesn't work
the same way. We discussed this earlier.
In P0114, the entire call stack is taken as a single coroutine. So when you
resume the coroutine, the resume will *always* take you to the exact cite
of the `break resumable` call that suspended it.
That doesn't work in P0057, even if you explicitly put `await` everywhere.
Remember: the scheduling of when the continuation of the function happens
is defined by the await expression, *not* by the caller. Even if the
awaiter allows the caller to resume it, it will only resume the most
*recent* coroutine. The caller has no way of knowing that the actual
suspend point was 4 coroutines up the coroutine stack.
They are two separate concepts with two separate use cases. So even if you
had implicit `await` calls in the code, it would not yield equivalent
behavior. We even discussed what it would take to make `await` behave like
P0114 coroutines, so that calling them again would jump you to the right
spot. It was ultimately deemed impossible.
That was what gave me the revelation that `await` was ultimately about the
expression causing the continuation, rather than the caller.
The behavior that P0114 provides is caller-centric, not
`awaitable`-centric. And implicitly adding `await` will not change that
fact.
--
---
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_658_1488580982.1445108918623
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><br><br>On Saturday, October 17, 2015 at 1:22:13 PM UTC-4,=
Gor Nishanov wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;ma=
rgin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=
=3D"ltr"><p>Two quick points:<br><br>On Saturday, October 17, 2015 at 10:07=
:12 AM UTC-7, Nicol Bolas wrote:</p><div><br></div><blockquote class=3D"gma=
il_quote" style=3D"margin:0px 0px 0px 0.8ex;padding-left:1ex;border-left-co=
lor:rgb(204,204,204);border-left-width:1px;border-left-style:solid"><div di=
r=3D"ltr">There is apparently an implementation of P0114. And there is an i=
mplementation of await. Use them to provide us with evidence of your claims=
..<br></div></blockquote><div><br></div><div>Unless something changed today.=
There is no a proof of concept implementation of P0114,</div></div></block=
quote><div><br>Oh. When I mentioned earlier that resumable expressions wasn=
't implemented, someone else said that it had been. My mistake.<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;"><div dir=3D"ltr"><div=
></div><blockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;=
padding-left:1ex;border-left-color:rgb(204,204,204);border-left-width:1px;b=
order-left-style:solid"><div dir=3D"ltr">would bother with). Its advantages=
are the ability to "await" within nested layers and to magically=
transform non-resumable functions into resumable functions without changin=
g their direct implementations.<br></div></blockquote><div><br></div><div>I=
described a=C2=A0kludge how P0057=C2=A0can support it in P0054 paper. Sinc=
e I too find that particular example appealing.</div></div></blockquote><di=
v><br>The problem is that the kludge doesn't work. Or at least, it does=
n't work the same way. We discussed this earlier.<br><br>In P0114, the =
entire call stack is taken as a single coroutine. So when you resume the co=
routine, the resume will <i>always</i> take you to the exact cite of the `b=
reak resumable` call that suspended it.<br><br>That doesn't work in P00=
57, even if you explicitly put `await` everywhere. Remember: the scheduling=
of when the continuation of the function happens is defined by the await e=
xpression, <i>not</i> by the caller. Even if the awaiter allows the caller =
to resume it, it will only resume the most <i>recent</i> coroutine. The cal=
ler has no way of knowing that the actual suspend point was 4 coroutines up=
the coroutine stack.<br><br>They are two separate concepts with two separa=
te use cases. So even if you had implicit `await` calls in the code, it wou=
ld not yield equivalent behavior. We even discussed what it would take to m=
ake `await` behave like P0114 coroutines, so that calling them again would =
jump you to the right spot. It was ultimately deemed impossible.<br><br>Tha=
t was what gave me the revelation that `await` was ultimately about the exp=
ression causing the continuation, rather than the caller.<br></div><br>The =
behavior that P0114 provides is caller-centric, not `awaitable`-centric. An=
d implicitly adding `await` will not change that fact.<br></div>
<p></p>
-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />
------=_Part_658_1488580982.1445108918623--
------=_Part_657_1257181696.1445108918622--
.
Author: Gor Nishanov <gornishanov@gmail.com>
Date: Sat, 17 Oct 2015 12:29:51 -0700 (PDT)
Raw View
------=_Part_903_1617720059.1445110191276
Content-Type: multipart/alternative;
boundary="----=_Part_904_187180316.1445110191283"
------=_Part_904_187180316.1445110191283
Content-Type: text/plain; charset=UTF-8
Hi Nicol:
On Saturday, October 17, 2015 at 12:08:39 PM UTC-7, Nicol Bolas wrote:
The problem is that the kludge doesn't work. Or at least, it doesn't work
> the same way. We discussed this earlier.
>
That was probably my fault in not explaining it more clearly.
> In P0114, the entire call stack is taken as a single coroutine. So when
> you resume the coroutine, the resume will *always* take you to the exact
> cite of the `break resumable` call that suspended it.
>
"entire call stack" here is an illusion. The same illusion that kludge is
doing. What effectively happens in P0114 is that all state machines are
inlined into each other. You don't have a stack. You have a single
"resumable" function that does entire thing.
Similar things happen in P0057 (whether with explicit or implicit awaits).
Since in this particular case coroutine lifetime does not escape the full
expression it is used in the same heap elision rules apply as for generator
case.
In a generator case:
void f(){
auto g = gen();
... bla
} // generator is destroyed, hence we can use automatic storage of f for
the generator
In the well-behaved sub-coroutine case (RAII semantics, destructor calls
coroutine_handle::destroy())
well_behaved_future<void> h() {
await async_io();
}
well_behaved_future<void> g() {
await h(); // life time starts and ends here, alloc elision applies here
}
well_behaved_future<void> f() {
await g(); // life time starts and ends here, alloc elision applies here
};
Just like with P0114, it is only possible in non-recursive scenarios where
things get inlined into each other.
--
---
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_904_187180316.1445110191283
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><p>Hi Nicol:<br><br>On Saturday, October 17, 2015 at 12:08=
:39 PM UTC-7, Nicol Bolas wrote:</p><div><br></div><blockquote class=3D"gma=
il_quote" style=3D"margin: 0px 0px 0px 0.8ex; padding-left: 1ex; border-lef=
t-color: rgb(204, 204, 204); border-left-width: 1px; border-left-style: sol=
id;"><div dir=3D"ltr">The problem is that the kludge doesn't work. Or a=
t least, it doesn't work the same way. We discussed this earlier.<br></=
div></blockquote><div><br></div><div>That was probably my fault=C2=A0in not=
=C2=A0explaining it more=C2=A0clearly.=C2=A0</div><div><br></div><blockquot=
e class=3D"gmail_quote" style=3D"margin: 0px 0px 0px 0.8ex; padding-left: 1=
ex; border-left-color: rgb(204, 204, 204); border-left-width: 1px; border-l=
eft-style: solid;"><div dir=3D"ltr"><br>In P0114, the entire call stack is =
taken as a single coroutine. So when you resume the coroutine, the resume w=
ill <i>always</i> take you to the exact cite of the `break resumable` call =
that suspended it.<br></div></blockquote><div><br></div><div>"entire c=
all stack" here is an illusion. The same illusion that kludge is doing=
.. What effectively happens in P0114 is that all state machines are inlined =
into each other. You don't have a stack. You have a single "resuma=
ble" function that does entire thing.</div><div><br></div><div>Similar=
things happen in P0057 (whether with explicit or implicit awaits). Since i=
n this particular case coroutine lifetime does not escape the full expressi=
on it is used in the same heap elision rules apply as for generator case.</=
div><div><br></div><div>In a generator case:</div><div><br></div><div class=
=3D"prettyprint" style=3D"border: 1px solid rgb(187, 187, 187); border-imag=
e: none; -ms-word-wrap: break-word; background-color: rgb(250, 250, 250);">=
<code class=3D"prettyprint"><div class=3D"subprettyprint"><span class=3D"st=
yled-by-prettify" style=3D"color: rgb(0, 0, 136);">void</span><span class=
=3D"styled-by-prettify" style=3D"color: rgb(0, 0, 0);"> f</span><span class=
=3D"styled-by-prettify" style=3D"color: rgb(102, 102, 0);">(){</span><span =
class=3D"styled-by-prettify" style=3D"color: rgb(0, 0, 0);"><br>=C2=A0 =C2=
=A0</span><span class=3D"styled-by-prettify" style=3D"color: rgb(0, 0, 136)=
;">auto</span><span class=3D"styled-by-prettify" style=3D"color: rgb(0, 0, =
0);"> g </span><span class=3D"styled-by-prettify" style=3D"color: rgb(102, =
102, 0);">=3D</span><span class=3D"styled-by-prettify" style=3D"color: rgb(=
0, 0, 0);"> gen</span><span class=3D"styled-by-prettify" style=3D"color: rg=
b(102, 102, 0);">();</span><span class=3D"styled-by-prettify" style=3D"colo=
r: rgb(0, 0, 0);"><br>=C2=A0 =C2=A0 </span><span class=3D"styled-by-prettif=
y" style=3D"color: rgb(102, 102, 0);">...</span><span class=3D"styled-by-pr=
ettify" style=3D"color: rgb(0, 0, 0);"> bla<br></span><span class=3D"styled=
-by-prettify" style=3D"color: rgb(102, 102, 0);">}</span><span class=3D"sty=
led-by-prettify" style=3D"color: rgb(0, 0, 0);"> </span><span class=3D"styl=
ed-by-prettify" style=3D"color: rgb(136, 0, 0);">// generator is destroyed,=
hence we can use automatic storage of f for the generator</span><span clas=
s=3D"styled-by-prettify" style=3D"color: rgb(0, 0, 0);"><br></span></div></=
code></div><div><br></div><div>In the well-behaved sub-coroutine case (RAII=
semantics, destructor calls coroutine_handle::destroy())</div><div><br></d=
iv><div class=3D"prettyprint" style=3D"border: 1px solid rgb(187, 187, 187)=
; border-image: none; -ms-word-wrap: break-word; background-color: rgb(250,=
250, 250);"><code class=3D"prettyprint"><div class=3D"subprettyprint"><spa=
n class=3D"styled-by-prettify" style=3D"color: rgb(0, 0, 0);">well_behaved_=
future</span><span class=3D"styled-by-prettify" style=3D"color: rgb(0, 136,=
0);"><void></span><span class=3D"styled-by-prettify" style=3D"color:=
rgb(0, 0, 0);"> h</span><span class=3D"styled-by-prettify" style=3D"color:=
rgb(102, 102, 0);">()</span><span class=3D"styled-by-prettify" style=3D"co=
lor: rgb(0, 0, 0);"> </span><span class=3D"styled-by-prettify" style=3D"col=
or: rgb(102, 102, 0);">{</span><span class=3D"styled-by-prettify" style=3D"=
color: rgb(0, 0, 0);"><br></span><font color=3D"#000000"><span class=3D"sty=
led-by-prettify" style=3D"color: rgb(0, 0, 0);">=C2=A0 await async_io</span=
><span class=3D"styled-by-prettify" style=3D"color: rgb(102, 102, 0);">();<=
/span></font><span class=3D"styled-by-prettify" style=3D"color: rgb(0, 0, 0=
);"><br></span><span class=3D"styled-by-prettify" style=3D"color: rgb(102, =
102, 0);">}</span><span class=3D"styled-by-prettify" style=3D"color: rgb(0,=
0, 0);"><br>well_behaved_future</span><span class=3D"styled-by-prettify" s=
tyle=3D"color: rgb(0, 136, 0);"><void></span><span class=3D"styled-by=
-prettify" style=3D"color: rgb(0, 0, 0);"> g</span><span class=3D"styled-by=
-prettify" style=3D"color: rgb(102, 102, 0);">()</span><span class=3D"style=
d-by-prettify" style=3D"color: rgb(0, 0, 0);"> </span><span class=3D"styled=
-by-prettify" style=3D"color: rgb(102, 102, 0);">{</span><span class=3D"sty=
led-by-prettify" style=3D"color: rgb(0, 0, 0);"><br></span><font color=3D"#=
000000"><span class=3D"styled-by-prettify" style=3D"color: rgb(0, 0, 0);">=
=C2=A0 await h</span></font><span class=3D"styled-by-prettify" style=3D"col=
or: rgb(102, 102, 0);">();</span><span class=3D"styled-by-prettify" style=
=3D"color: rgb(0, 0, 0);"> </span><span class=3D"styled-by-prettify" style=
=3D"color: rgb(136, 0, 0);">// life time starts and ends here, alloc elisio=
n applies here</span><span class=3D"styled-by-prettify" style=3D"color: rgb=
(0, 0, 0);"><br></span><span class=3D"styled-by-prettify" style=3D"color: r=
gb(102, 102, 0);">}</span><span class=3D"styled-by-prettify" style=3D"color=
: rgb(0, 0, 0);"><br>well_behaved_future</span><span class=3D"styled-by-pre=
ttify" style=3D"color: rgb(0, 136, 0);"><void></span><span class=3D"s=
tyled-by-prettify" style=3D"color: rgb(0, 0, 0);"> f</span><span class=3D"s=
tyled-by-prettify" style=3D"color: rgb(102, 102, 0);">()</span><span class=
=3D"styled-by-prettify" style=3D"color: rgb(0, 0, 0);"> </span><span class=
=3D"styled-by-prettify" style=3D"color: rgb(102, 102, 0);">{</span><span cl=
ass=3D"styled-by-prettify" style=3D"color: rgb(0, 0, 0);"> <br>=C2=A0 await=
g</span><span class=3D"styled-by-prettify" style=3D"color: rgb(102, 102, 0=
);">();</span><span class=3D"styled-by-prettify" style=3D"color: rgb(0, 0, =
0);"> </span><span class=3D"styled-by-prettify" style=3D"color: rgb(136, 0,=
0);">// life time starts and ends here, alloc elision applies here</span><=
span class=3D"styled-by-prettify" style=3D"color: rgb(0, 0, 0);"><br></span=
><span class=3D"styled-by-prettify" style=3D"color: rgb(102, 102, 0);">};</=
span><span class=3D"styled-by-prettify" style=3D"color: rgb(0, 0, 0);"><br>=
</span></div></code></div><br><div>Just like with P0114, it is only possibl=
e in non-recursive scenarios where things get inlined into each other.</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_904_187180316.1445110191283--
------=_Part_903_1617720059.1445110191276--
.
Author: Nicol Bolas <jmckesson@gmail.com>
Date: Sat, 17 Oct 2015 12:46:42 -0700 (PDT)
Raw View
------=_Part_673_628364363.1445111202816
Content-Type: multipart/alternative;
boundary="----=_Part_674_1139051303.1445111202817"
------=_Part_674_1139051303.1445111202817
Content-Type: text/plain; charset=UTF-8
On Saturday, October 17, 2015 at 3:29:51 PM UTC-4, Gor Nishanov wrote:
>
> Hi Nicol:
>
> On Saturday, October 17, 2015 at 12:08:39 PM UTC-7, Nicol Bolas wrote:
>
> The problem is that the kludge doesn't work. Or at least, it doesn't work
>> the same way. We discussed this earlier.
>>
>
> That was probably my fault in not explaining it more clearly.
>
>
>> In P0114, the entire call stack is taken as a single coroutine. So when
>> you resume the coroutine, the resume will *always* take you to the exact
>> cite of the `break resumable` call that suspended it.
>>
>
> "entire call stack" here is an illusion. The same illusion that kludge is
> doing. What effectively happens in P0114 is that all state machines are
> inlined into each other. You don't have a stack. You have a single
> "resumable" function that does entire thing.
>
> Similar things happen in P0057 (whether with explicit or implicit awaits).
> Since in this particular case coroutine lifetime does not escape the full
> expression it is used in the same heap elision rules apply as for generator
> case.
>
I'm not talking about elision rules. I'm talking about where we go when we
resume a coroutine. Again, we discussed this; remember my `processing`
example?
blah operation()
{
await Process1();
await Process2();
await Process3();
}
blah command
{
//Before operation.
await operation();
//After operation.
}
void caller
{
auto c = command();
c.resume();
c.resume();
}
When `c.resume` is called the first time, the coroutine should suspend
after Process1 has completed. When `c.resume` is called the second time, it
should resume immediately after Process1, and suspend after Process2.
But with `await`, that doesn't happen. The second call to `resume` will
resume in `command`, not in `operation`. It will skip the rest of
`operation` *entirely*.
Had we been using resumable expressions, this would have worked as expected.
This is why implicit await does not give the same effect as resumable
expressions.
--
---
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_674_1139051303.1445111202817
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<br><br>On Saturday, October 17, 2015 at 3:29:51 PM UTC-4, Gor Nishanov wro=
te:<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"><p>Hi Nico=
l:<br><br>On Saturday, October 17, 2015 at 12:08:39 PM UTC-7, Nicol Bolas w=
rote:</p><div><br></div><blockquote class=3D"gmail_quote" style=3D"margin:0=
px 0px 0px 0.8ex;padding-left:1ex;border-left-color:rgb(204,204,204);border=
-left-width:1px;border-left-style:solid"><div dir=3D"ltr">The problem is th=
at the kludge doesn't work. Or at least, it doesn't work the same w=
ay. We discussed this earlier.<br></div></blockquote><div><br></div><div>Th=
at was probably my fault=C2=A0in not=C2=A0explaining it more=C2=A0clearly.=
=C2=A0</div><div><br></div><blockquote class=3D"gmail_quote" style=3D"margi=
n:0px 0px 0px 0.8ex;padding-left:1ex;border-left-color:rgb(204,204,204);bor=
der-left-width:1px;border-left-style:solid"><div dir=3D"ltr"><br>In P0114, =
the entire call stack is taken as a single coroutine. So when you resume th=
e coroutine, the resume will <i>always</i> take you to the exact cite of th=
e `break resumable` call that suspended it.<br></div></blockquote><div><br>=
</div><div>"entire call stack" here is an illusion. The same illu=
sion that kludge is doing. What effectively happens in P0114 is that all st=
ate machines are inlined into each other. You don't have a stack. You h=
ave a single "resumable" function that does entire thing.</div><d=
iv><br></div><div>Similar things happen in P0057 (whether with explicit or =
implicit awaits). Since in this particular case coroutine lifetime does not=
escape the full expression it is used in the same heap elision rules apply=
as for generator case.</div></div></blockquote><div><br>I'm not talkin=
g about elision rules. I'm talking about where we go when we resume a c=
oroutine. Again, we discussed this; remember my `processing` example?<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: #000;" class=3D"styled-by-prettify">blah opera=
tion</span><span style=3D"color: #660;" class=3D"styled-by-prettify">()</sp=
an><span style=3D"color: #000;" class=3D"styled-by-prettify"><br></span><sp=
an style=3D"color: #660;" class=3D"styled-by-prettify">{</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"><br>=C2=A0 await </span><spa=
n style=3D"color: #606;" class=3D"styled-by-prettify">Process1</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 await </span><spa=
n style=3D"color: #606;" class=3D"styled-by-prettify">Process2</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 await </span><spa=
n style=3D"color: #606;" class=3D"styled-by-prettify">Process3</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><br>blah command<br></span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">{</span><span style=3D"color=
: #000;" class=3D"styled-by-prettify"><br>=C2=A0 </span><span style=3D"colo=
r: #800;" class=3D"styled-by-prettify">//Before operation.</span><span styl=
e=3D"color: #000;" class=3D"styled-by-prettify"><br>=C2=A0 await operation<=
/span><span style=3D"color: #660;" class=3D"styled-by-prettify">();</span><=
span style=3D"color: #000;" class=3D"styled-by-prettify"><br>=C2=A0 </span>=
<span style=3D"color: #800;" class=3D"styled-by-prettify">//After operation=
..</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br></spa=
n><span style=3D"color: #660;" class=3D"styled-by-prettify">}</span><span s=
tyle=3D"color: #000;" class=3D"styled-by-prettify"><br><br></span><span sty=
le=3D"color: #008;" class=3D"styled-by-prettify">void</span><span style=3D"=
color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #0=
08;" class=3D"styled-by-prettify">caller</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 </span><span style=3D"color: #008;" class=3D"styl=
ed-by-prettify">auto</span><span style=3D"color: #000;" class=3D"styled-by-=
prettify"> c </span><span style=3D"color: #660;" class=3D"styled-by-prettif=
y">=3D</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> com=
mand</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 c<=
/span><span style=3D"color: #660;" class=3D"styled-by-prettify">.</span><sp=
an style=3D"color: #000;" class=3D"styled-by-prettify">resume</span><span s=
tyle=3D"color: #660;" class=3D"styled-by-prettify">();</span><span style=3D=
"color: #000;" class=3D"styled-by-prettify"><br>=C2=A0 c</span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">.</span><span style=3D"color=
: #000;" class=3D"styled-by-prettify">resume</span><span style=3D"color: #6=
60;" class=3D"styled-by-prettify">();</span><span style=3D"color: #000;" cl=
ass=3D"styled-by-prettify"><br></span><span style=3D"color: #660;" class=3D=
"styled-by-prettify">}</span></div></code></div><br>When `c.resume` is call=
ed the first time, the coroutine should suspend after Process1 has complete=
d. When `c.resume` is called the second time, it should resume immediately =
after Process1, and suspend after Process2.<br><br>But with `await`, that d=
oesn't happen. The second call to `resume` will resume in `command`, no=
t in `operation`. It will skip the rest of `operation` <i>entirely</i>.<br>=
<br>Had we been using resumable expressions, this would have worked as expe=
cted.<br><br>This is why implicit await does not give the same effect as re=
sumable expressions.<br></div>
<p></p>
-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />
------=_Part_674_1139051303.1445111202817--
------=_Part_673_628364363.1445111202816--
.
Author: Nicol Bolas <jmckesson@gmail.com>
Date: Sat, 17 Oct 2015 12:52:30 -0700 (PDT)
Raw View
------=_Part_469_1051446746.1445111550910
Content-Type: multipart/alternative;
boundary="----=_Part_470_1959665716.1445111550910"
------=_Part_470_1959665716.1445111550910
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
On Saturday, October 17, 2015 at 1:28:25 PM UTC-4, Evgeny Panasyuk wrote:
>
> 17 October 2015 =D0=B3., 18:08:53 UTC+3 Nicol Bolas:
>>
>> And even when they can't, *you* can optimize them out with a decent=20
>>>> allocator.
>>>>
>>>
>>> First of all, I don't want to use custom allocators for simple things=
=20
>>> like generators. Second, even custom allocator is not zero-overhead - a=
t=20
>>> least it must check size, because it is not known at compile time.
>>>
>>
>> You are genuinely and seriously claiming that a conditional branch based=
=20
>> on two numbers constitutes "overhead". And this overhead is so incredibl=
y=20
>> *burdensome* (despite only happening in the generator's initialization)=
=20
>> that any and all language changes to remove said overhead are completely=
=20
>> justified.
>>
>
> This is not the only overhead.
> If you create array of structs that contain coroutine inside
>
Hold it. In order to store a typed coroutine, you must be able to copy=20
and/or move it. Correct? So... how do you do that?
I checked through P0114, and its coroutines are immobile by design. Always.=
=20
So you can't rely on that.
Even if we allow copying/moving in cases, it would only be in cases where:
1: All parameters to the function are copy/moveable.
2: All automatic variables declared are copy/moveable.
3: The promise type and return types are copy/moveable (though the latter=
=20
is necessitated by P0057).
So if my function takes a `const std::string &`, it's immobile. If my=20
function does a `for(auto &x : vec)`, it's immobile. And so on.
So those are the requirements for any coroutine callstack you plan on=20
sticking in an object. And unless you can come up with a way to copy=20
references (or any user-defined immobile type for that matter), these rules=
=20
are inviolate.
=20
> The performance of a generator that returns integers on a fixed range is=
=20
>> *irrelevant*. Nobody in their right mind is going to use generators for=
=20
>> that. We have *ranges* for that.=20
>>
>
>> The purpose of a generator, in a *real application*, is to be able to=20
>> have a process take an arbitrary amount of time. You get a value from th=
at=20
>> process, then you do something, then get another. Until the next value i=
s=20
>> available, your process stops. That's the idea.
>>
> =20
> That's not the only case. For instance consider "flatten" generator which=
=20
> takes things like container1<container2<T>> and gives linear sequence of =
T=20
> values - it is hard to do it proper manually, at least much harder than=
=20
> with yield/generator.
>
I guess ranges aren't functional enough for some people ;)
If the cost of generating that value is non-trivial, then the cost of the=
=20
>> virtual call to do said generation is negligible.
>>
> If the cost of *using* that value is non-trivial, then the cost of the=20
>> virtual call is again irrelevant.
>>
>
> virtual calls makes inlining much harder, i.e. prevents further=20
> optimizations.
>
If the code implementing the potentially inlined function is non-trivial,=
=20
then the compiler wouldn't try to inline it.
The overhead here is only "huge" if your generators *and* processing code=
=20
>> are so trivial that your code would be written better as a straight-up=
=20
>> range-based for loop.
>>
>
> Why better? Yield simplifies a lot of cases like "flatten".
>
Let's assume that's true.
Most uses of "flatten" would be of the form `for await(const auto &x :=20
generator_call())`. Which will be optimized just fine.
That's the thing about the simple cases. They're so simple that they're=20
almost always going to be optimized away. It's the complex ones that won't=
=20
be, and the code to execute them will be the primary limiting factor in=20
profiling.
Not only that, there is no way to put `flatten` into a struct. Why? Because=
=20
it will almost certainly take its object *by reference*. So its resulting=
=20
coroutine type will be immobile. And therefore, you can't make it a=20
structure member.
So you can't even adjust the `flatten` case to put it in a struct.
It can be even used as drop-in emulation of list comprehension (as far as I=
=20
> remember this was even mentioned in one of earlier versions of P0057).
> And I want to use convenient features even in code with performance=20
> requirements. This is one of main C++ strength.
>
And you can.
This is why the zero-overhead principle is not some inviolate rule of=20
>> *doctrine* which justifies any and all language changes. It is a=20
>> *principle*, who's application must be weighed against all other=20
>> applicable factors. It's there to remind us not to needlessly add undue=
=20
>> overhead. It is not mean to be used to judge that any proposal is a prio=
ri=20
>> wrong just because there may be a lower overhead way to do it.
>>
>
> Yes, I agree. But in this case we indeed have "needlessly add undue=20
> overhead", which can be avoided, and should be avoided in order to increa=
se=20
> applicability.
>
Every attempt you've made to upgrade P0057 to add this functionality=20
negatively impacts the resulting language. You're either making classes=20
look like function definitions or transforming function return types behind=
=20
peoples backs or something else.
P0057 is already difficult enough to deal with, involving a complex=20
interweaving of 3 types (the awaiter, the promise, and the return type).=20
What you're doing makes it all the harder.
And it is not that I just randomly select proposal and trying to blindly=20
> apply "zero-overhead doctrine". I knew that it should be nearly-zero=20
> overhead exactly in this place, long before I read this proposal.
>
And P0057 is "nearly-zero overhead".
=20
> And P0057 does gain something from this overhead. It gains not having=20
>> automatic generation of return types, so functions still make sense.
>>
>
> Within almost same design it could give both variants - auto generation o=
f=20
> return types, and some fixed ones.
>
You have a very narrow view of "same design".
To me, a design *feature* of P0057 is that the function is what it says it=
=20
is. The feature is very carefully designed to do this. That's why it=20
doesn't return the promise type, or otherwise expose that to the user.
If you start mucking around with the call signature, transforming the=20
return type into something else, then it's not "almost" the same design.=20
It's a different design.
So the question is this: should we break one of the basic design ideals of=
=20
the feature?
It gains the ability to transfer control to someone other than the caller=
=20
>> (which your proposal does not),
>>
>
> I do not exclude this feature, it can be implemented too.
>
I don't understand how you can come so close to my point yet keep missing=
=20
it.
P0057 exists for the *primary purpose* of transferring control to someone=
=20
other than the caller. That's its main use case and the reason why it was=
=20
proposed in the first place. That's the problem it exists to solve.
Other useful uses can be added on top of that, but you shouldn't treat that=
=20
use case as merely something that "can be implemented too."
It's a non-negotiable part of the system.
allowing the feature to be useful for *more than* just "generators". And so=
=20
>> forth.
>>
>
> Well, to be really widely useful - we need copyability, movability, etc.
>
Then I guess they won't be "widely useful" by you standard. C++ is not like=
=20
other languages, and its call stacks are not necessarily copyable or=20
moveable. We use far too many references to objects in order to make that a=
=20
reasonable action.
The best you'd ever be able to get is the ability to check to see if a=20
*particular* coroutine object is cloneable and to clone it if possible. And=
=20
to define rules that a specific function would have to abide by in order to=
=20
be cloneable.
Without this things like for example list monad or software transactional=
=20
> memory cannot be implemented.
>
Why do we want to implement "list monad"s? C++ is not a functional=20
language. It's bad enough that P0057 is going to lead to a rash of=20
functional-C++ programmers using `await` on `expected` objects...
And isn't transactional memory already being built into another TS? What=20
does that have to do with resumable functions?
--=20
---=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.
------=_Part_470_1959665716.1445111550910
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
On Saturday, October 17, 2015 at 1:28:25 PM UTC-4, Evgeny Panasyuk wrote:<b=
lockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;borde=
r-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr">17 October 2015=
=D0=B3., 18:08:53 UTC+3 Nicol Bolas:<blockquote class=3D"gmail_quote" styl=
e=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-left:1ex=
"><blockquote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;bor=
der-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><div> </div><blo=
ckquote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-le=
ft:1px #ccc solid;padding-left:1ex"><div>And even when they can't, <i>y=
ou</i> can optimize them out with a decent allocator.<br></div></blockquote=
><div><br>First of all, I don't want to use custom allocators for simpl=
e things like generators. Second, even custom allocator is not zero-overhea=
d - at least it must check size, because it is not known at compile time.<b=
r></div></div></blockquote><div><br>You are genuinely and seriously claimin=
g that a conditional branch based on two numbers constitutes "overhead=
". And this overhead is so incredibly <i>burdensome</i> (despite only =
happening in the generator's initialization) that any and all language =
changes to remove said overhead are completely justified.<br></div></blockq=
uote><div><br>This is not the only overhead.<br>If you create array of stru=
cts that contain coroutine inside</div></div></blockquote><div><br>Hold it.=
In order to store a typed coroutine, you must be able to copy and/or move =
it. Correct? So... how do you do that?<br><br>I checked through P0114, and =
its coroutines are immobile by design. Always. So you can't rely on tha=
t.<br><br>Even if we allow copying/moving in cases, it would only be in cas=
es where:<br><br>1: All parameters to the function are copy/moveable.<br><b=
r>2: All automatic variables declared are copy/moveable.<br><br>3: The prom=
ise type and return types are copy/moveable (though the latter is necessita=
ted by P0057).<br><br>So if my function takes a `const std::string &`, =
it's immobile. If my function does a `for(auto &x : vec)`, it's=
immobile. And so on.<br><br>So those are the requirements for any coroutin=
e callstack you plan on sticking in an object. And unless you can come up w=
ith a way to copy references (or any user-defined immobile type for that ma=
tter), these rules are inviolate.<br>=C2=A0</div><blockquote class=3D"gmail=
_quote" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;p=
adding-left: 1ex;"><div dir=3D"ltr"><blockquote class=3D"gmail_quote" style=
=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-left:1ex"=
><div>The performance of a generator that returns integers on a fixed range=
is <i>irrelevant</i>. Nobody in their right mind is going to use generator=
s for that. We have <i>ranges</i> for that. <br></div></blockquote><blockqu=
ote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1=
px #ccc solid;padding-left:1ex"><div><br>The purpose of a generator, in a <=
i>real application</i>, is to be able to have a process take an arbitrary a=
mount of time. You get a value from that process, then you do something, th=
en get another. Until the next value is available, your process stops. That=
's the idea.<br></div></blockquote><div>=C2=A0<br>That's not the on=
ly case. For instance consider "flatten" generator which takes th=
ings like container1<container2<T>> and gives linear sequence o=
f T values - it is hard to do it proper manually, at least much harder than=
with yield/generator.<br></div></div></blockquote><div><br>I guess ranges =
aren't functional enough for some people ;)<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;"><div dir=3D"ltr"><div></div><div></div><bloc=
kquote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-lef=
t:1px #ccc solid;padding-left:1ex"></blockquote><blockquote class=3D"gmail_=
quote" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;paddi=
ng-left:1ex"><div>If the cost of generating that value is non-trivial, then=
the cost of the virtual call to do said generation is negligible.</div></b=
lockquote><blockquote class=3D"gmail_quote" style=3D"margin:0;margin-left:0=
..8ex;border-left:1px #ccc solid;padding-left:1ex"><div>If the cost of <i>us=
ing</i> that value is non-trivial, then the cost of the virtual call is aga=
in irrelevant.<br></div></blockquote><div><br>virtual calls makes inlining =
much harder, i.e. prevents further optimizations.<br></div></div></blockquo=
te><div><br>If the code implementing the potentially inlined function is no=
n-trivial, then the compiler wouldn't try to inline it.<br><br></div><b=
lockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;borde=
r-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr"><div></div><blo=
ckquote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-le=
ft:1px #ccc solid;padding-left:1ex"><div>The overhead here is only "hu=
ge" if your generators <i>and</i> processing code are so trivial that =
your code would be written better as a straight-up range-based for loop.</d=
iv></blockquote><div><br>Why better? Yield simplifies a lot of cases like &=
quot;flatten".<br></div></div></blockquote><div><br>Let's assume t=
hat's true.<br><br>Most uses of "flatten" would be of the for=
m `for await(const auto &x : generator_call())`. Which will be optimize=
d just fine.<br><br>That's the thing about the simple cases. They'r=
e so simple that they're=20
almost always going to be optimized away. It's the complex ones that=20
won't be, and the code to execute them will be the primary limiting=20
factor in profiling.<br><br>Not only that, there is no way to put `flatten`=
into a struct. Why? Because it will almost certainly take its object <i>by=
reference</i>. So its resulting coroutine type will be immobile. And there=
fore, you can't make it a structure member.<br><br>So you can't eve=
n adjust the `flatten` case to put it in a struct.<br><br></div><blockquote=
class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1=
px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr"><div>It can be even used=
as drop-in emulation of list comprehension (as far as I remember this was =
even mentioned in one of earlier versions of P0057).<br>And I want to use c=
onvenient features even in code with performance requirements. This is one =
of main C++ strength.<br></div></div></blockquote><div><br>And you can.<br>=
<br></div><blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left:=
0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr"><di=
v></div><blockquote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8=
ex;border-left:1px #ccc solid;padding-left:1ex"><div>This is why the zero-o=
verhead principle is not some inviolate rule of <i>doctrine</i> which justi=
fies any and all language changes. It is a <i>principle</i>, who's appl=
ication must be weighed against all other applicable factors. It's ther=
e to remind us not to needlessly add undue overhead. It is not mean to be u=
sed to judge that any proposal is a priori wrong just because there may be =
a lower overhead way to do it.<br></div></blockquote><div><br>Yes, I agree.=
But in this case we indeed have "needlessly add undue overhead",=
which can be avoided, and should be avoided in order to increase applicabi=
lity.<br></div></div></blockquote><div><br>Every attempt you've made to=
upgrade P0057 to add this functionality negatively impacts the resulting l=
anguage. You're either making classes look like function definitions or=
transforming function return types behind peoples backs or something else.=
<br><br>P0057 is already difficult enough to deal with, involving a complex=
interweaving of 3 types (the awaiter, the promise, and the return type). W=
hat you're doing makes it all the harder.<br><br></div><blockquote clas=
s=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #c=
cc solid;padding-left: 1ex;"><div dir=3D"ltr"><div>And it is not that I jus=
t randomly select proposal and trying to blindly apply "zero-overhead =
doctrine". I knew that it should be nearly-zero overhead exactly in th=
is place, long before I read this proposal.<br></div></div></blockquote><di=
v><br>And P0057 is "nearly-zero overhead".<br>=C2=A0</div><blockq=
uote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-lef=
t: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr"><div></div><blockquo=
te class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1p=
x #ccc solid;padding-left:1ex"><div>And P0057 does gain something from this=
overhead. It gains not having automatic generation of return types, so fun=
ctions still make sense.</div></blockquote><div><br>Within almost same desi=
gn it could give both variants - auto generation of return types, and some =
fixed ones.<br></div></div></blockquote><div><br>You have a very narrow vie=
w of "same design".<br><br>To me, a design <i>feature</i> of P005=
7 is that the function is what it says it is. The feature is very carefully=
designed to do this. That's why it doesn't return the promise type=
, or otherwise expose that to the user.<br><br>If you start mucking around =
with the call signature, transforming the return type into something else, =
then it's not "almost" the same design. It's a different =
design.<br><br>So the question is this: should we break one of the basic de=
sign ideals of the feature?<br><br></div><blockquote class=3D"gmail_quote" =
style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-l=
eft: 1ex;"><div dir=3D"ltr"><div></div></div></blockquote><blockquote class=
=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #cc=
c solid;padding-left: 1ex;"><div dir=3D"ltr"><div> </div><blockquote class=
=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc s=
olid;padding-left:1ex"><div>It gains the ability to transfer control to som=
eone other than the caller (which your proposal does not),</div></blockquot=
e><div><br><span lang=3D"en"><span>I do not exclude</span> <span>this featu=
re, it can be implemented too.</span></span></div></div></blockquote><div><=
br>I don't understand how you can come so close to my point yet keep mi=
ssing it.<br><br>P0057 exists for the <i>primary purpose</i> of transferrin=
g control to someone other than the caller. That's its main use case an=
d the reason why it was proposed in the first place. That's the problem=
it exists to solve.<br><br>Other useful uses can be added on top of that, =
but you shouldn't treat that use case as merely something that "ca=
n be implemented too."<br><br>It's a non-negotiable part of the sy=
stem.<br><br></div><blockquote class=3D"gmail_quote" style=3D"margin: 0;mar=
gin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D=
"ltr"><div> </div><blockquote class=3D"gmail_quote" style=3D"margin:0;margi=
n-left:0.8ex;border-left:1px #ccc solid;padding-left:1ex"><div>allowing the=
feature to be useful for <i>more than</i> just "generators". And=
so forth.<br></div></blockquote><div><br>Well, to be really widely useful =
- we need copyability, movability, etc.</div></div></blockquote><div><br>Th=
en I guess they won't be "widely useful" by you standard. C++=
is not like other languages, and its call stacks are not necessarily copya=
ble or moveable. We use far too many references to objects in order to make=
that a reasonable action.<br><br>The best you'd ever be able to get is=
the ability to check to see if a <i>particular</i> coroutine object is clo=
neable and to clone it if possible. And to define rules that a specific fun=
ction would have to abide by in order to be cloneable.<br><br></div><blockq=
uote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-lef=
t: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr"><div>Without this th=
ings like for example list monad or software transactional memory cannot be=
implemented.<br></div></div></blockquote><div><br>Why do we want to implem=
ent "list monad"s? C++ is not a functional language. It's bad=
enough that P0057 is going to lead to a rash of functional-C++ programmers=
using `await` on `expected` objects...<br><br>And isn't transactional =
memory already being built into another TS? What does that have to do with =
resumable functions?<br></div>
<p></p>
-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />
------=_Part_470_1959665716.1445111550910--
------=_Part_469_1051446746.1445111550910--
.
Author: Giovanni Piero Deretta <gpderetta@gmail.com>
Date: Sat, 17 Oct 2015 21:39:22 +0100
Raw View
--047d7b3a84c644474b052252e8d2
Content-Type: text/plain; charset=UTF-8
On 17 Oct 2015 4:41 p.m., "Nicol Bolas" <jmckesson@gmail.com> wrote:
>
> On Saturday, October 17, 2015 at 10:24:29 AM UTC-4, Giovanni Piero
Deretta wrote:
>>
>>
>> On 16 Oct 2015 5:26 p.m., "Nicol Bolas" <jmck...@gmail.com> wrote:
>> .
>> >
>> > The nice thing about P0057 is that it doesn't have very many new
features. It pretty much stops at function suspend/resume and
internally-generated promise types. The return type of a coroutine is no
different from any other type. The awaiter type, even the promise type are
all types using the C++ rules for types.
>> >
>>
>> If the criterion is minimising the number of new language features, we
should just standardise Boost.coroutine. It is provably implementable as a
pure library, there is significant industry experience with it and it is
significantly more expressive than any stackless proposal.
>
>
> I think you mean Boost.Context. Boost.Coroutine is just an add-on library
for "asymmetric" coroutines, built ontop of Boost.Context. And we already
have Boost.Context proposed in P0099. Though adding Boost.Coroutines onto
it wouldn't go amiss.
>
I really meant Boost coroutine, whose interface is explicit continuation
passing. I also want type safe parameters and I do not want current_context
that hinder optimisations.
> In any case, my point was that P0057 is able to provide significant and
useful features without breaking the language substantially. So prospective
"improvements" on it should be judged accordingly.
>
What are these features that Boost coroutine doesn't have?
>> The only advantage of P0057 is that its coroutines are guaranteed to
need a single frame instead of a whole side stack. It doesn't guarantee
freedom from heap allocation nor from type erasure. Sure, the overhead
might optimisable away in some cases, but there is no guarantee, also the
same exact optimisations are applicable to a Boost.coroutine-like design.
>
>
> The cost of a Boost.Context switch is massive compared to the cost of a
type-erased function call. The cost of allocating even a small
execution_context is massive compared to the small stacks of P0057.
[Citation needed].
The additional cost is a few extra loads and stores for the called save
registers and stack pointers. Certainly not massive. Even this cost can be
reduced with a custom calling convention.
>
> I hope you are not seriously claiming that all costs greater than zero
are equal. Things like this are a good example of why principles should not
be treated as bludgeons.
Please, I did not make this claim. I do make the claim that in many
applications were c++ is used address space is not at premium while no
allocation and indirect calls are strict requirements.
>
>> In fact the same analysis used to remove heap allocation can be used to
remove the side stack.
>
>
> No, it can't.
>
> In P0057, there are exactly two places where you can get access to the
coroutine_handle: from within `await_suspend` called via an explicit
`await` expression and from within the promise object itself. The
interaction between the promise and the return type allow the return type
to store the handle. And thus, the compiler (assuming all of these are
inlined) can track exactly where the coroutine_handle ends up. It knows
where it gets resumed and it can see if the `generator` return object is
moved after its final destination.
>
> `execution_context` is much broader in scope. A context can be exited
from any function in the call stack. Equally importantly, this does not
necessarily resume the previous context; it can exit to any other context
in existence. Any function can access the current context and stick it into
any variable they wish.
>
> So there is no way for the optimizer to know that a particular
`execution_context` is local to a function. Without that locality, nothing
can be optimized away.
In a Boost coroutine like scenario, as long as the father coroutine handle
does not leave the child coroutine body the compiler can make the same
exact inference: the current function will only pass control to the caller
from the current scope.
Note that you can of course switch to a third coroutine from anywhere in
the call stack, but that doesn't invalidate the optimisation: for example
you can call a boost.coroutine from a p0057 generator just fine.
I do not understand what promises have anything to do with whether the
coroutine frame is heap allocated or not.
-- gpd
--
---
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/.
--047d7b3a84c644474b052252e8d2
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<p dir=3D"ltr"><br>
On 17 Oct 2015 4:41 p.m., "Nicol Bolas" <<a href=3D"mailto:jmc=
kesson@gmail.com">jmckesson@gmail.com</a>> wrote:<br>
><br>
> On Saturday, October 17, 2015 at 10:24:29 AM UTC-4, Giovanni Piero Der=
etta wrote:<br>
>><br>
>><br>
>> On 16 Oct 2015 5:26 p.m., "Nicol Bolas" <<a href=3D"m=
ailto:jmck...@gmail.com">jmck...@gmail.com</a>> wrote:<br>
>> .<br>
>> ><br>
>> > The nice thing about P0057 is that it doesn't have very m=
any new features. It pretty much stops at function suspend/resume and inter=
nally-generated promise types. The return type of a coroutine is no differe=
nt from any other type. The awaiter type, even the promise type are all typ=
es using the C++ rules for types.<br>
>> ><br>
>><br>
>> If the criterion is minimising the number of new language features=
, we should just standardise Boost.coroutine. It is provably implementable =
as a pure library, there is significant industry experience with it and it =
is significantly more expressive than any stackless proposal.<br>
><br>
><br>
> I think you mean Boost.Context. Boost.Coroutine is just an add-on libr=
ary for "asymmetric" coroutines, built ontop of Boost.Context. An=
d we already have Boost.Context proposed in P0099. Though adding Boost.Coro=
utines onto it wouldn't go amiss.<br>
></p>
<p dir=3D"ltr">I really meant Boost coroutine, whose interface is explicit =
continuation passing. I also want type safe parameters and I do not want cu=
rrent_context that hinder=C2=A0 optimisations.</p>
<p dir=3D"ltr">> In any case, my point was that P0057 is able to provide=
significant and useful features without breaking the language substantiall=
y. So prospective "improvements" on it should be judged according=
ly.<br>
></p>
<p dir=3D"ltr">What are these features that Boost coroutine doesn't hav=
e?</p>
<p dir=3D"ltr">>> The only advantage of P0057 is that its coroutines =
are guaranteed to need a single frame instead of a whole side stack. It doe=
sn't guarantee freedom from heap allocation nor from type erasure. Sure=
, the overhead might optimisable away in some cases, but there is no guaran=
tee, also the same exact optimisations are applicable to a Boost.coroutine-=
like design.<br>
><br>
><br>
> The cost of a Boost.Context switch is massive compared to the cost of =
a type-erased function call. The cost of allocating even a small execution_=
context is massive compared to the small stacks of P0057.</p>
<p dir=3D"ltr">[Citation needed]. <br>
The additional cost is a few extra loads and stores for the called save reg=
isters and stack pointers. Certainly not massive. Even this cost can be red=
uced with a custom calling convention.</p>
<p dir=3D"ltr">><br>
> I hope you are not seriously claiming that all costs greater than zero=
are equal. Things like this are a good example of why principles should no=
t be treated as bludgeons.</p>
<p dir=3D"ltr">Please, I did not make this claim. I do make the claim that =
in many=C2=A0 applications were c++ is used address space is not at premium=
while no allocation and indirect calls are strict requirements.</p>
<p dir=3D"ltr">><br>
>> In fact the same analysis used to remove heap allocation can be us=
ed to remove the side stack.<br>
><br>
><br>
> No, it can't.<br>
><br>
> In P0057, there are exactly two places where you can get access to the=
coroutine_handle: from within `await_suspend` called via an explicit `awai=
t` expression and from within the promise object itself. The interaction be=
tween the promise and the return type allow the return type to store the ha=
ndle. And thus, the compiler (assuming all of these are inlined) can track =
exactly where the coroutine_handle ends up. It knows where it gets resumed =
and it can see if the `generator` return object is moved after its final de=
stination.<br>
><br>
> `execution_context` is much broader in scope. A context can be exited =
from any function in the call stack. Equally importantly, this does not nec=
essarily resume the previous context; it can exit to any other context in e=
xistence. Any function can access the current context and stick it into any=
variable they wish.<br>
><br>
> So there is no way for the optimizer to know that a particular `execut=
ion_context` is local to a function. Without that locality, nothing can be =
optimized away.</p>
<p dir=3D"ltr">In a Boost coroutine like scenario, as long as the father co=
routine handle does not leave the child coroutine body the compiler can mak=
e the same exact inference: the current function will only pass control to =
the caller from the current scope. </p>
<p dir=3D"ltr"> Note that you can of course switch to a third coroutine fro=
m anywhere in the call stack, but that doesn't invalidate the optimisat=
ion: for example you can call a boost.coroutine from a p0057 generator just=
fine.</p>
<p dir=3D"ltr">I do not understand what promises have anything to do with w=
hether the coroutine frame is heap allocated or not.</p>
<p dir=3D"ltr">-- gpd</p>
<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 />
--047d7b3a84c644474b052252e8d2--
.
Author: Nicol Bolas <jmckesson@gmail.com>
Date: Sat, 17 Oct 2015 14:47:37 -0700 (PDT)
Raw View
------=_Part_743_1455901032.1445118457742
Content-Type: multipart/alternative;
boundary="----=_Part_744_474937781.1445118457742"
------=_Part_744_474937781.1445118457742
Content-Type: text/plain; charset=UTF-8
On Saturday, October 17, 2015 at 4:39:25 PM UTC-4, Giovanni Piero Deretta
wrote:
>
>
> On 17 Oct 2015 4:41 p.m., "Nicol Bolas" <jmck...@gmail.com <javascript:>>
> wrote:
> >
> > On Saturday, October 17, 2015 at 10:24:29 AM UTC-4, Giovanni Piero
> Deretta wrote:
> >>
> >>
> >> On 16 Oct 2015 5:26 p.m., "Nicol Bolas" <jmck...@gmail.com> wrote:
> >> .
> >> >
> >> > The nice thing about P0057 is that it doesn't have very many new
> features. It pretty much stops at function suspend/resume and
> internally-generated promise types. The return type of a coroutine is no
> different from any other type. The awaiter type, even the promise type are
> all types using the C++ rules for types.
> >> >
> >>
> >> If the criterion is minimising the number of new language features, we
> should just standardise Boost.coroutine. It is provably implementable as a
> pure library, there is significant industry experience with it and it is
> significantly more expressive than any stackless proposal.
> >
> >
> > I think you mean Boost.Context. Boost.Coroutine is just an add-on
> library for "asymmetric" coroutines, built ontop of Boost.Context. And we
> already have Boost.Context proposed in P0099. Though adding
> Boost.Coroutines onto it wouldn't go amiss.
> >
>
> I really meant Boost coroutine, whose interface is explicit continuation
> passing. I also want type safe parameters and I do not want current_context
> that hinder optimisations.
>
Um... no.
We all like to think about our own perspectives and use cases. I'm sure
that, for your specific needs, Boost.Coroutine is a perfectly adequate
solution. But features for standardization need to be *better* than that.
P0099 implements the most broad feature: creation of execution contexts and
switching between them. With that, you can implement any form of coroutine
you like.
What you want is *extremely* limited in its utility. You have to pass the
destination sink to every function you want to be able to yield. I don't
know of a whole lot of non-C++ coroutine features that are that limited in
their behavior.
Furthermore, I don't understand why you would want that when P0114 gives
you the same optimizations in the same circumstances where those
optimizations are possible. It simply is non-functional when those
optimizations aren't possible.
It's one thing to rely on an optimization not allocating a 512-byte stack.
It's quite another to rely on an optimization not allocation a 1-*megabyte*
stack. I'd want that to be a firm, standard-provided guarantee, not merely
a suggestion.
> In any case, my point was that P0057 is able to provide significant and
> useful features without breaking the language substantially. So prospective
> "improvements" on it should be judged accordingly.
> >
>
> What are these features that Boost coroutine doesn't have?
>
> >> The only advantage of P0057 is that its coroutines are guaranteed to
> need a single frame instead of a whole side stack. It doesn't guarantee
> freedom from heap allocation nor from type erasure. Sure, the overhead
> might optimisable away in some cases, but there is no guarantee, also the
> same exact optimisations are applicable to a Boost.coroutine-like design.
> >
> >
> > The cost of a Boost.Context switch is massive compared to the cost of a
> type-erased function call. The cost of allocating even a small
> execution_context is massive compared to the small stacks of P0057.
>
> [Citation needed].
>
Here are the performance stats for `execution_context
<http://www.boost.org/doc/libs/1_59_0/libs/context/doc/html/context/performance.html>.
And here are the stats for Boost.Coroutine
<http://www.boost.org/doc/libs/1_59_0/libs/coroutine/doc/html/coroutine/performance.html>.
I can't say what the cost of a virtual function call is, but I'd wager it's
rather less than 46 cycles (assuming cache hits, of course). And even with
a preallocated stack, 10350 cycles for an asymmetric coroutine is "massive"
for creation. I also find the 116-710 cycles for creating a
I would expect P0057 to be much rather on startup.
> The additional cost is a few extra loads and stores for the called save
> registers and stack pointers. Certainly not massive. Even this cost can be
> reduced with a custom calling convention.
>
"Massive" may have been an exaggeration on context switching, but there's
still a pretty significant performance difference between them. Not to
mention the whole "I allocated 1MB of stack space" thing.
> >
> > I hope you are not seriously claiming that all costs greater than zero
> are equal. Things like this are a good example of why principles should not
> be treated as bludgeons.
>
> Please, I did not make this claim. I do make the claim that in many
> applications were c++ is used address space is not at premium while no
> allocation and indirect calls are strict requirements.
>
I don't know of any application domain where "indirect calls" themselves
are expressly forbidden. Allocation, yes, there's lots of forbidding of
that (which is why P0057 allows user-defined allocation). Many application
environments frown on virtual function calls, but that's generally a part
of frowning on many other C++ things. I don't know of any programming
environments that out-right *forbid* indirect calls.
But I don't claim to know everything. So I accept the existence of such
application domains. However, your suggestion was to adopt Boost.Coroutine *instead
of* P0057, not in addition to. So while you would be serving your
application domain, you would also be performing a *disservice* to the
application domain served by P0057.
Remember that P0057's primary use case is .then-style continuations. And
Boost.Coroutine doesn't help with that at all.
They're two different tools for two different purposes.
>
> >> In fact the same analysis used to remove heap allocation can be used to
> remove the side stack.
> >
> >
> > No, it can't.
> >
> > In P0057, there are exactly two places where you can get access to the
> coroutine_handle: from within `await_suspend` called via an explicit
> `await` expression and from within the promise object itself. The
> interaction between the promise and the return type allow the return type
> to store the handle. And thus, the compiler (assuming all of these are
> inlined) can track exactly where the coroutine_handle ends up. It knows
> where it gets resumed and it can see if the `generator` return object is
> moved after its final destination.
> >
> > `execution_context` is much broader in scope. A context can be exited
> from any function in the call stack. Equally importantly, this does not
> necessarily resume the previous context; it can exit to any other context
> in existence. Any function can access the current context and stick it into
> any variable they wish.
> >
> > So there is no way for the optimizer to know that a particular
> `execution_context` is local to a function. Without that locality, nothing
> can be optimized away.
>
> In a Boost coroutine like scenario, as long as the father coroutine handle
> does not leave the child coroutine body the compiler can make the same
> exact inference: the current function will only pass control to the caller
> from the current scope.
>
> Note that you can of course switch to a third coroutine from anywhere in
> the call stack, but that doesn't invalidate the optimisation: for example
> you can call a boost.coroutine from a p0057 generator just fine.
>
So you don't just want Boost.Coroutine. You specifically want only the asymmetric
coroutines under that system
<http://www.boost.org/doc/libs/1_59_0/libs/coroutine/doc/html/coroutine/coroutine.html>.
That's an even bigger limitation.
I do not understand what promises have anything to do with whether the
> coroutine frame is heap allocated or not.
>
I brought up promise types because they're an implementation detail of
P0057. They're one of the only places that have easy access to the
coroutine_handle, and tracking who has access to it is necessary for
implementing the optimization.
--
---
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_744_474937781.1445118457742
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
On Saturday, October 17, 2015 at 4:39:25 PM UTC-4, Giovanni Piero Deretta w=
rote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8e=
x;border-left: 1px #ccc solid;padding-left: 1ex;"><p dir=3D"ltr"><br>
On 17 Oct 2015 4:41 p.m., "Nicol Bolas" <<a href=3D"javascript=
:" target=3D"_blank" gdf-obfuscated-mailto=3D"KWF74bCYDwAJ" rel=3D"nofollow=
" onmousedown=3D"this.href=3D'javascript:';return true;" onclick=3D=
"this.href=3D'javascript:';return true;">jmck...@gmail.com</a>> =
wrote:<br>
><br>
> On Saturday, October 17, 2015 at 10:24:29 AM UTC-4, Giovanni Piero Der=
etta wrote:<br>
>><br>
>><br>
>> On 16 Oct 2015 5:26 p.m., "Nicol Bolas" <<a>jmck...@g=
mail.com</a>> wrote:<br>
>> .<br>
>> ><br>
>> > The nice thing about P0057 is that it doesn't have very m=
any new features. It pretty much stops at function suspend/resume and inter=
nally-generated promise types. The return type of a coroutine is no differe=
nt from any other type. The awaiter type, even the promise type are all typ=
es using the C++ rules for types.<br>
>> ><br>
>><br>
>> If the criterion is minimising the number of new language features=
, we should just standardise Boost.coroutine. It is provably implementable =
as a pure library, there is significant industry experience with it and it =
is significantly more expressive than any stackless proposal.<br>
><br>
><br>
> I think you mean Boost.Context. Boost.Coroutine is just an add-on libr=
ary for "asymmetric" coroutines, built ontop of Boost.Context. An=
d we already have Boost.Context proposed in P0099. Though adding Boost.Coro=
utines onto it wouldn't go amiss.<br>
></p>
<p dir=3D"ltr">I really meant Boost coroutine, whose interface is explicit =
continuation passing. I also want type safe parameters and I do not want cu=
rrent_context that hinder=C2=A0 optimisations.</p></blockquote><div><br>Um.=
... no.<br><br>We all like to think about our own perspectives and use cases=
.. I'm sure that, for your specific needs, Boost.Coroutine is a perfectl=
y adequate solution. But features for standardization need to be <i>better<=
/i> than that. P0099 implements the most broad feature: creation of executi=
on contexts and switching between them. With that, you can implement any fo=
rm of coroutine you like.<br><br>What you want is <i>extremely</i> limited =
in its utility. You have to pass the destination sink to every function you=
want to be able to yield. I don't know of a whole lot of non-C++ corou=
tine features that are that limited in their behavior.<br><br>Furthermore, =
I don't understand why you would want that when P0114 gives you the sam=
e optimizations in the same circumstances where those optimizations are pos=
sible. It simply is non-functional when those optimizations aren't poss=
ible.<br><br>It's one thing to rely on an optimization not allocating a=
512-byte stack. It's quite another to rely on an optimization not allo=
cation a 1-<i>megabyte</i> stack. I'd want that to be a firm, standard-=
provided guarantee, not merely a suggestion.<br><br></div><blockquote class=
=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #cc=
c solid;padding-left: 1ex;">
<p dir=3D"ltr">> In any case, my point was that P0057 is able to provide=
significant and useful features without breaking the language substantiall=
y. So prospective "improvements" on it should be judged according=
ly.<br>
></p>
<p dir=3D"ltr">What are these features that Boost coroutine doesn't hav=
e?</p>
<p dir=3D"ltr">>> The only advantage of P0057 is that its coroutines =
are guaranteed to need a single frame instead of a whole side stack. It doe=
sn't guarantee freedom from heap allocation nor from type erasure. Sure=
, the overhead might optimisable away in some cases, but there is no guaran=
tee, also the same exact optimisations are applicable to a Boost.coroutine-=
like design.<br>
><br>
><br>
> The cost of a Boost.Context switch is massive compared to the cost of =
a type-erased function call. The cost of allocating even a small execution_=
context is massive compared to the small stacks of P0057.</p>
<p dir=3D"ltr">[Citation needed]. <br></p></blockquote><div><br>Here are th=
e <a href=3D"http://www.boost.org/doc/libs/1_59_0/libs/context/doc/html/con=
text/performance.html">performance stats for `execution_context</a>. And he=
re are the <a href=3D"http://www.boost.org/doc/libs/1_59_0/libs/coroutine/d=
oc/html/coroutine/performance.html">stats for Boost.Coroutine</a>. I can=
9;t say what the cost of a virtual function call is, but I'd wager it&#=
39;s rather less than 46 cycles (assuming cache hits, of course). And even =
with a preallocated stack, 10350 cycles for an asymmetric coroutine is &quo=
t;massive" for creation. I also find the 116-710 cycles for creating a=
<br><br>I would expect P0057 to be much rather on startup.<br>=C2=A0</div>=
<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;bor=
der-left: 1px #ccc solid;padding-left: 1ex;"><p dir=3D"ltr">
The additional cost is a few extra loads and stores for the called save reg=
isters and stack pointers. Certainly not massive. Even this cost can be red=
uced with a custom calling convention.</p></blockquote><div><br>"Massi=
ve" may have been an exaggeration on context switching, but there'=
s still a pretty significant performance difference between them. Not to me=
ntion the whole "I allocated 1MB of stack space" thing.<br>=C2=A0=
</div><blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8=
ex;border-left: 1px #ccc solid;padding-left: 1ex;">
<p dir=3D"ltr">><br>
> I hope you are not seriously claiming that all costs greater than zero=
are equal. Things like this are a good example of why principles should no=
t be treated as bludgeons.</p>
<p dir=3D"ltr">Please, I did not make this claim. I do make the claim that =
in many=C2=A0 applications were c++ is used address space is not at premium=
while no allocation and indirect calls are strict requirements.</p></block=
quote><div><br>I don't know of any application domain where "indir=
ect calls" themselves are expressly forbidden. Allocation, yes, there&=
#39;s lots of forbidding of that (which is why P0057 allows user-defined al=
location). Many application environments frown on virtual function calls, b=
ut that's generally a part of frowning on many other C++ things. I don&=
#39;t know of any programming environments that out-right <i>forbid</i> ind=
irect calls.<br><br>But I don't claim to know everything. So I accept t=
he existence of such application domains. However, your suggestion was to a=
dopt Boost.Coroutine <i>instead of</i> P0057, not in addition to. So while =
you would be serving your application domain, you would also be performing =
a <i>disservice</i> to the application domain served by P0057.<br><br>Remem=
ber that P0057's primary use case is .then-style continuations. And Boo=
st.Coroutine doesn't help with that at all.<br><br>They're two diff=
erent tools for two different purposes.<br><br></div><blockquote class=3D"g=
mail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc sol=
id;padding-left: 1ex;">
<p dir=3D"ltr">><br>
>> In fact the same analysis used to remove heap allocation can be us=
ed to remove the side stack.<br>
><br>
><br>
> No, it can't.<br>
><br>
> In P0057, there are exactly two places where you can get access to the=
coroutine_handle: from within `await_suspend` called via an explicit `awai=
t` expression and from within the promise object itself. The interaction be=
tween the promise and the return type allow the return type to store the ha=
ndle. And thus, the compiler (assuming all of these are inlined) can track =
exactly where the coroutine_handle ends up. It knows where it gets resumed =
and it can see if the `generator` return object is moved after its final de=
stination.<br>
><br>
> `execution_context` is much broader in scope. A context can be exited =
from any function in the call stack. Equally importantly, this does not nec=
essarily resume the previous context; it can exit to any other context in e=
xistence. Any function can access the current context and stick it into any=
variable they wish.<br>
><br>
> So there is no way for the optimizer to know that a particular `execut=
ion_context` is local to a function. Without that locality, nothing can be =
optimized away.</p>
<p dir=3D"ltr">In a Boost coroutine like scenario, as long as the father co=
routine handle does not leave the child coroutine body the compiler can mak=
e the same exact inference: the current function will only pass control to =
the caller from the current scope. </p>
<p dir=3D"ltr"> Note that you can of course switch to a third coroutine fro=
m anywhere in the call stack, but that doesn't invalidate the optimisat=
ion: for example you can call a boost.coroutine from a p0057 generator just=
fine.</p></blockquote><div><br>So you don't just want Boost.Coroutine.=
You specifically want only the <a href=3D"http://www.boost.org/doc/libs/1_=
59_0/libs/coroutine/doc/html/coroutine/coroutine.html">asymmetric coroutine=
s under that system</a>. That's an even bigger limitation.<br><br></div=
><blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;bo=
rder-left: 1px #ccc solid;padding-left: 1ex;">
<p dir=3D"ltr">I do not understand what promises have anything to do with w=
hether the coroutine frame is heap allocated or not.</p></blockquote><div><=
br></div>I brought up promise types because they're an implementation d=
etail of P0057. They're one of the only places that have easy access to=
the coroutine_handle, and tracking who has access to it is necessary for i=
mplementing the optimization.<br>
<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_744_474937781.1445118457742--
------=_Part_743_1455901032.1445118457742--
.
Author: Gor Nishanov <gornishanov@gmail.com>
Date: Sat, 17 Oct 2015 15:04:08 -0700 (PDT)
Raw View
------=_Part_566_877637557.1445119448548
Content-Type: multipart/alternative;
boundary="----=_Part_567_244262697.1445119448549"
------=_Part_567_244262697.1445119448549
Content-Type: text/plain; charset=UTF-8
On Saturday, October 17, 2015 at 12:46:43 PM UTC-7, Nicol Bolas wrote:
I'm not talking about elision rules. I'm talking about where we go when we
> resume a coroutine. Again, we discussed this; remember my `processing`
> example?
>
I remember. I just was not sure what conclusion you reached after the
discussion.
> blah operation()
> {
> await Process1();
> await Process2();
> await Process3();
> }
>
> blah command
> {
> //Before operation.
> await operation();
> //After operation.
> }
>
> void caller
> {
> auto c = command();
> c.resume();
> c.resume();
> }
>
Assuming that blah is a well behaved coroutine that has a coroutine handle
as a member, destroy in its destructor and start suspended, the code you
have shown is undefined behavior, since you are resuming and destroying
a coroutine that have an async activity in progress associated with it.
When you call the coroutine from the synchronous code you need to either
block waiting for async operation completing, or stash the handle somewhere
so that it is not destroyed at the end of caller.
You would use a helper function 'sync_await' or something like that, that
allows the caller to block until the awaitable is ready. So, I assume that
the caller bodies look like this:
void caller() { sync_await(command()); }
Then the execution will proceed as follows, command -> operation ->
Process1 -> let's say some OS async API, after that control is returned to
caller, where it awaits until command finishes.
OS resumes Process 1. Call sequence is as follows: OS -> Process1 ->
Operation -> Process 2 -> suspends waiting for some async acitivity to
finish
OS resumes Process 2. Call sequence is as follows: OS -> Process2 ->
Operation -> Process 3 -> suspends waiting for some async acitivity to
finish
OS resumes Process 3. Call sequence is as follows: OS -> Process3 ->
Operation -> Command -> informs a thread that is blocked waiting on
command() completion that we are done.
Caller finishes.
Hopefully, it was helpful, I will go dark for a week or so. So please do
not regard me not replying as disrespect :-), disagreement or agreement
with something you or somebody else says.
I will update you guys on the progress when I am back from Kona.
Cheers,
Gor
--
---
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_567_244262697.1445119448549
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><p><br><br>On Saturday, October 17, 2015 at 12:46:43 PM UT=
C-7, Nicol Bolas wrote:</p><div><br></div><blockquote class=3D"gmail_quote"=
style=3D"margin: 0px 0px 0px 0.8ex; padding-left: 1ex; border-left-color: =
rgb(204, 204, 204); border-left-width: 1px; border-left-style: solid;"><div=
>I'm not talking about elision rules. I'm talking about where we go=
when we resume a coroutine. Again, we discussed this; remember my `process=
ing` example?<br></div></blockquote><div><br></div><div>I remember. I just =
was not sure what conclusion you reached after the discussion.</div><div>=
=C2=A0<br></div><blockquote class=3D"gmail_quote" style=3D"margin: 0px 0px =
0px 0.8ex; padding-left: 1ex; border-left-color: rgb(204, 204, 204); border=
-left-width: 1px; border-left-style: solid;"><div style=3D"border: 1px soli=
d rgb(187, 187, 187); border-image: none; -ms-word-wrap: break-word; backgr=
ound-color: rgb(250, 250, 250);"><code><div><span style=3D"color: rgb(0, 0,=
0);">blah operation</span><span style=3D"color: rgb(102, 102, 0);">()</spa=
n><span style=3D"color: rgb(0, 0, 0);"><br></span><span style=3D"color: rgb=
(102, 102, 0);">{</span><span style=3D"color: rgb(0, 0, 0);"><br>=C2=A0 awa=
it </span><span style=3D"color: rgb(102, 0, 102);">Process1</span><span sty=
le=3D"color: rgb(102, 102, 0);">();</span><span style=3D"color: rgb(0, 0, 0=
);"><br>=C2=A0 await </span><span style=3D"color: rgb(102, 0, 102);">Proces=
s2</span><span style=3D"color: rgb(102, 102, 0);">();</span><span style=3D"=
color: rgb(0, 0, 0);"><br>=C2=A0 await </span><span style=3D"color: rgb(102=
, 0, 102);">Process3</span><span style=3D"color: rgb(102, 102, 0);">();</sp=
an><span style=3D"color: rgb(0, 0, 0);"><br></span><span style=3D"color: rg=
b(102, 102, 0);">}</span><span style=3D"color: rgb(0, 0, 0);"><br><br>blah =
command<br></span><span style=3D"color: rgb(102, 102, 0);">{</span><span st=
yle=3D"color: rgb(0, 0, 0);"><br>=C2=A0 </span><span style=3D"color: rgb(13=
6, 0, 0);">//Before operation.</span><span style=3D"color: rgb(0, 0, 0);"><=
br>=C2=A0 await operation</span><span style=3D"color: rgb(102, 102, 0);">()=
;</span><span style=3D"color: rgb(0, 0, 0);"><br>=C2=A0 </span><span style=
=3D"color: rgb(136, 0, 0);">//After operation.</span><span style=3D"color: =
rgb(0, 0, 0);"><br></span><span style=3D"color: rgb(102, 102, 0);">}</span>=
<span style=3D"color: rgb(0, 0, 0);"><br><br></span><span style=3D"color: r=
gb(0, 0, 136);">void</span><span style=3D"color: rgb(0, 0, 0);"> </span><sp=
an style=3D"color: rgb(0, 0, 136);">caller</span><span style=3D"color: rgb(=
0, 0, 0);"><br></span><span style=3D"color: rgb(102, 102, 0);">{</span><spa=
n style=3D"color: rgb(0, 0, 0);"><br>=C2=A0 </span><span style=3D"color: rg=
b(0, 0, 136);">auto</span><span style=3D"color: rgb(0, 0, 0);"> c </span><s=
pan style=3D"color: rgb(102, 102, 0);">=3D</span><span style=3D"color: rgb(=
0, 0, 0);"> command</span><span style=3D"color: rgb(102, 102, 0);">();</spa=
n><span style=3D"color: rgb(0, 0, 0);"><br>=C2=A0 c</span><span style=3D"co=
lor: rgb(102, 102, 0);">.</span><span style=3D"color: rgb(0, 0, 0);">resume=
</span><span style=3D"color: rgb(102, 102, 0);">();</span><span style=3D"co=
lor: rgb(0, 0, 0);"><br>=C2=A0 c</span><span style=3D"color: rgb(102, 102, =
0);">.</span><span style=3D"color: rgb(0, 0, 0);">resume</span><span style=
=3D"color: rgb(102, 102, 0);">();</span><span style=3D"color: rgb(0, 0, 0);=
"><br></span><span style=3D"color: rgb(102, 102, 0);">}</span></div></code>=
</div></blockquote><div><br></div><div>Assuming that blah is a well behaved=
coroutine that has a coroutine handle as a member, destroy in its destruct=
or and start suspended, the code you have shown is undefined behavior, sinc=
e you are resuming and destroying a=C2=A0coroutine that have an async activ=
ity in progress associated with it. When you call the coroutine from the sy=
nchronous code you need to either block waiting for async operation complet=
ing, or stash the handle somewhere so that it is not destroyed at the end o=
f caller.</div><div><br></div><div>You would use a helper function 'syn=
c_await' or something like that, that allows the caller to block until =
the awaitable is ready. So, I assume that the caller bodies look like this:=
</div><div><br></div><div class=3D"prettyprint" style=3D"border: 1px solid =
rgb(187, 187, 187); border-image: none; -ms-word-wrap: break-word; backgrou=
nd-color: rgb(250, 250, 250);"><code class=3D"prettyprint"><div class=3D"su=
bprettyprint"><span class=3D"styled-by-prettify" style=3D"color: rgb(0, 0, =
136);">void</span><span class=3D"styled-by-prettify" style=3D"color: rgb(0,=
0, 0);"> </span><span class=3D"styled-by-prettify" style=3D"color: rgb(0, =
0, 136);">caller</span><span class=3D"styled-by-prettify" style=3D"color: r=
gb(102, 102, 0);">()</span><span class=3D"styled-by-prettify" style=3D"colo=
r: rgb(0, 0, 0);"> </span><span class=3D"styled-by-prettify" style=3D"color=
: rgb(102, 102, 0);">{</span><span class=3D"styled-by-prettify" style=3D"co=
lor: rgb(0, 0, 0);"> sync_await</span><span class=3D"styled-by-prettify" st=
yle=3D"color: rgb(102, 102, 0);">(</span><span class=3D"styled-by-prettify"=
style=3D"color: rgb(0, 0, 0);">command</span><span class=3D"styled-by-pret=
tify" style=3D"color: rgb(102, 102, 0);">());</span><span class=3D"styled-b=
y-prettify" style=3D"color: rgb(0, 0, 0);"> </span><span class=3D"styled-by=
-prettify" style=3D"color: rgb(102, 102, 0);">}</span><span class=3D"styled=
-by-prettify" style=3D"color: rgb(0, 0, 0);"><br></span></div></code></div>=
<br><div>Then the execution will proceed as follows, command -> operatio=
n -> Process1 -> let's say some OS async API, after that control =
is returned to caller, where it awaits until command finishes.</div><div><b=
r></div><div>OS resumes Process 1. Call sequence is as follows: OS -> Pr=
ocess1 -> Operation ->=C2=A0Process 2 -> suspends waiting for some=
async acitivity to finish</div><div><div><div><div>OS resumes Process 2. C=
all sequence is as follows: OS -> Process2 -> Operation ->=C2=A0Pr=
ocess=C2=A03 -> suspends waiting for some async acitivity to finish</div=
></div>OS resumes Process 3. Call sequence is as follows: OS -> Process3=
-> Operation ->=C2=A0Command -> informs a thread that is blocked =
waiting on command() completion that we are done.</div><div><br></div><div>=
Caller finishes.</div><div><br></div><div>Hopefully, it was helpful, I will=
go dark for a week or so. So please do not regard me not replying as disre=
spect :-), disagreement or agreement with something you or somebody else=C2=
=A0says.</div><div><br></div><div>I will update you guys on the progress wh=
en I am back from Kona.</div><div><br></div><div>Cheers,</div><div>Gor<br><=
/div></div></div>
<p></p>
-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />
------=_Part_567_244262697.1445119448549--
------=_Part_566_877637557.1445119448548--
.
Author: Gor Nishanov <gornishanov@gmail.com>
Date: Sat, 17 Oct 2015 15:10:57 -0700 (PDT)
Raw View
------=_Part_972_1037351004.1445119857982
Content-Type: multipart/alternative;
boundary="----=_Part_973_2122108922.1445119857983"
------=_Part_973_2122108922.1445119857983
Content-Type: text/plain; charset=UTF-8
I lied. I will do one more post.
Here is an example of how a well-behaved future may look like. WARNING.
UNTESTED
template <> struct slim_future<void>
{
struct promise_type {
coroutine_handle<> parent;
bool initial_suspend() { return true; }
bool final_suspend() { return false; }
auto get_return_object() { return slim_future<void>{ this }; }
void return_void() { if (parent) { parent.resume(); } }
};
coroutine_handle<promise_type> h;
slim_future(slim_future const&) = delete;
slim_future(slim_future && rhs) : h(move(rhs.h)) { rhs.h = nullptr; }
explicit slim_future(promise_type* me) : h{ coroutine_handle
<promise_type>::from_promise(me) } {}
~slim_future() { h.destroy(); }
bool await_ready() { return false; }
void await_suspend(coroutine_handle<promise_type> parent) {
this->h.promise().parent = parent;
h.resume();
}
void await_resume() {}
};
and here is a code to use in your main, test driver to await for async
activity to finish:
template <typename Awaitable>
auto sync_await(Awaitable f)
{
mutex m;
condition_variable cv;
bool done = false;
auto w = [&]()->slim_future<void> {
await f;
{
lock_guard<mutex> lock(m);
done = true;
}
cv.notify_one();
}();
w.await_suspend(nullptr);
unique_lock<mutex> lock(m);
cv.wait(lock, [&] { return done; });
}
And when thinking through the cases, consider the example of heap elision I
showed earlier in the thread. Compiler has no idea about generators, async,
futures, etc.
It only looks at what happens to coroutine handles locally in this
function. Thus you understood how heap elision works for the generator, you
can observe that compiler will see the same sequence of operation on
coroutine handle for await f(); where f() returns slim future.
--
---
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_973_2122108922.1445119857983
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">I lied. I will do one more post.<div>Here is an example of=
how a well-behaved future may look like. WARNING. UNTESTED</div><div><br><=
/div><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"><span style=3D"color: #008=
;" class=3D"styled-by-prettify">template</span><span style=3D"color: #000;"=
class=3D"styled-by-prettify"> </span><span style=3D"color: #660;" class=3D=
"styled-by-prettify"><></span><span style=3D"color: #000;" class=3D"s=
tyled-by-prettify"> </span><span style=3D"color: #008;" class=3D"styled-by-=
prettify">struct</span><span style=3D"color: #000;" class=3D"styled-by-pret=
tify"> slim_future</span><span style=3D"color: #080;" class=3D"styled-by-pr=
ettify"><void></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 </span><span style=3D"color: #008;" class=3D"styled-by-pretti=
fy">struct</span><span style=3D"color: #000;" class=3D"styled-by-prettify">=
promise_type </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 coroutine_handle</span><span style=3D"color: #6=
60;" class=3D"styled-by-prettify"><></span><span style=3D"color: #000=
;" class=3D"styled-by-prettify"> parent</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">bool</span><span style=3D"color: =
#000;" class=3D"styled-by-prettify"> initial_suspend</span><span style=3D"c=
olor: #660;" class=3D"styled-by-prettify">()</span><span style=3D"color: #0=
00;" class=3D"styled-by-prettify"> </span><span style=3D"color: #660;" clas=
s=3D"styled-by-prettify">{</span><span style=3D"color: #000;" class=3D"styl=
ed-by-prettify"> </span><span style=3D"color: #008;" class=3D"styled-by-pre=
ttify">return</span><span style=3D"color: #000;" class=3D"styled-by-prettif=
y"> </span><span style=3D"color: #008;" class=3D"styled-by-prettify">true</=
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 </spa=
n><span style=3D"color: #008;" class=3D"styled-by-prettify">bool</span><spa=
n style=3D"color: #000;" class=3D"styled-by-prettify"> final_suspend</span>=
<span style=3D"color: #660;" class=3D"styled-by-prettify">()</span><span st=
yle=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"co=
lor: #660;" class=3D"styled-by-prettify">{</span><span style=3D"color: #000=
;" class=3D"styled-by-prettify"> </span><span style=3D"color: #008;" class=
=3D"styled-by-prettify">return</span><span style=3D"color: #000;" class=3D"=
styled-by-prettify"> </span><span style=3D"color: #008;" class=3D"styled-by=
-prettify">false</span><span style=3D"color: #660;" class=3D"styled-by-pret=
tify">;</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </=
span><span style=3D"color: #660;" class=3D"styled-by-prettify">}</span><spa=
n 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"=
>auto</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> get_=
return_object</span><span style=3D"color: #660;" class=3D"styled-by-prettif=
y">()</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"> </span><span style=3D"=
color: #008;" class=3D"styled-by-prettify">return</span><span style=3D"colo=
r: #000;" class=3D"styled-by-prettify"> slim_future</span><span style=3D"co=
lor: #080;" class=3D"styled-by-prettify"><void></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">this</span><span style=3D"color: #000;" class=3D"s=
tyled-by-prettify"> </span><span style=3D"color: #660;" class=3D"styled-by-=
prettify">};</span><span style=3D"color: #000;" class=3D"styled-by-prettify=
"> </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-pr=
ettify">void</span><span style=3D"color: #000;" class=3D"styled-by-prettify=
"> return_void</span><span style=3D"color: #660;" class=3D"styled-by-pretti=
fy">()</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"> </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;" cl=
ass=3D"styled-by-prettify">(</span><span style=3D"color: #000;" class=3D"st=
yled-by-prettify">parent</span><span style=3D"color: #660;" class=3D"styled=
-by-prettify">)</span><span style=3D"color: #000;" class=3D"styled-by-prett=
ify"> </span><span style=3D"color: #660;" class=3D"styled-by-prettify">{</s=
pan><span style=3D"color: #000;" class=3D"styled-by-prettify"> parent</span=
><span style=3D"color: #660;" class=3D"styled-by-prettify">.</span><span st=
yle=3D"color: #000;" class=3D"styled-by-prettify">resume</span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">();</span><span style=3D"col=
or: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #660;=
" class=3D"styled-by-prettify">}</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"> </span><span style=3D"color: #660;" class=3D"style=
d-by-prettify">}</span><span style=3D"color: #000;" class=3D"styled-by-pret=
tify"><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-pret=
tify"><br><br>=C2=A0 =C2=A0 coroutine_handle</span><span style=3D"color: #0=
80;" class=3D"styled-by-prettify"><promise_type></span><span style=3D=
"color: #000;" class=3D"styled-by-prettify"> h</span><span style=3D"color: =
#660;" class=3D"styled-by-prettify">;</span><span style=3D"color: #000;" cl=
ass=3D"styled-by-prettify"><br><br>=C2=A0 =C2=A0 slim_future</span><span st=
yle=3D"color: #660;" class=3D"styled-by-prettify">(</span><span style=3D"co=
lor: #000;" class=3D"styled-by-prettify">slim_future </span><span style=3D"=
color: #008;" class=3D"styled-by-prettify">const</span><span style=3D"color=
: #660;" class=3D"styled-by-prettify">&)</span><span style=3D"color: #0=
00;" class=3D"styled-by-prettify"> </span><span style=3D"color: #660;" clas=
s=3D"styled-by-prettify">=3D</span><span style=3D"color: #000;" class=3D"st=
yled-by-prettify"> </span><span style=3D"color: #008;" class=3D"styled-by-p=
rettify">delete</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 slim_future</span><span style=3D"color: #660;" class=3D"style=
d-by-prettify">(</span><span style=3D"color: #000;" class=3D"styled-by-pret=
tify">slim_future </span><span style=3D"color: #660;" class=3D"styled-by-pr=
ettify">&&</span><span style=3D"color: #000;" class=3D"styled-by-pr=
ettify"> 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: #660;" class=3D"styled-by-prettify">:</span><span st=
yle=3D"color: #000;" class=3D"styled-by-prettify"> h</span><span style=3D"c=
olor: #660;" class=3D"styled-by-prettify">(</span><span style=3D"color: #00=
0;" class=3D"styled-by-prettify">move</span><span style=3D"color: #660;" cl=
ass=3D"styled-by-prettify">(</span><span style=3D"color: #000;" class=3D"st=
yled-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=
">h</span><span style=3D"color: #660;" class=3D"styled-by-prettify">))</spa=
n><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span s=
tyle=3D"color: #660;" class=3D"styled-by-prettify">{</span><span style=3D"c=
olor: #000;" class=3D"styled-by-prettify"> rhs</span><span style=3D"color: =
#660;" class=3D"styled-by-prettify">.</span><span style=3D"color: #000;" cl=
ass=3D"styled-by-prettify">h </span><span style=3D"color: #660;" class=3D"s=
tyled-by-prettify">=3D</span><span style=3D"color: #000;" class=3D"styled-b=
y-prettify"> </span><span style=3D"color: #008;" class=3D"styled-by-prettif=
y">nullptr</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: #008;" class=3D"styled-by-prettify">explicit</span><spa=
n style=3D"color: #000;" class=3D"styled-by-prettify"> slim_future</span><s=
pan style=3D"color: #660;" class=3D"styled-by-prettify">(</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify">promise_type</span><span sty=
le=3D"color: #660;" class=3D"styled-by-prettify">*</span><span style=3D"col=
or: #000;" class=3D"styled-by-prettify"> me</span><span style=3D"color: #66=
0;" class=3D"styled-by-prettify">)</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"> </span><span style=3D"color: #660;" class=3D"style=
d-by-prettify">:</span><span style=3D"color: #000;" class=3D"styled-by-pret=
tify"> h</span><span style=3D"color: #660;" class=3D"styled-by-prettify">{<=
/span><span style=3D"color: #000;" class=3D"styled-by-prettify"> coroutine_=
handle</span><span style=3D"color: #080;" class=3D"styled-by-prettify"><=
promise_type></span><span style=3D"color: #660;" class=3D"styled-by-pret=
tify">::</span><span style=3D"color: #000;" class=3D"styled-by-prettify">fr=
om_promise</span><span style=3D"color: #660;" class=3D"styled-by-prettify">=
(</span><span style=3D"color: #000;" class=3D"styled-by-prettify">me</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: #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"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">slim_future</span><span style=3D"color: #660;" class=3D"styl=
ed-by-prettify">()</span><span style=3D"color: #000;" class=3D"styled-by-pr=
ettify"> </span><span style=3D"color: #660;" class=3D"styled-by-prettify">{=
</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> h</span><=
span style=3D"color: #660;" class=3D"styled-by-prettify">.</span><span styl=
e=3D"color: #000;" class=3D"styled-by-prettify">destroy</span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">();</span><span style=3D"col=
or: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #660;=
" class=3D"styled-by-prettify">}</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"><br><br>=C2=A0 =C2=A0 </span><span style=3D"color: =
#008;" class=3D"styled-by-prettify">bool</span><span style=3D"color: #000;"=
class=3D"styled-by-prettify"> await_ready</span><span style=3D"color: #660=
;" class=3D"styled-by-prettify">()</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"> </span><span style=3D"color: #660;" class=3D"style=
d-by-prettify">{</span><span style=3D"color: #000;" class=3D"styled-by-pret=
tify"> </span><span style=3D"color: #008;" class=3D"styled-by-prettify">ret=
urn</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span=
><span style=3D"color: #008;" class=3D"styled-by-prettify">false</span><spa=
n style=3D"color: #660;" class=3D"styled-by-prettify">;</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color=
: #660;" class=3D"styled-by-prettify">}</span><span style=3D"color: #000;" =
class=3D"styled-by-prettify"><br>=C2=A0 =C2=A0 </span><span style=3D"color:=
#008;" class=3D"styled-by-prettify">void</span><span style=3D"color: #000;=
" class=3D"styled-by-prettify"> await_suspend</span><span style=3D"color: #=
660;" class=3D"styled-by-prettify">(</span><span style=3D"color: #000;" cla=
ss=3D"styled-by-prettify">coroutine_handle</span><span style=3D"color: #080=
;" class=3D"styled-by-prettify"><promise_type></span><span style=3D"c=
olor: #000;" class=3D"styled-by-prettify"> parent</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"styled-b=
y-prettify"><br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 </span><span style=3D"color: #0=
08;" class=3D"styled-by-prettify">this</span><span style=3D"color: #660;" c=
lass=3D"styled-by-prettify">-></span><span style=3D"color: #000;" class=
=3D"styled-by-prettify">h</span><span style=3D"color: #660;" class=3D"style=
d-by-prettify">.</span><span style=3D"color: #000;" class=3D"styled-by-pret=
tify">promise</span><span style=3D"color: #660;" class=3D"styled-by-prettif=
y">().</span><span style=3D"color: #000;" class=3D"styled-by-prettify">pare=
nt </span><span style=3D"color: #660;" class=3D"styled-by-prettify">=3D</sp=
an><span style=3D"color: #000;" class=3D"styled-by-prettify"> parent</span>=
<span style=3D"color: #660;" class=3D"styled-by-prettify">;</span><span sty=
le=3D"color: #000;" class=3D"styled-by-prettify"><br>=C2=A0 =C2=A0 =C2=A0 =
=C2=A0 h</span><span style=3D"color: #660;" class=3D"styled-by-prettify">.<=
/span><span style=3D"color: #000;" class=3D"styled-by-prettify">resume</spa=
n><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">void</span><spa=
n style=3D"color: #000;" class=3D"styled-by-prettify"> await_resume</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: #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"st=
yled-by-prettify"><br></span></div></code></div><div><br><br></div><div>and=
here is a code to use in your main, test driver to await for async activit=
y to finish:</div><div><br></div><div class=3D"prettyprint" style=3D"border=
: 1px solid rgb(187, 187, 187); word-wrap: break-word; background-color: rg=
b(250, 250, 250);"><code class=3D"prettyprint"><div class=3D"subprettyprint=
"><span style=3D"color: #008;" class=3D"styled-by-prettify">template</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"=
color: #008;" class=3D"styled-by-prettify">typename</span><span style=3D"co=
lor: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #606=
;" class=3D"styled-by-prettify">Awaitable</span><span style=3D"color: #660;=
" class=3D"styled-by-prettify">></span><span style=3D"color: #000;" clas=
s=3D"styled-by-prettify"><br></span><span style=3D"color: #008;" class=3D"s=
tyled-by-prettify">auto</span><span style=3D"color: #000;" class=3D"styled-=
by-prettify"> sync_await</span><span style=3D"color: #660;" class=3D"styled=
-by-prettify">(</span><span style=3D"color: #606;" class=3D"styled-by-prett=
ify">Awaitable</span><span style=3D"color: #000;" class=3D"styled-by-pretti=
fy"> f</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 mutex m</s=
pan><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 cond=
ition_variable cv</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 </span><span style=3D"color: #008;" class=3D"styled-by-pret=
tify">bool</span><span style=3D"color: #000;" class=3D"styled-by-prettify">=
</span><span style=3D"color: #008;" class=3D"styled-by-prettify">done</spa=
n><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span s=
tyle=3D"color: #660;" class=3D"styled-by-prettify">=3D</span><span style=3D=
"color: #000;" class=3D"styled-by-prettify"> </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=
"styled-by-prettify"><br><br>=C2=A0 =C2=A0 </span><span style=3D"color: #00=
8;" class=3D"styled-by-prettify">auto</span><span style=3D"color: #000;" cl=
ass=3D"styled-by-prettify"> w </span><span style=3D"color: #660;" class=3D"=
styled-by-prettify">=3D</span><span style=3D"color: #000;" class=3D"styled-=
by-prettify"> </span><span style=3D"color: #660;" class=3D"styled-by-pretti=
fy">[&]()-></span><span style=3D"color: #000;" class=3D"styled-by-pr=
ettify">slim_future</span><span style=3D"color: #080;" class=3D"styled-by-p=
rettify"><void></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 await f</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"><br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 l=
ock_guard</span><span style=3D"color: #080;" class=3D"styled-by-prettify">&=
lt;mutex></span><span style=3D"color: #000;" class=3D"styled-by-prettify=
"> </span><span style=3D"color: #008;" class=3D"styled-by-prettify">lock</s=
pan><span style=3D"color: #660;" class=3D"styled-by-prettify">(</span><span=
style=3D"color: #000;" class=3D"styled-by-prettify">m</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">don=
e</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 st=
yle=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"co=
lor: #008;" class=3D"styled-by-prettify">true</span><span style=3D"color: #=
660;" class=3D"styled-by-prettify">;</span><span style=3D"color: #000;" cla=
ss=3D"styled-by-prettify"><br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 </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 =C2=A0 =C2=A0 cv</=
span><span style=3D"color: #660;" class=3D"styled-by-prettify">.</span><spa=
n style=3D"color: #000;" class=3D"styled-by-prettify">notify_one</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 sty=
le=3D"color: #000;" class=3D"styled-by-prettify"><br>=C2=A0 =C2=A0 w</span>=
<span style=3D"color: #660;" class=3D"styled-by-prettify">.</span><span sty=
le=3D"color: #000;" class=3D"styled-by-prettify">await_suspend</span><span =
style=3D"color: #660;" class=3D"styled-by-prettify">(</span><span style=3D"=
color: #008;" class=3D"styled-by-prettify">nullptr</span><span style=3D"col=
or: #660;" class=3D"styled-by-prettify">);</span><span style=3D"color: #000=
;" class=3D"styled-by-prettify"><br><br>=C2=A0 =C2=A0 unique_lock</span><sp=
an style=3D"color: #080;" class=3D"styled-by-prettify"><mutex></span>=
<span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span sty=
le=3D"color: #008;" class=3D"styled-by-prettify">lock</span><span style=3D"=
color: #660;" class=3D"styled-by-prettify">(</span><span style=3D"color: #0=
00;" class=3D"styled-by-prettify">m</span><span style=3D"color: #660;" clas=
s=3D"styled-by-prettify">);</span><span style=3D"color: #000;" class=3D"sty=
led-by-prettify"><br>=C2=A0 =C2=A0 cv</span><span style=3D"color: #660;" cl=
ass=3D"styled-by-prettify">.</span><span style=3D"color: #000;" class=3D"st=
yled-by-prettify">wait</span><span style=3D"color: #660;" class=3D"styled-b=
y-prettify">(</span><span style=3D"color: #008;" class=3D"styled-by-prettif=
y">lock</span><span style=3D"color: #660;" class=3D"styled-by-prettify">,</=
span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><spa=
n style=3D"color: #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"> </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: #008;" class=3D"styled-by=
-prettify">done</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><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></span></div></code></div><div>=
<br>And when thinking through the cases, consider the example of heap elisi=
on I showed earlier in the thread. Compiler has no idea about generators, a=
sync, futures, etc.</div><div>It only looks at what happens to coroutine ha=
ndles locally in this function. Thus you understood how heap elision works =
for the generator, you can observe that compiler will see the same sequence=
of operation on coroutine handle for await f(); where f() returns slim fut=
ure.</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_973_2122108922.1445119857983--
------=_Part_972_1037351004.1445119857982--
.
Author: Evgeny Panasyuk <evgeny.panasyuk@gmail.com>
Date: Sat, 17 Oct 2015 23:51:09 -0700 (PDT)
Raw View
------=_Part_927_1213310975.1445151069825
Content-Type: multipart/alternative;
boundary="----=_Part_928_1211755242.1445151069826"
------=_Part_928_1211755242.1445151069826
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
17 October 2015 =D0=B3., 20:07:12 UTC+3 Nicol Bolas:
>
> On Saturday, October 17, 2015 at 11:43:32 AM UTC-4, Evgeny Panasyuk wrote=
:
>>
>> 17 October 2015 =D0=B3., 16:31:25 UTC+3 Nicol Bolas:
>>
>>> P0057 is the result of numerous revisions of an idea, across several=20
>>> years, as well as with lots of implementation experience. Why should we=
=20
>>> impair such a design just because you think that, one day, someone=20
>>> *might* propose a better one?=20
>>>
>>
>> Yes, better design is possible.
>> But that is not the only issue - if there will be big overhead, it would=
=20
>> have limited usability. As Giovanni mentioned above, if performance is n=
ot=20
>> an issue - stackful coroutines would cover most of use cases of slow=20
>> stackless coroutines.
>>
>
> I don't understand you rhetoric here. On the one hand, you claim that=20
> there is "big overhead" and that P0057 are "slow stackless coroutines." Y=
et=20
> later, you specifically state that "Again, I should prepare detailed repo=
rt=20
> (in order for it to have real effect)". Which means that you, as of yet,=
=20
> have no actual evidence that overhead is "big" or that P0057 is "slow".
>
No. this is wrong conclusion. "need to make detailed report" !=3D "I don't=
=20
have any evidence".
=20
> You have repeatedly made the positive claims that P0057 is "slow", that i=
t=20
> has "big overhead". It's time to put up or shut up: present your evidence=
=20
> for these claims, or we should consider your statements to be at best=20
> conjecture.
>
> Note: "evidence" means actual evidence. Not "well, if you do this, the=20
> optimizer might not work" or whatever. Actual, good-faith evidence.
>
> There is apparently an implementation of P0114. And there is an=20
> implementation of await. Use them to provide us with evidence of your=20
> claims.
>
Here is an example:
auto numbers(int n)
{
for (int i =3D 0; i !=3D n; ++i)
yield i;
}
int main()
{
unsigned res =3D 0;
auto &&xs =3D numbers(1 << 30);
{
boost::progress_timer t;
for (auto x : xs)
res +=3D x;
}
cout << res << endl;
}
I made two variants. One is P0057 yield/generator, another one is similar=
=20
code based on Boost.Asio stackless coroutine macros.
I used VS2015 x64 for both cases.
P0057 version has allocation, i.e. even for this simple case elision=20
trickery is not implemented. But I do not measure allocation, I just=20
measure inner loop. Macro version is 4.57x faster. And note, macro version=
=20
is far from being optimal in a sense that with compiler support it is=20
possible to get even better result.
=20
> =20
>
>>
>>> You said that you do not want to change mechanics of function signature=
..
>>
>
> No, what I didn't want was for a function signature to *lie*. Where it=20
> magically is transformed into a struct, or the return type gets replaced =
by=20
> something else or some such.
>
What about case with "auto" return type, where it is generated via=20
specialization of coroutine_traits?
If in this case you still would say that "it is replaced by something else"=
=20
- then how it differs from P0057:
auto foo(int x)
{
yield x;
}
Here return type is not int.
=20
> And that part is what keeps tripping you up. Because if you insist on=20
> being able to return a compiler-generated type (whether it's directly or=
=20
> stored in the return object), there is no way to specify such a thing in=
=20
> C++. And therefore, there is going to have to be some place where you=20
> *cheat*.
>
Why returning generator in P0057 (when it's "result type" is auto) is not=
=20
cheating? And why returning traits<tag, params...>::type is cheating? What=
=20
is the principal difference?
=20
> =20
>
>> And no, your approach is not "closer" to P0057. It's farther. The return=
=20
>>> type is a coroutine now, not a future, or generator, or other user-defi=
ned=20
>>> type. It's an actual coroutine.
>>>
>>
>> No, I mean that actual return type would be specified by specialization=
=20
>> of coroutine_traits.
>>
>
> Which is rather the opposite of how P0057 works, where the return type is=
=20
> the return type, and the promise type is *deduced* from that.
>
> So again, you're deviating farther from P0057, not closer.
>
Hm, how any change in existing text is supposed to deviate closer to it?
=20
>
> That's not how P0057 works. Indeed, that's not what P0057 is *for*.=20
>>> Remember the general idea of await in P0057: it halts the function, but=
it=20
>>> also *explicitly* allows the transfer of control of the function to the=
*await=20
>>> expression*. And thus, control is not necessarily transferred to the=20
>>> return value.
>>>
>>
>> Yes, of course, it does not have to.=20
>>
>
> So... how do you do it? In P0057, it happens through `await_suspend`,=20
> which takes a coroutine_handle<>. So in your idea, how does it work?
>
For example await_suspend can be function template which takes concrete=20
coroutine.=20
=20
>
> Oh sure, you use different keywords. But the behavior of those keywords i=
s=20
>>> basically the behavior of the functions P0114 implements. Basically, P0=
114=20
>>> is what you want, even if you would prefer that the form appeared more =
like=20
>>> P0057.
>>>
>>
>> Personally I prefer P0114 - it is more powerful, gives less overhead, an=
d=20
>> shifts from concrete await or yield features towards more general langua=
ge=20
>> feature.
>> But if P0057 is much more likely to get into ISO, then I would like to=
=20
>> remove discussed overhead.
>>
>
> Here's my problem with that notion.
>
> What you really want is P0114. But you don't believe that it'll make it=
=20
> in. So instead, you propose suggestions to change P0057. Which will in th=
e=20
> end... turn it into a *gimped* version of P0114.
>
P0114 is much more powerful than changes I propose.
=20
>
> What P0114 fails is at .then-style continuations.
>
Why?
I already showed example of List Monad which is exactly .then-style.
There is already example within Boost.Asio which uses macro-based stackless=
=20
coroutine for .then style IO.
--=20
---=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.
------=_Part_928_1211755242.1445151069826
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
17 October 2015 =D0=B3., 20:07:12 UTC+3 Nicol Bolas:<blockquote class=3D"gm=
ail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc soli=
d;padding-left: 1ex;"><div dir=3D"ltr">On Saturday, October 17, 2015 at 11:=
43:32 AM UTC-4, Evgeny Panasyuk wrote:<blockquote class=3D"gmail_quote" sty=
le=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-left:1e=
x"><div dir=3D"ltr">17 October 2015 =D0=B3., 16:31:25 UTC+3 Nicol Bolas:<br=
><blockquote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;bord=
er-left:1px #ccc solid;padding-left:1ex"><div>P0057 is the result of numero=
us revisions of an idea, across several years, as well as with lots of impl=
ementation experience. Why should we impair such a design just because you =
think that, one day, someone <i>might</i> propose a better one? <br></div><=
/blockquote><div><br>Yes, better design is possible.<br>But that is not the=
only issue - if there will be big overhead, it would have limited usabilit=
y. As Giovanni mentioned above, if performance is not an issue - stackful c=
oroutines would cover most of use cases of slow stackless coroutines.<br></=
div></div></blockquote><div><br>I don't understand you rhetoric here. O=
n the one hand, you claim that there is "big overhead" and that P=
0057 are "slow stackless coroutines." Yet later, you specifically=
state that "Again, I should prepare detailed report (in order for it =
to have real effect)". Which means that you, as of yet, have no actual=
evidence that overhead is "big" or that P0057 is "slow"=
;.<br></div></div></blockquote><div><br>No. this is wrong conclusion. "=
;need to make detailed report" !=3D "I don't have any evidenc=
e".<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;"><div d=
ir=3D"ltr"><div>You have repeatedly made the positive claims that P0057 is =
"slow", that it has "big overhead". It's time to pu=
t up or shut up: present your evidence for these claims, or we should consi=
der your statements to be at best conjecture.<br><br>Note: "evidence&q=
uot; means actual evidence. Not "well, if you do this, the optimizer m=
ight not work" or whatever. Actual, good-faith evidence.<br><br>There =
is apparently an implementation of P0114. And there is an implementation of=
await. Use them to provide us with evidence of your claims.<br></div></div=
></blockquote><div><br>Here is an example:<br><div class=3D"prettyprint" st=
yle=3D"background-color: rgb(250, 250, 250); border-color: rgb(187, 187, 18=
7); border-style: solid; border-width: 1px; word-wrap: break-word;"><code c=
lass=3D"prettyprint"><div class=3D"subprettyprint"><span style=3D"color: #0=
08;" class=3D"styled-by-prettify">auto</span><span style=3D"color: #000;" c=
lass=3D"styled-by-prettify"> numbers</span><span style=3D"color: #660;" cla=
ss=3D"styled-by-prettify">(</span><span style=3D"color: #008;" class=3D"sty=
led-by-prettify">int</span><span style=3D"color: #000;" class=3D"styled-by-=
prettify"> n</span><span style=3D"color: #660;" class=3D"styled-by-prettify=
">)</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br></s=
pan><span style=3D"color: #660;" class=3D"styled-by-prettify">{</span><span=
style=3D"color: #000;" class=3D"styled-by-prettify"><br>=C2=A0 =C2=A0 </sp=
an><span style=3D"color: #008;" class=3D"styled-by-prettify">for</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=
: #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-prettify">=3D</span><span style=3D"color: #000;" class=3D"sty=
led-by-prettify"> </span><span style=3D"color: #066;" class=3D"styled-by-pr=
ettify">0</span><span style=3D"color: #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">!=3D</span><span =
style=3D"color: #000;" class=3D"styled-by-prettify"> n</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">i</span><span style=3D"color: #660;" class=3D"styled-by-p=
rettify">)</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">yield</span><span style=3D"color: #000;" class=3D"s=
tyled-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=
"><br></span><span style=3D"color: #660;" class=3D"styled-by-prettify">}</s=
pan><span style=3D"color: #000;" class=3D"styled-by-prettify"><br><br></spa=
n><span style=3D"color: #008;" class=3D"styled-by-prettify">int</span><span=
style=3D"color: #000;" class=3D"styled-by-prettify"> main</span><span styl=
e=3D"color: #660;" class=3D"styled-by-prettify">()</span><span style=3D"col=
or: #000;" class=3D"styled-by-prettify"><br></span><span style=3D"color: #6=
60;" class=3D"styled-by-prettify">{</span><span style=3D"color: #000;" clas=
s=3D"styled-by-prettify"><br>=C2=A0 =C2=A0 </span><span style=3D"color: #00=
8;" class=3D"styled-by-prettify">unsigned</span><span style=3D"color: #000;=
" class=3D"styled-by-prettify"> res </span><span style=3D"color: #660;" cla=
ss=3D"styled-by-prettify">=3D</span><span style=3D"color: #000;" class=3D"s=
tyled-by-prettify"> </span><span style=3D"color: #066;" class=3D"styled-by-=
prettify">0</span><span style=3D"color: #660;" class=3D"styled-by-prettify"=
>;</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br>=C2=
=A0 =C2=A0 </span><span style=3D"color: #008;" class=3D"styled-by-prettify"=
>auto</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </sp=
an><span style=3D"color: #660;" class=3D"styled-by-prettify">&&</sp=
an><span style=3D"color: #000;" class=3D"styled-by-prettify">xs </span><spa=
n style=3D"color: #660;" class=3D"styled-by-prettify">=3D</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"> numbers</span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">(</span><span style=3D"color=
: #066;" class=3D"styled-by-prettify">1</span><span style=3D"color: #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"st=
yled-by-prettify"> </span><span style=3D"color: #066;" class=3D"styled-by-p=
rettify">30</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>=C2=
=A0 =C2=A0 =C2=A0 =C2=A0 boost</span><span style=3D"color: #660;" class=3D"=
styled-by-prettify">::</span><span style=3D"color: #000;" class=3D"styled-b=
y-prettify">progress_timer t</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 </span><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"style=
d-by-prettify">(</span><span style=3D"color: #008;" class=3D"styled-by-pret=
tify">auto</span><span style=3D"color: #000;" class=3D"styled-by-prettify">=
x </span><span style=3D"color: #660;" class=3D"styled-by-prettify">:</span=
><span style=3D"color: #000;" class=3D"styled-by-prettify"> xs</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 res </span><span style=3D"color: #660;" class=3D"styled-by-pr=
ettify">+=3D</span><span style=3D"color: #000;" class=3D"styled-by-prettify=
"> x</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: #660;" class=3D"styled-by-prettify">}</spa=
n><span style=3D"color: #000;" class=3D"styled-by-prettify"><br>=C2=A0 =C2=
=A0 cout </span><span style=3D"color: #660;" class=3D"styled-by-prettify">&=
lt;<</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> re=
s </span><span style=3D"color: #660;" class=3D"styled-by-prettify"><<=
</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> endl</spa=
n><span style=3D"color: #660;" class=3D"styled-by-prettify">;</span><span s=
tyle=3D"color: #000;" class=3D"styled-by-prettify"><br></span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">}</span><span style=3D"color=
: #000;" class=3D"styled-by-prettify"><br></span></div></code></div>I made =
two variants. One is P0057 yield/generator, another one is similar code bas=
ed on Boost.Asio stackless coroutine macros.<br>I used VS2015 x64 for both =
cases.<br>P0057 version has allocation, i.e. even for this simple case elis=
ion trickery is not implemented. But I do not measure allocation, I just me=
asure inner loop. Macro version is 4.57x faster. And note, macro version is=
far from being optimal in a sense that with compiler support it is possibl=
e to get even better result.<br>=C2=A0</div><div></div><blockquote class=3D=
"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc s=
olid;padding-left: 1ex;"><div dir=3D"ltr"><div>=C2=A0</div><blockquote clas=
s=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc =
solid;padding-left:1ex"><div dir=3D"ltr"><div></div><blockquote class=3D"gm=
ail_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;p=
adding-left:1ex"><div></div><br></blockquote><div>You said that you do not =
want to change mechanics of function signature.</div></div></blockquote><di=
v><br>No, what I didn't want was for a function signature to <i>lie</i>=
.. Where it magically is transformed into a struct, or the return type gets =
replaced by something else or some such.<br></div></div></blockquote><div><=
br>What about case with "auto" return type, where it is generated=
via specialization of coroutine_traits?<br>If in this case you still would=
say that "it is replaced by something else" - then how it differ=
s from P0057:<br><code class=3D"prettyprint"><span style=3D"color: #008;" c=
lass=3D"styled-by-prettify">auto</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"> foo</span><span style=3D"color: #660;" class=3D"st=
yled-by-prettify">(</span><span style=3D"color: #008;" class=3D"styled-by-p=
rettify">int</span><span style=3D"color: #000;" class=3D"styled-by-prettify=
"> x</span><span style=3D"color: #660;" class=3D"styled-by-prettify">)</spa=
n><span style=3D"color: #000;" class=3D"styled-by-prettify"><br></span><spa=
n style=3D"color: #660;" class=3D"styled-by-prettify">{</span><span style=
=3D"color: #000;" 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 st=
yle=3D"color: #008;" class=3D"styled-by-prettify">yield</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"> x</span><span style=3D"colo=
r: #660;" class=3D"styled-by-prettify">;</span><span style=3D"color: #000;"=
class=3D"styled-by-prettify"><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></code>Here return type is not int.<br><br>=C2=A0=
</div><blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8=
ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr"><div>An=
d that part is what keeps tripping you up. Because if you insist on being a=
ble to return a compiler-generated type (whether it's directly or store=
d in the return object), there is no way to specify such a thing in C++. An=
d therefore, there is going to have to be some place where you <i>cheat</i>=
..<br></div></div></blockquote><div><br>Why returning generator in P0057 (wh=
en it's "result type" is auto) is not cheating? And why retur=
ning traits<tag, params...>::type is cheating? What is the principal =
difference?<br>=C2=A0</div><blockquote class=3D"gmail_quote" style=3D"margi=
n: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><di=
v dir=3D"ltr"><div>=C2=A0</div><blockquote class=3D"gmail_quote" style=3D"m=
argin:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-left:1ex"><div=
dir=3D"ltr"><blockquote class=3D"gmail_quote" style=3D"margin:0;margin-lef=
t:0.8ex;border-left:1px #ccc solid;padding-left:1ex"><div>And no, your appr=
oach is not "closer" to P0057. It's farther. The return type =
is a coroutine now, not a future, or generator, or other user-defined type.=
It's an actual coroutine.<br></div></blockquote><div><br>No, I mean th=
at actual return type would be specified by specialization of coroutine_tra=
its.<br></div></div></blockquote><div><br>Which is rather the opposite of h=
ow P0057 works, where the return type is the return type, and the promise t=
ype is <i>deduced</i> from that.<br><br>So again, you're deviating fart=
her from P0057, not closer.<br></div></div></blockquote><div><br>Hm, how an=
y change in existing text is supposed to deviate closer to it?<br>=C2=A0</d=
iv><blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;=
border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr"><div></div=
><div><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"><b=
lockquote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-=
left:1px #ccc solid;padding-left:1ex"><div>That's not how P0057 works. =
Indeed, that's not what P0057 is <i>for</i>. Remember the general idea =
of await in P0057: it halts the function, but it also <i>explicitly</i> all=
ows the transfer of control of the function to the <i>await expression</i>.=
And thus, control is not necessarily transferred to the return value.<br><=
/div></blockquote><div><br>Yes, of course, it does not have to. <br></div><=
/div></blockquote><div><br>So... how do you do it? In P0057, it happens thr=
ough `await_suspend`, which takes a coroutine_handle<>. So in your id=
ea, how does it work?<br></div></div></blockquote><div><br>For example awai=
t_suspend can be function template which takes concrete coroutine. <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;"><div dir=3D"ltr"><div=
><br></div><blockquote class=3D"gmail_quote" style=3D"margin:0;margin-left:=
0.8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><div></=
div><blockquote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;b=
order-left:1px #ccc solid;padding-left:1ex"><div>Oh sure, you use different=
keywords. But the behavior of those keywords is basically the behavior of =
the functions P0114 implements. Basically, P0114 is what you want, even if =
you would prefer that the form appeared more like P0057.<br></div></blockqu=
ote><div><br>Personally I prefer P0114 - it is more powerful, gives less ov=
erhead, and shifts from concrete await or yield features towards more gener=
al language feature.<br>But if P0057 is much more likely to get into ISO, t=
hen I would like to remove discussed overhead.<br></div></div></blockquote>=
<div><br>Here's my problem with that notion.<br><br>What you really wan=
t is P0114. But you don't believe that it'll make it in. So instead=
, you propose suggestions to change P0057. Which will in the end... turn it=
into a <i>gimped</i> version of P0114.<br></div></div></blockquote><div><b=
r>P0114 is much more powerful than changes I propose.<br>=C2=A0</div><block=
quote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-le=
ft: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr"><div><br>What P0114=
fails is at .then-style continuations.<br></div></div></blockquote><div><b=
r>Why?<br>I already showed example of List Monad which is exactly .then-sty=
le.<br>There is already example within Boost.Asio which uses macro-based st=
ackless coroutine for .then style IO.<br></div>
<p></p>
-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />
------=_Part_928_1211755242.1445151069826--
------=_Part_927_1213310975.1445151069825--
.
Author: Evgeny Panasyuk <evgeny.panasyuk@gmail.com>
Date: Sun, 18 Oct 2015 00:02:31 -0700 (PDT)
Raw View
------=_Part_8_1605409407.1445151751226
Content-Type: multipart/alternative;
boundary="----=_Part_9_1341253155.1445151751226"
------=_Part_9_1341253155.1445151751226
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
17 October 2015 =D0=B3., 19:30:02 UTC+3 Nicol Bolas:
>
>
> * Equal functionality to P0057 (P0114 makes .then continuations difficult=
).
>
Why? What is principal limitation for .then?
=20
>
> * Syntax does not favor typed or type-erasure. That is, you pick one base=
d=20
> solely on your needs, not on how difficult it is to use (P0114 fails here=
,=20
> as type-erasure requires lots of explicit user effort).
>
What kind of "lots of explicit user effort"? Does using *ready*=20
std::function for lambdas results in "lots of explicit user effort"?
--=20
---=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.
------=_Part_9_1341253155.1445151751226
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">17 October 2015 =D0=B3., 19:30:02 UTC+3 Nicol Bolas:<block=
quote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-le=
ft: 1px #ccc solid;padding-left: 1ex;"><br><div>* Equal functionality to P0=
057 (P0114 makes .then continuations difficult).<br></div></blockquote><div=
><br>Why? What is principal limitation for .then?<br>=C2=A0</div><blockquot=
e class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-left: =
1px #ccc solid;padding-left: 1ex;"><div><br>* Syntax does not favor typed o=
r type-erasure. That is, you pick one based solely on your needs, not on ho=
w difficult it is to use (P0114 fails here, as type-erasure requires lots o=
f explicit user effort).<br></div></blockquote><div><br>What kind of "=
lots of explicit user effort"? Does using *ready* std::function for la=
mbdas results in "lots of explicit user effort"?<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_9_1341253155.1445151751226--
------=_Part_8_1605409407.1445151751226--
.
Author: Evgeny Panasyuk <evgeny.panasyuk@gmail.com>
Date: Sun, 18 Oct 2015 00:14:01 -0700 (PDT)
Raw View
------=_Part_879_322501255.1445152441324
Content-Type: multipart/alternative;
boundary="----=_Part_880_1492620558.1445152441324"
------=_Part_880_1492620558.1445152441324
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
17 October 2015 =D0=B3., 21:31:36 UTC+3 Gor Nishanov:
>
> On Saturday, October 17, 2015 at 10:28:25 AM UTC-7, Evgeny Panasyuk wrote=
:
>>
>> Well, to be really widely useful - we need copyability, movability, etc.=
=20
>> Without this things like for example list monad
>>
>
> If you'd like to help getting your ideas through the committee, I would=
=20
> suggest the following approach.
>
> Start with a real problem that is hard to do today.
> Show a good faith best solution to the problem how it can be done today=
=20
> without feature X.
> Show, how using a particular language/library feature you want to add can=
=20
> make solving that problem simpler/less-error-prone/faster/etc.
> Grab clang and prototype your ideas and try them out.
> If you like the result, write a paper and start the ball rolling.
>
Thanks for suggestion. Yes, I am already thinking about this.
Perhaps I would start from macro-based emulation - it already works today,=
=20
just need to put it into right shape.
--=20
---=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.
------=_Part_880_1492620558.1445152441324
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
17 October 2015 =D0=B3., 21:31:36 UTC+3 Gor Nishanov:<blockquote class=3D"g=
mail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc sol=
id;padding-left: 1ex;"><div dir=3D"ltr">On Saturday, October 17, 2015 at 10=
:28:25 AM UTC-7, Evgeny Panasyuk wrote:<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>Well, to be really widely useful - we need copyab=
ility, movability, etc. Without this things like for example list monad</di=
v></div></blockquote><div><br></div><div>If you'd like to help getting =
your ideas through the committee, I would suggest the following approach.</=
div><div><br></div><div>Start with a real problem that is hard to do today.=
</div><div>Show a good faith best solution to the problem how it can be don=
e today without feature X.<br></div><div>Show, how using a particular langu=
age/library feature you want to add can make solving that problem simpler/l=
ess-error-prone/<wbr>faster/etc.</div><div>Grab clang and prototype your id=
eas and try them out.<br></div><div>If you like the result, write a paper a=
nd start the ball rolling.</div></div></blockquote><div><br>Thanks for sugg=
estion. Yes, I am already thinking about this.<br>Perhaps I would start fro=
m macro-based emulation - it already works today, just need to put it into =
right shape.<br></div>
<p></p>
-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />
------=_Part_880_1492620558.1445152441324--
------=_Part_879_322501255.1445152441324--
.
Author: Evgeny Panasyuk <evgeny.panasyuk@gmail.com>
Date: Sun, 18 Oct 2015 00:57:29 -0700 (PDT)
Raw View
------=_Part_925_1780718661.1445155049971
Content-Type: multipart/alternative;
boundary="----=_Part_926_556295803.1445155049972"
------=_Part_926_556295803.1445155049972
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
17 October 2015 =D0=B3., 22:52:31 UTC+3 Nicol Bolas:
>
> On Saturday, October 17, 2015 at 1:28:25 PM UTC-4, Evgeny Panasyuk wrote:
>>
>> 17 October 2015 =D0=B3., 18:08:53 UTC+3 Nicol Bolas:
>>>
>>> And even when they can't, *you* can optimize them out with a decent=20
>>>>> allocator.
>>>>>
>>>>
>>>> First of all, I don't want to use custom allocators for simple things=
=20
>>>> like generators. Second, even custom allocator is not zero-overhead - =
at=20
>>>> least it must check size, because it is not known at compile time.
>>>>
>>>
>>> You are genuinely and seriously claiming that a conditional branch base=
d=20
>>> on two numbers constitutes "overhead". And this overhead is so incredib=
ly=20
>>> *burdensome* (despite only happening in the generator's initialization)=
=20
>>> that any and all language changes to remove said overhead are completel=
y=20
>>> justified.
>>>
>>
>> This is not the only overhead.
>> If you create array of structs that contain coroutine inside
>>
>
> Hold it. In order to store a typed coroutine, you must be able to copy=20
> and/or move it. Correct? So... how do you do that?
>
=20
No, you don't need to copy/move it. You can create array (not std::vector)=
=20
of non-copyable and non-moveable things.
I checked through P0114, and its coroutines are immobile by design. Always.=
=20
> So you can't rely on that.
>
> Wrong, it is not by design. They are immobile only to prevent possible=20
subtle errors with local references. Copy/move can be easily enabled for=20
P0114. And this is already mentioned at 10.1.
=20
> Even if we allow copying/moving in cases, it would only be in cases where=
:
>
> 1: All parameters to the function are copy/moveable.
>
> 2: All automatic variables declared are copy/moveable.
>
> 3: The promise type and return types are copy/moveable (though the latter=
=20
> is necessitated by P0057).
>
> So if my function takes a `const std::string &`, it's immobile.
>
Right - whole object is automatically moveable/copyable if it's parts are=
=20
moveable/copyable.
=20
> If my function does a `for(auto &x : vec)`, it's immobile. And so on.
>
> So those are the requirements for any coroutine callstack you plan on=20
> sticking in an object. And unless you can come up with a way to copy=20
> references (or any user-defined immobile type for that matter), these rul=
es=20
> are inviolate.
>
I don't see problem here. Yes - you can't copy/move something with immobile=
=20
parts, yes there are limitations. But I do want copy/move when parts are=20
mobile.
=20
> =20
>
>> The performance of a generator that returns integers on a fixed range is=
=20
>>> *irrelevant*. Nobody in their right mind is going to use generators for=
=20
>>> that. We have *ranges* for that.=20
>>>
>>
>>> The purpose of a generator, in a *real application*, is to be able to=
=20
>>> have a process take an arbitrary amount of time. You get a value from t=
hat=20
>>> process, then you do something, then get another. Until the next value =
is=20
>>> available, your process stops. That's the idea.
>>>
>> =20
>> That's not the only case. For instance consider "flatten" generator whic=
h=20
>> takes things like container1<container2<T>> and gives linear sequence of=
T=20
>> values - it is hard to do it proper manually, at least much harder than=
=20
>> with yield/generator.
>>
>
> I guess ranges aren't functional enough for some people ;)
>
I am not sure what you mean. I do use ranges, and I do implement ranges.=20
And some implementations are much easier with yield coroutines than with=20
hand-made state-machine. Just try to implement flatten iterator.
=20
>
> If the cost of generating that value is non-trivial, then the cost of the=
=20
>>> virtual call to do said generation is negligible.
>>>
>> If the cost of *using* that value is non-trivial, then the cost of the=
=20
>>> virtual call is again irrelevant.
>>>
>>
>> virtual calls makes inlining much harder, i.e. prevents further=20
>> optimizations.
>>
>
> If the code implementing the potentially inlined function is non-trivial,=
=20
> then the compiler wouldn't try to inline it.
>
Obviously inlining is not just "call" optimization, it allows to fuse=20
different code parts. Yes, there are cases where compiler by default would=
=20
not try to inline some function. And what?
P0057 by design makes it much harder for compilers to perform inlining.
=20
>
> The overhead here is only "huge" if your generators *and* processing code=
=20
>>> are so trivial that your code would be written better as a straight-up=
=20
>>> range-based for loop.
>>>
>>
>> Why better? Yield simplifies a lot of cases like "flatten".
>>
>
> Let's assume that's true.
>
> Most uses of "flatten" would be of the form `for await(const auto &x :=20
> generator_call())`. Which will be optimized just fine.
> =20
>
That's the thing about the simple cases. They're so simple that they're=20
> almost always going to be optimized away. It's the complex ones that won'=
t=20
> be, and the code to execute them will be the primary limiting factor in=
=20
> profiling.
>
Just try to use VS2015 yield, and check what it does even for simple cases.
=20
> Not only that, there is no way to put `flatten` into a struct. Why?=20
> Because it will almost certainly take its object *by reference*. So its=
=20
> resulting coroutine type will be immobile. And therefore, you can't make =
it=20
> a structure member.
>
Just take pointer or reference_wrapper. Or it could be stored internally as=
=20
a pointer.
=20
>
> So you can't even adjust the `flatten` case to put it in a struct.
>
> It can be even used as drop-in emulation of list comprehension (as far as=
=20
>> I remember this was even mentioned in one of earlier versions of P0057).
>> And I want to use convenient features even in code with performance=20
>> requirements. This is one of main C++ strength.
>>
>
> And you can.
>
Intrinsic overhead of some feature would prevent me from using it in code=
=20
with performance requirements.
=20
>
>
>> Yes, I agree. But in this case we indeed have "needlessly add undue=20
>> overhead", which can be avoided, and should be avoided in order to incre=
ase=20
>> applicability.
>>
>
> Every attempt you've made to upgrade P0057 to add this functionality=20
> negatively impacts the resulting language. You're either making classes=
=20
> look like function definitions or transforming function return types behi=
nd=20
> peoples backs or something else.
>
>
P0057 already does some transformation behinds peoples backs. Just write=20
"auto test() { yield 1; }" - and you magically would get=20
std::generator<int> result type. Why it's better than=20
std::coroutine_traits<signature>::type?=20
And it is not that I just randomly select proposal and trying to blindly=20
>> apply "zero-overhead doctrine". I knew that it should be nearly-zero=20
>> overhead exactly in this place, long before I read this proposal.
>>
>
> And P0057 is "nearly-zero overhead".
>
No. It has intrinsic extra allocation, intrinsic extra indirect call, and=
=20
intrinsic additional indirection in case of array of things with coroutine=
=20
inside.
=20
>
> You have a very narrow view of "same design".
>
> To me, a design *feature* of P0057 is that the function is what it says=
=20
> it is. The feature is very carefully designed to do this. That's why it=
=20
> doesn't return the promise type, or otherwise expose that to the user.
>
> If you start mucking around with the call signature, transforming the=20
> return type into something else, then it's not "almost" the same design.=
=20
> It's a different design.
>
P0057 already "mucking around with the call signature".
=20
>
> I don't understand how you can come so close to my point yet keep missing=
=20
> it.
>
> P0057 exists for the *primary purpose* of transferring control to someone=
=20
> other than the caller. That's its main use case and the reason why it was=
=20
> proposed in the first place. That's the problem it exists to solve.
>
This was actually first motivated use case of Boost.Asio stackless=20
coroutine macros - to transfer control to someone other than caller.
=20
>
> Without this things like for example list monad or software transactional=
=20
>> memory cannot be implemented.
>>
>
> Why do we want to implement "list monad"s? C++ is not a functional=20
> language.
>
Yes, I don't think list monad is useful example, need to find better one -=
=20
for instance fork (already used in one of Boost.Asio examples).
List monad is just easy way to show what is impossible without copyability.
=20
> It's bad enough that P0057 is going to lead to a rash of functional-C++=
=20
> programmers using `await` on `expected` objects...
>
>
Well, authors of P0057 did explicitly mention such use cases like optional,=
=20
expected, etc:
https://github.com/boostcon/cppnow_presentations_2015/blob/master/files/Cpp=
Now2015_Coroutines_in_C%2B%2B17.pdf
=20
> And isn't transactional memory already being built into another TS? What=
=20
> does that have to do with resumable functions?
>
It could be made on top of it. And for instance in Haskell it is=20
implemented with STM monad.=20
--=20
---=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.
------=_Part_926_556295803.1445155049972
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
17 October 2015 =D0=B3., 22:52:31 UTC+3 Nicol Bolas:<blockquote class=3D"gm=
ail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc soli=
d;padding-left: 1ex;">On Saturday, October 17, 2015 at 1:28:25 PM UTC-4, Ev=
geny Panasyuk 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=
">17 October 2015 =D0=B3., 18:08:53 UTC+3 Nicol Bolas:<blockquote class=3D"=
gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid=
;padding-left:1ex"><blockquote class=3D"gmail_quote" style=3D"margin:0;marg=
in-left:0.8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"=
><div> </div><blockquote class=3D"gmail_quote" style=3D"margin:0;margin-lef=
t:0.8ex;border-left:1px #ccc solid;padding-left:1ex"><div>And even when the=
y can't, <i>you</i> can optimize them out with a decent allocator.<br><=
/div></blockquote><div><br>First of all, I don't want to use custom all=
ocators for simple things like generators. Second, even custom allocator is=
not zero-overhead - at least it must check size, because it is not known a=
t compile time.<br></div></div></blockquote><div><br>You are genuinely and =
seriously claiming that a conditional branch based on two numbers constitut=
es "overhead". And this overhead is so incredibly <i>burdensome</=
i> (despite only happening in the generator's initialization) that any =
and all language changes to remove said overhead are completely justified.<=
br></div></blockquote><div><br>This is not the only overhead.<br>If you cre=
ate array of structs that contain coroutine inside</div></div></blockquote>=
<div><br>Hold it. In order to store a typed coroutine, you must be able to =
copy and/or move it. Correct? So... how do you do that?<br></div></blockquo=
te><div>=C2=A0<br>No, you don't need to copy/move it. You can create ar=
ray (not std::vector) of non-copyable and non-moveable things.<br><br></div=
><blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;bo=
rder-left: 1px #ccc solid;padding-left: 1ex;"><div>I checked through P0114,=
and its coroutines are immobile by design. Always. So you can't rely o=
n that.<br><br></div></blockquote><div>Wrong, it is not by design. They are=
immobile only to prevent possible subtle errors with local references. Cop=
y/move can be easily enabled for P0114. And this is already mentioned at 10=
..1.<br>=C2=A0</div><blockquote class=3D"gmail_quote" style=3D"margin: 0;mar=
gin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div>Even i=
f we allow copying/moving in cases, it would only be in cases where:<br><br=
>1: All parameters to the function are copy/moveable.<br><br></div></blockq=
uote><blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8e=
x;border-left: 1px #ccc solid;padding-left: 1ex;"><div>2: All automatic var=
iables declared are copy/moveable.<br><br>3: The promise type and return ty=
pes are copy/moveable (though the latter is necessitated by P0057).<br><br>=
So if my function takes a `const std::string &`, it's immobile.</di=
v></blockquote><div><br><br>Right - whole object is automatically moveable/=
copyable if it's parts are moveable/copyable.<br>=C2=A0</div><blockquot=
e class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-left: =
1px #ccc solid;padding-left: 1ex;"><div>If my function does a `for(auto &am=
p;x : vec)`, it's immobile. And so on.<br><br>So those are the requirem=
ents for any coroutine callstack you plan on sticking in an object. And unl=
ess you can come up with a way to copy references (or any user-defined immo=
bile type for that matter), these rules are inviolate.<br></div></blockquot=
e><div><br>I don't see problem here. Yes - you can't copy/move some=
thing with immobile parts, yes there are limitations. But I do want copy/mo=
ve when parts are mobile.<br>=C2=A0<br></div><blockquote class=3D"gmail_quo=
te" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;paddi=
ng-left: 1ex;"><div>=C2=A0</div><blockquote class=3D"gmail_quote" style=3D"=
margin:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-left:1ex"><di=
v dir=3D"ltr"><blockquote class=3D"gmail_quote" style=3D"margin:0;margin-le=
ft:0.8ex;border-left:1px #ccc solid;padding-left:1ex"><div>The performance =
of a generator that returns integers on a fixed range is <i>irrelevant</i>.=
Nobody in their right mind is going to use generators for that. We have <i=
>ranges</i> for that. <br></div></blockquote><blockquote class=3D"gmail_quo=
te" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-=
left:1ex"><div><br>The purpose of a generator, in a <i>real application</i>=
, is to be able to have a process take an arbitrary amount of time. You get=
a value from that process, then you do something, then get another. Until =
the next value is available, your process stops. That's the idea.<br></=
div></blockquote><div>=C2=A0<br>That's not the only case. For instance =
consider "flatten" generator which takes things like container1&l=
t;container2<T>> and gives linear sequence of T values - it is har=
d to do it proper manually, at least much harder than with yield/generator.=
<br></div></div></blockquote><div><br>I guess ranges aren't functional =
enough for some people ;)<br></div></blockquote><div><br>I am not sure what=
you mean. I do use ranges, and I do implement ranges. And some implementat=
ions are much easier with yield coroutines than with hand-made state-machin=
e. Just try to implement flatten iterator.<br>=C2=A0</div><blockquote class=
=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #cc=
c solid;padding-left: 1ex;"><div><br></div><blockquote class=3D"gmail_quote=
" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-le=
ft:1ex"><div dir=3D"ltr"><div></div><div></div><blockquote class=3D"gmail_q=
uote" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;paddin=
g-left:1ex"></blockquote><blockquote class=3D"gmail_quote" style=3D"margin:=
0;margin-left:0.8ex;border-left:1px #ccc solid;padding-left:1ex"><div>If th=
e cost of generating that value is non-trivial, then the cost of the virtua=
l call to do said generation is negligible.</div></blockquote><blockquote c=
lass=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1px #c=
cc solid;padding-left:1ex"><div>If the cost of <i>using</i> that value is n=
on-trivial, then the cost of the virtual call is again irrelevant.<br></div=
></blockquote><div><br>virtual calls makes inlining much harder, i.e. preve=
nts further optimizations.<br></div></div></blockquote><div><br>If the code=
implementing the potentially inlined function is non-trivial, then the com=
piler wouldn't try to inline it.<br></div></blockquote><div><br>Obvious=
ly inlining is not just "call" optimization, it allows to fuse di=
fferent code parts. Yes, there are cases where compiler by default would no=
t try to inline some function. And what?<br>P0057 by design makes it much h=
arder for compilers to perform inlining.<br>=C2=A0<br></div><blockquote cla=
ss=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #=
ccc solid;padding-left: 1ex;"><div><br></div><blockquote class=3D"gmail_quo=
te" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-=
left:1ex"><div dir=3D"ltr"><div></div><blockquote class=3D"gmail_quote" sty=
le=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-left:1e=
x"><div>The overhead here is only "huge" if your generators <i>an=
d</i> processing code are so trivial that your code would be written better=
as a straight-up range-based for loop.</div></blockquote><div><br>Why bett=
er? Yield simplifies a lot of cases like "flatten".<br></div></di=
v></blockquote><div><br>Let's assume that's true.<br><br>Most uses =
of "flatten" would be of the form `for await(const auto &x : =
generator_call())`. Which will be optimized just fine.<br>=C2=A0</div></blo=
ckquote><blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0=
..8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div>That's the th=
ing about the simple cases. They're so simple that they're=20
almost always going to be optimized away. It's the complex ones that=20
won't be, and the code to execute them will be the primary limiting=20
factor in profiling.<br></div></blockquote><div><br>Just try to use VS2015 =
yield, and check what it does even for simple cases.<br>=C2=A0</div><blockq=
uote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-lef=
t: 1px #ccc solid;padding-left: 1ex;"><div>Not only that, there is no way t=
o put `flatten` into a struct. Why? Because it will almost certainly take i=
ts object <i>by reference</i>. So its resulting coroutine type will be immo=
bile. And therefore, you can't make it a structure member.<br></div></b=
lockquote><div><br>Just take pointer or reference_wrapper. Or it could be s=
tored internally as a pointer.<br>=C2=A0</div><blockquote class=3D"gmail_qu=
ote" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padd=
ing-left: 1ex;"><div><br>So you can't even adjust the `flatten` case to=
put it in a struct.<br><br></div><blockquote class=3D"gmail_quote" style=
=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-left:1ex"=
><div dir=3D"ltr"><div>It can be even used as drop-in emulation of list com=
prehension (as far as I remember this was even mentioned in one of earlier =
versions of P0057).<br>And I want to use convenient features even in code w=
ith performance requirements. This is one of main C++ strength.<br></div></=
div></blockquote><div><br>And you can.<br></div></blockquote><div><br>Intri=
nsic overhead of some feature would prevent me from using it in code with p=
erformance requirements.<br>=C2=A0</div><blockquote class=3D"gmail_quote" s=
tyle=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-le=
ft: 1ex;"><div><br></div><blockquote class=3D"gmail_quote" style=3D"margin:=
0;margin-left:0.8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir=
=3D"ltr"><div></div><br><div>Yes, I agree. But in this case we indeed have =
"needlessly add undue overhead", which can be avoided, and should=
be avoided in order to increase applicability.<br></div></div></blockquote=
><div><br>Every attempt you've made to upgrade P0057 to add this functi=
onality negatively impacts the resulting language. You're either making=
classes look like function definitions or transforming function return typ=
es behind peoples backs or something else.<br><br></div></blockquote><div><=
br>P0057 already does some transformation behinds peoples backs. Just write=
"auto test() { yield 1; }" - and you magically would get std::ge=
nerator<int> result type. Why it's better than std::coroutine_tra=
its<signature>::type? <br><br></div><blockquote class=3D"gmail_quote"=
style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-=
left: 1ex;"><blockquote class=3D"gmail_quote" style=3D"margin:0;margin-left=
:0.8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><div>A=
nd it is not that I just randomly select proposal and trying to blindly app=
ly "zero-overhead doctrine". I knew that it should be nearly-zero=
overhead exactly in this place, long before I read this proposal.<br></div=
></div></blockquote><div><br>And P0057 is "nearly-zero overhead".=
<br></div></blockquote><div><br>No. It has intrinsic extra allocation, intr=
insic extra indirect call, and intrinsic additional indirection in case of =
array of things with coroutine inside.<br>=C2=A0</div><blockquote class=3D"=
gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc so=
lid;padding-left: 1ex;"><br><div>You have a very narrow view of "same =
design".<br><br>To me, a design <i>feature</i> of P0057 is that the fu=
nction is what it says it is. The feature is very carefully designed to do =
this. That's why it doesn't return the promise type, or otherwise e=
xpose that to the user.<br><br>If you start mucking around with the call si=
gnature, transforming the return type into something else, then it's no=
t "almost" the same design. It's a different design.<br></div=
></blockquote><div><br>P0057 already "mucking around with the call sig=
nature".<br>=C2=A0</div><blockquote class=3D"gmail_quote" style=3D"mar=
gin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><=
br><div>I don't understand how you can come so close to my point yet ke=
ep missing it.<br><br>P0057 exists for the <i>primary purpose</i> of transf=
erring control to someone other than the caller. That's its main use ca=
se and the reason why it was proposed in the first place. That's the pr=
oblem it exists to solve.<br></div></blockquote><div><br>This was actually =
first motivated use case of Boost.Asio stackless coroutine macros - to tran=
sfer control to someone other than caller.<br>=C2=A0</div><blockquote class=
=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #cc=
c solid;padding-left: 1ex;"><div><br></div><blockquote class=3D"gmail_quote=
" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-le=
ft:1ex"><div dir=3D"ltr"><div>Without this things like for example list mon=
ad or software transactional memory cannot be implemented.<br></div></div><=
/blockquote><div><br>Why do we want to implement "list monad"s? C=
++ is not a functional language.</div></blockquote><div><br>Yes, I don'=
t think list monad is useful example, need to find better one - for instanc=
e fork (already used in one of Boost.Asio examples).<br>List monad is just =
easy way to show what is impossible without copyability.<br>=C2=A0</div><bl=
ockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border=
-left: 1px #ccc solid;padding-left: 1ex;"><div>It's bad enough that P00=
57 is going to lead to a rash of functional-C++ programmers using `await` o=
n `expected` objects...<br><br></div></blockquote><div><br>Well, authors of=
P0057 did explicitly mention such use cases like optional, expected, etc:<=
br>https://github.com/boostcon/cppnow_presentations_2015/blob/master/files/=
CppNow2015_Coroutines_in_C%2B%2B17.pdf<br>=C2=A0</div><blockquote class=3D"=
gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc so=
lid;padding-left: 1ex;"><div>And isn't transactional memory already bei=
ng built into another TS? What does that have to do with resumable function=
s?<br></div></blockquote><div><br>It could be made on top of it. And for in=
stance in Haskell it is implemented with STM monad. <br></div>
<p></p>
-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />
------=_Part_926_556295803.1445155049972--
------=_Part_925_1780718661.1445155049971--
.
Author: Evgeny Panasyuk <evgeny.panasyuk@gmail.com>
Date: Sun, 18 Oct 2015 01:02:49 -0700 (PDT)
Raw View
------=_Part_845_767107397.1445155369660
Content-Type: multipart/alternative;
boundary="----=_Part_846_467564723.1445155369660"
------=_Part_846_467564723.1445155369660
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
18 October 2015 =D0=B3., 0:47:38 UTC+3 Nicol Bolas :
>
>
> But I don't claim to know everything. So I accept the existence of such=
=20
> application domains. However, your suggestion was to adopt Boost.Coroutin=
e *instead=20
> of* P0057, not in addition to. So while you would be serving your=20
> application domain, you would also be performing a *disservice* to the=20
> application domain served by P0057.
>
> Remember that P0057's primary use case is .then-style continuations. And=
=20
> Boost.Coroutine doesn't help with that at all.
>
>
Why? await can be implemented on top of Boost.Coroutine. And I already did=
=20
this:
https://github.com/boostorg/coroutine/blob/master/example/cpp11/asymmetric/=
await_emu.cpp
https://github.com/panaseleus/await_emu
--=20
---=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.
------=_Part_846_467564723.1445155369660
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">18 October 2015 =D0=B3., 0:47:38 UTC+3 Nicol Bolas :<block=
quote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-le=
ft: 1px #ccc solid;padding-left: 1ex;"><br><div>But I don't claim to kn=
ow everything. So I accept the existence of such application domains. Howev=
er, your suggestion was to adopt Boost.Coroutine <i>instead of</i> P0057, n=
ot in addition to. So while you would be serving your application domain, y=
ou would also be performing a <i>disservice</i> to the application domain s=
erved by P0057.<br><br>Remember that P0057's primary use case is .then-=
style continuations. And Boost.Coroutine doesn't help with that at all.=
<br><br></div></blockquote><div><br>Why? await can be implemented on top of=
Boost.Coroutine. And I already did this:<br>https://github.com/boostorg/co=
routine/blob/master/example/cpp11/asymmetric/await_emu.cpp<br>https://githu=
b.com/panaseleus/await_emu<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_846_467564723.1445155369660--
------=_Part_845_767107397.1445155369660--
.
Author: TONGARI J <tongari95@gmail.com>
Date: Sun, 18 Oct 2015 16:07:53 +0800
Raw View
--001a1134bce295a08805225c865c
Content-Type: text/plain; charset=UTF-8
2015-10-18 14:51 GMT+08:00 Evgeny Panasyuk <evgeny.panasyuk@gmail.com>:
>
> Here is an example:
> auto numbers(int n)
> {
> for (int i = 0; i != n; ++i)
> yield i;
> }
>
> int main()
> {
> unsigned res = 0;
> auto &&xs = numbers(1 << 30);
> {
> boost::progress_timer t;
> for (auto x : xs)
> res += x;
> }
> cout << res << endl;
> }
> I made two variants. One is P0057 yield/generator, another one is similar
> code based on Boost.Asio stackless coroutine macros.
> I used VS2015 x64 for both cases.
> P0057 version has allocation, i.e. even for this simple case elision
> trickery is not implemented. But I do not measure allocation, I just
> measure inner loop. Macro version is 4.57x faster. And note, macro version
> is far from being optimal in a sense that with compiler support it is
> possible to get even better result.
>
Out of curiosity, what does the corresponding macro version look like? do
you provide the similar iterator API and use it for comparison?
--
---
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/.
--001a1134bce295a08805225c865c
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">2015=
-10-18 14:51 GMT+08:00 Evgeny Panasyuk <span dir=3D"ltr"><<a href=3D"mai=
lto:evgeny.panasyuk@gmail.com" target=3D"_blank">evgeny.panasyuk@gmail.com<=
/a>></span>:<blockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0p=
x 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-lef=
t-style:solid;padding-left:1ex"><div>Here is an example:<br><div style=3D"b=
order:1px solid rgb(187,187,187);word-wrap:break-word;background-color:rgb(=
250,250,250)"><code><div><span style=3D"color:rgb(0,0,136)">auto</span><spa=
n style=3D"color:rgb(0,0,0)"> numbers</span><span style=3D"color:rgb(102,10=
2,0)">(</span><span style=3D"color:rgb(0,0,136)">int</span><span style=3D"c=
olor:rgb(0,0,0)"> n</span><span style=3D"color:rgb(102,102,0)">)</span><spa=
n style=3D"color:rgb(0,0,0)"><br></span><span style=3D"color:rgb(102,102,0)=
">{</span><span style=3D"color:rgb(0,0,0)"><br>=C2=A0 =C2=A0 </span><span s=
tyle=3D"color:rgb(0,0,136)">for</span><span style=3D"color:rgb(0,0,0)"> </s=
pan><span style=3D"color:rgb(102,102,0)">(</span><span style=3D"color:rgb(0=
,0,136)">int</span><span style=3D"color:rgb(0,0,0)"> i </span><span style=
=3D"color:rgb(102,102,0)">=3D</span><span style=3D"color:rgb(0,0,0)"> </spa=
n><span style=3D"color:rgb(0,102,102)">0</span><span style=3D"color:rgb(102=
,102,0)">;</span><span style=3D"color:rgb(0,0,0)"> i </span><span style=3D"=
color:rgb(102,102,0)">!=3D</span><span style=3D"color:rgb(0,0,0)"> n</span>=
<span style=3D"color:rgb(102,102,0)">;</span><span style=3D"color:rgb(0,0,0=
)"> </span><span style=3D"color:rgb(102,102,0)">++</span><span style=3D"col=
or:rgb(0,0,0)">i</span><span style=3D"color:rgb(102,102,0)">)</span><span s=
tyle=3D"color:rgb(0,0,0)"><br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 </span><span styl=
e=3D"color:rgb(0,0,136)">yield</span><span style=3D"color:rgb(0,0,0)"> i</s=
pan><span style=3D"color:rgb(102,102,0)">;</span><span style=3D"color:rgb(0=
,0,0)"><br></span><span style=3D"color:rgb(102,102,0)">}</span><span style=
=3D"color:rgb(0,0,0)"><br><br></span><span style=3D"color:rgb(0,0,136)">int=
</span><span style=3D"color:rgb(0,0,0)"> main</span><span style=3D"color:rg=
b(102,102,0)">()</span><span style=3D"color:rgb(0,0,0)"><br></span><span st=
yle=3D"color:rgb(102,102,0)">{</span><span style=3D"color:rgb(0,0,0)"><br>=
=C2=A0 =C2=A0 </span><span style=3D"color:rgb(0,0,136)">unsigned</span><spa=
n style=3D"color:rgb(0,0,0)"> res </span><span style=3D"color:rgb(102,102,0=
)">=3D</span><span style=3D"color:rgb(0,0,0)"> </span><span style=3D"color:=
rgb(0,102,102)">0</span><span style=3D"color:rgb(102,102,0)">;</span><span =
style=3D"color:rgb(0,0,0)"><br>=C2=A0 =C2=A0 </span><span style=3D"color:rg=
b(0,0,136)">auto</span><span style=3D"color:rgb(0,0,0)"> </span><span style=
=3D"color:rgb(102,102,0)">&&</span><span style=3D"color:rgb(0,0,0)"=
>xs </span><span style=3D"color:rgb(102,102,0)">=3D</span><span style=3D"co=
lor:rgb(0,0,0)"> numbers</span><span style=3D"color:rgb(102,102,0)">(</span=
><span style=3D"color:rgb(0,102,102)">1</span><span style=3D"color:rgb(0,0,=
0)"> </span><span style=3D"color:rgb(102,102,0)"><<</span><span style=
=3D"color:rgb(0,0,0)"> </span><span style=3D"color:rgb(0,102,102)">30</span=
><span style=3D"color:rgb(102,102,0)">);</span><span style=3D"color:rgb(0,0=
,0)"><br>=C2=A0 =C2=A0 </span><span style=3D"color:rgb(102,102,0)">{</span>=
<span style=3D"color:rgb(0,0,0)"><br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 boost</spa=
n><span style=3D"color:rgb(102,102,0)">::</span><span style=3D"color:rgb(0,=
0,0)">progress_timer t</span><span style=3D"color:rgb(102,102,0)">;</span><=
span style=3D"color:rgb(0,0,0)"><br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 </span><spa=
n style=3D"color:rgb(0,0,136)">for</span><span style=3D"color:rgb(0,0,0)"> =
</span><span style=3D"color:rgb(102,102,0)">(</span><span style=3D"color:rg=
b(0,0,136)">auto</span><span style=3D"color:rgb(0,0,0)"> x </span><span sty=
le=3D"color:rgb(102,102,0)">:</span><span style=3D"color:rgb(0,0,0)"> xs</s=
pan><span style=3D"color:rgb(102,102,0)">)</span><span style=3D"color:rgb(0=
,0,0)"><br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 res </span><span style=
=3D"color:rgb(102,102,0)">+=3D</span><span style=3D"color:rgb(0,0,0)"> x</s=
pan><span style=3D"color:rgb(102,102,0)">;</span><span style=3D"color:rgb(0=
,0,0)"><br>=C2=A0 =C2=A0 </span><span style=3D"color:rgb(102,102,0)">}</spa=
n><span style=3D"color:rgb(0,0,0)"><br>=C2=A0 =C2=A0 cout </span><span styl=
e=3D"color:rgb(102,102,0)"><<</span><span style=3D"color:rgb(0,0,0)">=
res </span><span style=3D"color:rgb(102,102,0)"><<</span><span style=
=3D"color:rgb(0,0,0)"> endl</span><span style=3D"color:rgb(102,102,0)">;</s=
pan><span style=3D"color:rgb(0,0,0)"><br></span><span style=3D"color:rgb(10=
2,102,0)">}</span><span style=3D"color:rgb(0,0,0)"><br></span></div></code>=
</div>I made two variants. One is P0057 yield/generator, another one is sim=
ilar code based on Boost.Asio stackless coroutine macros.<br>I used VS2015 =
x64 for both cases.<br>P0057 version has allocation, i.e. even for this sim=
ple case elision trickery is not implemented. But I do not measure allocati=
on, I just measure inner loop. Macro version is 4.57x faster. And note, mac=
ro version is far from being optimal in a sense that with compiler support =
it is possible to get even better result.</div></blockquote><div><br></div>=
<div>Out of curiosity, what does the corresponding macro version look like?=
do you provide the similar iterator API and use it for comparison?</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 />
--001a1134bce295a08805225c865c--
.
Author: Evgeny Panasyuk <evgeny.panasyuk@gmail.com>
Date: Sun, 18 Oct 2015 01:52:32 -0700 (PDT)
Raw View
------=_Part_898_198255041.1445158353080
Content-Type: multipart/alternative;
boundary="----=_Part_899_96203393.1445158353081"
------=_Part_899_96203393.1445158353081
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
18 October 2015 =D0=B3., 11:07:55 UTC+3 TONGARI J:
>
>
> Out of curiosity, what does the corresponding macro version look like?
>
It is very similar in structure:
COROUTINE(int, yield_demo, (int, N),
(int, i))
{
for (i =3D 0; i !=3D N; ++i)
YIELD i;
return;
}
COROUTINE_END
Due limitation of macro-implementation major difference here is that you=20
have to put all locals (loop variable i) at the top, like in old C or=20
Pascal.
=20
> do you provide the similar iterator API and use it for comparison?
>
Yes, I used very similar input iterator to one defined int=20
std::experimental::generator, and used range-based-for (and actually *main*=
=20
is exactly same).
But if use coroutine directly, without iterators and range-based-for (which=
=20
are not well suited for input ranges), then GCC generates following code=20
within loop:
..L5:
addl $1, %ebx
cmpl $1073741824, %ebx
jne .L6
... branch with ret ...
..L6:
.cfi_restore_state
movl %ebx, %edi
call _Z5printi
jmp .L5
It is almost zero overhead. Small issue here is that looks like it does not=
=20
understand which branch is more likely, that's why there is "split" of code=
=20
and unconditional jump to .L5.
Anyway, I do realize that I should provide full code, more results data,=20
etc, make other tests, add await, etc. That's why I said that detailed=20
report is required.
--=20
---=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.
------=_Part_899_96203393.1445158353081
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">18 October 2015 =D0=B3., 11:07:55 UTC+3 TONGARI J:<blockqu=
ote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-left=
: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr"><div><div class=3D"gm=
ail_quote"><div><br></div><div>Out of curiosity, what does the correspondin=
g macro version look like?</div></div></div></div></blockquote><div><br>It =
is very similar in structure:<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: #000;" class=3D=
"styled-by-prettify">COROUTINE</span><span style=3D"color: #660;" class=3D"=
styled-by-prettify">(</span><span style=3D"color: #008;" class=3D"styled-by=
-prettify">int</span><span style=3D"color: #660;" class=3D"styled-by-pretti=
fy">,</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> yiel=
d_demo</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: #008;" class=3D"styled-by-prettify">int</span><span style=3D"color:=
#660;" class=3D"styled-by-prettify">,</span><span style=3D"color: #000;" c=
lass=3D"styled-by-prettify"> N</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 </span><span style=3D"color: #660;" class=3D"=
styled-by-prettify">(</span><span style=3D"color: #008;" class=3D"styled-by=
-prettify">int</span><span style=3D"color: #660;" class=3D"styled-by-pretti=
fy">,</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> i</s=
pan><span style=3D"color: #660;" class=3D"styled-by-prettify">))</span><spa=
n style=3D"color: #000;" class=3D"styled-by-prettify"><br></span><span styl=
e=3D"color: #660;" class=3D"styled-by-prettify">{</span><span style=3D"colo=
r: #000;" class=3D"styled-by-prettify"><br>=C2=A0 =C2=A0 </span><span style=
=3D"color: #008;" class=3D"styled-by-prettify">for</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">i </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: #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"> i </span><span st=
yle=3D"color: #660;" class=3D"styled-by-prettify">!=3D</span><span style=3D=
"color: #000;" class=3D"styled-by-prettify"> N</span><span style=3D"color: =
#660;" class=3D"styled-by-prettify">;</span><span style=3D"color: #000;" cl=
ass=3D"styled-by-prettify"> </span><span style=3D"color: #660;" class=3D"st=
yled-by-prettify">++</span><span style=3D"color: #000;" class=3D"styled-by-=
prettify">i</span><span style=3D"color: #660;" class=3D"styled-by-prettify"=
>)</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br>=C2=
=A0 =C2=A0 =C2=A0 =C2=A0 YIELD i</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">return</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>=
COROUTINE_END</span></div></code></div>Due limitation of macro-implementati=
on major difference here is that you have to put all locals (loop variable =
i) at the top, like in old C or Pascal.<br>=C2=A0</div><blockquote class=3D=
"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc s=
olid;padding-left: 1ex;"><div dir=3D"ltr"><div><div class=3D"gmail_quote"><=
div>do you provide the similar iterator API and use it for comparison?</div=
></div></div></div></blockquote><div><br>Yes, I used very similar input ite=
rator to one defined int std::experimental::generator, and used range-based=
-for (and actually <b>main</b> is exactly same).<br><br>But if use coroutin=
e directly, without iterators and range-based-for (which are not well suite=
d for input ranges), then GCC generates following code within loop:<br><div=
><pre class=3D"f0" style=3D"display: inline-block; padding: 0; margin: 0;">=
..L5:</pre></div><div><pre class=3D"f0" style=3D"display: inline-block; padd=
ing: 0; margin: 0;"> addl $1, %ebx</pre></div><div><pre class=3D"f0" style=
=3D"display: inline-block; padding: 0; margin: 0;"> cmpl $1073741824, %ebx<=
/pre></div><div><pre class=3D"f0" style=3D"display: inline-block; padding: =
0; margin: 0;"> jne .L6</pre></div>=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 ... branch with r=
et ...<br><div><pre class=3D"f0" style=3D"display: inline-block; padding: 0=
; margin: 0;">.L6:</pre></div><div><pre class=3D"f0" style=3D"display: inli=
ne-block; padding: 0; margin: 0;"> .cfi_restore_state</pre></div><div><pre =
class=3D"f0" style=3D"display: inline-block; padding: 0; margin: 0;"> movl =
%ebx, %edi</pre></div><div><pre class=3D"f0" style=3D"display: inline-block=
; padding: 0; margin: 0;"> call _Z5printi</pre></div><div><pre class=3D"f0"=
style=3D"display: inline-block; padding: 0; margin: 0;"> jmp .L5</pre></di=
v><br>It is almost zero overhead. Small issue here is that looks like it do=
es not understand which branch is more likely, that's why there is &quo=
t;split" of code and unconditional jump to .L5.<br><br>Anyway, I do re=
alize that I should provide full code, more results data, etc, make other t=
ests, add await, etc. That's why I said that detailed report is require=
d.<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_899_96203393.1445158353081--
------=_Part_898_198255041.1445158353080--
.
Author: Evgeny Panasyuk <evgeny.panasyuk@gmail.com>
Date: Sun, 18 Oct 2015 01:56:58 -0700 (PDT)
Raw View
------=_Part_1106_570274393.1445158619009
Content-Type: multipart/alternative;
boundary="----=_Part_1107_183814872.1445158619009"
------=_Part_1107_183814872.1445158619009
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
18 2015 =D0=B3., 11:52:33 UTC+3 Evgeny Panasyuk :
>
>
> But if use coroutine directly, without iterators and range-based-for=20
> (which are not well suited for input ranges), then GCC generates followin=
g=20
> code within loop:
>
> .L5:
>
> addl $1, %ebx
>
> cmpl $1073741824, %ebx
>
> jne .L6
>
> ... branch with ret ...
>
> .L6:
>
> .cfi_restore_state
>
> movl %ebx, %edi
>
> call _Z5printi
>
> jmp .L5
>
>
>
Small addition - at this test, I used "void print(int x);" instead of=20
summing yielded values (in order to make ASM more clear/concise).
--=20
---=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.
------=_Part_1107_183814872.1445158619009
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<br>18 2015 =D0=B3., 11:52:33 UTC+3 Evgeny Panasyuk :<blockquote class=3D"g=
mail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc sol=
id;padding-left: 1ex;"><div dir=3D"ltr"><br><div>But if use coroutine direc=
tly, without iterators and range-based-for (which are not well suited for i=
nput ranges), then GCC generates following code within loop:<br><div><pre s=
tyle=3D"display:inline-block;padding:0;margin:0">.L5:</pre></div><div><pre =
style=3D"display:inline-block;padding:0;margin:0"> addl $1, %ebx</pre></div=
><div><pre style=3D"display:inline-block;padding:0;margin:0"> cmpl $1073741=
824, %ebx</pre></div><div><pre style=3D"display:inline-block;padding:0;marg=
in:0"> jne .L6</pre></div>=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 ... branch with ret ...<br=
><div><pre style=3D"display:inline-block;padding:0;margin:0">.L6:</pre></di=
v><div><pre style=3D"display:inline-block;padding:0;margin:0"> .cfi_restore=
_state</pre></div><div><pre style=3D"display:inline-block;padding:0;margin:=
0"> movl %ebx, %edi</pre></div><div><pre style=3D"display:inline-block;padd=
ing:0;margin:0"> call _Z5printi</pre></div><div><pre style=3D"display:inlin=
e-block;padding:0;margin:0"> jmp .L5</pre></div><br></div></div></blockquot=
e><div><br>Small addition - at this test, I used "void print(int x);&q=
uot; instead of summing yielded values (in order to make ASM more clear/con=
cise).<br></div>
<p></p>
-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />
------=_Part_1107_183814872.1445158619009--
------=_Part_1106_570274393.1445158619009--
.
Author: Gor Nishanov <gornishanov@gmail.com>
Date: Sun, 18 Oct 2015 06:41:11 -0700 (PDT)
Raw View
------=_Part_1461_1391289553.1445175671704
Content-Type: multipart/alternative;
boundary="----=_Part_1462_1936934478.1445175671709"
------=_Part_1462_1936934478.1445175671709
Content-Type: text/plain; charset=UTF-8
On Saturday, October 17, 2015 at 11:51:10 PM UTC-7, Evgeny Panasyuk wrote:
>
> I used VS2015 x64 for both cases.
>
RTM of VS2015 does not implement heap elision, handle exceptions and
has many more limitations. Primary purpose of that and earlier releases is
to validate the design of customization points such as awaitable and
coroutine promise to make sure we did not miss important use cases.
The first public release of the compiler that performs heap elision is
likely to be VS Update 2 of VS2015.
I will let you know where it is out so that you can try it out and do the
per measurements.
--
---
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_1462_1936934478.1445175671709
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">On Saturday, October 17, 2015 at 11:51:10 PM UTC-7, Evgeny=
Panasyuk wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0px 0px =
0px 0.8ex; padding-left: 1ex; border-left-color: rgb(204, 204, 204); border=
-left-width: 1px; border-left-style: solid;"><div>I used VS2015 x64 for bot=
h cases.<br></div></blockquote><div><br></div><div>RTM of VS2015 does not i=
mplement heap elision, handle exceptions and has=C2=A0many more limitations=
.. Primary purpose of that and earlier releases is to validate the design of=
customization points such as awaitable and coroutine promise to make sure =
we did not miss important use cases.</div><div><br></div><div>The first pub=
lic release of the compiler that performs heap elision is likely to be VS U=
pdate 2 of VS2015.</div><div>=C2=A0I will let you know where it is out so t=
hat you can try it out and do the per measurements.</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_1462_1936934478.1445175671709--
------=_Part_1461_1391289553.1445175671704--
.
Author: Nicol Bolas <jmckesson@gmail.com>
Date: Sun, 18 Oct 2015 09:21:18 -0700 (PDT)
Raw View
------=_Part_92_23287679.1445185278168
Content-Type: multipart/alternative;
boundary="----=_Part_93_751022217.1445185278168"
------=_Part_93_751022217.1445185278168
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
On Sunday, October 18, 2015 at 3:02:31 AM UTC-4, Evgeny Panasyuk wrote:
>
> 17 October 2015 =D0=B3., 19:30:02 UTC+3 Nicol Bolas:
>>
>>
>> * Equal functionality to P0057 (P0114 makes .then continuations=20
>> difficult).
>>
>
> Why? What is principal limitation for .then?=20
>
Looking at P0114, I have absolutely no idea how to implement .then-style=20
continuations with that functionality. Those kinds of continuations work in=
=20
P0057 because the `await` expression does the continuation. `await_suspend`=
=20
is given the handle to the function and internally it uses the future=20
object it was given to .then that handle.
To do that kind of scheduling, you need to be able to get a handle to the=
=20
suspended coroutine from *within* the resumable function. And as far as I=
=20
can tell, P0114 doesn't have a way to do that.
P0114 tends to treat "await" as simply "stop here until some condition is=
=20
met; the caller will continue me when he's ready." Just look at the=20
`print_1_to` example; it's based on the assumption that the caller will=20
constantly keep recalling the function until it finishes.
The caller *always* schedules the continuation in P0114.
=20
> * Syntax does not favor typed or type-erasure. That is, you pick one base=
d=20
>> solely on your needs, not on how difficult it is to use (P0114 fails her=
e,=20
>> as type-erasure requires lots of explicit user effort).
>>
>
> What kind of "lots of explicit user effort"? Does using *ready*=20
> std::function for lambdas results in "lots of explicit user effort"?
>
Type erasure in P0114 requires that you declare your function internally as=
=20
a lambda, encapsulate it in some type, and explicitly specify the memory=20
allocator to use. This type must them take the place of the return type, so=
=20
if you have a promise/future scenario, you have to manage the promise and=
=20
return the future manually. This must be done *every single time* you want=
=20
type erasure.
Basically, all of the work that P0057 does implicitly has to be done=20
*explicitly* in P0114. I would call that "lots of explicit user effort".
--=20
---=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.
------=_Part_93_751022217.1445185278168
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">On Sunday, October 18, 2015 at 3:02:31 AM UTC-4, Evgeny Pa=
nasyuk wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-le=
ft: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr">=
17 October 2015 =D0=B3., 19:30:02 UTC+3 Nicol Bolas:<blockquote class=3D"gm=
ail_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;p=
adding-left:1ex"><br><div>* Equal functionality to P0057 (P0114 makes .then=
continuations difficult).<br></div></blockquote><div><br>Why? What is prin=
cipal limitation for .then? <br></div></div></blockquote><div><br>Looking a=
t P0114, I have absolutely no idea how to implement .then-style continuatio=
ns with that functionality. Those kinds of continuations work in P0057 beca=
use the `await` expression does the continuation. `await_suspend` is given =
the handle to the function and internally it uses the future object it was =
given to .then that handle.<br><br>To do that kind of scheduling, you need =
to be able to get a handle to the suspended coroutine from <i>within</i> th=
e resumable function. And as far as I can tell, P0114 doesn't have a wa=
y to do that.<br><br>P0114 tends to treat "await" as simply "=
;stop here until some condition is met; the caller will continue me when he=
's ready." Just look at the `print_1_to` example; it's based o=
n the assumption that the caller will constantly keep recalling the functio=
n until it finishes.<br><br>The caller <i>always</i> schedules the continua=
tion in P0114.<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;">=
<div dir=3D"ltr"><div></div><blockquote class=3D"gmail_quote" style=3D"marg=
in:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-left:1ex"><div>* =
Syntax does not favor typed or type-erasure. That is, you pick one based so=
lely on your needs, not on how difficult it is to use (P0114 fails here, as=
type-erasure requires lots of explicit user effort).<br></div></blockquote=
><div><br>What kind of "lots of explicit user effort"? Does using=
*ready* std::function for lambdas results in "lots of explicit user e=
ffort"?<br></div></div></blockquote><div><br>Type erasure in P0114 req=
uires that you declare your function internally as a lambda, encapsulate it=
in some type, and explicitly specify the memory allocator to use. This typ=
e must them take the place of the return type, so if you have a promise/fut=
ure scenario, you have to manage the promise and return the future manually=
.. This must be done <i>every single time</i> you want type erasure.<br><br>=
Basically, all of the work that P0057 does implicitly has to be done <i>exp=
licitly</i> in P0114. I would call that "lots of explicit user effort&=
quot;.<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_93_751022217.1445185278168--
------=_Part_92_23287679.1445185278168--
.
Author: Nicol Bolas <jmckesson@gmail.com>
Date: Sun, 18 Oct 2015 09:27:02 -0700 (PDT)
Raw View
------=_Part_1195_129683394.1445185622727
Content-Type: multipart/alternative;
boundary="----=_Part_1196_802985181.1445185622728"
------=_Part_1196_802985181.1445185622728
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
On Sunday, October 18, 2015 at 2:51:10 AM UTC-4, Evgeny Panasyuk wrote:
>
> 17 October 2015 =D0=B3., 20:07:12 UTC+3 Nicol Bolas:
>>
>> On Saturday, October 17, 2015 at 11:43:32 AM UTC-4, Evgeny Panasyuk wrot=
e:
>>>
>>> 17 October 2015 =D0=B3., 16:31:25 UTC+3 Nicol Bolas:
>>>
>>>> P0057 is the result of numerous revisions of an idea, across several=
=20
>>>> years, as well as with lots of implementation experience. Why should w=
e=20
>>>> impair such a design just because you think that, one day, someone=20
>>>> *might* propose a better one?=20
>>>>
>>>
>>> Yes, better design is possible.
>>> But that is not the only issue - if there will be big overhead, it woul=
d=20
>>> have limited usability. As Giovanni mentioned above, if performance is =
not=20
>>> an issue - stackful coroutines would cover most of use cases of slow=20
>>> stackless coroutines.
>>>
>>
>> I don't understand you rhetoric here. On the one hand, you claim that=20
>> there is "big overhead" and that P0057 are "slow stackless coroutines." =
Yet=20
>> later, you specifically state that "Again, I should prepare detailed rep=
ort=20
>> (in order for it to have real effect)". Which means that you, as of yet,=
=20
>> have no actual evidence that overhead is "big" or that P0057 is "slow".
>>
>
> No. this is wrong conclusion. "need to make detailed report" !=3D "I don'=
t=20
> have any evidence".
> =20
>
>> You have repeatedly made the positive claims that P0057 is "slow", that=
=20
>> it has "big overhead". It's time to put up or shut up: present your=20
>> evidence for these claims, or we should consider your statements to be a=
t=20
>> best conjecture.
>>
>> Note: "evidence" means actual evidence. Not "well, if you do this, the=
=20
>> optimizer might not work" or whatever. Actual, good-faith evidence.
>>
>> There is apparently an implementation of P0114. And there is an=20
>> implementation of await. Use them to provide us with evidence of your=20
>> claims.
>>
>
> Here is an example:
> auto numbers(int n)
> {
> for (int i =3D 0; i !=3D n; ++i)
> yield i;
> }
>
> int main()
> {
> unsigned res =3D 0;
> auto &&xs =3D numbers(1 << 30);
> {
> boost::progress_timer t;
> for (auto x : xs)
> res +=3D x;
> }
> cout << res << endl;
> }
> I made two variants. One is P0057 yield/generator, another one is similar=
=20
> code based on Boost.Asio stackless coroutine macros.
>
I used VS2015 x64 for both cases.
> P0057 version has allocation, i.e. even for this simple case elision=20
> trickery is not implemented. But I do not measure allocation, I just=20
> measure inner loop. Macro version is 4.57x faster.
>
What does the generated assembly look like? Is it inlining at all?
And note, macro version is far from being optimal in a sense that with=20
> compiler support it is possible to get even better result.
>
You said that you do not want to change mechanics of function signature.
>>>
>>
>> No, what I didn't want was for a function signature to *lie*. Where it=
=20
>> magically is transformed into a struct, or the return type gets replaced=
by=20
>> something else or some such.
>>
>
> What about case with "auto" return type, where it is generated via=20
> specialization of coroutine_traits?
>
So, what you're saying is that you want a distinction between concrete=20
coroutines and non-concrete coroutines. And that all concrete coroutines=20
*must* use auto return type deduction. And that the deduced type will=20
either be the coroutine type itself or some user-specified type that will=
=20
be given a template parameter that itself is the coroutine type. Presumably=
=20
being constructed with such a value, so that it can store the coroutine=20
internally.
However it is that this distinction between concrete and type-erased=20
coroutines is deduced (whether it's some parameter tag, a coroutine trait,=
=20
or a keyword), you still want `await` and `yield` to have their expected=20
behaviors within that function.
Is that what you're suggesting? For the rest of this post, I'll assume=20
that's the general idea.
If in this case you still would say that "it is replaced by something else"=
=20
> - then how it differs from P0057:
> auto foo(int x)
> {
> yield x;
> }
> Here return type is not int.
>
I don't see a `return` statement there, so I have no reason to expect the=
=20
type to be deduced as `int`. P0057 says that, if `yield` is encountered=20
before `return`, then the type will be deduced as `generator<T>`.
There is no lying or cheating going on; the rules of automatic return type=
=20
deduction simply *changed* due to the addition of a new keyword.
And that part is what keeps tripping you up. Because if you insist on being=
=20
>> able to return a compiler-generated type (whether it's directly or store=
d=20
>> in the return object), there is no way to specify such a thing in C++. A=
nd=20
>> therefore, there is going to have to be some place where you *cheat*.
>>
>
> Why returning generator in P0057 (when it's "result type" is auto) is not=
=20
> cheating? And why returning traits<tag, params...>::type is cheating? Wha=
t=20
> is the principal difference?
>
The reason the `yield` changes are more acceptable is that:
1) They only take effect when using automatic return type deduction. Your=
=20
previous suggestions have been about manipulating *concrete* return types=
=20
too. Only your current idea is focused only on auto-return semantics.
2) They take effect due to the presence of a new keyword, one who's nature=
=20
would reasonably affect automatic return type deduction. `yield` is=20
conceptually like a `return` statement, so it makes sense that it would=20
have some effect on return type deduction. This is not true of `await`.
3) Auto-return type deduction isn't magical, just very convenient. It is=20
possible for the user to actually write that type themselves. The exception=
=20
to #3 is returning a lambda of course.
But the main thrust of point #3 is that, if the user wants to, they can=20
always do it manually and get the same behavior.
If you tie non-type erased coroutines to automatic type deduction, then you=
=20
remove that ability.
And no, your approach is not "closer" to P0057. It's farther. The return=20
>>>> type is a coroutine now, not a future, or generator, or other user-def=
ined=20
>>>> type. It's an actual coroutine.
>>>>
>>>
>>> No, I mean that actual return type would be specified by specialization=
=20
>>> of coroutine_traits.
>>>
>>
>> Which is rather the opposite of how P0057 works, where the return type i=
s=20
>> the return type, and the promise type is *deduced* from that.
>>
>> So again, you're deviating farther from P0057, not closer.
>>
>
> Hm, how any change in existing text is supposed to deviate closer to it?
>
The question is not just of functionality, but *intent*. P0057 is carefully=
=20
designed to avoid making functions behave differently from what they appear=
=20
to be. Your idea *requires* that they behave differently from what they=20
appear to be.
That is, you're not merely deviating from the design of P0057, but the=20
ideas behind that design.
>> That's not how P0057 works. Indeed, that's not what P0057 is *for*.=20
>>>> Remember the general idea of await in P0057: it halts the function, bu=
t it=20
>>>> also *explicitly* allows the transfer of control of the function to=20
>>>> the *await expression*. And thus, control is not necessarily=20
>>>> transferred to the return value.
>>>>
>>>
>>> Yes, of course, it does not have to.=20
>>>
>>
>> So... how do you do it? In P0057, it happens through `await_suspend`,=20
>> which takes a coroutine_handle<>. So in your idea, how does it work?
>>
>
> For example await_suspend can be function template which takes concrete=
=20
> coroutine.
>
By value or reference? Who's responsible for destroying it? When does that=
=20
destruction happen? How does that happen?
Also, there's the question of the fact that your concrete coroutine is also=
=20
returned from the function. Regardless of the exact mechanics of it, you=20
have made it *very clear* that the return type of such concrete coroutines=
=20
is *always* the coroutine type or something that contains it.
So... who's supposed to continue it? With a `future<int>`, the idea is that=
=20
the caller *doesn't* continue it; it will continue itself. The most the=20
user will do is call `get` and sit there until the value shows up. But if=
=20
the return type is always some generated coroutine type, doesn't that imply=
=20
that the caller should continue it?
How does the caller know if he's supposed to continue it or if it continues=
=20
itself?
Oh sure, you use different keywords. But the behavior of those keywords is=
=20
>>>> basically the behavior of the functions P0114 implements. Basically, P=
0114=20
>>>> is what you want, even if you would prefer that the form appeared more=
like=20
>>>> P0057.
>>>>
>>>
>>> Personally I prefer P0114 - it is more powerful, gives less overhead,=
=20
>>> and shifts from concrete await or yield features towards more general=
=20
>>> language feature.
>>> But if P0057 is much more likely to get into ISO, then I would like to=
=20
>>> remove discussed overhead.
>>>
>>
>> Here's my problem with that notion.
>>
>> What you really want is P0114. But you don't believe that it'll make it=
=20
>> in. So instead, you propose suggestions to change P0057. Which will in t=
he=20
>> end... turn it into a *gimped* version of P0114.
>>
>
> P0114 is much more powerful than changes I propose.
>
Yes. Hence being the gimped version of P0114: all of the disadvantages of=
=20
P0114 with none of its advantages.
--=20
---=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.
------=_Part_1196_802985181.1445185622728
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
On Sunday, October 18, 2015 at 2:51:10 AM UTC-4, Evgeny Panasyuk wrote:<blo=
ckquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-=
left: 1px #ccc solid;padding-left: 1ex;">17 October 2015 =D0=B3., 20:07:12 =
UTC+3 Nicol Bolas:<blockquote class=3D"gmail_quote" style=3D"margin:0;margi=
n-left:0.8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr">=
On Saturday, October 17, 2015 at 11:43:32 AM UTC-4, Evgeny Panasyuk 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">17 October 2015 =D0=
=B3., 16:31:25 UTC+3 Nicol Bolas:<br><blockquote class=3D"gmail_quote" styl=
e=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-left:1ex=
"><div>P0057 is the result of numerous revisions of an idea, across several=
years, as well as with lots of implementation experience. Why should we im=
pair such a design just because you think that, one day, someone <i>might</=
i> propose a better one? <br></div></blockquote><div><br>Yes, better design=
is possible.<br>But that is not the only issue - if there will be big over=
head, it would have limited usability. As Giovanni mentioned above, if perf=
ormance is not an issue - stackful coroutines would cover most of use cases=
of slow stackless coroutines.<br></div></div></blockquote><div><br>I don&#=
39;t understand you rhetoric here. On the one hand, you claim that there is=
"big overhead" and that P0057 are "slow stackless coroutine=
s." Yet later, you specifically state that "Again, I should prepa=
re detailed report (in order for it to have real effect)". Which means=
that you, as of yet, have no actual evidence that overhead is "big&qu=
ot; or that P0057 is "slow".<br></div></div></blockquote><div><br=
>No. this is wrong conclusion. "need to make detailed report" !=
=3D "I don't have any evidence".<br>=C2=A0</div><blockquote c=
lass=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1px #c=
cc solid;padding-left:1ex"><div dir=3D"ltr"><div>You have repeatedly made t=
he positive claims that P0057 is "slow", that it has "big ov=
erhead". It's time to put up or shut up: present your evidence for=
these claims, or we should consider your statements to be at best conjectu=
re.<br><br>Note: "evidence" means actual evidence. Not "well=
, if you do this, the optimizer might not work" or whatever. Actual, g=
ood-faith evidence.<br><br>There is apparently an implementation of P0114. =
And there is an implementation of await. Use them to provide us with eviden=
ce of your claims.<br></div></div></blockquote><div><br>Here is an example:=
<br><div style=3D"background-color:rgb(250,250,250);border-color:rgb(187,18=
7,187);border-style:solid;border-width:1px;word-wrap:break-word"><code><div=
><span style=3D"color:#008">auto</span><span style=3D"color:#000"> numbers<=
/span><span style=3D"color:#660">(</span><span style=3D"color:#008">int</sp=
an><span style=3D"color:#000"> n</span><span style=3D"color:#660">)</span><=
span style=3D"color:#000"><br></span><span style=3D"color:#660">{</span><sp=
an 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:#660">(<=
/span><span style=3D"color:#008">int</span><span style=3D"color:#000"> i </=
span><span style=3D"color:#660">=3D</span><span style=3D"color:#000"> </spa=
n><span style=3D"color:#066">0</span><span style=3D"color:#660">;</span><sp=
an style=3D"color:#000"> i </span><span style=3D"color:#660">!=3D</span><sp=
an style=3D"color:#000"> n</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">i</span><span style=3D"color:#660">)</span><span style=3D"c=
olor:#000"><br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 </span><span style=3D"color:#008=
">yield</span><span style=3D"color:#000"> i</span><span style=3D"color:#660=
">;</span><span style=3D"color:#000"><br></span><span style=3D"color:#660">=
}</span><span style=3D"color:#000"><br><br></span><span style=3D"color:#008=
">int</span><span style=3D"color:#000"> main</span><span style=3D"color:#66=
0">()</span><span style=3D"color:#000"><br></span><span style=3D"color:#660=
">{</span><span style=3D"color:#000"><br>=C2=A0 =C2=A0 </span><span style=
=3D"color:#008">unsigned</span><span style=3D"color:#000"> res </span><span=
style=3D"color:#660">=3D</span><span style=3D"color:#000"> </span><span st=
yle=3D"color:#066">0</span><span style=3D"color:#660">;</span><span style=
=3D"color:#000"><br>=C2=A0 =C2=A0 </span><span style=3D"color:#008">auto</s=
pan><span style=3D"color:#000"> </span><span style=3D"color:#660">&&=
;</span><span style=3D"color:#000">xs </span><span style=3D"color:#660">=3D=
</span><span style=3D"color:#000"> numbers</span><span style=3D"color:#660"=
>(</span><span style=3D"color:#066">1</span><span style=3D"color:#000"> </s=
pan><span style=3D"color:#660"><<</span><span style=3D"color:#000"> <=
/span><span style=3D"color:#066">30</span><span style=3D"color:#660">);</sp=
an><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 =C2=A0 =C2=A0 b=
oost</span><span style=3D"color:#660">::</span><span style=3D"color:#000">p=
rogress_timer t</span><span style=3D"color:#660">;</span><span style=3D"col=
or:#000"><br>=C2=A0 =C2=A0 =C2=A0 =C2=A0 </span><span 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 style=3D"color:#000"> x </=
span><span style=3D"color:#660">:</span><span style=3D"color:#000"> xs</spa=
n><span style=3D"color:#660">)</span><span style=3D"color:#000"><br>=C2=A0 =
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 res </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"><br>=C2=A0 =C2=A0 </span><span style=3D"co=
lor:#660">}</span><span style=3D"color:#000"><br>=C2=A0 =C2=A0 cout </span>=
<span style=3D"color:#660"><<</span><span style=3D"color:#000"> res <=
/span><span style=3D"color:#660"><<</span><span style=3D"color:#000">=
endl</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>I made two variants. One is P0057 yield/generato=
r, another one is similar code based on Boost.Asio stackless coroutine macr=
os.<br></div></blockquote><blockquote class=3D"gmail_quote" style=3D"margin=
: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div=
>I used VS2015 x64 for both cases.<br>P0057 version has allocation, i.e. ev=
en for this simple case elision trickery is not implemented. But I do not m=
easure allocation, I just measure inner loop. Macro version is 4.57x faster=
..</div></blockquote><div><br>What does the generated assembly look like? Is=
it inlining at all?<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>And note, macro version is far from being optimal in a sense tha=
t with compiler support it is possible to get even better result.<br></div>=
</blockquote><div></div><blockquote class=3D"gmail_quote" style=3D"margin: =
0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div><=
/div><blockquote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;=
border-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><blockquote c=
lass=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1px #c=
cc solid;padding-left:1ex"><div dir=3D"ltr"><div>You said that you do not w=
ant to change mechanics of function signature.</div></div></blockquote><div=
><br>No, what I didn't want was for a function signature to <i>lie</i>.=
Where it magically is transformed into a struct, or the return type gets r=
eplaced by something else or some such.<br></div></div></blockquote><div><b=
r>What about case with "auto" return type, where it is generated =
via specialization of coroutine_traits?<br></div></blockquote><div><br>So, =
what you're saying is that you want a distinction between concrete coro=
utines and non-concrete coroutines. And that all concrete coroutines <i>mus=
t</i> use auto return type deduction. And that the deduced type will either=
be the coroutine type itself or some user-specified type that will be give=
n a template parameter that itself is the coroutine type. Presumably being =
constructed with such a value, so that it can store the coroutine internall=
y.<br><br>However it is that this distinction between concrete and type-era=
sed coroutines is deduced (whether it's some parameter tag, a coroutine=
trait, or a keyword), you still want `await` and `yield` to have their exp=
ected behaviors within that function.<br><br>Is that what you're sugges=
ting? For the rest of this post, I'll assume that's the general ide=
a.<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>If in thi=
s case you still would say that "it is replaced by something else"=
; - then how it differs from P0057:<br><code><span style=3D"color:#008">aut=
o</span><span style=3D"color:#000"> foo</span><span style=3D"color:#660">(<=
/span><span style=3D"color:#008">int</span><span style=3D"color:#000"> x</s=
pan><span style=3D"color:#660">)</span><span style=3D"color:#000"><br></spa=
n><span style=3D"color:#660">{</span><span style=3D"color:#000"></span><spa=
n style=3D"color:#000"><br>=C2=A0=C2=A0=C2=A0 </span><span style=3D"color:#=
008">yield</span><span style=3D"color:#000"> x</span><span style=3D"color:#=
660">;</span><span style=3D"color:#000"><br></span><span style=3D"color:#66=
0">}</span><span style=3D"color:#000"><br></span></code>Here return type is=
not int.<br></div></blockquote><div><br>I don't see a `return` stateme=
nt there, so I have no reason to expect the type to be deduced as `int`. P0=
057 says that, if `yield` is encountered before `return`, then the type wil=
l be deduced as `generator<T>`.<br><br>There is no lying or cheating =
going on; the rules of automatic return type deduction simply <i>changed</i=
> due to the addition of a new keyword.<br><br></div><blockquote class=3D"g=
mail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc sol=
id;padding-left: 1ex;"><div></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>And that part is what keeps tripping you up. Because=
if you insist on being able to return a compiler-generated type (whether i=
t's directly or stored in the return object), there is no way to specif=
y such a thing in C++. And therefore, there is going to have to be some pla=
ce where you <i>cheat</i>.<br></div></div></blockquote><div><br>Why returni=
ng generator in P0057 (when it's "result type" is auto) is no=
t cheating? And why returning traits<tag, params...>::type is cheatin=
g? What is the principal difference?</div></blockquote><div><br>The reason =
the `yield` changes are more acceptable is that:<br><br>1) They only take e=
ffect when using automatic return type deduction. Your previous suggestions=
have been about manipulating <i>concrete</i> return types too. Only your c=
urrent idea is focused only on auto-return semantics.<br><br>2) They take e=
ffect due to the presence of a new keyword, one who's nature would reas=
onably affect automatic return type deduction. `yield` is conceptually like=
a `return` statement, so it makes sense that it would have some effect on =
return type deduction. This is not true of `await`.<br><br>3) Auto-return t=
ype deduction isn't magical, just very convenient. It is possible for t=
he user to actually write that type themselves. The exception to #3 is retu=
rning a lambda of course.<br><br>But the main thrust of point #3 is that, i=
f the user wants to, they can always do it manually and get the same behavi=
or.<br><br>If you tie non-type erased coroutines to automatic type deductio=
n, then you remove that ability.<br><br></div><blockquote class=3D"gmail_qu=
ote" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padd=
ing-left: 1ex;"><div></div><blockquote class=3D"gmail_quote" style=3D"margi=
n:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir=
=3D"ltr"><div></div><blockquote class=3D"gmail_quote" style=3D"margin:0;mar=
gin-left:0.8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr=
"><blockquote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;bor=
der-left:1px #ccc solid;padding-left:1ex"><div>And no, your approach is not=
"closer" to P0057. It's farther. The return type is a corout=
ine now, not a future, or generator, or other user-defined type. It's a=
n actual coroutine.<br></div></blockquote><div><br>No, I mean that actual r=
eturn type would be specified by specialization of coroutine_traits.<br></d=
iv></div></blockquote><div><br>Which is rather the opposite of how P0057 wo=
rks, where the return type is the return type, and the promise type is <i>d=
educed</i> from that.<br><br>So again, you're deviating farther from P0=
057, not closer.<br></div></div></blockquote><div><br>Hm, how any change in=
existing text is supposed to deviate closer to it?</div></blockquote><div>=
<br>The question is not just of functionality, but <i>intent</i>. P0057 is =
carefully designed to avoid making functions behave differently from what t=
hey appear to be. Your idea <i>requires</i> that they behave differently fr=
om what they appear to be.<br><br>That is, you're not merely deviating =
from the design of P0057, but the ideas behind that design.<br><br></div><b=
lockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;borde=
r-left: 1px #ccc solid;padding-left: 1ex;"><div> </div><blockquote class=3D=
"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc soli=
d;padding-left:1ex"><div dir=3D"ltr"><div></div><div><br></div><blockquote =
class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1px #=
ccc solid;padding-left:1ex"><div dir=3D"ltr"><blockquote class=3D"gmail_quo=
te" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-=
left:1ex"><div>That's not how P0057 works. Indeed, that's not what =
P0057 is <i>for</i>. Remember the general idea of await in P0057: it halts =
the function, but it also <i>explicitly</i> allows the transfer of control =
of the function to the <i>await expression</i>. And thus, control is not ne=
cessarily transferred to the return value.<br></div></blockquote><div><br>Y=
es, of course, it does not have to. <br></div></div></blockquote><div><br>S=
o... how do you do it? In P0057, it happens through `await_suspend`, which =
takes a coroutine_handle<>. So in your idea, how does it work?<br></d=
iv></div></blockquote><div><br>For example await_suspend can be function te=
mplate which takes concrete coroutine.<br></div></blockquote><div><br>By va=
lue or reference? Who's responsible for destroying it? When does that d=
estruction happen? How does that happen?<br><br>Also, there's the quest=
ion of the fact that your concrete coroutine is also returned from the func=
tion. Regardless of the exact mechanics of it, you have made it <i>very cle=
ar</i> that the return type of such concrete coroutines is <i>always</i> th=
e coroutine type or something that contains it.<br><br>So... who's supp=
osed to continue it? With a `future<int>`, the idea is that the calle=
r <i>doesn't</i> continue it; it will continue itself. The most the use=
r will do is call `get` and sit there until the value shows up. But if the =
return type is always some generated coroutine type, doesn't that imply=
that the caller should continue it?<br><br>How does the caller know if he&=
#39;s supposed to continue it or if it continues itself?<br><br></div><bloc=
kquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-l=
eft: 1px #ccc solid;padding-left: 1ex;"><div></div><blockquote class=3D"gma=
il_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;pa=
dding-left:1ex"><div dir=3D"ltr"><div></div><blockquote class=3D"gmail_quot=
e" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-l=
eft:1ex"><div dir=3D"ltr"><div></div><blockquote class=3D"gmail_quote" styl=
e=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-left:1ex=
"><div>Oh sure, you use different keywords. But the behavior of those keywo=
rds is basically the behavior of the functions P0114 implements. Basically,=
P0114 is what you want, even if you would prefer that the form appeared mo=
re like P0057.<br></div></blockquote><div><br>Personally I prefer P0114 - i=
t is more powerful, gives less overhead, and shifts from concrete await or =
yield features towards more general language feature.<br>But if P0057 is mu=
ch more likely to get into ISO, then I would like to remove discussed overh=
ead.<br></div></div></blockquote><div><br>Here's my problem with that n=
otion.<br><br>What you really want is P0114. But you don't believe that=
it'll make it in. So instead, you propose suggestions to change P0057.=
Which will in the end... turn it into a <i>gimped</i> version of P0114.<br=
></div></div></blockquote><div><br>P0114 is much more powerful than changes=
I propose.<br></div></blockquote><div><br>Yes. Hence being the gimped vers=
ion of P0114: all of the disadvantages of P0114 with none of its advantages=
..</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_1196_802985181.1445185622728--
------=_Part_1195_129683394.1445185622727--
.
Author: Nicol Bolas <jmckesson@gmail.com>
Date: Sun, 18 Oct 2015 09:47:03 -0700 (PDT)
Raw View
------=_Part_1180_1991823088.1445186823441
Content-Type: multipart/alternative;
boundary="----=_Part_1181_147142665.1445186823441"
------=_Part_1181_147142665.1445186823441
Content-Type: text/plain; charset=UTF-8
On Saturday, October 17, 2015 at 6:04:08 PM UTC-4, Gor Nishanov wrote:
>
>
>
> On Saturday, October 17, 2015 at 12:46:43 PM UTC-7, Nicol Bolas wrote:
>
> I'm not talking about elision rules. I'm talking about where we go when we
>> resume a coroutine. Again, we discussed this; remember my `processing`
>> example?
>>
>
> I remember. I just was not sure what conclusion you reached after the
> discussion.
>
My general conclusion is that P0057 wasn't really intended to cover my
problem domain (though your linked-list-of-handles solution does allow it
to work). P0057 seems mainly about being able to do continuations, with
some additional features to make generators possible.
My problems seem to best be solved by using a stack. I could then structure
my code however I like, avoiding lots of `await` and anyone can yield.
That's not a slight against P0057. It just wasn't for solving what I
thought it was meant to solve.
I will update you guys on the progress when I am back from Kona.
>
Good luck!
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.
------=_Part_1181_147142665.1445186823441
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><br><br>On Saturday, October 17, 2015 at 6:04:08 PM UTC-4,=
Gor Nishanov wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;ma=
rgin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=
=3D"ltr"><p><br><br>On Saturday, October 17, 2015 at 12:46:43 PM UTC-7, Nic=
ol Bolas wrote:</p><div><br></div><blockquote class=3D"gmail_quote" style=
=3D"margin:0px 0px 0px 0.8ex;padding-left:1ex;border-left-color:rgb(204,204=
,204);border-left-width:1px;border-left-style:solid"><div>I'm not talki=
ng about elision rules. I'm talking about where we go when we resume a =
coroutine. Again, we discussed this; remember my `processing` example?<br><=
/div></blockquote><div><br></div><div>I remember. I just was not sure what =
conclusion you reached after the discussion.</div></div></blockquote><div><=
br>My general conclusion is that P0057 wasn't really intended to cover =
my problem domain (though your linked-list-of-handles solution does allow i=
t to work). P0057 seems mainly about being able to do continuations, with s=
ome additional features to make generators possible.<br><br>My problems see=
m to best be solved by using a stack. I could then structure my code howeve=
r I like, avoiding lots of `await` and anyone can yield.<br><br>That's =
not a slight against P0057. It just wasn't for solving what I thought i=
t was meant to solve.<br><br></div><blockquote class=3D"gmail_quote" style=
=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: =
1ex;"><div dir=3D"ltr"><div>I will update you guys on the progress when I a=
m back from Kona.</div></div></blockquote><div><br>Good luck!</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_1181_147142665.1445186823441--
------=_Part_1180_1991823088.1445186823441--
.
Author: Nicol Bolas <jmckesson@gmail.com>
Date: Sun, 18 Oct 2015 11:05:57 -0700 (PDT)
Raw View
------=_Part_449_469717640.1445191557693
Content-Type: multipart/alternative;
boundary="----=_Part_450_1302961710.1445191557693"
------=_Part_450_1302961710.1445191557693
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
On Sunday, October 18, 2015 at 4:02:50 AM UTC-4, Evgeny Panasyuk wrote:
>
> 18 October 2015 =D0=B3., 0:47:38 UTC+3 Nicol Bolas :
>>
>>
>> But I don't claim to know everything. So I accept the existence of such=
=20
>> application domains. However, your suggestion was to adopt Boost.Corouti=
ne *instead=20
>> of* P0057, not in addition to. So while you would be serving your=20
>> application domain, you would also be performing a *disservice* to the=
=20
>> application domain served by P0057.
>>
>> Remember that P0057's primary use case is .then-style continuations. And=
=20
>> Boost.Coroutine doesn't help with that at all.
>>
>>
> Why? await can be implemented on top of Boost.Coroutine. And I already di=
d=20
> this:
>
> https://github.com/boostorg/coroutine/blob/master/example/cpp11/asymmetri=
c/await_emu.cpp
> https://github.com/panaseleus/await_emu
>
I can't say that I was able to fully comprehend what all that code is=20
doing. But it seems to me that your `Awaiter` is simply storing the task to=
=20
be continued on a stack in your `.then` continuation. So it's not actually,=
=20
you know, *continuing* it. So if the task being awaited on was executed in=
=20
a different thread, it's not clear that the continuation would continue=20
using that thread.
It seems to me that you've *flattened* `.then`, not implemented it.
--=20
---=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.
------=_Part_450_1302961710.1445191557693
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<br><br>On Sunday, October 18, 2015 at 4:02:50 AM UTC-4, Evgeny Panasyuk wr=
ote:<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">18 Octobe=
r 2015 =D0=B3., 0:47:38 UTC+3 Nicol Bolas :<blockquote class=3D"gmail_quote=
" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-le=
ft:1ex"><br><div>But I don't claim to know everything. So I accept the =
existence of such application domains. However, your suggestion was to adop=
t Boost.Coroutine <i>instead of</i> P0057, not in addition to. So while you=
would be serving your application domain, you would also be performing a <=
i>disservice</i> to the application domain served by P0057.<br><br>Remember=
that P0057's primary use case is .then-style continuations. And Boost.=
Coroutine doesn't help with that at all.<br><br></div></blockquote><div=
><br>Why? await can be implemented on top of Boost.Coroutine. And I already=
did this:<br><a href=3D"https://github.com/boostorg/coroutine/blob/master/=
example/cpp11/asymmetric/await_emu.cpp" target=3D"_blank" rel=3D"nofollow" =
onmousedown=3D"this.href=3D'https://www.google.com/url?q\75https%3A%2F%=
2Fgithub.com%2Fboostorg%2Fcoroutine%2Fblob%2Fmaster%2Fexample%2Fcpp11%2Fasy=
mmetric%2Fawait_emu.cpp\46sa\75D\46sntz\0751\46usg\75AFQjCNHtquF64sn1Udojvg=
uA0Ru27sQ9nQ';return true;" onclick=3D"this.href=3D'https://www.goo=
gle.com/url?q\75https%3A%2F%2Fgithub.com%2Fboostorg%2Fcoroutine%2Fblob%2Fma=
ster%2Fexample%2Fcpp11%2Fasymmetric%2Fawait_emu.cpp\46sa\75D\46sntz\0751\46=
usg\75AFQjCNHtquF64sn1UdojvguA0Ru27sQ9nQ';return true;">https://github.=
com/boostorg/<wbr>coroutine/blob/master/example/<wbr>cpp11/asymmetric/await=
_emu.cpp</a><br><a href=3D"https://github.com/panaseleus/await_emu" target=
=3D"_blank" rel=3D"nofollow" onmousedown=3D"this.href=3D'https://www.go=
ogle.com/url?q\75https%3A%2F%2Fgithub.com%2Fpanaseleus%2Fawait_emu\46sa\75D=
\46sntz\0751\46usg\75AFQjCNEjZKUW8FjVHCowRyLvkHeXj90mRg';return true;" =
onclick=3D"this.href=3D'https://www.google.com/url?q\75https%3A%2F%2Fgi=
thub.com%2Fpanaseleus%2Fawait_emu\46sa\75D\46sntz\0751\46usg\75AFQjCNEjZKUW=
8FjVHCowRyLvkHeXj90mRg';return true;">https://github.com/panaseleus/<wb=
r>await_emu</a></div></div></blockquote><div><br>I can't say that I was=
able to fully comprehend what all that code is doing. But it seems to me t=
hat your `Awaiter` is simply storing the task to be continued on a stack in=
your `.then` continuation. So it's not actually, you know, <i>continui=
ng</i> it. So if the task being awaited on was executed in a different thre=
ad, it's not clear that the continuation would continue using that thre=
ad.<br><br>It seems to me that you've <i>flattened</i> `.then`, not imp=
lemented it.<br></div>
<p></p>
-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />
------=_Part_450_1302961710.1445191557693--
------=_Part_449_469717640.1445191557693--
.
Author: Nicol Bolas <jmckesson@gmail.com>
Date: Sun, 18 Oct 2015 11:23:24 -0700 (PDT)
Raw View
------=_Part_478_119973242.1445192605059
Content-Type: multipart/alternative;
boundary="----=_Part_479_1971637168.1445192605068"
------=_Part_479_1971637168.1445192605068
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
On Sunday, October 18, 2015 at 3:57:30 AM UTC-4, Evgeny Panasyuk wrote:
>
> 17 October 2015 =D0=B3., 22:52:31 UTC+3 Nicol Bolas:
>>
>> On Saturday, October 17, 2015 at 1:28:25 PM UTC-4, Evgeny Panasyuk wrote=
:
>>>
>>> 17 October 2015 =D0=B3., 18:08:53 UTC+3 Nicol Bolas:
>>>>
>>>> And even when they can't, *you* can optimize them out with a decent=20
>>>>>> allocator.
>>>>>>
>>>>>
>>>>> First of all, I don't want to use custom allocators for simple things=
=20
>>>>> like generators. Second, even custom allocator is not zero-overhead -=
at=20
>>>>> least it must check size, because it is not known at compile time.
>>>>>
>>>>
>>>> You are genuinely and seriously claiming that a conditional branch=20
>>>> based on two numbers constitutes "overhead". And this overhead is so=
=20
>>>> incredibly *burdensome* (despite only happening in the generator's=20
>>>> initialization) that any and all language changes to remove said overh=
ead=20
>>>> are completely justified.
>>>>
>>>
>>> This is not the only overhead.
>>> If you create array of structs that contain coroutine inside
>>>
>>
>> Hold it. In order to store a typed coroutine, you must be able to copy=
=20
>> and/or move it. Correct? So... how do you do that?
>>
> =20
> No, you don't need to copy/move it. You can create array (not std::vector=
)=20
> of non-copyable and non-moveable things.
>
Coroutine types are generated by the compiler, but so are the *contents of=
=20
those types*. A coroutine type would therefore not have a default=20
constructor. Coroutines have to do things like store the parameters they're=
=20
generated with and such. The way to construct a new one is to call a=20
coroutine function.
So no, you can't create an array of them. Not without having each array=20
element be initialized by calling the coroutine function.
I checked through P0114, and its coroutines are immobile by design. Always.=
=20
>> So you can't rely on that.
>>
>> Wrong, it is not by design. They are immobile only to prevent possible=
=20
> subtle errors with local references. Copy/move can be easily enabled for=
=20
> P0114. And this is already mentioned at 10.1.
>
It is "mentioned" only in the sense that the author said, "Yes, they're=20
immobile, but I suppose we could make them mobile. Maybe." That's hardly a=
=20
serious discussion of the issues surrounding the concept.
=20
> Even if we allow copying/moving in cases, it would only be in cases where=
:
>>
>> 1: All parameters to the function are copy/moveable.
>>
>> 2: All automatic variables declared are copy/moveable.
>>
>> 3: The promise type and return types are copy/moveable (though the latte=
r=20
>> is necessitated by P0057).
>>
>> So if my function takes a `const std::string &`, it's immobile.
>>
>
> Right - whole object is automatically moveable/copyable if it's parts are=
=20
> moveable/copyable.
> =20
>
>> If my function does a `for(auto &x : vec)`, it's immobile. And so on.
>>
>> So those are the requirements for any coroutine callstack you plan on=20
>> sticking in an object. And unless you can come up with a way to copy=20
>> references (or any user-defined immobile type for that matter), these ru=
les=20
>> are inviolate.
>>
>
> I don't see problem here. Yes - you can't copy/move something with=20
> immobile parts, yes there are limitations. But I do want copy/move when=
=20
> parts are mobile.
>
The problems are:
1) How many functions do you write that *don't* violate one of those rules=
=20
listed above? A lot of functions take reference parameters or use=20
references internally. Your simplest example, `flatten`, couldn't help but=
=20
violate it, thus requiring that it be rewritten to use `reference_wrapper`.
2) How exactly do you inform users of this problem? Does your inducer=20
syntax have a way to say, "I expect the type generated to be mobile, and if=
=20
it isn't, error"? Will it point to the declaration that breaks mobility?
If the cost of generating that value is non-trivial, then the cost of the=
=20
>>>> virtual call to do said generation is negligible.
>>>>
>>> If the cost of *using* that value is non-trivial, then the cost of the=
=20
>>>> virtual call is again irrelevant.
>>>>
>>>
>>> virtual calls makes inlining much harder, i.e. prevents further=20
>>> optimizations.
>>>
>>
>> If the code implementing the potentially inlined function is non-trivial=
,=20
>> then the compiler wouldn't try to inline it.
>>
>
> Obviously inlining is not just "call" optimization, it allows to fuse=20
> different code parts. Yes, there are cases where compiler by default woul=
d=20
> not try to inline some function. And what?
>
The point being that, if you were doing actual work, inlining wouldn't=20
happen.
Not only that, there is no way to put `flatten` into a struct. Why? Because=
=20
>> it will almost certainly take its object *by reference*. So its=20
>> resulting coroutine type will be immobile. And therefore, you can't make=
it=20
>> a structure member.
>>
>
> Just take pointer or reference_wrapper. Or it could be stored internally=
=20
> as a pointer.
>
So now you have to take all your variables by reference_wrapper. That's=20
certainly a very *teachable* feature, isn't it?
And I think that's rather my point, in a nutshell. Look at *everything it=
=20
takes* to make this all work:
1) A way to designate whether a coroutine uses concrete types or not.=20
Concrete coroutines must be inline.
2) `auto` gets deduced as either a magic type or some user-defined type=20
that may be given a magic type.
3) The magic type may or may not be copy/moveable, depending on the=20
properties of the function.
4) Any user-defined awaiter type must be prepared to handle any such magic=
=20
type, should it be used inside a concrete coroutine. Mobile or not, it had=
=20
better be ready to deal with it.
5) Any user-defined promise type must be prepared to handle any such magic=
=20
type, should that promise be used with a concrete coroutine. Mobile or not,=
=20
it had better be ready to deal with it.
6) Writers of concrete coroutines need to be extra careful to never ever=20
use references to anything. Even doing `for(reference_wrapper<int> i :=20
arr)` is death if `arr` is a local stack variable.
This is not minor tweaking. This is not some small change to P0057. This is=
=20
a giant, tumor-like growth on top of it.
It's bad enough that P0057 is going to lead to a rash of functional-C++=20
>> programmers using `await` on `expected` objects...
>>
>
> Well, authors of P0057 did explicitly mention such use cases like=20
> optional, expected, etc:
>
> https://github.com/boostcon/cppnow_presentations_2015/blob/master/files/C=
ppNow2015_Coroutines_in_C%2B%2B17.pdf
>
That doesn't make it *good*...
And isn't transactional memory already being built into another TS? What=20
>> does that have to do with resumable functions?
>>
>
> It could be made on top of it. And for instance in Haskell it is=20
> implemented with STM monad.
>
"Because Haskell does it" is not a convincing argument ;)
--=20
---=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.
------=_Part_479_1971637168.1445192605068
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
On Sunday, October 18, 2015 at 3:57:30 AM UTC-4, Evgeny Panasyuk wrote:<blo=
ckquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-=
left: 1px #ccc solid;padding-left: 1ex;">17 October 2015 =D0=B3., 22:52:31 =
UTC+3 Nicol Bolas:<blockquote class=3D"gmail_quote" style=3D"margin:0;margi=
n-left:0.8ex;border-left:1px #ccc solid;padding-left:1ex">On Saturday, Octo=
ber 17, 2015 at 1:28:25 PM UTC-4, Evgeny Panasyuk wrote:<blockquote class=
=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc s=
olid;padding-left:1ex"><div dir=3D"ltr">17 October 2015 =D0=B3., 18:08:53 U=
TC+3 Nicol Bolas:<blockquote class=3D"gmail_quote" style=3D"margin:0;margin=
-left:0.8ex;border-left:1px #ccc solid;padding-left:1ex"><blockquote class=
=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc s=
olid;padding-left:1ex"><div dir=3D"ltr"><div> </div><blockquote class=3D"gm=
ail_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;p=
adding-left:1ex"><div>And even when they can't, <i>you</i> can optimize=
them out with a decent allocator.<br></div></blockquote><div><br>First of =
all, I don't want to use custom allocators for simple things like gener=
ators. Second, even custom allocator is not zero-overhead - at least it mus=
t check size, because it is not known at compile time.<br></div></div></blo=
ckquote><div><br>You are genuinely and seriously claiming that a conditiona=
l branch based on two numbers constitutes "overhead". And this ov=
erhead is so incredibly <i>burdensome</i> (despite only happening in the ge=
nerator's initialization) that any and all language changes to remove s=
aid overhead are completely justified.<br></div></blockquote><div><br>This =
is not the only overhead.<br>If you create array of structs that contain co=
routine inside</div></div></blockquote><div><br>Hold it. In order to store =
a typed coroutine, you must be able to copy and/or move it. Correct? So... =
how do you do that?<br></div></blockquote><div>=C2=A0<br>No, you don't =
need to copy/move it. You can create array (not std::vector) of non-copyabl=
e and non-moveable things.<br></div></blockquote><div><br>Coroutine types a=
re generated by the compiler, but so are the <i>contents of those types</i>=
.. A coroutine type would therefore not have a default constructor. Coroutin=
es have to do things like store the parameters they're generated with a=
nd such. The way to construct a new one is to call a coroutine function.<br=
><br>So no, you can't create an array of them. Not without having each =
array element be initialized by calling the coroutine function.<br><br></di=
v><blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;b=
order-left: 1px #ccc solid;padding-left: 1ex;"><div></div><blockquote class=
=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc s=
olid;padding-left:1ex"><div>I checked through P0114, and its coroutines are=
immobile by design. Always. So you can't rely on that.<br><br></div></=
blockquote><div>Wrong, it is not by design. They are immobile only to preve=
nt possible subtle errors with local references. Copy/move can be easily en=
abled for P0114. And this is already mentioned at 10.1.<br></div></blockquo=
te><div><br>It is "mentioned" only in the sense that the author s=
aid, "Yes, they're immobile, but I suppose we could make them mobi=
le. Maybe." That's hardly a serious discussion of the issues surro=
unding the concept.<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;"><div></div><blockquote class=3D"gmail_quote" style=3D"margin:0;margin=
-left:0.8ex;border-left:1px #ccc solid;padding-left:1ex"><div>Even if we al=
low copying/moving in cases, it would only be in cases where:<br><br>1: All=
parameters to the function are copy/moveable.<br><br></div></blockquote><b=
lockquote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-=
left:1px #ccc solid;padding-left:1ex"><div>2: All automatic variables decla=
red are copy/moveable.<br><br>3: The promise type and return types are copy=
/moveable (though the latter is necessitated by P0057).<br><br>So if my fun=
ction takes a `const std::string &`, it's immobile.</div></blockquo=
te><div><br>Right - whole object is automatically moveable/copyable if it&#=
39;s parts are moveable/copyable.<br>=C2=A0</div><blockquote class=3D"gmail=
_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;padd=
ing-left:1ex"><div>If my function does a `for(auto &x : vec)`, it's=
immobile. And so on.<br><br>So those are the requirements for any coroutin=
e callstack you plan on sticking in an object. And unless you can come up w=
ith a way to copy references (or any user-defined immobile type for that ma=
tter), these rules are inviolate.<br></div></blockquote><div><br>I don'=
t see problem here. Yes - you can't copy/move something with immobile p=
arts, yes there are limitations. But I do want copy/move when parts are mob=
ile.<br></div></blockquote><div><br>The problems are:<br><br>1) How many fu=
nctions do you write that <i>don't</i> violate one of those rules liste=
d above? A lot of functions take reference parameters or use references int=
ernally. Your simplest example, `flatten`, couldn't help but violate it=
, thus requiring that it be rewritten to use `reference_wrapper`.<br><br>2)=
How exactly do you inform users of this problem? Does your inducer syntax =
have a way to say, "I expect the type generated to be mobile, and if i=
t isn't, error"? Will it point to the declaration that breaks mobi=
lity?<br><br></div><blockquote class=3D"gmail_quote" style=3D"margin: 0;mar=
gin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div></div>=
<div></div><blockquote class=3D"gmail_quote" style=3D"margin:0;margin-left:=
0.8ex;border-left:1px #ccc solid;padding-left:1ex"><div></div><blockquote c=
lass=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1px #c=
cc solid;padding-left:1ex"><div dir=3D"ltr"><div></div><div></div><blockquo=
te class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1p=
x #ccc solid;padding-left:1ex"></blockquote><blockquote class=3D"gmail_quot=
e" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-l=
eft:1ex"><div>If the cost of generating that value is non-trivial, then the=
cost of the virtual call to do said generation is negligible.</div></block=
quote><blockquote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex=
;border-left:1px #ccc solid;padding-left:1ex"><div>If the cost of <i>using<=
/i> that value is non-trivial, then the cost of the virtual call is again i=
rrelevant.<br></div></blockquote><div><br>virtual calls makes inlining much=
harder, i.e. prevents further optimizations.<br></div></div></blockquote><=
div><br>If the code implementing the potentially inlined function is non-tr=
ivial, then the compiler wouldn't try to inline it.<br></div></blockquo=
te><div><br>Obviously inlining is not just "call" optimization, i=
t allows to fuse different code parts. Yes, there are cases where compiler =
by default would not try to inline some function. And what?<br></div></bloc=
kquote><div><br>The point being that, if you were doing actual work, inlini=
ng wouldn't happen.<br><br></div><blockquote class=3D"gmail_quote" styl=
e=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left:=
1ex;"><div></div><blockquote class=3D"gmail_quote" style=3D"margin:0;margi=
n-left:0.8ex;border-left:1px #ccc solid;padding-left:1ex"><div>Not only tha=
t, there is no way to put `flatten` into a struct. Why? Because it will alm=
ost certainly take its object <i>by reference</i>. So its resulting corouti=
ne type will be immobile. And therefore, you can't make it a structure =
member.<br></div></blockquote><div><br>Just take pointer or reference_wrapp=
er. Or it could be stored internally as a pointer.<br></div></blockquote><d=
iv><br>So now you have to take all your variables by reference_wrapper. Tha=
t's certainly a very <i>teachable</i> feature, isn't it?<br><br>And=
I think that's rather my point, in a nutshell. Look at <i>everything i=
t takes</i> to make this all work:<br><br>1) A way to designate whether a c=
oroutine uses concrete types or not. Concrete coroutines must be inline.<br=
><br>2) `auto` gets deduced as either a magic type or some user-defined typ=
e that may be given a magic type.<br><br>3) The magic type may or may not b=
e copy/moveable, depending on the properties of the function.<br><br>4) Any=
user-defined awaiter type must be prepared to handle any such magic type, =
should it be used inside a concrete coroutine. Mobile or not, it had better=
be ready to deal with it.<br><br>5) Any user-defined promise type must be =
prepared to handle any such magic type, should that promise be used with a =
concrete coroutine. Mobile or not, it had better be ready to deal with it.<=
br><br>6) Writers of concrete coroutines need to be extra careful to never =
ever use references to anything. Even doing `for(reference_wrapper<int&g=
t; i : arr)` is death if `arr` is a local stack variable.<br><br>This is no=
t minor tweaking. This is not some small change to P0057. This is a giant, =
tumor-like growth on top of it.<br><br></div><blockquote class=3D"gmail_quo=
te" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;paddi=
ng-left: 1ex;"><blockquote class=3D"gmail_quote" style=3D"margin:0;margin-l=
eft:0.8ex;border-left:1px #ccc solid;padding-left:1ex"><div></div></blockqu=
ote><div></div><blockquote class=3D"gmail_quote" style=3D"margin:0;margin-l=
eft:0.8ex;border-left:1px #ccc solid;padding-left:1ex"><div>It's bad en=
ough that P0057 is going to lead to a rash of functional-C++ programmers us=
ing `await` on `expected` objects...<br></div></blockquote><div><br>Well, a=
uthors of P0057 did explicitly mention such use cases like optional, expect=
ed, etc:<br><a href=3D"https://github.com/boostcon/cppnow_presentations_201=
5/blob/master/files/CppNow2015_Coroutines_in_C%2B%2B17.pdf" target=3D"_blan=
k" rel=3D"nofollow" onmousedown=3D"this.href=3D'https://www.google.com/=
url?q\75https%3A%2F%2Fgithub.com%2Fboostcon%2Fcppnow_presentations_2015%2Fb=
lob%2Fmaster%2Ffiles%2FCppNow2015_Coroutines_in_C%252B%252B17.pdf\46sa\75D\=
46sntz\0751\46usg\75AFQjCNFcEe0Mw7ldfhbczwAitCv0L93NiA';return true;" o=
nclick=3D"this.href=3D'https://www.google.com/url?q\75https%3A%2F%2Fgit=
hub.com%2Fboostcon%2Fcppnow_presentations_2015%2Fblob%2Fmaster%2Ffiles%2FCp=
pNow2015_Coroutines_in_C%252B%252B17.pdf\46sa\75D\46sntz\0751\46usg\75AFQjC=
NFcEe0Mw7ldfhbczwAitCv0L93NiA';return true;">https://github.com/boostco=
n/<wbr>cppnow_presentations_2015/<wbr>blob/master/files/CppNow2015_<wbr>Cor=
outines_in_C%2B%2B17.pdf</a><br></div></blockquote><div><br>That doesn'=
t make it <i>good</i>...<br><br></div><blockquote class=3D"gmail_quote" sty=
le=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left=
: 1ex;"><div></div><blockquote class=3D"gmail_quote" style=3D"margin:0;marg=
in-left:0.8ex;border-left:1px #ccc solid;padding-left:1ex"><div>And isn'=
;t transactional memory already being built into another TS? What does that=
have to do with resumable functions?<br></div></blockquote><div><br>It cou=
ld be made on top of it. And for instance in Haskell it is implemented with=
STM monad.<br></div></blockquote><div><br>"Because Haskell does it&qu=
ot; is not a convincing argument ;)<br></div>
<p></p>
-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />
------=_Part_479_1971637168.1445192605068--
------=_Part_478_119973242.1445192605059--
.
Author: Giovanni Piero Deretta <gpderetta@gmail.com>
Date: Tue, 20 Oct 2015 15:09:54 -0700 (PDT)
Raw View
------=_Part_4153_1850746811.1445378994838
Content-Type: multipart/alternative;
boundary="----=_Part_4154_970643614.1445378994839"
------=_Part_4154_970643614.1445378994839
Content-Type: text/plain; charset=UTF-8
On Saturday, October 17, 2015 at 10:47:38 PM UTC+1, Nicol Bolas wrote:
>
> On Saturday, October 17, 2015 at 4:39:25 PM UTC-4, Giovanni Piero Deretta
> wrote:
>>
>>
>> On 17 Oct 2015 4:41 p.m., "Nicol Bolas" <jmck...@gmail.com> wrote:
>> >
>> > On Saturday, October 17, 2015 at 10:24:29 AM UTC-4, Giovanni Piero
>> Deretta wrote:
>> >>
>> >>
>> >> On 16 Oct 2015 5:26 p.m., "Nicol Bolas" <jmck...@gmail.com> wrote:
>> >> .
>> >> >
>> >> > The nice thing about P0057 is that it doesn't have very many new
>> features. It pretty much stops at function suspend/resume and
>> internally-generated promise types. The return type of a coroutine is no
>> different from any other type. The awaiter type, even the promise type are
>> all types using the C++ rules for types.
>> >> >
>> >>
>> >> If the criterion is minimising the number of new language features, we
>> should just standardise Boost.coroutine. It is provably implementable as a
>> pure library, there is significant industry experience with it and it is
>> significantly more expressive than any stackless proposal.
>> >
>> >
>> > I think you mean Boost.Context. Boost.Coroutine is just an add-on
>> library for "asymmetric" coroutines, built ontop of Boost.Context. And we
>> already have Boost.Context proposed in P0099. Though adding
>> Boost.Coroutines onto it wouldn't go amiss.
>> >
>>
>> I really meant Boost coroutine, whose interface is explicit continuation
>> passing. I also want type safe parameters and I do not want current_context
>> that hinder optimisations.
>>
>
> Um... no.
>
> We all like to think about our own perspectives and use cases. I'm sure
> that, for your specific needs, Boost.Coroutine is a perfectly adequate
> solution. But features for standardization need to be *better* than that.
> P0099 implements the most broad feature: creation of execution contexts and
> switching between them. With that, you can implement any form of coroutine
> you like.
>
that's what 'boost.coroutine' does, with the addition of the ability to
pass parameters. Implementing this feature on top of 'void' contexts is
awkward and inefficient. The global current context just hinder
optimisations and it is easy to build on top if required.
>
> What you want is *extremely* limited in its utility. You have to pass the
> destination sink to every function you want to be able to yield. I don't
> know of a whole lot of non-C++ coroutine features that are that limited in
> their behavior.
>
I do not know why would you want a global mutable variable. If you are fine
with spooky action at distance, you are free to use a global thread_local
static to store your coroutine, but the standard shouldn't certainly
encourage that.
>
> Furthermore, I don't understand why you would want that when P0114 gives
> you the same optimizations in the same circumstances where those
> optimizations are possible. It simply is non-functional when those
> optimizations aren't possible.
>
exactly because they are non functional in more complex cases.
>
> It's one thing to rely on an optimization not allocating a 512-byte stack.
> It's quite another to rely on an optimization not allocation a 1-
> *megabyte* stack. I'd want that to be a firm, standard-provided
> guarantee, not merely a suggestion.
>
Note that for stackfull coroutines there are options that allow allocating
the stack on demand (a.k.a. split stack). This optimisation is available
today in existing libraries. But yes, there should be a way, via
annotation, to guarantee optimisations.
>
> > In any case, my point was that P0057 is able to provide significant and
>> useful features without breaking the language substantially. So prospective
>> "improvements" on it should be judged accordingly.
>> >
>>
>> What are these features that Boost coroutine doesn't have?
>>
>> >> The only advantage of P0057 is that its coroutines are guaranteed to
>> need a single frame instead of a whole side stack. It doesn't guarantee
>> freedom from heap allocation nor from type erasure. Sure, the overhead
>> might optimisable away in some cases, but there is no guarantee, also the
>> same exact optimisations are applicable to a Boost.coroutine-like design.
>> >
>> >
>> > The cost of a Boost.Context switch is massive compared to the cost of a
>> type-erased function call. The cost of allocating even a small
>> execution_context is massive compared to the small stacks of P0057.
>>
>> [Citation needed].
>>
>
> Here are the performance stats for `execution_context
> <http://www.google.com/url?q=http%3A%2F%2Fwww.boost.org%2Fdoc%2Flibs%2F1_59_0%2Flibs%2Fcontext%2Fdoc%2Fhtml%2Fcontext%2Fperformance.html&sa=D&sntz=1&usg=AFQjCNHm7sI-vl2qX5jz3lNtp1ivKCOR0w>.
> And here are the stats for Boost.Coroutine
> <http://www.boost.org/doc/libs/1_59_0/libs/coroutine/doc/html/coroutine/performance.html>.
> I can't say what the cost of a virtual function call is, but I'd wager it's
> rather less than 46 cycles (assuming cache hits, of course). And even with
> a preallocated stack, 10350 cycles for an asymmetric coroutine is "massive"
> for creation.
>
you can implement context switching in single digit cycles. On my old
laptop I measure 5 clock cycles per context switch.
> I also find the 116-710 cycles for creating a
>
> I would expect P0057 to be much rather on startup.
>
sorry, can't parse that.
>
>> >> In fact the same analysis used to remove heap allocation can be used
>> to remove the side stack.
>> >
>> >
>> > No, it can't.
>> >
>> > In P0057, there are exactly two places where you can get access to the
>> coroutine_handle: from within `await_suspend` called via an explicit
>> `await` expression and from within the promise object itself. The
>> interaction between the promise and the return type allow the return type
>> to store the handle. And thus, the compiler (assuming all of these are
>> inlined) can track exactly where the coroutine_handle ends up. It knows
>> where it gets resumed and it can see if the `generator` return object is
>> moved after its final destination.
>> >
>> > `execution_context` is much broader in scope. A context can be exited
>> from any function in the call stack. Equally importantly, this does not
>> necessarily resume the previous context; it can exit to any other context
>> in existence. Any function can access the current context and stick it into
>> any variable they wish.
>> >
>> > So there is no way for the optimizer to know that a particular
>> `execution_context` is local to a function. Without that locality, nothing
>> can be optimized away.
>>
>> In a Boost coroutine like scenario, as long as the father coroutine
>> handle does not leave the child coroutine body the compiler can make the
>> same exact inference: the current function will only pass control to the
>> caller from the current scope.
>>
>> Note that you can of course switch to a third coroutine from anywhere in
>> the call stack, but that doesn't invalidate the optimisation: for example
>> you can call a boost.coroutine from a p0057 generator just fine.
>>
>
> So you don't just want Boost.Coroutine. You specifically want only the asymmetric
> coroutines under that system
> <http://www.boost.org/doc/libs/1_59_0/libs/coroutine/doc/html/coroutine/coroutine.html>.
> That's an even bigger limitation.
>
no, of course not, I want symmetric coroutines. Why would you say that?
>
> I do not understand what promises have anything to do with whether the
>> coroutine frame is heap allocated or not.
>>
>
> I brought up promise types because they're an implementation detail of
> P0057. They're one of the only places that have easy access to the
> coroutine_handle, and tracking who has access to it is necessary for
> implementing the optimization.
>
I still do not understand the relevance of the above for a stackful
coroutine implementaiton
--
---
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_4154_970643614.1445378994839
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
On Saturday, October 17, 2015 at 10:47:38 PM UTC+1, Nicol Bolas wrote:<bloc=
kquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-l=
eft: 1px #ccc solid;padding-left: 1ex;">On Saturday, October 17, 2015 at 4:=
39:25 PM UTC-4, Giovanni Piero Deretta wrote:<blockquote class=3D"gmail_quo=
te" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-=
left:1ex"><p dir=3D"ltr"><br>
On 17 Oct 2015 4:41 p.m., "Nicol Bolas" <<a rel=3D"nofollow">j=
mck...@gmail.com</a>> wrote:<br>
><br>
> On Saturday, October 17, 2015 at 10:24:29 AM UTC-4, Giovanni Piero Der=
etta wrote:<br>
>><br>
>><br>
>> On 16 Oct 2015 5:26 p.m., "Nicol Bolas" <<a>jmck...@g=
mail.com</a>> wrote:<br>
>> .<br>
>> ><br>
>> > The nice thing about P0057 is that it doesn't have very m=
any new features. It pretty much stops at function suspend/resume and inter=
nally-generated promise types. The return type of a coroutine is no differe=
nt from any other type. The awaiter type, even the promise type are all typ=
es using the C++ rules for types.<br>
>> ><br>
>><br>
>> If the criterion is minimising the number of new language features=
, we should just standardise Boost.coroutine. It is provably implementable =
as a pure library, there is significant industry experience with it and it =
is significantly more expressive than any stackless proposal.<br>
><br>
><br>
> I think you mean Boost.Context. Boost.Coroutine is just an add-on libr=
ary for "asymmetric" coroutines, built ontop of Boost.Context. An=
d we already have Boost.Context proposed in P0099. Though adding Boost.Coro=
utines onto it wouldn't go amiss.<br>
></p>
<p dir=3D"ltr">I really meant Boost coroutine, whose interface is explicit =
continuation passing. I also want type safe parameters and I do not want cu=
rrent_context that hinder=C2=A0 optimisations.</p></blockquote><div><br>Um.=
... no.<br><br>We all like to think about our own perspectives and use cases=
.. I'm sure that, for your specific needs, Boost.Coroutine is a perfectl=
y adequate solution. But features for standardization need to be <i>better<=
/i> than that. P0099 implements the most broad feature: creation of executi=
on contexts and switching between them. With that, you can implement any fo=
rm of coroutine you like.<br></div></blockquote><div><br>that's what &#=
39;boost.coroutine' does, with the addition of the ability to pass para=
meters. Implementing this feature on top of 'void' contexts is awkw=
ard and inefficient. The global current context just hinder optimisations a=
nd it is easy to build on top if required.<br>=C2=A0</div><blockquote class=
=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #cc=
c solid;padding-left: 1ex;"><div><br>What you want is <i>extremely</i> limi=
ted in its utility. You have to pass the destination sink to every function=
you want to be able to yield. I don't know of a whole lot of non-C++ c=
oroutine features that are that limited in their behavior.<br></div></block=
quote><div><br>I do not know why would you want a global mutable variable. =
If you are fine with spooky action at distance, you are free to use a globa=
l thread_local static to store your coroutine, but the standard shouldn'=
;t certainly encourage that. <br>=C2=A0</div><blockquote class=3D"gmail_quo=
te" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;paddi=
ng-left: 1ex;"><div><br>Furthermore, I don't understand why you would w=
ant that when P0114 gives you the same optimizations in the same circumstan=
ces where those optimizations are possible. It simply is non-functional whe=
n those optimizations aren't possible.<br></div></blockquote><div><br>e=
xactly because they are non functional in more complex cases.<br>=C2=A0</di=
v><blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;b=
order-left: 1px #ccc solid;padding-left: 1ex;"><div><br>It's one thing =
to rely on an optimization not allocating a 512-byte stack. It's quite =
another to rely on an optimization not allocation a 1-<i>megabyte</i> stack=
.. I'd want that to be a firm, standard-provided guarantee, not merely a=
suggestion.<br></div></blockquote><div><br>Note that for stackfull corouti=
nes there are options that allow allocating the stack on demand (a.k.a. spl=
it stack). This optimisation is available today in existing libraries. But =
yes, there should be a way, via annotation, to guarantee optimisations.<br>=
=C2=A0<br></div><blockquote class=3D"gmail_quote" style=3D"margin: 0;margin=
-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div><br></div=
><blockquote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;bord=
er-left:1px #ccc solid;padding-left:1ex">
<p dir=3D"ltr">> In any case, my point was that P0057 is able to provide=
significant and useful features without breaking the language substantiall=
y. So prospective "improvements" on it should be judged according=
ly.<br>
></p>
<p dir=3D"ltr">What are these features that Boost coroutine doesn't hav=
e?</p>
<p dir=3D"ltr">>> The only advantage of P0057 is that its coroutines =
are guaranteed to need a single frame instead of a whole side stack. It doe=
sn't guarantee freedom from heap allocation nor from type erasure. Sure=
, the overhead might optimisable away in some cases, but there is no guaran=
tee, also the same exact optimisations are applicable to a Boost.coroutine-=
like design.<br>
><br>
><br>
> The cost of a Boost.Context switch is massive compared to the cost of =
a type-erased function call. The cost of allocating even a small execution_=
context is massive compared to the small stacks of P0057.</p>
<p dir=3D"ltr">[Citation needed]. <br></p></blockquote><div><br>Here are th=
e <a href=3D"http://www.google.com/url?q=3Dhttp%3A%2F%2Fwww.boost.org%2Fdoc=
%2Flibs%2F1_59_0%2Flibs%2Fcontext%2Fdoc%2Fhtml%2Fcontext%2Fperformance.html=
&sa=3DD&sntz=3D1&usg=3DAFQjCNHm7sI-vl2qX5jz3lNtp1ivKCOR0w" targ=
et=3D"_blank" rel=3D"nofollow" onmousedown=3D"this.href=3D'http://www.g=
oogle.com/url?q\75http%3A%2F%2Fwww.boost.org%2Fdoc%2Flibs%2F1_59_0%2Flibs%2=
Fcontext%2Fdoc%2Fhtml%2Fcontext%2Fperformance.html\46sa\75D\46sntz\0751\46u=
sg\75AFQjCNHm7sI-vl2qX5jz3lNtp1ivKCOR0w';return true;" onclick=3D"this.=
href=3D'http://www.google.com/url?q\75http%3A%2F%2Fwww.boost.org%2Fdoc%=
2Flibs%2F1_59_0%2Flibs%2Fcontext%2Fdoc%2Fhtml%2Fcontext%2Fperformance.html\=
46sa\75D\46sntz\0751\46usg\75AFQjCNHm7sI-vl2qX5jz3lNtp1ivKCOR0w';return=
true;">performance stats for `execution_context</a>. And here are the <a h=
ref=3D"http://www.boost.org/doc/libs/1_59_0/libs/coroutine/doc/html/corouti=
ne/performance.html" target=3D"_blank" rel=3D"nofollow" onmousedown=3D"this=
..href=3D'http://www.google.com/url?q\75http%3A%2F%2Fwww.boost.org%2Fdoc=
%2Flibs%2F1_59_0%2Flibs%2Fcoroutine%2Fdoc%2Fhtml%2Fcoroutine%2Fperformance.=
html\46sa\75D\46sntz\0751\46usg\75AFQjCNG63O_4Zv5QPw5_HtW-Jm35bVLsfQ';r=
eturn true;" onclick=3D"this.href=3D'http://www.google.com/url?q\75http=
%3A%2F%2Fwww.boost.org%2Fdoc%2Flibs%2F1_59_0%2Flibs%2Fcoroutine%2Fdoc%2Fhtm=
l%2Fcoroutine%2Fperformance.html\46sa\75D\46sntz\0751\46usg\75AFQjCNG63O_4Z=
v5QPw5_HtW-Jm35bVLsfQ';return true;">stats for Boost.Coroutine</a>. I c=
an't say what the cost of a virtual function call is, but I'd wager=
it's rather less than 46 cycles (assuming cache hits, of course). And =
even with a preallocated stack, 10350 cycles for an asymmetric coroutine is=
"massive" for creation. </div></blockquote><div><br>you can impl=
ement context switching in single digit cycles. On my old laptop I measure =
5 clock cycles per context switch.<br><br>=C2=A0</div><blockquote class=3D"=
gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc so=
lid;padding-left: 1ex;"><div>I also find the 116-710 cycles for creating a =
<br><br>I would expect P0057 to be much rather on startup.<br></div></block=
quote><div><br>sorry, can't parse that. <br><br></div><blockquote class=
=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #cc=
c solid;padding-left: 1ex;"><blockquote class=3D"gmail_quote" style=3D"marg=
in:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-left:1ex">
<p dir=3D"ltr">><br>
>> In fact the same analysis used to remove heap allocation can be us=
ed to remove the side stack.<br>
><br>
><br>
> No, it can't.<br>
><br>
> In P0057, there are exactly two places where you can get access to the=
coroutine_handle: from within `await_suspend` called via an explicit `awai=
t` expression and from within the promise object itself. The interaction be=
tween the promise and the return type allow the return type to store the ha=
ndle. And thus, the compiler (assuming all of these are inlined) can track =
exactly where the coroutine_handle ends up. It knows where it gets resumed =
and it can see if the `generator` return object is moved after its final de=
stination.<br>
><br>
> `execution_context` is much broader in scope. A context can be exited =
from any function in the call stack. Equally importantly, this does not nec=
essarily resume the previous context; it can exit to any other context in e=
xistence. Any function can access the current context and stick it into any=
variable they wish.<br>
><br>
> So there is no way for the optimizer to know that a particular `execut=
ion_context` is local to a function. Without that locality, nothing can be =
optimized away.</p>
<p dir=3D"ltr">In a Boost coroutine like scenario, as long as the father co=
routine handle does not leave the child coroutine body the compiler can mak=
e the same exact inference: the current function will only pass control to =
the caller from the current scope. </p>
<p dir=3D"ltr"> Note that you can of course switch to a third coroutine fro=
m anywhere in the call stack, but that doesn't invalidate the optimisat=
ion: for example you can call a boost.coroutine from a p0057 generator just=
fine.</p></blockquote><div><br>So you don't just want Boost.Coroutine.=
You specifically want only the <a href=3D"http://www.boost.org/doc/libs/1_=
59_0/libs/coroutine/doc/html/coroutine/coroutine.html" target=3D"_blank" re=
l=3D"nofollow" onmousedown=3D"this.href=3D'http://www.google.com/url?q\=
75http%3A%2F%2Fwww.boost.org%2Fdoc%2Flibs%2F1_59_0%2Flibs%2Fcoroutine%2Fdoc=
%2Fhtml%2Fcoroutine%2Fcoroutine.html\46sa\75D\46sntz\0751\46usg\75AFQjCNGPx=
TzmVbH6KnEellWyNuXCvn3wKQ';return true;" onclick=3D"this.href=3D'ht=
tp://www.google.com/url?q\75http%3A%2F%2Fwww.boost.org%2Fdoc%2Flibs%2F1_59_=
0%2Flibs%2Fcoroutine%2Fdoc%2Fhtml%2Fcoroutine%2Fcoroutine.html\46sa\75D\46s=
ntz\0751\46usg\75AFQjCNGPxTzmVbH6KnEellWyNuXCvn3wKQ';return true;">asym=
metric coroutines under that system</a>. That's an even bigger limitati=
on.<br></div></blockquote><div><br>no, of course not, I want symmetric coro=
utines. Why would you say that? <br></div><blockquote class=3D"gmail_quote"=
style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-=
left: 1ex;"><div><br></div><blockquote class=3D"gmail_quote" style=3D"margi=
n:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-left:1ex">
<p dir=3D"ltr">I do not understand what promises have anything to do with w=
hether the coroutine frame is heap allocated or not.</p></blockquote><div><=
br></div>I brought up promise types because they're an implementation d=
etail of P0057. They're one of the only places that have easy access to=
the coroutine_handle, and tracking who has access to it is necessary for i=
mplementing the optimization.<br></blockquote><div><br>I still do not under=
stand the relevance of the above for a stackful coroutine implementaiton<br=
>=C2=A0</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_4154_970643614.1445378994839--
------=_Part_4153_1850746811.1445378994838--
.
Author: Oliver Kowalke <oliver.kowalke@gmail.com>
Date: Wed, 21 Oct 2015 00:59:06 +0200
Raw View
--089e01227efca39cd8052291363a
Content-Type: text/plain; charset=UTF-8
2015-10-21 0:09 GMT+02:00 Giovanni Piero Deretta <gpderetta@gmail.com>:
> We all like to think about our own perspectives and use cases. I'm sure
>> that, for your specific needs, Boost.Coroutine is a perfectly adequate
>> solution. But features for standardization need to be *better* than
>> that. P0099 implements the most broad feature: creation of execution
>> contexts and switching between them. With that, you can implement any form
>> of coroutine you like.
>>
>
> that's what 'boost.coroutine' does, with the addition of the ability to
> pass parameters. Implementing this feature on top of 'void' contexts is
> awkward and inefficient. The global current context just hinder
> optimisations and it is easy to build on top if required.
>
if you refer to class execution_context from boost.context - it allows to
pass data through a context switch.
execution_context::current() is a thread-local, local static pointer to a
execution_context.
P0099R1 will probably reflect this.
> Here are the performance stats for `execution_context
> <http://www.google.com/url?q=http%3A%2F%2Fwww.boost.org%2Fdoc%2Flibs%2F1_59_0%2Flibs%2Fcontext%2Fdoc%2Fhtml%2Fcontext%2Fperformance.html&sa=D&sntz=1&usg=AFQjCNHm7sI-vl2qX5jz3lNtp1ivKCOR0w>.
> And here are the stats for Boost.Coroutine
> <http://www.boost.org/doc/libs/1_59_0/libs/coroutine/doc/html/coroutine/performance.html>.
> I can't say what the cost of a virtual function call is, but I'd wager it's
> rather less than 46 cycles (assuming cache hits, of course). And even with
> a preallocated stack, 10350 cycles for an asymmetric coroutine is "massive"
> for creation.
>
> you can implement context switching in single digit cycles. On my old
> laptop I measure 5 clock cycles per context switch.
>
sure that the simple context switch will take < 10 CPU cycles - but you
need some maintenance code too
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.
--089e01227efca39cd8052291363a
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">2015=
-10-21 0:09 GMT+02:00 Giovanni Piero Deretta <span dir=3D"ltr"><<a href=
=3D"mailto:gpderetta@gmail.com" target=3D"_blank">gpderetta@gmail.com</a>&g=
t;</span>:<br><blockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px=
0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><blockquote=
class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;border-left:1px so=
lid rgb(204,204,204);padding-left:1ex"><div>We all like to think about our =
own perspectives and use cases. I'm sure that, for your specific needs,=
Boost.Coroutine is a perfectly adequate solution. But features for standar=
dization need to be <i>better</i> than that. P0099 implements the most broa=
d feature: creation of execution contexts and switching between them. With =
that, you can implement any form of coroutine you like.<br></div></blockquo=
te><div><br>that's what 'boost.coroutine' does, with the additi=
on of the ability to pass parameters. Implementing this feature on top of &=
#39;void' contexts is awkward and inefficient. The global current conte=
xt just hinder optimisations and it is easy to build on top if required.<br=
></div></blockquote><div><br></div><div>if you refer to class execution_con=
text from boost.context - it allows to pass data through a context switch.<=
br></div><div>execution_context::current() is a thread-local, local static =
pointer to a execution_context.<br></div><div>P0099R1 will probably reflect=
this.<br></div><div>=C2=A0</div><blockquote class=3D"gmail_quote" style=3D=
"margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-le=
ft:1ex"><div>Here are the <a href=3D"http://www.google.com/url?q=3Dhttp%3A%=
2F%2Fwww.boost.org%2Fdoc%2Flibs%2F1_59_0%2Flibs%2Fcontext%2Fdoc%2Fhtml%2Fco=
ntext%2Fperformance.html&sa=3DD&sntz=3D1&usg=3DAFQjCNHm7sI-vl2q=
X5jz3lNtp1ivKCOR0w" rel=3D"nofollow" target=3D"_blank">performance stats fo=
r `execution_context</a>. And here are the <a href=3D"http://www.boost.org/=
doc/libs/1_59_0/libs/coroutine/doc/html/coroutine/performance.html" rel=3D"=
nofollow" target=3D"_blank">stats for Boost.Coroutine</a>. I can't say =
what the cost of a virtual function call is, but I'd wager it's rat=
her less than 46 cycles (assuming cache hits, of course). And even with a p=
reallocated stack, 10350 cycles for an asymmetric coroutine is "massiv=
e" for creation. </div><div><br>you can implement context switching in=
single digit cycles. On my old laptop I measure 5 clock cycles per context=
switch.<br></div></blockquote><div><br></div><div>sure that the simple con=
text switch will take < 10 CPU cycles - but you need some maintenance co=
de too<br></div><div><br></div></div><br></div></div>
<p></p>
-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />
--089e01227efca39cd8052291363a--
.
Author: Giovanni Piero Deretta <gpderetta@gmail.com>
Date: Wed, 21 Oct 2015 02:09:04 -0700 (PDT)
Raw View
------=_Part_136_1732553253.1445418544634
Content-Type: multipart/alternative;
boundary="----=_Part_137_365265064.1445418544634"
------=_Part_137_365265064.1445418544634
Content-Type: text/plain; charset=UTF-8
On Tuesday, October 20, 2015 at 11:59:27 PM UTC+1, Oliver Kowalke wrote:
>
> 2015-10-21 0:09 GMT+02:00 Giovanni Piero Deretta <gpde...@gmail.com
> <javascript:>>:
>
>> We all like to think about our own perspectives and use cases. I'm sure
>>> that, for your specific needs, Boost.Coroutine is a perfectly adequate
>>> solution. But features for standardization need to be *better* than
>>> that. P0099 implements the most broad feature: creation of execution
>>> contexts and switching between them. With that, you can implement any form
>>> of coroutine you like.
>>>
>>
>> that's what 'boost.coroutine' does, with the addition of the ability to
>> pass parameters. Implementing this feature on top of 'void' contexts is
>> awkward and inefficient. The global current context just hinder
>> optimisations and it is easy to build on top if required.
>>
>
> if you refer to class execution_context from boost.context - it allows to
> pass data through a context switch.
>
to be clear, I meant the execution_context as described in P0099R0. I just
reread it and as far as I can tell doesn't have a native facility for
parameter passing. I believe this is an important functionality, and the
switching primitive should at least allow passing a void* through.
> execution_context::current() is a thread-local, local static pointer to a
> execution_context.
> P0099R1 will probably reflect this.
>
I still do not see what's the use case for current(). In a way it is a
wrong concept: an execution_context captures the state of an *halted*
thread of execution, so there is no valid execution_context state for the
currently running thread of execution.
>
>
>> Here are the performance stats for `execution_context
>> <http://www.google.com/url?q=http%3A%2F%2Fwww.boost.org%2Fdoc%2Flibs%2F1_59_0%2Flibs%2Fcontext%2Fdoc%2Fhtml%2Fcontext%2Fperformance.html&sa=D&sntz=1&usg=AFQjCNHm7sI-vl2qX5jz3lNtp1ivKCOR0w>.
>> And here are the stats for Boost.Coroutine
>> <http://www.boost.org/doc/libs/1_59_0/libs/coroutine/doc/html/coroutine/performance.html>.
>> I can't say what the cost of a virtual function call is, but I'd wager it's
>> rather less than 46 cycles (assuming cache hits, of course). And even with
>> a preallocated stack, 10350 cycles for an asymmetric coroutine is "massive"
>> for creation.
>>
>> you can implement context switching in single digit cycles. On my old
>> laptop I measure 5 clock cycles per context switch.
>>
>
> sure that the simple context switch will take < 10 CPU cycles - but you
> need some maintenance code too
>
>
>
what maintenance code exactly? I've just looked at boost.context
implementation and the operator() seems pretty minimal.
My "fast" context switching implementation uses GCC inline assembly and a
large list of clobbered registers so that the switching code itself does
not need to conservatively save and restore all callee saved registers; The
code works and is fast, but it is tricky and flaky (I would not recommend
it for a pure library implementation, depending on the version, GCC might
not like the large clobber list and you tend to hit dark corners of the
optimiser) but it shows that with compiler help context switch does not
need to be slow.
--
---
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_137_365265064.1445418544634
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
On Tuesday, October 20, 2015 at 11:59:27 PM UTC+1, Oliver Kowalke wrote:<bl=
ockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border=
-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr"><div><div class=
=3D"gmail_quote">2015-10-21 0:09 GMT+02:00 Giovanni Piero Deretta <span dir=
=3D"ltr"><<a href=3D"javascript:" target=3D"_blank" gdf-obfuscated-mailt=
o=3D"DzN_1RKMEAAJ" rel=3D"nofollow" onmousedown=3D"this.href=3D'javascr=
ipt:';return true;" onclick=3D"this.href=3D'javascript:';return=
true;">gpde...@gmail.com</a>></span>:<br><blockquote class=3D"gmail_quo=
te" style=3D"margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204=
);padding-left:1ex"><blockquote class=3D"gmail_quote" style=3D"margin:0px 0=
px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div>=
We all like to think about our own perspectives and use cases. I'm sure=
that, for your specific needs, Boost.Coroutine is a perfectly adequate sol=
ution. But features for standardization need to be <i>better</i> than that.=
P0099 implements the most broad feature: creation of execution contexts an=
d switching between them. With that, you can implement any form of coroutin=
e you like.<br></div></blockquote><div><br>that's what 'boost.corou=
tine' does, with the addition of the ability to pass parameters. Implem=
enting this feature on top of 'void' contexts is awkward and ineffi=
cient. The global current context just hinder optimisations and it is easy =
to build on top if required.<br></div></blockquote><div><br></div><div>if y=
ou refer to class execution_context from boost.context - it allows to pass =
data through a context switch.<br></div></div></div></div></blockquote><div=
><br>to be clear, I meant the execution_context as described in P0099R0. I =
just reread it and as far as I can tell doesn't have a native facility =
for parameter passing. I believe this is an important functionality, and th=
e switching primitive should at least allow passing a void* through.<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;"><div dir=3D"ltr"><div=
><div class=3D"gmail_quote"><div></div><div>execution_context::current() is=
a thread-local, local static pointer to a execution_context.<br></div><div=
>P0099R1 will probably reflect this.<br></div></div></div></div></blockquot=
e><div><br>I still do not see what's the use case for current(). In a w=
ay it is a wrong concept: an execution_context captures the state of an *ha=
lted* thread of execution, so there is no valid execution_context state for=
the currently running thread of execution.<br>=C2=A0</div><blockquote clas=
s=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #c=
cc solid;padding-left: 1ex;"><div dir=3D"ltr"><div><div class=3D"gmail_quot=
e"><div>=C2=A0</div><blockquote class=3D"gmail_quote" style=3D"margin:0px 0=
px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div>=
Here are the <a href=3D"http://www.google.com/url?q=3Dhttp%3A%2F%2Fwww.boos=
t.org%2Fdoc%2Flibs%2F1_59_0%2Flibs%2Fcontext%2Fdoc%2Fhtml%2Fcontext%2Fperfo=
rmance.html&sa=3DD&sntz=3D1&usg=3DAFQjCNHm7sI-vl2qX5jz3lNtp1ivK=
COR0w" rel=3D"nofollow" target=3D"_blank" onmousedown=3D"this.href=3D'h=
ttp://www.google.com/url?q\75http%3A%2F%2Fwww.boost.org%2Fdoc%2Flibs%2F1_59=
_0%2Flibs%2Fcontext%2Fdoc%2Fhtml%2Fcontext%2Fperformance.html\46sa\75D\46sn=
tz\0751\46usg\75AFQjCNHm7sI-vl2qX5jz3lNtp1ivKCOR0w';return true;" oncli=
ck=3D"this.href=3D'http://www.google.com/url?q\75http%3A%2F%2Fwww.boost=
..org%2Fdoc%2Flibs%2F1_59_0%2Flibs%2Fcontext%2Fdoc%2Fhtml%2Fcontext%2Fperfor=
mance.html\46sa\75D\46sntz\0751\46usg\75AFQjCNHm7sI-vl2qX5jz3lNtp1ivKCOR0w&=
#39;;return true;">performance stats for `execution_context</a>. And here a=
re the <a href=3D"http://www.boost.org/doc/libs/1_59_0/libs/coroutine/doc/h=
tml/coroutine/performance.html" rel=3D"nofollow" target=3D"_blank" onmoused=
own=3D"this.href=3D'http://www.google.com/url?q\75http%3A%2F%2Fwww.boos=
t.org%2Fdoc%2Flibs%2F1_59_0%2Flibs%2Fcoroutine%2Fdoc%2Fhtml%2Fcoroutine%2Fp=
erformance.html\46sa\75D\46sntz\0751\46usg\75AFQjCNG63O_4Zv5QPw5_HtW-Jm35bV=
LsfQ';return true;" onclick=3D"this.href=3D'http://www.google.com/u=
rl?q\75http%3A%2F%2Fwww.boost.org%2Fdoc%2Flibs%2F1_59_0%2Flibs%2Fcoroutine%=
2Fdoc%2Fhtml%2Fcoroutine%2Fperformance.html\46sa\75D\46sntz\0751\46usg\75AF=
QjCNG63O_4Zv5QPw5_HtW-Jm35bVLsfQ';return true;">stats for Boost.Corouti=
ne</a>. I can't say what the cost of a virtual function call is, but I&=
#39;d wager it's rather less than 46 cycles (assuming cache hits, of co=
urse). And even with a preallocated stack, 10350 cycles for an asymmetric c=
oroutine is "massive" for creation. </div><div><br>you can implem=
ent context switching in single digit cycles. On my old laptop I measure 5 =
clock cycles per context switch.<br></div></blockquote><div><br></div><div>=
sure that the simple context switch will take < 10 CPU cycles - but you =
need some maintenance code too<br></div><div><br></div></div><br></div></di=
v></blockquote><div><br>what maintenance code exactly? I've just looked=
at boost.context implementation and the operator() seems pretty minimal.<b=
r><br>My "fast" context switching implementation uses GCC inline =
assembly and a large list of clobbered registers so that the switching code=
itself does not need to conservatively save and restore all callee saved r=
egisters; The code works and is fast, but it is tricky and flaky (I would n=
ot recommend it for a pure library implementation, depending on the version=
, GCC might not like the large clobber list and you tend to hit dark corner=
s of the optimiser) but it shows that with compiler help context switch doe=
s not need to be slow.<br></div>
<p></p>
-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />
------=_Part_137_365265064.1445418544634--
------=_Part_136_1732553253.1445418544634--
.
Author: Oliver Kowalke <oliver.kowalke@gmail.com>
Date: Wed, 21 Oct 2015 12:44:43 +0200
Raw View
--089e015383e818e0ed05229b123b
Content-Type: text/plain; charset=UTF-8
2015-10-21 11:09 GMT+02:00 Giovanni Piero Deretta <gpderetta@gmail.com>:
> if you refer to class execution_context from boost.context - it allows to
>> pass data through a context switch.
>>
>
> to be clear, I meant the execution_context as described in P0099R0. I just
> reread it and as far as I can tell doesn't have a native facility for
> parameter passing. I believe this is an important functionality, and the
> switching primitive should at least allow passing a void* through.
>
yes, P0099R0 does not reflect this change - working on boost.fiber I
encountered the need for passing parameters through the context switch.
I added this functionality to boost.context - at the moment only of type
void pointer.
>
>
>> execution_context::current() is a thread-local, local static pointer to a
>> execution_context.
>> P0099R1 will probably reflect this.
>>
>
> I still do not see what's the use case for current(). In a way it is a
> wrong concept: an execution_context captures the state of an *halted*
> thread of execution, so there is no valid execution_context state for the
> currently running thread of execution.
>
for me, an execution context consits out of a stack and a set of CPU
registers (stack pointer, instruction pointer, some other registers defined
by the ABI).
if you start/enter main() or start/enter a thread (thread-fn) you already
have an execution context. You need a way to access this context.
Especially in teh case of userland-threads/fibers the main
execution-context can be handled as a fiber too. that's the case for
boost.fiber were the main context (running main())
is handled as the other threads (no difference). That means I need a way to
assign and access the main context. Without execution_context:current()
I would need to hold and pass the current context to each place where it is
need.
For instance you can run a fiber (from boost.fiber) and executing
coroutines from boost.coroutine2. both access the same current
execution_context.
Another example, boost.fiber allows directly call
boost::this_fiber::yiled() in main() without to invoke any initialization
functionality directly.
>
>
>> sure that the simple context switch will take < 10 CPU cycles - but you
>> need some maintenance code to
>>
>>
> what maintenance code exactly? I've just looked at boost.context
> implementation and the operator() seems pretty minimal.
>
the context switch using jump_fcontext() takes < 10 CPU cycles, while
execution_context::operator() need more cycles because it has to update TLS.
> My "fast" context switching implementation uses GCC inline assembly and a
> large list of clobbered registers so that the switching code itself does
> not need to conservatively save and restore all callee saved registers; The
> code works and is fast, but it is tricky and flaky (I would not recommend
> it for a pure library implementation, depending on the version, GCC might
> not like the large clobber list and you tend to hit dark corners of the
> optimiser) but it shows that with compiler help context switch does not
> need to be slow.
>
yes, but boost.context was required to support a broad range of compilers
and unfortunately MS decided to drop inline assembler for 64Bit MS VC.
--
---
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/.
--089e015383e818e0ed05229b123b
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">2015=
-10-21 11:09 GMT+02:00 Giovanni Piero Deretta <span dir=3D"ltr"><<a href=
=3D"mailto:gpderetta@gmail.com" target=3D"_blank">gpderetta@gmail.com</a>&g=
t;</span>:<br><blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;=
border-left:1px #ccc solid;padding-left:1ex"><span class=3D""><blockquote c=
lass=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1px #c=
cc solid;padding-left:1ex"><div dir=3D"ltr"><div><div class=3D"gmail_quote"=
><div>if you refer to class execution_context from boost.context - it allow=
s to pass data through a context switch.<br></div></div></div></div></block=
quote></span><div><br>to be clear, I meant the execution_context as describ=
ed in P0099R0. I just reread it and as far as I can tell doesn't have a=
native facility for parameter passing. I believe this is an important func=
tionality, and the switching primitive should at least allow passing a void=
* through.<br></div></blockquote><div><br></div><div>yes, P0099R0 does not =
reflect this change - working on boost.fiber I encountered the need for pas=
sing parameters through the context switch.<br></div><div>I added this func=
tionality to boost.context - at the moment only of type void pointer.<br></=
div><div>=C2=A0</div><blockquote class=3D"gmail_quote" style=3D"margin:0 0 =
0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div>=C2=A0</div><span =
class=3D""><blockquote class=3D"gmail_quote" style=3D"margin:0;margin-left:=
0.8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><div><d=
iv class=3D"gmail_quote"><div></div><div>execution_context::current() is a =
thread-local, local static pointer to a execution_context.<br></div><div>P0=
099R1 will probably reflect this.<br></div></div></div></div></blockquote><=
/span><div><br>I still do not see what's the use case for current(). In=
a way it is a wrong concept: an execution_context captures the state of an=
*halted* thread of execution, so there is no valid execution_context state=
for the currently running thread of execution.<br></div></blockquote><br><=
/div><div class=3D"gmail_quote">for me, an execution context consits out of=
a stack and a set of CPU registers (stack pointer, instruction pointer, so=
me other registers defined by the ABI).<br></div><div class=3D"gmail_quote"=
>if you start/enter main() or start/enter a thread (thread-fn) you already =
have an execution context. You need a way to access this context.<br></div>=
<div class=3D"gmail_quote">Especially in teh case of userland-threads/fiber=
s the main execution-context can be handled as a fiber too. that's the =
case for boost.fiber were the main context (running main())<br></div><div c=
lass=3D"gmail_quote">is handled as the other threads (no difference). That =
means I need a way to assign and access the main context. Without execution=
_context:current()<br></div><div class=3D"gmail_quote">I would need to hold=
and pass the current context to each place where it is need.<br></div><div=
class=3D"gmail_quote">For instance you can run a fiber (from boost.fiber) =
and executing coroutines from boost.coroutine2. both access the same curren=
t execution_context.<br></div><div class=3D"gmail_quote">Another example, b=
oost.fiber allows directly call boost::this_fiber::yiled() in main() withou=
t to invoke any initialization functionality directly.<br></div><div class=
=3D"gmail_quote"><div>=C2=A0</div><blockquote class=3D"gmail_quote" style=
=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div>=C2=
=A0</div><span class=3D""><blockquote class=3D"gmail_quote" style=3D"margin=
:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir=
=3D"ltr"><div><div class=3D"gmail_quote"><div>=C2=A0sure that the simple co=
ntext switch will take < 10 CPU cycles - but you need some maintenance c=
ode to</div></div><br></div></div></blockquote></span><div><br>what mainten=
ance code exactly? I've just looked at boost.context implementation and=
the operator() seems pretty minimal.<br></div></blockquote><div><br></div>=
<div>the context switch using jump_fcontext() takes < 10 CPU cycles, whi=
le execution_context::operator() need more cycles because it has to update =
TLS.<br></div><div>=C2=A0</div><blockquote class=3D"gmail_quote" style=3D"m=
argin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div>My "=
;fast" context switching implementation uses GCC inline assembly and a=
large list of clobbered registers so that the switching code itself does n=
ot need to conservatively save and restore all callee saved registers; The =
code works and is fast, but it is tricky and flaky (I would not recommend i=
t for a pure library implementation, depending on the version, GCC might no=
t like the large clobber list and you tend to hit dark corners of the optim=
iser) but it shows that with compiler help context switch does not need to =
be slow.<br></div></blockquote></div><br></div><div class=3D"gmail_extra">y=
es, but boost.context was required to support a broad range of compilers an=
d unfortunately MS decided to drop inline assembler for 64Bit MS VC.<br></d=
iv></div>
<p></p>
-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />
--089e015383e818e0ed05229b123b--
.
Author: Giovanni Piero Deretta <gpderetta@gmail.com>
Date: Wed, 21 Oct 2015 04:00:34 -0700 (PDT)
Raw View
------=_Part_4898_417097995.1445425234928
Content-Type: multipart/alternative;
boundary="----=_Part_4899_1753767469.1445425234928"
------=_Part_4899_1753767469.1445425234928
Content-Type: text/plain; charset=UTF-8
On Wednesday, October 21, 2015 at 11:45:04 AM UTC+1, Oliver Kowalke wrote:
>
> 2015-10-21 11:09 GMT+02:00 Giovanni Piero Deretta <gpde...@gmail.com
> <javascript:>>:
>
>> if you refer to class execution_context from boost.context - it allows to
>>> pass data through a context switch.
>>>
>>
>> to be clear, I meant the execution_context as described in P0099R0. I
>> just reread it and as far as I can tell doesn't have a native facility for
>> parameter passing. I believe this is an important functionality, and the
>> switching primitive should at least allow passing a void* through.
>>
>
> yes, P0099R0 does not reflect this change - working on boost.fiber I
> encountered the need for passing parameters through the context switch.
> I added this functionality to boost.context - at the moment only of type
> void pointer.
>
that's great. Do you guys plan to add this functionality to P0099R1? I
would prefer it to be typed, but I could live with void*.
>
>
>>
>>
>>> execution_context::current() is a thread-local, local static pointer to
>>> a execution_context.
>>> P0099R1 will probably reflect this.
>>>
>>
>> I still do not see what's the use case for current(). In a way it is a
>> wrong concept: an execution_context captures the state of an *halted*
>> thread of execution, so there is no valid execution_context state for the
>> currently running thread of execution.
>>
>
> for me, an execution context consits out of a stack and a set of CPU
> registers (stack pointer, instruction pointer, some other registers defined
> by the ABI).
>
well, yes, but you need to halt the currently executing thread of execution
to capture that context, right?
> if you start/enter main() or start/enter a thread (thread-fn) you already
> have an execution context. You need a way to access this context.
>
why? You need a context object only when suspending a coroutine. You might
as well create it on the fly on the stack. It is guaranteed to live for as
long as the coroutine is suspended, which is exactly as long as you need.
> Especially in teh case of userland-threads/fibers the main
> execution-context can be handled as a fiber too. that's the case for
> boost.fiber were the main context (running main())
> is handled as the other threads (no difference). That means I need a way
> to assign and access the main context. Without execution_context:current()
>
I still do not understand what you need ti for. You just need a place to
save this state, you can simply allocate an automatic object on the stack
and save into it, there is no need to use the same objects anywhere.
Another way to see it is that coroutines have no identity unless they are
suspended.
> I would need to hold and pass the current context to each place where it
> is need.
>
For instance you can run a fiber (from boost.fiber) and executing
> coroutines from boost.coroutine2. both access the same current
> execution_context.
>
I still do not see the need for them to share a global execution context,
each should run independently perfectly fine.
> Another example, boost.fiber allows directly call
> boost::this_fiber::yiled() in main() without to invoke any initialization
> functionality directly.
>
that's fine, yield would create a new context object in the stack, get the
next context pointer from the scheduler, jump to it and have the next
context in line push the pointer to the previous context on the back of the
scheduler. You do need to either have a thread_local scheduler or a way
to pass the scheduler to yield of course.
>
>
>>
>>
>>> sure that the simple context switch will take < 10 CPU cycles - but you
>>> need some maintenance code to
>>>
>>>
>> what maintenance code exactly? I've just looked at boost.context
>> implementation and the operator() seems pretty minimal.
>>
>
> the context switch using jump_fcontext() takes < 10 CPU cycles, while
> execution_context::operator() need more cycles because it has to update TLS.
>
one more reason not to have current_context :)
--
---
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_4899_1753767469.1445425234928
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<br><br>On Wednesday, October 21, 2015 at 11:45:04 AM UTC+1, Oliver Kowalke=
wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.=
8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr"><div><=
div class=3D"gmail_quote">2015-10-21 11:09 GMT+02:00 Giovanni Piero Deretta=
<span dir=3D"ltr"><<a href=3D"javascript:" target=3D"_blank" gdf-obfusc=
ated-mailto=3D"aLq_QJSyEAAJ" rel=3D"nofollow" onmousedown=3D"this.href=3D&#=
39;javascript:';return true;" onclick=3D"this.href=3D'javascript:&#=
39;;return true;">gpde...@gmail.com</a>></span>:<br><blockquote class=3D=
"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padding=
-left:1ex"><span><blockquote class=3D"gmail_quote" style=3D"margin:0;margin=
-left:0.8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><=
div><div class=3D"gmail_quote"><div>if you refer to class execution_context=
from boost.context - it allows to pass data through a context switch.<br><=
/div></div></div></div></blockquote></span><div><br>to be clear, I meant th=
e execution_context as described in P0099R0. I just reread it and as far as=
I can tell doesn't have a native facility for parameter passing. I bel=
ieve this is an important functionality, and the switching primitive should=
at least allow passing a void* through.<br></div></blockquote><div><br></d=
iv><div>yes, P0099R0 does not reflect this change - working on boost.fiber =
I encountered the need for passing parameters through the context switch.<b=
r></div><div>I added this functionality to boost.context - at the moment on=
ly of type void pointer.<br></div></div></div></div></blockquote><div><br>t=
hat's great. Do you guys plan to add this functionality to P0099R1? I w=
ould prefer it to be typed, but I could live with void*.<br>=C2=A0</div><bl=
ockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border=
-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr"><div><div class=
=3D"gmail_quote"><div></div><div>=C2=A0</div><blockquote class=3D"gmail_quo=
te" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"=
><div>=C2=A0</div><span><blockquote class=3D"gmail_quote" style=3D"margin:0=
;margin-left:0.8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir=3D=
"ltr"><div><div class=3D"gmail_quote"><div></div><div>execution_context::cu=
rrent() is a thread-local, local static pointer to a execution_context.<br>=
</div><div>P0099R1 will probably reflect this.<br></div></div></div></div><=
/blockquote></span><div><br>I still do not see what's the use case for =
current(). In a way it is a wrong concept: an execution_context captures th=
e state of an *halted* thread of execution, so there is no valid execution_=
context state for the currently running thread of execution.<br></div></blo=
ckquote><br></div><div class=3D"gmail_quote">for me, an execution context c=
onsits out of a stack and a set of CPU registers (stack pointer, instructio=
n pointer, some other registers defined by the ABI).<br></div></div></div><=
/blockquote><div><br>well, yes, but you need to halt the currently executin=
g thread of execution to capture that context, right?<br>=C2=A0<br></div><b=
lockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;borde=
r-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr"><div><div class=
=3D"gmail_quote"></div><div class=3D"gmail_quote">if you start/enter main()=
or start/enter a thread (thread-fn) you already have an execution context.=
You need a way to access this context.<br></div></div></div></blockquote><=
div><br>why? You need a context object only when suspending a coroutine. Yo=
u might as well create it on the fly on the stack. It is guaranteed to live=
for as long as the coroutine is suspended, which is exactly as long as you=
need.<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;"><div dir=
=3D"ltr"><div><div class=3D"gmail_quote"></div><div class=3D"gmail_quote">E=
specially in teh case of userland-threads/fibers the main execution-context=
can be handled as a fiber too. that's the case for boost.fiber were th=
e main context (running main())<br></div><div class=3D"gmail_quote">is hand=
led as the other threads (no difference). That means I need a way to assign=
and access the main context. Without execution_context:current()<br></div>=
</div></div></blockquote><div><br>I still do not understand what you need t=
i for. You just need a place to save this state, you can simply allocate an=
automatic object on the stack and save into it, there is no need to use th=
e same objects anywhere. Another way to see it is that coroutines have no i=
dentity unless they are suspended.<br>=C2=A0</div><blockquote class=3D"gmai=
l_quote" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;=
padding-left: 1ex;"><div dir=3D"ltr"><div><div class=3D"gmail_quote"></div>=
<div class=3D"gmail_quote">I would need to hold and pass the current contex=
t to each place where it is need.<br></div></div></div></blockquote><blockq=
uote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-lef=
t: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr"><div><div class=3D"g=
mail_quote"></div><div class=3D"gmail_quote">For instance you can run a fib=
er (from boost.fiber) and executing coroutines from boost.coroutine2. both =
access the same current execution_context.<br></div></div></div></blockquot=
e><div><br>I still do not see the need for them to share a global execution=
context, each should run independently perfectly fine.<br>=C2=A0</div><blo=
ckquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-=
left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr"><div><div class=
=3D"gmail_quote"></div><div class=3D"gmail_quote">Another example, boost.fi=
ber allows directly call boost::this_fiber::yiled() in main() without to in=
voke any initialization functionality directly.<br></div></div></div></bloc=
kquote><div><br>that's fine, yield would create a new context object in=
the stack, get the next context pointer from the scheduler, jump to it and=
have the next context in line push the pointer to the previous context on =
the back of the scheduler.=C2=A0=C2=A0 You do need to either have a thread_=
local scheduler or a way to pass the scheduler to yield of course.<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;"><div dir=3D"ltr"><div=
><div class=3D"gmail_quote"></div><div class=3D"gmail_quote"><div>=C2=A0</d=
iv><blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left=
:1px #ccc solid;padding-left:1ex"><div>=C2=A0</div><span><blockquote class=
=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc s=
olid;padding-left:1ex"><div dir=3D"ltr"><div><div class=3D"gmail_quote"><di=
v>=C2=A0sure that the simple context switch will take < 10 CPU cycles - =
but you need some maintenance code to</div></div><br></div></div></blockquo=
te></span><div><br>what maintenance code exactly? I've just looked at b=
oost.context implementation and the operator() seems pretty minimal.<br></d=
iv></blockquote><div><br></div><div>the context switch using jump_fcontext(=
) takes < 10 CPU cycles, while execution_context::operator() need more c=
ycles because it has to update TLS.<br></div></div></div></div></blockquote=
><div><br>one more reason not to have current_context :) <br></div>
<p></p>
-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />
------=_Part_4899_1753767469.1445425234928--
------=_Part_4898_417097995.1445425234928--
.
Author: Oliver Kowalke <oliver.kowalke@gmail.com>
Date: Wed, 21 Oct 2015 14:26:42 +0200
Raw View
--047d7bd6b514de9ae305229c7eda
Content-Type: text/plain; charset=UTF-8
2015-10-21 13:00 GMT+02:00 Giovanni Piero Deretta <gpderetta@gmail.com>:
>
>> yes, P0099R0 does not reflect this change - working on boost.fiber I
>> encountered the need for passing parameters through the context switch.
>> I added this functionality to boost.context - at the moment only of type
>> void pointer.
>>
>
> that's great. Do you guys plan to add this functionality to P0099R1? I
> would prefer it to be typed, but I could live with void*.
>
yes, probably in R0099R1
typed parameters would be preferable - R execution_context::operator()( Args
&& ... args)
R should be of type std::tuple< Args ... > if more than one argument was
passed.
I tried to implement it in boost.context but failed because I can't
determine the argument types of the function/functor passed to
execution_context' ctor
(e.g. the problem is that invoke() expects the exact types)
<snip>
the context switch using jump_fcontext() takes < 10 CPU cycles, while
>>> execution_context::operator() need more cycles because it has to update TLS.
>>>
>>
> one more reason not to have current_context :)
>
execution_context without static member-fn would be possible too, but this
would require to make the current object available at each place in the
source where a context switch happens.
the idea behind execution_context (and current()) is that an application
consist out of at least one thread-of-execution (==execution_context) and
the state of an execution context evolves
as the the program make progress (== at each state of the execution the set
of stack and the related registers have concrete values that evolve too).
inside an application you can have multiple, from each other distinct
execution-context'. For instance threads, fibers or coroutines.
A coroutine is distinct from a fiber in the interaction of the two
execution-context' - a (asymmetric) coroutine couples tightly two
execution-context'. The execution-context of the caller
and the execution-context of the callee (==executes the coroutine-fn). the
caller can only resume the coroutine (== switch to callee context), while
the callee can only suspend the coroutine
(== switch to caller). Data is directly transferred (both directions
possible; generators are a special coroutine -> data transfer only from
callee to caller).
the execution_context of fibers is not coupled, predecessor and successor
are unknown - a scheduler selects the next fiber to be resumed. Data is not
directly transferred.
delimited continuations can be described and implemented with
execution_context too.
does it makes sense to you?
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.
--047d7bd6b514de9ae305229c7eda
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">2015=
-10-21 13:00 GMT+02:00 Giovanni <span tabindex=3D"-1" id=3D":1l2.1" style=
=3D"" class=3D"">Piero</span> <span tabindex=3D"-1" id=3D":1l2.2" style=3D"=
" class=3D"">Deretta</span> <span dir=3D"ltr"><<a href=3D"mailto:gpderet=
ta@gmail.com" target=3D"_blank"><span tabindex=3D"-1" id=3D":1l2.3" style=
=3D"" class=3D"">gpderetta</span>@gmail.com</a>></span>:<br><blockquote =
class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid=
;padding-left:1ex"><span><blockquote class=3D"gmail_quote" style=3D"margin:=
0;margin-left:0.8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir=
=3D"ltr"><div><div class=3D"gmail_quote"><br><div>yes, P0099R0 does not ref=
lect this change - working on boost.fiber I encountered the need for passin=
g parameters through the context switch.<br></div><div>I added this functio=
nality to boost.context - at the moment only of type void pointer.<br></div=
></div></div></div></blockquote></span><div><br>that's great. Do you gu=
ys plan to add this functionality to P0099R1? I would prefer it to be typed=
, but I could live with void*.<br></div></blockquote><div><br></div><div>ye=
s, probably in R0099R1<br></div><div>typed parameters would be preferable -=
R execution_context::operator()( <span tabindex=3D"-1" id=3D":1l2.4" style=
=3D"" class=3D"">Args</span> && ... <span tabindex=3D"-1" id=3D":1l=
2.5" style=3D"" class=3D"">args</span>)<br></div><div>R should be of type s=
td::<span tabindex=3D"-1" id=3D":1l2.6" style=3D"" class=3D"">tuple</span>&=
lt; <span tabindex=3D"-1" id=3D":1l2.7" style=3D"" class=3D"">Args</span> .=
... > if more than one argument was passed.<br></div><div>I tried to impl=
ement it in boost.context but failed because I can't determine the argu=
ment types of the function/<span tabindex=3D"-1" id=3D":1l2.8" style=3D"" c=
lass=3D"">functor</span> passed to execution_context' <span tabindex=3D=
"-1" id=3D":1l2.9" style=3D"" class=3D"">ctor</span><br></div><div>(e.g. th=
e problem is that invoke() expects the exact types)<br></div><div>=C2=A0<br=
></div><div><snip> <br><br></div><blockquote class=3D"gmail_quote" st=
yle=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><span=
><blockquote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;bord=
er-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><div><div class=
=3D"gmail_quote"><blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8=
ex;border-left:1px #ccc solid;padding-left:1ex"><div class=3D"gmail_quote">=
<div>the context switch using jump_fcontext() takes < 10 CPU cycles, whi=
le execution_context::operator() need more cycles because it has to update =
TLS.<br></div></div></blockquote></div></div></div></blockquote></span><spa=
n></span><div><br>one more reason not to have current_context :)<br></div><=
/blockquote></div><br></div><div class=3D"gmail_extra">execution_context wi=
thout static member-<span tabindex=3D"-1" id=3D":1l2.10" style=3D"" class=
=3D"">fn</span> would be possible too, but this would require to make the c=
urrent object available at each place in the source where a context switch =
happens.<br></div><div class=3D"gmail_extra">the idea behind execution_cont=
ext (and current()) is that an application consist out of at least one thre=
ad-of-execution (=3D=3Dexecution_context) and the state of an execution con=
text evolves <br></div><div class=3D"gmail_extra">as the the program make p=
rogress (=3D=3D at each state of the execution the set of stack and the rel=
ated registers have concrete values that evolve too).<br></div><div class=
=3D"gmail_extra">inside an application you can have multiple, from each oth=
er distinct execution-context'. For instance threads, fibers or <span t=
abindex=3D"-1" id=3D":1l2.11" style=3D"" class=3D"">coroutines</span>.<br><=
/div><div class=3D"gmail_extra">A <span tabindex=3D"-1" id=3D":1l2.12" styl=
e=3D"" class=3D"">coroutine</span> is distinct from a fiber in the interact=
ion of the two execution-context' - a (asymmetric) <span tabindex=3D"-1=
" id=3D":1l2.13" style=3D"" class=3D"">coroutine</span> couples tightly two=
execution-context'. The execution-context of the caller<br></div><div =
class=3D"gmail_extra">and the execution-context of the <span tabindex=3D"-1=
" id=3D":1l2.14" style=3D"" class=3D"">callee</span> (=3D=3Dexecutes the <s=
pan tabindex=3D"-1" id=3D":1l2.15" style=3D"" class=3D"">coroutine</span>-<=
span tabindex=3D"-1" id=3D":1l2.16" style=3D"" class=3D"">fn</span>). the c=
aller can only resume the <span tabindex=3D"-1" id=3D":1l2.17" style=3D"" c=
lass=3D"">coroutine</span> (=3D=3D switch to <span tabindex=3D"-1" id=3D":1=
l2.18" style=3D"" class=3D"">callee</span> context), while the <span tabind=
ex=3D"-1" id=3D":1l2.19" style=3D"" class=3D"">callee</span> can only suspe=
nd the <span tabindex=3D"-1" id=3D":1l2.20" style=3D"" class=3D"">coroutine=
</span><br></div><div class=3D"gmail_extra">(=3D=3D switch to caller). Data=
is directly transferred (both directions possible; generators are a specia=
l <span tabindex=3D"-1" id=3D":1l2.21" style=3D"" class=3D"">coroutine</spa=
n> -> data transfer only from <span tabindex=3D"-1" id=3D":1l2.22" style=
=3D"" class=3D"">callee</span> to caller).<br></div><div class=3D"gmail_ext=
ra">the execution_context of fibers is not coupled, predecessor and success=
or are unknown - a scheduler selects the next fiber to be resumed. Data is =
not directly transferred.<br></div><div class=3D"gmail_extra">delimited con=
tinuations can be described and implemented with execution_context too.<br>=
</div><div class=3D"gmail_extra">does it makes sense to you?<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 />
--047d7bd6b514de9ae305229c7eda--
.
Author: Giovanni Piero Deretta <gpderetta@gmail.com>
Date: Wed, 21 Oct 2015 06:43:42 -0700 (PDT)
Raw View
------=_Part_2002_1038893772.1445435022562
Content-Type: multipart/alternative;
boundary="----=_Part_2003_1688347711.1445435022563"
------=_Part_2003_1688347711.1445435022563
Content-Type: text/plain; charset=UTF-8
On Wednesday, October 21, 2015 at 1:27:04 PM UTC+1, Oliver Kowalke wrote:
>
> 2015-10-21 13:00 GMT+02:00 Giovanni Piero Deretta <gpderetta@gmail.com
> <javascript:>>:
>
> one more reason not to have current_context :)
>>
>
> execution_context without static member-fn would be possible too, but
> this would require to make the current object available at each place in
> the source where a context switch happens.
>
Sorry for being dense, this I do not understand. I do not see how one
follows from the other and it doesn't match my experience.
> the idea behind execution_context (and current()) is that an application
> consist out of at least one thread-of-execution (==execution_context) and
> the state of an execution context evolves
> as the the program make progress (== at each state of the execution the
> set of stack and the related registers have concrete values that evolve
> too).
> inside an application you can have multiple, from each other distinct
> execution-context'. For instance threads, fibers or coroutines.
> A coroutine is distinct from a fiber in the interaction of the two
> execution-context' - a (asymmetric) coroutine couples tightly two
> execution-context'. The execution-context of the caller
> and the execution-context of the callee (==executes the coroutine-fn).
> the caller can only resume the coroutine (== switch to callee context),
> while the callee can only suspend the coroutine
> (== switch to caller). Data is directly transferred (both directions
> possible; generators are a special coroutine -> data transfer only from
> callee to caller).
> the execution_context of fibers is not coupled, predecessor and successor
> are unknown - a scheduler selects the next fiber to be resumed. Data is not
> directly transferred.
> delimited continuations can be described and implemented with
> execution_context too.
> does it makes sense to you?
>
yes, I still do not see the need for the global variable. To make things
more concrete, see my scheduler yield implementation here:
https://github.com/gpderetta/libtask/blob/master/task.cpp#L149
It puts the current continuation (yet another name in the
fiber/coroutine/context saga) on the back of a task queue and switches to
the next. There is no notion of current context. For convenience there is a
thread local scheduler, but it is not part of the continuation abstraction.
callcc is the task switching primitive: it suspend the current thread of
execution and resumes the target one. On the just awakened thread of
execution it returns the just suspened continuation. Optionally it takes a
function object that is run in the target thread of exectuion This function
object takes as a parameter a continuation representing the execution
object that was just suspended. By default this is the identity function.
-- gpd
--
---
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_2003_1688347711.1445435022563
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
On Wednesday, October 21, 2015 at 1:27:04 PM UTC+1, Oliver Kowalke wrote:<b=
lockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;borde=
r-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr"><div><div class=
=3D"gmail_quote">2015-10-21 13:00 GMT+02:00 Giovanni <span>Piero</span> <sp=
an>Deretta</span> <span dir=3D"ltr"><<a href=3D"javascript:" target=3D"_=
blank" gdf-obfuscated-mailto=3D"B329KiW4EAAJ" rel=3D"nofollow" onmousedown=
=3D"this.href=3D'javascript:';return true;" onclick=3D"this.href=3D=
'javascript:';return true;"><span>gpderetta</span>@gmail.com</a>>=
;</span>:<br><br><blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8=
ex;border-left:1px #ccc solid;padding-left:1ex"><div>one more reason not to=
have current_context :)<br></div></blockquote></div><br></div><div>executi=
on_context without static member-<span>fn</span> would be possible too, but=
this would require to make the current object available at each place in t=
he source where a context switch happens.<br></div></div></blockquote><div>=
<br>Sorry for being dense, this I do not understand. I do not see how one f=
ollows from the other and it doesn't match my experience.<br>=C2=A0</di=
v><blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;b=
order-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr"><div></div>=
<div>the idea behind execution_context (and current()) is that an applicati=
on consist out of at least one thread-of-execution (=3D=3Dexecution_context=
) and the state of an execution context evolves <br></div><div>as the the p=
rogram make progress (=3D=3D at each state of the execution the set of stac=
k and the related registers have concrete values that evolve too).<br></div=
><div>inside an application you can have multiple, from each other distinct=
execution-context'. For instance threads, fibers or <span>coroutines</=
span>.<br></div><div>A <span>coroutine</span> is distinct from a fiber in t=
he interaction of the two execution-context' - a (asymmetric) <span>cor=
outine</span> couples tightly two execution-context'. The execution-con=
text of the caller<br></div><div>and the execution-context of the <span>cal=
lee</span> (=3D=3Dexecutes the <span>coroutine</span>-<span>fn</span>). the=
caller can only resume the <span>coroutine</span> (=3D=3D switch to <span>=
callee</span> context), while the <span>callee</span> can only suspend the =
<span>coroutine</span><br></div><div>(=3D=3D switch to caller). Data is dir=
ectly transferred (both directions possible; generators are a special <span=
>coroutine</span> -> data transfer only from <span>callee</span> to call=
er).<br></div><div>the execution_context of fibers is not coupled, predeces=
sor and successor are unknown - a scheduler selects the next fiber to be re=
sumed. Data is not directly transferred.<br></div><div>delimited continuati=
ons can be described and implemented with execution_context too.<br></div><=
div>does it makes sense to you?<br></div></div></blockquote><div><br>yes, I=
still do not see the need for the global variable. To make things more con=
crete, see my scheduler yield implementation here: <br><br>=C2=A0 https://g=
ithub.com/gpderetta/libtask/blob/master/task.cpp#L149<br><br>It puts the cu=
rrent continuation (yet another name in the fiber/coroutine/context saga) o=
n the back of a task queue and switches to the next. There is no notion of =
current context. For convenience there is a thread local scheduler, but it =
is not part of the continuation abstraction.<br><br>callcc is the task swit=
ching primitive: it suspend the current thread of execution and resumes the=
target one. On the just awakened thread of execution it returns the just s=
uspened continuation. Optionally it takes a function object that is run in =
the target thread of exectuion This function object takes as a parameter a =
continuation representing the execution object that was just suspended. By =
default this is the identity function.<br>=C2=A0<br>-- gpd<br><br></div>
<p></p>
-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />
------=_Part_2003_1688347711.1445435022563--
------=_Part_2002_1038893772.1445435022562--
.
Author: Oliver Kowalke <oliver.kowalke@gmail.com>
Date: Wed, 21 Oct 2015 18:45:01 +0200
Raw View
--001a11c30b94aa5a610522a01ad6
Content-Type: text/plain; charset=UTF-8
2015-10-21 15:43 GMT+02:00 Giovanni Piero Deretta <gpderetta@gmail.com>:
>
> Sorry for being dense, this I do not understand. I do not see how one
> follows from the other and it doesn't match my experience.
>
for a context switch you need the current context, which is required to be
preserved, and a target context, which has to be resumed
I thought it is convenient only to know the target context and simply call
execution-context::operator() to switch to the target-context.
it is a small API - one function to resume the context, one function to
access the current context
> callcc is the task switching primitive: it suspend the current thread of
> execution and resumes the target one. On the just awakened thread of
> execution it returns the just suspened continuation.
>
it is not so much different than execution_context of course I could pass
the current context through the context switch
(execution_context::operator()) to the target context.
with your callcc the target context always knows its calling context
(parent context, what would be the right wording?).
but in some cases the target context does not need to know from which
context it was resumed.
maybe callcc and execution_context are equivalent
--
---
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/.
--001a11c30b94aa5a610522a01ad6
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">2015=
-10-21 15:43 GMT+02:00 Giovanni Piero Deretta <span dir=3D"ltr"><<a href=
=3D"mailto:gpderetta@gmail.com" target=3D"_blank">gpderetta@gmail.com</a>&g=
t;</span>:<br><blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;=
border-left:1px #ccc solid;padding-left:1ex"><span class=3D""></span><br><d=
iv>Sorry for being dense, this I do not understand. I do not see how one fo=
llows from the other and it doesn't match my experience.<br></div></blo=
ckquote><div><br></div><div>for a context switch you need the current conte=
xt, which is required to be preserved, and a target context, which has to b=
e resumed<br></div><div>I thought it is convenient only to know the target =
context and simply call execution-context::operator() to switch to the targ=
et-context.<br><br></div><div>it is a small API - one function to resume th=
e context, one function to access the current context<br></div><div>=C2=A0<=
/div><blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-le=
ft:1px #ccc solid;padding-left:1ex"><div>=C2=A0callcc is the task switching=
primitive: it suspend the current thread of execution and resumes the targ=
et one. On the just awakened thread of execution it returns the just suspen=
ed continuation.<br></div></blockquote><div>=C2=A0</div></div>it is not so =
much different than execution_context of course I could pass the current co=
ntext through the context switch (execution_context::operator()) to the tar=
get context.<br></div><div class=3D"gmail_extra">with your callcc the targe=
t context always knows its calling context (parent context, what would be t=
he right wording?).<br></div><div class=3D"gmail_extra">but in some cases t=
he target context does not need to know from which context it was resumed.<=
br></div><div class=3D"gmail_extra">maybe callcc and execution_context are =
equivalent<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 />
--001a11c30b94aa5a610522a01ad6--
.
Author: Giovanni Piero Deretta <gpderetta@gmail.com>
Date: Wed, 21 Oct 2015 10:15:57 -0700 (PDT)
Raw View
------=_Part_4609_210998052.1445447757761
Content-Type: multipart/alternative;
boundary="----=_Part_4610_1038812166.1445447757761"
------=_Part_4610_1038812166.1445447757761
Content-Type: text/plain; charset=UTF-8
On Wednesday, October 21, 2015 at 5:45:22 PM UTC+1, Oliver Kowalke wrote:
>
> 2015-10-21 15:43 GMT+02:00 Giovanni Piero Deretta <gpde...@gmail.com
> <javascript:>>:
>
>>
>> Sorry for being dense, this I do not understand. I do not see how one
>> follows from the other and it doesn't match my experience.
>>
>
> for a context switch you need the current context, which is required to be
> preserved, and a target context, which has to be resumed
> I thought it is convenient only to know the target context and simply call
> execution-context::operator() to switch to the target-context.
>
it is very convenient, but it doesn't need to save the current context
>
> it is a small API - one function to resume the context, one function to
> access the current context
>
>
>> callcc is the task switching primitive: it suspend the current thread of
>> execution and resumes the target one. On the just awakened thread of
>> execution it returns the just suspened continuation.
>>
>
> it is not so much different than execution_context of course I could pass
> the current context through the context switch
> (execution_context::operator()) to the target context.
> with your callcc the target context always knows its calling context
> (parent context, what would be the right wording?).
> but in some cases the target context does not need to know from which
> context it was resumed.
> maybe callcc and execution_context are equivalent
>
With parameter passing they are have equivalent expressibility. It is
trivial to implement callcc on top of, for example fcontext + parameter
passing:
Assuming this exists:
void* fcontext_swap (void* p, ctxt*src, ctx*dest);
callcc is equivalent to this:
ctx * callcc(ctx* dst, auto f = [](auto x) {} return x; })
{
struct data { ctx src; function<ctx*(ctx*)> f } data = { {},
std::ref(f) };
auto * otherdata = (data*)fcontext_swap(&data, &data.src, &dst));
return otherdata->f(&otherdata->src));
}
Although it is not a terribly efficient implementation. Note that the state
of the context that we are swapping from is saved in a variable local to
callcc, no need for a global. If the target context doesn't care about the
src context, the src context can capture and store its own continuation by
providing 'f' on swap. Again, no need for a global.
--
---
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_4610_1038812166.1445447757761
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
On Wednesday, October 21, 2015 at 5:45:22 PM UTC+1, Oliver Kowalke wrote:<b=
lockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;borde=
r-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr"><div><div class=
=3D"gmail_quote">2015-10-21 15:43 GMT+02:00 Giovanni Piero Deretta <span di=
r=3D"ltr"><<a href=3D"javascript:" target=3D"_blank" gdf-obfuscated-mail=
to=3D"LVAAmT3GEAAJ" rel=3D"nofollow" onmousedown=3D"this.href=3D'javasc=
ript:';return true;" onclick=3D"this.href=3D'javascript:';retur=
n true;">gpde...@gmail.com</a>></span>:<br><blockquote class=3D"gmail_qu=
ote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex=
"><span></span><br><div>Sorry for being dense, this I do not understand. I =
do not see how one follows from the other and it doesn't match my exper=
ience.<br></div></blockquote><div><br></div><div>for a context switch you n=
eed the current context, which is required to be preserved, and a target co=
ntext, which has to be resumed<br></div><div>I thought it is convenient onl=
y to know the target context and simply call execution-context::operator() =
to switch to the target-context.<br></div></div></div></div></blockquote><d=
iv><br>it is very convenient, but it doesn't need to save the current c=
ontext <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;"><div di=
r=3D"ltr"><div><div class=3D"gmail_quote"><div><br></div><div>it is a small=
API - one function to resume the context, one function to access the curre=
nt context<br></div><div>=C2=A0</div><blockquote class=3D"gmail_quote" styl=
e=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div>=
=C2=A0callcc is the task switching primitive: it suspend the current thread=
of execution and resumes the target one. On the just awakened thread of ex=
ecution it returns the just suspened continuation.<br></div></blockquote><d=
iv>=C2=A0</div></div>it is not so much different than execution_context of =
course I could pass the current context through the context switch (executi=
on_context::operator()<wbr>) to the target context.<br></div><div>with your=
callcc the target context always knows its calling context (parent context=
, what would be the right wording?).<br></div><div>but in some cases the ta=
rget context does not need to know from which context it was resumed.<br></=
div><div>maybe callcc and execution_context are equivalent<br></div></div><=
/blockquote><div><br>With parameter passing they are have equivalent expres=
sibility. It is trivial to implement callcc on top of, for example fcontext=
+ parameter passing:<br><br>Assuming this exists:<br>void* fcontext_swap (=
void* p, ctxt*src, ctx*dest);<br><br>callcc is equivalent to this:<br><br>c=
tx * callcc(ctx* dst, auto f =3D [](auto x) {} return x; })<br>{<br>=C2=A0=
=C2=A0=C2=A0=C2=A0 struct data { ctx src; function<ctx*(ctx*)> f } da=
ta =3D { {}, std::ref(f) };<br>=C2=A0=C2=A0=C2=A0=C2=A0 auto * otherdata =
=3D (data*)fcontext_swap(&data, &data.src, &dst));<br>=C2=A0=C2=
=A0 =C2=A0 return otherdata->f(&otherdata->src));<br>}<br>=C2=A0=
=C2=A0=C2=A0=C2=A0 <br>Although it is not a terribly efficient implementati=
on. Note that the state of the context that we are swapping from is saved i=
n a variable local to callcc, no need for a global. If the target context d=
oesn't care about the src context, the src context can capture and stor=
e its own continuation by providing 'f' on swap. Again, no need for=
a global.<br><br><br></div>
<p></p>
-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />
------=_Part_4610_1038812166.1445447757761--
------=_Part_4609_210998052.1445447757761--
.
Author: Oliver Kowalke <oliver.kowalke@gmail.com>
Date: Wed, 21 Oct 2015 19:35:48 +0200
Raw View
--047d7b33c6a642e3b00522a0d078
Content-Type: text/plain; charset=UTF-8
2015-10-21 19:15 GMT+02:00 Giovanni Piero Deretta <gpderetta@gmail.com>:
> On Wednesday, October 21, 2015 at 5:45:22 PM UTC+1, Oliver Kowalke wrote:
>>
>> 2015-10-21 15:43 GMT+02:00 Giovanni Piero Deretta <gpde...@gmail.com>:
>>
>>>
>>> Sorry for being dense, this I do not understand. I do not see how one
>>> follows from the other and it doesn't match my experience.
>>>
>>
>> for a context switch you need the current context, which is required to
>> be preserved, and a target context, which has to be resumed
>> I thought it is convenient only to know the target context and simply
>> call execution-context::operator() to switch to the target-context.
>>
>
> it is very convenient, but it doesn't need to save the current context
>
boost.context contains examples demonstrating why I introduced
execution_context::current()
main() -- jump to --> ctx1 -- jump to --> main()
void foo( execution_context * mctx) {
( * mctx)();
}
int main () {
execution_context mctx = execution_context::current();
execution_context ctx1 = execution_context( foo);
ctx1( & mctx);
execution_context ctx2 = execution_context( bar);
ctx2( & mctx);
return 0;
}
the body of main might occur at any function/at arbitrary call chain
>
>>
>> it is a small API - one function to resume the context, one function to
>> access the current context
>>
>>
>>> callcc is the task switching primitive: it suspend the current thread
>>> of execution and resumes the target one. On the just awakened thread of
>>> execution it returns the just suspened continuation.
>>>
>>
>> it is not so much different than execution_context of course I could pass
>> the current context through the context switch
>> (execution_context::operator()) to the target context.
>> with your callcc the target context always knows its calling context
>> (parent context, what would be the right wording?).
>> but in some cases the target context does not need to know from which
>> context it was resumed.
>> maybe callcc and execution_context are equivalent
>>
>
> With parameter passing they are have equivalent expressibility. It is
> trivial to implement callcc on top of, for example fcontext + parameter
> passing:
>
> Assuming this exists:
> void* fcontext_swap (void* p, ctxt*src, ctx*dest);
>
> callcc is equivalent to this:
>
> ctx * callcc(ctx* dst, auto f = [](auto x) {} return x; })
> {
> struct data { ctx src; function<ctx*(ctx*)> f } data = { {},
> std::ref(f) };
> auto * otherdata = (data*)fcontext_swap(&data, &data.src, &dst));
> return otherdata->f(&otherdata->src));
> }
>
> Although it is not a terribly efficient implementation. Note that the
> state of the context that we are swapping from is saved in a variable local
> to callcc, no need for a global. If the target context doesn't care about
> the src context, the src context can capture and store its own continuation
> by providing 'f' on swap. Again, no need for a global.
>
do you have an suggestion how the API should changed
--
---
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/.
--047d7b33c6a642e3b00522a0d078
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">2015=
-10-21 19:15 GMT+02:00 Giovanni Piero Deretta <span dir=3D"ltr"><<a href=
=3D"mailto:gpderetta@gmail.com" target=3D"_blank">gpderetta@gmail.com</a>&g=
t;</span>:<br><blockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px=
0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">On Wednesda=
y, October 21, 2015 at 5:45:22 PM UTC+1, Oliver Kowalke wrote:<span class=
=3D""><blockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;b=
order-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir=3D"ltr"><d=
iv><div class=3D"gmail_quote">2015-10-21 15:43 GMT+02:00 Giovanni Piero Der=
etta <span dir=3D"ltr"><<a rel=3D"nofollow">gpde...@gmail.com</a>></s=
pan>:<br><blockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8e=
x;border-left:1px solid rgb(204,204,204);padding-left:1ex"><span></span><br=
><div>Sorry for being dense, this I do not understand. I do not see how one=
follows from the other and it doesn't match my experience.<br></div></=
blockquote><div><br></div><div>for a context switch you need the current co=
ntext, which is required to be preserved, and a target context, which has t=
o be resumed<br></div><div>I thought it is convenient only to know the targ=
et context and simply call execution-context::operator() to switch to the t=
arget-context.<br></div></div></div></div></blockquote></span><div><br>it i=
s very convenient, but it doesn't need to save the current context <br>=
</div></blockquote><div><br></div><div>boost.context contains examples demo=
nstrating why I introduced execution_context::current()<br><br></div><div>m=
ain() -- jump to --> ctx1 -- jump to --> main()<br></div><div>=C2=A0<=
br></div><div>void foo( execution_context * mctx) {<br></div><div>=C2=A0 ( =
* mctx)();<br></div><div>}<br></div><div><br></div><div>int main () {<br></=
div><div>=C2=A0 execution_context mctx =3D execution_context::current();<br=
>=C2=A0 execution_context ctx1 =3D execution_context( foo);<br></div><div>=
=C2=A0 ctx1( & mctx);<br>=C2=A0 execution_context ctx2 =3D execution_co=
ntext( bar);<br>=C2=A0 ctx2( & mctx);</div><div>=C2=A0 return 0;<br>}<b=
r><br></div><div>the body of main might occur at any function/at arbitrary =
call chain <br></div><div><br></div><blockquote class=3D"gmail_quote" style=
=3D"margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding=
-left:1ex"><div>=C2=A0</div><span class=3D""><blockquote class=3D"gmail_quo=
te" style=3D"margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204=
);padding-left:1ex"><div dir=3D"ltr"><div><div class=3D"gmail_quote"><div><=
br></div><div>it is a small API - one function to resume the context, one f=
unction to access the current context<br></div><div>=C2=A0</div><blockquote=
class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;border-left:1px so=
lid rgb(204,204,204);padding-left:1ex"><div>=C2=A0callcc is the task switch=
ing primitive: it suspend the current thread of execution and resumes the t=
arget one. On the just awakened thread of execution it returns the just sus=
pened continuation.<br></div></blockquote><div>=C2=A0</div></div>it is not =
so much different than execution_context of course I could pass the current=
context through the context switch (execution_context::operator()) to the =
target context.<br></div><div>with your callcc the target context always kn=
ows its calling context (parent context, what would be the right wording?).=
<br></div><div>but in some cases the target context does not need to know f=
rom which context it was resumed.<br></div><div>maybe callcc and execution_=
context are equivalent<br></div></div></blockquote></span><div><br>With par=
ameter passing they are have equivalent expressibility. It is trivial to im=
plement callcc on top of, for example fcontext + parameter passing:<br><br>=
Assuming this exists:<br>void* fcontext_swap (void* p, ctxt*src, ctx*dest);=
<br><br>callcc is equivalent to this:<br><br>ctx * callcc(ctx* dst, auto f =
=3D [](auto x) {} return x; })<br>{<br>=C2=A0=C2=A0=C2=A0=C2=A0 struct data=
{ ctx src; function<ctx*(ctx*)> f } data =3D { {}, std::ref(f) };<br=
>=C2=A0=C2=A0=C2=A0=C2=A0 auto * otherdata =3D (data*)fcontext_swap(&da=
ta, &data.src, &dst));<br>=C2=A0=C2=A0 =C2=A0 return otherdata->=
f(&otherdata->src));<br>}<br>=C2=A0=C2=A0=C2=A0=C2=A0 <br>Although i=
t is not a terribly efficient implementation. Note that the state of the co=
ntext that we are swapping from is saved in a variable local to callcc, no =
need for a global. If the target context doesn't care about the src con=
text, the src context can capture and store its own continuation by providi=
ng 'f' on swap. Again, no need for a global.<br></div></blockquote>=
</div><br></div><div class=3D"gmail_extra">do you have an suggestion how th=
e API should changed<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 />
--047d7b33c6a642e3b00522a0d078--
.
Author: Giovanni Piero Deretta <gpderetta@gmail.com>
Date: Wed, 21 Oct 2015 20:16:26 +0100
Raw View
--001a114009ca0ef0940522a237db
Content-Type: text/plain; charset=UTF-8
On 21 Oct 2015 6:36 p.m., "Oliver Kowalke" <oliver.kowalke@gmail.com> wrote:
>
> 2015-10-21 19:15 GMT+02:00 Giovanni Piero Deretta <gpderetta@gmail.com>:
>>
>> On Wednesday, October 21, 2015 at 5:45:22 PM UTC+1, Oliver Kowalke wrote:
>>>
>>> 2015-10-21 15:43 GMT+02:00 Giovanni Piero Deretta <gpde...@gmail.com>:
>>>>
>>>>
>>>> Sorry for being dense, this I do not understand. I do not see how one
follows from the other and it doesn't match my experience.
>>>
>>>
>>> for a context switch you need the current context, which is required to
be preserved, and a target context, which has to be resumed
>>> I thought it is convenient only to know the target context and simply
call execution-context::operator() to switch to the target-context.
>>
>>
>> it is very convenient, but it doesn't need to save the current context
>
>
> boost.context contains examples demonstrating why I introduced
execution_context::current()
>
> main() -- jump to --> ctx1 -- jump to --> main()
>
> void foo( execution_context * mctx) {
> ( * mctx)();
> }
>
> int main () {
> execution_context mctx = execution_context::current();
> execution_context ctx1 = execution_context( foo);
> ctx1( & mctx);
> execution_context ctx2 = execution_context( bar);
> ctx2( & mctx);
> return 0;
> }
>
> the body of main might occur at any function/at arbitrary call chain
>
Can you elaborate on this? I think that the example might be missing some
pieces. What is bar for example?
>>
>>>
>>>
>>> it is a small API - one function to resume the context, one function to
access the current context
>>>
>>>>
>>>> callcc is the task switching primitive: it suspend the current thread
of execution and resumes the target one. On the just awakened thread of
execution it returns the just suspened continuation.
>>>
>>>
>>> it is not so much different than execution_context of course I could
pass the current context through the context switch
(execution_context::operator()) to the target context.
>>> with your callcc the target context always knows its calling context
(parent context, what would be the right wording?).
>>> but in some cases the target context does not need to know from which
context it was resumed.
>>> maybe callcc and execution_context are equivalent
>>
>>
>> With parameter passing they are have equivalent expressibility. It is
trivial to implement callcc on top of, for example fcontext + parameter
passing:
>>
>> Assuming this exists:
>> void* fcontext_swap (void* p, ctxt*src, ctx*dest);
>>
>> callcc is equivalent to this:
>>
>> ctx * callcc(ctx* dst, auto f = [](auto x) {} return x; })
>> {
>> struct data { ctx src; function<ctx*(ctx*)> f } data = { {},
std::ref(f) };
>> auto * otherdata = (data*)fcontext_swap(&data, &data.src, &dst));
>> return otherdata->f(&otherdata->src));
>> }
>>
>> Although it is not a terribly efficient implementation. Note that the
state of the context that we are swapping from is saved in a variable local
to callcc, no need for a global. If the target context doesn't care about
the src context, the src context can capture and store its own continuation
by providing 'f' on swap. Again, no need for a global.
>
>
> do you have an suggestion how the API should changed
>
> --
>
> ---
> You received this message because you are subscribed to a topic in the
Google Groups "ISO C++ Standard - Future Proposals" group.
> To unsubscribe from this topic, visit
https://groups.google.com/a/isocpp.org/d/topic/std-proposals/L5ZsY1SYnrA/unsubscribe
..
> To unsubscribe from this group and all its topics, 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/.
--
---
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/.
--001a114009ca0ef0940522a237db
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<p dir=3D"ltr"><br>
On 21 Oct 2015 6:36 p.m., "Oliver Kowalke" <<a href=3D"mailto:=
oliver.kowalke@gmail.com">oliver.kowalke@gmail.com</a>> wrote:<br>
><br>
> 2015-10-21 19:15 GMT+02:00 Giovanni Piero Deretta <<a href=3D"mailt=
o:gpderetta@gmail.com">gpderetta@gmail.com</a>>:<br>
>><br>
>> On Wednesday, October 21, 2015 at 5:45:22 PM UTC+1, Oliver Kowalke=
wrote:<br>
>>><br>
>>> 2015-10-21 15:43 GMT+02:00 Giovanni Piero Deretta <<a href=
=3D"mailto:gpde...@gmail.com">gpde...@gmail.com</a>>:<br>
>>>><br>
>>>><br>
>>>> Sorry for being dense, this I do not understand. I do not =
see how one follows from the other and it doesn't match my experience.<=
br>
>>><br>
>>><br>
>>> for a context switch you need the current context, which is re=
quired to be preserved, and a target context, which has to be resumed<br>
>>> I thought it is convenient only to know the target context and=
simply call execution-context::operator() to switch to the target-context.=
<br>
>><br>
>><br>
>> it is very convenient, but it doesn't need to save the current=
context <br>
><br>
><br>
> boost.context contains examples demonstrating why I introduced executi=
on_context::current()<br>
><br>
> main() -- jump to --> ctx1 -- jump to --> main()<br>
> =C2=A0<br>
> void foo( execution_context * mctx) {<br>
> =C2=A0 ( * mctx)();<br>
> }<br>
><br>
> int main () {<br>
> =C2=A0 execution_context mctx =3D execution_context::current();<br>
> =C2=A0 execution_context ctx1 =3D execution_context( foo);<br>
> =C2=A0 ctx1( & mctx);<br>
> =C2=A0 execution_context ctx2 =3D execution_context( bar);<br>
> =C2=A0 ctx2( & mctx);<br>
> =C2=A0 return 0;<br>
> }<br>
><br>
> the body of main might occur at any function/at arbitrary call chain <=
br>
></p>
<p dir=3D"ltr">Can you elaborate on this? I think that the example might be=
missing some pieces. What is bar for example?<br>
>> =C2=A0<br>
>>><br>
>>><br>
>>> it is a small API - one function to resume the context, one fu=
nction to access the current context<br>
>>> =C2=A0<br>
>>>><br>
>>>> =C2=A0callcc is the task switching primitive: it suspend t=
he current thread of execution and resumes the target one. On the just awak=
ened thread of execution it returns the just suspened continuation.<br>
>>><br>
>>> =C2=A0<br>
>>> it is not so much different than execution_context of course I=
could pass the current context through the context switch (execution_conte=
xt::operator()) to the target context.<br>
>>> with your callcc the target context always knows its calling c=
ontext (parent context, what would be the right wording?).<br>
>>> but in some cases the target context does not need to know fro=
m which context it was resumed.<br>
>>> maybe callcc and execution_context are equivalent<br>
>><br>
>><br>
>> With parameter passing they are have equivalent expressibility. It=
is trivial to implement callcc on top of, for example fcontext + parameter=
passing:<br>
>><br>
>> Assuming this exists:<br>
>> void* fcontext_swap (void* p, ctxt*src, ctx*dest);<br>
>><br>
>> callcc is equivalent to this:<br>
>><br>
>> ctx * callcc(ctx* dst, auto f =3D [](auto x) {} return x; })<br>
>> {<br>
>> =C2=A0=C2=A0=C2=A0=C2=A0 struct data { ctx src; function<ctx*(c=
tx*)> f } data =3D { {}, std::ref(f) };<br>
>> =C2=A0=C2=A0=C2=A0=C2=A0 auto * otherdata =3D (data*)fcontext_swap=
(&data, &data.src, &dst));<br>
>> =C2=A0=C2=A0 =C2=A0 return otherdata->f(&otherdata->src)=
);<br>
>> }<br>
>> =C2=A0=C2=A0=C2=A0=C2=A0 <br>
>> Although it is not a terribly efficient implementation. Note that =
the state of the context that we are swapping from is saved in a variable l=
ocal to callcc, no need for a global. If the target context doesn't car=
e about the src context, the src context can capture and store its own cont=
inuation by providing 'f' on swap. Again, no need for a global.<br>
><br>
><br>
> do you have an suggestion how the API should changed<br>
><br>
> -- <br>
><br>
> --- <br>
> You received this message because you are subscribed to a topic in the=
Google Groups "ISO C++ Standard - Future Proposals" group.<br>
> To unsubscribe from this topic, visit <a href=3D"https://groups.google=
..com/a/isocpp.org/d/topic/std-proposals/L5ZsY1SYnrA/unsubscribe">https://gr=
oups.google.com/a/isocpp.org/d/topic/std-proposals/L5ZsY1SYnrA/unsubscribe<=
/a>.<br>
> To unsubscribe from this group and all its topics, send an email to <a=
href=3D"mailto:std-proposals%2Bunsubscribe@isocpp.org">std-proposals+unsub=
scribe@isocpp.org</a>.<br>
> To post to this group, send email to <a href=3D"mailto:std-proposals@i=
socpp.org">std-proposals@isocpp.org</a>.<br>
> Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/g=
roup/std-proposals/">http://groups.google.com/a/isocpp.org/group/std-propos=
als/</a>.<br>
</p>
<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 />
--001a114009ca0ef0940522a237db--
.
Author: Oliver Kowalke <oliver.kowalke@gmail.com>
Date: Thu, 22 Oct 2015 14:11:36 +0200
Raw View
--001a1133151eb602310522b0664f
Content-Type: text/plain; charset=UTF-8
>
> Can you elaborate on this? I think that the example might be missing some
> pieces. What is bar for example?
>
yes, but let me re-structure the example:
void foo( execution_context * mctx) {
( * mctx)();
}
void fn1() {
....
execution_context mctx = execution_context::current();
execution_context ctx = execution_context( foo);
ctx( & mctx);
....
}
void fn2() {
....
execution_context mctx = execution_context::current();
execution_context ctx = execution_context( foo);
ctx( & mctx);
....
}
void bar() {
fn1();
fn2();
}
int main () {
bar();
return 0;
}
it doesn't matter if bar() is executed in main() or in the call-stack of a
separate execution-context - the code will work.
execution_context::current() represents the 'toplevel' context, the object
returned by the different invocations of current() will refer to the same
context object.
current() is required in order to get an context to which we can jump back.
concept of execution-context: a execution-context represents the flow of
instructions, an application might 1..N distinct execution-context'
(threads, fibers, coroutines ...)
The API of execution_context:
execution_context( Fn && fn, Args && ... args); // create an new
execution-context running fn( args ...)
void * operator()( void * vp); // resume *this while current context gets
suspended, vp is passed to resumed context
static execution_context current() // returns object pointing to current
context, used in operator() above
execution_context has the memory footprint of one pointer (control
structure; containing fcontext_t)
note there is no such thing like a default ctor
a different approach would be the concept of captured context'.
a object, instance of captured_context, is used to hold the captured state
of an execution-context.
captured_context( Fn && fn, Args && ... args); // create an new
captured-context running fn( args ...)
std::tuple< captured_context, void * > operator()( captured_context & from,
void * vp); // resume *this while 'from' gets suspended, vp is passed to
resumed context, no TLS
static captured_context current(); // no TLS used
captured_context has the memory footprint of two pointer (control structure
+ fcontext_t)
if a captured context has to be resumed we need to pass the current context
from which we switch to *this.
vp are data passed to the resumed context.
operator() returns a tuple consisting of the captured-context which has
been suspended while this context has been resumed.
we still need a way to get the current context (especially for main()) and
we don't want default ctor to represent this (expressiveness).
instead we use static member-fn current() without TLS. current() uses
internally a equivalent function to ucontext's get_context() (additional
impl in asm)
or the implementation uses capture_context::operator() together with an
dummy-fn.
current() would allow to create loops with captured_context:
captured_context ctx1 = captured_context::current();
// do something; loop
captured_context ctx2 = captured_context::current();
ctx1( ctx2);
an alternative API:
captured_context( Fn && fn, Args && ... args); // create an new
captured-context running fn( args ...)
std::tuple< captured_context, void * > operator()(void * vp); // resume
*this, vp is passed to resumed context, no TLS
operator() returns a std::tuple<> - the passed parameter vp and a
capture_context representing the (parent) context from which we jumped to
this context
with captured_context you can create loops that overwrite the stack, with
execution_context you can't
--
---
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/.
--001a1133151eb602310522b0664f
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"><blo=
ckquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;border-left=
:1px solid rgb(204,204,204);padding-left:1ex"><p dir=3D"ltr">Can you elabor=
ate on this? I think that the example might be missing some pieces. What is=
bar for example?<span><br></span></p></blockquote><div>yes, but let me re-=
structure the example:<br><br><div>void foo( execution_context * mctx) {<br=
></div><div>=C2=A0 ( * mctx)();<br></div><div>}<br><br></div><div>void fn1(=
) {<br>...<br><div>=C2=A0 execution_context mctx =3D execution_context::cur=
rent();<br>=C2=A0 execution_context ctx =3D execution_context( foo);<br></d=
iv><div>=C2=A0 ctx( & mctx);<br>...<br></div>}<br><br>void fn2() {<br>.=
...<br><div>=C2=A0 execution_context mctx =3D execution_context::current();<=
br>=C2=A0 execution_context ctx =3D execution_context( foo);<br></div><div>=
=C2=A0 ctx( & mctx);<br>...<br></div>}<br><br></div><div>void bar() {<b=
r></div><div>=C2=A0 fn1();<br></div><div>=C2=A0 fn2();<br>}<br></div><div><=
br></div><div>int main () {<br></div><div>=C2=A0=C2=A0 bar();<br></div><div=
>=C2=A0=C2=A0 return 0;<br></div>}<br><br></div><div>it doesn't matter =
if bar() is executed in main() or in the call-stack of a separate execution=
-context - the code will work.<br>execution_context::current() represents t=
he 'toplevel' context, the object returned by the different invocat=
ions of current() will refer to the same context object.<br></div><div>curr=
ent() is required in order to get an context to which we can jump back.<br>=
</div><div>concept of execution-context: a execution-context represents the=
flow of instructions, an application might 1..N distinct execution-context=
' (threads, fibers, coroutines ...)<br></div><div>The API of execution_=
context:<br></div><div><br>execution_context( Fn && fn, Args &&=
amp; ... args); // create an new execution-context running fn( args ...)<br=
></div><div>void * operator()( void * vp); // resume *this while current co=
ntext gets suspended, vp is passed to resumed context<br></div><div>static =
execution_context current() // returns object pointing to current context, =
used in operator() above<br><br></div><div>execution_context has the memory=
footprint of one pointer (control structure; containing fcontext_t)<br></d=
iv><br></div><div class=3D"gmail_quote">note there is no such thing like a =
default ctor<br></div><div class=3D"gmail_quote"><div><br><br></div><div>a =
different approach would be the concept of captured context'.<br></div>=
</div>a object, instance of captured_context, is used to hold the captured =
state of an execution-context.<br><br>captured_context( Fn && fn, A=
rgs && ... args); // create an new captured-context running fn( arg=
s ...)<br>std::tuple< captured_context, void * > operator()( captured=
_context & from, void * vp); // resume *this while 'from' gets =
suspended, vp is passed to resumed context, no TLS<br></div><div class=3D"g=
mail_extra">static captured_context current(); // no TLS used<br><br>captur=
ed_context has the memory footprint of two pointer (control structure + fco=
ntext_t)</div><div class=3D"gmail_extra"><br></div><div class=3D"gmail_extr=
a">if a captured context has to be resumed we need to pass the current cont=
ext from which we switch to *this.<br></div><div class=3D"gmail_extra">vp a=
re data passed to the resumed context.<br></div><div class=3D"gmail_extra">=
operator() returns a tuple consisting of the captured-context which has bee=
n suspended while this context has been resumed.<br><br></div><div class=3D=
"gmail_extra">we still need a way to get the current context (especially fo=
r main()) and we don't want default ctor to represent this (expressiven=
ess).<br></div><div class=3D"gmail_extra">instead we use static member-fn c=
urrent() without TLS. current() uses internally a equivalent function to uc=
ontext's get_context() (additional impl in asm) <br></div><div class=3D=
"gmail_extra">or the implementation uses capture_context::operator() togeth=
er with an dummy-fn.<br><br></div><div class=3D"gmail_extra">current() woul=
d allow to create loops with captured_context:<br><br></div><div class=3D"g=
mail_extra">captured_context ctx1 =3D captured_context::current();<br></div=
><div class=3D"gmail_extra">// do something; loop<br>captured_context ctx2 =
=3D captured_context::current();<br>ctx1( ctx2);<br><br></div><div class=3D=
"gmail_extra"><br>an alternative API:<br><br>captured_context( Fn &&=
; fn, Args && ... args); // create an new captured-context running =
fn( args ...)<br>std::tuple<
captured_context, void * > operator()(void * vp); // resume *this, vp i=
s passed to
resumed context, no TLS<br><br></div><div class=3D"gmail_extra">operator()=
returns a std::tuple<> - the passed parameter vp and a capture_conte=
xt representing the (parent) context from which we jumped to this context<b=
r><br><br></div><div class=3D"gmail_extra">with captured_context you can cr=
eate loops that overwrite the stack, with execution_context you can't<b=
r></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 />
--001a1133151eb602310522b0664f--
.
Author: Giovanni Piero Deretta <gpderetta@gmail.com>
Date: Thu, 22 Oct 2015 05:47:36 -0700 (PDT)
Raw View
------=_Part_729_898864384.1445518056758
Content-Type: multipart/alternative;
boundary="----=_Part_730_980195394.1445518056758"
------=_Part_730_980195394.1445518056758
Content-Type: text/plain; charset=UTF-8
On Thursday, October 22, 2015 at 1:11:59 PM UTC+1, Oliver Kowalke wrote:
>
> Can you elaborate on this? I think that the example might be missing some
>> pieces. What is bar for example?
>>
> yes, but let me re-structure the example:
>
> void foo( execution_context * mctx) {
> ( * mctx)();
> }
>
> void fn1() {
> ...
> execution_context mctx = execution_context::current();
> execution_context ctx = execution_context( foo);
> ctx( & mctx);
> ...
> }
>
> void fn2() {
> ...
> execution_context mctx = execution_context::current();
> execution_context ctx = execution_context( foo);
> ctx( & mctx);
> ...
> }
>
> void bar() {
> fn1();
> fn2();
> }
>
> int main () {
> bar();
> return 0;
> }
>
> it doesn't matter if bar() is executed in main() or in the call-stack of a
> separate execution-context - the code will work.
> execution_context::current() represents the 'toplevel' context, the object
> returned by the different invocations of current() will refer to the same
> context object.
> current() is required in order to get an context to which we can jump back.
> concept of execution-context: a execution-context represents the flow of
> instructions, an application might 1..N distinct execution-context'
> (threads, fibers, coroutines ...)
> The API of execution_context:
>
> execution_context( Fn && fn, Args && ... args); // create an new
> execution-context running fn( args ...)
> void * operator()( void * vp); // resume *this while current context gets
> suspended, vp is passed to resumed context
> static execution_context current() // returns object pointing to current
> context, used in operator() above
>
> execution_context has the memory footprint of one pointer (control
> structure; containing fcontext_t)
>
> note there is no such thing like a default ctor
>
>
another approach:
template<class T, class R>
class context;
template<class T, class R>
context::context() ; // create any empty context
template<class T, class R>
context::context( Fn && fn, Args && ... args); // requires
IsSame<result_of<Fn(context<R,T>, args..), context>;
template<class T, class R>
R context::operator()(T); // invokes context and implicitly pass to it this
context. On return 'this' contains the context we are coming from.
Returning it explicitly is an alternative.
template<class T, class R, class T2, class R2, class F>
context<T, R> transform(context<T2, R2> x, F f); // returns a new context
that when invoked switches to context 'x', but instead of returning from
operator() gives control to f. F is passed a context of type context<R,T>
as a parameter. requires IsSame<result_of<F(context<R, T>)>,
context<R2,T2>).
This is equivalent to your captured_context approach, except that
'transform' allows for a principled approach to get_context/set_context
without the "returns twice" madness.
Your example is simply:
void foo( context mctx) {
mctx();
}
void fn1() {
....
context ctx = execution( foo);
ctx();
....
}
void fn2() {
....
context ctx( foo);
ctx();
....
}
void bar() {
fn1();
fn2();
}
int main () {
bar();
return 0;
}
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.
------=_Part_730_980195394.1445518056758
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
On Thursday, October 22, 2015 at 1:11:59 PM UTC+1, Oliver Kowalke wrote:<bl=
ockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border=
-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr"><div><div class=
=3D"gmail_quote"><blockquote class=3D"gmail_quote" style=3D"margin:0px 0px =
0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><p dir=
=3D"ltr">Can you elaborate on this? I think that the example might be missi=
ng some pieces. What is bar for example?<span><br></span></p></blockquote><=
div>yes, but let me re-structure the example:<br><br><div>void foo( executi=
on_context * mctx) {<br></div><div>=C2=A0 ( * mctx)();<br></div><div>}<br><=
br></div><div>void fn1() {<br>...<br><div>=C2=A0 execution_context mctx =3D=
execution_context::current();<br>=C2=A0 execution_context ctx =3D executio=
n_context( foo);<br></div><div>=C2=A0 ctx( & mctx);<br>...<br></div>}<b=
r><br>void fn2() {<br>...<br><div>=C2=A0 execution_context mctx =3D executi=
on_context::current();<br>=C2=A0 execution_context ctx =3D execution_contex=
t( foo);<br></div><div>=C2=A0 ctx( & mctx);<br>...<br></div>}<br><br></=
div><div>void bar() {<br></div><div>=C2=A0 fn1();<br></div><div>=C2=A0 fn2(=
);<br>}<br></div><div><br></div><div>int main () {<br></div><div>=C2=A0=C2=
=A0 bar();<br></div><div>=C2=A0=C2=A0 return 0;<br></div>}<br><br></div><di=
v>it doesn't matter if bar() is executed in main() or in the call-stack=
of a separate execution-context - the code will work.<br>execution_context=
::current() represents the 'toplevel' context, the object returned =
by the different invocations of current() will refer to the same context ob=
ject.<br></div><div>current() is required in order to get an context to whi=
ch we can jump back.<br></div><div>concept of execution-context: a executio=
n-context represents the flow of instructions, an application might 1..N di=
stinct execution-context' (threads, fibers, coroutines ...)<br></div><d=
iv>The API of execution_context:<br></div><div><br>execution_context( Fn &a=
mp;& fn, Args && ... args); // create an new execution-context =
running fn( args ...)<br></div><div>void * operator()( void * vp); // resum=
e *this while current context gets suspended, vp is passed to resumed conte=
xt<br></div><div>static execution_context current() // returns object point=
ing to current context, used in operator() above<br><br></div><div>executio=
n_context has the memory footprint of one pointer (control structure; conta=
ining fcontext_t)<br></div><br></div><div class=3D"gmail_quote">note there =
is no such thing like a default ctor<br></div></div><br></div></blockquote>=
<div><br>another approach:<br><br>template<class T, class R><br>class=
context;<br><br>template<class T, class R><br>context::context() ; /=
/ create any empty context<br><br>template<class T, class R><br>conte=
xt::context( Fn && fn, Args && ... args); // requires IsSam=
e<result_of<Fn(context<R,T>, args..), context>;<br><br>templ=
ate<class T, class R><br>R context::operator()(T); // invokes context=
and implicitly pass to it this context. On return 'this' contains =
the context we are coming from. Returning it explicitly is an alternative.<=
br><br>template<class T, class R, class T2, class R2, class F><br>con=
text<T, R> transform(context<T2, R2> x, F f); //=20
returns a new context that when invoked switches to context 'x', bu=
t instead of returning from operator() gives control to f. F is passed a co=
ntext of type context<R,T> as a parameter. requires IsSame<result_=
of<F(context<R, T>)>, context<R2,T2>).<br><br>This is equ=
ivalent to your captured_context approach, except that 'transform' =
allows for a principled approach to get_context/set_context without the &qu=
ot;returns twice" madness.<br><br>Your example is simply:<br><br><div>=
void foo( context mctx) {<br></div><div>=C2=A0 mctx();<br></div><div>}<br><=
br></div><div>void fn1() {<br>...<br><div><div class=3D"IVILX2C-Db-b"></div=
>=C2=A0 context ctx =3D execution( foo);<br></div><div>=C2=A0 ctx();<br>...=
<br></div>}<br><br>void fn2() {<br>...<br><div><div class=3D"IVILX2C-Db-b">=
</div>=C2=A0 context ctx( foo);<br></div><div>=C2=A0 ctx();<br>...<br></div=
>}<br><br></div><div>void bar() {<br></div><div>=C2=A0 fn1();<br></div><div=
>=C2=A0 fn2();<br>}<br></div><div><br></div><div>int main () {<br></div><di=
v>=C2=A0=C2=A0 bar();<br></div><div>=C2=A0=C2=A0 return 0;<br></div>}<br><b=
r>=C2=A0</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_730_980195394.1445518056758--
------=_Part_729_898864384.1445518056758--
.
Author: Oliver Kowalke <oliver.kowalke@gmail.com>
Date: Thu, 22 Oct 2015 16:22:17 +0200
Raw View
--089e01227efc1483680522b23ac2
Content-Type: text/plain; charset=UTF-8
2015-10-22 14:47 GMT+02:00 Giovanni Piero Deretta <gpderetta@gmail.com>:
>
> template<class T, class R>
> class context;
>
> template<class T, class R>
> context::context() ; // create any empty context
>
> template<class T, class R>
> context::context( Fn && fn, Args && ... args); // requires
> IsSame<result_of<Fn(context<R,T>, args..), context>;
>
> template<class T, class R>
> R context::operator()(T); // invokes context and implicitly pass to it
> this context. On return 'this' contains the context we are coming from.
> Returning it explicitly is an alternative.
>
template<class T, class R, class T2, class R2, class F>
> context<T, R> transform(context<T2, R2> x, F f); // returns a new context
> that when invoked switches to context 'x', but instead of returning from
> operator() gives control to f. F is passed a context of type context<R,T>
> as a parameter. requires IsSame<result_of<F(context<R, T>)>,
> context<R2,T2>).
>
- I don't like default ctor representing a non valid context
- you still have the possibility to create harmful loops that overwrite the
stack
- storing multiple context' with different T and R in a container is more
difficult
- having T and R in the type signature of context prevents calling
operator() with altering types for each invocation
- transform looks for me like callcc; could be implemented by higher
abstractions
--
---
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/.
--089e01227efc1483680522b23ac2
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">2015=
-10-22 14:47 GMT+02:00 Giovanni Piero Deretta <span dir=3D"ltr"><<a href=
=3D"mailto:gpderetta@gmail.com" target=3D"_blank">gpderetta@gmail.com</a>&g=
t;</span>:<br><blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;=
border-left:1px #ccc solid;padding-left:1ex"><br><div>template<class T, =
class R><br>class context;<br><br>template<class T, class R><br>co=
ntext::context() ; // create any empty context<br><br>template<class T, =
class R><br>context::context( Fn && fn, Args && ... args=
); // requires IsSame<result_of<Fn(context<R,T>, args..), conte=
xt>;<br><br>template<class T, class R><br>R context::operator()(T)=
; // invokes context and implicitly pass to it this context. On return '=
;this' contains the context we are coming from. Returning it explicitly=
is an alternative.<br></div></blockquote><blockquote class=3D"gmail_quote"=
style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><d=
iv>template<class T, class R, class T2, class R2, class F><br>context=
<T, R> transform(context<T2, R2> x, F f); //=20
returns a new context that when invoked switches to context 'x', bu=
t instead of returning from operator() gives control to f. F is passed a co=
ntext of type context<R,T> as a parameter. requires IsSame<result_=
of<F(context<R, T>)>, context<R2,T2>).<br></div></blockqu=
ote></div><br></div><div class=3D"gmail_extra">- I don't like default c=
tor representing a non valid context<br></div><div class=3D"gmail_extra">- =
you still have the possibility to create harmful loops that overwrite the s=
tack<br></div><div class=3D"gmail_extra">- storing multiple context' wi=
th different T and R in a container is more difficult<br></div><div class=
=3D"gmail_extra">- having T and R in the type signature of context prevents=
calling operator() with altering types for each invocation<br></div><div c=
lass=3D"gmail_extra">- transform looks for me like callcc; could be impleme=
nted by higher abstractions<br></div><div class=3D"gmail_extra">=C2=A0 <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 />
--089e01227efc1483680522b23ac2--
.
Author: Giovanni Piero Deretta <gpderetta@gmail.com>
Date: Thu, 22 Oct 2015 07:42:26 -0700 (PDT)
Raw View
------=_Part_738_466634363.1445524946866
Content-Type: multipart/alternative;
boundary="----=_Part_739_728888655.1445524946867"
------=_Part_739_728888655.1445524946867
Content-Type: text/plain; charset=UTF-8
On Thursday, October 22, 2015 at 3:22:39 PM UTC+1, Oliver Kowalke wrote:
>
> 2015-10-22 14:47 GMT+02:00 Giovanni Piero Deretta <gpde...@gmail.com
> <javascript:>>:
>
>>
>> template<class T, class R>
>> class context;
>>
>> template<class T, class R>
>> context::context() ; // create any empty context
>>
>> template<class T, class R>
>> context::context( Fn && fn, Args && ... args); // requires
>> IsSame<result_of<Fn(context<R,T>, args..), context>;
>>
>> template<class T, class R>
>> R context::operator()(T); // invokes context and implicitly pass to it
>> this context. On return 'this' contains the context we are coming from.
>> Returning it explicitly is an alternative.
>>
> template<class T, class R, class T2, class R2, class F>
>> context<T, R> transform(context<T2, R2> x, F f); // returns a new context
>> that when invoked switches to context 'x', but instead of returning from
>> operator() gives control to f. F is passed a context of type context<R,T>
>> as a parameter. requires IsSame<result_of<F(context<R, T>)>,
>> context<R2,T2>).
>>
>
> - I don't like default ctor representing a non valid context
>
You stil need a way to represent a context that has terminated. The
alternative is to pass around context_ptr which can be null. I do not have
a strong preference.
> - you still have the possibility to create harmful loops that overwrite
> the stack
>
Could you give an example?
> - storing multiple context' with different T and R in a container is more
> difficult
>
well, yes of course. You need to use the same types or type erasure if you
need that. If we only allow passing pointers and default parameters and
returns to null, then we could have every context implicitly convert to
context<void, void>.
> - having T and R in the type signature of context prevents calling
> operator() with altering types for each invocation
>
you says it like it is a bad thing :). Setting them to void* or boost::any
would bypass typesafety (or postpone checks to runtime), but the
abstraction should be safe by default. Note that you can use transform for
changing temporarily or permanently the type of a continuation in a type
safe manner.
> - transform looks for me like callcc; could be implemented by higher
> abstractions
>
It is the same, but it needs to be a primitive if you want an efficient
implementation. Note that you need it anyway internally to implement new
context creation, destruction and to propagate exceptions.
-- gpd
--
---
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_739_728888655.1445524946867
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<br><br>On Thursday, October 22, 2015 at 3:22:39 PM UTC+1, Oliver Kowalke w=
rote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8e=
x;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr"><div><di=
v class=3D"gmail_quote">2015-10-22 14:47 GMT+02:00 Giovanni Piero Deretta <=
span dir=3D"ltr"><<a href=3D"javascript:" target=3D"_blank" gdf-obfuscat=
ed-mailto=3D"OqgtcQgNEQAJ" rel=3D"nofollow" onmousedown=3D"this.href=3D'=
;javascript:';return true;" onclick=3D"this.href=3D'javascript:'=
;;return true;">gpde...@gmail.com</a>></span>:<br><blockquote class=3D"g=
mail_quote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-l=
eft:1ex"><br><div>template<class T, class R><br>class context;<br><br=
>template<class T, class R><br>context::context() ; // create any emp=
ty context<br><br>template<class T, class R><br>context::context( Fn =
&& fn, Args && ... args); // requires IsSame<result_of&l=
t;Fn(context<R,<wbr>T>, args..), context>;<br><br>template<clas=
s T, class R><br>R context::operator()(T); // invokes context and implic=
itly pass to it this context. On return 'this' contains the context=
we are coming from. Returning it explicitly is an alternative.<br></div></=
blockquote><blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;bor=
der-left:1px #ccc solid;padding-left:1ex"><div>template<class T, class R=
, class T2, class R2, class F><br>context<T, R> transform(context&=
lt;T2, R2> x, F f); //=20
returns a new context that when invoked switches to context 'x', bu=
t instead of returning from operator() gives control to f. F is passed a co=
ntext of type context<R,T> as a parameter. requires IsSame<result_=
of<F(context<R, T>)>, context<R2,T2>).<br></div></blockqu=
ote></div><br></div><div>- I don't like default ctor representing a non=
valid context<br></div></div></blockquote><div><br>You stil need a way to =
represent a context that has terminated. The alternative is to pass around =
context_ptr which can be null. I do not have a strong preference.<br>=C2=A0=
</div><blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8=
ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr"><div></=
div><div>- you still have the possibility to create harmful loops that over=
write the stack<br></div></div></blockquote><div><br>Could you give an exam=
ple?<br>=C2=A0</div><blockquote class=3D"gmail_quote" style=3D"margin: 0;ma=
rgin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=
=3D"ltr"><div></div><div>- storing multiple context' with different T a=
nd R in a container is more difficult<br></div></div></blockquote><div><br>=
well, yes of course. You need to use the same types or type erasure if you =
need that. If we only allow passing pointers and default parameters and ret=
urns to null, then we could have every context implicitly convert to contex=
t<void, void>.<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;"><div dir=3D"ltr"><div></div><div>- having T and R in the type signatu=
re of context prevents calling operator() with altering types for each invo=
cation<br></div></div></blockquote><div><br>you says it like it is a bad th=
ing :). Setting them to void* or boost::any would bypass typesafety (or pos=
tpone checks to runtime), but the abstraction should be safe by default. No=
te that you can use transform for changing temporarily or permanently the t=
ype of a continuation in a type safe manner.<br>=C2=A0</div><blockquote cla=
ss=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #=
ccc solid;padding-left: 1ex;"><div dir=3D"ltr"><div></div><div>- transform =
looks for me like callcc; could be implemented by higher abstractions<br></=
div></div></blockquote><div><br>It is the same, but it needs to be a primit=
ive if you want an efficient implementation. Note that you need it anyway i=
nternally to implement new context creation, destruction and to propagate e=
xceptions. <br></div><br>-- gpd<br>
<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_739_728888655.1445524946867--
------=_Part_738_466634363.1445524946866--
.
Author: Oliver Kowalke <oliver.kowalke@gmail.com>
Date: Thu, 22 Oct 2015 17:18:54 +0200
Raw View
--089e0112cf1086c1340522b304dc
Content-Type: text/plain; charset=UTF-8
2015-10-22 16:42 GMT+02:00 Giovanni Piero Deretta <gpderetta@gmail.com>:
> - I don't like default ctor representing a non valid context
>>
>
> You stil need a way to represent a context that has terminated. The
> alternative is to pass around context_ptr which can be null. I do not have
> a strong preference.
>
maybe explicit `operator bool()`? -
>
>
>> - you still have the possibility to create harmful loops that overwrite
>> the stack
>>
>
> Could you give an example?
>
something like (template types omitted):
void foo( context<> mctx) {
mctx( mctx); // switch to main(), pass itself as argument
}
void main() {
context<> ctx( foo);
context<> mctx = ctx();
....
mctx(); // should jump to `context<> mctx = ctx();`
}
- context< void, context > mctx = ctx(); should enter foo()
- inside ctx() a context is created that captures to context of main() and
is passed as argument foo
- inside foo() mctx() does a context switch to main() (returning inside
ctx())
- mctx() gets itself as agument, which is transferred though the context
switch
- thus ctx() will return a context pointing to the instruction after
resuming ctx (e.g. after jump_fcontext() if boost.context would be used
internally)
>
>
>> - storing multiple context' with different T and R in a container is more
>> difficult
>>
>
> well, yes of course. You need to use the same types or type erasure if you
> need that. If we only allow passing pointers and default parameters and
> returns to null, then we could have every context implicitly convert to
> context<void, void>.
>
at least that would solve the problem I've had with invoke()
>
>
>> - having T and R in the type signature of context prevents calling
>> operator() with altering types for each invocation
>>
>
> you says it like it is a bad thing :). Setting them to void* or boost::any
> would bypass typesafety (or postpone checks to runtime), but the
> abstraction should be safe by default. Note that you can use transform for
> changing temporarily or permanently the type of a continuation in a type
> safe manner.
>
--
---
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/.
--089e0112cf1086c1340522b304dc
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">2015=
-10-22 16:42 GMT+02:00 Giovanni Piero Deretta <span dir=3D"ltr"><<a href=
=3D"mailto:gpderetta@gmail.com" target=3D"_blank">gpderetta@gmail.com</a>&g=
t;</span>:<br><blockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px=
0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><span class=
=3D""><blockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;b=
order-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir=3D"ltr"><d=
iv>- I don't like default ctor representing a non valid context<br></di=
v></div></blockquote></span><div><br>You stil need a way to represent a con=
text that has terminated. The alternative is to pass around context_ptr whi=
ch can be null. I do not have a strong preference.<br></div></blockquote><d=
iv><br></div><div>maybe explicit `operator bool()`? - <br></div><div>=C2=A0=
</div><blockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;b=
order-left:1px solid rgb(204,204,204);padding-left:1ex"><div>=C2=A0</div><s=
pan class=3D""><blockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0p=
x 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir=
=3D"ltr"><div></div><div>- you still have the possibility to create harmful=
loops that overwrite the stack<br></div></div></blockquote></span><div><br=
>Could you give an example?<br></div></blockquote><div><br></div><div>somet=
hing like (template types omitted):<br></div><div><br><div>void foo( contex=
t<> mctx) {<br></div><div>=C2=A0 mctx( mctx); // switch to main(), pa=
ss itself as argument<br></div>}<br><br>void main() {<br>context<> ct=
x( foo);<br>context<> mctx =3D ctx();<br>...<br></div><div>mctx(); //=
should jump to `context<> mctx =3D ctx();`<br>}<br><br>- context<=
void, context > mctx =3D ctx(); should enter foo()<br></div><div>- insi=
de ctx() a context is created that captures to context of main() and is pas=
sed as argument foo<br></div><div>- inside foo() mctx() does a context swit=
ch to main() (returning inside ctx())<br></div><div>- mctx() gets itself as=
agument, which is transferred though the context switch<br></div><div>- th=
us ctx() will return a context pointing to the instruction after resuming c=
tx (e.g. after jump_fcontext() if boost.context would be used internally)<b=
r></div><div>=C2=A0</div><blockquote class=3D"gmail_quote" style=3D"margin:=
0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">=
<div>=C2=A0</div><span class=3D""><blockquote class=3D"gmail_quote" style=
=3D"margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding=
-left:1ex"><div dir=3D"ltr"><div></div><div>- storing multiple context'=
with different T and R in a container is more difficult<br></div></div></b=
lockquote></span><div><br>well, yes of course. You need to use the same typ=
es or type erasure if you need that. If we only allow passing pointers and =
default parameters and returns to null, then we could have every context im=
plicitly convert to context<void, void>.<br></div></blockquote><div><=
br></div><div>at least that would solve the problem I've had with invok=
e()<br></div><div>=C2=A0</div><blockquote class=3D"gmail_quote" style=3D"ma=
rgin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:=
1ex"><div>=C2=A0</div><span class=3D""><blockquote class=3D"gmail_quote" st=
yle=3D"margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padd=
ing-left:1ex"><div dir=3D"ltr"><div>- having T and R in the type signature =
of context prevents calling operator() with altering types for each invocat=
ion<br></div></div></blockquote></span><div><br>you says it like it is a ba=
d thing :). Setting them to void* or boost::any would bypass typesafety (or=
postpone checks to runtime), but the abstraction should be safe by default=
.. Note that you can use transform for changing temporarily or permanently t=
he type of a continuation in a type safe manner.<br></div></blockquote></di=
v><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 />
--089e0112cf1086c1340522b304dc--
.
Author: Giovanni Piero Deretta <gpderetta@gmail.com>
Date: Thu, 22 Oct 2015 10:15:49 -0700 (PDT)
Raw View
------=_Part_806_385034664.1445534150053
Content-Type: multipart/alternative;
boundary="----=_Part_807_91102279.1445534150054"
------=_Part_807_91102279.1445534150054
Content-Type: text/plain; charset=UTF-8
On Thursday, October 22, 2015 at 4:19:16 PM UTC+1, Oliver Kowalke wrote:
>
> 2015-10-22 16:42 GMT+02:00 Giovanni Piero Deretta <gpde...@gmail.com
> <javascript:>>:
>
>> - I don't like default ctor representing a non valid context
>>>
>>
>> You stil need a way to represent a context that has terminated. The
>> alternative is to pass around context_ptr which can be null. I do not have
>> a strong preference.
>>
>
> maybe explicit `operator bool()`? -
>
ok, but if an empty state exists, the user should be able to create it.
>
>
>>
>>
>>> - you still have the possibility to create harmful loops that overwrite
>>> the stack
>>>
>>
>> Could you give an example?
>>
>
> something like (template types omitted):
>
> void foo( context<> mctx) {
> mctx( mctx); // switch to main(), pass itself as argument
> }
>
> void main() {
> context<> ctx( foo);
> context<> mctx = ctx();
> ...
> mctx(); // should jump to `context<> mctx = ctx();`
> }
>
> - context< void, context > mctx = ctx(); should enter foo()
> - inside ctx() a context is created that captures to context of main() and
> is passed as argument foo
> - inside foo() mctx() does a context switch to main() (returning inside
> ctx())
> - mctx() gets itself as agument, which is transferred though the context
> switch
> - thus ctx() will return a context pointing to the instruction after
> resuming ctx (e.g. after jump_fcontext() if boost.context would be used
> internally)
>
That does't work: first of all the context is passed implicitly, so calling
mtcx(mtcx) doesn't work. If you explicitly make it a context<context<...>
>, you still have a problem. A context must be movable, not copyable, so if
you move it to operator(), you no longer have an object to call operator()
on. If you pass by pointer, operator() will 'consume' this object, so main
will get an empty pointer; it will be again non empty only when operator()
returns.
Basically contextes follow a strictly linear typing discipline and must be
invoked exactly once.
--
---
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_807_91102279.1445534150054
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
On Thursday, October 22, 2015 at 4:19:16 PM UTC+1, Oliver Kowalke wrote:<bl=
ockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border=
-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr"><div><div class=
=3D"gmail_quote">2015-10-22 16:42 GMT+02:00 Giovanni Piero Deretta <span di=
r=3D"ltr"><<a href=3D"javascript:" target=3D"_blank" gdf-obfuscated-mail=
to=3D"PLkDZx8QEQAJ" rel=3D"nofollow" onmousedown=3D"this.href=3D'javasc=
ript:';return true;" onclick=3D"this.href=3D'javascript:';retur=
n true;">gpde...@gmail.com</a>></span>:<br><blockquote class=3D"gmail_qu=
ote" style=3D"margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,20=
4);padding-left:1ex"><span><blockquote class=3D"gmail_quote" style=3D"margi=
n:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex=
"><div dir=3D"ltr"><div>- I don't like default ctor representing a non =
valid context<br></div></div></blockquote></span><div><br>You stil need a w=
ay to represent a context that has terminated. The alternative is to pass a=
round context_ptr which can be null. I do not have a strong preference.<br>=
</div></blockquote><div><br></div><div>maybe explicit `operator bool()`? - =
<br></div></div></div></div></blockquote><div><br>ok, but if an empty state=
exists, the user should be able to create it.<br>=C2=A0</div><blockquote c=
lass=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px=
#ccc solid;padding-left: 1ex;"><div dir=3D"ltr"><div><div class=3D"gmail_q=
uote"><div></div><div>=C2=A0</div><blockquote class=3D"gmail_quote" style=
=3D"margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding=
-left:1ex"><div>=C2=A0</div><span><blockquote class=3D"gmail_quote" style=
=3D"margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding=
-left:1ex"><div dir=3D"ltr"><div></div><div>- you still have the possibilit=
y to create harmful loops that overwrite the stack<br></div></div></blockqu=
ote></span><div><br>Could you give an example?<br></div></blockquote><div><=
br></div><div>something like (template types omitted):<br></div><div><br><d=
iv>void foo( context<> mctx) {<br></div><div>=C2=A0 mctx( mctx); // s=
witch to main(), pass itself as argument<br></div>}<br><br>void main() {<br=
>context<> ctx( foo);<br>context<> mctx =3D ctx();<br>...<br></=
div><div>mctx(); // should jump to `context<> mctx =3D ctx();`<br>}<b=
r><br>- context< void, context > mctx =3D ctx(); should enter foo()<b=
r></div><div>- inside ctx() a context is created that captures to context o=
f main() and is passed as argument foo<br></div><div>- inside foo() mctx() =
does a context switch to main() (returning inside ctx())<br></div><div>- mc=
tx() gets itself as agument, which is transferred though the context switch=
<br></div><div>- thus ctx() will return a context pointing to the instructi=
on after resuming ctx (e.g. after jump_fcontext() if boost.context would be=
used internally)<br></div></div></div></div></blockquote><div><br>That doe=
s't work: first of all the context is passed implicitly, so calling mtc=
x(mtcx) doesn't work. If you explicitly make it a context<context<=
;...> >, you still have a problem. A context must be movable, not cop=
yable, so if you move it to operator(), you no longer have an object to cal=
l operator() on. If you pass by pointer, operator() will 'consume' =
this object, so main will get an empty pointer; it will be again non empty =
only when operator() returns.<br><br>Basically contextes follow a strictly =
linear typing discipline and must be invoked exactly once.<br></div>
<p></p>
-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />
------=_Part_807_91102279.1445534150054--
------=_Part_806_385034664.1445534150053--
.
Author: Oliver Kowalke <oliver.kowalke@gmail.com>
Date: Thu, 22 Oct 2015 19:50:14 +0200
Raw View
--089e0112cf10c394f40522b5210c
Content-Type: text/plain; charset=UTF-8
2015-10-22 19:15 GMT+02:00 Giovanni Piero Deretta <gpderetta@gmail.com>:
>> void foo( context<> mctx) {
>> mctx( mctx); // switch to main(), pass itself as argument
>> }
>>
>> void main() {
>> context<> ctx( foo);
>> context<> mctx = ctx();
>> ...
>> mctx(); // should jump to `context<> mctx = ctx();`
>> }
>>
>> - context< void, context > mctx = ctx(); should enter foo()
>> - inside ctx() a context is created that captures to context of main()
>> and is passed as argument foo
>> - inside foo() mctx() does a context switch to main() (returning inside
>> ctx())
>> - mctx() gets itself as agument, which is transferred though the context
>> switch
>> - thus ctx() will return a context pointing to the instruction after
>> resuming ctx (e.g. after jump_fcontext() if boost.context would be used
>> internally)
>>
>
> That does't work: first of all the context is passed implicitly, so
> calling mtcx(mtcx) doesn't work.
>
why? mctx is created inside ctx() - implicitly created as you say. mctx is
passed to foo() as argument.
(the API is similar to N3985)
with context::operator() you can transfer data through the context switch-
as you already requested.
the synthesized mctx could then be transferred as data == mctx() does
resume the context() of main().
I don't see why it is not possible to take the address of mctx and pass it
through the switch back.
> If you pass by pointer, operator() will 'consume' this object, so main
> will get an empty pointer; it will be again non empty only when operator()
> returns.
>
Then a synthesized context (== passed as arg to the context-fn) is not the
same as context created with context(Fn&&,Args&&...).
That means you can not create chains of context', e.g. main() -> ctx1 ->
ctx2 -> main()
To create such a circle you need to be able to pass the synthesized context
though a context switch, e.g.
- main() resumes ctx1 and mctx is synthesized and passed to context ctx1
- ctx1 resumes ctx2 and it is required to pass mctx as argument to ctx2
- ctx2 gets mctx as argument and calls mctx() == suspend ctx2 and resume
main() (== returning from ctx1() in main())
Otherwise we get some kind of N3985 == asymmetric context switching, that
means that a context can only switch back to its caller (! symmetric
context switching)
--
---
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/.
--089e0112cf10c394f40522b5210c
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">2015=
-10-22 19:15 GMT+02:00 Giovanni Piero Deretta <span dir=3D"ltr"><<a href=
=3D"mailto:gpderetta@gmail.com" target=3D"_blank">gpderetta@gmail.com</a>&g=
t;</span>:<br><br><blockquote class=3D"gmail_quote" style=3D"margin:0px 0px=
0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><span c=
lass=3D""><blockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8=
ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir=3D"ltr=
"><div><div class=3D"gmail_quote"><div><br><div>void foo( context<> m=
ctx) {<br></div><div>=C2=A0 mctx( mctx); // switch to main(), pass itself a=
s argument<br></div>}<br><br>void main() {<br>context<> ctx( foo);<br=
>context<> mctx =3D ctx();<br>...<br></div><div>mctx(); // should jum=
p to `context<> mctx =3D ctx();`<br>}<br><br>- context< void, cont=
ext > mctx =3D ctx(); should enter foo()<br></div><div>- inside ctx() a =
context is created that captures to context of main() and is passed as argu=
ment foo<br></div><div>- inside foo() mctx() does a context switch to main(=
) (returning inside ctx())<br></div><div>- mctx() gets itself as agument, w=
hich is transferred though the context switch<br></div><div>- thus ctx() wi=
ll return a context pointing to the instruction after resuming ctx (e.g. af=
ter jump_fcontext() if boost.context would be used internally)<br></div></d=
iv></div></div></blockquote></span><div><br>That does't work: first of =
all the context is passed implicitly, so calling mtcx(mtcx) doesn't wor=
k.</div></blockquote><div><br></div><div>why? mctx is created inside ctx() =
- implicitly created as you say. mctx is passed to foo() as argument.<br></=
div><div>(the API is similar to N3985)<br><br></div><div>with context::oper=
ator() you can transfer data through the context switch- as you already req=
uested.<br></div><div>the synthesized mctx could then be transferred as dat=
a =3D=3D mctx() does resume the context() of main().<br></div><div>I don=
9;t see why it is not possible to take the address of mctx and pass it thro=
ugh the switch back. <br></div><div>=C2=A0</div><blockquote class=3D"gmail_=
quote" style=3D"margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,=
204);padding-left:1ex"><div>=C2=A0If you pass by pointer, operator() will &=
#39;consume' this object, so main will get an empty pointer; it will be=
again non empty only when operator() returns.<br></div></blockquote><div><=
br></div>Then a synthesized context (=3D=3D passed as arg to the context-fn=
) is not the same as context created with context(Fn&&,Args&&am=
p;...).<br></div><div class=3D"gmail_quote">That means you can not create c=
hains of context', e.g. main() -> ctx1 -> ctx2 -> main()<br></=
div><div class=3D"gmail_quote">To create such a circle you need to be able =
to pass the synthesized context though a context switch, e.g.<br><br></div>=
<div class=3D"gmail_quote">- main() resumes ctx1 and mctx is synthesized an=
d passed to context ctx1<br></div><div class=3D"gmail_quote">- ctx1 resumes=
ctx2 and it is required to pass mctx as argument to ctx2<br></div><div cla=
ss=3D"gmail_quote">- ctx2 gets mctx as argument and calls mctx() =3D=3D sus=
pend ctx2 and resume main() (=3D=3D returning from ctx1() in main())<br><br=
></div><div class=3D"gmail_quote">Otherwise we get some kind of N3985 =3D=
=3D asymmetric context switching, that means that a context can only switch=
back to its caller (! symmetric context switching)<br></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 />
--089e0112cf10c394f40522b5210c--
.
Author: Oliver Kowalke <oliver.kowalke@gmail.com>
Date: Thu, 22 Oct 2015 20:08:09 +0200
Raw View
--089e015383e8d1f9c10522b5610d
Content-Type: text/plain; charset=UTF-8
2015-10-22 14:11 GMT+02:00 Oliver Kowalke <oliver.kowalke@gmail.com>:
> captured_context( Fn && fn, Args && ... args); // create an new
> captured-context running fn( args ...)
> std::tuple< captured_context, void * > operator()(void * vp); // resume
> *this, vp is passed to resumed context, no TLS
>
> operator() returns a std::tuple<> - the passed parameter vp and a
> capture_context representing the (parent) context from which we jumped to
> this context
>
should captured_context be moveable only?
--
---
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/.
--089e015383e8d1f9c10522b5610d
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">2015=
-10-22 14:11 GMT+02:00 Oliver Kowalke <span dir=3D"ltr"><<a href=3D"mail=
to:oliver.kowalke@gmail.com" target=3D"_blank">oliver.kowalke@gmail.com</a>=
></span>:<br><blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8e=
x;border-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><div class=
=3D"gmail_extra"><div class=3D"gmail_extra"><span class=3D""></span>capture=
d_context( Fn && fn, Args && ... args); // create an new ca=
ptured-context running fn( args ...)<br>std::tuple<
captured_context, void * > operator()(void * vp); // resume *this, vp i=
s passed to
resumed context, no TLS<br><br></div></div><div class=3D"gmail_extra">oper=
ator() returns a std::tuple<> - the passed parameter vp and a capture=
_context representing the (parent) context from which we jumped to this con=
text<br></div></div></blockquote></div><br></div><div class=3D"gmail_extra"=
>should captured_context be moveable only?<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 />
--089e015383e8d1f9c10522b5610d--
.
Author: Giovanni Piero Deretta <gpderetta@gmail.com>
Date: Thu, 22 Oct 2015 15:22:11 -0700 (PDT)
Raw View
------=_Part_1307_2027604823.1445552531866
Content-Type: multipart/alternative;
boundary="----=_Part_1308_602633958.1445552531866"
------=_Part_1308_602633958.1445552531866
Content-Type: text/plain; charset=UTF-8
On Thursday, October 22, 2015 at 6:50:36 PM UTC+1, Oliver Kowalke wrote:
>
> 2015-10-22 19:15 GMT+02:00 Giovanni Piero Deretta <gpde...@gmail.com
> <javascript:>>:
>
>
>>> void foo( context<> mctx) {
>>> mctx( mctx); // switch to main(), pass itself as argument
>>> }
>>>
>>> void main() {
>>> context<> ctx( foo);
>>> context<> mctx = ctx();
>>> ...
>>> mctx(); // should jump to `context<> mctx = ctx();`
>>> }
>>>
>>> - context< void, context > mctx = ctx(); should enter foo()
>>> - inside ctx() a context is created that captures to context of main()
>>> and is passed as argument foo
>>> - inside foo() mctx() does a context switch to main() (returning inside
>>> ctx())
>>> - mctx() gets itself as agument, which is transferred though the context
>>> switch
>>> - thus ctx() will return a context pointing to the instruction after
>>> resuming ctx (e.g. after jump_fcontext() if boost.context would be used
>>> internally)
>>>
>>
>> That does't work: first of all the context is passed implicitly, so
>> calling mtcx(mtcx) doesn't work.
>>
>
> why? mctx is created inside ctx() - implicitly created as you say. mctx is
> passed to foo() as argument.
> (the API is similar to N3985)
>
> with context::operator() you can transfer data through the context switch-
> as you already requested.
> the synthesized mctx could then be transferred as data == mctx() does
> resume the context() of main().
> I don't see why it is not possible to take the address of mctx and pass it
> through the switch back.
>
oh, yes, of course, you are free to pass it as a normal parameter. You used
context<>, so I thought you where explicitly talking about a void context.
Note that getting the type of the recursive context right is non obvious
though.
>
>
>> If you pass by pointer, operator() will 'consume' this object, so main
>> will get an empty pointer; it will be again non empty only when operator()
>> returns.
>>
>
> Then a synthesized context (== passed as arg to the context-fn) is not the
> same as context created with context(Fn&&,Args&&...).
>
All contextes are the same. The point is that a context can be called only
once. If you invoke it in foo to go back to main, you can't invoke it
again. To prevent misuse operator() should clear the context. When
operator() returns, context will again point to a new context.
> That means you can not create chains of context', e.g. main() -> ctx1 ->
> ctx2 -> main()
> To create such a circle you need to be able to pass the synthesized
> context though a context switch, e.g.
>
>
>
- main() resumes ctx1 and mctx is synthesized and passed to context ctx1
> - ctx1 resumes ctx2 and it is required to pass mctx as argument to ctx2
> - ctx2 gets mctx as argument and calls mctx() == suspend ctx2 and resume
> main() (== returning from ctx1() in main())
>
>
one way to implement this is with a (trivial) fifo scheduler of course. Le
me see if I can come up with a less dynamic setup.
using task = context<void, void>;
void work(task x, int i)
{
while(x) {
cout << i;
x();
}
}
auto splice(task1, task2) {
return transform(std::move(task1), [task2=std::move(task2)](auto from)
{ return splice(std::move(from), std::move(task2)); });
}
int main()
{
task stage1(work, 1);
task stage2(work, 2);
stage1 = splice(std::move(stage1), std::move(stage2));
while(stage1) {
cout << "main";
stage1();
}
}
If I got this right, this should print:
main
1
2
main
1
2
....
forever.
Applying splice multiple times should [1] you get longer pipelines. But
honestly it is positively mindbending.
[1] I haven't actually tried this!
--
---
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_1308_602633958.1445552531866
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
On Thursday, October 22, 2015 at 6:50:36 PM UTC+1, Oliver Kowalke wrote:<bl=
ockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border=
-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr"><div><div class=
=3D"gmail_quote">2015-10-22 19:15 GMT+02:00 Giovanni Piero Deretta <span di=
r=3D"ltr"><<a href=3D"javascript:" target=3D"_blank" gdf-obfuscated-mail=
to=3D"a6EwVGEYEQAJ" rel=3D"nofollow" onmousedown=3D"this.href=3D'javasc=
ript:';return true;" onclick=3D"this.href=3D'javascript:';retur=
n true;">gpde...@gmail.com</a>></span>:<br><br><blockquote class=3D"gmai=
l_quote" style=3D"margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,20=
4,204);padding-left:1ex"><span><blockquote class=3D"gmail_quote" style=3D"m=
argin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left=
:1ex"><div dir=3D"ltr"><div><div class=3D"gmail_quote"><div><br><div>void f=
oo( context<> mctx) {<br></div><div>=C2=A0 mctx( mctx); // switch to =
main(), pass itself as argument<br></div>}<br><br>void main() {<br>context&=
lt;> ctx( foo);<br>context<> mctx =3D ctx();<br>...<br></div><div>=
mctx(); // should jump to `context<> mctx =3D ctx();`<br>}<br><br>- c=
ontext< void, context > mctx =3D ctx(); should enter foo()<br></div><=
div>- inside ctx() a context is created that captures to context of main() =
and is passed as argument foo<br></div><div>- inside foo() mctx() does a co=
ntext switch to main() (returning inside ctx())<br></div><div>- mctx() gets=
itself as agument, which is transferred though the context switch<br></div=
><div>- thus ctx() will return a context pointing to the instruction after =
resuming ctx (e.g. after jump_fcontext() if boost.context would be used int=
ernally)<br></div></div></div></div></blockquote></span><div><br>That does&=
#39;t work: first of all the context is passed implicitly, so calling mtcx(=
mtcx) doesn't work.</div></blockquote><div><br></div><div>why? mctx is =
created inside ctx() - implicitly created as you say. mctx is passed to foo=
() as argument.<br></div><div>(the API is similar to N3985)<br><br></div><d=
iv>with context::operator() you can transfer data through the context switc=
h- as you already requested.<br></div><div>the synthesized mctx could then =
be transferred as data =3D=3D mctx() does resume the context() of main().<b=
r></div><div>I don't see why it is not possible to take the address of =
mctx and pass it through the switch back. <br></div><div></div></div></div>=
</div></blockquote><div><br>oh, yes, of course, you are free to pass it as =
a normal parameter. You used context<>, so I thought you where=C2=A0 =
explicitly talking about a void context. Note that getting the type of the =
recursive context right is non obvious though.<br>=C2=A0</div><blockquote c=
lass=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px=
#ccc solid;padding-left: 1ex;"><div dir=3D"ltr"><div><div class=3D"gmail_q=
uote"><div>=C2=A0</div><blockquote class=3D"gmail_quote" style=3D"margin:0p=
x 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><d=
iv>=C2=A0If you pass by pointer, operator() will 'consume' this obj=
ect, so main will get an empty pointer; it will be again non empty only whe=
n operator() returns.<br></div></blockquote><div><br></div>Then a synthesiz=
ed context (=3D=3D passed as arg to the context-fn) is not the same as cont=
ext created with context(Fn&&,Args&&...).<br></div></div></=
div></blockquote><div><br>All contextes are the same. The point is that a c=
ontext can be called=20
only once. If you invoke it in foo to go back to main, you can't invoke=
=20
it again. To prevent misuse operator() should clear the context. When=20
operator() returns, context will again point to a new context.<br>=C2=A0</d=
iv><blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;=
border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr"><div><div =
class=3D"gmail_quote"></div><div class=3D"gmail_quote">That means you can n=
ot create chains of context', e.g. main() -> ctx1 -> ctx2 -> m=
ain()<br></div><div>To create such a circle you need to be able to pass the=
synthesized context though a context switch, e.g.<br><br>=C2=A0</div></div=
></div></blockquote><blockquote class=3D"gmail_quote" style=3D"margin: 0;ma=
rgin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=
=3D"ltr"><div><div class=3D"gmail_quote"></div><div class=3D"gmail_quote">-=
main() resumes ctx1 and mctx is synthesized and passed to context ctx1<br>=
</div><div class=3D"gmail_quote">- ctx1 resumes ctx2 and it is required to =
pass mctx as argument to ctx2<br></div><div class=3D"gmail_quote">- ctx2 ge=
ts mctx as argument and calls mctx() =3D=3D suspend ctx2 and resume main() =
(=3D=3D returning from ctx1() in main())<br><br></div></div></div></blockqu=
ote><div><br>one way to implement this is with a (trivial) fifo scheduler o=
f course. Le me see if I can come up with a less dynamic setup.<br><br>usin=
g task =3D context<void, void>;<br><br>void work(task x, int i)<br>{<=
br>while(x) {<br>=C2=A0=C2=A0=C2=A0=C2=A0 cout << i;<br>=C2=A0=C2=A0=
=C2=A0=C2=A0 x();<br>=C2=A0=C2=A0=C2=A0 }<br>}<br><br>auto splice(task1, ta=
sk2) {<br>=C2=A0=C2=A0=C2=A0=C2=A0 return transform(std::move(task1), [task=
2=3Dstd::move(task2)](auto from) {=C2=A0 return splice(std::move(from), std=
::move(task2)); });<br>}<br><br>int main()<br>{<br>=C2=A0=C2=A0 task stage1=
(work, 1);<br>=C2=A0=C2=A0 task stage2(work, 2);<br><br>=C2=A0=C2=A0 stage1=
=3D splice(std::move(stage1), std::move(stage2)); =C2=A0 <br>=C2=A0=C2=A0 =
while(stage1) {<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 cout << "main&=
quot;;<br>=C2=A0 =C2=A0 =C2=A0 stage1();<br>=C2=A0=C2=A0=C2=A0 }<br>}<br><b=
r>If I got this right, this should print:<br>main<br>1<br>2<br>main<br>1<br=
>2<br>...<br><br>forever.<br></div><br>Applying splice multiple times shoul=
d [1] you get longer pipelines. But honestly it is positively mindbending. =
<br><br>[1] I haven't actually tried this!<br>
<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_1308_602633958.1445552531866--
------=_Part_1307_2027604823.1445552531866--
.
Author: Oliver Kowalke <oliver.kowalke@gmail.com>
Date: Fri, 23 Oct 2015 08:45:00 +0200
Raw View
--089e015383e88876050522bff496
Content-Type: text/plain; charset=UTF-8
>
> Then a synthesized context (== passed as arg to the context-fn) is not the
>> same as context created with context(Fn&&,Args&&...).
>>
>
> All contextes are the same. The point is that a context can be called only
> once. If you invoke it in foo to go back to main, you can't invoke it
> again. To prevent misuse operator() should clear the context. When
> operator() returns, context will again point to a new context.
>
if a context can be called only once how do you implement generators for
instance ( source/parent context not explicitly returned by
context::operator()):
void fibonacci( context<int> sink, int n) {
int first = 1, second = 1;
sink( first);
sink( second);
for ( int i = 0; i < n-2; ++i) {
int third = first + second;
first = second;
second = third;
sink( third);
}
}
context<int> source( fibinacci, 10);
for ( int i : source) {
std::cout << i << std::endl;
}
if a context can only be called once the fibonacci example would not work.
I assume that you mean that each invocation
of source() (context switch) updates the fcontext_t in sink is updated.
because sink can be moved down the callstack (to sub-routines) you need a
pointer to fcontext_t to update the structure or
you pass fcontext_t through jump_fcontext and update the structure before
you return from context::operator() of instance sink.
that's how boost.coroutine(2) works.
<snip>
but how should a absolute minimalistic API for stackful context switching
look like?
execution_context uses a pointer that is updated at each context switch,
e.g.
execution_context::operator() is implemented like:
void operator()( void * vp) {
ptr from( this);
current.swap( from); // *this becomes current execution-context
intptr_t ret = jump_fcontext( & from, this, vp); // resume *this
return reinterpret_cast< void * >( ret); // return parameter transferred
from *this
}
in contrast to context<> execution_context doesn't know its predecessor or
successor.
you criticize that current is a static pointer (that must be thread-local
because we operate in a multi-threaded env).
please note that this is a library implementation, it might be possible
that a compiler can implement execution_context in a
more efficient way.
at least the main aim should be to design a really minimalistic API useable
to build higher level abstractions.
--
---
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/.
--089e015383e88876050522bff496
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"><blo=
ckquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;border-left=
:1px solid rgb(204,204,204);padding-left:1ex"><span class=3D""><blockquote =
class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;border-left:1px sol=
id rgb(204,204,204);padding-left:1ex"><div dir=3D"ltr"><div><div class=3D"g=
mail_quote"><div></div>Then a synthesized context (=3D=3D passed as arg to =
the context-fn) is not the same as context created with context(Fn&&=
;,Args&&...).<br></div></div></div></blockquote></span><div><br>All=
contextes are the same. The point is that a context can be called=20
only once. If you invoke it in foo to go back to main, you can't invoke=
=20
it again. To prevent misuse operator() should clear the context. When=20
operator() returns, context will again point to a new context.<br></div></b=
lockquote><div><br></div><div>if a context can be called only once how do y=
ou implement generators for instance ( source/parent context not explicitly=
returned by context::operator()):<br><br></div><div>void fibonacci( contex=
t<int> sink, int n) {<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=
=C2=A0=C2=A0=C2=A0=C2=A0 int first =3D 1, second =3D 1;<br>=C2=A0=C2=A0=C2=
=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 sink( first);<br>=C2=A0=
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 sink( second);=
<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 for =
( int i =3D 0; i < n-2; ++i) {<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=A0=C2=A0 int third =3D first =
+ second;<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=A0=C2=A0 first =3D second;<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=A0=C2=A0 secon=
d =3D third;<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=A0=C2=A0 sink( third);<br>=C2=A0=C2=A0=C2=A0=C2=A0=
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 }<br>}<br><br></div><div>context=
<int> source( fibinacci, 10);<br></div><div>for ( int i : source) {<b=
r></div><div>=C2=A0=C2=A0 std::cout << i << std::endl;<br>}<br>=
<br></div><div>if=C2=A0 a context can only be called once the fibonacci exa=
mple would not work. I assume that you mean that each invocation<br></div><=
div>of source() (context switch) updates the fcontext_t in sink is updated.=
<br></div><div>because sink can be moved down the callstack (to sub-routine=
s) you need a pointer to fcontext_t to update the structure or<br></div><di=
v>you pass fcontext_t through jump_fcontext and update the structure before=
you return from context::operator() of instance sink.<br></div><div>that&#=
39;s how boost.coroutine(2) works.<br></div></div><br></div><div class=3D"g=
mail_extra"><snip><br><br></div><div class=3D"gmail_extra">but how sh=
ould a absolute minimalistic API for stackful context switching look like?<=
br></div><div class=3D"gmail_extra">execution_context uses a pointer that i=
s updated at each context switch, e.g.<br></div><div class=3D"gmail_extra">=
execution_context::operator() is implemented like:<br><br></div><div class=
=3D"gmail_extra">void operator()( void * vp) {<br></div><div class=3D"gmail=
_extra">=C2=A0 ptr from( this);<br></div><div class=3D"gmail_extra">=C2=A0 =
current.swap( from); // *this becomes current execution-context<br>=C2=A0 i=
ntptr_t ret =3D jump_fcontext( & from, this, vp); // resume *this<br>=
=C2=A0 return reinterpret_cast< void * >( ret); // return parameter t=
ransferred from *this<br>}<br><br></div><div class=3D"gmail_extra">in contr=
ast to context<> execution_context doesn't know its predecessor o=
r successor.<br></div><div class=3D"gmail_extra">you criticize that current=
is a static pointer (that must be thread-local because we operate in a mul=
ti-threaded env).<br></div><div class=3D"gmail_extra">please note that this=
is a library implementation, it might be possible that a compiler can impl=
ement execution_context in a<br></div><div class=3D"gmail_extra">more effic=
ient way.<br></div><div class=3D"gmail_extra">at least the main aim should =
be to design a really minimalistic API useable to build higher level abstra=
ctions.<br></div><div class=3D"gmail_extra"><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 />
--089e015383e88876050522bff496--
.
Author: Giovanni Piero Deretta <gpderetta@gmail.com>
Date: Fri, 23 Oct 2015 00:48:47 -0700 (PDT)
Raw View
------=_Part_25_373607433.1445586527624
Content-Type: multipart/alternative;
boundary="----=_Part_26_215664092.1445586527625"
------=_Part_26_215664092.1445586527625
Content-Type: text/plain; charset=UTF-8
On Friday, October 23, 2015 at 7:45:22 AM UTC+1, Oliver Kowalke wrote:
>
> Then a synthesized context (== passed as arg to the context-fn) is not the
>>> same as context created with context(Fn&&,Args&&...).
>>>
>>
>> All contextes are the same. The point is that a context can be called
>> only once. If you invoke it in foo to go back to main, you can't invoke it
>> again. To prevent misuse operator() should clear the context. When
>> operator() returns, context will again point to a new context.
>>
>
> if a context can be called only once how do you implement generators for
> instance ( source/parent context not explicitly returned by
> context::operator()):
>
> [...]
> if a context can only be called once the fibonacci example would not
> work. I assume that you mean that each invocation
> of source() (context switch) updates the fcontext_t in sink is updated.
>
exactly. Something like this:
template<class R, class T>
struct context {
fcontext_t * to;
// add typing to
R * operator()(T * p) {
struct payload { void * p; context_t current; } payload = {p};
auto other = (payload*)jump_fcontext(&payload.current, to,
&payload);
to = &other->current;
return (R*)other->p;
}
}
I slightly better implementation wouldn't need a level of indirection via
the stack to access p and current as they would be both passed in
registers. Something like this would work:
struct fcontext_t; // opaque type
std::pair<fcontext_t*, void *> jump_fcontext(fcontext_t * to, void* parm);
Note: no 'from' parameter: fcontext simply pushes any context state to the
top of the stack; fcontext_t is just a pointer to the stack. Many ABIs
allow passing the std::pair result in two registers instead of the stack.
> because sink can be moved down the callstack (to sub-routines) you need a
> pointer to fcontext_t to update the structure or
> you pass fcontext_t through jump_fcontext and update the structure before
> you return from context::operator() of instance sink.
> that's how boost.coroutine(2) works.
>
> <snip>
>
> but how should a absolute minimalistic API for stackful context switching
> look like?
> execution_context uses a pointer that is updated at each context switch,
> e.g.
> execution_context::operator() is implemented like:
>
> void operator()( void * vp) {
> ptr from( this);
> current.swap( from); // *this becomes current execution-context
> intptr_t ret = jump_fcontext( & from, this, vp); // resume *this
> return reinterpret_cast< void * >( ret); // return parameter transferred
> from *this
> }
>
> in contrast to context<> execution_context doesn't know its predecessor or
> successor.
>
as you can see the two implementations are almost identical, except that
the 'current' context is stack allocated and is passed explicitly to the
'other side' alongside vp, while execution_context uses the thread_local as
a side channel.
> you criticize that current is a static pointer (that must be thread-local
> because we operate in a multi-threaded env).
> please note that this is a library implementation, it might be possible
> that a compiler can implement execution_context in a
> more efficient way.
>
as long as the thread_local is not part of the api, it is just an
implementation detail. The problem is that the proposal makes is available
so its semantics must be preserved, which means that the just saved context
excapes to a potentially untrackable location from the compiler.
> at least the main aim should be to design a really minimalistic API
> useable to build higher level abstractions.
>
>
The most minimalistic API of all is fcontext itself (which is basically an
improvement over POSIX {make,swap}_context), but, although powerful, IMHO
is hard and unpleasant to use; I believe that the standard should
standardize a slightly higher level typed api, like context or
execution_context; In a sense context is sligly more minimal as it doesn't
require the global.
The 'callcc' or 'transform' I discussed elsethread can be implemented on
top of fcontext, but I still believe that making them part of the core api
allows for a slightly improved implementation. Note that 'transform' is a
generalization of make_context, so you only need one of the two.
--
---
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_26_215664092.1445586527625
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
On Friday, October 23, 2015 at 7:45:22 AM UTC+1, Oliver Kowalke wrote:<bloc=
kquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-l=
eft: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr"><div><div class=3D=
"gmail_quote"><blockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px=
0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><span><bloc=
kquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;border-left:=
1px solid rgb(204,204,204);padding-left:1ex"><div dir=3D"ltr"><div><div cla=
ss=3D"gmail_quote"><div></div>Then a synthesized context (=3D=3D passed as =
arg to the context-fn) is not the same as context created with context(Fn&a=
mp;&,Args&&...).<br></div></div></div></blockquote></span><div>=
<br>All contextes are the same. The point is that a context can be called=
=20
only once. If you invoke it in foo to go back to main, you can't invoke=
=20
it again. To prevent misuse operator() should clear the context. When=20
operator() returns, context will again point to a new context.<br></div></b=
lockquote><div><br></div><div>if a context can be called only once how do y=
ou implement generators for instance ( source/parent context not explicitly=
returned by context::operator()):<br><br></div>[...]<br><div>if=C2=A0 a co=
ntext can only be called once the fibonacci example would not work. I assum=
e that you mean that each invocation<br></div><div>of source() (context swi=
tch) updates the fcontext_t in sink is updated.<br></div></div></div></div>=
</blockquote><div><br>exactly. Something like this:<br><br>template<clas=
s R, class T><br>struct context {<br>=C2=A0=C2=A0=C2=A0 fcontext_t * to;=
<br><br>=C2=A0=C2=A0=C2=A0 // add typing to <br>=C2=A0=C2=A0=C2=A0 R * oper=
ator()(T * p) {<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=
=C2=A0 struct payload { void * p; context_t current;=C2=A0 } payload =3D {p=
};<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 auto oth=
er =3D (payload*)jump_fcontext(&payload.current, to, &payload);<br>=
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 to =3D &ot=
her->current;<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=
=C2=A0 return (R*)other->p;<br>=C2=A0=C2=A0=C2=A0 }<br>}<br><br>I slight=
ly better implementation wouldn't need a level of indirection via the s=
tack to access p and current as they would be both passed in registers. Som=
ething like this would work:<br><br>struct fcontext_t; // opaque type<br><b=
r>std::pair<fcontext_t*, void *> jump_fcontext(fcontext_t * to, void*=
parm);<br><br>Note: no 'from' parameter: fcontext simply pushes an=
y context state to the top of the stack; fcontext_t is just a pointer to th=
e stack. Many ABIs allow passing the std::pair result in=C2=A0 two register=
s instead of the stack.<br>=C2=A0</div><blockquote class=3D"gmail_quote" st=
yle=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-lef=
t: 1ex;"><div dir=3D"ltr"><div><div class=3D"gmail_quote"><div></div><div>b=
ecause sink can be moved down the callstack (to sub-routines) you need a po=
inter to fcontext_t to update the structure or<br></div><div>you pass fcont=
ext_t through jump_fcontext and update the structure before you return from=
context::operator() of instance sink.<br></div><div>that's how boost.c=
oroutine(2) works.<br></div></div><br></div><div><snip><br><br></div>=
<div>but how should a absolute minimalistic API for stackful context switch=
ing look like?<br></div><div>execution_context uses a pointer that is updat=
ed at each context switch, e.g.<br></div><div>execution_context::operator()=
is implemented like:<br><br></div><div>void operator()( void * vp) {<br></=
div><div>=C2=A0 ptr from( this);<br></div><div>=C2=A0 current.swap( from); =
// *this becomes current execution-context<br>=C2=A0 intptr_t ret =3D jump_=
fcontext( & from, this, vp); // resume *this<br>=C2=A0 return reinterpr=
et_cast< void * >( ret); // return parameter transferred from *this<b=
r>}<br><br></div><div>in contrast to context<> execution_context does=
n't know its predecessor or successor.<br></div></div></blockquote><div=
><br>as you can see the two implementations are almost identical, except th=
at the 'current' context is stack allocated and is passed explicitl=
y to the 'other side' alongside vp, while execution_context uses th=
e thread_local as a side channel.<br>=C2=A0</div><blockquote class=3D"gmail=
_quote" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;p=
adding-left: 1ex;"><div dir=3D"ltr"><div></div><div>you criticize that curr=
ent is a static pointer (that must be thread-local because we operate in a =
multi-threaded env).<br></div><div>please note that this is a library imple=
mentation, it might be possible that a compiler can implement execution_con=
text in a<br></div><div>more efficient way.<br></div></div></blockquote><di=
v><br>as long as the thread_local is not part of the api, it is just an imp=
lementation detail. The problem is that the proposal makes is available so =
its semantics must be preserved, which means that the just saved context ex=
capes to a potentially untrackable location from the compiler. <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;"><div dir=3D"ltr"><div></di=
v><div>at least the main aim should be to design a really minimalistic API =
useable to build higher level abstractions.<br></div><div><br></div></div><=
/blockquote><div><br>The most minimalistic API of all is fcontext itself (w=
hich is basically an improvement over POSIX {make,swap}_context), but, alth=
ough powerful, IMHO is hard and unpleasant to use; I believe that the stand=
ard should standardize a slightly higher level typed api, like context or e=
xecution_context; In a sense context is sligly more minimal as it doesn'=
;t require the global.<br><br>The 'callcc' or 'transform' I=
discussed elsethread can be implemented on top of fcontext, but I still be=
lieve that making them part of the core api allows for a slightly improved =
implementation. Note that 'transform' is a generalization of make_c=
ontext, so you only need one of the two.<br>=C2=A0</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_26_215664092.1445586527625--
------=_Part_25_373607433.1445586527624--
.
Author: Giovanni Piero Deretta <gpderetta@gmail.com>
Date: Fri, 23 Oct 2015 01:13:20 -0700 (PDT)
Raw View
------=_Part_128_1480644531.1445588000157
Content-Type: multipart/alternative;
boundary="----=_Part_129_649702840.1445588000157"
------=_Part_129_649702840.1445588000157
Content-Type: text/plain; charset=UTF-8
On Friday, October 23, 2015 at 8:48:48 AM UTC+1, Giovanni Piero Deretta
wrote:
>
> On Friday, October 23, 2015 at 7:45:22 AM UTC+1, Oliver Kowalke wrote:
>>
>> Then a synthesized context (== passed as arg to the context-fn) is not
>>>> the same as context created with context(Fn&&,Args&&...).
>>>>
>>>
>>> All contextes are the same. The point is that a context can be called
>>> only once. If you invoke it in foo to go back to main, you can't invoke it
>>> again. To prevent misuse operator() should clear the context. When
>>> operator() returns, context will again point to a new context.
>>>
>>
>> if a context can be called only once how do you implement generators for
>> instance ( source/parent context not explicitly returned by
>> context::operator()):
>>
>> [...]
>> if a context can only be called once the fibonacci example would not
>> work. I assume that you mean that each invocation
>> of source() (context switch) updates the fcontext_t in sink is updated.
>>
>
> exactly. Something like this:
>
> template<class R, class T>
> struct context {
> fcontext_t * to;
>
> // add typing to
> R * operator()(T * p) {
> struct payload { void * p; context_t current; } payload = {p};
> auto other = (payload*)jump_fcontext(&payload.current, to,
> &payload);
> to = &other->current;
> return (R*)other->p;
> }
> }
>
>
Actually, to match the semantics I proposed earlier:
R * operator()(T * p) {
struct payload { void * p; context_t current; } payload = {p};
auto other = (payload*)jump_fcontext(&
payload.current,
std::exchange(to, 0),
&payload);
to = &other->current;
return (R*)other->p;
}
note the std::exchange that temporarily nulls 'to' while this context is
swapped out.
--
---
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_129_649702840.1445588000157
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
On Friday, October 23, 2015 at 8:48:48 AM UTC+1, Giovanni Piero Deretta wro=
te:<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;=
border-left: 1px #ccc solid;padding-left: 1ex;">On Friday, October 23, 2015=
at 7:45:22 AM UTC+1, Oliver Kowalke wrote:<blockquote class=3D"gmail_quote=
" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-le=
ft:1ex"><div dir=3D"ltr"><div><div class=3D"gmail_quote"><blockquote class=
=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;border-left:1px solid rg=
b(204,204,204);padding-left:1ex"><span><blockquote class=3D"gmail_quote" st=
yle=3D"margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padd=
ing-left:1ex"><div dir=3D"ltr"><div><div class=3D"gmail_quote"><div></div>T=
hen a synthesized context (=3D=3D passed as arg to the context-fn) is not t=
he same as context created with context(Fn&&,Args&&...).<br=
></div></div></div></blockquote></span><div><br>All contextes are the same.=
The point is that a context can be called=20
only once. If you invoke it in foo to go back to main, you can't invoke=
=20
it again. To prevent misuse operator() should clear the context. When=20
operator() returns, context will again point to a new context.<br></div></b=
lockquote><div><br></div><div>if a context can be called only once how do y=
ou implement generators for instance ( source/parent context not explicitly=
returned by context::operator()):<br><br></div>[...]<br><div>if=C2=A0 a co=
ntext can only be called once the fibonacci example would not work. I assum=
e that you mean that each invocation<br></div><div>of source() (context swi=
tch) updates the fcontext_t in sink is updated.<br></div></div></div></div>=
</blockquote><div><br>exactly. Something like this:<br><br>template<clas=
s R, class T><br>struct context {<br>=C2=A0=C2=A0=C2=A0 fcontext_t * to;=
<br><br>=C2=A0=C2=A0=C2=A0 // add typing to <br>=C2=A0=C2=A0=C2=A0 R * oper=
ator()(T * p) {<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=
=C2=A0 struct payload { void * p; context_t current;=C2=A0 } payload =3D {p=
};<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 auto oth=
er =3D (payload*)jump_fcontext(&<wbr>payload.current, to, &payload)=
;<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 to =3D &a=
mp;other->current;<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=
=C2=A0=C2=A0 return (R*)other->p;<br>=C2=A0=C2=A0=C2=A0 }<br>}<br><br></=
div></blockquote><div><br>Actually, to match the semantics I proposed earli=
er:<br><br>=C2=A0=C2=A0=C2=A0=C2=A0 R * operator()(T * p) {<br>=C2=A0=C2=A0=
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 struct payload { void * p;=
context_t current;=C2=A0 } payload =3D {p};<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=
=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 auto other =3D (payload*)jump_fcontext(&a=
mp;<div>=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=C2=A0 <wbr>payload.current, <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=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 std::exchange(to, 0), <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=A0=
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 &payload);<br>=C2=A0=C2=A0=C2=A0=C2=A0=
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 to =3D &other->current;<br>=C2=
=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 return (R*)other-=
>p;<br>=C2=A0=C2=A0=C2=A0 }</div></div><br><br>note the std::exchange th=
at temporarily nulls 'to' while this context is swapped out.<br>
<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_129_649702840.1445588000157--
------=_Part_128_1480644531.1445588000157--
.
Author: Oliver Kowalke <oliver.kowalke@gmail.com>
Date: Fri, 23 Oct 2015 10:20:53 +0200
Raw View
--001a1140980e7125270522c14b40
Content-Type: text/plain; charset=UTF-8
>
> template<class R, class T>
> struct context {
> fcontext_t * to;
>
> // add typing to
> R * operator()(T * p) {
> struct payload { void * p; context_t current; } payload = {p};
> auto other = (payload*)jump_fcontext(&payload.current, to,
> &payload);
> to = &other->current;
> return (R*)other->p;
> }
> }
>
well, yes the same pattern is used in boost.coroutine - but I didn't
> I slightly better implementation wouldn't need a level of indirection via
> the stack to access p and current as they would be both passed in
> registers. Something like this would work:
>
> struct fcontext_t; // opaque type
> std::pair<fcontext_t*, void *> jump_fcontext(fcontext_t * to, void* parm);
> Note: no 'from' parameter: fcontext simply pushes any context state to the
> top of the stack; fcontext_t is just a pointer to the stack. Many ABIs
> allow passing the std::pair result in two registers instead of the stack.
>
jump_fcontext() implementation does actually push all registers at the end
of the stack and returns the last stack address - the difference that the
current impl updates the first parameter (== from).
void jump_fcontext( fcontext_t * from, fcontext_t to, intptr_t data);
maybe it's a good idea to change the return type of jump_fcontext() from
void to result_t { fcontext_t, void * } (or std::pair()) - of course it
would require modifications in the asm implementation.
> as long as the thread_local is not part of the api, it is just an
> implementation detail. The problem is that the proposal makes is available
> so its semantics must be preserved, which means that the just saved context
> excapes to a potentially untrackable location from the compiler.
>
can you elaborate it
>
>
>> at least the main aim should be to design a really minimalistic API
>> useable to build higher level abstractions.
>>
>
> The most minimalistic API of all is fcontext itself (which is basically an
> improvement over POSIX {make,swap}_context), but, although powerful, IMHO
> is hard and unpleasant to use; I believe that the standard should
> standardize a slightly higher level typed api, like context or
> execution_context; In a sense context is sligly more minimal as it doesn't
> require the global.
>
it doesn't matter if it is unpleasant to use - as Gor already mentioned,
the low-level API should be effective as possible even if it is hard to use.
higher-level abstractions can introduce more comfortable APIs.
--
---
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/.
--001a1140980e7125270522c14b40
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"><blo=
ckquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;border-left=
:1px solid rgb(204,204,204);padding-left:1ex"><span class=3D""></span><div>=
template<class R, class T><br>struct context {<br>=C2=A0=C2=A0=C2=A0 =
fcontext_t * to;<br><br>=C2=A0=C2=A0=C2=A0 // add typing to <br>=C2=A0=C2=
=A0=C2=A0 R * operator()(T * p) {<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=
=C2=A0=C2=A0=C2=A0=C2=A0 struct payload { void * p; context_t current;=C2=
=A0 } payload =3D {p};<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=
=C2=A0=C2=A0 auto other =3D (payload*)jump_fcontext(&payload.current, t=
o, &payload);<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=
=C2=A0 to =3D &other->current;<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=
=A0=C2=A0=C2=A0=C2=A0=C2=A0 return (R*)other->p;<br>=C2=A0=C2=A0=C2=A0 }=
<br>}<br></div></blockquote><div><br></div><div>well, yes the same pattern =
is used in boost.coroutine - but I didn't <br></div><div>=C2=A0</div><b=
lockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;border-le=
ft:1px solid rgb(204,204,204);padding-left:1ex"><div>I slightly better impl=
ementation wouldn't need a level of indirection via the stack to access=
p and current as they would be both passed in registers. Something like th=
is would work:<br><br>struct fcontext_t; // opaque type<br>std::pair<fco=
ntext_t*, void *> jump_fcontext(fcontext_t * to, void* parm);<br>Note: n=
o 'from' parameter: fcontext simply pushes any context state to the=
top of the stack; fcontext_t is just a pointer to the stack. Many ABIs all=
ow passing the std::pair result in=C2=A0 two registers instead of the stack=
..<br></div></blockquote><div><br></div><div>jump_fcontext() implementation =
does actually push all registers at the end of the stack and returns the la=
st stack address - the difference that the current impl updates the first p=
arameter (=3D=3D from).<br></div><div>void jump_fcontext( fcontext_t * from=
, fcontext_t to, intptr_t data);<br><br></div><div>maybe it's a good id=
ea to change the return type of jump_fcontext() from void to result_t { fco=
ntext_t, void * } (or std::pair()) - of course it would require modificatio=
ns in the asm implementation.<br></div><div>=C2=A0</div><blockquote class=
=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;border-left:1px solid rg=
b(204,204,204);padding-left:1ex"><span class=3D""></span><div>as long as th=
e thread_local is not part of the api, it is just an implementation detail.=
The problem is that the proposal makes is available so its semantics must =
be preserved, which means that the just saved context excapes to a potentia=
lly untrackable location from the compiler. <br></div></blockquote><div><br=
></div><div>can you elaborate it<br></div><div>=C2=A0</div><blockquote clas=
s=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;border-left:1px solid r=
gb(204,204,204);padding-left:1ex"><div>=C2=A0</div><span class=3D""><blockq=
uote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;border-left:1p=
x solid rgb(204,204,204);padding-left:1ex"><div dir=3D"ltr"><div></div><div=
>at least the main aim should be to design a really minimalistic API useabl=
e to build higher level abstractions.<br></div><div></div></div></blockquot=
e></span><div><br>The most minimalistic API of all is fcontext itself (whic=
h is basically an improvement over POSIX {make,swap}_context), but, althoug=
h powerful, IMHO is hard and unpleasant to use; I believe that the standard=
should standardize a slightly higher level typed api, like context or exec=
ution_context; In a sense context is sligly more minimal as it doesn't =
require the global.<br></div></blockquote></div><br></div><div class=3D"gma=
il_extra">it doesn't matter if it is unpleasant to use - as Gor already=
mentioned, the low-level API should be effective as possible even if it is=
hard to use.<br></div><div class=3D"gmail_extra">higher-level abstractions=
can introduce more comfortable APIs.<br><br></div></div>
<p></p>
-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />
--001a1140980e7125270522c14b40--
.
Author: Oliver Kowalke <oliver.kowalke@gmail.com>
Date: Fri, 23 Oct 2015 10:42:53 +0200
Raw View
--001a113de0e61953150522c19ad2
Content-Type: text/plain; charset=UTF-8
>
> The most minimalistic API of all is fcontext itself (which is basically an
> improvement over POSIX {make,swap}_context), but, although powerful
>
fcontext itself is a vehicle - it doesn't deal with stack
allocation/deallocation
--
---
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/.
--001a113de0e61953150522c19ad2
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"><blo=
ckquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1px #c=
cc solid;padding-left:1ex"><span class=3D""></span><div>The most minimalist=
ic API of all is fcontext itself (which is basically an improvement over PO=
SIX {make,swap}_context), but, although powerful<br></div></blockquote><div=
><br><br></div><div>fcontext itself is a vehicle - it doesn't deal with=
stack allocation/deallocation<br>=C2=A0<br></div></div></div></div>
<p></p>
-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />
--001a113de0e61953150522c19ad2--
.
Author: Oliver Kowalke <oliver.kowalke@gmail.com>
Date: Fri, 23 Oct 2015 10:57:02 +0200
Raw View
--047d7b2e489ab506cf0522c1cc25
Content-Type: text/plain; charset=UTF-8
>
> Actually, to match the semantics I proposed earlier:
>
> R * operator()(T * p) {
> struct payload { void * p; context_t current; } payload = {p};
> auto other = (payload*)jump_fcontext(&
> payload.current,
> std::exchange(to, 0),
> &payload);
> to = &other->current;
> return (R*)other->p;
> }
>
I'm feeling a little bit uncomfortable because context<> forces a special
signature of the context-fn, e.g.
void foo( context *, void *);
while exception_context doesn't
void foo();
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.
--047d7b2e489ab506cf0522c1cc25
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"><blo=
ckquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1px #c=
cc solid;padding-left:1ex"><span class=3D""></span><div>Actually, to match =
the semantics I proposed earlier:<span class=3D""><br><br>=C2=A0=C2=A0=C2=
=A0=C2=A0 R * operator()(T * p) {<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=
=C2=A0=C2=A0=C2=A0=C2=A0 struct payload { void * p; context_t current;=C2=
=A0 } payload =3D {p};<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=
=C2=A0=C2=A0 auto other =3D (payload*)jump_fcontext(&</span><div>=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=C2=A0 payload.current, <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=A0=C2=A0=C2=
=A0=C2=A0=C2=A0=C2=A0 std::exchange(to, 0), <br><span class=3D"">=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=C2=A0 &payload);<br>=C2=A0=C2=A0=C2=A0=C2=A0=
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 to =3D &other->current;<br>=C2=
=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 return (R*)other-=
>p;<br>=C2=A0=C2=A0=C2=A0 }</span></div></div></blockquote><div><br></di=
v><div>I'm feeling a little bit uncomfortable because context<> f=
orces a special signature of the context-fn, e.g.<br><br></div><div>void fo=
o( context *, void *);<br><br></div><div>while exception_context doesn'=
t<br><br></div><div>void foo();<br></div></div></div></div>
<p></p>
-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />
--047d7b2e489ab506cf0522c1cc25--
.
Author: Giovanni Piero Deretta <gpderetta@gmail.com>
Date: Fri, 23 Oct 2015 02:37:09 -0700 (PDT)
Raw View
------=_Part_25_248676893.1445593029347
Content-Type: multipart/alternative;
boundary="----=_Part_26_157917747.1445593029348"
------=_Part_26_157917747.1445593029348
Content-Type: text/plain; charset=UTF-8
On Friday, October 23, 2015 at 9:21:14 AM UTC+1, Oliver Kowalke wrote:
>
> template<class R, class T>
>> struct context {
>> fcontext_t * to;
>>
>>
> well, yes the same pattern is used in boost.coroutine - but I didn't
>
something is missing here?
>
>
>> I slightly better implementation wouldn't need a level of indirection via
>> the stack to access p and current as they would be both passed in
>> registers. Something like this would work:
>>
>> struct fcontext_t; // opaque type
>> std::pair<fcontext_t*, void *> jump_fcontext(fcontext_t * to, void* parm);
>> Note: no 'from' parameter: fcontext simply pushes any context state to
>> the top of the stack; fcontext_t is just a pointer to the stack. Many ABIs
>> allow passing the std::pair result in two registers instead of the stack.
>>
>
> jump_fcontext() implementation does actually push all registers at the end
> of the stack and returns the last stack address - the difference that the
> current impl updates the first parameter (== from).
> void jump_fcontext( fcontext_t * from, fcontext_t to, intptr_t data);
>
Ok, it is exactly the same then, fcontext_t already has pointer semantics
and 'from' is an input/output parameter. My only extra requirement is that
jump_fcontext should zero the 'from' context between switches so that a
swapped out context can be detected.
>
> maybe it's a good idea to change the return type of jump_fcontext() from
> void to result_t { fcontext_t, void * } (or std::pair()) - of course it
> would require modifications in the asm implementation.
>
I prefer input parameter plus result than input/output parameters, but it
is not a big deal.
>
>
>> as long as the thread_local is not part of the api, it is just an
>> implementation detail. The problem is that the proposal makes is available
>> so its semantics must be preserved, which means that the just saved context
>> excapes to a potentially untrackable location from the compiler.
>>
>
> can you elaborate it
>
void foo(context x)
{
x(1); x(2);
}
void bar()
{
context y(foo);
int i = y(); i = y();
}
I want the compiler to completely inline foo inside bar and remove any
allocation. It can do that if jump_fcontext is a builtin *and* it can
accurately track all uses of the fcontex_t; Writing its address to a global
variable can make the analysis more difficult. In fact to guarantee the
optimisation I would like to propose attributes that would prevent a
context address to be (transitively) passed to non attributed functions or
non-local variables; such a schema would not work well if assigning to a
global is always part of every use of context.
-- gpd
--
---
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_26_157917747.1445593029348
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">On Friday, October 23, 2015 at 9:21:14 AM UTC+1, Oliver Ko=
walke wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-lef=
t: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr"><=
div><div class=3D"gmail_quote"><blockquote class=3D"gmail_quote" style=3D"m=
argin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left=
:1ex"><span></span><div>template<class R, class T><br>struct context =
{<br>=C2=A0=C2=A0=C2=A0 fcontext_t * to;<br><br></div></blockquote><div><br=
></div><div>well, yes the same pattern is used in boost.coroutine - but I d=
idn't <br></div></div></div></div></blockquote><div><br>something is mi=
ssing here?<br>=C2=A0</div><blockquote class=3D"gmail_quote" style=3D"margi=
n: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><di=
v dir=3D"ltr"><div><div class=3D"gmail_quote"><div></div><div>=C2=A0</div><=
blockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;border-l=
eft:1px solid rgb(204,204,204);padding-left:1ex"><div>I slightly better imp=
lementation wouldn't need a level of indirection via the stack to acces=
s p and current as they would be both passed in registers. Something like t=
his would work:<br><br>struct fcontext_t; // opaque type<br>std::pair<fc=
ontext_t*, void *> jump_fcontext(fcontext_t * to, void* parm);<br>Note: =
no 'from' parameter: fcontext simply pushes any context state to th=
e top of the stack; fcontext_t is just a pointer to the stack. Many ABIs al=
low passing the std::pair result in=C2=A0 two registers instead of the stac=
k.<br></div></blockquote><div><br></div><div>jump_fcontext() implementation=
does actually push all registers at the end of the stack and returns the l=
ast stack address - the difference that the current impl updates the first =
parameter (=3D=3D from).<br></div><div>void jump_fcontext( fcontext_t * fro=
m, fcontext_t to, intptr_t data);<br></div></div></div></div></blockquote><=
div><br>Ok, it is exactly the same then,=C2=A0 fcontext_t already has point=
er semantics and 'from' is an input/output parameter. My only extra=
requirement is that jump_fcontext should zero the 'from' context b=
etween switches so that a swapped out context can be detected.<br>=C2=A0</d=
iv><blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;=
border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr"><div><div =
class=3D"gmail_quote"><div><br></div><div>maybe it's a good idea to cha=
nge the return type of jump_fcontext() from void to result_t { fcontext_t, =
void * } (or std::pair()) - of course it would require modifications in the=
asm implementation.<br></div></div></div></div></blockquote><div><br>I pre=
fer input parameter plus result than input/output parameters, but it is not=
a big deal.<br>=C2=A0</div><blockquote class=3D"gmail_quote" style=3D"marg=
in: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><d=
iv dir=3D"ltr"><div><div class=3D"gmail_quote"><div></div><div>=C2=A0</div>=
<blockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;border-=
left:1px solid rgb(204,204,204);padding-left:1ex"><span></span><div>as long=
as the thread_local is not part of the api, it is just an implementation d=
etail. The problem is that the proposal makes is available so its semantics=
must be preserved, which means that the just saved context excapes to a po=
tentially untrackable location from the compiler. <br></div></blockquote><d=
iv><br></div><div>can you elaborate it<br></div></div></div></div></blockqu=
ote><div><br>void foo(context x)<br>{<br>=C2=A0=C2=A0=C2=A0=C2=A0 x(1); x(2=
);<br>}<br><br>void bar()<br>{=C2=A0 <br>context y(foo);<br>int i =3D y(); =
i =3D y();<br>}<br>=C2=A0<br>I want the compiler to completely inline foo i=
nside bar and remove any allocation. It can do that if jump_fcontext is a b=
uiltin *and* it can accurately track all uses of the fcontex_t; Writing its=
address to a global variable can make the analysis more difficult. In fact=
to guarantee the optimisation I would like to propose attributes that woul=
d prevent a context address to be (transitively) passed to non attributed f=
unctions or non-local variables; such a schema would not work well if assig=
ning to a global is always part of every use of context.<br><br>-- gpd<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_26_157917747.1445593029348--
------=_Part_25_248676893.1445593029347--
.
Author: Giovanni Piero Deretta <gpderetta@gmail.com>
Date: Fri, 23 Oct 2015 10:47:00 +0100
Raw View
--001a11c310be3d49e80522c27ecb
Content-Type: text/plain; charset=UTF-8
On 23 Oct 2015 9:57 a.m., "Oliver Kowalke" <oliver.kowalke@gmail.com> wrote:
>>
>> Actually, to match the semantics I proposed earlier:
>>
>> R * operator()(T * p) {
>> struct payload { void * p; context_t current; } payload =
{p};
>> auto other = (payload*)jump_fcontext(&
>> payload.current,
>> std::exchange(to, 0),
>> &payload);
>> to = &other->current;
>> return (R*)other->p;
>> }
>
>
> I'm feeling a little bit uncomfortable because context<> forces a special
signature of the context-fn, e.g.
>
> void foo( context *, void *);
>
> while exception_context doesn't
>
> void foo();
>
Why is that desirable? From the point o view of foo, its parameter is just
like a callback (or an Iterator).
-- gpd
--
---
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/.
--001a11c310be3d49e80522c27ecb
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<p dir=3D"ltr"><br>
On 23 Oct 2015 9:57 a.m., "Oliver Kowalke" <<a href=3D"mailto:=
oliver.kowalke@gmail.com">oliver.kowalke@gmail.com</a>> wrote:<br>
>><br>
>> Actually, to match the semantics I proposed earlier:<br>
>><br>
>> =C2=A0=C2=A0=C2=A0=C2=A0 R * operator()(T * p) {<br>
>> =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 struc=
t payload { void * p; context_t current;=C2=A0 } payload =3D {p};<br>
>> =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 auto =
other =3D (payload*)jump_fcontext(&<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=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 payload.current, <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=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 std::exchange(to, 0), <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=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 &payload);<br>
>> =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 to =
=3D &other->current;<br>
>> =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 retur=
n (R*)other->p;<br>
>> =C2=A0=C2=A0=C2=A0 }<br>
><br>
><br>
> I'm feeling a little bit uncomfortable because context<> for=
ces a special signature of the context-fn, e.g.<br>
><br>
> void foo( context *, void *);<br>
><br>
> while exception_context doesn't<br>
><br>
> void foo();<br>
></p>
<p dir=3D"ltr">Why is that desirable? From the point o view of foo, its par=
ameter is just like a callback (or an Iterator).</p>
<p dir=3D"ltr">-- gpd</p>
<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 />
--001a11c310be3d49e80522c27ecb--
.
Author: Oliver Kowalke <oliver.kowalke@gmail.com>
Date: Tue, 27 Oct 2015 07:47:41 +0100
Raw View
--001a1140978c7c8482052310755a
Content-Type: text/plain; charset=UTF-8
2015-10-22 14:47 GMT+02:00 Giovanni Piero Deretta <gpderetta@gmail.com>:
> template<class T, class R>
> class context;
>
> template<class T, class R>
> context::context() ; // create any empty context
>
> template<class T, class R>
> context::context( Fn && fn, Args && ... args); // requires
> IsSame<result_of<Fn(context<R,T>, args..), context>;
>
> template<class T, class R>
> R context::operator()(T); // invokes context and implicitly pass to it
> this context. On return 'this' contains the context we are coming from.
> Returning it explicitly is an alternative.
>
I believe that this API might only work for asymmetric context switching:
void bar( context synthctx2) {
synthctx();
}
void foo( context synthctx1) {
context ctx2( bar);
ctx2();
}
context ctx1( foo);
ctx1();
context 'ctx1' and 'ctx2' own a side-stack
'synthctx1' and 'synthctx2' are synthesized context' (ctor of 'ctx1' and
'ctx2') passed as argument to 'foo() / 'bar()'
'synthctx1' is used to switch back to 'foo' (re-enter context ctx1), but it
does not own (or has a connection to) the side stack
managed by 'ctx1'!
in the ctor of 'ctx2' we have not access to the control structure managing
the side-stack of 'ctx1'
'synthctx1' is not equivalent to 'ctx1' but of the same type - that foolish
the user
another variation of the API; the current active context is passed as an
argument (no static pointer) to the context-fn:
context( Fn && fn, Args && ... args); // Fn signature '(context, void *)'
static context main_context();
void * operator()( context from, void * data);
ctor creates and owns side-stack
'operator()' requires the context to be resumed (+ data transferred to it)
and we can shared the ownership
of side-stack with the synthesized context.
the API requires static member function 'main_context()' because in
'main()' (or in top-level std::thread-fn)
we don't have a context at hand from which we switch to our desired context.
in order to be equivalent to the semantics of the other context',
'main_context()' returns a context that refers to
the same type (maybe allocated using 'schwarz pointers' etc.)
void bar( context currctx2, void * vp) {
context mctx = ( context *) vp;
( * mctx)( currctx2);
}
void foo( context currctx1, void * vp) {
context ctx2( bar);
ctx2( currctx1, vp);
}
context mctx = context::main_context();
context ctx1( foo);
ctx1( mctx, & mctx);
--
---
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/.
--001a1140978c7c8482052310755a
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">2015=
-10-22 14:47 GMT+02:00 Giovanni Piero Deretta <span dir=3D"ltr"><<a href=
=3D"mailto:gpderetta@gmail.com" target=3D"_blank">gpderetta@gmail.com</a>&g=
t;</span>:<br><blockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px=
0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">template<=
;class T, class R><br><div>class context;<br><br>template<class T, cl=
ass R><br>context::context() ; // create any empty context<br><br>templa=
te<class T, class R><br>context::context( Fn && fn, Args &=
;& ... args); // requires IsSame<result_of<Fn(context<R,T>,=
args..), context>;<br><br>template<class T, class R><br>R context=
::operator()(T); // invokes context and implicitly pass to it this context.=
On return 'this' contains the context we are coming from. Returnin=
g it explicitly is an alternative.<br></div></blockquote><div><br></div><di=
v>I believe that this API might only work for asymmetric context switching:=
<br><br></div><div>void bar( context synthctx2) {<br></div><div>=C2=A0=C2=
=A0 synthctx();<br></div><div>}<br><br></div><div>void foo( context synthct=
x1) {<br></div><div>=C2=A0=C2=A0 context ctx2( bar);<br></div><div>=C2=A0=
=C2=A0 ctx2();<br>}<br><br></div><div>context ctx1( foo);<br></div><div>ctx=
1();<br></div><div><br></div></div>context 'ctx1' and 'ctx2'=
; own a side-stack<br></div><div class=3D"gmail_extra">'synthctx1' =
and 'synthctx2' are synthesized context' (ctor of 'ctx1'=
; and 'ctx2') passed as argument to 'foo() / 'bar()'<br=
></div><div class=3D"gmail_extra">'synthctx1' is used to switch bac=
k to 'foo' (re-enter context ctx1), but it does not own (or has a c=
onnection to) the side stack<br></div><div class=3D"gmail_extra">managed by=
'ctx1'!<br></div><div class=3D"gmail_extra">in the ctor of 'ct=
x2' we have not access to the control structure managing the side-stack=
of 'ctx1'<br>'synthctx1' is not equivalent to 'ctx1=
9; but of the same type - that foolish the user<br><br></div><div class=3D"=
gmail_extra">another variation of the API; the current active context is pa=
ssed as an argument (no static pointer) to the context-fn:<br><br>context( =
Fn && fn, Args && ... args); // Fn signature '(context,=
void *)'<br></div><div class=3D"gmail_extra">static context main_conte=
xt();<br></div><div class=3D"gmail_extra">void * operator()( context from, =
void * data);<br><br></div><div class=3D"gmail_extra">ctor creates and owns=
side-stack<br></div><div class=3D"gmail_extra">'operator()' requir=
es the context to be resumed (+ data transferred to it) and we can shared t=
he ownership<br></div><div class=3D"gmail_extra">of side-stack with the syn=
thesized context.<br><br></div><div class=3D"gmail_extra">the API requires =
static member function 'main_context()' because in 'main()'=
(or in top-level std::thread-fn)<br></div><div class=3D"gmail_extra">we do=
n't have a context at hand from which we switch to our desired context.=
<br></div><div class=3D"gmail_extra">in order to be equivalent to the seman=
tics of the other context', 'main_context()' returns a context =
that refers to<br></div><div class=3D"gmail_extra">the same type (maybe all=
ocated using 'schwarz pointers' etc.)<br><br><div>void bar( contex=
t currctx2, void * vp) {<br>=C2=A0=C2=A0 context mctx =3D ( context *) vp;<=
br></div><div>=C2=A0=C2=A0 ( * mctx)( currctx2);<br></div><div>}<br><br></d=
iv><div>void foo( context currctx1, void * vp) {<br></div><div>=C2=A0=C2=A0=
context ctx2( bar);<br></div><div>=C2=A0=C2=A0 ctx2( currctx1, vp);<br>}<b=
r><br></div><div><div>context mctx =3D context::main_context();<br></div>co=
ntext ctx1( foo);<br></div>ctx1( mctx, & mctx);<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 />
--001a1140978c7c8482052310755a--
.
Author: Giovanni Piero Deretta <gpderetta@gmail.com>
Date: Tue, 27 Oct 2015 01:24:45 -0700 (PDT)
Raw View
------=_Part_71_194596750.1445934286048
Content-Type: multipart/alternative;
boundary="----=_Part_72_1627382834.1445934286049"
------=_Part_72_1627382834.1445934286049
Content-Type: text/plain; charset=UTF-8
On Tuesday, October 27, 2015 at 6:48:02 AM UTC, Oliver Kowalke wrote:
>
> 2015-10-22 14:47 GMT+02:00 Giovanni Piero Deretta <gpde...@gmail.com
> <javascript:>>:
>
>> template<class T, class R>
>> class context;
>>
>> template<class T, class R>
>> context::context() ; // create any empty context
>>
>> template<class T, class R>
>> context::context( Fn && fn, Args && ... args); // requires
>> IsSame<result_of<Fn(context<R,T>, args..), context>;
>>
>> template<class T, class R>
>> R context::operator()(T); // invokes context and implicitly pass to it
>> this context. On return 'this' contains the context we are coming from.
>> Returning it explicitly is an alternative.
>>
>
> I believe that this API might only work for asymmetric context switching:
>
> void bar( context synthctx2) {
> synthctx();
> }
>
> void foo( context synthctx1) {
> context ctx2( bar);
> ctx2();
> }
>
> context ctx1( foo);
> ctx1();
>
> context 'ctx1' and 'ctx2' own a side-stack
> 'synthctx1' and 'synthctx2' are synthesized context' (ctor of 'ctx1' and
> 'ctx2') passed as argument to 'foo() / 'bar()'
> 'synthctx1' is used to switch back to 'foo' (re-enter context ctx1), but
> it does not own (or has a connection to) the side stack
> managed by 'ctx1'!
> in the ctor of 'ctx2' we have not access to the control structure managing
> the side-stack of 'ctx1'
> 'synthctx1' is not equivalent to 'ctx1' but of the same type - that
> foolish the user
>
>
why would ctx2 need to access the control structure of ctx1? Note that I
have implemented the api and works perfeclty fine for both async coroutines
(i.e. generators) and synchronous (tasks, fibers)
Anyway, in my model, the stack is not owned by a context. It is owned by
the bottommost function frame. I neglected to mention a point in the
previous discussions: when returning to the bottomost frame (directly or
via an exception), a context must be passed. Because the api is completely
symmetric and explicit, there are no implicit pointers anywhere, expclitily
returning a context is needed so that the bottom stack frame know to which
context to return to on termination. This is the full example:
context bar( context other2) {
other2();
return other2;
}
context foo( context other) {
context bar_ctx( other );
bar_ctx();
return bar_ctx;
}
context foo_ctx( foo);
ctx();
To handle exceptions, there is a need of a wrapper exception type that
carries a context plus a nested exception. When the bottomost frame is
reached, it switches to the context payload, delete the outgoing context
stack and rethrows the exception.
Also note that there is nothing synthetic about the 'other' contextes; they
are contextes exactly like the others.
>
--
---
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_72_1627382834.1445934286049
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<iframe style=3D"padding: 0px; position: absolute; top: 0px; left: 0px; wid=
th: 778px; height: 188px; visibility: hidden;" frameborder=3D"0"></iframe><=
br>On Tuesday, October 27, 2015 at 6:48:02 AM UTC, Oliver Kowalke wrote:<bl=
ockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border=
-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr"><div><div class=
=3D"gmail_quote">2015-10-22 14:47 GMT+02:00 Giovanni Piero Deretta <span di=
r=3D"ltr"><<a href=3D"javascript:" target=3D"_blank" gdf-obfuscated-mail=
to=3D"LcX1bCB9EgAJ" rel=3D"nofollow" onmousedown=3D"this.href=3D'javasc=
ript:';return true;" onclick=3D"this.href=3D'javascript:';retur=
n true;">gpde...@gmail.com</a>></span>:<br><blockquote class=3D"gmail_qu=
ote" style=3D"margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,20=
4);padding-left:1ex">template<class T, class R><br><div>class context=
;<br><br>template<class T, class R><br>context::context() ; // create=
any empty context<br><br>template<class T, class R><br>context::cont=
ext( Fn && fn, Args && ... args); // requires IsSame<res=
ult_of<Fn(context<R,<wbr>T>, args..), context>;<br><br>template=
<class T, class R><br>R context::operator()(T); // invokes context an=
d implicitly pass to it this context. On return 'this' contains the=
context we are coming from. Returning it explicitly is an alternative.<br>=
</div></blockquote><div><br></div><div>I believe that this API might only w=
ork for asymmetric context switching:<br><br></div><div>void bar( context s=
ynthctx2) {<br></div><div>=C2=A0=C2=A0 synthctx();<br></div><div>}<br><br><=
/div><div>void foo( context synthctx1) {<br></div><div>=C2=A0=C2=A0 context=
ctx2( bar);<br></div><div>=C2=A0=C2=A0 ctx2();<br>}<br><br></div><div>cont=
ext ctx1( foo);<br></div><div>ctx1();<br></div><div><br></div></div>context=
'ctx1' and 'ctx2' own a side-stack<br></div><div>'synt=
hctx1' and 'synthctx2' are synthesized context' (ctor of &#=
39;ctx1' and 'ctx2') passed as argument to 'foo() / 'ba=
r()'<br></div><div>'synthctx1' is used to switch back to 'f=
oo' (re-enter context ctx1), but it does not own (or has a connection t=
o) the side stack<br></div><div>managed by 'ctx1'!<br></div><div>in=
the ctor of 'ctx2' we have not access to the control structure man=
aging the side-stack of 'ctx1'<br>'synthctx1' is not equiva=
lent to 'ctx1' but of the same type - that foolish the user<br><br>=
</div></div></blockquote><div><br>why would ctx2 need to access the control=
structure of ctx1? Note that I have implemented the api and works perfeclt=
y fine for both async coroutines (i.e. generators) and synchronous (tasks, =
fibers)<br>=C2=A0<br>Anyway, in my model, the stack is not owned by a conte=
xt. It is owned by the=C2=A0 bottommost function frame. I neglected to ment=
ion a point in the previous discussions: when returning to the bottomost fr=
ame (directly or via an exception), a context must be passed. Because the a=
pi is completely symmetric and explicit, there are no implicit pointers any=
where, expclitily returning a context is needed so that the bottom stack fr=
ame know to which context to return to on termination.=C2=A0 This is the fu=
ll example:<br><br><div>context bar( context other2) {<br></div><div>=C2=A0=
=C2=A0 other2();<br><br>=C2=A0=C2=A0 return other2;<br></div><div>}<br><br>=
</div><div>context foo( context other) {<br></div><div>=C2=A0=C2=A0 context=
bar_ctx( other );<br></div><div>=C2=A0=C2=A0 bar_ctx();<br><br>=C2=A0 retu=
rn bar_ctx;<br>}<br><br></div><div>context foo_ctx( foo);<br></div>ctx();<b=
r><br>To handle exceptions, there is a need of a wrapper exception type tha=
t carries a context plus a nested exception. When the bottomost frame is re=
ached, it switches to the context payload, delete the outgoing context stac=
k and rethrows the exception.<br>Also note that there is nothing synthetic =
about the 'other' contextes; they are contextes exactly like the ot=
hers.<br></div><blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-=
left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">
</blockquote>
<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_72_1627382834.1445934286049--
------=_Part_71_194596750.1445934286048--
.
Author: Oliver Kowalke <oliver.kowalke@gmail.com>
Date: Tue, 27 Oct 2015 09:42:45 +0100
Raw View
--089e0112cf1002cf4205231211a2
Content-Type: text/plain; charset=UTF-8
2015-10-27 9:24 GMT+01:00 Giovanni Piero Deretta <gpderetta@gmail.com>:
why would ctx2 need to access the control structure of ctx1?
>
how is the stack released (or who is responsible)?
> context bar( context other2) {
> other2();
>
> return other2;
> }
>
> context foo( context other) {
> context bar_ctx( other );
> bar_ctx();
>
> return bar_ctx;
> }
>
> context foo_ctx( foo);
> ctx();
>
I assume you mean context 'bar_ctx( bar);' and 'foo()' should return
'other' instead of 'bar_ctx' - right?
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.
--089e0112cf1002cf4205231211a2
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">2015=
-10-27 9:24 GMT+01:00 Giovanni Piero Deretta <span dir=3D"ltr"><<a href=
=3D"mailto:gpderetta@gmail.com" target=3D"_blank">gpderetta@gmail.com</a>&g=
t;</span>:<br><br><blockquote class=3D"gmail_quote" style=3D"margin:0px 0px=
0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><span c=
lass=3D""></span><div>why would ctx2 need to access the control structure o=
f ctx1?<br></div></blockquote><div><br></div><div>how is the stack released=
(or who is responsible)?<br></div><div>=C2=A0</div><blockquote class=3D"gm=
ail_quote" style=3D"margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,=
204,204);padding-left:1ex"><div><div>context bar( context other2) {<br></di=
v><div>=C2=A0=C2=A0 other2();<br><br>=C2=A0=C2=A0 return other2;<br></div><=
div>}<br><br></div><div>context foo( context other) {<br></div><div>=C2=A0=
=C2=A0 context bar_ctx( other );<br></div><div>=C2=A0=C2=A0 bar_ctx();<br><=
br>=C2=A0 return bar_ctx;<br>}<br><br></div><div>context foo_ctx( foo);<br>=
</div>ctx();<br></div></blockquote></div><br></div><div class=3D"gmail_extr=
a">I assume you mean context 'bar_ctx( bar);' and 'foo()' s=
hould return 'other' instead of 'bar_ctx' - right?<br></div=
></div>
<p></p>
-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />
--089e0112cf1002cf4205231211a2--
.
Author: Oliver Kowalke <oliver.kowalke@gmail.com>
Date: Tue, 27 Oct 2015 10:27:40 +0100
Raw View
--047d7bd6b514a4a1e7052312b127
Content-Type: text/plain; charset=UTF-8
2015-10-27 9:42 GMT+01:00 Oliver Kowalke <oliver.kowalke@gmail.com>:
> 2015-10-27 9:24 GMT+01:00 Giovanni Piero Deretta <gpderetta@gmail.com>:
>
> why would ctx2 need to access the control structure of ctx1?
>>
>
> how is the stack released (or who is responsible)?
>
fcontext gets exit() as return-address on its stack, e.g. if the toplevel
context-fn returns
exit( 0) is called.
at the top of the stack a control structure is created that handles the
stack destruction
(allocator, used to create the stack, will be utilized to destruct the
stack).
the control structure is owned by execution_context and if he last
reference goes out of scope
the stack gets destructed.
maybe we can register a function (destruct_stack()) that causes the stack
destruction as return-address for the toplevel context-fn.
e.g. if the context-fn returns, destruct_stack() gets called == the stack
destructs itself
--
---
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/.
--047d7bd6b514a4a1e7052312b127
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">2015=
-10-27 9:42 GMT+01:00 Oliver Kowalke <span dir=3D"ltr"><<a href=3D"mailt=
o:oliver.kowalke@gmail.com" target=3D"_blank">oliver.kowalke@gmail.com</a>&=
gt;</span>:<br><blockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0p=
x 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir=
=3D"ltr"><div class=3D"gmail_extra"><div class=3D"gmail_quote"><span>2015-1=
0-27 9:24 GMT+01:00 Giovanni Piero Deretta <span dir=3D"ltr"><<a href=3D=
"mailto:gpderetta@gmail.com" target=3D"_blank">gpderetta@gmail.com</a>><=
/span>:<br><br><blockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0p=
x 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><span></sp=
an><div>why would ctx2 need to access the control structure of ctx1?<br></d=
iv></blockquote><div><br></div></span><div>how is the stack released (or wh=
o is responsible)?<br></div></div></div></div></blockquote><div><br></div><=
/div>fcontext gets exit() as return-address on its stack, e.g. if the tople=
vel context-fn returns<br></div><div class=3D"gmail_extra">exit( 0) is call=
ed.<br></div><div class=3D"gmail_extra">at the top of the stack a control s=
tructure is created that handles the stack destruction<br></div><div class=
=3D"gmail_extra">(allocator, used to create the stack, will be utilized to =
destruct the stack).<br></div><div class=3D"gmail_extra">the control struct=
ure is owned by execution_context and if he last reference goes out of scop=
e<br></div><div class=3D"gmail_extra">the stack gets destructed.<br><br></d=
iv><div class=3D"gmail_extra">maybe we can register a function (destruct_st=
ack()) that causes the stack destruction as return-address for the topleve=
l context-fn.<br></div><div class=3D"gmail_extra">e.g. if the context-fn re=
turns, destruct_stack() gets called =3D=3D the stack destructs itself<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 />
--047d7bd6b514a4a1e7052312b127--
.
Author: Giovanni Piero Deretta <gpderetta@gmail.com>
Date: Tue, 27 Oct 2015 02:31:18 -0700 (PDT)
Raw View
------=_Part_62_2034551263.1445938278595
Content-Type: multipart/alternative;
boundary="----=_Part_63_2103871117.1445938278595"
------=_Part_63_2103871117.1445938278595
Content-Type: text/plain; charset=UTF-8
On Tuesday, October 27, 2015 at 8:43:07 AM UTC, Oliver Kowalke wrote:
>
> 2015-10-27 9:24 GMT+01:00 Giovanni Piero Deretta <gpde...@gmail.com
> <javascript:>>:
>
> why would ctx2 need to access the control structure of ctx1?
>>
>
> how is the stack released (or who is responsible)?
>
The bottommost frame of each stack when the execution reaches it.
>
>
>> context bar( context other2) {
>> other2();
>>
>> return other2;
>> }
>>
>> context foo( context other) {
>> context bar_ctx( other );
>> bar_ctx();
>>
>> return bar_ctx;
>> }
>>
>> context foo_ctx( foo);
>> ctx();
>>
>
> I assume you mean context 'bar_ctx( bar);' and 'foo()' should return
> 'other' instead of 'bar_ctx' - right?
>
yes, although returning any non spent context would be perfectly fine. That
would be the context that is resumed on exit.
--
---
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_63_2103871117.1445938278595
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">On Tuesday, October 27, 2015 at 8:43:07 AM UTC, Oliver Kow=
alke 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 class=3D"gmail_quote">2015-10-27 9:24 GMT+01:00 Giovanni Piero Dere=
tta <span dir=3D"ltr"><<a href=3D"javascript:" target=3D"_blank" gdf-obf=
uscated-mailto=3D"ztn5gHQQBwAJ" rel=3D"nofollow" onmousedown=3D"this.href=
=3D'javascript:';return true;" onclick=3D"this.href=3D'javascri=
pt:';return true;">gpde...@gmail.com</a>></span>:<br><br><blockquote=
class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;border-left:1px so=
lid rgb(204,204,204);padding-left:1ex"><span></span><div>why would ctx2 nee=
d to access the control structure of ctx1?<br></div></blockquote><div><br><=
/div><div>how is the stack released (or who is responsible)?<br></div></div=
></div></div></blockquote><div><br>The bottommost frame of each stack when =
the execution reaches it.<br>=C2=A0</div><blockquote class=3D"gmail_quote" =
style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-l=
eft: 1ex;"><div dir=3D"ltr"><div><div class=3D"gmail_quote"><div></div><div=
>=C2=A0</div><blockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px =
0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div><div>co=
ntext bar( context other2) {<br></div><div>=C2=A0=C2=A0 other2();<br><br>=
=C2=A0=C2=A0 return other2;<br></div><div>}<br><br></div><div>context foo( =
context other) {<br></div><div>=C2=A0=C2=A0 context bar_ctx( other );<br></=
div><div>=C2=A0=C2=A0 bar_ctx();<br><br>=C2=A0 return bar_ctx;<br>}<br><br>=
</div><div>context foo_ctx( foo);<br></div>ctx();<br></div></blockquote></d=
iv><br></div><div>I assume you mean context 'bar_ctx( bar);' and &#=
39;foo()' should return 'other' instead of 'bar_ctx' - =
right?<br></div></div></blockquote><div><br>yes, although returning any non=
spent context would be perfectly fine. That would be the context that is r=
esumed on exit.<br>=C2=A0</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_63_2103871117.1445938278595--
------=_Part_62_2034551263.1445938278595--
.
Author: Giovanni Piero Deretta <gpderetta@gmail.com>
Date: Tue, 27 Oct 2015 02:39:10 -0700 (PDT)
Raw View
------=_Part_6459_1429394112.1445938750178
Content-Type: multipart/alternative;
boundary="----=_Part_6460_1720180256.1445938750178"
------=_Part_6460_1720180256.1445938750178
Content-Type: text/plain; charset=UTF-8
On Tuesday, October 27, 2015 at 9:28:02 AM UTC, Oliver Kowalke wrote:
>
> 2015-10-27 9:42 GMT+01:00 Oliver Kowalke <oliver....@gmail.com
> <javascript:>>:
>
>> 2015-10-27 9:24 GMT+01:00 Giovanni Piero Deretta <gpde...@gmail.com
>> <javascript:>>:
>>
>> why would ctx2 need to access the control structure of ctx1?
>>>
>>
>> how is the stack released (or who is responsible)?
>>
>
> fcontext gets exit() as return-address on its stack, e.g. if the toplevel
> context-fn returns
> exit( 0) is called.
> at the top of the stack a control structure is created that handles the
> stack destruction
> (allocator, used to create the stack, will be utilized to destruct the
> stack).
> the control structure is owned by execution_context and if he last
> reference goes out of scope
> the stack gets destructed.
>
> it seems that we use different stack directions :). To me it make sense to
call the bottom of the stack the oldest function in a coroutine.
subroutines frames are pushed 'on top'.
Yes, the stack bottom would have in its frame a copy of the allocator used
to deallocate the stack (what you call the control structure). This
function is a local object and like all local objects should be 'owned' by
the function scope (i.e. the frame) where it resides. It is not reference
counted.
> maybe we can register a function (destruct_stack()) that causes the stack
> destruction as return-address for the toplevel context-fn.
> e.g. if the context-fn returns, destruct_stack() gets called == the stack
> destructs itself
>
then what? you still need a context to resume.
--
---
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_6460_1720180256.1445938750178
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
On Tuesday, October 27, 2015 at 9:28:02 AM UTC, Oliver Kowalke wrote:<block=
quote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-le=
ft: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr"><div><div class=3D"=
gmail_quote">2015-10-27 9:42 GMT+01:00 Oliver Kowalke <span dir=3D"ltr"><=
;<a href=3D"javascript:" target=3D"_blank" gdf-obfuscated-mailto=3D"8tXW0ec=
SBwAJ" rel=3D"nofollow" onmousedown=3D"this.href=3D'javascript:';re=
turn true;" onclick=3D"this.href=3D'javascript:';return true;">oliv=
er....@gmail.com</a>></span>:<br><blockquote class=3D"gmail_quote" style=
=3D"margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding=
-left:1ex"><div dir=3D"ltr"><div><div class=3D"gmail_quote"><span>2015-10-2=
7 9:24 GMT+01:00 Giovanni Piero Deretta <span dir=3D"ltr"><<a href=3D"ja=
vascript:" target=3D"_blank" gdf-obfuscated-mailto=3D"8tXW0ecSBwAJ" rel=3D"=
nofollow" onmousedown=3D"this.href=3D'javascript:';return true;" on=
click=3D"this.href=3D'javascript:';return true;">gpde...@gmail.com<=
/a>></span>:<br><br><blockquote class=3D"gmail_quote" style=3D"margin:0p=
x 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><s=
pan></span><div>why would ctx2 need to access the control structure of ctx1=
?<br></div></blockquote><div><br></div></span><div>how is the stack release=
d (or who is responsible)?<br></div></div></div></div></blockquote><div><br=
></div></div>fcontext gets exit() as return-address on its stack, e.g. if t=
he toplevel context-fn returns<br></div><div>exit( 0) is called.<br></div><=
div>at the top of the stack a control structure is created that handles the=
stack destruction<br></div><div>(allocator, used to create the stack, will=
be utilized to destruct the stack).<br></div><div>the control structure is=
owned by execution_context and if he last reference goes out of scope<br><=
/div><div>the stack gets destructed.<br><br></div></div></blockquote><div>i=
t seems that we use different stack directions :). To me it make sense to c=
all the bottom of the stack the oldest function in a coroutine. subroutines=
frames are pushed 'on top'.<br><br>Yes, the stack bottom would hav=
e in its frame a copy of the allocator used to deallocate the stack (what y=
ou call the control structure).=C2=A0 This function is a local object and l=
ike all local objects should be 'owned' by the function scope (i.e.=
the frame) where it resides. It is not reference counted. <br>=C2=A0</div>=
<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;bor=
der-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr"><div></div><d=
iv>maybe we can register a function (destruct_stack()) that causes the stac=
k destruction as return-address for the toplevel context-fn.<br></div><div=
>e.g. if the context-fn returns, destruct_stack() gets called =3D=3D the st=
ack destructs itself<br></div></div></blockquote><div><br>then what? you st=
ill need a context to resume.<br></div>
<p></p>
-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />
------=_Part_6460_1720180256.1445938750178--
------=_Part_6459_1429394112.1445938750178--
.
Author: Oliver Kowalke <oliver.kowalke@gmail.com>
Date: Tue, 27 Oct 2015 12:09:15 +0100
Raw View
--001a113adb28f25c740523141c20
Content-Type: text/plain; charset=UTF-8
2015-10-27 10:39 GMT+01:00 Giovanni Piero Deretta <gpderetta@gmail.com>:
>
>>
>> maybe we can register a function (destruct_stack()) that causes the stack
>> destruction as return-address for the toplevel context-fn.
>> e.g. if the context-fn returns, destruct_stack() gets called == the stack
>> destructs itself
>>
>
> then what? you still need a context to resume.
>
ucontext-API called exit() but then the appication termiantes
switching to another context by returning it from the context-fn or
explictly ivoke the context switch is another option
this requires that the target context is still alive
--
---
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/.
--001a113adb28f25c740523141c20
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">2015=
-10-27 10:39 GMT+01:00 Giovanni Piero Deretta <span dir=3D"ltr"><<a href=
=3D"mailto:gpderetta@gmail.com" target=3D"_blank">gpderetta@gmail.com</a>&g=
t;</span>:<br><blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;=
border-left:1px #ccc solid;padding-left:1ex">=C2=A0<span class=3D""><blockq=
uote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-left:=
1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><div></div><div>maybe we =
can register a function (destruct_stack()) that causes the stack destructio=
n as return-address for the toplevel context-fn.<br></div><div>e.g. if the=
context-fn returns, destruct_stack() gets called =3D=3D the stack destruct=
s itself<br></div></div></blockquote></span><div><br>then what? you still n=
eed a context to resume.<br></div></blockquote></div><br></div><div class=
=3D"gmail_extra">ucontext-API called exit() but then the appication termian=
tes<br>switching to another context by returning it from the context-fn or =
explictly ivoke the context switch is another option<br>this requires that =
the target context is still alive<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 />
--001a113adb28f25c740523141c20--
.
Author: Oliver Kowalke <oliver.kowalke@gmail.com>
Date: Wed, 28 Oct 2015 07:51:47 +0100
Raw View
--089e015383e800bc49052324a23b
Content-Type: text/plain; charset=UTF-8
In the context of userland-threads I'd like to handle main()/thread
entry-functions as userland-threds too especially the implementation should
not test what kind of userland-thread
is processed (for instance suspending inside mutex/condition_vairable).
This requires that you have exactly one representation (instance) for the
main()/thread entry-function.
it seams to me that the suggested API does not provide; multiple instances
of class context might represent (point to) the main()/thread entry-function
--
---
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/.
--089e015383e800bc49052324a23b
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><div>In the context of userland-threads I'd like to ha=
ndle main()/thread entry-functions as userland-threds too especially the im=
plementation should not test what kind of userland-thread<br></div><div>is =
processed (for instance suspending inside mutex/condition_vairable).<br></d=
iv><div>This requires that you have exactly one representation (instance) f=
or the main()/thread entry-function.<br></div><div>it seams to me that the =
suggested API does not provide; multiple instances of class context might r=
epresent (point to) the main()/thread entry-function<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 />
--089e015383e800bc49052324a23b--
.
Author: Giovanni Piero Deretta <gpderetta@gmail.com>
Date: Wed, 28 Oct 2015 03:02:15 -0700 (PDT)
Raw View
------=_Part_1886_1984344712.1446026535383
Content-Type: multipart/alternative;
boundary="----=_Part_1887_1554512874.1446026535384"
------=_Part_1887_1554512874.1446026535384
Content-Type: text/plain; charset=UTF-8
On Wednesday, October 28, 2015 at 6:52:13 AM UTC, Oliver Kowalke wrote:
>
> In the context of userland-threads I'd like to handle main()/thread
> entry-functions as userland-threds too especially the implementation should
> not test what kind of userland-thread
> is processed (for instance suspending inside mutex/condition_vairable).
> This requires that you have exactly one representation (instance) for the
> main()/thread entry-function.
> it seams to me that the suggested API does not provide; multiple instances
> of class context might represent (point to) the main()/thread entry-function
>
I do not see any problem with the proposed interface. What issues do you
see? Do you have a concrete example?
--
---
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_1887_1554512874.1446026535384
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">On Wednesday, October 28, 2015 at 6:52:13 AM UTC, Oliver K=
owalke wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-le=
ft: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr">=
<div>In the context of userland-threads I'd like to handle main()/threa=
d entry-functions as userland-threds too especially the implementation shou=
ld not test what kind of userland-thread<br></div><div>is processed (for in=
stance suspending inside mutex/condition_vairable).<br></div><div>This requ=
ires that you have exactly one representation (instance) for the main()/thr=
ead entry-function.<br></div><div>it seams to me that the suggested API doe=
s not provide; multiple instances of class context might represent (point t=
o) the main()/thread entry-function<br></div></div></blockquote><div><br>I =
do not see any problem with the proposed interface. What issues do you see?=
Do you have a concrete example? <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_1887_1554512874.1446026535384--
------=_Part_1886_1984344712.1446026535383--
.
Author: Oliver Kowalke <oliver.kowalke@gmail.com>
Date: Wed, 28 Oct 2015 11:34:46 +0100
Raw View
--001a1140980e7c7e11052327bfa3
Content-Type: text/plain; charset=UTF-8
2015-10-28 11:02 GMT+01:00 Giovanni Piero Deretta <gpderetta@gmail.com>:
> I do not see any problem with the proposed interface. What issues do you
> see? Do you have a concrete example?
>
in the context of boost.fiber a fiber representing the main-context is
available after entering main()
I believe this is only possible with a context-API that allows default
created (non-valid) context.
the main-context is updated (as each other fiber-context) after a context
switch
--
---
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/.
--001a1140980e7c7e11052327bfa3
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">2015=
-10-28 11:02 GMT+01:00 Giovanni Piero Deretta <span dir=3D"ltr"><<a href=
=3D"mailto:gpderetta@gmail.com" target=3D"_blank">gpderetta@gmail.com</a>&g=
t;</span>:<br><blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;=
border-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><div>I do not=
see any problem with the proposed interface. What issues do you see? Do yo=
u have a concrete example?<br></div></div></blockquote></div><br></div><div=
class=3D"gmail_extra">in the context of boost.fiber a fiber representing t=
he main-context is available after entering main()<br></div><div class=3D"g=
mail_extra">I believe this is only possible with a context-API that allows =
default created (non-valid) context.<br></div><div class=3D"gmail_extra">th=
e main-context is updated (as each other fiber-context) after a context swi=
tch<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 />
--001a1140980e7c7e11052327bfa3--
.
Author: Giovanni Piero Deretta <gpderetta@gmail.com>
Date: Wed, 28 Oct 2015 04:56:12 -0700 (PDT)
Raw View
------=_Part_4185_45379406.1446033372903
Content-Type: multipart/alternative;
boundary="----=_Part_4186_508555014.1446033372904"
------=_Part_4186_508555014.1446033372904
Content-Type: text/plain; charset=UTF-8
On Wednesday, October 28, 2015 at 10:35:10 AM UTC, Oliver Kowalke wrote:
>
> 2015-10-28 11:02 GMT+01:00 Giovanni Piero Deretta <gpde...@gmail.com
> <javascript:>>:
>
>> I do not see any problem with the proposed interface. What issues do you
>> see? Do you have a concrete example?
>>
>
> in the context of boost.fiber a fiber representing the main-context is
> available after entering main()
> I believe this is only possible with a context-API that allows default
> created (non-valid) context.
> the main-context is updated (as each other fiber-context) after a context
> switch
>
But why do you need it? In the proposed interface contextes are non null
only when they point to an halted context. You create one on the fly when
you need it:
struct node { context c; node * next; node* prev; };
thread_local intrusive_list<node> scheduler;
struct waitable { intrusive_list<node> wait_list; };
.....
/// scheduler yield implementation:
void yield()
{
assert (!scheduler.empty())
context front = scheduler.front().c;
scheduler.pop_front();
node self;
transform(front, [&](context selfc) { self.c = std::move(selfc);
scheduler.push_back(self); scheduler.return selfc; })();
}
/// we want to sleep in a waitable queue and yield to next
void wait(waitable& w)
{
context front = scheduler.front();
scheduler.pop_front();
node self;
transform(front, [&(context selfc) { node.c =std::move(selfc);
w.wait_list.push_back(node); scheduler.return selfc; })();
}
--
---
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_4186_508555014.1446033372904
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<br><br>On Wednesday, October 28, 2015 at 10:35:10 AM UTC, Oliver Kowalke w=
rote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8e=
x;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr"><div><di=
v class=3D"gmail_quote">2015-10-28 11:02 GMT+01:00 Giovanni Piero Deretta <=
span dir=3D"ltr"><<a href=3D"javascript:" target=3D"_blank" gdf-obfuscat=
ed-mailto=3D"GWNyxxnYEgAJ" rel=3D"nofollow" onmousedown=3D"this.href=3D'=
;javascript:';return true;" onclick=3D"this.href=3D'javascript:'=
;;return true;">gpde...@gmail.com</a>></span>:<br><blockquote class=3D"g=
mail_quote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-l=
eft:1ex"><div dir=3D"ltr"><div>I do not see any problem with the proposed i=
nterface. What issues do you see? Do you have a concrete example?<br></div>=
</div></blockquote></div><br></div><div>in the context of boost.fiber a fib=
er representing the main-context is available after entering main()<br></di=
v><div>I believe this is only possible with a context-API that allows defau=
lt created (non-valid) context.<br></div><div>the main-context is updated (=
as each other fiber-context) after a context switch<br></div></div></blockq=
uote><div><br>But why do you need it? In the proposed interface contextes a=
re non null only when they point to an halted context. You create one on th=
e fly when you need it:<br><br>struct node { context c; node * next; node* =
prev; };<br>thread_local intrusive_list<node> scheduler;<br><br>struc=
t waitable { intrusive_list<node> wait_list; };<br><br>....<br><br>//=
/ scheduler yield implementation:<br><br>void yield()<br>{<br>=C2=A0=C2=A0=
=C2=A0 assert (!scheduler.empty())<br>=C2=A0=C2=A0=C2=A0 <br>=C2=A0=C2=A0=
=C2=A0 context front =3D scheduler.front().c;<br>=C2=A0=C2=A0=C2=A0 schedul=
er.pop_front();<br>=C2=A0=C2=A0=C2=A0 node self;<br>=C2=A0=C2=A0=C2=A0 tran=
sform(front, [&](context selfc) {=C2=A0 self.c =3D std::move(selfc); sc=
heduler.push_back(self); scheduler.return selfc; })();<br>}<br><br>/// we w=
ant to sleep in a waitable queue and yield to next<br>void wait(waitable&am=
p; w)<br>{<br>=C2=A0=C2=A0=C2=A0 context front =3D scheduler.front();<br>=
=C2=A0=C2=A0=C2=A0 scheduler.pop_front();<br>=C2=A0=C2=A0=C2=A0 node self;<=
br>=C2=A0=C2=A0=C2=A0 transform(front, [&(context selfc) {=C2=A0 node.c=
=3Dstd::move(selfc); w.wait_list.push_back(node); scheduler.return selfc; =
})();<br>}<br><br><br><br><br><br><br>=C2=A0<br></div>
<p></p>
-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />
------=_Part_4186_508555014.1446033372904--
------=_Part_4185_45379406.1446033372903--
.
Author: Oliver Kowalke <oliver.kowalke@gmail.com>
Date: Wed, 28 Oct 2015 13:07:13 +0100
Raw View
--001a1140980e11dd0c0523290add
Content-Type: text/plain; charset=UTF-8
2015-10-28 12:56 GMT+01:00 Giovanni Piero Deretta <gpderetta@gmail.com>:
> But why do you need it? In the proposed interface contextes are non null
> only when they point to an halted context.
>
I want to handle the fiber of the main-context (==main()) as the other
fibers
otherwise the implementation must take care if the code (for instance
condition_variable::wait() is not called in a fiber -> no suspend operation)
--
---
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/.
--001a1140980e11dd0c0523290add
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">2015=
-10-28 12:56 GMT+01:00 Giovanni Piero Deretta <span dir=3D"ltr"><<a href=
=3D"mailto:gpderetta@gmail.com" target=3D"_blank">gpderetta@gmail.com</a>&g=
t;</span>:<br><blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;=
border-left:1px #ccc solid;padding-left:1ex"><div>But why do you need it? I=
n the proposed interface contextes are non null only when they point to an =
halted context. </div></blockquote><div><br></div><div>I want to handle the=
fiber of the main-context (=3D=3Dmain()) as the other fibers<br></div></di=
v>otherwise the implementation must take care if the code (for instance con=
dition_variable::wait() is not called in a fiber -> no suspend operation=
)<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 />
--001a1140980e11dd0c0523290add--
.
Author: Giovanni Piero Deretta <gpderetta@gmail.com>
Date: Wed, 28 Oct 2015 12:23:12 +0000
Raw View
--001a1141ffca114a3705232942a2
Content-Type: text/plain; charset=UTF-8
On 28 Oct 2015 12:07 p.m., "Oliver Kowalke" <oliver.kowalke@gmail.com>
wrote:
>
> 2015-10-28 12:56 GMT+01:00 Giovanni Piero Deretta <gpderetta@gmail.com>:
>>
>> But why do you need it? In the proposed interface contextes are non null
only when they point to an halted context.
>
>
> I want to handle the fiber of the main-context (==main()) as the other
fibers
> otherwise the implementation must take care if the code (for instance
condition_variable::wait() is not called in a fiber -> no suspend operation)
>
What do you think of my wait example? It doesn't really care where it is
being called from, it will work just fine, right?
If you want to carry around some persistent identity, like a fiber Id or
metadata, then yes, it will have to be switched manually, by that's
application specific and should belong in the minimal api.
> --
>
> ---
> You received this message because you are subscribed to a topic in the
Google Groups "ISO C++ Standard - Future Proposals" group.
> To unsubscribe from this topic, visit
https://groups.google.com/a/isocpp.org/d/topic/std-proposals/L5ZsY1SYnrA/unsubscribe
..
> To unsubscribe from this group and all its topics, 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/.
--
---
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/.
--001a1141ffca114a3705232942a2
Content-Type: text/html; charset=UTF-8
<p dir="ltr"><br>
On 28 Oct 2015 12:07 p.m., "Oliver Kowalke" <<a href="mailto:oliver.kowalke@gmail.com">oliver.kowalke@gmail.com</a>> wrote:<br>
><br>
> 2015-10-28 12:56 GMT+01:00 Giovanni Piero Deretta <<a href="mailto:gpderetta@gmail.com">gpderetta@gmail.com</a>>:<br>
>><br>
>> But why do you need it? In the proposed interface contextes are non null only when they point to an halted context.<br>
><br>
><br>
> I want to handle the fiber of the main-context (==main()) as the other fibers<br>
> otherwise the implementation must take care if the code (for instance condition_variable::wait() is not called in a fiber -> no suspend operation)<br>
></p>
<p dir="ltr">What do you think of my wait example? It doesn't really care where it is being called from, it will work just fine, right?</p>
<p dir="ltr">If you want to carry around some persistent identity, like a fiber Id or metadata, then yes, it will have to be switched manually, by that's application specific and should belong in the minimal api.</p>
<p dir="ltr">> -- <br>
><br>
> --- <br>
> You received this message because you are subscribed to a topic in the Google Groups "ISO C++ Standard - Future Proposals" group.<br>
> To unsubscribe from this topic, visit <a href="https://groups.google.com/a/isocpp.org/d/topic/std-proposals/L5ZsY1SYnrA/unsubscribe">https://groups.google.com/a/isocpp.org/d/topic/std-proposals/L5ZsY1SYnrA/unsubscribe</a>.<br>
> To unsubscribe from this group and all its topics, send an email to <a href="mailto:std-proposals%2Bunsubscribe@isocpp.org">std-proposals+unsubscribe@isocpp.org</a>.<br>
> To post to this group, send email to <a href="mailto:std-proposals@isocpp.org">std-proposals@isocpp.org</a>.<br>
> Visit this group at <a href="http://groups.google.com/a/isocpp.org/group/std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/</a>.<br>
</p>
<p></p>
-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an email to <a href="mailto:std-proposals+unsubscribe@isocpp.org">std-proposals+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href="mailto:std-proposals@isocpp.org">std-proposals@isocpp.org</a>.<br />
Visit this group at <a href="http://groups.google.com/a/isocpp.org/group/std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/</a>.<br />
--001a1141ffca114a3705232942a2--
.