220 35955 <efd8b147-9992-4c1d-8248-86c5bba73016@isocpp.org> article
Path: news.gmane.org!.POSTED!not-for-mail
From: Nicol Bolas <jmckesson@gmail.com>
Newsgroups: gmane.comp.lang.c++.isocpp.proposals
Subject: Re: auto return proposal
Date: Sun, 17 Dec 2017 08:24:40 -0800 (PST)
Lines: 282
Approved: news@gmane.org
Message-ID: <efd8b147-9992-4c1d-8248-86c5bba73016@isocpp.org>
References: <CAB+4KHJCie_iwSm5OQVaHfsutdVJVbBo3ALecvn1ibsKg4uDTQ@mail.gmail.com>
Reply-To: std-proposals@isocpp.org
NNTP-Posting-Host: blaine.gmane.org
Mime-Version: 1.0
Content-Type: multipart/mixed; 
	boundary="----=_Part_12481_1414933727.1513527880817"
X-Trace: blaine.gmane.org 1513527766 19568 195.159.176.226 (17 Dec 2017 16:22:46 GMT)
X-Complaints-To: usenet@blaine.gmane.org
NNTP-Posting-Date: Sun, 17 Dec 2017 16:22:46 +0000 (UTC)
To: ISO C++ Standard - Future Proposals <std-proposals@isocpp.org>
Original-X-From: std-proposals+bncBCEKFTV6ZUMBBSNU3LIQKGQEVRJCAMA@isocpp.org Sun Dec 17 17:22:41 2017
Return-path: <std-proposals+bncBCEKFTV6ZUMBBSNU3LIQKGQEVRJCAMA@isocpp.org>
Envelope-to: gclcip-std-proposals@m.gmane.org
Original-Received: from mail-vk0-f70.google.com ([209.85.213.70])
	by blaine.gmane.org with esmtp (Exim 4.84_2)
	(envelope-from <std-proposals+bncBCEKFTV6ZUMBBSNU3LIQKGQEVRJCAMA@isocpp.org>)
	id 1eQbi5-0004nK-4J
	for gclcip-std-proposals@m.gmane.org; Sun, 17 Dec 2017 17:22:41 +0100
Original-Received: by mail-vk0-f70.google.com with SMTP id x11sf6968168vkd.4
        for <gclcip-std-proposals@m.gmane.org>; Sun, 17 Dec 2017 08:24:43 -0800 (PST)
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
        d=isocpp-org.20150623.gappssmtp.com; s=20150623;
        h=date:from:to:message-id:in-reply-to:references:subject:mime-version
         :x-original-sender:reply-to:precedence:mailing-list:list-id
         :list-post:list-help:list-archive:list-subscribe:list-unsubscribe;
        bh=QbZDLr8yWnreRvUINFXJ2HIR1VS42krpcp3B/7vOtHE=;
        b=OMdBI25yJN9sh9C8H9Ne4rHKaurwi2btkSce57XybtQAIeuryIOnF129o6SwrzAcQv
         j+18j6gzNzixuT4GMC/YxTS31xdUaWExxj21U0s5ERf8NTny9CyBujWaVJ1G8xIrHSvN
         C70QdVhlci+2WbHoUukyObviwwwNXZMTKARDdec3mg3vrixamjGI5JNXzcoDXrmnO8Ag
         14U9BHsyiaQxtphNk2jGMtlexyUV4Z78KdVD2y5hSTKaZBTDGw3505+TNvMjSl4UrXyq
         IKds8gGpTPUEPIkBFDlvcLzhS6KrV+OrzhwdIpZB/ZiTZIkUwPUM6HxoxTp7NC2IYT6O
         +c+A==
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
        d=gmail.com; s=20161025;
        h=date:from:to:message-id:in-reply-to:references:subject:mime-version
         :x-original-sender:reply-to:precedence:mailing-list:list-id
         :list-post:list-help:list-archive:list-subscribe:list-unsubscribe;
        bh=QbZDLr8yWnreRvUINFXJ2HIR1VS42krpcp3B/7vOtHE=;
        b=iilY+9zbRNNQul7g2Oc8IfQ7wPGl1cb4Oh1BSi/ghHwZFIxKGC2yKWEED1nhrXCNoW
         D74ExTcCChoI88rnce0jL36YERvAy+ML3R0IiZUWb2BwdsL9SuylO3qa9wdaghVwXwse
         Lq0jxAYTY8sgfo8ewcwWh5H3WS5sTlr/tDMRkE/R7M1qxwhzOf3tUJx6azcTShsLd03N
         Su2CldGFIv20fQFt64KMYxJDMZFJTFEyMf4LdAhSd7ZLRP/1/4alM6dE/E4g7s25o6pB
         AMrFW7Udy52fREhstbwtYJpiAQUn5vx2R+4nRC6l7WkUFRnzu5kqeOwAhvrE2vIBVxeu
         zPOQ==
