220 14510 <ea89a2cb27274d6bb897412d29b47751@BL2PR03MB337.namprd03.prod.outlook.com> article
Path: news.gmane.org!not-for-mail
From: Gor Nishanov <gorn@microsoft.com>
Newsgroups: gmane.comp.lang.c++.isocpp.proposals
Subject: RE: Re: Range-based if versus  - await do-catch statement
Date: Wed, 12 Nov 2014 23:20:21 +0000
Lines: 534
Approved: news@gmane.org
Message-ID: <ea89a2cb27274d6bb897412d29b47751@BL2PR03MB337.namprd03.prod.outlook.com>
References: <CADbh+eQCaTPArs7YBUg9mYwrnJ2Gu3SRAfqUbPiLscpyxV8JqQ@mail.gmail.com>
 <m3tvcu$9ia$1@ger.gmane.org> <5463DF5A.7020607@wanadoo.fr>
Reply-To: std-proposals@isocpp.org
NNTP-Posting-Host: plane.gmane.org
Mime-Version: 1.0
Content-Type: multipart/alternative;
	boundary="_000_ea89a2cb27274d6bb897412d29b47751BL2PR03MB337namprd03pro_"
X-Trace: ger.gmane.org 1415834434 3904 80.91.229.3 (12 Nov 2014 23:20:34 GMT)
X-Complaints-To: usenet@ger.gmane.org
NNTP-Posting-Date: Wed, 12 Nov 2014 23:20:34 +0000 (UTC)
To: "Vicente J. Botet Escriba" <vicente.botet@wanadoo.fr>,
	"std-proposals@isocpp.org" <std-proposals@isocpp.org>
Original-X-From: std-proposals+bncBDPLV5PARYJRBOGWR6RQKGQE4WC26MQ@isocpp.org Thu Nov 13 00:20:26 2014
Return-path: <std-proposals+bncBDPLV5PARYJRBOGWR6RQKGQE4WC26MQ@isocpp.org>
Envelope-to: gclcip-std-proposals@m.gmane.org
Original-Received: from mail-vc0-f199.google.com ([209.85.220.199])
	by plane.gmane.org with esmtp (Exim 4.69)
	(envelope-from <std-proposals+bncBDPLV5PARYJRBOGWR6RQKGQE4WC26MQ@isocpp.org>)
	id 1XohD7-0004jZ-FH
	for gclcip-std-proposals@m.gmane.org; Thu, 13 Nov 2014 00:20:25 +0100
Original-Received: by mail-vc0-f199.google.com with SMTP id id10sf9353883vcb.10
        for <gclcip-std-proposals@m.gmane.org>; Wed, 12 Nov 2014 15:20:24 -0800 (PST)
X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
        d=1e100.net; s=20130820;
        h=x-gm-message-state:from:to:subject:thread-topic:thread-index:date
         :message-id:references:in-reply-to:accept-language:mime-version
         :x-original-sender:x-original-authentication-results:reply-to
         :precedence:mailing-list:list-id:list-post:list-help:list-archive
         :list-subscribe:list-unsubscribe:content-language:content-type;
        bh=ChoONQlj3nPhl05YXnMNVLS11ndRXxb4nSyQvN3S4qc=;
        b=hDMiOz98f9BQv9PB4sdBUK5QTgg65n69eqrCw9npA+mdZ0+6THzzxbtt5M44vITOgb
         CwXuoedcph+F3ewlfqk/jPdReZja6mkWYsr4yoZgU0KMtej/mVcO81o1QyLrRU0FqhwU
         DLng9TSo0hUWrkPbdxeDTOvyNQ5SVjAMibqWQ9YDWsAlZIKhHaarbkxFrnGEFny1doV6
         pmfRi1CLoWb2zlFKOU0fR+7NTYjllf0Hx2Fw8Q8EtEQ++C3C4vW7IaUroY2A+ljBdp5L
         TVbowDEvK2TXKPiegK1ITB8CHoe1yVosOLo5VEFPdKxY3O7k8trZ5G2BJ1n 
X-Gm-Message-State: ALoCoQnWgXl55sKe4MXLr1iBr89tpgnhrnw+NWY+jcyBpV/P1XeB9c+nW903ys2v/zW/jTi0m8C1
X-Received: by 10.236.229.193 with SMTP id h61mr39936834yhq.40.1415834424802;
        Wed, 12 Nov 2014 15:20:24 -0800 (PST)
