220 5268 <CAH5h6+V6s=n48y-NUBOzEQySEfZLsnLO3gqUjvxNkoCWpDKdkw@mail.gmail.com> article
Path: news.gmane.org!not-for-mail
From: minchul park <summerlight00@gmail.com>
Newsgroups: gmane.comp.lang.c++.isocpp.proposals
Subject: Re: Re: Some thoughts about coroutines
Date: Sat, 29 Jun 2013 09:55:03 +0900
Lines: 237
Approved: news@gmane.org
Message-ID: <CAH5h6+V6s=n48y-NUBOzEQySEfZLsnLO3gqUjvxNkoCWpDKdkw@mail.gmail.com>
References: <e4828fad-0428-46f8-ad6d-500848c2212b@isocpp.org>
	<291db835-d42d-40cd-8760-47cdf327680d@isocpp.org>
	<7d8a2d85-0995-4833-ad0c-75577f293b63@isocpp.org>
	<bca881ad-7d62-42d6-8e04-eb7320cebed1@isocpp.org>
	<2c77506f-433f-43b7-871f-e429c4b295bf@isocpp.org>
	<3e94ef89-4ea8-4549-827f-94dd7a32b9fa@isocpp.org>
	<1a1fd94c-eb51-4ff4-8e3d-7781a6c9b925@isocpp.org>
Reply-To: std-proposals@isocpp.org
NNTP-Posting-Host: plane.gmane.org
Mime-Version: 1.0
Content-Type: multipart/alternative; boundary=047d7b2e15d713e3d804e04072e4
X-Trace: ger.gmane.org 1372467306 15648 80.91.229.3 (29 Jun 2013 00:55:06 GMT)
X-Complaints-To: usenet@ger.gmane.org
NNTP-Posting-Date: Sat, 29 Jun 2013 00:55:06 +0000 (UTC)
To: std-proposals@isocpp.org
Original-X-From: std-proposals+bncBDH3HYO5YQIBBZ7AXCHAKGQEQ6ER2WA@isocpp.org Sat Jun 29 02:55:08 2013
Return-path: <std-proposals+bncBDH3HYO5YQIBBZ7AXCHAKGQEQ6ER2WA@isocpp.org>
Envelope-to: gclcip-std-proposals@m.gmane.org
Original-Received: from mail-ie0-f199.google.com ([209.85.223.199])
	by plane.gmane.org with esmtp (Exim 4.69)
	(envelope-from <std-proposals+bncBDH3HYO5YQIBBZ7AXCHAKGQEQ6ER2WA@isocpp.org>)
	id 1UsjRT-00054Y-AW
	for gclcip-std-proposals@m.gmane.org; Sat, 29 Jun 2013 02:55:07 +0200
Original-Received: by mail-ie0-f199.google.com with SMTP id 9sf9248022iec.10
        for <gclcip-std-proposals@m.gmane.org>; Fri, 28 Jun 2013 17:55:06 -0700 (PDT)
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
        d=gmail.com; s=20120113;
        h=x-beenthere:mime-version:in-reply-to:references:date:message-id
         :subject:from:to:x-original-sender:x-original-authentication-results
         :reply-to:precedence:mailing-list:list-id:x-google-group-id
         :list-post:list-help:list-archive:list-subscribe:list-unsubscribe
         :content-type;
        bh=No0TscF7LVfA4knMplc92oFYkKWu7GikG9cZShtTIV4=;
        b=vkv4rgyVD5bRWbQ1jHl72yBF+XIUsuh3ySFUOpuegWzR7kvICiQcxvdUfFJQgJxMOG
         tFuusK/cdDU5gadBqdyAJMEXmcGc5p8DA6YwV7hrYrt2pvMGUrYncTQXEddNoJ9B1ht+
         Ufdb4LMHXuY/PHqb3zapy93f0BzjtMdfGXkPm2JBpyGRijJ9u7WuG6LUe34pVIaUUHFx
         2j4Wq2arBYwbsaz1VqKSqHOcETcoaSGAXB+85X/+ZNj8LCFt43bV6jSvomO3q0bbtFb/
         6dLOd2jW27ms6hSpHm+aMuTY/MeC8g6k0yJdvuFngeED/T6KU8V879b/5g7Q3i/TT1bC
         XgVQ==