X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
        d=1e100.net; s=20161025;
        h=x-gm-message-state:date:from:to:message-id:in-reply-to:references
         :subject:mime-version: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=QbZDLr8yWnreRvUINFXJ2HIR1VS42krpcp3B/7vOtHE=;
        b=OWd8KNtDqalywq6Zg6BKs8YOJpPOvnD7gRUum1ynCzkCqxmLZmBmBwoVN67P90WEco
         xOkKLZ4T5rKse/18wnkc8tLEJoWvXNWZ1uLxIFhXYaI8U3rfm0vv2KK7TaaGYRk4zaI1
         LZTP/gwv+30QRfLB7C9DrxtDbmGEIh3pVO8zxZVJKuHDlrRTu+DkVXIqoVWorLlJ+6qT
         IJxyX5TKDCjerCiTMKqcg0XmxhJC7Mjl8QZBw2sWijd/cQcZdz+evIVu9QjOCiRKl++F
         kV78ItvecRs0dxsFxKKG75/btiqw9KnuodIlPLuHtzx38x6g4E8hbuarUTbs5lrZ1qVm
         CRBw==
X-Gm-Message-State: AKGB3mK6+UVeoXa0HQb+RJ6bwT16BclOrMB9W/rKj3zB4HOYyBkTKUL0
	n2a+NG3L73ULfv8B+20R+uMdOA==
X-Google-Smtp-Source: ACJfBou476tG6NaonnvHulDUDUOuOIBDSPFXXJYtBQLcThDudr1NQZRuS6WQv+3qMRQ3g0LepZU0OA==
X-Received: by 10.31.68.5 with SMTP id r5mr8146793vka.84.1513527883157;
        Sun, 17 Dec 2017 08:24:43 -0800 (PST)
X-BeenThere: std-proposals@isocpp.org
Original-Received: by 10.31.139.85 with SMTP id n82ls669310vkd.2.gmail; Sun, 17 Dec
 2017 08:24:41 -0800 (PST)
X-Received: by 10.31.161.87 with SMTP id k84mr2093937vke.10.1513527881434;
        Sun, 17 Dec 2017 08:24:41 -0800 (PST)
In-Reply-To: <CAB+4KHJCie_iwSm5OQVaHfsutdVJVbBo3ALecvn1ibsKg4uDTQ@mail.gmail.com>
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: <https://groups.google.com/a/isocpp.org/group/std-proposals/post>, <mailto:std-proposals@isocpp.org>
List-Help: <https://support.google.com/a/isocpp.org/bin/topic.py?topic=25838>, <mailto:std-proposals+help@isocpp.org>
List-Archive: <https://groups.google.com/a/isocpp.org/group/std-proposals/>
List-Subscribe: <https://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>,
 <https://groups.google.com/a/isocpp.org/group/std-proposals/subscribe>
Xref: news.gmane.org gmane.comp.lang.c++.isocpp.proposals:35955
Archived-At: <http://permalink.gmane.org/gmane.comp.lang.c++.isocpp.proposals/35955>

------=_Part_12481_1414933727.1513527880817
Content-Type: multipart/alternative; 
	boundary="----=_Part_12482_1746157203.1513527880818"

------=_Part_12482_1746157203.1513527880818
Content-Type: text/plain; charset="UTF-8"



On Sunday, December 17, 2017 at 2:51:00 AM UTC-5, Andrew Tomazos wrote:
>
> It is a common pattern to write a function that:
>
> 1. declares a local variable of the return type of the function
> 2. modifies the local variable
> 3. returns the local variable
>
> In such cases, the return type must be specified to declare the return 
> type of the function, and then again to declare the type of the local 
> variable.  Further, a return statement must be provided that names the 
> local variable:
>
>     ReturnType f() {
>         ReturnType result_var;
>         ...
>         return result_var;
>     }
>
> I propose introducing a new kind of local variable declaration called an 
> auto return variable as follows:
>
>     ReturnType f() {
>         auto return result_var;
>         ...
>     }
>
> Informal specification:
>
> * An auto return variable declaration is equivalent to a variable 
> declaration that has the same type as the return type of its enclosing 
> function.
>
> * A function may contain at most one auto return variable, and it may only 
> appear as a direct substatement of the outermost scope of its function-body.
>
> * A function that contains an auto return variable shall behave as if an 
> additional return statement (that returns the auto return variable) is 
> appended to the end of its function-body.
>
> Roughly summarizing: an auto return variable has a type that is deduced 
> from the return type of the function and is automatically returned at the 
> end of the function.
>

