﻿<!DOCTYPE HTML>
<!DOCTYPE html PUBLIC "" ""><HTML><HEAD><META content="IE=11.0000" 
http-equiv="X-UA-Compatible">
 <TITLE>D0070_ReturnBeforeAwait</TITLE> 
<META http-equiv="Content-Type" content="text/html; charset=utf-8"> 
<STYLE type="text/css">
/* GitHub stylesheet for MarkdownPad (http://markdownpad.com) */
/* Author: Nicolas Hery - http://nicolashery.com */
/* Version: b13fe65ca28d2e568c6ed5d7f06581183df8f2ff */
/* Source: https://github.com/nicolahery/markdownpad-github */

/* RESET
=============================================================================*/

html, body, div, span, applet, object, iframe, h1, h2, h3, h4, h5, h6, p, blockquote, pre, a, abbr, acronym, address, big, cite, code, del, dfn, em, img, ins, kbd, q, s, samp, small, strike, strong, sub, sup, tt, var, b, u, i, center, dl, dt, dd, ol, ul, li, fieldset, form, label, legend, table, caption, tbody, tfoot, thead, tr, th, td, article, aside, canvas, details, embed, figure, figcaption, footer, header, hgroup, menu, nav, output, ruby, section, summary, time, mark, audio, video {
  margin: 0;
  padding: 0;
  border: 0;
}

/* BODY
=============================================================================*/

body {
  font-family: Helvetica, arial, freesans, clean, sans-serif;
  font-size: 14px;
  line-height: 1.6;
  color: #333;
  background-color: #fff;
  padding: 20px;
  max-width: 960px;
  margin: 0 auto;
}

body>*:first-child {
  margin-top: 0 !important;
}

body>*:last-child {
  margin-bottom: 0 !important;
}

/* BLOCKS
=============================================================================*/

p, blockquote, ul, ol, dl, table, pre {
  margin: 15px 0;
}

/* HEADERS
=============================================================================*/

h1, h2, h3, h4, h5, h6 {
  margin: 20px 0 10px;
  padding: 0;
  font-weight: bold;
  -webkit-font-smoothing: antialiased;
}

h1 tt, h1 code, h2 tt, h2 code, h3 tt, h3 code, h4 tt, h4 code, h5 tt, h5 code, h6 tt, h6 code {
  font-size: inherit;
}

h1 {
  font-size: 28px;
  color: #000;
}

h2 {
  font-size: 24px;
  border-bottom: 1px solid #ccc;
  color: #000;
}

h3 {
  font-size: 18px;
}

h4 {
  font-size: 16px;
}

h5 {
  font-size: 14px;
}

h6 {
  color: #777;
  font-size: 14px;
}

body>h2:first-child, body>h1:first-child, body>h1:first-child+h2, body>h3:first-child, body>h4:first-child, body>h5:first-child, body>h6:first-child {
  margin-top: 0;
  padding-top: 0;
}

a:first-child h1, a:first-child h2, a:first-child h3, a:first-child h4, a:first-child h5, a:first-child h6 {
  margin-top: 0;
  padding-top: 0;
}

h1+p, h2+p, h3+p, h4+p, h5+p, h6+p {
  margin-top: 10px;
}

/* LINKS
=============================================================================*/

a {
  color: #4183C4;
  text-decoration: none;
}

a:hover {
  text-decoration: underline;
}

/* LISTS
=============================================================================*/

ul, ol {
  padding-left: 30px;
}

ul li > :first-child, 
ol li > :first-child, 
ul li ul:first-of-type, 
ol li ol:first-of-type, 
ul li ol:first-of-type, 
ol li ul:first-of-type {
  margin-top: 0px;
}

ul ul, ul ol, ol ol, ol ul {
  margin-bottom: 0;
}

dl {
  padding: 0;
}

dl dt {
  font-size: 14px;
  font-weight: bold;
  font-style: italic;
  padding: 0;
  margin: 15px 0 5px;
}

dl dt:first-child {
  padding: 0;
}

dl dt>:first-child {
  margin-top: 0px;
}

