Topic: Range-based if versus - await do-catch statement


Author: "Vicente J. Botet Escriba" <vicente.botet@wanadoo.fr>
Date: Wed, 12 Nov 2014 23:29:46 +0100
Raw View
This is a multi-part message in MIME format.
--------------090909050303000004010100
Content-Type: text/plain; charset=UTF-8; format=flowed
Content-Transfer-Encoding: quoted-printable

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 id=
ea.
>>
>> //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=20
*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, and=20
because the semantic and the efficiency, while close, would be quite=20
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=20
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/.

--------------090909050303000004010100
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 11/11/14 22:34, Matthew Woehlke a
      =C3=A9crit=C2=A0:<br>
    </div>
    <blockquote cite=3D"mid:m3tvcu$9ia$1@ger.gmane.org" type=3D"cite">
      <pre wrap=3D"">On 2014-11-11 16:12, Brent Friedman wrote:
</pre>
      <blockquote type=3D"cite">
        <pre wrap=3D"">I've noted in our codebase that we lean heavily on t=
he 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&amp; Item : range)
{
    DoSomething(Item);
    break;
}
</pre>
      </blockquote>
      <pre wrap=3D"">
    auto first_or_null(auto range) -&gt; decltype(&amp;range.begin())
    {
        auto begin =3D range.begin();
        auto end =3D range.end();
        return (begin =3D=3D end ? nullptr : &amp;(*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...


</pre>
    </blockquote>
    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> first_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 elemen=
t<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> 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 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<br>
    <br>
    <div>=C2=A0 if (!std::empty(range)) {<br>
    </div>
    <div>=C2=A0 =C2=A0 =C2=A0 DoSomething(*begin(range));<br>
      =C2=A0 } else {<br>
      =C2=A0 =C2=A0=C2=A0 // unsuccessful path... <br>
      =C2=A0 }<br>
    </div>
    <br>
    <br>
    Gor what do you think?<br>
    <br>
    Vicente
  </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 />

--------------090909050303000004010100--

.


Author: Gor Nishanov <gorn@microsoft.com>
Date: Wed, 12 Nov 2014 23:20:21 +0000
Raw View
--_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_--

.


Author: "Vicente J. Botet Escriba" <vicente.botet@wanadoo.fr>
Date: Thu, 13 Nov 2014 01:10:07 +0100
Raw View
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--

.


Author: Gor Nishanov <gorn@microsoft.com>
Date: Thu, 13 Nov 2014 01:59:01 +0000
Raw View
--_000_6e1462b914214c95a4ff7102f53a9755BL2PR03MB337namprd03pro_
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

I think it is a cool idea.

Though for me to become enthusiastic about it, I need to see a real example=
 where using do-catch is significantly better than using smaller functions =
(or even named lambdas).
Essentially, I think that if the same goal can be achieved by structuring y=
our code differently, it is goodness.

Also, I would like to keep the initial proposal small to ensure ease of pas=
sing. Once it is in, we can pile on to add more things on top =E2=98=BA.

In my example in PS, I was using futures, thus await was needed to strip te=
mporal aspect. I was using Wrap to prevent expansion of error. As I mention=
ed before Wrap was doing: future<T> -> future<expected<T>> transformation. =
Await only strips one level, allowing expected to be checked for errors pri=
or to dereference.

Gor

From: Vicente J. Botet Escriba [mailto:vicente.botet@wanadoo.fr]
Sent: Wednesday, November 12, 2014 4:10 PM
To: Gor Nishanov; std-proposals@isocpp.org
Subject: Re: [std-proposals] Re: Range-based if versus - await do-catch sta=
tement

Le 13/11/14 00:20, Gor Nishanov a =C3=A9crit :
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...
    }


This make use of exceptions, that if I'm not wrong, is more expensive that =
just a jump.

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);
}

This is the same as returning optional<T> directly, which impose to make us=
e 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 the r=
esult 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<mailto: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_6e1462b914214c95a4ff7102f53a9755BL2PR03MB337namprd03pro_
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;
 font-family:"Calibri","sans-serif";
 color:#1F497D;}