I am completely against the idea of having a function automatically return* 
anything*. If I see a function with a non-`void/auto` return type that ends 
without returning or throwing, I should be able to assume that it is 
*broken* (unless there is an `[[unreachable]]` attribute) without having to 
look any further. Changing that, just to make the language* slightly* more 
convenient in a few cases?

No thanks.

Furthermore, what if you want to return early? What if you want to do a 
conditional return of the value you created? That's not possible with your 
syntax. What about `constexpr if` and its ability to return different types?

To me, the fundamental foundation of this feature, the primary reason for 
it to exist, is to support named return value elision directly in the 
language, with all of the semantic guarantees that returning a prvalue 
directly has in C++17. So that's what this proposal should be focused on, 
not this imposing of an automatic return.

Here's the general idea. Note that this is a pure strawman syntax; I'm not 
saying this should add keywords or whatever.

You can declare a variable as the function's return value:

return_value Typename var_name;

You can only declare a variable as the function's return value if the 
function returns a value type (you cannot create return value variables for 
references). Such a declaration counts as a `return` statement for return 
type deduction.

If you declare multiple variables in the same function's block as the 
return value, the program is ill-formed.

If a variable declared as the return value is destroyed by exiting the 
block's scope by any means* other than* a return or throw statement, then 
the program has undefined behavior. In effect, by declaring a variable to 
be a return value, you are making the hard statement that this object is 
what you are returning in this block. Or you're throwing out of it. This 
also means you cannot create `return_value`s within a loop, unless the loop 
instance you create one in actually returns.

But these rules do allow you to have conditional return variables:

auto foo(int param)
{
  if(param > 0)
  {
    return_value vector<int> ret;
    generate_data(ret);
    return ret;
  }

  return {}; //Deduced from `return_value` statement
}

The statement `return auto;` returns the current return value variable in 
scope. If no such variable is in the function's scope, the program is 
ill-formed. This shall be exactly equivalent to `return var_name;`, where 
`var_name` is the name of the return value variable.

If you are in the scope of a return value variable, and you issue a 
`return` statement that is anything* other than* `return auto;` or `return 
var_name;`, the program is ill-formed.

Issuing a `return var_name;` for a return value variable does not copy or 
move the value into the function's return value object.

In terms of interaction with the Coroutines TS... I have no idea. I'm not 
knowledgeable enough to know how that should work. The simplest solution is 
to just make it ill-formed to use `return_value` in a coroutine.

In all other ways, return value variables should be like regular stack 
variables.

-- 
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.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/efd8b147-9992-4c1d-8248-86c5bba73016%40isocpp.org.

------=_Part_12482_1746157203.1513527880818
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><br><br>On Sunday, December 17, 2017 at 2:51:00 AM UTC-5, =
Andrew Tomazos wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;m=
argin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=
=3D"ltr">It is a common pattern to write a function that:<div><br><div>1. d=
eclares a local variable of the return type of the function</div></div><div=
>2. modifies the local variable</div><div>3. returns the local variable</di=
v><div><br></div><div>In such cases, the return type must be specified to d=
eclare the return type of the function, and then again to declare the type =
of the local variable.=C2=A0 Further, a return statement must be provided t=
hat names the local variable:<br></div><div><br></div><div>=C2=A0 =C2=A0 Re=
turnType f() {</div><div>=C2=A0 =C2=A0 =C2=A0 =C2=A0 ReturnType result_var;=
</div><div>=C2=A0 =C2=A0 =C2=A0 =C2=A0 ...</div><div>=C2=A0 =C2=A0 =C2=A0 =
=C2=A0 return result_var;</div><div>=C2=A0 =C2=A0 }</div><div><br></div><di=
v>I propose introducing a new kind of local variable declaration called an =
auto return variable as follows:</div><div><br></div><div>=C2=A0 =C2=A0 Ret=
urnType f() {</div><div>=C2=A0 =C2=A0 =C2=A0 =C2=A0 auto return result_var;=
</div><div>=C2=A0 =C2=A0 =C2=A0 =C2=A0 ...</div><div>=C2=A0 =C2=A0 }</div><=
div><br></div><div>Informal specification:</div><div><br></div><div>* An au=
to return variable declaration is equivalent to a variable declaration that=
 has the same type as the return type of its enclosing function.</div><div>=