dl dt>:last-child {
  margin-bottom: 0px;
}

dl dd {
  margin: 0 0 15px;
  padding: 0 15px;
}

dl dd>:first-child {
  margin-top: 0px;
}

dl dd>:last-child {
  margin-bottom: 0px;
}

/* CODE
=============================================================================*/

pre, code, tt {
  font-size: 12px;
  font-family: Consolas, "Liberation Mono", Courier, monospace;
}

code, tt {
  margin: 0 0px;
  padding: 0px 0px;
  white-space: nowrap;
  border: 1px solid #eaeaea;
  background-color: #f8f8f8;
  border-radius: 3px;
}

pre>code {
  margin: 0;
  padding: 0;
  white-space: pre;
  border: none;
  background: transparent;
}

pre {
  background-color: #f8f8f8;
  border: 1px solid #ccc;
  font-size: 13px;
  line-height: 19px;
  overflow: auto;
  padding: 6px 10px;
  border-radius: 3px;
}

pre code, pre tt {
  background-color: transparent;
  border: none;
}

kbd {
    -moz-border-bottom-colors: none;
    -moz-border-left-colors: none;
    -moz-border-right-colors: none;
    -moz-border-top-colors: none;
    background-color: #DDDDDD;
    background-image: linear-gradient(#F1F1F1, #DDDDDD);
    background-repeat: repeat-x;
    border-color: #DDDDDD #CCCCCC #CCCCCC #DDDDDD;
    border-image: none;
    border-radius: 2px 2px 2px 2px;
    border-style: solid;
    border-width: 1px;
    font-family: "Helvetica Neue",Helvetica,Arial,sans-serif;
    line-height: 10px;
    padding: 1px 4px;
}

/* QUOTES
=============================================================================*/

blockquote {
  border-left: 4px solid #DDD;
  padding: 0 15px;
  color: #777;
}

blockquote>:first-child {
  margin-top: 0px;
}

blockquote>:last-child {
  margin-bottom: 0px;
}

/* HORIZONTAL RULES
=============================================================================*/

hr {
  clear: both;
  margin: 15px 0;
  height: 0px;
  overflow: hidden;
  border: none;
  background: transparent;
  border-bottom: 4px solid #ddd;
  padding: 0;
}

/* TABLES
=============================================================================*/

table th {
  font-weight: bold;
}

table th, table td {
  border: 1px solid #ccc;
  padding: 6px 13px;
}

table tr {
  border-top: 1px solid #ccc;
  background-color: #fff;
}

table tr:nth-child(2n) {
  background-color: #f8f8f8;
}

/* IMAGES
=============================================================================*/

img {
  max-width: 100%
}
</STYLE>
 
<STYLE type="text/css">
.highlight  { background: #ffffff; }
.highlight .c { color: #999988; font-style: italic } /* Comment */
.highlight .err { color: #a61717; background-color: #e3d2d2 } /* Error */
.highlight .k { font-weight: bold } /* Keyword */
.highlight .o { font-weight: bold } /* Operator */
.highlight .cm { color: #999988; font-style: italic } /* Comment.Multiline */
.highlight .cp { color: #999999; font-weight: bold } /* Comment.Preproc */
.highlight .c1 { color: #999988; font-style: italic } /* Comment.Single */
.highlight .cs { color: #999999; font-weight: bold; font-style: italic } /* Comment.Special */
.highlight .gd { color: #000000; background-color: #ffdddd } /* Generic.Deleted */
.highlight .gd .x { color: #000000; background-color: #ffaaaa } /* Generic.Deleted.Specific */
.highlight .ge { font-style: italic } /* Generic.Emph */
.highlight .gr { color: #aa0000 } /* Generic.Error */
.highlight .gh { color: #999999 } /* Generic.Heading */
.highlight .gi { color: #000000; background-color: #ddffdd } /* Generic.Inserted */
.highlight .gi .x { color: #000000; background-color: #aaffaa } /* Generic.Inserted.Specific */
.highlight .go { color: #888888 } /* Generic.Output */
.highlight .gp { color: #555555 } /* Generic.Prompt */
.highlight .gs { font-weight: bold } /* Generic.Strong */
.highlight .gu { color: #aaaaaa } /* Generic.Subheading */
.highlight .gt { color: #aa0000 } /* Generic.Traceback */
.highlight .kc { font-weight: bold } /* Keyword.Constant */
.highlight .kd { font-weight: bold } /* Keyword.Declaration */
.highlight .kp { font-weight: bold } /* Keyword.Pseudo */
.highlight .kr { font-weight: bold } /* Keyword.Reserved */
.highlight .kt { color: #445588; font-weight: bold } /* Keyword.Type */
.highlight .m { color: #009999 } /* Literal.Number */
.highlight .s { color: #d14 } /* Literal.String */
.highlight .na { color: #008080 } /* Name.Attribute */
.highlight .nb { color: #0086B3 } /* Name.Builtin */
.highlight .nc { color: #445588; font-weight: bold } /* Name.Class */
.highlight .no { color: #008080 } /* Name.Constant */
.highlight .ni { color: #800080 } /* Name.Entity */
.highlight .ne { color: #990000; font-weight: bold } /* Name.Exception */
.highlight .nf { color: #990000; font-weight: bold } /* Name.Function */
.highlight .nn { color: #555555 } /* Name.Namespace */
.highlight .nt { color: #000080 } /* Name.Tag */
.highlight .nv { color: #008080 } /* Name.Variable */
.highlight .ow { font-weight: bold } /* Operator.Word */
.highlight .w { color: #bbbbbb } /* Text.Whitespace */
.highlight .mf { color: #009999 } /* Literal.Number.Float */
.highlight .mh { color: #009999 } /* Literal.Number.Hex */
.highlight .mi { color: #009999 } /* Literal.Number.Integer */
.highlight .mo { color: #009999 } /* Literal.Number.Oct */
.highlight .sb { color: #d14 } /* Literal.String.Backtick */
.highlight .sc { color: #d14 } /* Literal.String.Char */
.highlight .sd { color: #d14 } /* Literal.String.Doc */
.highlight .s2 { color: #d14 } /* Literal.String.Double */
.highlight .se { color: #d14 } /* Literal.String.Escape */
.highlight .sh { color: #d14 } /* Literal.String.Heredoc */
.highlight .si { color: #d14 } /* Literal.String.Interpol */
.highlight .sx { color: #d14 } /* Literal.String.Other */
.highlight .sr { color: #009926 } /* Literal.String.Regex */
.highlight .s1 { color: #d14 } /* Literal.String.Single */
.highlight .ss { color: #990073 } /* Literal.String.Symbol */
.highlight .bp { color: #999999 } /* Name.Builtin.Pseudo */
.highlight .vc { color: #008080 } /* Name.Variable.Class */
.highlight .vg { color: #008080 } /* Name.Variable.Global */
.highlight .vi { color: #008080 } /* Name.Variable.Instance */
.highlight .il { color: #009999 } /* Literal.Number.Integer.Long */
.pl-c {
    color: #969896;
}

.pl-c1,.pl-mdh,.pl-mm,.pl-mp,.pl-mr,.pl-s1 .pl-v,.pl-s3,.pl-sc,.pl-sv {
    color: #0086b3;
}

.pl-e,.pl-en {
    color: #795da3;
}

.pl-s1 .pl-s2,.pl-smi,.pl-smp,.pl-stj,.pl-vo,.pl-vpf {
    color: #333;
}

.pl-ent {
    color: #63a35c;
}

.pl-k,.pl-s,.pl-st {
    color: #a71d5d;
}

.pl-pds,.pl-s1,.pl-s1 .pl-pse .pl-s2,.pl-sr,.pl-sr .pl-cce,.pl-sr .pl-sra,.pl-sr .pl-sre,.pl-src,.pl-v {
    color: #df5000;
}

.pl-id {
    color: #b52a1d;
}

.pl-ii {
    background-color: #b52a1d;
    color: #f8f8f8;
}

.pl-sr .pl-cce {
    color: #63a35c;
    font-weight: bold;
}

.pl-ml {
    color: #693a17;
}

.pl-mh,.pl-mh .pl-en,.pl-ms {
    color: #1d3e81;
    font-weight: bold;
}

.pl-mq {
    color: #008080;
}

.pl-mi {
    color: #333;
    font-style: italic;
}

.pl-mb {
    color: #333;
    font-weight: bold;
}

.pl-md,.pl-mdhf {
    background-color: #ffecec;
    color: #bd2c00;
}

.pl-mdht,.pl-mi1 {
    background-color: #eaffea;
    color: #55a532;
}

.pl-mdr {
    color: #795da3;
    font-weight: bold;
}

.pl-mo {
    color: #1d3e81;
}
.task-list {
padding-left:10px;
margin-bottom:0;
}

.task-list li {
    margin-left: 20px;
}

.task-list-item {
list-style-type:none;
padding-left:10px;
}

.task-list-item label {
font-weight:400;
}

.task-list-item.enabled label {
cursor:pointer;
}

.task-list-item+.task-list-item {
margin-top:3px;
}

.task-list-item-checkbox {
display:inline-block;
margin-left:-20px;
margin-right:3px;
vertical-align:1px;
}
</STYLE>
 
<META name="GENERATOR" content="MSHTML 11.00.9600.18036"></HEAD> 
<BODY>
<TABLE>
  <THEAD>
  <TR>
    <TH>Document Number:</TH>
    <TH>P0070R00</TH></TR></THEAD>
  <TBODY>
  <TR>
    <TD>Date:</TD>
    <TD>2015-09-12</TD></TR>
  <TR>
    <TD>Project:</TD>
    <TD>Programming Language C++, Evolution</TD></TR>
  <TR>
    <TD>Revises:</TD>
    <TD>none</TD></TR>
  <TR>
    <TD>Reply to:</TD>
    <TD>gorn@microsoft.com</TD></TR></TBODY></TABLE>
<H1 id="p0070r00-coroutines-return-before-await">P0070R00: Coroutines: Return 
before Await</H1>
<H2 id="introduction">Introduction</H2>
<P>One of the concerns raised in Lenexa was that having a tag on the coroutine 
definition would be useful to help the compiler process the body of the function 
since coroutines require special handling of the return statements, but it is 
not known in advance whether a function is a coroutine or not until we encounter 
<CODE>await</CODE> or <CODE>yield</CODE> expressions. The vote taken (but not 
recorded on the wiki) was against having a tag. However, one of the suggestions 
made during the session was to introduce a new keyword, <CODE>co_return</CODE> 
that must be used in place of <CODE>return</CODE> in coroutines and coroutines 
only. This paper explores this suggestion and recommends against it. </P>
<P>The updated wording is provided in a separate paper <A href="http://wg21.link/P0057R00">P0057R00</A>.</P>
<H2 id="technical-difficulties-question">Technical difficulties question</H2>
<P>After Lenexa, we implemented "return before await" in MSVC compiler by 
deferring semantic analysis of the return statements until the end of the 
function. It did not require heroic effort as we already do several rewriting of 
the expressions within the body of the function after we've seen its body prior 
to emitting low-level representation to the back-end. If the function declared 
return type is <CODE>auto</CODE> or <CODE>decltype(auto)</CODE>, we deduce the 
return type on the first return statement seen as implied by 
N4527/[dcl.spec.auto]/11. </P>
<P>In GCC, according to a person familiar with it, a similar processing was done 
to handle named return value optimization, namely, GCC had to first observe all 
the return statements in the function before deciding on how to handle them, 
which meant that it had to parse until the end of the function before finalizing 
processing of the return statements. </P>
<P>This new information lessens the <EM>technical difficulty</EM> motivation to 
introducing new statement / keyword <CODE>co_return</CODE>.</P>
<H2 id="potential-source-of-confusion">Potential source of confusion</H2>
<P>Another argument raised was that without a different kind of return 
statement, coroutines would be confusing to the reader. For example, consider 
the following coroutine:</P>
<PRE><CODE>future&lt;int&gt; deep_thought() {
  await 7'500'000'000h;
  return 42;
}
</CODE></PRE>
<P>One may find it confusing that in a function returning 
<CODE>future&lt;int&gt;</CODE> we are allowing a return of an integer value. 
Intuitive reasoning behind this syntax is that coroutine when suspended must 
return back to the caller, and since the eventual result of the computation 
reported via <CODE>return</CODE> is not available yet, the caller receives a 
placeholder object, such as <CODE>future&lt;int&gt;</CODE> that can be used to 
obtain eventual value once available. Thus, in a coroutine, <CODE>return</CODE> 
statement indicates that the function is terminated, control needs to be 
returned to the caller and the result of the computation of the function to be 
provided to the interested party. This is similar to a normal function, with the 
exception that in a coroutine, <CODE>return</CODE> statement provides an 
<EM>eventual</EM> return value, as opposed to <EM>immediate</EM> return value 
and the interested party is not necessarily the function to which we return, but 
the one consuming the result from the <CODE>future&lt;int&gt;</CODE>. </P>
<P>Indeed, all of the programming languages that adopted an await construct end 
up making the same determination with respect to the return statement.</P>
<PRE><CODE>// Python                            // PHP/HACK
async def deep_thought(n):           async function DeepThought(): Awaitable&lt;int&gt; {
  await delay(7500000000);             await Awaitable.Delay(7500000000);
  return 42                            return 42;
                                     }
// Dart                              // C#                                
Future&lt;int&gt; DeepThought() async {    async Task&lt;int&gt; DeepThought() {       
  await Future.Delay(7500000000);      await Task.Delay(7500000000);
  return 42;                           return 42;                    
}                                    }
</CODE></PRE>
<P>Requiring a programmer to use a different kind of return statement in 
coroutines, seems unnecessary, given the practical experience of using similar 
constructs in other languages.</P>
<H2 id="but-what-about-generators-">But what about generators?</H2>
<P>Should we keep coroutines using <CODE>await</CODE> as proposed, but require 
to use a <CODE>co_return</CODE> statement only in generators?</P>
<P>First, unlike coroutines in other languages, in C++, coroutines are 
generalized functions. Library author defining <CODE>coroutine_traits</CODE> 
decides whether the function to which the trait applies will have the semantics 
of a generator, a task, an asynchronous generator, or even a regular function. 
Having a different kind of return statement breaks this property. </P>
<P>Second, comparing with existing practice in other language one finds that 3 
in 4 chose not to mangle the return statement in generators.</P>
<PRE><CODE>// Python                            // PHP/HACK
def gen(n):                          function gen() {
  yield 5                              yield 5;
  return                               return;
                                     }
// Dart                              // C#                                                 
Iterable gen() sync* {               IEnumerable&lt;int&gt; gen() {              
  yield 5;                             yield return 5;
  return;                              yield break;                    
}                                    }
</CODE></PRE>
<P>Even in the last case, C# design team preference was to use <CODE>yield 
expr</CODE> as a yield statement, but, because C# 1.0 was out for more than 5 
years, they did not want to break existing customers, they end up with 
<CODE>yield return</CODE> and that led to the decision to use <CODE>yield 
break</CODE>.</P><!--
Note, that with respect to using a tag to mark the coroutine, most of the languages do not have consistent chose to mark a coroutine with `await` with a tag, and leave the generator case tagless.--> 

<H2 id="conclusion">Conclusion</H2>
<P>Using return statement in coroutines is existing practice in other languages. 
There is no need reason to believe that C++ developers are more easily confused 
than developers in other languages and given that implementation experience 
showed that this is technically feasible, we recommend to stay with the return 
statement in the coroutines.</P>
<H2 id="references">References</H2>
<P><A href="https://www.python.org/dev/peps/pep-0492/">Python</A>: PEP 0492 -- 
Coroutines with async and await syntax (<A href="https://www.python.org/dev/peps/pep-0492/">https://www.python.org/dev/peps/pep-0492/</A>)<BR><A 
href="http://docs.hhvm.com/manual/en/hack.async.php)">Hack</A>: Hack Language 
Reference (<A 
href="http://docs.hhvm.com/manual/en/hack.async.php">http://docs.hhvm.com/manual/en/hack.async.php</A>)<BR>[C#]: 
C# 5.0 Language Specification (<A href="https://msdn.microsoft.com/en-us/library/ms228593(v=vs.110).aspx">https://msdn.microsoft.com/en-us/library/ms228593(v=vs.110).aspx</A>)<BR><A 
href="http://queue.acm.org/detail.cfm?id=2747873)">Dart</A>: Spicing Up Dart 
with Side Effects (<A 
href="http://queue.acm.org/detail.cfm?id=2747873">http://queue.acm.org/detail.cfm?id=2747873</A>)<BR><A 
href="http://open-std.org/JTC1/SC22/WG21/docs/papers/2015/n4527.pdf">N4527</A>: 
Working Draft, Standard for Programming Language C++ (<A href="http://open-std.org/JTC1/SC22/WG21/docs/papers/2015/n4527.pdf">http://open-std.org/JTC1/SC22/WG21/docs/papers/2015/n4527.pdf</A>)<BR><A 
href="https://isocpp.org/files/papers/N4402.pdf">N4402</A>: Resumable Functions 
(revision 4) (<A 
href="https://isocpp.org/files/papers/N4402.pdf">https://isocpp.org/files/papers/N4402.pdf</A>)<BR><A 
href="http://wg21.link/P0057R00">P0057r00</A>: Wording for Coroutines, Revision 
3 (<A href="http://wg21.link/P0057R00">http://wg21.link/P0057R00</A>)</P><!--   


In fact, `yield expr` is a syntactic sugar for `await $promise.yield_value(expr)`.


## Should we revisit the tag question then?

One might notice in the examples in the previous section, all of the other langauges had a tag on the declaration of the function. Should we revisit the issue? Before we do that, let's examine whether the same set of languages use tag for other kinds of coroutines. 

```
// Python                            // PHP/HACK
def gen(n):                          function gen() {
  yield 5                              yield 5;
  return                               return;
                                     }
// Dart                              // C#                                                 
Iterable gen() sync* {               IEnumerable<int> gen() {              
  yield 5;                             yield return 5;
  return;                              yield break;                    
}                                    }
```

With generators we see less consistency. Dart chose to stick with a tag (sync* for generator as opposed to `async` for `await` case). All other chose not to have a tag. C# stands out as it chose to go with with "whitespace keywords" yield return and yield break in a generator. According to the people on the design team of C# coroutines and they explained that their preference was to use `yield` as a keyword, but, since C# was already out for a five years they did not want break existing customers using `yield` as identifier.

## But what about generators?

In C++, coroutines are generalized functions. Depending on `coroutine_traits` they can be use to build a generator, a task-like coroutine with an eventual value, an asynchronous generators, and regular function. 

Indeed, a regular function returning type T can be though of as a coroutine with the following coroutine_promise defined.

```
struct promise_type {
  T result;
  T get_return_object() { return result; }
  void return_value(T v) { result = move(v); }
  suspend_never inital_suspend() {}
  suspend_never final_suspend() {}
};
```

bla bla


## Should we revisit the tag question again?


--> <!--
## Consistency argument

One may argue that if we end up with keywords `co_await`, `co_yield`, would it be nicer to have a `co_return` statement to match the other coroutine related keywords?

First, we are not sure what the final decision on the name of the keywords would be. The sense of the room was that we can make `await` a keyword and only the `yield` was a problem. We may end up with `await` and `yieldexpr`, for example. With this choice of keywords there is no aesthetically important reason why the name of the return statement needs to be mangled.

Second, one of the usage of function body transformation that coroutine allows is to deal with expansion of `value_or` using *await-expression*. 
  --> <!--
Let's consider two aspects of what a `return` statement does in a non-coroutine function. (I am using C11 standard wording as it is more verbose and spells out the details I want to highlight more than C++ standard wording).

1. A return statement **terminates execution** of the current function and **returns control to its caller**. A function may have any number of return statements.
2. If a return statement with an expression is executed, **the value of the expression** is returned to the caller **as the value of the function call expression**.

From the outside (caller perspective), `deep_thought` is a regular function. When a caller calls it, it expects a future<int> that can be used to get to the eventual value when the deferred / asynchronous computation linked to the future computes the value. Whether the future returned is the result of a call to `std::async` or produces as a result of a suspension of a coroutine due to *await-expression* is an implementation detail not observed by the caller. 

 On the implementation side, coroutine is a generalization of the function. It adds one more operation to a function body, namely, ** return to its caller without terminating the function** and without returning the result of the function yet, via `await` or `yield`. We did not get to the `return` statement yet. We don't know the result of the function (computation represented by the function) yet. But, we need to give a value back to the caller  --> 
<!-- 
## Interactions with auto type deduction

Consider the following example N4527/[dcl.spec.auto]:

```
auto sum(int i) {
  if (i == 1)
    return i; // sum’s return type is int
  else
    return sum(i-1)+i; // OK, sum’s return type has been deduced
}
```
Now let's add an `await` to it.

```
auto sum(int i) {
  if (i == 1)
    return i; // sum’s return type is int
  else if (i < 1'000'000)
    return sum(i-1)+i; // OK, sum’s return type has been deduced
  else
    return await cloud_sum(i);
}
```
--> <!--
# DXXXX: Coroutines: Lexical Consideration

## Introduction

In Lenexa, there were two lexical questions with respect to coroutines. 
1. Do coroutines need to have a tag of some sort in the definition to indicate that it is a coroutine.
2. Can we use yield as a keyword?
3. 

## Compiler implementer difficulty

## DART

## C#

### Return Statement

8.9.4 The return statement
**The return statement returns control to the current caller of the function in which the return statement appears.**
return-statement:
return   expressionopt   ;
A return statement with no expression can be used only in a function member that does not compute a value, that is, a method with the result type (§10.6.10) void, the set accessor of a property or indexer, the add and remove accessors of an event, an instance constructor, a static constructor, or a destructor.
A return statement with an expression can only be used in a function member that computes a value, that is, a method with a non-void result type, the get accessor of a property or indexer, or a user-defined operator. An implicit conversion (§6.1) must exist from the type of the expression to the return type of the containing function member.
Return statements can also be used in the body of anonymous function expressions (§7.15), and participate in determining which conversions exist for those functions.
It is a compile-time error for a return statement to appear in a finally block (§8.10).
A return statement is executed as follows:
•    If the return statement specifies an expression, the expression is evaluated and the resulting value is converted to the return type of the containing function by an implicit conversion. The result of the conversion becomes the result value produced by the function.
•    If the return statement is enclosed by one or more try or catch blocks with associated finally blocks, control is initially transferred to the finally block of the innermost try statement. When and if control reaches the end point of a finally block, control is transferred to the finally block of the next enclosing try statement. This process is repeated until the finally blocks of all enclosing try statements have been executed.
** If the containing function is not an async function, control is returned to the caller of the containing function along with the result value, if any. If the containing function is an async function, control is returned to the current caller, and the result value, if any, is recorded in the return task as described in (§10.14.1).**
Because a return statement unconditionally transfers control elsewhere, the end point of a return statement is never reachable.

### C++ Return Statement

6.6.3 The return statement [stmt.return]
** 1 A function returns to its caller by the return statement. **
2 The expression or braced-init-list of a return statement is called its operand. A return statement with
no operand shall be used only in a function whose **immediate or eventual** return type is cv void, a constructor (12.1), or a
destructor (12.4). A return statement with an operand of type void shall be used only in a function whose **immediate or eventual** return type is cv void. A return statement with any other operand shall be used only in a function whose
return type is not cv void; the return statement initializes the object or reference to be returned by copyinitialization
(8.5) from the operand. [ Note: A return statement can involve the construction and copy or
move of a temporary object (12.2). A copy or move operation associated with a return statement may be
elided or considered as an rvalue for the purpose of overload resolution in selecting a constructor (12.8).
—end note ] [ Example:
std::pair<std::string,int> f(const char* p, int x) {
return {p,x};
}
—end example ] Flowing off the end of a function is equivalent to a return with no value; this results in
undefined behavior in a value-returning function.
3 The copy-initialization of the returned entity is sequenced before the destruction of temporaries at the end
of the full-expression established by the operand of the return statement, which, in turn,

### C++ Coroutine return statement (Old Version)

1 A resumable function returns to its caller by the return statement or when suspended at a suspend-resume
point.
2 In this clause, _Pr refers to the promise object of the enclosing resumable function.
3 A return statement with neither an expression nor a braced-init-list can be used only in resumable functions
that do not produce an eventual value or have an eventual return type of void. In the latter case, completion
of the resumable function is reported by calling _Pr.set_result(). A return statement with an expression
of non-void type can be used only in resumable functions producing an eventual value; the value of the
expression is supplied to a promise of the resumable function by calling _Pr.set_result(expression ) or
_Pr.set_result(braced-init-list ).
[ Example:
std::future<std::pair<std::string,int>> f(const char* p, int x) {
await g();
return {p,x};
}
—end example ]
Flowing off the end of a function is equivalent to a return with no value; the program is not well-formed if
this happens in an eventual-value-returning resumable function.
4 A return statement with an expression of type void can be used only in functions without an eventual
return type or with an eventual return type of void; the expression is evaluated just before the function
returns to its caller.
5 Prior to returning to the caller, a resumable function evaluates _Pr.final_suspend() predicate. If _-
Pr.final_suspend() contextually converted to bool evaluates to true, the resumable function suspends at
final suspend point (8.4.4), otherwise, resumable function flows off the end of the function-body and destroys
the resumable function state and frees any extra memory dynamically allocated to store the state.

### CoReturn version

6.6.4 The coroutine-return-keyword statement [stmt.coreturn]
Add this section to 6.6.
1 A coroutine returns to its caller by the coroutine-return-keyword statement or when suspended
at a suspend-resume point (8.4.4). A coroutine-return-keyword statement shall not appear
in a function other than a coroutine.
2 If the promise type (8.4.4) of the coroutine defines the member function return_void, the coroutine
is considered to have an eventual return type of void, if the promise type (8.4.4) of the
coroutine defines the member function return_value, the coroutine is considered to have a nonvoid
eventual return type, otherwise, the coroutine is considered not to have an eventual return
type. If the promise type defines both return_value and return_void member functions, the
program is ill-formed.
3 In this section, p refers to the promise object (8.4.4) of the enclosing coroutine.
4 A coroutine-return-keyword statement with neither an expression nor a braced-init-list can be
used only in coroutines that do not have an eventual return type or have an eventual return type
of void. In the latter case, completion of the coroutine is signaled to the promise of the coroutine
by calling p.return_void(). A coroutine-return-keyword statement with an expression of
non-void type can be used only in coroutines producing an eventual value; the value of the
expression is supplied to the promise of the coroutine by calling p.return_value(expression )
or p.return_value(braced-init-list ). Flowing off the end of a coroutine is equivalent to a
coreturn with no value; this results in undefined behavior in a coroutine with non-void return
type.
5 Prior to returning to the caller, a coroutine evaluates the p.final_suspend() predicate. If
p.final_suspend() contextually converted to bool evaluates to true, the coroutine suspends
at final suspend point (8.4.4), otherwise, the coroutine destroys the coroutine state (8.4.4) and
frees the memory dynamically allocated (if any) to store the state.
6 A coroutine-return-keyword statement with an expression of type cv void can be used only in
functions without an eventual return type or with an eventual return type of void; the expression
is evaluated just before the call to p.final_suspend() and p.return_void() respectively.

### Experimental version

### PHP

async function gen_add(Awaitable<int> $genA, Awaitable<int> $genB): Awaitable<int> {
  list($a, $b) = await genva($genA, $genB);
  return $a + $b;
}

--> 
</BODY></HTML><!-- This document was created with MarkdownPad, the Markdown editor for Windows (http://markdownpad.com) -->
