220 14511 <5463F6DF.8060103@wanadoo.fr> article
Path: news.gmane.org!not-for-mail
From: "Vicente J. Botet Escriba" <vicente.botet@wanadoo.fr>
Newsgroups: gmane.comp.lang.c++.isocpp.proposals
Subject: Re: Re: Range-based if versus  - await do-catch statement
Date: Thu, 13 Nov 2014 01:10:07 +0100
Lines: 686
Approved: news@gmane.org
Message-ID: <5463F6DF.8060103@wanadoo.fr>
References: <CADbh+eQCaTPArs7YBUg9mYwrnJ2Gu3SRAfqUbPiLscpyxV8JqQ@mail.gmail.com> <m3tvcu$9ia$1@ger.gmane.org> <5463DF5A.7020607@wanadoo.fr> <ea89a2cb27274d6bb897412d29b47751@BL2PR03MB337.namprd03.prod.outlook.com>
Reply-To: std-proposals@isocpp.org
NNTP-Posting-Host: plane.gmane.org
Mime-Version: 1.0
Content-Type: multipart/alternative;
 boundary="------------080204000206010400090406"
X-Trace: ger.gmane.org 1415837417 17167 80.91.229.3 (13 Nov 2014 00:10:17 GMT)
X-Complaints-To: usenet@ger.gmane.org
NNTP-Posting-Date: Thu, 13 Nov 2014 00:10:17 +0000 (UTC)
To: Gor Nishanov <gorn@microsoft.com>, 
 "std-proposals@isocpp.org" <std-proposals@isocpp.org>
Original-X-From: std-proposals+bncBDH67CONY4PBBYPNR6RQKGQEHUELZWY@isocpp.org Thu Nov 13 01:10:10 2014
Return-path: <std-proposals+bncBDH67CONY4PBBYPNR6RQKGQEHUELZWY@isocpp.org>
Envelope-to: gclcip-std-proposals@m.gmane.org
Original-Received: from mail-wg0-f72.google.com ([74.125.82.72])
	by plane.gmane.org with esmtp (Exim 4.69)
	(envelope-from <std-proposals+bncBDH67CONY4PBBYPNR6RQKGQEHUELZWY@isocpp.org>)
	id 1XohzG-0003NX-E6
	for gclcip-std-proposals@m.gmane.org; Thu, 13 Nov 2014 01:10:10 +0100
Original-Received: by mail-wg0-f72.google.com with SMTP id y19sf29068wgg.11
        for <gclcip-std-proposals@m.gmane.org>; Wed, 12 Nov 2014 16:10:10 -0800 (PST)
X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
        d=1e100.net; s=20130820;
        h=x-gm-message-state:message-id:date:from:user-agent:mime-version:to
         :subject:references:in-reply-to: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-type;
        bh=tYVCuMJYEI/ucbNBgeqo7OindQ7G3RLylQ4C+rIzkXI=;
        b=HPezbWllkQkv1guCamh9zGwB1ymlddnnBnzlGiVYiaUmrjxugdHcx2DUfUfN0i/NMT
         +IxLJ6jQrw1oCi3kn+LfYQG7sWIQb+yjerpKoNGiVTI2UObstolODubuXMuL7vp9BPLw
         GZwDLHSZ7xgDxvJfOTBno/fng0MxZcALqNv6d+lIVRhBW4JGQIpzeQ8ABnYx8//HQqOO
         NuW4FSG99dzViqhca5tBIlM+yDi3TtH/FT3ejTHUugaq5/w7Jitjh8aWZAx/H95Y3kLz
         k5guqM01Y/hL4MV37fnYbuHW2ye3P0DDf9Y31ngkN33xyDXwJwbiAAR9C0u2NM60f4QH
         n9Qg==
X-Gm-Message-State: ALoCoQlak1/KtCru74UnhUeZIFTNuTx70vemK8QqP+RjP8TRn6EHHluW1wt7xyQS+Z8FpXquYY5E
X-Received: by 10.152.30.66 with SMTP id q2mr8530547lah.2.1415837410059;
        Wed, 12 Nov 2014 16:10:10 -0800 (PST)
X-BeenThere: std-proposals@isocpp.org
Original-Received: by 10.180.21.129 with SMTP id v1ls18110wie.38.gmail; Wed, 12 Nov
 2014 16:10:08 -0800 (PST)
X-Received: by 10.181.8.72 with SMTP id di8mr815372wid.1.1415837408916;
        Wed, 12 Nov 2014 16:10:08 -0800 (PST)