<br></div><div>* A function may contain at most one auto return variable, a=
nd it may only appear as a direct substatement of the outermost scope of it=
s function-body.</div><div><br></div><div>* A function that contains an aut=
o return variable shall behave as if an additional return statement (that r=
eturns the auto return variable) is appended to the end of its function-bod=
y.</div><div><br></div><div>Roughly summarizing: an auto return variable ha=
s a type that is deduced from the return type of the function and is automa=
tically returned at the end of the function.</div></div></blockquote><div><=
br></div><div>I am completely against the idea of having a function automat=
ically return<i> anything</i>. If I see a function with a non-`void/auto` r=
eturn type that ends without returning or throwing, I should be able to ass=
ume that it is <i>broken</i> (unless there is an `[[unreachable]]` attribut=
e) without having to look any further. Changing that, just to make the lang=
uage<i> slightly</i> more convenient in a few cases?</div><div><br></div><d=
iv>No thanks.</div><div><i><br></i></div><div>Furthermore, what if you want=
 to return early? What if you want to do a conditional return of the value =
you created? That&#39;s not possible with your syntax. What about `constexp=
r if` and its ability to return different types?</div><div><br></div><div>T=
o me, the fundamental foundation of this feature, the primary reason for it=
 to exist, is to support named return value elision directly in the languag=
e, with all of the semantic guarantees that returning a prvalue directly ha=
s in C++17. So that&#39;s what this proposal should be focused on, not this=
 imposing of an automatic return.</div><div><br></div><div>Here&#39;s the g=
eneral idea. Note that this is a pure strawman syntax; I&#39;m not saying t=
his should add keywords or whatever.</div><div><br></div><div>You can decla=
re a variable as the function&#39;s return value:</div><div><br></div><div =
class=3D"prettyprint" style=3D"border: 1px solid rgb(187, 187, 187); word-w=
rap: break-word; background-color: rgb(250, 250, 250);"><code class=3D"pret=
typrint"><div class=3D"subprettyprint"><span class=3D"styled-by-prettify" s=
tyle=3D"color: #000;">return_value </span><span class=3D"styled-by-prettify=
" style=3D"color: #606;">Typename</span><span class=3D"styled-by-prettify" =
style=3D"color: #000;"> var_name</span><span class=3D"styled-by-prettify" s=
tyle=3D"color: #660;">;</span></div></code></div><div><br></div><div>You ca=
n only declare a variable as the function&#39;s return value if the functio=
n returns a value type (you cannot create return value variables for refere=
nces). Such a declaration counts as a `return` statement for return type de=
duction.</div><div><br></div><div>If you declare multiple variables in the =
same function&#39;s block as the return value, the program is ill-formed.</=
div><div><br></div><div>If a variable declared as the return value is destr=
oyed by exiting the block&#39;s scope by any means<i> other than</i> a retu=
rn or throw statement, then the program has undefined behavior. In effect, =
by declaring a variable to be a return value, you are making the hard state=
ment that this object is what you are returning in this block. Or you&#39;r=
e throwing out of it. This also means you cannot create `return_value`s wit=
hin a loop, unless the loop instance you create one in actually returns.</d=
iv><div><br></div><div>But these rules do allow you to have conditional ret=
urn variables:</div><div><br></div><div class=3D"prettyprint" style=3D"bord=
er: 1px solid rgb(187, 187, 187); word-wrap: break-word; background-color: =
rgb(250, 250, 250);"><code class=3D"prettyprint"><div class=3D"subprettypri=
nt"><span class=3D"styled-by-prettify" style=3D"color: #008;">auto</span><s=
pan class=3D"styled-by-prettify" style=3D"color: #000;"> foo</span><span cl=
ass=3D"styled-by-prettify" style=3D"color: #660;">(</span><span class=3D"st=
yled-by-prettify" style=3D"color: #008;">int</span><span class=3D"styled-by=
-prettify" style=3D"color: #000;"> param</span><span class=3D"styled-by-pre=
ttify" style=3D"color: #660;">)</span><span class=3D"styled-by-prettify" st=
yle=3D"color: #000;"><br></span><span class=3D"styled-by-prettify" style=3D=
"color: #660;">{</span><span class=3D"styled-by-prettify" style=3D"color: #=
000;"><br>=C2=A0 </span><span class=3D"styled-by-prettify" style=3D"color: =
#008;">if</span><span class=3D"styled-by-prettify" style=3D"color: #660;">(=
</span><span class=3D"styled-by-prettify" style=3D"color: #000;">param </sp=
an><span class=3D"styled-by-prettify" style=3D"color: #660;">&gt;</span><sp=
an class=3D"styled-by-prettify" style=3D"color: #000;"> </span><span class=
=3D"styled-by-prettify" style=3D"color: #066;">0</span><span class=3D"style=
d-by-prettify" style=3D"color: #660;">)</span><span class=3D"styled-by-pret=
tify" style=3D"color: #000;"><br>=C2=A0 </span><span class=3D"styled-by-pre=
ttify" style=3D"color: #660;">{</span><span class=3D"styled-by-prettify" st=
yle=3D"color: #000;"><br>=C2=A0 =C2=A0 return_value vector</span><span clas=
s=3D"styled-by-prettify" style=3D"color: #080;">&lt;int&gt;</span><span cla=
ss=3D"styled-by-prettify" style=3D"color: #000;"> ret</span><span class=3D"=
styled-by-prettify" style=3D"color: #660;">;</span><span class=3D"styled-by=
-prettify" style=3D"color: #000;"><br>=C2=A0 =C2=A0 generate_data</span><sp=
an class=3D"styled-by-prettify" style=3D"color: #660;">(</span><span class=
=3D"styled-by-prettify" style=3D"color: #000;">ret</span><span class=3D"sty=
led-by-prettify" style=3D"color: #660;">);</span><span class=3D"styled-by-p=
rettify" style=3D"color: #000;"><br>=C2=A0 =C2=A0 </span><span class=3D"sty=
led-by-prettify" style=3D"color: #008;">return</span><span class=3D"styled-=
by-prettify" style=3D"color: #000;"> ret</span><span class=3D"styled-by-pre=
ttify" style=3D"color: #660;">;</span><span class=3D"styled-by-prettify" st=
yle=3D"color: #000;"><br>=C2=A0 </span><span class=3D"styled-by-prettify" s=
tyle=3D"color: #660;">}</span><span class=3D"styled-by-prettify" style=3D"c=
olor: #000;"><br><br>=C2=A0 </span><span class=3D"styled-by-prettify" style=
=3D"color: #008;">return</span><span class=3D"styled-by-prettify" style=3D"=
color: #000;"> </span><span class=3D"styled-by-prettify" style=3D"color: #6=
60;">{};</span><span class=3D"styled-by-prettify" style=3D"color: #000;"> <=
/span><span class=3D"styled-by-prettify" style=3D"color: #800;">//Deduced f=
rom `return_value` statement</span><span class=3D"styled-by-prettify" style=
=3D"color: #000;"><br></span><span class=3D"styled-by-prettify" style=3D"co=
lor: #660;">}</span></div></code></div><div><br></div><div>The statement `r=
eturn auto;` returns the current return value variable in scope. If no such=
 variable is in the function&#39;s scope, the program is ill-formed. This s=
hall be exactly equivalent to `return var_name;`, where `var_name` is the n=
ame of the return value variable.</div><div><br></div><div>If you are in th=
e scope of a return value variable, and you issue a `return` statement that=
 is anything<i> other than</i> `return auto;` or `return var_name;`, the pr=
ogram is ill-formed.</div><div><br></div><div>Issuing a `return var_name;` =
for a return value variable does not copy or move the value into the functi=
on&#39;s return value object.</div><div><br></div><div>In terms of interact=
ion with the Coroutines TS... I have no idea. I&#39;m not knowledgeable eno=
ugh to know how that should work. The simplest solution is to just make it =
ill-formed to use `return_value` in a coroutine.</div><div><br></div><div>I=
n all other ways, return value variables should be like regular stack varia=
bles.</div><div><br></div></div>

<p></p>

-- <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 />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/efd8b147-9992-4c1d-8248-86c5bba73016%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/efd8b147-9992-4c1d-8248-86c5bba73016=
%40isocpp.org</a>.<br />

------=_Part_12482_1746157203.1513527880818--

------=_Part_12481_1414933727.1513527880817--

.