X-BeenThere: std-proposals@isocpp.org
Original-Received: by 10.107.162.13 with SMTP id l13ls2318550ioe.104.gmail; Wed, 12 Nov
 2014 15:20:23 -0800 (PST)
X-Received: by 10.67.14.129 with SMTP id fg1mr50360454pad.114.1415834423892;
        Wed, 12 Nov 2014 15:20:23 -0800 (PST)
Original-Received: from na01-bn1-obe.outbound.protection.outlook.com (mail-bn1on0145.outbound.protection.outlook.com. [157.56.110.145])
        by mx.google.com with ESMTPS id ub8si23970802pac.231.2014.11.12.15.20.23
        for <std-proposals@isocpp.org>
        (version=TLSv1 cipher=ECDHE-RSA-AES128-SHA bits=128/128);
        Wed, 12 Nov 2014 15:20:23 -0800 (PST)
Received-SPF: pass (google.com: domain of gorn@microsoft.com designates 157.56.110.145 as permitted sender) client-ip=157.56.110.145;
Original-Received: from BL2PR03MB337.namprd03.prod.outlook.com (10.141.68.16) by
 BL2PR03MB338.namprd03.prod.outlook.com (10.141.68.18) with Microsoft SMTP
 Server (TLS) id 15.1.26.9; Wed, 12 Nov 2014 23:20:22 +0000
Original-Received: from BL2PR03MB337.namprd03.prod.outlook.com ([10.141.68.16]) by
 BL2PR03MB337.namprd03.prod.outlook.com ([10.141.68.16]) with mapi id
 15.01.0026.003; Wed, 12 Nov 2014 23:20:22 +0000
Thread-Topic: [std-proposals] Re: Range-based if versus  - await do-catch
 statement
Thread-Index: AQHP/sgsibaxZl5od0KYbRHjUOpYiJxdl17Q
In-Reply-To: <5463DF5A.7020607@wanadoo.fr>
Accept-Language: en-US
X-MS-Has-Attach: 
X-MS-TNEF-Correlator: 
x-originating-ip: [2001:4898:80e8:ed31::3]
x-microsoft-antispam: BCL:0;PCL:0;RULEID:;SRVR:BL2PR03MB338;
x-exchange-antispam-report-test: UriScan:;
x-exchange-antispam-report-cfa: BCL:0;PCL:0;RULEID:;SRVR:BL2PR03MB338;
x-forefront-prvs: 03932714EB
x-forefront-antispam-report: SFV:NSPM;SFS:(10019020)(6009001)(377424004)(189002)(199003)(76104003)(24454002)(377454003)(479174003)(561944003)(86362001)(106116001)(101416001)(107886001)(77156002)(19625215002)(86612001)(15975445006)(40100003)(107046002)(15202345003)(62966003)(105586002)(74316001)(99286002)(99396003)(46102003)(21056001)(95666004)(20776003)(64706001)(106356001)(31966008)(122556002)(76576001)(4396001)(2656002)(33646002)(97736003)(19580395003)(87936001)(50986999)(92566001)(108616004)(120916001)(19580405001)(76176999)(54356999)(19300405004)(3826002)(24736002);DIR:OUT;SFP:1102;SCL:1;SRVR:BL2PR03MB338;H:BL2PR03MB337.namprd03.prod.outlook.com;FPR:;SPF:None;MLV:sfv;PTR:InfoNoRecords;MX:1;A:1;LANG:en;
X-OriginatorOrg: microsoft.onmicrosoft.com
X-Original-Sender: gorn@microsoft.com
X-Original-Authentication-Results: mx.google.com;       spf=pass (google.com:
 domain of gorn@microsoft.com designates 157.56.110.145 as permitted sender)
 smtp.mail=gorn@microsoft.com;       dmarc=pass (p=NONE dis=NONE) header.from=microsoft.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: <mailto:googlegroups-manage+399137483710+unsubscribe@googlegroups.com>,
 <http://groups.google.com/a/isocpp.org/group/std-proposals/subscribe>
Content-Language: en-US
Xref: news.gmane.org gmane.comp.lang.c++.isocpp.proposals:14510
Archived-At: <http://permalink.gmane.org/gmane.comp.lang.c++.isocpp.proposals/14510>