Original-Received: from smtp.smtpout.orange.fr (smtp05.smtpout.orange.fr. [80.12.242.127])
        by mx.google.com with ESMTP id em9si29790749wib.65.2014.11.12.16.10.08
        for <std-proposals@isocpp.org>;
        Wed, 12 Nov 2014 16:10:08 -0800 (PST)
Received-SPF: none (google.com: vicente.botet@wanadoo.fr does not designate permitted sender hosts) client-ip=80.12.242.127;
Original-Received: from new-host.home ([81.53.62.225])
	by mwinf5d28 with ME
	id EoA71p00C4rb8U103oA7h2; Thu, 13 Nov 2014 01:10:08 +0100
X-ME-Helo: new-host.home
X-ME-Auth: dmljZW50ZS5ib3RldEB3YW5hZG9vLmZy
X-ME-Date: Thu, 13 Nov 2014 01:10:08 +0100
X-ME-IP: 81.53.62.225
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.7; rv:24.0) Gecko/20100101 Thunderbird/24.6.0
In-Reply-To: <ea89a2cb27274d6bb897412d29b47751@BL2PR03MB337.namprd03.prod.outlook.com>
X-Original-Sender: vicente.botet@wanadoo.fr
X-Original-Authentication-Results: mx.google.com;       spf=none (google.com:
 vicente.botet@wanadoo.fr does not designate permitted sender hosts) smtp.mail=vicente.botet@wanadoo.fr
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>
Xref: news.gmane.org gmane.comp.lang.c++.isocpp.proposals:14511
Archived-At: <http://permalink.gmane.org/gmane.comp.lang.c++.isocpp.proposals/14511>

This is a multi-part message in MIME format.
--------------080204000206010400090406
Content-Type: text/plain; charset=UTF-8; format=flowed
Content-Transfer-Encoding: quoted-printable

Le 13/11/14 00:20, Gor Nishanov a =C3=A9crit :
>
> I highly recommend small functions and Sean Parent=E2=80=99s suggestion o=
f not=20
> having more than one for-loop in a function. J
>
> 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 J, then you=20
> can use optional=E2=80=99s .value() to achieve nearly the same syntax as =
do-catch.
>
> *try* {
>       auto&& item =3D ExpandSomething().value();
>       DoSomething(item);
>     } *catch* (...) { // if there is no such first element
>       // unsuccessful path...
>     }
>
This make use of exceptions, that if I'm not wrong, is more expensive=20
that just a jump.
>
> As much as I like N4134 there might be cases where using something=20
> else would be as good. J
>
> **
>
> *Gor*
>
> **
>
> *P.S.*
>
> Await will be useful where you use unconditional error propagation on=20
> 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 ha=
ve to=20
> use await at all for optional or expected.
>
> In case of the future, you may need a wrapper: future<T> ->=20
> future<Expected<T>>, so that await bar() will strip the temporal=20
> 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);
>
> }
>
This is the same as returning optional<T> directly, which impose to make=20
use of operator*(). I don't see the interest of the nesting.
Could you come back to the OP example?
My do-catch suggestion has the advantage to don't need to dereference=20
the result and probably been more efficient than using exceptions.

It is very similar to the Haskell do-notation for MonadError

do { action1; action2; action3 } `catchError` handler



Vicente

> *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=20
> do-catch statement
>
> 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 convenienc=
e of
>
>         range-based for even when it's not perhaps the best way to expres=
s an idea.
>
>          =20
>
>         //do something to the first item
>
>         for (auto& Item : range)
>
>         {
>
>              DoSomething(Item);
>
>              break;
>
>         }
>
>      =20
>
>          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));
>
>          }
>
>      =20
>
>          if (auto item =3D first_or_null(range))
>
>      =20
>
>     Basically you want that, right? :-)
>
>      =20
>
>     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...
>
>      =20
>
>      =20
>
> If the result of first_or_null (why not optional<T&>) is configured=20
> with *await*, 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=20
> returning from the function if there is no value.
>
> This is clearly more complex than your original proposal, but it=20
> introduces a mechanism to catch the await errors, which could be=20
> applicable to other cases.
>
> I have used *do* instead of *try* to recall the Haskell do-notation,=20
> and because the semantic and the efficiency, while close, would be=20
> 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=20
> 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/.

--------------080204000206010400090406
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<html>
  <head>
    <meta content=3D"text/html; charset=3DUTF-8" http-equiv=3D"Content-Type=
