220 21405 <f6812409-ed88-47b1-88ef-da8fad96dbdf@isocpp.org> article
Path: news.gmane.org!not-for-mail
From: Nicol Bolas <jmckesson@gmail.com>
Newsgroups: gmane.comp.lang.c++.isocpp.proposals
Subject: Re: Resumable expressions p0114r0 vs async/await P0057R0
Date: Wed, 7 Oct 2015 08:21:58 -0700 (PDT)
Lines: 260
Approved: news@gmane.org
Message-ID: <f6812409-ed88-47b1-88ef-da8fad96dbdf@isocpp.org>
References: <639f0012-8cb4-4db3-82a6-8d042a3497f9@isocpp.org>
 <401aa118-ed0b-4c7b-92cf-3fbd706eff9d@isocpp.org>
 <fcbcc1c4-535c-4fa2-a17d-4acffe84a4b5@isocpp.org>
 <1d15dbc4-e0c1-4df1-86db-014e11f14d26@isocpp.org>
 <1bf00a8f-5f20-43de-a319-2712ab34eafd@isocpp.org>
 <36f46c03-b1f1-4230-b686-a7a9a1c491cb@isocpp.org>
 <9e17f8a6-4f5b-47dd-9f76-a4675a5ede3c@isocpp.org>
 <c74e1892-2a61-46e3-a4ca-81255363b07e@isocpp.org>
 <1105ae90-7e2b-49be-b88e-84493c9a1810@isocpp.org>
 <9838dc2a-6f1b-4dca-b4b9-72b6a9917c38@isocpp.org>
 <b7796fea-ab43-4f19-945c-2579e775ffde@isocpp.org>
 <8067ed4f-3f08-41eb-b897-0760690fd55e@isocpp.org>
Reply-To: std-proposals@isocpp.org
NNTP-Posting-Host: plane.gmane.org
Mime-Version: 1.0
Content-Type: multipart/mixed; 
	boundary="----=_Part_204_674066700.1444231318942"
X-Trace: ger.gmane.org 1444231323 10709 80.91.229.3 (7 Oct 2015 15:22:03 GMT)
X-Complaints-To: usenet@ger.gmane.org
NNTP-Posting-Date: Wed, 7 Oct 2015 15:22:03 +0000 (UTC)
Cc: german.diago@hubblehome.com
To: ISO C++ Standard - Future Proposals <std-proposals@isocpp.org>
Original-X-From: std-proposals+bncBCEKFTV6ZUMBBGHR2SYAKGQEWQU2SRY@isocpp.org Wed Oct 07 17:22:03 2015
Return-path: <std-proposals+bncBCEKFTV6ZUMBBGHR2SYAKGQEWQU2SRY@isocpp.org>
Envelope-to: gclcip-std-proposals@m.gmane.org
Original-Received: from mail-ig0-f198.google.com ([209.85.213.198])
	by plane.gmane.org with esmtp (Exim 4.69)
	(envelope-from <std-proposals+bncBCEKFTV6ZUMBBGHR2SYAKGQEWQU2SRY@isocpp.org>)
	id 1ZjqXZ-0002kP-RC
	for gclcip-std-proposals@m.gmane.org; Wed, 07 Oct 2015 17:22:02 +0200
Original-Received: by igbbp9 with SMTP id bp9sf47002931igb.3
        for <gclcip-std-proposals@m.gmane.org>; Wed, 07 Oct 2015 08:22:01 -0700 (PDT)
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
        d=gmail.com; s=20120113;
        h=date:from:to:cc:message-id:in-reply-to:references:subject
         :mime-version:content-type:x-original-sender:reply-to:precedence
         :mailing-list:list-id:x-spam-checked-in-group:list-post:list-help
         :list-archive:list-subscribe:list-unsubscribe;
        bh=0Ax9TEra/X23T6vbI/J79OqOnhsKaAZLxvh3ob1xUV8=;
        b=ObNl9/KbAIUc/o6La7VlppJxabH4s7yefdYaf7crLSGa/4DIblhZnvoJLj3DPlcM0R
         uESm4to2hOI3TgW87mtkRrB92gg/X/z/62ynrMsNac7nsfAAdkcVnqUFZFYoEn0B3pet
         CQl8/NrgJUYqXV+5GG1+sJPuLUcpEP5g1qCwJpPurOonzzo1U1ZUJHnd55uFyTVVrBAY
         Y7aoHtpDtZTH9GqOle2jOB3efHl4hJVLUmDFHYXNWILKiR0iwrscuWX8JvY+SzneLtF0
         p6mqF955iqlXBvXisLWoPfZ7XOxewrwvDdvcdiSiXFOVJ3L0NTAb6pQLM0ktF4LQlFRS
         yokQ==