X-Received: by 10.182.129.19 with SMTP id ns19mr4153998obb.32.1372467306314;
        Fri, 28 Jun 2013 17:55:06 -0700 (PDT)
X-BeenThere: std-proposals@isocpp.org
Original-Received: by 10.182.209.4 with SMTP id mi4ls47489obc.95.gmail; Fri, 28 Jun
 2013 17:55:03 -0700 (PDT)
X-Received: by 10.60.103.115 with SMTP id fv19mr6060742oeb.74.1372467303698;
        Fri, 28 Jun 2013 17:55:03 -0700 (PDT)
Original-Received: from mail-ie0-x22b.google.com (mail-ie0-x22b.google.com [2607:f8b0:4001:c03::22b])
        by mx.google.com with ESMTPS id x4si573562oej.8.2013.06.28.17.55.03
        for <std-proposals@isocpp.org>
        (version=TLSv1 cipher=ECDHE-RSA-RC4-SHA bits=128/128);
        Fri, 28 Jun 2013 17:55:03 -0700 (PDT)
Received-SPF: pass (google.com: domain of summerlight00@gmail.com designates 2607:f8b0:4001:c03::22b as permitted sender) client-ip=2607:f8b0:4001:c03::22b;
Original-Received: by mail-ie0-f171.google.com with SMTP id qd12so5469890ieb.16
        for <std-proposals@isocpp.org>; Fri, 28 Jun 2013 17:55:03 -0700 (PDT)
X-Received: by 10.50.103.3 with SMTP id fs3mr6303798igb.39.1372467303275; Fri,
 28 Jun 2013 17:55:03 -0700 (PDT)
Original-Received: by 10.64.62.200 with HTTP; Fri, 28 Jun 2013 17:55:03 -0700 (PDT)
In-Reply-To: <1a1fd94c-eb51-4ff4-8e3d-7781a6c9b925@isocpp.org>
X-Original-Sender: summerlight00@gmail.com
X-Original-Authentication-Results: mx.google.com;       spf=pass (google.com:
 domain of summerlight00@gmail.com designates 2607:f8b0:4001:c03::22b as
 permitted sender) smtp.mail=summerlight00@gmail.com;       dkim=pass header.i=@gmail.com
Precedence: list
Mailing-list: list std-proposals@isocpp.org; contact std-proposals+owners@isocpp.org
List-ID: <std-proposals.isocpp.org>
X-Google-Group-Id: 399137483710
List-Post: <http://groups.google.com/a/isocpp.org/group/std-proposals/post>, <mailto:std-proposals@isocpp.org>
List-Help: <http://support.google.com/a/isocpp.org/bin/topic.py?topic=25838>, <mailto:std-proposals+help@isocpp.org>
List-Archive: <http://groups.google.com/a/isocpp.org/group/std-proposals/>
List-Subscribe: <http://groups.google.com/a/isocpp.org/group/std-proposals/subscribe>,
 <mailto:std-proposals+subscribe@isocpp.org>
List-Unsubscribe: <http://groups.google.com/a/isocpp.org/group/std-proposals/subscribe>,
 <mailto:googlegroups-manage+399137483710+unsubscribe@googlegroups.com>
Xref: news.gmane.org gmane.comp.lang.c++.isocpp.proposals:5268
Archived-At: <http://permalink.gmane.org/gmane.comp.lang.c++.isocpp.proposals/5268>

--047d7b2e15d713e3d804e04072e4
Content-Type: text/plain; charset=ISO-8859-1

For the sake of clarity, it's worth to note that the second proposal is a
description of generator, rather than coroutine. They should be
distinguished.

Coroutine is not just about a simple programming pattern like
producer/consumer (which is actually external iterator) - It's more
primitive building block to support every kind of cooperative multitasking,
so it should maintain its own continuation. So if you want to call
something coroutine, it should have its own callstack(which represents
continuation in C++).