">
  </head>
  <body bgcolor=3D"#FFFFFF" text=3D"#000000">
    <div class=3D"moz-cite-prefix">Le 13/11/14 00:20, Gor Nishanov a
      =C3=A9crit=C2=A0:<br>
    </div>
    <blockquote
cite=3D"mid:ea89a2cb27274d6bb897412d29b47751@BL2PR03MB337.namprd03.prod.out=
look.com"
      type=3D"cite">
      <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]-->
      <div class=3D"WordSection1">
        <p class=3D"MsoNormal"><span
style=3D"font-size:11.0pt;font-family:&quot;Calibri&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;,&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;Calibri&quot;,&quot;sans-serif&=
quot;;color:#1F497D"><o:p>=C2=A0</o:p></span></p>
        <p class=3D"MsoNormal"><span
style=3D"font-size:11.0pt;font-family:&quot;Calibri&quot;,&quot;sans-serif&=
quot;;color:#1F497D">With
            smaller functions you can always write:<o:p></o:p></span></p>
        <p class=3D"MsoNormal"><span
style=3D"font-size:11.0pt;font-family:&quot;Calibri&quot;,&quot;sans-serif&=
quot;;color:#1F497D"><o:p>=C2=A0</o:p></span></p>
        <p class=3D"MsoNormal"><span
style=3D"font-size:11.0pt;font-family:&quot;Calibri&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;Calibri&quot;,&quot;sans-serif&=
quot;;color:#1F497D">=C2=A0=C2=A0
            for(x: bar()) {
            <o:p></o:p></span></p>
        <p class=3D"MsoNormal"><span
style=3D"font-size:11.0pt;font-family:&quot;Calibri&quot;,&quot;sans-serif&=
quot;;color:#1F497D">=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=
=C2=A0Do
            Something with X;<o:p></o:p></span></p>
        <p class=3D"MsoNormal"><span
style=3D"font-size:11.0pt;font-family:&quot;Calibri&quot;,&quot;sans-serif&=
quot;;color:#1F497D">=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0
            Return;<o:p></o:p></span></p>
        <p class=3D"MsoNormal"><span
style=3D"font-size:11.0pt;font-family:&quot;Calibri&quot;,&quot;sans-serif&=
quot;;color:#1F497D">=C2=A0=C2=A0
            }
            <o:p></o:p></span></p>
        <p class=3D"MsoNormal"><span
style=3D"font-size:11.0pt;font-family:&quot;Calibri&quot;,&quot;sans-serif&=
quot;;color:#1F497D">=C2=A0=C2=A0=C2=A0Otherwise;<o:p></o:p></span></p>
        <p class=3D"MsoNormal"><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;Calibri&quot;,&quot;sans-serif&=
quot;;color:#1F497D"><o:p>=C2=A0</o:p></span></p>
        <p class=3D"MsoNormal"><span
style=3D"font-size:11.0pt;font-family:&quot;Calibri&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;,&quot;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;Calibri&quot;,&quot;sans-serif&=
quot;;color:#1F497D"><o:p>=C2=A0</o:p></span></p>
        <p class=3D"MsoNormal">=C2=A0=C2=A0=C2=A0 <b>try</b> { <br>
          =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 auto&amp;&amp; item =3D ExpandSome=
thing().value();<br>
          =C2=A0 =C2=A0=C2=A0=C2=A0 DoSomething(item);<br>
          =C2=A0=C2=A0=C2=A0 } <b>catch</b> (...) { // if there is no such =
first
          element<br>
          =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 // unsuccessful path... <br>
          =C2=A0=C2=A0=C2=A0 }<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>
      </div>
    </blockquote>
    This make use of exceptions, that if I'm not wrong, is more
    expensive that just a jump.<br>
    <blockquote
cite=3D"mid:ea89a2cb27274d6bb897412d29b47751@BL2PR03MB337.namprd03.prod.out=
look.com"
      type=3D"cite">
      <div class=3D"WordSection1">
        <p class=3D"MsoNormal"><span
style=3D"font-size:11.0pt;font-family:&quot;Calibri&quot;,&quot;sans-serif&=
quot;;color:#1F497D">As
            much as I like N4134 there 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;,&quot;sans-serif&=
quot;;color:#1F497D"><o:p></o:p></span></p>
        <p class=3D"MsoNormal"><b><o:p>=C2=A0</o:p></b></p>
        <p class=3D"MsoNormal"><b>Gor<o:p></o:p></b></p>
        <p class=3D"MsoNormal"><b><o:p>=C2=A0</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;Calibri&quot;,&quot;sans-serif&=