X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
        d=1e100.net; s=20130820;
        h=x-gm-message-state:date:from:to:cc:message-id:in-reply-to
         :references:subject:mime-version:content-type:x-original-sender
         :reply-to:precedence:mailing-list:list-id:x-spam-checked-in-group
         :list-post:list-help:list-archive:list-subscribe:list-unsubscribe;
        bh=0Ax9TEra/X23T6vbI/J79OqOnhsKaAZLxvh3ob1xUV8=;
        b=jHPoIZjtV5ZUY0OpgNh4181wPYIRjcNYCOEC1UBQ0hpwBXjwGPpJKygF6ECTIM0KoG
         513XMCKEgSwbkjYxzJ8kEo2NNTTHpEoIrXH3xvHdXtE3YhyLsqlSXDpH4VLI904dWrml
         s6ez0waiVO3sQJ3CPQ+cVz+PS/FPwkeinedRrgn8O0sgVeMu/Leb2VxSSxmBGO/kpNq2
         NvL3iqtkyTVFF2GhbWiy1WC/1SiDpKU8U3Bc5tKlRuPU8RelkeV9xLgonSExdpQYbodr
         q0cwUkyQfGByoXSD/xmpT86LtygdXdC8tKha3StQ7mxHq3CeVRqMHcFpYKKP1lddj0mm
         rhOw==
X-Gm-Message-State: ALoCoQmZYt2VLG5nVvvCUoxFPPCLe6fM7MKfQ+jhJxnBEdxVS2pZSKkE9cTbSDI8hJzJompZSBm3
X-Received: by 10.182.106.228 with SMTP id gx4mr1317707obb.34.1444231320949;
        Wed, 07 Oct 2015 08:22:00 -0700 (PDT)
X-BeenThere: std-proposals@isocpp.org
Original-Received: by 10.107.46.152 with SMTP id u24ls246124iou.29.gmail; Wed, 07 Oct
 2015 08:21:59 -0700 (PDT)
X-Received: by 10.50.72.80 with SMTP id b16mr41748igv.6.1444231319799;
        Wed, 07 Oct 2015 08:21:59 -0700 (PDT)
In-Reply-To: <8067ed4f-3f08-41eb-b897-0760690fd55e@isocpp.org>
X-Original-Sender: jmckesson@gmail.com
Precedence: list
Mailing-list: list std-proposals@isocpp.org; contact std-proposals+owners@isocpp.org
List-ID: <std-proposals.isocpp.org>
X-Spam-Checked-In-Group: 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: <mailto:googlegroups-manage+399137483710+unsubscribe@googlegroups.com>,
 <http://groups.google.com/a/isocpp.org/group/std-proposals/subscribe>
Xref: news.gmane.org gmane.comp.lang.c++.isocpp.proposals:21405
Archived-At: <http://permalink.gmane.org/gmane.comp.lang.c++.isocpp.proposals/21405>

------=_Part_204_674066700.1444231318942
Content-Type: multipart/alternative; 
	boundary="----=_Part_205_1539282392.1444231318943"

------=_Part_205_1539282392.1444231318943
Content-Type: text/plain; charset=UTF-8


Actually, I misunderstood two things about resumable expressions, both of 
which lead me to believe that P0114 is *broken*. Though not irreparably.

*1) Implicit resumable deduction.*

Apparently, implicit resumable deduction happens more often than I thought. 
It happens on `inline` functions, member functions in class definitions, 
and so forth. Indeed, pretty much the only place where resumable deduction 
is not implicit... is in normal functions in .cpp files.

Which leads to breakage #1:

//Some header file.
inline int a_func()
{
  return 5;
}

inline int b_func()
{
  break resumable;
  return 5;
}

//Some cpp file.

static void func()
{
  auto x = a_func() + b_func();
  internal_global_var += x;
}

void caller()
{
  func();
}

OK, where will the compile error point? Well, the compile error will cite 
the first line of `func`. Which seems OK. You're calling a resumable 
function from a non-resumable context, and the function isn't inline, so it 
won't be implicitly deduced. That sounds legitimate.

But wait: what happens if you stick `inline` in front of `func`? It's a 
static function, so making it `inline` seems harmless (though silly). Yet 
suddenly... the error moves. Now it points at `caller`.