Of course, generator has its own advantage. It has much easier to use, and
maybe more efficient on its primary use cases since it's just simple
syntax-sugared state machine functor. Since iterator pattern is widely
adapted in C++ community, it deserves its own syntax. So I'm not against
about generator proposal, but still, it can't be a replacement of coroutine.


And I guess you have doubt about necessity of deep yield. Think about
simple IO scenario. Maybe the most simple pseudo code may looks like below.

void some_protocol(end_point dest) {
  session s(dest);
  // some processing
  s.send(buffer);
  s.recv(buffer); // unbounded blocking

  // use received data
}

But the code has some performance issue. One recv call can blocks other
computation. It can be resolved by mapping one thread to one session , but
it has its own performance problem. So let's introduce some asynchronous
code.

end_point dest;
session s(dest); // connected and maintained by some other code - its
lifetime is not bounded to the scope.

void async_recv_handler(session& s) {
  // use received data
}

void async_protocol(session& s) {
  // some processing
  s.send(buffer);
  s.recv(recv_handler);
}

It's much more complex due to the nature of asynchronous process. Maybe CPS
with lambda can mitigates it, but it's still ugly. However, if we have
"deep yield" backed up by coroutine-based cooperative task scheduler, then
the code becomes drastically simpler.

void some_protocol(end_point dest) {
  session s(dest);

  s.recv(buffer); // deep yielded inside of network library

  // use received data
}


The root cause of the problem is strong coupling between continuation and
thread. We want to map one continuation to one conceptual computation
context, but in C++11, thread is the only way to achieve it since they are
strongly coupled.

The fundamental solution is to decouple continuation from thread and treat
continuation as first-class object. Though it's very hard (or technically
infeasible) to implement it as a first class object in the context of C++,
but coroutine can be the practically sufficient solution which can be
applied almost every cases. The necessity of "deep yield" means this.

I also want to note that generator just maintains only its own function
frame, which is not sufficient to represent continuation in general use
case.


On Fri, Jun 28, 2013 at 10:10 AM, <asaelr@gmail.com> wrote:

> Another thing - what should *operator()* return when the coroutine is
> done? We can't know it's done before the internal function actually ends,
> so we can't just check *isdone() *(or, maybe, *operator bool()* ) to know
> if we shouldn't call *operator()*.
> (One solution is to let the coroutine not to return control just when
> yielding, but instead continue running until just before the next *return*statement, but I think it's kind of evil)
>
>  --
>
> ---
> You received this message because you are 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/.
>
>
>



-- 
Min-chul Park (summerlight00@gmail.com / http://summerlight.tistory.com)

-- 

--- 
You received this message because you are 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/.



--047d7b2e15d713e3d804e04072e4
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">For the sake of clarity, it&#39;s worth to note that the s=
econd proposal is a description of generator, rather than coroutine. They s=
hould be distinguished.<div><br></div><div>Coroutine is not just about a si=
mple programming pattern like producer/consumer (which is actually external=
 iterator) - It&#39;s more primitive building block to support every kind o=
f cooperative multitasking, so it should maintain its own continuation. So =
if you want to call something coroutine, it should have its own callstack(w=
hich represents continuation in C++).</div>
<div><br></div><div>Of course, generator has its own advantage. It has much=
 easier to use, and maybe more efficient on its primary use cases since it&=
#39;s just simple syntax-sugared state machine functor. Since iterator patt=
ern is widely adapted in C++ community, it deserves its own syntax. So I&#3=
9;m not against about generator proposal, but still, it can&#39;t be a repl=
acement of coroutine.<br>
<div><br></div><div><br></div><div>And I guess you have doubt about necessi=
ty of deep yield. Think about simple IO scenario. Maybe the most simple pse=
udo code may looks like below.</div></div><div><br></div><div style>void so=
me_protocol(end_point dest) {</div>
<div style>=A0 session s(dest);</div><div style>=A0 // some processing</div=
><div style>=A0 s.send(buffer);</div><div style>=A0 s.recv(buffer); // unbo=
unded blocking<br></div><div style><br></div><div style>=A0 // use received=
 data</div>
<div style>}</div><div style><br></div><div style>But the code has some per=
formance issue. One recv call can blocks other computation. It can be resol=
ved by mapping one thread to one session , but it has its own performance p=
roblem. So let&#39;s introduce some asynchronous code.</div>
<div style><br></div><div style>end_point dest;</div><div style>session s(d=
est); // connected and maintained by some other code - its lifetime is not =
bounded to the scope.</div><div style><br></div><div style>void async_recv_=
handler(session&amp; s) {<br>
</div><div style>=A0 // use received data</div><div style>}</div><div style=
><br></div><div style>void async_protocol(session&amp; s) {</div><div style=
><div>=A0 // some processing</div><div>=A0 s.send(buffer);</div></div><div =
style>
=A0 s.recv(recv_handler);</div><div style>}</div><div style><br></div><div =
style>It&#39;s much more complex due to the nature of asynchronous process.=
 Maybe CPS with lambda can mitigates it, but it&#39;s still ugly. However, =
if we have &quot;deep yield&quot; backed up by coroutine-based cooperative =
task scheduler, then the code becomes drastically simpler.</div>
<div style><br></div><div style><div>void some_protocol(end_point dest) {</=
div><div>=A0 session s(dest);</div><div><br></div><div>=A0 s.recv(buffer); =
// deep yielded inside of network library<br></div><div><br></div><div>=A0 =
// use received data</div>
<div>}</div><div><br></div><div><br></div><div style>The root cause of the =
problem is strong coupling between continuation and thread. We want to map =
one continuation to one conceptual computation context, but in C++11, threa=
d is the only way to achieve it since they are strongly coupled.</div>
<div style><br></div><div style>The fundamental solution is to decouple con=
tinuation from thread and treat continuation as first-class object. Though =
it&#39;s very hard (or technically infeasible) to implement it as a first c=
lass object in the context of C++, but coroutine can be the practically suf=
ficient solution which can be applied almost every cases. The necessity of =
&quot;deep yield&quot; means this.</div>
<div style><br></div><div style>I also want to note that generator just mai=
ntains only its own function frame, which is not sufficient to represent co=
ntinuation in general use case.=A0</div></div></div><div class=3D"gmail_ext=
ra">
<br><br><div class=3D"gmail_quote">On Fri, Jun 28, 2013 at 10:10 AM,  <span=
 dir=3D"ltr">&lt;<a href=3D"mailto:asaelr@gmail.com" target=3D"_blank">asae=
lr@gmail.com</a>&gt;</span> wrote:<br><blockquote class=3D"gmail_quote" sty=
le=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
Another thing - what should <i>operator()</i> return when the coroutine is =
done? We can&#39;t know it&#39;s done before the internal function actually=
 ends, so we can&#39;t just check <i>isdone() </i>(or, maybe, <i>operator b=
ool()</i> ) to know if we shouldn&#39;t call <i>operator()</i>.<br>
(One solution is to let the coroutine not to return control just when yield=
ing, but instead continue running until just before the next <i>return</i> =
statement, but I think it&#39;s kind of evil)<div class=3D"HOEnZb"><div cla=
ss=3D"h5">
<br>

<p></p>

-- <br>
=A0<br>
--- <br>
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br>
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals%2Bunsubscribe@isocpp.org" target=3D=
"_blank">std-proposals+unsubscribe@isocpp.org</a>.<br>
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org" target=3D"_blank">std-proposals@isocpp.org</a>.<br>
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/" target=3D"_blank">http://groups.google.com/a/isocpp.org/gro=
up/std-proposals/</a>.<br>
=A0<br>
=A0<br>
</div></div></blockquote></div><br><br clear=3D"all"><div><br></div>-- <br>=
<div>Min-chul Park (<a href=3D"mailto:summerlight00@gmail.com" target=3D"_b=
lank">summerlight00@gmail.com</a>=A0/ <a href=3D"http://summerlight.tistory=
..com/" target=3D"_blank">http://summerlight.tistory.com</a>)</div>

</div>

<p></p>

-- <br />
&nbsp;<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.<br />
To post to this group, send email to std-proposals@isocpp.org.<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 />
&nbsp;<br />
&nbsp;<br />

--047d7b2e15d713e3d804e04072e4--

.