quot;;color:#1F497D"><o:p>=C2=A0</o:p></span></p>
        <p class=3D"MsoNormal"><span
style=3D"font-size:11.0pt;font-family:&quot;Calibri&quot;,&quot;sans-serif&=
quot;;color:#1F497D">Await
            will be useful where 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;Calibri&quot;,&quot;sans-serif&=
quot;;color:#1F497D"><o:p>=C2=A0</o:p></span></p>
        <p class=3D"MsoNormal"><span
style=3D"font-size:11.0pt;font-family:&quot;Calibri&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;Calibri&quot;,&quot;sans-serif&=
quot;;color:#1F497D">=C2=A0=C2=A0=C2=A0
            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;Calibri&quot;,&quot;sans-serif&=
quot;;color:#1F497D">=C2=A0=C2=A0=C2=A0
            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;Calibri&quot;,&quot;sans-serif&=
quot;;color:#1F497D">=C2=A0=C2=A0=C2=A0
            return g(x,y);<o:p></o:p></span></p>
        <p class=3D"MsoNormal"><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;Calibri&quot;,&quot;sans-serif&=
quot;;color:#1F497D"><o:p>=C2=A0</o:p></span></p>
        <p class=3D"MsoNormal"><span
style=3D"font-size:11.0pt;font-family:&quot;Calibri&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;Calibri&quot;,&quot;sans-serif&=
quot;;color:#1F497D">In
            case of the future, you 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;Calibri&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;Calibri&quot;,&quot;sans-serif&=
quot;;color:#1F497D"><o:p>=C2=A0</o:p></span></p>
        <p class=3D"MsoNormal"><span
style=3D"font-size:11.0pt;font-family:&quot;Calibri&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;Calibri&quot;,&quot;sans-serif&=
quot;;color:#1F497D"><o:p>=C2=A0</o:p></span></p>
        <p class=3D"MsoNormal"><span
style=3D"font-size:11.0pt;font-family:&quot;Calibri&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;Calibri&quot;,&quot;sans-serif&=
quot;;color:#1F497D">=C2=A0=C2=A0=C2=A0
            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;Calibri&quot;,&quot;sans-serif&=
quot;;color:#1F497D">=C2=A0=C2=A0=C2=A0
            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;Calibri&quot;,&quot;sans-serif&=
quot;;color:#1F497D">=C2=A0=C2=A0=C2=A0
            if (y.has_error())
            <o:p></o:p></span></p>
        <p class=3D"MsoNormal"><span
style=3D"font-size:11.0pt;font-family:&quot;Calibri&quot;,&quot;sans-serif&=
quot;;color:#1F497D">=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0return
            DoSomething();<o:p></o:p></span></p>
        <p class=3D"MsoNormal"><span
style=3D"font-size:11.0pt;font-family:&quot;Calibri&quot;,&quot;sans-serif&=
quot;;color:#1F497D">=C2=A0=C2=A0=C2=A0
            else<o:p></o:p></span></p>
        <p class=3D"MsoNormal"><span
style=3D"font-size:11.0pt;font-family:&quot;Calibri&quot;,&quot;sans-serif&=
quot;;color:#1F497D">=C2=A0=C2=A0=C2=A0
            =C2=A0=C2=A0=C2=A0=C2=A0return g(x,y);<o:p></o:p></span></p>
        <p class=3D"MsoNormal"><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;Calibri&quot;,&quot;sans-serif&=
quot;;color:#1F497D"><o:p>=C2=A0</o:p></span></p>
      </div>
    </blockquote>
    This is the same as returning optional&lt;T&gt; directly, which
    impose to make use of operator*(). I don't see the interest of the
    nesting.<br>
    Could you come back to the OP example?<br>
    My do-catch suggestion has the advantage to don't need to
    dereference the result and probably been more efficient than using
    exceptions.<br>
    <br>
    It is very similar to the Haskell do-notation for MonadError<br>
    <br>
    <meta http-equiv=3D"content-type" content=3D"text/html; charset=3DUTF-8=
">
    <pre>do { action1; action2; action3 } `catchError` handler
</pre>
    <br>
    <br>
    Vicente <br>
    <br>
    <blockquote
cite=3D"mid:ea89a2cb27274d6bb897412d29b47751@BL2PR03MB337.namprd03.prod.out=
look.com"
      type=3D"cite">
      <div class=3D"WordSection1">
        <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><span