Why? The last time anyone mentioned `resumable` was 2 function levels below 
`caller`, and in a completely different file. All because someone thought 
they'd help the compiler out with inlining by (mis)using the `inline` 
keyword.

The distance between where the last `resumable` was and where the improper 
use of a resumable function call is (ie: where the error actually happened) 
should be exactly one. That is, one call. The compiler should be able to 
point at the call, and the user should be able to see, *from the call 
itself*, that this function can't be called in this way.

I should not have to look at the implementation of your code, and the code 
you call, ad-infinitium, before I'm able to decide whether and/or how I can 
call your function.

If the question is this: should it be possible to *accidentally* write a 
coroutine by calling a coroutine? My answer to that should be "only if the 
caller can easily see that they've done so." And the only way to do that is 
to put something in the function *signature* that says "hey, I'm a 
coroutine; if you call me, so are you."

For resumable expressions, that's spelled `resumable`. And therefore, every 
resumable function ought to be *explicitly* tagged as such.

Of course, taking away implicit `resumable` deduction breaks the marquee 
feature of resumable expressions: the ability for templates to become 
coroutines based on what template parameters they're given.

I don't care. The downsides of this approach are not worth the advantages.

`resumable` may not be "viral". But it is just as infectious as await. And 
a silent infection is far more pernicious than a noisy one.

*2) Implicit `resumable` deduction oversight.*

I must assume that this is an oversight. Otherwise, the proposal makes no 
sense.

The proposal states that a function is implicitly resumable if it calls 
`break resumable` or calls any resumable function. *Period*.

What about calling a resumable function within a resumable expression? IE: 
`resumable auto x = resumable_func()`. No exception is listed for this; 
calling `resumable_func` makes the calling function resumable, period. And 
if it's not in an implicitly resumable deduction context, it is a compile 
error.

I have to assume that this was simply a mistake. That the section on 
implicit deduction was meant to have allowances for resumable expressions, 
that any functions called in such an expression effectively don't count. 
Otherwise, *main itself* will have to be resumable if you call any 
resumable 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/.

------=_Part_205_1539282392.1444231318943
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><br>Actually, I misunderstood two things about resumable e=
xpressions, both of which lead me to believe that P0114 is <i>broken</i>. T=
hough not irreparably.<br><br><u><b>1) Implicit resumable deduction.</b></u=
><br><br>Apparently, implicit resumable deduction happens more often than I=
 thought. It happens on `inline` functions, member functions in class defin=
itions, and so forth. Indeed, pretty much the only place where resumable de=
duction is not implicit... is in normal functions in .cpp files.<br><br>Whi=
ch leads to breakage #1:<br><br><div class=3D"prettyprint" style=3D"backgro=
und-color: rgb(250, 250, 250); border-color: rgb(187, 187, 187); border-sty=
le: solid; border-width: 1px; word-wrap: break-word;"><code class=3D"pretty=
print"><div class=3D"subprettyprint"><span style=3D"color: #800;" class=3D"=
styled-by-prettify">//Some header file.</span><span style=3D"color: #000;" =
class=3D"styled-by-prettify"><br></span><span style=3D"color: #008;" class=
=3D"styled-by-prettify">inline</span><span style=3D"color: #000;" class=3D"=
styled-by-prettify"> </span><span style=3D"color: #008;" class=3D"styled-by=
-prettify">int</span><span style=3D"color: #000;" class=3D"styled-by-pretti=
fy"> a_func</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 </span><spa=
n style=3D"color: #008;" class=3D"styled-by-prettify">return</span><span st=
yle=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"co=
lor: #066;" class=3D"styled-by-prettify">5</span><span style=3D"color: #660=
;" class=3D"styled-by-prettify">;</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"><br></span><span style=3D"color: #660;" class=3D"st=
yled-by-prettify">}</span><span style=3D"color: #000;" class=3D"styled-by-p=
rettify"><br><br></span><span style=3D"color: #008;" class=3D"styled-by-pre=
ttify">inline</span><span style=3D"color: #000;" class=3D"styled-by-prettif=
y"> </span><span style=3D"color: #008;" class=3D"styled-by-prettify">int</s=
pan><span style=3D"color: #000;" class=3D"styled-by-prettify"> b_func</span=
><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 </span><span style=3D"colo=
r: #008;" class=3D"styled-by-prettify">break</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"><br>=C2=A0 </span><span style=3D"color: #008;" cla=
ss=3D"styled-by-prettify">return</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"> </span><span style=3D"color: #066;" class=3D"style=
d-by-prettify">5</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><br></span><sp=
an style=3D"color: #800;" class=3D"styled-by-prettify">//Some cpp file.</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">static</span><sp=
an style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=
=3D"color: #008;" class=3D"styled-by-prettify">void</span><span style=3D"co=
lor: #000;" class=3D"styled-by-prettify"> func</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 </span><span style=3D"color: #008;" class=3D"styl=
ed-by-prettify">auto</span><span style=3D"color: #000;" class=3D"styled-by-=
prettify"> x </span><span style=3D"color: #660;" class=3D"styled-by-prettif=
y">=3D</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> a_f=
unc</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"> b_func</span><span style=3D"colo=
r: #660;" class=3D"styled-by-prettify">();</span><span style=3D"color: #000=
;" class=3D"styled-by-prettify"><br>=C2=A0 internal_global_var </span><span=
 style=3D"color: #660;" class=3D"styled-by-prettify">+=3D</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"> x</span><span style=3D"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><br></span><span style=3D"color: #008;" class=3D"styled-=