--_000_ea89a2cb27274d6bb897412d29b47751BL2PR03MB337namprd03pro_
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

I highly recommend small functions and Sean Parent=E2=80=99s suggestion of =
not having more than one for-loop in a function. =E2=98=BA

With smaller functions you can always write:

Void foo() {
   for(x: bar()) {
          Do Something with X;
          Return;
   }
   Otherwise;
}

Also, if you are OK with using exceptions for control flow =E2=98=BA, then =
you can use optional=E2=80=99s .value() to achieve nearly the same syntax a=
s do-catch.

    try {
      auto&& item =3D ExpandSomething().value();
      DoSomething(item);
    } catch (...) { // if there is no such first element
      // unsuccessful path...
    }

As much as I like N4134 there might be cases where using something else wou=
ld be as good. =E2=98=BA

Gor

P.S.

Await will be useful where you use unconditional error propagation on most =
expands, such as

M<T> f() {
    auto x =3D await f1();
    auto y =3D await f2(x);
    return g(x,y);
}

In those cases where you want to check for an error. You don=E2=80=99t have=
 to use await at all for optional or expected.
In case of the future, you may need a wrapper: future<T> -> future<Expected=
<T>>, so that await bar() will strip the temporal expected leaving expected=
<T> enabling you to check for the error.
Thus you can use plain if. No need for try-catch

I.e.

future<T> f() {
    auto x =3D await f1();
    auto y =3D await WrapErrorWithExpected(f2(x));
    if (y.has_error())
        return DoSomething();
    else
        return g(x,y);
}

From: Vicente J. Botet Escriba [mailto:vicente.botet@wanadoo.fr]
Sent: Wednesday, November 12, 2014 2:30 PM
To: std-proposals@isocpp.org; Gor Nishanov
Subject: Re: [std-proposals] Re: Range-based if versus - await do-catch sta=
tement

Le 11/11/14 22:34, Matthew Woehlke a =C3=A9crit :

On 2014-11-11 16:12, Brent Friedman wrote:

I've noted in our codebase that we lean heavily on the convenience of

range-based for even when it's not perhaps the best way to express an idea.



//do something to the first item

for (auto& Item : range)

{

    DoSomething(Item);

    break;

}



    auto first_or_null(auto range) -> decltype(&range.begin())

    {

        auto begin =3D range.begin();

        auto end =3D range.end();

        return (begin =3D=3D end ? nullptr : &(*begin));

    }



    if (auto item =3D first_or_null(range))



Basically you want that, right? :-)



I'm not sure if that actually works, and it requires an additional

dereference when you go to use 'item', but OTOH it wouldn't require a

language change...




If the result of first_or_null (why not optional<T&>) is configured with aw=
ait, would the following be a good syntax for you?

    do {
      auto& item =3D await first_or_null(range)) ;
      DoSomething(item);
    } catch (...) { // if there is no such element
      // unsuccessful path...
    }

We will need to adapt await to jump to the catch part instead of returning =
from the function if there is no value.

This is clearly more complex than your original proposal, but it introduces=
 a mechanism to catch the await errors, which could be applicable to other =
cases.

I have used do instead of try to recall the Haskell do-notation, and becaus=
e the semantic and the efficiency, while close, would be quite different.

Another possibility is to configure directly any range with await

    do {
      auto& item =3D await range ;
      DoSomething(item);
    } catch (...) { // if there is no such first element
      // unsuccessful path...
    }

The next question is, how would perform the generated code ? Would it be as=
 efficient as
  if (!std::empty(range)) {
      DoSomething(*begin(range));
  } else {
     // unsuccessful path...
  }


Gor what do you think?

Vicente

--=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/.

--_000_ea89a2cb27274d6bb897412d29b47751BL2PR03MB337namprd03pro_
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<html xmlns:v=3D"urn:schemas-microsoft-com:vml" xmlns:o=3D"urn:schemas-micr=
osoft-com:office:office" xmlns:w=3D"urn:schemas-microsoft-com:office:word" =
xmlns:m=3D"http://schemas.microsoft.com/office/2004/12/omml" xmlns=3D"http:=
//www.w3.org/TR/REC-html40">
<head>
<meta http-equiv=3D"Content-Type" content=3D"text/html; charset=3Dutf-8">
<meta name=3D"Generator" content=3D"Microsoft Word 15 (filtered medium)">
<style><!--
/* Font Definitions */
@font-face
	{font-family:Wingdings;
	panose-1:5 0 0 0 0 0 0 0 0 0;}