style=3D"font-size:11.0pt;font-family:&quot;Calibri&quot;,&quot;sans-serif&=
quot;;color:windowtext">
                Vicente J. Botet Escriba
                [<a class=3D"moz-txt-link-freetext" href=3D"mailto:vicente.=
botet@wanadoo.fr">mailto:vicente.botet@wanadoo.fr</a>]
                <br>
                <b>Sent:</b> Wednesday, November 12, 2014 2:30 PM<br>
                <b>To:</b> <a class=3D"moz-txt-link-abbreviated" href=3D"ma=
ilto:std-proposals@isocpp.org">std-proposals@isocpp.org</a>; Gor Nishanov<b=
r>
                <b>Subject:</b> Re: [std-proposals] Re: Range-based if
                versus - await do-catch statement<o:p></o:p></span></p>
          </div>
        </div>
        <p class=3D"MsoNormal"><o:p>=C2=A0</o:p></p>
        <div>
          <p class=3D"MsoNormal">Le 11/11/14 22:34, Matthew Woehlke a
            =C3=A9crit=C2=A0:<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 con=
venience 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>=C2=A0</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>=C2=A0=C2=A0=C2=A0 DoSomething(Item);<o:p></o:p></pre>
            <pre>=C2=A0=C2=A0=C2=A0 break;<o:p></o:p></pre>
            <pre>}<o:p></o:p></pre>
          </blockquote>
          <pre><o:p>=C2=A0</o:p></pre>
          <pre>=C2=A0=C2=A0=C2=A0 auto first_or_null(auto range) -&gt; decl=
type(&amp;range.begin())<o:p></o:p></pre>
          <pre>=C2=A0=C2=A0=C2=A0 {<o:p></o:p></pre>
          <pre>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 auto begin =3D ra=
nge.begin();<o:p></o:p></pre>
          <pre>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 auto end =3D rang=
e.end();<o:p></o:p></pre>
          <pre>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 return (begin =3D=
=3D end ? nullptr : &amp;(*begin));<o:p></o:p></pre>
          <pre>=C2=A0=C2=A0=C2=A0 }<o:p></o:p></pre>
          <pre><o:p>=C2=A0</o:p></pre>
          <pre>=C2=A0=C2=A0=C2=A0 if (auto item =3D first_or_null(range))<o=
:p></o:p></pre>
          <pre><o:p>=C2=A0</o:p></pre>
          <pre>Basically you want that, right? :-)<o:p></o:p></pre>
          <pre><o:p>=C2=A0</o:p></pre>
          <pre>I'm not sure if that actually works, and it requires an addi=
tional<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>=C2=A0</o:p></pre>
          <pre><o:p>=C2=A0</o:p></pre>
        </blockquote>
        <p class=3D"MsoNormal" style=3D"margin-bottom:12.0pt">If the result
          of first_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>
          =C2=A0=C2=A0=C2=A0 <b>do</b> { <br>
          =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 auto&amp; item =3D <b>await</b> fi=
rst_or_null(range)) ;<br>
          =C2=A0 =C2=A0=C2=A0=C2=A0 DoSomething(item);<br>
          =C2=A0=C2=A0=C2=A0 } <b>catch</b> (...) { // if there is no such =
element<br>
          =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 // unsuccessful path... <br>
          =C2=A0=C2=A0=C2=A0 }<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-notation, and because the semantic and the
          efficiency, while close, would be quite different.
          <br>
          <br>
          Another possibility is to configure directly any range with
          await<br>
          <br>
          =C2=A0=C2=A0=C2=A0 <b>do</b> { <br>
          =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 auto&amp; item =3D <b>await</b> ra=
nge ;<br>
          =C2=A0 =C2=A0=C2=A0=C2=A0 DoSomething(item);<br>
          =C2=A0=C2=A0=C2=A0 } <b>catch</b> (...) { // if there is no such =
first
          element<br>
          =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 // unsuccessful path... <br>
          =C2=A0=C2=A0=C2=A0 }<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">=C2=A0 if (!std::empty(range)) {<o:p></o:p=
></p>
        </div>
        <div>
          <p class=3D"MsoNormal">=C2=A0 =C2=A0 =C2=A0 DoSomething(*begin(ra=
nge));<br>
            =C2=A0 } else {<br>
            =C2=A0 =C2=A0=C2=A0 // unsuccessful path... <br>
            =C2=A0 }<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>
    </blockquote>
    <br>
  </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 />

--------------080204000206010400090406--

.