by-prettify">void</span><span style=3D"color: #000;" class=3D"styled-by-pre=
ttify"> </span><span style=3D"color: #008;" class=3D"styled-by-prettify">ca=
ller</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 func</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></div></code></div><br>OK,=
 where will the compile error point? Well, the compile error will cite the =
first line of `func`. Which seems OK. You&#39;re calling a resumable functi=
on from a non-resumable context, and the function isn&#39;t inline, so it w=
on&#39;t be implicitly deduced. That sounds legitimate.<br><br>But wait: wh=
at happens if you stick `inline` in front of `func`? It&#39;s a static func=
tion, so making it `inline` seems harmless (though silly). Yet suddenly... =
the error moves. Now it points at `caller`.<br><br>Why? The last time anyon=
e mentioned `resumable` was 2 function levels below `caller`, and in a comp=
letely different file. All because someone thought they&#39;d help the comp=
iler out with inlining by (mis)using the `inline` keyword.<br><br>The dista=
nce between where the last `resumable` was and where the improper use of a =
resumable function call is (ie: where the error actually happened) should b=
e exactly one. That is, one call. The compiler should be able to point at t=
he call, and the user should be able to see, <i>from the call itself</i>, t=
hat this function can&#39;t be called in this way.<br><br>I should not have=
 to look at the implementation of your code, and the code you call, ad-infi=
nitium, before I&#39;m able to decide whether and/or how I can call your fu=
nction.<br><br>If the question is this: should it be possible to <i>acciden=
tally</i> write a coroutine by calling a coroutine? My answer to that shoul=
d be &quot;only if the caller can easily see that they&#39;ve done so.&quot=
; And the only way to do that is to put something in the function <i>signat=
ure</i> that says &quot;hey, I&#39;m a coroutine; if you call me, so are yo=
u.&quot;<br><br>For resumable expressions, that&#39;s spelled `resumable`. =
And therefore, every resumable function ought to be <i>explicitly</i> tagge=
d as such.<br><br>Of course, taking away implicit `resumable` deduction bre=
aks the marquee feature of resumable expressions: the ability for templates=
 to become coroutines based on what template parameters they&#39;re given.<=
br><br>I don&#39;t care. The downsides of this approach are not worth the a=
dvantages.<br><br>`resumable` may not be &quot;viral&quot;. But it is just =
as infectious as await. And a silent infection is far more pernicious than =
a noisy one.<br><br><b><u>2) Implicit `resumable` deduction oversight.</u><=
/b><br><br>I must assume that this is an oversight. Otherwise, the proposal=
 makes no sense.<br><br>The proposal states that a function is implicitly r=
esumable if it calls `break resumable` or calls any resumable function. <i>=
Period</i>.<br><br>What about calling a resumable function within a resumab=
le expression? IE: `resumable auto x =3D resumable_func()`. No exception is=
 listed for this; calling `resumable_func` makes the calling function resum=
able, period. And if it&#39;s not in an implicitly resumable deduction cont=
ext, it is a compile error.<br><br>I have to assume that this was simply a =
mistake. That the section on implicit deduction was meant to have allowance=
s for resumable expressions, that any functions called in such an expressio=
n effectively don&#39;t count. Otherwise, <i>main itself</i> will have to b=
e resumable if you call any resumable function.<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&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
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_205_1539282392.1444231318943--
------=_Part_204_674066700.1444231318942--

.