span.EmailStyle20
 {mso-style-type:personal;
 font-family:"Calibri","sans-serif";
 color:#1F497D;}
span.EmailStyle21
 {mso-style-type:personal-compose;
 font-family:"Calibri","sans-serif";
 color:windowtext;}
..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 think it is a cool idea=
..<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">Though for me to become e=
nthusiastic about it, I need to see a real example where using do-catch is =
significantly better than using smaller functions (or even
 named lambdas).<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">Essentially, I think that=
 if the same goal can be achieved by structuring your code differently, it =
is goodness.<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, I would like to kee=
p the initial proposal small to ensure ease of passing. Once it is in, we c=
an pile on to add more things on top
</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">In my example in PS, I wa=
s using futures, thus await was needed to strip temporal aspect. I was usin=
g Wrap to prevent expansion of error. As I mentioned before
 Wrap was doing: future&lt;T&gt; -&gt; future&lt;expected&lt;T&gt;&gt; tran=
sformation. Await only strips one level, allowing expected to be checked fo=
r errors prior to dereference.<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">Gor<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 4:10 PM<br>
<b>To:</b> Gor Nishanov; std-proposals@isocpp.org<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 13/11/14 00:20, Gor Nishanov a =C3=A9crit&nbsp;:<=
o:p></o:p></p>
</div>
<blockquote style=3D"margin-top:5.0pt;margin-bottom:5.0pt">
<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><o:p></o:p></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;</span><o:p></o:p><=
/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:</span><o:p></o:p></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;</span><o:p></o:p><=
/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() {</span><o:p><=
/o:p></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()=
) {
</span><o:p></o:p></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;</span><o:p></o:p></=
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;</span><o:p></o:p></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; }
</span><o:p></o:p></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;</span><o:p></o:p></p>
<p class=3D"MsoNormal"><span style=3D"font-size:11.0pt;font-family:&quot;Ca=
libri&quot;,&quot;sans-serif&quot;;color:#1F497D">}</span><o:p></o:p></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;</span><o:p></o:p><=
/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.</span><o:p></o:p></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;</span><o:p></o:p><=
/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>
<br>
<o:p></o:p></p>
</blockquote>
<p class=3D"MsoNormal">This make use of exceptions, that if I'm not wrong, =
is more expensive that just a jump.<br>
<br>
<o:p></o:p></p>
<blockquote style=3D"margin-top:5.0pt;margin-bottom:5.0pt">
<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><o:p></o:p></p>
<p class=3D"MsoNormal"><b>&nbsp;</b><o:p></o:p></p>
<p class=3D"MsoNormal"><b>Gor</b><o:p></o:p></p>
<p class=3D"MsoNormal"><b>&nbsp;</b><o:p></o:p></p>
<p class=3D"MsoNormal"><b>P.S.</b><o:p></o:p></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;</span><o:p></o:p><=
/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</span><o=
:p></o:p></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;</span><o:p></o:p><=
/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() {</span><o=
:p></o:p></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();</span><o:p></o:p></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);</span><o:p></o:p></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);</span><o:p></o:p></p>
<p class=3D"MsoNormal"><span style=3D"font-size:11.0pt;font-family:&quot;Ca=
libri&quot;,&quot;sans-serif&quot;;color:#1F497D">}</span><o:p></o:p></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;</span><o:p></o:p><=
/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.</span><o:p></o:p></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.</span><o:p></o:p></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</span><o:p></o:p></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;</span><o:p></o:p><=
/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.</span><o:p></o:p></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;</span><o:p></o:p><=
/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() {</sp=
an><o:p></o:p></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();</span><o:p></o:p></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));</span><o:p></o:p></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())
</span><o:p></o:p></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();</span><o:p></o:p></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</=
span><o:p></o:p></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);</span><o:p></o:p></p>
<p class=3D"MsoNormal"><span style=3D"font-size:11.0pt;font-family:&quot;Ca=
libri&quot;,&quot;sans-serif&quot;;color:#1F497D">}</span><o:p></o:p></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;</span><o:p></o:p><=
/p>
</blockquote>
<p class=3D"MsoNormal" style=3D"margin-bottom:12.0pt">This is the same as r=
eturning 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 r=
esult and probably been more efficient than using exceptions.<br>
<br>
It is very similar to the Haskell do-notation for MonadError<o:p></o:p></p>
<pre>do { action1; action2; action3 } `catchError` handler<o:p></o:p></pre>
<p class=3D"MsoNormal"><br>
<br>
Vicente <br>
<br>
<br>
<o:p></o:p></p>
<blockquote style=3D"margin-top:5.0pt;margin-bottom:5.0pt">
<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 [<a href=3D"mailto:vic=
ente.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 href=3D"mailto:std-proposals@isocpp.org">std-proposals@isocpp=
..org</a>; Gor Nishanov<br>
<b>Subject:</b> Re: [std-proposals] Re: Range-based if versus - await do-ca=
tch statement</span><o:p></o:p></p>
</div>
</div>
<p class=3D"MsoNormal">&nbsp;<o:p></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>&nbsp;<o:p></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>&nbsp;<o:p></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>&nbsp;<o:p></o:p></pre>
<pre>&nbsp;&nbsp;&nbsp; if (auto item =3D first_or_null(range))<o:p></o:p><=
/pre>
<pre>&nbsp;<o:p></o:p></pre>
<pre>Basically you want that, right? :-)<o:p></o:p></pre>
<pre>&nbsp;<o:p></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>&nbsp;<o:p></o:p></pre>
<pre>&nbsp;<o:p></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>
</blockquote>
<p class=3D"MsoNormal"><o:p>&nbsp;</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_6e1462b914214c95a4ff7102f53a9755BL2PR03MB337namprd03pro_--

.