@font-face
	{font-family:"Cambria Math";
	panose-1:2 4 5 3 5 4 6 3 2 4;}
@font-face
	{font-family:Calibri;
	panose-1:2 15 5 2 2 2 4 3 2 4;}
@font-face
	{font-family:Consolas;
	panose-1:2 11 6 9 2 2 4 3 2 4;}
/* Style Definitions */
p.MsoNormal, li.MsoNormal, div.MsoNormal
	{margin:0in;
	margin-bottom:.0001pt;
	font-size:12.0pt;
	font-family:"Times New Roman","serif";
	color:black;}
a:link, span.MsoHyperlink
	{mso-style-priority:99;
	color:#0563C1;
	text-decoration:underline;}
a:visited, span.MsoHyperlinkFollowed
	{mso-style-priority:99;
	color:#954F72;
	text-decoration:underline;}
pre
	{mso-style-priority:99;
	mso-style-link:"HTML Preformatted Char";
	margin:0in;
	margin-bottom:.0001pt;
	font-size:10.0pt;
	font-family:"Courier New";
	color:black;}
span.HTMLPreformattedChar
	{mso-style-name:"HTML Preformatted Char";
	mso-style-priority:99;
	mso-style-link:"HTML Preformatted";
	font-family:Consolas;
	color:black;}
span.EmailStyle19
	{mso-style-type:personal-reply;
	font-family:"Calibri","sans-serif";
	color:#1F497D;}
..MsoChpDefault
	{mso-style-type:export-only;
	font-size:10.0pt;}
@page WordSection1
	{size:8.5in 11.0in;
	margin:1.0in 1.0in 1.0in 1.0in;}
div.WordSection1
	{page:WordSection1;}
--></style><!--[if gte mso 9]><xml>
<o:shapedefaults v:ext=3D"edit" spidmax=3D"1026" />
</xml><![endif]--><!--[if gte mso 9]><xml>
<o:shapelayout v:ext=3D"edit">
<o:idmap v:ext=3D"edit" data=3D"1" />
</o:shapelayout></xml><![endif]-->
</head>
<body bgcolor=3D"white" lang=3D"EN-US" link=3D"#0563C1" vlink=3D"#954F72">
<div class=3D"WordSection1">
<p class=3D"MsoNormal"><span style=3D"font-size:11.0pt;font-family:&quot;Ca=
libri&quot;,&quot;sans-serif&quot;;color:#1F497D">I highly recommend small =
functions and Sean Parent=E2=80=99s suggestion of not having more than one =
for-loop in a function.
</span><span style=3D"font-size:11.0pt;font-family:Wingdings;color:#1F497D"=
>J</span><span style=3D"font-size:11.0pt;font-family:&quot;Calibri&quot;,&q=
uot;sans-serif&quot;;color:#1F497D"><o:p></o:p></span></p>
<p class=3D"MsoNormal"><span style=3D"font-size:11.0pt;font-family:&quot;Ca=
libri&quot;,&quot;sans-serif&quot;;color:#1F497D"><o:p>&nbsp;</o:p></span><=
/p>
<p class=3D"MsoNormal"><span style=3D"font-size:11.0pt;font-family:&quot;Ca=
libri&quot;,&quot;sans-serif&quot;;color:#1F497D">With smaller functions yo=
u can always write:<o:p></o:p></span></p>
<p class=3D"MsoNormal"><span style=3D"font-size:11.0pt;font-family:&quot;Ca=
libri&quot;,&quot;sans-serif&quot;;color:#1F497D"><o:p>&nbsp;</o:p></span><=
/p>
<p class=3D"MsoNormal"><span style=3D"font-size:11.0pt;font-family:&quot;Ca=
libri&quot;,&quot;sans-serif&quot;;color:#1F497D">Void foo() {<o:p></o:p></=
span></p>
<p class=3D"MsoNormal"><span style=3D"font-size:11.0pt;font-family:&quot;Ca=
libri&quot;,&quot;sans-serif&quot;;color:#1F497D">&nbsp;&nbsp; for(x: bar()=
) {
<o:p></o:p></span></p>
<p class=3D"MsoNormal"><span style=3D"font-size:11.0pt;font-family:&quot;Ca=
libri&quot;,&quot;sans-serif&quot;;color:#1F497D">&nbsp;&nbsp;&nbsp;&nbsp;&=
nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Do Something with X;<o:p></o:p></span></=
p>
<p class=3D"MsoNormal"><span style=3D"font-size:11.0pt;font-family:&quot;Ca=
libri&quot;,&quot;sans-serif&quot;;color:#1F497D">&nbsp;&nbsp;&nbsp;&nbsp;&=
nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Return;<o:p></o:p></span></p>
<p class=3D"MsoNormal"><span style=3D"font-size:11.0pt;font-family:&quot;Ca=
libri&quot;,&quot;sans-serif&quot;;color:#1F497D">&nbsp;&nbsp; }
<o:p></o:p></span></p>
<p class=3D"MsoNormal"><span style=3D"font-size:11.0pt;font-family:&quot;Ca=
libri&quot;,&quot;sans-serif&quot;;color:#1F497D">&nbsp;&nbsp;&nbsp;Otherwi=
se;<o:p></o:p></span></p>
<p class=3D"MsoNormal"><span style=3D"font-size:11.0pt;font-family:&quot;Ca=
libri&quot;,&quot;sans-serif&quot;;color:#1F497D">}<o:p></o:p></span></p>
<p class=3D"MsoNormal"><span style=3D"font-size:11.0pt;font-family:&quot;Ca=
libri&quot;,&quot;sans-serif&quot;;color:#1F497D"><o:p>&nbsp;</o:p></span><=
/p>
<p class=3D"MsoNormal"><span style=3D"font-size:11.0pt;font-family:&quot;Ca=
libri&quot;,&quot;sans-serif&quot;;color:#1F497D">Also, if you are OK with =
using exceptions for control flow
</span><span style=3D"font-size:11.0pt;font-family:Wingdings;color:#1F497D"=
>J</span><span style=3D"font-size:11.0pt;font-family:&quot;Calibri&quot;,&q=
uot;sans-serif&quot;;color:#1F497D">, then you can use optional=E2=80=99s .=
value() to achieve nearly the same syntax as do-catch.<o:p></o:p></span></p=
>
<p class=3D"MsoNormal"><span style=3D"font-size:11.0pt;font-family:&quot;Ca=
libri&quot;,&quot;sans-serif&quot;;color:#1F497D"><o:p>&nbsp;</o:p></span><=
/p>
<p class=3D"MsoNormal">&nbsp;&nbsp;&nbsp; <b>try</b> { <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; auto&amp;&amp; item =3D ExpandSomething().va=
lue();<br>
&nbsp; &nbsp;&nbsp;&nbsp; DoSomething(item);<br>
&nbsp;&nbsp;&nbsp; } <b>catch</b> (...) { // if there is no such first elem=
ent<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // unsuccessful path... <br>
&nbsp;&nbsp;&nbsp; }<br>
<br>
<span style=3D"font-size:11.0pt;font-family:&quot;Calibri&quot;,&quot;sans-=
serif&quot;;color:#1F497D"><o:p></o:p></span></p>
<p class=3D"MsoNormal"><span style=3D"font-size:11.0pt;font-family:&quot;Ca=
libri&quot;,&quot;sans-serif&quot;;color:#1F497D">As much as I like N4134 t=
here might be cases where using something else would be as good.
</span><span style=3D"font-size:11.0pt;font-family:Wingdings;color:#1F497D"=
>J</span><span style=3D"font-size:11.0pt;font-family:&quot;Calibri&quot;,&q=
uot;sans-serif&quot;;color:#1F497D"><o:p></o:p></span></p>
<p class=3D"MsoNormal"><b><o:p>&nbsp;</o:p></b></p>
<p class=3D"MsoNormal"><b>Gor<o:p></o:p></b></p>
<p class=3D"MsoNormal"><b><o:p>&nbsp;</o:p></b></p>
<p class=3D"MsoNormal"><b>P.S.<o:p></o:p></b></p>
<p class=3D"MsoNormal"><span style=3D"font-size:11.0pt;font-family:&quot;Ca=
libri&quot;,&quot;sans-serif&quot;;color:#1F497D"><o:p>&nbsp;</o:p></span><=
/p>
<p class=3D"MsoNormal"><span style=3D"font-size:11.0pt;font-family:&quot;Ca=
libri&quot;,&quot;sans-serif&quot;;color:#1F497D">Await will be useful wher=
e you use unconditional error propagation on most expands, such as<o:p></o:=
p></span></p>
<p class=3D"MsoNormal"><span style=3D"font-size:11.0pt;font-family:&quot;Ca=
libri&quot;,&quot;sans-serif&quot;;color:#1F497D"><o:p>&nbsp;</o:p></span><=
/p>
<p class=3D"MsoNormal"><span style=3D"font-size:11.0pt;font-family:&quot;Ca=
libri&quot;,&quot;sans-serif&quot;;color:#1F497D">M&lt;T&gt; f() {<o:p></o:=
p></span></p>
<p class=3D"MsoNormal"><span style=3D"font-size:11.0pt;font-family:&quot;Ca=
libri&quot;,&quot;sans-serif&quot;;color:#1F497D">&nbsp;&nbsp;&nbsp; auto x=
 =3D await f1();<o:p></o:p></span></p>
<p class=3D"MsoNormal"><span style=3D"font-size:11.0pt;font-family:&quot;Ca=
libri&quot;,&quot;sans-serif&quot;;color:#1F497D">&nbsp;&nbsp;&nbsp; auto y=
 =3D await f2(x);<o:p></o:p></span></p>
<p class=3D"MsoNormal"><span style=3D"font-size:11.0pt;font-family:&quot;Ca=
libri&quot;,&quot;sans-serif&quot;;color:#1F497D">&nbsp;&nbsp;&nbsp; return=
 g(x,y);<o:p></o:p></span></p>
<p class=3D"MsoNormal"><span style=3D"font-size:11.0pt;font-family:&quot;Ca=
libri&quot;,&quot;sans-serif&quot;;color:#1F497D">}<o:p></o:p></span></p>
<p class=3D"MsoNormal"><span style=3D"font-size:11.0pt;font-family:&quot;Ca=
libri&quot;,&quot;sans-serif&quot;;color:#1F497D"><o:p>&nbsp;</o:p></span><=
/p>
<p class=3D"MsoNormal"><span style=3D"font-size:11.0pt;font-family:&quot;Ca=
libri&quot;,&quot;sans-serif&quot;;color:#1F497D">In those cases where you =
want to check for an error. You don=E2=80=99t have to use await at all for =
optional or expected.<o:p></o:p></span></p>
<p class=3D"MsoNormal"><span style=3D"font-size:11.0pt;font-family:&quot;Ca=
libri&quot;,&quot;sans-serif&quot;;color:#1F497D">In case of the future, yo=
u may need a wrapper: future&lt;T&gt; -&gt; future&lt;Expected&lt;T&gt;&gt;=
, so that await bar() will strip the temporal expected leaving expected&lt;=
T&gt; enabling
 you to check for the error.<o:p></o:p></span></p>
<p class=3D"MsoNormal"><span style=3D"font-size:11.0pt;font-family:&quot;Ca=
libri&quot;,&quot;sans-serif&quot;;color:#1F497D">Thus you can use plain if=
.. No need for try-catch<o:p></o:p></span></p>
<p class=3D"MsoNormal"><span style=3D"font-size:11.0pt;font-family:&quot;Ca=
libri&quot;,&quot;sans-serif&quot;;color:#1F497D"><o:p>&nbsp;</o:p></span><=
/p>
<p class=3D"MsoNormal"><span style=3D"font-size:11.0pt;font-family:&quot;Ca=
libri&quot;,&quot;sans-serif&quot;;color:#1F497D">I.e.<o:p></o:p></span></p=
>
<p class=3D"MsoNormal"><span style=3D"font-size:11.0pt;font-family:&quot;Ca=
libri&quot;,&quot;sans-serif&quot;;color:#1F497D"><o:p>&nbsp;</o:p></span><=
/p>
<p class=3D"MsoNormal"><span style=3D"font-size:11.0pt;font-family:&quot;Ca=
libri&quot;,&quot;sans-serif&quot;;color:#1F497D">future&lt;T&gt; f() {<o:p=
></o:p></span></p>
<p class=3D"MsoNormal"><span style=3D"font-size:11.0pt;font-family:&quot;Ca=
libri&quot;,&quot;sans-serif&quot;;color:#1F497D">&nbsp;&nbsp;&nbsp; auto x=
 =3D await f1();<o:p></o:p></span></p>
<p class=3D"MsoNormal"><span style=3D"font-size:11.0pt;font-family:&quot;Ca=
libri&quot;,&quot;sans-serif&quot;;color:#1F497D">&nbsp;&nbsp;&nbsp; auto y=
 =3D await WrapErrorWithExpected(f2(x));<o:p></o:p></span></p>
<p class=3D"MsoNormal"><span style=3D"font-size:11.0pt;font-family:&quot;Ca=
libri&quot;,&quot;sans-serif&quot;;color:#1F497D">&nbsp;&nbsp;&nbsp; if (y.=
has_error())
<o:p></o:p></span></p>
<p class=3D"MsoNormal"><span style=3D"font-size:11.0pt;font-family:&quot;Ca=
libri&quot;,&quot;sans-serif&quot;;color:#1F497D">&nbsp;&nbsp;&nbsp;&nbsp;&=
nbsp;&nbsp;&nbsp;&nbsp;return DoSomething();<o:p></o:p></span></p>
<p class=3D"MsoNormal"><span style=3D"font-size:11.0pt;font-family:&quot;Ca=
libri&quot;,&quot;sans-serif&quot;;color:#1F497D">&nbsp;&nbsp;&nbsp; else<o=
:p></o:p></span></p>
<p class=3D"MsoNormal"><span style=3D"font-size:11.0pt;font-family:&quot;Ca=
libri&quot;,&quot;sans-serif&quot;;color:#1F497D">&nbsp;&nbsp;&nbsp; &nbsp;=
&nbsp;&nbsp;&nbsp;return g(x,y);<o:p></o:p></span></p>
<p class=3D"MsoNormal"><span style=3D"font-size:11.0pt;font-family:&quot;Ca=
libri&quot;,&quot;sans-serif&quot;;color:#1F497D">}<o:p></o:p></span></p>
<p class=3D"MsoNormal"><span style=3D"font-size:11.0pt;font-family:&quot;Ca=
libri&quot;,&quot;sans-serif&quot;;color:#1F497D"><o:p>&nbsp;</o:p></span><=
/p>
<div>
<div style=3D"border:none;border-top:solid #E1E1E1 1.0pt;padding:3.0pt 0in =
0in 0in">
<p class=3D"MsoNormal"><b><span style=3D"font-size:11.0pt;font-family:&quot=
;Calibri&quot;,&quot;sans-serif&quot;;color:windowtext">From:</span></b><sp=
an style=3D"font-size:11.0pt;font-family:&quot;Calibri&quot;,&quot;sans-ser=
if&quot;;color:windowtext"> Vicente J. Botet Escriba [mailto:vicente.botet@=
wanadoo.fr]
<br>
<b>Sent:</b> Wednesday, November 12, 2014 2:30 PM<br>
<b>To:</b> std-proposals@isocpp.org; Gor Nishanov<br>
<b>Subject:</b> Re: [std-proposals] Re: Range-based if versus - await do-ca=
tch statement<o:p></o:p></span></p>
</div>
</div>
<p class=3D"MsoNormal"><o:p>&nbsp;</o:p></p>
<div>
<p class=3D"MsoNormal">Le 11/11/14 22:34, Matthew Woehlke a =C3=A9crit&nbsp=
;:<o:p></o:p></p>
</div>
<blockquote style=3D"margin-top:5.0pt;margin-bottom:5.0pt">
<pre>On 2014-11-11 16:12, Brent Friedman wrote:<o:p></o:p></pre>
<blockquote style=3D"margin-top:5.0pt;margin-bottom:5.0pt">
<pre>I've noted in our codebase that we lean heavily on the convenience of<=
o:p></o:p></pre>
<pre>range-based for even when it's not perhaps the best way to express an =
idea.<o:p></o:p></pre>
<pre><o:p>&nbsp;</o:p></pre>
<pre>//do something to the first item<o:p></o:p></pre>
<pre>for (auto&amp; Item : range)<o:p></o:p></pre>
<pre>{<o:p></o:p></pre>
<pre>&nbsp;&nbsp;&nbsp; DoSomething(Item);<o:p></o:p></pre>
<pre>&nbsp;&nbsp;&nbsp; break;<o:p></o:p></pre>
<pre>}<o:p></o:p></pre>
</blockquote>
<pre><o:p>&nbsp;</o:p></pre>
<pre>&nbsp;&nbsp;&nbsp; auto first_or_null(auto range) -&gt; decltype(&amp;=
range.begin())<o:p></o:p></pre>
<pre>&nbsp;&nbsp;&nbsp; {<o:p></o:p></pre>
<pre>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; auto begin =3D range.begin(=
);<o:p></o:p></pre>
<pre>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; auto end =3D range.end();<o=
:p></o:p></pre>
<pre>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return (begin =3D=3D end ? =
nullptr : &amp;(*begin));<o:p></o:p></pre>
<pre>&nbsp;&nbsp;&nbsp; }<o:p></o:p></pre>
<pre><o:p>&nbsp;</o:p></pre>
<pre>&nbsp;&nbsp;&nbsp; if (auto item =3D first_or_null(range))<o:p></o:p><=
/pre>
<pre><o:p>&nbsp;</o:p></pre>
<pre>Basically you want that, right? :-)<o:p></o:p></pre>
<pre><o:p>&nbsp;</o:p></pre>
<pre>I'm not sure if that actually works, and it requires an additional<o:p=
></o:p></pre>
<pre>dereference when you go to use 'item', but OTOH it wouldn't require a<=
o:p></o:p></pre>
<pre>language change...<o:p></o:p></pre>
<pre><o:p>&nbsp;</o:p></pre>
<pre><o:p>&nbsp;</o:p></pre>
</blockquote>
<p class=3D"MsoNormal" style=3D"margin-bottom:12.0pt">If the result of firs=
t_or_null (why not optional&lt;T&amp;&gt;) is configured with
<b>await</b>, would the following be a good syntax for you?<br>
<br>
&nbsp;&nbsp;&nbsp; <b>do</b> { <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; auto&amp; item =3D <b>await</b> first_or_nul=
l(range)) ;<br>
&nbsp; &nbsp;&nbsp;&nbsp; DoSomething(item);<br>
&nbsp;&nbsp;&nbsp; } <b>catch</b> (...) { // if there is no such element<br=
>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // unsuccessful path... <br>
&nbsp;&nbsp;&nbsp; }<br>
<br>
We will need to adapt <b>await</b> to jump to the <b>catch</b> part instead=
 of returning from the function if there is no value.<br>
<br>
This is clearly more complex than your original proposal, but it introduces=
 a mechanism to catch the await errors, which could be applicable to other =
cases.
<br>
<br>
I have used <b>do</b> instead of <b>try</b> to recall the Haskell do-notati=
on, and because the semantic and the efficiency, while close, would be quit=
e different.
<br>
<br>
Another possibility is to configure directly any range with await<br>
<br>
&nbsp;&nbsp;&nbsp; <b>do</b> { <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; auto&amp; item =3D <b>await</b> range ;<br>
&nbsp; &nbsp;&nbsp;&nbsp; DoSomething(item);<br>
&nbsp;&nbsp;&nbsp; } <b>catch</b> (...) { // if there is no such first elem=
ent<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // unsuccessful path... <br>
&nbsp;&nbsp;&nbsp; }<br>
<br>
The next question is, how would perform the generated code ? Would it be as=
 efficient as<o:p></o:p></p>
<div>
<p class=3D"MsoNormal">&nbsp; if (!std::empty(range)) {<o:p></o:p></p>
</div>
<div>
<p class=3D"MsoNormal">&nbsp; &nbsp; &nbsp; DoSomething(*begin(range));<br>
&nbsp; } else {<br>
&nbsp; &nbsp;&nbsp; // unsuccessful path... <br>
&nbsp; }<o:p></o:p></p>
</div>
<p class=3D"MsoNormal"><br>
<br>
Gor what do you think?<br>
<br>
Vicente <o:p></o:p></p>
</div>
</body>
</html>

<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 />

--_000_ea89a2cb27274d6bb897412d29b47751BL2PR03MB337namprd03pro_--

.
